diff options
Diffstat (limited to 'net/ipv4/inet_connection_sock.c')
| -rw-r--r-- | net/ipv4/inet_connection_sock.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 4351ca2cf0b..537731b3bcb 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
| @@ -446,6 +446,28 @@ extern int sysctl_tcp_synack_retries; | |||
| 446 | 446 | ||
| 447 | EXPORT_SYMBOL_GPL(inet_csk_reqsk_queue_hash_add); | 447 | EXPORT_SYMBOL_GPL(inet_csk_reqsk_queue_hash_add); |
| 448 | 448 | ||
| 449 | /* Decide when to expire the request and when to resend SYN-ACK */ | ||
| 450 | static inline void syn_ack_recalc(struct request_sock *req, const int thresh, | ||
| 451 | const int max_retries, | ||
| 452 | const u8 rskq_defer_accept, | ||
| 453 | int *expire, int *resend) | ||
| 454 | { | ||
| 455 | if (!rskq_defer_accept) { | ||
| 456 | *expire = req->retrans >= thresh; | ||
| 457 | *resend = 1; | ||
| 458 | return; | ||
| 459 | } | ||
| 460 | *expire = req->retrans >= thresh && | ||
| 461 | (!inet_rsk(req)->acked || req->retrans >= max_retries); | ||
| 462 | /* | ||
| 463 | * Do not resend while waiting for data after ACK, | ||
| 464 | * start to resend on end of deferring period to give | ||
| 465 | * last chance for data or ACK to create established socket. | ||
| 466 | */ | ||
| 467 | *resend = !inet_rsk(req)->acked || | ||
| 468 | req->retrans >= rskq_defer_accept - 1; | ||
| 469 | } | ||
| 470 | |||
| 449 | void inet_csk_reqsk_queue_prune(struct sock *parent, | 471 | void inet_csk_reqsk_queue_prune(struct sock *parent, |
| 450 | const unsigned long interval, | 472 | const unsigned long interval, |
| 451 | const unsigned long timeout, | 473 | const unsigned long timeout, |
| @@ -501,9 +523,15 @@ void inet_csk_reqsk_queue_prune(struct sock *parent, | |||
| 501 | reqp=&lopt->syn_table[i]; | 523 | reqp=&lopt->syn_table[i]; |
| 502 | while ((req = *reqp) != NULL) { | 524 | while ((req = *reqp) != NULL) { |
| 503 | if (time_after_eq(now, req->expires)) { | 525 | if (time_after_eq(now, req->expires)) { |
| 504 | if ((req->retrans < thresh || | 526 | int expire = 0, resend = 0; |
| 505 | (inet_rsk(req)->acked && req->retrans < max_retries)) | 527 | |
| 506 | && !req->rsk_ops->rtx_syn_ack(parent, req)) { | 528 | syn_ack_recalc(req, thresh, max_retries, |
| 529 | queue->rskq_defer_accept, | ||
| 530 | &expire, &resend); | ||
| 531 | if (!expire && | ||
| 532 | (!resend || | ||
| 533 | !req->rsk_ops->rtx_syn_ack(parent, req) || | ||
| 534 | inet_rsk(req)->acked)) { | ||
| 507 | unsigned long timeo; | 535 | unsigned long timeo; |
| 508 | 536 | ||
| 509 | if (req->retrans++ == 0) | 537 | if (req->retrans++ == 0) |
