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, 73 insertions, 91 deletions
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 779d0ed9ae94..df0e6714aa11 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -159,13 +159,15 @@ 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_event_ack_recv(struct sock *sk, struct sk_buff *skb) 162static void dccp_handle_ackvec_processing(struct sock *sk, struct sk_buff *skb)
163{ 163{
164 struct dccp_sock *dp = dccp_sk(sk); 164 struct dccp_ackvec *av = dccp_sk(sk)->dccps_hc_rx_ackvec;
165 165
166 if (dccp_msk(sk)->dccpms_send_ack_vector) 166 if (av == NULL)
167 dccp_ackvec_check_rcv_ackno(dp->dccps_hc_rx_ackvec, sk, 167 return;
168 DCCP_SKB_CB(skb)->dccpd_ack_seq); 168 if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
169 dccp_ackvec_clear_state(av, DCCP_SKB_CB(skb)->dccpd_ack_seq);
170 dccp_ackvec_input(av, skb);
169} 171}
170 172
171static void dccp_deliver_input_to_ccids(struct sock *sk, struct sk_buff *skb) 173static void dccp_deliver_input_to_ccids(struct sock *sk, struct sk_buff *skb)
@@ -364,22 +366,13 @@ discard:
364int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, 366int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
365 const struct dccp_hdr *dh, const unsigned len) 367 const struct dccp_hdr *dh, const unsigned len)
366{ 368{
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 if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) 375 dccp_handle_ackvec_processing(sk, skb);
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;
383 dccp_deliver_input_to_ccids(sk, skb); 376 dccp_deliver_input_to_ccids(sk, skb);
384 377
385 return __dccp_rcv_established(sk, skb, dh, len); 378 return __dccp_rcv_established(sk, skb, dh, len);
@@ -421,40 +414,33 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
421 goto out_invalid_packet; 414 goto out_invalid_packet;
422 } 415 }
423 416
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 */
424 if (dccp_parse_options(sk, NULL, skb)) 422 if (dccp_parse_options(sk, NULL, skb))
425 goto out_invalid_packet; 423 return 1;
426 424
427 /* Obtain usec RTT sample from SYN exchange (used by CCID 3) */ 425 /* Obtain usec RTT sample from SYN exchange (used by CCID 3) */
428 if (likely(dp->dccps_options_received.dccpor_timestamp_echo)) 426 if (likely(dp->dccps_options_received.dccpor_timestamp_echo))
429 dp->dccps_syn_rtt = dccp_sample_rtt(sk, 10 * (tstamp - 427 dp->dccps_syn_rtt = dccp_sample_rtt(sk, 10 * (tstamp -
430 dp->dccps_options_received.dccpor_timestamp_echo)); 428 dp->dccps_options_received.dccpor_timestamp_echo));
431 429
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
438 /* Stop the REQUEST timer */ 430 /* Stop the REQUEST timer */
439 inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS); 431 inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS);
440 WARN_ON(sk->sk_send_head == NULL); 432 WARN_ON(sk->sk_send_head == NULL);
441 kfree_skb(sk->sk_send_head); 433 kfree_skb(sk->sk_send_head);
442 sk->sk_send_head = NULL; 434 sk->sk_send_head = NULL;
443 435
444 dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq;
445 dccp_update_gsr(sk, dp->dccps_isr);
446 /* 436 /*
447 * SWL and AWL are initially adjusted so that they are not less than 437 * Set ISR, GSR from packet. ISS was set in dccp_v{4,6}_connect
448 * the initial Sequence Numbers received and sent, respectively: 438 * and GSS in dccp_transmit_skb(). Setting AWL/AWH and SWL/SWH
449 * SWL := max(GSR + 1 - floor(W/4), ISR), 439 * is done as part of activating the feature values below, since
450 * AWL := max(GSS - W' + 1, ISS). 440 * these settings depend on the local/remote Sequence Window
451 * These adjustments MUST be applied only at the beginning of the 441 * features, which were undefined or not confirmed until now.
452 * connection.
453 *
454 * AWL was adjusted in dccp_v4_connect -acme
455 */ 442 */
456 dccp_set_seqno(&dp->dccps_swl, 443 dp->dccps_gsr = dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq;
457 max48(dp->dccps_swl, dp->dccps_isr));
458 444
459 dccp_sync_mss(sk, icsk->icsk_pmtu_cookie); 445 dccp_sync_mss(sk, icsk->icsk_pmtu_cookie);
460 446
@@ -475,6 +461,15 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
475 */ 461 */
476 dccp_set_state(sk, DCCP_PARTOPEN); 462 dccp_set_state(sk, DCCP_PARTOPEN);
477 463
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
478 /* Make sure socket is routed, for correct metrics. */ 473 /* Make sure socket is routed, for correct metrics. */
479 icsk->icsk_af_ops->rebuild_header(sk); 474 icsk->icsk_af_ops->rebuild_header(sk);
480 475
@@ -509,6 +504,16 @@ out_invalid_packet:
509 /* dccp_v4_do_rcv will send a reset */ 504 /* dccp_v4_do_rcv will send a reset */
510 DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; 505 DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR;
511 return 1; 506 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;
512} 517}
513 518
514static int dccp_rcv_respond_partopen_state_process(struct sock *sk, 519static int dccp_rcv_respond_partopen_state_process(struct sock *sk,
@@ -590,8 +595,6 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
590 if (inet_csk(sk)->icsk_af_ops->conn_request(sk, 595 if (inet_csk(sk)->icsk_af_ops->conn_request(sk,
591 skb) < 0) 596 skb) < 0)
592 return 1; 597 return 1;
593
594 /* FIXME: do congestion control initialization */
595 goto discard; 598 goto discard;
596 } 599 }
597 if (dh->dccph_type == DCCP_PKT_RESET) 600 if (dh->dccph_type == DCCP_PKT_RESET)
@@ -600,30 +603,36 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
600 /* Caller (dccp_v4_do_rcv) will send Reset */ 603 /* Caller (dccp_v4_do_rcv) will send Reset */
601 dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; 604 dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
602 return 1; 605 return 1;
606 } else if (sk->sk_state == DCCP_CLOSED) {
607 dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
608 return 1;
603 } 609 }
604 610
605 if (sk->sk_state != DCCP_REQUESTING) { 611 /* Step 6: Check sequence numbers (omitted in LISTEN/REQUEST state) */
606 if (dccp_check_seqno(sk, skb)) 612 if (sk->sk_state != DCCP_REQUESTING && dccp_check_seqno(sk, skb))
607 goto discard; 613 goto discard;
608
609 /*
610 * Step 8: Process options and mark acknowledgeable
611 */
612 if (dccp_parse_options(sk, NULL, skb))
613 return 1;
614
615 if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
616 dccp_event_ack_recv(sk, skb);
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 614
624 dccp_deliver_input_to_ccids(sk, skb); 615 /*
616 * Step 7: Check for unexpected packet types
617 * If (S.is_server and P.type == Response)
618 * or (S.is_client and P.type == Request)
619 * or (S.state == RESPOND and P.type == Data),
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;
625 } 630 }
626 631
632 /* Step 8: Process options */
633 if (dccp_parse_options(sk, NULL, skb))
634 return 1;
635
627 /* 636 /*
628 * Step 9: Process Reset 637 * Step 9: Process Reset
629 * If P.type == Reset, 638 * If P.type == Reset,
@@ -631,44 +640,22 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
631 * S.state := TIMEWAIT 640 * S.state := TIMEWAIT
632 * Set TIMEWAIT timer 641 * Set TIMEWAIT timer
633 * Drop packet and return 642 * Drop packet and return
634 */ 643 */
635 if (dh->dccph_type == DCCP_PKT_RESET) { 644 if (dh->dccph_type == DCCP_PKT_RESET) {
636 dccp_rcv_reset(sk, skb); 645 dccp_rcv_reset(sk, skb);
637 return 0; 646 return 0;
638 /* 647 } else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) { /* Step 13 */
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) {
655 if (dccp_rcv_closereq(sk, skb)) 648 if (dccp_rcv_closereq(sk, skb))
656 return 0; 649 return 0;
657 goto discard; 650 goto discard;
658 } else if (dh->dccph_type == DCCP_PKT_CLOSE) { 651 } else if (dh->dccph_type == DCCP_PKT_CLOSE) { /* Step 14 */
659 if (dccp_rcv_close(sk, skb)) 652 if (dccp_rcv_close(sk, skb))
660 return 0; 653 return 0;
661 goto discard; 654 goto discard;
662 } 655 }
663 656
664 switch (sk->sk_state) { 657 switch (sk->sk_state) {
665 case DCCP_CLOSED:
666 dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
667 return 1;
668
669 case DCCP_REQUESTING: 658 case DCCP_REQUESTING:
670 /* FIXME: do congestion control initialization */
671
672 queued = dccp_rcv_request_sent_state_process(sk, skb, dh, len); 659 queued = dccp_rcv_request_sent_state_process(sk, skb, dh, len);
673 if (queued >= 0) 660 if (queued >= 0)
674 return queued; 661 return queued;
@@ -676,8 +663,12 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
676 __kfree_skb(skb); 663 __kfree_skb(skb);
677 return 0; 664 return 0;
678 665
679 case DCCP_RESPOND:
680 case DCCP_PARTOPEN: 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:
681 queued = dccp_rcv_respond_partopen_state_process(sk, skb, 672 queued = dccp_rcv_respond_partopen_state_process(sk, skb,
682 dh, len); 673 dh, len);
683 break; 674 break;
@@ -716,16 +707,7 @@ u32 dccp_sample_rtt(struct sock *sk, long delta)
716 /* dccpor_elapsed_time is either zeroed out or set and > 0 */ 707 /* dccpor_elapsed_time is either zeroed out or set and > 0 */
717 delta -= dccp_sk(sk)->dccps_options_received.dccpor_elapsed_time * 10; 708 delta -= dccp_sk(sk)->dccps_options_received.dccpor_elapsed_time * 10;
718 709
719 if (unlikely(delta <= 0)) { 710 return dccp_sane_rtt(delta);
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;
729} 711}
730 712
731EXPORT_SYMBOL_GPL(dccp_sample_rtt); 713EXPORT_SYMBOL_GPL(dccp_sample_rtt);