Module: kamailio
Branch: master
Commit: 308b7a2f7b6a7c50e05a2c83537f85b95f979c32
URL:
https://github.com/kamailio/kamailio/commit/308b7a2f7b6a7c50e05a2c83537f85b…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)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/308b7a2f7b6a7c50e05a2c83537f85b…
Patch:
https://github.com/kamailio/kamailio/commit/308b7a2f7b6a7c50e05a2c83537f85b…
---
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