Bug 1795697: Update libusrsctp. r=ng

Differential Revision: https://phabricator.services.mozilla.com/D159616
This commit is contained in:
Byron Campen [:bwc] 2022-10-27 14:21:37 +00:00
parent a2cad07649
commit e0d638f358
60 changed files with 4396 additions and 4142 deletions

View File

@ -319,7 +319,8 @@ static RefPtr<DataChannelConnection> GetConnectionFromSocket(
// Called when the buffer empties to the threshold value. This is called
// from SctpDtlsInput() through the sctp stack. SctpDtlsInput() calls
// usrsctp_conninput() under lock
static int threshold_event(struct socket* sock, uint32_t sb_free) {
static int threshold_event(struct socket* sock, uint32_t sb_free,
void* ulp_info) {
RefPtr<DataChannelConnection> connection = GetConnectionFromSocket(sock);
connection->mLock.AssertCurrentThreadOwns();
if (connection) {

View File

@ -18,3 +18,4 @@ sctp updated to version 9168 from SVN on Tue Mar 3 12:11:40 EST 2015
sctp updated to version 9209 from SVN on Tue Mar 24 18:11:59 EDT 2015
sctp updated to version 0e076261b832121cf120ddc04aaff87ac3a34d30 from git on Tue Nov 28 15:20:51 EST 2017
sctp updated to version ea345b6d0c8a0f8701cf49445dba5ec8d34e2305 from git on Tue 30 Jun 14:01:18 CEST 2020
sctp updated to version 8e12cd9e01fc94d2e84ea1afa351c845966e116e from git on Mon Oct 17 10:23:01 CDT 2022

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 356357 2020-01-04 20:33:12Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_H_
@ -43,10 +43,8 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp.h 356357 2020-01-04 20:33:12Z tuexen $
#if defined(__APPLE__) || defined(__linux__)
#include <stdint.h>
#endif
#include <sys/types.h>
#if !defined(_WIN32)
#define SCTP_PACKED __attribute__((packed))
#else
@ -191,7 +189,6 @@ struct sctp_paramhdr {
#define SCTP_STREAM_RESET_INCOMING 0x00000001
#define SCTP_STREAM_RESET_OUTGOING 0x00000002
/* here on down are more implementation specific */
#define SCTP_SET_DEBUG_LEVEL 0x00001005
#define SCTP_CLR_STAT_LOG 0x00001007
@ -213,7 +210,6 @@ struct sctp_paramhdr {
#define SCTP_PCB_STATUS 0x00001104
#define SCTP_GET_NONCE_VALUES 0x00001105
/* Special hook for dynamically setting primary for all assoc's,
* this is a write only option that requires root privilege.
*/
@ -336,7 +332,6 @@ struct sctp_paramhdr {
/* First-come, first-serve */
#define SCTP_SS_FIRST_COME 0x00000005
/* fragment interleave constants
* setting must be one of these or
* EINVAL returned.
@ -607,7 +602,6 @@ struct sctp_error_auth_invalid_hmac {
#define SCTP_MOBILITY_FASTHANDOFF 0x00000002
#define SCTP_MOBILITY_PRIM_DELETED 0x00000004
/* Smallest PMTU allowed when disabling PMTU discovery */
#define SCTP_SMALLEST_PMTU 512
/* Largest PMTU allowed when disabling PMTU discovery */
@ -632,9 +626,9 @@ struct sctp_error_auth_invalid_hmac {
*/
#define SCTP_MAX_SACK_DELAY 500 /* per RFC4960 */
#define SCTP_MAX_HB_INTERVAL 14400000 /* 4 hours in ms */
#define SCTP_MIN_COOKIE_LIFE 1000 /* 1 second in ms */
#define SCTP_MAX_COOKIE_LIFE 3600000 /* 1 hour in ms */
/* Types of logging/KTR tracing that can be enabled via the
* sysctl net.inet.sctp.sctp_logging. You must also enable
* SUBSYS tracing.

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 362377 2020-06-19 12:35:29Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
@ -555,8 +555,8 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
/* notify upper layer */
sctp_ulp_notify(SCTP_NOTIFY_ASCONF_SET_PRIMARY, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
if ((stcb->asoc.primary_destination->dest_state & SCTP_ADDR_REACHABLE) &&
(!(stcb->asoc.primary_destination->dest_state & SCTP_ADDR_PF)) &&
(stcb->asoc.alternate)) {
((stcb->asoc.primary_destination->dest_state & SCTP_ADDR_PF) == 0) &&
(stcb->asoc.alternate != NULL)) {
sctp_free_remote_addr(stcb->asoc.alternate);
stcb->asoc.alternate = NULL;
}
@ -584,7 +584,6 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
SCTP_MOBILITY_PRIM_DELETED) &&
(stcb->asoc.primary_destination->dest_state &
SCTP_ADDR_UNCONFIRMED) == 0) {
sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED,
stcb->sctp_ep, stcb, NULL,
SCTP_FROM_SCTP_ASCONF + SCTP_LOC_1);
@ -738,7 +737,7 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
sctp_m_freem(m_ack);
return;
}
if (param_length <= sizeof(struct sctp_paramhdr)) {
if (param_length < sizeof(struct sctp_asconf_paramhdr)) {
SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: param length (%u) too short\n", param_length);
sctp_m_freem(m_ack);
return;
@ -1008,7 +1007,6 @@ sctp_asconf_nets_cleanup(struct sctp_tcb *stcb, struct sctp_ifn *ifn)
}
}
void
sctp_assoc_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *dstnet)
{
@ -1134,7 +1132,7 @@ sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
return;
}
/* Multiple local addresses exsist in the association. */
/* Multiple local addresses exist in the association. */
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
/* clear any cached route and source address */
#if defined(__FreeBSD__) && !defined(__Userspace__)
@ -1369,7 +1367,6 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
return (0);
}
/*
* add an asconf operation for the given ifa and type.
* type = SCTP_ADD_IP_ADDRESS, SCTP_DEL_IP_ADDRESS, SCTP_SET_PRIM_ADDR.
@ -1741,7 +1738,7 @@ sctp_handle_asconf_ack(struct mbuf *m, int offset,
SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got unexpected next serial number! Aborting asoc!\n");
SCTP_SNPRINTF(msg, sizeof(msg), "Never sent serial number %8.8x", serial_num);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
*abort_no_unlock = 1;
return;
}
@ -1780,7 +1777,7 @@ sctp_handle_asconf_ack(struct mbuf *m, int offset,
sctp_asconf_ack_clear(stcb);
return;
}
if (param_length < sizeof(struct sctp_paramhdr)) {
if (param_length < sizeof(struct sctp_asconf_paramhdr)) {
sctp_asconf_ack_clear(stcb);
return;
}
@ -1989,7 +1986,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
sin6 = &ifa->address.sin6;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
/* we skip unspecifed addresses */
/* we skip unspecified addresses */
return;
}
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
@ -2020,7 +2017,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
sin = &ifa->address.sin;
if (sin->sin_addr.s_addr == 0) {
/* we skip unspecifed addresses */
/* we skip unspecified addresses */
return;
}
if (stcb->asoc.scope.ipv4_local_scope == 0 &&
@ -2061,7 +2058,6 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
}
int
sctp_asconf_iterator_ep(struct sctp_inpcb *inp, void *ptr, uint32_t val SCTP_UNUSED)
{
@ -2125,7 +2121,6 @@ sctp_asconf_iterator_ep_end(struct sctp_inpcb *inp, void *ptr, uint32_t val SCTP
laddr->action = 0;
break;
}
}
} else if (l->action == SCTP_DEL_IP_ADDRESS) {
LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) {
@ -2177,7 +2172,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
sin6 = &ifa->address.sin6;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
/* we skip unspecifed addresses */
/* we skip unspecified addresses */
continue;
}
#if defined(__FreeBSD__) && !defined(__Userspace__)
@ -2211,7 +2206,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
sin = &ifa->address.sin;
if (sin->sin_addr.s_addr == 0) {
/* we skip unspecifed addresses */
/* we skip unspecified addresses */
continue;
}
#if defined(__FreeBSD__) && !defined(__Userspace__)
@ -2242,7 +2237,6 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
return;
else
continue;
break;
}
if (type == SCTP_ADD_IP_ADDRESS) {
@ -2272,7 +2266,6 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
*/
stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
net->RTO = 0;
}
}
} else if (type == SCTP_SET_PRIM_ADDR) {
@ -2501,7 +2494,7 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
sin = &sctp_ifa->address.sin;
if (sin->sin_addr.s_addr == 0) {
/* skip unspecifed addresses */
/* skip unspecified addresses */
continue;
}
#if defined(__FreeBSD__) && !defined(__Userspace__)
@ -2535,7 +2528,7 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
sin6 = &sctp_ifa->address.sin6;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
/* we skip unspecifed addresses */
/* we skip unspecified addresses */
continue;
}
#if defined(__FreeBSD__) && !defined(__Userspace__)
@ -2605,7 +2598,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
struct sctp_asconf_chunk *acp;
struct sctp_asconf_paramhdr *aph;
struct sctp_asconf_addr_param *aap;
uint32_t p_length;
uint32_t p_length, overhead;
uint32_t correlation_id = 1; /* 0 is reserved... */
caddr_t ptr, lookup_ptr;
uint8_t lookup_used = 0;
@ -2618,6 +2611,20 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
if (aa == NULL)
return (NULL);
/* Consider IP header and SCTP common header. */
if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
overhead = SCTP_MIN_OVERHEAD;
} else {
overhead = SCTP_MIN_V4_OVERHEAD;
}
/* Consider ASONF chunk. */
overhead += sizeof(struct sctp_asconf_chunk);
/* Consider AUTH chunk. */
overhead += sctp_get_auth_chunk_len(stcb->asoc.peer_hmac_id);
if (stcb->asoc.smallest_mtu <= overhead) {
/* MTU too small. */
return (NULL);
}
/*
* get a chunk header mbuf and a cluster for the asconf params since
* it's simpler to fill in the asconf chunk header lookup address on
@ -2627,14 +2634,14 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
if (m_asconf_chk == NULL) {
/* no mbuf's */
SCTPDBG(SCTP_DEBUG_ASCONF1,
"compose_asconf: couldn't get chunk mbuf!\n");
"sctp_compose_asconf: couldn't get chunk mbuf!\n");
return (NULL);
}
m_asconf = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
if (m_asconf == NULL) {
/* no mbuf's */
SCTPDBG(SCTP_DEBUG_ASCONF1,
"compose_asconf: couldn't get mbuf!\n");
"sctp_compose_asconf: couldn't get mbuf!\n");
sctp_m_freem(m_asconf_chk);
return (NULL);
}
@ -2659,7 +2666,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
/* get the parameter length */
p_length = SCTP_SIZE32(aa->ap.aph.ph.param_length);
/* will it fit in current chunk? */
if ((SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu) ||
if ((SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu - overhead) ||
(SCTP_BUF_LEN(m_asconf) + p_length > MCLBYTES)) {
/* won't fit, so we're done with this chunk */
break;
@ -2759,10 +2766,12 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
break;
#endif
default:
p_size = 0;
addr_size = 0;
addr_ptr = NULL;
break;
SCTPDBG(SCTP_DEBUG_ASCONF1,
"sctp_compose_asconf: no usable lookup addr (family = %d)!\n",
found_addr->sa_family);
sctp_m_freem(m_asconf_chk);
sctp_m_freem(m_asconf);
return (NULL);
}
lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
memcpy(lookup->addr, addr_ptr, addr_size);
@ -2770,12 +2779,10 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
} else {
/* uh oh... don't have any address?? */
SCTPDBG(SCTP_DEBUG_ASCONF1,
"compose_asconf: no lookup addr!\n");
/* XXX for now, we send a IPv4 address of 0.0.0.0 */
lookup->ph.param_type = htons(SCTP_IPV4_ADDRESS);
lookup->ph.param_length = htons(SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param)));
memset(lookup->addr, 0, sizeof(struct in_addr));
SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param));
"sctp_compose_asconf: no lookup addr!\n");
sctp_m_freem(m_asconf_chk);
sctp_m_freem(m_asconf);
return (NULL);
}
}
/* chain it all together */
@ -3315,10 +3322,9 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
}
void
sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
struct sctp_nets *net)
sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb, struct sctp_nets *net)
{
struct sctp_asconf_addr *aa;
struct sctp_asconf_addr *aa_vtag, *aa_add, *aa_del;
struct sctp_ifa *sctp_ifap;
struct sctp_asconf_tag_param *vtag;
#ifdef INET
@ -3327,6 +3333,7 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
#ifdef INET6
struct sockaddr_in6 *to6;
#endif
if (net == NULL) {
SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: Missing net\n");
return;
@ -3335,108 +3342,84 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: Missing stcb\n");
return;
}
/* Need to have in the asconf:
* - vtagparam(my_vtag/peer_vtag)
* - add(0.0.0.0)
* - del(0.0.0.0)
* - Any global addresses add(addr)
*/
SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
SCTP_M_ASC_ADDR);
if (aa == NULL) {
/* didn't get memory */
SCTPDBG(SCTP_DEBUG_ASCONF1,
"sctp_asconf_send_nat_state_update: failed to get memory!\n");
/* Need to have in the ASCONF:
* - VTAG(my_vtag/peer_vtag)
* - ADD(wildcard)
* - DEL(wildcard)
* - ADD(Any global addresses)
*/
SCTP_MALLOC(aa_vtag, struct sctp_asconf_addr *, sizeof(struct sctp_asconf_addr), SCTP_M_ASC_ADDR);
SCTP_MALLOC(aa_add, struct sctp_asconf_addr *, sizeof(struct sctp_asconf_addr), SCTP_M_ASC_ADDR);
SCTP_MALLOC(aa_del, struct sctp_asconf_addr *, sizeof(struct sctp_asconf_addr), SCTP_M_ASC_ADDR);
if ((aa_vtag == NULL) || (aa_add == NULL) || (aa_del == NULL)) {
/* Didn't get memory */
SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: failed to get memory!\n");
out:
if (aa_vtag != NULL) {
SCTP_FREE(aa_vtag, SCTP_M_ASC_ADDR);
}
if (aa_add != NULL) {
SCTP_FREE(aa_add, SCTP_M_ASC_ADDR);
}
if (aa_del != NULL) {
SCTP_FREE(aa_del, SCTP_M_ASC_ADDR);
}
return;
}
aa->special_del = 0;
/* fill in asconf address parameter fields */
/* top level elements are "networked" during send */
aa->ifa = NULL;
aa->sent = 0; /* clear sent flag */
vtag = (struct sctp_asconf_tag_param *)&aa->ap.aph;
memset(aa_vtag, 0, sizeof(struct sctp_asconf_addr));
aa_vtag->special_del = 0;
/* Fill in ASCONF address parameter fields. */
/* Top level elements are "networked" during send. */
aa_vtag->ifa = NULL;
aa_vtag->sent = 0; /* clear sent flag */
vtag = (struct sctp_asconf_tag_param *)&aa_vtag->ap.aph;
vtag->aph.ph.param_type = SCTP_NAT_VTAGS;
vtag->aph.ph.param_length = sizeof(struct sctp_asconf_tag_param);
vtag->local_vtag = htonl(stcb->asoc.my_vtag);
vtag->remote_vtag = htonl(stcb->asoc.peer_vtag);
TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
SCTP_M_ASC_ADDR);
if (aa == NULL) {
/* didn't get memory */
SCTPDBG(SCTP_DEBUG_ASCONF1,
"sctp_asconf_send_nat_state_update: failed to get memory!\n");
return;
}
memset(aa, 0, sizeof(struct sctp_asconf_addr));
/* fill in asconf address parameter fields */
/* ADD(0.0.0.0) */
memset(aa_add, 0, sizeof(struct sctp_asconf_addr));
memset(aa_del, 0, sizeof(struct sctp_asconf_addr));
switch (net->ro._l_addr.sa.sa_family) {
#ifdef INET
case AF_INET:
aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
aa->ap.addrp.ph.param_length = sizeof (struct sctp_ipv4addr_param);
/* No need to add an address, we are using 0.0.0.0 */
TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
aa_add->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
aa_add->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
aa_add->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
aa_add->ap.addrp.ph.param_length = sizeof (struct sctp_ipv4addr_param);
/* No need to fill the address, we are using 0.0.0.0 */
aa_del->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
aa_del->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
aa_del->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
aa_del->ap.addrp.ph.param_length = sizeof (struct sctp_ipv4addr_param);
/* No need to fill the address, we are using 0.0.0.0 */
break;
#endif
#ifdef INET6
case AF_INET6:
aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
aa->ap.addrp.ph.param_length = sizeof (struct sctp_ipv6addr_param);
/* No need to add an address, we are using 0.0.0.0 */
TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
aa_add->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
aa_add->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
aa_add->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
aa_add->ap.addrp.ph.param_length = sizeof (struct sctp_ipv6addr_param);
/* No need to fill the address, we are using ::0 */
aa_del->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
aa_del->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
aa_del->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
aa_del->ap.addrp.ph.param_length = sizeof (struct sctp_ipv6addr_param);
/* No need to fill the address, we are using ::0 */
break;
#endif
default:
SCTPDBG(SCTP_DEBUG_ASCONF1,
"sctp_asconf_send_nat_state_update: unknown address family\n");
SCTP_FREE(aa, SCTP_M_ASC_ADDR);
return;
}
SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
SCTP_M_ASC_ADDR);
if (aa == NULL) {
/* didn't get memory */
SCTPDBG(SCTP_DEBUG_ASCONF1,
"sctp_asconf_send_nat_state_update: failed to get memory!\n");
return;
}
memset(aa, 0, sizeof(struct sctp_asconf_addr));
/* fill in asconf address parameter fields */
/* ADD(0.0.0.0) */
switch (net->ro._l_addr.sa.sa_family) {
#ifdef INET
case AF_INET:
aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
aa->ap.addrp.ph.param_length = sizeof (struct sctp_ipv4addr_param);
/* No need to add an address, we are using 0.0.0.0 */
TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
break;
#endif
#ifdef INET6
case AF_INET6:
aa->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
aa->ap.addrp.ph.param_length = sizeof (struct sctp_ipv6addr_param);
/* No need to add an address, we are using 0.0.0.0 */
TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
break;
#endif
default:
SCTPDBG(SCTP_DEBUG_ASCONF1,
"sctp_asconf_send_nat_state_update: unknown address family\n");
SCTP_FREE(aa, SCTP_M_ASC_ADDR);
return;
"sctp_asconf_send_nat_state_update: unknown address family %d\n",
net->ro._l_addr.sa.sa_family);
goto out;
}
TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa_vtag, next);
TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa_add, next);
TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa_del, next);
/* Now we must hunt the addresses and add all global addresses */
if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
struct sctp_vrf *vrf = NULL;

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.h 362377 2020-06-19 12:35:29Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_ASCONF_H_
@ -61,7 +61,6 @@ extern uint32_t
sctp_addr_mgmt_ep_sa(struct sctp_inpcb *, struct sockaddr *, uint32_t,
uint32_t);
extern int sctp_asconf_iterator_ep(struct sctp_inpcb *inp, void *ptr,
uint32_t val);
extern void sctp_asconf_iterator_stcb(struct sctp_inpcb *inp,
@ -69,7 +68,6 @@ extern void sctp_asconf_iterator_stcb(struct sctp_inpcb *inp,
void *ptr, uint32_t type);
extern void sctp_asconf_iterator_end(void *ptr, uint32_t val);
extern int32_t
sctp_set_primary_ip_address_sa(struct sctp_tcb *,
struct sockaddr *);

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.c 362054 2020-06-11 13:34:09Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
@ -53,7 +53,6 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.c 362054 2020-06-11 13:34:09Z tue
#define SCTP_AUTH_DEBUG2 (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_AUTH2)
#endif /* SCTP_DEBUG */
void
sctp_clear_chunklist(sctp_auth_chklist_t *chklist)
{
@ -101,7 +100,6 @@ sctp_copy_chunklist(sctp_auth_chklist_t *list)
return (new_list);
}
/*
* add a chunk to the required chunks list
*/
@ -241,7 +239,6 @@ sctp_unpack_auth_chunks(const uint8_t *ptr, uint8_t num_chunks,
return (size);
}
/*
* allocate structure space for a key of length keylen
*/
@ -458,7 +455,6 @@ sctp_compute_hashkey(sctp_key_t *key1, sctp_key_t *key2, sctp_key_t *shared)
return (new_key);
}
sctp_sharedkey_t *
sctp_alloc_sharedkey(void)
{
@ -632,7 +628,6 @@ sctp_copy_skeylist(const struct sctp_keyhead *src, struct sctp_keyhead *dest)
return (count);
}
sctp_hmaclist_t *
sctp_alloc_hmaclist(uint16_t num_hmacs)
{
@ -826,7 +821,6 @@ sctp_free_authinfo(sctp_authinfo_t *authinfo)
/* SCTP_FREE(authinfo, SCTP_M_AUTH_??); */
}
uint32_t
sctp_get_auth_chunk_len(uint16_t hmac_algo)
{
@ -1166,7 +1160,6 @@ sctp_auth_is_supported_hmac(sctp_hmaclist_t *list, uint16_t id)
return (0);
}
/*-
* clear any cached key(s) if they match the given key id on an association.
* the cached key(s) will be recomputed and re-cached at next use.
@ -1579,7 +1572,6 @@ sctp_fill_hmac_digest_m(struct mbuf *m, uint32_t auth_offset,
m, auth_offset, auth->hmac);
}
static void
sctp_zero_m(struct mbuf *m, uint32_t m_offset, uint32_t size)
{
@ -1645,10 +1637,8 @@ sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *auth,
"SCTP AUTH Chunk: shared key %u, HMAC id %u\n",
shared_key_id, hmac_id);
#if defined(__Userspace__)
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
#if defined(__Userspace__) && defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
return (0);
#endif
#endif
/* is the indicated HMAC supported? */
if (!sctp_auth_is_supported_hmac(stcb->asoc.local_hmacs, hmac_id)) {
@ -1800,7 +1790,6 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, so_locked);
}
/*-
* validates the AUTHentication related parameters in an INIT/INIT-ACK
* Note: currently only used for INIT as INIT-ACK is handled inline
@ -1915,7 +1904,6 @@ sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
saw_asconf = 1;
if (chunks->chunk_types[i] == SCTP_ASCONF_ACK)
saw_asconf_ack = 1;
}
if (num_chunks)
got_chklist = 1;

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.h 338749 2018-09-18 10:53:07Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_AUTH_H_
@ -99,8 +99,6 @@ typedef struct sctp_authinformation {
uint16_t recv_keyid; /* last recv keyid (cached) */
} sctp_authinfo_t;
/*
* Macros
*/
@ -149,7 +147,6 @@ extern void sctp_auth_key_acquire(struct sctp_tcb *stcb, uint16_t keyid);
extern void sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t keyid,
int so_locked);
/* hmac list handling */
extern sctp_hmaclist_t *sctp_alloc_hmaclist(uint16_t num_hmacs);
extern void sctp_free_hmaclist(sctp_hmaclist_t *list);

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 358080 2020-02-18 19:41:55Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
@ -78,8 +78,8 @@ MALLOC_DEFINE(SCTP_M_MCORE, "sctp_mcore", "sctp mcore queue");
/* Global NON-VNET structure that controls the iterator */
struct iterator_control sctp_it_ctl;
#if !(defined(__FreeBSD__) && !defined(__Userspace__))
static void
sctp_cleanup_itqueue(void)
{
@ -195,7 +195,7 @@ sctp_startup_iterator(void)
kproc_create(sctp_iterator_thread,
(void *)NULL,
&sctp_it_ctl.thread_proc,
RFPROC,
0,
SCTP_KTHREAD_PAGES,
SCTP_KTRHEAD_NAME);
#elif defined(__APPLE__)
@ -244,7 +244,6 @@ sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa)
#endif /* __Userspace__ */
#endif /* INET6 */
#if !defined(__Userspace__)
static uint32_t
sctp_is_desired_interface_type(struct ifnet *ifn)
@ -294,13 +293,14 @@ sctp_is_desired_interface_type(struct ifnet *ifn)
return (result);
}
#endif
#if defined(__APPLE__) && !defined(__Userspace__)
int
sctp_is_vmware_interface(struct ifnet *ifn)
{
return (strncmp(ifnet_name(ifn), "vmnet", 5) == 0);
}
#endif
#if defined(_WIN32) && defined(__Userspace__)
@ -448,7 +448,7 @@ sctp_init_ifns_for_vrf(int vrfid)
#if defined(INET6)
if ((ifa->ifa_addr->sa_family == AF_INET6) &&
IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
/* skip unspecifed addresses */
/* skip unspecified addresses */
continue;
}
#endif
@ -476,7 +476,6 @@ sctp_init_ifns_for_vrf(int vrfid)
#endif
}
#endif
#if defined(__APPLE__) && !defined(__Userspace__)
static void
sctp_init_ifns_for_vrf(int vrfid)
@ -522,7 +521,7 @@ sctp_init_ifns_for_vrf(int vrfid)
}
if (ifa->ifa_addr->sa_family == AF_INET6) {
if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
/* skip unspecifed addresses */
/* skip unspecified addresses */
continue;
}
} else {
@ -555,7 +554,6 @@ sctp_init_ifns_for_vrf(int vrfid)
ifnet_list_free(ifnetlist);
}
#endif
#if defined(__FreeBSD__) && !defined(__Userspace__)
static void
sctp_init_ifns_for_vrf(int vrfid)
@ -596,7 +594,7 @@ sctp_init_ifns_for_vrf(int vrfid)
#ifdef INET6
case AF_INET6:
if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
/* skip unspecifed addresses */
/* skip unspecified addresses */
continue;
}
break;
@ -701,7 +699,7 @@ sctp_addr_change(struct ifaddr *ifa, int cmd)
case AF_INET6:
ifa_flags = ((struct in6_ifaddr *)ifa)->ia6_flags;
if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
/* skip unspecifed addresses */
/* skip unspecified addresses */
return;
}
break;
@ -719,7 +717,6 @@ sctp_addr_change(struct ifaddr *ifa, int cmd)
#endif
(void *)ifa, ifa->ifa_addr, ifa_flags, 1);
} else {
sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, ifa->ifa_addr,
#if defined(__APPLE__) && !defined(__Userspace__)
ifnet_index(ifa->ifa_ifp),
@ -777,9 +774,9 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
struct mbuf *m = NULL;
#if defined(__FreeBSD__) || defined(__Userspace__)
#if defined(__Userspace__)
m = m_getm2(NULL, space_needed, how, type, want_header ? M_PKTHDR : 0, allonebuf);
m = m_getm2(NULL, space_needed, how, type, want_header ? M_PKTHDR : 0, allonebuf);
#else
m = m_getm2(NULL, space_needed, how, type, want_header ? M_PKTHDR : 0);
m = m_getm2(NULL, space_needed, how, type, want_header ? M_PKTHDR : 0);
#endif
if (m == NULL) {
/* bad, no memory */
@ -791,7 +788,7 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
m_freem(m);
return (NULL);
}
KASSERT(SCTP_BUF_NEXT(m) == NULL, ("%s: no chain allowed", __FUNCTION__));
KASSERT(SCTP_BUF_NEXT(m) == NULL, ("%s: no chain allowed", __func__));
}
#endif
#ifdef SCTP_MBUF_LOGGING
@ -845,7 +842,6 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
return (m);
}
#ifdef SCTP_PACKET_LOGGING
void
sctp_packet_log(struct mbuf *m)
@ -921,7 +917,6 @@ sctp_packet_log(struct mbuf *m)
SCTP_BASE_VAR(packet_log_end));
SCTP_BASE_VAR(packet_log_end) = 0;
goto no_log;
}
lenat = (int *)&SCTP_BASE_VAR(packet_log_buffer)[thisbegin];
*lenat = total_len;
@ -947,7 +942,6 @@ sctp_packet_log(struct mbuf *m)
atomic_subtract_int(&SCTP_BASE_VAR(packet_log_writers), 1);
}
int
sctp_copy_out_packet_log(uint8_t *target, int length)
{
@ -955,11 +949,10 @@ sctp_copy_out_packet_log(uint8_t *target, int length)
* start copying up to length bytes out.
* We return the number of bytes copied.
*/
int tocopy, this_copy;
int this_copy;
int *lenat;
int did_delay = 0;
tocopy = length;
if (length < (int)(2 * sizeof(int))) {
/* not enough room */
return (0);
@ -987,7 +980,7 @@ sctp_copy_out_packet_log(uint8_t *target, int length)
memcpy((void *)lenat, (void *)SCTP_BASE_VAR(packet_log_buffer), this_copy);
if (SCTP_PKTLOG_WRITERS_NEED_LOCK) {
atomic_subtract_int(&SCTP_BASE_VAR(packet_log_writers),
SCTP_PKTLOG_WRITERS_NEED_LOCK);
SCTP_PKTLOG_WRITERS_NEED_LOCK);
}
SCTP_IP_PKTLOG_UNLOCK();
return (this_copy + sizeof(int));

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.h 353480 2019-10-13 18:17:08Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_BSD_ADDR_H_
@ -49,7 +49,6 @@ void sctp_wakeup_iterator(void);
void sctp_startup_iterator(void);
#ifdef INET6
void sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa);
#endif

View File

@ -136,7 +136,7 @@ sctp_os_timer_stop(sctp_os_timer_t *c)
/*
* Don't attempt to delete a callout that's not on the queue.
*/
if (!(c->c_flags & SCTP_CALLOUT_PENDING)) {
if ((c->c_flags & SCTP_CALLOUT_PENDING) == 0) {
c->c_flags &= ~SCTP_CALLOUT_ACTIVE;
SCTP_TIMERQ_UNLOCK();
return (0);

View File

@ -95,6 +95,11 @@ int sctp_os_timer_stop(sctp_os_timer_t *);
void sctp_handle_tick(uint32_t);
#define SCTP_OS_TIMER_INIT sctp_os_timer_init
/*
* NOTE: The next two shouldn't be called directly outside of sctp_timer_start()
* and sctp_timer_stop(), since they don't handle incrementing/decrementing
* relevant reference counts.
*/
#define SCTP_OS_TIMER_START sctp_os_timer_start
#define SCTP_OS_TIMER_STOP sctp_os_timer_stop
/* MT FIXME: Is the following correct? */

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_cc_functions.c 359405 2020-03-28 20:25:45Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
@ -64,7 +64,7 @@ sctp_enforce_cwnd_limit(struct sctp_association *assoc, struct sctp_nets *net)
if ((assoc->max_cwnd > 0) &&
(net->cwnd > assoc->max_cwnd) &&
(net->cwnd > (net->mtu - sizeof(struct sctphdr)))) {
net->cwnd = assoc->max_cwnd ;
net->cwnd = assoc->max_cwnd;
if (net->cwnd < (net->mtu - sizeof(struct sctphdr))) {
net->cwnd = net->mtu - sizeof(struct sctphdr);
}
@ -163,7 +163,6 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb,
(uint64_t)net->mtu *
(uint64_t)net->ssthresh) /
(uint64_t)t_ssthresh);
}
if (asoc->sctp_cmt_on_off == SCTP_CMT_RPV2) {
uint32_t srtt;
@ -251,15 +250,14 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb,
#define SCTP_INST_NEUTRAL 2 /* Neutral, no indication */
#define SCTP_INST_GAINING 3 /* Gaining, step down possible */
#if defined(__FreeBSD__) && !defined(__Userspace__)
static int
cc_bw_same(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw,
uint64_t rtt_offset, uint64_t vtag, uint8_t inst_ind)
uint64_t rtt_offset, uint64_t vtag, uint8_t inst_ind)
#else
static int
cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nbw,
uint64_t rtt_offset, uint8_t inst_ind)
uint64_t rtt_offset, uint8_t inst_ind)
#endif
{
#if defined(__FreeBSD__) && !defined(__Userspace__)
@ -410,11 +408,11 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
#if defined(__FreeBSD__) && !defined(__Userspace__)
static int
cc_bw_decrease(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw, uint64_t rtt_offset,
uint64_t vtag, uint8_t inst_ind)
uint64_t vtag, uint8_t inst_ind)
#else
static int
cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nbw, uint64_t rtt_offset,
uint8_t inst_ind)
uint8_t inst_ind)
#endif
{
#if defined(__FreeBSD__) && !defined(__Userspace__)
@ -766,7 +764,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
#if defined(__FreeBSD__) && !defined(__Userspace__)
int old_cwnd;
#endif
uint32_t t_ssthresh, t_cwnd, incr;
uint32_t t_ssthresh, incr;
uint64_t t_ucwnd_sbw;
uint64_t t_path_mptcp;
uint64_t mptcp_like_alpha;
@ -775,7 +773,6 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
/* MT FIXME: Don't compute this over and over again */
t_ssthresh = 0;
t_cwnd = 0;
t_ucwnd_sbw = 0;
t_path_mptcp = 0;
mptcp_like_alpha = 1;
@ -785,7 +782,6 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
max_path = 0;
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
t_ssthresh += net->ssthresh;
t_cwnd += net->cwnd;
/* lastsa>>3; we don't need to devide ...*/
srtt = net->lastsa;
if (srtt > 0) {
@ -817,7 +813,6 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
/* update cwnd and Early FR */
/******************************/
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
#ifdef JANA_CMT_FAST_RECOVERY
/*
* CMT fast recovery code. Need to debug.
@ -837,7 +832,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
continue;
}
#ifdef JANA_CMT_FAST_RECOVERY
/* CMT fast recovery code
/* CMT fast recovery code
*/
/*
if (sctp_cmt_on_off > 0 && net->fast_retran_loss_recovery && net->will_exit_fast_recovery == 0) {
@ -1008,7 +1003,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
net->partial_bytes_acked += net->net_ack;
if ((net->flight_size + net->net_ack >= net->cwnd) &&
(net->partial_bytes_acked >= net->cwnd)) {
(net->partial_bytes_acked >= net->cwnd)) {
net->partial_bytes_acked -= net->cwnd;
#if defined(__FreeBSD__) && !defined(__Userspace__)
old_cwnd = net->cwnd;
@ -1101,7 +1096,6 @@ sctp_cwnd_update_exit_pf_common(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_n
(void *)net, net->cwnd);
}
static void
sctp_cwnd_update_after_timeout(struct sctp_tcb *stcb, struct sctp_nets *net)
{
@ -1179,7 +1173,7 @@ sctp_cwnd_update_after_timeout(struct sctp_tcb *stcb, struct sctp_nets *net)
static void
sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets *net,
int in_window, int num_pkt_lost, int use_rtcc)
int in_window, int num_pkt_lost, int use_rtcc)
{
int old_cwnd = net->cwnd;
if ((use_rtcc) && (net->lan_type == SCTP_LAN_LOCAL) && (net->cc_mod.rtcc.use_dccc_ecn)) {
@ -1207,10 +1201,9 @@ sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets *
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SAT);
}
}
SCTP_STAT_INCR(sctps_ecnereducedcwnd);
} else {
} else {
if (in_window == 0) {
SCTP_STAT_INCR(sctps_ecnereducedcwnd);
net->ssthresh = net->cwnd / 2;
@ -1357,7 +1350,7 @@ sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb,
static void
sctp_cwnd_update_after_output(struct sctp_tcb *stcb,
struct sctp_nets *net, int burst_limit)
struct sctp_nets *net, int burst_limit)
{
int old_cwnd = net->cwnd;
@ -1381,8 +1374,8 @@ sctp_cwnd_update_after_output(struct sctp_tcb *stcb,
static void
sctp_cwnd_update_after_sack(struct sctp_tcb *stcb,
struct sctp_association *asoc,
int accum_moved, int reneged_all, int will_exit)
struct sctp_association *asoc,
int accum_moved, int reneged_all, int will_exit)
{
/* Passing a zero argument in last disables the rtcc algorithm */
sctp_cwnd_update_after_sack_common(stcb, asoc, accum_moved, reneged_all, will_exit, 0);
@ -1390,7 +1383,7 @@ sctp_cwnd_update_after_sack(struct sctp_tcb *stcb,
static void
sctp_cwnd_update_after_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net,
int in_window, int num_pkt_lost)
int in_window, int num_pkt_lost)
{
/* Passing a zero argument in last disables the rtcc algorithm */
sctp_cwnd_update_after_ecn_echo_common(stcb, net, in_window, num_pkt_lost, 0);
@ -1403,25 +1396,23 @@ sctp_cwnd_update_after_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net,
*/
static void
sctp_cwnd_update_rtcc_after_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net,
int in_window, int num_pkt_lost)
int in_window, int num_pkt_lost)
{
sctp_cwnd_update_after_ecn_echo_common(stcb, net, in_window, num_pkt_lost, 1);
}
static
void sctp_cwnd_update_rtcc_tsn_acknowledged(struct sctp_nets *net,
struct sctp_tmit_chunk *tp1)
static void sctp_cwnd_update_rtcc_tsn_acknowledged(struct sctp_nets *net,
struct sctp_tmit_chunk *tp1)
{
net->cc_mod.rtcc.bw_bytes += tp1->send_size;
}
static void
sctp_cwnd_prepare_rtcc_net_for_sack(struct sctp_tcb *stcb SCTP_UNUSED,
struct sctp_nets *net)
struct sctp_nets *net)
{
if (net->cc_mod.rtcc.tls_needs_set > 0) {
/* We had a bw measurment going on */
/* We had a bw measurement going on */
struct timeval ltls;
SCTP_GETPTIME_TIMEVAL(&ltls);
timevalsub(&ltls, &net->cc_mod.rtcc.tls);
@ -1431,7 +1422,7 @@ sctp_cwnd_prepare_rtcc_net_for_sack(struct sctp_tcb *stcb SCTP_UNUSED,
static void
sctp_cwnd_new_rtcc_transmission_begins(struct sctp_tcb *stcb,
struct sctp_nets *net)
struct sctp_nets *net)
{
#if defined(__FreeBSD__) && !defined(__Userspace__)
uint64_t vtag, probepoint;
@ -1492,7 +1483,7 @@ sctp_cwnd_new_rtcc_transmission_begins(struct sctp_tcb *stcb,
static void
sctp_set_rtcc_initial_cc_param(struct sctp_tcb *stcb,
struct sctp_nets *net)
struct sctp_nets *net)
{
#if defined(__FreeBSD__) && !defined(__Userspace__)
uint64_t vtag, probepoint;
@ -1527,15 +1518,14 @@ sctp_set_rtcc_initial_cc_param(struct sctp_tcb *stcb,
net->cc_mod.rtcc.use_dccc_ecn = SCTP_BASE_SYSCTL(sctp_use_dccc_ecn);
net->cc_mod.rtcc.step_cnt = 0;
net->cc_mod.rtcc.last_step_state = 0;
}
static int
sctp_cwnd_rtcc_socket_option(struct sctp_tcb *stcb, int setorget,
struct sctp_cc_option *cc_opt)
struct sctp_cc_option *cc_opt)
{
struct sctp_nets *net;
if (setorget == 1) {
/* a set */
if (cc_opt->option == SCTP_CC_OPT_RTCC_SETMODE) {
@ -1600,8 +1590,8 @@ sctp_cwnd_update_rtcc_packet_transmitted(struct sctp_tcb *stcb SCTP_UNUSED,
static void
sctp_cwnd_update_rtcc_after_sack(struct sctp_tcb *stcb,
struct sctp_association *asoc,
int accum_moved, int reneged_all, int will_exit)
struct sctp_association *asoc,
int accum_moved, int reneged_all, int will_exit)
{
/* Passing a one argument at the last enables the rtcc algorithm */
sctp_cwnd_update_after_sack_common(stcb, asoc, accum_moved, reneged_all, will_exit, 1);
@ -1842,15 +1832,14 @@ sctp_hs_cwnd_update_after_fr(struct sctp_tcb *stcb,
static void
sctp_hs_cwnd_update_after_sack(struct sctp_tcb *stcb,
struct sctp_association *asoc,
int accum_moved, int reneged_all SCTP_UNUSED, int will_exit)
struct sctp_association *asoc,
int accum_moved, int reneged_all SCTP_UNUSED, int will_exit)
{
struct sctp_nets *net;
/******************************/
/* update cwnd and Early FR */
/******************************/
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
#ifdef JANA_CMT_FAST_RECOVERY
/*
* CMT fast recovery code. Need to debug.
@ -1870,7 +1859,7 @@ sctp_hs_cwnd_update_after_sack(struct sctp_tcb *stcb,
continue;
}
#ifdef JANA_CMT_FAST_RECOVERY
/* CMT fast recovery code
/* CMT fast recovery code
*/
/*
if (sctp_cmt_on_off > 0 && net->fast_retran_loss_recovery && net->will_exit_fast_recovery == 0) {
@ -1934,7 +1923,6 @@ sctp_hs_cwnd_update_after_sack(struct sctp_tcb *stcb,
}
}
/*
* H-TCP congestion control. The algorithm is detailed in:
* R.N.Shorten, D.J.Leith:
@ -1943,7 +1931,6 @@ sctp_hs_cwnd_update_after_sack(struct sctp_tcb *stcb,
* http://www.hamilton.ie/net/htcp3.pdf
*/
static int use_rtt_scaling = 1;
static int use_bandwidth_switch = 1;
@ -2081,19 +2068,19 @@ htcp_alpha_update(struct htcp *ca)
if (diff > (uint32_t)hz) {
diff -= hz;
factor = 1+ ( 10*diff + ((diff/2)*(diff/2)/hz))/hz;
factor = 1+ (10 * diff + ((diff / 2) * (diff / 2) / hz)) / hz;
}
if (use_rtt_scaling && minRTT) {
uint32_t scale = (hz<<3)/(10*minRTT);
scale = min(max(scale, 1U<<2), 10U<<3); /* clamping ratio to interval [0.5,10]<<3 */
factor = (factor<<3)/scale;
if (!factor)
uint32_t scale = (hz << 3) / (10 * minRTT);
scale = min(max(scale, 1U << 2), 10U << 3); /* clamping ratio to interval [0.5,10]<<3 */
factor = (factor << 3) / scale;
if (factor != 0)
factor = 1;
}
ca->alpha = 2*factor*((1<<7)-ca->beta);
if (!ca->alpha)
ca->alpha = 2 * factor * ((1 << 7) - ca->beta);
if (ca->alpha != 0)
ca->alpha = ALPHA_BASE;
}
@ -2131,10 +2118,10 @@ htcp_cong_avoid(struct sctp_tcb *stcb, struct sctp_nets *net)
{
/*-
* How to handle these functions?
* if (!tcp_is_cwnd_limited(sk, in_flight)) RRS - good question.
* if (!tcp_is_cwnd_limited(sk, in_flight)) RRS - good question.
* return;
*/
if (net->cwnd <= net->ssthresh) {
if (net->cwnd <= net->ssthresh) {
/* We are in slow start */
if (net->flight_size + net->net_ack >= net->cwnd) {
if (net->net_ack > (net->mtu * SCTP_BASE_SYSCTL(sctp_L2_abc_variable))) {
@ -2150,7 +2137,6 @@ htcp_cong_avoid(struct sctp_tcb *stcb, struct sctp_nets *net)
sctp_log_cwnd(stcb, net, net->net_ack,
SCTP_CWND_LOG_FROM_SS);
}
}
sctp_enforce_cwnd_limit(&stcb->asoc, net);
} else {
@ -2167,7 +2153,7 @@ htcp_cong_avoid(struct sctp_tcb *stcb, struct sctp_nets *net)
*/
/* What is snd_cwnd_cnt?? */
if (((net->partial_bytes_acked/net->mtu * net->cc_mod.htcp_ca.alpha) >> 7)*net->mtu >= net->cwnd) {
/*-
/*-
* Does SCTP have a cwnd clamp?
* if (net->snd_cwnd < net->snd_cwnd_clamp) - Nope (RRS).
*/
@ -2238,7 +2224,6 @@ sctp_htcp_cwnd_update_after_sack(struct sctp_tcb *stcb,
/* update cwnd and Early FR */
/******************************/
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
#ifdef JANA_CMT_FAST_RECOVERY
/*
* CMT fast recovery code. Need to debug.
@ -2258,7 +2243,7 @@ sctp_htcp_cwnd_update_after_sack(struct sctp_tcb *stcb,
continue;
}
#ifdef JANA_CMT_FAST_RECOVERY
/* CMT fast recovery code
/* CMT fast recovery code
*/
/*
if (sctp_cmt_on_off > 0 && net->fast_retran_loss_recovery && net->will_exit_fast_recovery == 0) {

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_constants.h 362107 2020-06-12 16:40:10Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_CONSTANTS_H_
@ -42,8 +42,8 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_constants.h 362107 2020-06-12 16:40:10
#if defined(_WIN32) && defined(__Userspace__)
extern void getwintimeofday(struct timeval *tv);
#endif
#endif
/* IANA assigned port number for SCTP over UDP encapsulation */
#define SCTP_OVER_UDP_TUNNELING_PORT 9899
@ -92,13 +92,11 @@ extern void getwintimeofday(struct timeval *tv);
/* #define SCTP_AUDITING_ENABLED 1 used for debug/auditing */
#define SCTP_AUDIT_SIZE 256
#define SCTP_KTRHEAD_NAME "sctp_iterator"
#define SCTP_KTHREAD_PAGES 0
#define SCTP_MCORE_NAME "sctp_core_worker"
/* If you support Multi-VRF how big to
* make the initial array of VRF's to.
*/
@ -268,7 +266,6 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_LOCK_UNKNOWN 2
/* number of associations by default for zone allocation */
#define SCTP_MAX_NUM_OF_ASOC 40000
/* how many addresses per assoc remote and local */
@ -393,7 +390,6 @@ extern void getwintimeofday(struct timeval *tv);
#define IS_SCTP_CONTROL(a) (((a)->chunk_type != SCTP_DATA) && ((a)->chunk_type != SCTP_IDATA))
#define IS_SCTP_DATA(a) (((a)->chunk_type == SCTP_DATA) || ((a)->chunk_type == SCTP_IDATA))
/* SCTP parameter types */
/*************0x0000 series*************/
#define SCTP_HEARTBEAT_INFO 0x0001
@ -458,7 +454,6 @@ extern void getwintimeofday(struct timeval *tv);
/* mask to get sticky */
#define SCTP_STICKY_OPTIONS_MASK 0x0c
/*
* SCTP states for internal state machine
*/
@ -562,12 +557,11 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_IS_TIMER_TYPE_VALID(t) (((t) > SCTP_TIMER_TYPE_NONE) && \
((t) < SCTP_TIMER_TYPE_LAST))
#if defined(__APPLE__) && !defined(__Userspace__)
/* Number of ticks to run the main timer at in msec */
#define SCTP_MAIN_TIMER_DEFAULT 10
#endif
#endif
/* max number of TSN's dup'd that I will hold */
#define SCTP_MAX_DUP_TSNS 20
@ -616,8 +610,7 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_RTO_UPPER_BOUND (60000) /* 60 sec in ms */
#define SCTP_RTO_LOWER_BOUND (1000) /* 1 sec is ms */
#define SCTP_RTO_INITIAL (3000) /* 3 sec in ms */
#define SCTP_RTO_INITIAL (1000) /* 1 sec in ms */
#define SCTP_INP_KILL_TIMEOUT 20 /* number of ms to retry kill of inpcb */
#define SCTP_ASOC_KILL_TIMEOUT 10 /* number of ms to retry kill of inpcb */
@ -629,7 +622,6 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_DEF_PMTU_RAISE_SEC 600 /* 10 min between raise attempts */
/* How many streams I request initially by default */
#define SCTP_OSTREAM_INITIAL 10
#define SCTP_ISTREAM_INITIAL 2048
@ -699,8 +691,6 @@ extern void getwintimeofday(struct timeval *tv);
/* amount peer is obligated to have in rwnd or I will abort */
#define SCTP_MIN_RWND 1500
#define SCTP_DEFAULT_MAXSEGMENT 65535
#define SCTP_CHUNK_BUFFER_SIZE 512
#define SCTP_PARAM_BUFFER_SIZE 512
@ -712,7 +702,6 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_NUMBER_OF_SECRETS 8 /* or 8 * 4 = 32 octets */
#define SCTP_SECRET_SIZE 32 /* number of octets in a 256 bits */
/*
* SCTP upper layer notifications
*/
@ -743,6 +732,7 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_NOTIFY_NO_PEER_AUTH 25
#define SCTP_NOTIFY_SENDER_DRY 26
#define SCTP_NOTIFY_REMOTE_ERROR 27
#define SCTP_NOTIFY_ASSOC_TIMEDOUT 28
/* This is the value for messages that are NOT completely
* copied down where we will start to split the message.
@ -753,7 +743,11 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_DEFAULT_SPLIT_POINT_MIN 2904
/* Maximum length of diagnostic information in error causes */
#if defined(__Userspace__)
#define SCTP_DIAG_INFO_LEN 256
#else
#define SCTP_DIAG_INFO_LEN 128
#endif
/* ABORT CODES and other tell-tale location
* codes are generated by adding the below
@ -811,6 +805,7 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_LOC_34 0x00000022
#define SCTP_LOC_35 0x00000023
#define SCTP_LOC_36 0x00000024
#define SCTP_LOC_37 0x00000025
/* Free assoc codes */
#define SCTP_NORMAL_PROC 0
@ -830,7 +825,6 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_DONOT_SETSCOPE 0
#define SCTP_DO_SETSCOPE 1
/* This value determines the default for when
* we try to add more on the send queue., if
* there is room. This prevents us from cycling
@ -913,7 +907,6 @@ extern void getwintimeofday(struct timeval *tv);
} \
} while (0)
#define SCTP_RETRAN_DONE -1
#define SCTP_RETRAN_EXIT -2
@ -969,7 +962,6 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_SO_LOCKED 1
#define SCTP_SO_NOT_LOCKED 0
/*-
* For address locks, do we hold the lock?
*/
@ -1003,7 +995,6 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_GETPTIME_TIMEVAL(x) gettimeofday(x, NULL)
#endif
#endif
#if defined(_KERNEL)
#define SCTP_GETTIME_TIMEVAL(x) (getmicrouptime(x))
#define SCTP_GETPTIME_TIMEVAL(x) (microuptime(x))
@ -1013,7 +1004,7 @@ extern void getwintimeofday(struct timeval *tv);
#define sctp_sowwakeup(inp, so) \
do { \
if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { \
inp->sctp_flags |= SCTP_PCB_FLAGS_WAKEOUTPUT; \
sctp_pcb_add_flags(inp, SCTP_PCB_FLAGS_WAKEOUTPUT); \
} else { \
sowwakeup(so); \
} \
@ -1023,8 +1014,8 @@ do { \
#define sctp_sowwakeup_locked(inp, so) \
do { \
if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { \
sctp_pcb_add_flags(inp, SCTP_PCB_FLAGS_WAKEOUTPUT); \
SOCKBUF_UNLOCK(&((so)->so_snd)); \
inp->sctp_flags |= SCTP_PCB_FLAGS_WAKEOUTPUT; \
} else { \
sowwakeup_locked(so); \
} \
@ -1033,8 +1024,8 @@ do { \
#define sctp_sowwakeup_locked(inp, so) \
do { \
if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { \
sctp_pcb_add_flags(inp, SCTP_PCB_FLAGS_WAKEOUTPUT); \
SOCKBUF_UNLOCK(&((so)->so_snd)); \
inp->sctp_flags |= SCTP_PCB_FLAGS_WAKEOUTPUT; \
} else { \
sowwakeup(so); \
} \
@ -1044,7 +1035,7 @@ do { \
#define sctp_sorwakeup(inp, so) \
do { \
if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { \
inp->sctp_flags |= SCTP_PCB_FLAGS_WAKEINPUT; \
sctp_pcb_add_flags(inp, SCTP_PCB_FLAGS_WAKEINPUT); \
} else { \
sorwakeup(so); \
} \
@ -1054,7 +1045,7 @@ do { \
#define sctp_sorwakeup_locked(inp, so) \
do { \
if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { \
inp->sctp_flags |= SCTP_PCB_FLAGS_WAKEINPUT; \
sctp_pcb_add_flags(inp, SCTP_PCB_FLAGS_WAKEINPUT); \
SOCKBUF_UNLOCK(&((so)->so_rcv)); \
} else { \
sorwakeup_locked(so); \
@ -1065,7 +1056,7 @@ do { \
#define sctp_sorwakeup_locked(inp, so) \
do { \
if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { \
inp->sctp_flags |= SCTP_PCB_FLAGS_WAKEINPUT; \
sctp_pcb_add_flags(inp, SCTP_PCB_FLAGS_WAKEINPUT); \
SOCKBUF_UNLOCK(&((so)->so_rcv)); \
} else { \
sorwakeup(so); \

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_crc32.c 362498 2020-06-22 14:36:14Z tuexen $");
__FBSDID("$FreeBSD$");
#include "opt_sctp.h"
@ -733,31 +733,34 @@ static uint32_t
#endif
sctp_finalize_crc32c(uint32_t crc32c)
{
uint32_t result;
#if BYTE_ORDER == BIG_ENDIAN
uint8_t byte0, byte1, byte2, byte3;
uint32_t byte0, byte1, byte2, byte3;
#endif
/* Complement the result */
result = ~crc32c;
#if BYTE_ORDER == BIG_ENDIAN
/*
* For BIG-ENDIAN platforms the result is in little-endian form. So we
* must swap the bytes to return the result in network byte order.
* For BIG-ENDIAN platforms, the result is in LITTLE-ENDIAN byte order.
* For LITTLE-ENDIAN platforms, the result is in in BIG-ENDIAN byte
* order. So for BIG-ENDIAN platforms the bytes must be swapped to
* return the result always in network byte order (aka BIG-ENDIAN).
*/
byte0 = result & 0x000000ff;
byte1 = (result >> 8) & 0x000000ff;
byte2 = (result >> 16) & 0x000000ff;
byte3 = (result >> 24) & 0x000000ff;
byte0 = crc32c & 0x000000ff;
byte1 = (crc32c >> 8) & 0x000000ff;
byte2 = (crc32c >> 16) & 0x000000ff;
byte3 = (crc32c >> 24) & 0x000000ff;
crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
#else
/*
* For LITTLE ENDIAN platforms the result is in already in network
* byte order.
*/
crc32c = result;
#endif
return (crc32c);
return (~crc32c);
}
static int
sctp_calculate_cksum_cb(void *arg, void *data, u_int len)
{
uint32_t *basep;
basep = arg;
*basep = calculate_crc32c(*basep, data, len);
return (0);
}
/*
@ -767,32 +770,19 @@ sctp_finalize_crc32c(uint32_t crc32c)
* it is compiled on a kernel with SCTP support.
*/
uint32_t
sctp_calculate_cksum(struct mbuf *m, uint32_t offset)
sctp_calculate_cksum(struct mbuf *m, int32_t offset)
{
uint32_t base = 0xffffffff;
uint32_t base;
int len;
while (offset > 0) {
KASSERT(m != NULL, ("sctp_calculate_cksum, offset > length of mbuf chain"));
if (offset < (uint32_t)m->m_len) {
break;
}
offset -= m->m_len;
m = m->m_next;
}
if (offset > 0) {
base = calculate_crc32c(base,
(unsigned char *)(m->m_data + offset),
(unsigned int)(m->m_len - offset));
m = m->m_next;
}
while (m != NULL) {
base = calculate_crc32c(base,
(unsigned char *)m->m_data,
(unsigned int)m->m_len);
m = m->m_next;
}
base = sctp_finalize_crc32c(base);
return (base);
M_ASSERTPKTHDR(m);
KASSERT(offset < m->m_pkthdr.len,
("%s: invalid offset %u into mbuf %p", __func__, offset, m));
base = 0xffffffff;
len = m->m_pkthdr.len - offset;
(void)m_apply(m, offset, len, sctp_calculate_cksum_cb, &base);
return (sctp_finalize_crc32c(base));
}
#if defined(__FreeBSD__) && !defined(__Userspace__)

View File

@ -34,14 +34,14 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_crc32.h 362338 2020-06-18 19:32:34Z markj $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_CRC32_H_
#define _NETINET_SCTP_CRC32_H_
#if defined(_KERNEL)
uint32_t sctp_calculate_cksum(struct mbuf *, uint32_t);
uint32_t sctp_calculate_cksum(struct mbuf *, int32_t);
#if defined(__FreeBSD__) && !defined(__Userspace__)
#if defined(SCTP) || defined(SCTP_SUPPORT)
void sctp_delayed_cksum(struct mbuf *, uint32_t offset);
@ -51,6 +51,6 @@ void sctp_delayed_cksum(struct mbuf *, uint32_t offset);
#if defined(__Userspace__)
uint32_t calculate_crc32c(uint32_t, const unsigned char *, unsigned int);
uint32_t sctp_finalize_crc32c(uint32_t);
uint32_t sctp_calculate_cksum(struct mbuf *, uint32_t);
uint32_t sctp_calculate_cksum(struct mbuf *, int32_t);
#endif
#endif /* __crc32c_h__ */

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_header.h 309682 2016-12-07 19:30:59Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_HEADER_H_
@ -66,7 +66,6 @@ struct sctp_ipv4addr_param {
#define SCTP_V6_ADDR_BYTES 16
struct sctp_ipv6addr_param {
struct sctp_paramhdr ph;/* type=SCTP_IPV6_PARAM_TYPE, len=20 */
uint8_t addr[SCTP_V6_ADDR_BYTES]; /* IPV6 address */
@ -110,14 +109,12 @@ struct sctp_heartbeat_info_param {
char address[SCTP_ADDRMAX];
} SCTP_PACKED;
/* draft-ietf-tsvwg-prsctp */
/* PR-SCTP supported parameter */
struct sctp_prsctp_supported_param {
struct sctp_paramhdr ph;
} SCTP_PACKED;
/* draft-ietf-tsvwg-addip-sctp */
struct sctp_asconf_paramhdr { /* an ASCONF "parameter" */
struct sctp_paramhdr ph;/* a SCTP parameter header */
@ -129,14 +126,12 @@ struct sctp_asconf_addr_param { /* an ASCONF address parameter */
struct sctp_ipv6addr_param addrp; /* max storage size */
} SCTP_PACKED;
struct sctp_asconf_tag_param { /* an ASCONF NAT-Vtag parameter */
struct sctp_asconf_paramhdr aph; /* asconf "parameter" */
uint32_t local_vtag;
uint32_t remote_vtag;
uint32_t local_vtag;
uint32_t remote_vtag;
} SCTP_PACKED;
struct sctp_asconf_addrv4_param { /* an ASCONF address (v4) parameter */
struct sctp_asconf_paramhdr aph; /* asconf "parameter" */
struct sctp_ipv4addr_param addrp; /* max storage size */
@ -149,7 +144,6 @@ struct sctp_supported_chunk_types_param {
uint8_t chunk_types[];
} SCTP_PACKED;
/*
* Structures for DATA chunks
*/
@ -260,7 +254,6 @@ struct sctp_init_msg {
#define sctp_init_ack_chunk sctp_init_chunk
#define sctp_init_ack_msg sctp_init_msg
/* Selective Ack (SACK) */
struct sctp_gap_ack_block {
uint16_t start; /* Gap Ack block start */
@ -297,7 +290,6 @@ struct sctp_nr_sack_chunk {
struct sctp_nr_sack nr_sack;
} SCTP_PACKED;
/* Heartbeat Request (HEARTBEAT) */
struct sctp_heartbeat {
struct sctp_heartbeat_info_param hb_info;
@ -312,7 +304,6 @@ struct sctp_heartbeat_chunk {
#define sctp_heartbeat_ack sctp_heartbeat
#define sctp_heartbeat_ack_chunk sctp_heartbeat_chunk
/* Abort Asssociation (ABORT) */
struct sctp_abort_chunk {
struct sctp_chunkhdr ch;
@ -324,27 +315,23 @@ struct sctp_abort_msg {
struct sctp_abort_chunk msg;
} SCTP_PACKED;
/* Shutdown Association (SHUTDOWN) */
struct sctp_shutdown_chunk {
struct sctp_chunkhdr ch;
uint32_t cumulative_tsn_ack;
} SCTP_PACKED;
/* Shutdown Acknowledgment (SHUTDOWN ACK) */
struct sctp_shutdown_ack_chunk {
struct sctp_chunkhdr ch;
} SCTP_PACKED;
/* Operation Error (ERROR) */
struct sctp_error_chunk {
struct sctp_chunkhdr ch;
/* optional error causes follow */
} SCTP_PACKED;
/* Cookie Echo (COOKIE ECHO) */
struct sctp_cookie_echo_chunk {
struct sctp_chunkhdr ch;
@ -436,7 +423,6 @@ struct sctp_chunk_desc {
uint32_t tsn_ifany;
} SCTP_PACKED;
struct sctp_pktdrop_chunk {
struct sctp_chunkhdr ch;
uint32_t bottle_bw;
@ -487,10 +473,10 @@ struct sctp_stream_reset_response_tsn {
} SCTP_PACKED;
struct sctp_stream_reset_add_strm {
struct sctp_paramhdr ph;
uint32_t request_seq;
uint16_t number_of_streams;
uint16_t reserved;
struct sctp_paramhdr ph;
uint32_t request_seq;
uint16_t number_of_streams;
uint16_t reserved;
} SCTP_PACKED;
#define SCTP_STREAM_RESET_RESULT_NOTHING_TO_DO 0x00000000 /* XXX: unused */
@ -563,43 +549,41 @@ struct sctp_auth_chunk {
#ifndef SCTP_MAX_OVERHEAD
#ifdef INET6
#define SCTP_MAX_OVERHEAD (sizeof(struct sctp_data_chunk) + \
sizeof(struct sctphdr) + \
sizeof(struct sctp_ecne_chunk) + \
sizeof(struct sctp_sack_chunk) + \
sizeof(struct ip6_hdr))
sizeof(struct sctphdr) + \
sizeof(struct sctp_ecne_chunk) + \
sizeof(struct sctp_sack_chunk) + \
sizeof(struct ip6_hdr))
#define SCTP_MED_OVERHEAD (sizeof(struct sctp_data_chunk) + \
sizeof(struct sctphdr) + \
sizeof(struct ip6_hdr))
sizeof(struct sctphdr) + \
sizeof(struct ip6_hdr))
#define SCTP_MIN_OVERHEAD (sizeof(struct ip6_hdr) + \
sizeof(struct sctphdr))
sizeof(struct sctphdr))
#else
#define SCTP_MAX_OVERHEAD (sizeof(struct sctp_data_chunk) + \
sizeof(struct sctphdr) + \
sizeof(struct sctp_ecne_chunk) + \
sizeof(struct sctp_sack_chunk) + \
sizeof(struct ip))
sizeof(struct sctphdr) + \
sizeof(struct sctp_ecne_chunk) + \
sizeof(struct sctp_sack_chunk) + \
sizeof(struct ip))
#define SCTP_MED_OVERHEAD (sizeof(struct sctp_data_chunk) + \
sizeof(struct sctphdr) + \
sizeof(struct ip))
sizeof(struct sctphdr) + \
sizeof(struct ip))
#define SCTP_MIN_OVERHEAD (sizeof(struct ip) + \
sizeof(struct sctphdr))
sizeof(struct sctphdr))
#endif /* INET6 */
#endif /* !SCTP_MAX_OVERHEAD */
#define SCTP_MED_V4_OVERHEAD (sizeof(struct sctp_data_chunk) + \
sizeof(struct sctphdr) + \
sizeof(struct ip))
sizeof(struct sctphdr) + \
sizeof(struct ip))
#define SCTP_MIN_V4_OVERHEAD (sizeof(struct ip) + \
sizeof(struct sctphdr))
sizeof(struct sctphdr))
#if defined(_WIN32) && !defined(__Userspace__)
#include <packoff.h>

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 363076 2020-07-10 11:15:10Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
@ -74,7 +74,6 @@ sctp_add_chk_to_control(struct sctp_queued_to_read *control,
struct sctp_association *asoc,
struct sctp_tmit_chunk *chk, int hold_rlock);
void
sctp_set_rwnd(struct sctp_tcb *stcb, struct sctp_association *asoc)
{
@ -134,8 +133,6 @@ sctp_calc_rwnd(struct sctp_tcb *stcb, struct sctp_association *asoc)
return (calc);
}
/*
* Build out our readq entry based on the incoming packet.
*/
@ -306,19 +303,18 @@ sctp_build_ctl_nchunk(struct sctp_inpcb *inp, struct sctp_sndrcvinfo *sinfo)
return (ret);
}
static void
sctp_mark_non_revokable(struct sctp_association *asoc, uint32_t tsn)
{
uint32_t gap, i, cumackp1;
int fnd = 0;
int in_r=0, in_nr=0;
uint32_t gap, i;
int in_r, in_nr;
if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
return;
}
cumackp1 = asoc->cumulative_tsn + 1;
if (SCTP_TSN_GT(cumackp1, tsn)) {
/* this tsn is behind the cum ack and thus we don't
if (SCTP_TSN_GE(asoc->cumulative_tsn, tsn)) {
/*
* This tsn is behind the cum ack and thus we don't
* need to worry about it being moved from one to the other.
*/
return;
@ -326,33 +322,27 @@ sctp_mark_non_revokable(struct sctp_association *asoc, uint32_t tsn)
SCTP_CALC_TSN_TO_GAP(gap, tsn, asoc->mapping_array_base_tsn);
in_r = SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap);
in_nr = SCTP_IS_TSN_PRESENT(asoc->nr_mapping_array, gap);
if ((in_r == 0) && (in_nr == 0)) {
#ifdef INVARIANTS
panic("Things are really messed up now");
#else
SCTP_PRINTF("gap:%x tsn:%x\n", gap, tsn);
sctp_print_mapping_array(asoc);
#endif
}
if (in_nr == 0)
KASSERT(in_r || in_nr, ("%s: Things are really messed up now", __func__));
if (!in_nr) {
SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
if (in_r)
SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
if (SCTP_TSN_GT(tsn, asoc->highest_tsn_inside_nr_map)) {
asoc->highest_tsn_inside_nr_map = tsn;
}
if (tsn == asoc->highest_tsn_inside_map) {
/* We must back down to see what the new highest is */
for (i = tsn - 1; SCTP_TSN_GE(i, asoc->mapping_array_base_tsn); i--) {
SCTP_CALC_TSN_TO_GAP(gap, i, asoc->mapping_array_base_tsn);
if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
asoc->highest_tsn_inside_map = i;
fnd = 1;
break;
}
if (SCTP_TSN_GT(tsn, asoc->highest_tsn_inside_nr_map)) {
asoc->highest_tsn_inside_nr_map = tsn;
}
if (!fnd) {
asoc->highest_tsn_inside_map = asoc->mapping_array_base_tsn - 1;
}
if (in_r) {
SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
if (tsn == asoc->highest_tsn_inside_map) {
/* We must back down to see what the new highest is. */
for (i = tsn - 1; SCTP_TSN_GE(i, asoc->mapping_array_base_tsn); i--) {
SCTP_CALC_TSN_TO_GAP(gap, i, asoc->mapping_array_base_tsn);
if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
asoc->highest_tsn_inside_map = i;
break;
}
}
if (!SCTP_TSN_GE(i, asoc->mapping_array_base_tsn)) {
asoc->highest_tsn_inside_map = asoc->mapping_array_base_tsn - 1;
}
}
}
}
@ -407,7 +397,7 @@ sctp_place_control_in_stream(struct sctp_stream_in *strm,
if (unordered) {
control->on_strm_q = SCTP_ON_UNORDERED;
} else {
control->on_strm_q = SCTP_ON_ORDERED ;
control->on_strm_q = SCTP_ON_ORDERED;
}
break;
} else if (SCTP_MID_EQ(asoc->idata_supported, at->mid, control->mid)) {
@ -428,9 +418,9 @@ sctp_place_control_in_stream(struct sctp_stream_in *strm,
}
TAILQ_INSERT_AFTER(q, at, control, next_instrm);
if (unordered) {
control->on_strm_q = SCTP_ON_UNORDERED ;
control->on_strm_q = SCTP_ON_UNORDERED;
} else {
control->on_strm_q = SCTP_ON_ORDERED ;
control->on_strm_q = SCTP_ON_ORDERED;
}
break;
}
@ -472,7 +462,7 @@ sctp_abort_in_reasm(struct sctp_tcb *stcb,
chk->data = NULL;
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_1;
sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
sctp_abort_an_association(stcb->sctp_ep, stcb, oper, false, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
}
@ -524,7 +514,7 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb,
* with TSN 1? If the peer is doing some sort of funky TSN/SSN
* assignment this could happen... and I don't see how this would be
* a violation. So for now I am undecided an will leave the sort by
* SSN alone. Maybe a hybred approach is the answer
* SSN alone. Maybe a hybrid approach is the answer
*
*/
struct sctp_queued_to_read *at;
@ -560,10 +550,9 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb,
}
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_2;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
return;
}
queue_needed = 1;
asoc->size_on_all_streams += control->length;
@ -668,13 +657,12 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb,
sctp_clean_up_control(stcb, control);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_3;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
}
}
}
static void
sctp_setup_tail_pointer(struct sctp_queued_to_read *control)
{
@ -850,7 +838,7 @@ restart:
}
memset(nc, 0, sizeof(struct sctp_queued_to_read));
TAILQ_REMOVE(&control->reasm, chk, sctp_next);
sctp_add_chk_to_control(control, strm, stcb, asoc, chk, SCTP_READ_LOCK_NOT_HELD);
sctp_add_chk_to_control(control, strm, stcb, asoc, chk, inp_read_lock_held);
fsn++;
cnt_added++;
chk = NULL;
@ -939,7 +927,7 @@ restart:
}
if (cnt_added && strm->pd_api_started) {
#if defined(__Userspace__)
sctp_invoke_recv_callback(stcb->sctp_ep, stcb, control, SCTP_READ_LOCK_NOT_HELD);
sctp_invoke_recv_callback(stcb->sctp_ep, stcb, control, inp_read_lock_held);
#endif
sctp_wakeup_the_read_socket(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
}
@ -1005,7 +993,7 @@ sctp_inject_old_unordered_data(struct sctp_tcb *stcb,
* we started the pd-api on the higher TSN (since
* the equals part is a TSN failure it must be that).
*
* We are completly hosed in that case since I have
* We are completely hosed in that case since I have
* no way to recover. This really will only happen
* if we can get more TSN's higher before the pd-api-point.
*/
@ -1079,7 +1067,6 @@ place_chunk:
SCTP_FROM_SCTP_INDATA + SCTP_LOC_5);
return;
}
}
if (inserted == 0) {
/* Its at the end */
@ -1134,7 +1121,7 @@ sctp_deliver_reasm_check(struct sctp_tcb *stcb, struct sctp_association *asoc,
/* We just put the last bit on */
if (control->on_strm_q) {
#ifdef INVARIANTS
if (control->on_strm_q != SCTP_ON_UNORDERED ) {
if (control->on_strm_q != SCTP_ON_UNORDERED) {
panic("Huh control: %p on_q: %d -- not unordered?",
control, control->on_strm_q);
}
@ -1198,7 +1185,7 @@ done_un:
if (control->end_added) {
if (control->on_strm_q) {
#ifdef INVARIANTS
if (control->on_strm_q != SCTP_ON_ORDERED ) {
if (control->on_strm_q != SCTP_ON_ORDERED) {
panic("Huh control: %p on_q: %d -- not ordered?",
control, control->on_strm_q);
}
@ -1251,7 +1238,7 @@ deliver_more:
/* We are done with it afterwards */
if (control->on_strm_q) {
#ifdef INVARIANTS
if (control->on_strm_q != SCTP_ON_ORDERED ) {
if (control->on_strm_q != SCTP_ON_ORDERED) {
panic("Huh control: %p on_q: %d -- not ordered?",
control, control->on_strm_q);
}
@ -1313,7 +1300,6 @@ out:
return (ret);
}
uint32_t
sctp_add_chk_to_control(struct sctp_queued_to_read *control,
struct sctp_stream_in *strm,
@ -1576,6 +1562,15 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
chk->rec.data.fsn);
TAILQ_FOREACH(at, &control->reasm, sctp_next) {
if (SCTP_TSN_GT(at->rec.data.fsn, chk->rec.data.fsn)) {
if (chk->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
/* Last not at the end? huh? */
SCTPDBG(SCTP_DEBUG_XXX,
"Last fragment not last in list: -- abort\n");
sctp_abort_in_reasm(stcb, control,
chk, abort_flag,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_14);
return;
}
/*
* This one in queue is bigger than the new one, insert
* the new one before at.
@ -1602,7 +1597,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
at->rec.data.fsn);
sctp_abort_in_reasm(stcb, control,
chk, abort_flag,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_14);
SCTP_FROM_SCTP_INDATA + SCTP_LOC_15);
return;
}
}
@ -1759,8 +1754,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
* empty data chunk.
*/
op_err = sctp_generate_no_user_data_cause(tsn);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_15;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_16;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
return (0);
}
@ -1826,7 +1821,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
* receiver. Send peer an ABORT!
*/
op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
return (0);
}
@ -1897,8 +1892,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
SCTP_SNPRINTF(msg, sizeof(msg), "Reassembly problem (MID=%8.8x)", mid);
err_out:
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_16;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_17;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
return (0);
}
@ -1951,7 +1946,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
* When we have NO room in the rwnd we check to make sure
* the reader is doing its job...
*/
if (stcb->sctp_socket->so_rcv.sb_cc) {
if (SCTP_SBAVAIL(&stcb->sctp_socket->so_rcv) > 0) {
/* some to read, wake-up */
#if defined(__APPLE__) && !defined(__Userspace__)
struct socket *so;
@ -2044,8 +2039,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
(uint16_t)mid);
}
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_17;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_18;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
return (0);
}
@ -2241,7 +2236,6 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
unsigned char inserted = 0;
TAILQ_FOREACH_SAFE(lcontrol, &asoc->pending_reply_queue, next, nlcontrol) {
if (SCTP_TSN_GT(control->sinfo_tsn, lcontrol->sinfo_tsn)) {
continue;
} else {
/* found it */
@ -2417,7 +2411,6 @@ static const int8_t sctp_map_lookup_tab[256] = {
0, 1, 0, 2, 0, 1, 0, 8
};
void
sctp_slide_mapping_arrays(struct sctp_tcb *stcb)
{
@ -2553,7 +2546,6 @@ sctp_slide_mapping_arrays(struct sctp_tcb *stcb)
* we will be able to slide it forward. Really I
* don't think this should happen :-0
*/
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
sctp_log_map((uint32_t) distance, (uint32_t) slide_from,
(uint32_t) asoc->mapping_array_size,
@ -2565,7 +2557,6 @@ sctp_slide_mapping_arrays(struct sctp_tcb *stcb)
for (ii = 0; ii < distance; ii++) {
asoc->mapping_array[ii] = asoc->mapping_array[slide_from + ii];
asoc->nr_mapping_array[ii] = asoc->nr_mapping_array[slide_from + ii];
}
for (ii = distance; ii < asoc->mapping_array_size; ii++) {
asoc->mapping_array[ii] = 0;
@ -2617,7 +2608,7 @@ sctp_sack_check(struct sctp_tcb *stcb, int was_a_gap)
if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
stcb->sctp_ep, stcb, NULL,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_18);
SCTP_FROM_SCTP_INDATA + SCTP_LOC_19);
}
sctp_send_shutdown(stcb,
((stcb->asoc.alternate) ? stcb->asoc.alternate : stcb->asoc.primary_destination));
@ -2637,20 +2628,16 @@ sctp_sack_check(struct sctp_tcb *stcb, int was_a_gap)
(stcb->asoc.numduptsns) || /* we have dup's */
(is_a_gap) || /* is still a gap */
(stcb->asoc.delayed_ack == 0) || /* Delayed sack disabled */
(stcb->asoc.data_pkts_seen >= stcb->asoc.sack_freq) /* hit limit of pkts */
) {
(stcb->asoc.data_pkts_seen >= stcb->asoc.sack_freq)) { /* hit limit of pkts */
if ((stcb->asoc.sctp_cmt_on_off > 0) &&
(SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) &&
(stcb->asoc.send_sack == 0) &&
(stcb->asoc.numduptsns == 0) &&
(stcb->asoc.delayed_ack) &&
(!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer))) {
/*
* CMT DAC algorithm: With CMT,
* delay acks even in the face of
* reordering. Therefore, if acks
* that do not have to be sent
* because of the above reasons,
@ -2669,7 +2656,7 @@ sctp_sack_check(struct sctp_tcb *stcb, int was_a_gap)
* duplicates.
*/
sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_19);
SCTP_FROM_SCTP_INDATA + SCTP_LOC_20);
sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
}
} else {
@ -2768,10 +2755,10 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
struct mbuf *op_err;
char msg[SCTP_DIAG_INFO_LEN];
SCTP_SNPRINTF(msg, sizeof(msg), "%s", "I-DATA chunk received when DATA was negotiated");
SCTP_SNPRINTF(msg, sizeof(msg), "%s", "DATA chunk received when I-DATA was negotiated");
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_20;
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_21;
sctp_abort_an_association(inp, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
return (2);
}
if ((asoc->idata_supported == 0) &&
@ -2779,10 +2766,10 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
struct mbuf *op_err;
char msg[SCTP_DIAG_INFO_LEN];
SCTP_SNPRINTF(msg, sizeof(msg), "%s", "DATA chunk received when I-DATA was negotiated");
SCTP_SNPRINTF(msg, sizeof(msg), "%s", "I-DATA chunk received when DATA was negotiated");
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_21;
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_22;
sctp_abort_an_association(inp, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
return (2);
}
if ((ch->chunk_type == SCTP_DATA) ||
@ -2806,8 +2793,8 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
ch->chunk_type == SCTP_DATA ? "DATA" : "I-DATA",
chk_length);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_22;
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_23;
sctp_abort_an_association(inp, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
return (2);
}
#ifdef SCTP_AUDITING_ENABLED
@ -2874,7 +2861,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
SCTP_SNPRINTF(msg, sizeof(msg), "DATA chunk followed by chunk of type %2.2x",
ch->chunk_type);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
sctp_abort_an_association(inp, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
return (2);
}
default:
@ -2892,8 +2879,8 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
SCTP_SNPRINTF(msg, sizeof(msg), "Chunk of length %u", chk_length);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_23;
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_24;
sctp_abort_an_association(inp, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
return (2);
}
if (ch->chunk_type & 0x40) {
@ -3132,7 +3119,6 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
tp1->do_rtt = 0;
}
}
}
if (tp1->sent <= SCTP_DATAGRAM_RESEND) {
if (SCTP_TSN_GT(tp1->rec.data.tsn,
@ -3207,7 +3193,6 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
return (wake_him); /* Return value only used for nr-sack */
}
static int
sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct sctp_association *asoc,
uint32_t last_tsn, uint32_t *biggest_tsn_acked,
@ -3328,7 +3313,6 @@ sctp_check_for_revoked(struct sctp_tcb *stcb,
}
}
static void
sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
uint32_t biggest_tsn_acked, uint32_t biggest_tsn_newly_acked, uint32_t this_sack_lowest_newack, int accum_moved)
@ -3336,7 +3320,6 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
struct sctp_tmit_chunk *tp1;
int strike_flag = 0;
struct timeval now;
int tot_retrans = 0;
uint32_t sending_seq;
struct sctp_nets *net;
int num_dests_sacked = 0;
@ -3397,7 +3380,6 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
continue;
}
}
}
if (SCTP_TSN_GT(tp1->rec.data.tsn, asoc->this_sack_highest_gap) &&
!(accum_moved && asoc->fast_retran_loss_recovery)) {
@ -3418,7 +3400,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
*/
if (tp1->whoTo && tp1->whoTo->saw_newack == 0) {
/*
* No new acks were receieved for data sent to this
* No new acks were received for data sent to this
* dest. Therefore, according to the SFR algo for
* CMT, no data sent to this dest can be marked for
* FR using this SACK.
@ -3429,7 +3411,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
tp1->whoTo->this_sack_highest_newack) &&
!(accum_moved && asoc->fast_retran_loss_recovery)) {
/*
* CMT: New acks were receieved for data sent to
* CMT: New acks were received for data sent to
* this dest. But no new acks were seen for data
* sent after tp1. Therefore, according to the SFR
* algo for CMT, tp1 cannot be marked for FR using
@ -3507,7 +3489,6 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
(1)
#endif
) {
if (SCTP_TSN_GE(biggest_tsn_newly_acked,
tp1->rec.data.fast_retran_tsn)) {
/*
@ -3694,9 +3675,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
tp1->whoTo->find_pseudo_cumack = 1;
tp1->whoTo->find_rtx_pseudo_cumack = 1;
}
} else {/* CMT is OFF */
#ifdef SCTP_FR_TO_ALTERNATE
/* Can we find an alternate? */
alt = sctp_find_alternate_net(stcb, tp1->whoTo, 0);
@ -3711,7 +3690,6 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
}
tp1->rec.data.doing_fast_retransmit = 1;
tot_retrans++;
/* mark the sending seq for possible subsequent FR's */
/*
* SCTP_PRINTF("Marking TSN for FR new value %x\n",
@ -3812,7 +3790,7 @@ sctp_try_advance_peer_ack_point(struct sctp_tcb *stcb,
* Now is this one marked for resend and its time is
* now up?
*/
#if !(defined(__FreeBSD__) && !defined(__Userspace__))
#if !(defined(__FreeBSD__) && !defined(__Userspace__))
if (timercmp(&now, &tp1->rec.data.timetodrop, >)) {
#else
if (timevalcmp(&now, &tp1->rec.data.timetodrop, >)) {
@ -3894,24 +3872,23 @@ sctp_fs_audit(struct sctp_association *asoc)
if ((inflight > 0) || (inbetween > 0)) {
#ifdef INVARIANTS
panic("Flight size-express incorrect? \n");
panic("Flight size-express incorrect F: %d I: %d R: %d Ab: %d ACK: %d",
inflight, inbetween, resend, above, acked);
#else
SCTP_PRINTF("asoc->total_flight: %d cnt: %d\n",
entry_flight, entry_cnt);
SCTP_PRINTF("Flight size-express incorrect F: %d I: %d R: %d Ab: %d ACK: %d\n",
inflight, inbetween, resend, above, acked);
inflight, inbetween, resend, above, acked);
ret = 1;
#endif
}
return (ret);
}
static void
sctp_window_probe_recovery(struct sctp_tcb *stcb,
struct sctp_association *asoc,
struct sctp_tmit_chunk *tp1)
struct sctp_association *asoc,
struct sctp_tmit_chunk *tp1)
{
tp1->window_probe = 0;
if ((tp1->sent >= SCTP_DATAGRAM_ACKED) || (tp1->data == NULL)) {
@ -4025,8 +4002,8 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
"Cum ack %8.8x greater or equal than TSN %8.8x",
cumack, send_s);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_24;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
return;
}
asoc->this_sack_highest_gap = cumack;
@ -4107,7 +4084,6 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
tp1->whoTo->new_pseudo_cumack = 1;
tp1->whoTo->find_pseudo_cumack = 1;
tp1->whoTo->find_rtx_pseudo_cumack = 1;
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
/* sa_ignore NO_NULL_CHK */
sctp_log_cwnd(stcb, tp1->whoTo, tp1->rec.data.tsn, SCTP_CWND_LOG_FROM_SACK);
@ -4156,7 +4132,6 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
break;
}
}
}
#if defined(__Userspace__)
if (stcb->sctp_ep->recv_callback) {
@ -4176,7 +4151,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
(inp->send_sb_threshold == 0))) {
atomic_add_int(&stcb->asoc.refcnt, 1);
SCTP_TCB_UNLOCK(stcb);
inp->send_callback(stcb->sctp_socket, sb_free_now);
inp->send_callback(stcb->sctp_socket, sb_free_now, inp->ulp_info);
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
}
@ -4227,7 +4202,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
* is optional.
*/
net->error_count = 0;
if (!(net->dest_state & SCTP_ADDR_REACHABLE)) {
if ((net->dest_state & SCTP_ADDR_REACHABLE) == 0) {
/* addr came good */
net->dest_state |= SCTP_ADDR_REACHABLE;
sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb,
@ -4244,7 +4219,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
net->dest_state &= ~SCTP_ADDR_PF;
sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_25);
SCTP_FROM_SCTP_INDATA + SCTP_LOC_26);
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
asoc->cc_functions.sctp_cwnd_update_exit_pf(stcb, net);
/* Done with this net */
@ -4319,7 +4294,7 @@ again:
} else if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
stcb, net,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_26);
SCTP_FROM_SCTP_INDATA + SCTP_LOC_27);
}
}
}
@ -4371,8 +4346,8 @@ again:
*abort_now = 1;
/* XXX */
op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_27;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_28;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
return;
}
if ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) &&
@ -4493,7 +4468,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
* old sack, if so discard. 2) If there is nothing left in the send
* queue (cum-ack is equal to last acked) then you have a duplicate
* too, update any rwnd change and verify no timers are running.
* then return. 3) Process any new consequtive data i.e. cum-ack
* then return. 3) Process any new consecutive data i.e. cum-ack
* moved process these first and note that it moved. 4) Process any
* sack blocks. 5) Drop any acked from the queue. 6) Check for any
* revoked blocks and mark. 7) Update the cwnd. 8) Nothing left,
@ -4586,8 +4561,8 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
"Cum ack %8.8x greater or equal than TSN %8.8x",
cum_ack, send_s);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_28;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_29;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
return;
}
/**********************/
@ -4618,7 +4593,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
/* stop any timers */
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_29);
stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_30);
net->partial_bytes_acked = 0;
net->flight_size = 0;
}
@ -4630,7 +4605,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
* We init netAckSz and netAckSz2 to 0. These are used to track 2
* things. The total byte count acked is tracked in netAckSz AND
* netAck2 is used to track the total bytes acked that are un-
* amibguious and were never retransmitted. We track these on a per
* ambiguous and were never retransmitted. We track these on a per
* destination address basis.
*/
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
@ -4745,8 +4720,6 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
tp1->whoTo->new_pseudo_cumack = 1;
tp1->whoTo->find_pseudo_cumack = 1;
tp1->whoTo->find_rtx_pseudo_cumack = 1;
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_LOGGING_ENABLE) {
sctp_log_sack(asoc->last_acked_seq,
cum_ack,
@ -4784,7 +4757,6 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
asoc->this_sack_highest_gap = last_tsn;
if ((num_seg > 0) || (num_nr_seg > 0)) {
/*
* thisSackHighestGap will increase while handling NEW
* segments this_sack_highest_newack will increase while
@ -4818,14 +4790,13 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
if (net->new_pseudo_cumack)
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
stcb, net,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_30);
SCTP_FROM_SCTP_INDATA + SCTP_LOC_31);
}
} else {
if (accum_moved) {
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_31);
stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_32);
}
}
}
@ -4904,7 +4875,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
(inp->send_sb_threshold == 0))) {
atomic_add_int(&stcb->asoc.refcnt, 1);
SCTP_TCB_UNLOCK(stcb);
inp->send_callback(stcb->sctp_socket, sb_free_now);
inp->send_callback(stcb->sctp_socket, sb_free_now, inp->ulp_info);
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
}
@ -5011,7 +4982,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
* is optional.
*/
net->error_count = 0;
if (!(net->dest_state & SCTP_ADDR_REACHABLE)) {
if ((net->dest_state & SCTP_ADDR_REACHABLE) == 0) {
/* addr came good */
net->dest_state |= SCTP_ADDR_REACHABLE;
sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb,
@ -5030,7 +5001,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
net->dest_state &= ~SCTP_ADDR_PF;
sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_32);
SCTP_FROM_SCTP_INDATA + SCTP_LOC_33);
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
asoc->cc_functions.sctp_cwnd_update_exit_pf(stcb, net);
/* Done with this net */
@ -5055,7 +5026,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
/* stop all timers */
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
stcb, net,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_33);
SCTP_FROM_SCTP_INDATA + SCTP_LOC_34);
net->flight_size = 0;
net->partial_bytes_acked = 0;
}
@ -5093,8 +5064,8 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
*abort_now = 1;
/* XXX */
op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_34;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_35;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
return;
}
if ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) &&
@ -5234,12 +5205,11 @@ again:
if (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
sctp_timer_start(SCTP_TIMER_TYPE_SEND,
stcb->sctp_ep, stcb, net);
}
} else if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
stcb, net,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_35);
SCTP_FROM_SCTP_INDATA + SCTP_LOC_36);
}
}
}
@ -5356,7 +5326,7 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
TAILQ_FOREACH_SAFE(control, &strmin->inqueue, next_instrm, ncontrol) {
if (SCTP_MID_GE(asoc->idata_supported, mid, control->mid)) {
/* this is deliverable now */
if (((control->sinfo_flags >> 8) & SCTP_DATA_NOT_FRAG) == SCTP_DATA_NOT_FRAG) {
if (((control->sinfo_flags >> 8) & SCTP_DATA_NOT_FRAG) == SCTP_DATA_NOT_FRAG) {
if (control->on_strm_q) {
if (control->on_strm_q == SCTP_ON_ORDERED) {
TAILQ_REMOVE(&strmin->inqueue, control, next_instrm);
@ -5458,7 +5428,6 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
control,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_HELD, SCTP_SO_NOT_LOCKED);
}
mid = strmin->last_mid_delivered + 1;
} else {
@ -5479,17 +5448,12 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
}
}
static void
sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb,
struct sctp_association *asoc,
uint16_t stream, uint32_t mid, int ordered, uint32_t cumtsn)
struct sctp_association *asoc, struct sctp_stream_in *strm,
struct sctp_queued_to_read *control, int ordered, uint32_t cumtsn)
{
struct sctp_queued_to_read *control;
struct sctp_stream_in *strm;
struct sctp_tmit_chunk *chk, *nchk;
int cnt_removed=0;
/*
* For now large messages held on the stream reasm that are
@ -5499,23 +5463,18 @@ sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb,
* delivery function... to see if it can be delivered... But
* for now we just dump everything on the queue.
*/
strm = &asoc->strmin[stream];
control = sctp_find_reasm_entry(strm, mid, ordered, asoc->idata_supported);
if (control == NULL) {
/* Not found */
return;
}
if (!asoc->idata_supported && !ordered && SCTP_TSN_GT(control->fsn_included, cumtsn)) {
if (!asoc->idata_supported && !ordered &&
control->first_frag_seen &&
SCTP_TSN_GT(control->fsn_included, cumtsn)) {
return;
}
TAILQ_FOREACH_SAFE(chk, &control->reasm, sctp_next, nchk) {
/* Purge hanging chunks */
if (!asoc->idata_supported && (ordered == 0)) {
if (!asoc->idata_supported && !ordered) {
if (SCTP_TSN_GT(chk->rec.data.tsn, cumtsn)) {
break;
}
}
cnt_removed++;
TAILQ_REMOVE(&control->reasm, chk, sctp_next);
if (asoc->size_on_reasm_queue >= chk->send_size) {
asoc->size_on_reasm_queue -= chk->send_size;
@ -5605,7 +5564,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
unsigned int i, fwd_sz, m_size;
uint32_t str_seq;
struct sctp_stream_in *strm;
struct sctp_queued_to_read *control, *sv;
struct sctp_queued_to_read *control, *ncontrol, *sv;
asoc = &stcb->asoc;
if ((fwd_sz = ntohs(fwd->ch.chunk_length)) < sizeof(struct sctp_forward_tsn_chunk)) {
@ -5643,8 +5602,8 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
"New cum ack %8.8x too high, highest TSN %8.8x",
new_cum_tsn, asoc->highest_tsn_inside_map);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_36;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_37;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
return;
}
SCTP_STAT_INCR(sctps_fwdtsn_map_over);
@ -5678,10 +5637,14 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
/* This is now done as part of clearing up the stream/seq */
if (asoc->idata_supported == 0) {
uint16_t sid;
/* Flush all the un-ordered data based on cum-tsn */
SCTP_INP_READ_LOCK(stcb->sctp_ep);
for (sid = 0 ; sid < asoc->streamincnt; sid++) {
sctp_flush_reassm_for_str_seq(stcb, asoc, sid, 0, 0, new_cum_tsn);
for (sid = 0; sid < asoc->streamincnt; sid++) {
strm = &asoc->strmin[sid];
if (!TAILQ_EMPTY(&strm->uno_inqueue)) {
sctp_flush_reassm_for_str_seq(stcb, asoc, strm, TAILQ_FIRST(&strm->uno_inqueue), 0, new_cum_tsn);
}
}
SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
}
@ -5693,7 +5656,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
if (m && fwd_sz) {
/* New method. */
unsigned int num_str;
uint32_t mid, cur_mid;
uint32_t mid;
uint16_t sid;
uint16_t ordered, flags;
struct sctp_strseq *stseq, strseqbuf;
@ -5757,8 +5720,24 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
asoc->fragmented_delivery_inprogress = 0;
}
strm = &asoc->strmin[sid];
for (cur_mid = strm->last_mid_delivered; SCTP_MID_GE(asoc->idata_supported, mid, cur_mid); cur_mid++) {
sctp_flush_reassm_for_str_seq(stcb, asoc, sid, cur_mid, ordered, new_cum_tsn);
if (ordered) {
TAILQ_FOREACH_SAFE(control, &strm->inqueue, next_instrm, ncontrol) {
if (SCTP_MID_GE(asoc->idata_supported, mid, control->mid)) {
sctp_flush_reassm_for_str_seq(stcb, asoc, strm, control, ordered, new_cum_tsn);
}
}
} else {
if (asoc->idata_supported) {
TAILQ_FOREACH_SAFE(control, &strm->uno_inqueue, next_instrm, ncontrol) {
if (SCTP_MID_GE(asoc->idata_supported, mid, control->mid)) {
sctp_flush_reassm_for_str_seq(stcb, asoc, strm, control, ordered, new_cum_tsn);
}
}
} else {
if (!TAILQ_EMPTY(&strm->uno_inqueue)) {
sctp_flush_reassm_for_str_seq(stcb, asoc, strm, TAILQ_FIRST(&strm->uno_inqueue), ordered, new_cum_tsn);
}
}
}
TAILQ_FOREACH(control, &stcb->sctp_ep->read_queue, next) {
if ((control->sinfo_stream == sid) &&

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.h 361116 2020-05-16 19:26:39Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_INDATA_H_
@ -44,12 +44,11 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.h 361116 2020-05-16 19:26:39Z t
struct sctp_queued_to_read *
sctp_build_readq_entry(struct sctp_tcb *stcb,
struct sctp_nets *net,
uint32_t tsn, uint32_t ppid,
uint32_t context, uint16_t sid,
uint32_t mid, uint8_t flags,
struct mbuf *dm);
struct sctp_nets *net,
uint32_t tsn, uint32_t ppid,
uint32_t context, uint16_t sid,
uint32_t mid, uint8_t flags,
struct mbuf *dm);
#define sctp_build_readq_entry_mac(_ctl, in_it, context, net, tsn, ppid, sid, flags, dm, tfsn, mid) do { \
if (_ctl) { \
@ -76,11 +75,9 @@ sctp_build_readq_entry(struct sctp_tcb *stcb,
} \
} while (0)
struct mbuf *
sctp_build_ctl_nchunk(struct sctp_inpcb *inp,
struct sctp_sndrcvinfo *sinfo);
struct sctp_sndrcvinfo *sinfo);
void sctp_set_rwnd(struct sctp_tcb *, struct sctp_association *);
@ -89,7 +86,7 @@ sctp_calc_rwnd(struct sctp_tcb *stcb, struct sctp_association *asoc);
void
sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
uint32_t rwnd, int *abort_now, int ecne_seen);
uint32_t rwnd, int *abort_now, int ecne_seen);
void
sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
@ -101,7 +98,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
/* draft-ietf-tsvwg-usctp */
void
sctp_handle_forward_tsn(struct sctp_tcb *,
struct sctp_forward_tsn_chunk *, int *, struct mbuf *, int);
struct sctp_forward_tsn_chunk *, int *, struct mbuf *, int);
struct sctp_tmit_chunk *
sctp_try_advance_peer_ack_point(struct sctp_tcb *, struct sctp_association *);
@ -113,8 +110,8 @@ sctp_update_acked(struct sctp_tcb *, struct sctp_shutdown_chunk *, int *);
int
sctp_process_data(struct mbuf **, int, int *, int,
struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *, uint32_t *);
struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *, uint32_t *);
void sctp_slide_mapping_arrays(struct sctp_tcb *stcb);

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.h 326672 2017-12-07 22:19:08Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_INPUT_H_
@ -56,9 +56,9 @@ struct sctp_stream_reset_request *
sctp_find_stream_reset(struct sctp_tcb *stcb, uint32_t seq,
struct sctp_tmit_chunk **bchk);
void sctp_reset_in_stream(struct sctp_tcb *stcb, uint32_t number_entries,
uint16_t *list);
void
sctp_reset_in_stream(struct sctp_tcb *stcb, uint32_t number_entries,
uint16_t *list);
int sctp_is_there_unsent_data(struct sctp_tcb *stcb, int so_locked);

View File

@ -63,6 +63,9 @@ __FBSDID("$FreeBSD$");
#define SCTP_INP_INFO_TRYLOCK() 1
#define SCTP_INP_INFO_RUNLOCK()
#define SCTP_INP_INFO_WUNLOCK()
#define SCTP_INP_INFO_LOCK_ASSERT()
#define SCTP_INP_INFO_RLOCK_ASSERT()
#define SCTP_INP_INFO_WLOCK_ASSERT()
#define SCTP_WQ_ADDR_INIT()
#define SCTP_WQ_ADDR_DESTROY()
@ -76,6 +79,8 @@ __FBSDID("$FreeBSD$");
#define SCTP_IPI_ADDR_WLOCK()
#define SCTP_IPI_ADDR_RUNLOCK()
#define SCTP_IPI_ADDR_WUNLOCK()
#define SCTP_IPI_ADDR_LOCK_ASSERT()
#define SCTP_IPI_ADDR_WLOCK_ASSERT()
#define SCTP_IPI_ITERATOR_WQ_INIT()
#define SCTP_IPI_ITERATOR_WQ_DESTROY()
@ -109,11 +114,6 @@ __FBSDID("$FreeBSD$");
#define SCTP_ASOC_CREATE_LOCK_CONTENDED(_inp) (0) /* Don't know if this is possible */
#define SCTP_TCB_SEND_LOCK_INIT(_tcb)
#define SCTP_TCB_SEND_LOCK_DESTROY(_tcb)
#define SCTP_TCB_SEND_LOCK(_tcb)
#define SCTP_TCB_SEND_UNLOCK(_tcb)
#define SCTP_INP_INCR_REF(_inp)
#define SCTP_INP_DECR_REF(_inp)

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_os.h 361872 2020-06-06 18:20:09Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_OS_H_
@ -69,15 +69,12 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_os.h 361872 2020-06-06 18:20:09Z tuexe
#else
#define MODULE_GLOBAL(_B) (_B)
#endif
#if defined(__Userspace__)
#include <netinet/sctp_os_userspace.h>
#endif
#if defined(__APPLE__) && !defined(__Userspace__)
#include <netinet/sctp_os_macosx.h>
#endif
#if defined(_WIN32) && !defined(__Userspace__)
#include <netinet/sctp_os_windows.h>
#endif

View File

@ -52,6 +52,7 @@
#include "user_environment.h"
typedef CRITICAL_SECTION userland_mutex_t;
#if WINVER < 0x0600
typedef CRITICAL_SECTION userland_rwlock_t;
enum {
C_SIGNAL = 0,
C_BROADCAST = 1,
@ -72,6 +73,7 @@ void WakeAllXPConditionVariable(userland_cond_t *);
#define SleepConditionVariableCS(cond, mtx, time) SleepXPConditionVariable(cond, mtx)
#define WakeAllConditionVariable(cond) WakeAllXPConditionVariable(cond)
#else
typedef SRWLOCK userland_rwlock_t;
#define DeleteConditionVariable(cond)
typedef CONDITION_VARIABLE userland_cond_t;
#endif
@ -283,10 +285,15 @@ typedef char* caddr_t;
#else /* !defined(Userspace_os_Windows) */
#include <sys/socket.h>
#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__native_client__) || defined(__Fuchsia__)
#include <pthread.h>
#if defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__)
#error "Unsupported build configuration."
#endif
#include <pthread.h>
typedef pthread_mutex_t userland_mutex_t;
typedef pthread_rwlock_t userland_rwlock_t;
typedef pthread_cond_t userland_cond_t;
typedef pthread_t userland_thread_t;
#endif
@ -509,7 +516,7 @@ struct sx {int dummy;};
#if !defined(_WIN32)
#include <netinet/ip6.h>
#endif
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(_WIN32)
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(_WIN32) || defined(__EMSCRIPTEN__)
#include "user_ip6_var.h"
#else
#include <netinet6/ip6_var.h>
@ -876,14 +883,12 @@ static inline void sctp_userspace_rtfree(sctp_rtentry_t *rt)
/*************************/
/* MTU */
/*************************/
int sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af);
int sctp_userspace_get_mtu_from_ifn(uint32_t if_index);
#define SCTP_GATHER_MTU_FROM_IFN_INFO(ifn, ifn_index, af) sctp_userspace_get_mtu_from_ifn(ifn_index, af)
#define SCTP_GATHER_MTU_FROM_IFN_INFO(ifn, ifn_index) sctp_userspace_get_mtu_from_ifn(ifn_index)
#define SCTP_GATHER_MTU_FROM_ROUTE(sctp_ifa, sa, rt) ((rt != NULL) ? rt->rt_rmx.rmx_mtu : 0)
#define SCTP_GATHER_MTU_FROM_INTFC(sctp_ifn) (sctp_ifn->ifn_mtu)
#define SCTP_SET_MTU_OF_ROUTE(sa, rt, mtu) do { \
if (rt != NULL) \
rt->rt_rmx.rmx_mtu = mtu; \
@ -955,6 +960,8 @@ int sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af);
/* wakeup a socket */
#define SCTP_SOWAKEUP(so) wakeup(&(so)->so_timeo, so)
/* number of bytes ready to read */
#define SCTP_SBAVAIL(sb) (sb)->sb_cc
/* clear the socket buffer state */
#define SCTP_SB_CLEAR(sb) \
(sb).sb_cc = 0; \
@ -1034,13 +1041,13 @@ extern void sctp_userspace_ip_output(int *result, struct mbuf *o_pak,
sctp_route_t *ro, void *stcb,
uint32_t vrf_id);
#define SCTP_IP_OUTPUT(result, o_pak, ro, stcb, vrf_id) sctp_userspace_ip_output(&result, o_pak, ro, stcb, vrf_id);
#define SCTP_IP_OUTPUT(result, o_pak, ro, inp, vrf_id) sctp_userspace_ip_output(&result, o_pak, ro, inp, vrf_id);
#if defined(INET6)
extern void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak,
struct route_in6 *ro, void *stcb,
uint32_t vrf_id);
#define SCTP_IP6_OUTPUT(result, o_pak, ro, ifp, stcb, vrf_id) sctp_userspace_ip6_output(&result, o_pak, ro, stcb, vrf_id);
#define SCTP_IP6_OUTPUT(result, o_pak, ro, ifp, inp, vrf_id) sctp_userspace_ip6_output(&result, o_pak, ro, inp, vrf_id);
#endif
@ -1132,7 +1139,7 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int a
#define SCTP_IS_LISTENING(inp) ((inp->sctp_flags & SCTP_PCB_FLAGS_ACCEPTING) != 0)
#if defined(__APPLE__) || defined(__DragonFly__) || defined(__linux__) || defined(__native_client__) || defined(__NetBSD__) || defined(_WIN32) || defined(__Fuchsia__)
#if defined(__APPLE__) || defined(__DragonFly__) || defined(__linux__) || defined(__native_client__) || defined(__NetBSD__) || defined(_WIN32) || defined(__Fuchsia__) || defined(__EMSCRIPTEN__)
int
timingsafe_bcmp(const void *, const void *, size_t);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.h 362054 2020-06-11 13:34:09Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_OUTPUT_H_
@ -44,38 +44,34 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_output.h 362054 2020-06-11 13:34:09Z t
#if defined(_KERNEL) || defined(__Userspace__)
struct mbuf *
sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp,
struct sctp_tcb *stcb,
struct sctp_scoping *scope,
struct mbuf *m_at,
int cnt_inits_to,
uint16_t *padding_len, uint16_t *chunk_len);
struct sctp_scoping *scope,
struct mbuf *m_at,
int cnt_inits_to,
uint16_t *padding_len, uint16_t *chunk_len);
int sctp_is_addr_restricted(struct sctp_tcb *, struct sctp_ifa *);
int
sctp_is_address_in_scope(struct sctp_ifa *ifa,
struct sctp_scoping *scope,
int do_update);
int do_update);
int
sctp_is_addr_in_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa);
struct sctp_ifa *
sctp_source_address_selection(struct sctp_inpcb *inp,
struct sctp_tcb *stcb,
sctp_route_t *ro, struct sctp_nets *net,
int non_asoc_addr_ok, uint32_t vrf_id);
struct sctp_tcb *stcb,
sctp_route_t *ro, struct sctp_nets *net,
int non_asoc_addr_ok, uint32_t vrf_id);
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Userspace__)
int
sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t *ro);
int
sctp_v4src_match_nexthop(struct sctp_ifa *sifa, sctp_route_t *ro);
int sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t *ro);
int sctp_v4src_match_nexthop(struct sctp_ifa *sifa, sctp_route_t *ro);
#endif
void sctp_send_initiate(struct sctp_inpcb *, struct sctp_tcb *, int);
@ -93,24 +89,23 @@ sctp_send_initiate_ack(struct sctp_inpcb *, struct sctp_tcb *,
struct mbuf *
sctp_arethere_unrecognized_parameters(struct mbuf *, int, int *,
struct sctp_chunkhdr *, int *, int *);
struct sctp_chunkhdr *, int *, int *);
void sctp_queue_op_err(struct sctp_tcb *, struct mbuf *);
int
sctp_send_cookie_echo(struct mbuf *, int, int, struct sctp_tcb *,
struct sctp_nets *);
struct sctp_nets *);
void sctp_send_cookie_ack(struct sctp_tcb *);
void
sctp_send_heartbeat_ack(struct sctp_tcb *, struct mbuf *, int, int,
struct sctp_nets *);
struct sctp_nets *);
void
sctp_remove_from_wheel(struct sctp_tcb *stcb,
struct sctp_association *asoc,
struct sctp_stream_out *strq, int holds_lock);
struct sctp_association *asoc,
struct sctp_stream_out *strq, int holds_lock);
void sctp_send_shutdown(struct sctp_tcb *, struct sctp_nets *);
@ -129,7 +124,7 @@ void sctp_send_asconf(struct sctp_tcb *, struct sctp_nets *, int addr_locked);
void sctp_send_asconf_ack(struct sctp_tcb *);
int sctp_get_frag_point(struct sctp_tcb *, struct sctp_association *);
uint32_t sctp_get_frag_point(struct sctp_tcb *);
void sctp_toss_old_cookies(struct sctp_tcb *, struct sctp_association *);
@ -139,10 +134,9 @@ void sctp_fix_ecn_echo(struct sctp_association *);
void sctp_move_chunks_from_net(struct sctp_tcb *stcb, struct sctp_nets *net);
#define SCTP_DATA_CHUNK_OVERHEAD(stcb) ((stcb)->asoc.idata_supported ? \
sizeof(struct sctp_idata_chunk) : \
sizeof(struct sctp_data_chunk))
sizeof(struct sctp_idata_chunk) : \
sizeof(struct sctp_data_chunk))
#if defined(__FreeBSD__) && !defined(__Userspace__)
int
@ -179,18 +173,15 @@ void
sctp_send_packet_dropped(struct sctp_tcb *, struct sctp_nets *, struct mbuf *,
int, int, int);
void sctp_send_cwr(struct sctp_tcb *, struct sctp_nets *, uint32_t, uint8_t);
void
sctp_add_stream_reset_result(struct sctp_tmit_chunk *, uint32_t, uint32_t);
void
sctp_send_deferred_reset_response(struct sctp_tcb *,
struct sctp_stream_reset_list *,
int);
struct sctp_stream_reset_list *,
int);
void
sctp_add_stream_reset_result_tsn(struct sctp_tmit_chunk *,
@ -210,12 +201,13 @@ sctp_send_abort(struct mbuf *, int, struct sockaddr *, struct sockaddr *,
#endif
uint32_t, uint16_t);
void sctp_send_operr_to(struct sockaddr *, struct sockaddr *,
struct sctphdr *, uint32_t, struct mbuf *,
void
sctp_send_operr_to(struct sockaddr *, struct sockaddr *,
struct sctphdr *, uint32_t, struct mbuf *,
#if defined(__FreeBSD__) && !defined(__Userspace__)
uint8_t, uint32_t, uint16_t,
uint8_t, uint32_t, uint16_t,
#endif
uint32_t, uint16_t);
uint32_t, uint16_t);
#endif /* _KERNEL || __Userspace__ */

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 362106 2020-06-12 16:31:13Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_PCB_H_
@ -147,7 +147,6 @@ struct sctp_tagblock {
struct sctp_timewait vtag_block[SCTP_NUMBER_IN_VTAG_BLOCK];
};
struct sctp_epinfo {
#if defined(__FreeBSD__) && !defined(__Userspace__)
#ifdef INET
@ -211,8 +210,8 @@ struct sctp_epinfo {
struct mtx ipi_pktlog_mtx;
struct mtx wq_addr_mtx;
#elif defined(SCTP_PROCESS_LEVEL_LOCKS)
userland_mutex_t ipi_ep_mtx;
userland_mutex_t ipi_addr_mtx;
userland_rwlock_t ipi_ep_mtx;
userland_rwlock_t ipi_addr_mtx;
userland_mutex_t ipi_count_mtx;
userland_mutex_t ipi_pktlog_mtx;
userland_mutex_t wq_addr_mtx;
@ -277,7 +276,6 @@ struct sctp_epinfo {
#endif
};
struct sctp_base_info {
/* All static structures that
* anchor the system must be here.
@ -314,6 +312,7 @@ struct sctp_base_info {
int timer_thread_started;
#if !defined(_WIN32)
pthread_mutexattr_t mtx_attr;
pthread_rwlockattr_t rwlock_attr;
#if defined(INET) || defined(INET6)
int userspace_route;
userland_thread_t recvthreadroute;
@ -440,7 +439,6 @@ struct sctp_pcbtsn_rlog {
};
#define SCTP_READ_LOG_SIZE 135 /* we choose the number to make a pcb a page */
struct sctp_inpcb {
/*-
* put an inpcb in front of it all, kind of a waste but we need to
@ -451,7 +449,6 @@ struct sctp_inpcb {
char align[(sizeof(struct inpcb) + SCTP_ALIGNM1) &
~SCTP_ALIGNM1];
} ip_inp;
#if defined(__APPLE__) && !defined(__Userspace__)
/* leave some space in case i386 inpcb is bigger than ppc */
uint8_t padding[128];
@ -461,7 +458,7 @@ struct sctp_inpcb {
struct sctp_readhead read_queue;
LIST_ENTRY(sctp_inpcb) sctp_list; /* lists all endpoints */
/* hash of all endpoints for model */
/* hash of all endpoints for model */
LIST_ENTRY(sctp_inpcb) sctp_hash;
/* count of local addresses bound, 0 if bound all */
int laddr_count;
@ -485,7 +482,6 @@ struct sctp_inpcb {
#ifdef SCTP_TRACK_FREED_ASOCS
struct sctpasochead sctp_asoc_free_list;
#endif
struct sctp_iterator *inp_starting_point_for_iterator;
uint32_t sctp_frag_point;
uint32_t partial_delivery_point;
uint32_t sctp_context;
@ -581,7 +577,7 @@ struct sctp_inpcb {
int (*recv_callback)(struct socket *, union sctp_sockstore, void *, size_t,
struct sctp_rcvinfo, int, void *);
uint32_t send_sb_threshold;
int (*send_callback)(struct socket *, uint32_t);
int (*send_callback)(struct socket *, uint32_t, void *);
#endif
};
@ -589,7 +585,7 @@ struct sctp_inpcb {
int register_recv_cb (struct socket *,
int (*)(struct socket *, union sctp_sockstore, void *, size_t,
struct sctp_rcvinfo, int, void *));
int register_send_cb (struct socket *, uint32_t, int (*)(struct socket *, uint32_t));
int register_send_cb (struct socket *, uint32_t, int (*)(struct socket *, uint32_t, void *));
int register_ulp_info (struct socket *, void *);
int retrieve_ulp_info (struct socket *, void **);
@ -621,16 +617,12 @@ struct sctp_tcb {
uint16_t resv;
#if defined(__FreeBSD__) && !defined(__Userspace__)
struct mtx tcb_mtx;
struct mtx tcb_send_mtx;
#elif defined(SCTP_PROCESS_LEVEL_LOCKS)
userland_mutex_t tcb_mtx;
userland_mutex_t tcb_send_mtx;
#elif defined(__APPLE__) && !defined(__Userspace__)
lck_mtx_t* tcb_mtx;
lck_mtx_t* tcb_send_mtx;
#elif defined(_WIN32) && !defined(__Userspace__)
struct spinlock tcb_lock;
struct spinlock tcb_send_lock;
#elif defined(__Userspace__)
#endif
#if defined(__APPLE__) && !defined(__Userspace__)
@ -640,11 +632,8 @@ struct sctp_tcb {
#endif
};
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <netinet/sctp_lock_bsd.h>
#elif defined(__APPLE__) && !defined(__Userspace__)
/*
* Apple MacOS X 10.4 "Tiger"
@ -678,7 +667,7 @@ struct sctp_tcb {
* the real definition.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
VNET_DECLARE(struct sctp_base_info, system_base_info) ;
VNET_DECLARE(struct sctp_base_info, system_base_info);
#else
extern struct sctp_base_info system_base_info;
#endif
@ -720,26 +709,35 @@ void sctp_update_ifn_mtu(uint32_t ifn_index, uint32_t mtu);
void sctp_free_ifn(struct sctp_ifn *sctp_ifnp);
void sctp_free_ifa(struct sctp_ifa *sctp_ifap);
void sctp_del_addr_from_vrf(uint32_t vrfid, struct sockaddr *addr,
uint32_t ifn_index, const char *if_name);
struct sctp_nets *sctp_findnet(struct sctp_tcb *, struct sockaddr *);
struct sctp_inpcb *sctp_pcb_findep(struct sockaddr *, int, int, uint32_t);
#if defined(__FreeBSD__) && !defined(__Userspace__)
int sctp_inpcb_bind(struct socket *, struct sockaddr *,
struct sctp_ifa *,struct thread *);
int
sctp_inpcb_bind(struct socket *, struct sockaddr *,
struct sctp_ifa *, struct thread *);
int
sctp_inpcb_bind_locked(struct sctp_inpcb *, struct sockaddr *,
struct sctp_ifa *, struct thread *);
#elif defined(_WIN32) && !defined(__Userspace__)
int sctp_inpcb_bind(struct socket *, struct sockaddr *,
struct sctp_ifa *,PKTHREAD);
int
sctp_inpcb_bind(struct socket *, struct sockaddr *,
struct sctp_ifa *, PKTHREAD);
int
sctp_inpcb_bind_locked(struct sctp_inpcb *, struct sockaddr *,
struct sctp_ifa *, PKTHREAD);
#else
/* struct proc is a dummy for __Userspace__ */
int sctp_inpcb_bind(struct socket *, struct sockaddr *,
struct sctp_ifa *, struct proc *);
int
sctp_inpcb_bind(struct socket *, struct sockaddr *,
struct sctp_ifa *, struct proc *);
int
sctp_inpcb_bind_locked(struct sctp_inpcb *, struct sockaddr *,
struct sctp_ifa *, struct proc *);
#endif
struct sctp_tcb *
@ -790,30 +788,31 @@ void sctp_inpcb_free(struct sctp_inpcb *, int, int);
#if defined(__FreeBSD__) && !defined(__Userspace__)
struct sctp_tcb *
sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *,
int *, uint32_t, uint32_t, uint16_t, uint16_t, struct thread *,
int);
int *, uint32_t, uint32_t, uint32_t, uint16_t, uint16_t,
struct thread *, int);
struct sctp_tcb *
sctp_aloc_assoc_connected(struct sctp_inpcb *, struct sockaddr *,
int *, uint32_t, uint32_t, uint32_t, uint16_t, uint16_t,
struct thread *, int);
#elif defined(_WIN32) && !defined(__Userspace__)
struct sctp_tcb *
sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *,
int *, uint32_t, uint32_t, uint16_t, uint16_t, PKTHREAD, int);
sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *, int *, uint32_t,
uint32_t, uint32_t, uint16_t, uint16_t, PKTHREAD, int);
struct sctp_tcb *
sctp_aloc_assoc_connected(struct sctp_inpcb *, struct sockaddr *, int *, uint32_t,
uint32_t, uint32_t, uint16_t, uint16_t, PKTHREAD, int);
#else
/* proc will be NULL for __Userspace__ */
struct sctp_tcb *
sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *,
int *, uint32_t, uint32_t, uint16_t, uint16_t, struct proc *,
int);
sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *, int *, uint32_t,
uint32_t, uint32_t, uint16_t, uint16_t, struct proc *, int);
struct sctp_tcb *
sctp_aloc_assoc_connected(struct sctp_inpcb *, struct sockaddr *, int *, uint32_t,
uint32_t, uint32_t, uint16_t, uint16_t, struct proc *, int);
#endif
int sctp_free_assoc(struct sctp_inpcb *, struct sctp_tcb *, int, int);
void sctp_delete_from_timewait(uint32_t, uint16_t, uint16_t);
int sctp_is_in_timewait(uint32_t tag, uint16_t lport, uint16_t rport);
void
sctp_add_vtag_to_timewait(uint32_t tag, uint32_t time, uint16_t lport, uint16_t rport);
void sctp_add_local_addr_ep(struct sctp_inpcb *, struct sctp_ifa *, uint32_t);
void sctp_del_local_addr_ep(struct sctp_inpcb *, struct sctp_ifa *);
@ -843,7 +842,8 @@ int
sctp_set_primary_addr(struct sctp_tcb *, struct sockaddr *,
struct sctp_nets *);
int sctp_is_vtag_good(uint32_t, uint16_t lport, uint16_t rport, struct timeval *);
bool
sctp_is_vtag_good(uint32_t, uint16_t lport, uint16_t rport, struct timeval *);
/* void sctp_drain(void); */
@ -853,6 +853,9 @@ int sctp_swap_inpcb_for_listen(struct sctp_inpcb *inp);
void sctp_clean_up_stream(struct sctp_tcb *stcb, struct sctp_readhead *rh);
void
sctp_pcb_add_flags(struct sctp_inpcb *, uint32_t);
/*-
* Null in last arg inpcb indicate run on ALL ep's. Specific inp in last arg
* indicates run on ONLY assoc's of the specified endpoint.

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_peeloff.c 362054 2020-06-11 13:34:09Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
@ -134,7 +134,6 @@ sctp_do_peeloff(struct socket *head, struct socket *so, sctp_assoc_t assoc_id)
n_inp->sctp_context = inp->sctp_context;
n_inp->max_cwnd = inp->max_cwnd;
n_inp->local_strreset_support = inp->local_strreset_support;
n_inp->inp_starting_point_for_iterator = NULL;
/* copy in the authentication parameters from the original endpoint */
if (n_inp->sctp_ep.local_hmacs)
sctp_free_hmaclist(n_inp->sctp_ep.local_hmacs);

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_peeloff.h 309607 2016-12-06 10:21:25Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_PEELOFF_H_

View File

@ -60,6 +60,9 @@
#define SCTP_INP_INFO_RUNLOCK()
#define SCTP_INP_INFO_WLOCK()
#define SCTP_INP_INFO_WUNLOCK()
#define SCTP_INP_INFO_LOCK_ASSERT()
#define SCTP_INP_INFO_RLOCK_ASSERT()
#define SCTP_INP_INFO_WLOCK_ASSERT()
#define SCTP_INP_INFO_LOCK_DESTROY()
#define SCTP_IPI_COUNT_INIT()
#define SCTP_IPI_COUNT_DESTROY()
@ -69,16 +72,14 @@
#define SCTP_INP_INFO_RUNLOCK()
#define SCTP_INP_INFO_WLOCK()
#define SCTP_INP_INFO_WUNLOCK()
#define SCTP_INP_INFO_LOCK_ASSERT()
#define SCTP_INP_INFO_RLOCK_ASSERT()
#define SCTP_INP_INFO_WLOCK_ASSERT()
#define SCTP_INP_INFO_LOCK_DESTROY()
#define SCTP_IPI_COUNT_INIT()
#define SCTP_IPI_COUNT_DESTROY()
#endif
#define SCTP_TCB_SEND_LOCK_INIT(_tcb)
#define SCTP_TCB_SEND_LOCK_DESTROY(_tcb)
#define SCTP_TCB_SEND_LOCK(_tcb)
#define SCTP_TCB_SEND_UNLOCK(_tcb)
/* Lock for INP */
#define SCTP_INP_LOCK_INIT(_inp)
#define SCTP_INP_LOCK_DESTROY(_inp)
@ -128,6 +129,7 @@
LeaveCriticalSection(&SCTP_BASE_INFO(wq_addr_mtx))
#define SCTP_WQ_ADDR_LOCK_ASSERT()
#if WINVER < 0x0600
#define SCTP_INP_INFO_LOCK_INIT() \
InitializeCriticalSection(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_LOCK_DESTROY() \
@ -142,6 +144,27 @@
LeaveCriticalSection(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_WUNLOCK() \
LeaveCriticalSection(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_LOCK_ASSERT()
#define SCTP_INP_INFO_RLOCK_ASSERT()
#define SCTP_INP_INFO_WLOCK_ASSERT()
#else
#define SCTP_INP_INFO_LOCK_INIT() \
InitializeSRWLock(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_LOCK_DESTROY()
#define SCTP_INP_INFO_RLOCK() \
AcquireSRWLockShared(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_TRYLOCK() \
TryAcquireSRWLockShared(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_WLOCK() \
AcquireSRWLockExclusive(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_RUNLOCK() \
ReleaseSRWLockShared(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_WUNLOCK() \
ReleaseSRWLockExclusive(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_LOCK_ASSERT()
#define SCTP_INP_INFO_RLOCK_ASSERT()
#define SCTP_INP_INFO_WLOCK_ASSERT()
#endif
#define SCTP_IP_PKTLOG_INIT() \
InitializeCriticalSection(&SCTP_BASE_INFO(ipi_pktlog_mtx))
@ -190,17 +213,8 @@
#define SCTP_INP_RLOCK_ASSERT(_tcb)
#define SCTP_INP_WLOCK_ASSERT(_tcb)
#define SCTP_TCB_SEND_LOCK_INIT(_tcb) \
InitializeCriticalSection(&(_tcb)->tcb_send_mtx)
#define SCTP_TCB_SEND_LOCK_DESTROY(_tcb) \
DeleteCriticalSection(&(_tcb)->tcb_send_mtx)
#define SCTP_TCB_SEND_LOCK(_tcb) \
EnterCriticalSection(&(_tcb)->tcb_send_mtx)
#define SCTP_TCB_SEND_UNLOCK(_tcb) \
LeaveCriticalSection(&(_tcb)->tcb_send_mtx)
#define SCTP_INP_INCR_REF(_inp) atomic_add_int(&((_inp)->refcount), 1)
#define SCTP_INP_DECR_REF(_inp) atomic_add_int(&((_inp)->refcount), -1)
#define SCTP_INP_DECR_REF(_inp) atomic_subtract_int(&((_inp)->refcount), 1)
#define SCTP_ASOC_CREATE_LOCK_INIT(_inp) \
InitializeCriticalSection(&(_inp)->inp_create_mtx)
@ -258,9 +272,9 @@
(void)pthread_mutex_destroy(&SCTP_BASE_INFO(wq_addr_mtx))
#ifdef INVARIANTS
#define SCTP_WQ_ADDR_LOCK() \
KASSERT(pthread_mutex_lock(&SCTP_BASE_INFO(wq_addr_mtx)) == 0, ("%s: wq_addr_mtx already locked", __func__))
KASSERT(pthread_mutex_lock(&SCTP_BASE_INFO(wq_addr_mtx)) == 0, ("%s:%d: wq_addr_mtx already locked", __FILE__, __LINE__))
#define SCTP_WQ_ADDR_UNLOCK() \
KASSERT(pthread_mutex_unlock(&SCTP_BASE_INFO(wq_addr_mtx)) == 0, ("%s: wq_addr_mtx not locked", __func__))
KASSERT(pthread_mutex_unlock(&SCTP_BASE_INFO(wq_addr_mtx)) == 0, ("%s:%d: wq_addr_mtx not locked", __FILE__, __LINE__))
#else
#define SCTP_WQ_ADDR_LOCK() \
(void)pthread_mutex_lock(&SCTP_BASE_INFO(wq_addr_mtx))
@ -268,33 +282,36 @@
(void)pthread_mutex_unlock(&SCTP_BASE_INFO(wq_addr_mtx))
#endif
#define SCTP_WQ_ADDR_LOCK_ASSERT() \
KASSERT(pthread_mutex_trylock(&SCTP_BASE_INFO(wq_addr_mtx)) == EBUSY, ("%s: wq_addr_mtx not locked", __func__))
KASSERT(pthread_mutex_trylock(&SCTP_BASE_INFO(wq_addr_mtx)) == EBUSY, ("%s:%d: wq_addr_mtx not locked", __FILE__, __LINE__))
#define SCTP_INP_INFO_LOCK_INIT() \
(void)pthread_mutex_init(&SCTP_BASE_INFO(ipi_ep_mtx), &SCTP_BASE_VAR(mtx_attr))
(void)pthread_rwlock_init(&SCTP_BASE_INFO(ipi_ep_mtx), &SCTP_BASE_VAR(rwlock_attr))
#define SCTP_INP_INFO_LOCK_DESTROY() \
(void)pthread_mutex_destroy(&SCTP_BASE_INFO(ipi_ep_mtx))
(void)pthread_rwlock_destroy(&SCTP_BASE_INFO(ipi_ep_mtx))
#ifdef INVARIANTS
#define SCTP_INP_INFO_RLOCK() \
KASSERT(pthread_mutex_lock(&SCTP_BASE_INFO(ipi_ep_mtx)) == 0, ("%s: ipi_ep_mtx already locked", __func__))
KASSERT(pthread_rwlock_rdlock(&SCTP_BASE_INFO(ipi_ep_mtx)) == 0, ("%s%d: ipi_ep_mtx already locked", __FILE__, __LINE__))
#define SCTP_INP_INFO_WLOCK() \
KASSERT(pthread_mutex_lock(&SCTP_BASE_INFO(ipi_ep_mtx)) == 0, ("%s: ipi_ep_mtx already locked", __func__))
KASSERT(pthread_rwlock_wrlock(&SCTP_BASE_INFO(ipi_ep_mtx)) == 0, ("%s:%d: ipi_ep_mtx already locked", __FILE__, __LINE__))
#define SCTP_INP_INFO_RUNLOCK() \
KASSERT(pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_ep_mtx)) == 0, ("%s: ipi_ep_mtx not locked", __func__))
KASSERT(pthread_rwlock_unlock(&SCTP_BASE_INFO(ipi_ep_mtx)) == 0, ("%s:%d: ipi_ep_mtx not locked", __FILE__, __LINE__))
#define SCTP_INP_INFO_WUNLOCK() \
KASSERT(pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_ep_mtx)) == 0, ("%s: ipi_ep_mtx not locked", __func__))
KASSERT(pthread_rwlock_unlock(&SCTP_BASE_INFO(ipi_ep_mtx)) == 0, ("%s:%d: ipi_ep_mtx not locked", __FILE__, __LINE__))
#else
#define SCTP_INP_INFO_RLOCK() \
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_ep_mtx))
(void)pthread_rwlock_rdlock(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_WLOCK() \
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_ep_mtx))
(void)pthread_rwlock_wrlock(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_RUNLOCK() \
(void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_ep_mtx))
(void)pthread_rwlock_unlock(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_WUNLOCK() \
(void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_ep_mtx))
(void)pthread_rwlock_unlock(&SCTP_BASE_INFO(ipi_ep_mtx))
#endif
#define SCTP_INP_INFO_LOCK_ASSERT()
#define SCTP_INP_INFO_RLOCK_ASSERT()
#define SCTP_INP_INFO_WLOCK_ASSERT()
#define SCTP_INP_INFO_TRYLOCK() \
(!(pthread_mutex_trylock(&SCTP_BASE_INFO(ipi_ep_mtx))))
(!(pthread_rwlock_tryrdlock(&SCTP_BASE_INFO(ipi_ep_mtx))))
#define SCTP_IP_PKTLOG_INIT() \
(void)pthread_mutex_init(&SCTP_BASE_INFO(ipi_pktlog_mtx), &SCTP_BASE_VAR(mtx_attr))
@ -302,9 +319,9 @@
(void)pthread_mutex_destroy(&SCTP_BASE_INFO(ipi_pktlog_mtx))
#ifdef INVARIANTS
#define SCTP_IP_PKTLOG_LOCK() \
KASSERT(pthread_mutex_lock(&SCTP_BASE_INFO(ipi_pktlog_mtx)) == 0, ("%s: ipi_pktlog_mtx already locked", __func__))
KASSERT(pthread_mutex_lock(&SCTP_BASE_INFO(ipi_pktlog_mtx)) == 0, ("%s:%d: ipi_pktlog_mtx already locked", __FILE__, __LINE__))
#define SCTP_IP_PKTLOG_UNLOCK() \
KASSERT(pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_pktlog_mtx)) == 0, ("%s: ipi_pktlog_mtx not locked", __func__))
KASSERT(pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_pktlog_mtx)) == 0, ("%s:%d: ipi_pktlog_mtx not locked", __FILE__, __LINE__))
#else
#define SCTP_IP_PKTLOG_LOCK() \
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_pktlog_mtx))
@ -324,9 +341,9 @@
(void)pthread_mutex_destroy(&(_inp)->inp_rdata_mtx)
#ifdef INVARIANTS
#define SCTP_INP_READ_LOCK(_inp) \
KASSERT(pthread_mutex_lock(&(_inp)->inp_rdata_mtx) == 0, ("%s: inp_rdata_mtx already locked", __func__))
KASSERT(pthread_mutex_lock(&(_inp)->inp_rdata_mtx) == 0, ("%s:%d: inp_rdata_mtx already locked", __FILE__, __LINE__))
#define SCTP_INP_READ_UNLOCK(_inp) \
KASSERT(pthread_mutex_unlock(&(_inp)->inp_rdata_mtx) == 0, ("%s: inp_rdata_mtx not locked", __func__))
KASSERT(pthread_mutex_unlock(&(_inp)->inp_rdata_mtx) == 0, ("%s:%d: inp_rdata_mtx not locked", __FILE__, __LINE__))
#else
#define SCTP_INP_READ_LOCK(_inp) \
(void)pthread_mutex_lock(&(_inp)->inp_rdata_mtx)
@ -340,26 +357,26 @@
(void)pthread_mutex_destroy(&(_inp)->inp_mtx)
#ifdef INVARIANTS
#ifdef SCTP_LOCK_LOGGING
#define SCTP_INP_RLOCK(_inp) do { \
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_INP); \
KASSERT(pthread_mutex_lock(&(_inp)->inp_mtx) == 0, ("%s: inp_mtx already locked", __func__)) \
#define SCTP_INP_RLOCK(_inp) do { \
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_INP); \
KASSERT(pthread_mutex_lock(&(_inp)->inp_mtx) == 0, ("%s:%d: inp_mtx already locked", __FILE__, __LINE__)); \
} while (0)
#define SCTP_INP_WLOCK(_inp) do { \
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_INP); \
KASSERT(pthread_mutex_lock(&(_inp)->inp_mtx) == 0, ("%s: inp_mtx already locked", __func__))
#define SCTP_INP_WLOCK(_inp) do { \
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_INP); \
KASSERT(pthread_mutex_lock(&(_inp)->inp_mtx) == 0, ("%s:%d: inp_mtx already locked", __FILE__, __LINE__)); \
} while (0)
#else
#define SCTP_INP_RLOCK(_inp) \
KASSERT(pthread_mutex_lock(&(_inp)->inp_mtx) == 0, ("%s: inp_mtx already locked", __func__))
KASSERT(pthread_mutex_lock(&(_inp)->inp_mtx) == 0, ("%s:%d: inp_mtx already locked", __FILE__, __LINE__))
#define SCTP_INP_WLOCK(_inp) \
KASSERT(pthread_mutex_lock(&(_inp)->inp_mtx) == 0, ("%s: inp_mtx already locked", __func__))
KASSERT(pthread_mutex_lock(&(_inp)->inp_mtx) == 0, ("%s:%d: inp_mtx already locked", __FILE__, __LINE__))
#endif
#define SCTP_INP_RUNLOCK(_inp) \
KASSERT(pthread_mutex_unlock(&(_inp)->inp_mtx) == 0, ("%s: inp_mtx not locked", __func__))
KASSERT(pthread_mutex_unlock(&(_inp)->inp_mtx) == 0, ("%s:%d: inp_mtx not locked", __FILE__, __LINE__))
#define SCTP_INP_WUNLOCK(_inp) \
KASSERT(pthread_mutex_unlock(&(_inp)->inp_mtx) == 0, ("%s: inp_mtx not locked", __func__))
KASSERT(pthread_mutex_unlock(&(_inp)->inp_mtx) == 0, ("%s:%d: inp_mtx not locked", __FILE__, __LINE__))
#else
#ifdef SCTP_LOCK_LOGGING
#define SCTP_INP_RLOCK(_inp) do { \
@ -384,27 +401,11 @@
(void)pthread_mutex_unlock(&(_inp)->inp_mtx)
#endif
#define SCTP_INP_RLOCK_ASSERT(_inp) \
KASSERT(pthread_mutex_trylock(&(_inp)->inp_mtx) == EBUSY, ("%s: inp_mtx not locked", __func__))
KASSERT(pthread_mutex_trylock(&(_inp)->inp_mtx) == EBUSY, ("%s:%d: inp_mtx not locked", __FILE__, __LINE__))
#define SCTP_INP_WLOCK_ASSERT(_inp) \
KASSERT(pthread_mutex_trylock(&(_inp)->inp_mtx) == EBUSY, ("%s: inp_mtx not locked", __func__))
KASSERT(pthread_mutex_trylock(&(_inp)->inp_mtx) == EBUSY, ("%s:%d: inp_mtx not locked", __FILE__, __LINE__))
#define SCTP_INP_INCR_REF(_inp) atomic_add_int(&((_inp)->refcount), 1)
#define SCTP_INP_DECR_REF(_inp) atomic_add_int(&((_inp)->refcount), -1)
#define SCTP_TCB_SEND_LOCK_INIT(_tcb) \
(void)pthread_mutex_init(&(_tcb)->tcb_send_mtx, &SCTP_BASE_VAR(mtx_attr))
#define SCTP_TCB_SEND_LOCK_DESTROY(_tcb) \
(void)pthread_mutex_destroy(&(_tcb)->tcb_send_mtx)
#ifdef INVARIANTS
#define SCTP_TCB_SEND_LOCK(_tcb) \
KASSERT(pthread_mutex_lock(&(_tcb)->tcb_send_mtx) == 0, ("%s: tcb_send_mtx already locked", __func__))
#define SCTP_TCB_SEND_UNLOCK(_tcb) \
KASSERT(pthread_mutex_unlock(&(_tcb)->tcb_send_mtx) == 0, ("%s: tcb_send_mtx not locked", __func__))
#else
#define SCTP_TCB_SEND_LOCK(_tcb) \
(void)pthread_mutex_lock(&(_tcb)->tcb_send_mtx)
#define SCTP_TCB_SEND_UNLOCK(_tcb) \
(void)pthread_mutex_unlock(&(_tcb)->tcb_send_mtx)
#endif
#define SCTP_INP_DECR_REF(_inp) atomic_subtract_int(&((_inp)->refcount), 1)
#define SCTP_ASOC_CREATE_LOCK_INIT(_inp) \
(void)pthread_mutex_init(&(_inp)->inp_create_mtx, &SCTP_BASE_VAR(mtx_attr))
@ -412,17 +413,17 @@
(void)pthread_mutex_destroy(&(_inp)->inp_create_mtx)
#ifdef INVARIANTS
#ifdef SCTP_LOCK_LOGGING
#define SCTP_ASOC_CREATE_LOCK(_inp) do { \
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_CREATE); \
KASSERT(pthread_mutex_lock(&(_inp)->inp_create_mtx) == 0, ("%s: inp_create_mtx already locked", __func__)) \
#define SCTP_ASOC_CREATE_LOCK(_inp) do { \
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_CREATE); \
KASSERT(pthread_mutex_lock(&(_inp)->inp_create_mtx) == 0, ("%s:%d: inp_create_mtx already locked", __FILE__, __LINE__)); \
} while (0)
#else
#define SCTP_ASOC_CREATE_LOCK(_inp) \
KASSERT(pthread_mutex_lock(&(_inp)->inp_create_mtx) == 0, ("%s: inp_create_mtx already locked", __func__))
KASSERT(pthread_mutex_lock(&(_inp)->inp_create_mtx) == 0, ("%s:%d: inp_create_mtx already locked", __FILE__, __LINE__))
#endif
#define SCTP_ASOC_CREATE_UNLOCK(_inp) \
KASSERT(pthread_mutex_unlock(&(_inp)->inp_create_mtx) == 0, ("%s: inp_create_mtx not locked", __func__))
KASSERT(pthread_mutex_unlock(&(_inp)->inp_create_mtx) == 0, ("%s:%d: inp_create_mtx not locked", __FILE__, __LINE__))
#else
#ifdef SCTP_LOCK_LOGGING
#define SCTP_ASOC_CREATE_LOCK(_inp) do { \
@ -451,17 +452,17 @@
(void)pthread_mutex_destroy(&(_tcb)->tcb_mtx)
#ifdef INVARIANTS
#ifdef SCTP_LOCK_LOGGING
#define SCTP_TCB_LOCK(_tcb) do { \
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
sctp_log_lock(_tcb->sctp_ep, _tcb, SCTP_LOG_LOCK_TCB); \
KASSERT(pthread_mutex_lock(&(_tcb)->tcb_mtx) == 0, ("%s: tcb_mtx already locked", __func__)) \
#define SCTP_TCB_LOCK(_tcb) do { \
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
sctp_log_lock(_tcb->sctp_ep, _tcb, SCTP_LOG_LOCK_TCB); \
KASSERT(pthread_mutex_lock(&(_tcb)->tcb_mtx) == 0, ("%s:%d: tcb_mtx already locked", __FILE__, __LINE__)) \
} while (0)
#else
#define SCTP_TCB_LOCK(_tcb) \
KASSERT(pthread_mutex_lock(&(_tcb)->tcb_mtx) == 0, ("%s: tcb_mtx already locked", __func__))
KASSERT(pthread_mutex_lock(&(_tcb)->tcb_mtx) == 0, ("%s:%d: tcb_mtx already locked", __FILE__, __LINE__))
#endif
#define SCTP_TCB_UNLOCK(_tcb) \
KASSERT(pthread_mutex_unlock(&(_tcb)->tcb_mtx) == 0, ("%s: tcb_mtx not locked", __func__))
KASSERT(pthread_mutex_unlock(&(_tcb)->tcb_mtx) == 0, ("%s:%d: tcb_mtx not locked", __FILE__, __LINE__))
#else
#ifdef SCTP_LOCK_LOGGING
#define SCTP_TCB_LOCK(_tcb) do { \
@ -476,7 +477,7 @@
#define SCTP_TCB_UNLOCK(_tcb) (void)pthread_mutex_unlock(&(_tcb)->tcb_mtx)
#endif
#define SCTP_TCB_LOCK_ASSERT(_tcb) \
KASSERT(pthread_mutex_trylock(&(_tcb)->tcb_mtx) == EBUSY, ("%s: tcb_mtx not locked", __func__))
KASSERT(pthread_mutex_trylock(&(_tcb)->tcb_mtx) == EBUSY, ("%s:%d: tcb_mtx not locked", __FILE__, __LINE__))
#define SCTP_TCB_TRYLOCK(_tcb) (!(pthread_mutex_trylock(&(_tcb)->tcb_mtx)))
#endif
@ -506,12 +507,12 @@
SOCKBUF_UNLOCK(&(_so)->so_rcv)
#else
#define SOCKBUF_LOCK_ASSERT(_so_buf) \
KASSERT(pthread_mutex_trylock(SOCKBUF_MTX(_so_buf)) == EBUSY, ("%s: socket buffer not locked", __func__))
KASSERT(pthread_mutex_trylock(SOCKBUF_MTX(_so_buf)) == EBUSY, ("%s:%d: socket buffer not locked", __FILE__, __LINE__))
#ifdef INVARIANTS
#define SOCKBUF_LOCK(_so_buf) \
KASSERT(pthread_mutex_lock(SOCKBUF_MTX(_so_buf)) == 0, ("%s: sockbuf_mtx already locked", __func__))
KASSERT(pthread_mutex_lock(SOCKBUF_MTX(_so_buf)) == 0, ("%s:%d: sockbuf_mtx already locked", __FILE__, __LINE__))
#define SOCKBUF_UNLOCK(_so_buf) \
KASSERT(pthread_mutex_unlock(SOCKBUF_MTX(_so_buf)) == 0, ("%s: sockbuf_mtx not locked", __func__))
KASSERT(pthread_mutex_unlock(SOCKBUF_MTX(_so_buf)) == 0, ("%s:%d: sockbuf_mtx not locked", __FILE__, __LINE__))
#else
#define SOCKBUF_LOCK(_so_buf) \
pthread_mutex_lock(SOCKBUF_MTX(_so_buf))
@ -531,6 +532,7 @@
#if defined(_WIN32)
/* address list locks */
#if WINVER < 0x0600
#define SCTP_IPI_ADDR_INIT() \
InitializeCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_DESTROY() \
@ -543,7 +545,23 @@
EnterCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_WUNLOCK() \
LeaveCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_LOCK_ASSERT()
#define SCTP_IPI_ADDR_WLOCK_ASSERT()
#else
#define SCTP_IPI_ADDR_INIT() \
InitializeSRWLock(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_DESTROY()
#define SCTP_IPI_ADDR_RLOCK() \
AcquireSRWLockShared(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_RUNLOCK() \
ReleaseSRWLockShared(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_WLOCK() \
AcquireSRWLockExclusive(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_WUNLOCK() \
ReleaseSRWLockExclusive(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_LOCK_ASSERT()
#define SCTP_IPI_ADDR_WLOCK_ASSERT()
#endif
/* iterator locks */
#define SCTP_ITERATOR_LOCK_INIT() \
@ -567,28 +585,30 @@
#else
/* address list locks */
#define SCTP_IPI_ADDR_INIT() \
(void)pthread_mutex_init(&SCTP_BASE_INFO(ipi_addr_mtx), &SCTP_BASE_VAR(mtx_attr))
(void)pthread_rwlock_init(&SCTP_BASE_INFO(ipi_addr_mtx), &SCTP_BASE_VAR(rwlock_attr))
#define SCTP_IPI_ADDR_DESTROY() \
(void)pthread_mutex_destroy(&SCTP_BASE_INFO(ipi_addr_mtx))
(void)pthread_rwlock_destroy(&SCTP_BASE_INFO(ipi_addr_mtx))
#ifdef INVARIANTS
#define SCTP_IPI_ADDR_RLOCK() \
KASSERT(pthread_mutex_lock(&SCTP_BASE_INFO(ipi_addr_mtx)) == 0, ("%s: ipi_addr_mtx already locked", __func__))
KASSERT(pthread_rwlock_rdlock(&SCTP_BASE_INFO(ipi_addr_mtx)) == 0, ("%s:%d: ipi_addr_mtx already locked", __FILE__, __LINE__))
#define SCTP_IPI_ADDR_RUNLOCK() \
KASSERT(pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_addr_mtx)) == 0, ("%s: ipi_addr_mtx not locked", __func__))
KASSERT(pthread_rwlock_unlock(&SCTP_BASE_INFO(ipi_addr_mtx)) == 0, ("%s:%d: ipi_addr_mtx not locked", __FILE__, __LINE__))
#define SCTP_IPI_ADDR_WLOCK() \
KASSERT(pthread_mutex_lock(&SCTP_BASE_INFO(ipi_addr_mtx)) == 0, ("%s: ipi_addr_mtx already locked", __func__))
KASSERT(pthread_rwlock_wrlock(&SCTP_BASE_INFO(ipi_addr_mtx)) == 0, ("%s:%d: ipi_addr_mtx already locked", __FILE__, __LINE__))
#define SCTP_IPI_ADDR_WUNLOCK() \
KASSERT(pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_addr_mtx)) == 0, ("%s: ipi_addr_mtx not locked", __func__))
KASSERT(pthread_rwlock_unlock(&SCTP_BASE_INFO(ipi_addr_mtx)) == 0, ("%s:%d: ipi_addr_mtx not locked", __FILE__, __LINE__))
#else
#define SCTP_IPI_ADDR_RLOCK() \
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_addr_mtx))
(void)pthread_rwlock_rdlock(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_RUNLOCK() \
(void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_addr_mtx))
(void)pthread_rwlock_unlock(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_WLOCK() \
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_addr_mtx))
(void)pthread_rwlock_wrlock(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_WUNLOCK() \
(void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_addr_mtx))
(void)pthread_rwlock_unlock(&SCTP_BASE_INFO(ipi_addr_mtx))
#endif
#define SCTP_IPI_ADDR_LOCK_ASSERT()
#define SCTP_IPI_ADDR_WLOCK_ASSERT()
/* iterator locks */
#define SCTP_ITERATOR_LOCK_INIT() \
@ -597,9 +617,9 @@
(void)pthread_mutex_destroy(&sctp_it_ctl.it_mtx)
#ifdef INVARIANTS
#define SCTP_ITERATOR_LOCK() \
KASSERT(pthread_mutex_lock(&sctp_it_ctl.it_mtx) == 0, ("%s: it_mtx already locked", __func__))
KASSERT(pthread_mutex_lock(&sctp_it_ctl.it_mtx) == 0, ("%s:%d: it_mtx already locked", __FILE__, __LINE__))
#define SCTP_ITERATOR_UNLOCK() \
KASSERT(pthread_mutex_unlock(&sctp_it_ctl.it_mtx) == 0, ("%s: it_mtx not locked", __func__))
KASSERT(pthread_mutex_unlock(&sctp_it_ctl.it_mtx) == 0, ("%s:%d: it_mtx not locked", __FILE__, __LINE__))
#else
#define SCTP_ITERATOR_LOCK() \
(void)pthread_mutex_lock(&sctp_it_ctl.it_mtx)
@ -613,9 +633,9 @@
(void)pthread_mutex_destroy(&sctp_it_ctl.ipi_iterator_wq_mtx)
#ifdef INVARIANTS
#define SCTP_IPI_ITERATOR_WQ_LOCK() \
KASSERT(pthread_mutex_lock(&sctp_it_ctl.ipi_iterator_wq_mtx) == 0, ("%s: ipi_iterator_wq_mtx already locked", __func__))
KASSERT(pthread_mutex_lock(&sctp_it_ctl.ipi_iterator_wq_mtx) == 0, ("%s:%d: ipi_iterator_wq_mtx already locked", __FILE__, __LINE__))
#define SCTP_IPI_ITERATOR_WQ_UNLOCK() \
KASSERT(pthread_mutex_unlock(&sctp_it_ctl.ipi_iterator_wq_mtx) == 0, ("%s: ipi_iterator_wq_mtx not locked", __func__))
KASSERT(pthread_mutex_unlock(&sctp_it_ctl.ipi_iterator_wq_mtx) == 0, ("%s:%d: ipi_iterator_wq_mtx not locked", __FILE__, __LINE__))
#else
#define SCTP_IPI_ITERATOR_WQ_LOCK() \
(void)pthread_mutex_lock(&sctp_it_ctl.ipi_iterator_wq_mtx)

View File

@ -80,7 +80,25 @@ sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx)
{
SHA1_Final(digest, &ctx->sha_ctx);
}
#elif defined(SCTP_USE_MBEDTLS_SHA1)
void
sctp_sha1_init(struct sctp_sha1_context *ctx)
{
mbedtls_sha1_init(&ctx->sha1_ctx);
mbedtls_sha1_starts_ret(&ctx->sha1_ctx);
}
void
sctp_sha1_update(struct sctp_sha1_context *ctx, const unsigned char *ptr, unsigned int siz)
{
mbedtls_sha1_update_ret(&ctx->sha1_ctx, ptr, siz);
}
void
sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx)
{
mbedtls_sha1_finish_ret(&ctx->sha1_ctx, digest);
}
#else
#include <string.h>

View File

@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$");
#include <pk11pub.h>
#elif defined(SCTP_USE_OPENSSL_SHA1)
#include <openssl/sha.h>
#elif defined(SCTP_USE_MBEDTLS_SHA1)
#include <mbedtls/sha1.h>
#endif
struct sctp_sha1_context {
@ -53,6 +55,8 @@ struct sctp_sha1_context {
struct PK11Context *pk11_ctx;
#elif defined(SCTP_USE_OPENSSL_SHA1)
SHA_CTX sha_ctx;
#elif defined(SCTP_USE_MBEDTLS_SHA1)
mbedtls_sha1_context sha1_ctx;
#else
unsigned int A;
unsigned int B;

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 362106 2020-06-12 16:31:13Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_STRUCTS_H_
@ -65,7 +65,6 @@ struct sctp_timer {
uint32_t stopped_from;
};
struct sctp_foo_stuff {
struct sctp_inpcb *inp;
uint32_t lineno;
@ -73,7 +72,6 @@ struct sctp_foo_stuff {
int updown;
};
/*
* This is the information we track on each interface that we know about from
* the distant end.
@ -137,6 +135,26 @@ struct sctp_mcore_ctrl {
#endif
#endif
/* This struct is here to cut out the compatiabilty
* pad that bulks up both the inp and stcb. The non
* pad portion MUST stay in complete sync with
* sctp_sndrcvinfo... i.e. if sinfo_xxxx is added
* this must be done here too.
*/
struct sctp_nonpad_sndrcvinfo {
uint16_t sinfo_stream;
uint16_t sinfo_ssn;
uint16_t sinfo_flags;
uint32_t sinfo_ppid;
uint32_t sinfo_context;
uint32_t sinfo_timetolive;
uint32_t sinfo_tsn;
uint32_t sinfo_cumtsn;
sctp_assoc_t sinfo_assoc_id;
uint16_t sinfo_keynumber;
uint16_t sinfo_keynumber_valid;
};
struct sctp_iterator {
TAILQ_ENTRY(sctp_iterator) sctp_nxt_itr;
#if defined(__FreeBSD__) && !defined(__Userspace__)
@ -163,13 +181,12 @@ struct sctp_iterator {
#define SCTP_ITERATOR_DO_ALL_INP 0x00000001
#define SCTP_ITERATOR_DO_SINGLE_INP 0x00000002
TAILQ_HEAD(sctpiterators, sctp_iterator);
struct sctp_copy_all {
struct sctp_inpcb *inp; /* ep */
struct mbuf *m;
struct sctp_sndrcvinfo sndrcv;
struct sctp_nonpad_sndrcvinfo sndrcv;
ssize_t sndlen;
int cnt_sent;
int cnt_failed;
@ -293,7 +310,6 @@ struct rtcc_cc {
uint8_t last_inst_ind; /* Last saved inst indication */
};
struct sctp_nets {
TAILQ_ENTRY(sctp_nets) sctp_next; /* next link */
@ -436,7 +452,6 @@ struct sctp_nets {
#endif
};
struct sctp_data_chunkrec {
uint32_t tsn; /* the TSN of this transmit */
uint32_t mid; /* the message identifier of this transmit */
@ -475,7 +490,6 @@ struct chk_id {
uint8_t can_take_data;
};
struct sctp_tmit_chunk {
union {
struct sctp_data_chunkrec data;
@ -561,6 +575,7 @@ struct sctp_queued_to_read { /* sinfo structure Pluse more */
* the user is in the explict MSG_EOR mode
* and wrote some data, but has not completed
* sending.
* ss_next and scheduled are only used by the FCFS stream scheduler.
*/
struct sctp_stream_queue_pending {
struct mbuf *data;
@ -584,6 +599,8 @@ struct sctp_stream_queue_pending {
uint8_t sender_all_done;
uint8_t put_last_out;
uint8_t discard_rest;
uint8_t processing;
bool scheduled;
};
/*
@ -603,6 +620,19 @@ struct sctp_stream_in {
TAILQ_HEAD(sctpwheel_listhead, sctp_stream_out);
TAILQ_HEAD(sctplist_listhead, sctp_stream_queue_pending);
/*
* This union holds all data necessary for
* different stream schedulers.
*/
struct scheduling_data {
struct sctp_stream_out *locked_on_sending;
/* circular looking for output selection */
struct sctp_stream_out *last_out_stream;
union {
struct sctpwheel_listhead wheel;
struct sctplist_listhead list;
} out;
};
/* Round-robin schedulers */
struct ss_rr {
@ -626,28 +656,17 @@ struct ss_fb {
int32_t rounds;
};
/*
* This union holds all data necessary for
* different stream schedulers.
*/
struct scheduling_data {
struct sctp_stream_out *locked_on_sending;
/* circular looking for output selection */
struct sctp_stream_out *last_out_stream;
union {
struct sctpwheel_listhead wheel;
struct sctplist_listhead list;
} out;
};
/*
* This union holds all parameters per stream
* necessary for different stream schedulers.
*/
union scheduling_parameters {
struct ss_rr rr;
struct ss_prio prio;
struct ss_fb fb;
struct scheduling_parameters {
union {
struct ss_rr rr;
struct ss_prio prio;
struct ss_fb fb;
} ss;
bool scheduled;
};
/* States for outgoing streams */
@ -657,12 +676,10 @@ union scheduling_parameters {
#define SCTP_STREAM_RESET_PENDING 0x03
#define SCTP_STREAM_RESET_IN_FLIGHT 0x04
#define SCTP_MAX_STREAMS_AT_ONCE_RESET 200
/* This struct is used to track the traffic on outbound streams */
struct sctp_stream_out {
struct sctp_streamhead outqueue;
union scheduling_parameters ss_params;
struct scheduling_parameters ss_params;
uint32_t chunks_on_queues; /* send queue and sent queue */
#if defined(SCTP_DETAILED_STR_STATS)
uint32_t abandoned_unsent[SCTP_PR_SCTP_MAX + 1];
@ -682,6 +699,8 @@ struct sctp_stream_out {
uint8_t state;
};
#define SCTP_MAX_STREAMS_AT_ONCE_RESET 200
/* used to keep track of the addresses yet to try to add/delete */
TAILQ_HEAD(sctp_asconf_addrhead, sctp_asconf_addr);
struct sctp_asconf_addr {
@ -728,26 +747,6 @@ struct sctp_fs_spec_log {
uint8_t decr;
};
/* This struct is here to cut out the compatiabilty
* pad that bulks up both the inp and stcb. The non
* pad portion MUST stay in complete sync with
* sctp_sndrcvinfo... i.e. if sinfo_xxxx is added
* this must be done here too.
*/
struct sctp_nonpad_sndrcvinfo {
uint16_t sinfo_stream;
uint16_t sinfo_ssn;
uint16_t sinfo_flags;
uint32_t sinfo_ppid;
uint32_t sinfo_context;
uint32_t sinfo_timetolive;
uint32_t sinfo_tsn;
uint32_t sinfo_cumtsn;
sctp_assoc_t sinfo_assoc_id;
uint16_t sinfo_keynumber;
uint16_t sinfo_keynumber_valid;
};
/*
* JRS - Structure to hold function pointers to the functions responsible
* for congestion control.
@ -787,16 +786,15 @@ struct sctp_cc_functions {
* for stream scheduling.
*/
struct sctp_ss_functions {
void (*sctp_ss_init)(struct sctp_tcb *stcb, struct sctp_association *asoc,
int holds_lock);
void (*sctp_ss_init)(struct sctp_tcb *stcb, struct sctp_association *asoc);
void (*sctp_ss_clear)(struct sctp_tcb *stcb, struct sctp_association *asoc,
int clear_values, int holds_lock);
bool clear_values);
void (*sctp_ss_init_stream)(struct sctp_tcb *stcb, struct sctp_stream_out *strq, struct sctp_stream_out *with_strq);
void (*sctp_ss_add_to_stream)(struct sctp_tcb *stcb, struct sctp_association *asoc,
struct sctp_stream_out *strq, struct sctp_stream_queue_pending *sp, int holds_lock);
int (*sctp_ss_is_empty)(struct sctp_tcb *stcb, struct sctp_association *asoc);
struct sctp_stream_out *strq, struct sctp_stream_queue_pending *sp);
bool (*sctp_ss_is_empty)(struct sctp_tcb *stcb, struct sctp_association *asoc);
void (*sctp_ss_remove_from_stream)(struct sctp_tcb *stcb, struct sctp_association *asoc,
struct sctp_stream_out *strq, struct sctp_stream_queue_pending *sp, int holds_lock);
struct sctp_stream_out *strq, struct sctp_stream_queue_pending *sp);
struct sctp_stream_out* (*sctp_ss_select_stream)(struct sctp_tcb *stcb,
struct sctp_nets *net, struct sctp_association *asoc);
void (*sctp_ss_scheduled)(struct sctp_tcb *stcb, struct sctp_nets *net,
@ -807,7 +805,7 @@ struct sctp_ss_functions {
struct sctp_stream_out *strq, uint16_t *value);
int (*sctp_ss_set_value)(struct sctp_tcb *stcb, struct sctp_association *asoc,
struct sctp_stream_out *strq, uint16_t value);
int (*sctp_ss_is_user_msgs_incomplete)(struct sctp_tcb *stcb, struct sctp_association *asoc);
bool (*sctp_ss_is_user_msgs_incomplete)(struct sctp_tcb *stcb, struct sctp_association *asoc);
};
/* used to save ASCONF chunks for retransmission */
@ -920,7 +918,6 @@ struct sctp_association {
/* last place I got a control from */
struct sctp_nets *last_control_chunk_from;
/*
* wait to the point the cum-ack passes req->send_reset_at_tsn for
* any req on the list.
@ -984,7 +981,6 @@ struct sctp_association {
/* Original seq number I used ??questionable to keep?? */
uint32_t init_seq_number;
/* The Advanced Peer Ack Point, as required by the PR-SCTP */
/* (A1 in Section 4.2) */
uint32_t advanced_peer_ack_point;

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 361934 2020-06-08 20:23:20Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
@ -61,7 +61,7 @@ FEATURE(sctp, "Stream Control Transmission Protocol");
*/
void
sctp_init_sysctls()
sctp_init_sysctls(void)
{
SCTP_BASE_SYSCTL(sctp_sendspace) = SCTPCTL_MAXDGRAM_DEFAULT;
SCTP_BASE_SYSCTL(sctp_recvspace) = SCTPCTL_RECVSPACE_DEFAULT;
@ -175,8 +175,8 @@ sctp_init_sysctls()
SCTP_BASE_SYSCTL(sctp_output_unlocked) = SCTPCTL_OUTPUT_UNLOCKED_DEFAULT;
#endif
}
#if defined(_WIN32) && !defined(__Userspace__)
void
sctp_finish_sysctls()
{
@ -201,7 +201,7 @@ sctp_sysctl_number_of_addresses(struct sctp_inpcb *inp)
struct sctp_laddr *laddr;
cnt = 0;
/* neither Mac OS X nor FreeBSD support mulitple routing functions */
/* neither Mac OS X nor FreeBSD support multiple routing functions */
if ((vrf = sctp_find_vrf(inp->def_vrf_id)) == NULL) {
return (0);
}
@ -246,8 +246,15 @@ sctp_sysctl_copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *st
{
struct sctp_ifn *sctp_ifn;
struct sctp_ifa *sctp_ifa;
int loopback_scope, ipv4_local_scope, local_scope, site_scope;
int ipv4_addr_legal, ipv6_addr_legal;
int loopback_scope;
#ifdef INET
int ipv4_local_scope;
int ipv4_addr_legal;
#endif
#ifdef INET6
int local_scope, site_scope;
int ipv6_addr_legal;
#endif
#if defined(__Userspace__)
int conn_addr_legal;
#endif
@ -257,68 +264,90 @@ sctp_sysctl_copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *st
int error;
/* Turn on all the appropriate scope */
if (stcb) {
if (stcb != NULL) {
/* use association specific values */
loopback_scope = stcb->asoc.scope.loopback_scope;
#ifdef INET
ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
#endif
#ifdef INET6
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;
#endif
#if defined(__Userspace__)
conn_addr_legal = stcb->asoc.scope.conn_addr_legal;
#endif
} else {
/* Use generic values for endpoints. */
loopback_scope = 1;
#ifdef INET
ipv4_local_scope = 1;
#endif
#ifdef INET6
local_scope = 1;
site_scope = 1;
#endif
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
#ifdef INET6
ipv6_addr_legal = 1;
#endif
#ifdef INET
if (SCTP_IPV6_V6ONLY(inp)) {
ipv4_addr_legal = 0;
} else {
ipv4_addr_legal = 1;
}
#endif
#if defined(__Userspace__)
conn_addr_legal = 0;
#endif
} else {
#ifdef INET6
ipv6_addr_legal = 0;
#endif
#if defined(__Userspace__)
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) {
conn_addr_legal = 1;
#ifdef INET
ipv4_addr_legal = 0;
#endif
} else {
conn_addr_legal = 0;
#ifdef INET
ipv4_addr_legal = 1;
#endif
}
#else
#ifdef INET
ipv4_addr_legal = 1;
#endif
#endif
}
}
/* neither Mac OS X nor FreeBSD support mulitple routing functions */
/* Neither Mac OS X nor FreeBSD support multiple routing functions. */
if ((vrf = sctp_find_vrf(inp->def_vrf_id)) == NULL) {
SCTP_INP_RUNLOCK(inp);
SCTP_INP_INFO_RUNLOCK();
return (-1);
return (ENOENT);
}
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
if ((loopback_scope == 0) && SCTP_IFN_IS_IFT_LOOP(sctp_ifn))
/* Skip loopback if loopback_scope not set */
if ((loopback_scope == 0) && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
/* Skip loopback if loopback_scope not set. */
continue;
}
LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
if (stcb) {
if (stcb != NULL) {
/*
* ignore if blacklisted at
* association level
* Ignore if blacklisted at
* association level.
*/
if (sctp_is_addr_restricted(stcb, sctp_ifa))
if (sctp_is_addr_restricted(stcb, sctp_ifa)) {
continue;
}
}
switch (sctp_ifa->address.sa.sa_family) {
#ifdef INET
@ -327,16 +356,18 @@ sctp_sysctl_copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *st
struct sockaddr_in *sin;
sin = &sctp_ifa->address.sin;
if (sin->sin_addr.s_addr == 0)
if (sin->sin_addr.s_addr == 0) {
continue;
}
#if defined(__FreeBSD__) && !defined(__Userspace__)
if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
&sin->sin_addr) != 0) {
continue;
}
#endif
if ((ipv4_local_scope == 0) && (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)))
if ((ipv4_local_scope == 0) && (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
continue;
}
} else {
continue;
}
@ -348,8 +379,9 @@ sctp_sysctl_copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *st
struct sockaddr_in6 *sin6;
sin6 = &sctp_ifa->address.sin6;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
continue;
}
#if defined(__FreeBSD__) && !defined(__Userspace__)
if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
&sin6->sin6_addr) != 0) {
@ -357,11 +389,13 @@ sctp_sysctl_copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *st
}
#endif
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
if (local_scope == 0)
if (local_scope == 0) {
continue;
}
}
if ((site_scope == 0) && (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)))
if ((site_scope == 0) && (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
continue;
}
} else {
continue;
}
@ -382,7 +416,7 @@ sctp_sysctl_copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *st
SCTP_INP_RUNLOCK(inp);
SCTP_INP_INFO_RUNLOCK();
error = SYSCTL_OUT(req, &xladdr, sizeof(struct xsctp_laddr));
if (error) {
if (error != 0) {
return (error);
} else {
SCTP_INP_INFO_RLOCK();
@ -393,7 +427,7 @@ sctp_sysctl_copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *st
} else {
LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
/* ignore if blacklisted at association level */
if (stcb && sctp_is_addr_restricted(stcb, laddr->ifa))
if (stcb != NULL && sctp_is_addr_restricted(stcb, laddr->ifa))
continue;
memset((void *)&xladdr, 0, sizeof(struct xsctp_laddr));
memcpy((void *)&xladdr.address, (const void *)&laddr->ifa->address, sizeof(union sctp_sockstore));
@ -402,7 +436,7 @@ sctp_sysctl_copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *st
SCTP_INP_RUNLOCK(inp);
SCTP_INP_INFO_RUNLOCK();
error = SYSCTL_OUT(req, &xladdr, sizeof(struct xsctp_laddr));
if (error) {
if (error != 0) {
return (error);
} else {
SCTP_INP_INFO_RLOCK();
@ -416,7 +450,7 @@ sctp_sysctl_copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *st
SCTP_INP_INFO_RUNLOCK();
error = SYSCTL_OUT(req, &xladdr, sizeof(struct xsctp_laddr));
if (error) {
if (error != 0) {
return (error);
} else {
SCTP_INP_INFO_RLOCK();
@ -727,8 +761,8 @@ sctp_sysctl_handle_udp_tunneling(SYSCTL_HANDLER_ARGS)
}
return (error);
}
#if defined(__APPLE__) && !defined(__Userspace__)
int sctp_is_vmware_interface(struct ifnet *);
static int

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.h 361895 2020-06-07 14:39:20Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_SYSCTL_H_
@ -56,7 +56,7 @@ struct sctp_sysctl {
uint32_t sctp_nrsack_enable;
uint32_t sctp_pktdrop_enable;
uint32_t sctp_fr_max_burst_default;
#if !(defined(__FreeBSD__) && !defined(__Userspace__))
#if !(defined(__FreeBSD__) && !defined(__Userspace__))
uint32_t sctp_no_csum_on_loopback;
#endif
uint32_t sctp_peer_chunk_oh;
@ -170,7 +170,7 @@ struct sctp_sysctl {
#define SCTPCTL_AUTOASCONF_DEFAULT 1
/* autoasconf: Enable SCTP Auto-ASCONF */
#define SCTPCTL_MULTIPLEASCONFS_DESC "Enable SCTP Muliple-ASCONFs"
#define SCTPCTL_MULTIPLEASCONFS_DESC "Enable SCTP Multiple-ASCONFs"
#define SCTPCTL_MULTIPLEASCONFS_MIN 0
#define SCTPCTL_MULTIPLEASCONFS_MAX 1
#define SCTPCTL_MULTIPLEASCONFS_DEFAULT SCTP_DEFAULT_MULTIPLE_ASCONFS
@ -241,7 +241,6 @@ struct sctp_sysctl {
#define SCTPCTL_FRMAXBURST_MAX 0xFFFFFFFF
#define SCTPCTL_FRMAXBURST_DEFAULT SCTP_DEF_FRMAX_BURST
/* maxchunks: Default max chunks on queue per asoc */
#define SCTPCTL_MAXCHUNKS_DESC "Default max chunks on queue per asoc"
#define SCTPCTL_MAXCHUNKS_MIN 0
@ -344,10 +343,10 @@ struct sctp_sysctl {
#define SCTPCTL_INIT_RTO_MAX_MAX 0xFFFFFFFF
#define SCTPCTL_INIT_RTO_MAX_DEFAULT SCTP_RTO_UPPER_BOUND
/* valid_cookie_life: Default cookie lifetime in sec */
#define SCTPCTL_VALID_COOKIE_LIFE_DESC "Default cookie lifetime in seconds"
#define SCTPCTL_VALID_COOKIE_LIFE_MIN 0
#define SCTPCTL_VALID_COOKIE_LIFE_MAX 0xFFFFFFFF
/* valid_cookie_life: Default cookie lifetime in ms */
#define SCTPCTL_VALID_COOKIE_LIFE_DESC "Default cookie lifetime in ms"
#define SCTPCTL_VALID_COOKIE_LIFE_MIN SCTP_MIN_COOKIE_LIFE
#define SCTPCTL_VALID_COOKIE_LIFE_MAX SCTP_MAX_COOKIE_LIFE
#define SCTPCTL_VALID_COOKIE_LIFE_DEFAULT SCTP_DEFAULT_COOKIE_LIFE
/* init_rtx_max: Default maximum number of retransmission for INIT chunks */
@ -595,16 +594,12 @@ struct sctp_sysctl {
#define SCTPCTL_IGNORE_VMWARE_INTERFACES_MIN 0
#define SCTPCTL_IGNORE_VMWARE_INTERFACES_MAX 1
#define SCTPCTL_IGNORE_VMWARE_INTERFACES_DEFAULT SCTPCTL_IGNORE_VMWARE_INTERFACES_MAX
#endif
#if defined(__APPLE__) && !defined(__Userspace__)
#define SCTPCTL_OUTPUT_UNLOCKED_DESC "Unlock socket when sending packets down to IP"
#define SCTPCTL_OUTPUT_UNLOCKED_MIN 0
#define SCTPCTL_OUTPUT_UNLOCKED_MAX 1
#define SCTPCTL_OUTPUT_UNLOCKED_DEFAULT SCTPCTL_OUTPUT_UNLOCKED_MIN
#endif
#if defined(__APPLE__) && !defined(__Userspace__)
#define SCTPCTL_ADDR_WATCHDOG_LIMIT_DESC "Address watchdog limit"
#define SCTPCTL_ADDR_WATCHDOG_LIMIT_MIN 0
#define SCTPCTL_ADDR_WATCHDOG_LIMIT_MAX 0xFFFFFFFF
@ -614,8 +609,8 @@ struct sctp_sysctl {
#define SCTPCTL_VTAG_WATCHDOG_LIMIT_MIN 0
#define SCTPCTL_VTAG_WATCHDOG_LIMIT_MAX 0xFFFFFFFF
#define SCTPCTL_VTAG_WATCHDOG_LIMIT_DEFAULT SCTPCTL_VTAG_WATCHDOG_LIMIT_MIN
#endif
#endif
#if defined(_KERNEL) || defined(__Userspace__)
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Userspace__)
#if defined(SYSCTL_DECL)

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 362054 2020-06-11 13:34:09Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#define _IP_VHL
@ -114,7 +114,7 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
} else if ((net->pf_threshold < net->failure_threshold) &&
(net->error_count > net->pf_threshold)) {
if (!(net->dest_state & SCTP_ADDR_PF)) {
if ((net->dest_state & SCTP_ADDR_PF) == 0) {
net->dest_state |= SCTP_ADDR_PF;
net->last_active = sctp_get_tick_count();
sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
@ -132,20 +132,20 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0) {
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_INCR,
stcb->asoc.overall_error_count,
(stcb->asoc.overall_error_count+1),
SCTP_FROM_SCTP_TIMER,
__LINE__);
stcb->asoc.overall_error_count,
(stcb->asoc.overall_error_count+1),
SCTP_FROM_SCTP_TIMER,
__LINE__);
}
stcb->asoc.overall_error_count++;
}
} else {
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_INCR,
stcb->asoc.overall_error_count,
(stcb->asoc.overall_error_count+1),
SCTP_FROM_SCTP_TIMER,
__LINE__);
stcb->asoc.overall_error_count,
(stcb->asoc.overall_error_count+1),
SCTP_FROM_SCTP_TIMER,
__LINE__);
}
stcb->asoc.overall_error_count++;
}
@ -164,15 +164,15 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
"Association error counter exceeded");
inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_2;
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
sctp_abort_an_association(inp, stcb, op_err, true, SCTP_SO_NOT_LOCKED);
return (1);
}
return (0);
}
/*
* sctp_find_alternate_net() returns a non-NULL pointer as long
* the argument net is non-NULL.
* sctp_find_alternate_net() returns a non-NULL pointer as long as there
* exists nets, which are not being deleted.
*/
struct sctp_nets *
sctp_find_alternate_net(struct sctp_tcb *stcb,
@ -181,20 +181,20 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
{
/* Find and return an alternate network if possible */
struct sctp_nets *alt, *mnet, *min_errors_net = NULL , *max_cwnd_net = NULL;
int once;
bool looped;
/* JRS 5/14/07 - Initialize min_errors to an impossible value. */
int min_errors = -1;
uint32_t max_cwnd = 0;
if (stcb->asoc.numnets == 1) {
/* No others but net */
/* No selection can be made. */
return (TAILQ_FIRST(&stcb->asoc.nets));
}
/*
* JRS 5/14/07 - If mode is set to 2, use the CMT PF find alternate net algorithm.
* This algorithm chooses the active destination (not in PF state) with the largest
* cwnd value. If all destinations are in PF state, unreachable, or unconfirmed, choose
* the desination that is in PF state with the lowest error count. In case of a tie,
* the destination that is in PF state with the lowest error count. In case of a tie,
* choose the destination that was most recently active.
*/
if (mode == 2) {
@ -323,25 +323,22 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
return (max_cwnd_net);
}
}
mnet = net;
once = 0;
if (mnet == NULL) {
mnet = TAILQ_FIRST(&stcb->asoc.nets);
if (mnet == NULL) {
return (NULL);
}
/* Look for an alternate net, which is active. */
if ((net != NULL) && ((net->dest_state & SCTP_ADDR_BEING_DELETED) == 0)) {
alt = TAILQ_NEXT(net, sctp_next);
} else {
alt = TAILQ_FIRST(&stcb->asoc.nets);
}
looped = false;
for (;;) {
alt = TAILQ_NEXT(mnet, sctp_next);
if (alt == NULL) {
once++;
if (once > 1) {
break;
if (!looped) {
alt = TAILQ_FIRST(&stcb->asoc.nets);
looped = true;
}
alt = TAILQ_FIRST(&stcb->asoc.nets);
/* Definitely out of candidates. */
if (alt == NULL) {
return (NULL);
break;
}
}
#if defined(__FreeBSD__) && !defined(__Userspace__)
@ -361,43 +358,56 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
#else
(alt->ro.ro_rt != NULL) &&
#endif
(!(alt->dest_state & SCTP_ADDR_UNCONFIRMED))) {
/* Found a reachable address */
((alt->dest_state & SCTP_ADDR_UNCONFIRMED) == 0) &&
(alt != net)) {
/* Found an alternate net, which is reachable. */
break;
}
mnet = alt;
alt = TAILQ_NEXT(alt, sctp_next);
}
if (alt == NULL) {
/* Case where NO insv network exists (dormant state) */
/* we rotate destinations */
once = 0;
mnet = net;
/*
* In case no active alternate net has been found, look for
* an alternate net, which is confirmed.
*/
if ((net != NULL) && ((net->dest_state & SCTP_ADDR_BEING_DELETED) == 0)) {
alt = TAILQ_NEXT(net, sctp_next);
} else {
alt = TAILQ_FIRST(&stcb->asoc.nets);
}
looped = false;
for (;;) {
if (mnet == NULL) {
return (TAILQ_FIRST(&stcb->asoc.nets));
}
alt = TAILQ_NEXT(mnet, sctp_next);
if (alt == NULL) {
once++;
if (once > 1) {
break;
if (!looped) {
alt = TAILQ_FIRST(&stcb->asoc.nets);
looped = true;
}
alt = TAILQ_FIRST(&stcb->asoc.nets);
/* Definitely out of candidates. */
if (alt == NULL) {
break;
}
}
if ((!(alt->dest_state & SCTP_ADDR_UNCONFIRMED)) &&
if (((alt->dest_state & SCTP_ADDR_UNCONFIRMED) == 0) &&
(alt != net)) {
/* Found an alternate address */
/* Found an alternate net, which is confirmed. */
break;
}
mnet = alt;
alt = TAILQ_NEXT(alt, sctp_next);
}
}
if (alt == NULL) {
return (net);
/*
* In case no confirmed alternate net has been found, just
* return net, if it is not being deleted. In the other case
* just return the first net.
*/
if ((net != NULL) && ((net->dest_state & SCTP_ADDR_BEING_DELETED) == 0)) {
alt = net;
}
if (alt == NULL) {
alt = TAILQ_FIRST(&stcb->asoc.nets);
}
}
return (alt);
}
@ -497,8 +507,9 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
unsigned int cnt_mk;
uint32_t orig_flight, orig_tf;
uint32_t tsnlast, tsnfirst;
#ifndef INVARIANTS
int recovery_cnt = 0;
#endif
/* none in flight now */
audit_tf = 0;
@ -537,8 +548,8 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
min_wait.tv_sec = min_wait.tv_usec = 0;
}
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
sctp_log_fr(cur_rto, now.tv_sec, now.tv_usec, SCTP_FR_T3_MARK_TIME);
sctp_log_fr(0, min_wait.tv_sec, min_wait.tv_usec, SCTP_FR_T3_MARK_TIME);
sctp_log_fr(cur_rto, (uint32_t)now.tv_sec, now.tv_usec, SCTP_FR_T3_MARK_TIME);
sctp_log_fr(0, (uint32_t)min_wait.tv_sec, min_wait.tv_usec, SCTP_FR_T3_MARK_TIME);
}
/*
* Our rwnd will be incorrect here since we are not adding back the
@ -560,10 +571,10 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
/* Strange case our list got out of order? */
SCTP_PRINTF("Our list is out of order? last_acked:%x chk:%x\n",
(unsigned int)stcb->asoc.last_acked_seq, (unsigned int)chk->rec.data.tsn);
recovery_cnt++;
#ifdef INVARIANTS
panic("last acked >= chk on sent-Q");
#else
recovery_cnt++;
SCTP_PRINTF("Recover attempts a restart cnt:%d\n", recovery_cnt);
sctp_recover_sent_list(stcb);
if (recovery_cnt < 10) {
@ -585,7 +596,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
/* validate its been outstanding long enough */
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
sctp_log_fr(chk->rec.data.tsn,
chk->sent_rcv_time.tv_sec,
(uint32_t)chk->sent_rcv_time.tv_sec,
chk->sent_rcv_time.tv_usec,
SCTP_FR_T3_MARK_TIME);
}
@ -597,7 +608,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
*/
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
sctp_log_fr(0,
chk->sent_rcv_time.tv_sec,
(uint32_t)chk->sent_rcv_time.tv_sec,
chk->sent_rcv_time.tv_usec,
SCTP_FR_T3_STOPPED);
}
@ -810,7 +821,6 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
return (0);
}
int
sctp_t3rxt_timer(struct sctp_inpcb *inp,
struct sctp_tcb *stcb,
@ -852,11 +862,11 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
if (net != stcb->asoc.primary_destination) {
/* send a immediate HB if our RTO is stale */
struct timeval now;
unsigned int ms_goneby;
uint32_t ms_goneby;
(void)SCTP_GETTIME_TIMEVAL(&now);
if (net->last_sent_time.tv_sec) {
ms_goneby = (now.tv_sec - net->last_sent_time.tv_sec) * 1000;
ms_goneby = (uint32_t)(now.tv_sec - net->last_sent_time.tv_sec) * 1000;
} else {
ms_goneby = 0;
}
@ -911,7 +921,7 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
num_mk = 0;
num_abandoned = 0;
(void)sctp_mark_all_for_resend(stcb, net, alt, win_probe,
&num_mk, &num_abandoned);
&num_mk, &num_abandoned);
/* FR Loss recovery just ended with the T3. */
stcb->asoc.fast_retran_loss_recovery = 0;
@ -930,16 +940,16 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
/* Backoff the timer and cwnd */
sctp_backoff_on_timeout(stcb, net, win_probe, num_mk, num_abandoned);
if ((!(net->dest_state & SCTP_ADDR_REACHABLE)) ||
if (((net->dest_state & SCTP_ADDR_REACHABLE) == 0) ||
(net->dest_state & SCTP_ADDR_PF)) {
/* Move all pending over too */
sctp_move_chunks_from_net(stcb, net);
/* Get the address that failed, to
* force a new src address selecton and
* force a new src address selection and
* a route allocation.
*/
if (net->ro._s_addr) {
if (net->ro._s_addr != NULL) {
sctp_free_ifa(net->ro._s_addr);
net->ro._s_addr = NULL;
}
@ -949,7 +959,7 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
#if defined(__FreeBSD__) && !defined(__Userspace__)
RO_NHFREE(&net->ro);
#else
if (net->ro.ro_rt) {
if (net->ro.ro_rt != NULL) {
RTFREE(net->ro.ro_rt);
net->ro.ro_rt = NULL;
}
@ -964,7 +974,7 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
* change-primary then this flag must be cleared
* from any net structures.
*/
if (stcb->asoc.alternate) {
if (stcb->asoc.alternate != NULL) {
sctp_free_remote_addr(stcb->asoc.alternate);
}
stcb->asoc.alternate = alt;
@ -1077,7 +1087,7 @@ sctp_cookie_timer(struct sctp_inpcb *inp,
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
"Cookie timer expired, but no cookie");
inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_3;
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
sctp_abort_an_association(inp, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
} else {
#ifdef INVARIANTS
panic("Cookie timer expires in wrong state?");
@ -1163,7 +1173,7 @@ sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
atomic_add_int(&alt->ref_count, 1);
}
}
if (!(net->dest_state & SCTP_ADDR_REACHABLE)) {
if ((net->dest_state & SCTP_ADDR_REACHABLE) == 0) {
/*
* If the address went un-reachable, we need to move to
* alternates for ALL chk's in queue
@ -1258,7 +1268,7 @@ sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
chk->sent = SCTP_DATAGRAM_RESEND;
chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
}
if (!(net->dest_state & SCTP_ADDR_REACHABLE)) {
if ((net->dest_state & SCTP_ADDR_REACHABLE) == 0) {
/*
* If the address went un-reachable, we need to move
* to the alternate for ALL chunks in queue
@ -1349,17 +1359,17 @@ sctp_shutdownack_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
static void
sctp_audit_stream_queues_for_size(struct sctp_inpcb *inp,
struct sctp_tcb *stcb)
sctp_audit_stream_queues_for_size(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
{
struct sctp_stream_queue_pending *sp;
unsigned int i, chks_in_queue = 0;
int being_filled = 0;
/*
* This function is ONLY called when the send/sent queues are empty.
*/
if ((stcb == NULL) || (inp == NULL))
return;
KASSERT(inp != NULL, ("inp is NULL"));
KASSERT(stcb != NULL, ("stcb is NULL"));
SCTP_TCB_LOCK_ASSERT(stcb);
KASSERT(TAILQ_EMPTY(&stcb->asoc.send_queue), ("send_queue not empty"));
KASSERT(TAILQ_EMPTY(&stcb->asoc.sent_queue), ("sent_queue not empty"));
if (stcb->asoc.sent_queue_retran_cnt) {
SCTP_PRINTF("Hmm, sent_queue_retran_cnt is non-zero %d\n",
@ -1368,7 +1378,7 @@ sctp_audit_stream_queues_for_size(struct sctp_inpcb *inp,
}
if (stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, &stcb->asoc)) {
/* No stream scheduler information, initialize scheduler */
stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc, 0);
stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc);
if (!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, &stcb->asoc)) {
/* yep, we lost a stream or two */
SCTP_PRINTF("Found additional streams NOT managed by scheduler, corrected\n");
@ -1416,15 +1426,11 @@ int
sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct sctp_nets *net)
{
uint8_t net_was_pf;
bool net_was_pf;
if (net->dest_state & SCTP_ADDR_PF) {
net_was_pf = 1;
} else {
net_was_pf = 0;
}
net_was_pf = (net->dest_state & SCTP_ADDR_PF) != 0;
if (net->hb_responded == 0) {
if (net->ro._s_addr) {
if (net->ro._s_addr != NULL) {
/* Invalidate the src address if we did not get
* a response last time.
*/
@ -1439,7 +1445,7 @@ sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
}
/* Zero PBA, if it needs it */
if (net->partial_bytes_acked) {
if (net->partial_bytes_acked > 0) {
net->partial_bytes_acked = 0;
}
if ((stcb->asoc.total_output_queue_size > 0) &&
@ -1447,10 +1453,11 @@ sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
(TAILQ_EMPTY(&stcb->asoc.sent_queue))) {
sctp_audit_stream_queues_for_size(inp, stcb);
}
if (!(net->dest_state & SCTP_ADDR_NOHB) &&
!((net_was_pf == 0) && (net->dest_state & SCTP_ADDR_PF))) {
/* when move to PF during threshold mangement, a HB has been
queued in that routine */
if ((((net->dest_state & SCTP_ADDR_NOHB) == 0) ||
(net->dest_state & SCTP_ADDR_UNCONFIRMED)) &&
(net_was_pf || ((net->dest_state & SCTP_ADDR_PF) == 0))) {
/* When moving to PF during threshold management, a HB has been
queued in that routine. */
uint32_t ms_gone_by;
if ((net->last_sent_time.tv_sec > 0) ||
@ -1472,6 +1479,7 @@ sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
ms_gone_by = 0xffffffff;
}
if ((ms_gone_by >= net->heart_beat_delay) ||
(net->dest_state & SCTP_ADDR_UNCONFIRMED) ||
(net->dest_state & SCTP_ADDR_PF)) {
sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
}

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.h 359195 2020-03-21 16:12:19Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_TIMER_H_
@ -99,6 +99,5 @@ void sctp_slowtimo(void);
void sctp_gc(struct inpcbinfo *);
#endif
#endif
#endif
#endif

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_uio.h 362473 2020-06-21 23:12:56Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_UIO_H_
@ -45,7 +45,6 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_uio.h 362473 2020-06-21 23:12:56Z tuex
#define _KERNEL
#endif
#endif
#if !defined(_WIN32)
#if !defined(_KERNEL)
#include <stdint.h>
@ -129,7 +128,6 @@ struct sctp_initmsg {
* all sendrcvinfo's need a verfid for SENDING only.
*/
#define SCTP_ALIGN_RESV_PAD 92
#define SCTP_ALIGN_RESV_PAD_SHORT 76
@ -441,7 +439,6 @@ struct sctp_setadaption {
uint32_t ssb_adaption_ind;
};
/*
* Partial Delivery API event
*/
@ -458,7 +455,6 @@ struct sctp_pdapi_event {
/* indication values */
#define SCTP_PARTIAL_DELIVERY_ABORTED 0x0001
/*
* authentication key event
*/
@ -478,7 +474,6 @@ struct sctp_authkey_event {
#define SCTP_AUTH_NO_AUTH 0x0002
#define SCTP_AUTH_FREE_KEY 0x0003
struct sctp_sender_dry_event {
uint16_t sender_dry_type;
uint16_t sender_dry_flags;
@ -486,7 +481,6 @@ struct sctp_sender_dry_event {
sctp_assoc_t sender_dry_assoc_id;
};
/*
* Stream reset event - subscribe to SCTP_STREAM_RESET_EVENT
*/
@ -534,7 +528,6 @@ struct sctp_stream_change_event {
#define SCTP_STREAM_CHANGE_DENIED 0x0004
#define SCTP_STREAM_CHANGE_FAILED 0x0008
/* SCTP notification event */
struct sctp_tlv {
uint16_t sn_type;
@ -1137,7 +1130,6 @@ struct sctpstat {
#define SCTP_STAT_DECR_COUNTER64(_x) SCTP_STAT_DECR(_x)
#define SCTP_STAT_DECR_GAUGE32(_x) SCTP_STAT_DECR(_x)
/***********************************/
/* And something for us old timers */
/***********************************/
@ -1171,7 +1163,6 @@ struct sctpstat {
#endif
/***********************************/
struct xsctp_inpcb {
uint32_t last;
uint32_t flags;
@ -1286,7 +1277,7 @@ int
sctp_lower_sosend(struct socket *so,
struct sockaddr *addr,
struct uio *uio,
struct mbuf *i_pak,
struct mbuf *top,
struct mbuf *control,
int flags,
struct sctp_sndrcvinfo *srcv

View File

@ -32,7 +32,7 @@
#include <sys/timeb.h>
#include <iphlpapi.h>
#if !defined(__MINGW32__)
#pragma comment(lib, "IPHLPAPI.lib")
#pragma comment(lib, "iphlpapi.lib")
#endif
#endif
#include <netinet/sctp_os_userspace.h>
@ -96,7 +96,7 @@ sctp_userspace_set_threadname(const char *name)
#if !defined(_WIN32) && !defined(__native_client__)
int
sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
sctp_userspace_get_mtu_from_ifn(uint32_t if_index)
{
#if defined(INET) || defined(INET6)
struct ifreq ifr;
@ -104,34 +104,26 @@ sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
#endif
int mtu;
switch (af) {
#if defined(INET)
case AF_INET:
#endif
#if defined(INET6)
case AF_INET6:
#endif
if (if_index == 0xffffffff) {
mtu = 1280;
} else {
mtu = 0;
#if defined(INET) || defined(INET6)
memset(&ifr, 0, sizeof(struct ifreq));
mtu = 0;
if (if_indextoname(if_index, ifr.ifr_name) != NULL) {
/* TODO can I use the raw socket here and not have to open a new one with each query? */
if ((fd = socket(af, SOCK_DGRAM, 0)) < 0) {
break;
}
if (ioctl(fd, SIOCGIFMTU, &ifr) >= 0) {
mtu = ifr.ifr_mtu;
}
close(fd);
}
break;
#if defined(INET)
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
#else
if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) >= 0) {
#endif
if (ioctl(fd, SIOCGIFMTU, &ifr) >= 0) {
mtu = ifr.ifr_mtu;
}
close(fd);
}
}
#endif
case AF_CONN:
mtu = 1280;
break;
default:
mtu = 0;
break;
}
return (mtu);
}
@ -139,13 +131,13 @@ sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
#if defined(__native_client__)
int
sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
sctp_userspace_get_mtu_from_ifn(uint32_t if_index)
{
return 1280;
}
#endif
#if defined(__APPLE__) || defined(__DragonFly__) || defined(__linux__) || defined(__native_client__) || defined(__NetBSD__) || defined(_WIN32) || defined(__Fuchsia__)
#if defined(__APPLE__) || defined(__DragonFly__) || defined(__linux__) || defined(__native_client__) || defined(__NetBSD__) || defined(__QNX__) || defined(_WIN32) || defined(__Fuchsia__) || defined(__EMSCRIPTEN__)
int
timingsafe_bcmp(const void *b1, const void *b2, size_t n)
{
@ -160,7 +152,7 @@ timingsafe_bcmp(const void *b1, const void *b2, size_t n)
#ifdef _WIN32
int
sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
sctp_userspace_get_mtu_from_ifn(uint32_t if_index)
{
#if defined(INET) || defined(INET6)
PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt;
@ -168,15 +160,11 @@ sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
#endif
int mtu;
switch (af) {
#if defined(INET)
case AF_INET:
#endif
#if defined(INET6)
case AF_INET6:
#endif
#if defined(INET) || defined(INET6)
if (if_index == 0xffffffff) {
mtu = 1280;
} else {
mtu = 0;
#if defined(INET) || defined(INET6)
AdapterAddrsSize = 0;
pAdapterAddrs = NULL;
if ((Err = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &AdapterAddrsSize)) != 0) {
@ -206,14 +194,7 @@ sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
if (pAdapterAddrs != NULL) {
GlobalFree(pAdapterAddrs);
}
break;
#endif
case AF_CONN:
mtu = 1280;
break;
default:
mtu = 0;
break;
}
return (mtu);
}

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_var.h 360292 2020-04-25 09:06:11Z melifaro $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_VAR_H_
@ -48,7 +48,6 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_var.h 360292 2020-04-25 09:06:11Z meli
extern struct pr_usrreqs sctp_usrreqs;
#endif
#define sctp_feature_on(inp, feature) (inp->sctp_features |= feature)
#define sctp_feature_off(inp, feature) (inp->sctp_features &= ~feature)
#define sctp_is_feature_on(inp, feature) ((inp->sctp_features & feature) == feature)
@ -90,7 +89,7 @@ extern struct pr_usrreqs sctp_usrreqs;
#define sctp_sbspace(asoc, sb) ((long) ((sctp_maxspace(sb) > (asoc)->sb_cc) ? (sctp_maxspace(sb) - (asoc)->sb_cc) : 0))
#define sctp_sbspace_failedmsgs(sb) ((long) ((sctp_maxspace(sb) > (sb)->sb_cc) ? (sctp_maxspace(sb) - (sb)->sb_cc) : 0))
#define sctp_sbspace_failedmsgs(sb) ((long) ((sctp_maxspace(sb) > SCTP_SBAVAIL(sb)) ? (sctp_maxspace(sb) - SCTP_SBAVAIL(sb)) : 0))
#define sctp_sbspace_sub(a,b) (((a) > (b)) ? ((a) - (b)) : 0)
@ -187,11 +186,9 @@ extern struct pr_usrreqs sctp_usrreqs;
}
#if defined(__FreeBSD__) && !defined(__Userspace__)
#define sctp_free_remote_addr(__net) { \
if ((__net)) { \
if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&(__net)->ref_count)) { \
(void)SCTP_OS_TIMER_STOP(&(__net)->rxt_timer.timer); \
RO_NHFREE(&(__net)->ro); \
if ((__net)->src_addr_selected) { \
sctp_free_ifa((__net)->ro._s_addr); \
@ -228,13 +225,10 @@ extern struct pr_usrreqs sctp_usrreqs;
SCTP_BUF_TYPE(m) != MT_OOBDATA) \
atomic_add_int(&(sb)->sb_ctl,SCTP_BUF_LEN((m))); \
}
#else /* FreeBSD Version <= 500000 or non-FreeBSD */
#define sctp_free_remote_addr(__net) { \
if ((__net)) { \
if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&(__net)->ref_count)) { \
(void)SCTP_OS_TIMER_STOP(&(__net)->rxt_timer.timer); \
if ((__net)->ro.ro_rt) { \
RTFREE((__net)->ro.ro_rt); \
(__net)->ro.ro_rt = NULL; \
@ -369,7 +363,6 @@ struct sctp_inpcb;
struct sctp_tcb;
struct sctphdr;
#if defined(__FreeBSD__) || defined(_WIN32) || defined(__Userspace__)
void sctp_close(struct socket *so);
#else
@ -391,10 +384,10 @@ int sctp_input(struct mbuf **, int *, int);
void sctp_input(struct mbuf *, int);
#endif
#endif
void sctp_pathmtu_adjustment(struct sctp_tcb *, uint16_t);
void sctp_pathmtu_adjustment(struct sctp_tcb *, uint32_t, bool);
#else
#if defined(__Userspace__)
void sctp_pathmtu_adjustment(struct sctp_tcb *, uint16_t);
void sctp_pathmtu_adjustment(struct sctp_tcb *, uint32_t, bool);
#else
void sctp_input(struct mbuf *,...);
#endif
@ -409,7 +402,9 @@ void sctp_init(uint16_t,
#elif defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) &&!defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
void sctp_init(struct protosw *pp, struct domain *dp);
#else
#if !defined(__FreeBSD__)
void sctp_init(void);
#endif
void sctp_notify(struct sctp_inpcb *, struct sctp_tcb *, struct sctp_nets *,
uint8_t, uint8_t, uint16_t, uint32_t);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctputil.h 362448 2020-06-20 20:20:16Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_UTIL_H_
@ -64,7 +64,6 @@ sctp_log_trace(uint32_t fr, const char *str SCTP_UNUSED, uint32_t a, uint32_t b,
#define sctp_get_associd(stcb) ((sctp_assoc_t)stcb->asoc.assoc_id)
/*
* Function prototypes
*/
@ -84,7 +83,7 @@ uint32_t sctp_select_initial_TSN(struct sctp_pcb *);
uint32_t sctp_select_a_tag(struct sctp_inpcb *, uint16_t lport, uint16_t rport, int);
int sctp_init_asoc(struct sctp_inpcb *, struct sctp_tcb *, uint32_t, uint32_t, uint16_t);
int sctp_init_asoc(struct sctp_inpcb *, struct sctp_tcb *, uint32_t, uint32_t, uint32_t, uint16_t);
void sctp_fill_random_store(struct sctp_pcb *);
@ -94,6 +93,14 @@ sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin,
void
sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, uint32_t sending_tsn, uint32_t recv_tsn, int flag);
/*
* NOTE: sctp_timer_start() will increment the reference count of any relevant
* structure the timer is referencing, in order to prevent a race condition
* between the timer executing and the structure being freed.
*
* When the timer fires or sctp_timer_stop() is called, these references are
* removed.
*/
void
sctp_timer_start(int, struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *);
@ -105,9 +112,6 @@ sctp_timer_stop(int, struct sctp_inpcb *, struct sctp_tcb *,
int
sctp_dynamic_set_primary(struct sockaddr *sa, uint32_t vrf_id);
void
sctp_mtu_size_reset(struct sctp_inpcb *, struct sctp_association *, uint32_t);
void
sctp_wakeup_the_read_socket(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
int so_locked
@ -165,18 +169,17 @@ sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp,
struct sctp_inpcb *new_inp,
struct sctp_tcb *stcb, int waitflags);
void sctp_stop_timers_for_shutdown(struct sctp_tcb *);
/* Stop all timers for association and remote addresses. */
void sctp_stop_association_timers(struct sctp_tcb *, bool);
void sctp_report_all_outbound(struct sctp_tcb *, uint16_t, int, int);
void sctp_report_all_outbound(struct sctp_tcb *, uint16_t, int);
int sctp_expand_mapping_array(struct sctp_association *, uint32_t);
void sctp_abort_notification(struct sctp_tcb *, uint8_t, uint16_t,
struct sctp_abort_chunk *, int);
void sctp_abort_notification(struct sctp_tcb *, bool, bool, uint16_t,
struct sctp_abort_chunk *, int);
/* We abort responding to an IP packet for some reason */
void
@ -188,11 +191,10 @@ sctp_abort_association(struct sctp_inpcb *, struct sctp_tcb *, struct mbuf *,
#endif
uint32_t, uint16_t);
/* We choose to abort via user input */
void
sctp_abort_an_association(struct sctp_inpcb *, struct sctp_tcb *,
struct mbuf *, int);
struct mbuf *, bool, int);
void sctp_handle_ootb(struct mbuf *, int, int,
struct sockaddr *, struct sockaddr *,
@ -272,34 +274,10 @@ void sctp_bindx_delete_address(struct sctp_inpcb *inp, struct sockaddr *sa,
int sctp_local_addr_count(struct sctp_tcb *stcb);
#ifdef SCTP_MBCNT_LOGGING
void
sctp_free_bufspace(struct sctp_tcb *, struct sctp_association *,
struct sctp_tmit_chunk *, int);
#else
#define sctp_free_bufspace(stcb, asoc, tp1, chk_cnt) \
do { \
if (tp1->data != NULL) { \
atomic_subtract_int(&((asoc)->chunks_on_out_queue), chk_cnt); \
if ((asoc)->total_output_queue_size >= tp1->book_size) { \
atomic_subtract_int(&((asoc)->total_output_queue_size), tp1->book_size); \
} else { \
(asoc)->total_output_queue_size = 0; \
} \
if (stcb->sctp_socket && ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \
if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) { \
atomic_subtract_int(&((stcb)->sctp_socket->so_snd.sb_cc), tp1->book_size); \
} else { \
stcb->sctp_socket->so_snd.sb_cc = 0; \
} \
} \
} \
} while (0)
#endif
#define sctp_free_spbufspace(stcb, asoc, sp) \
do { \
if (sp->data != NULL) { \
@ -356,7 +334,6 @@ void sctp_log_strm_del_alt(struct sctp_tcb *stcb, uint32_t, uint16_t, uint16_t,
void sctp_log_nagle_event(struct sctp_tcb *stcb, int action);
#ifdef SCTP_MBUF_LOGGING
void
sctp_log_mb(struct mbuf *m, int from);
@ -390,7 +367,6 @@ void sctp_log_map(uint32_t, uint32_t, uint32_t, int);
void sctp_print_mapping_array(struct sctp_association *asoc);
void sctp_clr_stat_log(void);
#ifdef SCTP_AUDITING_ENABLED
void
sctp_auditing(int, struct sctp_inpcb *, struct sctp_tcb *,

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 361895 2020-06-07 14:39:20Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
@ -105,7 +105,7 @@ void
in6_sin_2_v4mapsin6(const struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
{
memset(sin6, 0, sizeof(struct sockaddr_in6));
sin6->sin6_family = AF_INET6;
sin6->sin6_family = AF_INET6;
#ifdef HAVE_SIN6_LEN
sin6->sin6_len = sizeof(struct sockaddr_in6);
#endif
@ -116,9 +116,9 @@ in6_sin_2_v4mapsin6(const struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
((uint32_t *)&sin6->sin6_addr)[2] = htonl(0xffff);
((uint32_t *)&sin6->sin6_addr)[3] = sin->sin_addr.s_addr;
#else
sin6->sin6_addr.s6_addr32[0] = 0;
sin6->sin6_addr.s6_addr32[0] = 0;
sin6->sin6_addr.s6_addr32[1] = 0;
sin6->sin6_addr.s6_addr32[2] = htonl(0xffff);
sin6->sin6_addr.s6_addr32[2] = htonl(0xffff);
sin6->sin6_addr.s6_addr32[3] = sin->sin_addr.s_addr;
#endif
}
@ -259,13 +259,14 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
goto out;
}
ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff);
#if defined(__FreeBSD__)
ecn_bits = IPV6_TRAFFIC_CLASS(ip6);
if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) {
SCTP_STAT_INCR(sctps_recvhwcrc);
compute_crc = 0;
} else {
#else
ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff);
if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
(IN6_ARE_ADDR_EQUAL(&src.sin6_addr, &dst.sin6_addr))) {
SCTP_STAT_INCR(sctps_recvhwcrc);
@ -299,7 +300,6 @@ sctp6_input(struct mbuf **i_pak, int *offp)
return (sctp6_input_with_port(i_pak, offp, 0));
}
#endif
#if defined(__FreeBSD__)
int
sctp6_input(struct mbuf **i_pak, int *offp, int proto SCTP_UNUSED)
@ -341,7 +341,7 @@ sctp6_notify(struct sctp_inpcb *inp,
case ICMP6_PARAM_PROB:
/* Treat it like an ABORT. */
if (icmp6_code == ICMP6_PARAMPROB_NEXTHEADER) {
sctp_abort_notification(stcb, 1, 0, NULL, SCTP_SO_NOT_LOCKED);
sctp_abort_notification(stcb, true, false, 0, NULL, SCTP_SO_NOT_LOCKED);
#if defined(__APPLE__)
so = SCTP_INP_SO(inp);
atomic_add_int(&stcb->asoc.refcnt, 1);
@ -387,7 +387,7 @@ sctp6_notify(struct sctp_inpcb *inp,
}
/* Update the association MTU */
if (stcb->asoc.smallest_mtu > next_mtu) {
sctp_pathmtu_adjustment(stcb, next_mtu);
sctp_pathmtu_adjustment(stcb, next_mtu, true);
}
/* Finally, start the PMTU timer if it was running before. */
if (timer_stopped) {
@ -549,8 +549,8 @@ sctp6_ctlinput(int cmd, struct sockaddr *pktdst, void *d)
ip6cp->ip6c_icmp6->icmp6_code,
ntohl(ip6cp->ip6c_icmp6->icmp6_mtu));
#if defined(__Userspace__)
if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) &&
(stcb->sctp_socket != NULL) {
if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
(stcb->sctp_socket != NULL)) {
struct socket *upcall_socket;
upcall_socket = stcb->sctp_socket;
@ -655,10 +655,10 @@ out:
return (error);
}
SYSCTL_PROC(_net_inet6_sctp6, OID_AUTO, getcred, CTLTYPE_OPAQUE | CTLFLAG_RW,
0, 0,
sctp6_getcred, "S,ucred", "Get the ucred of a SCTP6 connection");
SYSCTL_PROC(_net_inet6_sctp6, OID_AUTO, getcred,
CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
0, 0, sctp6_getcred, "S,ucred",
"Get the ucred of a SCTP6 connection");
#endif
/* This is the same as the sctp_abort() could be made common */
@ -911,7 +911,6 @@ out:
return (error);
}
#if defined(__FreeBSD__) || defined(_WIN32) || defined(__Userspace__)
#if !defined(__Userspace__)
static void
@ -949,16 +948,13 @@ sctp6_disconnect(struct socket *so)
return (sctp_disconnect(so));
}
int
#if defined(__FreeBSD__) && !defined(__Userspace__)
sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
struct mbuf *control, struct thread *p);
#else
sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
struct mbuf *control, struct proc *p);
#endif
#if !defined(_WIN32) && !defined(__Userspace__)
@ -1013,6 +1009,46 @@ sctp6_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *nam,
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EDESTADDRREQ);
return (EDESTADDRREQ);
}
switch (addr->sa_family) {
#ifdef INET
case AF_INET:
#if defined(HAVE_SA_LEN)
if (addr->sa_len != sizeof(struct sockaddr_in)) {
if (control) {
SCTP_RELEASE_PKT(control);
control = NULL;
}
SCTP_RELEASE_PKT(m);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
return (EINVAL);
}
#endif
break;
#endif
#ifdef INET6
case AF_INET6:
#if defined(HAVE_SA_LEN)
if (addr->sa_len != sizeof(struct sockaddr_in6)) {
if (control) {
SCTP_RELEASE_PKT(control);
control = NULL;
}
SCTP_RELEASE_PKT(m);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
return (EINVAL);
}
#endif
break;
#endif
default:
if (control) {
SCTP_RELEASE_PKT(control);
control = NULL;
}
SCTP_RELEASE_PKT(m);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
return (EINVAL);
}
#ifdef INET
sin6 = (struct sockaddr_in6 *)addr;
if (SCTP_IPV6_V6ONLY(inp)) {
@ -1021,15 +1057,26 @@ sctp6_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *nam,
* v4 addr or v4-mapped addr
*/
if (addr->sa_family == AF_INET) {
if (control) {
SCTP_RELEASE_PKT(control);
control = NULL;
}
SCTP_RELEASE_PKT(m);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
return (EINVAL);
}
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
if (control) {
SCTP_RELEASE_PKT(control);
control = NULL;
}
SCTP_RELEASE_PKT(m);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
return (EINVAL);
}
}
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
if ((addr->sa_family == AF_INET6) &&
IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
struct sockaddr_in sin;
/* convert v4-mapped into v4 addr and send */
@ -1207,7 +1254,8 @@ sctp6_connect(struct socket *so, struct mbuf *nam, struct proc *p)
return (EINVAL);
}
}
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
if ((addr->sa_family == AF_INET6) &&
IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
/* convert v4-mapped into v4 addr */
in6_sin6_2_sin(&store.sin, sin6);
addr = &store.sa;
@ -1241,20 +1289,15 @@ sctp6_connect(struct socket *so, struct mbuf *nam, struct proc *p)
return (EALREADY);
}
/* We are GOOD to go */
stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id,
inp->sctp_ep.pre_open_stream_count,
inp->sctp_ep.port, p,
SCTP_INITIALIZE_AUTH_PARAMS);
stcb = sctp_aloc_assoc_connected(inp, addr, &error, 0, 0, vrf_id,
inp->sctp_ep.pre_open_stream_count,
inp->sctp_ep.port, p,
SCTP_INITIALIZE_AUTH_PARAMS);
SCTP_ASOC_CREATE_UNLOCK(inp);
if (stcb == NULL) {
/* Gak! no memory */
return (error);
}
if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
/* Set the connected flag so we can queue data */
soisconnecting(so);
}
SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
(void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
#if defined(__FreeBSD__) && !defined(__Userspace__)
@ -1560,7 +1603,6 @@ sctp6_in6getaddr(struct socket *so, struct mbuf *nam)
return (error);
}
#if !defined(__Userspace__)
static int
sctp6_getpeeraddr(struct socket *so, struct sockaddr **nam)
@ -1710,7 +1752,7 @@ sctp6_usrreq(so, req, m, nam, control, p)
switch (family) {
case PF_INET:
error = in_control(so, (long)m, (caddr_t)nam,
(struct ifnet *)control );
(struct ifnet *)control);
break;
#ifdef INET6
case PF_INET6:

View File

@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_var.h 317457 2017-04-26 19:26:40Z tuexen $");
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET6_SCTP6_VAR_H_
@ -70,7 +70,7 @@ void sctp6_ctlinput(int, struct sockaddr *, void *, struct ifnet * SCTP_UNUSED);
#else
void sctp6_ctlinput(int, struct sockaddr *, void *);
#endif
#if !((defined(__FreeBSD__) || defined(__APPLE__)) && !defined(__Userspace__))
#if !((defined(__FreeBSD__) || defined(__APPLE__)) && !defined(__Userspace__))
extern void in6_sin_2_v4mapsin6(struct sockaddr_in *, struct sockaddr_in6 *);
extern void in6_sin6_2_sin(struct sockaddr_in *, struct sockaddr_in6 *);
extern void in6_sin6_2_sin_in_sock(struct sockaddr *);

View File

@ -30,18 +30,23 @@
/* __Userspace__ */
#include <stdlib.h>
#if !defined(_WIN32)
#if defined(_WIN32)
#if !defined(_CRT_RAND_S) && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
#define _CRT_RAND_S
#endif
#else
#include <stdint.h>
#include <netinet/sctp_os_userspace.h>
#endif
#ifdef INVARIANTS
#include <netinet/sctp_pcb.h>
#endif
#include <user_environment.h>
#include <sys/types.h>
/* #include <sys/param.h> defines MIN */
#if !defined(MIN)
#define MIN(arg1,arg2) ((arg1) < (arg2) ? (arg1) : (arg2))
#endif
#include <string.h>
#define uHZ 1000
@ -64,69 +69,316 @@ userland_mutex_t atomic_mtx;
* provide _some_ kind of randomness. This should only be used
* inside other RNG's, like arc4random(9).
*/
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
#include <string.h>
void
init_random(void)
{
return;
}
int
read_random(void *buf, int count)
void
read_random(void *buf, size_t size)
{
memset(buf, 'A', count);
return (count);
memset(buf, 'A', size);
return;
}
#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
void
finish_random(void)
{
return;
}
/* This define can be used to optionally use OpenSSL's random number utility,
* which is capable of bypassing the chromium sandbox which normally would
* prevent opening files, including /dev/urandom.
*/
#elif defined(SCTP_USE_OPENSSL_RAND)
#include <openssl/rand.h>
/* Requiring BoringSSL because it guarantees that RAND_bytes will succeed. */
#ifndef OPENSSL_IS_BORINGSSL
#error Only BoringSSL is supported with SCTP_USE_OPENSSL_RAND.
#endif
void
init_random(void)
{
return;
}
int
read_random(void *buf, int count)
void
read_random(void *buf, size_t size)
{
if (count >= 0) {
arc4random_buf(buf, count);
RAND_bytes((uint8_t *)buf, size);
return;
}
void
finish_random(void)
{
return;
}
#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) || defined(__Bitrig__)
#include <stdlib.h>
void
init_random(void)
{
return;
}
void
read_random(void *buf, size_t size)
{
arc4random_buf(buf, size);
return;
}
void
finish_random(void)
{
return;
}
#elif defined(_WIN32)
#include <stdlib.h>
void
init_random(void)
{
return;
}
void
read_random(void *buf, size_t size)
{
unsigned int randval;
size_t position, remaining;
position = 0;
while (position < size) {
if (rand_s(&randval) == 0) {
remaining = MIN(size - position, sizeof(unsigned int));
memcpy((char *)buf + position, &randval, remaining);
position += sizeof(unsigned int);
}
}
return (count);
return;
}
void
finish_random(void)
{
return;
}
#elif (defined(__ANDROID__) && (__ANDROID_API__ < 28)) || defined(__QNX__) || defined(__EMSCRIPTEN__)
#include <fcntl.h>
static int fd = -1;
void
init_random(void)
{
fd = open("/dev/urandom", O_RDONLY);
return;
}
void
read_random(void *buf, size_t size)
{
size_t position;
ssize_t n;
position = 0;
while (position < size) {
n = read(fd, (char *)buf + position, size - position);
if (n > 0) {
position += n;
}
}
return;
}
void
finish_random(void)
{
close(fd);
return;
}
#elif defined(__ANDROID__) && (__ANDROID_API__ >= 28)
#include <sys/random.h>
void
init_random(void)
{
return;
}
void
read_random(void *buf, size_t size)
{
size_t position;
ssize_t n;
position = 0;
while (position < size) {
n = getrandom((char *)buf + position, size - position, 0);
if (n > 0) {
position += n;
}
}
return;
}
void
finish_random(void)
{
return;
}
#elif defined(__linux__)
#include <fcntl.h>
#include <unistd.h>
#include <sys/syscall.h>
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
void __msan_unpoison(void *, size_t);
#endif
#endif
#ifdef __NR_getrandom
#if !defined(GRND_NONBLOCK)
#define GRND_NONBLOCK 1
#endif
static int getrandom_available = 0;
#endif
static int fd = -1;
void
init_random(void)
{
#ifdef __NR_getrandom
char dummy;
ssize_t n = syscall(__NR_getrandom, &dummy, sizeof(dummy), GRND_NONBLOCK);
if (n > 0 || errno == EINTR || errno == EAGAIN) {
/* Either getrandom succeeded, was interrupted or is waiting for entropy;
* all of which mean the syscall is available.
*/
getrandom_available = 1;
} else {
#ifdef INVARIANTS
if (errno != ENOSYS) {
panic("getrandom syscall returned unexpected error: %d", errno);
}
#endif
/* If the syscall isn't available, fall back to /dev/urandom. */
#endif
fd = open("/dev/urandom", O_RDONLY);
#ifdef __NR_getrandom
}
#endif
return;
}
void
read_random(void *buf, size_t size)
{
size_t position;
ssize_t n;
position = 0;
while (position < size) {
#ifdef __NR_getrandom
if (getrandom_available) {
/* Using syscall directly because getrandom isn't present in glibc < 2.25.
*/
n = syscall(__NR_getrandom, (char *)buf + position, size - position, 0);
if (n > 0) {
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
/* Need to do this because MSan doesn't realize that syscall has
* initialized the output buffer.
*/
__msan_unpoison(buf + position, n);
#endif
#endif
position += n;
} else if (errno != EINTR && errno != EAGAIN) {
#ifdef INVARIANTS
panic("getrandom syscall returned unexpected error: %d", errno);
#endif
}
} else
#endif /* __NR_getrandom */
{
n = read(fd, (char *)buf + position, size - position);
if (n > 0) {
position += n;
}
}
}
return;
}
void
finish_random(void)
{
if (fd != -1) {
close(fd);
}
return;
}
#elif defined(__Fuchsia__)
#include <zircon/syscalls.h>
void
init_random(void)
{
return;
}
void
read_random(void *buf, size_t size)
{
zx_cprng_draw(buf, size);
return;
}
void
finish_random(void)
{
return;
}
#elif defined(__native_client__)
#include <nacl/nacl_random.h>
void
init_random(void)
{
return;
}
void
read_random(void *buf, size_t size)
{
size_t position;
size_t n;
position = 0;
while (position < size) {
if (nacl_secure_random((char *)buf + position, size - position, &n) == 0)
position += n;
}
}
return;
}
void
finish_random(void)
{
return;
}
#else
void
init_random(void)
{
struct timeval now;
unsigned int seed;
(void)SCTP_GETTIME_TIMEVAL(&now);
seed = 0;
seed |= (unsigned int)now.tv_sec;
seed |= (unsigned int)now.tv_usec;
#if !defined(_WIN32) &&! defined(__native_client__)
seed |= getpid();
#endif
#if defined(_WIN32) || defined(__native_client__)
srand(seed);
#else
srandom(seed);
#endif
return;
}
int
read_random(void *buf, int count)
{
uint32_t randval;
int size, i;
/* Fill buf[] with random(9) output */
for (i = 0; i < count; i+= (int)sizeof(uint32_t)) {
randval = random();
size = MIN(count - i, (int)sizeof(uint32_t));
memcpy(&((char *)buf)[i], &randval, (size_t)size);
}
return (count);
}
#error "Unknown platform. Please provide platform specific RNG."
#endif

View File

@ -68,7 +68,8 @@ extern int nmbclusters;
#endif
void init_random(void);
int read_random(void *, int);
void read_random(void *, size_t);
void finish_random(void);
/* errno's may differ per OS. errno.h now included in sctp_os_userspace.h */
/* Source: /usr/src/sys/sys/errno.h */
@ -90,7 +91,11 @@ extern u_short ip_id;
#if defined(INVARIANTS)
#include <stdlib.h>
static inline void
#if defined(_WIN32)
static inline void __declspec(noreturn)
#else
static inline void __attribute__((__noreturn__))
#endif
terminate_non_graceful(void) {
abort();
}

View File

@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*

View File

@ -39,7 +39,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@ -87,13 +87,11 @@ struct ip6_hdr {
#if defined(_WIN32)
#define s6_addr16 u.Word
#endif
#if !defined(_WIN32)
#if !defined(__linux__)
#if !defined(_WIN32) && !defined(__linux__) && !defined(__EMSCRIPTEN__)
#define s6_addr8 __u6_addr.__u6_addr8
#define s6_addr16 __u6_addr.__u6_addr16
#define s6_addr32 __u6_addr.__u6_addr32
#endif
#endif
#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__)
struct route_in6 {

View File

@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*

View File

@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*

View File

@ -80,8 +80,6 @@ static void mb_dtor_clust(void *, void *);
static int mbuf_constructor_dup(struct mbuf *m, int pkthdr, short type)
{
int flags = pkthdr;
if (type == MT_NOINIT)
return (0);
m->m_next = NULL;
m->m_nextpkt = NULL;
@ -506,7 +504,7 @@ mbuf_initialize(void *dummy)
#else
zone_mbuf = umem_cache_create(MBUF_MEM_NAME, MSIZE, 0,
mb_ctor_mbuf, mb_dtor_mbuf, NULL,
NUULL,
NULL,
NULL, 0);
#endif
/*zone_ext_refcnt = umem_cache_create(MBUF_EXTREFCNT_MEM_NAME, sizeof(u_int), 0,
@ -577,13 +575,6 @@ mb_ctor_mbuf(void *mem, void *arg, int flgs)
flags = args->flags;
type = args->type;
/*
* The mbuf is initialized later.
*
*/
if (type == MT_NOINIT)
return (0);
m->m_next = NULL;
m->m_nextpkt = NULL;
m->m_len = 0;
@ -1310,6 +1301,38 @@ out: if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))
m->m_pkthdr.len = totlen;
}
/*
* Apply function f to the data in an mbuf chain starting "off" bytes from
* the beginning, continuing for "len" bytes.
*/
int
m_apply(struct mbuf *m, int off, int len,
int (*f)(void *, void *, u_int), void *arg)
{
u_int count;
int rval;
KASSERT(off >= 0, ("m_apply, negative off %d", off));
KASSERT(len >= 0, ("m_apply, negative len %d", len));
while (off > 0) {
KASSERT(m != NULL, ("m_apply, offset > size of mbuf chain"));
if (off < m->m_len)
break;
off -= m->m_len;
m = m->m_next;
}
while (len > 0) {
KASSERT(m != NULL, ("m_apply, offset > size of mbuf chain"));
count = min(m->m_len - off, len);
rval = (*f)(arg, mtod(m, caddr_t) + off, count);
if (rval)
return (rval);
len -= count;
off = 0;
m = m->m_next;
}
return (0);
}
/*
* Lesser-used path for M_PREPEND:

View File

@ -113,6 +113,7 @@ void m_freem(struct mbuf *);
struct m_tag *m_tag_alloc(uint32_t, int, int, int);
struct mbuf *m_copym(struct mbuf *, int, int, int);
void m_copyback(struct mbuf *, int, int, caddr_t);
int m_apply(struct mbuf *, int, int, int (*)(void *, void *, u_int), void *arg);
struct mbuf *m_pullup(struct mbuf *, int);
struct mbuf *m_pulldown(struct mbuf *, int off, int len, int *offp);
int m_dup_pkthdr(struct mbuf *, struct mbuf *, int);
@ -125,9 +126,6 @@ void m_copydata(const struct mbuf *, int, int, caddr_t);
#define MBUF_CLUSTER_MEM_NAME "mbuf_cluster"
#define MBUF_EXTREFCNT_MEM_NAME "mbuf_ext_refcnt"
#define MT_NOINIT 255 /* Not a type but a flag to allocate
a non-initialized mbuf */
/*
* Mbufs are of a single size, MSIZE (sys/param.h), which includes overhead.
* An mbuf may add a single "mbuf cluster" of size MCLBYTES (also in
@ -293,9 +291,6 @@ struct mbuf {
#define MT_OOBDATA 15 /* expedited data */
#define MT_NTYPES 16 /* number of mbuf types for mbtypes[] */
#define MT_NOINIT 255 /* Not a type but a flag to allocate
a non-initialized mbuf */
/*
* __Userspace__ flags like M_NOWAIT are defined in malloc.h
* Flags like these are used in functions like uma_zalloc()
@ -332,6 +327,10 @@ extern int max_protohdr; /* Size of largest protocol layer header. See user_mbuf
(!(((m)->m_flags & M_EXT)) || \
(*((m)->m_ext.ref_cnt) == 1)) ) \
/* Check if the supplied mbuf has a packet header, or else panic. */
#define M_ASSERTPKTHDR(m) \
KASSERT((m) != NULL && (m)->m_flags & M_PKTHDR, \
("%s: no mbuf packet header!", __func__))
/*
* Compute the amount of space available before the current start of data in

View File

@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*

View File

@ -56,11 +56,17 @@
#endif
#endif
#endif
#if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__)
#include <net/route.h>
#if defined(HAVE_NET_ROUTE_H)
# include <net/route.h>
#elif defined(__APPLE__)
/* Apple SDKs for iOS, tvOS, watchOS, etc. don't ship this header */
# define RTM_NEWADDR 0xc
# define RTM_DELADDR 0xd
# define RTAX_IFA 5
# define RTAX_MAX 8
#endif
/* local macros and datatypes used to get IP addresses system independently */
#if !defined(IP_PKTINFO ) && !defined(IP_RECVDSTADDR)
#if !defined(IP_PKTINFO) && !defined(IP_RECVDSTADDR)
# error "Can't determine socket option to use to get UDP IP"
#endif
@ -274,6 +280,7 @@ recv_function_raw(void *arg)
struct sctp_chunkhdr *ch;
struct sockaddr_in src, dst;
#if !defined(_WIN32)
ssize_t res;
unsigned int ncounter;
struct msghdr msg;
struct iovec recv_iovec[MAXLEN_MBUF_CHAIN];
@ -340,14 +347,16 @@ recv_function_raw(void *arg)
msg.msg_iovlen = MAXLEN_MBUF_CHAIN;
msg.msg_control = NULL;
msg.msg_controllen = 0;
ncounter = n = recvmsg(SCTP_BASE_VAR(userspace_rawsctp), &msg, 0);
if (n < 0) {
res = recvmsg(SCTP_BASE_VAR(userspace_rawsctp), &msg, 0);
if (res < 0) {
if (errno == EAGAIN || errno == EINTR) {
continue;
} else {
break;
}
}
ncounter = (unsigned int)res;
n = (int)res;
#endif
SCTP_HEADER_LEN(recvmbuf[0]) = n; /* length of total packet */
SCTP_STAT_INCR(sctps_recvpackets);
@ -371,13 +380,20 @@ recv_function_raw(void *arg)
} while (ncounter > 0);
}
offset = sizeof(struct ip) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
if (SCTP_BUF_LEN(recvmbuf[0]) < offset) {
if ((recvmbuf[0] = m_pullup(recvmbuf[0], offset)) == NULL) {
SCTP_STAT_INCR(sctps_hdrops);
continue;
}
}
iphdr = mtod(recvmbuf[0], struct ip *);
sh = (struct sctphdr *)((caddr_t)iphdr + sizeof(struct ip));
ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
offset = sizeof(struct ip) + sizeof(struct sctphdr);
offset -= sizeof(struct sctp_chunkhdr);
if (iphdr->ip_tos != 0) {
ecn = iphdr->ip_tos & 0x02;
ecn = iphdr->ip_tos & 0x03;
}
dst.sin_family = AF_INET;
@ -444,7 +460,8 @@ recv_function_raw6(void *arg)
{
struct mbuf **recvmbuf6;
#if !defined(_WIN32)
unsigned int ncounter = 0;
ssize_t res;
unsigned int ncounter;
struct iovec recv_iovec[MAXLEN_MBUF_CHAIN];
struct msghdr msg;
struct cmsghdr *cmsgptr;
@ -531,15 +548,16 @@ recv_function_raw6(void *arg)
msg.msg_control = (void *)cmsgbuf;
msg.msg_controllen = (socklen_t)CMSG_SPACE(sizeof (struct in6_pktinfo));
msg.msg_flags = 0;
ncounter = n = recvmsg(SCTP_BASE_VAR(userspace_rawsctp6), &msg, 0);
if (n < 0) {
res = recvmsg(SCTP_BASE_VAR(userspace_rawsctp6), &msg, 0);
if (res < 0) {
if (errno == EAGAIN || errno == EINTR) {
continue;
} else {
break;
}
}
ncounter = (unsigned int)res;
n = (int)res;
#endif
SCTP_HEADER_LEN(recvmbuf6[0]) = n; /* length of total packet */
SCTP_STAT_INCR(sctps_recvpackets);
@ -579,9 +597,16 @@ recv_function_raw6(void *arg)
continue;
}
offset = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
if (SCTP_BUF_LEN(recvmbuf6[0]) < offset) {
if ((recvmbuf6[0] = m_pullup(recvmbuf6[0], offset)) == NULL) {
SCTP_STAT_INCR(sctps_hdrops);
continue;
}
}
sh = mtod(recvmbuf6[0], struct sctphdr *);
ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
offset = sizeof(struct sctphdr);
offset -= sizeof(struct sctp_chunkhdr);
dst.sin6_family = AF_INET6;
#ifdef HAVE_SIN6_LEN
@ -648,6 +673,7 @@ recv_function_udp(void *arg)
#endif
int compute_crc = 1;
#if !defined(_WIN32)
ssize_t res;
unsigned int ncounter;
struct iovec iov[MAXLEN_MBUF_CHAIN];
struct msghdr msg;
@ -701,14 +727,16 @@ recv_function_udp(void *arg)
msg.msg_controllen = sizeof(cmsgbuf);
msg.msg_flags = 0;
ncounter = n = recvmsg(SCTP_BASE_VAR(userspace_udpsctp), &msg, 0);
if (n < 0) {
res = recvmsg(SCTP_BASE_VAR(userspace_udpsctp), &msg, 0);
if (res < 0) {
if (errno == EAGAIN || errno == EINTR) {
continue;
} else {
break;
}
}
ncounter = (unsigned int)res;
n = (int)res;
#else
nResult = WSAIoctl(SCTP_BASE_VAR(userspace_udpsctp), SIO_GET_EXTENSION_FUNCTION_POINTER,
&WSARecvMsg_GUID, sizeof WSARecvMsg_GUID,
@ -793,10 +821,17 @@ recv_function_udp(void *arg)
continue;
}
/*offset = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);*/
offset = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
if (SCTP_BUF_LEN(udprecvmbuf[0]) < offset) {
if ((udprecvmbuf[0] = m_pullup(udprecvmbuf[0], offset)) == NULL) {
SCTP_STAT_INCR(sctps_hdrops);
continue;
}
}
sh = mtod(udprecvmbuf[0], struct sctphdr *);
ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
offset = sizeof(struct sctphdr);
offset -= sizeof(struct sctp_chunkhdr);
port = src.sin_port;
src.sin_port = sh->src_port;
dst.sin_port = sh->dest_port;
@ -853,6 +888,7 @@ recv_function_udp6(void *arg)
struct iovec iov[MAXLEN_MBUF_CHAIN];
struct msghdr msg;
struct cmsghdr *cmsgptr;
ssize_t res;
unsigned int ncounter;
#else
GUID WSARecvMsg_GUID = WSAID_WSARECVMSG;
@ -903,14 +939,16 @@ recv_function_udp6(void *arg)
msg.msg_controllen = (socklen_t)CMSG_SPACE(sizeof (struct in6_pktinfo));
msg.msg_flags = 0;
ncounter = n = recvmsg(SCTP_BASE_VAR(userspace_udpsctp6), &msg, 0);
if (n < 0) {
res = recvmsg(SCTP_BASE_VAR(userspace_udpsctp6), &msg, 0);
if (res < 0) {
if (errno == EAGAIN || errno == EINTR) {
continue;
} else {
break;
}
}
ncounter = (unsigned int)res;
n = (int)res;
#else
nResult = WSAIoctl(SCTP_BASE_VAR(userspace_udpsctp6), SIO_GET_EXTENSION_FUNCTION_POINTER,
&WSARecvMsg_GUID, sizeof WSARecvMsg_GUID,
@ -981,9 +1019,16 @@ recv_function_udp6(void *arg)
continue;
}
offset = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
if (SCTP_BUF_LEN(udprecvmbuf6[0]) < offset) {
if ((udprecvmbuf6[0] = m_pullup(udprecvmbuf6[0], offset)) == NULL) {
SCTP_STAT_INCR(sctps_hdrops);
continue;
}
}
sh = mtod(udprecvmbuf6[0], struct sctphdr *);
ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
offset = sizeof(struct sctphdr);
offset -= sizeof(struct sctp_chunkhdr);
port = src.sin6_port;
src.sin6_port = sh->src_port;
@ -1172,7 +1217,7 @@ recv_thread_init(void)
}
}
}
if (SCTP_BASE_VAR(userspace_udpsctp) == -1) {
if ((SCTP_BASE_VAR(userspace_udpsctp) == -1) && (SCTP_BASE_SYSCTL(sctp_udp_tunneling_port) != 0)) {
if ((SCTP_BASE_VAR(userspace_udpsctp) = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
#if defined(_WIN32)
SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/UDP/IPv4 (errno = %d).\n", WSAGetLastError());
@ -1309,7 +1354,7 @@ recv_thread_init(void)
}
}
}
if (SCTP_BASE_VAR(userspace_udpsctp6) == -1) {
if ((SCTP_BASE_VAR(userspace_udpsctp6) == -1) && (SCTP_BASE_SYSCTL(sctp_udp_tunneling_port) != 0)) {
if ((SCTP_BASE_VAR(userspace_udpsctp6) = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
#if defined(_WIN32)
SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError());

View File

@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*

View File

@ -115,8 +115,8 @@ usrsctp_init(uint16_t port,
void
usrsctp_init_nothreads(uint16_t port,
int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
void (*debug_printf)(const char *format, ...))
int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
void (*debug_printf)(const char *format, ...))
{
init_sync();
sctp_init(port, conn_output, debug_printf, 0);
@ -251,7 +251,7 @@ sofree(struct socket *so)
ACCEPT_LOCK_ASSERT();
SOCK_LOCK_ASSERT(so);
/* SS_NOFDREF unset in accept call. this condition seems irrelevent
/* SS_NOFDREF unset in accept call. this condition seems irrelevant
* for __Userspace__...
*/
if (so->so_count != 0 ||
@ -296,7 +296,7 @@ sofree(struct socket *so)
* necessary from sorflush().
*
* Notice that the socket buffer and kqueue state are torn down
* before calling pru_detach. This means that protocols shold not
* before calling pru_detach. This means that protocols should not
* assume they can perform socket wakeups, etc, in their detach code.
*/
sodealloc(so);
@ -1324,11 +1324,11 @@ struct socket *
usrsctp_socket(int domain, int type, int protocol,
int (*receive_cb)(struct socket *sock, union sctp_sockstore addr, void *data,
size_t datalen, struct sctp_rcvinfo, int flags, void *ulp_info),
int (*send_cb)(struct socket *sock, uint32_t sb_free),
int (*send_cb)(struct socket *sock, uint32_t sb_free, void *ulp_info),
uint32_t sb_threshold,
void *ulp_info)
{
struct socket *so;
struct socket *so = NULL;
if ((protocol == IPPROTO_SCTP) && (SCTP_BASE_VAR(sctp_pcb_initialized) == 0)) {
errno = EPROTONOSUPPORT;
@ -1878,7 +1878,7 @@ soconnect(struct socket *so, struct sockaddr *nam)
* Otherwise, if connected, try to disconnect first. This allows
* user to disconnect by connecting to, e.g., a null address.
*/
if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) && (error = sodisconnect(so))) {
if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) && (sodisconnect(so) != 0)) {
error = EISCONN;
} else {
/*
@ -2210,7 +2210,7 @@ usrsctp_getsockopt(struct socket *so, int level, int option_name,
int *buf_size;
buf_size = (int *)option_value;
*buf_size = so->so_rcv.sb_hiwat;;
*buf_size = so->so_rcv.sb_hiwat;
*option_len = (socklen_t)sizeof(int);
return (0);
}
@ -2695,22 +2695,26 @@ usrsctp_getpaddrs(struct socket *so, sctp_assoc_t id, struct sockaddr **raddrs)
{
struct sctp_getaddresses *addrs;
struct sockaddr *sa;
sctp_assoc_t asoc;
caddr_t lim;
socklen_t opt_len;
uint32_t size_of_addresses;
int cnt;
if (raddrs == NULL) {
errno = EFAULT;
return (-1);
}
asoc = id;
opt_len = (socklen_t)sizeof(sctp_assoc_t);
if (usrsctp_getsockopt(so, IPPROTO_SCTP, SCTP_GET_REMOTE_ADDR_SIZE, &asoc, &opt_len) != 0) {
return (-1);
/* When calling getsockopt(), the value contains the assoc_id. */
size_of_addresses = (uint32_t)id;
opt_len = (socklen_t)sizeof(uint32_t);
if (usrsctp_getsockopt(so, IPPROTO_SCTP, SCTP_GET_REMOTE_ADDR_SIZE, &size_of_addresses, &opt_len) != 0) {
if (errno == ENOENT) {
return (0);
} else {
return (-1);
}
}
/* size required is returned in 'asoc' */
opt_len = (socklen_t)((size_t)asoc + sizeof(struct sctp_getaddresses));
opt_len = (socklen_t)((size_t)size_of_addresses + sizeof(struct sctp_getaddresses));
addrs = calloc(1, (size_t)opt_len);
if (addrs == NULL) {
errno = ENOMEM;
@ -2770,10 +2774,10 @@ int
usrsctp_getladdrs(struct socket *so, sctp_assoc_t id, struct sockaddr **raddrs)
{
struct sctp_getaddresses *addrs;
caddr_t lim;
struct sockaddr *sa;
size_t size_of_addresses;
caddr_t lim;
socklen_t opt_len;
uint32_t size_of_addresses;
int cnt;
if (raddrs == NULL) {
@ -2781,13 +2785,8 @@ usrsctp_getladdrs(struct socket *so, sctp_assoc_t id, struct sockaddr **raddrs)
return (-1);
}
size_of_addresses = 0;
opt_len = (socklen_t)sizeof(int);
opt_len = (socklen_t)sizeof(uint32_t);
if (usrsctp_getsockopt(so, IPPROTO_SCTP, SCTP_GET_LOCAL_ADDR_SIZE, &size_of_addresses, &opt_len) != 0) {
errno = ENOMEM;
return (-1);
}
if (size_of_addresses == 0) {
errno = ENOTCONN;
return (-1);
}
opt_len = (socklen_t)(size_of_addresses + sizeof(struct sctp_getaddresses));
@ -2800,9 +2799,12 @@ usrsctp_getladdrs(struct socket *so, sctp_assoc_t id, struct sockaddr **raddrs)
/* Now lets get the array of addresses */
if (usrsctp_getsockopt(so, IPPROTO_SCTP, SCTP_GET_LOCAL_ADDRESSES, addrs, &opt_len) != 0) {
free(addrs);
errno = ENOMEM;
return (-1);
}
if (size_of_addresses == 0) {
free(addrs);
return (0);
}
*raddrs = &addrs->addr[0].sa;
cnt = 0;
sa = &addrs->addr[0].sa;
@ -2850,14 +2852,13 @@ usrsctp_freeladdrs(struct sockaddr *addrs)
#ifdef INET
void
sctp_userspace_ip_output(int *result, struct mbuf *o_pak,
sctp_route_t *ro, void *stcb,
sctp_route_t *ro, void *inp,
uint32_t vrf_id)
{
struct mbuf *m;
struct mbuf *m_orig;
int iovcnt;
int len;
int send_count;
struct ip *ip;
struct udphdr *udp;
struct sockaddr_in dst;
@ -2930,16 +2931,13 @@ sctp_userspace_ip_output(int *result, struct mbuf *o_pak,
m_adj(m, sizeof(struct ip) + sizeof(struct udphdr));
}
send_count = 0;
for (iovcnt = 0; m != NULL && iovcnt < MAXLEN_MBUF_CHAIN; m = m->m_next, iovcnt++) {
#if !defined(_WIN32)
send_iovec[iovcnt].iov_base = (caddr_t)m->m_data;
send_iovec[iovcnt].iov_len = SCTP_BUF_LEN(m);
send_count += send_iovec[iovcnt].iov_len;
#else
send_iovec[iovcnt].buf = (caddr_t)m->m_data;
send_iovec[iovcnt].len = SCTP_BUF_LEN(m);
send_count += send_iovec[iovcnt].len;
#endif
}
@ -2995,14 +2993,13 @@ free_mbuf:
#if defined(INET6)
void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak,
struct route_in6 *ro, void *stcb,
struct route_in6 *ro, void *inp,
uint32_t vrf_id)
{
struct mbuf *m;
struct mbuf *m_orig;
int iovcnt;
int len;
int send_count;
struct ip6_hdr *ip6;
struct udphdr *udp;
struct sockaddr_in6 dst;
@ -3073,19 +3070,16 @@ void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak,
if (use_udp_tunneling) {
m_adj(m, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
} else {
m_adj(m, sizeof(struct ip6_hdr));
m_adj(m, sizeof(struct ip6_hdr));
}
send_count = 0;
for (iovcnt = 0; m != NULL && iovcnt < MAXLEN_MBUF_CHAIN; m = m->m_next, iovcnt++) {
#if !defined(_WIN32)
send_iovec[iovcnt].iov_base = (caddr_t)m->m_data;
send_iovec[iovcnt].iov_len = SCTP_BUF_LEN(m);
send_count += send_iovec[iovcnt].iov_len;
#else
send_iovec[iovcnt].buf = (caddr_t)m->m_data;
send_iovec[iovcnt].len = SCTP_BUF_LEN(m);
send_count += send_iovec[iovcnt].len;
#endif
}
if (m != NULL) {
@ -3297,7 +3291,7 @@ usrsctp_conninput(void *addr, const void *buffer, size_t length, uint8_t ecn_bit
struct mbuf *m, *mm;
struct sctphdr *sh;
struct sctp_chunkhdr *ch;
int remaining;
int remaining, offset;
SCTP_STAT_INCR(sctps_recvpackets);
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
@ -3327,17 +3321,19 @@ usrsctp_conninput(void *addr, const void *buffer, size_t length, uint8_t ecn_bit
}
KASSERT(remaining == 0, ("usrsctp_conninput: %zu bytes left", remaining));
m_copyback(m, 0, (int)length, (caddr_t)buffer);
if (SCTP_BUF_LEN(m) < (int)(sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr))) {
if ((m = m_pullup(m, sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr))) == NULL) {
offset = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
if (SCTP_BUF_LEN(m) < offset) {
if ((m = m_pullup(m, offset)) == NULL) {
SCTP_STAT_INCR(sctps_hdrops);
return;
}
}
sh = mtod(m, struct sctphdr *);;
sh = mtod(m, struct sctphdr *);
ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
offset -= sizeof(struct sctp_chunkhdr);
src.sconn_port = sh->src_port;
dst.sconn_port = sh->dest_port;
sctp_common_input_processing(&m, 0, sizeof(struct sctphdr), (int)length,
sctp_common_input_processing(&m, 0, offset, (int)length,
(struct sockaddr *)&src,
(struct sockaddr *)&dst,
sh, ch,

View File

@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*

View File

@ -64,19 +64,19 @@ extern "C" {
#elif defined(SCTP_STDINT_INCLUDE)
#include SCTP_STDINT_INCLUDE
#else
#define uint8_t unsigned __int8
#define uint16_t unsigned __int16
#define uint32_t unsigned __int32
#define uint64_t unsigned __int64
#define int16_t __int16
#define int32_t __int32
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
typedef __int16 int16_t;
typedef __int32 int32_t;
#endif
#ifndef ssize_t
#ifdef _WIN64
#define ssize_t __int64
typedef __int64 ssize_t;
#elif defined _WIN32
#define ssize_t int
typedef int ssize_t;
#else
#error "Unknown platform!"
#endif
@ -904,7 +904,7 @@ struct socket *
usrsctp_socket(int domain, int type, int protocol,
int (*receive_cb)(struct socket *sock, union sctp_sockstore addr, void *data,
size_t datalen, struct sctp_rcvinfo, int flags, void *ulp_info),
int (*send_cb)(struct socket *sock, uint32_t sb_free),
int (*send_cb)(struct socket *sock, uint32_t sb_free, void *ulp_info),
uint32_t sb_threshold,
void *ulp_info);