Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add dontreuseaddr parameter #573

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

smititelu
Copy link
Contributor

@smititelu smititelu commented Mar 18, 2022

Hi,

Premises:

  • debian 9
  • use -tn parameter
  • sysctl -w net.ipv4.ip_local_port_range="60000 64000" -> set a range of allowed ports

We had the following issue:

  • bind() syscall selected only odd ports in that interval
  • bind() syscall chose to reuse a port when always reaching 1/4 of the configured range of allowed ports

Example:
For the premises, 1000 TCP calls worked, and on 1001 TCP call it failed with error:
2022-03-15 15:44:18.049457 1647355458.049457: Unable to connect a TCP/SCTP/TLS socket, errno = 99 (Cannot assign requested address)

Everything worked ok on UDP and all 4000 ports were used.

We have figured out that not setting SO_REUSEADDR for TCP sockets, fixed this.

Thank you,
Stefan

@smititelu
Copy link
Contributor Author

updated the flag to SIPP_OPTION_SETFLAG

@wdoekes
Copy link
Member

wdoekes commented Nov 17, 2022

Have you figured out why it helps yet?

@smititelu
Copy link
Contributor Author

Hi, it helps because will open the requested number of TCP ports, and not try to reuse any of already opened ones.

@wdoekes
Copy link
Member

wdoekes commented Nov 29, 2022

Not fond of that fix because it adds more options. And it disables REUSEADDR everywhere, including for single listening sockets.

Does this fix work for you?

diff --git a/include/sipp.hpp b/include/sipp.hpp
index 9a533cb..c0668db 100644
--- a/include/sipp.hpp
+++ b/include/sipp.hpp
@@ -340,7 +340,7 @@ MAYBE_EXTERN int_vt_map         userVarMap;
 
 MAYBE_EXTERN SIPpSocket* new_sipp_socket(bool use_ipv6, int transport);
 MAYBE_EXTERN int      sipp_bind_socket(SIPpSocket *socket, struct sockaddr_storage *saddr, int *port);
-MAYBE_EXTERN void     sipp_customize_socket(SIPpSocket *socket);
+MAYBE_EXTERN void     sipp_customize_socket(SIPpSocket *socket, bool reuseaddr = true);
 MAYBE_EXTERN bool     test_socket         DEFVAL(true);
 
 #include "time.hpp"
diff --git a/src/call.cpp b/src/call.cpp
index b83f19c..f7220e4 100644
--- a/src/call.cpp
+++ b/src/call.cpp
@@ -1375,7 +1375,7 @@ bool call::connect_socket_if_needed()
             return true;
         }
 
-        sipp_customize_socket(call_socket);
+        sipp_customize_socket(call_socket, false);
 
         if (use_remote_sending_addr) {
             L_dest = &remote_sending_sockaddr;
@@ -1470,7 +1470,7 @@ int call::send_raw(const char * msg, int index, int len)
                     ERROR_NO("Unable to get a socket for rsa option");
                 }
 
-                sipp_customize_socket(call_remote_socket);
+                sipp_customize_socket(call_remote_socket, false);
 
                 if(transport != T_UDP) {
                     if (call_remote_socket->connect(L_dest)) {
@@ -5755,7 +5755,7 @@ call::T_ActionResult call::executeAction(const char* msg, message* curmsg)
                 }
 
                 if (!existing) {
-                    sipp_customize_socket(call_socket);
+                    sipp_customize_socket(call_socket, false);
                 }
             }
 
diff --git a/src/socket.cpp b/src/socket.cpp
index dadf0dd..8a25027 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -1724,16 +1724,16 @@ void SIPpSocket::sipp_sctp_peer_params()
 }
 #endif
 
-void sipp_customize_socket(SIPpSocket *socket)
+void sipp_customize_socket(SIPpSocket *socket, bool reuseaddr /*= true*/)
 {
     unsigned int buffsize = buff_size;
 
-    /* Allows fast TCP reuse of the socket */
     if (socket->ss_transport == T_TCP || socket->ss_transport == T_TLS ||
             socket->ss_transport == T_SCTP) {
         int sock_opt = 1;
 
-        if (setsockopt(socket->ss_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&sock_opt,
+        /* Allows fast TCP reuse of the socket */
+        if (reuseaddr && setsockopt(socket->ss_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&sock_opt,
                        sizeof (sock_opt)) == -1) {
             ERROR_NO("setsockopt(SO_REUSEADDR) failed");
         }
@@ -2668,7 +2668,7 @@ void connect_to_peer(char *peer_host, int peer_port, struct sockaddr_storage *pe
         }
     }
 
-    sipp_customize_socket(*peer_socket);
+    sipp_customize_socket(*peer_socket, false);
 }
 
 SIPpSocket **get_peer_socket(char * peer) {

@smititelu
Copy link
Contributor Author

Meanwhile system upgraded from debian 9 to debian 11 and I can not reproduce this issue anymore with the latest master branch. Your code changes look ok to me, it's just I can't properly test them anymore.

I am fine with either of these options:

  1. just close this PR and will reopen/reference it if issue happens again
  2. merge your changes

Thank you,
Stefan

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants