farhadi / node-smpp

SMPP client and server implementation in node.js
MIT License
417 stars 177 forks source link

Session Randomly dropped by the server | ECONNRESET #251

Open sam08sk opened 5 months ago

sam08sk commented 5 months ago

Hello,

I have a decent understanding of this library. However, I cannot resolve a random disconnection issue that keeps happening. Every few minutes or sometimes hours, the client gets disconnected from the SMPP server and gives only the following error in the logs

2024-03-22T11:30:38: Error: read ECONNRESET
2024-03-22T11:30:38:     at TCP.onStreamRead (node:internal/stream_base_commons:217:20) {
2024-03-22T11:30:38:   errno: -104,
2024-03-22T11:30:38:   code: 'ECONNRESET',
2024-03-22T11:30:38:   syscall: 'read'
2024-03-22T11:30:38: }

I have tried inspecting this but there is no error I can pinpoint that cause this. TCP dump taken reveals that the server sends [FIN, ACK] packet that causes disconnection. My best guess is that the client does not send "enquire_link" quickly enough and this causes disconnection. The client cannot change the enquire_link_interval period which is 60 seconds. Is there a way to increase the window we wait for enquire_link PDU before we disconnect? Is my understanding flawed here?

Also, I tried handling this by using session.on("error", (){}) but it doesn't work. I cannot even catch and log this error.

I would appreciate any help.

-Thanks in advance

dotsinspace commented 5 months ago

Same...Have you find the solution ?

dotsinspace commented 5 months ago

This is why i start hating this library...no support nothing.

sam08sk commented 4 months ago

@juliangut @farhadi Hey guys, I just need some direction here. What part is responsible for dropping the connection if the server doesn't receive enquire_link_pdu in time? And where is this time interval written? Is it 60s, or 30s? I would really appreciate any guidance.

You've done solid work here, especially with the proxy protocol support.

-Thanks in advance

dotsinspace commented 4 months ago

@sam08sk enquire_link can be set to anything generally its between 50 to 60. now you have to make sure to respond to the client on event enquire_link with response..thats it and it should not be a issue.

How you have used the proxy protocol..truly i didn't know what it does...Please help

sam08sk commented 4 months ago

@dotsinspace The client is sending enquire_link every 60 seconds, the server randomly sends a disconnect signal (FIN packet) to the client which causes the disconnection. This does not happen if the client is sending enquire_link every 30 seconds. So I am wondering where this particular setting could be.

The proxy protocol is only used in complex systems. Where there is an external load balancer that faces the internet, and then an internal load balancer in front of our SMPP server. The original IP of the client is lost in this kind of setup and can be preserved in the proxy protocol. Nginx has similar support. To get the original IP of the client in these kinds of setups, the proxy protocol is a must-have.

-Cheers

dotsinspace commented 4 months ago

@sam08sk you can set this setting on your side in auto_enquire_link_period. Please make to add enquire_link as per client need. over and all if enquire_link is 30 then client has to send packet within 30seconds to make sure that connection is live. same for you if you are creating session. you have to make sure to set auto_enquire_link_period as per your need.

This library has one huge issue and that is ( Contributers ) are not responding or anyone is not responding on issues of this library.

sam08sk commented 4 months ago

@dotsinspace Thank you for your response. A look at the source reveals that the auto_enquire_link_period option is for the client, not the server, am I right? On the server side, there is no such option. I am only accepting SMPP connections from clients, I am not connecting to any server via SMPP using this library. When these clients connect, if they don't send enquire_link for a "time" the connection is dropped by this library. Where is this "time" set?

I understand the inability to respond, such is the nature of open source I guess. I appreciate you taking the time and suggest a possible solution.

-Cheers

dotsinspace commented 4 months ago

As far as i know the process. when client connects then Client has to make sure that they send enquire_link in timely manner for which your server has to respond back to the client with ROK on enquire_link_resp. now coming to the time part...i think you should try it with 55s to 60s. Why because library doesn't provide any straight forward documentation on it and i have tested it..and 55s to 60s ensures smooth connection else you can set setTimeout on socket using JS Proxy.

dotsinspace commented 4 months ago

@sam08sk did you found out the reason for CONNECTION RESET ?

denishrana09 commented 3 months ago

Have you handled enquire_link listener on your server?

It means, whenever client tries to send enquire pdu to your server, you have to respond it.

some basic code:


// let say you created the server like this
const server = smpp.createServer({ debug: false });

server.on('session', (session) => {
  session.on('bind_transceiver', (pdu) => {
    // ...
  });

  session.on('error', (pdu) => {
    // ...
  });

  session.on('unbind', (pdu) => {
    console.log(`Unbind request received`);
    session.send(pdu.response());
    session.close();
  });

  session.on('enquire_link', (pdu) => {
    session.send(pdu.response());
  });
})
sam08sk commented 3 months ago

Hello everyone, thank you for your responses. Yes, I have done everything by the book. I solved this issue by looking at the different setups I did for different customers, and why one was stable and another one not. The culprit was "Proxy Protocol". I know it may not help you as you might not be using this at all. I disabled this and now the connection has been stable for a week.

This feature is also marked experimental so I think it is not production ready yet. This has introduced another problem now. I cannot get real IP of the SMPP clients, only the IP of load balancer so I am unable to perform whitelisting, but I'll try another approach for that instead of using proxy protocol here.

dotsinspace commented 3 months ago

In my case Proxy Protocol is disabled...but still if i run my app in pm2 with instances > 1 then some of the connection will drop. and @denishrana09 yes did it already.