summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctputil.c
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2007-05-28 11:17:24 +0000
committerrrs <rrs@FreeBSD.org>2007-05-28 11:17:24 +0000
commit953518c197f1cb83f3542e5632414645fa326689 (patch)
treed5292e14a920c4cac31f0eb379628b79f9c77442 /sys/netinet/sctputil.c
parentb4b7eeb094a1d9171e9bc849d768dd1b422dc540 (diff)
downloadFreeBSD-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.c46
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;
}
OpenPOWER on IntegriCloud