mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 23:02:20 +00:00
Bug 1795697: Update libusrsctp. r=ng
Differential Revision: https://phabricator.services.mozilla.com/D159616
This commit is contained in:
parent
a2cad07649
commit
e0d638f358
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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 *);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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? */
|
||||
|
@ -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(<ls);
|
||||
timevalsub(<ls, &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) {
|
||||
|
@ -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); \
|
||||
|
@ -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__)
|
||||
|
@ -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__ */
|
||||
|
@ -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>
|
||||
|
@ -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) &&
|
||||
|
@ -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
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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_
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
@ -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 *,
|
||||
|
@ -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:
|
||||
|
@ -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 *);
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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());
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user