diff options
author | Arnaldo Carvalho de Melo <acme@mandriva.com> | 2005-08-17 02:10:59 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2005-08-29 19:01:50 -0400 |
commit | e92ae93a8aa66aea12935420cb22d4df1c18d023 (patch) | |
tree | 61ffc292a8e437f7d44bbfe00c4e052f7488dd25 /net/dccp | |
parent | ba602a816132dcc66e875dddf2c62512a9f6f8cb (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>
Diffstat (limited to 'net/dccp')
-rw-r--r-- | net/dccp/dccp.h | 3 | ||||
-rw-r--r-- | net/dccp/input.c | 33 | ||||
-rw-r--r-- | net/dccp/ipv4.c | 18 | ||||
-rw-r--r-- | net/dccp/output.c | 5 |
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); | |||
122 | extern int dccp_send_response(struct sock *sk); | 122 | extern int dccp_send_response(struct sock *sk); |
123 | extern void dccp_send_ack(struct sock *sk); | 123 | extern void dccp_send_ack(struct sock *sk); |
124 | extern void dccp_send_delayed_ack(struct sock *sk); | 124 | extern void dccp_send_delayed_ack(struct sock *sk); |
125 | extern void dccp_send_sync(struct sock *sk, u64 seq); | 125 | extern void dccp_send_sync(struct sock *sk, const u64 seq, |
126 | const enum dccp_pkt_type pkt_type); | ||
126 | 127 | ||
127 | extern int dccp_write_xmit(struct sock *sk, struct sk_buff *skb, | 128 | extern 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, | |||
242 | check_seq: | 246 | check_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)) { |
244 | send_sync: | 248 | send_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 | ||
407 | void dccp_send_sync(struct sock *sk, u64 seq) | 407 | void 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); |