Bug 855620: Update SCTP library to rev 8441 rs=me r=tuexen

This commit is contained in:
Randell Jesup 2013-03-31 21:09:25 -04:00
parent 807a3f1c2c
commit 93688dbf36
31 changed files with 1064 additions and 907 deletions

View File

@ -12,3 +12,4 @@ sctp updated to version 8176 from SVN on Wed Sep 5 18:02:08 EDT 2012
sctp updated to version 8263 from SVN on Sun Sep 16 00:48:48 EDT 2012
sctp updated to version 8279 from SVN on Thu Sep 20 18:19:24 EDT 2012
sctp updated to version 8397 from SVN on Wed Jan 9 00:41:16 EST 2013
sctp updated to version 8443 from SVN on Sun Mar 31 09:05:07 EDT 2013

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 235990 2012-05-25 11:14:08Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 246595 2013-02-09 17:26:14Z tuexen $");
#endif
#ifndef _NETINET_SCTP_H_
@ -514,11 +514,21 @@ struct sctp_error_unrecognized_chunk {
#define SCTP_PCB_FLAGS_SOCKET_GONE 0x10000000
#define SCTP_PCB_FLAGS_SOCKET_ALLGONE 0x20000000
#define SCTP_PCB_FLAGS_SOCKET_CANT_READ 0x40000000
#if defined(__Userspace__)
#define SCTP_PCB_FLAGS_BOUND_CONN 0x80000000
/* flags to copy to new PCB */
#define SCTP_PCB_COPY_FLAGS (SCTP_PCB_FLAGS_BOUNDALL|\
SCTP_PCB_FLAGS_WAKEINPUT|\
SCTP_PCB_FLAGS_BOUND_V6|\
SCTP_PCB_FLAGS_BOUND_CONN)
#else
/* flags to copy to new PCB */
#define SCTP_PCB_COPY_FLAGS (SCTP_PCB_FLAGS_BOUNDALL|\
SCTP_PCB_FLAGS_WAKEINPUT|\
SCTP_PCB_FLAGS_BOUND_V6)
#endif
/*
* PCB Features (in sctp_features bitmask)

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 243882 2012-12-05 08:04:20Z glebius $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 246595 2013-02-09 17:26:14Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -1933,7 +1933,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
return;
}
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
if (stcb->asoc.local_scope == 0) {
if (stcb->asoc.scope.local_scope == 0) {
return;
}
/* is it the right link local scope? */
@ -1941,7 +1941,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
return;
}
}
if (stcb->asoc.site_scope == 0 &&
if (stcb->asoc.scope.site_scope == 0 &&
IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
return;
}
@ -1965,7 +1965,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/* we skip unspecifed addresses */
return;
}
if (stcb->asoc.ipv4_local_scope == 0 &&
if (stcb->asoc.scope.ipv4_local_scope == 0 &&
IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
return;
}
@ -2124,7 +2124,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
continue;
}
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
if (stcb->asoc.local_scope == 0) {
if (stcb->asoc.scope.local_scope == 0) {
continue;
}
/* is it the right link local scope? */
@ -2153,7 +2153,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/* we skip unspecifed addresses */
continue;
}
if (stcb->asoc.ipv4_local_scope == 0 &&
if (stcb->asoc.scope.ipv4_local_scope == 0 &&
IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
continue;
}
@ -2215,13 +2215,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
} else {
/* Need to check scopes for this guy */
if (sctp_is_address_in_scope(ifa,
stcb->asoc.ipv4_addr_legal,
stcb->asoc.ipv6_addr_legal,
stcb->asoc.loopback_scope,
stcb->asoc.ipv4_local_scope,
stcb->asoc.local_scope,
stcb->asoc.site_scope,0) == 0) {
if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) {
continue;
}
}
@ -2455,7 +2449,7 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
return (NULL);
}
LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
if (stcb->asoc.loopback_scope == 0 &&
if (stcb->asoc.scope.loopback_scope == 0 &&
SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
/* Skip if loopback_scope not set */
continue;
@ -2464,7 +2458,7 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
switch (sctp_ifa->address.sa.sa_family) {
#ifdef INET
case AF_INET:
if (stcb->asoc.ipv4_addr_legal) {
if (stcb->asoc.scope.ipv4_addr_legal) {
struct sockaddr_in *sin;
sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
@ -2472,7 +2466,7 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
/* skip unspecifed addresses */
continue;
}
if (stcb->asoc.ipv4_local_scope == 0 &&
if (stcb->asoc.scope.ipv4_local_scope == 0 &&
IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))
continue;
@ -2488,7 +2482,7 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
#endif
#ifdef INET6
case AF_INET6:
if (stcb->asoc.ipv6_addr_legal) {
if (stcb->asoc.scope.ipv6_addr_legal) {
struct sockaddr_in6 *sin6;
if (sctp_ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
@ -2500,10 +2494,10 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
/* we skip unspecifed addresses */
continue;
}
if (stcb->asoc.local_scope == 0 &&
if (stcb->asoc.scope.local_scope == 0 &&
IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
continue;
if (stcb->asoc.site_scope == 0 &&
if (stcb->asoc.scope.site_scope == 0 &&
IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
continue;

View File

@ -49,13 +49,8 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 239035 2012-08-04 08:03:30Z
#include <netinet/sctp_sysctl.h>
#include <netinet/sctp_indata.h>
#if !defined(__Userspace_os_Windows)
#if defined(ANDROID)
#include <unistd.h>
#include <ifaddrs-android-ext.h>
#else
#include <sys/unistd.h>
#endif
#endif
/* Declare all of our malloc named types */
#ifndef __Panda__
@ -178,7 +173,7 @@ sctp_iterator_thread(void *v SCTP_UNUSED)
panic("Hmm. thread_terminate() continues...");
#endif
#if defined(__Userspace__)
return NULL;
return (NULL);
#endif
#endif
}
@ -371,12 +366,12 @@ sctp_init_ifns_for_vrf(int vrfid)
/* Enumerate through each returned adapter and save its information */
for (pAdapt = pAdapterAddrs; pAdapt; pAdapt = pAdapt->Next) {
if (pAdapt->IfType == IF_TYPE_IEEE80211 || pAdapt->IfType == IF_TYPE_ETHERNET_CSMACD) {
ifa = (struct ifaddrs*)malloc(sizeof(struct ifaddrs));
ifa->ifa_name = strdup(pAdapt->AdapterName);
ifa->ifa_flags = pAdapt->Flags;
ifa->ifa_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in));
if (pAdapt->FirstUnicastAddress) {
memcpy(ifa->ifa_addr, pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in));
for (pUnicast = pAdapt->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
ifa = (struct ifaddrs*)malloc(sizeof(struct ifaddrs));
ifa->ifa_name = strdup(pAdapt->AdapterName);
ifa->ifa_flags = pAdapt->Flags;
ifa->ifa_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in));
memcpy(ifa->ifa_addr, pUnicast->Address.lpSockaddr, sizeof(struct sockaddr_in));
sctp_ifa = sctp_add_addr_to_vrf(0,
ifa,
@ -386,7 +381,7 @@ sctp_init_ifns_for_vrf(int vrfid)
(void *)ifa,
ifa->ifa_addr,
ifa->ifa_flags,
0);
0);
if (sctp_ifa) {
sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
}
@ -397,53 +392,51 @@ sctp_init_ifns_for_vrf(int vrfid)
FREE(pAdapterAddrs);
#endif
#ifdef INET6
if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) {
AdapterAddrsSize = 0;
AdapterAddrsSize = 0;
if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, NULL, &AdapterAddrsSize)) != 0) {
if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) {
SCTP_PRINTF("GetAdaptersV6Addresses() sizing failed with error code %d\n", Err);
SCTP_PRINTF("err = %d; AdapterAddrsSize = %d\n", Err, AdapterAddrsSize);
return;
}
}
/* Allocate memory from sizing information */
if ((pAdapterAddrs6 = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) {
SCTP_PRINTF("Memory allocation error!\n");
if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, NULL, &AdapterAddrsSize)) != 0) {
if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) {
SCTP_PRINTF("GetAdaptersV6Addresses() sizing failed with error code %d\n", Err);
SCTP_PRINTF("err = %d; AdapterAddrsSize = %d\n", Err, AdapterAddrsSize);
return;
}
/* Get actual adapter information */
if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, pAdapterAddrs6, &AdapterAddrsSize)) != ERROR_SUCCESS) {
SCTP_PRINTF("GetAdaptersV6Addresses() failed with error code %d\n", Err);
return;
}
/* Enumerate through each returned adapter and save its information */
for (pAdapt = pAdapterAddrs6; pAdapt; pAdapt = pAdapt->Next) {
if (pAdapt->IfType == IF_TYPE_IEEE80211 || pAdapt->IfType == IF_TYPE_ETHERNET_CSMACD) {
for (pUnicast = pAdapt->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
ifa = (struct ifaddrs*)malloc(sizeof(struct ifaddrs));
ifa->ifa_name = strdup(pAdapt->AdapterName);
ifa->ifa_flags = pAdapt->Flags;
ifa->ifa_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in6));
memcpy(ifa->ifa_addr, pUnicast->Address.lpSockaddr, sizeof(struct sockaddr_in6));
sctp_ifa = sctp_add_addr_to_vrf(0,
ifa,
pAdapt->Ipv6IfIndex,
(pAdapt->IfType == IF_TYPE_IEEE80211)?MIB_IF_TYPE_ETHERNET:pAdapt->IfType,
ifa->ifa_name,
(void *)ifa,
ifa->ifa_addr,
ifa->ifa_flags,
0);
if (sctp_ifa) {
sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
}
}
/* Allocate memory from sizing information */
if ((pAdapterAddrs6 = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) {
SCTP_PRINTF("Memory allocation error!\n");
return;
}
/* Get actual adapter information */
if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, pAdapterAddrs6, &AdapterAddrsSize)) != ERROR_SUCCESS) {
SCTP_PRINTF("GetAdaptersV6Addresses() failed with error code %d\n", Err);
return;
}
/* Enumerate through each returned adapter and save its information */
for (pAdapt = pAdapterAddrs6; pAdapt; pAdapt = pAdapt->Next) {
if (pAdapt->IfType == IF_TYPE_IEEE80211 || pAdapt->IfType == IF_TYPE_ETHERNET_CSMACD) {
for (pUnicast = pAdapt->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
ifa = (struct ifaddrs*)malloc(sizeof(struct ifaddrs));
ifa->ifa_name = strdup(pAdapt->AdapterName);
ifa->ifa_flags = pAdapt->Flags;
ifa->ifa_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in6));
memcpy(ifa->ifa_addr, pUnicast->Address.lpSockaddr, sizeof(struct sockaddr_in6));
sctp_ifa = sctp_add_addr_to_vrf(0,
ifa,
pAdapt->Ipv6IfIndex,
(pAdapt->IfType == IF_TYPE_IEEE80211)?MIB_IF_TYPE_ETHERNET:pAdapt->IfType,
ifa->ifa_name,
(void *)ifa,
ifa->ifa_addr,
ifa->ifa_flags,
0);
if (sctp_ifa) {
sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
}
}
}
if (pAdapterAddrs6)
FREE(pAdapterAddrs6);
}
if (pAdapterAddrs6)
FREE(pAdapterAddrs6);
#endif
}
#elif defined(__Userspace__)

View File

@ -130,12 +130,11 @@ sctp_timeout(void *arg SCTP_UNUSED)
void (*c_func)(void *);
void *c_arg;
SCTP_TIMERQ_LOCK();
#if defined(__APPLE__)
/* update our tick count */
ticks += SCTP_BASE_VAR(sctp_main_timer_ticks);
#endif
SCTP_TIMERQ_LOCK();
c = TAILQ_FIRST(&SCTP_BASE_INFO(callqueue));
while (c) {
if (c->c_time <= ticks) {

View File

@ -579,7 +579,7 @@ sctp_crc32c_sb8_64_bit(uint32_t crc,
for (li = 0; li < end_bytes; li++)
crc = sctp_crc_tableil8_o32[(crc ^ *p_buf++) & 0x000000FF] ^
(crc >> 8);
return crc;
return (crc);
}

View File

@ -185,7 +185,11 @@ struct sctp_init {
} SCTP_PACKED;
#define SCTP_IDENTIFICATION_SIZE 16
#define SCTP_ADDRESS_SIZE 4
#if defined(__Userspace__)
#define SCTP_RESERVE_SPACE 5
#else
#define SCTP_RESERVE_SPACE 6
#endif
/* state cookie header */
struct sctp_state_cookie { /* this is our definition... */
uint8_t identification[SCTP_IDENTIFICATION_SIZE];/* id of who we are */
@ -207,6 +211,9 @@ struct sctp_state_cookie { /* this is our definition... */
uint16_t myport; /* my port address used in the INIT */
uint8_t ipv4_addr_legal;/* Are V4 addr legal? */
uint8_t ipv6_addr_legal;/* Are V6 addr legal? */
#if defined(__Userspace__)
uint8_t conn_addr_legal;
#endif
uint8_t local_scope; /* IPv6 local scope flag */
uint8_t site_scope; /* IPv6 site scope flag */

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 243882 2012-12-05 08:04:20Z glebius $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 246674 2013-02-11 13:57:03Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -4243,24 +4243,21 @@ again:
abort_out_now:
*abort_now = 1;
/* XXX */
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
0, M_NOWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
sizeof(uint32_t);
SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr);
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_24);
}
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_24;
sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
} else {
struct sctp_nets *netp;
if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
(SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
@ -4282,19 +4279,20 @@ again:
} else if ((SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED) &&
(asoc->stream_queue_cnt == 0)) {
struct sctp_nets *netp;
if (asoc->alternate) {
netp = asoc->alternate;
} else {
netp = asoc->primary_destination;
}
if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) {
goto abort_out_now;
}
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
sctp_send_shutdown_ack(stcb, netp);
sctp_stop_timers_for_shutdown(stcb);
if (asoc->alternate) {
netp = asoc->alternate;
} else {
netp = asoc->primary_destination;
}
sctp_send_shutdown_ack(stcb, netp);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK,
stcb->sctp_ep, stcb, netp);
}
@ -4998,30 +4996,22 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
abort_out_now:
*abort_now = 1;
/* XXX */
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
0, M_NOWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
sizeof(uint32_t);
SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr);
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_31);
}
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_31;
sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
return;
} else {
struct sctp_nets *netp;
if (asoc->alternate) {
netp = asoc->alternate;
} else {
netp = asoc->primary_destination;
}
if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
(SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
@ -5029,6 +5019,11 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
sctp_stop_timers_for_shutdown(stcb);
if (asoc->alternate) {
netp = asoc->alternate;
} else {
netp = asoc->primary_destination;
}
sctp_send_shutdown(stcb, netp);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
stcb->sctp_ep, stcb, netp);
@ -5039,19 +5034,20 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
} else if ((SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED) &&
(asoc->stream_queue_cnt == 0)) {
struct sctp_nets *netp;
if (asoc->alternate) {
netp = asoc->alternate;
} else {
netp = asoc->primary_destination;
}
if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) {
goto abort_out_now;
}
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
sctp_send_shutdown_ack(stcb, netp);
sctp_stop_timers_for_shutdown(stcb);
if (asoc->alternate) {
netp = asoc->alternate;
} else {
netp = asoc->primary_destination;
}
sctp_send_shutdown_ack(stcb, netp);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK,
stcb->sctp_ep, stcb, netp);
return;

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 243882 2012-12-05 08:04:20Z glebius $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 246595 2013-02-09 17:26:14Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -997,7 +997,6 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
} else {
/* no outstanding data to send, so move on... */
/* send SHUTDOWN-ACK */
sctp_send_shutdown_ack(stcb, net);
/* move to SHUTDOWN-ACK-SENT state */
if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
(SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
@ -1006,6 +1005,7 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
sctp_stop_timers_for_shutdown(stcb);
sctp_send_shutdown_ack(stcb, net);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK, stcb->sctp_ep,
stcb, net);
}
@ -2193,13 +2193,19 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
asoc = &stcb->asoc;
/* get scope variables out of cookie */
asoc->ipv4_local_scope = cookie->ipv4_scope;
asoc->site_scope = cookie->site_scope;
asoc->local_scope = cookie->local_scope;
asoc->loopback_scope = cookie->loopback_scope;
asoc->scope.ipv4_local_scope = cookie->ipv4_scope;
asoc->scope.site_scope = cookie->site_scope;
asoc->scope.local_scope = cookie->local_scope;
asoc->scope.loopback_scope = cookie->loopback_scope;
if ((asoc->ipv4_addr_legal != cookie->ipv4_addr_legal) ||
(asoc->ipv6_addr_legal != cookie->ipv6_addr_legal)) {
#if defined(__Userspace__)
if ((asoc->scope.ipv4_addr_legal != cookie->ipv4_addr_legal) ||
(asoc->scope.ipv6_addr_legal != cookie->ipv6_addr_legal) ||
(asoc->scope.conn_addr_legal != cookie->conn_addr_legal)) {
#else
if ((asoc->scope.ipv4_addr_legal != cookie->ipv4_addr_legal) ||
(asoc->scope.ipv6_addr_legal != cookie->ipv6_addr_legal)) {
#endif
struct mbuf *op_err;
/*
@ -5805,7 +5811,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
#endif
if (inp == NULL) {
SCTP_STAT_INCR(sctps_noport);
#if defined(__FreeBSD__) && __FreeBSD_version >= 900001
#if defined(__FreeBSD__) && (((__FreeBSD_version < 900000) && (__FreeBSD_version >= 804000)) || (__FreeBSD_version > 900000))
if (badport_bandlim(BANDLIM_SCTP_OOTB) < 0) {
goto out;
}

View File

@ -64,9 +64,11 @@ typedef struct
HANDLE events_[C_MAX_EVENTS];
} userland_cond_t;
#define InitializeConditionVariable(cond) InitializeXPConditionVariable(cond)
#define DeleteConditionVariable(cond) DeleteXPConditionVariable(cond)
#define SleepConditionVariableCS(cond, mtx, time) SleepXPConditionVariable(cond, mtx)
#define WakeAllConditionVariable(cond) WakeAllXPConditionVariable(cond)
#else
#define DeleteConditionVariable(cond)
typedef CONDITION_VARIABLE userland_cond_t;
#endif
typedef HANDLE userland_thread_t;
@ -381,7 +383,7 @@ struct udphdr {
#else /* !defined(Userspace_os_Windows) */
#include <sys/cdefs.h> /* needed? added from old __FreeBSD__ */
#include <sys/socket.h>
#if defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Linux) || defined(__Userspace_os_Android)
#if defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD)
#include <pthread.h>
#endif
typedef pthread_mutex_t userland_mutex_t;
@ -461,9 +463,7 @@ struct sx {int dummy;};
/* for getifaddrs */
#include <sys/types.h>
#if !defined(__Userspace_os_Windows)
#if !defined(ANDROID)
#include <ifaddrs.h>
#endif
/* for ioctl */
#include <sys/ioctl.h>
@ -498,7 +498,7 @@ struct sx {int dummy;};
#include <netinet/ip6.h>
#include <netinet/icmp6.h>
#endif
#if defined(__Userspace_os_Linux) || defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Windows)
#if defined(__Userspace_os_Linux) || defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) ||defined(__Userspace_os_Windows)
#include "user_ip6_var.h"
#else
#include <netinet6/ip6_var.h>
@ -1115,7 +1115,7 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int a
/* with the current included files, this is defined in Linux but
* in FreeBSD, it is behind a _KERNEL in sys/socket.h ...
*/
#if defined(__Userspace_os_FreeBSD)
#if defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD)
/* stolen from /usr/include/sys/socket.h */
#define CMSG_ALIGN(n) _ALIGN(n)
#elif defined(__Userspace_os_Darwin)

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 244033 2012-12-08 15:11:09Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 246687 2013-02-11 21:02:49Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -1890,15 +1890,10 @@ struct sack_track sack_array[256] = {
int
sctp_is_address_in_scope(struct sctp_ifa *ifa,
int ipv4_addr_legal,
int ipv6_addr_legal,
int loopback_scope,
int ipv4_local_scope,
int local_scope SCTP_UNUSED, /* XXX */
int site_scope,
int do_update)
struct sctp_scoping *scope,
int do_update)
{
if ((loopback_scope == 0) &&
if ((scope->loopback_scope == 0) &&
(ifa->ifn_p) && SCTP_IFN_IS_IFT_LOOP(ifa->ifn_p)) {
/*
* skip loopback if not in scope *
@ -1908,7 +1903,7 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa,
switch (ifa->address.sa.sa_family) {
#ifdef INET
case AF_INET:
if (ipv4_addr_legal) {
if (scope->ipv4_addr_legal) {
struct sockaddr_in *sin;
sin = (struct sockaddr_in *)&ifa->address.sin;
@ -1916,7 +1911,7 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa,
/* not in scope , unspecified */
return (0);
}
if ((ipv4_local_scope == 0) &&
if ((scope->ipv4_local_scope == 0) &&
(IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
/* private address not in scope */
return (0);
@ -1928,7 +1923,7 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa,
#endif
#ifdef INET6
case AF_INET6:
if (ipv6_addr_legal) {
if (scope->ipv6_addr_legal) {
struct sockaddr_in6 *sin6;
#if !defined(__Panda__)
@ -1952,7 +1947,7 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa,
(IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
return (0);
}
if ((site_scope == 0) &&
if ((scope->site_scope == 0) &&
(IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
return (0);
}
@ -1963,6 +1958,9 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa,
#endif
#if defined(__Userspace__)
case AF_CONN:
if (!scope->conn_addr_legal) {
return (0);
}
break;
#endif
default:
@ -2097,13 +2095,12 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if (sctp_is_addr_restricted(stcb, sctp_ifap)) {
continue;
}
if (sctp_is_address_in_scope(sctp_ifap,
scope->ipv4_addr_legal,
scope->ipv6_addr_legal,
scope->loopback_scope,
scope->ipv4_local_scope,
scope->local_scope,
scope->site_scope, 1) == 0) {
#if defined(__Userspace__)
if (sctp_ifap->address.sa.sa_family == AF_CONN) {
continue;
}
#endif
if (sctp_is_address_in_scope(sctp_ifap, scope, 1) == 0) {
continue;
}
cnt++;
@ -2132,13 +2129,13 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if (sctp_is_addr_restricted(stcb, sctp_ifap)) {
continue;
}
#if defined(__Userspace__)
if (sctp_ifap->address.sa.sa_family == AF_CONN) {
continue;
}
#endif
if (sctp_is_address_in_scope(sctp_ifap,
scope->ipv4_addr_legal,
scope->ipv6_addr_legal,
scope->loopback_scope,
scope->ipv4_local_scope,
scope->local_scope,
scope->site_scope, 0) == 0) {
scope, 0) == 0) {
continue;
}
if ((chunk_len != NULL) &&
@ -2185,13 +2182,13 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
*/
continue;
}
#if defined(__Userspace__)
if (laddr->ifa->address.sa.sa_family == AF_CONN) {
continue;
}
#endif
if (sctp_is_address_in_scope(laddr->ifa,
scope->ipv4_addr_legal,
scope->ipv6_addr_legal,
scope->loopback_scope,
scope->ipv4_local_scope,
scope->local_scope,
scope->site_scope, 1) == 0) {
scope, 1) == 0) {
continue;
}
cnt++;
@ -2210,13 +2207,13 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
continue;
}
#if defined(__Userspace__)
if (laddr->ifa->address.sa.sa_family == AF_CONN) {
continue;
}
#endif
if (sctp_is_address_in_scope(laddr->ifa,
scope->ipv4_addr_legal,
scope->ipv6_addr_legal,
scope->loopback_scope,
scope->ipv4_local_scope,
scope->local_scope,
scope->site_scope, 0) == 0) {
scope, 0) == 0) {
continue;
}
if ((chunk_len != NULL) &&
@ -2839,13 +2836,7 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn,
#endif
#endif
if (stcb) {
if (sctp_is_address_in_scope(ifa,
stcb->asoc.ipv4_addr_legal,
stcb->asoc.ipv6_addr_legal,
stcb->asoc.loopback_scope,
stcb->asoc.ipv4_local_scope,
stcb->asoc.local_scope,
stcb->asoc.site_scope, 0) == 0) {
if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) {
continue;
}
if (((non_asoc_addr_ok == 0) &&
@ -2891,13 +2882,7 @@ sctp_count_num_preferred_boundall(struct sctp_ifn *ifn,
continue;
}
if (stcb) {
if (sctp_is_address_in_scope(ifa,
stcb->asoc.ipv4_addr_legal,
stcb->asoc.ipv6_addr_legal,
stcb->asoc.loopback_scope,
stcb->asoc.ipv4_local_scope,
stcb->asoc.local_scope,
stcb->asoc.site_scope, 0) == 0) {
if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) {
continue;
}
if (((non_asoc_addr_ok == 0) &&
@ -3091,13 +3076,7 @@ again_with_private_addresses_allowed:
continue;
}
if (stcb) {
if (sctp_is_address_in_scope(sifa,
stcb->asoc.ipv4_addr_legal,
stcb->asoc.ipv6_addr_legal,
stcb->asoc.loopback_scope,
stcb->asoc.ipv4_local_scope,
stcb->asoc.local_scope,
stcb->asoc.site_scope, 0) == 0) {
if (sctp_is_address_in_scope(sifa, &stcb->asoc.scope, 0) == 0) {
SCTPDBG(SCTP_DEBUG_OUTPUT2, "NOT in scope\n");
sifa = NULL;
continue;
@ -3144,13 +3123,7 @@ again_with_private_addresses_allowed:
if (sifa == NULL)
continue;
if (stcb) {
if (sctp_is_address_in_scope(sifa,
stcb->asoc.ipv4_addr_legal,
stcb->asoc.ipv6_addr_legal,
stcb->asoc.loopback_scope,
stcb->asoc.ipv4_local_scope,
stcb->asoc.local_scope,
stcb->asoc.site_scope, 0) == 0) {
if (sctp_is_address_in_scope(sifa, &stcb->asoc.scope, 0) == 0) {
sifa = NULL;
continue;
}
@ -3171,12 +3144,12 @@ again_with_private_addresses_allowed:
}
}
#ifdef INET
if ((retried == 0) && (stcb->asoc.ipv4_local_scope == 0)) {
stcb->asoc.ipv4_local_scope = 1;
if ((retried == 0) && (stcb->asoc.scope.ipv4_local_scope == 0)) {
stcb->asoc.scope.ipv4_local_scope = 1;
retried = 1;
goto again_with_private_addresses_allowed;
} else if (retried == 1) {
stcb->asoc.ipv4_local_scope = 0;
stcb->asoc.scope.ipv4_local_scope = 0;
}
#endif
out:
@ -3205,12 +3178,7 @@ out:
}
if (stcb) {
if (sctp_is_address_in_scope(tmp_sifa,
stcb->asoc.ipv4_addr_legal,
stcb->asoc.ipv6_addr_legal,
stcb->asoc.loopback_scope,
stcb->asoc.ipv4_local_scope,
stcb->asoc.local_scope,
stcb->asoc.site_scope, 0) == 0) {
&stcb->asoc.scope, 0) == 0) {
continue;
}
if (((non_asoc_addr_ok == 0) &&
@ -4268,7 +4236,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
SCTP_STAT_INCR(sctps_sendhwcrc);
#else
if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
(stcb) && (stcb->asoc.loopback_scope))) {
(stcb) && (stcb->asoc.scope.loopback_scope))) {
sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip));
SCTP_STAT_INCR(sctps_sendswcrc);
} else {
@ -4702,6 +4670,10 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
SCTP_STAT_INCR(sctps_sendnocrc);
#else
#if defined(__FreeBSD__) && __FreeBSD_version >= 800000
#if __FreeBSD_version < 900000
sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip6_hdr));
SCTP_STAT_INCR(sctps_sendswcrc);
#else
#if __FreeBSD_version > 901000
m->m_pkthdr.csum_flags = CSUM_SCTP_IPV6;
#else
@ -4709,9 +4681,10 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
#endif
m->m_pkthdr.csum_data = 0;
SCTP_STAT_INCR(sctps_sendhwcrc);
#endif
#else
if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
(stcb) && (stcb->asoc.loopback_scope))) {
(stcb) && (stcb->asoc.scope.loopback_scope))) {
sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip6_hdr));
SCTP_STAT_INCR(sctps_sendswcrc);
} else {
@ -4870,7 +4843,6 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
#endif
)
{
struct sctp_scoping scp;
struct mbuf *m;
struct sctp_nets *net;
struct sctp_init_chunk *init;
@ -4955,50 +4927,44 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
init->init.num_inbound_streams = htons(stcb->asoc.max_inbound_streams);
init->init.initial_tsn = htonl(stcb->asoc.init_seq_number);
#if defined(INET) || defined(INET6)
/* now the address restriction */
/* XXX Should we take the address family of the socket into account? */
sup_addr = (struct sctp_supported_addr_param *)(mtod(m, caddr_t) + chunk_len);
sup_addr->ph.param_type = htons(SCTP_SUPPORTED_ADDRTYPE);
#ifdef INET6
#ifdef INET
/* we support 2 types: IPv4/IPv6 */
parameter_len = (uint16_t)(sizeof(struct sctp_paramhdr) + 2 * sizeof(uint16_t));
sup_addr->ph.param_length = htons(parameter_len);
sup_addr->addr_type[0] = htons(SCTP_IPV4_ADDRESS);
sup_addr->addr_type[1] = htons(SCTP_IPV6_ADDRESS);
padding_len = 0;
#else
/* we support 1 type: IPv6 */
parameter_len = (uint16_t)(sizeof(struct sctp_paramhdr) + sizeof(uint16_t));
sup_addr->ph.param_length = htons(parameter_len);
sup_addr->addr_type[0] = htons(SCTP_IPV6_ADDRESS);
sup_addr->addr_type[1] = htons(0); /* this is the padding */
padding_len = (uint16_t)sizeof(uint16_t);
#endif
#else
/* we support 1 type: IPv4 */
parameter_len = (uint16_t)(sizeof(struct sctp_paramhdr) + sizeof(uint16_t));
sup_addr->ph.param_length = htons(parameter_len);
sup_addr->addr_type[0] = htons(SCTP_IPV4_ADDRESS);
sup_addr->addr_type[1] = htons(0); /* this is the padding */
padding_len = (uint16_t)sizeof(uint16_t);
#endif
chunk_len += parameter_len;
#endif
/* Adaptation layer indication parameter */
/* XXX: Should we include this always? */
if (padding_len > 0) {
memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
chunk_len += padding_len;
padding_len = 0;
if (stcb->asoc.scope.ipv4_addr_legal || stcb->asoc.scope.ipv6_addr_legal) {
uint8_t i;
parameter_len = (uint16_t)sizeof(struct sctp_paramhdr);
if (stcb->asoc.scope.ipv4_addr_legal) {
parameter_len += (uint16_t)sizeof(uint16_t);
}
if (stcb->asoc.scope.ipv6_addr_legal) {
parameter_len += (uint16_t)sizeof(uint16_t);
}
sup_addr = (struct sctp_supported_addr_param *)(mtod(m, caddr_t) + chunk_len);
sup_addr->ph.param_type = htons(SCTP_SUPPORTED_ADDRTYPE);
sup_addr->ph.param_length = htons(parameter_len);
i = 0;
if (stcb->asoc.scope.ipv4_addr_legal) {
sup_addr->addr_type[i++] = htons(SCTP_IPV4_ADDRESS);
}
if (stcb->asoc.scope.ipv6_addr_legal) {
sup_addr->addr_type[i++] = htons(SCTP_IPV6_ADDRESS);
}
padding_len = 4 - 2 * i;
chunk_len += parameter_len;
}
/* Adaptation layer indication parameter */
if (inp->sctp_ep.adaptation_layer_indicator_provided) {
if (padding_len > 0) {
memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
chunk_len += padding_len;
padding_len = 0;
}
parameter_len = (uint16_t)sizeof(struct sctp_adaptation_layer_indication);
ali = (struct sctp_adaptation_layer_indication *)(mtod(m, caddr_t) + chunk_len);
ali->ph.param_type = htons(SCTP_ULP_ADAPTATION);
ali->ph.param_length = htons(parameter_len);
ali->indication = ntohl(inp->sctp_ep.adaptation_layer_indicator);
chunk_len += parameter_len;
}
parameter_len = (uint16_t)sizeof(struct sctp_adaptation_layer_indication);
ali = (struct sctp_adaptation_layer_indication *)(mtod(m, caddr_t) + chunk_len);
ali->ph.param_type = htons(SCTP_ULP_ADAPTATION);
ali->ph.param_length = htons(parameter_len);
ali->indication = ntohl(inp->sctp_ep.adaptation_layer_indicator);
chunk_len += parameter_len;
if (SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly)) {
/* Add NAT friendly parameter. */
@ -5143,13 +5109,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
* address within the stcb. But for now this is a quick
* hack to get the address stuff teased apart.
*/
scp.ipv4_addr_legal = stcb->asoc.ipv4_addr_legal;
scp.ipv6_addr_legal = stcb->asoc.ipv6_addr_legal;
scp.loopback_scope = stcb->asoc.loopback_scope;
scp.ipv4_local_scope = stcb->asoc.ipv4_local_scope;
scp.local_scope = stcb->asoc.local_scope;
scp.site_scope = stcb->asoc.site_scope;
sctp_add_addresses_to_i_ia(inp, stcb, &scp, m, cnt_inits_to, &padding_len, &chunk_len);
sctp_add_addresses_to_i_ia(inp, stcb, &stcb->asoc.scope, m, cnt_inits_to, &padding_len, &chunk_len);
init->ch.chunk_length = htons(chunk_len);
if (padding_len > 0) {
@ -5797,24 +5757,29 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
*/
stc.site_scope = stc.local_scope = stc.loopback_scope = 0;
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
struct inpcb *in_inp;
/* Its a V6 socket */
in_inp = (struct inpcb *)inp;
stc.ipv6_addr_legal = 1;
/* Now look at the binding flag to see if V4 will be legal */
if (SCTP_IPV6_V6ONLY(in_inp) == 0) {
stc.ipv4_addr_legal = 1;
} else {
/* V4 addresses are NOT legal on the association */
if (SCTP_IPV6_V6ONLY(inp)) {
stc.ipv4_addr_legal = 0;
} else {
stc.ipv4_addr_legal = 1;
}
#if defined(__Userspace__)
stc.conn_addr_legal = 0;
#endif
} else {
/* Its a V4 socket, no - V6 */
stc.ipv4_addr_legal = 1;
stc.ipv6_addr_legal = 0;
#if defined(__Userspace__)
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) {
stc.conn_addr_legal = 1;
stc.ipv4_addr_legal = 0;
} else {
stc.conn_addr_legal = 0;
stc.ipv4_addr_legal = 1;
}
#else
stc.ipv4_addr_legal = 1;
#endif
}
#ifdef SCTP_DONT_DO_PRIVADDR_SCOPE
stc.ipv4_scope = 1;
#else
@ -5862,7 +5827,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
{
stc.addr_type = SCTP_IPV6_ADDRESS;
memcpy(&stc.address, &src6->sin6_addr, sizeof(struct in6_addr));
#if defined(__FreeBSD__) && __FreeBSD_version > 900000
#if defined(__FreeBSD__) && (((__FreeBSD_version < 900000) && (__FreeBSD_version >= 804000)) || (__FreeBSD_version > 900000))
stc.scope_id = in6_getscope(&src6->sin6_addr);
#else
stc.scope_id = 0;
@ -5932,7 +5897,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
#endif
default:
/* TSNH */
goto do_a_abort;
goto do_a_abort;
break;
}
} else {
@ -5942,10 +5907,10 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct sctp_nets *lnet;
#endif
stc.loopback_scope = asoc->loopback_scope;
stc.ipv4_scope = asoc->ipv4_local_scope;
stc.site_scope = asoc->site_scope;
stc.local_scope = asoc->local_scope;
stc.loopback_scope = asoc->scope.loopback_scope;
stc.ipv4_scope = asoc->scope.ipv4_local_scope;
stc.site_scope = asoc->scope.site_scope;
stc.local_scope = asoc->scope.local_scope;
#ifdef INET6
/* Why do we not consider IPv4 LL addresses? */
TAILQ_FOREACH(lnet, &asoc->nets, sctp_next) {
@ -6122,12 +6087,16 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
htons(inp->sctp_ep.max_open_streams_intome);
/* adaptation layer indication parameter */
ali = (struct sctp_adaptation_layer_indication *)((caddr_t)initack + sizeof(*initack));
ali->ph.param_type = htons(SCTP_ULP_ADAPTATION);
ali->ph.param_length = htons(sizeof(*ali));
ali->indication = ntohl(inp->sctp_ep.adaptation_layer_indicator);
SCTP_BUF_LEN(m) += sizeof(*ali);
ecn = (struct sctp_ecn_supported_param *)((caddr_t)ali + sizeof(*ali));
if (inp->sctp_ep.adaptation_layer_indicator_provided) {
ali = (struct sctp_adaptation_layer_indication *)((caddr_t)initack + sizeof(*initack));
ali->ph.param_type = htons(SCTP_ULP_ADAPTATION);
ali->ph.param_length = htons(sizeof(*ali));
ali->indication = ntohl(inp->sctp_ep.adaptation_layer_indicator);
SCTP_BUF_LEN(m) += sizeof(*ali);
ecn = (struct sctp_ecn_supported_param *)((caddr_t)ali + sizeof(*ali));
} else {
ecn = (struct sctp_ecn_supported_param *)((caddr_t)initack + sizeof(*initack));
}
/* ECN parameter */
if (((asoc != NULL) && (asoc->ecn_allowed == 1)) ||
@ -6227,6 +6196,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
*/
scp.ipv4_addr_legal = stc.ipv4_addr_legal;
scp.ipv6_addr_legal = stc.ipv6_addr_legal;
#if defined(__Userspace__)
scp.conn_addr_legal = stc.conn_addr_legal;
#endif
scp.loopback_scope = stc.loopback_scope;
scp.ipv4_local_scope = stc.ipv4_scope;
scp.local_scope = stc.local_scope;
@ -6838,7 +6810,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
if (m) {
ph = mtod(m, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
ph->param_length = htons(ca->sndlen);
ph->param_length = htons(sizeof(struct sctp_paramhdr) + ca->sndlen);
}
/* We add one here to keep the assoc from
* dis-appearing on us.
@ -6882,12 +6854,13 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
(SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
(SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
/* only send SHUTDOWN the first time through */
sctp_send_shutdown(stcb, net);
if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
sctp_stop_timers_for_shutdown(stcb);
sctp_send_shutdown(stcb, net);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb,
net);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb,
@ -11562,7 +11535,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
#if defined(SCTP_WITH_NO_CSUM)
SCTP_STAT_INCR(sctps_sendnocrc);
#else
#if defined(__FreeBSD__) && __FreeBSD_version >= 800000
#if defined(__FreeBSD__) && __FreeBSD_version >= 900000
#if __FreeBSD_version > 901000
mout->m_pkthdr.csum_flags = CSUM_SCTP_IPV6;
#else
@ -13413,10 +13386,11 @@ sctp_lower_sosend(struct socket *so,
}
if (mm) {
struct sctp_paramhdr *ph;
/* now move forward the data pointer */
ph = mtod(mm, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
ph->param_length = htons((sizeof(struct sctp_paramhdr) + tot_out));
ph->param_length = htons(sizeof(struct sctp_paramhdr) + tot_out);
ph++;
SCTP_BUF_LEN(mm) = tot_out + sizeof(struct sctp_paramhdr);
if (top == NULL) {
@ -14010,18 +13984,19 @@ dataless_eof:
(SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
struct sctp_nets *netp;
if (stcb->asoc.alternate) {
netp = stcb->asoc.alternate;
} else {
netp = stcb->asoc.primary_destination;
}
/* only send SHUTDOWN the first time through */
sctp_send_shutdown(stcb, netp);
if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
sctp_stop_timers_for_shutdown(stcb);
if (stcb->asoc.alternate) {
netp = stcb->asoc.alternate;
} else {
netp = stcb->asoc.primary_destination;
}
sctp_send_shutdown(stcb, netp);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb,
netp);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb,

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.h 244021 2012-12-08 08:22:33Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.h 246595 2013-02-09 17:26:14Z tuexen $");
#endif
#ifndef _NETINET_SCTP_OUTPUT_H_
@ -57,13 +57,9 @@ int sctp_is_addr_restricted(struct sctp_tcb *, struct sctp_ifa *);
int
sctp_is_address_in_scope(struct sctp_ifa *ifa,
int ipv4_addr_legal,
int ipv6_addr_legal,
int loopback_scope,
int ipv4_local_scope,
int local_scope,
int site_scope,
struct sctp_scoping *scope,
int do_update);
int
sctp_is_addr_in_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa);

File diff suppressed because it is too large Load Diff

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 243186 2012-11-17 20:04:04Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 246687 2013-02-11 21:02:49Z tuexen $");
#endif
#ifndef _NETINET_SCTP_PCB_H_
@ -404,6 +404,7 @@ struct sctp_pcb {
int auto_close_time;
uint32_t initial_sequence_debug;
uint32_t adaptation_layer_indicator;
uint8_t adaptation_layer_indicator_provided;
uint32_t store_at;
uint32_t max_burst;
uint32_t fr_max_burst;

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 242714 2012-11-07 22:11:38Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 246595 2013-02-09 17:26:14Z tuexen $");
#endif
#ifndef _NETINET_SCTP_STRUCTS_H_
@ -653,6 +653,9 @@ struct sctp_asconf_addr {
struct sctp_scoping {
uint8_t ipv4_addr_legal;
uint8_t ipv6_addr_legal;
#if defined(__Userspace__)
uint8_t conn_addr_legal;
#endif
uint8_t loopback_scope;
uint8_t ipv4_local_scope;
uint8_t local_scope;
@ -1221,17 +1224,7 @@ struct sctp_association {
*/
uint8_t peer_supports_pktdrop;
/* Do we allow V6/V4? */
uint8_t ipv4_addr_legal;
uint8_t ipv6_addr_legal;
/* Address scoping flags */
/* scope value for IPv4 */
uint8_t ipv4_local_scope;
/* scope values for IPv6 */
uint8_t local_scope;
uint8_t site_scope;
/* loopback scope */
uint8_t loopback_scope;
struct sctp_scoping scope;
/* flags to handle send alternate net tracking */
uint8_t used_alt_onsack;
uint8_t used_alt_asconfack;

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 243186 2012-11-17 20:04:04Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 246595 2013-02-09 17:26:14Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -225,6 +225,9 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s
struct sctp_ifa *sctp_ifa;
int loopback_scope, ipv4_local_scope, local_scope, site_scope;
int ipv4_addr_legal, ipv6_addr_legal;
#if defined(__Userspace__)
int conn_addr_legal;
#endif
struct sctp_vrf *vrf;
struct xsctp_laddr xladdr;
struct sctp_laddr *laddr;
@ -233,29 +236,45 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s
/* Turn on all the appropriate scope */
if (stcb) {
/* use association specific values */
loopback_scope = stcb->asoc.loopback_scope;
ipv4_local_scope = stcb->asoc.ipv4_local_scope;
local_scope = stcb->asoc.local_scope;
site_scope = stcb->asoc.site_scope;
loopback_scope = stcb->asoc.scope.loopback_scope;
ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
local_scope = stcb->asoc.scope.local_scope;
site_scope = stcb->asoc.scope.site_scope;
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
#if defined(__Userspace__)
conn_addr_legal = stcb->asoc.scope.conn_addr_legal;
#endif
} else {
/* use generic values for endpoints */
/* Use generic values for endpoints. */
loopback_scope = 1;
ipv4_local_scope = 1;
local_scope = 1;
site_scope = 1;
}
/* use only address families of interest */
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
ipv6_addr_legal = 1;
if (SCTP_IPV6_V6ONLY(inp)) {
ipv4_addr_legal = 0;
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
ipv6_addr_legal = 1;
if (SCTP_IPV6_V6ONLY(inp)) {
ipv4_addr_legal = 0;
} else {
ipv4_addr_legal = 1;
}
#if defined(__Userspace__)
conn_addr_legal = 0;
#endif
} else {
ipv6_addr_legal = 0;
#if defined(__Userspace__)
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) {
conn_addr_legal = 1;
ipv4_addr_legal = 0;
} else {
conn_addr_legal = 0;
ipv4_addr_legal = 1;
}
#else
ipv4_addr_legal = 1;
#endif
}
} else {
ipv4_addr_legal = 1;
ipv6_addr_legal = 0;
}
/* neither Mac OS X nor FreeBSD support mulitple routing functions */
@ -330,6 +349,13 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s
continue;
}
break;
#endif
#if defined(__Userspace__)
case AF_CONN:
if (!conn_addr_legal) {
continue;
}
break;
#endif
default:
continue;

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 243882 2012-12-05 08:04:20Z glebius $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 246588 2013-02-09 08:27:08Z tuexen $");
#endif
#define _IP_VHL
@ -1581,18 +1581,20 @@ sctp_autoclose_timer(struct sctp_inpcb *inp,
if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) {
/* only send SHUTDOWN 1st time thru */
struct sctp_nets *netp;
if (stcb->asoc.alternate) {
netp = stcb->asoc.alternate;
} else {
netp = stcb->asoc.primary_destination;
}
sctp_send_shutdown(stcb, netp);
if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
(SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
sctp_stop_timers_for_shutdown(stcb);
if (stcb->asoc.alternate) {
netp = stcb->asoc.alternate;
} else {
netp = stcb->asoc.primary_destination;
}
sctp_send_shutdown(stcb, netp);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
stcb->sctp_ep, stcb,
netp);

View File

@ -332,6 +332,14 @@ InitializeXPConditionVariable(userland_cond_t *cv)
cv->events_[C_BROADCAST] = CreateEvent (NULL, TRUE, FALSE, NULL);
}
void
DeleteXPConditionVariable(userland_cond_t *cv)
{
CloseHandle(cv->events_[C_BROADCAST]);
CloseHandle(cv->events_[C_SIGNAL]);
DeleteCriticalSection(&(cv->waiters_count_lock));
}
int
SleepXPConditionVariable(userland_cond_t *cv, userland_mutex_t *mtx)
{

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 244730 2012-12-27 08:10:58Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 246687 2013-02-11 21:02:49Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -846,6 +846,7 @@ sctpconn_attach(struct socket *so, int proto SCTP_UNUSED, uint32_t vrf_id)
inp = (struct sctp_inpcb *)so->so_pcb;
SCTP_INP_WLOCK(inp);
inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUND_V6;
inp->sctp_flags |= SCTP_PCB_FLAGS_BOUND_CONN;
ip_inp = &inp->ip_inp.inp;
ip_inp->inp_vflag |= INP_CONN;
ip_inp->inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
@ -1209,25 +1210,25 @@ sctp_disconnect(struct socket *so)
(SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
/* only send SHUTDOWN 1st time thru */
struct sctp_nets *netp;
if (stcb->asoc.alternate) {
netp = stcb->asoc.alternate;
} else {
netp = stcb->asoc.primary_destination;
}
sctp_stop_timers_for_shutdown(stcb);
sctp_send_shutdown(stcb,netp);
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
(SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
sctp_stop_timers_for_shutdown(stcb);
if (stcb->asoc.alternate) {
netp = stcb->asoc.alternate;
} else {
netp = stcb->asoc.primary_destination;
}
sctp_send_shutdown(stcb,netp);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
stcb->sctp_ep, stcb, netp);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
stcb->sctp_ep, stcb, netp);
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
}
} else {
/*
@ -1267,22 +1268,16 @@ sctp_disconnect(struct socket *so)
(asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
struct mbuf *op_err;
abort_anyway:
op_err = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
0, M_NOWAIT, 1, MT_DATA);
if (op_err) {
/* Fill in the user initiated abort */
struct sctp_paramhdr *ph;
uint32_t *ippp;
SCTP_BUF_LEN(op_err) =
(sizeof(struct sctp_paramhdr) + sizeof(uint32_t));
ph = mtod(op_err,
struct sctp_paramhdr *);
ph->param_type = htons(
SCTP_CAUSE_USER_INITIATED_ABT);
SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
ph = mtod(op_err, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
ph->param_length = htons(SCTP_BUF_LEN(op_err));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_USRREQ+SCTP_LOC_4);
}
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ+SCTP_LOC_4;
sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED);
@ -1427,24 +1422,25 @@ sctp_shutdown(struct socket *so)
if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) {
/* only send SHUTDOWN the first time through */
struct sctp_nets *netp;
if (stcb->asoc.alternate) {
netp = stcb->asoc.alternate;
} else {
netp = stcb->asoc.primary_destination;
}
sctp_stop_timers_for_shutdown(stcb);
sctp_send_shutdown(stcb, netp);
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
(SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
sctp_stop_timers_for_shutdown(stcb);
if (stcb->asoc.alternate) {
netp = stcb->asoc.alternate;
} else {
netp = stcb->asoc.primary_destination;
}
sctp_send_shutdown(stcb, netp);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
stcb->sctp_ep, stcb, netp);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
stcb->sctp_ep, stcb, netp);
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
}
} else {
/*
@ -1480,22 +1476,16 @@ sctp_shutdown(struct socket *so)
(asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
struct mbuf *op_err;
abort_anyway:
op_err = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
0, M_NOWAIT, 1, MT_DATA);
if (op_err) {
/* Fill in the user initiated abort */
struct sctp_paramhdr *ph;
uint32_t *ippp;
SCTP_BUF_LEN(op_err) =
sizeof(struct sctp_paramhdr) + sizeof(uint32_t);
ph = mtod(op_err,
struct sctp_paramhdr *);
ph->param_type = htons(
SCTP_CAUSE_USER_INITIATED_ABT);
SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
ph = mtod(op_err, struct sctp_paramhdr *);
ph->param_type = htons( SCTP_CAUSE_USER_INITIATED_ABT);
ph->param_length = htons(SCTP_BUF_LEN(op_err));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_USRREQ+SCTP_LOC_6);
}
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ+SCTP_LOC_6;
sctp_abort_an_association(stcb->sctp_ep, stcb,
@ -1530,10 +1520,25 @@ sctp_fill_user_address(struct sockaddr_storage *ss, struct sockaddr *sa)
#ifdef HAVE_SA_LEN
memcpy(ss, sa, sa->sa_len);
#else
if (sa->sa_family == AF_INET) {
switch (sa->sa_family) {
#ifdef INET
case AF_INET:
memcpy(ss, sa, sizeof(struct sockaddr_in));
} else {
break;
#endif
#ifdef INET6
case AF_INET6:
memcpy(ss, sa, sizeof(struct sockaddr_in6));
break;
#endif
#if defined(__Userspace__)
case AF_CONN:
memcpy(ss, sa, sizeof(struct sockaddr_conn));
break;
#endif
default:
/* TSNH */
break;
}
#endif
return (0);
@ -1556,6 +1561,9 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
int loopback_scope, ipv4_local_scope, local_scope, site_scope;
size_t actual;
int ipv4_addr_legal, ipv6_addr_legal;
#if defined(__Userspace__)
int conn_addr_legal;
#endif
struct sctp_vrf *vrf;
actual = 0;
@ -1564,23 +1572,45 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
if (stcb) {
/* Turn on all the appropriate scope */
loopback_scope = stcb->asoc.loopback_scope;
ipv4_local_scope = stcb->asoc.ipv4_local_scope;
local_scope = stcb->asoc.local_scope;
site_scope = stcb->asoc.site_scope;
loopback_scope = stcb->asoc.scope.loopback_scope;
ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
local_scope = stcb->asoc.scope.local_scope;
site_scope = stcb->asoc.scope.site_scope;
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
#if defined(__Userspace__)
conn_addr_legal = stcb->asoc.scope.conn_addr_legal;
#endif
} else {
/* Turn on ALL scope, since we look at the EP */
loopback_scope = ipv4_local_scope = local_scope =
site_scope = 1;
}
ipv4_addr_legal = ipv6_addr_legal = 0;
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
ipv6_addr_legal = 1;
if (SCTP_IPV6_V6ONLY(inp) == 0) {
/* Use generic values for endpoints. */
loopback_scope = 1;
ipv4_local_scope = 1;
local_scope = 1;
site_scope = 1;
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
ipv6_addr_legal = 1;
if (SCTP_IPV6_V6ONLY(inp)) {
ipv4_addr_legal = 0;
} else {
ipv4_addr_legal = 1;
}
#if defined(__Userspace__)
conn_addr_legal = 0;
#endif
} else {
ipv6_addr_legal = 0;
#if defined(__Userspace__)
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) {
conn_addr_legal = 1;
ipv4_addr_legal = 0;
} else {
conn_addr_legal = 0;
ipv4_addr_legal = 1;
}
#else
ipv4_addr_legal = 1;
#endif
}
} else {
ipv4_addr_legal = 1;
}
vrf = sctp_find_vrf(vrf_id);
if (vrf == NULL) {
@ -1699,7 +1729,7 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
continue;
}
memcpy(sas, sin6, sizeof(*sin6));
((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin6));
actual += sizeof(*sin6);
if (actual >= limit) {
@ -1709,6 +1739,20 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
continue;
}
break;
#endif
#if defined(__Userspace__)
case AF_CONN:
if (conn_addr_legal) {
memcpy(sas, &sctp_ifa->address.sconn, sizeof(struct sockaddr_conn));
((struct sockaddr_conn *)sas)->sconn_port = inp->sctp_lport;
sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_conn));
actual += sizeof(struct sockaddr_conn);
if (actual >= limit) {
return (actual);
}
} else {
continue;
}
#endif
default:
/* TSNH */
@ -1721,6 +1765,7 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
#ifndef HAVE_SA_LEN
uint32_t sa_len = 0;
#endif
LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
if (stcb) {
if (sctp_is_addr_restricted(stcb, laddr->ifa)) {
@ -1729,20 +1774,51 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
}
if (sctp_fill_user_address(sas, &laddr->ifa->address.sa))
continue;
#ifndef HAVE_SA_LEN
if (laddr->ifa->address.sa.sa_family == AF_INET) {
sa_len = sizeof(struct sockaddr_in);
} else {
sa_len = sizeof(struct sockaddr_in6);
}
switch (laddr->ifa->address.sa.sa_family) {
#ifdef INET
case AF_INET:
((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport;
break;
#endif
((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
#ifdef INET6
case AF_INET6:
((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
break;
#endif
#if defined(__Userspace__)
case AF_CONN:
((struct sockaddr_conn *)sas)->sconn_port = inp->sctp_lport;
break;
#endif
default:
/* TSNH */
break;
}
#ifdef HAVE_SA_LEN
sas = (struct sockaddr_storage *)((caddr_t)sas +
laddr->ifa->address.sa.sa_len);
actual += laddr->ifa->address.sa.sa_len;
#else
switch (laddr->ifa->address.sa.sa_family) {
#ifdef INET
case AF_INET:
sa_len = sizeof(struct sockaddr_in);
break;
#endif
#ifdef INET6
case AF_INET6:
sa_len = sizeof(struct sockaddr_in6);
break;
#endif
#if defined(__Userspace__)
case AF_CONN:
sa_len = sizeof(struct sockaddr_conn);
break;
#endif
default:
/* TSNH */
break;
}
sas = (struct sockaddr_storage *)((caddr_t)sas + sa_len);
actual += sa_len;
#endif
@ -1826,6 +1902,11 @@ sctp_count_max_addresses_vrf(struct sctp_inpcb *inp, uint32_t vrf_id)
case AF_INET6:
cnt += sizeof(struct sockaddr_in6);
break;
#endif
#if defined(__Userspace__)
case AF_CONN:
cnt += sizeof(struct sockaddr_conn);
break;
#endif
default:
break;
@ -5320,6 +5401,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
SCTP_CHECK_AND_CAST(adap_bits, optval, struct sctp_setadaptation, optsize);
SCTP_INP_WLOCK(inp);
inp->sctp_ep.adaptation_layer_indicator = adap_bits->ssb_adaptation_ind;
inp->sctp_ep.adaptation_layer_indicator_provided = 1;
SCTP_INP_WUNLOCK(inp);
break;
}
@ -6790,7 +6872,15 @@ sctp_connect(struct socket *so, struct mbuf *nam, struct proc *p)
error = EINVAL;
goto out_now;
}
#endif /* INET6 */
#endif
#if defined(__Userspace__)
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) &&
(addr->sa_family != AF_CONN)) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
error = EINVAL;
goto out_now;
}
#endif
if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) ==
SCTP_PCB_FLAGS_UNBOUND) {
/* Bind a ephemeral port */
@ -7320,8 +7410,8 @@ sctp_accept(struct socket *so, struct mbuf *nam)
#ifdef HAVE_SIN_LEN
sin->sin_len = sizeof(*sin);
#endif
sin->sin_port = ((struct sockaddr_in *)&store)->sin_port;
sin->sin_addr = ((struct sockaddr_in *)&store)->sin_addr;
sin->sin_port = store.sin.sin_port;
sin->sin_addr = store.sin.sin_addr;
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__)
*addr = (struct sockaddr *)sin;
#elif !defined(__Panda__)
@ -7347,9 +7437,8 @@ sctp_accept(struct socket *so, struct mbuf *nam)
#ifdef HAVE_SIN6_LEN
sin6->sin6_len = sizeof(*sin6);
#endif
sin6->sin6_port = ((struct sockaddr_in6 *)&store)->sin6_port;
sin6->sin6_addr = ((struct sockaddr_in6 *)&store)->sin6_addr;
sin6->sin6_port = store.sin6.sin6_port;
sin6->sin6_addr = store.sin6.sin6_addr;
#if defined(SCTP_EMBEDDED_V6_SCOPE)
#ifdef SCTP_KAME
if ((error = sa6_recoverscope(sin6)) != 0) {
@ -7374,6 +7463,25 @@ sctp_accept(struct socket *so, struct mbuf *nam)
#endif
break;
}
#endif
#if defined(__Userspace__)
case AF_CONN:
{
struct sockaddr_conn *sconn;
SCTP_MALLOC_SONAME(sconn, struct sockaddr_conn *, sizeof(struct sockaddr_conn));
if (sconn == NULL) {
return (ENOMEM);
}
sconn->sconn_family = AF_CONN;
#ifdef HAVE_SCONN_LEN
sconn->sconn_len = sizeof(struct sockaddr_conn);
#endif
sconn->sconn_port = store.sconn.sconn_port;
sconn->sconn_addr = store.sconn.sconn_addr;
*addr = (struct sockaddr *)sconn;
break;
}
#endif
default:
/* TSNH */
@ -7852,7 +7960,7 @@ register_recv_cb(struct socket *so,
SCTP_INP_WLOCK(inp);
inp->recv_callback = receive_cb;
SCTP_INP_WUNLOCK(inp);
return 1;
return (1);
}
int
@ -7873,7 +7981,7 @@ register_send_cb(struct socket *so, uint32_t sb_threshold, int (*send_cb)(struct
* of the send buffer if this is called a second time e.g. if the
* threshold changes.
*/
return 1;
return (1);
}
int
@ -7888,6 +7996,6 @@ register_ulp_info (struct socket *so, void *ulp_info)
SCTP_INP_WLOCK(inp);
inp->ulp_info = ulp_info;
SCTP_INP_WUNLOCK(inp);
return 1;
return (1);
}
#endif

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 244728 2012-12-27 08:02:58Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 247412 2013-02-27 19:51:47Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -947,7 +947,7 @@ sctp_select_a_tag(struct sctp_inpcb *inp, uint16_t lport, uint16_t rport, int ch
}
int
sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
uint32_t override_tag, uint32_t vrf_id)
{
struct sctp_association *asoc;
@ -967,23 +967,23 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
asoc = &stcb->asoc;
/* init all variables to a known value. */
SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_INUSE);
asoc->max_burst = m->sctp_ep.max_burst;
asoc->fr_max_burst = m->sctp_ep.fr_max_burst;
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 = m->sctp_cmt_on_off;
asoc->ecn_allowed = m->sctp_ecn_enable;
asoc->max_burst = inp->sctp_ep.max_burst;
asoc->fr_max_burst = inp->sctp_ep.fr_max_burst;
asoc->heart_beat_delay = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
asoc->cookie_life = inp->sctp_ep.def_cookie_life;
asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off;
asoc->ecn_allowed = inp->sctp_ecn_enable;
asoc->sctp_nr_sack_on_off = (uint8_t)SCTP_BASE_SYSCTL(sctp_nr_sack_on_off);
asoc->sctp_cmt_pf = (uint8_t)0;
asoc->sctp_frag_point = m->sctp_frag_point;
asoc->sctp_features = m->sctp_features;
asoc->default_dscp = m->sctp_ep.default_dscp;
asoc->sctp_frag_point = inp->sctp_frag_point;
asoc->sctp_features = inp->sctp_features;
asoc->default_dscp = inp->sctp_ep.default_dscp;
#ifdef INET6
if (m->sctp_ep.default_flowlabel) {
asoc->default_flowlabel = m->sctp_ep.default_flowlabel;
if (inp->sctp_ep.default_flowlabel) {
asoc->default_flowlabel = inp->sctp_ep.default_flowlabel;
} else {
if (m->ip_inp.inp.inp_flags & IN6P_AUTOFLOWLABEL) {
asoc->default_flowlabel = sctp_select_initial_TSN(&m->sctp_ep);
if (inp->ip_inp.inp.inp_flags & IN6P_AUTOFLOWLABEL) {
asoc->default_flowlabel = sctp_select_initial_TSN(&inp->sctp_ep);
asoc->default_flowlabel &= 0x000fffff;
asoc->default_flowlabel |= 0x80000000;
} else {
@ -995,11 +995,11 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
if (override_tag) {
asoc->my_vtag = override_tag;
} else {
asoc->my_vtag = sctp_select_a_tag(m, stcb->sctp_ep->sctp_lport, stcb->rport, 1);
asoc->my_vtag = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 1);
}
/* Get the nonce tags */
asoc->my_vtag_nonce = sctp_select_a_tag(m, stcb->sctp_ep->sctp_lport, stcb->rport, 0);
asoc->peer_vtag_nonce = sctp_select_a_tag(m, stcb->sctp_ep->sctp_lport, stcb->rport, 0);
asoc->my_vtag_nonce = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 0);
asoc->peer_vtag_nonce = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 0);
asoc->vrf_id = vrf_id;
#ifdef SCTP_ASOCLOG_OF_TSNS
@ -1016,7 +1016,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
asoc->refcnt = 0;
asoc->assoc_up_sent = 0;
asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number = asoc->sending_seq =
sctp_select_initial_TSN(&m->sctp_ep);
sctp_select_initial_TSN(&inp->sctp_ep);
asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
/* we are optimisitic here */
asoc->peer_supports_pktdrop = 1;
@ -1034,49 +1034,55 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
/* here we are different, we hold the next one we expect */
asoc->str_reset_seq_in = asoc->last_acked_seq + 1;
asoc->initial_init_rto_max = m->sctp_ep.initial_init_rto_max;
asoc->initial_rto = m->sctp_ep.initial_rto;
asoc->initial_init_rto_max = inp->sctp_ep.initial_init_rto_max;
asoc->initial_rto = inp->sctp_ep.initial_rto;
asoc->max_init_times = m->sctp_ep.max_init_times;
asoc->max_send_times = m->sctp_ep.max_send_times;
asoc->def_net_failure = m->sctp_ep.def_net_failure;
asoc->def_net_pf_threshold = m->sctp_ep.def_net_pf_threshold;
asoc->max_init_times = inp->sctp_ep.max_init_times;
asoc->max_send_times = inp->sctp_ep.max_send_times;
asoc->def_net_failure = inp->sctp_ep.def_net_failure;
asoc->def_net_pf_threshold = inp->sctp_ep.def_net_pf_threshold;
asoc->free_chunk_cnt = 0;
asoc->iam_blocking = 0;
asoc->context = m->sctp_context;
asoc->local_strreset_support = m->local_strreset_support;
asoc->def_send = m->def_send;
asoc->delayed_ack = TICKS_TO_MSEC(m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
asoc->sack_freq = m->sctp_ep.sctp_sack_freq;
asoc->context = inp->sctp_context;
asoc->local_strreset_support = inp->local_strreset_support;
asoc->def_send = inp->def_send;
asoc->delayed_ack = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
asoc->sack_freq = inp->sctp_ep.sctp_sack_freq;
asoc->pr_sctp_cnt = 0;
asoc->total_output_queue_size = 0;
if (m->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
struct in6pcb *inp6;
/* Its a V6 socket */
inp6 = (struct in6pcb *)m;
asoc->ipv6_addr_legal = 1;
/* Now look at the binding flag to see if V4 will be legal */
if (SCTP_IPV6_V6ONLY(inp6) == 0) {
asoc->ipv4_addr_legal = 1;
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
asoc->scope.ipv6_addr_legal = 1;
if (SCTP_IPV6_V6ONLY(inp) == 0) {
asoc->scope.ipv4_addr_legal = 1;
} else {
/* V4 addresses are NOT legal on the association */
asoc->ipv4_addr_legal = 0;
asoc->scope.ipv4_addr_legal = 0;
}
#if defined(__Userspace__)
asoc->scope.conn_addr_legal = 0;
#endif
} else {
/* Its a V4 socket, no - V6 */
asoc->ipv4_addr_legal = 1;
asoc->ipv6_addr_legal = 0;
asoc->scope.ipv6_addr_legal = 0;
#if defined(__Userspace__)
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) {
asoc->scope.conn_addr_legal = 1;
asoc->scope.ipv4_addr_legal = 0;
} else {
asoc->scope.conn_addr_legal = 0;
asoc->scope.ipv4_addr_legal = 1;
}
#else
asoc->scope.ipv4_addr_legal = 1;
#endif
}
asoc->my_rwnd = max(SCTP_SB_LIMIT_RCV(m->sctp_socket), SCTP_MINIMAL_RWND);
asoc->peers_rwnd = SCTP_SB_LIMIT_RCV(m->sctp_socket);
asoc->my_rwnd = max(SCTP_SB_LIMIT_RCV(inp->sctp_socket), SCTP_MINIMAL_RWND);
asoc->peers_rwnd = SCTP_SB_LIMIT_RCV(inp->sctp_socket);
asoc->smallest_mtu = m->sctp_frag_point;
asoc->minrto = m->sctp_ep.sctp_minrto;
asoc->maxrto = m->sctp_ep.sctp_maxrto;
asoc->smallest_mtu = inp->sctp_frag_point;
asoc->minrto = inp->sctp_ep.sctp_minrto;
asoc->maxrto = inp->sctp_ep.sctp_maxrto;
asoc->locked_on_sending = NULL;
asoc->stream_locked_on = 0;
@ -1093,20 +1099,20 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
/* Setup to fill the hb random cache at first HB */
asoc->hb_random_idx = 4;
asoc->sctp_autoclose_ticks = m->sctp_ep.auto_close_time;
asoc->sctp_autoclose_ticks = inp->sctp_ep.auto_close_time;
stcb->asoc.congestion_control_module = m->sctp_ep.sctp_default_cc_module;
stcb->asoc.cc_functions = sctp_cc_functions[m->sctp_ep.sctp_default_cc_module];
stcb->asoc.congestion_control_module = inp->sctp_ep.sctp_default_cc_module;
stcb->asoc.cc_functions = sctp_cc_functions[inp->sctp_ep.sctp_default_cc_module];
stcb->asoc.stream_scheduling_module = m->sctp_ep.sctp_default_ss_module;
stcb->asoc.ss_functions = sctp_ss_functions[m->sctp_ep.sctp_default_ss_module];
stcb->asoc.stream_scheduling_module = inp->sctp_ep.sctp_default_ss_module;
stcb->asoc.ss_functions = sctp_ss_functions[inp->sctp_ep.sctp_default_ss_module];
/*
* Now the stream parameters, here we allocate space for all streams
* that we request by default.
*/
asoc->strm_realoutsize = asoc->streamoutcnt = asoc->pre_open_streams =
m->sctp_ep.pre_open_stream_count;
inp->sctp_ep.pre_open_stream_count;
SCTP_MALLOC(asoc->strmout, struct sctp_stream_out *,
asoc->streamoutcnt * sizeof(struct sctp_stream_out),
SCTP_M_STRMO);
@ -1161,7 +1167,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
TAILQ_INIT(&asoc->sent_queue);
TAILQ_INIT(&asoc->reasmqueue);
TAILQ_INIT(&asoc->resetHead);
asoc->max_inbound_streams = m->sctp_ep.max_open_streams_intome;
asoc->max_inbound_streams = inp->sctp_ep.max_open_streams_intome;
TAILQ_INIT(&asoc->asconf_queue);
/* authentication fields */
asoc->authinfo.random = NULL;
@ -1172,7 +1178,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
asoc->authinfo.recv_keyid = 0;
LIST_INIT(&asoc->shared_keys);
asoc->marked_retrans = 0;
asoc->port = m->sctp_ep.port;
asoc->port = inp->sctp_ep.port;
asoc->timoinit = 0;
asoc->timodata = 0;
asoc->timosack = 0;
@ -2791,6 +2797,7 @@ set_error:
if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC))) {
SOCK_LOCK(stcb->sctp_socket);
if (from_peer) {
if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) {
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNREFUSED);
@ -2822,7 +2829,11 @@ set_error:
if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC))) {
#if defined(__APPLE__)
socantrcvmore(stcb->sctp_socket);
#else
socantrcvmore_locked(stcb->sctp_socket);
#endif
}
sorwakeup(stcb->sctp_socket);
sowwakeup(stcb->sctp_socket);
@ -7457,26 +7468,24 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
{
int loopback_scope, ipv4_local_scope, local_scope, site_scope;
int ipv4_addr_legal, ipv6_addr_legal;
#if defined(__Userspace__)
int conn_addr_legal;
#endif
struct sctp_vrf *vrf;
struct sctp_ifn *sctp_ifn;
struct sctp_ifa *sctp_ifa;
int count = 0;
/* Turn on all the appropriate scopes */
loopback_scope = stcb->asoc.loopback_scope;
ipv4_local_scope = stcb->asoc.ipv4_local_scope;
local_scope = stcb->asoc.local_scope;
site_scope = stcb->asoc.site_scope;
ipv4_addr_legal = ipv6_addr_legal = 0;
if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
ipv6_addr_legal = 1;
if (SCTP_IPV6_V6ONLY(stcb->sctp_ep) == 0) {
ipv4_addr_legal = 1;
}
} else {
ipv4_addr_legal = 1;
}
loopback_scope = stcb->asoc.scope.loopback_scope;
ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
local_scope = stcb->asoc.scope.local_scope;
site_scope = stcb->asoc.scope.site_scope;
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
#if defined(__Userspace__)
conn_addr_legal = stcb->asoc.scope.conn_addr_legal;
#endif
SCTP_IPI_ADDR_RLOCK();
vrf = sctp_find_vrf(stcb->asoc.vrf_id);
if (vrf == NULL) {
@ -7571,7 +7580,9 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
#endif
#if defined(__Userspace__)
case AF_CONN:
count++;
if (conn_addr_legal) {
count++;
}
break;
#endif
default:

View File

@ -1004,7 +1004,7 @@ static
int
sctp6_disconnect(struct socket *so)
{
return(sctp_disconnect(so));
return (sctp_disconnect(so));
}

View File

@ -34,10 +34,8 @@
#if !defined (__Userspace_os_Windows)
#include <stdint.h>
#if !defined(__Userspace_os_FreeBSD)
#if !defined(ANDROID)
#include <sys/sysctl.h>
#endif
#endif
#include <netinet/sctp_os_userspace.h>
#endif
#include <user_environment.h>

View File

@ -35,13 +35,6 @@
#include <user_route.h> /* was <net/route.h> */
#if defined(ANDROID)
#include <arpa/inet.h>
#include <netinet/in.h>
/* missing defines in Android bionic libc/NDK */
typedef uint16_t in_port_t;
#endif
#define in6pcb inpcb /* for KAME src sync over BSD*'s */
#define in6p_sp inp_sp /* for KAME src sync over BSD*'s */
struct inpcbpolicy;

View File

@ -95,7 +95,7 @@ struct ip6_hdr {
#endif
#endif
#if !defined(__Userspace_os_FreeBSD)
#if !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_OpenBSD)
struct route_in6 {
struct rtentry *ro_rt;
struct llentry *ro_lle;

View File

@ -59,20 +59,6 @@ sctp_zone_t zone_mbuf;
sctp_zone_t zone_clust;
sctp_zone_t zone_ext_refcnt;
/*__Userspace__
* constructor callback_data
* mbuf_mb_args will be passed as callback data to umem_cache_create.
* umem_cache_alloc will then be able to use this callback data when the constructor
* function mb_ctor_mbuf is called. See user_mbuf.c
* This is important because mbuf_mb_args would specify flags like M_PKTHDR
* and type like MT_DATA or MT_HEADER. This information is needed in mb_ctor_mbuf
* to properly initialize the mbuf being allocated.
*
* Argument structure passed to UMA routines during mbuf and packet
* allocations.
*/
struct mb_args mbuf_mb_args;
/* __Userspace__ clust_mb_args will be passed as callback data to mb_ctor_clust
* and mb_dtor_clust.
* Note: I had to use struct clust_args as an encapsulation for an mbuf pointer.
@ -92,18 +78,6 @@ static void mb_dtor_clust(void *, void *);
/***************** Functions taken from user_mbuf.h *************/
/* __Userspace__ Setter function for mbuf_mb_args */
static void set_mbuf_mb_args(int flags, short type) {
mbuf_mb_args.flags = flags;
mbuf_mb_args.type = type;
}
#if USING_MBUF_CONSTRUCTOR
/* __Userspace__ Setter function for clust_mb_args */
static void set_clust_mb_args(struct mbuf * mb) {
clust_mb_args.parent_mbuf = mb;
}
#endif
static int mbuf_constructor_dup(struct mbuf *m, int pkthdr, short type)
{
int flags = pkthdr;
@ -136,12 +110,16 @@ struct mbuf *
m_get(int how, short type)
{
struct mbuf *mret;
#if defined(SCTP_SIMPLE_ALLOCATOR)
struct mb_args mbuf_mb_args;
/* The following setter function is not yet being enclosed within
* #if USING_MBUF_CONSTRUCTOR - #endif, until I have thoroughly tested
* mb_dtor_mbuf. See comment there
*/
set_mbuf_mb_args(0, type);
mbuf_mb_args.flags = 0;
mbuf_mb_args.type = type;
#endif
/* Mbuf master zone, zone_mbuf, has already been
* created in mbuf_init() */
mret = SCTP_ZONE_GET(zone_mbuf, struct mbuf);
@ -174,12 +152,16 @@ struct mbuf *
m_gethdr(int how, short type)
{
struct mbuf *mret;
#if defined(SCTP_SIMPLE_ALLOCATOR)
struct mb_args mbuf_mb_args;
/* The following setter function is not yet being enclosed within
* #if USING_MBUF_CONSTRUCTOR - #endif, until I have thoroughly tested
* mb_dtor_mbuf. See comment there
*/
set_mbuf_mb_args(M_PKTHDR, type);
mbuf_mb_args.flags = M_PKTHDR;
mbuf_mb_args.type = type;
#endif
mret = SCTP_ZONE_GET(zone_mbuf, struct mbuf);
#if defined(SCTP_SIMPLE_ALLOCATOR)
mb_ctor_mbuf(mret, &mbuf_mb_args, 0);
@ -213,7 +195,7 @@ m_free(struct mbuf *m)
mb_free_ext(m);
else if ((m->m_flags & M_NOFREE) == 0) {
#if defined(SCTP_SIMPLE_ALLOCATOR)
mb_dtor_mbuf(m, &mbuf_mb_args);
mb_dtor_mbuf(m, NULL);
#endif
SCTP_ZONE_FREE(zone_mbuf, m);
}
@ -262,13 +244,15 @@ void
m_clget(struct mbuf *m, int how)
{
caddr_t mclust_ret;
#if defined(SCTP_SIMPLE_ALLOCATOR)
struct clust_args clust_mb_args;
#endif
if (m->m_flags & M_EXT) {
SCTPDBG(SCTP_DEBUG_USR, "%s: %p mbuf already has cluster\n", __func__, (void *)m);
}
m->m_ext.ext_buf = (char *)NULL;
#if USING_MBUF_CONSTRUCTOR
set_clust_mb_args(m);
#if defined(SCTP_SIMPLE_ALLOCATOR)
clust_mb_args.parent_mbuf = m;
#endif
mclust_ret = SCTP_ZONE_GET(zone_clust, char);
#if defined(SCTP_SIMPLE_ALLOCATOR)
@ -366,9 +350,9 @@ mbuf_init(void *dummy)
SCTP_ZONE_INIT(zone_mbuf, MBUF_MEM_NAME, MSIZE, 0);
#else
zone_mbuf = umem_cache_create(MBUF_MEM_NAME, MSIZE, 0,
mb_ctor_mbuf, mb_dtor_mbuf, NULL,
&mbuf_mb_args,
NULL, 0);
mb_ctor_mbuf, mb_dtor_mbuf, NULL,
NUULL,
NULL, 0);
#endif
/*zone_ext_refcnt = umem_cache_create(MBUF_EXTREFCNT_MEM_NAME, sizeof(u_int), 0,
NULL, NULL, NULL,
@ -498,16 +482,10 @@ mb_ctor_mbuf(void *mem, void *arg, int flgs)
static void
mb_dtor_mbuf(void *mem, void *arg)
{
struct mbuf *m;
struct mb_args *args;
int flags;
m = (struct mbuf *)mem;
args = (struct mb_args *)arg;
flags = args->flags;
if ((flags & MB_NOTAGS) == 0 && (m->m_flags & M_PKTHDR) != 0) {
if ((m->m_flags & M_PKTHDR) != 0) {
m_tag_delete_chain(m, NULL);
}
}
@ -693,7 +671,7 @@ mb_free_ext(struct mbuf *m)
m->m_ext.ext_type = 0;
m->m_flags &= ~M_EXT;
#if defined(SCTP_SIMPLE_ALLOCATOR)
mb_dtor_mbuf(m, &mbuf_mb_args);
mb_dtor_mbuf(m, NULL);
#endif
SCTP_ZONE_FREE(zone_mbuf, m);

View File

@ -93,34 +93,15 @@ extern sctp_zone_t zone_ext_refcnt;
#define mtod(m, t) ((t)((m)->m_data))
#define dtom(x) ((struct mbuf *)((intptr_t)(x) & ~(MSIZE-1)))
struct mb_args {
int flags; /* Flags for mbuf being allocated */
short type; /* Type of mbuf being allocated */
};
struct clust_args {
struct mbuf * parent_mbuf;
struct mbuf * parent_mbuf;
};
/*__Userspace__
* mbuf_mb_args will be passed as callback data to umem_cache_create.
* umem_cache_alloc will then be able to use this callback data when the constructor
* function mb_ctor_mbuf is called. See user_mbuf.c
* This is important because mbuf_mb_args would specify flags like M_PKTHDR
* and type like MT_DATA or MT_HEADER. This information is needed in mb_ctor_mbuf
* to properly initialize the mbuf being allocated.
*
* Argument structure passed to UMA routines during mbuf and packet
* allocations.
*/
extern struct mb_args mbuf_mb_args;
/* __Userspace__ clust_mb_args will be passed as callback data to mb_ctor_clust
* and mb_dtor_clust.
*/
extern struct clust_args clust_mb_args;
struct mbuf * m_split(struct mbuf *, int, int);
void m_cat(struct mbuf *m, struct mbuf *n);
void m_adj(struct mbuf *, int);
@ -143,7 +124,6 @@ void m_copydata(const struct mbuf *, int, int, caddr_t);
#define MT_NOINIT 255 /* Not a type but a flag to allocate
a non-initialized mbuf */
#define MB_NOTAGS 0x1UL /* no tags attached to mbuf */
/*
* General mbuf allocator statistics structure.
@ -344,10 +324,6 @@ struct mbuf {
#define MT_NOINIT 255 /* Not a type but a flag to allocate
a non-initialized mbuf */
#define MB_NOTAGS 0x1UL /* no tags attached to mbuf */
/*
* __Userspace__ flags like M_NOWAIT are defined in malloc.h
* Flags like these are used in functions like uma_zalloc()

View File

@ -442,7 +442,7 @@ recv_function_raw(void *arg)
#else
pthread_exit(NULL);
#endif
return NULL;
return (NULL);
}
#endif
@ -626,7 +626,7 @@ recv_function_raw6(void *arg)
#else
pthread_exit(NULL);
#endif
return NULL;
return (NULL);
}
#endif
@ -831,7 +831,7 @@ recv_function_udp(void *arg)
#else
pthread_exit(NULL);
#endif
return NULL;
return (NULL);
}
#endif
@ -1018,7 +1018,7 @@ recv_function_udp6(void *arg)
#else
pthread_exit(NULL);
#endif
return NULL;
return (NULL);
}
#endif

View File

@ -73,9 +73,9 @@ user_sctp_timer_iterate(void *arg)
if (SCTP_BASE_VAR(timer_thread_should_exit)) {
break;
}
SCTP_TIMERQ_LOCK();
/* update our tick count */
ticks += MSEC_TO_TICKS(TIMEOUT_INTERVAL);
SCTP_TIMERQ_LOCK();
c = TAILQ_FIRST(&SCTP_BASE_INFO(callqueue));
while (c) {
if (c->c_time <= ticks) {

View File

@ -717,8 +717,6 @@ uiomove(void *cp, int n, struct uio *uio)
else
bcopy(iov->iov_base, cp, cnt);
break;
case UIO_NOCOPY:
break;
}
iov->iov_base = (char *)iov->iov_base + cnt;
iov->iov_len -= cnt;
@ -1066,7 +1064,7 @@ userspace_sctp_recvmsg(struct socket *so,
void *dbuf,
size_t len,
struct sockaddr *from,
socklen_t * fromlen,
socklen_t *fromlenp,
struct sctp_sndrcvinfo *sinfo,
int *msg_flags)
{
@ -1076,6 +1074,7 @@ userspace_sctp_recvmsg(struct socket *so,
int iovlen = 1;
int error = 0;
int ulen, i, retval;
socklen_t fromlen;
iov[0].iov_base = dbuf;
iov[0].iov_len = len;
@ -1095,8 +1094,13 @@ userspace_sctp_recvmsg(struct socket *so,
}
}
ulen = auio.uio_resid;
if (fromlenp != NULL) {
fromlen = *fromlenp;
} else {
fromlen = 0;
}
error = sctp_sorecvmsg(so, &auio, (struct mbuf **)NULL,
from, *fromlen, msg_flags,
from, fromlen, msg_flags,
(struct sctp_sndrcvinfo *)sinfo, 1);
if (error) {
@ -1104,7 +1108,29 @@ userspace_sctp_recvmsg(struct socket *so,
error == EINTR || error == EWOULDBLOCK))
error = 0;
}
if ((fromlenp != NULL) && (fromlen > 0) && (from != NULL)) {
switch (from->sa_family) {
#if defined(INET)
case AF_INET:
*fromlenp = sizeof(struct sockaddr_in);
break;
#endif
#if defined(INET6)
case AF_INET6:
*fromlenp = sizeof(struct sockaddr_in6);
break;
#endif
case AF_CONN:
*fromlenp = sizeof(struct sockaddr_conn);
break;
default:
*fromlenp = 0;
break;
}
if (*fromlenp > fromlen) {
*fromlenp = fromlen;
}
}
if (error == 0){
/* ready return value */
retval = (int)ulen - auio.uio_resid;
@ -1120,7 +1146,7 @@ usrsctp_recvv(struct socket *so,
void *dbuf,
size_t len,
struct sockaddr *from,
socklen_t * fromlen,
socklen_t *fromlenp,
void *info,
socklen_t *infolen,
unsigned int *infotype,
@ -1131,6 +1157,7 @@ usrsctp_recvv(struct socket *so,
struct iovec *tiov;
int iovlen = 1;
int ulen, i;
socklen_t fromlen;
struct sctp_rcvinfo *rcv;
struct sctp_recvv_rn *rn;
struct sctp_extrcvinfo seinfo;
@ -1156,8 +1183,13 @@ usrsctp_recvv(struct socket *so,
}
}
ulen = auio.uio_resid;
if (fromlenp != NULL) {
fromlen = *fromlenp;
} else {
fromlen = 0;
}
errno = sctp_sorecvmsg(so, &auio, (struct mbuf **)NULL,
from, *fromlen, msg_flags,
from, fromlen, msg_flags,
(struct sctp_sndrcvinfo *)&seinfo, 1);
if (errno) {
if (auio.uio_resid != (int)ulen &&
@ -1216,6 +1248,29 @@ usrsctp_recvv(struct socket *so,
*infolen = 0;
}
}
if ((fromlenp != NULL) && (fromlen > 0) && (from != NULL)) {
switch (from->sa_family) {
#if defined(INET)
case AF_INET:
*fromlenp = sizeof(struct sockaddr_in);
break;
#endif
#if defined(INET6)
case AF_INET6:
*fromlenp = sizeof(struct sockaddr_in6);
break;
#endif
case AF_CONN:
*fromlenp = sizeof(struct sockaddr_conn);
break;
default:
*fromlenp = 0;
break;
}
if (*fromlenp > fromlen) {
*fromlenp = fromlen;
}
}
if (errno == 0) {
/* ready return value */
return ((int)ulen - auio.uio_resid);
@ -1828,7 +1883,6 @@ user_accept(struct socket *head, struct sockaddr **name, socklen_t *namelen, st
* we will return the socket for accepted connection.
*/
sa = 0;
error = soaccept(so, &sa);
if (error) {
/*
@ -3084,7 +3138,7 @@ usrsctp_deregister_address(void *addr)
"conn");
}
#define PREAMBLE_FORMAT "\n%c %02d:%02d:%02d.%06d "
#define PREAMBLE_FORMAT "\n%c %02d:%02d:%02d.%06ld "
#define PREAMBLE_LENGTH 19
#define HEADER "0000 "
#define TRAILER "# SCTP_PACKET\n"
@ -3100,6 +3154,7 @@ usrsctp_dumppacket(void *buf, size_t len, int outbound)
#else
struct timeval tv;
struct tm *t;
time_t sec;
#endif
if ((len == 0) || (buf == NULL)) {
@ -3114,13 +3169,14 @@ usrsctp_dumppacket(void *buf, size_t len, int outbound)
localtime_s(&t, &tb.time);
_snprintf_s(dump_buf, PREAMBLE_LENGTH + 1, PREAMBLE_LENGTH, PREAMBLE_FORMAT,
outbound ? 'O' : 'I',
t.tm_hour, t.tm_min, t.tm_sec, 1000 * tb.millitm);
t.tm_hour, t.tm_min, t.tm_sec, (long)(1000 * tb.millitm));
#else
gettimeofday(&tv, NULL);
t = localtime(&tv.tv_sec);
sec = (time_t)tv.tv_sec;
t = localtime((const time_t *)&sec);
snprintf(dump_buf, PREAMBLE_LENGTH + 1, PREAMBLE_FORMAT,
outbound ? 'O' : 'I',
t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec);
t->tm_hour, t->tm_min, t->tm_sec, (long)tv.tv_usec);
#endif
pos += PREAMBLE_LENGTH;
#ifdef _WIN32

View File

@ -37,11 +37,6 @@
#include <sys/types.h>
#include <unistd.h>
#endif
#if defined(ANDROID)
/* Android bionic libc is missing some defines in sys/types.h. Pick them
* up elsewhere */
#include <linux/coda.h>
#endif
/* #include <sys/selinfo.h> */ /*__Userspace__ alternative?*/ /* for struct selinfo */
/* #include <sys/_lock.h> was 0 byte file */
@ -59,21 +54,22 @@
#define SS_CANTRCVMORE 0x020
#define SS_CANTSENDMORE 0x010
#if defined (__Userspace_os_FreeBSD) || defined(__Userspace_os_Darwin) || defined (__Userspace_os_Windows)
#if defined (__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) || defined(__Userspace_os_Darwin) || defined (__Userspace_os_Windows)
#define UIO_MAXIOV 1024
#define ERESTART (-1)
#endif
#if !defined(__Userspace_os_Darwin)
#if !defined(__Userspace_os_Darwin) && !defined(__Userspace_os_OpenBSD)
enum uio_rw { UIO_READ, UIO_WRITE };
#endif
#if !defined(__Userspace_os_OpenBSD)
/* Segment flag values. */
enum uio_seg {
UIO_USERSPACE, /* from user data space */
UIO_SYSSPACE, /* from system space */
UIO_NOCOPY /* don't copy, already in object */
UIO_SYSSPACE /* from system space */
};
#endif
struct proc {
int stub; /* struct proc is a dummy for __Userspace__ */
@ -273,9 +269,9 @@ extern userland_mutex_t accept_mtx;
InitializeCriticalSection(SOCKBUF_MTX(_sb))
#define SOCKBUF_LOCK_DESTROY(_sb) DeleteCriticalSection(SOCKBUF_MTX(_sb))
#define SOCKBUF_COND_INIT(_sb) InitializeConditionVariable((&(_sb)->sb_cond))
#define SOCKBUF_COND_DESTROY(_sb)
#define SOCKBUF_COND_DESTROY(_sb) DeleteConditionVariable((&(_sb)->sb_cond))
#define SOCK_COND_INIT(_so) InitializeConditionVariable((&(_so)->timeo_cond))
#define SOCK_COND_DESTROY(_so)
#define SOCK_COND_DESTROY(_so) DeleteConditionVariable((&(_so)->timeo_cond))
#define SOCK_COND(_so) (&(_so)->timeo_cond)
#else
#define SOCKBUF_LOCK_INIT(_sb, _name) \

View File

@ -850,7 +850,7 @@ struct sctp_timeouts {
void
usrsctp_init(uint16_t,
int (*)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
void (*)(const char *, ...));
void (*)(const char *format, ...));
struct socket *
usrsctp_socket(int domain, int type, int protocol,