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.c44
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
521unable_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
514static int dccp_rcv_respond_partopen_state_process(struct sock *sk, 532static 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;