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

Author: Daniel-Constantin Mierla <mico...@gmail.com>
Committer: Daniel-Constantin Mierla <mico...@gmail.com>
Date: 2023-10-13T17:33:51+02:00

core: tcp - limit number of accepted connections per src ip

- default 1024

---

Modified: src/core/tcp_conn.h
Modified: src/core/tcp_main.c
Modified: src/core/tcp_read.c

---

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

---

diff --git a/src/core/tcp_conn.h b/src/core/tcp_conn.h
index 4cb3da51f40..2a4a2dd7b0d 100644
--- a/src/core/tcp_conn.h
+++ b/src/core/tcp_conn.h
@@ -47,6 +47,8 @@
 
 #define KSR_TCP_MSGREAD_TIMEOUT 20 /* timeout (secs) to read SIP message */
 
+#define KSR_TCP_ACCEPT_IPLIMIT 1024 /* limit accepted tcp connections from IP 
*/
+
 /* tcp connection flags */
 #define F_CONN_READ_W 2                  /* watched for READ ev. in main */
 #define F_CONN_WRITE_W 4         /* watched for WRITE (main) */
@@ -281,6 +283,7 @@ typedef struct tcp_connection
        unsigned int flags;                     /* connection related flags */
        snd_flags_t send_flags;         /* special send flags */
        enum tcp_conn_states state; /* connection state */
+       enum tcp_conn_states initstate; /* initial connection state */
        void *extra_data; /* extra data associated to the connection, 0 for 
tcp*/
        struct timer_ln timer;
        time_t timestamp; /* connection creation timestamp */
diff --git a/src/core/tcp_main.c b/src/core/tcp_main.c
index 9f39dd72444..aac5347431d 100644
--- a/src/core/tcp_main.c
+++ b/src/core/tcp_main.c
@@ -1162,6 +1162,30 @@ int tcpconn_read_haproxy(struct tcp_connection *c)
        return (bytes >= 0) ? retval : -1;
 }
 
+int tcp_connection_limit_srcip(union sockaddr_union *srcaddr, int limit)
+{
+       struct tcp_connection *con;
+       ip_addr_t src_ip;
+       int n;
+       int i;
+
+       n = 0;
+       su2ip_addr(&src_ip, srcaddr);
+       TCPCONN_LOCK;
+       for(i = 0; i < TCP_ID_HASH_SIZE && n < limit; i++) {
+               for(con = tcpconn_id_hash[i]; con && n < limit; con = 
con->id_next) {
+                       if(con->initstate == S_CONN_ACCEPT) {
+                               if(ip_addr_cmp(&src_ip, &con->rcv.src_ip)) {
+                                       n++;
+                               }
+                       }
+               }
+       }
+       TCPCONN_UNLOCK;
+
+       return (n >= limit) ? 1 : 0;
+}
+
 struct tcp_connection *tcpconn_new(int sock, union sockaddr_union *su,
                union sockaddr_union *local_addr, struct socket_info *ba, int 
type,
                int state)
@@ -1217,6 +1241,7 @@ struct tcp_connection *tcpconn_new(int sock, union 
sockaddr_union *su,
        c->rcv.proto_reserved1 = 0; /* this will be filled before 
receive_message*/
        c->rcv.proto_reserved2 = 0;
        c->state = state;
+       c->initstate = state;
        c->extra_data = 0;
        c->timestamp = time(NULL);
 #ifdef USE_TLS
@@ -4426,6 +4451,12 @@ static inline int handle_new_connect(struct socket_info 
*si)
                tcp_safe_close(new_sock);
                return 1; /* success, because the accept was successful */
        }
+       if(unlikely(tcp_connection_limit_srcip(&su, KSR_TCP_ACCEPT_IPLIMIT))) {
+               LM_CRIT("hit the limit of connections per source IP (%s) - 
rejecting\n",
+                               su2a(&su, sizeof(su)));
+               tcp_safe_close(new_sock);
+               return 1; /* success, because the accept was successful */
+       }
        (*tcp_connections_no)++;
        if(unlikely(si->proto == PROTO_TLS))
                (*tls_connections_no)++;
diff --git a/src/core/tcp_read.c b/src/core/tcp_read.c
index 2ad9579854f..31c6e92444c 100644
--- a/src/core/tcp_read.c
+++ b/src/core/tcp_read.c
@@ -448,7 +448,6 @@ int tcp_read_headers(struct tcp_connection *c, 
rd_conn_flags_t *read_flags)
                        bytes = tcp_read(c, read_flags);
                if(bytes <= 0)
                        return bytes;
-               LM_DBG("===== read %d bytes\n", bytes);
                gettimeofday(&tvnow, NULL);
                tvdiff = 1000000 * (tvnow.tv_sec - r->tvrstart.tv_sec)
                                 + (tvnow.tv_usec - r->tvrstart.tv_usec);
@@ -1661,12 +1660,10 @@ int tcp_read_req(struct tcp_connection *con, int 
*bytes_read,
                req->content_len = 0;
                req->bytes_to_go = 0;
                req->pos = req->buf + size;
-               LM_DBG("=== reset message read start time\n");
                req->tvrstart.tv_sec = 0;
                req->tvrstart.tv_usec = 0;
 
                if(unlikely(size)) {
-                       LM_DBG("=== set message read start time\n");
                        gettimeofday(&req->tvrstart, NULL);
                        memmove(req->buf, req->parsed, size);
                        req->parsed = req->buf; /* fix req->parsed after using 
it */

_______________________________________________
Kamailio (SER) - Development Mailing List
To unsubscribe send an email to sr-dev-le...@lists.kamailio.org

Reply via email to