diff options
author | Samuel Jero <sj323707@ohio.edu> | 2012-02-26 18:22:02 -0700 |
---|---|---|
committer | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2012-03-03 09:02:52 -0700 |
commit | f541fb7e20c848f947ca65fbf169efe69400c942 (patch) | |
tree | 689f3a7a46ca00b6610667e33313f339645b229d /net/dccp/ipv6.c | |
parent | 793734b587a670e47a8d65f9e5211ba2188bb904 (diff) | |
download | linux-f541fb7e20c848f947ca65fbf169efe69400c942.tar.bz2 |
dccp: fix bug in sequence number validation during connection setup
This fixes a bug in the sequence number validation during the initial handshake.
The code did not treat the initial sequence numbers ISS and ISR as read-only and
did not keep state for GSR and GSS as required by the specification. This causes
problems with retransmissions during the initial handshake, causing the
budding connection to be reset.
This patch now treats ISS/ISR as read-only and tracks GSS/GSR as required.
Signed-off-by: Samuel Jero <sj323707@ohio.edu>
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Diffstat (limited to 'net/dccp/ipv6.c')
-rw-r--r-- | net/dccp/ipv6.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index ce903f747e64..4dc588f520e0 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -193,7 +193,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, */ WARN_ON(req->sk != NULL); - if (seq != dccp_rsk(req)->dreq_iss) { + if (!between48(seq, dccp_rsk(req)->dreq_iss, + dccp_rsk(req)->dreq_gss)) { NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); goto out; } @@ -440,11 +441,12 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) * * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie * - * In fact we defer setting S.GSR, S.SWL, S.SWH to - * dccp_create_openreq_child. + * Setting S.SWL/S.SWH to is deferred to dccp_create_openreq_child(). */ dreq->dreq_isr = dcb->dccpd_seq; + dreq->dreq_gsr = dreq->dreq_isr; dreq->dreq_iss = dccp_v6_init_sequence(skb); + dreq->dreq_gss = dreq->dreq_iss; dreq->dreq_service = service; if (dccp_v6_send_response(sk, req, NULL)) |