aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/input.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/input.c')
-rw-r--r--net/dccp/input.c164
1 files changed, 91 insertions, 73 deletions
diff --git a/net/dccp/input.c b/net/dccp/input.c
index df0e6714aa11..779d0ed9ae94 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -159,15 +159,13 @@ static void dccp_rcv_reset(struct sock *sk, struct sk_buff *skb)
159 dccp_time_wait(sk, DCCP_TIME_WAIT, 0); 159 dccp_time_wait(sk, DCCP_TIME_WAIT, 0);
160} 160}
161 161
162static void dccp_handle_ackvec_processing(struct sock *sk, struct sk_buff *skb) 162static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb)
163{ 163{
164 struct dccp_ackvec *av = dccp_sk(sk)->dccps_hc_rx_ackvec; 164 struct dccp_sock *dp = dccp_sk(sk);
165 165
166 if (av == NULL) 166 if (dccp_msk(sk)->dccpms_send_ack_vector)
167 return; 167 dccp_ackvec_check_rcv_ackno(dp->dccps_hc_rx_ackvec, sk,
168 if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) 168 DCCP_SKB_CB(skb)->dccpd_ack_seq);
169 dccp_ackvec_clear_state(av, DCCP_SKB_CB(skb)->dccpd_ack_seq);
170 dccp_ackvec_input(av, skb);
171} 169}
172 170
173static void dccp_deliver_input_to_ccids(struct sock *sk, struct sk_buff *skb) 171static void dccp_deliver_input_to_ccids(struct sock *sk, struct sk_buff *skb)
@@ -366,13 +364,22 @@ discard:
366int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, 364int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
367 const struct dccp_hdr *dh, const unsigned len) 365 const struct dccp_hdr *dh, const unsigned len)
368{ 366{
367 struct dccp_sock *dp = dccp_sk(sk);
368
369 if (dccp_check_seqno(sk, skb)) 369 if (dccp_check_seqno(sk, skb))
370 goto discard; 370 goto discard;
371 371
372 if (dccp_parse_options(sk, NULL, skb)) 372 if (dccp_parse_options(sk, NULL, skb))
373 return 1; 373 return 1;
374 374
375 dccp_handle_ackvec_processing(sk, skb); 375 if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
376 dccp_event_ack_recv(sk, skb);
377
378 if (dccp_msk(sk)->dccpms_send_ack_vector &&
379 dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
380 DCCP_SKB_CB(skb)->dccpd_seq,
381 DCCP_ACKVEC_STATE_RECEIVED))
382 goto discard;
376 dccp_deliver_input_to_ccids(sk, skb); 383 dccp_deliver_input_to_ccids(sk, skb);
377 384
378 return __dccp_rcv_established(sk, skb, dh, len); 385 return __dccp_rcv_established(sk, skb, dh, len);
@@ -414,33 +421,40 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
414 goto out_invalid_packet; 421 goto out_invalid_packet;
415 } 422 }
416 423
417 /*
418 * If option processing (Step 8) failed, return 1 here so that
419 * dccp_v4_do_rcv() sends a Reset. The Reset code depends on
420 * the option type and is set in dccp_parse_options().
421 */
422 if (dccp_parse_options(sk, NULL, skb)) 424 if (dccp_parse_options(sk, NULL, skb))
423 return 1; 425 goto out_invalid_packet;
424 426
425 /* Obtain usec RTT sample from SYN exchange (used by CCID 3) */ 427 /* Obtain usec RTT sample from SYN exchange (used by CCID 3) */
426 if (likely(dp->dccps_options_received.dccpor_timestamp_echo)) 428 if (likely(dp->dccps_options_received.dccpor_timestamp_echo))
427 dp->dccps_syn_rtt = dccp_sample_rtt(sk, 10 * (tstamp - 429 dp->dccps_syn_rtt = dccp_sample_rtt(sk, 10 * (tstamp -
428 dp->dccps_options_received.dccpor_timestamp_echo)); 430 dp->dccps_options_received.dccpor_timestamp_echo));
429 431
432 if (dccp_msk(sk)->dccpms_send_ack_vector &&
433 dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
434 DCCP_SKB_CB(skb)->dccpd_seq,
435 DCCP_ACKVEC_STATE_RECEIVED))
436 goto out_invalid_packet; /* FIXME: change error code */
437
430 /* Stop the REQUEST timer */ 438 /* Stop the REQUEST timer */
431 inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS); 439 inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS);
432 WARN_ON(sk->sk_send_head == NULL); 440 WARN_ON(sk->sk_send_head == NULL);
433 kfree_skb(sk->sk_send_head); 441 kfree_skb(sk->sk_send_head);
434 sk->sk_send_head = NULL; 442 sk->sk_send_head = NULL;
435 443
444 dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq;
445 dccp_update_gsr(sk, dp->dccps_isr);
436 /* 446 /*
437 * Set ISR, GSR from packet. ISS was set in dccp_v{4,6}_connect 447 * SWL and AWL are initially adjusted so that they are not less than
438 * and GSS in dccp_transmit_skb(). Setting AWL/AWH and SWL/SWH 448 * the initial Sequence Numbers received and sent, respectively:
439 * is done as part of activating the feature values below, since 449 * SWL := max(GSR + 1 - floor(W/4), ISR),
440 * these settings depend on the local/remote Sequence Window 450 * AWL := max(GSS - W' + 1, ISS).
441 * features, which were undefined or not confirmed until now. 451 * These adjustments MUST be applied only at the beginning of the
452 * connection.
453 *
454 * AWL was adjusted in dccp_v4_connect -acme
442 */ 455 */
443 dp->dccps_gsr = dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq; 456 dccp_set_seqno(&dp->dccps_swl,
457 max48(dp->dccps_swl, dp->dccps_isr));
444 458
445 dccp_sync_mss(sk, icsk->icsk_pmtu_cookie); 459 dccp_sync_mss(sk, icsk->icsk_pmtu_cookie);
446 460
@@ -461,15 +475,6 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
461 */ 475 */
462 dccp_set_state(sk, DCCP_PARTOPEN); 476 dccp_set_state(sk, DCCP_PARTOPEN);
463 477
464 /*
465 * If feature negotiation was successful, activate features now;
466 * an activation failure means that this host could not activate
467 * one ore more features (e.g. insufficient memory), which would
468 * leave at least one feature in an undefined state.
469 */
470 if (dccp_feat_activate_values(sk, &dp->dccps_featneg))
471 goto unable_to_proceed;
472
473 /* Make sure socket is routed, for correct metrics. */ 478 /* Make sure socket is routed, for correct metrics. */
474 icsk->icsk_af_ops->rebuild_header(sk); 479 icsk->icsk_af_ops->rebuild_header(sk);
475 480
@@ -504,16 +509,6 @@ out_invalid_packet:
504 /* dccp_v4_do_rcv will send a reset */ 509 /* dccp_v4_do_rcv will send a reset */
505 DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; 510 DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR;
506 return 1; 511 return 1;
507
508unable_to_proceed:
509 DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_ABORTED;
510 /*
511 * We mark this socket as no longer usable, so that the loop in
512 * dccp_sendmsg() terminates and the application gets notified.
513 */
514 dccp_set_state(sk, DCCP_CLOSED);
515 sk->sk_err = ECOMM;
516 return 1;
517} 512}
518 513
519static int dccp_rcv_respond_partopen_state_process(struct sock *sk, 514static int dccp_rcv_respond_partopen_state_process(struct sock *sk,
@@ -595,6 +590,8 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
595 if (inet_csk(sk)->icsk_af_ops->conn_request(sk, 590 if (inet_csk(sk)->icsk_af_ops->conn_request(sk,
596 skb) < 0) 591 skb) < 0)
597 return 1; 592 return 1;
593
594 /* FIXME: do congestion control initialization */
598 goto discard; 595 goto discard;
599 } 596 }
600 if (dh->dccph_type == DCCP_PKT_RESET) 597 if (dh->dccph_type == DCCP_PKT_RESET)
@@ -603,35 +600,29 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
603 /* Caller (dccp_v4_do_rcv) will send Reset */ 600 /* Caller (dccp_v4_do_rcv) will send Reset */
604 dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; 601 dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
605 return 1; 602 return 1;
606 } else if (sk->sk_state == DCCP_CLOSED) {
607 dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
608 return 1;
609 } 603 }
610 604
611 /* Step 6: Check sequence numbers (omitted in LISTEN/REQUEST state) */ 605 if (sk->sk_state != DCCP_REQUESTING) {
612 if (sk->sk_state != DCCP_REQUESTING && dccp_check_seqno(sk, skb)) 606 if (dccp_check_seqno(sk, skb))
613 goto discard; 607 goto discard;
614 608
615 /* 609 /*
616 * Step 7: Check for unexpected packet types 610 * Step 8: Process options and mark acknowledgeable
617 * If (S.is_server and P.type == Response) 611 */
618 * or (S.is_client and P.type == Request) 612 if (dccp_parse_options(sk, NULL, skb))
619 * or (S.state == RESPOND and P.type == Data), 613 return 1;
620 * Send Sync packet acknowledging P.seqno
621 * Drop packet and return
622 */
623 if ((dp->dccps_role != DCCP_ROLE_CLIENT &&
624 dh->dccph_type == DCCP_PKT_RESPONSE) ||
625 (dp->dccps_role == DCCP_ROLE_CLIENT &&
626 dh->dccph_type == DCCP_PKT_REQUEST) ||
627 (sk->sk_state == DCCP_RESPOND && dh->dccph_type == DCCP_PKT_DATA)) {
628 dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNC);
629 goto discard;
630 }
631 614
632 /* Step 8: Process options */ 615 if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
633 if (dccp_parse_options(sk, NULL, skb)) 616 dccp_event_ack_recv(sk, skb);
634 return 1; 617
618 if (dccp_msk(sk)->dccpms_send_ack_vector &&
619 dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
620 DCCP_SKB_CB(skb)->dccpd_seq,
621 DCCP_ACKVEC_STATE_RECEIVED))
622 goto discard;
623
624 dccp_deliver_input_to_ccids(sk, skb);
625 }
635 626
636 /* 627 /*
637 * Step 9: Process Reset 628 * Step 9: Process Reset
@@ -640,22 +631,44 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
640 * S.state := TIMEWAIT 631 * S.state := TIMEWAIT
641 * Set TIMEWAIT timer 632 * Set TIMEWAIT timer
642 * Drop packet and return 633 * Drop packet and return
643 */ 634 */
644 if (dh->dccph_type == DCCP_PKT_RESET) { 635 if (dh->dccph_type == DCCP_PKT_RESET) {
645 dccp_rcv_reset(sk, skb); 636 dccp_rcv_reset(sk, skb);
646 return 0; 637 return 0;
647 } else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) { /* Step 13 */ 638 /*
639 * Step 7: Check for unexpected packet types
640 * If (S.is_server and P.type == Response)
641 * or (S.is_client and P.type == Request)
642 * or (S.state == RESPOND and P.type == Data),
643 * Send Sync packet acknowledging P.seqno
644 * Drop packet and return
645 */
646 } else if ((dp->dccps_role != DCCP_ROLE_CLIENT &&
647 dh->dccph_type == DCCP_PKT_RESPONSE) ||
648 (dp->dccps_role == DCCP_ROLE_CLIENT &&
649 dh->dccph_type == DCCP_PKT_REQUEST) ||
650 (sk->sk_state == DCCP_RESPOND &&
651 dh->dccph_type == DCCP_PKT_DATA)) {
652 dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNC);
653 goto discard;
654 } else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) {
648 if (dccp_rcv_closereq(sk, skb)) 655 if (dccp_rcv_closereq(sk, skb))
649 return 0; 656 return 0;
650 goto discard; 657 goto discard;
651 } else if (dh->dccph_type == DCCP_PKT_CLOSE) { /* Step 14 */ 658 } else if (dh->dccph_type == DCCP_PKT_CLOSE) {
652 if (dccp_rcv_close(sk, skb)) 659 if (dccp_rcv_close(sk, skb))
653 return 0; 660 return 0;
654 goto discard; 661 goto discard;
655 } 662 }
656 663
657 switch (sk->sk_state) { 664 switch (sk->sk_state) {
665 case DCCP_CLOSED:
666 dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
667 return 1;
668
658 case DCCP_REQUESTING: 669 case DCCP_REQUESTING:
670 /* FIXME: do congestion control initialization */
671
659 queued = dccp_rcv_request_sent_state_process(sk, skb, dh, len); 672 queued = dccp_rcv_request_sent_state_process(sk, skb, dh, len);
660 if (queued >= 0) 673 if (queued >= 0)
661 return queued; 674 return queued;
@@ -663,12 +676,8 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
663 __kfree_skb(skb); 676 __kfree_skb(skb);
664 return 0; 677 return 0;
665 678
666 case DCCP_PARTOPEN:
667 /* Step 8: if using Ack Vectors, mark packet acknowledgeable */
668 dccp_handle_ackvec_processing(sk, skb);
669 dccp_deliver_input_to_ccids(sk, skb);
670 /* fall through */
671 case DCCP_RESPOND: 679 case DCCP_RESPOND:
680 case DCCP_PARTOPEN:
672 queued = dccp_rcv_respond_partopen_state_process(sk, skb, 681 queued = dccp_rcv_respond_partopen_state_process(sk, skb,
673 dh, len); 682 dh, len);
674 break; 683 break;
@@ -707,7 +716,16 @@ u32 dccp_sample_rtt(struct sock *sk, long delta)
707 /* dccpor_elapsed_time is either zeroed out or set and > 0 */ 716 /* dccpor_elapsed_time is either zeroed out or set and > 0 */
708 delta -= dccp_sk(sk)->dccps_options_received.dccpor_elapsed_time * 10; 717 delta -= dccp_sk(sk)->dccps_options_received.dccpor_elapsed_time * 10;
709 718
710 return dccp_sane_rtt(delta); 719 if (unlikely(delta <= 0)) {
720 DCCP_WARN("unusable RTT sample %ld, using min\n", delta);
721 return DCCP_SANE_RTT_MIN;
722 }
723 if (unlikely(delta > DCCP_SANE_RTT_MAX)) {
724 DCCP_WARN("RTT sample %ld too large, using max\n", delta);
725 return DCCP_SANE_RTT_MAX;
726 }
727
728 return delta;
711} 729}
712 730
713EXPORT_SYMBOL_GPL(dccp_sample_rtt); 731EXPORT_SYMBOL_GPL(dccp_sample_rtt);