[sr-dev] git:master:308b7a2f: core: tcp - new core parameter tcp_accept_unique

Daniel-Constantin Mierla miconda at gmail.com
Fri Aug 16 10:16:46 CEST 2019


Module: kamailio
Branch: master
Commit: 308b7a2f7b6a7c50e05a2c83537f85b95f979c32
URL: https://github.com/kamailio/kamailio/commit/308b7a2f7b6a7c50e05a2c83537f85b95f979c32

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date: 2019-08-16T10:11:21+02:00

core: tcp - new core parameter tcp_accept_unique

- if set to 1, do an extra check when a new connection is created to be
sure the is no overlapping with another connection on local ip/port and
remote ip/port
- recently some tcp/ip router/balancers can do port sharing, but that can create
troubles for routing of the requests with the current tcp routing implementation
(e.g., using the wrong connection in such group)
- default is set to 0

---

Modified: src/core/cfg.lex
Modified: src/core/cfg.y
Modified: src/core/globals.h
Modified: src/core/tcp_main.c

---

Diff:  https://github.com/kamailio/kamailio/commit/308b7a2f7b6a7c50e05a2c83537f85b95f979c32.diff
Patch: https://github.com/kamailio/kamailio/commit/308b7a2f7b6a7c50e05a2c83537f85b95f979c32.patch

---

diff --git a/src/core/cfg.lex b/src/core/cfg.lex
index dd1b935d8f..20a8fd94ef 100644
--- a/src/core/cfg.lex
+++ b/src/core/cfg.lex
@@ -375,6 +375,7 @@ MHOMED		mhomed
 DISABLE_TCP		"disable_tcp"
 TCP_CHILDREN	"tcp_children"
 TCP_ACCEPT_ALIASES	"tcp_accept_aliases"
+TCP_ACCEPT_UNIQUE	"tcp_accept_unique"
 TCP_SEND_TIMEOUT	"tcp_send_timeout"
 TCP_CONNECT_TIMEOUT	"tcp_connect_timeout"
 TCP_CON_LIFETIME	"tcp_connection_lifetime"
@@ -814,6 +815,8 @@ IMPORTFILE      "import_file"
 <INITIAL>{TCP_CHILDREN}	{ count(); yylval.strval=yytext; return TCP_CHILDREN; }
 <INITIAL>{TCP_ACCEPT_ALIASES}	{ count(); yylval.strval=yytext;
 									return TCP_ACCEPT_ALIASES; }
+<INITIAL>{TCP_ACCEPT_UNIQUE}	{ count(); yylval.strval=yytext;
+									return TCP_ACCEPT_UNIQUE; }
 <INITIAL>{TCP_SEND_TIMEOUT}		{ count(); yylval.strval=yytext;
 									return TCP_SEND_TIMEOUT; }
 <INITIAL>{TCP_CONNECT_TIMEOUT}		{ count(); yylval.strval=yytext;
diff --git a/src/core/cfg.y b/src/core/cfg.y
index 4c7dcd1307..3adff2429b 100644
--- a/src/core/cfg.y
+++ b/src/core/cfg.y
@@ -406,6 +406,7 @@ extern char *default_routename;
 %token MHOMED
 %token DISABLE_TCP
 %token TCP_ACCEPT_ALIASES
+%token TCP_ACCEPT_UNIQUE
 %token TCP_CHILDREN
 %token TCP_CONNECT_TIMEOUT
 %token TCP_SEND_TIMEOUT
@@ -994,6 +995,14 @@ assign_stm:
 		#endif
 	}
 	| TCP_ACCEPT_ALIASES EQUAL error { yyerror("boolean value expected"); }
+	| TCP_ACCEPT_UNIQUE EQUAL NUMBER {
+		#ifdef USE_TCP
+			tcp_accept_unique=$3;
+		#else
+			warn("tcp support not compiled in");
+		#endif
+	}
+	| TCP_ACCEPT_UNIQUE EQUAL error { yyerror("number expected"); }
 	| TCP_CHILDREN EQUAL NUMBER {
 		#ifdef USE_TCP
 			tcp_cfg_children_no=$3;
diff --git a/src/core/globals.h b/src/core/globals.h
index 3790058075..78a8e5aadc 100644
--- a/src/core/globals.h
+++ b/src/core/globals.h
@@ -93,6 +93,7 @@ extern int socket_workers;
 #ifdef USE_TCP
 extern int tcp_main_pid;
 extern int tcp_cfg_children_no;
+extern int tcp_accept_unique;
 extern int tcp_children_no;
 extern int tcp_disable;
 extern enum poll_types tcp_poll_method;
diff --git a/src/core/tcp_main.c b/src/core/tcp_main.c
index 54288e908f..7ecaf47eb6 100644
--- a/src/core/tcp_main.c
+++ b/src/core/tcp_main.c
@@ -158,6 +158,7 @@ enum poll_types tcp_poll_method=0; /* by default choose the best method */
 int tcp_main_max_fd_no=0;
 int tcp_max_connections=DEFAULT_TCP_MAX_CONNECTIONS;
 int tls_max_connections=DEFAULT_TLS_MAX_CONNECTIONS;
+int tcp_accept_unique=0;
 
 static union sockaddr_union tcp_source_ipv4_addr; /* saved bind/srv v4 addr. */
 static union sockaddr_union* tcp_source_ipv4=0;
@@ -1655,6 +1656,24 @@ struct tcp_connection* _tcpconn_find(int id, struct ip_addr* ip, int port,
 }
 
 
+/**
+ * find if a tcp connection exits by id or remote+local address/port
+ * - return: 1 if found; 0 if not found
+ */
+int tcpconn_exists(int conn_id, ip_addr_t* peer_ip, int peer_port,
+						ip_addr_t* local_ip, int local_port)
+{
+	tcp_connection_t* c;
+
+	TCPCONN_LOCK;
+	c=_tcpconn_find(conn_id, peer_ip, peer_port, local_ip, local_port);
+	TCPCONN_UNLOCK;
+	if (c) {
+		return 1;
+	}
+	return 0;
+
+}
 
 /* _tcpconn_find with locks and timeout
  * local_addr contains the desired local ip:port. If null any local address 
@@ -4245,6 +4264,15 @@ static inline int handle_new_connect(struct socket_info* si)
 	/* add socket to list */
 	tcpconn=tcpconn_new(new_sock, &su, dst_su, si, si->proto, S_CONN_ACCEPT);
 	if (likely(tcpconn)){
+		if(tcp_accept_unique) {
+			if(tcpconn_exists(0, &tcpconn->rcv.dst_ip, tcpconn->rcv.dst_port,
+						&tcpconn->rcv.src_ip, tcpconn->rcv.src_port)) {
+				LM_ERR("duplicated connection by local and remote addresses\n");
+				_tcpconn_free(tcpconn);
+				tcp_safe_close(new_sock);
+				return 1; /* success, because the accept was succesfull */
+			}
+		}
 		tcpconn->flags|=F_CONN_PASSIVE;
 #ifdef TCP_PASS_NEW_CONNECTION_ON_DATA
 		atomic_set(&tcpconn->refcnt, 1); /* safe, not yet available to the




More information about the sr-dev mailing list