diff options
author | rrs <rrs@FreeBSD.org> | 2007-10-30 14:09:24 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2007-10-30 14:09:24 +0000 |
commit | 814ed57392bec9cf5be68e30ad73cd809079b7ed (patch) | |
tree | 06d1ed3e2635e73c3786a3d9087f96f533011d02 /sys/netinet/sctputil.c | |
parent | d0be68189d3bb9676d666e1749a0a8d3a967577c (diff) | |
download | FreeBSD-src-814ed57392bec9cf5be68e30ad73cd809079b7ed.zip FreeBSD-src-814ed57392bec9cf5be68e30ad73cd809079b7ed.tar.gz |
- Change the Time Wait of vtags value to match the cookie-life
- Select a tag gains ability to optionally save new tags
off in the timewait system.
- When looking up associations do not give back a stcb that
is in the about-to-be-freed state, and instead continue
looking for other candiates.
- New function to query to see if value is in time-wait.
- Timewait had a time comparison error that caused very
few vtags to actually stay in time-wait.
- When setting tags in time-wait, we now use the time
requested NOT a fixed constant value.
- sstat now gets the proper associd when we do the query.
- When we process an association, we expect the tag chosen
(if we have one from a cookie) to be in time-wait. Before
we would NOT allow the assoc up by checking if its good.
In theory this should have caused almost all assoc not
to come up except for the time-comparison bug above (this
bug was hidden by the time comparison bug :-D).
- Don't save tags for nonce values in the time-wait cache
since these are used only during cookie collisions and do
not matter if they are unique or not.
MFC after: 1 week
Diffstat (limited to 'sys/netinet/sctputil.c')
-rw-r--r-- | sys/netinet/sctputil.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index c1ffe81..2d76c4e 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -844,7 +844,7 @@ retry: } uint32_t -sctp_select_a_tag(struct sctp_inpcb *inp) +sctp_select_a_tag(struct sctp_inpcb *inp, int save_in_twait) { u_long x, not_done; struct timeval now; @@ -857,7 +857,7 @@ sctp_select_a_tag(struct sctp_inpcb *inp) /* we never use 0 */ continue; } - if (sctp_is_vtag_good(inp, x, &now)) { + if (sctp_is_vtag_good(inp, x, &now, save_in_twait)) { not_done = 0; } } @@ -908,19 +908,25 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb, struct timeval now; (void)SCTP_GETTIME_TIMEVAL(&now); - if (sctp_is_vtag_good(m, override_tag, &now)) { + if (sctp_is_in_timewait(override_tag)) { + /* + * It must be in the time-wait hash, we put it there + * when we aloc one. If not the peer is playing + * games. + */ asoc->my_vtag = override_tag; } else { SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM); + panic("Huh is_in_timewait fails"); return (ENOMEM); } } else { - asoc->my_vtag = sctp_select_a_tag(m); + asoc->my_vtag = sctp_select_a_tag(m, 1); } /* Get the nonce tags */ - asoc->my_vtag_nonce = sctp_select_a_tag(m); - asoc->peer_vtag_nonce = sctp_select_a_tag(m); + asoc->my_vtag_nonce = sctp_select_a_tag(m, 0); + asoc->peer_vtag_nonce = sctp_select_a_tag(m, 0); asoc->vrf_id = vrf_id; if (sctp_is_feature_on(m, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) |