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.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 1ce101062824..df0fb2c149a6 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -103,6 +103,21 @@ static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb)
103 DCCP_SKB_CB(skb)->dccpd_ack_seq); 103 DCCP_SKB_CB(skb)->dccpd_ack_seq);
104} 104}
105 105
106static void dccp_deliver_input_to_ccids(struct sock *sk, struct sk_buff *skb)
107{
108 const struct dccp_sock *dp = dccp_sk(sk);
109
110 /* Don't deliver to RX CCID when node has shut down read end. */
111 if (!(sk->sk_shutdown & RCV_SHUTDOWN))
112 ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
113 /*
114 * Until the TX queue has been drained, we can not honour SHUT_WR, since
115 * we need received feedback as input to adjust congestion control.
116 */
117 if (sk->sk_write_queue.qlen > 0 || !(sk->sk_shutdown & SEND_SHUTDOWN))
118 ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
119}
120
106static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb) 121static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
107{ 122{
108 const struct dccp_hdr *dh = dccp_hdr(skb); 123 const struct dccp_hdr *dh = dccp_hdr(skb);
@@ -209,8 +224,9 @@ static int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
209 case DCCP_PKT_DATAACK: 224 case DCCP_PKT_DATAACK:
210 case DCCP_PKT_DATA: 225 case DCCP_PKT_DATA:
211 /* 226 /*
212 * FIXME: check if sk_receive_queue is full, schedule DATA_DROPPED 227 * FIXME: schedule DATA_DROPPED (RFC 4340, 11.7.2) if and when
213 * option if it is. 228 * - sk_shutdown == RCV_SHUTDOWN, use Code 1, "Not Listening"
229 * - sk_receive_queue is full, use Code 2, "Receive Buffer"
214 */ 230 */
215 __skb_pull(skb, dh->dccph_doff * 4); 231 __skb_pull(skb, dh->dccph_doff * 4);
216 __skb_queue_tail(&sk->sk_receive_queue, skb); 232 __skb_queue_tail(&sk->sk_receive_queue, skb);
@@ -300,9 +316,7 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
300 DCCP_SKB_CB(skb)->dccpd_seq, 316 DCCP_SKB_CB(skb)->dccpd_seq,
301 DCCP_ACKVEC_STATE_RECEIVED)) 317 DCCP_ACKVEC_STATE_RECEIVED))
302 goto discard; 318 goto discard;
303 319 dccp_deliver_input_to_ccids(sk, skb);
304 ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
305 ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
306 320
307 return __dccp_rcv_established(sk, skb, dh, len); 321 return __dccp_rcv_established(sk, skb, dh, len);
308discard: 322discard:
@@ -543,8 +557,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
543 DCCP_ACKVEC_STATE_RECEIVED)) 557 DCCP_ACKVEC_STATE_RECEIVED))
544 goto discard; 558 goto discard;
545 559
546 ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); 560 dccp_deliver_input_to_ccids(sk, skb);
547 ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
548 } 561 }
549 562
550 /* 563 /*