Add dontreuseaddr parameter
Hi,
Premises:
- debian 9
- use
-tnparameter - 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 intervalbind()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
updated the flag to SIPP_OPTION_SETFLAG
Have you figured out why it helps yet?
Hi, it helps because will open the requested number of TCP ports, and not try to reuse any of already opened ones.
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) {
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:
- just close this PR and will reopen/reference it if issue happens again
- merge your changes
Thank you, Stefan