sipp icon indicating copy to clipboard operation
sipp copied to clipboard

Add dontreuseaddr parameter

Open smititelu opened this issue 3 years ago • 5 comments

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 avatar Mar 18 '22 10:03 smititelu

updated the flag to SIPP_OPTION_SETFLAG

smititelu avatar Mar 18 '22 11:03 smititelu

Have you figured out why it helps yet?

wdoekes avatar Nov 17 '22 13:11 wdoekes

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

smititelu avatar Nov 28 '22 14:11 smititelu

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) {

wdoekes avatar Nov 29 '22 08:11 wdoekes

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

smititelu avatar Dec 06 '22 08:12 smititelu