diff options
Diffstat (limited to 'net/dccp/input.c')
| -rw-r--r-- | net/dccp/input.c | 47 | 
1 files changed, 30 insertions, 17 deletions
diff --git a/net/dccp/input.c b/net/dccp/input.c index 7371a2f3acf4..565bc80557ce 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -1,6 +1,6 @@  /*   *  net/dccp/input.c - *  + *   *  An implementation of the DCCP protocol   *  Arnaldo Carvalho de Melo <acme@conectiva.com.br>   * @@ -82,7 +82,7 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)  	 *	  Otherwise,  	 *	     Drop packet and return  	 */ -	if (dh->dccph_type == DCCP_PKT_SYNC ||  +	if (dh->dccph_type == DCCP_PKT_SYNC ||  	    dh->dccph_type == DCCP_PKT_SYNCACK) {  		if (between48(DCCP_SKB_CB(skb)->dccpd_ack_seq,  			      dp->dccps_awl, dp->dccps_awh) && @@ -185,8 +185,8 @@ static int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb,  		dccp_rcv_close(sk, skb);  		return 0;  	case DCCP_PKT_REQUEST: -		/* Step 7  -            	 *   or (S.is_server and P.type == Response) +		/* Step 7 +		 *   or (S.is_server and P.type == Response)  		 *   or (S.is_client and P.type == Request)  		 *   or (S.state >= OPEN and P.type == Request  		 *	and P.seqno >= S.OSR) @@ -248,8 +248,18 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,  			    DCCP_ACKVEC_STATE_RECEIVED))  		goto discard; -	ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); -	ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb); +	/* +	 * Deliver to the CCID module in charge. +	 * FIXME: Currently DCCP operates one-directional only, i.e. a listening +	 *        server is not at the same time a connecting client. There is +	 *        not much sense in delivering to both rx/tx sides at the moment +	 *        (only one is active at a time); when moving to bidirectional +	 *        service, this needs to be revised. +	 */ +	if (dccp_sk(sk)->dccps_role == DCCP_ROLE_SERVER) +		ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); +	else +		ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);  	return __dccp_rcv_established(sk, skb, dh, len);  discard: @@ -264,7 +274,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,  					       const struct dccp_hdr *dh,  					       const unsigned len)  { -	/*  +	/*  	 *  Step 4: Prepare sequence numbers in REQUEST  	 *     If S.state == REQUEST,  	 *	  If (P.type == Response or P.type == Reset) @@ -332,7 +342,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,  		 *	      from the Response * /  		 *	  S.state := PARTOPEN  		 *	  Set PARTOPEN timer -		 * 	  Continue with S.state == PARTOPEN +		 *	  Continue with S.state == PARTOPEN  		 *	  / * Step 12 will send the Ack completing the  		 *	      three-way handshake * /  		 */ @@ -363,7 +373,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,  			 */  			__kfree_skb(skb);  			return 0; -		}  +		}  		dccp_send_ack(sk);  		return -1;  	} @@ -371,7 +381,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,  out_invalid_packet:  	/* dccp_v4_do_rcv will send a reset */  	DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; -	return 1;  +	return 1;  }  static int dccp_rcv_respond_partopen_state_process(struct sock *sk, @@ -478,14 +488,17 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,  		if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)  			dccp_event_ack_recv(sk, skb); - 		if (dccp_msk(sk)->dccpms_send_ack_vector && +		if (dccp_msk(sk)->dccpms_send_ack_vector &&  		    dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, - 				    DCCP_SKB_CB(skb)->dccpd_seq, - 				    DCCP_ACKVEC_STATE_RECEIVED)) - 			goto discard; +				    DCCP_SKB_CB(skb)->dccpd_seq, +				    DCCP_ACKVEC_STATE_RECEIVED)) +			goto discard; -		ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); -		ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb); +		/* XXX see the comments in dccp_rcv_established about this */ +		if (dccp_sk(sk)->dccps_role == DCCP_ROLE_SERVER) +			ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); +		else +			ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);  	}  	/* @@ -567,7 +580,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,  		}  	} -	if (!queued) {  +	if (!queued) {  discard:  		__kfree_skb(skb);  	}  | 
