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/input.c | |
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/input.c')
-rw-r--r-- | net/dccp/input.c | 33 |
1 files changed, 25 insertions, 8 deletions
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 | ||