Skip to content

Commit e9b001c

Browse files
committed
tcp: ensure unique connection id
Many thanks to Bence Szigeti from Genesys for reporting and fixing this!
1 parent 5b5ce1f commit e9b001c

1 file changed

Lines changed: 35 additions & 1 deletion

File tree

‎net/net_tcp.c‎

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ static int tcp_dispatch_sock[2] = { -1, -1 };
110110
static unsigned int* connection_id=0;
111111
static int *tcp_main_proc_no = 0;
112112

113+
/* connections are created both by TCP main (on accept) and by any other
114+
* process (on connect), so the counter above must be incremented under lock -
115+
* otherwise concurrent creations may end up sharing the same connection ID */
116+
static gen_lock_t* connection_id_lock=0;
117+
113118
/* array of TCP partitions */
114119
static struct tcp_partition tcp_parts[TCP_PARTITION_SIZE];
115120

@@ -974,6 +979,18 @@ static inline void tcpconn_ref(struct tcp_connection* c)
974979
}
975980

976981

982+
static inline unsigned int tcpconn_next_id(void)
983+
{
984+
unsigned int id;
985+
986+
lock_get(connection_id_lock);
987+
id = (*connection_id)++;
988+
lock_release(connection_id_lock);
989+
990+
return id;
991+
}
992+
993+
977994
static struct tcp_connection* tcpconn_new(int sock, const union sockaddr_union* su,
978995
const struct socket_info* si, const struct tcp_conn_profile *prof,
979996
int state, int flags)
@@ -1026,7 +1043,7 @@ static struct tcp_connection* tcpconn_new(int sock, const union sockaddr_union*
10261043
}
10271044
print_ip("tcpconn_new: new tcp connection to: ", &c->rcv.src_ip, "\n");
10281045
LM_DBG("on port %d, proto %d\n", c->rcv.src_port, si->proto);
1029-
c->id=(*connection_id)++;
1046+
c->id=tcpconn_next_id();
10301047
c->cid = (unsigned long long)c->id
10311048
| ( (unsigned long long)(startup_time&0xFFFFFF) << 32 )
10321049
| ( (unsigned long long)(rand()&0xFF) << 56 );
@@ -2128,6 +2145,17 @@ int tcp_init(void)
21282145
// The rand() function returns a pseudo-random integer in the range 0 to
21292146
// RAND_MAX inclusive (i.e., the mathematical range [0, RAND_MAX]).
21302147
*connection_id=(unsigned int)rand();
2148+
connection_id_lock=lock_alloc();
2149+
if (connection_id_lock==0){
2150+
LM_CRIT("could not alloc connection ID lock\n");
2151+
goto error;
2152+
}
2153+
if (lock_init(connection_id_lock)==0){
2154+
LM_CRIT("could not init connection ID lock\n");
2155+
lock_dealloc((void*)connection_id_lock);
2156+
connection_id_lock=0;
2157+
goto error;
2158+
}
21312159
tcp_connections_no = (unsigned int *)shm_malloc(sizeof(*tcp_connections_no));
21322160
if (tcp_connections_no == 0) {
21332161
LM_CRIT("could not alloc tcp connection counter in shm memory\n");
@@ -2252,6 +2280,12 @@ void tcp_destroy(void)
22522280
tcp_connections_lock = 0;
22532281
}
22542282

2283+
if (connection_id_lock){
2284+
lock_destroy(connection_id_lock);
2285+
lock_dealloc((void*)connection_id_lock);
2286+
connection_id_lock=0;
2287+
}
2288+
22552289
for ( part=0 ; part<TCP_PARTITION_SIZE ; part++ ) {
22562290
if (tcp_parts[part].tcpconn_id_hash){
22572291
shm_free(tcp_parts[part].tcpconn_id_hash);

0 commit comments

Comments
 (0)