diff options
author | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2008-09-04 01:30:19 -0400 |
---|---|---|
committer | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2008-09-04 01:45:30 -0400 |
commit | c49b22729f3da7479c4e6c572d53fdd40201d0bd (patch) | |
tree | 2c58a67f089c97a55a132697ecf2ccc438bbed7f /net/dccp/input.c | |
parent | e70cacb90d76f0632f7bba69c87a62e709e84619 (diff) |
dccp: Integration of dynamic feature activation - part 3 (client side)
This integrates feature-activation in the client, with these details:
1. When dccp_parse_options() fails, the reset code is already set, request_sent
_state_process() currently overrides this with `Packet Error', which is not
intended - so changed to use the reset code set in dccp_parse_options();
2. There was a FIXME to change the error code when dccp_ackvec_add() fails.
I have looked this up and found that:
* the check whether ackno < ISN is already made earlier,
* this Response is likely the 1st packet with an Ackno that the client gets,
* so when dccp_ackvec_add() fails, the reason is likely not a packet error.
3. When feature negotiation fails, the socket should be marked as not usable,
so that the application is notified that an error occurs. This is achieved
by a new label, which uses an error code of `Aborted' and which sets the
socket state to CLOSED, as well as sk_err.
4. Avoids parsing the Ack twice in Respond state by not doing option processing
again in dccp_rcv_respond_partopen_state_process (as option processing has
already been done on the request_sock in dccp_check_req).
Since this addresses congestion-control initialisation, a corresponding
FIXME has been removed.
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
Diffstat (limited to 'net/dccp/input.c')
-rw-r--r-- | net/dccp/input.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/net/dccp/input.c b/net/dccp/input.c index 3070015edc75..0672b7e1763e 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c | |||
@@ -421,8 +421,13 @@ 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)) |
@@ -475,6 +480,15 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk, | |||
475 | */ | 480 | */ |
476 | dccp_set_state(sk, DCCP_PARTOPEN); | 481 | dccp_set_state(sk, DCCP_PARTOPEN); |
477 | 482 | ||
483 | /* | ||
484 | * If feature negotiation was successful, activate features now; | ||
485 | * an activation failure means that this host could not activate | ||
486 | * one ore more features (e.g. insufficient memory), which would | ||
487 | * leave at least one feature in an undefined state. | ||
488 | */ | ||
489 | if (dccp_feat_activate_values(sk, &dp->dccps_featneg)) | ||
490 | goto unable_to_proceed; | ||
491 | |||
478 | /* Make sure socket is routed, for correct metrics. */ | 492 | /* Make sure socket is routed, for correct metrics. */ |
479 | icsk->icsk_af_ops->rebuild_header(sk); | 493 | icsk->icsk_af_ops->rebuild_header(sk); |
480 | 494 | ||
@@ -509,6 +523,16 @@ out_invalid_packet: | |||
509 | /* dccp_v4_do_rcv will send a reset */ | 523 | /* dccp_v4_do_rcv will send a reset */ |
510 | DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; | 524 | DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; |
511 | return 1; | 525 | return 1; |
526 | |||
527 | unable_to_proceed: | ||
528 | DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_ABORTED; | ||
529 | /* | ||
530 | * We mark this socket as no longer usable, so that the loop in | ||
531 | * dccp_sendmsg() terminates and the application gets notified. | ||
532 | */ | ||
533 | dccp_set_state(sk, DCCP_CLOSED); | ||
534 | sk->sk_err = ECOMM; | ||
535 | return 1; | ||
512 | } | 536 | } |
513 | 537 | ||
514 | static int dccp_rcv_respond_partopen_state_process(struct sock *sk, | 538 | static int dccp_rcv_respond_partopen_state_process(struct sock *sk, |
@@ -600,7 +624,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
600 | return 1; | 624 | return 1; |
601 | } | 625 | } |
602 | 626 | ||
603 | if (sk->sk_state != DCCP_REQUESTING) { | 627 | if (sk->sk_state != DCCP_REQUESTING && sk->sk_state != DCCP_RESPOND) { |
604 | if (dccp_check_seqno(sk, skb)) | 628 | if (dccp_check_seqno(sk, skb)) |
605 | goto discard; | 629 | goto discard; |
606 | 630 | ||
@@ -665,8 +689,6 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
665 | return 1; | 689 | return 1; |
666 | 690 | ||
667 | case DCCP_REQUESTING: | 691 | case DCCP_REQUESTING: |
668 | /* FIXME: do congestion control initialization */ | ||
669 | |||
670 | queued = dccp_rcv_request_sent_state_process(sk, skb, dh, len); | 692 | queued = dccp_rcv_request_sent_state_process(sk, skb, dh, len); |
671 | if (queued >= 0) | 693 | if (queued >= 0) |
672 | return queued; | 694 | return queued; |