aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@mandriva.com>2005-08-17 02:10:59 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-08-29 19:01:50 -0400
commite92ae93a8aa66aea12935420cb22d4df1c18d023 (patch)
tree61ffc292a8e437f7d44bbfe00c4e052f7488dd25
parentba602a816132dcc66e875dddf2c62512a9f6f8cb (diff)
[DCCP]: Send SYNCACK packets in response to SYNC packets
Also fix step 6 when receiving SYNC or SYNCACK packets, i.e. we were not using the updated swl. Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/dccp/dccp.h3
-rw-r--r--net/dccp/input.c33
-rw-r--r--net/dccp/ipv4.c18
-rw-r--r--net/dccp/output.c5
4 files changed, 40 insertions, 19 deletions
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index fff794c8dfff..4efdce47000b 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -122,7 +122,8 @@ extern int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb);
122extern int dccp_send_response(struct sock *sk); 122extern int dccp_send_response(struct sock *sk);
123extern void dccp_send_ack(struct sock *sk); 123extern void dccp_send_ack(struct sock *sk);
124extern void dccp_send_delayed_ack(struct sock *sk); 124extern void dccp_send_delayed_ack(struct sock *sk);
125extern void dccp_send_sync(struct sock *sk, u64 seq); 125extern void dccp_send_sync(struct sock *sk, const u64 seq,
126 const enum dccp_pkt_type pkt_type);
126 127
127extern int dccp_write_xmit(struct sock *sk, struct sk_buff *skb, 128extern int dccp_write_xmit(struct sock *sk, struct sk_buff *skb,
128 const int len); 129 const int len);
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 9dadfc362511..68b6e72551ef 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -50,7 +50,7 @@ static void dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb)
50 * Drop packet and return 50 * Drop packet and return
51 */ 51 */
52 if (dccp_sk(sk)->dccps_role != DCCP_ROLE_CLIENT) { 52 if (dccp_sk(sk)->dccps_role != DCCP_ROLE_CLIENT) {
53 dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq); 53 dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, DCCP_PKT_SYNC);
54 return; 54 return;
55 } 55 }
56 56
@@ -76,8 +76,7 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
76{ 76{
77 const struct dccp_hdr *dh = dccp_hdr(skb); 77 const struct dccp_hdr *dh = dccp_hdr(skb);
78 struct dccp_sock *dp = dccp_sk(sk); 78 struct dccp_sock *dp = dccp_sk(sk);
79 u64 lswl = dp->dccps_swl; 79 u64 lswl, lawl;
80 u64 lawl = dp->dccps_awl;
81 80
82 /* 81 /*
83 * Step 5: Prepare sequence numbers for Sync 82 * Step 5: Prepare sequence numbers for Sync
@@ -99,6 +98,8 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
99 dccp_update_gsr(sk, DCCP_SKB_CB(skb)->dccpd_seq); 98 dccp_update_gsr(sk, DCCP_SKB_CB(skb)->dccpd_seq);
100 else 99 else
101 return -1; 100 return -1;
101 }
102
102 /* 103 /*
103 * Step 6: Check sequence numbers 104 * Step 6: Check sequence numbers
104 * Let LSWL = S.SWL and LAWL = S.AWL 105 * Let LSWL = S.SWL and LAWL = S.AWL
@@ -113,7 +114,10 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
113 * Send Sync packet acknowledging P.seqno 114 * Send Sync packet acknowledging P.seqno
114 * Drop packet and return 115 * Drop packet and return
115 */ 116 */
116 } else if (dh->dccph_type == DCCP_PKT_CLOSEREQ || 117 lswl = dp->dccps_swl;
118 lawl = dp->dccps_awl;
119
120 if (dh->dccph_type == DCCP_PKT_CLOSEREQ ||
117 dh->dccph_type == DCCP_PKT_CLOSE || 121 dh->dccph_type == DCCP_PKT_CLOSE ||
118 dh->dccph_type == DCCP_PKT_RESET) { 122 dh->dccph_type == DCCP_PKT_RESET) {
119 lswl = dp->dccps_gsr; 123 lswl = dp->dccps_gsr;
@@ -132,8 +136,8 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
132 DCCP_PKT_WITHOUT_ACK_SEQ)) 136 DCCP_PKT_WITHOUT_ACK_SEQ))
133 dp->dccps_gar = DCCP_SKB_CB(skb)->dccpd_ack_seq; 137 dp->dccps_gar = DCCP_SKB_CB(skb)->dccpd_ack_seq;
134 } else { 138 } else {
135 dccp_pr_debug("Step 6 failed, sending SYNC...\n"); 139 LIMIT_NETDEBUG("Step 6 failed, sending SYNC...\n");
136 dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq); 140 dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, DCCP_PKT_SYNC);
137 return -1; 141 return -1;
138 } 142 }
139 143
@@ -242,9 +246,21 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
242check_seq: 246check_seq:
243 if (!before48(DCCP_SKB_CB(skb)->dccpd_seq, dp->dccps_osr)) { 247 if (!before48(DCCP_SKB_CB(skb)->dccpd_seq, dp->dccps_osr)) {
244send_sync: 248send_sync:
245 dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq); 249 dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq,
250 DCCP_PKT_SYNC);
246 } 251 }
247 break; 252 break;
253 case DCCP_PKT_SYNC:
254 dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq,
255 DCCP_PKT_SYNCACK);
256 /*
257 * From the draft:
258 *
259 * As with DCCP-Ack packets, DCCP-Sync and DCCP-SyncAck packets
260 * MAY have non-zero-length application data areas, whose
261 * contents * receivers MUST ignore.
262 */
263 goto discard;
248 } 264 }
249 265
250 DCCP_INC_STATS_BH(DCCP_MIB_INERRS); 266 DCCP_INC_STATS_BH(DCCP_MIB_INERRS);
@@ -517,7 +533,8 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
517 dh->dccph_type == DCCP_PKT_REQUEST) || 533 dh->dccph_type == DCCP_PKT_REQUEST) ||
518 (sk->sk_state == DCCP_RESPOND && 534 (sk->sk_state == DCCP_RESPOND &&
519 dh->dccph_type == DCCP_PKT_DATA)) { 535 dh->dccph_type == DCCP_PKT_DATA)) {
520 dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq); 536 dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq,
537 DCCP_PKT_SYNC);
521 goto discard; 538 goto discard;
522 } 539 }
523 540
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index bc3cfc0533cc..335e00e9631d 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -376,7 +376,7 @@ static inline void dccp_do_pmtu_discovery(struct sock *sk,
376 * probing, since DCCP-Sync probes do not risk application 376 * probing, since DCCP-Sync probes do not risk application
377 * data loss. 377 * data loss.
378 */ 378 */
379 dccp_send_sync(sk, dp->dccps_gsr); 379 dccp_send_sync(sk, dp->dccps_gsr, DCCP_PKT_SYNC);
380 } /* else let the usual retransmit timer handle it */ 380 } /* else let the usual retransmit timer handle it */
381} 381}
382 382
@@ -1008,7 +1008,7 @@ static inline int dccp_invalid_packet(struct sk_buff *skb)
1008 return 1; 1008 return 1;
1009 1009
1010 if (!pskb_may_pull(skb, sizeof(struct dccp_hdr))) { 1010 if (!pskb_may_pull(skb, sizeof(struct dccp_hdr))) {
1011 dccp_pr_debug("pskb_may_pull failed\n"); 1011 printk(KERN_WARNING "DCCP: pskb_may_pull failed\n");
1012 return 1; 1012 return 1;
1013 } 1013 }
1014 1014
@@ -1016,7 +1016,7 @@ static inline int dccp_invalid_packet(struct sk_buff *skb)
1016 1016
1017 /* If the packet type is not understood, drop packet and return */ 1017 /* If the packet type is not understood, drop packet and return */
1018 if (dh->dccph_type >= DCCP_PKT_INVALID) { 1018 if (dh->dccph_type >= DCCP_PKT_INVALID) {
1019 dccp_pr_debug("invalid packet type\n"); 1019 printk(KERN_WARNING "DCCP: invalid packet type\n");
1020 return 1; 1020 return 1;
1021 } 1021 }
1022 1022
@@ -1025,12 +1025,13 @@ static inline int dccp_invalid_packet(struct sk_buff *skb)
1025 * packet, drop packet and return 1025 * packet, drop packet and return
1026 */ 1026 */
1027 if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) { 1027 if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) {
1028 dccp_pr_debug("Offset(%u) too small 1\n", dh->dccph_doff); 1028 printk(KERN_WARNING "DCCP: Offset(%u) too small 1\n",
1029 dh->dccph_doff);
1029 return 1; 1030 return 1;
1030 } 1031 }
1031 1032
1032 if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) { 1033 if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) {
1033 dccp_pr_debug("P.Data Offset(%u) too small 2\n", 1034 printk(KERN_WARNING "DCCP: P.Data Offset(%u) too small 2\n",
1034 dh->dccph_doff); 1035 dh->dccph_doff);
1035 return 1; 1036 return 1;
1036 } 1037 }
@@ -1045,15 +1046,16 @@ static inline int dccp_invalid_packet(struct sk_buff *skb)
1045 dh->dccph_type != DCCP_PKT_DATA && 1046 dh->dccph_type != DCCP_PKT_DATA &&
1046 dh->dccph_type != DCCP_PKT_ACK && 1047 dh->dccph_type != DCCP_PKT_ACK &&
1047 dh->dccph_type != DCCP_PKT_DATAACK) { 1048 dh->dccph_type != DCCP_PKT_DATAACK) {
1048 dccp_pr_debug("P.type (%s) not Data, Ack nor DataAck and " 1049 printk(KERN_WARNING "DCCP: P.type (%s) not Data, Ack nor "
1049 "P.X == 0\n", dccp_packet_name(dh->dccph_type)); 1050 "DataAck and P.X == 0\n",
1051 dccp_packet_name(dh->dccph_type));
1050 return 1; 1052 return 1;
1051 } 1053 }
1052 1054
1053 /* If the header checksum is incorrect, drop packet and return */ 1055 /* If the header checksum is incorrect, drop packet and return */
1054 if (dccp_v4_verify_checksum(skb, skb->nh.iph->saddr, 1056 if (dccp_v4_verify_checksum(skb, skb->nh.iph->saddr,
1055 skb->nh.iph->daddr) < 0) { 1057 skb->nh.iph->daddr) < 0) {
1056 dccp_pr_debug("header checksum is incorrect\n"); 1058 printk(KERN_WARNING "DCCP: header checksum is incorrect\n");
1057 return 1; 1059 return 1;
1058 } 1060 }
1059 1061
diff --git a/net/dccp/output.c b/net/dccp/output.c
index dcc061bed924..384fd0920983 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -404,7 +404,8 @@ void dccp_send_delayed_ack(struct sock *sk)
404 sk_reset_timer(sk, &icsk->icsk_delack_timer, timeout); 404 sk_reset_timer(sk, &icsk->icsk_delack_timer, timeout);
405} 405}
406 406
407void dccp_send_sync(struct sock *sk, u64 seq) 407void dccp_send_sync(struct sock *sk, const u64 seq,
408 const enum dccp_pkt_type pkt_type)
408{ 409{
409 /* 410 /*
410 * We are not putting this on the write queue, so 411 * We are not putting this on the write queue, so
@@ -420,7 +421,7 @@ void dccp_send_sync(struct sock *sk, u64 seq)
420 /* Reserve space for headers and prepare control bits. */ 421 /* Reserve space for headers and prepare control bits. */
421 skb_reserve(skb, MAX_DCCP_HEADER); 422 skb_reserve(skb, MAX_DCCP_HEADER);
422 skb->csum = 0; 423 skb->csum = 0;
423 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_SYNC; 424 DCCP_SKB_CB(skb)->dccpd_type = pkt_type;
424 DCCP_SKB_CB(skb)->dccpd_seq = seq; 425 DCCP_SKB_CB(skb)->dccpd_seq = seq;
425 426
426 skb_set_owner_w(skb, sk); 427 skb_set_owner_w(skb, sk);