aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c98
1 files changed, 70 insertions, 28 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index eeb8a92aa416..2bdb0da237e6 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4426,7 +4426,7 @@ drop:
4426 } 4426 }
4427 __skb_queue_head(&tp->out_of_order_queue, skb); 4427 __skb_queue_head(&tp->out_of_order_queue, skb);
4428 } else { 4428 } else {
4429 struct sk_buff *skb1 = tp->out_of_order_queue.prev; 4429 struct sk_buff *skb1 = skb_peek_tail(&tp->out_of_order_queue);
4430 u32 seq = TCP_SKB_CB(skb)->seq; 4430 u32 seq = TCP_SKB_CB(skb)->seq;
4431 u32 end_seq = TCP_SKB_CB(skb)->end_seq; 4431 u32 end_seq = TCP_SKB_CB(skb)->end_seq;
4432 4432
@@ -4443,15 +4443,18 @@ drop:
4443 } 4443 }
4444 4444
4445 /* Find place to insert this segment. */ 4445 /* Find place to insert this segment. */
4446 do { 4446 while (1) {
4447 if (!after(TCP_SKB_CB(skb1)->seq, seq)) 4447 if (!after(TCP_SKB_CB(skb1)->seq, seq))
4448 break; 4448 break;
4449 } while ((skb1 = skb1->prev) != 4449 if (skb_queue_is_first(&tp->out_of_order_queue, skb1)) {
4450 (struct sk_buff *)&tp->out_of_order_queue); 4450 skb1 = NULL;
4451 break;
4452 }
4453 skb1 = skb_queue_prev(&tp->out_of_order_queue, skb1);
4454 }
4451 4455
4452 /* Do skb overlap to previous one? */ 4456 /* Do skb overlap to previous one? */
4453 if (skb1 != (struct sk_buff *)&tp->out_of_order_queue && 4457 if (skb1 && before(seq, TCP_SKB_CB(skb1)->end_seq)) {
4454 before(seq, TCP_SKB_CB(skb1)->end_seq)) {
4455 if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { 4458 if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) {
4456 /* All the bits are present. Drop. */ 4459 /* All the bits are present. Drop. */
4457 __kfree_skb(skb); 4460 __kfree_skb(skb);
@@ -4463,15 +4466,26 @@ drop:
4463 tcp_dsack_set(sk, seq, 4466 tcp_dsack_set(sk, seq,
4464 TCP_SKB_CB(skb1)->end_seq); 4467 TCP_SKB_CB(skb1)->end_seq);
4465 } else { 4468 } else {
4466 skb1 = skb1->prev; 4469 if (skb_queue_is_first(&tp->out_of_order_queue,
4470 skb1))
4471 skb1 = NULL;
4472 else
4473 skb1 = skb_queue_prev(
4474 &tp->out_of_order_queue,
4475 skb1);
4467 } 4476 }
4468 } 4477 }
4469 __skb_queue_after(&tp->out_of_order_queue, skb1, skb); 4478 if (!skb1)
4479 __skb_queue_head(&tp->out_of_order_queue, skb);
4480 else
4481 __skb_queue_after(&tp->out_of_order_queue, skb1, skb);
4470 4482
4471 /* And clean segments covered by new one as whole. */ 4483 /* And clean segments covered by new one as whole. */
4472 while ((skb1 = skb->next) != 4484 while (!skb_queue_is_last(&tp->out_of_order_queue, skb)) {
4473 (struct sk_buff *)&tp->out_of_order_queue && 4485 skb1 = skb_queue_next(&tp->out_of_order_queue, skb);
4474 after(end_seq, TCP_SKB_CB(skb1)->seq)) { 4486
4487 if (!after(end_seq, TCP_SKB_CB(skb1)->seq))
4488 break;
4475 if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) { 4489 if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) {
4476 tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq, 4490 tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq,
4477 end_seq); 4491 end_seq);
@@ -4492,7 +4506,10 @@ add_sack:
4492static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb, 4506static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb,
4493 struct sk_buff_head *list) 4507 struct sk_buff_head *list)
4494{ 4508{
4495 struct sk_buff *next = skb->next; 4509 struct sk_buff *next = NULL;
4510
4511 if (!skb_queue_is_last(list, skb))
4512 next = skb_queue_next(list, skb);
4496 4513
4497 __skb_unlink(skb, list); 4514 __skb_unlink(skb, list);
4498 __kfree_skb(skb); 4515 __kfree_skb(skb);
@@ -4503,6 +4520,9 @@ static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb,
4503 4520
4504/* Collapse contiguous sequence of skbs head..tail with 4521/* Collapse contiguous sequence of skbs head..tail with
4505 * sequence numbers start..end. 4522 * sequence numbers start..end.
4523 *
4524 * If tail is NULL, this means until the end of the list.
4525 *
4506 * Segments with FIN/SYN are not collapsed (only because this 4526 * Segments with FIN/SYN are not collapsed (only because this
4507 * simplifies code) 4527 * simplifies code)
4508 */ 4528 */
@@ -4511,15 +4531,23 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list,
4511 struct sk_buff *head, struct sk_buff *tail, 4531 struct sk_buff *head, struct sk_buff *tail,
4512 u32 start, u32 end) 4532 u32 start, u32 end)
4513{ 4533{
4514 struct sk_buff *skb; 4534 struct sk_buff *skb, *n;
4535 bool end_of_skbs;
4515 4536
4516 /* First, check that queue is collapsible and find 4537 /* First, check that queue is collapsible and find
4517 * the point where collapsing can be useful. */ 4538 * the point where collapsing can be useful. */
4518 for (skb = head; skb != tail;) { 4539 skb = head;
4540restart:
4541 end_of_skbs = true;
4542 skb_queue_walk_from_safe(list, skb, n) {
4543 if (skb == tail)
4544 break;
4519 /* No new bits? It is possible on ofo queue. */ 4545 /* No new bits? It is possible on ofo queue. */
4520 if (!before(start, TCP_SKB_CB(skb)->end_seq)) { 4546 if (!before(start, TCP_SKB_CB(skb)->end_seq)) {
4521 skb = tcp_collapse_one(sk, skb, list); 4547 skb = tcp_collapse_one(sk, skb, list);
4522 continue; 4548 if (!skb)
4549 break;
4550 goto restart;
4523 } 4551 }
4524 4552
4525 /* The first skb to collapse is: 4553 /* The first skb to collapse is:
@@ -4529,16 +4557,24 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list,
4529 */ 4557 */
4530 if (!tcp_hdr(skb)->syn && !tcp_hdr(skb)->fin && 4558 if (!tcp_hdr(skb)->syn && !tcp_hdr(skb)->fin &&
4531 (tcp_win_from_space(skb->truesize) > skb->len || 4559 (tcp_win_from_space(skb->truesize) > skb->len ||
4532 before(TCP_SKB_CB(skb)->seq, start) || 4560 before(TCP_SKB_CB(skb)->seq, start))) {
4533 (skb->next != tail && 4561 end_of_skbs = false;
4534 TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb->next)->seq)))
4535 break; 4562 break;
4563 }
4564
4565 if (!skb_queue_is_last(list, skb)) {
4566 struct sk_buff *next = skb_queue_next(list, skb);
4567 if (next != tail &&
4568 TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(next)->seq) {
4569 end_of_skbs = false;
4570 break;
4571 }
4572 }
4536 4573
4537 /* Decided to skip this, advance start seq. */ 4574 /* Decided to skip this, advance start seq. */
4538 start = TCP_SKB_CB(skb)->end_seq; 4575 start = TCP_SKB_CB(skb)->end_seq;
4539 skb = skb->next;
4540 } 4576 }
4541 if (skb == tail || tcp_hdr(skb)->syn || tcp_hdr(skb)->fin) 4577 if (end_of_skbs || tcp_hdr(skb)->syn || tcp_hdr(skb)->fin)
4542 return; 4578 return;
4543 4579
4544 while (before(start, end)) { 4580 while (before(start, end)) {
@@ -4583,7 +4619,8 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list,
4583 } 4619 }
4584 if (!before(start, TCP_SKB_CB(skb)->end_seq)) { 4620 if (!before(start, TCP_SKB_CB(skb)->end_seq)) {
4585 skb = tcp_collapse_one(sk, skb, list); 4621 skb = tcp_collapse_one(sk, skb, list);
4586 if (skb == tail || 4622 if (!skb ||
4623 skb == tail ||
4587 tcp_hdr(skb)->syn || 4624 tcp_hdr(skb)->syn ||
4588 tcp_hdr(skb)->fin) 4625 tcp_hdr(skb)->fin)
4589 return; 4626 return;
@@ -4610,17 +4647,21 @@ static void tcp_collapse_ofo_queue(struct sock *sk)
4610 head = skb; 4647 head = skb;
4611 4648
4612 for (;;) { 4649 for (;;) {
4613 skb = skb->next; 4650 struct sk_buff *next = NULL;
4651
4652 if (!skb_queue_is_last(&tp->out_of_order_queue, skb))
4653 next = skb_queue_next(&tp->out_of_order_queue, skb);
4654 skb = next;
4614 4655
4615 /* Segment is terminated when we see gap or when 4656 /* Segment is terminated when we see gap or when
4616 * we are at the end of all the queue. */ 4657 * we are at the end of all the queue. */
4617 if (skb == (struct sk_buff *)&tp->out_of_order_queue || 4658 if (!skb ||
4618 after(TCP_SKB_CB(skb)->seq, end) || 4659 after(TCP_SKB_CB(skb)->seq, end) ||
4619 before(TCP_SKB_CB(skb)->end_seq, start)) { 4660 before(TCP_SKB_CB(skb)->end_seq, start)) {
4620 tcp_collapse(sk, &tp->out_of_order_queue, 4661 tcp_collapse(sk, &tp->out_of_order_queue,
4621 head, skb, start, end); 4662 head, skb, start, end);
4622 head = skb; 4663 head = skb;
4623 if (skb == (struct sk_buff *)&tp->out_of_order_queue) 4664 if (!skb)
4624 break; 4665 break;
4625 /* Start new segment */ 4666 /* Start new segment */
4626 start = TCP_SKB_CB(skb)->seq; 4667 start = TCP_SKB_CB(skb)->seq;
@@ -4681,10 +4722,11 @@ static int tcp_prune_queue(struct sock *sk)
4681 tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss); 4722 tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss);
4682 4723
4683 tcp_collapse_ofo_queue(sk); 4724 tcp_collapse_ofo_queue(sk);
4684 tcp_collapse(sk, &sk->sk_receive_queue, 4725 if (!skb_queue_empty(&sk->sk_receive_queue))
4685 sk->sk_receive_queue.next, 4726 tcp_collapse(sk, &sk->sk_receive_queue,
4686 (struct sk_buff *)&sk->sk_receive_queue, 4727 skb_peek(&sk->sk_receive_queue),
4687 tp->copied_seq, tp->rcv_nxt); 4728 NULL,
4729 tp->copied_seq, tp->rcv_nxt);
4688 sk_mem_reclaim(sk); 4730 sk_mem_reclaim(sk);
4689 4731
4690 if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) 4732 if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf)