aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_timer.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@ghostprotocols.net>2005-08-09 23:15:09 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-08-29 18:49:50 -0400
commita019d6fe2b9da68ea4ba6cf3c4e86fc1dbf554c3 (patch)
treef82f0523c313228d64998fac30790edcfd0785c3 /net/ipv4/tcp_timer.c
parent7c657876b63cb1d8a2ec06f8fc6c37bb8412e66c (diff)
[ICSK]: Move generalised functions from tcp to inet_connection_sock
This also improves reqsk_queue_prune and renames it to inet_csk_reqsk_queue_prune, as it deals with both inet_connection_sock and inet_request_sock objects, not just with request_sock ones thus belonging to inet_request_sock. Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_timer.c')
-rw-r--r--net/ipv4/tcp_timer.c93
1 files changed, 2 insertions, 91 deletions
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index b614ad4d30c9..72cec6981830 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -424,103 +424,14 @@ out_unlock:
424 sock_put(sk); 424 sock_put(sk);
425} 425}
426 426
427void reqsk_queue_prune(struct request_sock_queue *queue, struct sock *parent,
428 const unsigned long interval, const unsigned long timeout,
429 const unsigned long max_rto, int max_retries)
430{
431 struct inet_connection_sock *icsk = inet_csk(parent);
432 struct listen_sock *lopt = queue->listen_opt;
433 int thresh = max_retries;
434 unsigned long now = jiffies;
435 struct request_sock **reqp, *req;
436 int i, budget;
437
438 if (lopt == NULL || lopt->qlen == 0)
439 return;
440
441 /* Normally all the openreqs are young and become mature
442 * (i.e. converted to established socket) for first timeout.
443 * If synack was not acknowledged for 3 seconds, it means
444 * one of the following things: synack was lost, ack was lost,
445 * rtt is high or nobody planned to ack (i.e. synflood).
446 * When server is a bit loaded, queue is populated with old
447 * open requests, reducing effective size of queue.
448 * When server is well loaded, queue size reduces to zero
449 * after several minutes of work. It is not synflood,
450 * it is normal operation. The solution is pruning
451 * too old entries overriding normal timeout, when
452 * situation becomes dangerous.
453 *
454 * Essentially, we reserve half of room for young
455 * embrions; and abort old ones without pity, if old
456 * ones are about to clog our table.
457 */
458 if (lopt->qlen>>(lopt->max_qlen_log-1)) {
459 int young = (lopt->qlen_young<<1);
460
461 while (thresh > 2) {
462 if (lopt->qlen < young)
463 break;
464 thresh--;
465 young <<= 1;
466 }
467 }
468
469 if (queue->rskq_defer_accept)
470 max_retries = queue->rskq_defer_accept;
471
472 budget = 2 * (lopt->nr_table_entries / (timeout / interval));
473 i = lopt->clock_hand;
474
475 do {
476 reqp=&lopt->syn_table[i];
477 while ((req = *reqp) != NULL) {
478 if (time_after_eq(now, req->expires)) {
479 if ((req->retrans < thresh ||
480 (inet_rsk(req)->acked && req->retrans < max_retries))
481 && !req->rsk_ops->rtx_syn_ack(parent, req, NULL)) {
482 unsigned long timeo;
483
484 if (req->retrans++ == 0)
485 lopt->qlen_young--;
486 timeo = min((timeout << req->retrans), max_rto);
487 req->expires = now + timeo;
488 reqp = &req->dl_next;
489 continue;
490 }
491
492 /* Drop this request */
493 inet_csk_reqsk_queue_unlink(parent, req, reqp);
494 reqsk_queue_removed(&icsk->icsk_accept_queue, req);
495 reqsk_free(req);
496 continue;
497 }
498 reqp = &req->dl_next;
499 }
500
501 i = (i + 1) & (lopt->nr_table_entries - 1);
502
503 } while (--budget > 0);
504
505 lopt->clock_hand = i;
506
507 if (lopt->qlen)
508 inet_csk_reset_keepalive_timer(parent, interval);
509}
510
511EXPORT_SYMBOL_GPL(reqsk_queue_prune);
512
513/* 427/*
514 * Timer for listening sockets 428 * Timer for listening sockets
515 */ 429 */
516 430
517static void tcp_synack_timer(struct sock *sk) 431static void tcp_synack_timer(struct sock *sk)
518{ 432{
519 struct inet_connection_sock *icsk = inet_csk(sk); 433 inet_csk_reqsk_queue_prune(sk, TCP_SYNQ_INTERVAL,
520 const int max_retries = icsk->icsk_syn_retries ? : sysctl_tcp_synack_retries; 434 TCP_TIMEOUT_INIT, TCP_RTO_MAX);
521
522 reqsk_queue_prune(&icsk->icsk_accept_queue, sk, TCP_SYNQ_INTERVAL,
523 TCP_TIMEOUT_INIT, TCP_RTO_MAX, max_retries);
524} 435}
525 436
526void tcp_set_keepalive(struct sock *sk, int val) 437void tcp_set_keepalive(struct sock *sk, int val)