summaryrefslogtreecommitdiffstats
path: root/src/tcp.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2009-09-23 17:58:19 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2009-09-23 17:58:19 +0200
commit90bbd8b34565ff5106dde34e0798c5e33fb4b786 (patch)
treea9691294ce49d2ca0f9503839de4cb35e1bcb866 /src/tcp.c
parentb52b2712e51172b0c03d3ed25a8f6377d81e51e9 (diff)
conntrackd: rate-limit the amount of connect() calls
This patch rate-limits the amount of connect() calls to avoid syn-floods when the other peer is not connected and we are generating updates. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/tcp.c')
-rw-r--r--src/tcp.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/src/tcp.c b/src/tcp.c
index ce2cd6f..c551c54 100644
--- a/src/tcp.c
+++ b/src/tcp.c
@@ -224,6 +224,10 @@ tcp_client_init(struct tcp_sock *m, struct tcp_conf *c)
return 0;
}
+/* We use this to rate-limit the amount of connect() calls per second. */
+static struct alarm_block tcp_connect_alarm;
+static void tcp_connect_alarm_cb(struct alarm_block *a, void *data) {}
+
struct tcp_sock *tcp_client_create(struct tcp_conf *c)
{
struct tcp_sock *m;
@@ -239,6 +243,8 @@ struct tcp_sock *tcp_client_create(struct tcp_conf *c)
return NULL;
}
+ init_alarm(&tcp_connect_alarm, NULL, tcp_connect_alarm_cb);
+
return m;
}
@@ -286,12 +292,20 @@ int tcp_accept(struct tcp_sock *m)
return m->client_fd;
}
+#define TCP_CONNECT_TIMEOUT 1
+
ssize_t tcp_send(struct tcp_sock *m, const void *data, int size)
{
ssize_t ret = 0;
switch(m->state) {
case TCP_CLIENT_DISCONNECTED:
+ /* We rate-limit the amount of connect() calls. */
+ if (alarm_pending(&tcp_connect_alarm)) {
+ ret = -1;
+ break;
+ }
+ add_alarm(&tcp_connect_alarm, TCP_CONNECT_TIMEOUT, 0);
ret = connect(m->fd, (struct sockaddr *)&m->addr,
m->sockaddr_len);
if (ret == -1) {