diff options
Diffstat (limited to 'net/dccp/input.c')
-rw-r--r-- | net/dccp/input.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/net/dccp/input.c b/net/dccp/input.c index 779d0ed9ae94..5eb443f656c1 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c | |||
@@ -163,7 +163,7 @@ static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb) | |||
163 | { | 163 | { |
164 | struct dccp_sock *dp = dccp_sk(sk); | 164 | struct dccp_sock *dp = dccp_sk(sk); |
165 | 165 | ||
166 | if (dccp_msk(sk)->dccpms_send_ack_vector) | 166 | if (dp->dccps_hc_rx_ackvec != NULL) |
167 | dccp_ackvec_check_rcv_ackno(dp->dccps_hc_rx_ackvec, sk, | 167 | dccp_ackvec_check_rcv_ackno(dp->dccps_hc_rx_ackvec, sk, |
168 | DCCP_SKB_CB(skb)->dccpd_ack_seq); | 168 | DCCP_SKB_CB(skb)->dccpd_ack_seq); |
169 | } | 169 | } |
@@ -375,7 +375,7 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, | |||
375 | if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) | 375 | if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) |
376 | dccp_event_ack_recv(sk, skb); | 376 | dccp_event_ack_recv(sk, skb); |
377 | 377 | ||
378 | if (dccp_msk(sk)->dccpms_send_ack_vector && | 378 | if (dp->dccps_hc_rx_ackvec != NULL && |
379 | dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, | 379 | dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, |
380 | DCCP_SKB_CB(skb)->dccpd_seq, | 380 | DCCP_SKB_CB(skb)->dccpd_seq, |
381 | DCCP_ACKVEC_STATE_RECEIVED)) | 381 | DCCP_ACKVEC_STATE_RECEIVED)) |
@@ -421,20 +421,19 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk, | |||
421 | goto out_invalid_packet; | 421 | goto out_invalid_packet; |
422 | } | 422 | } |
423 | 423 | ||
424 | /* | ||
425 | * If option processing (Step 8) failed, return 1 here so that | ||
426 | * dccp_v4_do_rcv() sends a Reset. The Reset code depends on | ||
427 | * the option type and is set in dccp_parse_options(). | ||
428 | */ | ||
424 | if (dccp_parse_options(sk, NULL, skb)) | 429 | if (dccp_parse_options(sk, NULL, skb)) |
425 | goto out_invalid_packet; | 430 | return 1; |
426 | 431 | ||
427 | /* Obtain usec RTT sample from SYN exchange (used by CCID 3) */ | 432 | /* Obtain usec RTT sample from SYN exchange (used by CCID 3) */ |
428 | if (likely(dp->dccps_options_received.dccpor_timestamp_echo)) | 433 | if (likely(dp->dccps_options_received.dccpor_timestamp_echo)) |
429 | dp->dccps_syn_rtt = dccp_sample_rtt(sk, 10 * (tstamp - | 434 | dp->dccps_syn_rtt = dccp_sample_rtt(sk, 10 * (tstamp - |
430 | dp->dccps_options_received.dccpor_timestamp_echo)); | 435 | dp->dccps_options_received.dccpor_timestamp_echo)); |
431 | 436 | ||
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 */ | 437 | /* Stop the REQUEST timer */ |
439 | inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS); | 438 | inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS); |
440 | WARN_ON(sk->sk_send_head == NULL); | 439 | WARN_ON(sk->sk_send_head == NULL); |
@@ -475,6 +474,15 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk, | |||
475 | */ | 474 | */ |
476 | dccp_set_state(sk, DCCP_PARTOPEN); | 475 | dccp_set_state(sk, DCCP_PARTOPEN); |
477 | 476 | ||
477 | /* | ||
478 | * If feature negotiation was successful, activate features now; | ||
479 | * an activation failure means that this host could not activate | ||
480 | * one ore more features (e.g. insufficient memory), which would | ||
481 | * leave at least one feature in an undefined state. | ||
482 | */ | ||
483 | if (dccp_feat_activate_values(sk, &dp->dccps_featneg)) | ||
484 | goto unable_to_proceed; | ||
485 | |||
478 | /* Make sure socket is routed, for correct metrics. */ | 486 | /* Make sure socket is routed, for correct metrics. */ |
479 | icsk->icsk_af_ops->rebuild_header(sk); | 487 | icsk->icsk_af_ops->rebuild_header(sk); |
480 | 488 | ||
@@ -509,6 +517,16 @@ out_invalid_packet: | |||
509 | /* dccp_v4_do_rcv will send a reset */ | 517 | /* dccp_v4_do_rcv will send a reset */ |
510 | DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; | 518 | DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; |
511 | return 1; | 519 | return 1; |
520 | |||
521 | unable_to_proceed: | ||
522 | DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_ABORTED; | ||
523 | /* | ||
524 | * We mark this socket as no longer usable, so that the loop in | ||
525 | * dccp_sendmsg() terminates and the application gets notified. | ||
526 | */ | ||
527 | dccp_set_state(sk, DCCP_CLOSED); | ||
528 | sk->sk_err = ECOMM; | ||
529 | return 1; | ||
512 | } | 530 | } |
513 | 531 | ||
514 | static int dccp_rcv_respond_partopen_state_process(struct sock *sk, | 532 | static int dccp_rcv_respond_partopen_state_process(struct sock *sk, |
@@ -590,8 +608,6 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
590 | if (inet_csk(sk)->icsk_af_ops->conn_request(sk, | 608 | if (inet_csk(sk)->icsk_af_ops->conn_request(sk, |
591 | skb) < 0) | 609 | skb) < 0) |
592 | return 1; | 610 | return 1; |
593 | |||
594 | /* FIXME: do congestion control initialization */ | ||
595 | goto discard; | 611 | goto discard; |
596 | } | 612 | } |
597 | if (dh->dccph_type == DCCP_PKT_RESET) | 613 | if (dh->dccph_type == DCCP_PKT_RESET) |
@@ -602,7 +618,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
602 | return 1; | 618 | return 1; |
603 | } | 619 | } |
604 | 620 | ||
605 | if (sk->sk_state != DCCP_REQUESTING) { | 621 | if (sk->sk_state != DCCP_REQUESTING && sk->sk_state != DCCP_RESPOND) { |
606 | if (dccp_check_seqno(sk, skb)) | 622 | if (dccp_check_seqno(sk, skb)) |
607 | goto discard; | 623 | goto discard; |
608 | 624 | ||
@@ -615,7 +631,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
615 | if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) | 631 | if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) |
616 | dccp_event_ack_recv(sk, skb); | 632 | dccp_event_ack_recv(sk, skb); |
617 | 633 | ||
618 | if (dccp_msk(sk)->dccpms_send_ack_vector && | 634 | if (dp->dccps_hc_rx_ackvec != NULL && |
619 | dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, | 635 | dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, |
620 | DCCP_SKB_CB(skb)->dccpd_seq, | 636 | DCCP_SKB_CB(skb)->dccpd_seq, |
621 | DCCP_ACKVEC_STATE_RECEIVED)) | 637 | DCCP_ACKVEC_STATE_RECEIVED)) |
@@ -667,8 +683,6 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
667 | return 1; | 683 | return 1; |
668 | 684 | ||
669 | case DCCP_REQUESTING: | 685 | case DCCP_REQUESTING: |
670 | /* FIXME: do congestion control initialization */ | ||
671 | |||
672 | queued = dccp_rcv_request_sent_state_process(sk, skb, dh, len); | 686 | queued = dccp_rcv_request_sent_state_process(sk, skb, dh, len); |
673 | if (queued >= 0) | 687 | if (queued >= 0) |
674 | return queued; | 688 | return queued; |