Skip to content

Commit

Permalink
Add separate queue max lengths for request and accept queues.
Browse files Browse the repository at this point in the history
  • Loading branch information
Erik Nordström committed Feb 4, 2014
1 parent de67cf9 commit 461547c
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 22 deletions.
6 changes: 1 addition & 5 deletions src/stack/af_serval.c
Expand Up @@ -332,10 +332,8 @@ static int serval_listen_stop(struct sock *sk)

reqsk_free(&srsk->rsk.req);
serval_sock_request_queue_removed(sk);

/* Decrease backlog */
sk_acceptq_removed(sk);
}

/* Destroy accept queue of sockets that completed three-way
handshake (and send appropriate packets to other ends) */
while (1) {
Expand Down Expand Up @@ -378,7 +376,6 @@ static int serval_listen_stop(struct sock *sk)
sock_put(child);
}
reqsk_free(&srsk->rsk.req);
serval_sock_request_queue_removed(sk);
sk_acceptq_removed(sk);
}

Expand Down Expand Up @@ -442,7 +439,6 @@ struct sock *serval_accept_dequeue(struct sock *parent,

list_del(&srsk->lh);
reqsk_free(&srsk->rsk.req);
serval_sock_request_queue_removed(parent);
sk_acceptq_removed(parent);
return sk;
}
Expand Down
9 changes: 8 additions & 1 deletion src/stack/serval_sal.c
Expand Up @@ -1841,7 +1841,12 @@ static int serval_sal_rcv_syn(struct sock *sk,

LOG_SSK(sk, "REQUEST verno=%u\n", ctx->verno);

if (sk->sk_ack_backlog >= sk->sk_max_ack_backlog) {
if (serval_sock_request_queue_is_full(sk)) {
LOG_DBG("Request queue is full, potential SYN flood!\n");
goto drop;
}

if (sk_acceptq_is_full(sk)) {
LOG_ERR("ack backlog is full (size=%u max=%u)\n",
sk->sk_ack_backlog, sk->sk_max_ack_backlog);
goto drop;
Expand Down Expand Up @@ -2103,6 +2108,8 @@ static struct sock * serval_sal_request_sock_handle(struct sock *sk,

/* Move request sock to accept queue */
list_move_tail(&srsk->lh, &ssk->accept_queue);
serval_sock_request_queue_removed(sk);
sk_acceptq_added(sk);
nsk->sk_ack_backlog = 0;

newinet = inet_sk(nsk);
Expand Down
30 changes: 14 additions & 16 deletions src/stack/serval_sock.c
Expand Up @@ -44,6 +44,8 @@ static DEFINE_RWLOCK(sock_list_lock);
/* The number of (prefix) bytes to hash on in the serviceID */
#define SERVICE_KEY_LEN (8)

#define DEFAULT_MAX_REQUEST_QLEN 500

static const char *sock_state_str[] = {
[ SAL_INIT ] = "INIT",
[ SAL_CONNECTED ] = "CONNECTED",
Expand Down Expand Up @@ -342,8 +344,10 @@ void serval_sock_request_queue_prune(struct sock *parent,
struct serval_request_sock *srsk, *tmp;
unsigned long now = jiffies;

if (pssk->request_qlen == 0)
if (pssk->request_qlen == 0) {
LOG_DBG("Request queue len=0, no pruning needed\n");
return;
}

LOG_DBG("Pruning request queue (len=%lu)\n", pssk->request_qlen);

Expand All @@ -355,23 +359,15 @@ void serval_sock_request_queue_prune(struct sock *parent,
reqsk_free(req);
}
}
list_for_each_entry_safe(srsk, tmp, &pssk->accept_queue, lh) {
if (time_after_eq(now, srsk->rsk.req.expires)) {
struct request_sock *req = &srsk->rsk.req;
list_del(&srsk->lh);
serval_sock_request_queue_removed(parent);
if (req->sk)
sock_put(req->sk);
reqsk_free(req);
}
}

if (pssk->request_qlen)
serval_sock_reset_keepalive_timer(parent, interval);
}

void serval_sock_reqsk_queue_add(struct sock *sk, struct request_sock *rsk,
unsigned long timeout)
unsigned long timeout)
{
serval_reqsk_queue(rsk, &serval_sk(sk)->syn_queue, timeout);
sk_acceptq_added(sk);
serval_sock_request_queue_added(sk, timeout);
}

Expand Down Expand Up @@ -665,6 +661,7 @@ void serval_sock_init(struct sock *sk)
ssk->sal_state = SAL_RSYN_INITIAL;
ssk->udp_encap_sport = 0;
ssk->udp_encap_dport = 0;
ssk->max_request_qlen = DEFAULT_MAX_REQUEST_QLEN;
INIT_LIST_HEAD(&ssk->sock_node);
INIT_LIST_HEAD(&ssk->accept_queue);
INIT_LIST_HEAD(&ssk->syn_queue);
Expand Down Expand Up @@ -1060,9 +1057,9 @@ struct sock *sock_list_iterator_next(struct sock_list_iterator *iter)
int serval_sock_flow_print_header(char *buf, size_t buflen)
{
return snprintf(buf, buflen,
"%-10s %-10s %-15s %-15s %-6s %-8s %-10s %s\n",
"%-10s %-10s %-15s %-15s %-6s %-8s %-8s %-10s %s\n",
"srcFlowID", "dstFlowID",
"srcIP", "dstIP", "proto", "backlog", "state", "dev");
"srcIP", "dstIP", "proto", "reqQ", "backlog", "state", "dev");
}

int serval_sock_flow_print(struct sock *sk, char *buf, size_t buflen)
Expand All @@ -1074,14 +1071,15 @@ int serval_sock_flow_print(struct sock *sk, char *buf, size_t buflen)
sk->sk_bound_dev_if);

len = snprintf(buf, buflen,
"%-10s %-10s %-15s %-15s %-6s %-8u %-10s %s\n",
"%-10s %-10s %-15s %-15s %-6s %-8lu %-8u %-10s %s\n",
flow_id_to_str(&ssk->local_flowid),
flow_id_to_str(&ssk->peer_flowid),
inet_ntop(AF_INET, &inet_sk(sk)->inet_saddr,
src, 18),
inet_ntop(AF_INET, &inet_sk(sk)->inet_daddr,
dst, 18),
sk->sk_prot->name,
serval_sk(sk)->request_qlen,
sk->sk_ack_backlog,
serval_sock_state_str(sk),
dev ? dev->name : "unbound");
Expand Down
6 changes: 6 additions & 0 deletions src/stack/serval_sock.h
Expand Up @@ -157,6 +157,7 @@ struct serval_sock {
struct list_head syn_queue;
struct list_head accept_queue;
unsigned long request_qlen;
unsigned long max_request_qlen;
struct sk_buff *ctrl_queue;
struct sk_buff *ctrl_send_head;
u8 local_nonce[SAL_NONCE_SIZE];
Expand Down Expand Up @@ -266,6 +267,11 @@ void serval_sock_request_queue_prune(struct sock *parent,
const unsigned long timeout,
const unsigned long max_rto);

static inline int serval_sock_request_queue_is_full(struct sock *sk)
{
return serval_sk(sk)->request_qlen > serval_sk(sk)->max_request_qlen;
}

static inline void serval_sock_request_queue_added(struct sock *sk,
unsigned long timeout)
{
Expand Down

0 comments on commit 461547c

Please sign in to comment.