diff options
author | rrs <rrs@FreeBSD.org> | 2007-05-28 11:17:24 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2007-05-28 11:17:24 +0000 |
commit | 953518c197f1cb83f3542e5632414645fa326689 (patch) | |
tree | d5292e14a920c4cac31f0eb379628b79f9c77442 /sys/netinet/sctputil.c | |
parent | b4b7eeb094a1d9171e9bc849d768dd1b422dc540 (diff) | |
download | FreeBSD-src-953518c197f1cb83f3542e5632414645fa326689.zip FreeBSD-src-953518c197f1cb83f3542e5632414645fa326689.tar.gz |
- fixed autclose to not allow setting on 1-2-1 model.
- bounded cookie-life to 1 second minimum in socket option set.
- Delayed_ack_time becomes delayed_ack per new socket api document.
- Improve port number selection, we now use low/high bounds and
no chance of a endless loop. Only one call to random per bind
as well.
- fixes so set_peer_primary pre-screens addresses to be
valid to this host.
- maxseg did not allow setting on an assoc basis. We needed
to thus track and use an association value instead of a inp value.
- Fixed ep get of HB status to report back properly.
- use settings flag to tell if assoc level hb is on off not
the timer.. since the timer may still run if unconf address
are present.
- check for crazy ENABLE/DISABLE conditions.
- set and get of pmtud (fixed path mtu) not always taking into account ovh.
- Getting PMTU info on stcb only needs to return PMTUD_ENABLED if
any net is doing PMTU discovery.
- Panic or warning fixed to not do so when a valid ip frag is
taking place.
- sndrcvinfo appearing in both inp and stcb was full size, instead
of the non-pad version. This saves about 92 bytes from each struct
by carefully converting to use the smaller version.
- one-2-one model get(maxseg) would always get ep value, never the
tcb's value.
- The delayed ack time could be under a tick, this fixes so
it bounds it to at least 1 tick for platforms whos tick
is more than a ms.
- Fragment interleave level set to wrong default value.
- Fragment interleave could not set level 0.
- Defered stream reset was broken due to a guard check and ntohl issue.
- Found two lock order reversals and fixed.
- Tighten up address checking, if the user gives an address the sa_len
had better be set properly.
- Get asoc by assoc-id would return a locked tcb when it was asked
not to if the tcb was in the restart hash.
- sysctl to dig down and get more association details
Reviewed by: gnn
Diffstat (limited to 'sys/netinet/sctputil.c')
-rw-r--r-- | sys/netinet/sctputil.c | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index f3c685a..7558875 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -923,6 +923,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_association *asoc, asoc->heart_beat_delay = TICKS_TO_MSEC(m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]); asoc->cookie_life = m->sctp_ep.def_cookie_life; asoc->sctp_cmt_on_off = (uint8_t) sctp_cmt_on_off; + asoc->sctp_frag_point = m->sctp_frag_point; #ifdef INET asoc->default_tos = m->ip_inp.inp.inp_ip_tos; #else @@ -1453,6 +1454,11 @@ sctp_timeout_handler(void *t) /* call the handler for the appropriate timer type */ switch (tmr->type) { + case SCTP_TIMER_TYPE_ZERO_COPY: + if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE)) { + SCTP_ZERO_COPY_EVENT(inp, inp->sctp_socket); + } + break; case SCTP_TIMER_TYPE_ADDR_WQ: sctp_handle_addr_wq(); break; @@ -1770,6 +1776,10 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, SCTP_TCB_LOCK_ASSERT(stcb); } switch (t_type) { + case SCTP_TIMER_TYPE_ZERO_COPY: + tmr = &inp->sctp_ep.zero_copy_timer; + to_ticks = SCTP_ZERO_COPY_TICK_DELAY; + break; case SCTP_TIMER_TYPE_ADDR_WQ: /* Only 1 tick away :-) */ tmr = &sctppcbinfo.addr_wq_timer; @@ -2117,6 +2127,10 @@ sctp_timer_stop(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, SCTP_TCB_LOCK_ASSERT(stcb); } switch (t_type) { + case SCTP_TIMER_TYPE_ZERO_COPY: + tmr = &inp->sctp_ep.zero_copy_timer; + break; + case SCTP_TIMER_TYPE_ADDR_WQ: tmr = &sctppcbinfo.addr_wq_timer; break; @@ -5214,9 +5228,7 @@ get_more_data: copied_so_far += cp_len; } } - if ((out_flags & MSG_EOR) || - (uio->uio_resid == 0) - ) { + if ((out_flags & MSG_EOR) || (uio->uio_resid == 0)) { break; } if (((stcb) && (in_flags & MSG_PEEK) == 0) && @@ -5238,8 +5250,7 @@ get_more_data: * a MSG_EOR/or read all the user wants... <OR> * control->length == 0. */ - if ((out_flags & MSG_EOR) && - ((in_flags & MSG_PEEK) == 0)) { + if ((out_flags & MSG_EOR) && ((in_flags & MSG_PEEK) == 0)) { /* we are done with this control */ if (control->length == 0) { if (control->data) { @@ -5592,6 +5603,7 @@ sctp_dynamic_set_primary(struct sockaddr *sa, uint32_t vrf_id) /* Now incr the count and int wi structure */ SCTP_INCR_LADDR_COUNT(); bzero(wi, sizeof(*wi)); + (void)SCTP_GETTIME_TIMEVAL(&wi->start_time); wi->ifa = ifa; wi->action = SCTP_SET_PRIM_ADDR; atomic_add_int(&ifa->refcount, 1); @@ -5739,7 +5751,8 @@ sctp_l_soreceive(struct socket *so, int -sctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr, int totaddr, int *error) +sctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr, + int totaddr, int *error) { int added = 0; int i; @@ -5777,8 +5790,9 @@ out_now: } struct sctp_tcb * -sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr, int *totaddr, - int *num_v4, int *num_v6, int *error, int max) +sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr, + int *totaddr, int *num_v4, int *num_v6, int *error, + int limit, int *bad_addr) { struct sockaddr *sa; struct sctp_tcb *stcb = NULL; @@ -5792,6 +5806,11 @@ sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr, int *to if (sa->sa_family == AF_INET) { (*num_v4) += 1; incr = sizeof(struct sockaddr_in); + if (sa->sa_len != incr) { + *error = EINVAL; + *bad_addr = 1; + return (NULL); + } } else if (sa->sa_family == AF_INET6) { struct sockaddr_in6 *sin6; @@ -5799,21 +5818,30 @@ sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr, int *to if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { /* Must be non-mapped for connectx */ *error = EINVAL; + *bad_addr = 1; return (NULL); } (*num_v6) += 1; incr = sizeof(struct sockaddr_in6); + if (sa->sa_len != incr) { + *error = EINVAL; + *bad_addr = 1; + return (NULL); + } } else { *totaddr = i; /* we are done */ break; } + SCTP_INP_INCR_REF(inp); stcb = sctp_findassociation_ep_addr(&inp, sa, NULL, NULL, NULL); if (stcb != NULL) { /* Already have or am bring up an association */ return (stcb); + } else { + SCTP_INP_DECR_REF(inp); } - if ((at + incr) > max) { + if ((at + incr) > limit) { *totaddr = i; break; } |