Issue #2058 - Initial update of usrsctp library

This commit is contained in:
Basilisk-Dev 2023-08-26 21:58:02 -04:00 • committed by roytam1
commit de80c8a019
63 changed files with 15015 additions and 13306 deletions

View file

@ -16,3 +16,4 @@ sctp updated to version 8443 from SVN on Sun Mar 31 09:05:07 EDT 2013
sctp updated to version 8815 from SVN on Tue Mar 4 08:50:51 EST 2014 sctp updated to version 8815 from SVN on Tue Mar 4 08:50:51 EST 2014
sctp updated to version 9168 from SVN on Tue Mar 3 12:11:40 EST 2015 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 9209 from SVN on Tue Mar 24 18:11:59 EDT 2015
sctp updated to version 0.9.5.0 from https://github.com/sctplab/usrsctp/releases/tag/0.9.5.0 on Sat Aug 26 21:54:00 EDT 2023

View file

@ -1,12 +1,9 @@
This code is imported from the usrsctp library via netwerk/sctp/update_sctp.sh. This code is imported from the usrsctp library. The current code is version
0.9.5.0.
The project is accessed via: The project is accessed on GitHub at the following location:
svn co --username your.username https://sctp-refimpl.googlecode.com/svn/trunk sctpSVN https://github.com/sctplab/usrsctp
If you just want a read-only copy use
svn co http://sctp-refimpl.googlecode.com/svn/trunk sctpSVN
The usrsctp library is based on the FreeBSD kernel implementation, and the The usrsctp library is based on the FreeBSD kernel implementation, and the
userspace implementation was largely done my Michael Tuexen and Irene userspace implementation was largely done my Michael Tuexen and Irene

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,22 +32,20 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 356270 2020-01-02 13:55:10Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp.h 366750 2020-10-16 10:44:48Z tuexen $");
#endif #endif
#ifndef _NETINET_SCTP_H_ #ifndef _NETINET_SCTP_H_
#define _NETINET_SCTP_H_ #define _NETINET_SCTP_H_
#if (defined(__APPLE__) || defined(__Userspace_os_Linux) || defined(__Userspace_os_Darwin)) #if defined(__APPLE__) || defined(__linux__)
#include <stdint.h> #include <stdint.h>
#endif #endif
#include <sys/types.h> #include <sys/types.h>
#if !defined(_WIN32)
#if !defined(__Userspace_os_Windows)
#define SCTP_PACKED __attribute__((packed)) #define SCTP_PACKED __attribute__((packed))
#else #else
#pragma pack (push, 1) #pragma pack (push, 1)
@ -189,7 +189,6 @@ struct sctp_paramhdr {
#define SCTP_STREAM_RESET_INCOMING 0x00000001 #define SCTP_STREAM_RESET_INCOMING 0x00000001
#define SCTP_STREAM_RESET_OUTGOING 0x00000002 #define SCTP_STREAM_RESET_OUTGOING 0x00000002
/* here on down are more implementation specific */ /* here on down are more implementation specific */
#define SCTP_SET_DEBUG_LEVEL 0x00001005 #define SCTP_SET_DEBUG_LEVEL 0x00001005
#define SCTP_CLR_STAT_LOG 0x00001007 #define SCTP_CLR_STAT_LOG 0x00001007
@ -202,13 +201,15 @@ struct sctp_paramhdr {
#define SCTP_PLUGGABLE_SS 0x00001203 #define SCTP_PLUGGABLE_SS 0x00001203
#define SCTP_SS_VALUE 0x00001204 #define SCTP_SS_VALUE 0x00001204
#define SCTP_CC_OPTION 0x00001205 /* Options for CC modules */ #define SCTP_CC_OPTION 0x00001205 /* Options for CC modules */
/* For I-DATA */
#define SCTP_INTERLEAVING_SUPPORTED 0x00001206
/* read only */ /* read only */
#define SCTP_GET_SNDBUF_USE 0x00001101 #define SCTP_GET_SNDBUF_USE 0x00001101
#define SCTP_GET_STAT_LOG 0x00001103 #define SCTP_GET_STAT_LOG 0x00001103
#define SCTP_PCB_STATUS 0x00001104 #define SCTP_PCB_STATUS 0x00001104
#define SCTP_GET_NONCE_VALUES 0x00001105 #define SCTP_GET_NONCE_VALUES 0x00001105
/* Special hook for dynamically setting primary for all assoc's, /* Special hook for dynamically setting primary for all assoc's,
* this is a write only option that requires root privilege. * this is a write only option that requires root privilege.
*/ */
@ -281,11 +282,11 @@ struct sctp_paramhdr {
#define SCTP_PEELOFF 0x0000800a #define SCTP_PEELOFF 0x0000800a
/* the real worker for sctp_getaddrlen() */ /* the real worker for sctp_getaddrlen() */
#define SCTP_GET_ADDR_LEN 0x0000800b #define SCTP_GET_ADDR_LEN 0x0000800b
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
/* temporary workaround for Apple listen() issue, no args used */ /* temporary workaround for Apple listen() issue, no args used */
#define SCTP_LISTEN_FIX 0x0000800c #define SCTP_LISTEN_FIX 0x0000800c
#endif #endif
#if defined(__Windows__) #if defined(_WIN32) && !defined(__Userspace__)
/* workaround for Cygwin on Windows: returns the SOCKET handle */ /* workaround for Cygwin on Windows: returns the SOCKET handle */
#define SCTP_GET_HANDLE 0x0000800d #define SCTP_GET_HANDLE 0x0000800d
#endif #endif
@ -331,7 +332,6 @@ struct sctp_paramhdr {
/* First-come, first-serve */ /* First-come, first-serve */
#define SCTP_SS_FIRST_COME 0x00000005 #define SCTP_SS_FIRST_COME 0x00000005
/* fragment interleave constants /* fragment interleave constants
* setting must be one of these or * setting must be one of these or
* EINVAL returned. * EINVAL returned.
@ -402,33 +402,32 @@ struct sctp_error_cause {
} SCTP_PACKED; } SCTP_PACKED;
struct sctp_error_invalid_stream { struct sctp_error_invalid_stream {
struct sctp_error_cause cause; /* code=SCTP_ERROR_INVALID_STREAM */ struct sctp_error_cause cause; /* code=SCTP_CAUSE_INVALID_STREAM */
uint16_t stream_id; /* stream id of the DATA in error */ uint16_t stream_id; /* stream id of the DATA in error */
uint16_t reserved; uint16_t reserved;
} SCTP_PACKED; } SCTP_PACKED;
struct sctp_error_missing_param { struct sctp_error_missing_param {
struct sctp_error_cause cause; /* code=SCTP_ERROR_MISSING_PARAM */ struct sctp_error_cause cause; /* code=SCTP_CAUSE_MISSING_PARAM */
uint32_t num_missing_params; /* number of missing parameters */ uint32_t num_missing_params; /* number of missing parameters */
/* uint16_t param_type's follow */ uint16_t type[];
} SCTP_PACKED; } SCTP_PACKED;
struct sctp_error_stale_cookie { struct sctp_error_stale_cookie {
struct sctp_error_cause cause; /* code=SCTP_ERROR_STALE_COOKIE */ struct sctp_error_cause cause; /* code=SCTP_CAUSE_STALE_COOKIE */
uint32_t stale_time; /* time in usec of staleness */ uint32_t stale_time; /* time in usec of staleness */
} SCTP_PACKED; } SCTP_PACKED;
struct sctp_error_out_of_resource { struct sctp_error_out_of_resource {
struct sctp_error_cause cause; /* code=SCTP_ERROR_OUT_OF_RESOURCES */ struct sctp_error_cause cause; /* code=SCTP_CAUSE_OUT_OF_RESOURCES */
} SCTP_PACKED; } SCTP_PACKED;
struct sctp_error_unresolv_addr { struct sctp_error_unresolv_addr {
struct sctp_error_cause cause; /* code=SCTP_ERROR_UNRESOLVABLE_ADDR */ struct sctp_error_cause cause; /* code=SCTP_CAUSE_UNRESOLVABLE_ADDR */
} SCTP_PACKED; } SCTP_PACKED;
struct sctp_error_unrecognized_chunk { struct sctp_error_unrecognized_chunk {
struct sctp_error_cause cause; /* code=SCTP_ERROR_UNRECOG_CHUNK */ struct sctp_error_cause cause; /* code=SCTP_CAUSE_UNRECOG_CHUNK */
struct sctp_chunkhdr ch;/* header from chunk in error */ struct sctp_chunkhdr ch;/* header from chunk in error */
} SCTP_PACKED; } SCTP_PACKED;
@ -437,6 +436,11 @@ struct sctp_error_no_user_data {
uint32_t tsn; /* TSN of the empty data chunk */ uint32_t tsn; /* TSN of the empty data chunk */
} SCTP_PACKED; } SCTP_PACKED;
struct sctp_error_auth_invalid_hmac {
struct sctp_error_cause cause; /* code=SCTP_CAUSE_UNSUPPORTED_HMACID */
uint16_t hmac_id;
} SCTP_PACKED;
/* /*
* Main SCTP chunk types we place these here so natd and f/w's in user land * Main SCTP chunk types we place these here so natd and f/w's in user land
* can find them. * can find them.
@ -462,6 +466,7 @@ struct sctp_error_no_user_data {
/* EY nr_sack chunk id*/ /* EY nr_sack chunk id*/
#define SCTP_NR_SELECTIVE_ACK 0x10 #define SCTP_NR_SELECTIVE_ACK 0x10
/************0x40 series ***********/ /************0x40 series ***********/
#define SCTP_IDATA 0x40
/************0x80 series ***********/ /************0x80 series ***********/
/* RFC5061 */ /* RFC5061 */
#define SCTP_ASCONF_ACK 0x80 #define SCTP_ASCONF_ACK 0x80
@ -477,7 +482,7 @@ struct sctp_error_no_user_data {
#define SCTP_FORWARD_CUM_TSN 0xc0 #define SCTP_FORWARD_CUM_TSN 0xc0
/* RFC5061 */ /* RFC5061 */
#define SCTP_ASCONF 0xc1 #define SCTP_ASCONF 0xc1
#define SCTP_IFORWARD_CUM_TSN 0xc2
/* ABORT and SHUTDOWN COMPLETE FLAG */ /* ABORT and SHUTDOWN COMPLETE FLAG */
#define SCTP_HAD_NO_TCB 0x01 #define SCTP_HAD_NO_TCB 0x01
@ -520,6 +525,7 @@ struct sctp_error_no_user_data {
#define SCTP_PCB_FLAGS_BOUNDALL 0x00000004 #define SCTP_PCB_FLAGS_BOUNDALL 0x00000004
#define SCTP_PCB_FLAGS_ACCEPTING 0x00000008 #define SCTP_PCB_FLAGS_ACCEPTING 0x00000008
#define SCTP_PCB_FLAGS_UNBOUND 0x00000010 #define SCTP_PCB_FLAGS_UNBOUND 0x00000010
#define SCTP_PCB_FLAGS_SND_ITERATOR_UP 0x00000020
#define SCTP_PCB_FLAGS_CLOSE_IP 0x00040000 #define SCTP_PCB_FLAGS_CLOSE_IP 0x00040000
#define SCTP_PCB_FLAGS_WAS_CONNECTED 0x00080000 #define SCTP_PCB_FLAGS_WAS_CONNECTED 0x00080000
#define SCTP_PCB_FLAGS_WAS_ABORTED 0x00100000 #define SCTP_PCB_FLAGS_WAS_ABORTED 0x00100000
@ -561,7 +567,6 @@ struct sctp_error_no_user_data {
#define SCTP_PCB_FLAGS_INTERLEAVE_STRMS 0x0000000000000010 #define SCTP_PCB_FLAGS_INTERLEAVE_STRMS 0x0000000000000010
#define SCTP_PCB_FLAGS_DO_ASCONF 0x0000000000000020 #define SCTP_PCB_FLAGS_DO_ASCONF 0x0000000000000020
#define SCTP_PCB_FLAGS_AUTO_ASCONF 0x0000000000000040 #define SCTP_PCB_FLAGS_AUTO_ASCONF 0x0000000000000040
#define SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE 0x0000000000000080
/* socket options */ /* socket options */
#define SCTP_PCB_FLAGS_NODELAY 0x0000000000000100 #define SCTP_PCB_FLAGS_NODELAY 0x0000000000000100
#define SCTP_PCB_FLAGS_AUTOCLOSE 0x0000000000000200 #define SCTP_PCB_FLAGS_AUTOCLOSE 0x0000000000000200
@ -597,14 +602,13 @@ struct sctp_error_no_user_data {
#define SCTP_MOBILITY_FASTHANDOFF 0x00000002 #define SCTP_MOBILITY_FASTHANDOFF 0x00000002
#define SCTP_MOBILITY_PRIM_DELETED 0x00000004 #define SCTP_MOBILITY_PRIM_DELETED 0x00000004
/* Smallest PMTU allowed when disabling PMTU discovery */ /* Smallest PMTU allowed when disabling PMTU discovery */
#define SCTP_SMALLEST_PMTU 512 #define SCTP_SMALLEST_PMTU 512
/* Largest PMTU allowed when disabling PMTU discovery */ /* Largest PMTU allowed when disabling PMTU discovery */
#define SCTP_LARGEST_PMTU 65536 #define SCTP_LARGEST_PMTU 65536
#if defined(__Userspace_os_Windows) #if defined(_WIN32)
#pragma pack() #pragma pack(pop)
#endif #endif
#undef SCTP_PACKED #undef SCTP_PACKED
@ -622,9 +626,9 @@ struct sctp_error_no_user_data {
*/ */
#define SCTP_MAX_SACK_DELAY 500 /* per RFC4960 */ #define SCTP_MAX_SACK_DELAY 500 /* per RFC4960 */
#define SCTP_MAX_HB_INTERVAL 14400000 /* 4 hours in ms */ #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 */ #define SCTP_MAX_COOKIE_LIFE 3600000 /* 1 hour in ms */
/* Types of logging/KTR tracing that can be enabled via the /* Types of logging/KTR tracing that can be enabled via the
* sysctl net.inet.sctp.sctp_logging. You must also enable * sysctl net.inet.sctp.sctp_logging. You must also enable
* SUBSYS tracing. * SUBSYS tracing.

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.h 237715 2012-06-28 16:01:08Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.h 365071 2020-09-01 21:19:14Z mjg $");
#endif #endif
#ifndef _NETINET_SCTP_ASCONF_H_ #ifndef _NETINET_SCTP_ASCONF_H_
@ -43,7 +45,7 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.h 237715 2012-06-28 16:01:08Z t
/* /*
* function prototypes * function prototypes
*/ */
extern void sctp_asconf_cleanup(struct sctp_tcb *, struct sctp_nets *); extern void sctp_asconf_cleanup(struct sctp_tcb *);
extern struct mbuf *sctp_compose_asconf(struct sctp_tcb *, int *, int); extern struct mbuf *sctp_compose_asconf(struct sctp_tcb *, int *, int);
@ -56,9 +58,8 @@ sctp_handle_asconf_ack(struct mbuf *, int, struct sctp_asconf_ack_chunk *,
struct sctp_tcb *, struct sctp_nets *, int *); struct sctp_tcb *, struct sctp_nets *, int *);
extern uint32_t extern uint32_t
sctp_addr_mgmt_ep_sa(struct sctp_inpcb *, struct sockaddr *, sctp_addr_mgmt_ep_sa(struct sctp_inpcb *, struct sockaddr *, uint32_t,
uint32_t, uint32_t, struct sctp_ifa *); uint32_t);
extern int sctp_asconf_iterator_ep(struct sctp_inpcb *inp, void *ptr, extern int sctp_asconf_iterator_ep(struct sctp_inpcb *inp, void *ptr,
uint32_t val); uint32_t val);
@ -67,14 +68,10 @@ extern void sctp_asconf_iterator_stcb(struct sctp_inpcb *inp,
void *ptr, uint32_t type); void *ptr, uint32_t type);
extern void sctp_asconf_iterator_end(void *ptr, uint32_t val); extern void sctp_asconf_iterator_end(void *ptr, uint32_t val);
extern int32_t extern int32_t
sctp_set_primary_ip_address_sa(struct sctp_tcb *, sctp_set_primary_ip_address_sa(struct sctp_tcb *,
struct sockaddr *); struct sockaddr *);
extern void
sctp_set_primary_ip_address(struct sctp_ifa *ifa);
extern void extern void
sctp_check_address_list(struct sctp_tcb *, struct mbuf *, int, int, sctp_check_address_list(struct sctp_tcb *, struct mbuf *, int, int,
struct sockaddr *, uint16_t, uint16_t, uint16_t, uint16_t); struct sockaddr *, uint16_t, uint16_t, uint16_t, uint16_t);

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.c 355931 2019-12-20 15:25:08Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.c 365071 2020-09-01 21:19:14Z mjg $");
#endif #endif
#include <netinet/sctp_os.h> #include <netinet/sctp_os.h>
@ -51,11 +53,10 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.c 355931 2019-12-20 15:25:08Z tue
#define SCTP_AUTH_DEBUG2 (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_AUTH2) #define SCTP_AUTH_DEBUG2 (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_AUTH2)
#endif /* SCTP_DEBUG */ #endif /* SCTP_DEBUG */
void void
sctp_clear_chunklist(sctp_auth_chklist_t *chklist) sctp_clear_chunklist(sctp_auth_chklist_t *chklist)
{ {
bzero(chklist, sizeof(*chklist)); memset(chklist, 0, sizeof(*chklist));
/* chklist->num_chunks = 0; */ /* chklist->num_chunks = 0; */
} }
@ -94,12 +95,11 @@ sctp_copy_chunklist(sctp_auth_chklist_t *list)
if (new_list == NULL) if (new_list == NULL)
return (NULL); return (NULL);
/* copy it */ /* copy it */
bcopy(list, new_list, sizeof(*new_list)); memcpy(new_list, list, sizeof(*new_list));
return (new_list); return (new_list);
} }
/* /*
* add a chunk to the required chunks list * add a chunk to the required chunks list
*/ */
@ -239,7 +239,6 @@ sctp_unpack_auth_chunks(const uint8_t *ptr, uint8_t num_chunks,
return (size); return (size);
} }
/* /*
* allocate structure space for a key of length keylen * allocate structure space for a key of length keylen
*/ */
@ -340,7 +339,7 @@ sctp_set_key(uint8_t *key, uint32_t keylen)
/* out of memory */ /* out of memory */
return (NULL); return (NULL);
} }
bcopy(key, new_key->key, keylen); memcpy(new_key->key, key, keylen);
return (new_key); return (new_key);
} }
@ -429,34 +428,33 @@ sctp_compute_hashkey(sctp_key_t *key1, sctp_key_t *key2, sctp_key_t *shared)
if (sctp_compare_key(key1, key2) <= 0) { if (sctp_compare_key(key1, key2) <= 0) {
/* key is shared + key1 + key2 */ /* key is shared + key1 + key2 */
if (sctp_get_keylen(shared)) { if (sctp_get_keylen(shared)) {
bcopy(shared->key, key_ptr, shared->keylen); memcpy(key_ptr, shared->key, shared->keylen);
key_ptr += shared->keylen; key_ptr += shared->keylen;
} }
if (sctp_get_keylen(key1)) { if (sctp_get_keylen(key1)) {
bcopy(key1->key, key_ptr, key1->keylen); memcpy(key_ptr, key1->key, key1->keylen);
key_ptr += key1->keylen; key_ptr += key1->keylen;
} }
if (sctp_get_keylen(key2)) { if (sctp_get_keylen(key2)) {
bcopy(key2->key, key_ptr, key2->keylen); memcpy(key_ptr, key2->key, key2->keylen);
} }
} else { } else {
/* key is shared + key2 + key1 */ /* key is shared + key2 + key1 */
if (sctp_get_keylen(shared)) { if (sctp_get_keylen(shared)) {
bcopy(shared->key, key_ptr, shared->keylen); memcpy(key_ptr, shared->key, shared->keylen);
key_ptr += shared->keylen; key_ptr += shared->keylen;
} }
if (sctp_get_keylen(key2)) { if (sctp_get_keylen(key2)) {
bcopy(key2->key, key_ptr, key2->keylen); memcpy(key_ptr, key2->key, key2->keylen);
key_ptr += key2->keylen; key_ptr += key2->keylen;
} }
if (sctp_get_keylen(key1)) { if (sctp_get_keylen(key1)) {
bcopy(key1->key, key_ptr, key1->keylen); memcpy(key_ptr, key1->key, key1->keylen);
} }
} }
return (new_key); return (new_key);
} }
sctp_sharedkey_t * sctp_sharedkey_t *
sctp_alloc_sharedkey(void) sctp_alloc_sharedkey(void)
{ {
@ -523,7 +521,7 @@ sctp_insert_sharedkey(struct sctp_keyhead *shared_keys,
} else if (new_skey->keyid == skey->keyid) { } else if (new_skey->keyid == skey->keyid) {
/* replace the existing key */ /* replace the existing key */
/* verify this key *can* be replaced */ /* verify this key *can* be replaced */
if ((skey->deactivated) && (skey->refcount > 1)) { if ((skey->deactivated) || (skey->refcount > 1)) {
SCTPDBG(SCTP_DEBUG_AUTH1, SCTPDBG(SCTP_DEBUG_AUTH1,
"can't replace shared key id %u\n", "can't replace shared key id %u\n",
new_skey->keyid); new_skey->keyid);
@ -544,7 +542,7 @@ sctp_insert_sharedkey(struct sctp_keyhead *shared_keys,
} }
} }
/* shouldn't reach here */ /* shouldn't reach here */
return (0); return (EINVAL);
} }
void void
@ -560,16 +558,12 @@ sctp_auth_key_acquire(struct sctp_tcb *stcb, uint16_t key_id)
atomic_add_int(&skey->refcount, 1); atomic_add_int(&skey->refcount, 1);
SCTPDBG(SCTP_DEBUG_AUTH2, SCTPDBG(SCTP_DEBUG_AUTH2,
"%s: stcb %p key %u refcount acquire to %d\n", "%s: stcb %p key %u refcount acquire to %d\n",
__FUNCTION__, (void *)stcb, key_id, skey->refcount); __func__, (void *)stcb, key_id, skey->refcount);
} }
} }
void void
sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id, int so_locked sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id, int so_locked)
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif
)
{ {
sctp_sharedkey_t *skey; sctp_sharedkey_t *skey;
@ -578,20 +572,20 @@ sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id, int so_locked
/* decrement the ref count */ /* decrement the ref count */
if (skey) { if (skey) {
sctp_free_sharedkey(skey);
SCTPDBG(SCTP_DEBUG_AUTH2, SCTPDBG(SCTP_DEBUG_AUTH2,
"%s: stcb %p key %u refcount release to %d\n", "%s: stcb %p key %u refcount release to %d\n",
__FUNCTION__, (void *)stcb, key_id, skey->refcount); __func__, (void *)stcb, key_id, skey->refcount);
/* see if a notification should be generated */ /* see if a notification should be generated */
if ((skey->refcount <= 1) && (skey->deactivated)) { if ((skey->refcount <= 2) && (skey->deactivated)) {
/* notify ULP that key is no longer used */ /* notify ULP that key is no longer used */
sctp_ulp_notify(SCTP_NOTIFY_AUTH_FREE_KEY, stcb, sctp_ulp_notify(SCTP_NOTIFY_AUTH_FREE_KEY, stcb,
key_id, 0, so_locked); key_id, 0, so_locked);
SCTPDBG(SCTP_DEBUG_AUTH2, SCTPDBG(SCTP_DEBUG_AUTH2,
"%s: stcb %p key %u no longer used, %d\n", "%s: stcb %p key %u no longer used, %d\n",
__FUNCTION__, (void *)stcb, key_id, skey->refcount); __func__, (void *)stcb, key_id, skey->refcount);
} }
sctp_free_sharedkey(skey);
} }
} }
@ -624,14 +618,16 @@ sctp_copy_skeylist(const struct sctp_keyhead *src, struct sctp_keyhead *dest)
LIST_FOREACH(skey, src, next) { LIST_FOREACH(skey, src, next) {
new_skey = sctp_copy_sharedkey(skey); new_skey = sctp_copy_sharedkey(skey);
if (new_skey != NULL) { if (new_skey != NULL) {
(void)sctp_insert_sharedkey(dest, new_skey); if (sctp_insert_sharedkey(dest, new_skey)) {
sctp_free_sharedkey(new_skey);
} else {
count++; count++;
} }
} }
}
return (count); return (count);
} }
sctp_hmaclist_t * sctp_hmaclist_t *
sctp_alloc_hmaclist(uint16_t num_hmacs) sctp_alloc_hmaclist(uint16_t num_hmacs)
{ {
@ -655,7 +651,6 @@ sctp_free_hmaclist(sctp_hmaclist_t *list)
{ {
if (list != NULL) { if (list != NULL) {
SCTP_FREE(list,SCTP_M_AUTH_HL); SCTP_FREE(list,SCTP_M_AUTH_HL);
list = NULL;
} }
} }
@ -772,7 +767,7 @@ sctp_serialize_hmaclist(sctp_hmaclist_t *list, uint8_t *ptr)
for (i = 0; i < list->num_algo; i++) { for (i = 0; i < list->num_algo; i++) {
hmac_id = htons(list->hmac[i]); hmac_id = htons(list->hmac[i]);
bcopy(&hmac_id, ptr, sizeof(hmac_id)); memcpy(ptr, &hmac_id, sizeof(hmac_id));
ptr += sizeof(hmac_id); ptr += sizeof(hmac_id);
} }
return (list->num_algo * sizeof(hmac_id)); return (list->num_algo * sizeof(hmac_id));
@ -803,7 +798,7 @@ sctp_alloc_authinfo(void)
/* out of memory */ /* out of memory */
return (NULL); return (NULL);
} }
bzero(new_authinfo, sizeof(*new_authinfo)); memset(new_authinfo, 0, sizeof(*new_authinfo));
return (new_authinfo); return (new_authinfo);
} }
@ -826,7 +821,6 @@ sctp_free_authinfo(sctp_authinfo_t *authinfo)
/* SCTP_FREE(authinfo, SCTP_M_AUTH_??); */ /* SCTP_FREE(authinfo, SCTP_M_AUTH_??); */
} }
uint32_t uint32_t
sctp_get_auth_chunk_len(uint16_t hmac_algo) sctp_get_auth_chunk_len(uint16_t hmac_algo)
{ {
@ -974,10 +968,10 @@ sctp_hmac(uint16_t hmac_algo, uint8_t *key, uint32_t keylen,
key = temp; key = temp;
} }
/* initialize the inner/outer pads with the key and "append" zeroes */ /* initialize the inner/outer pads with the key and "append" zeroes */
bzero(ipad, blocklen); memset(ipad, 0, blocklen);
bzero(opad, blocklen); memset(opad, 0, blocklen);
bcopy(key, ipad, keylen); memcpy(ipad, key, keylen);
bcopy(key, opad, keylen); memcpy(opad, key, keylen);
/* XOR the key with ipad and opad values */ /* XOR the key with ipad and opad values */
for (i = 0; i < blocklen; i++) { for (i = 0; i < blocklen; i++) {
@ -1034,10 +1028,10 @@ sctp_hmac_m(uint16_t hmac_algo, uint8_t *key, uint32_t keylen,
key = temp; key = temp;
} }
/* initialize the inner/outer pads with the key and "append" zeroes */ /* initialize the inner/outer pads with the key and "append" zeroes */
bzero(ipad, blocklen); memset(ipad, 0, blocklen);
bzero(opad, blocklen); memset(opad, 0, blocklen);
bcopy(key, ipad, keylen); memcpy(ipad, key, keylen);
bcopy(key, opad, keylen); memcpy(opad, key, keylen);
/* XOR the key with ipad and opad values */ /* XOR the key with ipad and opad values */
for (i = 0; i < blocklen; i++) { for (i = 0; i < blocklen; i++) {
@ -1079,40 +1073,6 @@ sctp_hmac_m(uint16_t hmac_algo, uint8_t *key, uint32_t keylen,
return (digestlen); return (digestlen);
} }
/*-
* verify the HMAC digest using the desired hash key, text, and HMAC
* algorithm.
* Returns -1 on error, 0 on success.
*/
int
sctp_verify_hmac(uint16_t hmac_algo, uint8_t *key, uint32_t keylen,
uint8_t *text, uint32_t textlen,
uint8_t *digest, uint32_t digestlen)
{
uint32_t len;
uint8_t temp[SCTP_AUTH_DIGEST_LEN_MAX];
/* sanity check the material and length */
if ((key == NULL) || (keylen == 0) ||
(text == NULL) || (textlen == 0) || (digest == NULL)) {
/* can't do HMAC with empty key or text or digest */
return (-1);
}
len = sctp_get_hmac_digest_len(hmac_algo);
if ((len == 0) || (digestlen != len))
return (-1);
/* compute the expected hash */
if (sctp_hmac(hmac_algo, key, keylen, text, textlen, temp) != len)
return (-1);
if (memcmp(digest, temp, digestlen) != 0)
return (-1);
else
return (0);
}
/* /*
* computes the requested HMAC using a key struct (which may be modified if * computes the requested HMAC using a key struct (which may be modified if
* the keylen exceeds the HMAC block len). * the keylen exceeds the HMAC block len).
@ -1145,7 +1105,7 @@ sctp_compute_hmac(uint16_t hmac_algo, sctp_key_t *key, uint8_t *text,
sctp_hmac_final(hmac_algo, &ctx, temp); sctp_hmac_final(hmac_algo, &ctx, temp);
/* save the hashed key as the new key */ /* save the hashed key as the new key */
key->keylen = digestlen; key->keylen = digestlen;
bcopy(temp, key->key, key->keylen); memcpy(key->key, temp, key->keylen);
} }
return (sctp_hmac(hmac_algo, key->key, key->keylen, text, textlen, return (sctp_hmac(hmac_algo, key->key, key->keylen, text, textlen,
digest)); digest));
@ -1179,7 +1139,7 @@ sctp_compute_hmac_m(uint16_t hmac_algo, sctp_key_t *key, struct mbuf *m,
sctp_hmac_final(hmac_algo, &ctx, temp); sctp_hmac_final(hmac_algo, &ctx, temp);
/* save the hashed key as the new key */ /* save the hashed key as the new key */
key->keylen = digestlen; key->keylen = digestlen;
bcopy(temp, key->key, key->keylen); memcpy(key->key, temp, key->keylen);
} }
return (sctp_hmac_m(hmac_algo, key->key, key->keylen, m, m_offset, digest, 0)); return (sctp_hmac_m(hmac_algo, key->key, key->keylen, m, m_offset, digest, 0));
} }
@ -1200,7 +1160,6 @@ sctp_auth_is_supported_hmac(sctp_hmaclist_t *list, uint16_t id)
return (0); return (0);
} }
/*- /*-
* clear any cached key(s) if they match the given key id on an association. * 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. * the cached key(s) will be recomputed and re-cached at next use.
@ -1458,7 +1417,7 @@ sctp_auth_get_cookie_params(struct sctp_tcb *stcb, struct mbuf *m,
if (plen > sizeof(random_store)) if (plen > sizeof(random_store))
break; break;
phdr = sctp_get_next_param(m, offset, phdr = sctp_get_next_param(m, offset,
(struct sctp_paramhdr *)random_store, min(plen, sizeof(random_store))); (struct sctp_paramhdr *)random_store, plen);
if (phdr == NULL) if (phdr == NULL)
return; return;
/* save the random and length for the key */ /* save the random and length for the key */
@ -1471,7 +1430,7 @@ sctp_auth_get_cookie_params(struct sctp_tcb *stcb, struct mbuf *m,
if (plen > sizeof(hmacs_store)) if (plen > sizeof(hmacs_store))
break; break;
phdr = sctp_get_next_param(m, offset, phdr = sctp_get_next_param(m, offset,
(struct sctp_paramhdr *)hmacs_store, min(plen,sizeof(hmacs_store))); (struct sctp_paramhdr *)hmacs_store, plen);
if (phdr == NULL) if (phdr == NULL)
return; return;
/* save the hmacs list and num for the key */ /* save the hmacs list and num for the key */
@ -1493,7 +1452,7 @@ sctp_auth_get_cookie_params(struct sctp_tcb *stcb, struct mbuf *m,
if (plen > sizeof(chunks_store)) if (plen > sizeof(chunks_store))
break; break;
phdr = sctp_get_next_param(m, offset, phdr = sctp_get_next_param(m, offset,
(struct sctp_paramhdr *)chunks_store, min(plen,sizeof(chunks_store))); (struct sctp_paramhdr *)chunks_store, plen);
if (phdr == NULL) if (phdr == NULL)
return; return;
chunks = (struct sctp_auth_chunk_list *)phdr; chunks = (struct sctp_auth_chunk_list *)phdr;
@ -1525,19 +1484,19 @@ sctp_auth_get_cookie_params(struct sctp_tcb *stcb, struct mbuf *m,
/* copy in the RANDOM */ /* copy in the RANDOM */
if (p_random != NULL) { if (p_random != NULL) {
keylen = sizeof(*p_random) + random_len; keylen = sizeof(*p_random) + random_len;
bcopy(p_random, new_key->key, keylen); memcpy(new_key->key, p_random, keylen);
} else { } else {
keylen = 0; keylen = 0;
} }
/* append in the AUTH chunks */ /* append in the AUTH chunks */
if (chunks != NULL) { if (chunks != NULL) {
bcopy(chunks, new_key->key + keylen, memcpy(new_key->key + keylen, chunks,
sizeof(*chunks) + num_chunks); sizeof(*chunks) + num_chunks);
keylen += sizeof(*chunks) + num_chunks; keylen += sizeof(*chunks) + num_chunks;
} }
/* append in the HMACs */ /* append in the HMACs */
if (hmacs != NULL) { if (hmacs != NULL) {
bcopy(hmacs, new_key->key + keylen, memcpy(new_key->key + keylen, hmacs,
sizeof(*hmacs) + hmacs_len); sizeof(*hmacs) + hmacs_len);
} }
} }
@ -1576,7 +1535,7 @@ sctp_fill_hmac_digest_m(struct mbuf *m, uint32_t auth_offset,
/* zero the digest + chunk padding */ /* zero the digest + chunk padding */
digestlen = sctp_get_hmac_digest_len(stcb->asoc.peer_hmac_id); digestlen = sctp_get_hmac_digest_len(stcb->asoc.peer_hmac_id);
bzero(auth->hmac, SCTP_SIZE32(digestlen)); memset(auth->hmac, 0, SCTP_SIZE32(digestlen));
/* is the desired key cached? */ /* is the desired key cached? */
if ((keyid != stcb->asoc.authinfo.assoc_keyid) || if ((keyid != stcb->asoc.authinfo.assoc_keyid) ||
@ -1613,9 +1572,8 @@ sctp_fill_hmac_digest_m(struct mbuf *m, uint32_t auth_offset,
m, auth_offset, auth->hmac); m, auth_offset, auth->hmac);
} }
static void static void
sctp_bzero_m(struct mbuf *m, uint32_t m_offset, uint32_t size) sctp_zero_m(struct mbuf *m, uint32_t m_offset, uint32_t size)
{ {
struct mbuf *m_tmp; struct mbuf *m_tmp;
uint8_t *data; uint8_t *data;
@ -1633,11 +1591,11 @@ sctp_bzero_m(struct mbuf *m, uint32_t m_offset, uint32_t size)
/* now use the rest of the mbuf chain */ /* now use the rest of the mbuf chain */
while ((m_tmp != NULL) && (size > 0)) { while ((m_tmp != NULL) && (size > 0)) {
data = mtod(m_tmp, uint8_t *) + m_offset; data = mtod(m_tmp, uint8_t *) + m_offset;
if (size > (uint32_t) SCTP_BUF_LEN(m_tmp)) { if (size > (uint32_t)(SCTP_BUF_LEN(m_tmp) - m_offset)) {
bzero(data, SCTP_BUF_LEN(m_tmp)); memset(data, 0, SCTP_BUF_LEN(m_tmp) - m_offset);
size -= SCTP_BUF_LEN(m_tmp); size -= SCTP_BUF_LEN(m_tmp) - m_offset;
} else { } else {
bzero(data, size); memset(data, 0, size);
size = 0; size = 0;
} }
/* clear the offset since it's only for the first mbuf */ /* clear the offset since it's only for the first mbuf */
@ -1679,10 +1637,13 @@ sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *auth,
"SCTP AUTH Chunk: shared key %u, HMAC id %u\n", "SCTP AUTH Chunk: shared key %u, HMAC id %u\n",
shared_key_id, hmac_id); shared_key_id, hmac_id);
#if defined(__Userspace__) && defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
return (0);
#endif
/* is the indicated HMAC supported? */ /* is the indicated HMAC supported? */
if (!sctp_auth_is_supported_hmac(stcb->asoc.local_hmacs, hmac_id)) { if (!sctp_auth_is_supported_hmac(stcb->asoc.local_hmacs, hmac_id)) {
struct mbuf *m_err; struct mbuf *op_err;
struct sctp_auth_invalid_hmac *err; struct sctp_error_auth_invalid_hmac *cause;
SCTP_STAT_INCR(sctps_recvivalhmacid); SCTP_STAT_INCR(sctps_recvivalhmacid);
SCTPDBG(SCTP_DEBUG_AUTH1, SCTPDBG(SCTP_DEBUG_AUTH1,
@ -1692,20 +1653,19 @@ sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *auth,
* report this in an Error Chunk: Unsupported HMAC * report this in an Error Chunk: Unsupported HMAC
* Identifier * Identifier
*/ */
m_err = sctp_get_mbuf_for_msg(sizeof(*err), 0, M_NOWAIT, op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_error_auth_invalid_hmac),
1, MT_HEADER); 0, M_NOWAIT, 1, MT_HEADER);
if (m_err != NULL) { if (op_err != NULL) {
/* pre-reserve some space */ /* pre-reserve some space */
SCTP_BUF_RESV_UF(m_err, sizeof(struct sctp_chunkhdr)); SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
/* fill in the error */ /* fill in the error */
err = mtod(m_err, struct sctp_auth_invalid_hmac *); cause = mtod(op_err, struct sctp_error_auth_invalid_hmac *);
bzero(err, sizeof(*err)); cause->cause.code = htons(SCTP_CAUSE_UNSUPPORTED_HMACID);
err->ph.param_type = htons(SCTP_CAUSE_UNSUPPORTED_HMACID); cause->cause.length = htons(sizeof(struct sctp_error_auth_invalid_hmac));
err->ph.param_length = htons(sizeof(*err)); cause->hmac_id = ntohs(hmac_id);
err->hmac_id = ntohs(hmac_id); SCTP_BUF_LEN(op_err) = sizeof(struct sctp_error_auth_invalid_hmac);
SCTP_BUF_LEN(m_err) = sizeof(*err);
/* queue it */ /* queue it */
sctp_queue_op_err(stcb, m_err); sctp_queue_op_err(stcb, op_err);
} }
return (-1); return (-1);
} }
@ -1755,13 +1715,13 @@ sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *auth,
return (-1); return (-1);
} }
/* save a copy of the digest, zero the pseudo header, and validate */ /* save a copy of the digest, zero the pseudo header, and validate */
bcopy(auth->hmac, digest, digestlen); memcpy(digest, auth->hmac, digestlen);
sctp_bzero_m(m, offset + sizeof(*auth), SCTP_SIZE32(digestlen)); sctp_zero_m(m, offset + sizeof(*auth), SCTP_SIZE32(digestlen));
(void)sctp_compute_hmac_m(hmac_id, stcb->asoc.authinfo.recv_key, (void)sctp_compute_hmac_m(hmac_id, stcb->asoc.authinfo.recv_key,
m, offset, computed_digest); m, offset, computed_digest);
/* compare the computed digest with the one in the AUTH chunk */ /* compare the computed digest with the one in the AUTH chunk */
if (memcmp(digest, computed_digest, digestlen) != 0) { if (timingsafe_bcmp(digest, computed_digest, digestlen) != 0) {
SCTP_STAT_INCR(sctps_recvauthfailed); SCTP_STAT_INCR(sctps_recvauthfailed);
SCTPDBG(SCTP_DEBUG_AUTH1, SCTPDBG(SCTP_DEBUG_AUTH1,
"SCTP Auth: HMAC digest check failed\n"); "SCTP Auth: HMAC digest check failed\n");
@ -1775,11 +1735,7 @@ sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *auth,
*/ */
void void
sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication, sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
uint16_t keyid, uint16_t alt_keyid, int so_locked uint16_t keyid, uint16_t alt_keyid, int so_locked)
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif
)
{ {
struct mbuf *m_notify; struct mbuf *m_notify;
struct sctp_authkey_event *auth; struct sctp_authkey_event *auth;
@ -1826,15 +1782,14 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
sctp_m_freem(m_notify); sctp_m_freem(m_notify);
return; return;
} }
control->spec_flags = M_NOTIFICATION;
control->length = SCTP_BUF_LEN(m_notify); control->length = SCTP_BUF_LEN(m_notify);
control->spec_flags = M_NOTIFICATION;
/* not that we need this */ /* not that we need this */
control->tail_mbuf = m_notify; control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb, control, sctp_add_to_readq(stcb->sctp_ep, stcb, control,
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, so_locked); &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, so_locked);
} }
/*- /*-
* validates the AUTHentication related parameters in an INIT/INIT-ACK * validates the AUTHentication related parameters in an INIT/INIT-ACK
* Note: currently only used for INIT as INIT-ACK is handled inline * Note: currently only used for INIT as INIT-ACK is handled inline
@ -1843,7 +1798,7 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
int int
sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit) sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
{ {
struct sctp_paramhdr *phdr, parm_buf; struct sctp_paramhdr *phdr, param_buf;
uint16_t ptype, plen; uint16_t ptype, plen;
int peer_supports_asconf = 0; int peer_supports_asconf = 0;
int peer_supports_auth = 0; int peer_supports_auth = 0;
@ -1852,7 +1807,7 @@ sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
uint8_t saw_asconf_ack = 0; uint8_t saw_asconf_ack = 0;
/* go through each of the params. */ /* go through each of the params. */
phdr = sctp_get_next_param(m, offset, &parm_buf, sizeof(parm_buf)); phdr = sctp_get_next_param(m, offset, &param_buf, sizeof(param_buf));
while (phdr) { while (phdr) {
ptype = ntohs(phdr->param_type); ptype = ntohs(phdr->param_type);
plen = ntohs(phdr->param_length); plen = ntohs(phdr->param_length);
@ -1866,11 +1821,15 @@ sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
if (ptype == SCTP_SUPPORTED_CHUNK_EXT) { if (ptype == SCTP_SUPPORTED_CHUNK_EXT) {
/* A supported extension chunk */ /* A supported extension chunk */
struct sctp_supported_chunk_types_param *pr_supported; struct sctp_supported_chunk_types_param *pr_supported;
uint8_t local_store[SCTP_PARAM_BUFFER_SIZE]; uint8_t local_store[SCTP_SMALL_CHUNK_STORE];
int num_ent, i; int num_ent, i;
if (plen > sizeof(local_store)) {
break;
}
phdr = sctp_get_next_param(m, offset, phdr = sctp_get_next_param(m, offset,
(struct sctp_paramhdr *)&local_store, min(plen,sizeof(local_store))); (struct sctp_paramhdr *)&local_store,
plen);
if (phdr == NULL) { if (phdr == NULL) {
return (-1); return (-1);
} }
@ -1888,7 +1847,6 @@ sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
} }
} }
} else if (ptype == SCTP_RANDOM) { } else if (ptype == SCTP_RANDOM) {
got_random = 1;
/* enforce the random length */ /* enforce the random length */
if (plen != (sizeof(struct sctp_auth_random) + if (plen != (sizeof(struct sctp_auth_random) +
SCTP_AUTH_RANDOM_SIZE_REQUIRED)) { SCTP_AUTH_RANDOM_SIZE_REQUIRED)) {
@ -1896,20 +1854,23 @@ sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
"SCTP: invalid RANDOM len\n"); "SCTP: invalid RANDOM len\n");
return (-1); return (-1);
} }
got_random = 1;
} else if (ptype == SCTP_HMAC_LIST) { } else if (ptype == SCTP_HMAC_LIST) {
uint8_t store[SCTP_PARAM_BUFFER_SIZE];
struct sctp_auth_hmac_algo *hmacs; struct sctp_auth_hmac_algo *hmacs;
uint8_t store[SCTP_PARAM_BUFFER_SIZE];
int num_hmacs; int num_hmacs;
if (plen > sizeof(store)) if (plen > sizeof(store)) {
break; break;
}
phdr = sctp_get_next_param(m, offset, phdr = sctp_get_next_param(m, offset,
(struct sctp_paramhdr *)store, min(plen,sizeof(store))); (struct sctp_paramhdr *)store,
if (phdr == NULL) plen);
if (phdr == NULL) {
return (-1); return (-1);
}
hmacs = (struct sctp_auth_hmac_algo *)phdr; hmacs = (struct sctp_auth_hmac_algo *)phdr;
num_hmacs = (plen - sizeof(*hmacs)) / num_hmacs = (plen - sizeof(*hmacs)) / sizeof(hmacs->hmac_ids[0]);
sizeof(hmacs->hmac_ids[0]);
/* validate the hmac list */ /* validate the hmac list */
if (sctp_verify_hmac_param(hmacs, num_hmacs)) { if (sctp_verify_hmac_param(hmacs, num_hmacs)) {
SCTPDBG(SCTP_DEBUG_AUTH1, SCTPDBG(SCTP_DEBUG_AUTH1,
@ -1918,16 +1879,19 @@ sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
} }
got_hmacs = 1; got_hmacs = 1;
} else if (ptype == SCTP_CHUNK_LIST) { } else if (ptype == SCTP_CHUNK_LIST) {
int i, num_chunks; struct sctp_auth_chunk_list *chunks;
uint8_t chunks_store[SCTP_SMALL_CHUNK_STORE]; uint8_t chunks_store[SCTP_SMALL_CHUNK_STORE];
/* did the peer send a non-empty chunk list? */ int i, num_chunks;
struct sctp_auth_chunk_list *chunks = NULL;
if (plen > sizeof(chunks_store)) {
break;
}
phdr = sctp_get_next_param(m, offset, phdr = sctp_get_next_param(m, offset,
(struct sctp_paramhdr *)chunks_store, (struct sctp_paramhdr *)chunks_store,
min(plen,sizeof(chunks_store))); plen);
if (phdr == NULL) if (phdr == NULL) {
return (-1); return (-1);
}
/*- /*-
* Flip through the list and mark that the * Flip through the list and mark that the
* peer supports asconf/asconf_ack. * peer supports asconf/asconf_ack.
@ -1940,7 +1904,6 @@ sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
saw_asconf = 1; saw_asconf = 1;
if (chunks->chunk_types[i] == SCTP_ASCONF_ACK) if (chunks->chunk_types[i] == SCTP_ASCONF_ACK)
saw_asconf_ack = 1; saw_asconf_ack = 1;
} }
if (num_chunks) if (num_chunks)
got_chklist = 1; got_chklist = 1;
@ -1950,8 +1913,8 @@ sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
if (offset >= limit) { if (offset >= limit) {
break; break;
} }
phdr = sctp_get_next_param(m, offset, &parm_buf, phdr = sctp_get_next_param(m, offset, &param_buf,
sizeof(parm_buf)); sizeof(param_buf));
} }
/* validate authentication required parameters */ /* validate authentication required parameters */
if (got_random && got_hmacs) { if (got_random && got_hmacs) {

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.h 271673 2014-09-16 14:20:33Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.h 365071 2020-09-01 21:19:14Z mjg $");
#endif #endif
#ifndef _NETINET_SCTP_AUTH_H_ #ifndef _NETINET_SCTP_AUTH_H_
@ -97,8 +99,6 @@ typedef struct sctp_authinformation {
uint16_t recv_keyid; /* last recv keyid (cached) */ uint16_t recv_keyid; /* last recv keyid (cached) */
} sctp_authinfo_t; } sctp_authinfo_t;
/* /*
* Macros * Macros
*/ */
@ -147,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, extern void sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t keyid,
int so_locked); int so_locked);
/* hmac list handling */ /* hmac list handling */
extern sctp_hmaclist_t *sctp_alloc_hmaclist(uint16_t num_hmacs); extern sctp_hmaclist_t *sctp_alloc_hmaclist(uint16_t num_hmacs);
extern void sctp_free_hmaclist(sctp_hmaclist_t *list); extern void sctp_free_hmaclist(sctp_hmaclist_t *list);
@ -168,8 +167,6 @@ extern uint32_t sctp_get_auth_chunk_len(uint16_t hmac_algo);
extern uint32_t sctp_get_hmac_digest_len(uint16_t hmac_algo); extern uint32_t sctp_get_hmac_digest_len(uint16_t hmac_algo);
extern uint32_t sctp_hmac(uint16_t hmac_algo, uint8_t *key, uint32_t keylen, extern uint32_t sctp_hmac(uint16_t hmac_algo, uint8_t *key, uint32_t keylen,
uint8_t *text, uint32_t textlen, uint8_t *digest); uint8_t *text, uint32_t textlen, uint8_t *digest);
extern int sctp_verify_hmac(uint16_t hmac_algo, uint8_t *key, uint32_t keylen,
uint8_t *text, uint32_t textlen, uint8_t *digest, uint32_t digestlen);
extern uint32_t sctp_compute_hmac(uint16_t hmac_algo, sctp_key_t *key, extern uint32_t sctp_compute_hmac(uint16_t hmac_algo, sctp_key_t *key,
uint8_t *text, uint32_t textlen, uint8_t *digest); uint8_t *text, uint32_t textlen, uint8_t *digest);
extern int sctp_auth_is_supported_hmac(sctp_hmaclist_t *list, uint16_t id); extern int sctp_auth_is_supported_hmac(sctp_hmaclist_t *list, uint16_t id);

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 276914 2015-01-10 20:49:57Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 366426 2020-10-04 15:37:34Z tuexen $");
#endif #endif
#include <netinet/sctp_os.h> #include <netinet/sctp_os.h>
@ -48,13 +50,11 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 276914 2015-01-10 20:49:57Z
#include <netinet/sctp_asconf.h> #include <netinet/sctp_asconf.h>
#include <netinet/sctp_sysctl.h> #include <netinet/sctp_sysctl.h>
#include <netinet/sctp_indata.h> #include <netinet/sctp_indata.h>
#if defined(__FreeBSD__) && !defined(__Userspace__)
#if defined(__FreeBSD__)
#include <sys/unistd.h> #include <sys/unistd.h>
#endif #endif
/* Declare all of our malloc named types */ /* Declare all of our malloc named types */
#ifndef __Panda__
MALLOC_DEFINE(SCTP_M_MAP, "sctp_map", "sctp asoc map descriptor"); MALLOC_DEFINE(SCTP_M_MAP, "sctp_map", "sctp asoc map descriptor");
MALLOC_DEFINE(SCTP_M_STRMI, "sctp_stri", "sctp stream in array"); MALLOC_DEFINE(SCTP_M_STRMI, "sctp_stri", "sctp stream in array");
MALLOC_DEFINE(SCTP_M_STRMO, "sctp_stro", "sctp stream out array"); MALLOC_DEFINE(SCTP_M_STRMO, "sctp_stro", "sctp stream out array");
@ -75,12 +75,11 @@ MALLOC_DEFINE(SCTP_M_MVRF, "sctp_mvrf", "sctp mvrf pcb list");
MALLOC_DEFINE(SCTP_M_ITER, "sctp_iter", "sctp iterator control"); MALLOC_DEFINE(SCTP_M_ITER, "sctp_iter", "sctp iterator control");
MALLOC_DEFINE(SCTP_M_SOCKOPT, "sctp_socko", "sctp socket option"); MALLOC_DEFINE(SCTP_M_SOCKOPT, "sctp_socko", "sctp socket option");
MALLOC_DEFINE(SCTP_M_MCORE, "sctp_mcore", "sctp mcore queue"); MALLOC_DEFINE(SCTP_M_MCORE, "sctp_mcore", "sctp mcore queue");
#endif
/* Global NON-VNET structure that controls the iterator */ /* Global NON-VNET structure that controls the iterator */
struct iterator_control sctp_it_ctl; struct iterator_control sctp_it_ctl;
#if !(defined(__FreeBSD__) && !defined(__Userspace__))
#if !defined(__FreeBSD__)
static void static void
sctp_cleanup_itqueue(void) sctp_cleanup_itqueue(void)
{ {
@ -108,7 +107,7 @@ void
sctp_wakeup_iterator(void) sctp_wakeup_iterator(void)
{ {
#if defined(SCTP_PROCESS_LEVEL_LOCKS) #if defined(SCTP_PROCESS_LEVEL_LOCKS)
#if defined(__Userspace_os_Windows) #if defined(_WIN32)
WakeAllConditionVariable(&sctp_it_ctl.iterator_wakeup); WakeAllConditionVariable(&sctp_it_ctl.iterator_wakeup);
#else #else
pthread_cond_broadcast(&sctp_it_ctl.iterator_wakeup); pthread_cond_broadcast(&sctp_it_ctl.iterator_wakeup);
@ -125,9 +124,12 @@ static void
#endif #endif
sctp_iterator_thread(void *v SCTP_UNUSED) sctp_iterator_thread(void *v SCTP_UNUSED)
{ {
#if defined(__Userspace__)
sctp_userspace_set_threadname("SCTP iterator");
#endif
SCTP_IPI_ITERATOR_WQ_LOCK(); SCTP_IPI_ITERATOR_WQ_LOCK();
/* In FreeBSD this thread never terminates. */ /* In FreeBSD this thread never terminates. */
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
for (;;) { for (;;) {
#else #else
while ((sctp_it_ctl.iterator_flags & SCTP_ITERATOR_MUST_EXIT) == 0) { while ((sctp_it_ctl.iterator_flags & SCTP_ITERATOR_MUST_EXIT) == 0) {
@ -136,25 +138,25 @@ sctp_iterator_thread(void *v SCTP_UNUSED)
msleep(&sctp_it_ctl.iterator_running, msleep(&sctp_it_ctl.iterator_running,
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
&sctp_it_ctl.ipi_iterator_wq_mtx, &sctp_it_ctl.ipi_iterator_wq_mtx,
#elif defined(__APPLE__) || defined(__Userspace_os_Darwin) #elif defined(__APPLE__)
sctp_it_ctl.ipi_iterator_wq_mtx, sctp_it_ctl.ipi_iterator_wq_mtx,
#endif #endif
0, "waiting_for_work", 0); 0, "waiting_for_work", 0);
#else #else
#if defined(__Userspace_os_Windows) #if defined(_WIN32)
SleepConditionVariableCS(&sctp_it_ctl.iterator_wakeup, &sctp_it_ctl.ipi_iterator_wq_mtx, INFINITE); SleepConditionVariableCS(&sctp_it_ctl.iterator_wakeup, &sctp_it_ctl.ipi_iterator_wq_mtx, INFINITE);
#else #else
pthread_cond_wait(&sctp_it_ctl.iterator_wakeup, &sctp_it_ctl.ipi_iterator_wq_mtx); pthread_cond_wait(&sctp_it_ctl.iterator_wakeup, &sctp_it_ctl.ipi_iterator_wq_mtx);
#endif #endif
#endif #endif
#if !defined(__FreeBSD__) #if !(defined(__FreeBSD__) && !defined(__Userspace__))
if (sctp_it_ctl.iterator_flags & SCTP_ITERATOR_MUST_EXIT) { if (sctp_it_ctl.iterator_flags & SCTP_ITERATOR_MUST_EXIT) {
break; break;
} }
#endif #endif
sctp_iterator_worker(); sctp_iterator_worker();
} }
#if !defined(__FreeBSD__) #if !(defined(__FreeBSD__) && !defined(__Userspace__))
/* Now this thread needs to be terminated */ /* Now this thread needs to be terminated */
sctp_cleanup_itqueue(); sctp_cleanup_itqueue();
sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_EXITED; sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_EXITED;
@ -183,12 +185,14 @@ sctp_startup_iterator(void)
SCTP_ITERATOR_LOCK_INIT(); SCTP_ITERATOR_LOCK_INIT();
SCTP_IPI_ITERATOR_WQ_INIT(); SCTP_IPI_ITERATOR_WQ_INIT();
TAILQ_INIT(&sctp_it_ctl.iteratorhead); TAILQ_INIT(&sctp_it_ctl.iteratorhead);
#if defined(__FreeBSD__) #if defined(__Userspace__)
#if __FreeBSD_version <= 701000 if (sctp_userspace_thread_create(&sctp_it_ctl.thread_proc, &sctp_iterator_thread)) {
kthread_create(sctp_iterator_thread, SCTP_PRINTF("ERROR: Creating sctp_iterator_thread failed.\n");
#else } else {
SCTP_BASE_VAR(iterator_thread_started) = 1;
}
#elif defined(__FreeBSD__)
kproc_create(sctp_iterator_thread, kproc_create(sctp_iterator_thread,
#endif
(void *)NULL, (void *)NULL,
&sctp_it_ctl.thread_proc, &sctp_it_ctl.thread_proc,
RFPROC, RFPROC,
@ -196,14 +200,6 @@ sctp_startup_iterator(void)
SCTP_KTRHEAD_NAME); SCTP_KTRHEAD_NAME);
#elif defined(__APPLE__) #elif defined(__APPLE__)
kernel_thread_start((thread_continue_t)sctp_iterator_thread, NULL, &sctp_it_ctl.thread_proc); kernel_thread_start((thread_continue_t)sctp_iterator_thread, NULL, &sctp_it_ctl.thread_proc);
#elif defined(__Userspace__)
#if defined(__Userspace_os_Windows)
if ((sctp_it_ctl.thread_proc = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&sctp_iterator_thread, NULL, 0, NULL)) == NULL) {
#else
if (pthread_create(&sctp_it_ctl.thread_proc, NULL, &sctp_iterator_thread, NULL)) {
#endif
SCTP_PRINTF("ERROR: Creating sctp_iterator_thread failed.\n");
}
#endif #endif
} }
@ -248,7 +244,6 @@ sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa)
#endif /* __Userspace__ */ #endif /* __Userspace__ */
#endif /* INET6 */ #endif /* INET6 */
#if !defined(__Userspace__) #if !defined(__Userspace__)
static uint32_t static uint32_t
sctp_is_desired_interface_type(struct ifnet *ifn) sctp_is_desired_interface_type(struct ifnet *ifn)
@ -256,7 +251,7 @@ sctp_is_desired_interface_type(struct ifnet *ifn)
int result; int result;
/* check the interface type to see if it's one we care about */ /* check the interface type to see if it's one we care about */
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
switch(ifnet_type(ifn)) { switch(ifnet_type(ifn)) {
#else #else
switch (ifn->if_type) { switch (ifn->if_type) {
@ -282,7 +277,7 @@ sctp_is_desired_interface_type(struct ifnet *ifn)
case IFT_GIF: case IFT_GIF:
case IFT_L2VLAN: case IFT_L2VLAN:
case IFT_STF: case IFT_STF:
#if !defined(__APPLE__) #if !(defined(__APPLE__) && !defined(__Userspace__))
case IFT_IP: case IFT_IP:
case IFT_IPOVERCDLC: case IFT_IPOVERCDLC:
case IFT_IPOVERCLAW: case IFT_IPOVERCLAW:
@ -298,21 +293,29 @@ sctp_is_desired_interface_type(struct ifnet *ifn)
return (result); return (result);
} }
#endif #endif
#if defined(__APPLE__) && !defined(__Userspace__)
#if defined(__APPLE__)
int int
sctp_is_vmware_interface(struct ifnet *ifn) sctp_is_vmware_interface(struct ifnet *ifn)
{ {
return (strncmp(ifnet_name(ifn), "vmnet", 5) == 0); return (strncmp(ifnet_name(ifn), "vmnet", 5) == 0);
} }
#endif #endif
#if defined(__Userspace_os_Windows) #if defined(_WIN32) && defined(__Userspace__)
#ifdef MALLOC
#undef MALLOC
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#endif
#ifdef FREE
#undef FREE
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
#endif
static void static void
sctp_init_ifns_for_vrf(int vrfid) sctp_init_ifns_for_vrf(int vrfid)
{ {
#if defined(INET) || defined(INET6) #if defined(INET) || defined(INET6)
struct ifaddrs *ifa;
struct sctp_ifa *sctp_ifa; struct sctp_ifa *sctp_ifa;
DWORD Err, AdapterAddrsSize; DWORD Err, AdapterAddrsSize;
PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt; PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt;
@ -338,6 +341,7 @@ sctp_init_ifns_for_vrf(int vrfid)
/* Get actual adapter information */ /* Get actual adapter information */
if ((Err = GetAdaptersAddresses(AF_INET, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) { if ((Err = GetAdaptersAddresses(AF_INET, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) {
SCTP_PRINTF("GetAdaptersV4Addresses() failed with error code %d\n", Err); SCTP_PRINTF("GetAdaptersV4Addresses() failed with error code %d\n", Err);
FREE(pAdapterAddrs);
return; return;
} }
/* Enumerate through each returned adapter and save its information */ /* Enumerate through each returned adapter and save its information */
@ -347,20 +351,14 @@ sctp_init_ifns_for_vrf(int vrfid)
if (IN4_ISLINKLOCAL_ADDRESS(&(((struct sockaddr_in *)(pUnicast->Address.lpSockaddr))->sin_addr))) { if (IN4_ISLINKLOCAL_ADDRESS(&(((struct sockaddr_in *)(pUnicast->Address.lpSockaddr))->sin_addr))) {
continue; continue;
} }
ifa = (struct ifaddrs*)malloc(sizeof(struct ifaddrs));
ifa->ifa_name = _strdup(pAdapt->AdapterName);
ifa->ifa_flags = pAdapt->Flags;
ifa->ifa_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in));
memcpy(ifa->ifa_addr, pUnicast->Address.lpSockaddr, sizeof(struct sockaddr_in));
sctp_ifa = sctp_add_addr_to_vrf(0, sctp_ifa = sctp_add_addr_to_vrf(0,
ifa, NULL,
pAdapt->IfIndex, pAdapt->IfIndex,
(pAdapt->IfType == IF_TYPE_IEEE80211)?MIB_IF_TYPE_ETHERNET:pAdapt->IfType, (pAdapt->IfType == IF_TYPE_IEEE80211)?MIB_IF_TYPE_ETHERNET:pAdapt->IfType,
ifa->ifa_name, pAdapt->AdapterName,
(void *)ifa, NULL,
ifa->ifa_addr, pUnicast->Address.lpSockaddr,
ifa->ifa_flags, pAdapt->Flags,
0); 0);
if (sctp_ifa) { if (sctp_ifa) {
sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE; sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
@ -368,8 +366,7 @@ sctp_init_ifns_for_vrf(int vrfid)
} }
} }
} }
if (pAdapterAddrs) FREE(pAdapterAddrs);
GlobalFree(pAdapterAddrs);
#endif #endif
#ifdef INET6 #ifdef INET6
AdapterAddrsSize = 0; AdapterAddrsSize = 0;
@ -389,25 +386,21 @@ sctp_init_ifns_for_vrf(int vrfid)
/* Get actual adapter information */ /* Get actual adapter information */
if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) { if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) {
SCTP_PRINTF("GetAdaptersV6Addresses() failed with error code %d\n", Err); SCTP_PRINTF("GetAdaptersV6Addresses() failed with error code %d\n", Err);
FREE(pAdapterAddrs);
return; return;
} }
/* Enumerate through each returned adapter and save its information */ /* Enumerate through each returned adapter and save its information */
for (pAdapt = pAdapterAddrs; pAdapt; pAdapt = pAdapt->Next) { for (pAdapt = pAdapterAddrs; pAdapt; pAdapt = pAdapt->Next) {
if (pAdapt->IfType == IF_TYPE_IEEE80211 || pAdapt->IfType == IF_TYPE_ETHERNET_CSMACD) { if (pAdapt->IfType == IF_TYPE_IEEE80211 || pAdapt->IfType == IF_TYPE_ETHERNET_CSMACD) {
for (pUnicast = pAdapt->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) { for (pUnicast = pAdapt->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
ifa = (struct ifaddrs*)malloc(sizeof(struct ifaddrs));
ifa->ifa_name = _strdup(pAdapt->AdapterName);
ifa->ifa_flags = pAdapt->Flags;
ifa->ifa_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in6));
memcpy(ifa->ifa_addr, pUnicast->Address.lpSockaddr, sizeof(struct sockaddr_in6));
sctp_ifa = sctp_add_addr_to_vrf(0, sctp_ifa = sctp_add_addr_to_vrf(0,
ifa, NULL,
pAdapt->Ipv6IfIndex, pAdapt->Ipv6IfIndex,
(pAdapt->IfType == IF_TYPE_IEEE80211)?MIB_IF_TYPE_ETHERNET:pAdapt->IfType, (pAdapt->IfType == IF_TYPE_IEEE80211)?MIB_IF_TYPE_ETHERNET:pAdapt->IfType,
ifa->ifa_name, pAdapt->AdapterName,
(void *)ifa, NULL,
ifa->ifa_addr, pUnicast->Address.lpSockaddr,
ifa->ifa_flags, pAdapt->Flags,
0); 0);
if (sctp_ifa) { if (sctp_ifa) {
sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE; sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
@ -415,8 +408,7 @@ sctp_init_ifns_for_vrf(int vrfid)
} }
} }
} }
if (pAdapterAddrs) FREE(pAdapterAddrs);
GlobalFree(pAdapterAddrs);
#endif #endif
} }
#elif defined(__Userspace__) #elif defined(__Userspace__)
@ -425,15 +417,15 @@ sctp_init_ifns_for_vrf(int vrfid)
{ {
#if defined(INET) || defined(INET6) #if defined(INET) || defined(INET6)
int rc; int rc;
struct ifaddrs *ifa = NULL; struct ifaddrs *ifa, *ifas;
struct sctp_ifa *sctp_ifa; struct sctp_ifa *sctp_ifa;
uint32_t ifa_flags; uint32_t ifa_flags;
rc = getifaddrs(&g_interfaces); rc = getifaddrs(&ifas);
if (rc != 0) { if (rc != 0) {
return; return;
} }
for (ifa = g_interfaces; ifa; ifa = ifa->ifa_next) { for (ifa = ifas; ifa; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL) { if (ifa->ifa_addr == NULL) {
continue; continue;
} }
@ -468,11 +460,11 @@ sctp_init_ifns_for_vrf(int vrfid)
#endif #endif
ifa_flags = 0; ifa_flags = 0;
sctp_ifa = sctp_add_addr_to_vrf(vrfid, sctp_ifa = sctp_add_addr_to_vrf(vrfid,
ifa, NULL,
if_nametoindex(ifa->ifa_name), if_nametoindex(ifa->ifa_name),
0, 0,
ifa->ifa_name, ifa->ifa_name,
(void *)ifa, NULL,
ifa->ifa_addr, ifa->ifa_addr,
ifa_flags, ifa_flags,
0); 0);
@ -480,11 +472,11 @@ sctp_init_ifns_for_vrf(int vrfid)
sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE; sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
} }
} }
freeifaddrs(ifas);
#endif #endif
} }
#endif #endif
#if defined(__APPLE__) && !defined(__Userspace__)
#if defined(__APPLE__)
static void static void
sctp_init_ifns_for_vrf(int vrfid) sctp_init_ifns_for_vrf(int vrfid)
{ {
@ -543,13 +535,13 @@ sctp_init_ifns_for_vrf(int vrfid)
} else { } else {
ifa_flags = 0; ifa_flags = 0;
} }
snprintf(name, SCTP_IFNAMSIZ, "%s%d", ifnet_name(ifn), ifnet_unit(ifn)); SCTP_SNPRINTF(name, SCTP_IFNAMSIZ, "%s%d", ifnet_name(ifn), ifnet_unit(ifn));
sctp_ifa = sctp_add_addr_to_vrf(vrfid, sctp_ifa = sctp_add_addr_to_vrf(vrfid,
(void *)ifn, (void *)ifn, /* XXX */
ifnet_index(ifn), ifnet_index(ifn),
ifnet_type(ifn), ifnet_type(ifn),
name, name,
(void *)ifa, (void *)ifa, /* XXX */
ifa->ifa_addr, ifa->ifa_addr,
ifa_flags, ifa_flags,
0); 0);
@ -562,8 +554,7 @@ sctp_init_ifns_for_vrf(int vrfid)
ifnet_list_free(ifnetlist); ifnet_list_free(ifnetlist);
} }
#endif #endif
#if defined(__FreeBSD__) && !defined(__Userspace__)
#if defined(__FreeBSD__)
static void static void
sctp_init_ifns_for_vrf(int vrfid) sctp_init_ifns_for_vrf(int vrfid)
{ {
@ -572,6 +563,7 @@ sctp_init_ifns_for_vrf(int vrfid)
* any IFA that exists as we float through the * any IFA that exists as we float through the
* list of IFA's * list of IFA's
*/ */
struct epoch_tracker et;
struct ifnet *ifn; struct ifnet *ifn;
struct ifaddr *ifa; struct ifaddr *ifa;
struct sctp_ifa *sctp_ifa; struct sctp_ifa *sctp_ifa;
@ -581,17 +573,13 @@ sctp_init_ifns_for_vrf(int vrfid)
#endif #endif
IFNET_RLOCK(); IFNET_RLOCK();
TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_list) { NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_link) {
if (sctp_is_desired_interface_type(ifn) == 0) { if (sctp_is_desired_interface_type(ifn) == 0) {
/* non desired type */ /* non desired type */
continue; continue;
} }
#if (__FreeBSD_version >= 803000 && __FreeBSD_version < 900000) || __FreeBSD_version > 900000 CK_STAILQ_FOREACH(ifa, &ifn->if_addrhead, ifa_link) {
IF_ADDR_RLOCK(ifn);
#else
IF_ADDR_LOCK(ifn);
#endif
TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
if (ifa->ifa_addr == NULL) { if (ifa->ifa_addr == NULL) {
continue; continue;
} }
@ -643,12 +631,8 @@ sctp_init_ifns_for_vrf(int vrfid)
sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE; sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
} }
} }
#if (__FreeBSD_version >= 803000 && __FreeBSD_version < 900000) || __FreeBSD_version > 900000
IF_ADDR_RUNLOCK(ifn);
#else
IF_ADDR_UNLOCK(ifn);
#endif
} }
NET_EPOCH_EXIT(et);
IFNET_RUNLOCK(); IFNET_RUNLOCK();
} }
#endif #endif
@ -676,10 +660,14 @@ sctp_addr_change(struct ifaddr *ifa, int cmd)
return; return;
#else #else
uint32_t ifa_flags = 0; uint32_t ifa_flags = 0;
if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) {
return;
}
/* BSD only has one VRF, if this changes /* BSD only has one VRF, if this changes
* we will need to hook in the right * we will need to hook in the right
* things here to get the id to pass to * things here to get the id to pass to
* the address managment routine. * the address management routine.
*/ */
if (SCTP_BASE_VAR(first_time) == 0) { if (SCTP_BASE_VAR(first_time) == 0) {
/* Special test to see if my ::1 will showup with this */ /* Special test to see if my ::1 will showup with this */
@ -722,16 +710,15 @@ sctp_addr_change(struct ifaddr *ifa, int cmd)
} }
if (cmd == RTM_ADD) { if (cmd == RTM_ADD) {
(void)sctp_add_addr_to_vrf(SCTP_DEFAULT_VRFID, (void *)ifa->ifa_ifp, (void)sctp_add_addr_to_vrf(SCTP_DEFAULT_VRFID, (void *)ifa->ifa_ifp,
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
ifnet_index(ifa->ifa_ifp), ifnet_type(ifa->ifa_ifp), ifnet_name(ifa->ifa_ifp), ifnet_index(ifa->ifa_ifp), ifnet_type(ifa->ifa_ifp), ifnet_name(ifa->ifa_ifp),
#else #else
ifa->ifa_ifp->if_index, ifa->ifa_ifp->if_type, ifa->ifa_ifp->if_xname, ifa->ifa_ifp->if_index, ifa->ifa_ifp->if_type, ifa->ifa_ifp->if_xname,
#endif #endif
(void *)ifa, ifa->ifa_addr, ifa_flags, 1); (void *)ifa, ifa->ifa_addr, ifa_flags, 1);
} else { } else {
sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, ifa->ifa_addr, sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, ifa->ifa_addr,
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
ifnet_index(ifa->ifa_ifp), ifnet_index(ifa->ifa_ifp),
ifnet_name(ifa->ifa_ifp)); ifnet_name(ifa->ifa_ifp));
#else #else
@ -746,26 +733,13 @@ sctp_addr_change(struct ifaddr *ifa, int cmd)
#endif #endif
} }
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
void void
sctp_add_or_del_interfaces(int (*pred)(struct ifnet *), int add) sctp_addr_change_event_handler(void *arg __unused, struct ifaddr *ifa, int cmd) {
{ sctp_addr_change(ifa, cmd);
struct ifnet *ifn;
struct ifaddr *ifa;
IFNET_RLOCK();
TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_list) {
if (!(*pred)(ifn)) {
continue;
}
TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
sctp_addr_change(ifa, add ? RTM_ADD : RTM_DELETE);
}
}
IFNET_RUNLOCK();
} }
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
void void
sctp_add_or_del_interfaces(int (*pred)(struct ifnet *), int add) sctp_add_or_del_interfaces(int (*pred)(struct ifnet *), int add)
{ {
@ -798,148 +772,51 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
int how, int allonebuf, int type) int how, int allonebuf, int type)
{ {
struct mbuf *m = NULL; struct mbuf *m = NULL;
#if defined(__FreeBSD__) || defined(__Userspace__)
#if defined(__Userspace__) #if defined(__Userspace__)
m = m_getm2(NULL, space_needed, how, type, want_header ? M_PKTHDR : 0, allonebuf);
/* #else
* __Userspace__
* Using m_clget, which creates and mbuf and a cluster and
* hooks those together.
* TODO: This does not yet have functionality for jumbo packets.
*
*/
int mbuf_threshold;
if (want_header) {
MGETHDR(m, how, type);
} else {
MGET(m, how, type);
}
if (m == NULL) {
return (NULL);
}
if (allonebuf == 0)
mbuf_threshold = SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count);
else
mbuf_threshold = 1;
if ((int)space_needed > (((mbuf_threshold - 1) * MLEN) + MHLEN)) {
MCLGET(m, how);
if (m == NULL) {
return (NULL);
}
if (SCTP_BUF_IS_EXTENDED(m) == 0) {
sctp_m_freem(m);
return (NULL);
}
}
SCTP_BUF_LEN(m) = 0;
SCTP_BUF_NEXT(m) = SCTP_BUF_NEXT_PKT(m) = NULL;
/* __Userspace__
* Check if anything need to be done to ensure logging works
*/
#ifdef SCTP_MBUF_LOGGING
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
sctp_log_mb(m, SCTP_MBUF_IALLOC);
}
#endif
#elif defined(__FreeBSD__) && __FreeBSD_version > 1100052
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) { if (m == NULL) {
/* bad, no memory */ /* bad, no memory */
return (m); return (m);
} }
#if !defined(__Userspace__)
if (allonebuf) { if (allonebuf) {
if (SCTP_BUF_SIZE(m) < space_needed) { if (SCTP_BUF_SIZE(m) < space_needed) {
m_freem(m); m_freem(m);
return (NULL); return (NULL);
} }
} KASSERT(SCTP_BUF_NEXT(m) == NULL, ("%s: no chain allowed", __func__));
if (SCTP_BUF_NEXT(m)) {
sctp_m_freem(SCTP_BUF_NEXT(m));
SCTP_BUF_NEXT(m) = NULL;
}
#ifdef SCTP_MBUF_LOGGING
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
sctp_log_mb(m, SCTP_MBUF_IALLOC);
} }
#endif #endif
#elif defined(__FreeBSD__) && __FreeBSD_version > 602000
m = m_getm2(NULL, space_needed, how, type, want_header ? M_PKTHDR : 0);
if (m == NULL) {
/* bad, no memory */
return (m);
}
if (allonebuf) {
int siz;
if (SCTP_BUF_IS_EXTENDED(m)) {
siz = SCTP_BUF_EXTEND_SIZE(m);
} else {
if (want_header)
siz = MHLEN;
else
siz = MLEN;
}
if (siz < space_needed) {
m_freem(m);
return (NULL);
}
}
if (SCTP_BUF_NEXT(m)) {
sctp_m_freem(SCTP_BUF_NEXT(m));
SCTP_BUF_NEXT(m) = NULL;
}
#ifdef SCTP_MBUF_LOGGING #ifdef SCTP_MBUF_LOGGING
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) { if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
sctp_log_mb(m, SCTP_MBUF_IALLOC); sctp_log_mb(m, SCTP_MBUF_IALLOC);
} }
#endif #endif
#else #else
#if defined(__FreeBSD__) && __FreeBSD_version >= 601000
int aloc_size;
int index = 0;
#endif
int mbuf_threshold; int mbuf_threshold;
unsigned int size;
if (want_header) { if (want_header) {
MGETHDR(m, how, type); MGETHDR(m, how, type);
size = MHLEN;
} else { } else {
MGET(m, how, type); MGET(m, how, type);
size = MLEN;
} }
if (m == NULL) { if (m == NULL) {
return (NULL); return (NULL);
} }
if (allonebuf == 0) if (allonebuf == 0) {
mbuf_threshold = SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count); mbuf_threshold = SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count);
else
mbuf_threshold = 1;
if (space_needed > (((mbuf_threshold - 1) * MLEN) + MHLEN)) {
#if defined(__FreeBSD__) && __FreeBSD_version >= 601000
try_again:
index = 4;
if (space_needed <= MCLBYTES) {
aloc_size = MCLBYTES;
} else { } else {
aloc_size = MJUMPAGESIZE; mbuf_threshold = 1;
index = 5;
} }
m_cljget(m, how, aloc_size);
if (m == NULL) { if (space_needed > (unsigned int)(((mbuf_threshold - 1) * MLEN) + MHLEN)) {
return (NULL);
}
if (SCTP_BUF_IS_EXTENDED(m) == 0) {
if ((aloc_size != MCLBYTES) &&
(allonebuf == 0)) {
aloc_size -= 10;
goto try_again;
}
sctp_m_freem(m);
return (NULL);
}
#else
MCLGET(m, how); MCLGET(m, how);
if (m == NULL) { if (m == NULL) {
return (NULL); return (NULL);
@ -948,7 +825,11 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
sctp_m_freem(m); sctp_m_freem(m);
return (NULL); return (NULL);
} }
#endif size = SCTP_BUF_EXTEND_SIZE(m);
}
if (allonebuf != 0 && size < space_needed) {
m_freem(m);
return (NULL);
} }
SCTP_BUF_LEN(m) = 0; SCTP_BUF_LEN(m) = 0;
SCTP_BUF_NEXT(m) = SCTP_BUF_NEXT_PKT(m) = NULL; SCTP_BUF_NEXT(m) = SCTP_BUF_NEXT_PKT(m) = NULL;
@ -961,7 +842,6 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
return (m); return (m);
} }
#ifdef SCTP_PACKET_LOGGING #ifdef SCTP_PACKET_LOGGING
void void
sctp_packet_log(struct mbuf *m) sctp_packet_log(struct mbuf *m)
@ -1037,7 +917,6 @@ sctp_packet_log(struct mbuf *m)
SCTP_BASE_VAR(packet_log_end)); SCTP_BASE_VAR(packet_log_end));
SCTP_BASE_VAR(packet_log_end) = 0; SCTP_BASE_VAR(packet_log_end) = 0;
goto no_log; goto no_log;
} }
lenat = (int *)&SCTP_BASE_VAR(packet_log_buffer)[thisbegin]; lenat = (int *)&SCTP_BASE_VAR(packet_log_buffer)[thisbegin];
*lenat = total_len; *lenat = total_len;
@ -1063,7 +942,6 @@ sctp_packet_log(struct mbuf *m)
atomic_subtract_int(&SCTP_BASE_VAR(packet_log_writers), 1); atomic_subtract_int(&SCTP_BASE_VAR(packet_log_writers), 1);
} }
int int
sctp_copy_out_packet_log(uint8_t *target, int length) sctp_copy_out_packet_log(uint8_t *target, int length)
{ {

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.h 237540 2012-06-24 21:25:54Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.h 365071 2020-09-01 21:19:14Z mjg $");
#endif #endif
#ifndef _NETINET_SCTP_BSD_ADDR_H_ #ifndef _NETINET_SCTP_BSD_ADDR_H_
@ -47,7 +49,6 @@ void sctp_wakeup_iterator(void);
void sctp_startup_iterator(void); void sctp_startup_iterator(void);
#ifdef INET6 #ifdef INET6
void sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa); void sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa);
#endif #endif
@ -59,8 +60,10 @@ int sctp_copy_out_packet_log(uint8_t *target, int length);
#endif #endif
#if !defined(__Panda__)
void sctp_addr_change(struct ifaddr *ifa, int cmd); void sctp_addr_change(struct ifaddr *ifa, int cmd);
#if defined(__FreeBSD__) && !defined(__Userspace__)
void sctp_addr_change_event_handler(void *, struct ifaddr *, int);
#endif #endif
void sctp_add_or_del_interfaces(int (*pred)(struct ifnet *), int add); void sctp_add_or_del_interfaces(int (*pred)(struct ifnet *), int add);

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -32,18 +34,19 @@
#if defined(__Userspace__) #if defined(__Userspace__)
#include <sys/types.h> #include <sys/types.h>
#if !defined (__Userspace_os_Windows) #if !defined(_WIN32)
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h> #include <unistd.h>
#include <pthread.h> #include <pthread.h>
#endif #endif
#if defined(__Userspace_os_NaCl) #if defined(__native_client__)
#include <sys/select.h> #include <sys/select.h>
#endif #endif
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#include <user_atomic.h>
#include <netinet/sctp_sysctl.h> #include <netinet/sctp_sysctl.h>
#include <netinet/sctp_pcb.h> #include <netinet/sctp_pcb.h>
#else #else
@ -51,16 +54,26 @@
#include <netinet/sctp_callout.h> #include <netinet/sctp_callout.h>
#include <netinet/sctp_pcb.h> #include <netinet/sctp_pcb.h>
#endif #endif
#include <netinet/sctputil.h>
/* /*
* Callout/Timer routines for OS that doesn't have them * Callout/Timer routines for OS that doesn't have them
*/ */
#if defined(__APPLE__) || defined(__Userspace__) #if defined(__APPLE__) || defined(__Userspace__)
int ticks = 0; static uint32_t ticks = 0;
#else #else
extern int ticks; extern int ticks;
#endif #endif
uint32_t sctp_get_tick_count(void) {
uint32_t ret;
SCTP_TIMERQ_LOCK();
ret = ticks;
SCTP_TIMERQ_UNLOCK();
return ret;
}
/* /*
* SCTP_TIMERQ_LOCK protects: * SCTP_TIMERQ_LOCK protects:
* - SCTP_BASE_INFO(callqueue) * - SCTP_BASE_INFO(callqueue)
@ -71,20 +84,23 @@ static sctp_os_timer_t *sctp_os_timer_next = NULL;
void void
sctp_os_timer_init(sctp_os_timer_t *c) sctp_os_timer_init(sctp_os_timer_t *c)
{ {
bzero(c, sizeof(*c)); memset(c, 0, sizeof(*c));
} }
void int
sctp_os_timer_start(sctp_os_timer_t *c, int to_ticks, void (*ftn) (void *), sctp_os_timer_start(sctp_os_timer_t *c, uint32_t to_ticks, void (*ftn) (void *),
void *arg) void *arg)
{ {
int ret = 0;
/* paranoia */ /* paranoia */
if ((c == NULL) || (ftn == NULL)) if ((c == NULL) || (ftn == NULL))
return; return (ret);
SCTP_TIMERQ_LOCK(); SCTP_TIMERQ_LOCK();
/* check to see if we're rescheduling a timer */ /* check to see if we're rescheduling a timer */
if (c->c_flags & SCTP_CALLOUT_PENDING) { if (c->c_flags & SCTP_CALLOUT_PENDING) {
ret = 1;
if (c == sctp_os_timer_next) { if (c == sctp_os_timer_next) {
sctp_os_timer_next = TAILQ_NEXT(c, tqe); sctp_os_timer_next = TAILQ_NEXT(c, tqe);
} }
@ -101,7 +117,7 @@ sctp_os_timer_start(sctp_os_timer_t *c, int to_ticks, void (*ftn) (void *),
* We could unlock/splx here and lock/spl at the TAILQ_INSERT_TAIL, * We could unlock/splx here and lock/spl at the TAILQ_INSERT_TAIL,
* but there's no point since doing this setup doesn't take much time. * but there's no point since doing this setup doesn't take much time.
*/ */
if (to_ticks <= 0) if (to_ticks == 0)
to_ticks = 1; to_ticks = 1;
c->c_arg = arg; c->c_arg = arg;
@ -110,6 +126,7 @@ sctp_os_timer_start(sctp_os_timer_t *c, int to_ticks, void (*ftn) (void *),
c->c_time = ticks + to_ticks; c->c_time = ticks + to_ticks;
TAILQ_INSERT_TAIL(&SCTP_BASE_INFO(callqueue), c, tqe); TAILQ_INSERT_TAIL(&SCTP_BASE_INFO(callqueue), c, tqe);
SCTP_TIMERQ_UNLOCK(); SCTP_TIMERQ_UNLOCK();
return (ret);
} }
int int
@ -133,8 +150,8 @@ sctp_os_timer_stop(sctp_os_timer_t *c)
return (1); return (1);
} }
static void void
sctp_handle_tick(int delta) sctp_handle_tick(uint32_t elapsed_ticks)
{ {
sctp_os_timer_t *c; sctp_os_timer_t *c;
void (*c_func)(void *); void (*c_func)(void *);
@ -142,10 +159,10 @@ sctp_handle_tick(int delta)
SCTP_TIMERQ_LOCK(); SCTP_TIMERQ_LOCK();
/* update our tick count */ /* update our tick count */
ticks += delta; ticks += elapsed_ticks;
c = TAILQ_FIRST(&SCTP_BASE_INFO(callqueue)); c = TAILQ_FIRST(&SCTP_BASE_INFO(callqueue));
while (c) { while (c) {
if (c->c_time <= ticks) { if (SCTP_UINT32_GE(ticks, c->c_time)) {
sctp_os_timer_next = TAILQ_NEXT(c, tqe); sctp_os_timer_next = TAILQ_NEXT(c, tqe);
TAILQ_REMOVE(&SCTP_BASE_INFO(callqueue), c, tqe); TAILQ_REMOVE(&SCTP_BASE_INFO(callqueue), c, tqe);
c_func = c->c_func; c_func = c->c_func;
@ -163,7 +180,7 @@ sctp_handle_tick(int delta)
SCTP_TIMERQ_UNLOCK(); SCTP_TIMERQ_UNLOCK();
} }
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
void void
sctp_timeout(void *arg SCTP_UNUSED) sctp_timeout(void *arg SCTP_UNUSED)
{ {
@ -178,43 +195,55 @@ sctp_timeout(void *arg SCTP_UNUSED)
void * void *
user_sctp_timer_iterate(void *arg) user_sctp_timer_iterate(void *arg)
{ {
sctp_userspace_set_threadname("SCTP timer");
for (;;) { for (;;) {
#if defined (__Userspace_os_Windows) #if defined(_WIN32)
Sleep(TIMEOUT_INTERVAL); Sleep(TIMEOUT_INTERVAL);
#else #else
struct timeval timeout; struct timespec amount, remaining;
timeout.tv_sec = 0; remaining.tv_sec = 0;
timeout.tv_usec = 1000 * TIMEOUT_INTERVAL; remaining.tv_nsec = TIMEOUT_INTERVAL * 1000 * 1000;
select(0, NULL, NULL, NULL, &timeout); do {
amount = remaining;
} while (nanosleep(&amount, &remaining) == -1);
#endif #endif
if (SCTP_BASE_VAR(timer_thread_should_exit)) { if (atomic_cmpset_int(&SCTP_BASE_VAR(timer_thread_should_exit), 1, 1)) {
break; break;
} }
sctp_handle_tick(MSEC_TO_TICKS(TIMEOUT_INTERVAL)); sctp_handle_tick(sctp_msecs_to_ticks(TIMEOUT_INTERVAL));
} }
return (NULL); return (NULL);
} }
void void
sctp_start_timer(void) sctp_start_timer_thread(void)
{ {
/* /*
* No need to do SCTP_TIMERQ_LOCK_INIT(); * No need to do SCTP_TIMERQ_LOCK_INIT();
* here, it is being done in sctp_pcb_init() * here, it is being done in sctp_pcb_init()
*/ */
#if defined (__Userspace_os_Windows)
if ((SCTP_BASE_VAR(timer_thread) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)user_sctp_timer_iterate, NULL, 0, NULL)) == NULL) {
SCTP_PRINTF("ERROR; Creating ithread failed\n");
}
#else
int rc; int rc;
rc = pthread_create(&SCTP_BASE_VAR(timer_thread), NULL, user_sctp_timer_iterate, NULL); rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(timer_thread), user_sctp_timer_iterate);
if (rc) { if (rc) {
SCTP_PRINTF("ERROR; return code from pthread_create() is %d\n", rc); SCTP_PRINTF("ERROR; return code from sctp_thread_create() is %d\n", rc);
} else {
SCTP_BASE_VAR(timer_thread_started) = 1;
} }
#endif
} }
void
sctp_stop_timer_thread(void)
{
atomic_cmpset_int(&SCTP_BASE_VAR(timer_thread_should_exit), 0, 1);
if (SCTP_BASE_VAR(timer_thread_started)) {
#if defined(_WIN32)
WaitForSingleObject(SCTP_BASE_VAR(timer_thread), INFINITE);
CloseHandle(SCTP_BASE_VAR(timer_thread));
#else
pthread_join(SCTP_BASE_VAR(timer_thread), NULL);
#endif
}
}
#endif #endif

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -28,7 +30,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD$"); __FBSDID("$FreeBSD$");
#endif #endif
@ -51,26 +53,31 @@ __FBSDID("$FreeBSD$");
#define SCTP_TICKS_PER_FASTTIMO 20 /* called about every 20ms */ #define SCTP_TICKS_PER_FASTTIMO 20 /* called about every 20ms */
#if defined(__Userspace__) #if defined(__Userspace__)
#if defined(__Userspace_os_Windows) #if defined(_WIN32)
#define SCTP_TIMERQ_LOCK() EnterCriticalSection(&SCTP_BASE_VAR(timer_mtx)) #define SCTP_TIMERQ_LOCK() EnterCriticalSection(&SCTP_BASE_VAR(timer_mtx))
#define SCTP_TIMERQ_UNLOCK() LeaveCriticalSection(&SCTP_BASE_VAR(timer_mtx)) #define SCTP_TIMERQ_UNLOCK() LeaveCriticalSection(&SCTP_BASE_VAR(timer_mtx))
#define SCTP_TIMERQ_LOCK_INIT() InitializeCriticalSection(&SCTP_BASE_VAR(timer_mtx)) #define SCTP_TIMERQ_LOCK_INIT() InitializeCriticalSection(&SCTP_BASE_VAR(timer_mtx))
#define SCTP_TIMERQ_LOCK_DESTROY() DeleteCriticalSection(&SCTP_BASE_VAR(timer_mtx)) #define SCTP_TIMERQ_LOCK_DESTROY() DeleteCriticalSection(&SCTP_BASE_VAR(timer_mtx))
#else #else
#ifdef INVARIANTS
#define SCTP_TIMERQ_LOCK() KASSERT(pthread_mutex_lock(&SCTP_BASE_VAR(timer_mtx)) == 0, ("%s: timer_mtx already locked", __func__))
#define SCTP_TIMERQ_UNLOCK() KASSERT(pthread_mutex_unlock(&SCTP_BASE_VAR(timer_mtx)) == 0, ("%s: timer_mtx not locked", __func__))
#else
#define SCTP_TIMERQ_LOCK() (void)pthread_mutex_lock(&SCTP_BASE_VAR(timer_mtx)) #define SCTP_TIMERQ_LOCK() (void)pthread_mutex_lock(&SCTP_BASE_VAR(timer_mtx))
#define SCTP_TIMERQ_UNLOCK() (void)pthread_mutex_unlock(&SCTP_BASE_VAR(timer_mtx)) #define SCTP_TIMERQ_UNLOCK() (void)pthread_mutex_unlock(&SCTP_BASE_VAR(timer_mtx))
#define SCTP_TIMERQ_LOCK_INIT() (void)pthread_mutex_init(&SCTP_BASE_VAR(timer_mtx), NULL) #endif
#define SCTP_TIMERQ_LOCK_INIT() (void)pthread_mutex_init(&SCTP_BASE_VAR(timer_mtx), &SCTP_BASE_VAR(mtx_attr))
#define SCTP_TIMERQ_LOCK_DESTROY() (void)pthread_mutex_destroy(&SCTP_BASE_VAR(timer_mtx)) #define SCTP_TIMERQ_LOCK_DESTROY() (void)pthread_mutex_destroy(&SCTP_BASE_VAR(timer_mtx))
#endif #endif
extern int ticks;
#endif #endif
uint32_t sctp_get_tick_count(void);
TAILQ_HEAD(calloutlist, sctp_callout); TAILQ_HEAD(calloutlist, sctp_callout);
struct sctp_callout { struct sctp_callout {
TAILQ_ENTRY(sctp_callout) tqe; TAILQ_ENTRY(sctp_callout) tqe;
int c_time; /* ticks to the event */ uint32_t c_time; /* ticks to the event */
void *c_arg; /* function argument */ void *c_arg; /* function argument */
void (*c_func)(void *); /* function to call */ void (*c_func)(void *); /* function to call */
int c_flags; /* state of this entry */ int c_flags; /* state of this entry */
@ -81,10 +88,18 @@ typedef struct sctp_callout sctp_os_timer_t;
#define SCTP_CALLOUT_PENDING 0x0004 /* callout is waiting for timeout */ #define SCTP_CALLOUT_PENDING 0x0004 /* callout is waiting for timeout */
void sctp_os_timer_init(sctp_os_timer_t *tmr); void sctp_os_timer_init(sctp_os_timer_t *tmr);
void sctp_os_timer_start(sctp_os_timer_t *, int, void (*)(void *), void *); /* Returns 1 if pending timer was rescheduled, 0 otherwise. */
int sctp_os_timer_start(sctp_os_timer_t *, uint32_t, void (*)(void *), void *);
/* Returns 1 if pending timer was stopped, 0 otherwise. */
int sctp_os_timer_stop(sctp_os_timer_t *); int sctp_os_timer_stop(sctp_os_timer_t *);
void sctp_handle_tick(uint32_t);
#define SCTP_OS_TIMER_INIT sctp_os_timer_init #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_START sctp_os_timer_start
#define SCTP_OS_TIMER_STOP sctp_os_timer_stop #define SCTP_OS_TIMER_STOP sctp_os_timer_stop
/* MT FIXME: Is the following correct? */ /* MT FIXME: Is the following correct? */
@ -94,9 +109,10 @@ int sctp_os_timer_stop(sctp_os_timer_t *);
#define SCTP_OS_TIMER_DEACTIVATE(tmr) ((tmr)->c_flags &= ~SCTP_CALLOUT_ACTIVE) #define SCTP_OS_TIMER_DEACTIVATE(tmr) ((tmr)->c_flags &= ~SCTP_CALLOUT_ACTIVE)
#if defined(__Userspace__) #if defined(__Userspace__)
void sctp_start_timer(void); void sctp_start_timer_thread(void);
void sctp_stop_timer_thread(void);
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
void sctp_timeout(void *); void sctp_timeout(void *);
#endif #endif

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_cc_functions.c 279859 2015-03-10 19:49:25Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_cc_functions.c 366517 2020-10-07 15:22:48Z tuexen $");
#endif #endif
#include <netinet/sctp_os.h> #include <netinet/sctp_os.h>
@ -48,8 +50,8 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_cc_functions.c 279859 2015-03-10 19:49
#include <netinet/sctp_timer.h> #include <netinet/sctp_timer.h>
#include <netinet/sctp_auth.h> #include <netinet/sctp_auth.h>
#include <netinet/sctp_asconf.h> #include <netinet/sctp_asconf.h>
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <netinet/sctp_dtrace_declare.h> #include <netinet/sctp_kdtrace.h>
#endif #endif
#define SHIFT_MPTCP_MULTI_N 40 #define SHIFT_MPTCP_MULTI_N 40
@ -99,8 +101,8 @@ sctp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net)
} }
sctp_enforce_cwnd_limit(assoc, net); sctp_enforce_cwnd_limit(assoc, net);
net->ssthresh = assoc->peers_rwnd; net->ssthresh = assoc->peers_rwnd;
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE(sctp, cwnd, net, init, SDT_PROBE5(sctp, cwnd, net, init,
stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net, stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net,
0, net->cwnd); 0, net->cwnd);
#endif #endif
@ -161,7 +163,6 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb,
(uint64_t)net->mtu * (uint64_t)net->mtu *
(uint64_t)net->ssthresh) / (uint64_t)net->ssthresh) /
(uint64_t)t_ssthresh); (uint64_t)t_ssthresh);
} }
if (asoc->sctp_cmt_on_off == SCTP_CMT_RPV2) { if (asoc->sctp_cmt_on_off == SCTP_CMT_RPV2) {
uint32_t srtt; uint32_t srtt;
@ -194,8 +195,8 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb,
} }
net->cwnd = net->ssthresh; net->cwnd = net->ssthresh;
sctp_enforce_cwnd_limit(asoc, net); sctp_enforce_cwnd_limit(asoc, net);
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE(sctp, cwnd, net, fr, SDT_PROBE5(sctp, cwnd, net, fr,
stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net, stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net,
old_cwnd, net->cwnd); old_cwnd, net->cwnd);
#endif #endif
@ -212,7 +213,7 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb,
/* Mark end of the window */ /* Mark end of the window */
asoc->fast_recovery_tsn = asoc->sending_seq - 1; asoc->fast_recovery_tsn = asoc->sending_seq - 1;
} else { } else {
asoc->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1; asoc->fast_recovery_tsn = lchk->rec.data.tsn - 1;
} }
/* /*
@ -225,11 +226,12 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb,
/* Mark end of the window */ /* Mark end of the window */
net->fast_recovery_tsn = asoc->sending_seq - 1; net->fast_recovery_tsn = asoc->sending_seq - 1;
} else { } else {
net->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1; net->fast_recovery_tsn = lchk->rec.data.tsn - 1;
} }
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, sctp_timer_stop(SCTP_TIMER_TYPE_SEND,
stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INDATA+SCTP_LOC_32 ); stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_CC_FUNCTIONS + SCTP_LOC_1);
sctp_timer_start(SCTP_TIMER_TYPE_SEND, sctp_timer_start(SCTP_TIMER_TYPE_SEND,
stcb->sctp_ep, stcb, net); stcb->sctp_ep, stcb, net);
} }
@ -244,12 +246,11 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb,
} }
/* Defines for instantaneous bw decisions */ /* Defines for instantaneous bw decisions */
#define SCTP_INST_LOOSING 1 /* Loosing to other flows */ #define SCTP_INST_LOOSING 1 /* Losing to other flows */
#define SCTP_INST_NEUTRAL 2 /* Neutral, no indication */ #define SCTP_INST_NEUTRAL 2 /* Neutral, no indication */
#define SCTP_INST_GAINING 3 /* Gaining, step down possible */ #define SCTP_INST_GAINING 3 /* Gaining, step down possible */
#if defined(__FreeBSD__) && !defined(__Userspace__)
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
static int static int
cc_bw_same(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw, 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)
@ -259,11 +260,11 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
uint64_t rtt_offset, uint8_t inst_ind) uint64_t rtt_offset, uint8_t inst_ind)
#endif #endif
{ {
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
uint64_t oth, probepoint; uint64_t oth, probepoint;
#endif #endif
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
probepoint = (((uint64_t)net->cwnd) << 32); probepoint = (((uint64_t)net->cwnd) << 32);
#endif #endif
if (net->rtt > net->cc_mod.rtcc.lbw_rtt + rtt_offset) { if (net->rtt > net->cc_mod.rtcc.lbw_rtt + rtt_offset) {
@ -272,10 +273,10 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
* we don't update bw.. so we don't * we don't update bw.. so we don't
* update the rtt either. * update the rtt either.
*/ */
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
/* Probe point 5 */ /* Probe point 5 */
probepoint |= ((5 << 16) | 1); probepoint |= ((5 << 16) | 1);
SDT_PROBE(sctp, cwnd, net, rttvar, SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag, vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw), ((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt), ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -292,13 +293,13 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
((net->cc_mod.rtcc.step_cnt > net->cc_mod.rtcc.steady_step) && ((net->cc_mod.rtcc.step_cnt > net->cc_mod.rtcc.steady_step) &&
((net->cc_mod.rtcc.step_cnt % net->cc_mod.rtcc.steady_step) == 0))) { ((net->cc_mod.rtcc.step_cnt % net->cc_mod.rtcc.steady_step) == 0))) {
/* Try a step down */ /* Try a step down */
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
oth = net->cc_mod.rtcc.vol_reduce; oth = net->cc_mod.rtcc.vol_reduce;
oth <<= 16; oth <<= 16;
oth |= net->cc_mod.rtcc.step_cnt; oth |= net->cc_mod.rtcc.step_cnt;
oth <<= 16; oth <<= 16;
oth |= net->cc_mod.rtcc.last_step_state; oth |= net->cc_mod.rtcc.last_step_state;
SDT_PROBE(sctp, cwnd, net, rttstep, SDT_PROBE5(sctp, cwnd, net, rttstep,
vtag, vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw), ((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt), ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -321,10 +322,10 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
* we update both the bw and the rtt here to * we update both the bw and the rtt here to
* lock this in as a good step down. * lock this in as a good step down.
*/ */
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
/* Probe point 6 */ /* Probe point 6 */
probepoint |= ((6 << 16) | 0); probepoint |= ((6 << 16) | 0);
SDT_PROBE(sctp, cwnd, net, rttvar, SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag, vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw), ((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt), ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -332,13 +333,13 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
probepoint); probepoint);
#endif #endif
if (net->cc_mod.rtcc.steady_step) { if (net->cc_mod.rtcc.steady_step) {
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
oth = net->cc_mod.rtcc.vol_reduce; oth = net->cc_mod.rtcc.vol_reduce;
oth <<= 16; oth <<= 16;
oth |= net->cc_mod.rtcc.step_cnt; oth |= net->cc_mod.rtcc.step_cnt;
oth <<= 16; oth <<= 16;
oth |= net->cc_mod.rtcc.last_step_state; oth |= net->cc_mod.rtcc.last_step_state;
SDT_PROBE(sctp, cwnd, net, rttstep, SDT_PROBE5(sctp, cwnd, net, rttstep,
vtag, vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw), ((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt), ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -367,10 +368,10 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
} }
/* Ok bw and rtt remained the same .. no update to any /* Ok bw and rtt remained the same .. no update to any
*/ */
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
/* Probe point 7 */ /* Probe point 7 */
probepoint |= ((7 << 16) | net->cc_mod.rtcc.ret_from_eq); probepoint |= ((7 << 16) | net->cc_mod.rtcc.ret_from_eq);
SDT_PROBE(sctp, cwnd, net, rttvar, SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag, vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw), ((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt), ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -404,7 +405,7 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
return ((int)net->cc_mod.rtcc.ret_from_eq); return ((int)net->cc_mod.rtcc.ret_from_eq);
} }
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
static int static int
cc_bw_decrease(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw, uint64_t rtt_offset, 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)
@ -414,12 +415,12 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
uint8_t inst_ind) uint8_t inst_ind)
#endif #endif
{ {
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
uint64_t oth, probepoint; uint64_t oth, probepoint;
#endif #endif
/* Bandwidth decreased.*/ /* Bandwidth decreased.*/
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
probepoint = (((uint64_t)net->cwnd) << 32); probepoint = (((uint64_t)net->cwnd) << 32);
#endif #endif
if (net->rtt > net->cc_mod.rtcc.lbw_rtt+rtt_offset) { if (net->rtt > net->cc_mod.rtcc.lbw_rtt+rtt_offset) {
@ -428,10 +429,10 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
if ((net->cwnd > net->cc_mod.rtcc.cwnd_at_bw_set) && if ((net->cwnd > net->cc_mod.rtcc.cwnd_at_bw_set) &&
(inst_ind != SCTP_INST_LOOSING)) { (inst_ind != SCTP_INST_LOOSING)) {
/* We caused it maybe.. back off? */ /* We caused it maybe.. back off? */
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
/* PROBE POINT 1 */ /* PROBE POINT 1 */
probepoint |= ((1 << 16) | 1); probepoint |= ((1 << 16) | 1);
SDT_PROBE(sctp, cwnd, net, rttvar, SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag, vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw), ((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt), ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -445,10 +446,10 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
} }
return (1); return (1);
} }
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
/* Probe point 2 */ /* Probe point 2 */
probepoint |= ((2 << 16) | 0); probepoint |= ((2 << 16) | 0);
SDT_PROBE(sctp, cwnd, net, rttvar, SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag, vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw), ((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt), ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -457,13 +458,13 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
#endif #endif
/* Someone else - fight for more? */ /* Someone else - fight for more? */
if (net->cc_mod.rtcc.steady_step) { if (net->cc_mod.rtcc.steady_step) {
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
oth = net->cc_mod.rtcc.vol_reduce; oth = net->cc_mod.rtcc.vol_reduce;
oth <<= 16; oth <<= 16;
oth |= net->cc_mod.rtcc.step_cnt; oth |= net->cc_mod.rtcc.step_cnt;
oth <<= 16; oth <<= 16;
oth |= net->cc_mod.rtcc.last_step_state; oth |= net->cc_mod.rtcc.last_step_state;
SDT_PROBE(sctp, cwnd, net, rttstep, SDT_PROBE5(sctp, cwnd, net, rttstep,
vtag, vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw), ((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt), ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -485,10 +486,10 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
goto out_decision; goto out_decision;
} else if (net->rtt < net->cc_mod.rtcc.lbw_rtt-rtt_offset) { } else if (net->rtt < net->cc_mod.rtcc.lbw_rtt-rtt_offset) {
/* bw & rtt decreased */ /* bw & rtt decreased */
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
/* Probe point 3 */ /* Probe point 3 */
probepoint |= ((3 << 16) | 0); probepoint |= ((3 << 16) | 0);
SDT_PROBE(sctp, cwnd, net, rttvar, SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag, vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw), ((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt), ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -496,13 +497,13 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
probepoint); probepoint);
#endif #endif
if (net->cc_mod.rtcc.steady_step) { if (net->cc_mod.rtcc.steady_step) {
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
oth = net->cc_mod.rtcc.vol_reduce; oth = net->cc_mod.rtcc.vol_reduce;
oth <<= 16; oth <<= 16;
oth |= net->cc_mod.rtcc.step_cnt; oth |= net->cc_mod.rtcc.step_cnt;
oth <<= 16; oth <<= 16;
oth |= net->cc_mod.rtcc.last_step_state; oth |= net->cc_mod.rtcc.last_step_state;
SDT_PROBE(sctp, cwnd, net, rttstep, SDT_PROBE5(sctp, cwnd, net, rttstep,
vtag, vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw), ((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt), ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -521,10 +522,10 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
goto out_decision; goto out_decision;
} }
/* The bw decreased but rtt stayed the same */ /* The bw decreased but rtt stayed the same */
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
/* Probe point 4 */ /* Probe point 4 */
probepoint |= ((4 << 16) | 0); probepoint |= ((4 << 16) | 0);
SDT_PROBE(sctp, cwnd, net, rttvar, SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag, vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw), ((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt), ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -532,13 +533,13 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
probepoint); probepoint);
#endif #endif
if (net->cc_mod.rtcc.steady_step) { if (net->cc_mod.rtcc.steady_step) {
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
oth = net->cc_mod.rtcc.vol_reduce; oth = net->cc_mod.rtcc.vol_reduce;
oth <<= 16; oth <<= 16;
oth |= net->cc_mod.rtcc.step_cnt; oth |= net->cc_mod.rtcc.step_cnt;
oth <<= 16; oth <<= 16;
oth |= net->cc_mod.rtcc.last_step_state; oth |= net->cc_mod.rtcc.last_step_state;
SDT_PROBE(sctp, cwnd, net, rttstep, SDT_PROBE5(sctp, cwnd, net, rttstep,
vtag, vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw), ((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt), ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -565,7 +566,7 @@ out_decision:
} }
} }
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
static int static int
cc_bw_increase(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw, uint64_t vtag) cc_bw_increase(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw, uint64_t vtag)
#else #else
@ -573,7 +574,7 @@ static int
cc_bw_increase(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nbw) cc_bw_increase(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nbw)
#endif #endif
{ {
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
uint64_t oth, probepoint; uint64_t oth, probepoint;
#endif #endif
@ -583,10 +584,10 @@ cc_bw_increase(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
* update. Note that we pay no attention to * update. Note that we pay no attention to
* the inst_ind since our overall sum is increasing. * the inst_ind since our overall sum is increasing.
*/ */
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
/* PROBE POINT 0 */ /* PROBE POINT 0 */
probepoint = (((uint64_t)net->cwnd) << 32); probepoint = (((uint64_t)net->cwnd) << 32);
SDT_PROBE(sctp, cwnd, net, rttvar, SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag, vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw), ((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt), ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -594,13 +595,13 @@ cc_bw_increase(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
probepoint); probepoint);
#endif #endif
if (net->cc_mod.rtcc.steady_step) { if (net->cc_mod.rtcc.steady_step) {
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
oth = net->cc_mod.rtcc.vol_reduce; oth = net->cc_mod.rtcc.vol_reduce;
oth <<= 16; oth <<= 16;
oth |= net->cc_mod.rtcc.step_cnt; oth |= net->cc_mod.rtcc.step_cnt;
oth <<= 16; oth <<= 16;
oth |= net->cc_mod.rtcc.last_step_state; oth |= net->cc_mod.rtcc.last_step_state;
SDT_PROBE(sctp, cwnd, net, rttstep, SDT_PROBE5(sctp, cwnd, net, rttstep,
vtag, vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw), ((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt), ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -617,14 +618,14 @@ cc_bw_increase(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
return (0); return (0);
} }
/* RTCC Algoritm to limit growth of cwnd, return /* RTCC Algorithm to limit growth of cwnd, return
* true if you want to NOT allow cwnd growth * true if you want to NOT allow cwnd growth
*/ */
static int static int
cc_bw_limit(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw) cc_bw_limit(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw)
{ {
uint64_t bw_offset, rtt_offset; uint64_t bw_offset, rtt_offset;
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
uint64_t probepoint, rtt, vtag; uint64_t probepoint, rtt, vtag;
#endif #endif
uint64_t bytes_for_this_rtt, inst_bw; uint64_t bytes_for_this_rtt, inst_bw;
@ -670,7 +671,7 @@ cc_bw_limit(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw)
* change within 1/32nd * change within 1/32nd
*/ */
bw_shift = SCTP_BASE_SYSCTL(sctp_rttvar_bw); bw_shift = SCTP_BASE_SYSCTL(sctp_rttvar_bw);
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
rtt = stcb->asoc.my_vtag; rtt = stcb->asoc.my_vtag;
vtag = (rtt << 32) | (((uint32_t)(stcb->sctp_ep->sctp_lport)) << 16) | (stcb->rport); vtag = (rtt << 32) | (((uint32_t)(stcb->sctp_ep->sctp_lport)) << 16) | (stcb->rport);
probepoint = (((uint64_t)net->cwnd) << 32); probepoint = (((uint64_t)net->cwnd) << 32);
@ -691,12 +692,12 @@ cc_bw_limit(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw)
inst_ind = SCTP_INST_LOOSING; inst_ind = SCTP_INST_LOOSING;
else else
inst_ind = SCTP_INST_NEUTRAL; inst_ind = SCTP_INST_NEUTRAL;
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
probepoint |= ((0xb << 16) | inst_ind); probepoint |= ((0xb << 16) | inst_ind);
#endif #endif
} else { } else {
inst_ind = net->cc_mod.rtcc.last_inst_ind; inst_ind = net->cc_mod.rtcc.last_inst_ind;
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
inst_bw = bytes_for_this_rtt / (uint64_t)(net->rtt); inst_bw = bytes_for_this_rtt / (uint64_t)(net->rtt);
/* Can't determine do not change */ /* Can't determine do not change */
probepoint |= ((0xc << 16) | inst_ind); probepoint |= ((0xc << 16) | inst_ind);
@ -704,14 +705,14 @@ cc_bw_limit(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw)
} }
} else { } else {
inst_ind = net->cc_mod.rtcc.last_inst_ind; inst_ind = net->cc_mod.rtcc.last_inst_ind;
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
inst_bw = bytes_for_this_rtt; inst_bw = bytes_for_this_rtt;
/* Can't determine do not change */ /* Can't determine do not change */
probepoint |= ((0xd << 16) | inst_ind); probepoint |= ((0xd << 16) | inst_ind);
#endif #endif
} }
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE(sctp, cwnd, net, rttvar, SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag, vtag,
((nbw << 32) | inst_bw), ((nbw << 32) | inst_bw),
((net->cc_mod.rtcc.lbw_rtt << 32) | rtt), ((net->cc_mod.rtcc.lbw_rtt << 32) | rtt),
@ -724,7 +725,7 @@ cc_bw_limit(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw)
} }
bw_offset = net->cc_mod.rtcc.lbw >> bw_shift; bw_offset = net->cc_mod.rtcc.lbw >> bw_shift;
if (nbw > net->cc_mod.rtcc.lbw + bw_offset) { if (nbw > net->cc_mod.rtcc.lbw + bw_offset) {
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
ret = cc_bw_increase(stcb, net, nbw, vtag); ret = cc_bw_increase(stcb, net, nbw, vtag);
#else #else
ret = cc_bw_increase(stcb, net, nbw); ret = cc_bw_increase(stcb, net, nbw);
@ -733,7 +734,7 @@ cc_bw_limit(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw)
} }
rtt_offset = net->cc_mod.rtcc.lbw_rtt >> SCTP_BASE_SYSCTL(sctp_rttvar_rtt); rtt_offset = net->cc_mod.rtcc.lbw_rtt >> SCTP_BASE_SYSCTL(sctp_rttvar_rtt);
if (nbw < net->cc_mod.rtcc.lbw - bw_offset) { if (nbw < net->cc_mod.rtcc.lbw - bw_offset) {
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
ret = cc_bw_decrease(stcb, net, nbw, rtt_offset, vtag, inst_ind); ret = cc_bw_decrease(stcb, net, nbw, rtt_offset, vtag, inst_ind);
#else #else
ret = cc_bw_decrease(stcb, net, nbw, rtt_offset, inst_ind); ret = cc_bw_decrease(stcb, net, nbw, rtt_offset, inst_ind);
@ -744,7 +745,7 @@ cc_bw_limit(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw)
* we are in a situation where * we are in a situation where
* the bw stayed the same. * the bw stayed the same.
*/ */
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
ret = cc_bw_same(stcb, net, nbw, rtt_offset, vtag, inst_ind); ret = cc_bw_same(stcb, net, nbw, rtt_offset, vtag, inst_ind);
#else #else
ret = cc_bw_same(stcb, net, nbw, rtt_offset, inst_ind); ret = cc_bw_same(stcb, net, nbw, rtt_offset, inst_ind);
@ -760,7 +761,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
int accum_moved, int reneged_all SCTP_UNUSED, int will_exit, int use_rtcc) int accum_moved, int reneged_all SCTP_UNUSED, int will_exit, int use_rtcc)
{ {
struct sctp_nets *net; struct sctp_nets *net;
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
int old_cwnd; int old_cwnd;
#endif #endif
uint32_t t_ssthresh, t_cwnd, incr; uint32_t t_ssthresh, t_cwnd, incr;
@ -814,7 +815,6 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
/* update cwnd and Early FR */ /* update cwnd and Early FR */
/******************************/ /******************************/
TAILQ_FOREACH(net, &asoc->nets, sctp_next) { TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
#ifdef JANA_CMT_FAST_RECOVERY #ifdef JANA_CMT_FAST_RECOVERY
/* /*
* CMT fast recovery code. Need to debug. * CMT fast recovery code. Need to debug.
@ -876,7 +876,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
continue; continue;
} }
} else { } else {
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
uint64_t vtag, probepoint; uint64_t vtag, probepoint;
probepoint = (((uint64_t)net->cwnd) << 32); probepoint = (((uint64_t)net->cwnd) << 32);
@ -885,7 +885,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
(((uint32_t)(stcb->sctp_ep->sctp_lport)) << 16) | (((uint32_t)(stcb->sctp_ep->sctp_lport)) << 16) |
(stcb->rport); (stcb->rport);
SDT_PROBE(sctp, cwnd, net, rttvar, SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag, vtag,
nbw, nbw,
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt), ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -912,7 +912,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
if (net->flight_size + net->net_ack >= net->cwnd) { if (net->flight_size + net->net_ack >= net->cwnd) {
uint32_t limit; uint32_t limit;
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
old_cwnd = net->cwnd; old_cwnd = net->cwnd;
#endif #endif
switch (asoc->sctp_cmt_on_off) { switch (asoc->sctp_cmt_on_off) {
@ -984,8 +984,8 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
sctp_log_cwnd(stcb, net, incr, sctp_log_cwnd(stcb, net, incr,
SCTP_CWND_LOG_FROM_SS); SCTP_CWND_LOG_FROM_SS);
} }
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE(sctp, cwnd, net, ack, SDT_PROBE5(sctp, cwnd, net, ack,
stcb->asoc.my_vtag, stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net, net,
@ -1007,7 +1007,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
if ((net->flight_size + net->net_ack >= net->cwnd) && 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; net->partial_bytes_acked -= net->cwnd;
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
old_cwnd = net->cwnd; old_cwnd = net->cwnd;
#endif #endif
switch (asoc->sctp_cmt_on_off) { switch (asoc->sctp_cmt_on_off) {
@ -1048,8 +1048,8 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
} }
net->cwnd += incr; net->cwnd += incr;
sctp_enforce_cwnd_limit(asoc, net); sctp_enforce_cwnd_limit(asoc, net);
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE(sctp, cwnd, net, ack, SDT_PROBE5(sctp, cwnd, net, ack,
stcb->asoc.my_vtag, stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net, net,
@ -1075,7 +1075,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
} }
} }
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
static void static void
sctp_cwnd_update_exit_pf_common(struct sctp_tcb *stcb, struct sctp_nets *net) sctp_cwnd_update_exit_pf_common(struct sctp_tcb *stcb, struct sctp_nets *net)
#else #else
@ -1083,14 +1083,14 @@ static void
sctp_cwnd_update_exit_pf_common(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net) sctp_cwnd_update_exit_pf_common(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net)
#endif #endif
{ {
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
int old_cwnd; int old_cwnd;
old_cwnd = net->cwnd; old_cwnd = net->cwnd;
#endif #endif
net->cwnd = net->mtu; net->cwnd = net->mtu;
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE(sctp, cwnd, net, ack, SDT_PROBE5(sctp, cwnd, net, ack,
stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net, stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net,
old_cwnd, net->cwnd); old_cwnd, net->cwnd);
#endif #endif
@ -1098,7 +1098,6 @@ sctp_cwnd_update_exit_pf_common(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_n
(void *)net, net->cwnd); (void *)net, net->cwnd);
} }
static void static void
sctp_cwnd_update_after_timeout(struct sctp_tcb *stcb, struct sctp_nets *net) sctp_cwnd_update_after_timeout(struct sctp_tcb *stcb, struct sctp_nets *net)
{ {
@ -1162,8 +1161,8 @@ sctp_cwnd_update_after_timeout(struct sctp_tcb *stcb, struct sctp_nets *net)
} }
net->cwnd = net->mtu; net->cwnd = net->mtu;
net->partial_bytes_acked = 0; net->partial_bytes_acked = 0;
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE(sctp, cwnd, net, to, SDT_PROBE5(sctp, cwnd, net, to,
stcb->asoc.my_vtag, stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net, net,
@ -1198,13 +1197,12 @@ sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets *
sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SAT); sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SAT);
} }
} else { } else {
/* Further tuning down required over the drastic orginal cut */ /* Further tuning down required over the drastic original cut */
net->ssthresh -= (net->mtu * num_pkt_lost); net->ssthresh -= (net->mtu * num_pkt_lost);
net->cwnd -= (net->mtu * num_pkt_lost); net->cwnd -= (net->mtu * num_pkt_lost);
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { 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_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SAT);
} }
} }
SCTP_STAT_INCR(sctps_ecnereducedcwnd); SCTP_STAT_INCR(sctps_ecnereducedcwnd);
} else { } else {
@ -1217,8 +1215,8 @@ sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets *
net->RTO <<= 1; net->RTO <<= 1;
} }
net->cwnd = net->ssthresh; net->cwnd = net->ssthresh;
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE(sctp, cwnd, net, ecn, SDT_PROBE5(sctp, cwnd, net, ecn,
stcb->asoc.my_vtag, stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net, net,
@ -1338,8 +1336,8 @@ sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb,
sctp_enforce_cwnd_limit(&stcb->asoc, net); sctp_enforce_cwnd_limit(&stcb->asoc, net);
if (net->cwnd - old_cwnd != 0) { if (net->cwnd - old_cwnd != 0) {
/* log only changes */ /* log only changes */
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE(sctp, cwnd, net, pd, SDT_PROBE5(sctp, cwnd, net, pd,
stcb->asoc.my_vtag, stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net, net,
@ -1363,8 +1361,8 @@ sctp_cwnd_update_after_output(struct sctp_tcb *stcb,
if (burst_limit) { if (burst_limit) {
net->cwnd = (net->flight_size + (burst_limit * net->mtu)); net->cwnd = (net->flight_size + (burst_limit * net->mtu));
sctp_enforce_cwnd_limit(&stcb->asoc, net); sctp_enforce_cwnd_limit(&stcb->asoc, net);
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE(sctp, cwnd, net, bl, SDT_PROBE5(sctp, cwnd, net, bl,
stcb->asoc.my_vtag, stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net, net,
@ -1381,7 +1379,7 @@ sctp_cwnd_update_after_sack(struct sctp_tcb *stcb,
struct sctp_association *asoc, struct sctp_association *asoc,
int accum_moved, int reneged_all, int will_exit) int accum_moved, int reneged_all, int will_exit)
{ {
/* Passing a zero argument in last disables the rtcc algoritm */ /* 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); sctp_cwnd_update_after_sack_common(stcb, asoc, accum_moved, reneged_all, will_exit, 0);
} }
@ -1389,13 +1387,13 @@ static void
sctp_cwnd_update_after_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net, 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 algoritm */ /* 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); sctp_cwnd_update_after_ecn_echo_common(stcb, net, in_window, num_pkt_lost, 0);
} }
/* Here starts the RTCCVAR type CC invented by RRS which /* Here starts the RTCCVAR type CC invented by RRS which
* is a slight mod to RFC2581. We reuse a common routine or * is a slight mod to RFC2581. We reuse a common routine or
* two since these algoritms are so close and need to * two since these algorithms are so close and need to
* remain the same. * remain the same.
*/ */
static void static void
@ -1405,9 +1403,7 @@ sctp_cwnd_update_rtcc_after_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *ne
sctp_cwnd_update_after_ecn_echo_common(stcb, net, in_window, num_pkt_lost, 1); 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,
static
void sctp_cwnd_update_rtcc_tsn_acknowledged(struct sctp_nets *net,
struct sctp_tmit_chunk *tp1) struct sctp_tmit_chunk *tp1)
{ {
net->cc_mod.rtcc.bw_bytes += tp1->send_size; net->cc_mod.rtcc.bw_bytes += tp1->send_size;
@ -1430,19 +1426,19 @@ static void
sctp_cwnd_new_rtcc_transmission_begins(struct sctp_tcb *stcb, sctp_cwnd_new_rtcc_transmission_begins(struct sctp_tcb *stcb,
struct sctp_nets *net) struct sctp_nets *net)
{ {
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
uint64_t vtag, probepoint; uint64_t vtag, probepoint;
#endif #endif
if (net->cc_mod.rtcc.lbw) { if (net->cc_mod.rtcc.lbw) {
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
/* Clear the old bw.. we went to 0 in-flight */ /* Clear the old bw.. we went to 0 in-flight */
vtag = (net->rtt << 32) | (((uint32_t)(stcb->sctp_ep->sctp_lport)) << 16) | vtag = (net->rtt << 32) | (((uint32_t)(stcb->sctp_ep->sctp_lport)) << 16) |
(stcb->rport); (stcb->rport);
probepoint = (((uint64_t)net->cwnd) << 32); probepoint = (((uint64_t)net->cwnd) << 32);
/* Probe point 8 */ /* Probe point 8 */
probepoint |= ((8 << 16) | 0); probepoint |= ((8 << 16) | 0);
SDT_PROBE(sctp, cwnd, net, rttvar, SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag, vtag,
((net->cc_mod.rtcc.lbw << 32) | 0), ((net->cc_mod.rtcc.lbw << 32) | 0),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt), ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -1491,19 +1487,19 @@ static void
sctp_set_rtcc_initial_cc_param(struct sctp_tcb *stcb, sctp_set_rtcc_initial_cc_param(struct sctp_tcb *stcb,
struct sctp_nets *net) struct sctp_nets *net)
{ {
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
uint64_t vtag, probepoint; uint64_t vtag, probepoint;
#endif #endif
sctp_set_initial_cc_param(stcb, net); sctp_set_initial_cc_param(stcb, net);
stcb->asoc.use_precise_time = 1; stcb->asoc.use_precise_time = 1;
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #if defined(__FreeBSD__) && !defined(__Userspace__)
probepoint = (((uint64_t)net->cwnd) << 32); probepoint = (((uint64_t)net->cwnd) << 32);
probepoint |= ((9 << 16) | 0); probepoint |= ((9 << 16) | 0);
vtag = (net->rtt << 32) | vtag = (net->rtt << 32) |
(((uint32_t)(stcb->sctp_ep->sctp_lport)) << 16) | (((uint32_t)(stcb->sctp_ep->sctp_lport)) << 16) |
(stcb->rport); (stcb->rport);
SDT_PROBE(sctp, cwnd, net, rttvar, SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag, vtag,
0, 0,
0, 0,
@ -1524,8 +1520,6 @@ 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.use_dccc_ecn = SCTP_BASE_SYSCTL(sctp_use_dccc_ecn);
net->cc_mod.rtcc.step_cnt = 0; net->cc_mod.rtcc.step_cnt = 0;
net->cc_mod.rtcc.last_step_state = 0; net->cc_mod.rtcc.last_step_state = 0;
} }
static int static int
@ -1533,6 +1527,7 @@ 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; struct sctp_nets *net;
if (setorget == 1) { if (setorget == 1) {
/* a set */ /* a set */
if (cc_opt->option == SCTP_CC_OPT_RTCC_SETMODE) { if (cc_opt->option == SCTP_CC_OPT_RTCC_SETMODE) {
@ -1600,7 +1595,7 @@ sctp_cwnd_update_rtcc_after_sack(struct sctp_tcb *stcb,
struct sctp_association *asoc, struct sctp_association *asoc,
int accum_moved, int reneged_all, int will_exit) int accum_moved, int reneged_all, int will_exit)
{ {
/* Passing a one argument at the last enables the rtcc algoritm */ /* 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); sctp_cwnd_update_after_sack_common(stcb, asoc, accum_moved, reneged_all, will_exit, 1);
} }
@ -1616,13 +1611,13 @@ sctp_rtt_rtcc_calculated(struct sctp_tcb *stcb SCTP_UNUSED,
struct sctp_hs_raise_drop { struct sctp_hs_raise_drop {
int32_t cwnd; int32_t cwnd;
int32_t increase; int8_t increase;
int32_t drop_percent; int8_t drop_percent;
}; };
#define SCTP_HS_TABLE_SIZE 73 #define SCTP_HS_TABLE_SIZE 73
struct sctp_hs_raise_drop sctp_cwnd_adjust[SCTP_HS_TABLE_SIZE] = { static const struct sctp_hs_raise_drop sctp_cwnd_adjust[SCTP_HS_TABLE_SIZE] = {
{38, 1, 50}, /* 0 */ {38, 1, 50}, /* 0 */
{118, 2, 44}, /* 1 */ {118, 2, 44}, /* 1 */
{221, 3, 41}, /* 2 */ {221, 3, 41}, /* 2 */
@ -1722,7 +1717,7 @@ sctp_hs_cwnd_increase(struct sctp_tcb *stcb, struct sctp_nets *net)
} }
} }
net->last_hs_used = indx; net->last_hs_used = indx;
incr = ((sctp_cwnd_adjust[indx].increase) << 10); incr = (((int32_t)sctp_cwnd_adjust[indx].increase) << 10);
net->cwnd += incr; net->cwnd += incr;
} }
sctp_enforce_cwnd_limit(&stcb->asoc, net); sctp_enforce_cwnd_limit(&stcb->asoc, net);
@ -1748,7 +1743,7 @@ sctp_hs_cwnd_decrease(struct sctp_tcb *stcb, struct sctp_nets *net)
} else { } else {
/* drop by the proper amount */ /* drop by the proper amount */
net->ssthresh = net->cwnd - (int)((net->cwnd / 100) * net->ssthresh = net->cwnd - (int)((net->cwnd / 100) *
sctp_cwnd_adjust[net->last_hs_used].drop_percent); (int32_t)sctp_cwnd_adjust[net->last_hs_used].drop_percent);
net->cwnd = net->ssthresh; net->cwnd = net->ssthresh;
/* now where are we */ /* now where are we */
indx = net->last_hs_used; indx = net->last_hs_used;
@ -1805,7 +1800,7 @@ sctp_hs_cwnd_update_after_fr(struct sctp_tcb *stcb,
/* Mark end of the window */ /* Mark end of the window */
asoc->fast_recovery_tsn = asoc->sending_seq - 1; asoc->fast_recovery_tsn = asoc->sending_seq - 1;
} else { } else {
asoc->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1; asoc->fast_recovery_tsn = lchk->rec.data.tsn - 1;
} }
/* /*
@ -1818,11 +1813,12 @@ sctp_hs_cwnd_update_after_fr(struct sctp_tcb *stcb,
/* Mark end of the window */ /* Mark end of the window */
net->fast_recovery_tsn = asoc->sending_seq - 1; net->fast_recovery_tsn = asoc->sending_seq - 1;
} else { } else {
net->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1; net->fast_recovery_tsn = lchk->rec.data.tsn - 1;
} }
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, sctp_timer_stop(SCTP_TIMER_TYPE_SEND,
stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INDATA+SCTP_LOC_32); stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_CC_FUNCTIONS + SCTP_LOC_2);
sctp_timer_start(SCTP_TIMER_TYPE_SEND, sctp_timer_start(SCTP_TIMER_TYPE_SEND,
stcb->sctp_ep, stcb, net); stcb->sctp_ep, stcb, net);
} }
@ -1846,7 +1842,6 @@ sctp_hs_cwnd_update_after_sack(struct sctp_tcb *stcb,
/* update cwnd and Early FR */ /* update cwnd and Early FR */
/******************************/ /******************************/
TAILQ_FOREACH(net, &asoc->nets, sctp_next) { TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
#ifdef JANA_CMT_FAST_RECOVERY #ifdef JANA_CMT_FAST_RECOVERY
/* /*
* CMT fast recovery code. Need to debug. * CMT fast recovery code. Need to debug.
@ -1930,7 +1925,6 @@ sctp_hs_cwnd_update_after_sack(struct sctp_tcb *stcb,
} }
} }
/* /*
* H-TCP congestion control. The algorithm is detailed in: * H-TCP congestion control. The algorithm is detailed in:
* R.N.Shorten, D.J.Leith: * R.N.Shorten, D.J.Leith:
@ -1939,7 +1933,6 @@ sctp_hs_cwnd_update_after_sack(struct sctp_tcb *stcb,
* http://www.hamilton.ie/net/htcp3.pdf * http://www.hamilton.ie/net/htcp3.pdf
*/ */
static int use_rtt_scaling = 1; static int use_rtt_scaling = 1;
static int use_bandwidth_switch = 1; static int use_bandwidth_switch = 1;
@ -1958,7 +1951,7 @@ htcp_cong_time(struct htcp *ca)
static inline uint32_t static inline uint32_t
htcp_ccount(struct htcp *ca) htcp_ccount(struct htcp *ca)
{ {
return (htcp_cong_time(ca)/ca->minRTT); return (ca->minRTT == 0 ? htcp_cong_time(ca) : htcp_cong_time(ca)/ca->minRTT);
} }
static inline void static inline void
@ -1996,7 +1989,7 @@ measure_rtt(struct sctp_nets *net)
if (net->fast_retran_ip == 0 && net->ssthresh < 0xFFFF && htcp_ccount(&net->cc_mod.htcp_ca) > 3) { if (net->fast_retran_ip == 0 && net->ssthresh < 0xFFFF && htcp_ccount(&net->cc_mod.htcp_ca) > 3) {
if (net->cc_mod.htcp_ca.maxRTT < net->cc_mod.htcp_ca.minRTT) if (net->cc_mod.htcp_ca.maxRTT < net->cc_mod.htcp_ca.minRTT)
net->cc_mod.htcp_ca.maxRTT = net->cc_mod.htcp_ca.minRTT; net->cc_mod.htcp_ca.maxRTT = net->cc_mod.htcp_ca.minRTT;
if (net->cc_mod.htcp_ca.maxRTT < srtt && srtt <= net->cc_mod.htcp_ca.maxRTT+MSEC_TO_TICKS(20)) if (net->cc_mod.htcp_ca.maxRTT < srtt && srtt <= net->cc_mod.htcp_ca.maxRTT+sctp_msecs_to_ticks(20))
net->cc_mod.htcp_ca.maxRTT = srtt; net->cc_mod.htcp_ca.maxRTT = srtt;
} }
} }
@ -2056,7 +2049,7 @@ htcp_beta_update(struct htcp *ca, uint32_t minRTT, uint32_t maxRTT)
} }
} }
if (ca->modeswitch && minRTT > (uint32_t)MSEC_TO_TICKS(10) && maxRTT) { if (ca->modeswitch && minRTT > sctp_msecs_to_ticks(10) && maxRTT) {
ca->beta = (minRTT<<7)/maxRTT; ca->beta = (minRTT<<7)/maxRTT;
if (ca->beta < BETA_MIN) if (ca->beta < BETA_MIN)
ca->beta = BETA_MIN; ca->beta = BETA_MIN;
@ -2084,12 +2077,12 @@ htcp_alpha_update(struct htcp *ca)
uint32_t scale = (hz << 3) / (10 * minRTT); uint32_t scale = (hz << 3) / (10 * minRTT);
scale = min(max(scale, 1U << 2), 10U << 3); /* clamping ratio to interval [0.5,10]<<3 */ scale = min(max(scale, 1U << 2), 10U << 3); /* clamping ratio to interval [0.5,10]<<3 */
factor = (factor << 3) / scale; factor = (factor << 3) / scale;
if (!factor) if (factor != 0)
factor = 1; factor = 1;
} }
ca->alpha = 2 * factor * ((1 << 7) - ca->beta); ca->alpha = 2 * factor * ((1 << 7) - ca->beta);
if (!ca->alpha) if (ca->alpha != 0)
ca->alpha = ALPHA_BASE; ca->alpha = ALPHA_BASE;
} }
@ -2146,7 +2139,6 @@ htcp_cong_avoid(struct sctp_tcb *stcb, struct sctp_nets *net)
sctp_log_cwnd(stcb, net, net->net_ack, sctp_log_cwnd(stcb, net, net->net_ack,
SCTP_CWND_LOG_FROM_SS); SCTP_CWND_LOG_FROM_SS);
} }
} }
sctp_enforce_cwnd_limit(&stcb->asoc, net); sctp_enforce_cwnd_limit(&stcb->asoc, net);
} else { } else {
@ -2234,7 +2226,6 @@ sctp_htcp_cwnd_update_after_sack(struct sctp_tcb *stcb,
/* update cwnd and Early FR */ /* update cwnd and Early FR */
/******************************/ /******************************/
TAILQ_FOREACH(net, &asoc->nets, sctp_next) { TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
#ifdef JANA_CMT_FAST_RECOVERY #ifdef JANA_CMT_FAST_RECOVERY
/* /*
* CMT fast recovery code. Need to debug. * CMT fast recovery code. Need to debug.
@ -2331,7 +2322,7 @@ sctp_htcp_cwnd_update_after_fr(struct sctp_tcb *stcb,
/* Mark end of the window */ /* Mark end of the window */
asoc->fast_recovery_tsn = asoc->sending_seq - 1; asoc->fast_recovery_tsn = asoc->sending_seq - 1;
} else { } else {
asoc->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1; asoc->fast_recovery_tsn = lchk->rec.data.tsn - 1;
} }
/* /*
@ -2344,11 +2335,12 @@ sctp_htcp_cwnd_update_after_fr(struct sctp_tcb *stcb,
/* Mark end of the window */ /* Mark end of the window */
net->fast_recovery_tsn = asoc->sending_seq - 1; net->fast_recovery_tsn = asoc->sending_seq - 1;
} else { } else {
net->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1; net->fast_recovery_tsn = lchk->rec.data.tsn - 1;
} }
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, sctp_timer_stop(SCTP_TIMER_TYPE_SEND,
stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INDATA+SCTP_LOC_32); stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_CC_FUNCTIONS + SCTP_LOC_3);
sctp_timer_start(SCTP_TIMER_TYPE_SEND, sctp_timer_start(SCTP_TIMER_TYPE_SEND,
stcb->sctp_ep, stcb, net); stcb->sctp_ep, stcb, net);
} }
@ -2403,9 +2395,9 @@ sctp_htcp_cwnd_update_after_ecn_echo(struct sctp_tcb *stcb,
} }
} }
struct sctp_cc_functions sctp_cc_functions[] = { const struct sctp_cc_functions sctp_cc_functions[] = {
{ {
#if defined(__Windows__) || defined(__Userspace_os_Windows) #if defined(_WIN32) && !defined(__MINGW32__)
sctp_set_initial_cc_param, sctp_set_initial_cc_param,
sctp_cwnd_update_after_sack, sctp_cwnd_update_after_sack,
sctp_cwnd_update_exit_pf_common, sctp_cwnd_update_exit_pf_common,
@ -2426,7 +2418,7 @@ struct sctp_cc_functions sctp_cc_functions[] = {
#endif #endif
}, },
{ {
#if defined(__Windows__) || defined(__Userspace_os_Windows) #if defined(_WIN32) && !defined(__MINGW32__)
sctp_set_initial_cc_param, sctp_set_initial_cc_param,
sctp_hs_cwnd_update_after_sack, sctp_hs_cwnd_update_after_sack,
sctp_cwnd_update_exit_pf_common, sctp_cwnd_update_exit_pf_common,
@ -2447,7 +2439,7 @@ struct sctp_cc_functions sctp_cc_functions[] = {
#endif #endif
}, },
{ {
#if defined(__Windows__) || defined(__Userspace_os_Windows) #if defined(_WIN32) && !defined(__MINGW32__)
sctp_htcp_set_initial_cc_param, sctp_htcp_set_initial_cc_param,
sctp_htcp_cwnd_update_after_sack, sctp_htcp_cwnd_update_after_sack,
sctp_cwnd_update_exit_pf_common, sctp_cwnd_update_exit_pf_common,
@ -2468,7 +2460,7 @@ struct sctp_cc_functions sctp_cc_functions[] = {
#endif #endif
}, },
{ {
#if defined(__Windows__) || defined(__Userspace_os_Windows) #if defined(_WIN32) && !defined(__MINGW32__)
sctp_set_rtcc_initial_cc_param, sctp_set_rtcc_initial_cc_param,
sctp_cwnd_update_rtcc_after_sack, sctp_cwnd_update_rtcc_after_sack,
sctp_cwnd_update_exit_pf_common, sctp_cwnd_update_exit_pf_common,

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,18 +32,18 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_constants.h 271204 2014-09-06 19:12:14Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_constants.h 365071 2020-09-01 21:19:14Z mjg $");
#endif #endif
#ifndef _NETINET_SCTP_CONSTANTS_H_ #ifndef _NETINET_SCTP_CONSTANTS_H_
#define _NETINET_SCTP_CONSTANTS_H_ #define _NETINET_SCTP_CONSTANTS_H_
#if defined(__Userspace_os_Windows) #if defined(_WIN32) && defined(__Userspace__)
extern void getwintimeofday(struct timeval *tv); extern void getwintimeofday(struct timeval *tv);
#endif
#endif
/* IANA assigned port number for SCTP over UDP encapsulation */ /* IANA assigned port number for SCTP over UDP encapsulation */
#define SCTP_OVER_UDP_TUNNELING_PORT 9899 #define SCTP_OVER_UDP_TUNNELING_PORT 9899
@ -71,6 +73,10 @@ extern void getwintimeofday(struct timeval *tv);
*/ */
#define SCTP_LARGEST_INIT_ACCEPTED (65535 - 2048) #define SCTP_LARGEST_INIT_ACCEPTED (65535 - 2048)
/* Largest length of a chunk */
#define SCTP_MAX_CHUNK_LENGTH 0xffff
/* Largest length of an error cause */
#define SCTP_MAX_CAUSE_LENGTH 0xffff
/* Number of addresses where we just skip the counting */ /* Number of addresses where we just skip the counting */
#define SCTP_COUNT_LIMIT 40 #define SCTP_COUNT_LIMIT 40
@ -86,22 +92,16 @@ extern void getwintimeofday(struct timeval *tv);
/* #define SCTP_AUDITING_ENABLED 1 used for debug/auditing */ /* #define SCTP_AUDITING_ENABLED 1 used for debug/auditing */
#define SCTP_AUDIT_SIZE 256 #define SCTP_AUDIT_SIZE 256
#define SCTP_KTRHEAD_NAME "sctp_iterator" #define SCTP_KTRHEAD_NAME "sctp_iterator"
#define SCTP_KTHREAD_PAGES 0 #define SCTP_KTHREAD_PAGES 0
#define SCTP_MCORE_NAME "sctp_core_worker" #define SCTP_MCORE_NAME "sctp_core_worker"
/* If you support Multi-VRF how big to /* If you support Multi-VRF how big to
* make the initial array of VRF's to. * make the initial array of VRF's to.
*/ */
#define SCTP_DEFAULT_VRF_SIZE 4 #define SCTP_DEFAULT_VRF_SIZE 4
/* constants for rto calc */
#define sctp_align_safe_nocopy 0
#define sctp_align_unsafe_makecopy 1
/* JRS - Values defined for the HTCP algorithm */ /* JRS - Values defined for the HTCP algorithm */
#define ALPHA_BASE (1<<7) /* 1.0 with shift << 7 */ #define ALPHA_BASE (1<<7) /* 1.0 with shift << 7 */
#define BETA_MIN (1<<6) /* 0.5 with shift << 7 */ #define BETA_MIN (1<<6) /* 0.5 with shift << 7 */
@ -266,7 +266,6 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_LOCK_UNKNOWN 2 #define SCTP_LOCK_UNKNOWN 2
/* number of associations by default for zone allocation */ /* number of associations by default for zone allocation */
#define SCTP_MAX_NUM_OF_ASOC 40000 #define SCTP_MAX_NUM_OF_ASOC 40000
/* how many addresses per assoc remote and local */ /* how many addresses per assoc remote and local */
@ -276,7 +275,7 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_DEFAULT_MULTIPLE_ASCONFS 0 #define SCTP_DEFAULT_MULTIPLE_ASCONFS 0
/* /*
* Theshold for rwnd updates, we have to read (sb_hiwat >> * Threshold for rwnd updates, we have to read (sb_hiwat >>
* SCTP_RWND_HIWAT_SHIFT) before we will look to see if we need to send a * SCTP_RWND_HIWAT_SHIFT) before we will look to see if we need to send a
* window update sack. When we look, we compare the last rwnd we sent vs the * window update sack. When we look, we compare the last rwnd we sent vs the
* current rwnd. It too must be greater than this value. Using 3 divdes the * current rwnd. It too must be greater than this value. Using 3 divdes the
@ -346,6 +345,7 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_RTT_FROM_NON_DATA 0 #define SCTP_RTT_FROM_NON_DATA 0
#define SCTP_RTT_FROM_DATA 1 #define SCTP_RTT_FROM_DATA 1
#define PR_SCTP_UNORDERED_FLAG 0x0001
/* IP hdr (20/40) + 12+2+2 (enet) + sctp common 12 */ /* IP hdr (20/40) + 12+2+2 (enet) + sctp common 12 */
#define SCTP_FIRST_MBUF_RESV 68 #define SCTP_FIRST_MBUF_RESV 68
@ -387,9 +387,8 @@ extern void getwintimeofday(struct timeval *tv);
/* align to 32-bit sizes */ /* align to 32-bit sizes */
#define SCTP_SIZE32(x) ((((x) + 3) >> 2) << 2) #define SCTP_SIZE32(x) ((((x) + 3) >> 2) << 2)
#define IS_SCTP_CONTROL(a) ((a)->chunk_type != SCTP_DATA) #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) #define IS_SCTP_DATA(a) (((a)->chunk_type == SCTP_DATA) || ((a)->chunk_type == SCTP_IDATA))
/* SCTP parameter types */ /* SCTP parameter types */
/*************0x0000 series*************/ /*************0x0000 series*************/
@ -405,7 +404,7 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_HOSTNAME_ADDRESS 0x000b #define SCTP_HOSTNAME_ADDRESS 0x000b
#define SCTP_SUPPORTED_ADDRTYPE 0x000c #define SCTP_SUPPORTED_ADDRTYPE 0x000c
/* draft-ietf-stewart-tsvwg-strreset-xxx */ /* RFC 6525 */
#define SCTP_STR_RESET_OUT_REQUEST 0x000d #define SCTP_STR_RESET_OUT_REQUEST 0x000d
#define SCTP_STR_RESET_IN_REQUEST 0x000e #define SCTP_STR_RESET_IN_REQUEST 0x000e
#define SCTP_STR_RESET_TSN_REQUEST 0x000f #define SCTP_STR_RESET_TSN_REQUEST 0x000f
@ -421,27 +420,18 @@ extern void getwintimeofday(struct timeval *tv);
/*************0x8000 series*************/ /*************0x8000 series*************/
#define SCTP_ECN_CAPABLE 0x8000 #define SCTP_ECN_CAPABLE 0x8000
/* draft-ietf-tsvwg-auth-xxx */ /* RFC 4895 */
#define SCTP_RANDOM 0x8002 #define SCTP_RANDOM 0x8002
#define SCTP_CHUNK_LIST 0x8003 #define SCTP_CHUNK_LIST 0x8003
#define SCTP_HMAC_LIST 0x8004 #define SCTP_HMAC_LIST 0x8004
/* /* RFC 4820 */
* draft-ietf-tsvwg-addip-sctp-xx param=0x8008 len=0xNNNN Byte | Byte | Byte #define SCTP_PAD 0x8005
* | Byte Byte | Byte ... /* RFC 5061 */
*
* Where each byte is a chunk type extension supported. For example, to support
* all chunks one would have (in hex):
*
* 80 01 00 09 C0 C1 80 81 82 00 00 00
*
* Has the parameter. C0 = PR-SCTP (RFC3758) C1, 80 = ASCONF (addip draft) 81
* = Packet Drop 82 = Stream Reset 83 = Authentication
*/
#define SCTP_SUPPORTED_CHUNK_EXT 0x8008 #define SCTP_SUPPORTED_CHUNK_EXT 0x8008
/*************0xC000 series*************/ /*************0xC000 series*************/
#define SCTP_PRSCTP_SUPPORTED 0xc000 #define SCTP_PRSCTP_SUPPORTED 0xc000
/* draft-ietf-tsvwg-addip-sctp */ /* RFC 5061 */
#define SCTP_ADD_IP_ADDRESS 0xc001 #define SCTP_ADD_IP_ADDRESS 0xc001
#define SCTP_DEL_IP_ADDRESS 0xc002 #define SCTP_DEL_IP_ADDRESS 0xc002
#define SCTP_ERROR_CAUSE_IND 0xc003 #define SCTP_ERROR_CAUSE_IND 0xc003
@ -464,9 +454,8 @@ extern void getwintimeofday(struct timeval *tv);
/* mask to get sticky */ /* mask to get sticky */
#define SCTP_STICKY_OPTIONS_MASK 0x0c #define SCTP_STICKY_OPTIONS_MASK 0x0c
/* /*
* SCTP states for internal state machine XXX (should match "user" values) * SCTP states for internal state machine
*/ */
#define SCTP_STATE_EMPTY 0x0000 #define SCTP_STATE_EMPTY 0x0000
#define SCTP_STATE_INUSE 0x0001 #define SCTP_STATE_INUSE 0x0001
@ -484,10 +473,14 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_STATE_IN_ACCEPT_QUEUE 0x1000 #define SCTP_STATE_IN_ACCEPT_QUEUE 0x1000
#define SCTP_STATE_MASK 0x007f #define SCTP_STATE_MASK 0x007f
#define SCTP_GET_STATE(asoc) ((asoc)->state & SCTP_STATE_MASK) #define SCTP_GET_STATE(_stcb) \
#define SCTP_SET_STATE(asoc, newstate) ((asoc)->state = ((asoc)->state & ~SCTP_STATE_MASK) | newstate) ((_stcb)->asoc.state & SCTP_STATE_MASK)
#define SCTP_CLEAR_SUBSTATE(asoc, substate) ((asoc)->state &= ~substate) #define SCTP_SET_STATE(_stcb, _state) \
#define SCTP_ADD_SUBSTATE(asoc, substate) ((asoc)->state |= substate) sctp_set_state(_stcb, _state)
#define SCTP_CLEAR_SUBSTATE(_stcb, _substate) \
(_stcb)->asoc.state &= ~(_substate)
#define SCTP_ADD_SUBSTATE(_stcb, _substate) \
sctp_add_substate(_stcb, _substate)
/* SCTP reachability state for each address */ /* SCTP reachability state for each address */
#define SCTP_ADDR_REACHABLE 0x001 #define SCTP_ADDR_REACHABLE 0x001
@ -517,7 +510,7 @@ extern void getwintimeofday(struct timeval *tv);
/* Maximum the mapping array will grow to (TSN mapping array) */ /* Maximum the mapping array will grow to (TSN mapping array) */
#define SCTP_MAPPING_ARRAY 512 #define SCTP_MAPPING_ARRAY 512
/* size of the inital malloc on the mapping array */ /* size of the initial malloc on the mapping array */
#define SCTP_INITIAL_MAPPING_ARRAY 16 #define SCTP_INITIAL_MAPPING_ARRAY 16
/* how much we grow the mapping array each call */ /* how much we grow the mapping array each call */
#define SCTP_MAPPING_ARRAY_INCR 32 #define SCTP_MAPPING_ARRAY_INCR 32
@ -553,26 +546,22 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_TIMER_TYPE_ASCONF 10 #define SCTP_TIMER_TYPE_ASCONF 10
#define SCTP_TIMER_TYPE_SHUTDOWNGUARD 11 #define SCTP_TIMER_TYPE_SHUTDOWNGUARD 11
#define SCTP_TIMER_TYPE_AUTOCLOSE 12 #define SCTP_TIMER_TYPE_AUTOCLOSE 12
#define SCTP_TIMER_TYPE_EVENTWAKE 13 #define SCTP_TIMER_TYPE_STRRESET 13
#define SCTP_TIMER_TYPE_STRRESET 14 #define SCTP_TIMER_TYPE_INPKILL 14
#define SCTP_TIMER_TYPE_INPKILL 15 #define SCTP_TIMER_TYPE_ASOCKILL 15
#define SCTP_TIMER_TYPE_ASOCKILL 16 #define SCTP_TIMER_TYPE_ADDR_WQ 16
#define SCTP_TIMER_TYPE_ADDR_WQ 17 #define SCTP_TIMER_TYPE_PRIM_DELETED 17
#define SCTP_TIMER_TYPE_ZERO_COPY 18
#define SCTP_TIMER_TYPE_ZCOPY_SENDQ 19
#define SCTP_TIMER_TYPE_PRIM_DELETED 20
/* add new timers here - and increment LAST */ /* add new timers here - and increment LAST */
#define SCTP_TIMER_TYPE_LAST 21 #define SCTP_TIMER_TYPE_LAST 18
#define SCTP_IS_TIMER_TYPE_VALID(t) (((t) > SCTP_TIMER_TYPE_NONE) && \ #define SCTP_IS_TIMER_TYPE_VALID(t) (((t) > SCTP_TIMER_TYPE_NONE) && \
((t) < SCTP_TIMER_TYPE_LAST)) ((t) < SCTP_TIMER_TYPE_LAST))
#if defined(__APPLE__) && !defined(__Userspace__)
#if defined(__APPLE__)
/* Number of ticks to run the main timer at in msec */ /* Number of ticks to run the main timer at in msec */
#define SCTP_MAIN_TIMER_DEFAULT 10 #define SCTP_MAIN_TIMER_DEFAULT 10
#endif
#endif
/* max number of TSN's dup'd that I will hold */ /* max number of TSN's dup'd that I will hold */
#define SCTP_MAX_DUP_TSNS 20 #define SCTP_MAX_DUP_TSNS 20
@ -591,22 +580,7 @@ extern void getwintimeofday(struct timeval *tv);
* number of clusters as a base. This way high bandwidth environments will * number of clusters as a base. This way high bandwidth environments will
* not get impacted by the lower bandwidth sending a bunch of 1 byte chunks * not get impacted by the lower bandwidth sending a bunch of 1 byte chunks
*/ */
#ifdef __Panda__
#define SCTP_ASOC_MAX_CHUNKS_ON_QUEUE 10240
#else
#define SCTP_ASOC_MAX_CHUNKS_ON_QUEUE 512 #define SCTP_ASOC_MAX_CHUNKS_ON_QUEUE 512
#endif
/* The conversion from time to ticks and vice versa is done by rounding
* upwards. This way we can test in the code the time to be positive and
* know that this corresponds to a positive number of ticks.
*/
#define MSEC_TO_TICKS(x) ((hz == 1000) ? x : ((((x) * hz) + 999) / 1000))
#define TICKS_TO_MSEC(x) ((hz == 1000) ? x : ((((x) * 1000) + (hz - 1)) / hz))
#define SEC_TO_TICKS(x) ((x) * hz)
#define TICKS_TO_SEC(x) (((x) + (hz - 1)) / hz)
/* /*
* Basically the minimum amount of time before I do a early FR. Making this * Basically the minimum amount of time before I do a early FR. Making this
@ -628,10 +602,6 @@ extern void getwintimeofday(struct timeval *tv);
/* 30 seconds + RTO (in ms) */ /* 30 seconds + RTO (in ms) */
#define SCTP_HB_DEFAULT_MSEC 30000 #define SCTP_HB_DEFAULT_MSEC 30000
/* Max time I will wait for Shutdown to complete */
#define SCTP_DEF_MAX_SHUTDOWN_SEC 180
/* /*
* This is how long a secret lives, NOT how long a cookie lives how many * This is how long a secret lives, NOT how long a cookie lives how many
* ticks the current secret will live. * ticks the current secret will live.
@ -642,7 +612,6 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_RTO_LOWER_BOUND (1000) /* 1 sec is ms */ #define SCTP_RTO_LOWER_BOUND (1000) /* 1 sec is ms */
#define SCTP_RTO_INITIAL (3000) /* 3 sec in ms */ #define SCTP_RTO_INITIAL (3000) /* 3 sec in ms */
#define SCTP_INP_KILL_TIMEOUT 20 /* number of ms to retry kill of inpcb */ #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 */ #define SCTP_ASOC_KILL_TIMEOUT 10 /* number of ms to retry kill of inpcb */
@ -653,8 +622,7 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_DEF_PMTU_RAISE_SEC 600 /* 10 min between raise attempts */ #define SCTP_DEF_PMTU_RAISE_SEC 600 /* 10 min between raise attempts */
/* How many streams I request initially by default */
/* How many streams I request initally by default */
#define SCTP_OSTREAM_INITIAL 10 #define SCTP_OSTREAM_INITIAL 10
#define SCTP_ISTREAM_INITIAL 2048 #define SCTP_ISTREAM_INITIAL 2048
@ -736,7 +704,6 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_NUMBER_OF_SECRETS 8 /* or 8 * 4 = 32 octets */ #define SCTP_NUMBER_OF_SECRETS 8 /* or 8 * 4 = 32 octets */
#define SCTP_SECRET_SIZE 32 /* number of octets in a 256 bits */ #define SCTP_SECRET_SIZE 32 /* number of octets in a 256 bits */
/* /*
* SCTP upper layer notifications * SCTP upper layer notifications
*/ */
@ -777,7 +744,11 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_DEFAULT_SPLIT_POINT_MIN 2904 #define SCTP_DEFAULT_SPLIT_POINT_MIN 2904
/* Maximum length of diagnostic information in error causes */ /* Maximum length of diagnostic information in error causes */
#define SCTP_DIAG_INFO_LEN 64 #if defined(__Userspace__)
#define SCTP_DIAG_INFO_LEN 256
#else
#define SCTP_DIAG_INFO_LEN 128
#endif
/* ABORT CODES and other tell-tale location /* ABORT CODES and other tell-tale location
* codes are generated by adding the below * codes are generated by adding the below
@ -795,8 +766,8 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_FROM_SCTP_ASCONF 0x80000000 #define SCTP_FROM_SCTP_ASCONF 0x80000000
#define SCTP_FROM_SCTP_OUTPUT 0x90000000 #define SCTP_FROM_SCTP_OUTPUT 0x90000000
#define SCTP_FROM_SCTP_PEELOFF 0xa0000000 #define SCTP_FROM_SCTP_PEELOFF 0xa0000000
#define SCTP_FROM_SCTP_PANDA 0xb0000000 #define SCTP_FROM_SCTP_SYSCTL 0xb0000000
#define SCTP_FROM_SCTP_SYSCTL 0xc0000000 #define SCTP_FROM_SCTP_CC_FUNCTIONS 0xc0000000
/* Location ID's */ /* Location ID's */
#define SCTP_LOC_1 0x00000001 #define SCTP_LOC_1 0x00000001
@ -832,7 +803,10 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_LOC_31 0x0000001f #define SCTP_LOC_31 0x0000001f
#define SCTP_LOC_32 0x00000020 #define SCTP_LOC_32 0x00000020
#define SCTP_LOC_33 0x00000021 #define SCTP_LOC_33 0x00000021
#define SCTP_LOC_34 0x00000022
#define SCTP_LOC_35 0x00000023
#define SCTP_LOC_36 0x00000024
#define SCTP_LOC_37 0x00000025
/* Free assoc codes */ /* Free assoc codes */
#define SCTP_NORMAL_PROC 0 #define SCTP_NORMAL_PROC 0
@ -852,7 +826,6 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_DONOT_SETSCOPE 0 #define SCTP_DONOT_SETSCOPE 0
#define SCTP_DO_SETSCOPE 1 #define SCTP_DO_SETSCOPE 1
/* This value determines the default for when /* This value determines the default for when
* we try to add more on the send queue., if * we try to add more on the send queue., if
* there is room. This prevents us from cycling * there is room. This prevents us from cycling
@ -879,7 +852,7 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_CHUNKQUEUE_SCALE 10 #define SCTP_CHUNKQUEUE_SCALE 10
#endif #endif
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
/* clock variance is 1 ms */ /* clock variance is 1 ms */
#define SCTP_CLOCK_GRANULARITY 1 #define SCTP_CLOCK_GRANULARITY 1
#else #else
@ -908,12 +881,20 @@ extern void getwintimeofday(struct timeval *tv);
/* modular comparison */ /* modular comparison */
/* See RFC 1982 for details. */ /* See RFC 1982 for details. */
#define SCTP_SSN_GT(a, b) (((a < b) && ((uint16_t)(b - a) > (1U<<15))) || \ #define SCTP_UINT16_GT(a, b) (((a < b) && ((uint16_t)(b - a) > (1U<<15))) || \
((a > b) && ((uint16_t)(a - b) < (1U<<15)))) ((a > b) && ((uint16_t)(a - b) < (1U<<15))))
#define SCTP_SSN_GE(a, b) (SCTP_SSN_GT(a, b) || (a == b)) #define SCTP_UINT16_GE(a, b) (SCTP_UINT16_GT(a, b) || (a == b))
#define SCTP_TSN_GT(a, b) (((a < b) && ((uint32_t)(b - a) > (1U<<31))) || \ #define SCTP_UINT32_GT(a, b) (((a < b) && ((uint32_t)(b - a) > (1U<<31))) || \
((a > b) && ((uint32_t)(a - b) < (1U<<31)))) ((a > b) && ((uint32_t)(a - b) < (1U<<31))))
#define SCTP_TSN_GE(a, b) (SCTP_TSN_GT(a, b) || (a == b)) #define SCTP_UINT32_GE(a, b) (SCTP_UINT32_GT(a, b) || (a == b))
#define SCTP_SSN_GT(a, b) SCTP_UINT16_GT(a, b)
#define SCTP_SSN_GE(a, b) SCTP_UINT16_GE(a, b)
#define SCTP_TSN_GT(a, b) SCTP_UINT32_GT(a, b)
#define SCTP_TSN_GE(a, b) SCTP_UINT32_GE(a, b)
#define SCTP_MID_GT(i, a, b) (((i) == 1) ? SCTP_UINT32_GT(a, b) : SCTP_UINT16_GT((uint16_t)a, (uint16_t)b))
#define SCTP_MID_GE(i, a, b) (((i) == 1) ? SCTP_UINT32_GE(a, b) : SCTP_UINT16_GE((uint16_t)a, (uint16_t)b))
#define SCTP_MID_EQ(i, a, b) (((i) == 1) ? a == b : (uint16_t)a == (uint16_t)b)
/* Mapping array manipulation routines */ /* Mapping array manipulation routines */
#define SCTP_IS_TSN_PRESENT(arry, gap) ((arry[(gap >> 3)] >> (gap & 0x07)) & 0x01) #define SCTP_IS_TSN_PRESENT(arry, gap) ((arry[(gap >> 3)] >> (gap & 0x07)) & 0x01)
@ -927,7 +908,6 @@ extern void getwintimeofday(struct timeval *tv);
} \ } \
} while (0) } while (0)
#define SCTP_RETRAN_DONE -1 #define SCTP_RETRAN_DONE -1
#define SCTP_RETRAN_EXIT -2 #define SCTP_RETRAN_EXIT -2
@ -936,7 +916,7 @@ extern void getwintimeofday(struct timeval *tv);
* element. Each entry will take 2 4 byte ints (and of course the overhead * element. Each entry will take 2 4 byte ints (and of course the overhead
* of the next pointer as well). Using 15 as an example will yield * ((8 * * of the next pointer as well). Using 15 as an example will yield * ((8 *
* 15) + 8) or 128 bytes of overhead for each timewait block that gets * 15) + 8) or 128 bytes of overhead for each timewait block that gets
* initialized. Increasing it to 31 would yeild 256 bytes per block. * initialized. Increasing it to 31 would yield 256 bytes per block.
*/ */
#define SCTP_NUMBER_IN_VTAG_BLOCK 15 #define SCTP_NUMBER_IN_VTAG_BLOCK 15
/* /*
@ -978,15 +958,11 @@ extern void getwintimeofday(struct timeval *tv);
/*- /*-
* defines for socket lock states. * defines for socket lock states.
* Used by __APPLE__ and SCTP_SO_LOCK_TESTING * Used by __APPLE__
*/ */
#define SCTP_SO_LOCKED 1 #define SCTP_SO_LOCKED 1
#define SCTP_SO_NOT_LOCKED 0 #define SCTP_SO_NOT_LOCKED 0
#define SCTP_HOLDS_LOCK 1
#define SCTP_NOT_LOCKED 0
/*- /*-
* For address locks, do we hold the lock? * For address locks, do we hold the lock?
*/ */
@ -1002,17 +978,17 @@ extern void getwintimeofday(struct timeval *tv);
(((uint8_t *)&(a)->s_addr)[1] == 168))) (((uint8_t *)&(a)->s_addr)[1] == 168)))
#define IN4_ISLOOPBACK_ADDRESS(a) \ #define IN4_ISLOOPBACK_ADDRESS(a) \
((((uint8_t *)&(a)->s_addr)[0] == 127) && \ (((uint8_t *)&(a)->s_addr)[0] == 127)
(((uint8_t *)&(a)->s_addr)[1] == 0) && \
(((uint8_t *)&(a)->s_addr)[2] == 0) && \
(((uint8_t *)&(a)->s_addr)[3] == 1))
#define IN4_ISLINKLOCAL_ADDRESS(a) \ #define IN4_ISLINKLOCAL_ADDRESS(a) \
((((uint8_t *)&(a)->s_addr)[0] == 169) && \ ((((uint8_t *)&(a)->s_addr)[0] == 169) && \
(((uint8_t *)&(a)->s_addr)[1] == 254)) (((uint8_t *)&(a)->s_addr)[1] == 254))
/* Maximum size of optval for IPPROTO_SCTP level socket options. */
#define SCTP_SOCKET_OPTION_LIMIT (64 * 1024)
#if defined(__Userspace__) #if defined(__Userspace__)
#if defined(__Userspace_os_Windows) #if defined(_WIN32)
#define SCTP_GETTIME_TIMEVAL(x) getwintimeofday(x) #define SCTP_GETTIME_TIMEVAL(x) getwintimeofday(x)
#define SCTP_GETPTIME_TIMEVAL(x) getwintimeofday(x) /* this doesn't seem to ever be used.. */ #define SCTP_GETPTIME_TIMEVAL(x) getwintimeofday(x) /* this doesn't seem to ever be used.. */
#else #else
@ -1020,7 +996,6 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_GETPTIME_TIMEVAL(x) gettimeofday(x, NULL) #define SCTP_GETPTIME_TIMEVAL(x) gettimeofday(x, NULL)
#endif #endif
#endif #endif
#if defined(_KERNEL) #if defined(_KERNEL)
#define SCTP_GETTIME_TIMEVAL(x) (getmicrouptime(x)) #define SCTP_GETTIME_TIMEVAL(x) (getmicrouptime(x))
#define SCTP_GETPTIME_TIMEVAL(x) (microuptime(x)) #define SCTP_GETPTIME_TIMEVAL(x) (microuptime(x))
@ -1036,7 +1011,7 @@ do { \
} \ } \
} while (0) } while (0)
#if defined(__FreeBSD__) || defined(__Windows__) || defined(__Userspace__) #if defined(__FreeBSD__) || defined(_WIN32) || defined(__Userspace__)
#define sctp_sowwakeup_locked(inp, so) \ #define sctp_sowwakeup_locked(inp, so) \
do { \ do { \
if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { \ if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { \
@ -1067,7 +1042,7 @@ do { \
} \ } \
} while (0) } while (0)
#if defined(__FreeBSD__) || defined(__Windows__) || defined(__Userspace__) #if defined(__FreeBSD__) || defined(_WIN32) || defined(__Userspace__)
#define sctp_sorwakeup_locked(inp, so) \ #define sctp_sorwakeup_locked(inp, so) \
do { \ do { \
if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { \ if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { \

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,20 +32,31 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_crc32.c 235828 2012-05-23 11:26:28Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_crc32.c 362498 2020-06-22 14:36:14Z tuexen $");
#endif
#include "opt_sctp.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/gsb_crc32.h>
#include <sys/mbuf.h>
#include <netinet/sctp.h>
#include <netinet/sctp_crc32.h>
#if defined(SCTP) || defined(SCTP_SUPPORT)
#include <netinet/sctp_os.h>
#include <netinet/sctp_pcb.h>
#endif
#else
#include <netinet/sctp_os.h> #include <netinet/sctp_os.h>
#include <netinet/sctp.h> #include <netinet/sctp.h>
#include <netinet/sctp_crc32.h> #include <netinet/sctp_crc32.h>
#include <netinet/sctp_pcb.h> #include <netinet/sctp_pcb.h>
#endif
#if !(defined(__FreeBSD__) && !defined(__Userspace__))
#if !defined(SCTP_WITH_NO_CSUM)
#if defined(__FreeBSD__) && __FreeBSD_version >= 800000
#else
/** /**
* *
* Routine Description: * Routine Description:
@ -94,7 +107,7 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_crc32.c 235828 2012-05-23 11:26:28Z tu
* File Name = ............................ 8x256_tables.c * File Name = ............................ 8x256_tables.c
*/ */
static uint32_t sctp_crc_tableil8_o32[256] = static const uint32_t sctp_crc_tableil8_o32[256] =
{ {
0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB, 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24, 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
@ -150,7 +163,7 @@ static uint32_t sctp_crc_tableil8_o32[256] =
* File Name = ............................ 8x256_tables.c * File Name = ............................ 8x256_tables.c
*/ */
static uint32_t sctp_crc_tableil8_o40[256] = static const uint32_t sctp_crc_tableil8_o40[256] =
{ {
0x00000000, 0x13A29877, 0x274530EE, 0x34E7A899, 0x4E8A61DC, 0x5D28F9AB, 0x69CF5132, 0x7A6DC945, 0x00000000, 0x13A29877, 0x274530EE, 0x34E7A899, 0x4E8A61DC, 0x5D28F9AB, 0x69CF5132, 0x7A6DC945,
0x9D14C3B8, 0x8EB65BCF, 0xBA51F356, 0xA9F36B21, 0xD39EA264, 0xC03C3A13, 0xF4DB928A, 0xE7790AFD, 0x9D14C3B8, 0x8EB65BCF, 0xBA51F356, 0xA9F36B21, 0xD39EA264, 0xC03C3A13, 0xF4DB928A, 0xE7790AFD,
@ -206,7 +219,7 @@ static uint32_t sctp_crc_tableil8_o40[256] =
* File Name = ............................ 8x256_tables.c * File Name = ............................ 8x256_tables.c
*/ */
static uint32_t sctp_crc_tableil8_o48[256] = static const uint32_t sctp_crc_tableil8_o48[256] =
{ {
0x00000000, 0xA541927E, 0x4F6F520D, 0xEA2EC073, 0x9EDEA41A, 0x3B9F3664, 0xD1B1F617, 0x74F06469, 0x00000000, 0xA541927E, 0x4F6F520D, 0xEA2EC073, 0x9EDEA41A, 0x3B9F3664, 0xD1B1F617, 0x74F06469,
0x38513EC5, 0x9D10ACBB, 0x773E6CC8, 0xD27FFEB6, 0xA68F9ADF, 0x03CE08A1, 0xE9E0C8D2, 0x4CA15AAC, 0x38513EC5, 0x9D10ACBB, 0x773E6CC8, 0xD27FFEB6, 0xA68F9ADF, 0x03CE08A1, 0xE9E0C8D2, 0x4CA15AAC,
@ -262,7 +275,7 @@ static uint32_t sctp_crc_tableil8_o48[256] =
* File Name = ............................ 8x256_tables.c * File Name = ............................ 8x256_tables.c
*/ */
static uint32_t sctp_crc_tableil8_o56[256] = static const uint32_t sctp_crc_tableil8_o56[256] =
{ {
0x00000000, 0xDD45AAB8, 0xBF672381, 0x62228939, 0x7B2231F3, 0xA6679B4B, 0xC4451272, 0x1900B8CA, 0x00000000, 0xDD45AAB8, 0xBF672381, 0x62228939, 0x7B2231F3, 0xA6679B4B, 0xC4451272, 0x1900B8CA,
0xF64463E6, 0x2B01C95E, 0x49234067, 0x9466EADF, 0x8D665215, 0x5023F8AD, 0x32017194, 0xEF44DB2C, 0xF64463E6, 0x2B01C95E, 0x49234067, 0x9466EADF, 0x8D665215, 0x5023F8AD, 0x32017194, 0xEF44DB2C,
@ -318,7 +331,7 @@ static uint32_t sctp_crc_tableil8_o56[256] =
* File Name = ............................ 8x256_tables.c * File Name = ............................ 8x256_tables.c
*/ */
static uint32_t sctp_crc_tableil8_o64[256] = static const uint32_t sctp_crc_tableil8_o64[256] =
{ {
0x00000000, 0x38116FAC, 0x7022DF58, 0x4833B0F4, 0xE045BEB0, 0xD854D11C, 0x906761E8, 0xA8760E44, 0x00000000, 0x38116FAC, 0x7022DF58, 0x4833B0F4, 0xE045BEB0, 0xD854D11C, 0x906761E8, 0xA8760E44,
0xC5670B91, 0xFD76643D, 0xB545D4C9, 0x8D54BB65, 0x2522B521, 0x1D33DA8D, 0x55006A79, 0x6D1105D5, 0xC5670B91, 0xFD76643D, 0xB545D4C9, 0x8D54BB65, 0x2522B521, 0x1D33DA8D, 0x55006A79, 0x6D1105D5,
@ -374,7 +387,7 @@ static uint32_t sctp_crc_tableil8_o64[256] =
* File Name = ............................ 8x256_tables.c * File Name = ............................ 8x256_tables.c
*/ */
uint32_t sctp_crc_tableil8_o72[256] = static const uint32_t sctp_crc_tableil8_o72[256] =
{ {
0x00000000, 0xEF306B19, 0xDB8CA0C3, 0x34BCCBDA, 0xB2F53777, 0x5DC55C6E, 0x697997B4, 0x8649FCAD, 0x00000000, 0xEF306B19, 0xDB8CA0C3, 0x34BCCBDA, 0xB2F53777, 0x5DC55C6E, 0x697997B4, 0x8649FCAD,
0x6006181F, 0x8F367306, 0xBB8AB8DC, 0x54BAD3C5, 0xD2F32F68, 0x3DC34471, 0x097F8FAB, 0xE64FE4B2, 0x6006181F, 0x8F367306, 0xBB8AB8DC, 0x54BAD3C5, 0xD2F32F68, 0x3DC34471, 0x097F8FAB, 0xE64FE4B2,
@ -430,7 +443,7 @@ uint32_t sctp_crc_tableil8_o72[256] =
* File Name = ............................ 8x256_tables.c * File Name = ............................ 8x256_tables.c
*/ */
static uint32_t sctp_crc_tableil8_o80[256] = static const uint32_t sctp_crc_tableil8_o80[256] =
{ {
0x00000000, 0x68032CC8, 0xD0065990, 0xB8057558, 0xA5E0C5D1, 0xCDE3E919, 0x75E69C41, 0x1DE5B089, 0x00000000, 0x68032CC8, 0xD0065990, 0xB8057558, 0xA5E0C5D1, 0xCDE3E919, 0x75E69C41, 0x1DE5B089,
0x4E2DFD53, 0x262ED19B, 0x9E2BA4C3, 0xF628880B, 0xEBCD3882, 0x83CE144A, 0x3BCB6112, 0x53C84DDA, 0x4E2DFD53, 0x262ED19B, 0x9E2BA4C3, 0xF628880B, 0xEBCD3882, 0x83CE144A, 0x3BCB6112, 0x53C84DDA,
@ -486,7 +499,7 @@ static uint32_t sctp_crc_tableil8_o80[256] =
* File Name = ............................ 8x256_tables.c * File Name = ............................ 8x256_tables.c
*/ */
static uint32_t sctp_crc_tableil8_o88[256] = static const uint32_t sctp_crc_tableil8_o88[256] =
{ {
0x00000000, 0x493C7D27, 0x9278FA4E, 0xDB448769, 0x211D826D, 0x6821FF4A, 0xB3657823, 0xFA590504, 0x00000000, 0x493C7D27, 0x9278FA4E, 0xDB448769, 0x211D826D, 0x6821FF4A, 0xB3657823, 0xFA590504,
0x423B04DA, 0x0B0779FD, 0xD043FE94, 0x997F83B3, 0x632686B7, 0x2A1AFB90, 0xF15E7CF9, 0xB86201DE, 0x423B04DA, 0x0B0779FD, 0xD043FE94, 0x997F83B3, 0x632686B7, 0x2A1AFB90, 0xF15E7CF9, 0xB86201DE,
@ -613,7 +626,7 @@ multitable_crc32c(uint32_t crc32c,
return (sctp_crc32c_sb8_64_bit(crc32c, buffer, length, to_even_word)); return (sctp_crc32c_sb8_64_bit(crc32c, buffer, length, to_even_word));
} }
static uint32_t sctp_crc_c[256] = { static const uint32_t sctp_crc_c[256] = {
0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB, 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
@ -696,8 +709,11 @@ singletable_crc32c(uint32_t crc32c,
return (crc32c); return (crc32c);
} }
#if defined(__Userspace__)
uint32_t
#else
static uint32_t static uint32_t
#endif
calculate_crc32c(uint32_t crc32c, calculate_crc32c(uint32_t crc32c,
const unsigned char *buffer, const unsigned char *buffer,
unsigned int length) unsigned int length)
@ -708,24 +724,26 @@ calculate_crc32c(uint32_t crc32c,
return (multitable_crc32c(crc32c, buffer, length)); return (multitable_crc32c(crc32c, buffer, length));
} }
} }
#endif /* FreeBSD < 80000 || other OS */
#endif
#if defined(__Userspace__)
uint32_t
#else
static uint32_t static uint32_t
#endif
sctp_finalize_crc32c(uint32_t crc32c) sctp_finalize_crc32c(uint32_t crc32c)
{ {
uint32_t result; uint32_t result;
#if BYTE_ORDER == BIG_ENDIAN #if BYTE_ORDER == BIG_ENDIAN
uint8_t byte0, byte1, byte2, byte3; uint8_t byte0, byte1, byte2, byte3;
#endif #endif
/* Complement the result */ /* Complement the result */
result = ~crc32c; result = ~crc32c;
#if BYTE_ORDER == BIG_ENDIAN #if BYTE_ORDER == BIG_ENDIAN
/* /*
* For BIG-ENDIAN.. aka Motorola byte order the result is in * For BIG-ENDIAN platforms the result is in little-endian form. So we
* little-endian form. So we must manually swap the bytes. Then we * must swap the bytes to return the result in network byte order.
* can call htonl() which does nothing...
*/ */
byte0 = result & 0x000000ff; byte0 = result & 0x000000ff;
byte1 = (result >> 8) & 0x000000ff; byte1 = (result >> 8) & 0x000000ff;
@ -734,66 +752,61 @@ sctp_finalize_crc32c(uint32_t crc32c)
crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3); crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
#else #else
/* /*
* For INTEL platforms the result comes out in network order. No * For LITTLE ENDIAN platforms the result is in already in network
* htonl is required or the swap above. So we optimize out both the * byte order.
* htonl and the manual swap above.
*/ */
crc32c = result; crc32c = result;
#endif #endif
return (crc32c); return (crc32c);
} }
/*
* Compute the SCTP checksum in network byte order for a given mbuf chain m
* which contains an SCTP packet starting at offset.
* Since this function is also called by ipfw, don't assume that
* it is compiled on a kernel with SCTP support.
*/
uint32_t uint32_t
sctp_calculate_cksum(struct mbuf *m, uint32_t offset) sctp_calculate_cksum(struct mbuf *m, uint32_t offset)
{ {
/*
* given a mbuf chain with a packetheader offset by 'offset'
* pointing at a sctphdr (with csum set to 0) go through the chain
* of SCTP_BUF_NEXT()'s and calculate the SCTP checksum. This also
* has a side bonus as it will calculate the total length of the
* mbuf chain. Note: if offset is greater than the total mbuf
* length, checksum=1, pktlen=0 is returned (ie. no real error code)
*/
uint32_t base = 0xffffffff; uint32_t base = 0xffffffff;
struct mbuf *at;
at = m; while (offset > 0) {
/* find the correct mbuf and offset into mbuf */ KASSERT(m != NULL, ("sctp_calculate_cksum, offset > length of mbuf chain"));
while ((at != NULL) && (offset > (uint32_t) SCTP_BUF_LEN(at))) { if (offset < (uint32_t)m->m_len) {
offset -= SCTP_BUF_LEN(at); /* update remaining offset break;
* left */
at = SCTP_BUF_NEXT(at);
} }
while (at != NULL) { offset -= m->m_len;
if ((SCTP_BUF_LEN(at) - offset) > 0) { m = m->m_next;
}
if (offset > 0) {
base = calculate_crc32c(base, base = calculate_crc32c(base,
(unsigned char *)(SCTP_BUF_AT(at, offset)), (unsigned char *)(m->m_data + offset),
(unsigned int)(SCTP_BUF_LEN(at) - offset)); (unsigned int)(m->m_len - offset));
m = m->m_next;
} }
if (offset) { while (m != NULL) {
/* we only offset once into the first mbuf */ base = calculate_crc32c(base,
if (offset < (uint32_t) SCTP_BUF_LEN(at)) (unsigned char *)m->m_data,
offset = 0; (unsigned int)m->m_len);
else m = m->m_next;
offset -= SCTP_BUF_LEN(at);
}
at = SCTP_BUF_NEXT(at);
} }
base = sctp_finalize_crc32c(base); base = sctp_finalize_crc32c(base);
return (base); return (base);
} }
#endif /* !defined(SCTP_WITH_NO_CSUM) */
#if defined(__FreeBSD__) && !defined(__Userspace__)
#if defined(SCTP) || defined(SCTP_SUPPORT)
#if defined(__FreeBSD__) VNET_DEFINE(struct sctp_base_info, system_base_info);
/*
* Compute and insert the SCTP checksum in network byte order for a given
* mbuf chain m which contains an SCTP packet starting at offset.
*/
void void
sctp_delayed_cksum(struct mbuf *m, uint32_t offset) sctp_delayed_cksum(struct mbuf *m, uint32_t offset)
{ {
#if defined(SCTP_WITH_NO_CSUM)
#ifdef INVARIANTS
panic("sctp_delayed_cksum() called when using no SCTP CRC.");
#endif
#else
uint32_t checksum; uint32_t checksum;
checksum = sctp_calculate_cksum(m, offset); checksum = sctp_calculate_cksum(m, offset);
@ -801,18 +814,18 @@ sctp_delayed_cksum(struct mbuf *m, uint32_t offset)
SCTP_STAT_INCR(sctps_sendswcrc); SCTP_STAT_INCR(sctps_sendswcrc);
offset += offsetof(struct sctphdr, checksum); offset += offsetof(struct sctphdr, checksum);
if (offset + sizeof(uint32_t) > (uint32_t) (m->m_len)) { if (offset + sizeof(uint32_t) > (uint32_t)(m->m_pkthdr.len)) {
SCTP_PRINTF("sctp_delayed_cksum(): m->len: %d, off: %d.\n", #ifdef INVARIANTS
(uint32_t) m->m_len, offset); panic("sctp_delayed_cksum(): m->m_pkthdr.len: %d, offset: %u.",
/* m->m_pkthdr.len, offset);
* XXX this shouldn't happen, but if it does, the correct #else
* behavior may be to insert the checksum in the appropriate SCTP_PRINTF("sctp_delayed_cksum(): m->m_pkthdr.len: %d, offset: %u.\n",
* next mbuf in the chain. m->m_pkthdr.len, offset);
*/ #endif
return; return;
} }
*(uint32_t *) (m->m_data + offset) = checksum; m_copyback(m, (int)offset, (int)sizeof(uint32_t), (caddr_t)&checksum);
#endif
} }
#endif #endif
#endif

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,25 +32,25 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_crc32.h 235828 2012-05-23 11:26:28Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_crc32.h 362338 2020-06-18 19:32:34Z markj $");
#endif #endif
#ifndef _NETINET_SCTP_CRC32_H_ #ifndef _NETINET_SCTP_CRC32_H_
#define _NETINET_SCTP_CRC32_H_ #define _NETINET_SCTP_CRC32_H_
#if defined(_KERNEL) #if defined(_KERNEL)
#if !defined(SCTP_WITH_NO_CSUM)
uint32_t sctp_calculate_cksum(struct mbuf *, uint32_t); uint32_t sctp_calculate_cksum(struct mbuf *, uint32_t);
#endif #if defined(__FreeBSD__) && !defined(__Userspace__)
#if defined(__FreeBSD__) #if defined(SCTP) || defined(SCTP_SUPPORT)
void sctp_delayed_cksum(struct mbuf *, uint32_t offset); void sctp_delayed_cksum(struct mbuf *, uint32_t offset);
#endif #endif
#endif
#endif /* _KERNEL */ #endif /* _KERNEL */
#if defined(__Userspace__) #if defined(__Userspace__)
#if !defined(SCTP_WITH_NO_CSUM) 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 *, uint32_t);
#endif #endif
#endif
#endif /* __crc32c_h__ */ #endif /* __crc32c_h__ */

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,24 +32,24 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_header.h 273168 2014-10-16 15:36:04Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_header.h 366114 2020-09-24 12:26:06Z tuexen $");
#endif #endif
#ifndef _NETINET_SCTP_HEADER_H_ #ifndef _NETINET_SCTP_HEADER_H_
#define _NETINET_SCTP_HEADER_H_ #define _NETINET_SCTP_HEADER_H_
#if defined(__Windows__) && !defined(__Userspace_os_Windows) #if defined(_WIN32) && !defined(__Userspace__)
#include <packon.h> #include <packon.h>
#endif #endif
#if !defined(__Userspace_os_Windows) #if !defined(_WIN32)
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#include <netinet/sctp.h> #include <netinet/sctp.h>
#include <netinet/sctp_constants.h> #include <netinet/sctp_constants.h>
#if !defined(__Userspace_os_Windows) #if !defined(_WIN32)
#define SCTP_PACKED __attribute__((packed)) #define SCTP_PACKED __attribute__((packed))
#else #else
#pragma pack (push, 1) #pragma pack (push, 1)
@ -64,7 +66,6 @@ struct sctp_ipv4addr_param {
#define SCTP_V6_ADDR_BYTES 16 #define SCTP_V6_ADDR_BYTES 16
struct sctp_ipv6addr_param { struct sctp_ipv6addr_param {
struct sctp_paramhdr ph;/* type=SCTP_IPV6_PARAM_TYPE, len=20 */ struct sctp_paramhdr ph;/* type=SCTP_IPV6_PARAM_TYPE, len=20 */
uint8_t addr[SCTP_V6_ADDR_BYTES]; /* IPV6 address */ uint8_t addr[SCTP_V6_ADDR_BYTES]; /* IPV6 address */
@ -108,14 +109,12 @@ struct sctp_heartbeat_info_param {
char address[SCTP_ADDRMAX]; char address[SCTP_ADDRMAX];
} SCTP_PACKED; } SCTP_PACKED;
/* draft-ietf-tsvwg-prsctp */ /* draft-ietf-tsvwg-prsctp */
/* PR-SCTP supported parameter */ /* PR-SCTP supported parameter */
struct sctp_prsctp_supported_param { struct sctp_prsctp_supported_param {
struct sctp_paramhdr ph; struct sctp_paramhdr ph;
} SCTP_PACKED; } SCTP_PACKED;
/* draft-ietf-tsvwg-addip-sctp */ /* draft-ietf-tsvwg-addip-sctp */
struct sctp_asconf_paramhdr { /* an ASCONF "parameter" */ struct sctp_asconf_paramhdr { /* an ASCONF "parameter" */
struct sctp_paramhdr ph;/* a SCTP parameter header */ struct sctp_paramhdr ph;/* a SCTP parameter header */
@ -127,14 +126,12 @@ struct sctp_asconf_addr_param { /* an ASCONF address parameter */
struct sctp_ipv6addr_param addrp; /* max storage size */ struct sctp_ipv6addr_param addrp; /* max storage size */
} SCTP_PACKED; } SCTP_PACKED;
struct sctp_asconf_tag_param { /* an ASCONF NAT-Vtag parameter */ struct sctp_asconf_tag_param { /* an ASCONF NAT-Vtag parameter */
struct sctp_asconf_paramhdr aph; /* asconf "parameter" */ struct sctp_asconf_paramhdr aph; /* asconf "parameter" */
uint32_t local_vtag; uint32_t local_vtag;
uint32_t remote_vtag; uint32_t remote_vtag;
} SCTP_PACKED; } SCTP_PACKED;
struct sctp_asconf_addrv4_param { /* an ASCONF address (v4) parameter */ struct sctp_asconf_addrv4_param { /* an ASCONF address (v4) parameter */
struct sctp_asconf_paramhdr aph; /* asconf "parameter" */ struct sctp_asconf_paramhdr aph; /* asconf "parameter" */
struct sctp_ipv4addr_param addrp; /* max storage size */ struct sctp_ipv4addr_param addrp; /* max storage size */
@ -147,15 +144,14 @@ struct sctp_supported_chunk_types_param {
uint8_t chunk_types[]; uint8_t chunk_types[];
} SCTP_PACKED; } SCTP_PACKED;
/* /*
* Structures for DATA chunks * Structures for DATA chunks
*/ */
struct sctp_data { struct sctp_data {
uint32_t tsn; uint32_t tsn;
uint16_t stream_id; uint16_t sid;
uint16_t stream_sequence; uint16_t ssn;
uint32_t protocol_id; uint32_t ppid;
/* user data follows */ /* user data follows */
} SCTP_PACKED; } SCTP_PACKED;
@ -164,6 +160,23 @@ struct sctp_data_chunk {
struct sctp_data dp; struct sctp_data dp;
} SCTP_PACKED; } SCTP_PACKED;
struct sctp_idata {
uint32_t tsn;
uint16_t sid;
uint16_t reserved; /* Where does the SSN go? */
uint32_t mid;
union {
uint32_t ppid;
uint32_t fsn; /* Fragment Sequence Number */
} ppid_fsn;
/* user data follows */
} SCTP_PACKED;
struct sctp_idata_chunk {
struct sctp_chunkhdr ch;
struct sctp_idata dp;
} SCTP_PACKED;
/* /*
* Structures for the control chunks * Structures for the control chunks
*/ */
@ -220,34 +233,6 @@ struct sctp_state_cookie { /* this is our definition... */
*/ */
} SCTP_PACKED; } SCTP_PACKED;
/* Used for NAT state error cause */
struct sctp_missing_nat_state {
uint16_t cause;
uint16_t length;
uint8_t data[];
} SCTP_PACKED;
struct sctp_inv_mandatory_param {
uint16_t cause;
uint16_t length;
uint32_t num_param;
uint16_t param;
/*
* We include this to 0 it since only a missing cookie will cause
* this error.
*/
uint16_t resv;
} SCTP_PACKED;
struct sctp_unresolv_addr {
uint16_t cause;
uint16_t length;
uint16_t addr_type;
uint16_t reserved; /* Only one invalid addr type */
} SCTP_PACKED;
/* state cookie parameter */ /* state cookie parameter */
struct sctp_state_cookie_param { struct sctp_state_cookie_param {
struct sctp_paramhdr ph; struct sctp_paramhdr ph;
@ -269,7 +254,6 @@ struct sctp_init_msg {
#define sctp_init_ack_chunk sctp_init_chunk #define sctp_init_ack_chunk sctp_init_chunk
#define sctp_init_ack_msg sctp_init_msg #define sctp_init_ack_msg sctp_init_msg
/* Selective Ack (SACK) */ /* Selective Ack (SACK) */
struct sctp_gap_ack_block { struct sctp_gap_ack_block {
uint16_t start; /* Gap Ack block start */ uint16_t start; /* Gap Ack block start */
@ -306,7 +290,6 @@ struct sctp_nr_sack_chunk {
struct sctp_nr_sack nr_sack; struct sctp_nr_sack nr_sack;
} SCTP_PACKED; } SCTP_PACKED;
/* Heartbeat Request (HEARTBEAT) */ /* Heartbeat Request (HEARTBEAT) */
struct sctp_heartbeat { struct sctp_heartbeat {
struct sctp_heartbeat_info_param hb_info; struct sctp_heartbeat_info_param hb_info;
@ -321,7 +304,6 @@ struct sctp_heartbeat_chunk {
#define sctp_heartbeat_ack sctp_heartbeat #define sctp_heartbeat_ack sctp_heartbeat
#define sctp_heartbeat_ack_chunk sctp_heartbeat_chunk #define sctp_heartbeat_ack_chunk sctp_heartbeat_chunk
/* Abort Asssociation (ABORT) */ /* Abort Asssociation (ABORT) */
struct sctp_abort_chunk { struct sctp_abort_chunk {
struct sctp_chunkhdr ch; struct sctp_chunkhdr ch;
@ -333,27 +315,23 @@ struct sctp_abort_msg {
struct sctp_abort_chunk msg; struct sctp_abort_chunk msg;
} SCTP_PACKED; } SCTP_PACKED;
/* Shutdown Association (SHUTDOWN) */ /* Shutdown Association (SHUTDOWN) */
struct sctp_shutdown_chunk { struct sctp_shutdown_chunk {
struct sctp_chunkhdr ch; struct sctp_chunkhdr ch;
uint32_t cumulative_tsn_ack; uint32_t cumulative_tsn_ack;
} SCTP_PACKED; } SCTP_PACKED;
/* Shutdown Acknowledgment (SHUTDOWN ACK) */ /* Shutdown Acknowledgment (SHUTDOWN ACK) */
struct sctp_shutdown_ack_chunk { struct sctp_shutdown_ack_chunk {
struct sctp_chunkhdr ch; struct sctp_chunkhdr ch;
} SCTP_PACKED; } SCTP_PACKED;
/* Operation Error (ERROR) */ /* Operation Error (ERROR) */
struct sctp_error_chunk { struct sctp_error_chunk {
struct sctp_chunkhdr ch; struct sctp_chunkhdr ch;
/* optional error causes follow */ /* optional error causes follow */
} SCTP_PACKED; } SCTP_PACKED;
/* Cookie Echo (COOKIE ECHO) */ /* Cookie Echo (COOKIE ECHO) */
struct sctp_cookie_echo_chunk { struct sctp_cookie_echo_chunk {
struct sctp_chunkhdr ch; struct sctp_chunkhdr ch;
@ -388,28 +366,11 @@ struct sctp_shutdown_complete_chunk {
struct sctp_chunkhdr ch; struct sctp_chunkhdr ch;
} SCTP_PACKED; } SCTP_PACKED;
/* Oper error holding a stale cookie */
struct sctp_stale_cookie_msg {
struct sctp_paramhdr ph;/* really an error cause */
uint32_t time_usec;
} SCTP_PACKED;
struct sctp_adaptation_layer_indication { struct sctp_adaptation_layer_indication {
struct sctp_paramhdr ph; struct sctp_paramhdr ph;
uint32_t indication; uint32_t indication;
} SCTP_PACKED; } SCTP_PACKED;
struct sctp_cookie_while_shutting_down {
struct sctphdr sh;
struct sctp_chunkhdr ch;
struct sctp_paramhdr ph;/* really an error cause */
} SCTP_PACKED;
struct sctp_shutdown_complete_msg {
struct sctphdr sh;
struct sctp_shutdown_complete_chunk shut_cmp;
} SCTP_PACKED;
/* /*
* draft-ietf-tsvwg-addip-sctp * draft-ietf-tsvwg-addip-sctp
*/ */
@ -437,10 +398,16 @@ struct sctp_forward_tsn_chunk {
} SCTP_PACKED; } SCTP_PACKED;
struct sctp_strseq { struct sctp_strseq {
uint16_t stream; uint16_t sid;
uint16_t sequence; uint16_t ssn;
} SCTP_PACKED; } SCTP_PACKED;
struct sctp_strseq_mid {
uint16_t sid;
uint16_t flags;
uint32_t mid;
};
struct sctp_forward_tsn_msg { struct sctp_forward_tsn_msg {
struct sctphdr sh; struct sctphdr sh;
struct sctp_forward_tsn_chunk msg; struct sctp_forward_tsn_chunk msg;
@ -456,7 +423,6 @@ struct sctp_chunk_desc {
uint32_t tsn_ifany; uint32_t tsn_ifany;
} SCTP_PACKED; } SCTP_PACKED;
struct sctp_pktdrop_chunk { struct sctp_pktdrop_chunk {
struct sctp_chunkhdr ch; struct sctp_chunkhdr ch;
uint32_t bottle_bw; uint32_t bottle_bw;
@ -572,12 +538,6 @@ struct sctp_auth_chunk {
uint8_t hmac[]; uint8_t hmac[];
} SCTP_PACKED; } SCTP_PACKED;
struct sctp_auth_invalid_hmac {
struct sctp_paramhdr ph;
uint16_t hmac_id;
uint16_t padding;
} SCTP_PACKED;
/* /*
* we pre-reserve enough room for a ECNE or CWR AND a SACK with no missing * we pre-reserve enough room for a ECNE or CWR AND a SACK with no missing
* pieces. If ENCE is missing we could have a couple of blocks. This way we * pieces. If ENCE is missing we could have a couple of blocks. This way we
@ -598,7 +558,6 @@ struct sctp_auth_invalid_hmac {
sizeof(struct sctphdr) + \ sizeof(struct sctphdr) + \
sizeof(struct ip6_hdr)) sizeof(struct ip6_hdr))
#define SCTP_MIN_OVERHEAD (sizeof(struct ip6_hdr) + \ #define SCTP_MIN_OVERHEAD (sizeof(struct ip6_hdr) + \
sizeof(struct sctphdr)) sizeof(struct sctphdr))
@ -613,7 +572,6 @@ struct sctp_auth_invalid_hmac {
sizeof(struct sctphdr) + \ sizeof(struct sctphdr) + \
sizeof(struct ip)) sizeof(struct ip))
#define SCTP_MIN_OVERHEAD (sizeof(struct ip) + \ #define SCTP_MIN_OVERHEAD (sizeof(struct ip) + \
sizeof(struct sctphdr)) sizeof(struct sctphdr))
@ -627,11 +585,11 @@ struct sctp_auth_invalid_hmac {
#define SCTP_MIN_V4_OVERHEAD (sizeof(struct ip) + \ #define SCTP_MIN_V4_OVERHEAD (sizeof(struct ip) + \
sizeof(struct sctphdr)) sizeof(struct sctphdr))
#if defined(__Windows__) #if defined(_WIN32) && !defined(__Userspace__)
#include <packoff.h> #include <packoff.h>
#endif #endif
#if defined(__Userspace_os_Windows) #if defined(_WIN32) && defined(__Userspace__)
#pragma pack () #pragma pack(pop)
#endif #endif
#undef SCTP_PACKED #undef SCTP_PACKED
#endif /* !__sctp_header_h__ */ #endif /* !__sctp_header_h__ */

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.h 252585 2013-07-03 18:48:43Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.h 365071 2020-09-01 21:19:14Z mjg $");
#endif #endif
#ifndef _NETINET_SCTP_INDATA_H_ #ifndef _NETINET_SCTP_INDATA_H_
@ -44,41 +46,35 @@ struct sctp_queued_to_read *
sctp_build_readq_entry(struct sctp_tcb *stcb, sctp_build_readq_entry(struct sctp_tcb *stcb,
struct sctp_nets *net, struct sctp_nets *net,
uint32_t tsn, uint32_t ppid, uint32_t tsn, uint32_t ppid,
uint32_t context, uint16_t stream_no, uint32_t context, uint16_t sid,
uint16_t stream_seq, uint8_t flags, uint32_t mid, uint8_t flags,
struct mbuf *dm); struct mbuf *dm);
#define sctp_build_readq_entry_mac(_ctl, in_it, context, net, tsn, ppid, sid, flags, dm, tfsn, mid) do { \
#define sctp_build_readq_entry_mac(_ctl, in_it, context, net, tsn, ppid, stream_no, stream_seq, flags, dm) do { \
if (_ctl) { \ if (_ctl) { \
atomic_add_int(&((net)->ref_count), 1); \ atomic_add_int(&((net)->ref_count), 1); \
(_ctl)->sinfo_stream = stream_no; \ memset(_ctl, 0, sizeof(struct sctp_queued_to_read)); \
(_ctl)->sinfo_ssn = stream_seq; \ (_ctl)->sinfo_stream = sid; \
TAILQ_INIT(&_ctl->reasm); \
(_ctl)->top_fsn = tfsn; \
(_ctl)->mid = mid; \
(_ctl)->sinfo_flags = (flags << 8); \ (_ctl)->sinfo_flags = (flags << 8); \
(_ctl)->sinfo_ppid = ppid; \ (_ctl)->sinfo_ppid = ppid; \
(_ctl)->sinfo_context = context; \ (_ctl)->sinfo_context = context; \
(_ctl)->sinfo_timetolive = 0; \ (_ctl)->fsn_included = 0xffffffff; \
(_ctl)->sinfo_tsn = tsn; \ (_ctl)->sinfo_tsn = tsn; \
(_ctl)->sinfo_cumtsn = tsn; \ (_ctl)->sinfo_cumtsn = tsn; \
(_ctl)->sinfo_assoc_id = sctp_get_associd((in_it)); \ (_ctl)->sinfo_assoc_id = sctp_get_associd((in_it)); \
(_ctl)->length = 0; \
(_ctl)->held_length = 0; \
(_ctl)->whoFrom = net; \ (_ctl)->whoFrom = net; \
(_ctl)->data = dm; \ (_ctl)->data = dm; \
(_ctl)->tail_mbuf = NULL; \
(_ctl)->aux_data = NULL; \
(_ctl)->stcb = (in_it); \ (_ctl)->stcb = (in_it); \
(_ctl)->port_from = (in_it)->rport; \ (_ctl)->port_from = (in_it)->rport; \
(_ctl)->spec_flags = 0; \ if ((in_it)->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { \
(_ctl)->do_not_ref_stcb = 0; \ (_ctl)->do_not_ref_stcb = 1; \
(_ctl)->end_added = 0; \ }\
(_ctl)->pdapi_aborted = 0; \
(_ctl)->some_taken = 0; \
} \ } \
} while (0) } while (0)
struct mbuf * struct mbuf *
sctp_build_ctl_nchunk(struct sctp_inpcb *inp, sctp_build_ctl_nchunk(struct sctp_inpcb *inp,
struct sctp_sndrcvinfo *sinfo); struct sctp_sndrcvinfo *sinfo);
@ -114,14 +110,8 @@ sctp_update_acked(struct sctp_tcb *, struct sctp_shutdown_chunk *, int *);
int int
sctp_process_data(struct mbuf **, int, int *, int, sctp_process_data(struct mbuf **, int, int *, int,
struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *,
struct sctp_inpcb *, struct sctp_tcb *, struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *, uint32_t *, struct sctp_nets *, uint32_t *);
#if defined(__FreeBSD__)
uint8_t, uint32_t,
#endif
uint32_t, uint16_t);
void sctp_slide_mapping_arrays(struct sctp_tcb *stcb); void sctp_slide_mapping_arrays(struct sctp_tcb *stcb);

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.h 273168 2014-10-16 15:36:04Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_input.h 365071 2020-09-01 21:19:14Z mjg $");
#endif #endif
#ifndef _NETINET_SCTP_INPUT_H_ #ifndef _NETINET_SCTP_INPUT_H_
@ -43,12 +45,10 @@ void
sctp_common_input_processing(struct mbuf **, int, int, int, sctp_common_input_processing(struct mbuf **, int, int, int,
struct sockaddr *, struct sockaddr *, struct sockaddr *, struct sockaddr *,
struct sctphdr *, struct sctp_chunkhdr *, struct sctphdr *, struct sctp_chunkhdr *,
#if !defined(SCTP_WITH_NO_CSUM)
uint8_t, uint8_t,
#endif
uint8_t, uint8_t,
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
uint8_t, uint32_t, uint8_t, uint32_t, uint16_t,
#endif #endif
uint32_t, uint16_t); uint32_t, uint16_t);
@ -56,10 +56,10 @@ struct sctp_stream_reset_request *
sctp_find_stream_reset(struct sctp_tcb *stcb, uint32_t seq, sctp_find_stream_reset(struct sctp_tcb *stcb, uint32_t seq,
struct sctp_tmit_chunk **bchk); struct sctp_tmit_chunk **bchk);
void sctp_reset_in_stream(struct sctp_tcb *stcb, uint32_t number_entries, void
sctp_reset_in_stream(struct sctp_tcb *stcb, uint32_t number_entries,
uint16_t *list); uint16_t *list);
int sctp_is_there_unsent_data(struct sctp_tcb *stcb, int so_locked); int sctp_is_there_unsent_data(struct sctp_tcb *stcb, int so_locked);
#endif #endif

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -31,7 +33,7 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD$"); __FBSDID("$FreeBSD$");
#endif #endif
@ -66,7 +68,7 @@ __FBSDID("$FreeBSD$");
#define SCTP_WQ_ADDR_DESTROY() #define SCTP_WQ_ADDR_DESTROY()
#define SCTP_WQ_ADDR_LOCK() #define SCTP_WQ_ADDR_LOCK()
#define SCTP_WQ_ADDR_UNLOCK() #define SCTP_WQ_ADDR_UNLOCK()
#define SCTP_WQ_ADDR_LOCK_ASSERT()
#define SCTP_IPI_ADDR_INIT() #define SCTP_IPI_ADDR_INIT()
#define SCTP_IPI_ADDR_DESTROY() #define SCTP_IPI_ADDR_DESTROY()
@ -74,20 +76,19 @@ __FBSDID("$FreeBSD$");
#define SCTP_IPI_ADDR_WLOCK() #define SCTP_IPI_ADDR_WLOCK()
#define SCTP_IPI_ADDR_RUNLOCK() #define SCTP_IPI_ADDR_RUNLOCK()
#define SCTP_IPI_ADDR_WUNLOCK() #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_INIT()
#define SCTP_IPI_ITERATOR_WQ_DESTROY() #define SCTP_IPI_ITERATOR_WQ_DESTROY()
#define SCTP_IPI_ITERATOR_WQ_LOCK() #define SCTP_IPI_ITERATOR_WQ_LOCK()
#define SCTP_IPI_ITERATOR_WQ_UNLOCK() #define SCTP_IPI_ITERATOR_WQ_UNLOCK()
#define SCTP_IP_PKTLOG_INIT() #define SCTP_IP_PKTLOG_INIT()
#define SCTP_IP_PKTLOG_LOCK() #define SCTP_IP_PKTLOG_LOCK()
#define SCTP_IP_PKTLOG_UNLOCK() #define SCTP_IP_PKTLOG_UNLOCK()
#define SCTP_IP_PKTLOG_DESTROY() #define SCTP_IP_PKTLOG_DESTROY()
#define SCTP_INP_READ_INIT(_inp) #define SCTP_INP_READ_INIT(_inp)
#define SCTP_INP_READ_DESTROY(_inp) #define SCTP_INP_READ_DESTROY(_inp)
#define SCTP_INP_READ_LOCK(_inp) #define SCTP_INP_READ_LOCK(_inp)
@ -98,9 +99,10 @@ __FBSDID("$FreeBSD$");
#define SCTP_INP_LOCK_DESTROY(_inp) #define SCTP_INP_LOCK_DESTROY(_inp)
#define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp) #define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp)
#define SCTP_INP_RLOCK(_inp) #define SCTP_INP_RLOCK(_inp)
#define SCTP_INP_WLOCK(_inp) #define SCTP_INP_WLOCK(_inp)
#define SCTP_INP_RLOCK_ASSERT(_inp)
#define SCTP_INP_WLOCK_ASSERT(_inp)
#define SCTP_INP_LOCK_CONTENDED(_inp) (0) /* Don't know if this is possible */ #define SCTP_INP_LOCK_CONTENDED(_inp) (0) /* Don't know if this is possible */
@ -212,14 +214,6 @@ __FBSDID("$FreeBSD$");
} while (0) } while (0)
/* not sure if __Userspace__ needs these (but copied nonetheless...) */
#if defined(SCTP_SO_LOCK_TESTING)
#define SCTP_INP_SO(sctpinp) (sctpinp)->ip_inp.inp.inp_socket
#define SCTP_SOCKET_LOCK(so, refcnt)
#define SCTP_SOCKET_UNLOCK(so, refcnt)
#endif
/* these were in sctp_lock_empty.h but aren't in sctp_lock_bsd.h ... */ /* these were in sctp_lock_empty.h but aren't in sctp_lock_bsd.h ... */
#if 0 #if 0
#define SCTP_IPI_ADDR_LOCK() #define SCTP_IPI_ADDR_LOCK()

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2006-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2006-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_os.h 235828 2012-05-23 11:26:28Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_os.h 365071 2020-09-01 21:19:14Z mjg $");
#endif #endif
#ifndef _NETINET_SCTP_OS_H_ #ifndef _NETINET_SCTP_OS_H_
@ -62,25 +64,18 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_os.h 235828 2012-05-23 11:26:28Z tuexe
* SCTP_ZONE_DESTROY(zone) * SCTP_ZONE_DESTROY(zone)
*/ */
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <netinet/sctp_os_bsd.h> #include <netinet/sctp_os_bsd.h>
#else #else
#define MODULE_GLOBAL(_B) (_B) #define MODULE_GLOBAL(_B) (_B)
#endif #endif
#if defined(__Userspace__) #if defined(__Userspace__)
#include <netinet/sctp_os_userspace.h> #include <netinet/sctp_os_userspace.h>
#endif #endif
#if defined(__APPLE__) && !defined(__Userspace__)
#if defined(__APPLE__)
#include <netinet/sctp_os_macosx.h> #include <netinet/sctp_os_macosx.h>
#endif #endif
#if defined(_WIN32) && !defined(__Userspace__)
#if defined(__Panda__)
#include <ip/sctp/sctp_os_iox.h>
#endif
#if defined(__Windows__)
#include <netinet/sctp_os_windows.h> #include <netinet/sctp_os_windows.h>
#endif #endif

View file

@ -41,12 +41,12 @@
#include <errno.h> #include <errno.h>
#if defined(__Userspace_os_Windows) #if defined(_WIN32)
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#include <iphlpapi.h> #include <iphlpapi.h>
#include <Mswsock.h> #include <mswsock.h>
#include <Windows.h> #include <windows.h>
#include "user_environment.h" #include "user_environment.h"
typedef CRITICAL_SECTION userland_mutex_t; typedef CRITICAL_SECTION userland_mutex_t;
#if WINVER < 0x0600 #if WINVER < 0x0600
@ -78,33 +78,33 @@ typedef HANDLE userland_thread_t;
#define IPVERSION 4 #define IPVERSION 4
#define MAXTTL 255 #define MAXTTL 255
/* VS2010 comes with stdint.h */ /* VS2010 comes with stdint.h */
#if _MSC_VER >= 1600 #if !defined(_MSC_VER) || (_MSC_VER >= 1600)
#include <stdint.h> #include <stdint.h>
#else #else
#define uint64_t unsigned __int64 typedef unsigned __int64 uint64_t;
#define uint32_t unsigned __int32 typedef unsigned __int32 uint32_t;
#define int32_t __int32 typedef __int32 int32_t;
#define uint16_t unsigned __int16 typedef unsigned __int16 uint16_t;
#define int16_t __int16 typedef __int16 int16_t;
#define uint8_t unsigned __int8 typedef unsigned __int8 uint8_t;
#define int8_t __int8 typedef __int8 int8_t;
#endif #endif
#ifndef _SIZE_T_DEFINED #ifndef _SIZE_T_DEFINED
#define size_t __int32 #define size_t __int32
#endif #endif
#define u_long unsigned __int64 #ifndef _SIZE_T_DEFINED
#define u_int unsigned __int32 #typedef __int32 size_t;
#define u_int32_t unsigned __int32 #endif
#define u_int16_t unsigned __int16 typedef unsigned __int32 u_int;
#define u_int8_t unsigned __int8 typedef unsigned char u_char;
#define u_char unsigned char typedef unsigned __int16 u_short;
#define n_short unsigned __int16 typedef unsigned __int8 sa_family_t;
#define u_short unsigned __int16 #ifndef _SSIZE_T_DEFINED
#define n_time unsigned __int32 typedef __int64 ssize_t;
#define sa_family_t unsigned __int8 #endif
#define ssize_t __int64 #if !defined(__MINGW32__)
#define __func__ __FUNCTION__ #define __func__ __FUNCTION__
#endif
#ifndef EWOULDBLOCK #ifndef EWOULDBLOCK
#define EWOULDBLOCK WSAEWOULDBLOCK #define EWOULDBLOCK WSAEWOULDBLOCK
#endif #endif
@ -218,9 +218,19 @@ typedef char* caddr_t;
#define bzero(buf, len) memset(buf, 0, len) #define bzero(buf, len) memset(buf, 0, len)
#define bcopy(srcKey, dstKey, len) memcpy(dstKey, srcKey, len) #define bcopy(srcKey, dstKey, len) memcpy(dstKey, srcKey, len)
#if _MSC_VER < 1900
#define snprintf(data, size, format, ...) _snprintf_s(data, size, _TRUNCATE, format, __VA_ARGS__) #if defined(_MSC_VER) && (_MSC_VER < 1900) && !defined(__MINGW32__)
#define SCTP_SNPRINTF(data, size, format, ...) \
if (_snprintf_s(data, size, _TRUNCATE, format, __VA_ARGS__) < 0) { \
data[0] = '\0'; \
}
#else
#define SCTP_SNPRINTF(data, ...) \
if (snprintf(data, __VA_ARGS__) < 0 ) { \
data[0] = '\0'; \
}
#endif #endif
#define inline __inline #define inline __inline
#define __inline__ __inline #define __inline__ __inline
#define MSG_EOR 0x8 /* data completes record */ #define MSG_EOR 0x8 /* data completes record */
@ -274,7 +284,7 @@ typedef char* caddr_t;
#else /* !defined(Userspace_os_Windows) */ #else /* !defined(Userspace_os_Windows) */
#include <sys/socket.h> #include <sys/socket.h>
#if defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Linux) || defined(__Userspace_os_NetBSD) || defined(__Userspace_os_OpenBSD) || defined(__Userspace_os_NaCl) #if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__native_client__) || defined(__Fuchsia__) || defined(__EMSCRIPTEN_PTHREADS__)
#include <pthread.h> #include <pthread.h>
#endif #endif
typedef pthread_mutex_t userland_mutex_t; typedef pthread_mutex_t userland_mutex_t;
@ -282,7 +292,7 @@ typedef pthread_cond_t userland_cond_t;
typedef pthread_t userland_thread_t; typedef pthread_t userland_thread_t;
#endif #endif
#if defined(__Userspace_os_Windows) || defined(__Userspace_os_NaCl) #if defined(_WIN32) || defined(__native_client__)
#define IFNAMSIZ 64 #define IFNAMSIZ 64
@ -345,7 +355,7 @@ struct udphdr {
}; };
struct iovec { struct iovec {
unsigned long len; size_t len;
char *buf; char *buf;
}; };
@ -376,43 +386,9 @@ struct ifkpi {
int ifk_value; int ifk_value;
} ifk_data; } ifk_data;
}; };
struct ifreq {
char ifr_name[16];
union {
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
short ifru_flags;
int ifru_metric;
int ifru_mtu;
int ifru_phys;
int ifru_media;
int ifru_intval;
char* ifru_data;
struct ifdevmtu ifru_devmtu;
struct ifkpi ifru_kpi;
uint32_t ifru_wake_flags;
} ifr_ifru;
#define ifr_addr ifr_ifru.ifru_addr
#define ifr_dstaddr ifr_ifru.ifru_dstaddr
#define ifr_broadaddr ifr_ifru.ifru_broadaddr
#define ifr_flags ifr_ifru.ifru_flags[0]
#define ifr_prevflags ifr_ifru.ifru_flags[1]
#define ifr_metric ifr_ifru.ifru_metric
#define ifr_mtu ifr_ifru.ifru_mtu
#define ifr_phys ifr_ifru.ifru_phys
#define ifr_media ifr_ifru.ifru_media
#define ifr_data ifr_ifru.ifru_data
#define ifr_devmtu ifr_ifru.ifru_devmtu
#define ifr_intval ifr_ifru.ifru_intval
#define ifr_kpi ifr_ifru.ifru_kpi
#define ifr_wake_flags ifr_ifru.ifru_wake_flags
};
#endif #endif
#if defined(__Userspace_os_Windows) #if defined(_WIN32)
int Win_getifaddrs(struct ifaddrs**); int Win_getifaddrs(struct ifaddrs**);
#define getifaddrs(interfaces) (int)Win_getifaddrs(interfaces) #define getifaddrs(interfaces) (int)Win_getifaddrs(interfaces)
int win_if_nametoindex(const char *); int win_if_nametoindex(const char *);
@ -423,9 +399,9 @@ int win_if_nametoindex(const char *);
#define mtx_unlock(arg1) #define mtx_unlock(arg1)
#define mtx_assert(arg1,arg2) #define mtx_assert(arg1,arg2)
#define MA_OWNED 7 /* sys/mutex.h typically on FreeBSD */ #define MA_OWNED 7 /* sys/mutex.h typically on FreeBSD */
#if !defined(__Userspace_os_FreeBSD) #if !defined(__FreeBSD__)
struct mtx {int dummy;}; struct mtx {int dummy;};
#if !defined(__Userspace_os_NetBSD) #if !defined(__NetBSD__)
struct selinfo {int dummy;}; struct selinfo {int dummy;};
#endif #endif
struct sx {int dummy;}; struct sx {int dummy;};
@ -433,6 +409,7 @@ struct sx {int dummy;};
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdbool.h>
/* #include <sys/param.h> in FreeBSD defines MSIZE */ /* #include <sys/param.h> in FreeBSD defines MSIZE */
/* #include <sys/ktr.h> */ /* #include <sys/ktr.h> */
/* #include <sys/systm.h> */ /* #include <sys/systm.h> */
@ -455,22 +432,22 @@ struct sx {int dummy;};
#include <user_mbuf.h> #include <user_mbuf.h>
/* #include <sys/uio.h> */ /* #include <sys/uio.h> */
/* #include <sys/lock.h> */ /* #include <sys/lock.h> */
#if defined(__FreeBSD__) && __FreeBSD_version > 602000 #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/rwlock.h> #include <sys/rwlock.h>
#endif #endif
/* #include <sys/kthread.h> */ /* #include <sys/kthread.h> */
#if defined(__FreeBSD__) && __FreeBSD_version > 602000 #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/priv.h> #include <sys/priv.h>
#endif #endif
/* #include <sys/random.h> */ /* #include <sys/random.h> */
/* #include <sys/limits.h> */ #include <limits.h>
/* #include <machine/cpu.h> */ /* #include <machine/cpu.h> */
#if defined(__Userspace_os_Darwin) #if defined(__APPLE__)
/* was a 0 byte file. needed for structs if_data(64) and net_event_data */ /* was a 0 byte file. needed for structs if_data(64) and net_event_data */
#include <net/if_var.h> #include <net/if_var.h>
#endif #endif
#if defined(__Userspace_os_FreeBSD) #if defined(__FreeBSD__)
#include <net/if_types.h> #include <net/if_types.h>
/* #include <net/if_var.h> was a 0 byte file. causes struct mtx redefinition */ /* #include <net/if_var.h> was a 0 byte file. causes struct mtx redefinition */
#endif #endif
@ -478,7 +455,7 @@ struct sx {int dummy;};
* userspace as well? */ * userspace as well? */
/* on FreeBSD, this results in a redefintion of struct route */ /* on FreeBSD, this results in a redefintion of struct route */
/* #include <net/route.h> */ /* #include <net/route.h> */
#if !defined(__Userspace_os_Windows) && !defined(__Userspace_os_NaCl) #if !defined(_WIN32) && !defined(__native_client__)
#include <net/if.h> #include <net/if.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/in_systm.h> #include <netinet/in_systm.h>
@ -494,7 +471,7 @@ struct sx {int dummy;};
/* for getifaddrs */ /* for getifaddrs */
#include <sys/types.h> #include <sys/types.h>
#if !defined(__Userspace_os_Windows) #if !defined(_WIN32)
#if defined(INET) || defined(INET6) #if defined(INET) || defined(INET6)
#include <ifaddrs.h> #include <ifaddrs.h>
#endif #endif
@ -504,6 +481,8 @@ struct sx {int dummy;};
/* for close, etc. */ /* for close, etc. */
#include <unistd.h> #include <unistd.h>
/* for gettimeofday */
#include <sys/time.h>
#endif #endif
/* lots of errno's used and needed in userspace */ /* lots of errno's used and needed in userspace */
@ -511,7 +490,7 @@ struct sx {int dummy;};
/* for offsetof */ /* for offsetof */
#include <stddef.h> #include <stddef.h>
#if defined(SCTP_PROCESS_LEVEL_LOCKS) && !defined(__Userspace_os_Windows) #if defined(SCTP_PROCESS_LEVEL_LOCKS) && !defined(_WIN32)
/* for pthread_mutex_lock, pthread_mutex_unlock, etc. */ /* for pthread_mutex_lock, pthread_mutex_unlock, etc. */
#include <pthread.h> #include <pthread.h>
#endif #endif
@ -522,22 +501,21 @@ struct sx {int dummy;};
#endif /* IPSEC */ #endif /* IPSEC */
#ifdef INET6 #ifdef INET6
#if defined(__Userspace_os_FreeBSD) #if defined(__FreeBSD__)
#include <sys/domain.h> #include <sys/domain.h>
#endif #endif
#ifdef IPSEC #ifdef IPSEC
#include <netipsec/ipsec6.h> #include <netipsec/ipsec6.h>
#endif #endif
#if !defined(__Userspace_os_Windows) #if !defined(_WIN32)
#include <netinet/ip6.h> #include <netinet/ip6.h>
#include <netinet/icmp6.h>
#endif #endif
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Linux) || defined(__Userspace_os_NetBSD) || defined(__Userspace_os_OpenBSD) || defined(__Userspace_os_Windows) #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(_WIN32) || defined(__EMSCRIPTEN__)
#include "user_ip6_var.h" #include "user_ip6_var.h"
#else #else
#include <netinet6/ip6_var.h> #include <netinet6/ip6_var.h>
#endif #endif
#if defined(__Userspace_os_FreeBSD) #if defined(__FreeBSD__)
#include <netinet6/in6_pcb.h> #include <netinet6/in6_pcb.h>
#include <netinet6/ip6protosw.h> #include <netinet6/ip6protosw.h>
/* #include <netinet6/nd6.h> was a 0 byte file */ /* #include <netinet6/nd6.h> was a 0 byte file */
@ -552,7 +530,7 @@ struct sx {int dummy;};
#include "netinet/sctp_sha1.h" #include "netinet/sctp_sha1.h"
#if __FreeBSD_version >= 700000 #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <netinet/ip_options.h> #include <netinet/ip_options.h>
#endif #endif
@ -561,11 +539,6 @@ struct sx {int dummy;};
SCTP_BASE_VAR(debug_printf)(__VA_ARGS__); \ SCTP_BASE_VAR(debug_printf)(__VA_ARGS__); \
} }
#if defined(__FreeBSD__)
#ifndef in6pcb
#define in6pcb inpcb
#endif
#endif
/* Declare all the malloc names for all the various mallocs */ /* Declare all the malloc names for all the various mallocs */
MALLOC_DECLARE(SCTP_M_MAP); MALLOC_DECLARE(SCTP_M_MAP);
MALLOC_DECLARE(SCTP_M_STRMI); MALLOC_DECLARE(SCTP_M_STRMI);
@ -610,12 +583,12 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT);
/* /*
* *
*/ */
#if !defined(__Userspace_os_Darwin) #if !defined(__APPLE__)
#define USER_ADDR_NULL (NULL) /* FIX ME: temp */ #define USER_ADDR_NULL (NULL) /* FIX ME: temp */
#endif #endif
#if defined(SCTP_DEBUG)
#include <netinet/sctp_constants.h> #include <netinet/sctp_constants.h>
#if defined(SCTP_DEBUG)
#define SCTPDBG(level, ...) \ #define SCTPDBG(level, ...) \
{ \ { \
do { \ do { \
@ -669,7 +642,7 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT);
#define SCTP_VRF_IFN_HASH_SIZE 3 #define SCTP_VRF_IFN_HASH_SIZE 3
#define SCTP_INIT_VRF_TABLEID(vrf) #define SCTP_INIT_VRF_TABLEID(vrf)
#if !defined(__Userspace_os_Windows) #if !defined(_WIN32)
#define SCTP_IFN_IS_IFT_LOOP(ifn) (strncmp((ifn)->ifn_name, "lo", 2) == 0) #define SCTP_IFN_IS_IFT_LOOP(ifn) (strncmp((ifn)->ifn_name, "lo", 2) == 0)
/* BSD definition */ /* BSD definition */
/* #define SCTP_ROUTE_IS_REAL_LOOP(ro) ((ro)->ro_rt && (ro)->ro_rt->rt_ifa && (ro)->ro_rt->rt_ifa->ifa_ifp && (ro)->ro_rt->rt_ifa->ifa_ifp->if_type == IFT_LOOP) */ /* #define SCTP_ROUTE_IS_REAL_LOOP(ro) ((ro)->ro_rt && (ro)->ro_rt->rt_ifa && (ro)->ro_rt->rt_ifa->ifa_ifp && (ro)->ro_rt->rt_ifa->ifa_ifp->if_type == IFT_LOOP) */
@ -763,14 +736,6 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT);
umem_cache_destroy(zone); umem_cache_destroy(zone);
#endif #endif
/* global struct ifaddrs used in sctp_init_ifns_for_vrf getifaddrs call
* but references to fields are needed to persist as the vrf is queried.
* getifaddrs allocates memory that needs to be freed with a freeifaddrs
* call; this global is used to call freeifaddrs upon in sctp_pcb_finish
*/
extern struct ifaddrs *g_interfaces;
/* /*
* __Userspace__ Defining sctp_hashinit_flags() and sctp_hashdestroy() for userland. * __Userspace__ Defining sctp_hashinit_flags() and sctp_hashdestroy() for userland.
*/ */
@ -810,10 +775,8 @@ sctp_hashfreedestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask);
/*__Userspace__ defining KTR_SUBSYS 1 as done in sctp_os_macosx.h */ /*__Userspace__ defining KTR_SUBSYS 1 as done in sctp_os_macosx.h */
#define KTR_SUBSYS 1 #define KTR_SUBSYS 1
#define sctp_get_tick_count() (ticks)
/* The packed define for 64 bit platforms */ /* The packed define for 64 bit platforms */
#if !defined(__Userspace_os_Windows) #if !defined(_WIN32)
#define SCTP_PACKED __attribute__((packed)) #define SCTP_PACKED __attribute__((packed))
#define SCTP_UNUSED __attribute__((unused)) #define SCTP_UNUSED __attribute__((unused))
#else #else
@ -842,6 +805,13 @@ sctp_hashfreedestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask);
M_ALIGN(m, len); \ M_ALIGN(m, len); \
} }
#if !defined(_WIN32)
#define SCTP_SNPRINTF(data, ...) \
if (snprintf(data, __VA_ARGS__) < 0) { \
data[0] = '\0'; \
}
#endif
/* We make it so if you have up to 4 threads /* We make it so if you have up to 4 threads
* writting based on the default size of * writting based on the default size of
* the packet log 65 k, that would be * the packet log 65 k, that would be
@ -888,7 +858,7 @@ static inline void sctp_userspace_rtalloc(sctp_route_t *ro)
* SCTP_GET_IF_INDEX_FROM_ROUTE macro. * SCTP_GET_IF_INDEX_FROM_ROUTE macro.
*/ */
} }
#define SCTP_RTALLOC(ro, vrf_id) sctp_userspace_rtalloc((sctp_route_t *)ro) #define SCTP_RTALLOC(ro, vrf_id, fibnum) sctp_userspace_rtalloc((sctp_route_t *)ro)
/* dummy rtfree needed once user_route.h is included */ /* dummy rtfree needed once user_route.h is included */
static inline void sctp_userspace_rtfree(sctp_rtentry_t *rt) static inline void sctp_userspace_rtfree(sctp_rtentry_t *rt)
@ -900,7 +870,6 @@ static inline void sctp_userspace_rtfree(sctp_rtentry_t *rt)
return; return;
} }
free(rt); free(rt);
rt = NULL;
} }
#define rtfree(arg1) sctp_userspace_rtfree(arg1) #define rtfree(arg1) sctp_userspace_rtfree(arg1)
@ -921,10 +890,6 @@ int sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af);
rt->rt_rmx.rmx_mtu = mtu; \ rt->rt_rmx.rmx_mtu = mtu; \
} while(0) } while(0)
/* (de-)register interface event notifications */
#define SCTP_REGISTER_INTERFACE(ifhandle, af)
#define SCTP_DEREGISTER_INTERFACE(ifhandle, af)
/*************************/ /*************************/
/* These are for logging */ /* These are for logging */
@ -949,13 +914,6 @@ int sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af);
#define SCTP_GET_HEADER_FOR_OUTPUT(o_pak) 0 #define SCTP_GET_HEADER_FOR_OUTPUT(o_pak) 0
#define SCTP_RELEASE_HEADER(m) #define SCTP_RELEASE_HEADER(m)
#define SCTP_RELEASE_PKT(m) sctp_m_freem(m) #define SCTP_RELEASE_PKT(m) sctp_m_freem(m)
/* UDP __Userspace__ - dummy definition */
#define SCTP_ENABLE_UDP_CSUM(m) m=m
/* BSD definition */
/* #define SCTP_ENABLE_UDP_CSUM(m) do { \ */
/* m->m_pkthdr.csum_flags = CSUM_UDP; \ */
/* m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); \ */
/* } while (0) */
#define SCTP_GET_PKT_VRFID(m, vrf_id) ((vrf_id = SCTP_DEFAULT_VRFID) != SCTP_DEFAULT_VRFID) #define SCTP_GET_PKT_VRFID(m, vrf_id) ((vrf_id = SCTP_DEFAULT_VRFID) != SCTP_DEFAULT_VRFID)
@ -981,11 +939,11 @@ int sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af);
*/ */
/* get the v6 hop limit */ /* get the v6 hop limit */
#define SCTP_GET_HLIM(inp, ro) 128 /* As done for __Windows__ */ #define SCTP_GET_HLIM(inp, ro) 128
#define IPv6_HOP_LIMIT 128 #define IPv6_HOP_LIMIT 128
/* is the endpoint v6only? */ /* is the endpoint v6only? */
#define SCTP_IPV6_V6ONLY(inp) (((struct inpcb *)inp)->inp_flags & IN6P_IPV6_V6ONLY) #define SCTP_IPV6_V6ONLY(sctp_inpcb) ((sctp_inpcb)->ip_inp.inp.inp_flags & IN6P_IPV6_V6ONLY)
/* is the socket non-blocking? */ /* is the socket non-blocking? */
#define SCTP_SO_IS_NBIO(so) ((so)->so_state & SS_NBIO) #define SCTP_SO_IS_NBIO(so) ((so)->so_state & SS_NBIO)
#define SCTP_SET_SO_NBIO(so) ((so)->so_state |= SS_NBIO) #define SCTP_SET_SO_NBIO(so) ((so)->so_state |= SS_NBIO)
@ -1007,11 +965,6 @@ int sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af);
#define SCTP_SB_LIMIT_RCV(so) so->so_rcv.sb_hiwat #define SCTP_SB_LIMIT_RCV(so) so->so_rcv.sb_hiwat
#define SCTP_SB_LIMIT_SND(so) so->so_snd.sb_hiwat #define SCTP_SB_LIMIT_SND(so) so->so_snd.sb_hiwat
/* Future zero copy wakeup/send function */
#define SCTP_ZERO_COPY_EVENT(inp, so)
/* This is re-pulse ourselves for sendbuf */
#define SCTP_ZERO_COPY_SENDQ_EVENT(inp, so)
#define SCTP_READ_RANDOM(buf, len) read_random(buf, len) #define SCTP_READ_RANDOM(buf, len) read_random(buf, len)
#define SCTP_SHA1_CTX struct sctp_sha1_context #define SCTP_SHA1_CTX struct sctp_sha1_context
@ -1025,7 +978,7 @@ int sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af);
/* sctp_pcb.h */ /* sctp_pcb.h */
#if defined(__Userspace_os_Windows) #if defined(_WIN32)
#define SHUT_RD 1 #define SHUT_RD 1
#define SHUT_WR 2 #define SHUT_WR 2
#define SHUT_RDWR 3 #define SHUT_RDWR 3
@ -1044,12 +997,22 @@ int sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af);
struct sockaddr_conn { struct sockaddr_conn {
#ifdef HAVE_SCONN_LEN #ifdef HAVE_SCONN_LEN
uint8_t sconn_len; uint8_t sconn_len;
#endif
uint8_t sconn_family; uint8_t sconn_family;
#else
uint16_t sconn_family;
#endif
uint16_t sconn_port; uint16_t sconn_port;
void *sconn_addr; void *sconn_addr;
}; };
typedef void *(*start_routine_t)(void *);
extern int
sctp_userspace_thread_create(userland_thread_t *thread, start_routine_t start_routine);
void
sctp_userspace_set_threadname(const char *name);
/* /*
* SCTP protocol specific mbuf flags. * SCTP protocol specific mbuf flags.
*/ */
@ -1088,7 +1051,7 @@ extern void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak,
{ \ { \
if (stcb && stcb->sctp_ep) \ if (stcb && stcb->sctp_ep) \
result = ip6_output(o_pak, \ result = ip6_output(o_pak, \
((struct in6pcb *)(stcb->sctp_ep))->in6p_outputopts, \ ((struct inpcb *)(stcb->sctp_ep))->in6p_outputopts, \
(ro), 0, 0, ifp, NULL); \ (ro), 0, 0, ifp, NULL); \
else \ else \
result = ip6_output(o_pak, NULL, (ro), 0, 0, ifp, NULL); \ result = ip6_output(o_pak, NULL, (ro), 0, 0, ifp, NULL); \
@ -1102,12 +1065,12 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int a
/* with the current included files, this is defined in Linux but /* with the current included files, this is defined in Linux but
* in FreeBSD, it is behind a _KERNEL in sys/socket.h ... * in FreeBSD, it is behind a _KERNEL in sys/socket.h ...
*/ */
#if defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) || defined(__Userspace_os_NaCl) #if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__native_client__)
/* stolen from /usr/include/sys/socket.h */ /* stolen from /usr/include/sys/socket.h */
#define CMSG_ALIGN(n) _ALIGN(n) #define CMSG_ALIGN(n) _ALIGN(n)
#elif defined(__Userspace_os_NetBSD) #elif defined(__NetBSD__)
#define CMSG_ALIGN(n) (((n) + __ALIGNBYTES) & ~__ALIGNBYTES) #define CMSG_ALIGN(n) (((n) + __ALIGNBYTES) & ~__ALIGNBYTES)
#elif defined(__Userspace_os_Darwin) #elif defined(__APPLE__)
#if !defined(__DARWIN_ALIGNBYTES) #if !defined(__DARWIN_ALIGNBYTES)
#define __DARWIN_ALIGNBYTES (sizeof(__darwin_size_t) - 1) #define __DARWIN_ALIGNBYTES (sizeof(__darwin_size_t) - 1)
#endif #endif
@ -1127,7 +1090,7 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int a
#endif #endif
#define I_AM_HERE \ #define I_AM_HERE \
do { \ do { \
SCTP_PRINTF("%s:%d at %s\n", __FILE__, __LINE__ , __FUNCTION__); \ SCTP_PRINTF("%s:%d at %s\n", __FILE__, __LINE__ , __func__); \
} while (0) } while (0)
#ifndef timevalsub #ifndef timevalsub
@ -1142,7 +1105,7 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int a
} while (0) } while (0)
#endif #endif
#if defined(__Userspace_os_Linux) #if defined(__linux__)
#if !defined(TAILQ_FOREACH_SAFE) #if !defined(TAILQ_FOREACH_SAFE)
#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ #define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = ((head)->tqh_first); \ for ((var) = ((head)->tqh_first); \
@ -1156,16 +1119,23 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int a
(var) = (tvar)) (var) = (tvar))
#endif #endif
#endif #endif
#if defined(__Userspace_os_DragonFly) #if defined(__DragonFly__)
#define TAILQ_FOREACH_SAFE TAILQ_FOREACH_MUTABLE #define TAILQ_FOREACH_SAFE TAILQ_FOREACH_MUTABLE
#define LIST_FOREACH_SAFE LIST_FOREACH_MUTABLE #define LIST_FOREACH_SAFE LIST_FOREACH_MUTABLE
#endif #endif
#if defined(__Userspace_os_NaCl) #if defined(__native_client__)
#define timercmp(tvp, uvp, cmp) \ #define timercmp(tvp, uvp, cmp) \
(((tvp)->tv_sec == (uvp)->tv_sec) ? \ (((tvp)->tv_sec == (uvp)->tv_sec) ? \
((tvp)->tv_usec cmp (uvp)->tv_usec) : \ ((tvp)->tv_usec cmp (uvp)->tv_usec) : \
((tvp)->tv_sec cmp (uvp)->tv_sec)) ((tvp)->tv_sec cmp (uvp)->tv_sec))
#endif #endif
#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__) || defined(__EMSCRIPTEN__)
int
timingsafe_bcmp(const void *, const void *, size_t);
#endif
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.h 272751 2014-10-08 15:30:59Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_output.h 366114 2020-09-24 12:26:06Z tuexen $");
#endif #endif
#ifndef _NETINET_SCTP_OUTPUT_H_ #ifndef _NETINET_SCTP_OUTPUT_H_
@ -42,7 +44,6 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_output.h 272751 2014-10-08 15:30:59Z t
#if defined(_KERNEL) || defined(__Userspace__) #if defined(_KERNEL) || defined(__Userspace__)
struct mbuf * struct mbuf *
sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp,
struct sctp_tcb *stcb, struct sctp_tcb *stcb,
@ -51,10 +52,8 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp,
int cnt_inits_to, int cnt_inits_to,
uint16_t *padding_len, uint16_t *chunk_len); uint16_t *padding_len, uint16_t *chunk_len);
int sctp_is_addr_restricted(struct sctp_tcb *, struct sctp_ifa *); int sctp_is_addr_restricted(struct sctp_tcb *, struct sctp_ifa *);
int int
sctp_is_address_in_scope(struct sctp_ifa *ifa, sctp_is_address_in_scope(struct sctp_ifa *ifa,
struct sctp_scoping *scope, struct sctp_scoping *scope,
@ -70,35 +69,31 @@ sctp_source_address_selection(struct sctp_inpcb *inp,
int non_asoc_addr_ok, uint32_t vrf_id); int non_asoc_addr_ok, uint32_t vrf_id);
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Userspace__) #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Userspace__)
int int sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t *ro);
sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t *ro);
int int sctp_v4src_match_nexthop(struct sctp_ifa *sifa, sctp_route_t *ro);
sctp_v4src_match_nexthop(struct sctp_ifa *sifa, sctp_route_t *ro);
#endif #endif
void sctp_send_initiate(struct sctp_inpcb *, struct sctp_tcb *, int void sctp_send_initiate(struct sctp_inpcb *, struct sctp_tcb *, int);
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif
);
void void
sctp_send_initiate_ack(struct sctp_inpcb *, struct sctp_tcb *, struct mbuf *, sctp_send_initiate_ack(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *, struct mbuf *,
int, int, int, int,
struct sockaddr *, struct sockaddr *, struct sockaddr *, struct sockaddr *,
struct sctphdr *, struct sctp_init_chunk *, struct sctphdr *, struct sctp_init_chunk *,
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
uint8_t, uint32_t, uint8_t, uint32_t,
#endif #endif
uint32_t, uint16_t, int); uint32_t, uint16_t);
struct mbuf * struct mbuf *
sctp_arethere_unrecognized_parameters(struct mbuf *, int, int *, sctp_arethere_unrecognized_parameters(struct mbuf *, int, int *,
struct sctp_chunkhdr *, int *); struct sctp_chunkhdr *, int *, int *);
void sctp_queue_op_err(struct sctp_tcb *, struct mbuf *); void sctp_queue_op_err(struct sctp_tcb *, struct mbuf *);
int int
sctp_send_cookie_echo(struct mbuf *, int, struct sctp_tcb *, 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_cookie_ack(struct sctp_tcb *);
@ -112,7 +107,6 @@ sctp_remove_from_wheel(struct sctp_tcb *stcb,
struct sctp_association *asoc, struct sctp_association *asoc,
struct sctp_stream_out *strq, int holds_lock); struct sctp_stream_out *strq, int holds_lock);
void sctp_send_shutdown(struct sctp_tcb *, struct sctp_nets *); void sctp_send_shutdown(struct sctp_tcb *, struct sctp_nets *);
void sctp_send_shutdown_ack(struct sctp_tcb *, struct sctp_nets *); void sctp_send_shutdown_ack(struct sctp_tcb *, struct sctp_nets *);
@ -121,8 +115,8 @@ void sctp_send_shutdown_complete(struct sctp_tcb *, struct sctp_nets *, int);
void sctp_send_shutdown_complete2(struct sockaddr *, struct sockaddr *, void sctp_send_shutdown_complete2(struct sockaddr *, struct sockaddr *,
struct sctphdr *, struct sctphdr *,
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
uint8_t, uint32_t, uint8_t, uint32_t, uint16_t,
#endif #endif
uint32_t, uint16_t); uint32_t, uint16_t);
@ -140,11 +134,15 @@ void sctp_fix_ecn_echo(struct sctp_association *);
void sctp_move_chunks_from_net(struct sctp_tcb *stcb, struct sctp_nets *net); void sctp_move_chunks_from_net(struct sctp_tcb *stcb, struct sctp_nets *net);
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 #define SCTP_DATA_CHUNK_OVERHEAD(stcb) ((stcb)->asoc.idata_supported ? \
sizeof(struct sctp_idata_chunk) : \
sizeof(struct sctp_data_chunk))
#if defined(__FreeBSD__) && !defined(__Userspace__)
int int
sctp_output(struct sctp_inpcb *, struct mbuf *, struct sockaddr *, sctp_output(struct sctp_inpcb *, struct mbuf *, struct sockaddr *,
struct mbuf *, struct thread *, int); struct mbuf *, struct thread *, int);
#elif defined(__Windows__) #elif defined(_WIN32) && !defined(__Userspace__)
sctp_output(struct sctp_inpcb *, struct mbuf *, struct sockaddr *, sctp_output(struct sctp_inpcb *, struct mbuf *, struct sockaddr *,
struct mbuf *, PKTHREAD, int); struct mbuf *, PKTHREAD, int);
#else #else
@ -153,30 +151,15 @@ sctp_output(struct sctp_inpcb *, struct mbuf *, struct sockaddr *,
#endif #endif
int int
sctp_output(struct sctp_inpcb *, sctp_output(struct sctp_inpcb *,
#if defined(__Panda__)
pakhandle_type,
#else
struct mbuf *, struct mbuf *,
#endif
struct sockaddr *, struct sockaddr *,
#if defined(__Panda__)
pakhandle_type,
#else
struct mbuf *, struct mbuf *,
#endif
struct proc *, int); struct proc *, int);
#endif #endif
void sctp_chunk_output(struct sctp_inpcb *, struct sctp_tcb *, int, int void sctp_chunk_output(struct sctp_inpcb *, struct sctp_tcb *, int, int);
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED void sctp_send_abort_tcb(struct sctp_tcb *, struct mbuf *, int);
#endif
);
void sctp_send_abort_tcb(struct sctp_tcb *, struct mbuf *, int
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif
);
void send_forward_tsn(struct sctp_tcb *, struct sctp_association *); void send_forward_tsn(struct sctp_tcb *, struct sctp_association *);
@ -186,43 +169,43 @@ void sctp_send_hb(struct sctp_tcb *, struct sctp_nets *, int);
void sctp_send_ecn_echo(struct sctp_tcb *, struct sctp_nets *, uint32_t); void sctp_send_ecn_echo(struct sctp_tcb *, struct sctp_nets *, uint32_t);
void void
sctp_send_packet_dropped(struct sctp_tcb *, struct sctp_nets *, struct mbuf *, sctp_send_packet_dropped(struct sctp_tcb *, struct sctp_nets *, struct mbuf *,
int, int, int); int, int, int);
void sctp_send_cwr(struct sctp_tcb *, struct sctp_nets *, uint32_t, uint8_t); void sctp_send_cwr(struct sctp_tcb *, struct sctp_nets *, uint32_t, uint8_t);
void
sctp_add_stream_reset_out(struct sctp_tmit_chunk *,
int, uint16_t *, uint32_t, uint32_t, uint32_t);
void void
sctp_add_stream_reset_result(struct sctp_tmit_chunk *, uint32_t, uint32_t); 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);
void void
sctp_add_stream_reset_result_tsn(struct sctp_tmit_chunk *, sctp_add_stream_reset_result_tsn(struct sctp_tmit_chunk *,
uint32_t, uint32_t, uint32_t, uint32_t); uint32_t, uint32_t, uint32_t, uint32_t);
int
sctp_send_stream_reset_out_if_possible(struct sctp_tcb *, int);
int int
sctp_send_str_reset_req(struct sctp_tcb *, uint16_t , uint16_t *, uint8_t, sctp_send_str_reset_req(struct sctp_tcb *, uint16_t , uint16_t *,
uint8_t, uint8_t, uint8_t, uint16_t, uint16_t, uint8_t); uint8_t, uint8_t, uint8_t, uint16_t, uint16_t, uint8_t);
void void
sctp_send_abort(struct mbuf *, int, struct sockaddr *, struct sockaddr *, sctp_send_abort(struct mbuf *, int, struct sockaddr *, struct sockaddr *,
struct sctphdr *, uint32_t, struct mbuf *, struct sctphdr *, uint32_t, struct mbuf *,
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
uint8_t, uint32_t, uint8_t, uint32_t, uint16_t,
#endif #endif
uint32_t, uint16_t); uint32_t, uint16_t);
void sctp_send_operr_to(struct sockaddr *, struct sockaddr *, void
sctp_send_operr_to(struct sockaddr *, struct sockaddr *,
struct sctphdr *, uint32_t, struct mbuf *, struct sctphdr *, uint32_t, struct mbuf *,
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
uint8_t, uint32_t, uint8_t, uint32_t, uint16_t,
#endif #endif
uint32_t, uint16_t); uint32_t, uint16_t);
@ -233,20 +216,15 @@ int
sctp_sosend(struct socket *so, sctp_sosend(struct socket *so,
struct sockaddr *addr, struct sockaddr *addr,
struct uio *uio, struct uio *uio,
#ifdef __Panda__
pakhandle_type top,
pakhandle_type control,
#else
struct mbuf *top, struct mbuf *top,
struct mbuf *control, struct mbuf *control,
#endif #if defined(__APPLE__) && !defined(__Userspace__)
#if defined(__APPLE__) || defined(__Panda__)
int flags int flags
#else #else
int flags, int flags,
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 #if defined(__FreeBSD__) && !defined(__Userspace__)
struct thread *p struct thread *p
#elif defined(__Windows__) #elif defined(_WIN32) && !defined(__Userspace__)
PKTHREAD p PKTHREAD p
#else #else
#if defined(__Userspace__) #if defined(__Userspace__)

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 279859 2015-03-10 19:49:25Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 365071 2020-09-01 21:19:14Z mjg $");
#endif #endif
#ifndef _NETINET_SCTP_PCB_H_ #ifndef _NETINET_SCTP_PCB_H_
@ -109,7 +111,7 @@ struct sctp_ifa {
* appropriate locks. This is for V6. * appropriate locks. This is for V6.
*/ */
union sctp_sockstore address; union sctp_sockstore address;
uint32_t refcount; /* number of folks refering to this */ uint32_t refcount; /* number of folks referring to this */
uint32_t flags; uint32_t flags;
uint32_t localifa_flags; uint32_t localifa_flags;
uint32_t vrf_id; /* vrf_id of this addr (for deleting) */ uint32_t vrf_id; /* vrf_id of this addr (for deleting) */
@ -145,9 +147,8 @@ struct sctp_tagblock {
struct sctp_timewait vtag_block[SCTP_NUMBER_IN_VTAG_BLOCK]; struct sctp_timewait vtag_block[SCTP_NUMBER_IN_VTAG_BLOCK];
}; };
struct sctp_epinfo { struct sctp_epinfo {
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
#ifdef INET #ifdef INET
struct socket *udp4_tun_socket; struct socket *udp4_tun_socket;
#endif #endif
@ -187,7 +188,7 @@ struct sctp_epinfo {
struct sctppcbhead listhead; struct sctppcbhead listhead;
struct sctpladdr addr_wq; struct sctpladdr addr_wq;
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
struct inpcbhead inplisthead; struct inpcbhead inplisthead;
struct inpcbinfo sctbinfo; struct inpcbinfo sctbinfo;
#endif #endif
@ -202,18 +203,10 @@ struct sctp_epinfo {
sctp_zone_t ipi_zone_asconf; sctp_zone_t ipi_zone_asconf;
sctp_zone_t ipi_zone_asconf_ack; sctp_zone_t ipi_zone_asconf_ack;
#if defined(__FreeBSD__) && __FreeBSD_version >= 503000 #if defined(__FreeBSD__) && !defined(__Userspace__)
#if __FreeBSD_version <= 602000
struct mtx ipi_ep_mtx;
#else
struct rwlock ipi_ep_mtx; struct rwlock ipi_ep_mtx;
#endif
struct mtx ipi_iterator_wq_mtx; struct mtx ipi_iterator_wq_mtx;
#if __FreeBSD_version <= 602000
struct mtx ipi_addr_mtx;
#else
struct rwlock ipi_addr_mtx; struct rwlock ipi_addr_mtx;
#endif
struct mtx ipi_pktlog_mtx; struct mtx ipi_pktlog_mtx;
struct mtx wq_addr_mtx; struct mtx wq_addr_mtx;
#elif defined(SCTP_PROCESS_LEVEL_LOCKS) #elif defined(SCTP_PROCESS_LEVEL_LOCKS)
@ -222,7 +215,7 @@ struct sctp_epinfo {
userland_mutex_t ipi_count_mtx; userland_mutex_t ipi_count_mtx;
userland_mutex_t ipi_pktlog_mtx; userland_mutex_t ipi_pktlog_mtx;
userland_mutex_t wq_addr_mtx; userland_mutex_t wq_addr_mtx;
#elif defined(__APPLE__) #elif defined(__APPLE__) && !defined(__Userspace__)
#ifdef _KERN_LOCKS_H_ #ifdef _KERN_LOCKS_H_
lck_mtx_t *ipi_addr_mtx; lck_mtx_t *ipi_addr_mtx;
lck_mtx_t *ipi_count_mtx; lck_mtx_t *ipi_count_mtx;
@ -233,13 +226,12 @@ struct sctp_epinfo {
void *ipi_count_mtx; void *ipi_count_mtx;
void *logging_mtx; void *logging_mtx;
#endif /* _KERN_LOCKS_H_ */ #endif /* _KERN_LOCKS_H_ */
#elif defined(__Windows__) #elif defined(_WIN32) && !defined(__Userspace__)
struct rwlock ipi_ep_lock; struct rwlock ipi_ep_lock;
struct rwlock ipi_addr_lock; struct rwlock ipi_addr_lock;
struct spinlock ipi_pktlog_mtx; struct spinlock ipi_pktlog_mtx;
struct rwlock wq_addr_mtx; struct rwlock wq_addr_mtx;
#elif defined(__Userspace__) #elif defined(__Userspace__)
/* TODO decide on __Userspace__ locks */
#endif #endif
uint32_t ipi_count_ep; uint32_t ipi_count_ep;
@ -284,14 +276,17 @@ struct sctp_epinfo {
#endif #endif
}; };
struct sctp_base_info { struct sctp_base_info {
/* All static structures that /* All static structures that
* anchor the system must be here. * anchor the system must be here.
*/ */
struct sctp_epinfo sctppcbinfo; struct sctp_epinfo sctppcbinfo;
#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT) #if defined(__FreeBSD__) && !defined(__Userspace__)
#if defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
struct sctpstat *sctpstat; struct sctpstat *sctpstat;
#else
struct sctpstat sctpstat;
#endif
#else #else
struct sctpstat sctpstat; struct sctpstat sctpstat;
#endif #endif
@ -303,33 +298,50 @@ struct sctp_base_info {
int packet_log_end; int packet_log_end;
uint8_t packet_log_buffer[SCTP_PACKET_LOG_SIZE]; uint8_t packet_log_buffer[SCTP_PACKET_LOG_SIZE];
#endif #endif
#if defined(__APPLE__) #if defined(__FreeBSD__) && !defined(__Userspace__)
eventhandler_tag eh_tag;
#endif
#if defined(__APPLE__) && !defined(__Userspace__)
int sctp_main_timer_ticks; int sctp_main_timer_ticks;
#endif #endif
#if defined(__Userspace__) #if defined(__Userspace__)
userland_mutex_t timer_mtx; userland_mutex_t timer_mtx;
userland_thread_t timer_thread; userland_thread_t timer_thread;
uint8_t timer_thread_should_exit; int timer_thread_should_exit;
#if !defined(__Userspace_os_Windows) int iterator_thread_started;
int timer_thread_started;
#if !defined(_WIN32)
pthread_mutexattr_t mtx_attr;
#if defined(INET) || defined(INET6) #if defined(INET) || defined(INET6)
int userspace_route; int userspace_route;
userland_thread_t recvthreadroute; userland_thread_t recvthreadroute;
#endif #endif
#endif #endif
#ifdef INET #ifdef INET
#if defined(_WIN32) && !defined(__MINGW32__)
SOCKET userspace_rawsctp;
SOCKET userspace_udpsctp;
#else
int userspace_rawsctp; int userspace_rawsctp;
int userspace_udpsctp; int userspace_udpsctp;
#endif
userland_thread_t recvthreadraw; userland_thread_t recvthreadraw;
userland_thread_t recvthreadudp; userland_thread_t recvthreadudp;
#endif #endif
#ifdef INET6 #ifdef INET6
#if defined(_WIN32) && !defined(__MINGW32__)
SOCKET userspace_rawsctp6;
SOCKET userspace_udpsctp6;
#else
int userspace_rawsctp6; int userspace_rawsctp6;
int userspace_udpsctp6; int userspace_udpsctp6;
#endif
userland_thread_t recvthreadraw6; userland_thread_t recvthreadraw6;
userland_thread_t recvthreadudp6; userland_thread_t recvthreadudp6;
#endif #endif
int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df); int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df);
void (*debug_printf)(const char *format, ...); void (*debug_printf)(const char *format, ...);
int crc32c_offloaded;
#endif #endif
}; };
@ -344,11 +356,11 @@ struct sctp_pcb {
uint32_t secret_key[SCTP_HOW_MANY_SECRETS][SCTP_NUMBER_OF_SECRETS]; uint32_t secret_key[SCTP_HOW_MANY_SECRETS][SCTP_NUMBER_OF_SECRETS];
unsigned int size_of_a_cookie; unsigned int size_of_a_cookie;
unsigned int sctp_timeoutticks[SCTP_NUM_TMRS]; uint32_t sctp_timeoutticks[SCTP_NUM_TMRS];
unsigned int sctp_minrto; uint32_t sctp_minrto;
unsigned int sctp_maxrto; uint32_t sctp_maxrto;
unsigned int initial_rto; uint32_t initial_rto;
int initial_init_rto_max; uint32_t initial_init_rto_max;
unsigned int sctp_sack_freq; unsigned int sctp_sack_freq;
uint32_t sctp_sws_sender; uint32_t sctp_sws_sender;
@ -361,6 +373,7 @@ struct sctp_pcb {
sctp_auth_chklist_t *local_auth_chunks; sctp_auth_chklist_t *local_auth_chunks;
sctp_hmaclist_t *local_hmacs; sctp_hmaclist_t *local_hmacs;
uint16_t default_keyid; uint16_t default_keyid;
uint32_t default_mtu;
/* various thresholds */ /* various thresholds */
/* Max times I will init at a guy */ /* Max times I will init at a guy */
@ -388,13 +401,9 @@ struct sctp_pcb {
*/ */
struct sctp_timer signature_change; struct sctp_timer signature_change;
/* Zero copy full buffer timer */
struct sctp_timer zero_copy_timer;
/* Zero copy app to transport (sendq) read repulse timer */
struct sctp_timer zero_copy_sendq_timer;
uint32_t def_cookie_life; uint32_t def_cookie_life;
/* defaults to 0 */ /* defaults to 0 */
int auto_close_time; uint32_t auto_close_time;
uint32_t initial_sequence_debug; uint32_t initial_sequence_debug;
uint32_t adaptation_layer_indicator; uint32_t adaptation_layer_indicator;
uint8_t adaptation_layer_indicator_provided; uint8_t adaptation_layer_indicator_provided;
@ -429,19 +438,17 @@ struct sctp_pcbtsn_rlog {
}; };
#define SCTP_READ_LOG_SIZE 135 /* we choose the number to make a pcb a page */ #define SCTP_READ_LOG_SIZE 135 /* we choose the number to make a pcb a page */
struct sctp_inpcb { struct sctp_inpcb {
/*- /*-
* put an inpcb in front of it all, kind of a waste but we need to * put an inpcb in front of it all, kind of a waste but we need to
* for compatability with all the other stuff. * for compatibility with all the other stuff.
*/ */
union { union {
struct inpcb inp; struct inpcb inp;
char align[(sizeof(struct in6pcb) + SCTP_ALIGNM1) & char align[(sizeof(struct inpcb) + SCTP_ALIGNM1) &
~SCTP_ALIGNM1]; ~SCTP_ALIGNM1];
} ip_inp; } ip_inp;
#if defined(__APPLE__) && !defined(__Userspace__)
#if defined(__APPLE__)
/* leave some space in case i386 inpcb is bigger than ppc */ /* leave some space in case i386 inpcb is bigger than ppc */
uint8_t padding[128]; uint8_t padding[128];
#endif #endif
@ -484,6 +491,7 @@ struct sctp_inpcb {
uint8_t ecn_supported; uint8_t ecn_supported;
uint8_t prsctp_supported; uint8_t prsctp_supported;
uint8_t auth_supported; uint8_t auth_supported;
uint8_t idata_supported;
uint8_t asconf_supported; uint8_t asconf_supported;
uint8_t reconfig_supported; uint8_t reconfig_supported;
uint8_t nrsack_supported; uint8_t nrsack_supported;
@ -497,26 +505,9 @@ struct sctp_inpcb {
* they are candidates with sctp_sendm for * they are candidates with sctp_sendm for
* de-supporting. * de-supporting.
*/ */
#ifdef __Panda__
pakhandle_type pak_to_read;
pakhandle_type pak_to_read_sendq;
#endif
struct mbuf *pkt, *pkt_last; struct mbuf *pkt, *pkt_last;
struct mbuf *control; struct mbuf *control;
#if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__)) #if defined(__FreeBSD__) && !defined(__Userspace__)
#ifndef INP_IPV6
#define INP_IPV6 0x1
#endif
#ifndef INP_IPV4
#define INP_IPV4 0x2
#endif
uint8_t inp_vflag;
/* TODO __Userspace__ where is our inp_vlag going to be? */
uint8_t inp_ip_ttl;
uint8_t inp_ip_tos; /* defined as macro in user_inpcb.h */
uint8_t inp_ip_resv;
#endif
#if defined(__FreeBSD__) && __FreeBSD_version >= 503000
struct mtx inp_mtx; struct mtx inp_mtx;
struct mtx inp_create_mtx; struct mtx inp_create_mtx;
struct mtx inp_rdata_mtx; struct mtx inp_rdata_mtx;
@ -526,7 +517,7 @@ struct sctp_inpcb {
userland_mutex_t inp_create_mtx; userland_mutex_t inp_create_mtx;
userland_mutex_t inp_rdata_mtx; userland_mutex_t inp_rdata_mtx;
int32_t refcount; int32_t refcount;
#elif defined(__APPLE__) #elif defined(__APPLE__) && !defined(__Userspace__)
#if defined(SCTP_APPLE_RWLOCK) #if defined(SCTP_APPLE_RWLOCK)
lck_rw_t *inp_mtx; lck_rw_t *inp_mtx;
#else #else
@ -534,16 +525,15 @@ struct sctp_inpcb {
#endif #endif
lck_mtx_t *inp_create_mtx; lck_mtx_t *inp_create_mtx;
lck_mtx_t *inp_rdata_mtx; lck_mtx_t *inp_rdata_mtx;
#elif defined(__Windows__) #elif defined(_WIN32) && !defined(__Userspace__)
struct rwlock inp_lock; struct rwlock inp_lock;
struct spinlock inp_create_lock; struct spinlock inp_create_lock;
struct spinlock inp_rdata_lock; struct spinlock inp_rdata_lock;
int32_t refcount; int32_t refcount;
#elif defined(__Userspace__) #elif defined(__Userspace__)
/* TODO decide on __Userspace__ locks */
int32_t refcount; int32_t refcount;
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
int32_t refcount; int32_t refcount;
uint32_t lock_caller1; uint32_t lock_caller1;
@ -564,6 +554,7 @@ struct sctp_inpcb {
uint32_t i_am_here_line; uint32_t i_am_here_line;
#endif #endif
uint32_t def_vrf_id; uint32_t def_vrf_id;
uint16_t fibnum;
#ifdef SCTP_MVRF #ifdef SCTP_MVRF
uint32_t *m_vrf_ids; uint32_t *m_vrf_ids;
uint32_t num_vrfs; uint32_t num_vrfs;
@ -586,7 +577,7 @@ struct sctp_inpcb {
int (*recv_callback)(struct socket *, union sctp_sockstore, void *, size_t, int (*recv_callback)(struct socket *, union sctp_sockstore, void *, size_t,
struct sctp_rcvinfo, int, void *); struct sctp_rcvinfo, int, void *);
uint32_t send_sb_threshold; uint32_t send_sb_threshold;
int (*send_callback)(struct socket *, uint32_t); int (*send_callback)(struct socket *, uint32_t, void *);
#endif #endif
}; };
@ -594,8 +585,9 @@ struct sctp_inpcb {
int register_recv_cb (struct socket *, int register_recv_cb (struct socket *,
int (*)(struct socket *, union sctp_sockstore, void *, size_t, int (*)(struct socket *, union sctp_sockstore, void *, size_t,
struct sctp_rcvinfo, int, void *)); 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 register_ulp_info (struct socket *, void *);
int retrieve_ulp_info (struct socket *, void **);
#endif #endif
struct sctp_tcb { struct sctp_tcb {
@ -623,34 +615,30 @@ struct sctp_tcb {
int freed_from_where; int freed_from_where;
uint16_t rport; /* remote port in network format */ uint16_t rport; /* remote port in network format */
uint16_t resv; uint16_t resv;
#if defined(__FreeBSD__) && __FreeBSD_version >= 503000 #if defined(__FreeBSD__) && !defined(__Userspace__)
struct mtx tcb_mtx; struct mtx tcb_mtx;
struct mtx tcb_send_mtx; struct mtx tcb_send_mtx;
#elif defined(SCTP_PROCESS_LEVEL_LOCKS) #elif defined(SCTP_PROCESS_LEVEL_LOCKS)
userland_mutex_t tcb_mtx; userland_mutex_t tcb_mtx;
userland_mutex_t tcb_send_mtx; userland_mutex_t tcb_send_mtx;
#elif defined(__APPLE__) #elif defined(__APPLE__) && !defined(__Userspace__)
lck_mtx_t* tcb_mtx; lck_mtx_t* tcb_mtx;
lck_mtx_t* tcb_send_mtx; lck_mtx_t* tcb_send_mtx;
#elif defined(__Windows__) #elif defined(_WIN32) && !defined(__Userspace__)
struct spinlock tcb_lock; struct spinlock tcb_lock;
struct spinlock tcb_send_lock; struct spinlock tcb_send_lock;
#elif defined(__Userspace__) #elif defined(__Userspace__)
/* TODO decide on __Userspace__ locks */
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
uint32_t caller1; uint32_t caller1;
uint32_t caller2; uint32_t caller2;
uint32_t caller3; uint32_t caller3;
#endif #endif
}; };
#if defined(__FreeBSD__) && !defined(__Userspace__)
#if defined(__FreeBSD__) && __FreeBSD_version >= 503000
#include <netinet/sctp_lock_bsd.h> #include <netinet/sctp_lock_bsd.h>
#elif defined(__APPLE__) && !defined(__Userspace__)
#elif defined(__APPLE__)
/* /*
* Apple MacOS X 10.4 "Tiger" * Apple MacOS X 10.4 "Tiger"
*/ */
@ -661,7 +649,7 @@ struct sctp_tcb {
#include <netinet/sctp_process_lock.h> #include <netinet/sctp_process_lock.h>
#elif defined(__Windows__) #elif defined(_WIN32) && !defined(__Userspace__)
#include <netinet/sctp_lock_windows.h> #include <netinet/sctp_lock_windows.h>
@ -676,14 +664,13 @@ struct sctp_tcb {
#include <netinet/sctp_lock_empty.h> #include <netinet/sctp_lock_empty.h>
#endif #endif
/* TODO where to put non-_KERNEL things for __Userspace__? */
#if defined(_KERNEL) || defined(__Userspace__) #if defined(_KERNEL) || defined(__Userspace__)
/* Attention Julian, this is the extern that /* Attention Julian, this is the extern that
* goes with the base info. sctp_pcb.c has * goes with the base info. sctp_pcb.c has
* the real definition. * the real definition.
*/ */
#if defined(__FreeBSD__) && __FreeBSD_version >= 801000 #if defined(__FreeBSD__) && !defined(__Userspace__)
VNET_DECLARE(struct sctp_base_info, system_base_info); VNET_DECLARE(struct sctp_base_info, system_base_info);
#else #else
extern struct sctp_base_info system_base_info; extern struct sctp_base_info system_base_info;
@ -726,20 +713,17 @@ void sctp_update_ifn_mtu(uint32_t ifn_index, uint32_t mtu);
void sctp_free_ifn(struct sctp_ifn *sctp_ifnp); void sctp_free_ifn(struct sctp_ifn *sctp_ifnp);
void sctp_free_ifa(struct sctp_ifa *sctp_ifap); void sctp_free_ifa(struct sctp_ifa *sctp_ifap);
void sctp_del_addr_from_vrf(uint32_t vrfid, struct sockaddr *addr, void sctp_del_addr_from_vrf(uint32_t vrfid, struct sockaddr *addr,
uint32_t ifn_index, const char *if_name); uint32_t ifn_index, const char *if_name);
struct sctp_nets *sctp_findnet(struct sctp_tcb *, struct sockaddr *); struct sctp_nets *sctp_findnet(struct sctp_tcb *, struct sockaddr *);
struct sctp_inpcb *sctp_pcb_findep(struct sockaddr *, int, int, uint32_t); struct sctp_inpcb *sctp_pcb_findep(struct sockaddr *, int, int, uint32_t);
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 #if defined(__FreeBSD__) && !defined(__Userspace__)
int sctp_inpcb_bind(struct socket *, struct sockaddr *, int sctp_inpcb_bind(struct socket *, struct sockaddr *,
struct sctp_ifa *,struct thread *); struct sctp_ifa *,struct thread *);
#elif defined(__Windows__) #elif defined(_WIN32) && !defined(__Userspace__)
int sctp_inpcb_bind(struct socket *, struct sockaddr *, int sctp_inpcb_bind(struct socket *, struct sockaddr *,
struct sctp_ifa *,PKTHREAD); struct sctp_ifa *,PKTHREAD);
#else #else
@ -790,24 +774,28 @@ int sctp_is_address_on_local_host(struct sockaddr *addr, uint32_t vrf_id);
void sctp_inpcb_free(struct sctp_inpcb *, int, int); void sctp_inpcb_free(struct sctp_inpcb *, int, int);
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 #define SCTP_DONT_INITIALIZE_AUTH_PARAMS 0
#define SCTP_INITIALIZE_AUTH_PARAMS 1
#if defined(__FreeBSD__) && !defined(__Userspace__)
struct sctp_tcb * struct sctp_tcb *
sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *, sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *,
int *, uint32_t, uint32_t, struct thread *); int *, uint32_t, uint32_t, uint16_t, uint16_t, struct thread *,
#elif defined(__Windows__) int);
#elif defined(_WIN32) && !defined(__Userspace__)
struct sctp_tcb * struct sctp_tcb *
sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *, sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *,
int *, uint32_t, uint32_t, PKTHREAD); int *, uint32_t, uint32_t, uint16_t, uint16_t, PKTHREAD, int);
#else #else
/* proc will be NULL for __Userspace__ */ /* proc will be NULL for __Userspace__ */
struct sctp_tcb * struct sctp_tcb *
sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *, sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *,
int *, uint32_t, uint32_t, struct proc *); int *, uint32_t, uint32_t, uint16_t, uint16_t, struct proc *,
int);
#endif #endif
int sctp_free_assoc(struct sctp_inpcb *, struct sctp_tcb *, int, int); int sctp_free_assoc(struct sctp_inpcb *, struct sctp_tcb *, int, int);
void sctp_delete_from_timewait(uint32_t, uint16_t, uint16_t); 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); int sctp_is_in_timewait(uint32_t tag, uint16_t lport, uint16_t rport);
@ -817,19 +805,19 @@ sctp_add_vtag_to_timewait(uint32_t tag, uint32_t time, uint16_t lport, uint16_t
void sctp_add_local_addr_ep(struct sctp_inpcb *, struct sctp_ifa *, uint32_t); void sctp_add_local_addr_ep(struct sctp_inpcb *, struct sctp_ifa *, uint32_t);
int sctp_insert_laddr(struct sctpladdr *, struct sctp_ifa *, uint32_t);
void sctp_remove_laddr(struct sctp_laddr *);
void sctp_del_local_addr_ep(struct sctp_inpcb *, struct sctp_ifa *); void sctp_del_local_addr_ep(struct sctp_inpcb *, struct sctp_ifa *);
int sctp_add_remote_addr(struct sctp_tcb *, struct sockaddr *, struct sctp_nets **, int, int); int sctp_add_remote_addr(struct sctp_tcb *, struct sockaddr *, struct sctp_nets **, uint16_t, int, int);
void sctp_remove_net(struct sctp_tcb *, struct sctp_nets *); void sctp_remove_net(struct sctp_tcb *, struct sctp_nets *);
int sctp_del_remote_addr(struct sctp_tcb *, struct sockaddr *); int sctp_del_remote_addr(struct sctp_tcb *, struct sockaddr *);
#if defined(__Userspace__)
void sctp_pcb_init(int);
#else
void sctp_pcb_init(void); void sctp_pcb_init(void);
#endif
void sctp_pcb_finish(void); void sctp_pcb_finish(void);
@ -838,7 +826,7 @@ void sctp_del_local_addr_restricted(struct sctp_tcb *, struct sctp_ifa *);
int int
sctp_load_addresses_from_init(struct sctp_tcb *, struct mbuf *, int, int, sctp_load_addresses_from_init(struct sctp_tcb *, struct mbuf *, int, int,
struct sockaddr *, struct sockaddr *, struct sockaddr *); struct sockaddr *, struct sockaddr *, struct sockaddr *, uint16_t);
int int
sctp_set_primary_addr(struct sctp_tcb *, struct sockaddr *, sctp_set_primary_addr(struct sctp_tcb *, struct sockaddr *,
@ -846,11 +834,14 @@ sctp_set_primary_addr(struct sctp_tcb *, struct sockaddr *,
int sctp_is_vtag_good(uint32_t, uint16_t lport, uint16_t rport, struct timeval *); int sctp_is_vtag_good(uint32_t, uint16_t lport, uint16_t rport, struct timeval *);
/* void sctp_drain(void); */
int sctp_destination_is_reachable(struct sctp_tcb *, struct sockaddr *); int sctp_destination_is_reachable(struct sctp_tcb *, struct sockaddr *);
int sctp_swap_inpcb_for_listen(struct sctp_inpcb *inp); int sctp_swap_inpcb_for_listen(struct sctp_inpcb *inp);
void sctp_clean_up_stream(struct sctp_tcb *stcb, struct sctp_readhead *rh);
/*- /*-
* Null in last arg inpcb indicate run on ALL ep's. Specific inp in last arg * 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. * indicates run on ONLY assoc's of the specified endpoint.
@ -865,15 +856,12 @@ sctp_initiate_iterator(inp_func inpf,
end_func ef, end_func ef,
struct sctp_inpcb *, struct sctp_inpcb *,
uint8_t co_off); uint8_t co_off);
#if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP) #if defined(__FreeBSD__) && !defined(__Userspace__)
#if defined(SCTP_MCORE_INPUT) && defined(SMP)
void void
sctp_queue_to_mcore(struct mbuf *m, int off, int cpu_to_use); sctp_queue_to_mcore(struct mbuf *m, int off, int cpu_to_use);
#endif #endif
#ifdef INVARIANTS
void
sctp_validate_no_locks(struct sctp_inpcb *inp);
#endif #endif
#endif /* _KERNEL */ #endif /* _KERNEL */

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_peeloff.c 279859 2015-03-10 19:49:25Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_peeloff.c 362054 2020-06-11 13:34:09Z tuexen $");
#endif #endif
#include <netinet/sctp_os.h> #include <netinet/sctp_os.h>
@ -47,10 +49,6 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_peeloff.c 279859 2015-03-10 19:49:25Z
#include <netinet/sctputil.h> #include <netinet/sctputil.h>
#include <netinet/sctp_auth.h> #include <netinet/sctp_auth.h>
#if defined(__APPLE__)
#define APPLE_FILE_NO 5
#endif
int int
sctp_can_peel_off(struct socket *head, sctp_assoc_t assoc_id) sctp_can_peel_off(struct socket *head, sctp_assoc_t assoc_id)
{ {
@ -77,7 +75,7 @@ sctp_can_peel_off(struct socket *head, sctp_assoc_t assoc_id)
SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_PEELOFF, ENOENT); SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_PEELOFF, ENOENT);
return (ENOENT); return (ENOENT);
} }
state = SCTP_GET_STATE((&stcb->asoc)); state = SCTP_GET_STATE(stcb);
if ((state == SCTP_STATE_EMPTY) || if ((state == SCTP_STATE_EMPTY) ||
(state == SCTP_STATE_INUSE)) { (state == SCTP_STATE_INUSE)) {
SCTP_TCB_UNLOCK(stcb); SCTP_TCB_UNLOCK(stcb);
@ -107,7 +105,7 @@ sctp_do_peeloff(struct socket *head, struct socket *so, sctp_assoc_t assoc_id)
return (ENOTCONN); return (ENOTCONN);
} }
state = SCTP_GET_STATE((&stcb->asoc)); state = SCTP_GET_STATE(stcb);
if ((state == SCTP_STATE_EMPTY) || if ((state == SCTP_STATE_EMPTY) ||
(state == SCTP_STATE_INUSE)) { (state == SCTP_STATE_INUSE)) {
SCTP_TCB_UNLOCK(stcb); SCTP_TCB_UNLOCK(stcb);
@ -162,7 +160,7 @@ sctp_do_peeloff(struct socket *head, struct socket *so, sctp_assoc_t assoc_id)
atomic_add_int(&stcb->asoc.refcnt, 1); atomic_add_int(&stcb->asoc.refcnt, 1);
SCTP_TCB_UNLOCK(stcb); SCTP_TCB_UNLOCK(stcb);
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
sctp_pull_off_control_to_new_inp(inp, n_inp, stcb, SBL_WAIT); sctp_pull_off_control_to_new_inp(inp, n_inp, stcb, SBL_WAIT);
#else #else
sctp_pull_off_control_to_new_inp(inp, n_inp, stcb, M_WAITOK); sctp_pull_off_control_to_new_inp(inp, n_inp, stcb, M_WAITOK);
@ -176,14 +174,6 @@ sctp_do_peeloff(struct socket *head, struct socket *so, sctp_assoc_t assoc_id)
struct socket * struct socket *
sctp_get_peeloff(struct socket *head, sctp_assoc_t assoc_id, int *error) sctp_get_peeloff(struct socket *head, sctp_assoc_t assoc_id, int *error)
{ {
#if defined(__Userspace__)
/* if __Userspace__ chooses to originally not support peeloff, put it here... */
#endif
#if defined(__Panda__)
SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_PEELOFF, EINVAL);
*error = EINVAL;
return (NULL);
#else
struct socket *newso; struct socket *newso;
struct sctp_inpcb *inp, *n_inp; struct sctp_inpcb *inp, *n_inp;
struct sctp_tcb *stcb; struct sctp_tcb *stcb;
@ -203,18 +193,15 @@ sctp_get_peeloff(struct socket *head, sctp_assoc_t assoc_id, int *error)
} }
atomic_add_int(&stcb->asoc.refcnt, 1); atomic_add_int(&stcb->asoc.refcnt, 1);
SCTP_TCB_UNLOCK(stcb); SCTP_TCB_UNLOCK(stcb);
#if defined(__FreeBSD__) && __FreeBSD_version >= 801000 #if defined(__FreeBSD__) && !defined(__Userspace__)
CURVNET_SET(head->so_vnet); CURVNET_SET(head->so_vnet);
#endif #endif
newso = sonewconn(head, SS_ISCONNECTED newso = sonewconn(head, SS_ISCONNECTED
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
, NULL , NULL
#elif defined(__Panda__)
/* place this socket in the assoc's vrf id */
, NULL, stcb->asoc.vrf_id
#endif #endif
); );
#if defined(__FreeBSD__) && __FreeBSD_version >= 801000 #if defined(__FreeBSD__) && !defined(__Userspace__)
CURVNET_RESTORE(); CURVNET_RESTORE();
#endif #endif
if (newso == NULL) { if (newso == NULL) {
@ -225,7 +212,7 @@ sctp_get_peeloff(struct socket *head, sctp_assoc_t assoc_id, int *error)
return (NULL); return (NULL);
} }
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
else { else {
SCTP_SOCKET_LOCK(newso, 1); SCTP_SOCKET_LOCK(newso, 1);
} }
@ -280,11 +267,12 @@ sctp_get_peeloff(struct socket *head, sctp_assoc_t assoc_id, int *error)
SCTP_FROM_SCTP_PEELOFF + SCTP_LOC_1); SCTP_FROM_SCTP_PEELOFF + SCTP_LOC_1);
} }
/* Turn off any non-blocking semantic. */ /* Turn off any non-blocking semantic. */
SOCK_LOCK(newso);
SCTP_CLEAR_SO_NBIO(newso); SCTP_CLEAR_SO_NBIO(newso);
newso->so_state |= SS_ISCONNECTED; newso->so_state |= SS_ISCONNECTED;
SOCK_UNLOCK(newso);
/* We remove it right away */ /* We remove it right away */
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__)
#ifdef SCTP_LOCK_LOGGING #ifdef SCTP_LOCK_LOGGING
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) { if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) {
sctp_log_lock(inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_SOCK); sctp_log_lock(inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_SOCK);
@ -293,16 +281,6 @@ sctp_get_peeloff(struct socket *head, sctp_assoc_t assoc_id, int *error)
TAILQ_REMOVE(&head->so_comp, newso, so_list); TAILQ_REMOVE(&head->so_comp, newso, so_list);
head->so_qlen--; head->so_qlen--;
SOCK_UNLOCK(head); SOCK_UNLOCK(head);
#else
newso = TAILQ_FIRST(&head->so_q);
if (soqremque(newso, 1) == 0) {
SCTP_PRINTF("soremque failed, peeloff-fails (invarients would panic)\n");
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PEELOFF, ENOTCONN);
*error = ENOTCONN;
return (NULL);
}
#endif
/* /*
* Now we must move it from one hash table to another and get the * Now we must move it from one hash table to another and get the
* stcb in the right place. * stcb in the right place.
@ -314,13 +292,12 @@ sctp_get_peeloff(struct socket *head, sctp_assoc_t assoc_id, int *error)
* And now the final hack. We move data in the pending side i.e. * And now the final hack. We move data in the pending side i.e.
* head to the new socket buffer. Let the GRUBBING begin :-0 * head to the new socket buffer. Let the GRUBBING begin :-0
*/ */
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
sctp_pull_off_control_to_new_inp(inp, n_inp, stcb, SBL_WAIT); sctp_pull_off_control_to_new_inp(inp, n_inp, stcb, SBL_WAIT);
#else #else
sctp_pull_off_control_to_new_inp(inp, n_inp, stcb, M_WAITOK); sctp_pull_off_control_to_new_inp(inp, n_inp, stcb, M_WAITOK);
#endif #endif
atomic_subtract_int(&stcb->asoc.refcnt, 1); atomic_subtract_int(&stcb->asoc.refcnt, 1);
return (newso); return (newso);
#endif
} }
#endif #endif

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_peeloff.h 243516 2012-11-25 14:25:08Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_peeloff.h 309607 2016-12-06 10:21:25Z tuexen $");
#endif #endif
#ifndef _NETINET_SCTP_PEELOFF_H_ #ifndef _NETINET_SCTP_PEELOFF_H_
@ -40,13 +42,13 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_peeloff.h 243516 2012-11-25 14:25:08Z
#if defined(HAVE_SCTP_PEELOFF_SOCKOPT) #if defined(HAVE_SCTP_PEELOFF_SOCKOPT)
/* socket option peeloff */ /* socket option peeloff */
struct sctp_peeloff_opt { struct sctp_peeloff_opt {
#if !defined(__Windows__) #if !(defined(_WIN32) && !defined(__Userspace__))
int s; int s;
#else #else
HANDLE s; HANDLE s;
#endif #endif
sctp_assoc_t assoc_id; sctp_assoc_t assoc_id;
#if !defined(__Windows__) #if !(defined(_WIN32) && !defined(__Userspace__))
int new_sd; int new_sd;
#else #else
HANDLE new_sd; HANDLE new_sd;

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2011, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2011, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2011, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2011, by Michael Tuexen. All rights reserved.
@ -51,7 +53,7 @@
* per socket level locking * per socket level locking
*/ */
#if defined(__Userspace_os_Windows) #if defined(_WIN32)
/* Lock for INFO stuff */ /* Lock for INFO stuff */
#define SCTP_INP_INFO_LOCK_INIT() #define SCTP_INP_INFO_LOCK_INIT()
#define SCTP_INP_INFO_RLOCK() #define SCTP_INP_INFO_RLOCK()
@ -84,7 +86,9 @@
#define SCTP_INP_RLOCK(_inp) #define SCTP_INP_RLOCK(_inp)
#define SCTP_INP_RUNLOCK(_inp) #define SCTP_INP_RUNLOCK(_inp)
#define SCTP_INP_WLOCK(_inp) #define SCTP_INP_WLOCK(_inp)
#define SCTP_INP_WUNLOCK(_inep) #define SCTP_INP_WUNLOCK(_inp)
#define SCTP_INP_RLOCK_ASSERT(_inp)
#define SCTP_INP_WLOCK_ASSERT(_inp)
#define SCTP_INP_INCR_REF(_inp) #define SCTP_INP_INCR_REF(_inp)
#define SCTP_INP_DECR_REF(_inp) #define SCTP_INP_DECR_REF(_inp)
@ -113,7 +117,7 @@
*/ */
#define SCTP_IPI_COUNT_INIT() #define SCTP_IPI_COUNT_INIT()
#if defined(__Userspace_os_Windows) #if defined(_WIN32)
#define SCTP_WQ_ADDR_INIT() \ #define SCTP_WQ_ADDR_INIT() \
InitializeCriticalSection(&SCTP_BASE_INFO(wq_addr_mtx)) InitializeCriticalSection(&SCTP_BASE_INFO(wq_addr_mtx))
#define SCTP_WQ_ADDR_DESTROY() \ #define SCTP_WQ_ADDR_DESTROY() \
@ -122,7 +126,7 @@
EnterCriticalSection(&SCTP_BASE_INFO(wq_addr_mtx)) EnterCriticalSection(&SCTP_BASE_INFO(wq_addr_mtx))
#define SCTP_WQ_ADDR_UNLOCK() \ #define SCTP_WQ_ADDR_UNLOCK() \
LeaveCriticalSection(&SCTP_BASE_INFO(wq_addr_mtx)) LeaveCriticalSection(&SCTP_BASE_INFO(wq_addr_mtx))
#define SCTP_WQ_ADDR_LOCK_ASSERT()
#define SCTP_INP_INFO_LOCK_INIT() \ #define SCTP_INP_INFO_LOCK_INIT() \
InitializeCriticalSection(&SCTP_BASE_INFO(ipi_ep_mtx)) InitializeCriticalSection(&SCTP_BASE_INFO(ipi_ep_mtx))
@ -164,63 +168,53 @@
#define SCTP_INP_LOCK_INIT(_inp) \ #define SCTP_INP_LOCK_INIT(_inp) \
InitializeCriticalSection(&(_inp)->inp_mtx) InitializeCriticalSection(&(_inp)->inp_mtx)
#define SCTP_ASOC_CREATE_LOCK_INIT(_inp) \
InitializeCriticalSection(&(_inp)->inp_create_mtx)
#define SCTP_INP_LOCK_DESTROY(_inp) \ #define SCTP_INP_LOCK_DESTROY(_inp) \
DeleteCriticalSection(&(_inp)->inp_mtx) DeleteCriticalSection(&(_inp)->inp_mtx)
#define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp) \
DeleteCriticalSection(&(_inp)->inp_create_mtx)
#ifdef SCTP_LOCK_LOGGING #ifdef SCTP_LOCK_LOGGING
#define SCTP_INP_RLOCK(_inp) do { \ #define SCTP_INP_RLOCK(_inp) do { \
if(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_INP);\ if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_INP); \
EnterCriticalSection(&(_inp)->inp_mtx); \ EnterCriticalSection(&(_inp)->inp_mtx); \
} while (0) } while (0)
#define SCTP_INP_WLOCK(_inp) do { \ #define SCTP_INP_WLOCK(_inp) do { \
sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_INP);\ if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_INP); \
EnterCriticalSection(&(_inp)->inp_mtx); \ EnterCriticalSection(&(_inp)->inp_mtx); \
} while (0) } while (0)
#else #else
#define SCTP_INP_RLOCK(_inp) \
#define SCTP_INP_RLOCK(_inp) do { \ EnterCriticalSection(&(_inp)->inp_mtx)
EnterCriticalSection(&(_inp)->inp_mtx); \ #define SCTP_INP_WLOCK(_inp) \
} while (0) EnterCriticalSection(&(_inp)->inp_mtx)
#define SCTP_INP_WLOCK(_inp) do { \
EnterCriticalSection(&(_inp)->inp_mtx); \
} while (0)
#endif #endif
#define SCTP_INP_RLOCK_ASSERT(_tcb)
#define SCTP_INP_WLOCK_ASSERT(_tcb)
#define SCTP_TCB_SEND_LOCK_INIT(_tcb) \ #define SCTP_TCB_SEND_LOCK_INIT(_tcb) \
InitializeCriticalSection(&(_tcb)->tcb_send_mtx) InitializeCriticalSection(&(_tcb)->tcb_send_mtx)
#define SCTP_TCB_SEND_LOCK_DESTROY(_tcb) \ #define SCTP_TCB_SEND_LOCK_DESTROY(_tcb) \
DeleteCriticalSection(&(_tcb)->tcb_send_mtx) DeleteCriticalSection(&(_tcb)->tcb_send_mtx)
#define SCTP_TCB_SEND_LOCK(_tcb) \
#define SCTP_TCB_SEND_LOCK(_tcb) do { \ EnterCriticalSection(&(_tcb)->tcb_send_mtx)
EnterCriticalSection(&(_tcb)->tcb_send_mtx); \
} while (0)
#define SCTP_TCB_SEND_UNLOCK(_tcb) \ #define SCTP_TCB_SEND_UNLOCK(_tcb) \
LeaveCriticalSection(&(_tcb)->tcb_send_mtx) LeaveCriticalSection(&(_tcb)->tcb_send_mtx)
#define SCTP_INP_INCR_REF(_inp) atomic_add_int(&((_inp)->refcount), 1) #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_add_int(&((_inp)->refcount), -1)
#define SCTP_ASOC_CREATE_LOCK_INIT(_inp) \
InitializeCriticalSection(&(_inp)->inp_create_mtx)
#define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp) \
DeleteCriticalSection(&(_inp)->inp_create_mtx)
#ifdef SCTP_LOCK_LOGGING #ifdef SCTP_LOCK_LOGGING
#define SCTP_ASOC_CREATE_LOCK(_inp) do { \ #define SCTP_ASOC_CREATE_LOCK(_inp) do { \
if(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_CREATE); \ if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_CREATE); \
EnterCriticalSection(&(_inp)->inp_create_mtx); \ EnterCriticalSection(&(_inp)->inp_create_mtx); \
} while (0) } while (0)
#else #else
#define SCTP_ASOC_CREATE_LOCK(_inp) do { \ #define SCTP_ASOC_CREATE_LOCK(_inp) \
EnterCriticalSection(&(_inp)->inp_create_mtx); \ EnterCriticalSection(&(_inp)->inp_create_mtx)
} while (0)
#endif #endif
#define SCTP_INP_RUNLOCK(_inp) \ #define SCTP_INP_RUNLOCK(_inp) \
@ -240,65 +234,83 @@
#define SCTP_TCB_LOCK_INIT(_tcb) \ #define SCTP_TCB_LOCK_INIT(_tcb) \
InitializeCriticalSection(&(_tcb)->tcb_mtx) InitializeCriticalSection(&(_tcb)->tcb_mtx)
#define SCTP_TCB_LOCK_DESTROY(_tcb) \ #define SCTP_TCB_LOCK_DESTROY(_tcb) \
DeleteCriticalSection(&(_tcb)->tcb_mtx) DeleteCriticalSection(&(_tcb)->tcb_mtx)
#ifdef SCTP_LOCK_LOGGING #ifdef SCTP_LOCK_LOGGING
#define SCTP_TCB_LOCK(_tcb) do { \ #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); \ if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
sctp_log_lock(_tcb->sctp_ep, _tcb, SCTP_LOG_LOCK_TCB); \
EnterCriticalSection(&(_tcb)->tcb_mtx); \ EnterCriticalSection(&(_tcb)->tcb_mtx); \
} while (0) } while (0)
#else #else
#define SCTP_TCB_LOCK(_tcb) do { \ #define SCTP_TCB_LOCK(_tcb) \
EnterCriticalSection(&(_tcb)->tcb_mtx); \ EnterCriticalSection(&(_tcb)->tcb_mtx)
} while (0)
#endif #endif
#define SCTP_TCB_TRYLOCK(_tcb) ((TryEnterCriticalSection(&(_tcb)->tcb_mtx))) #define SCTP_TCB_TRYLOCK(_tcb) ((TryEnterCriticalSection(&(_tcb)->tcb_mtx)))
#define SCTP_TCB_UNLOCK(_tcb) \
#define SCTP_TCB_UNLOCK(_tcb) do { \ LeaveCriticalSection(&(_tcb)->tcb_mtx)
LeaveCriticalSection(&(_tcb)->tcb_mtx); \
} while (0)
#define SCTP_TCB_LOCK_ASSERT(_tcb) #define SCTP_TCB_LOCK_ASSERT(_tcb)
#else /* all Userspaces except Windows */ #else /* all Userspaces except Windows */
#define SCTP_WQ_ADDR_INIT() \ #define SCTP_WQ_ADDR_INIT() \
(void)pthread_mutex_init(&SCTP_BASE_INFO(wq_addr_mtx), NULL) (void)pthread_mutex_init(&SCTP_BASE_INFO(wq_addr_mtx), &SCTP_BASE_VAR(mtx_attr))
#define SCTP_WQ_ADDR_DESTROY() \ #define SCTP_WQ_ADDR_DESTROY() \
(void)pthread_mutex_destroy(&SCTP_BASE_INFO(wq_addr_mtx)) (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__))
#define SCTP_WQ_ADDR_UNLOCK() \
KASSERT(pthread_mutex_unlock(&SCTP_BASE_INFO(wq_addr_mtx)) == 0, ("%s: wq_addr_mtx not locked", __func__))
#else
#define SCTP_WQ_ADDR_LOCK() \ #define SCTP_WQ_ADDR_LOCK() \
(void)pthread_mutex_lock(&SCTP_BASE_INFO(wq_addr_mtx)) (void)pthread_mutex_lock(&SCTP_BASE_INFO(wq_addr_mtx))
#define SCTP_WQ_ADDR_UNLOCK() \ #define SCTP_WQ_ADDR_UNLOCK() \
(void)pthread_mutex_unlock(&SCTP_BASE_INFO(wq_addr_mtx)) (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__))
#define SCTP_INP_INFO_LOCK_INIT() \ #define SCTP_INP_INFO_LOCK_INIT() \
(void)pthread_mutex_init(&SCTP_BASE_INFO(ipi_ep_mtx), NULL) (void)pthread_mutex_init(&SCTP_BASE_INFO(ipi_ep_mtx), &SCTP_BASE_VAR(mtx_attr))
#define SCTP_INP_INFO_LOCK_DESTROY() \ #define SCTP_INP_INFO_LOCK_DESTROY() \
(void)pthread_mutex_destroy(&SCTP_BASE_INFO(ipi_ep_mtx)) (void)pthread_mutex_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__))
#define SCTP_INP_INFO_WLOCK() \
KASSERT(pthread_mutex_lock(&SCTP_BASE_INFO(ipi_ep_mtx)) == 0, ("%s: ipi_ep_mtx already locked", __func__))
#define SCTP_INP_INFO_RUNLOCK() \
KASSERT(pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_ep_mtx)) == 0, ("%s: ipi_ep_mtx not locked", __func__))
#define SCTP_INP_INFO_WUNLOCK() \
KASSERT(pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_ep_mtx)) == 0, ("%s: ipi_ep_mtx not locked", __func__))
#else
#define SCTP_INP_INFO_RLOCK() \ #define SCTP_INP_INFO_RLOCK() \
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_ep_mtx)) (void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_TRYLOCK() \
(!(pthread_mutex_trylock(&SCTP_BASE_INFO(ipi_ep_mtx))))
#define SCTP_INP_INFO_WLOCK() \ #define SCTP_INP_INFO_WLOCK() \
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_ep_mtx)) (void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_RUNLOCK() \ #define SCTP_INP_INFO_RUNLOCK() \
(void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_ep_mtx)) (void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_WUNLOCK() \ #define SCTP_INP_INFO_WUNLOCK() \
(void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_ep_mtx)) (void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_ep_mtx))
#endif
#define SCTP_INP_INFO_TRYLOCK() \
(!(pthread_mutex_trylock(&SCTP_BASE_INFO(ipi_ep_mtx))))
#define SCTP_IP_PKTLOG_INIT() \ #define SCTP_IP_PKTLOG_INIT() \
(void)pthread_mutex_init(&SCTP_BASE_INFO(ipi_pktlog_mtx), NULL) (void)pthread_mutex_init(&SCTP_BASE_INFO(ipi_pktlog_mtx), &SCTP_BASE_VAR(mtx_attr))
#define SCTP_IP_PKTLOG_DESTROY() \ #define SCTP_IP_PKTLOG_DESTROY() \
(void)pthread_mutex_destroy(&SCTP_BASE_INFO(ipi_pktlog_mtx)) (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__))
#define SCTP_IP_PKTLOG_UNLOCK() \
KASSERT(pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_pktlog_mtx)) == 0, ("%s: ipi_pktlog_mtx not locked", __func__))
#else
#define SCTP_IP_PKTLOG_LOCK() \ #define SCTP_IP_PKTLOG_LOCK() \
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_pktlog_mtx)) (void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_pktlog_mtx))
#define SCTP_IP_PKTLOG_UNLOCK() \ #define SCTP_IP_PKTLOG_UNLOCK() \
(void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_pktlog_mtx)) (void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_pktlog_mtx))
#endif
/* /*
@ -307,88 +319,124 @@
* or cookie secrets we lock the INP level. * or cookie secrets we lock the INP level.
*/ */
#define SCTP_INP_READ_INIT(_inp) \ #define SCTP_INP_READ_INIT(_inp) \
(void)pthread_mutex_init(&(_inp)->inp_rdata_mtx, NULL) (void)pthread_mutex_init(&(_inp)->inp_rdata_mtx, &SCTP_BASE_VAR(mtx_attr))
#define SCTP_INP_READ_DESTROY(_inp) \ #define SCTP_INP_READ_DESTROY(_inp) \
(void)pthread_mutex_destroy(&(_inp)->inp_rdata_mtx) (void)pthread_mutex_destroy(&(_inp)->inp_rdata_mtx)
#ifdef INVARIANTS
#define SCTP_INP_READ_LOCK(_inp) do { \ #define SCTP_INP_READ_LOCK(_inp) \
(void)pthread_mutex_lock(&(_inp)->inp_rdata_mtx); \ KASSERT(pthread_mutex_lock(&(_inp)->inp_rdata_mtx) == 0, ("%s: inp_rdata_mtx already locked", __func__))
} while (0) #define SCTP_INP_READ_UNLOCK(_inp) \
KASSERT(pthread_mutex_unlock(&(_inp)->inp_rdata_mtx) == 0, ("%s: inp_rdata_mtx not locked", __func__))
#else
#define SCTP_INP_READ_LOCK(_inp) \
(void)pthread_mutex_lock(&(_inp)->inp_rdata_mtx)
#define SCTP_INP_READ_UNLOCK(_inp) \ #define SCTP_INP_READ_UNLOCK(_inp) \
(void)pthread_mutex_unlock(&(_inp)->inp_rdata_mtx) (void)pthread_mutex_unlock(&(_inp)->inp_rdata_mtx)
#endif
#define SCTP_INP_LOCK_INIT(_inp) \ #define SCTP_INP_LOCK_INIT(_inp) \
(void)pthread_mutex_init(&(_inp)->inp_mtx, NULL) (void)pthread_mutex_init(&(_inp)->inp_mtx, &SCTP_BASE_VAR(mtx_attr))
#define SCTP_ASOC_CREATE_LOCK_INIT(_inp) \
(void)pthread_mutex_init(&(_inp)->inp_create_mtx, NULL)
#define SCTP_INP_LOCK_DESTROY(_inp) \ #define SCTP_INP_LOCK_DESTROY(_inp) \
(void)pthread_mutex_destroy(&(_inp)->inp_mtx) (void)pthread_mutex_destroy(&(_inp)->inp_mtx)
#ifdef INVARIANTS
#define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp) \
(void)pthread_mutex_destroy(&(_inp)->inp_create_mtx)
#ifdef SCTP_LOCK_LOGGING #ifdef SCTP_LOCK_LOGGING
#define SCTP_INP_RLOCK(_inp) do { \ #define SCTP_INP_RLOCK(_inp) do { \
if(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_INP);\ if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
(void)pthread_mutex_lock(&(_inp)->inp_mtx); \ sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_INP); \
KASSERT(pthread_mutex_lock(&(_inp)->inp_mtx) == 0, ("%s: inp_mtx already locked", __func__)) \
} while (0) } while (0)
#define SCTP_INP_WLOCK(_inp) do { \ #define SCTP_INP_WLOCK(_inp) do { \
sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_INP);\ if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
(void)pthread_mutex_lock(&(_inp)->inp_mtx); \ sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_INP); \
KASSERT(pthread_mutex_lock(&(_inp)->inp_mtx) == 0, ("%s: inp_mtx already locked", __func__))
} while (0) } while (0)
#else #else
#define SCTP_INP_RLOCK(_inp) \
#define SCTP_INP_RLOCK(_inp) do { \ KASSERT(pthread_mutex_lock(&(_inp)->inp_mtx) == 0, ("%s: inp_mtx already locked", __func__))
(void)pthread_mutex_lock(&(_inp)->inp_mtx); \ #define SCTP_INP_WLOCK(_inp) \
} while (0) KASSERT(pthread_mutex_lock(&(_inp)->inp_mtx) == 0, ("%s: inp_mtx already locked", __func__))
#define SCTP_INP_WLOCK(_inp) do { \
(void)pthread_mutex_lock(&(_inp)->inp_mtx); \
} while (0)
#endif #endif
#define SCTP_INP_RUNLOCK(_inp) \
KASSERT(pthread_mutex_unlock(&(_inp)->inp_mtx) == 0, ("%s: inp_mtx not locked", __func__))
#define SCTP_TCB_SEND_LOCK_INIT(_tcb) \ #define SCTP_INP_WUNLOCK(_inp) \
(void)pthread_mutex_init(&(_tcb)->tcb_send_mtx, NULL) KASSERT(pthread_mutex_unlock(&(_inp)->inp_mtx) == 0, ("%s: inp_mtx not locked", __func__))
#else
#define SCTP_TCB_SEND_LOCK_DESTROY(_tcb) \
(void)pthread_mutex_destroy(&(_tcb)->tcb_send_mtx)
#define SCTP_TCB_SEND_LOCK(_tcb) do { \
(void)pthread_mutex_lock(&(_tcb)->tcb_send_mtx); \
} while (0)
#define SCTP_TCB_SEND_UNLOCK(_tcb) \
(void)pthread_mutex_unlock(&(_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)
#ifdef SCTP_LOCK_LOGGING #ifdef SCTP_LOCK_LOGGING
#define SCTP_ASOC_CREATE_LOCK(_inp) do { \ #define SCTP_INP_RLOCK(_inp) do { \
if(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_CREATE); \ if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
(void)pthread_mutex_lock(&(_inp)->inp_create_mtx); \ sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_INP); \
(void)pthread_mutex_lock(&(_inp)->inp_mtx); \
} 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); \
(void)pthread_mutex_lock(&(_inp)->inp_mtx); \
} while (0) } while (0)
#else #else
#define SCTP_ASOC_CREATE_LOCK(_inp) do { \ #define SCTP_INP_RLOCK(_inp) \
(void)pthread_mutex_lock(&(_inp)->inp_create_mtx); \ (void)pthread_mutex_lock(&(_inp)->inp_mtx)
} while (0) #define SCTP_INP_WLOCK(_inp) \
(void)pthread_mutex_lock(&(_inp)->inp_mtx)
#endif #endif
#define SCTP_INP_RUNLOCK(_inp) \ #define SCTP_INP_RUNLOCK(_inp) \
(void)pthread_mutex_unlock(&(_inp)->inp_mtx) (void)pthread_mutex_unlock(&(_inp)->inp_mtx)
#define SCTP_INP_WUNLOCK(_inp) \ #define SCTP_INP_WUNLOCK(_inp) \
(void)pthread_mutex_unlock(&(_inp)->inp_mtx) (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__))
#define SCTP_INP_WLOCK_ASSERT(_inp) \
KASSERT(pthread_mutex_trylock(&(_inp)->inp_mtx) == EBUSY, ("%s: inp_mtx not locked", __func__))
#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_ASOC_CREATE_LOCK_INIT(_inp) \
(void)pthread_mutex_init(&(_inp)->inp_create_mtx, &SCTP_BASE_VAR(mtx_attr))
#define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp) \
(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__)) \
} 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__))
#endif
#define SCTP_ASOC_CREATE_UNLOCK(_inp) \
KASSERT(pthread_mutex_unlock(&(_inp)->inp_create_mtx) == 0, ("%s: inp_create_mtx not locked", __func__))
#else
#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); \
(void)pthread_mutex_lock(&(_inp)->inp_create_mtx); \
} while (0)
#else
#define SCTP_ASOC_CREATE_LOCK(_inp) \
(void)pthread_mutex_lock(&(_inp)->inp_create_mtx)
#endif
#define SCTP_ASOC_CREATE_UNLOCK(_inp) \ #define SCTP_ASOC_CREATE_UNLOCK(_inp) \
(void)pthread_mutex_unlock(&(_inp)->inp_create_mtx) (void)pthread_mutex_unlock(&(_inp)->inp_create_mtx)
#endif
/* /*
* For the majority of things (once we have found the association) we will * For the majority of things (once we have found the association) we will
* lock the actual association mutex. This will protect all the assoiciation * lock the actual association mutex. This will protect all the assoiciation
@ -398,28 +446,38 @@
*/ */
#define SCTP_TCB_LOCK_INIT(_tcb) \ #define SCTP_TCB_LOCK_INIT(_tcb) \
(void)pthread_mutex_init(&(_tcb)->tcb_mtx, NULL) (void)pthread_mutex_init(&(_tcb)->tcb_mtx, &SCTP_BASE_VAR(mtx_attr))
#define SCTP_TCB_LOCK_DESTROY(_tcb) \ #define SCTP_TCB_LOCK_DESTROY(_tcb) \
(void)pthread_mutex_destroy(&(_tcb)->tcb_mtx) (void)pthread_mutex_destroy(&(_tcb)->tcb_mtx)
#ifdef INVARIANTS
#ifdef SCTP_LOCK_LOGGING #ifdef SCTP_LOCK_LOGGING
#define SCTP_TCB_LOCK(_tcb) do { \ #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); \ if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
(void)pthread_mutex_lock(&(_tcb)->tcb_mtx); \ 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__)) \
} while (0) } while (0)
#else #else
#define SCTP_TCB_LOCK(_tcb) \
KASSERT(pthread_mutex_lock(&(_tcb)->tcb_mtx) == 0, ("%s: tcb_mtx already locked", __func__))
#endif
#define SCTP_TCB_UNLOCK(_tcb) \
KASSERT(pthread_mutex_unlock(&(_tcb)->tcb_mtx) == 0, ("%s: tcb_mtx not locked", __func__))
#else
#ifdef SCTP_LOCK_LOGGING
#define SCTP_TCB_LOCK(_tcb) do { \ #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); \
(void)pthread_mutex_lock(&(_tcb)->tcb_mtx); \ (void)pthread_mutex_lock(&(_tcb)->tcb_mtx); \
} while (0) } while (0)
#else
#define SCTP_TCB_LOCK(_tcb) \
(void)pthread_mutex_lock(&(_tcb)->tcb_mtx)
#endif #endif
#define SCTP_TCB_TRYLOCK(_tcb) (!(pthread_mutex_trylock(&(_tcb)->tcb_mtx)))
#define SCTP_TCB_UNLOCK(_tcb) (void)pthread_mutex_unlock(&(_tcb)->tcb_mtx) #define SCTP_TCB_UNLOCK(_tcb) (void)pthread_mutex_unlock(&(_tcb)->tcb_mtx)
#endif
#define SCTP_TCB_LOCK_ASSERT(_tcb) #define SCTP_TCB_LOCK_ASSERT(_tcb) \
KASSERT(pthread_mutex_trylock(&(_tcb)->tcb_mtx) == EBUSY, ("%s: tcb_mtx not locked", __func__))
#define SCTP_TCB_TRYLOCK(_tcb) (!(pthread_mutex_trylock(&(_tcb)->tcb_mtx)))
#endif #endif
#endif /* SCTP_PER_SOCKET_LOCKING */ #endif /* SCTP_PER_SOCKET_LOCKING */
@ -434,29 +492,36 @@
#define SCTP_INP_READ_CONTENDED(_inp) (0) /* Don't know if this is possible */ #define SCTP_INP_READ_CONTENDED(_inp) (0) /* Don't know if this is possible */
#define SCTP_ASOC_CREATE_LOCK_CONTENDED(_inp) (0) /* Don't know if this is possible */ #define SCTP_ASOC_CREATE_LOCK_CONTENDED(_inp) (0) /* Don't know if this is possible */
/* socket locks */ /* socket locks */
#if defined(__Userspace__) #if defined(_WIN32)
#if defined(__Userspace_os_Windows)
#define SOCKBUF_LOCK_ASSERT(_so_buf) #define SOCKBUF_LOCK_ASSERT(_so_buf)
#define SOCKBUF_LOCK(_so_buf) EnterCriticalSection(&(_so_buf)->sb_mtx) #define SOCKBUF_LOCK(_so_buf) \
#define SOCKBUF_UNLOCK(_so_buf) LeaveCriticalSection(&(_so_buf)->sb_mtx) EnterCriticalSection(&(_so_buf)->sb_mtx)
#define SOCK_LOCK(_so) SOCKBUF_LOCK(&(_so)->so_rcv) #define SOCKBUF_UNLOCK(_so_buf) \
#define SOCK_UNLOCK(_so) SOCKBUF_UNLOCK(&(_so)->so_rcv) LeaveCriticalSection(&(_so_buf)->sb_mtx)
#define SOCK_LOCK(_so) \
SOCKBUF_LOCK(&(_so)->so_rcv)
#define SOCK_UNLOCK(_so) \
SOCKBUF_UNLOCK(&(_so)->so_rcv)
#else #else
#define SOCKBUF_LOCK_ASSERT(_so_buf) KASSERT(pthread_mutex_trylock(SOCKBUF_MTX(_so_buf)) == EBUSY, ("%s: socket buffer not locked", __func__)) #define SOCKBUF_LOCK_ASSERT(_so_buf) \
#define SOCKBUF_LOCK(_so_buf) pthread_mutex_lock(SOCKBUF_MTX(_so_buf)) KASSERT(pthread_mutex_trylock(SOCKBUF_MTX(_so_buf)) == EBUSY, ("%s: socket buffer not locked", __func__))
#define SOCKBUF_UNLOCK(_so_buf) pthread_mutex_unlock(SOCKBUF_MTX(_so_buf)) #ifdef INVARIANTS
#define SOCK_LOCK(_so) SOCKBUF_LOCK(&(_so)->so_rcv) #define SOCKBUF_LOCK(_so_buf) \
#define SOCK_UNLOCK(_so) SOCKBUF_UNLOCK(&(_so)->so_rcv) KASSERT(pthread_mutex_lock(SOCKBUF_MTX(_so_buf)) == 0, ("%s: sockbuf_mtx already locked", __func__))
#define SOCKBUF_UNLOCK(_so_buf) \
KASSERT(pthread_mutex_unlock(SOCKBUF_MTX(_so_buf)) == 0, ("%s: sockbuf_mtx not locked", __func__))
#else
#define SOCKBUF_LOCK(_so_buf) \
pthread_mutex_lock(SOCKBUF_MTX(_so_buf))
#define SOCKBUF_UNLOCK(_so_buf) \
pthread_mutex_unlock(SOCKBUF_MTX(_so_buf))
#endif #endif
#else #define SOCK_LOCK(_so) \
#define SOCK_LOCK(_so) SOCKBUF_LOCK(&(_so)->so_rcv)
#define SOCK_UNLOCK(_so) #define SOCK_UNLOCK(_so) \
#define SOCKBUF_LOCK(_so_buf) SOCKBUF_UNLOCK(&(_so)->so_rcv)
#define SOCKBUF_UNLOCK(_so_buf)
#define SOCKBUF_LOCK_ASSERT(_so_buf)
#endif #endif
#define SCTP_STATLOG_INIT_LOCK() #define SCTP_STATLOG_INIT_LOCK()
@ -464,179 +529,149 @@
#define SCTP_STATLOG_UNLOCK() #define SCTP_STATLOG_UNLOCK()
#define SCTP_STATLOG_DESTROY() #define SCTP_STATLOG_DESTROY()
#if defined(__Userspace_os_Windows) #if defined(_WIN32)
/* address list locks */ /* address list locks */
#define SCTP_IPI_ADDR_INIT() \ #define SCTP_IPI_ADDR_INIT() \
InitializeCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx)) InitializeCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_DESTROY() \ #define SCTP_IPI_ADDR_DESTROY() \
DeleteCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx)) DeleteCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_RLOCK() \ #define SCTP_IPI_ADDR_RLOCK() \
do { \ EnterCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
EnterCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx)); \
} while (0)
#define SCTP_IPI_ADDR_RUNLOCK() \ #define SCTP_IPI_ADDR_RUNLOCK() \
LeaveCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx)) LeaveCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_WLOCK() \ #define SCTP_IPI_ADDR_WLOCK() \
do { \ EnterCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
EnterCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx)); \
} while (0)
#define SCTP_IPI_ADDR_WUNLOCK() \ #define SCTP_IPI_ADDR_WUNLOCK() \
LeaveCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx)) LeaveCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_LOCK_ASSERT()
#define SCTP_IPI_ADDR_WLOCK_ASSERT()
/* iterator locks */ /* iterator locks */
#define SCTP_ITERATOR_LOCK_INIT() \ #define SCTP_ITERATOR_LOCK_INIT() \
InitializeCriticalSection(&sctp_it_ctl.it_mtx) InitializeCriticalSection(&sctp_it_ctl.it_mtx)
#define SCTP_ITERATOR_LOCK_DESTROY() \
DeleteCriticalSection(&sctp_it_ctl.it_mtx)
#define SCTP_ITERATOR_LOCK() \ #define SCTP_ITERATOR_LOCK() \
do { \ EnterCriticalSection(&sctp_it_ctl.it_mtx)
EnterCriticalSection(&sctp_it_ctl.it_mtx); \
} while (0)
#define SCTP_ITERATOR_UNLOCK() \ #define SCTP_ITERATOR_UNLOCK() \
LeaveCriticalSection(&sctp_it_ctl.it_mtx) LeaveCriticalSection(&sctp_it_ctl.it_mtx)
#define SCTP_ITERATOR_LOCK_DESTROY() \
DeleteCriticalSection(&sctp_it_ctl.it_mtx)
#define SCTP_IPI_ITERATOR_WQ_INIT() \ #define SCTP_IPI_ITERATOR_WQ_INIT() \
InitializeCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx) InitializeCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx)
#define SCTP_IPI_ITERATOR_WQ_DESTROY() \ #define SCTP_IPI_ITERATOR_WQ_DESTROY() \
DeleteCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx) DeleteCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx)
#define SCTP_IPI_ITERATOR_WQ_LOCK() \ #define SCTP_IPI_ITERATOR_WQ_LOCK() \
do { \ EnterCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx)
EnterCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx); \
} while (0)
#define SCTP_IPI_ITERATOR_WQ_UNLOCK() \ #define SCTP_IPI_ITERATOR_WQ_UNLOCK() \
LeaveCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx) LeaveCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx)
#else /* end of __Userspace_os_Windows */ #else
/* address list locks */ /* address list locks */
#define SCTP_IPI_ADDR_INIT() \ #define SCTP_IPI_ADDR_INIT() \
(void)pthread_mutex_init(&SCTP_BASE_INFO(ipi_addr_mtx), NULL) (void)pthread_mutex_init(&SCTP_BASE_INFO(ipi_addr_mtx), &SCTP_BASE_VAR(mtx_attr))
#define SCTP_IPI_ADDR_DESTROY() \ #define SCTP_IPI_ADDR_DESTROY() \
(void)pthread_mutex_destroy(&SCTP_BASE_INFO(ipi_addr_mtx)) (void)pthread_mutex_destroy(&SCTP_BASE_INFO(ipi_addr_mtx))
#ifdef INVARIANTS
#define SCTP_IPI_ADDR_RLOCK() \ #define SCTP_IPI_ADDR_RLOCK() \
do { \ KASSERT(pthread_mutex_lock(&SCTP_BASE_INFO(ipi_addr_mtx)) == 0, ("%s: ipi_addr_mtx already locked", __func__))
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_addr_mtx)); \ #define SCTP_IPI_ADDR_RUNLOCK() \
} while (0) KASSERT(pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_addr_mtx)) == 0, ("%s: ipi_addr_mtx not locked", __func__))
#define SCTP_IPI_ADDR_WLOCK() \
KASSERT(pthread_mutex_lock(&SCTP_BASE_INFO(ipi_addr_mtx)) == 0, ("%s: ipi_addr_mtx already locked", __func__))
#define SCTP_IPI_ADDR_WUNLOCK() \
KASSERT(pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_addr_mtx)) == 0, ("%s: ipi_addr_mtx not locked", __func__))
#define SCTP_IPI_ADDR_LOCK_ASSERT() \
KASSERT(pthread_mutex_trylock(&SCTP_BASE_INFO(ipi_addr_mtx)) == EBUSY, ("%s: ipi_addr_mtx not locked", __func__))
#define SCTP_IPI_ADDR_WLOCK_ASSERT() \
KASSERT(pthread_mutex_trylock(&SCTP_BASE_INFO(ipi_addr_mtx)) == EBUSY, ("%s: ipi_addr_mtx not locked", __func__))
#else
#define SCTP_IPI_ADDR_RLOCK() \
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_RUNLOCK() \ #define SCTP_IPI_ADDR_RUNLOCK() \
(void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_addr_mtx)) (void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_WLOCK() \ #define SCTP_IPI_ADDR_WLOCK() \
do { \ (void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_addr_mtx))
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_addr_mtx)); \
} while (0)
#define SCTP_IPI_ADDR_WUNLOCK() \ #define SCTP_IPI_ADDR_WUNLOCK() \
(void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_addr_mtx)) (void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_LOCK_ASSERT()
#define SCTP_IPI_ADDR_WLOCK_ASSERT()
#endif
/* iterator locks */ /* iterator locks */
#define SCTP_ITERATOR_LOCK_INIT() \ #define SCTP_ITERATOR_LOCK_INIT() \
(void)pthread_mutex_init(&sctp_it_ctl.it_mtx, NULL) (void)pthread_mutex_init(&sctp_it_ctl.it_mtx, &SCTP_BASE_VAR(mtx_attr))
#define SCTP_ITERATOR_LOCK() \
do { \
(void)pthread_mutex_lock(&sctp_it_ctl.it_mtx); \
} while (0)
#define SCTP_ITERATOR_UNLOCK() \
(void)pthread_mutex_unlock(&sctp_it_ctl.it_mtx)
#define SCTP_ITERATOR_LOCK_DESTROY() \ #define SCTP_ITERATOR_LOCK_DESTROY() \
(void)pthread_mutex_destroy(&sctp_it_ctl.it_mtx) (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__))
#define SCTP_ITERATOR_UNLOCK() \
KASSERT(pthread_mutex_unlock(&sctp_it_ctl.it_mtx) == 0, ("%s: it_mtx not locked", __func__))
#else
#define SCTP_ITERATOR_LOCK() \
(void)pthread_mutex_lock(&sctp_it_ctl.it_mtx)
#define SCTP_ITERATOR_UNLOCK() \
(void)pthread_mutex_unlock(&sctp_it_ctl.it_mtx)
#endif
#define SCTP_IPI_ITERATOR_WQ_INIT() \ #define SCTP_IPI_ITERATOR_WQ_INIT() \
(void)pthread_mutex_init(&sctp_it_ctl.ipi_iterator_wq_mtx, NULL) (void)pthread_mutex_init(&sctp_it_ctl.ipi_iterator_wq_mtx, &SCTP_BASE_VAR(mtx_attr))
#define SCTP_IPI_ITERATOR_WQ_DESTROY() \ #define SCTP_IPI_ITERATOR_WQ_DESTROY() \
(void)pthread_mutex_destroy(&sctp_it_ctl.ipi_iterator_wq_mtx) (void)pthread_mutex_destroy(&sctp_it_ctl.ipi_iterator_wq_mtx)
#ifdef INVARIANTS
#define SCTP_IPI_ITERATOR_WQ_LOCK() \ #define SCTP_IPI_ITERATOR_WQ_LOCK() \
do { \ KASSERT(pthread_mutex_lock(&sctp_it_ctl.ipi_iterator_wq_mtx) == 0, ("%s: ipi_iterator_wq_mtx already locked", __func__))
(void)pthread_mutex_lock(&sctp_it_ctl.ipi_iterator_wq_mtx); \ #define SCTP_IPI_ITERATOR_WQ_UNLOCK() \
} while (0) KASSERT(pthread_mutex_unlock(&sctp_it_ctl.ipi_iterator_wq_mtx) == 0, ("%s: ipi_iterator_wq_mtx not locked", __func__))
#else
#define SCTP_IPI_ITERATOR_WQ_LOCK() \
(void)pthread_mutex_lock(&sctp_it_ctl.ipi_iterator_wq_mtx)
#define SCTP_IPI_ITERATOR_WQ_UNLOCK() \ #define SCTP_IPI_ITERATOR_WQ_UNLOCK() \
(void)pthread_mutex_unlock(&sctp_it_ctl.ipi_iterator_wq_mtx) (void)pthread_mutex_unlock(&sctp_it_ctl.ipi_iterator_wq_mtx)
#endif #endif
#endif
#define SCTP_INCR_EP_COUNT() \ #define SCTP_INCR_EP_COUNT() \
do { \ atomic_add_int(&SCTP_BASE_INFO(ipi_count_ep), 1)
atomic_add_int(&SCTP_BASE_INFO(ipi_count_ep), 1); \
} while (0)
#define SCTP_DECR_EP_COUNT() \ #define SCTP_DECR_EP_COUNT() \
do { \ atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_ep), 1)
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_ep), 1); \
} while (0)
#define SCTP_INCR_ASOC_COUNT() \ #define SCTP_INCR_ASOC_COUNT() \
do { \ atomic_add_int(&SCTP_BASE_INFO(ipi_count_asoc), 1)
atomic_add_int(&SCTP_BASE_INFO(ipi_count_asoc), 1); \
} while (0)
#define SCTP_DECR_ASOC_COUNT() \ #define SCTP_DECR_ASOC_COUNT() \
do { \ atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_asoc), 1)
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_asoc), 1); \
} while (0)
#define SCTP_INCR_LADDR_COUNT() \ #define SCTP_INCR_LADDR_COUNT() \
do { \ atomic_add_int(&SCTP_BASE_INFO(ipi_count_laddr), 1)
atomic_add_int(&SCTP_BASE_INFO(ipi_count_laddr), 1); \
} while (0)
#define SCTP_DECR_LADDR_COUNT() \ #define SCTP_DECR_LADDR_COUNT() \
do { \ atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_laddr), 1)
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_laddr), 1); \
} while (0)
#define SCTP_INCR_RADDR_COUNT() \ #define SCTP_INCR_RADDR_COUNT() \
do { \ atomic_add_int(&SCTP_BASE_INFO(ipi_count_raddr), 1)
atomic_add_int(&SCTP_BASE_INFO(ipi_count_raddr), 1); \
} while (0)
#define SCTP_DECR_RADDR_COUNT() \ #define SCTP_DECR_RADDR_COUNT() \
do { \ atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_raddr), 1)
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_raddr), 1); \
} while (0)
#define SCTP_INCR_CHK_COUNT() \ #define SCTP_INCR_CHK_COUNT() \
do { \ atomic_add_int(&SCTP_BASE_INFO(ipi_count_chunk), 1)
atomic_add_int(&SCTP_BASE_INFO(ipi_count_chunk), 1); \
} while (0)
#define SCTP_DECR_CHK_COUNT() \ #define SCTP_DECR_CHK_COUNT() \
do { \ atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_chunk), 1)
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_chunk), 1); \
} while (0)
#define SCTP_INCR_READQ_COUNT() \ #define SCTP_INCR_READQ_COUNT() \
do { \ atomic_add_int(&SCTP_BASE_INFO(ipi_count_readq), 1)
atomic_add_int(&SCTP_BASE_INFO(ipi_count_readq), 1); \
} while (0)
#define SCTP_DECR_READQ_COUNT() \ #define SCTP_DECR_READQ_COUNT() \
do { \ atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_readq), 1)
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_readq), 1); \
} while (0)
#define SCTP_INCR_STRMOQ_COUNT() \ #define SCTP_INCR_STRMOQ_COUNT() \
do { \ atomic_add_int(&SCTP_BASE_INFO(ipi_count_strmoq), 1)
atomic_add_int(&SCTP_BASE_INFO(ipi_count_strmoq), 1); \
} while (0)
#define SCTP_DECR_STRMOQ_COUNT() \ #define SCTP_DECR_STRMOQ_COUNT() \
do { \ atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_strmoq), 1)
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_strmoq), 1); \
} while (0)
#endif #endif

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2013, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2013, by Michael Tuexen. All rights reserved.
@ -82,9 +84,9 @@ sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx)
#else #else
#include <string.h> #include <string.h>
#if defined(__Userspace_os_Windows) #if defined(_WIN32) && defined(__Userspace__)
#include <winsock2.h> #include <winsock2.h>
#elif !defined(__Windows__) #elif !(defined(_WIN32) && !defined(__Userspace__))
#include <arpa/inet.h> #include <arpa/inet.h>
#endif #endif

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,7 +32,7 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD$"); __FBSDID("$FreeBSD$");
#endif #endif
@ -41,16 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h> #include <sys/types.h>
#if defined(SCTP_USE_NSS_SHA1) #if defined(SCTP_USE_NSS_SHA1)
#if defined(__Userspace_os_Darwin)
/* The NSS sources require __APPLE__ to be defined.
* XXX: Remove this ugly hack once the platform defines have been cleaned up.
*/
#define __APPLE__
#endif
#include <pk11pub.h> #include <pk11pub.h>
#if defined(__Userspace_os_Darwin)
#undef __APPLE__
#endif
#elif defined(SCTP_USE_OPENSSL_SHA1) #elif defined(SCTP_USE_OPENSSL_SHA1)
#include <openssl/sha.h> #include <openssl/sha.h>
#endif #endif
@ -81,7 +74,7 @@ struct sctp_sha1_context {
#endif #endif
}; };
#if (defined(__APPLE__) && defined(KERNEL)) #if (defined(__APPLE__) && !defined(__Userspace__) && defined(KERNEL))
#ifndef _KERNEL #ifndef _KERNEL
#define _KERNEL #define _KERNEL
#endif #endif

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2010-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2010-2012, by Michael Tuexen. All rights reserved.
* Copyright (c) 2010-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2010-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2010-2012, by Robin Seggelmann. All rights reserved. * Copyright (c) 2010-2012, by Robin Seggelmann. All rights reserved.
@ -26,9 +28,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_ss_functions.c 235828 2012-05-23 11:26:28Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_ss_functions.c 365071 2020-09-01 21:19:14Z mjg $");
#endif #endif
#include <netinet/sctp_pcb.h> #include <netinet/sctp_pcb.h>
@ -57,7 +59,12 @@ sctp_ss_default_init(struct sctp_tcb *stcb, struct sctp_association *asoc,
{ {
uint16_t i; uint16_t i;
TAILQ_INIT(&asoc->ss_data.out_wheel); if (holds_lock == 0) {
SCTP_TCB_SEND_LOCK(stcb);
}
asoc->ss_data.locked_on_sending = NULL;
asoc->ss_data.last_out_stream = NULL;
TAILQ_INIT(&asoc->ss_data.out.wheel);
/* /*
* If there is data in the stream queues already, * If there is data in the stream queues already,
* the scheduler of an existing association has * the scheduler of an existing association has
@ -67,7 +74,10 @@ sctp_ss_default_init(struct sctp_tcb *stcb, struct sctp_association *asoc,
for (i = 0; i < stcb->asoc.streamoutcnt; i++) { for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
stcb->asoc.ss_functions.sctp_ss_add_to_stream(stcb, &stcb->asoc, stcb->asoc.ss_functions.sctp_ss_add_to_stream(stcb, &stcb->asoc,
&stcb->asoc.strmout[i], &stcb->asoc.strmout[i],
NULL, holds_lock); NULL, 1);
}
if (holds_lock == 0) {
SCTP_TCB_SEND_UNLOCK(stcb);
} }
return; return;
} }
@ -79,13 +89,15 @@ sctp_ss_default_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (holds_lock == 0) { if (holds_lock == 0) {
SCTP_TCB_SEND_LOCK(stcb); SCTP_TCB_SEND_LOCK(stcb);
} }
while (!TAILQ_EMPTY(&asoc->ss_data.out_wheel)) { while (!TAILQ_EMPTY(&asoc->ss_data.out.wheel)) {
struct sctp_stream_out *strq = TAILQ_FIRST(&asoc->ss_data.out_wheel); struct sctp_stream_out *strq;
TAILQ_REMOVE(&asoc->ss_data.out_wheel, TAILQ_FIRST(&asoc->ss_data.out_wheel), ss_params.rr.next_spoke);
strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.rr.next_spoke);
strq->ss_params.rr.next_spoke.tqe_next = NULL; strq->ss_params.rr.next_spoke.tqe_next = NULL;
strq->ss_params.rr.next_spoke.tqe_prev = NULL; strq->ss_params.rr.next_spoke.tqe_prev = NULL;
} }
asoc->last_out_stream = NULL; asoc->ss_data.last_out_stream = NULL;
if (holds_lock == 0) { if (holds_lock == 0) {
SCTP_TCB_SEND_UNLOCK(stcb); SCTP_TCB_SEND_UNLOCK(stcb);
} }
@ -93,8 +105,16 @@ sctp_ss_default_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
} }
static void static void
sctp_ss_default_init_stream(struct sctp_stream_out *strq, struct sctp_stream_out *with_strq SCTP_UNUSED) sctp_ss_default_init_stream(struct sctp_tcb *stcb, struct sctp_stream_out *strq, struct sctp_stream_out *with_strq)
{ {
if (with_strq != NULL) {
if (stcb->asoc.ss_data.locked_on_sending == with_strq) {
stcb->asoc.ss_data.locked_on_sending = strq;
}
if (stcb->asoc.ss_data.last_out_stream == with_strq) {
stcb->asoc.ss_data.last_out_stream = strq;
}
}
strq->ss_params.rr.next_spoke.tqe_next = NULL; strq->ss_params.rr.next_spoke.tqe_next = NULL;
strq->ss_params.rr.next_spoke.tqe_prev = NULL; strq->ss_params.rr.next_spoke.tqe_prev = NULL;
return; return;
@ -112,7 +132,7 @@ sctp_ss_default_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (!TAILQ_EMPTY(&strq->outqueue) && if (!TAILQ_EMPTY(&strq->outqueue) &&
(strq->ss_params.rr.next_spoke.tqe_next == NULL) && (strq->ss_params.rr.next_spoke.tqe_next == NULL) &&
(strq->ss_params.rr.next_spoke.tqe_prev == NULL)) { (strq->ss_params.rr.next_spoke.tqe_prev == NULL)) {
TAILQ_INSERT_TAIL(&asoc->ss_data.out_wheel, TAILQ_INSERT_TAIL(&asoc->ss_data.out.wheel,
strq, ss_params.rr.next_spoke); strq, ss_params.rr.next_spoke);
} }
if (holds_lock == 0) { if (holds_lock == 0) {
@ -124,7 +144,7 @@ sctp_ss_default_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
static int static int
sctp_ss_default_is_empty(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_association *asoc) sctp_ss_default_is_empty(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_association *asoc)
{ {
if (TAILQ_EMPTY(&asoc->ss_data.out_wheel)) { if (TAILQ_EMPTY(&asoc->ss_data.out.wheel)) {
return (1); return (1);
} else { } else {
return (0); return (0);
@ -143,19 +163,19 @@ sctp_ss_default_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (TAILQ_EMPTY(&strq->outqueue) && if (TAILQ_EMPTY(&strq->outqueue) &&
(strq->ss_params.rr.next_spoke.tqe_next != NULL || (strq->ss_params.rr.next_spoke.tqe_next != NULL ||
strq->ss_params.rr.next_spoke.tqe_prev != NULL)) { strq->ss_params.rr.next_spoke.tqe_prev != NULL)) {
if (asoc->last_out_stream == strq) { if (asoc->ss_data.last_out_stream == strq) {
asoc->last_out_stream = TAILQ_PREV(asoc->last_out_stream, asoc->ss_data.last_out_stream = TAILQ_PREV(asoc->ss_data.last_out_stream,
sctpwheel_listhead, sctpwheel_listhead,
ss_params.rr.next_spoke); ss_params.rr.next_spoke);
if (asoc->last_out_stream == NULL) { if (asoc->ss_data.last_out_stream == NULL) {
asoc->last_out_stream = TAILQ_LAST(&asoc->ss_data.out_wheel, asoc->ss_data.last_out_stream = TAILQ_LAST(&asoc->ss_data.out.wheel,
sctpwheel_listhead); sctpwheel_listhead);
} }
if (asoc->last_out_stream == strq) { if (asoc->ss_data.last_out_stream == strq) {
asoc->last_out_stream = NULL; asoc->ss_data.last_out_stream = NULL;
} }
} }
TAILQ_REMOVE(&asoc->ss_data.out_wheel, strq, ss_params.rr.next_spoke); TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.rr.next_spoke);
strq->ss_params.rr.next_spoke.tqe_next = NULL; strq->ss_params.rr.next_spoke.tqe_next = NULL;
strq->ss_params.rr.next_spoke.tqe_prev = NULL; strq->ss_params.rr.next_spoke.tqe_prev = NULL;
} }
@ -165,22 +185,24 @@ sctp_ss_default_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
return; return;
} }
static struct sctp_stream_out * static struct sctp_stream_out *
sctp_ss_default_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, sctp_ss_default_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net,
struct sctp_association *asoc) struct sctp_association *asoc)
{ {
struct sctp_stream_out *strq, *strqt; struct sctp_stream_out *strq, *strqt;
strqt = asoc->last_out_stream; if (asoc->ss_data.locked_on_sending) {
return (asoc->ss_data.locked_on_sending);
}
strqt = asoc->ss_data.last_out_stream;
default_again: default_again:
/* Find the next stream to use */ /* Find the next stream to use */
if (strqt == NULL) { if (strqt == NULL) {
strq = TAILQ_FIRST(&asoc->ss_data.out_wheel); strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
} else { } else {
strq = TAILQ_NEXT(strqt, ss_params.rr.next_spoke); strq = TAILQ_NEXT(strqt, ss_params.rr.next_spoke);
if (strq == NULL) { if (strq == NULL) {
strq = TAILQ_FIRST(&asoc->ss_data.out_wheel); strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
} }
} }
@ -200,7 +222,7 @@ default_again:
if (TAILQ_FIRST(&strq->outqueue) && if (TAILQ_FIRST(&strq->outqueue) &&
TAILQ_FIRST(&strq->outqueue)->net != NULL && TAILQ_FIRST(&strq->outqueue)->net != NULL &&
TAILQ_FIRST(&strq->outqueue)->net != net) { TAILQ_FIRST(&strq->outqueue)->net != net) {
if (strq == asoc->last_out_stream) { if (strq == asoc->ss_data.last_out_stream) {
return (NULL); return (NULL);
} else { } else {
strqt = strq; strqt = strq;
@ -212,11 +234,25 @@ default_again:
} }
static void static void
sctp_ss_default_scheduled(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net SCTP_UNUSED, sctp_ss_default_scheduled(struct sctp_tcb *stcb,
struct sctp_association *asoc SCTP_UNUSED, struct sctp_nets *net SCTP_UNUSED,
struct sctp_stream_out *strq, int moved_how_much SCTP_UNUSED) struct sctp_association *asoc,
struct sctp_stream_out *strq,
int moved_how_much SCTP_UNUSED)
{ {
asoc->last_out_stream = strq; struct sctp_stream_queue_pending *sp;
asoc->ss_data.last_out_stream = strq;
if (stcb->asoc.idata_supported == 0) {
sp = TAILQ_FIRST(&strq->outqueue);
if ((sp != NULL) && (sp->some_taken == 1)) {
stcb->asoc.ss_data.locked_on_sending = strq;
} else {
stcb->asoc.ss_data.locked_on_sending = NULL;
}
} else {
stcb->asoc.ss_data.locked_on_sending = NULL;
}
return; return;
} }
@ -244,6 +280,26 @@ sctp_ss_default_set_value(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_associa
return (-1); return (-1);
} }
static int
sctp_ss_default_is_user_msgs_incomplete(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_association *asoc)
{
struct sctp_stream_out *strq;
struct sctp_stream_queue_pending *sp;
if (asoc->stream_queue_cnt != 1) {
return (0);
}
strq = asoc->ss_data.locked_on_sending;
if (strq == NULL) {
return (0);
}
sp = TAILQ_FIRST(&strq->outqueue);
if (sp == NULL) {
return (0);
}
return (!sp->msg_is_complete);
}
/* /*
* Real round-robin algorithm. * Real round-robin algorithm.
* Always interates the streams in ascending order. * Always interates the streams in ascending order.
@ -261,17 +317,17 @@ sctp_ss_rr_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (!TAILQ_EMPTY(&strq->outqueue) && if (!TAILQ_EMPTY(&strq->outqueue) &&
(strq->ss_params.rr.next_spoke.tqe_next == NULL) && (strq->ss_params.rr.next_spoke.tqe_next == NULL) &&
(strq->ss_params.rr.next_spoke.tqe_prev == NULL)) { (strq->ss_params.rr.next_spoke.tqe_prev == NULL)) {
if (TAILQ_EMPTY(&asoc->ss_data.out_wheel)) { if (TAILQ_EMPTY(&asoc->ss_data.out.wheel)) {
TAILQ_INSERT_HEAD(&asoc->ss_data.out_wheel, strq, ss_params.rr.next_spoke); TAILQ_INSERT_HEAD(&asoc->ss_data.out.wheel, strq, ss_params.rr.next_spoke);
} else { } else {
strqt = TAILQ_FIRST(&asoc->ss_data.out_wheel); strqt = TAILQ_FIRST(&asoc->ss_data.out.wheel);
while (strqt != NULL && (strqt->stream_no < strq->stream_no)) { while (strqt != NULL && (strqt->sid < strq->sid)) {
strqt = TAILQ_NEXT(strqt, ss_params.rr.next_spoke); strqt = TAILQ_NEXT(strqt, ss_params.rr.next_spoke);
} }
if (strqt != NULL) { if (strqt != NULL) {
TAILQ_INSERT_BEFORE(strqt, strq, ss_params.rr.next_spoke); TAILQ_INSERT_BEFORE(strqt, strq, ss_params.rr.next_spoke);
} else { } else {
TAILQ_INSERT_TAIL(&asoc->ss_data.out_wheel, strq, ss_params.rr.next_spoke); TAILQ_INSERT_TAIL(&asoc->ss_data.out.wheel, strq, ss_params.rr.next_spoke);
} }
} }
} }
@ -290,7 +346,7 @@ static struct sctp_stream_out *
sctp_ss_rrp_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net SCTP_UNUSED, sctp_ss_rrp_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net SCTP_UNUSED,
struct sctp_association *asoc) struct sctp_association *asoc)
{ {
return (asoc->last_out_stream); return (asoc->ss_data.last_out_stream);
} }
static void static void
@ -299,15 +355,15 @@ sctp_ss_rrp_packet_done(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net
{ {
struct sctp_stream_out *strq, *strqt; struct sctp_stream_out *strq, *strqt;
strqt = asoc->last_out_stream; strqt = asoc->ss_data.last_out_stream;
rrp_again: rrp_again:
/* Find the next stream to use */ /* Find the next stream to use */
if (strqt == NULL) { if (strqt == NULL) {
strq = TAILQ_FIRST(&asoc->ss_data.out_wheel); strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
} else { } else {
strq = TAILQ_NEXT(strqt, ss_params.rr.next_spoke); strq = TAILQ_NEXT(strqt, ss_params.rr.next_spoke);
if (strq == NULL) { if (strq == NULL) {
strq = TAILQ_FIRST(&asoc->ss_data.out_wheel); strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
} }
} }
@ -327,7 +383,7 @@ rrp_again:
if (TAILQ_FIRST(&strq->outqueue) && if (TAILQ_FIRST(&strq->outqueue) &&
TAILQ_FIRST(&strq->outqueue)->net != NULL && TAILQ_FIRST(&strq->outqueue)->net != NULL &&
TAILQ_FIRST(&strq->outqueue)->net != net) { TAILQ_FIRST(&strq->outqueue)->net != net) {
if (strq == asoc->last_out_stream) { if (strq == asoc->ss_data.last_out_stream) {
strq = NULL; strq = NULL;
} else { } else {
strqt = strq; strqt = strq;
@ -335,11 +391,10 @@ rrp_again:
} }
} }
} }
asoc->last_out_stream = strq; asoc->ss_data.last_out_stream = strq;
return; return;
} }
/* /*
* Priority algorithm. * Priority algorithm.
* Always prefers streams based on their priority id. * Always prefers streams based on their priority id.
@ -351,17 +406,18 @@ sctp_ss_prio_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (holds_lock == 0) { if (holds_lock == 0) {
SCTP_TCB_SEND_LOCK(stcb); SCTP_TCB_SEND_LOCK(stcb);
} }
while (!TAILQ_EMPTY(&asoc->ss_data.out_wheel)) { while (!TAILQ_EMPTY(&asoc->ss_data.out.wheel)) {
struct sctp_stream_out *strq = TAILQ_FIRST(&asoc->ss_data.out_wheel); struct sctp_stream_out *strq;
strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
if (clear_values) { if (clear_values) {
strq->ss_params.prio.priority = 0; strq->ss_params.prio.priority = 0;
} }
TAILQ_REMOVE(&asoc->ss_data.out_wheel, TAILQ_FIRST(&asoc->ss_data.out_wheel), ss_params.prio.next_spoke); TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.prio.next_spoke);
strq->ss_params.prio.next_spoke.tqe_next = NULL; strq->ss_params.prio.next_spoke.tqe_next = NULL;
strq->ss_params.prio.next_spoke.tqe_prev = NULL; strq->ss_params.prio.next_spoke.tqe_prev = NULL;
} }
asoc->last_out_stream = NULL; asoc->ss_data.last_out_stream = NULL;
if (holds_lock == 0) { if (holds_lock == 0) {
SCTP_TCB_SEND_UNLOCK(stcb); SCTP_TCB_SEND_UNLOCK(stcb);
} }
@ -369,8 +425,16 @@ sctp_ss_prio_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
} }
static void static void
sctp_ss_prio_init_stream(struct sctp_stream_out *strq, struct sctp_stream_out *with_strq) sctp_ss_prio_init_stream(struct sctp_tcb *stcb, struct sctp_stream_out *strq, struct sctp_stream_out *with_strq)
{ {
if (with_strq != NULL) {
if (stcb->asoc.ss_data.locked_on_sending == with_strq) {
stcb->asoc.ss_data.locked_on_sending = strq;
}
if (stcb->asoc.ss_data.last_out_stream == with_strq) {
stcb->asoc.ss_data.last_out_stream = strq;
}
}
strq->ss_params.prio.next_spoke.tqe_next = NULL; strq->ss_params.prio.next_spoke.tqe_next = NULL;
strq->ss_params.prio.next_spoke.tqe_prev = NULL; strq->ss_params.prio.next_spoke.tqe_prev = NULL;
if (with_strq != NULL) { if (with_strq != NULL) {
@ -395,17 +459,17 @@ sctp_ss_prio_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (!TAILQ_EMPTY(&strq->outqueue) && if (!TAILQ_EMPTY(&strq->outqueue) &&
(strq->ss_params.prio.next_spoke.tqe_next == NULL) && (strq->ss_params.prio.next_spoke.tqe_next == NULL) &&
(strq->ss_params.prio.next_spoke.tqe_prev == NULL)) { (strq->ss_params.prio.next_spoke.tqe_prev == NULL)) {
if (TAILQ_EMPTY(&asoc->ss_data.out_wheel)) { if (TAILQ_EMPTY(&asoc->ss_data.out.wheel)) {
TAILQ_INSERT_HEAD(&asoc->ss_data.out_wheel, strq, ss_params.prio.next_spoke); TAILQ_INSERT_HEAD(&asoc->ss_data.out.wheel, strq, ss_params.prio.next_spoke);
} else { } else {
strqt = TAILQ_FIRST(&asoc->ss_data.out_wheel); strqt = TAILQ_FIRST(&asoc->ss_data.out.wheel);
while (strqt != NULL && strqt->ss_params.prio.priority < strq->ss_params.prio.priority) { while (strqt != NULL && strqt->ss_params.prio.priority < strq->ss_params.prio.priority) {
strqt = TAILQ_NEXT(strqt, ss_params.prio.next_spoke); strqt = TAILQ_NEXT(strqt, ss_params.prio.next_spoke);
} }
if (strqt != NULL) { if (strqt != NULL) {
TAILQ_INSERT_BEFORE(strqt, strq, ss_params.prio.next_spoke); TAILQ_INSERT_BEFORE(strqt, strq, ss_params.prio.next_spoke);
} else { } else {
TAILQ_INSERT_TAIL(&asoc->ss_data.out_wheel, strq, ss_params.prio.next_spoke); TAILQ_INSERT_TAIL(&asoc->ss_data.out.wheel, strq, ss_params.prio.next_spoke);
} }
} }
} }
@ -427,18 +491,18 @@ sctp_ss_prio_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (TAILQ_EMPTY(&strq->outqueue) && if (TAILQ_EMPTY(&strq->outqueue) &&
(strq->ss_params.prio.next_spoke.tqe_next != NULL || (strq->ss_params.prio.next_spoke.tqe_next != NULL ||
strq->ss_params.prio.next_spoke.tqe_prev != NULL)) { strq->ss_params.prio.next_spoke.tqe_prev != NULL)) {
if (asoc->last_out_stream == strq) { if (asoc->ss_data.last_out_stream == strq) {
asoc->last_out_stream = TAILQ_PREV(asoc->last_out_stream, sctpwheel_listhead, asoc->ss_data.last_out_stream = TAILQ_PREV(asoc->ss_data.last_out_stream, sctpwheel_listhead,
ss_params.prio.next_spoke); ss_params.prio.next_spoke);
if (asoc->last_out_stream == NULL) { if (asoc->ss_data.last_out_stream == NULL) {
asoc->last_out_stream = TAILQ_LAST(&asoc->ss_data.out_wheel, asoc->ss_data.last_out_stream = TAILQ_LAST(&asoc->ss_data.out.wheel,
sctpwheel_listhead); sctpwheel_listhead);
} }
if (asoc->last_out_stream == strq) { if (asoc->ss_data.last_out_stream == strq) {
asoc->last_out_stream = NULL; asoc->ss_data.last_out_stream = NULL;
} }
} }
TAILQ_REMOVE(&asoc->ss_data.out_wheel, strq, ss_params.prio.next_spoke); TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.prio.next_spoke);
strq->ss_params.prio.next_spoke.tqe_next = NULL; strq->ss_params.prio.next_spoke.tqe_next = NULL;
strq->ss_params.prio.next_spoke.tqe_prev = NULL; strq->ss_params.prio.next_spoke.tqe_prev = NULL;
} }
@ -454,18 +518,21 @@ sctp_ss_prio_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net,
{ {
struct sctp_stream_out *strq, *strqt, *strqn; struct sctp_stream_out *strq, *strqt, *strqn;
strqt = asoc->last_out_stream; if (asoc->ss_data.locked_on_sending) {
return (asoc->ss_data.locked_on_sending);
}
strqt = asoc->ss_data.last_out_stream;
prio_again: prio_again:
/* Find the next stream to use */ /* Find the next stream to use */
if (strqt == NULL) { if (strqt == NULL) {
strq = TAILQ_FIRST(&asoc->ss_data.out_wheel); strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
} else { } else {
strqn = TAILQ_NEXT(strqt, ss_params.prio.next_spoke); strqn = TAILQ_NEXT(strqt, ss_params.prio.next_spoke);
if (strqn != NULL && if (strqn != NULL &&
strqn->ss_params.prio.priority == strqt->ss_params.prio.priority) { strqn->ss_params.prio.priority == strqt->ss_params.prio.priority) {
strq = strqn; strq = strqn;
} else { } else {
strq = TAILQ_FIRST(&asoc->ss_data.out_wheel); strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
} }
} }
@ -485,7 +552,7 @@ prio_again:
if (TAILQ_FIRST(&strq->outqueue) && if (TAILQ_FIRST(&strq->outqueue) &&
TAILQ_FIRST(&strq->outqueue)->net != NULL && TAILQ_FIRST(&strq->outqueue)->net != NULL &&
TAILQ_FIRST(&strq->outqueue)->net != net) { TAILQ_FIRST(&strq->outqueue)->net != net) {
if (strq == asoc->last_out_stream) { if (strq == asoc->ss_data.last_out_stream) {
return (NULL); return (NULL);
} else { } else {
strqt = strq; strqt = strq;
@ -531,16 +598,18 @@ sctp_ss_fb_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (holds_lock == 0) { if (holds_lock == 0) {
SCTP_TCB_SEND_LOCK(stcb); SCTP_TCB_SEND_LOCK(stcb);
} }
while (!TAILQ_EMPTY(&asoc->ss_data.out_wheel)) { while (!TAILQ_EMPTY(&asoc->ss_data.out.wheel)) {
struct sctp_stream_out *strq = TAILQ_FIRST(&asoc->ss_data.out_wheel); struct sctp_stream_out *strq;
strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
if (clear_values) { if (clear_values) {
strq->ss_params.fb.rounds = -1; strq->ss_params.fb.rounds = -1;
} }
TAILQ_REMOVE(&asoc->ss_data.out_wheel, TAILQ_FIRST(&asoc->ss_data.out_wheel), ss_params.fb.next_spoke); TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.fb.next_spoke);
strq->ss_params.fb.next_spoke.tqe_next = NULL; strq->ss_params.fb.next_spoke.tqe_next = NULL;
strq->ss_params.fb.next_spoke.tqe_prev = NULL; strq->ss_params.fb.next_spoke.tqe_prev = NULL;
} }
asoc->last_out_stream = NULL; asoc->ss_data.last_out_stream = NULL;
if (holds_lock == 0) { if (holds_lock == 0) {
SCTP_TCB_SEND_UNLOCK(stcb); SCTP_TCB_SEND_UNLOCK(stcb);
} }
@ -548,8 +617,16 @@ sctp_ss_fb_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
} }
static void static void
sctp_ss_fb_init_stream(struct sctp_stream_out *strq, struct sctp_stream_out *with_strq) sctp_ss_fb_init_stream(struct sctp_tcb *stcb, struct sctp_stream_out *strq, struct sctp_stream_out *with_strq)
{ {
if (with_strq != NULL) {
if (stcb->asoc.ss_data.locked_on_sending == with_strq) {
stcb->asoc.ss_data.locked_on_sending = strq;
}
if (stcb->asoc.ss_data.last_out_stream == with_strq) {
stcb->asoc.ss_data.last_out_stream = strq;
}
}
strq->ss_params.fb.next_spoke.tqe_next = NULL; strq->ss_params.fb.next_spoke.tqe_next = NULL;
strq->ss_params.fb.next_spoke.tqe_prev = NULL; strq->ss_params.fb.next_spoke.tqe_prev = NULL;
if (with_strq != NULL) { if (with_strq != NULL) {
@ -573,7 +650,7 @@ sctp_ss_fb_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
(strq->ss_params.fb.next_spoke.tqe_prev == NULL)) { (strq->ss_params.fb.next_spoke.tqe_prev == NULL)) {
if (strq->ss_params.fb.rounds < 0) if (strq->ss_params.fb.rounds < 0)
strq->ss_params.fb.rounds = TAILQ_FIRST(&strq->outqueue)->length; strq->ss_params.fb.rounds = TAILQ_FIRST(&strq->outqueue)->length;
TAILQ_INSERT_TAIL(&asoc->ss_data.out_wheel, strq, ss_params.fb.next_spoke); TAILQ_INSERT_TAIL(&asoc->ss_data.out.wheel, strq, ss_params.fb.next_spoke);
} }
if (holds_lock == 0) { if (holds_lock == 0) {
SCTP_TCB_SEND_UNLOCK(stcb); SCTP_TCB_SEND_UNLOCK(stcb);
@ -593,18 +670,18 @@ sctp_ss_fb_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (TAILQ_EMPTY(&strq->outqueue) && if (TAILQ_EMPTY(&strq->outqueue) &&
(strq->ss_params.fb.next_spoke.tqe_next != NULL || (strq->ss_params.fb.next_spoke.tqe_next != NULL ||
strq->ss_params.fb.next_spoke.tqe_prev != NULL)) { strq->ss_params.fb.next_spoke.tqe_prev != NULL)) {
if (asoc->last_out_stream == strq) { if (asoc->ss_data.last_out_stream == strq) {
asoc->last_out_stream = TAILQ_PREV(asoc->last_out_stream, sctpwheel_listhead, asoc->ss_data.last_out_stream = TAILQ_PREV(asoc->ss_data.last_out_stream, sctpwheel_listhead,
ss_params.fb.next_spoke); ss_params.fb.next_spoke);
if (asoc->last_out_stream == NULL) { if (asoc->ss_data.last_out_stream == NULL) {
asoc->last_out_stream = TAILQ_LAST(&asoc->ss_data.out_wheel, asoc->ss_data.last_out_stream = TAILQ_LAST(&asoc->ss_data.out.wheel,
sctpwheel_listhead); sctpwheel_listhead);
} }
if (asoc->last_out_stream == strq) { if (asoc->ss_data.last_out_stream == strq) {
asoc->last_out_stream = NULL; asoc->ss_data.last_out_stream = NULL;
} }
} }
TAILQ_REMOVE(&asoc->ss_data.out_wheel, strq, ss_params.fb.next_spoke); TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.fb.next_spoke);
strq->ss_params.fb.next_spoke.tqe_next = NULL; strq->ss_params.fb.next_spoke.tqe_next = NULL;
strq->ss_params.fb.next_spoke.tqe_prev = NULL; strq->ss_params.fb.next_spoke.tqe_prev = NULL;
} }
@ -620,11 +697,14 @@ sctp_ss_fb_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net,
{ {
struct sctp_stream_out *strq = NULL, *strqt; struct sctp_stream_out *strq = NULL, *strqt;
if (asoc->last_out_stream == NULL || if (asoc->ss_data.locked_on_sending) {
TAILQ_FIRST(&asoc->ss_data.out_wheel) == TAILQ_LAST(&asoc->ss_data.out_wheel, sctpwheel_listhead)) { return (asoc->ss_data.locked_on_sending);
strqt = TAILQ_FIRST(&asoc->ss_data.out_wheel); }
if (asoc->ss_data.last_out_stream == NULL ||
TAILQ_FIRST(&asoc->ss_data.out.wheel) == TAILQ_LAST(&asoc->ss_data.out.wheel, sctpwheel_listhead)) {
strqt = TAILQ_FIRST(&asoc->ss_data.out.wheel);
} else { } else {
strqt = TAILQ_NEXT(asoc->last_out_stream, ss_params.fb.next_spoke); strqt = TAILQ_NEXT(asoc->ss_data.last_out_stream, ss_params.fb.next_spoke);
} }
do { do {
if ((strqt != NULL) && if ((strqt != NULL) &&
@ -641,22 +721,33 @@ sctp_ss_fb_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net,
if (strqt != NULL) { if (strqt != NULL) {
strqt = TAILQ_NEXT(strqt, ss_params.fb.next_spoke); strqt = TAILQ_NEXT(strqt, ss_params.fb.next_spoke);
} else { } else {
strqt = TAILQ_FIRST(&asoc->ss_data.out_wheel); strqt = TAILQ_FIRST(&asoc->ss_data.out.wheel);
} }
} while (strqt != strq); } while (strqt != strq);
return (strq); return (strq);
} }
static void static void
sctp_ss_fb_scheduled(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net SCTP_UNUSED, sctp_ss_fb_scheduled(struct sctp_tcb *stcb, struct sctp_nets *net SCTP_UNUSED,
struct sctp_association *asoc, struct sctp_stream_out *strq, struct sctp_association *asoc, struct sctp_stream_out *strq,
int moved_how_much SCTP_UNUSED) int moved_how_much SCTP_UNUSED)
{ {
struct sctp_stream_queue_pending *sp;
struct sctp_stream_out *strqt; struct sctp_stream_out *strqt;
int subtract; int subtract;
if (stcb->asoc.idata_supported == 0) {
sp = TAILQ_FIRST(&strq->outqueue);
if ((sp != NULL) && (sp->some_taken == 1)) {
stcb->asoc.ss_data.locked_on_sending = strq;
} else {
stcb->asoc.ss_data.locked_on_sending = NULL;
}
} else {
stcb->asoc.ss_data.locked_on_sending = NULL;
}
subtract = strq->ss_params.fb.rounds; subtract = strq->ss_params.fb.rounds;
TAILQ_FOREACH(strqt, &asoc->ss_data.out_wheel, ss_params.fb.next_spoke) { TAILQ_FOREACH(strqt, &asoc->ss_data.out.wheel, ss_params.fb.next_spoke) {
strqt->ss_params.fb.rounds -= subtract; strqt->ss_params.fb.rounds -= subtract;
if (strqt->ss_params.fb.rounds < 0) if (strqt->ss_params.fb.rounds < 0)
strqt->ss_params.fb.rounds = 0; strqt->ss_params.fb.rounds = 0;
@ -666,7 +757,7 @@ sctp_ss_fb_scheduled(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net SC
} else { } else {
strq->ss_params.fb.rounds = -1; strq->ss_params.fb.rounds = -1;
} }
asoc->last_out_stream = strq; asoc->ss_data.last_out_stream = strq;
return; return;
} }
@ -676,8 +767,8 @@ sctp_ss_fb_scheduled(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net SC
*/ */
static void static void
sctp_ss_fcfs_add(struct sctp_tcb *stcb, struct sctp_association *asoc, sctp_ss_fcfs_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
struct sctp_stream_out *strq, struct sctp_stream_queue_pending *sp, struct sctp_stream_out *strq SCTP_UNUSED,
int holds_lock); struct sctp_stream_queue_pending *sp, int holds_lock);
static void static void
sctp_ss_fcfs_init(struct sctp_tcb *stcb, struct sctp_association *asoc, sctp_ss_fcfs_init(struct sctp_tcb *stcb, struct sctp_association *asoc,
@ -687,7 +778,10 @@ sctp_ss_fcfs_init(struct sctp_tcb *stcb, struct sctp_association *asoc,
struct sctp_stream_queue_pending *sp; struct sctp_stream_queue_pending *sp;
uint16_t i; uint16_t i;
TAILQ_INIT(&asoc->ss_data.out_list); if (holds_lock == 0) {
SCTP_TCB_SEND_LOCK(stcb);
}
TAILQ_INIT(&asoc->ss_data.out.list);
/* /*
* If there is data in the stream queues already, * If there is data in the stream queues already,
* the scheduler of an existing association has * the scheduler of an existing association has
@ -706,12 +800,15 @@ sctp_ss_fcfs_init(struct sctp_tcb *stcb, struct sctp_association *asoc,
x++; x++;
} }
if (sp != NULL) { if (sp != NULL) {
sctp_ss_fcfs_add(stcb, &stcb->asoc, &stcb->asoc.strmout[i], sp, holds_lock); sctp_ss_fcfs_add(stcb, &stcb->asoc, &stcb->asoc.strmout[i], sp, 1);
add_more = 1; add_more = 1;
} }
} }
n++; n++;
} }
if (holds_lock == 0) {
SCTP_TCB_SEND_UNLOCK(stcb);
}
return; return;
} }
@ -719,12 +816,17 @@ static void
sctp_ss_fcfs_clear(struct sctp_tcb *stcb, struct sctp_association *asoc, sctp_ss_fcfs_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
int clear_values, int holds_lock) int clear_values, int holds_lock)
{ {
struct sctp_stream_queue_pending *sp;
if (clear_values) { if (clear_values) {
if (holds_lock == 0) { if (holds_lock == 0) {
SCTP_TCB_SEND_LOCK(stcb); SCTP_TCB_SEND_LOCK(stcb);
} }
while (!TAILQ_EMPTY(&asoc->ss_data.out_list)) { while (!TAILQ_EMPTY(&asoc->ss_data.out.list)) {
TAILQ_REMOVE(&asoc->ss_data.out_list, TAILQ_FIRST(&asoc->ss_data.out_list), ss_next); sp = TAILQ_FIRST(&asoc->ss_data.out.list);
TAILQ_REMOVE(&asoc->ss_data.out.list, sp, ss_next);
sp->ss_next.tqe_next = NULL;
sp->ss_next.tqe_prev = NULL;
} }
if (holds_lock == 0) { if (holds_lock == 0) {
SCTP_TCB_SEND_UNLOCK(stcb); SCTP_TCB_SEND_UNLOCK(stcb);
@ -734,9 +836,18 @@ sctp_ss_fcfs_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
} }
static void static void
sctp_ss_fcfs_init_stream(struct sctp_stream_out *strq SCTP_UNUSED, struct sctp_stream_out *with_strq SCTP_UNUSED) sctp_ss_fcfs_init_stream(struct sctp_tcb *stcb, struct sctp_stream_out *strq, struct sctp_stream_out *with_strq)
{ {
/* Nothing to be done here */ if (with_strq != NULL) {
if (stcb->asoc.ss_data.locked_on_sending == with_strq) {
stcb->asoc.ss_data.locked_on_sending = strq;
}
if (stcb->asoc.ss_data.last_out_stream == with_strq) {
stcb->asoc.ss_data.last_out_stream = strq;
}
}
strq->ss_params.fb.next_spoke.tqe_next = NULL;
strq->ss_params.fb.next_spoke.tqe_prev = NULL;
return; return;
} }
@ -750,7 +861,7 @@ sctp_ss_fcfs_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
} }
if (sp && (sp->ss_next.tqe_next == NULL) && if (sp && (sp->ss_next.tqe_next == NULL) &&
(sp->ss_next.tqe_prev == NULL)) { (sp->ss_next.tqe_prev == NULL)) {
TAILQ_INSERT_TAIL(&asoc->ss_data.out_list, sp, ss_next); TAILQ_INSERT_TAIL(&asoc->ss_data.out.list, sp, ss_next);
} }
if (holds_lock == 0) { if (holds_lock == 0) {
SCTP_TCB_SEND_UNLOCK(stcb); SCTP_TCB_SEND_UNLOCK(stcb);
@ -761,7 +872,7 @@ sctp_ss_fcfs_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
static int static int
sctp_ss_fcfs_is_empty(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_association *asoc) sctp_ss_fcfs_is_empty(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_association *asoc)
{ {
if (TAILQ_EMPTY(&asoc->ss_data.out_list)) { if (TAILQ_EMPTY(&asoc->ss_data.out.list)) {
return (1); return (1);
} else { } else {
return (0); return (0);
@ -779,7 +890,9 @@ sctp_ss_fcfs_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (sp && if (sp &&
((sp->ss_next.tqe_next != NULL) || ((sp->ss_next.tqe_next != NULL) ||
(sp->ss_next.tqe_prev != NULL))) { (sp->ss_next.tqe_prev != NULL))) {
TAILQ_REMOVE(&asoc->ss_data.out_list, sp, ss_next); TAILQ_REMOVE(&asoc->ss_data.out.list, sp, ss_next);
sp->ss_next.tqe_next = NULL;
sp->ss_next.tqe_prev = NULL;
} }
if (holds_lock == 0) { if (holds_lock == 0) {
SCTP_TCB_SEND_UNLOCK(stcb); SCTP_TCB_SEND_UNLOCK(stcb);
@ -787,7 +900,6 @@ sctp_ss_fcfs_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
return; return;
} }
static struct sctp_stream_out * static struct sctp_stream_out *
sctp_ss_fcfs_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, sctp_ss_fcfs_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net,
struct sctp_association *asoc) struct sctp_association *asoc)
@ -795,10 +907,13 @@ sctp_ss_fcfs_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net,
struct sctp_stream_out *strq; struct sctp_stream_out *strq;
struct sctp_stream_queue_pending *sp; struct sctp_stream_queue_pending *sp;
sp = TAILQ_FIRST(&asoc->ss_data.out_list); if (asoc->ss_data.locked_on_sending) {
return (asoc->ss_data.locked_on_sending);
}
sp = TAILQ_FIRST(&asoc->ss_data.out.list);
default_again: default_again:
if (sp != NULL) { if (sp != NULL) {
strq = &asoc->strmout[sp->stream]; strq = &asoc->strmout[sp->sid];
} else { } else {
strq = NULL; strq = NULL;
} }
@ -827,10 +942,10 @@ default_again:
return (strq); return (strq);
} }
struct sctp_ss_functions sctp_ss_functions[] = { const struct sctp_ss_functions sctp_ss_functions[] = {
/* SCTP_SS_DEFAULT */ /* SCTP_SS_DEFAULT */
{ {
#if defined(__Windows__) || defined(__Userspace_os_Windows) #if defined(_WIN32)
sctp_ss_default_init, sctp_ss_default_init,
sctp_ss_default_clear, sctp_ss_default_clear,
sctp_ss_default_init_stream, sctp_ss_default_init_stream,
@ -841,7 +956,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
sctp_ss_default_scheduled, sctp_ss_default_scheduled,
sctp_ss_default_packet_done, sctp_ss_default_packet_done,
sctp_ss_default_get_value, sctp_ss_default_get_value,
sctp_ss_default_set_value sctp_ss_default_set_value,
sctp_ss_default_is_user_msgs_incomplete
#else #else
.sctp_ss_init = sctp_ss_default_init, .sctp_ss_init = sctp_ss_default_init,
.sctp_ss_clear = sctp_ss_default_clear, .sctp_ss_clear = sctp_ss_default_clear,
@ -853,12 +969,13 @@ struct sctp_ss_functions sctp_ss_functions[] = {
.sctp_ss_scheduled = sctp_ss_default_scheduled, .sctp_ss_scheduled = sctp_ss_default_scheduled,
.sctp_ss_packet_done = sctp_ss_default_packet_done, .sctp_ss_packet_done = sctp_ss_default_packet_done,
.sctp_ss_get_value = sctp_ss_default_get_value, .sctp_ss_get_value = sctp_ss_default_get_value,
.sctp_ss_set_value = sctp_ss_default_set_value .sctp_ss_set_value = sctp_ss_default_set_value,
.sctp_ss_is_user_msgs_incomplete = sctp_ss_default_is_user_msgs_incomplete
#endif #endif
}, },
/* SCTP_SS_ROUND_ROBIN */ /* SCTP_SS_ROUND_ROBIN */
{ {
#if defined(__Windows__) || defined(__Userspace_os_Windows) #if defined(_WIN32)
sctp_ss_default_init, sctp_ss_default_init,
sctp_ss_default_clear, sctp_ss_default_clear,
sctp_ss_default_init_stream, sctp_ss_default_init_stream,
@ -869,7 +986,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
sctp_ss_default_scheduled, sctp_ss_default_scheduled,
sctp_ss_default_packet_done, sctp_ss_default_packet_done,
sctp_ss_default_get_value, sctp_ss_default_get_value,
sctp_ss_default_set_value sctp_ss_default_set_value,
sctp_ss_default_is_user_msgs_incomplete
#else #else
.sctp_ss_init = sctp_ss_default_init, .sctp_ss_init = sctp_ss_default_init,
.sctp_ss_clear = sctp_ss_default_clear, .sctp_ss_clear = sctp_ss_default_clear,
@ -881,12 +999,13 @@ struct sctp_ss_functions sctp_ss_functions[] = {
.sctp_ss_scheduled = sctp_ss_default_scheduled, .sctp_ss_scheduled = sctp_ss_default_scheduled,
.sctp_ss_packet_done = sctp_ss_default_packet_done, .sctp_ss_packet_done = sctp_ss_default_packet_done,
.sctp_ss_get_value = sctp_ss_default_get_value, .sctp_ss_get_value = sctp_ss_default_get_value,
.sctp_ss_set_value = sctp_ss_default_set_value .sctp_ss_set_value = sctp_ss_default_set_value,
.sctp_ss_is_user_msgs_incomplete = sctp_ss_default_is_user_msgs_incomplete
#endif #endif
}, },
/* SCTP_SS_ROUND_ROBIN_PACKET */ /* SCTP_SS_ROUND_ROBIN_PACKET */
{ {
#if defined(__Windows__) || defined(__Userspace_os_Windows) #if defined(_WIN32)
sctp_ss_default_init, sctp_ss_default_init,
sctp_ss_default_clear, sctp_ss_default_clear,
sctp_ss_default_init_stream, sctp_ss_default_init_stream,
@ -897,7 +1016,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
sctp_ss_default_scheduled, sctp_ss_default_scheduled,
sctp_ss_rrp_packet_done, sctp_ss_rrp_packet_done,
sctp_ss_default_get_value, sctp_ss_default_get_value,
sctp_ss_default_set_value sctp_ss_default_set_value,
sctp_ss_default_is_user_msgs_incomplete
#else #else
.sctp_ss_init = sctp_ss_default_init, .sctp_ss_init = sctp_ss_default_init,
.sctp_ss_clear = sctp_ss_default_clear, .sctp_ss_clear = sctp_ss_default_clear,
@ -909,12 +1029,13 @@ struct sctp_ss_functions sctp_ss_functions[] = {
.sctp_ss_scheduled = sctp_ss_default_scheduled, .sctp_ss_scheduled = sctp_ss_default_scheduled,
.sctp_ss_packet_done = sctp_ss_rrp_packet_done, .sctp_ss_packet_done = sctp_ss_rrp_packet_done,
.sctp_ss_get_value = sctp_ss_default_get_value, .sctp_ss_get_value = sctp_ss_default_get_value,
.sctp_ss_set_value = sctp_ss_default_set_value .sctp_ss_set_value = sctp_ss_default_set_value,
.sctp_ss_is_user_msgs_incomplete = sctp_ss_default_is_user_msgs_incomplete
#endif #endif
}, },
/* SCTP_SS_PRIORITY */ /* SCTP_SS_PRIORITY */
{ {
#if defined(__Windows__) || defined(__Userspace_os_Windows) #if defined(_WIN32)
sctp_ss_default_init, sctp_ss_default_init,
sctp_ss_prio_clear, sctp_ss_prio_clear,
sctp_ss_prio_init_stream, sctp_ss_prio_init_stream,
@ -925,7 +1046,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
sctp_ss_default_scheduled, sctp_ss_default_scheduled,
sctp_ss_default_packet_done, sctp_ss_default_packet_done,
sctp_ss_prio_get_value, sctp_ss_prio_get_value,
sctp_ss_prio_set_value sctp_ss_prio_set_value,
sctp_ss_default_is_user_msgs_incomplete
#else #else
.sctp_ss_init = sctp_ss_default_init, .sctp_ss_init = sctp_ss_default_init,
.sctp_ss_clear = sctp_ss_prio_clear, .sctp_ss_clear = sctp_ss_prio_clear,
@ -937,12 +1059,13 @@ struct sctp_ss_functions sctp_ss_functions[] = {
.sctp_ss_scheduled = sctp_ss_default_scheduled, .sctp_ss_scheduled = sctp_ss_default_scheduled,
.sctp_ss_packet_done = sctp_ss_default_packet_done, .sctp_ss_packet_done = sctp_ss_default_packet_done,
.sctp_ss_get_value = sctp_ss_prio_get_value, .sctp_ss_get_value = sctp_ss_prio_get_value,
.sctp_ss_set_value = sctp_ss_prio_set_value .sctp_ss_set_value = sctp_ss_prio_set_value,
.sctp_ss_is_user_msgs_incomplete = sctp_ss_default_is_user_msgs_incomplete
#endif #endif
}, },
/* SCTP_SS_FAIR_BANDWITH */ /* SCTP_SS_FAIR_BANDWITH */
{ {
#if defined(__Windows__) || defined(__Userspace_os_Windows) #if defined(_WIN32)
sctp_ss_default_init, sctp_ss_default_init,
sctp_ss_fb_clear, sctp_ss_fb_clear,
sctp_ss_fb_init_stream, sctp_ss_fb_init_stream,
@ -953,7 +1076,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
sctp_ss_fb_scheduled, sctp_ss_fb_scheduled,
sctp_ss_default_packet_done, sctp_ss_default_packet_done,
sctp_ss_default_get_value, sctp_ss_default_get_value,
sctp_ss_default_set_value sctp_ss_default_set_value,
sctp_ss_default_is_user_msgs_incomplete
#else #else
.sctp_ss_init = sctp_ss_default_init, .sctp_ss_init = sctp_ss_default_init,
.sctp_ss_clear = sctp_ss_fb_clear, .sctp_ss_clear = sctp_ss_fb_clear,
@ -965,12 +1089,13 @@ struct sctp_ss_functions sctp_ss_functions[] = {
.sctp_ss_scheduled = sctp_ss_fb_scheduled, .sctp_ss_scheduled = sctp_ss_fb_scheduled,
.sctp_ss_packet_done = sctp_ss_default_packet_done, .sctp_ss_packet_done = sctp_ss_default_packet_done,
.sctp_ss_get_value = sctp_ss_default_get_value, .sctp_ss_get_value = sctp_ss_default_get_value,
.sctp_ss_set_value = sctp_ss_default_set_value .sctp_ss_set_value = sctp_ss_default_set_value,
.sctp_ss_is_user_msgs_incomplete = sctp_ss_default_is_user_msgs_incomplete
#endif #endif
}, },
/* SCTP_SS_FIRST_COME */ /* SCTP_SS_FIRST_COME */
{ {
#if defined(__Windows__) || defined(__Userspace_os_Windows) #if defined(_WIN32)
sctp_ss_fcfs_init, sctp_ss_fcfs_init,
sctp_ss_fcfs_clear, sctp_ss_fcfs_clear,
sctp_ss_fcfs_init_stream, sctp_ss_fcfs_init_stream,
@ -981,7 +1106,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
sctp_ss_default_scheduled, sctp_ss_default_scheduled,
sctp_ss_default_packet_done, sctp_ss_default_packet_done,
sctp_ss_default_get_value, sctp_ss_default_get_value,
sctp_ss_default_set_value sctp_ss_default_set_value,
sctp_ss_default_is_user_msgs_incomplete
#else #else
.sctp_ss_init = sctp_ss_fcfs_init, .sctp_ss_init = sctp_ss_fcfs_init,
.sctp_ss_clear = sctp_ss_fcfs_clear, .sctp_ss_clear = sctp_ss_fcfs_clear,
@ -993,7 +1119,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
.sctp_ss_scheduled = sctp_ss_default_scheduled, .sctp_ss_scheduled = sctp_ss_default_scheduled,
.sctp_ss_packet_done = sctp_ss_default_packet_done, .sctp_ss_packet_done = sctp_ss_default_packet_done,
.sctp_ss_get_value = sctp_ss_default_get_value, .sctp_ss_get_value = sctp_ss_default_get_value,
.sctp_ss_set_value = sctp_ss_default_set_value .sctp_ss_set_value = sctp_ss_default_set_value,
.sctp_ss_is_user_msgs_incomplete = sctp_ss_default_is_user_msgs_incomplete
#endif #endif
} }
}; };

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 279859 2015-03-10 19:49:25Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 365071 2020-09-01 21:19:14Z mjg $");
#endif #endif
#ifndef _NETINET_SCTP_STRUCTS_H_ #ifndef _NETINET_SCTP_STRUCTS_H_
@ -53,7 +55,7 @@ struct sctp_timer {
void *ep; void *ep;
void *tcb; void *tcb;
void *net; void *net;
#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 #if defined(__FreeBSD__) && !defined(__Userspace__)
void *vnet; void *vnet;
#endif #endif
@ -63,7 +65,6 @@ struct sctp_timer {
uint32_t stopped_from; uint32_t stopped_from;
}; };
struct sctp_foo_stuff { struct sctp_foo_stuff {
struct sctp_inpcb *inp; struct sctp_inpcb *inp;
uint32_t lineno; uint32_t lineno;
@ -71,7 +72,6 @@ struct sctp_foo_stuff {
int updown; int updown;
}; };
/* /*
* This is the information we track on each interface that we know about from * This is the information we track on each interface that we know about from
* the distant end. * the distant end.
@ -80,6 +80,7 @@ TAILQ_HEAD(sctpnetlisthead, sctp_nets);
struct sctp_stream_reset_list { struct sctp_stream_reset_list {
TAILQ_ENTRY(sctp_stream_reset_list) next_resp; TAILQ_ENTRY(sctp_stream_reset_list) next_resp;
uint32_t seq;
uint32_t tsn; uint32_t tsn;
uint32_t number_entries; uint32_t number_entries;
uint16_t list_of_streams[]; uint16_t list_of_streams[];
@ -110,13 +111,12 @@ typedef void (*asoc_func) (struct sctp_inpcb *, struct sctp_tcb *, void *ptr,
typedef int (*inp_func) (struct sctp_inpcb *, void *ptr, uint32_t val); typedef int (*inp_func) (struct sctp_inpcb *, void *ptr, uint32_t val);
typedef void (*end_func) (void *ptr, uint32_t val); typedef void (*end_func) (void *ptr, uint32_t val);
#if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP) #if defined(__FreeBSD__) && !defined(__Userspace__)
#if defined(SCTP_MCORE_INPUT) && defined(SMP)
/* whats on the mcore control struct */ /* whats on the mcore control struct */
struct sctp_mcore_queue { struct sctp_mcore_queue {
TAILQ_ENTRY(sctp_mcore_queue) next; TAILQ_ENTRY(sctp_mcore_queue) next;
#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
struct vnet *vn; struct vnet *vn;
#endif
struct mbuf *m; struct mbuf *m;
int off; int off;
int v6; int v6;
@ -132,14 +132,12 @@ struct sctp_mcore_ctrl {
int running; int running;
int cpuid; int cpuid;
}; };
#endif #endif
#endif
struct sctp_iterator { struct sctp_iterator {
TAILQ_ENTRY(sctp_iterator) sctp_nxt_itr; TAILQ_ENTRY(sctp_iterator) sctp_nxt_itr;
#if defined(__FreeBSD__) && __FreeBSD_version >= 801000 #if defined(__FreeBSD__) && !defined(__Userspace__)
struct vnet *vn; struct vnet *vn;
#endif #endif
struct sctp_timer tmr; struct sctp_timer tmr;
@ -163,14 +161,13 @@ struct sctp_iterator {
#define SCTP_ITERATOR_DO_ALL_INP 0x00000001 #define SCTP_ITERATOR_DO_ALL_INP 0x00000001
#define SCTP_ITERATOR_DO_SINGLE_INP 0x00000002 #define SCTP_ITERATOR_DO_SINGLE_INP 0x00000002
TAILQ_HEAD(sctpiterators, sctp_iterator); TAILQ_HEAD(sctpiterators, sctp_iterator);
struct sctp_copy_all { struct sctp_copy_all {
struct sctp_inpcb *inp; /* ep */ struct sctp_inpcb *inp; /* ep */
struct mbuf *m; struct mbuf *m;
struct sctp_sndrcvinfo sndrcv; struct sctp_sndrcvinfo sndrcv;
int sndlen; ssize_t sndlen;
int cnt_sent; int cnt_sent;
int cnt_failed; int cnt_failed;
}; };
@ -181,10 +178,10 @@ struct sctp_asconf_iterator {
}; };
struct iterator_control { struct iterator_control {
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
struct mtx ipi_iterator_wq_mtx; struct mtx ipi_iterator_wq_mtx;
struct mtx it_mtx; struct mtx it_mtx;
#elif defined(__APPLE__) #elif defined(__APPLE__) && !defined(__Userspace__)
lck_mtx_t *ipi_iterator_wq_mtx; lck_mtx_t *ipi_iterator_wq_mtx;
lck_mtx_t *it_mtx; lck_mtx_t *it_mtx;
#elif defined(SCTP_PROCESS_LEVEL_LOCKS) #elif defined(SCTP_PROCESS_LEVEL_LOCKS)
@ -197,7 +194,7 @@ struct iterator_control {
pthread_mutex_t it_mtx; pthread_mutex_t it_mtx;
pthread_cond_t iterator_wakeup; pthread_cond_t iterator_wakeup;
#endif #endif
#elif defined(__Windows__) #elif defined(_WIN32) && !defined(__Userspace__)
struct spinlock it_lock; struct spinlock it_lock;
struct spinlock ipi_iterator_wq_lock; struct spinlock ipi_iterator_wq_lock;
KEVENT iterator_wakeup[2]; KEVENT iterator_wakeup[2];
@ -205,7 +202,7 @@ struct iterator_control {
#else #else
void *it_mtx; void *it_mtx;
#endif #endif
#if !defined(__Windows__) #if !(defined(_WIN32) && !defined(__Userspace__))
#if !defined(__Userspace__) #if !defined(__Userspace__)
SCTP_PROCESS_STRUCT thread_proc; SCTP_PROCESS_STRUCT thread_proc;
#else #else
@ -217,7 +214,7 @@ struct iterator_control {
uint32_t iterator_running; uint32_t iterator_running;
uint32_t iterator_flags; uint32_t iterator_flags;
}; };
#if !defined(__FreeBSD__) #if !(defined(__FreeBSD__) && !defined(__Userspace__))
#define SCTP_ITERATOR_MUST_EXIT 0x00000001 #define SCTP_ITERATOR_MUST_EXIT 0x00000001
#define SCTP_ITERATOR_EXITED 0x00000002 #define SCTP_ITERATOR_EXITED 0x00000002
#endif #endif
@ -225,17 +222,21 @@ struct iterator_control {
#define SCTP_ITERATOR_STOP_CUR_INP 0x00000008 #define SCTP_ITERATOR_STOP_CUR_INP 0x00000008
struct sctp_net_route { struct sctp_net_route {
#if defined(__FreeBSD__) && !defined(__Userspace__)
struct nhop_object *ro_nh;
struct llentry *ro_lle;
char *ro_prepend;
uint16_t ro_plen;
uint16_t ro_flags;
uint16_t ro_mtu;
uint16_t spare;
#else
sctp_rtentry_t *ro_rt; sctp_rtentry_t *ro_rt;
#if defined(__FreeBSD__)
#if __FreeBSD_version >= 800000
void *ro_lle;
#endif #endif
#if __FreeBSD_version >= 900000 #if defined(__APPLE__) && !defined(__Userspace__)
void *ro_ia; #if !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION) && !defined(APPLE_ELCAPITAN)
int ro_flags; struct llentry *ro_lle;
#endif #endif
#endif
#if defined(__APPLE__)
#if !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION) #if !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION)
struct ifaddr *ro_srcia; struct ifaddr *ro_srcia;
#endif #endif
@ -289,7 +290,6 @@ struct rtcc_cc {
uint8_t last_inst_ind; /* Last saved inst indication */ uint8_t last_inst_ind; /* Last saved inst indication */
}; };
struct sctp_nets { struct sctp_nets {
TAILQ_ENTRY(sctp_nets) sctp_next; /* next link */ TAILQ_ENTRY(sctp_nets) sctp_next; /* next link */
@ -317,7 +317,7 @@ struct sctp_nets {
int lastsa; int lastsa;
int lastsv; int lastsv;
uint64_t rtt; /* last measured rtt value in us */ uint64_t rtt; /* last measured rtt value in us */
unsigned int RTO; uint32_t RTO;
/* This is used for SHUTDOWN/SHUTDOWN-ACK/SEND or INIT timers */ /* This is used for SHUTDOWN/SHUTDOWN-ACK/SEND or INIT timers */
struct sctp_timer rxt_timer; struct sctp_timer rxt_timer;
@ -426,18 +426,17 @@ struct sctp_nets {
uint8_t last_hs_used; /* index into the last HS table entry we used */ uint8_t last_hs_used; /* index into the last HS table entry we used */
uint8_t lan_type; uint8_t lan_type;
uint8_t rto_needed; uint8_t rto_needed;
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
uint32_t flowid; uint32_t flowid;
uint8_t flowtype; uint8_t flowtype;
#endif #endif
}; };
struct sctp_data_chunkrec { struct sctp_data_chunkrec {
uint32_t TSN_seq; /* the TSN of this transmit */ uint32_t tsn; /* the TSN of this transmit */
uint16_t stream_seq; /* the stream sequence number of this transmit */ uint32_t mid; /* the message identifier of this transmit */
uint16_t stream_number; /* the stream number of this guy */ uint16_t sid; /* the stream number of this guy */
uint32_t payloadtype; uint32_t ppid;
uint32_t context; /* from send */ uint32_t context; /* from send */
uint32_t cwnd_at_send; uint32_t cwnd_at_send;
/* /*
@ -446,6 +445,7 @@ struct sctp_data_chunkrec {
*/ */
uint32_t fast_retran_tsn; /* sending_seq at the time of FR */ uint32_t fast_retran_tsn; /* sending_seq at the time of FR */
struct timeval timetodrop; /* time we drop it from queue */ struct timeval timetodrop; /* time we drop it from queue */
uint32_t fsn; /* Fragment Sequence Number */
uint8_t doing_fast_retransmit; uint8_t doing_fast_retransmit;
uint8_t rcv_flags; /* flags pulled from data chunk on inbound for uint8_t rcv_flags; /* flags pulled from data chunk on inbound for
* outbound holds sending flags for PR-SCTP. * outbound holds sending flags for PR-SCTP.
@ -470,7 +470,6 @@ struct chk_id {
uint8_t can_take_data; uint8_t can_take_data;
}; };
struct sctp_tmit_chunk { struct sctp_tmit_chunk {
union { union {
struct sctp_data_chunkrec data; struct sctp_data_chunkrec data;
@ -498,14 +497,8 @@ struct sctp_tmit_chunk {
uint8_t window_probe; uint8_t window_probe;
}; };
/*
* The first part of this structure MUST be the entire sinfo structure. Maybe
* I should have made it a sub structure... we can circle back later and do
* that if we want.
*/
struct sctp_queued_to_read { /* sinfo structure Pluse more */ struct sctp_queued_to_read { /* sinfo structure Pluse more */
uint16_t sinfo_stream; /* off the wire */ uint16_t sinfo_stream; /* off the wire */
uint16_t sinfo_ssn; /* off the wire */
uint16_t sinfo_flags; /* SCTP_UNORDERED from wire use SCTP_EOF for uint16_t sinfo_flags; /* SCTP_UNORDERED from wire use SCTP_EOF for
* EOR */ * EOR */
uint32_t sinfo_ppid; /* off the wire */ uint32_t sinfo_ppid; /* off the wire */
@ -515,8 +508,11 @@ struct sctp_queued_to_read { /* sinfo structure Pluse more */
uint32_t sinfo_cumtsn; /* Use this in reassembly as last TSN */ uint32_t sinfo_cumtsn; /* Use this in reassembly as last TSN */
sctp_assoc_t sinfo_assoc_id; /* our assoc id */ sctp_assoc_t sinfo_assoc_id; /* our assoc id */
/* Non sinfo stuff */ /* Non sinfo stuff */
uint32_t mid; /* Fragment Index */
uint32_t length; /* length of data */ uint32_t length; /* length of data */
uint32_t held_length; /* length held in sb */ uint32_t held_length; /* length held in sb */
uint32_t top_fsn; /* Highest FSN in queue */
uint32_t fsn_included; /* Highest FSN in *data portion */
struct sctp_nets *whoFrom; /* where it came from */ struct sctp_nets *whoFrom; /* where it came from */
struct mbuf *data; /* front of the mbuf chain of data with struct mbuf *data; /* front of the mbuf chain of data with
* PKT_HDR */ * PKT_HDR */
@ -524,14 +520,24 @@ struct sctp_queued_to_read { /* sinfo structure Pluse more */
struct mbuf *aux_data; /* used to hold/cache control if o/s does not take it from us */ struct mbuf *aux_data; /* used to hold/cache control if o/s does not take it from us */
struct sctp_tcb *stcb; /* assoc, used for window update */ struct sctp_tcb *stcb; /* assoc, used for window update */
TAILQ_ENTRY(sctp_queued_to_read) next; TAILQ_ENTRY(sctp_queued_to_read) next;
TAILQ_ENTRY(sctp_queued_to_read) next_instrm;
struct sctpchunk_listhead reasm;
uint16_t port_from; uint16_t port_from;
uint16_t spec_flags; /* Flags to hold the notification field */ uint16_t spec_flags; /* Flags to hold the notification field */
uint8_t do_not_ref_stcb; uint8_t do_not_ref_stcb;
uint8_t end_added; uint8_t end_added;
uint8_t pdapi_aborted; uint8_t pdapi_aborted;
uint8_t pdapi_started;
uint8_t some_taken; uint8_t some_taken;
uint8_t last_frag_seen;
uint8_t first_frag_seen;
uint8_t on_read_q;
uint8_t on_strm_q;
}; };
#define SCTP_ON_ORDERED 1
#define SCTP_ON_UNORDERED 2
/* This data structure will be on the outbound /* This data structure will be on the outbound
* stream queues. Data will be pulled off from * stream queues. Data will be pulled off from
* the front of the mbuf data and chunk-ified * the front of the mbuf data and chunk-ified
@ -557,12 +563,13 @@ struct sctp_stream_queue_pending {
struct sctp_nets *net; struct sctp_nets *net;
TAILQ_ENTRY (sctp_stream_queue_pending) next; TAILQ_ENTRY (sctp_stream_queue_pending) next;
TAILQ_ENTRY (sctp_stream_queue_pending) ss_next; TAILQ_ENTRY (sctp_stream_queue_pending) ss_next;
uint32_t fsn;
uint32_t length; uint32_t length;
uint32_t timetolive; uint32_t timetolive;
uint32_t ppid; uint32_t ppid;
uint32_t context; uint32_t context;
uint16_t sinfo_flags; uint16_t sinfo_flags;
uint16_t stream; uint16_t sid;
uint16_t act_flags; uint16_t act_flags;
uint16_t auth_keyid; uint16_t auth_keyid;
uint8_t holds_key_ref; uint8_t holds_key_ref;
@ -571,6 +578,7 @@ struct sctp_stream_queue_pending {
uint8_t sender_all_done; uint8_t sender_all_done;
uint8_t put_last_out; uint8_t put_last_out;
uint8_t discard_rest; uint8_t discard_rest;
uint8_t processing;
}; };
/* /*
@ -580,9 +588,11 @@ struct sctp_stream_queue_pending {
TAILQ_HEAD(sctpwheelunrel_listhead, sctp_stream_in); TAILQ_HEAD(sctpwheelunrel_listhead, sctp_stream_in);
struct sctp_stream_in { struct sctp_stream_in {
struct sctp_readhead inqueue; struct sctp_readhead inqueue;
uint16_t stream_no; struct sctp_readhead uno_inqueue;
uint16_t last_sequence_delivered; /* used for re-order */ uint32_t last_mid_delivered; /* used for re-order */
uint16_t sid;
uint8_t delivery_started; uint8_t delivery_started;
uint8_t pd_api_started;
}; };
TAILQ_HEAD(sctpwheel_listhead, sctp_stream_out); TAILQ_HEAD(sctpwheel_listhead, sctp_stream_out);
@ -614,9 +624,14 @@ struct ss_fb {
* This union holds all data necessary for * This union holds all data necessary for
* different stream schedulers. * different stream schedulers.
*/ */
union scheduling_data { struct scheduling_data {
struct sctpwheel_listhead out_wheel; struct sctp_stream_out *locked_on_sending;
struct sctplist_listhead out_list; /* circular looking for output selection */
struct sctp_stream_out *last_out_stream;
union {
struct sctpwheel_listhead wheel;
struct sctplist_listhead list;
} out;
}; };
/* /*
@ -629,11 +644,20 @@ union scheduling_parameters {
struct ss_fb fb; struct ss_fb fb;
}; };
/* States for outgoing streams */
#define SCTP_STREAM_CLOSED 0x00
#define SCTP_STREAM_OPENING 0x01
#define SCTP_STREAM_OPEN 0x02
#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 */ /* This struct is used to track the traffic on outbound streams */
struct sctp_stream_out { struct sctp_stream_out {
struct sctp_streamhead outqueue; struct sctp_streamhead outqueue;
union scheduling_parameters ss_params; union scheduling_parameters ss_params;
uint32_t chunks_on_queues; uint32_t chunks_on_queues; /* send queue and sent queue */
#if defined(SCTP_DETAILED_STR_STATS) #if defined(SCTP_DETAILED_STR_STATS)
uint32_t abandoned_unsent[SCTP_PR_SCTP_MAX + 1]; uint32_t abandoned_unsent[SCTP_PR_SCTP_MAX + 1];
uint32_t abandoned_sent[SCTP_PR_SCTP_MAX + 1]; uint32_t abandoned_sent[SCTP_PR_SCTP_MAX + 1];
@ -642,9 +666,14 @@ struct sctp_stream_out {
uint32_t abandoned_unsent[1]; uint32_t abandoned_unsent[1];
uint32_t abandoned_sent[1]; uint32_t abandoned_sent[1];
#endif #endif
uint16_t stream_no; /* For associations using DATA chunks, the lower 16-bit of
uint16_t next_sequence_send; /* next one I expect to send out */ * next_mid_ordered are used as the next SSN.
*/
uint32_t next_mid_ordered;
uint32_t next_mid_unordered;
uint16_t sid;
uint8_t last_msg_incomplete; uint8_t last_msg_incomplete;
uint8_t state;
}; };
/* used to keep track of the addresses yet to try to add/delete */ /* used to keep track of the addresses yet to try to add/delete */
@ -674,12 +703,13 @@ struct sctp_scoping {
struct sctp_tsn_log { struct sctp_tsn_log {
void *stcb; void *stcb;
uint32_t tsn; uint32_t tsn;
uint32_t seq;
uint16_t strm; uint16_t strm;
uint16_t seq;
uint16_t sz; uint16_t sz;
uint16_t flgs; uint16_t flgs;
uint16_t in_pos; uint16_t in_pos;
uint16_t in_out; uint16_t in_out;
uint16_t resv;
}; };
#define SCTP_FS_SPEC_LOG_SIZE 200 #define SCTP_FS_SPEC_LOG_SIZE 200
@ -755,7 +785,7 @@ struct sctp_ss_functions {
int holds_lock); int holds_lock);
void (*sctp_ss_clear)(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); int clear_values, int holds_lock);
void (*sctp_ss_init_stream)(struct sctp_stream_out *strq, struct sctp_stream_out *with_strq); 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, 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); 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); int (*sctp_ss_is_empty)(struct sctp_tcb *stcb, struct sctp_association *asoc);
@ -771,6 +801,7 @@ struct sctp_ss_functions {
struct sctp_stream_out *strq, uint16_t *value); struct sctp_stream_out *strq, uint16_t *value);
int (*sctp_ss_set_value)(struct sctp_tcb *stcb, struct sctp_association *asoc, int (*sctp_ss_set_value)(struct sctp_tcb *stcb, struct sctp_association *asoc,
struct sctp_stream_out *strq, uint16_t value); struct sctp_stream_out *strq, uint16_t value);
int (*sctp_ss_is_user_msgs_incomplete)(struct sctp_tcb *stcb, struct sctp_association *asoc);
}; };
/* used to save ASCONF chunks for retransmission */ /* used to save ASCONF chunks for retransmission */
@ -818,7 +849,6 @@ struct sctp_association {
struct sctp_timer strreset_timer; /* stream reset */ struct sctp_timer strreset_timer; /* stream reset */
struct sctp_timer shut_guard_timer; /* shutdown guard */ struct sctp_timer shut_guard_timer; /* shutdown guard */
struct sctp_timer autoclose_timer; /* automatic close timer */ struct sctp_timer autoclose_timer; /* automatic close timer */
struct sctp_timer delayed_event_timer; /* timer for delayed events */
struct sctp_timer delete_prim_timer; /* deleting primary dst */ struct sctp_timer delete_prim_timer; /* deleting primary dst */
/* list of restricted local addresses */ /* list of restricted local addresses */
@ -850,20 +880,8 @@ struct sctp_association {
struct sctpchunk_listhead sent_queue; struct sctpchunk_listhead sent_queue;
struct sctpchunk_listhead send_queue; struct sctpchunk_listhead send_queue;
/* re-assembly queue for fragmented chunks on the inbound path */
struct sctpchunk_listhead reasmqueue;
/* Scheduling queues */ /* Scheduling queues */
union scheduling_data ss_data; struct scheduling_data ss_data;
/* This pointer will be set to NULL
* most of the time. But when we have
* a fragmented message, where we could
* not get out all of the message at
* the last send then this will point
* to the stream to go get data from.
*/
struct sctp_stream_out *locked_on_sending;
/* If an iterator is looking at me, this is it */ /* If an iterator is looking at me, this is it */
struct sctp_iterator *stcb_starting_point_for_iterator; struct sctp_iterator *stcb_starting_point_for_iterator;
@ -896,9 +914,6 @@ struct sctp_association {
/* last place I got a control from */ /* last place I got a control from */
struct sctp_nets *last_control_chunk_from; struct sctp_nets *last_control_chunk_from;
/* circular looking for output selection */
struct sctp_stream_out *last_out_stream;
/* /*
* wait to the point the cum-ack passes req->send_reset_at_tsn for * wait to the point the cum-ack passes req->send_reset_at_tsn for
* any req on the list. * any req on the list.
@ -918,7 +933,6 @@ struct sctp_association {
uint32_t stream_scheduling_module; uint32_t stream_scheduling_module;
uint32_t vrf_id; uint32_t vrf_id;
uint32_t cookie_preserve_req; uint32_t cookie_preserve_req;
/* ASCONF next seq I am sending out, inits at init-tsn */ /* ASCONF next seq I am sending out, inits at init-tsn */
uint32_t asconf_seq_out; uint32_t asconf_seq_out;
@ -963,7 +977,6 @@ struct sctp_association {
/* Original seq number I used ??questionable to keep?? */ /* Original seq number I used ??questionable to keep?? */
uint32_t init_seq_number; uint32_t init_seq_number;
/* The Advanced Peer Ack Point, as required by the PR-SCTP */ /* The Advanced Peer Ack Point, as required by the PR-SCTP */
/* (A1 in Section 4.2) */ /* (A1 in Section 4.2) */
uint32_t advanced_peer_ack_point; uint32_t advanced_peer_ack_point;
@ -992,7 +1005,7 @@ struct sctp_association {
uint32_t sat_t3_recovery_tsn; uint32_t sat_t3_recovery_tsn;
uint32_t tsn_last_delivered; uint32_t tsn_last_delivered;
/* /*
* For the pd-api we should re-write this a bit more efficent. We * For the pd-api we should re-write this a bit more efficient. We
* could have multiple sctp_queued_to_read's that we are building at * could have multiple sctp_queued_to_read's that we are building at
* once. Now we only do this when we get ready to deliver to the * once. Now we only do this when we get ready to deliver to the
* socket buffer. Note that we depend on the fact that the struct is * socket buffer. Note that we depend on the fact that the struct is
@ -1087,7 +1100,7 @@ struct sctp_association {
uint32_t heart_beat_delay; uint32_t heart_beat_delay;
/* autoclose */ /* autoclose */
unsigned int sctp_autoclose_ticks; uint32_t sctp_autoclose_ticks;
/* how many preopen streams we have */ /* how many preopen streams we have */
unsigned int pre_open_streams; unsigned int pre_open_streams;
@ -1096,7 +1109,7 @@ struct sctp_association {
unsigned int max_inbound_streams; unsigned int max_inbound_streams;
/* the cookie life I award for any cookie, in seconds */ /* the cookie life I award for any cookie, in seconds */
unsigned int cookie_life; uint32_t cookie_life;
/* time to delay acks for */ /* time to delay acks for */
unsigned int delayed_ack; unsigned int delayed_ack;
unsigned int old_delayed_ack; unsigned int old_delayed_ack;
@ -1105,10 +1118,10 @@ struct sctp_association {
unsigned int numduptsns; unsigned int numduptsns;
int dup_tsns[SCTP_MAX_DUP_TSNS]; int dup_tsns[SCTP_MAX_DUP_TSNS];
unsigned int initial_init_rto_max; /* initial RTO for INIT's */ uint32_t initial_init_rto_max; /* initial RTO for INIT's */
unsigned int initial_rto; /* initial send RTO */ uint32_t initial_rto; /* initial send RTO */
unsigned int minrto; /* per assoc RTO-MIN */ uint32_t minrto; /* per assoc RTO-MIN */
unsigned int maxrto; /* per assoc RTO-MAX */ uint32_t maxrto; /* per assoc RTO-MAX */
/* authentication fields */ /* authentication fields */
sctp_auth_chklist_t *local_auth_chunks; sctp_auth_chklist_t *local_auth_chunks;
@ -1125,6 +1138,7 @@ struct sctp_association {
uint32_t chunks_on_out_queue; /* total chunks floating around, uint32_t chunks_on_out_queue; /* total chunks floating around,
* locked by send socket buffer */ * locked by send socket buffer */
uint32_t peers_adaptation; uint32_t peers_adaptation;
uint32_t default_mtu;
uint16_t peer_hmac_id; /* peer HMAC id to send */ uint16_t peer_hmac_id; /* peer HMAC id to send */
/* /*
@ -1198,7 +1212,7 @@ struct sctp_association {
uint8_t hb_random_idx; uint8_t hb_random_idx;
uint8_t default_dscp; uint8_t default_dscp;
uint8_t asconf_del_pending; /* asconf delete last addr pending */ uint8_t asconf_del_pending; /* asconf delete last addr pending */
uint8_t trigger_reset;
/* /*
* This value, plus all other ack'd but above cum-ack is added * This value, plus all other ack'd but above cum-ack is added
* together to cross check against the bit that we have yet to * together to cross check against the bit that we have yet to
@ -1214,17 +1228,16 @@ struct sctp_association {
uint8_t reconfig_supported; uint8_t reconfig_supported;
uint8_t nrsack_supported; uint8_t nrsack_supported;
uint8_t pktdrop_supported; uint8_t pktdrop_supported;
uint8_t idata_supported;
/* Did the peer make the stream config (add out) request */ /* Did the peer make the stream config (add out) request */
uint8_t peer_req_out; uint8_t peer_req_out;
uint8_t local_strreset_support; uint8_t local_strreset_support;
uint8_t peer_supports_nat; uint8_t peer_supports_nat;
struct sctp_scoping scope; struct sctp_scoping scope;
/* flags to handle send alternate net tracking */ /* flags to handle send alternate net tracking */
uint8_t used_alt_onsack;
uint8_t used_alt_asconfack; uint8_t used_alt_asconfack;
uint8_t fast_retran_loss_recovery; uint8_t fast_retran_loss_recovery;
uint8_t sat_t3_loss_recovery; uint8_t sat_t3_loss_recovery;

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 277424 2015-01-20 19:08:55Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 365071 2020-09-01 21:19:14Z mjg $");
#endif #endif
#include <netinet/sctp_os.h> #include <netinet/sctp_os.h>
@ -42,15 +44,15 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 277424 2015-01-20 19:08:55Z t
#include <netinet/sctp_pcb.h> #include <netinet/sctp_pcb.h>
#include <netinet/sctputil.h> #include <netinet/sctputil.h>
#include <netinet/sctp_output.h> #include <netinet/sctp_output.h>
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/smp.h> #include <sys/smp.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
#include <netinet/sctp_bsd_addr.h> #include <netinet/sctp_bsd_addr.h>
#endif #endif
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
FEATURE(sctp, "Stream Control Transmission Protocol"); FEATURE(sctp, "Stream Control Transmission Protocol");
#endif #endif
@ -72,20 +74,35 @@ sctp_init_sysctls()
SCTP_BASE_SYSCTL(sctp_reconfig_enable) = SCTPCTL_RECONFIG_ENABLE_DEFAULT; SCTP_BASE_SYSCTL(sctp_reconfig_enable) = SCTPCTL_RECONFIG_ENABLE_DEFAULT;
SCTP_BASE_SYSCTL(sctp_nrsack_enable) = SCTPCTL_NRSACK_ENABLE_DEFAULT; SCTP_BASE_SYSCTL(sctp_nrsack_enable) = SCTPCTL_NRSACK_ENABLE_DEFAULT;
SCTP_BASE_SYSCTL(sctp_pktdrop_enable) = SCTPCTL_PKTDROP_ENABLE_DEFAULT; SCTP_BASE_SYSCTL(sctp_pktdrop_enable) = SCTPCTL_PKTDROP_ENABLE_DEFAULT;
SCTP_BASE_SYSCTL(sctp_strict_sacks) = SCTPCTL_STRICT_SACKS_DEFAULT; #if !(defined(__FreeBSD__) && !defined(__Userspace__))
#if !(defined(__FreeBSD__) && __FreeBSD_version >= 800000)
#if !defined(SCTP_WITH_NO_CSUM)
SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) = SCTPCTL_LOOPBACK_NOCSUM_DEFAULT; SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) = SCTPCTL_LOOPBACK_NOCSUM_DEFAULT;
#endif
#endif #endif
SCTP_BASE_SYSCTL(sctp_peer_chunk_oh) = SCTPCTL_PEER_CHKOH_DEFAULT; SCTP_BASE_SYSCTL(sctp_peer_chunk_oh) = SCTPCTL_PEER_CHKOH_DEFAULT;
SCTP_BASE_SYSCTL(sctp_max_burst_default) = SCTPCTL_MAXBURST_DEFAULT; SCTP_BASE_SYSCTL(sctp_max_burst_default) = SCTPCTL_MAXBURST_DEFAULT;
SCTP_BASE_SYSCTL(sctp_fr_max_burst_default) = SCTPCTL_FRMAXBURST_DEFAULT; SCTP_BASE_SYSCTL(sctp_fr_max_burst_default) = SCTPCTL_FRMAXBURST_DEFAULT;
SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue) = SCTPCTL_MAXCHUNKS_DEFAULT; SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue) = SCTPCTL_MAXCHUNKS_DEFAULT;
#if defined(__Userspace__)
if (SCTP_BASE_SYSCTL(sctp_hashtblsize) == 0) {
SCTP_BASE_SYSCTL(sctp_hashtblsize) = SCTPCTL_TCBHASHSIZE_DEFAULT; SCTP_BASE_SYSCTL(sctp_hashtblsize) = SCTPCTL_TCBHASHSIZE_DEFAULT;
}
#else
SCTP_BASE_SYSCTL(sctp_hashtblsize) = SCTPCTL_TCBHASHSIZE_DEFAULT;
#endif
#if defined(__Userspace__)
if (SCTP_BASE_SYSCTL(sctp_pcbtblsize) == 0) {
SCTP_BASE_SYSCTL(sctp_pcbtblsize) = SCTPCTL_PCBHASHSIZE_DEFAULT; SCTP_BASE_SYSCTL(sctp_pcbtblsize) = SCTPCTL_PCBHASHSIZE_DEFAULT;
}
#else
SCTP_BASE_SYSCTL(sctp_pcbtblsize) = SCTPCTL_PCBHASHSIZE_DEFAULT;
#endif
SCTP_BASE_SYSCTL(sctp_min_split_point) = SCTPCTL_MIN_SPLIT_POINT_DEFAULT; SCTP_BASE_SYSCTL(sctp_min_split_point) = SCTPCTL_MIN_SPLIT_POINT_DEFAULT;
#if defined(__Userspace__)
if (SCTP_BASE_SYSCTL(sctp_chunkscale) == 0) {
SCTP_BASE_SYSCTL(sctp_chunkscale) = SCTPCTL_CHUNKSCALE_DEFAULT; SCTP_BASE_SYSCTL(sctp_chunkscale) = SCTPCTL_CHUNKSCALE_DEFAULT;
}
#else
SCTP_BASE_SYSCTL(sctp_chunkscale) = SCTPCTL_CHUNKSCALE_DEFAULT;
#endif
SCTP_BASE_SYSCTL(sctp_delayed_sack_time_default) = SCTPCTL_DELAYED_SACK_TIME_DEFAULT; SCTP_BASE_SYSCTL(sctp_delayed_sack_time_default) = SCTPCTL_DELAYED_SACK_TIME_DEFAULT;
SCTP_BASE_SYSCTL(sctp_sack_freq_default) = SCTPCTL_SACK_FREQ_DEFAULT; SCTP_BASE_SYSCTL(sctp_sack_freq_default) = SCTPCTL_SACK_FREQ_DEFAULT;
SCTP_BASE_SYSCTL(sctp_system_free_resc_limit) = SCTPCTL_SYS_RESOURCE_DEFAULT; SCTP_BASE_SYSCTL(sctp_system_free_resc_limit) = SCTPCTL_SYS_RESOURCE_DEFAULT;
@ -115,7 +132,6 @@ sctp_init_sysctls()
SCTP_BASE_SYSCTL(sctp_do_drain) = SCTPCTL_DO_SCTP_DRAIN_DEFAULT; SCTP_BASE_SYSCTL(sctp_do_drain) = SCTPCTL_DO_SCTP_DRAIN_DEFAULT;
SCTP_BASE_SYSCTL(sctp_hb_maxburst) = SCTPCTL_HB_MAX_BURST_DEFAULT; SCTP_BASE_SYSCTL(sctp_hb_maxburst) = SCTPCTL_HB_MAX_BURST_DEFAULT;
SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit) = SCTPCTL_ABORT_AT_LIMIT_DEFAULT; SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit) = SCTPCTL_ABORT_AT_LIMIT_DEFAULT;
SCTP_BASE_SYSCTL(sctp_strict_data_order) = SCTPCTL_STRICT_DATA_ORDER_DEFAULT;
SCTP_BASE_SYSCTL(sctp_min_residual) = SCTPCTL_MIN_RESIDUAL_DEFAULT; SCTP_BASE_SYSCTL(sctp_min_residual) = SCTPCTL_MIN_RESIDUAL_DEFAULT;
SCTP_BASE_SYSCTL(sctp_max_retran_chunk) = SCTPCTL_MAX_RETRAN_CHUNK_DEFAULT; SCTP_BASE_SYSCTL(sctp_max_retran_chunk) = SCTPCTL_MAX_RETRAN_CHUNK_DEFAULT;
SCTP_BASE_SYSCTL(sctp_logging_level) = SCTPCTL_LOGGING_LEVEL_DEFAULT; SCTP_BASE_SYSCTL(sctp_logging_level) = SCTPCTL_LOGGING_LEVEL_DEFAULT;
@ -133,9 +149,10 @@ sctp_init_sysctls()
SCTP_BASE_SYSCTL(sctp_steady_step) = SCTPCTL_RTTVAR_STEADYS_DEFAULT; SCTP_BASE_SYSCTL(sctp_steady_step) = SCTPCTL_RTTVAR_STEADYS_DEFAULT;
SCTP_BASE_SYSCTL(sctp_use_dccc_ecn) = SCTPCTL_RTTVAR_DCCCECN_DEFAULT; SCTP_BASE_SYSCTL(sctp_use_dccc_ecn) = SCTPCTL_RTTVAR_DCCCECN_DEFAULT;
SCTP_BASE_SYSCTL(sctp_blackhole) = SCTPCTL_BLACKHOLE_DEFAULT; SCTP_BASE_SYSCTL(sctp_blackhole) = SCTPCTL_BLACKHOLE_DEFAULT;
SCTP_BASE_SYSCTL(sctp_sendall_limit) = SCTPCTL_SENDALL_LIMIT_DEFAULT;
SCTP_BASE_SYSCTL(sctp_diag_info_code) = SCTPCTL_DIAG_INFO_CODE_DEFAULT; SCTP_BASE_SYSCTL(sctp_diag_info_code) = SCTPCTL_DIAG_INFO_CODE_DEFAULT;
#if defined(SCTP_LOCAL_TRACE_BUF) #if defined(SCTP_LOCAL_TRACE_BUF)
#if defined(__Windows__) #if defined(_WIN32) && !defined(__Userspace__)
/* On Windows, the resource for global variables is limited. */ /* On Windows, the resource for global variables is limited. */
MALLOC(SCTP_BASE_SYSCTL(sctp_log), struct sctp_log *, sizeof(struct sctp_log), M_SYSCTL, M_ZERO); MALLOC(SCTP_BASE_SYSCTL(sctp_log), struct sctp_log *, sizeof(struct sctp_log), M_SYSCTL, M_ZERO);
#else #else
@ -148,18 +165,18 @@ sctp_init_sysctls()
#if defined(SCTP_DEBUG) #if defined(SCTP_DEBUG)
SCTP_BASE_SYSCTL(sctp_debug_on) = SCTPCTL_DEBUG_DEFAULT; SCTP_BASE_SYSCTL(sctp_debug_on) = SCTPCTL_DEBUG_DEFAULT;
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
SCTP_BASE_SYSCTL(sctp_ignore_vmware_interfaces) = SCTPCTL_IGNORE_VMWARE_INTERFACES_DEFAULT; SCTP_BASE_SYSCTL(sctp_ignore_vmware_interfaces) = SCTPCTL_IGNORE_VMWARE_INTERFACES_DEFAULT;
SCTP_BASE_SYSCTL(sctp_main_timer) = SCTPCTL_MAIN_TIMER_DEFAULT; SCTP_BASE_SYSCTL(sctp_main_timer) = SCTPCTL_MAIN_TIMER_DEFAULT;
SCTP_BASE_SYSCTL(sctp_addr_watchdog_limit) = SCTPCTL_ADDR_WATCHDOG_LIMIT_DEFAULT; SCTP_BASE_SYSCTL(sctp_addr_watchdog_limit) = SCTPCTL_ADDR_WATCHDOG_LIMIT_DEFAULT;
SCTP_BASE_SYSCTL(sctp_vtag_watchdog_limit) = SCTPCTL_VTAG_WATCHDOG_LIMIT_DEFAULT; SCTP_BASE_SYSCTL(sctp_vtag_watchdog_limit) = SCTPCTL_VTAG_WATCHDOG_LIMIT_DEFAULT;
#endif #endif
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) #if defined(__APPLE__) && !defined(__Userspace__)
SCTP_BASE_SYSCTL(sctp_output_unlocked) = SCTPCTL_OUTPUT_UNLOCKED_DEFAULT; SCTP_BASE_SYSCTL(sctp_output_unlocked) = SCTPCTL_OUTPUT_UNLOCKED_DEFAULT;
#endif #endif
} }
#if defined(_WIN32) && !defined(__Userspace__)
#if defined(__Windows__)
void void
sctp_finish_sysctls() sctp_finish_sysctls()
{ {
@ -172,7 +189,7 @@ sctp_finish_sysctls()
} }
#endif #endif
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__Windows__) #if !defined(__Userspace__)
/* It returns an upper limit. No filtering is done here */ /* It returns an upper limit. No filtering is done here */
static unsigned int static unsigned int
sctp_sysctl_number_of_addresses(struct sctp_inpcb *inp) sctp_sysctl_number_of_addresses(struct sctp_inpcb *inp)
@ -312,7 +329,7 @@ sctp_sysctl_copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *st
sin = &sctp_ifa->address.sin; sin = &sctp_ifa->address.sin;
if (sin->sin_addr.s_addr == 0) if (sin->sin_addr.s_addr == 0)
continue; continue;
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
if (prison_check_ip4(inp->ip_inp.inp.inp_cred, if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
&sin->sin_addr) != 0) { &sin->sin_addr) != 0) {
continue; continue;
@ -330,13 +347,10 @@ sctp_sysctl_copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *st
if (ipv6_addr_legal) { if (ipv6_addr_legal) {
struct sockaddr_in6 *sin6; struct sockaddr_in6 *sin6;
#if defined(SCTP_EMBEDDED_V6_SCOPE) && !defined(SCTP_KAME)
struct sockaddr_in6 lsa6;
#endif
sin6 = &sctp_ifa->address.sin6; sin6 = &sctp_ifa->address.sin6;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
continue; continue;
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
if (prison_check_ip6(inp->ip_inp.inp.inp_cred, if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
&sin6->sin6_addr) != 0) { &sin6->sin6_addr) != 0) {
continue; continue;
@ -345,21 +359,6 @@ sctp_sysctl_copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *st
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
if (local_scope == 0) if (local_scope == 0)
continue; continue;
#if defined(SCTP_EMBEDDED_V6_SCOPE)
if (sin6->sin6_scope_id == 0) {
#ifdef SCTP_KAME
/* bad link local address */
if (sa6_recoverscope(sin6) != 0)
continue;
#else
lsa6 = *sin6;
/* bad link local address */
if (in6_recoverscope(&lsa6, &lsa6.sin6_addr, NULL))
continue;
sin6 = &lsa6;
#endif /* SCTP_KAME */
}
#endif /* SCTP_EMBEDDED_V6_SCOPE */
} }
if ((site_scope == 0) && (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) if ((site_scope == 0) && (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)))
continue; continue;
@ -429,7 +428,7 @@ sctp_sysctl_copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *st
/* /*
* sysctl functions * sysctl functions
*/ */
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
static int static int
sctp_sysctl_handle_assoclist SYSCTL_HANDLER_ARGS sctp_sysctl_handle_assoclist SYSCTL_HANDLER_ARGS
{ {
@ -459,7 +458,7 @@ sctp_sysctl_handle_assoclist(SYSCTL_HANDLER_ARGS)
number_of_remote_addresses = 0; number_of_remote_addresses = 0;
SCTP_INP_INFO_RLOCK(); SCTP_INP_INFO_RLOCK();
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
if (req->oldptr == USER_ADDR_NULL) { if (req->oldptr == USER_ADDR_NULL) {
#else #else
if (req->oldptr == NULL) { if (req->oldptr == NULL) {
@ -484,14 +483,14 @@ sctp_sysctl_handle_assoclist(SYSCTL_HANDLER_ARGS)
(number_of_remote_addresses + number_of_associations) * sizeof(struct xsctp_raddr); (number_of_remote_addresses + number_of_associations) * sizeof(struct xsctp_raddr);
/* request some more memory than needed */ /* request some more memory than needed */
#if !defined(__Windows__) #if !(defined(_WIN32) && !defined(__Userspace__))
req->oldidx = (n + n / 8); req->oldidx = (n + n / 8);
#else #else
req->dataidx = (n + n / 8); req->dataidx = (n + n / 8);
#endif #endif
return (0); return (0);
} }
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
if (req->newptr != USER_ADDR_NULL) { if (req->newptr != USER_ADDR_NULL) {
#else #else
if (req->newptr != NULL) { if (req->newptr != NULL) {
@ -500,6 +499,9 @@ sctp_sysctl_handle_assoclist(SYSCTL_HANDLER_ARGS)
SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_SYSCTL, EPERM); SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_SYSCTL, EPERM);
return (EPERM); return (EPERM);
} }
memset(&xinpcb, 0, sizeof(xinpcb));
memset(&xstcb, 0, sizeof(xstcb));
memset(&xraddr, 0, sizeof(xraddr));
LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) { LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) {
SCTP_INP_RLOCK(inp); SCTP_INP_RLOCK(inp);
if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) { if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
@ -509,23 +511,34 @@ sctp_sysctl_handle_assoclist(SYSCTL_HANDLER_ARGS)
xinpcb.last = 0; xinpcb.last = 0;
xinpcb.local_port = ntohs(inp->sctp_lport); xinpcb.local_port = ntohs(inp->sctp_lport);
xinpcb.flags = inp->sctp_flags; xinpcb.flags = inp->sctp_flags;
#if defined(__FreeBSD__) && __FreeBSD_version < 1000048
xinpcb.features = (uint32_t)inp->sctp_features;
#else
xinpcb.features = inp->sctp_features; xinpcb.features = inp->sctp_features;
#endif
xinpcb.total_sends = inp->total_sends; xinpcb.total_sends = inp->total_sends;
xinpcb.total_recvs = inp->total_recvs; xinpcb.total_recvs = inp->total_recvs;
xinpcb.total_nospaces = inp->total_nospaces; xinpcb.total_nospaces = inp->total_nospaces;
xinpcb.fragmentation_point = inp->sctp_frag_point; xinpcb.fragmentation_point = inp->sctp_frag_point;
#if defined(__FreeBSD__) && !defined(__Userspace__)
xinpcb.socket = (uintptr_t)inp->sctp_socket;
#else
xinpcb.socket = inp->sctp_socket;
#endif
so = inp->sctp_socket; so = inp->sctp_socket;
if ((so == NULL) || if ((so == NULL) ||
(!SCTP_IS_LISTENING(inp)) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
xinpcb.qlen = 0; xinpcb.qlen = 0;
xinpcb.maxqlen = 0; xinpcb.maxqlen = 0;
} else { } else {
#if defined(__FreeBSD__) && !defined(__Userspace__)
xinpcb.qlen = so->sol_qlen;
xinpcb.qlen_old = so->sol_qlen > USHRT_MAX ?
USHRT_MAX : (uint16_t) so->sol_qlen;
xinpcb.maxqlen = so->sol_qlimit;
xinpcb.maxqlen_old = so->sol_qlimit > USHRT_MAX ?
USHRT_MAX : (uint16_t) so->sol_qlimit;
#else
xinpcb.qlen = so->so_qlen; xinpcb.qlen = so->so_qlen;
xinpcb.maxqlen = so->so_qlimit; xinpcb.maxqlen = so->so_qlimit;
#endif
} }
SCTP_INP_INCR_REF(inp); SCTP_INP_INCR_REF(inp);
SCTP_INP_RUNLOCK(inp); SCTP_INP_RUNLOCK(inp);
@ -552,17 +565,9 @@ sctp_sysctl_handle_assoclist(SYSCTL_HANDLER_ARGS)
if (stcb->asoc.primary_destination != NULL) if (stcb->asoc.primary_destination != NULL)
xstcb.primary_addr = stcb->asoc.primary_destination->ro._l_addr; xstcb.primary_addr = stcb->asoc.primary_destination->ro._l_addr;
xstcb.heartbeat_interval = stcb->asoc.heart_beat_delay; xstcb.heartbeat_interval = stcb->asoc.heart_beat_delay;
xstcb.state = SCTP_GET_STATE(&stcb->asoc); /* FIXME */ xstcb.state = (uint32_t)sctp_map_assoc_state(stcb->asoc.state);
#if defined(__FreeBSD__)
#if __FreeBSD_version >= 800000
/* 7.0 does not support these */
xstcb.assoc_id = sctp_get_associd(stcb); xstcb.assoc_id = sctp_get_associd(stcb);
xstcb.peers_rwnd = stcb->asoc.peers_rwnd; xstcb.peers_rwnd = stcb->asoc.peers_rwnd;
#endif
#else
xstcb.assoc_id = sctp_get_associd(stcb);
xstcb.peers_rwnd = stcb->asoc.peers_rwnd;
#endif
xstcb.in_streams = stcb->asoc.streamincnt; xstcb.in_streams = stcb->asoc.streamincnt;
xstcb.out_streams = stcb->asoc.streamoutcnt; xstcb.out_streams = stcb->asoc.streamoutcnt;
xstcb.max_nr_retrans = stcb->asoc.overall_error_count; xstcb.max_nr_retrans = stcb->asoc.overall_error_count;
@ -614,15 +619,17 @@ sctp_sysctl_handle_assoclist(SYSCTL_HANDLER_ARGS)
xraddr.cwnd = net->cwnd; xraddr.cwnd = net->cwnd;
xraddr.flight_size = net->flight_size; xraddr.flight_size = net->flight_size;
xraddr.mtu = net->mtu; xraddr.mtu = net->mtu;
#if defined(__FreeBSD__)
#if __FreeBSD_version >= 800000
xraddr.rtt = net->rtt / 1000; xraddr.rtt = net->rtt / 1000;
xraddr.heartbeat_interval = net->heart_beat_delay; xraddr.heartbeat_interval = net->heart_beat_delay;
#endif xraddr.ssthresh = net->ssthresh;
#else xraddr.encaps_port = net->port;
xraddr.rtt = net->rtt / 1000; if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
xraddr.heartbeat_interval = net->heart_beat_delay; xraddr.state = SCTP_UNCONFIRMED;
#endif } else if (net->dest_state & SCTP_ADDR_REACHABLE) {
xraddr.state = SCTP_ACTIVE;
} else {
xraddr.state = SCTP_INACTIVE;
}
xraddr.start_time.tv_sec = (uint32_t)net->start_time.tv_sec; xraddr.start_time.tv_sec = (uint32_t)net->start_time.tv_sec;
xraddr.start_time.tv_usec = (uint32_t)net->start_time.tv_usec; xraddr.start_time.tv_usec = (uint32_t)net->start_time.tv_usec;
SCTP_INP_RUNLOCK(inp); SCTP_INP_RUNLOCK(inp);
@ -669,7 +676,7 @@ skip:
return (error); return (error);
} }
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
static int static int
sctp_sysctl_handle_udp_tunneling SYSCTL_HANDLER_ARGS sctp_sysctl_handle_udp_tunneling SYSCTL_HANDLER_ARGS
{ {
@ -686,22 +693,14 @@ sctp_sysctl_handle_udp_tunneling(SYSCTL_HANDLER_ARGS)
old = SCTP_BASE_SYSCTL(sctp_udp_tunneling_port); old = SCTP_BASE_SYSCTL(sctp_udp_tunneling_port);
SCTP_INP_INFO_RUNLOCK(); SCTP_INP_INFO_RUNLOCK();
new = old; new = old;
#if defined(__FreeBSD__) && __FreeBSD_version >= 800056 && __FreeBSD_version < 1000100
#ifdef VIMAGE
error = vnet_sysctl_handle_int(oidp, &new, 0, req);
#else
error = sysctl_handle_int(oidp, &new, 0, req); error = sysctl_handle_int(oidp, &new, 0, req);
#endif
#else
error = sysctl_handle_int(oidp, &new, 0, req);
#endif
if ((error == 0) && if ((error == 0) &&
#if defined (__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
(req->newptr != USER_ADDR_NULL)) { (req->newptr != USER_ADDR_NULL)) {
#else #else
(req->newptr != NULL)) { (req->newptr != NULL)) {
#endif #endif
#if defined(__Windows__) #if defined(_WIN32) && !defined(__Userspace__)
SCTP_INP_INFO_WLOCK(); SCTP_INP_INFO_WLOCK();
sctp_over_udp_restart(); sctp_over_udp_restart();
SCTP_INP_INFO_WUNLOCK(); SCTP_INP_INFO_WUNLOCK();
@ -728,8 +727,8 @@ sctp_sysctl_handle_udp_tunneling(SYSCTL_HANDLER_ARGS)
} }
return (error); return (error);
} }
#if defined(__APPLE__) && !defined(__Userspace__)
#if defined(__APPLE__)
int sctp_is_vmware_interface(struct ifnet *); int sctp_is_vmware_interface(struct ifnet *);
static int static int
@ -762,7 +761,7 @@ sctp_sysctl_handle_vmware_interfaces SYSCTL_HANDLER_ARGS
} }
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
static int static int
sctp_sysctl_handle_auth SYSCTL_HANDLER_ARGS sctp_sysctl_handle_auth SYSCTL_HANDLER_ARGS
{ {
@ -776,17 +775,9 @@ sctp_sysctl_handle_auth(SYSCTL_HANDLER_ARGS)
uint32_t new; uint32_t new;
new = SCTP_BASE_SYSCTL(sctp_auth_enable); new = SCTP_BASE_SYSCTL(sctp_auth_enable);
#if defined(__FreeBSD__) && __FreeBSD_version >= 800056 && __FreeBSD_version < 1000100
#ifdef VIMAGE
error = vnet_sysctl_handle_int(oidp, &new, 0, req);
#else
error = sysctl_handle_int(oidp, &new, 0, req); error = sysctl_handle_int(oidp, &new, 0, req);
#endif
#else
error = sysctl_handle_int(oidp, &new, 0, req);
#endif
if ((error == 0) && if ((error == 0) &&
#if defined (__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
(req->newptr != USER_ADDR_NULL)) { (req->newptr != USER_ADDR_NULL)) {
#else #else
(req->newptr != NULL)) { (req->newptr != NULL)) {
@ -807,7 +798,7 @@ sctp_sysctl_handle_auth(SYSCTL_HANDLER_ARGS)
return (error); return (error);
} }
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
static int static int
sctp_sysctl_handle_asconf SYSCTL_HANDLER_ARGS sctp_sysctl_handle_asconf SYSCTL_HANDLER_ARGS
{ {
@ -821,17 +812,9 @@ sctp_sysctl_handle_asconf(SYSCTL_HANDLER_ARGS)
uint32_t new; uint32_t new;
new = SCTP_BASE_SYSCTL(sctp_asconf_enable); new = SCTP_BASE_SYSCTL(sctp_asconf_enable);
#if defined(__FreeBSD__) && __FreeBSD_version >= 800056 && __FreeBSD_version < 1000100
#ifdef VIMAGE
error = vnet_sysctl_handle_int(oidp, &new, 0, req);
#else
error = sysctl_handle_int(oidp, &new, 0, req); error = sysctl_handle_int(oidp, &new, 0, req);
#endif
#else
error = sysctl_handle_int(oidp, &new, 0, req);
#endif
if ((error == 0) && if ((error == 0) &&
#if defined (__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
(req->newptr != USER_ADDR_NULL)) { (req->newptr != USER_ADDR_NULL)) {
#else #else
(req->newptr != NULL)) { (req->newptr != NULL)) {
@ -852,7 +835,7 @@ sctp_sysctl_handle_asconf(SYSCTL_HANDLER_ARGS)
return (error); return (error);
} }
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
static int static int
sctp_sysctl_handle_stats SYSCTL_HANDLER_ARGS sctp_sysctl_handle_stats SYSCTL_HANDLER_ARGS
{ {
@ -863,7 +846,7 @@ sctp_sysctl_handle_stats(SYSCTL_HANDLER_ARGS)
{ {
#endif #endif
int error; int error;
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
#if defined(SMP) && defined(SCTP_USE_PERCPU_STAT) #if defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
struct sctpstat *sarry; struct sctpstat *sarry;
struct sctpstat sb; struct sctpstat sb;
@ -872,7 +855,7 @@ sctp_sysctl_handle_stats(SYSCTL_HANDLER_ARGS)
struct sctpstat sb_temp; struct sctpstat sb_temp;
#endif #endif
#if defined (__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
if ((req->newptr != USER_ADDR_NULL) && if ((req->newptr != USER_ADDR_NULL) &&
#else #else
if ((req->newptr != NULL) && if ((req->newptr != NULL) &&
@ -880,7 +863,7 @@ sctp_sysctl_handle_stats(SYSCTL_HANDLER_ARGS)
(req->newlen != sizeof(struct sctpstat))) { (req->newlen != sizeof(struct sctpstat))) {
return (EINVAL); return (EINVAL);
} }
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
memset(&sb_temp, 0, sizeof(struct sctpstat)); memset(&sb_temp, 0, sizeof(struct sctpstat));
if (req->newptr != NULL) { if (req->newptr != NULL) {
@ -932,7 +915,6 @@ sctp_sysctl_handle_stats(SYSCTL_HANDLER_ARGS)
sb.sctps_recvauthfailed += sarry->sctps_recvauthfailed; sb.sctps_recvauthfailed += sarry->sctps_recvauthfailed;
sb.sctps_recvexpress += sarry->sctps_recvexpress; sb.sctps_recvexpress += sarry->sctps_recvexpress;
sb.sctps_recvexpressm += sarry->sctps_recvexpressm; sb.sctps_recvexpressm += sarry->sctps_recvexpressm;
sb.sctps_recvnocrc += sarry->sctps_recvnocrc;
sb.sctps_recvswcrc += sarry->sctps_recvswcrc; sb.sctps_recvswcrc += sarry->sctps_recvswcrc;
sb.sctps_recvhwcrc += sarry->sctps_recvhwcrc; sb.sctps_recvhwcrc += sarry->sctps_recvhwcrc;
sb.sctps_sendpackets += sarry->sctps_sendpackets; sb.sctps_sendpackets += sarry->sctps_sendpackets;
@ -945,7 +927,6 @@ sctp_sysctl_handle_stats(SYSCTL_HANDLER_ARGS)
sb.sctps_sendecne += sarry->sctps_sendecne; sb.sctps_sendecne += sarry->sctps_sendecne;
sb.sctps_sendauth += sarry->sctps_sendauth; sb.sctps_sendauth += sarry->sctps_sendauth;
sb.sctps_senderrors += sarry->sctps_senderrors; sb.sctps_senderrors += sarry->sctps_senderrors;
sb.sctps_sendnocrc += sarry->sctps_sendnocrc;
sb.sctps_sendswcrc += sarry->sctps_sendswcrc; sb.sctps_sendswcrc += sarry->sctps_sendswcrc;
sb.sctps_sendhwcrc += sarry->sctps_sendhwcrc; sb.sctps_sendhwcrc += sarry->sctps_sendhwcrc;
sb.sctps_pdrpfmbox += sarry->sctps_pdrpfmbox; sb.sctps_pdrpfmbox += sarry->sctps_pdrpfmbox;
@ -1039,7 +1020,7 @@ sctp_sysctl_handle_stats(SYSCTL_HANDLER_ARGS)
} }
#if defined(SCTP_LOCAL_TRACE_BUF) #if defined(SCTP_LOCAL_TRACE_BUF)
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
static int static int
sctp_sysctl_handle_trace_log SYSCTL_HANDLER_ARGS sctp_sysctl_handle_trace_log SYSCTL_HANDLER_ARGS
{ {
@ -1051,7 +1032,7 @@ sctp_sysctl_handle_trace_log(SYSCTL_HANDLER_ARGS)
#endif #endif
int error; int error;
#if defined(__Windows__) #if defined(_WIN32) && !defined(__Userspace__)
error = SYSCTL_OUT(req, SCTP_BASE_SYSCTL(sctp_log), sizeof(struct sctp_log)); error = SYSCTL_OUT(req, SCTP_BASE_SYSCTL(sctp_log), sizeof(struct sctp_log));
#else #else
error = SYSCTL_OUT(req, &SCTP_BASE_SYSCTL(sctp_log), sizeof(struct sctp_log)); error = SYSCTL_OUT(req, &SCTP_BASE_SYSCTL(sctp_log), sizeof(struct sctp_log));
@ -1059,7 +1040,7 @@ sctp_sysctl_handle_trace_log(SYSCTL_HANDLER_ARGS)
return (error); return (error);
} }
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
static int static int
sctp_sysctl_handle_trace_log_clear SYSCTL_HANDLER_ARGS sctp_sysctl_handle_trace_log_clear SYSCTL_HANDLER_ARGS
{ {
@ -1070,7 +1051,7 @@ sctp_sysctl_handle_trace_log_clear(SYSCTL_HANDLER_ARGS)
{ {
#endif #endif
int error = 0; int error = 0;
#if defined(__Windows__) #if defined(_WIN32) && !defined(__Userspace__)
int value = 0; int value = 0;
if (req->new_data == NULL) { if (req->new_data == NULL) {
@ -1088,33 +1069,8 @@ sctp_sysctl_handle_trace_log_clear(SYSCTL_HANDLER_ARGS)
} }
#endif #endif
#if defined(__APPLE__) || defined(__FreeBSD__) #if (defined(__APPLE__) || defined(__FreeBSD__)) && !defined(__Userspace__)
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
#if __FreeBSD_version >= 800056 && __FreeBSD_version < 1000100
#ifdef VIMAGE
#define SCTP_UINT_SYSCTL(name, var_name, prefix) \
static int \
sctp_sysctl_handle_##mib_name(SYSCTL_HANDLER_ARGS) \
{ \
int error; \
uint32_t new; \
\
new = SCTP_BASE_SYSCTL(var_name); \
error = vnet_sysctl_handle_int(oidp, &new, 0, req); \
if ((error == 0) && (req->newptr != NULL)) { \
if ((new < prefix##_MIN) || \
(new > prefix##_MAX)) { \
error = EINVAL; \
} else { \
SCTP_BASE_SYSCTL(var_name) = new; \
} \
} \
return (error); \
} \
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, mib_name, \
CTLTYPE_UINT|CTLFLAG_RW, NULL, 0, \
sctp_sysctl_handle_##mib_name, "UI", prefix##_DESC);
#else
#define SCTP_UINT_SYSCTL(mib_name, var_name, prefix) \ #define SCTP_UINT_SYSCTL(mib_name, var_name, prefix) \
static int \ static int \
sctp_sysctl_handle_##mib_name(SYSCTL_HANDLER_ARGS) \ sctp_sysctl_handle_##mib_name(SYSCTL_HANDLER_ARGS) \
@ -1137,31 +1093,6 @@ sctp_sysctl_handle_trace_log_clear(SYSCTL_HANDLER_ARGS)
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, mib_name, \ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, mib_name, \
CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RW, NULL, 0, \ CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RW, NULL, 0, \
sctp_sysctl_handle_##mib_name, "UI", prefix##_DESC); sctp_sysctl_handle_##mib_name, "UI", prefix##_DESC);
#endif
#else
#define SCTP_UINT_SYSCTL(mib_name, var_name, prefix) \
static int \
sctp_sysctl_handle_##mib_name(SYSCTL_HANDLER_ARGS) \
{ \
int error; \
uint32_t new; \
\
new = SCTP_BASE_SYSCTL(var_name); \
error = sysctl_handle_int(oidp, &new, 0, req); \
if ((error == 0) && (req->newptr != NULL)) { \
if ((new < prefix##_MIN) || \
(new > prefix##_MAX)) { \
error = EINVAL; \
} else { \
SCTP_BASE_SYSCTL(var_name) = new; \
} \
} \
return (error); \
} \
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, mib_name, \
CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RW, NULL, 0, \
sctp_sysctl_handle_##mib_name, "UI", prefix##_DESC);
#endif
#else #else
#define SCTP_UINT_SYSCTL(mib_name, var_name, prefix) \ #define SCTP_UINT_SYSCTL(mib_name, var_name, prefix) \
static int \ static int \
@ -1208,12 +1139,9 @@ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, asconf_enable, CTLFLAG_VNET|CTLTYPE_UINT|C
SCTP_UINT_SYSCTL(reconfig_enable, sctp_reconfig_enable, SCTPCTL_RECONFIG_ENABLE) SCTP_UINT_SYSCTL(reconfig_enable, sctp_reconfig_enable, SCTPCTL_RECONFIG_ENABLE)
SCTP_UINT_SYSCTL(nrsack_enable, sctp_nrsack_enable, SCTPCTL_NRSACK_ENABLE) SCTP_UINT_SYSCTL(nrsack_enable, sctp_nrsack_enable, SCTPCTL_NRSACK_ENABLE)
SCTP_UINT_SYSCTL(pktdrop_enable, sctp_pktdrop_enable, SCTPCTL_PKTDROP_ENABLE) SCTP_UINT_SYSCTL(pktdrop_enable, sctp_pktdrop_enable, SCTPCTL_PKTDROP_ENABLE)
SCTP_UINT_SYSCTL(strict_sacks, sctp_strict_sacks, SCTPCTL_STRICT_SACKS) #if defined(__APPLE__) && !defined(__Userspace__)
#if defined(__APPLE__)
#if !defined(SCTP_WITH_NO_CSUM)
SCTP_UINT_SYSCTL(loopback_nocsum, sctp_no_csum_on_loopback, SCTPCTL_LOOPBACK_NOCSUM) SCTP_UINT_SYSCTL(loopback_nocsum, sctp_no_csum_on_loopback, SCTPCTL_LOOPBACK_NOCSUM)
#endif #endif
#endif
SCTP_UINT_SYSCTL(peer_chkoh, sctp_peer_chunk_oh, SCTPCTL_PEER_CHKOH) SCTP_UINT_SYSCTL(peer_chkoh, sctp_peer_chunk_oh, SCTPCTL_PEER_CHKOH)
SCTP_UINT_SYSCTL(maxburst, sctp_max_burst_default, SCTPCTL_MAXBURST) SCTP_UINT_SYSCTL(maxburst, sctp_max_burst_default, SCTPCTL_MAXBURST)
SCTP_UINT_SYSCTL(fr_maxburst, sctp_fr_max_burst_default, SCTPCTL_FRMAXBURST) SCTP_UINT_SYSCTL(fr_maxburst, sctp_fr_max_burst_default, SCTPCTL_FRMAXBURST)
@ -1251,7 +1179,6 @@ SCTP_UINT_SYSCTL(max_chained_mbufs, sctp_mbuf_threshold_count, SCTPCTL_MAX_CHAIN
SCTP_UINT_SYSCTL(do_sctp_drain, sctp_do_drain, SCTPCTL_DO_SCTP_DRAIN) SCTP_UINT_SYSCTL(do_sctp_drain, sctp_do_drain, SCTPCTL_DO_SCTP_DRAIN)
SCTP_UINT_SYSCTL(hb_max_burst, sctp_hb_maxburst, SCTPCTL_HB_MAX_BURST) SCTP_UINT_SYSCTL(hb_max_burst, sctp_hb_maxburst, SCTPCTL_HB_MAX_BURST)
SCTP_UINT_SYSCTL(abort_at_limit, sctp_abort_if_one_2_one_hits_limit, SCTPCTL_ABORT_AT_LIMIT) SCTP_UINT_SYSCTL(abort_at_limit, sctp_abort_if_one_2_one_hits_limit, SCTPCTL_ABORT_AT_LIMIT)
SCTP_UINT_SYSCTL(strict_data_order, sctp_strict_data_order, SCTPCTL_STRICT_DATA_ORDER)
SCTP_UINT_SYSCTL(min_residual, sctp_min_residual, SCTPCTL_MIN_RESIDUAL) SCTP_UINT_SYSCTL(min_residual, sctp_min_residual, SCTPCTL_MIN_RESIDUAL)
SCTP_UINT_SYSCTL(max_retran_chunk, sctp_max_retran_chunk, SCTPCTL_MAX_RETRAN_CHUNK) SCTP_UINT_SYSCTL(max_retran_chunk, sctp_max_retran_chunk, SCTPCTL_MAX_RETRAN_CHUNK)
SCTP_UINT_SYSCTL(log_level, sctp_logging_level, SCTPCTL_LOGGING_LEVEL) SCTP_UINT_SYSCTL(log_level, sctp_logging_level, SCTPCTL_LOGGING_LEVEL)
@ -1279,18 +1206,19 @@ SCTP_UINT_SYSCTL(rttvar_eqret, sctp_rttvar_eqret, SCTPCTL_RTTVAR_EQRET)
SCTP_UINT_SYSCTL(rttvar_steady_step, sctp_steady_step, SCTPCTL_RTTVAR_STEADYS) SCTP_UINT_SYSCTL(rttvar_steady_step, sctp_steady_step, SCTPCTL_RTTVAR_STEADYS)
SCTP_UINT_SYSCTL(use_dcccecn, sctp_use_dccc_ecn, SCTPCTL_RTTVAR_DCCCECN) SCTP_UINT_SYSCTL(use_dcccecn, sctp_use_dccc_ecn, SCTPCTL_RTTVAR_DCCCECN)
SCTP_UINT_SYSCTL(blackhole, sctp_blackhole, SCTPCTL_BLACKHOLE) SCTP_UINT_SYSCTL(blackhole, sctp_blackhole, SCTPCTL_BLACKHOLE)
SCTP_UINT_SYSCTL(sendall_limit, sctp_sendall_limit, SCTPCTL_SENDALL_LIMIT)
SCTP_UINT_SYSCTL(diag_info_code, sctp_diag_info_code, SCTPCTL_DIAG_INFO_CODE) SCTP_UINT_SYSCTL(diag_info_code, sctp_diag_info_code, SCTPCTL_DIAG_INFO_CODE)
#ifdef SCTP_DEBUG #ifdef SCTP_DEBUG
SCTP_UINT_SYSCTL(debug, sctp_debug_on, SCTPCTL_DEBUG) SCTP_UINT_SYSCTL(debug, sctp_debug_on, SCTPCTL_DEBUG)
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
SCTP_UINT_SYSCTL(main_timer, sctp_main_timer, SCTPCTL_MAIN_TIMER) SCTP_UINT_SYSCTL(main_timer, sctp_main_timer, SCTPCTL_MAIN_TIMER)
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, ignore_vmware_interfaces, CTLTYPE_UINT|CTLFLAG_RW, SYSCTL_PROC(_net_inet_sctp, OID_AUTO, ignore_vmware_interfaces, CTLTYPE_UINT|CTLFLAG_RW,
NULL, 0, sctp_sysctl_handle_vmware_interfaces, "IU", SCTPCTL_IGNORE_VMWARE_INTERFACES_DESC); NULL, 0, sctp_sysctl_handle_vmware_interfaces, "IU", SCTPCTL_IGNORE_VMWARE_INTERFACES_DESC);
SCTP_UINT_SYSCTL(addr_watchdog_limit, sctp_addr_watchdog_limit, SCTPCTL_ADDR_WATCHDOG_LIMIT) SCTP_UINT_SYSCTL(addr_watchdog_limit, sctp_addr_watchdog_limit, SCTPCTL_ADDR_WATCHDOG_LIMIT)
SCTP_UINT_SYSCTL(vtag_watchdog_limit, sctp_vtag_watchdog_limit, SCTPCTL_VTAG_WATCHDOG_LIMIT) SCTP_UINT_SYSCTL(vtag_watchdog_limit, sctp_vtag_watchdog_limit, SCTPCTL_VTAG_WATCHDOG_LIMIT)
#endif #endif
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) #if defined(__APPLE__) && !defined(__Userspace__)
SCTP_UINT_SYSCTL(output_unlocked, sctp_output_unlocked, SCTPCTL_OUTPUT_UNLOCKED) SCTP_UINT_SYSCTL(output_unlocked, sctp_output_unlocked, SCTPCTL_OUTPUT_UNLOCKED)
#endif #endif
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, stats, CTLFLAG_VNET|CTLTYPE_STRUCT|CTLFLAG_RW, SYSCTL_PROC(_net_inet_sctp, OID_AUTO, stats, CTLFLAG_VNET|CTLTYPE_STRUCT|CTLFLAG_RW,
@ -1298,7 +1226,7 @@ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, stats, CTLFLAG_VNET|CTLTYPE_STRUCT|CTLFLAG
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, assoclist, CTLFLAG_VNET|CTLTYPE_OPAQUE|CTLFLAG_RD, SYSCTL_PROC(_net_inet_sctp, OID_AUTO, assoclist, CTLFLAG_VNET|CTLTYPE_OPAQUE|CTLFLAG_RD,
NULL, 0, sctp_sysctl_handle_assoclist, "S,xassoc", "List of active SCTP associations"); NULL, 0, sctp_sysctl_handle_assoclist, "S,xassoc", "List of active SCTP associations");
#elif defined(__Windows__) #elif defined(_WIN32) && !defined(__Userspace__)
#define RANGECHK(var, min, max) \ #define RANGECHK(var, min, max) \
if ((var) < (min)) { (var) = (min); } \ if ((var) < (min)) { (var) = (min); } \
@ -1320,10 +1248,7 @@ sctp_sysctl_handle_int(SYSCTL_HANDLER_ARGS)
RANGECHK(SCTP_BASE_SYSCTL(sctp_reconfig_enable), SCTPCTL_RECONFIG_ENABLE_MIN, SCTPCTL_RECONFIG_ENABLE_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_reconfig_enable), SCTPCTL_RECONFIG_ENABLE_MIN, SCTPCTL_RECONFIG_ENABLE_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_nrsack_enable), SCTPCTL_NRSACK_ENABLE_MIN, SCTPCTL_NRSACK_ENABLE_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_nrsack_enable), SCTPCTL_NRSACK_ENABLE_MIN, SCTPCTL_NRSACK_ENABLE_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_pktdrop_enable), SCTPCTL_PKTDROP_ENABLE_MIN, SCTPCTL_PKTDROP_ENABLE_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_pktdrop_enable), SCTPCTL_PKTDROP_ENABLE_MIN, SCTPCTL_PKTDROP_ENABLE_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_strict_sacks), SCTPCTL_STRICT_SACKS_MIN, SCTPCTL_STRICT_SACKS_MAX);
#if !defined(SCTP_WITH_NO_CSUM)
RANGECHK(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback), SCTPCTL_LOOPBACK_NOCSUM_MIN, SCTPCTL_LOOPBACK_NOCSUM_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback), SCTPCTL_LOOPBACK_NOCSUM_MIN, SCTPCTL_LOOPBACK_NOCSUM_MAX);
#endif
RANGECHK(SCTP_BASE_SYSCTL(sctp_peer_chunk_oh), SCTPCTL_PEER_CHKOH_MIN, SCTPCTL_PEER_CHKOH_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_peer_chunk_oh), SCTPCTL_PEER_CHKOH_MIN, SCTPCTL_PEER_CHKOH_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_max_burst_default), SCTPCTL_MAXBURST_MIN, SCTPCTL_MAXBURST_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_max_burst_default), SCTPCTL_MAXBURST_MIN, SCTPCTL_MAXBURST_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_fr_max_burst_default), SCTPCTL_FRMAXBURST_MIN, SCTPCTL_FRMAXBURST_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_fr_max_burst_default), SCTPCTL_FRMAXBURST_MIN, SCTPCTL_FRMAXBURST_MAX);
@ -1361,7 +1286,6 @@ sctp_sysctl_handle_int(SYSCTL_HANDLER_ARGS)
RANGECHK(SCTP_BASE_SYSCTL(sctp_do_drain), SCTPCTL_DO_SCTP_DRAIN_MIN, SCTPCTL_DO_SCTP_DRAIN_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_do_drain), SCTPCTL_DO_SCTP_DRAIN_MIN, SCTPCTL_DO_SCTP_DRAIN_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_hb_maxburst), SCTPCTL_HB_MAX_BURST_MIN, SCTPCTL_HB_MAX_BURST_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_hb_maxburst), SCTPCTL_HB_MAX_BURST_MIN, SCTPCTL_HB_MAX_BURST_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit), SCTPCTL_ABORT_AT_LIMIT_MIN, SCTPCTL_ABORT_AT_LIMIT_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit), SCTPCTL_ABORT_AT_LIMIT_MIN, SCTPCTL_ABORT_AT_LIMIT_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_strict_data_order), SCTPCTL_STRICT_DATA_ORDER_MIN, SCTPCTL_STRICT_DATA_ORDER_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_min_residual), SCTPCTL_MIN_RESIDUAL_MIN, SCTPCTL_MIN_RESIDUAL_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_min_residual), SCTPCTL_MIN_RESIDUAL_MIN, SCTPCTL_MIN_RESIDUAL_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_max_retran_chunk), SCTPCTL_MAX_RETRAN_CHUNK_MIN, SCTPCTL_MAX_RETRAN_CHUNK_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_max_retran_chunk), SCTPCTL_MAX_RETRAN_CHUNK_MIN, SCTPCTL_MAX_RETRAN_CHUNK_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_logging_level), SCTPCTL_LOGGING_LEVEL_MIN, SCTPCTL_LOGGING_LEVEL_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_logging_level), SCTPCTL_LOGGING_LEVEL_MIN, SCTPCTL_LOGGING_LEVEL_MAX);
@ -1381,6 +1305,7 @@ sctp_sysctl_handle_int(SYSCTL_HANDLER_ARGS)
RANGECHK(SCTP_BASE_SYSCTL(sctp_enable_sack_immediately), SCTPCTL_SACK_IMMEDIATELY_ENABLE_MIN, SCTPCTL_SACK_IMMEDIATELY_ENABLE_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_enable_sack_immediately), SCTPCTL_SACK_IMMEDIATELY_ENABLE_MIN, SCTPCTL_SACK_IMMEDIATELY_ENABLE_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly), SCTPCTL_NAT_FRIENDLY_INITS_MIN, SCTPCTL_NAT_FRIENDLY_INITS_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly), SCTPCTL_NAT_FRIENDLY_INITS_MIN, SCTPCTL_NAT_FRIENDLY_INITS_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_blackhole), SCTPCTL_BLACKHOLE_MIN, SCTPCTL_BLACKHOLE_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_blackhole), SCTPCTL_BLACKHOLE_MIN, SCTPCTL_BLACKHOLE_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_sendall_limit), SCTPCTL_SENDALL_LIMIT_MIN, SCTPCTL_SENDALL_LIMIT_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_diag_info_code), SCTPCTL_DIAG_INFO_CODE_MIN, SCTPCTL_DIAG_INFO_CODE_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_diag_info_code), SCTPCTL_DIAG_INFO_CODE_MIN, SCTPCTL_DIAG_INFO_CODE_MAX);
#ifdef SCTP_DEBUG #ifdef SCTP_DEBUG
RANGECHK(SCTP_BASE_SYSCTL(sctp_debug_on), SCTPCTL_DEBUG_MIN, SCTPCTL_DEBUG_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_debug_on), SCTPCTL_DEBUG_MIN, SCTPCTL_DEBUG_MAX);
@ -1432,15 +1357,9 @@ sysctl_setup_sctp(void)
&SCTP_BASE_SYSCTL(sctp_pktdrop_enable), 0, sctp_sysctl_handle_int, &SCTP_BASE_SYSCTL(sctp_pktdrop_enable), 0, sctp_sysctl_handle_int,
SCTPCTL_PKTDROP_ENABLE_DESC); SCTPCTL_PKTDROP_ENABLE_DESC);
sysctl_add_oid(&sysctl_oid_top, "strict_sacks", CTLTYPE_INT|CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_strict_sacks), 0, sctp_sysctl_handle_int,
SCTPCTL_STRICT_SACKS_DESC);
#if !defined(SCTP_WITH_NO_CSUM)
sysctl_add_oid(&sysctl_oid_top, "loopback_nocsum", CTLTYPE_INT|CTLFLAG_RW, sysctl_add_oid(&sysctl_oid_top, "loopback_nocsum", CTLTYPE_INT|CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback), 0, sctp_sysctl_handle_int, &SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback), 0, sctp_sysctl_handle_int,
SCTPCTL_LOOPBACK_NOCSUM_DESC); SCTPCTL_LOOPBACK_NOCSUM_DESC);
#endif
sysctl_add_oid(&sysctl_oid_top, "peer_chkoh", CTLTYPE_INT|CTLFLAG_RW, sysctl_add_oid(&sysctl_oid_top, "peer_chkoh", CTLTYPE_INT|CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_peer_chunk_oh), 0, sctp_sysctl_handle_int, &SCTP_BASE_SYSCTL(sctp_peer_chunk_oh), 0, sctp_sysctl_handle_int,
@ -1590,10 +1509,6 @@ sysctl_setup_sctp(void)
&SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit), 0, sctp_sysctl_handle_int, &SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit), 0, sctp_sysctl_handle_int,
SCTPCTL_ABORT_AT_LIMIT_DESC); SCTPCTL_ABORT_AT_LIMIT_DESC);
sysctl_add_oid(&sysctl_oid_top, "strict_data_order", CTLTYPE_INT|CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_strict_data_order), 0, sctp_sysctl_handle_int,
SCTPCTL_STRICT_DATA_ORDER_DESC);
sysctl_add_oid(&sysctl_oid_top, "min_residual", CTLTYPE_INT|CTLFLAG_RW, sysctl_add_oid(&sysctl_oid_top, "min_residual", CTLTYPE_INT|CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_min_residual), 0, sctp_sysctl_handle_int, &SCTP_BASE_SYSCTL(sctp_min_residual), 0, sctp_sysctl_handle_int,
SCTPCTL_MIN_RESIDUAL_DESC); SCTPCTL_MIN_RESIDUAL_DESC);
@ -1684,6 +1599,10 @@ sysctl_setup_sctp(void)
&SCTP_BASE_SYSCTL(sctp_blackhole), 0, sctp_sysctl_handle_int, &SCTP_BASE_SYSCTL(sctp_blackhole), 0, sctp_sysctl_handle_int,
SCTPCTL_BLACKHOLE_DESC); SCTPCTL_BLACKHOLE_DESC);
sysctl_add_oid(&sysctl_oid_top, "sendall_limit", CTLTYPE_INT|CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_sendall_limit), 0, sctp_sysctl_handle_int,
SCTPCTL_SENDALL_LIMIT_DESC);
sysctl_add_oid(&sysctl_oid_top, "diag_info_code", CTLTYPE_INT|CTLFLAG_RW, sysctl_add_oid(&sysctl_oid_top, "diag_info_code", CTLTYPE_INT|CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_diag_info_code), 0, sctp_sysctl_handle_int, &SCTP_BASE_SYSCTL(sctp_diag_info_code), 0, sctp_sysctl_handle_int,
SCTPCTL_DIAG_INFO_CODE_DESC); SCTPCTL_DIAG_INFO_CODE_DESC);

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.h 271204 2014-09-06 19:12:14Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.h 366750 2020-10-16 10:44:48Z tuexen $");
#endif #endif
#ifndef _NETINET_SCTP_SYSCTL_H_ #ifndef _NETINET_SCTP_SYSCTL_H_
@ -54,11 +56,8 @@ struct sctp_sysctl {
uint32_t sctp_nrsack_enable; uint32_t sctp_nrsack_enable;
uint32_t sctp_pktdrop_enable; uint32_t sctp_pktdrop_enable;
uint32_t sctp_fr_max_burst_default; uint32_t sctp_fr_max_burst_default;
uint32_t sctp_strict_sacks; #if !(defined(__FreeBSD__) && !defined(__Userspace__))
#if !(defined(__FreeBSD__) && __FreeBSD_version >= 800000)
#if !defined(SCTP_WITH_NO_CSUM)
uint32_t sctp_no_csum_on_loopback; uint32_t sctp_no_csum_on_loopback;
#endif
#endif #endif
uint32_t sctp_peer_chunk_oh; uint32_t sctp_peer_chunk_oh;
uint32_t sctp_max_burst_default; uint32_t sctp_max_burst_default;
@ -96,7 +95,6 @@ struct sctp_sysctl {
uint32_t sctp_do_drain; uint32_t sctp_do_drain;
uint32_t sctp_hb_maxburst; uint32_t sctp_hb_maxburst;
uint32_t sctp_abort_if_one_2_one_hits_limit; uint32_t sctp_abort_if_one_2_one_hits_limit;
uint32_t sctp_strict_data_order;
uint32_t sctp_min_residual; uint32_t sctp_min_residual;
uint32_t sctp_max_retran_chunk; uint32_t sctp_max_retran_chunk;
uint32_t sctp_logging_level; uint32_t sctp_logging_level;
@ -115,7 +113,7 @@ struct sctp_sysctl {
uint32_t sctp_use_dccc_ecn; uint32_t sctp_use_dccc_ecn;
uint32_t sctp_diag_info_code; uint32_t sctp_diag_info_code;
#if defined(SCTP_LOCAL_TRACE_BUF) #if defined(SCTP_LOCAL_TRACE_BUF)
#if defined(__Windows__) #if defined(_WIN32) && !defined(__Userspace__)
struct sctp_log *sctp_log; struct sctp_log *sctp_log;
#else #else
struct sctp_log sctp_log; struct sctp_log sctp_log;
@ -127,16 +125,17 @@ struct sctp_sysctl {
uint32_t sctp_buffer_splitting; uint32_t sctp_buffer_splitting;
uint32_t sctp_initial_cwnd; uint32_t sctp_initial_cwnd;
uint32_t sctp_blackhole; uint32_t sctp_blackhole;
uint32_t sctp_sendall_limit;
#if defined(SCTP_DEBUG) #if defined(SCTP_DEBUG)
uint32_t sctp_debug_on; uint32_t sctp_debug_on;
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
uint32_t sctp_ignore_vmware_interfaces; uint32_t sctp_ignore_vmware_interfaces;
uint32_t sctp_main_timer; uint32_t sctp_main_timer;
uint32_t sctp_addr_watchdog_limit; uint32_t sctp_addr_watchdog_limit;
uint32_t sctp_vtag_watchdog_limit; uint32_t sctp_vtag_watchdog_limit;
#endif #endif
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) #if defined(__APPLE__) && !defined(__Userspace__)
uint32_t sctp_output_unlocked; uint32_t sctp_output_unlocked;
#endif #endif
}; };
@ -148,13 +147,21 @@ struct sctp_sysctl {
#define SCTPCTL_MAXDGRAM_DESC "Maximum outgoing SCTP buffer size" #define SCTPCTL_MAXDGRAM_DESC "Maximum outgoing SCTP buffer size"
#define SCTPCTL_MAXDGRAM_MIN 0 #define SCTPCTL_MAXDGRAM_MIN 0
#define SCTPCTL_MAXDGRAM_MAX 0xFFFFFFFF #define SCTPCTL_MAXDGRAM_MAX 0xFFFFFFFF
#if defined(__Userspace__)
#define SCTPCTL_MAXDGRAM_DEFAULT SB_MAX
#else
#define SCTPCTL_MAXDGRAM_DEFAULT 262144 /* 256k */ #define SCTPCTL_MAXDGRAM_DEFAULT 262144 /* 256k */
#endif
/* recvspace: Maximum incoming SCTP buffer size */ /* recvspace: Maximum incoming SCTP buffer size */
#define SCTPCTL_RECVSPACE_DESC "Maximum incoming SCTP buffer size" #define SCTPCTL_RECVSPACE_DESC "Maximum incoming SCTP buffer size"
#define SCTPCTL_RECVSPACE_MIN 0 #define SCTPCTL_RECVSPACE_MIN 0
#define SCTPCTL_RECVSPACE_MAX 0xFFFFFFFF #define SCTPCTL_RECVSPACE_MAX 0xFFFFFFFF
#if defined(__Userspace__)
#define SCTPCTL_RECVSPACE_DEFAULT SB_RAW
#else
#define SCTPCTL_RECVSPACE_DEFAULT 262144 /* 256k */ #define SCTPCTL_RECVSPACE_DEFAULT 262144 /* 256k */
#endif
/* autoasconf: Enable SCTP Auto-ASCONF */ /* autoasconf: Enable SCTP Auto-ASCONF */
#define SCTPCTL_AUTOASCONF_DESC "Enable SCTP Auto-ASCONF" #define SCTPCTL_AUTOASCONF_DESC "Enable SCTP Auto-ASCONF"
@ -210,12 +217,6 @@ struct sctp_sysctl {
#define SCTPCTL_PKTDROP_ENABLE_MAX 1 #define SCTPCTL_PKTDROP_ENABLE_MAX 1
#define SCTPCTL_PKTDROP_ENABLE_DEFAULT 0 #define SCTPCTL_PKTDROP_ENABLE_DEFAULT 0
/* strict_sacks: Enable SCTP Strict SACK checking */
#define SCTPCTL_STRICT_SACKS_DESC "Enable SCTP Strict SACK checking"
#define SCTPCTL_STRICT_SACKS_MIN 0
#define SCTPCTL_STRICT_SACKS_MAX 1
#define SCTPCTL_STRICT_SACKS_DEFAULT 1
/* loopback_nocsum: Enable NO Csum on packets sent on loopback */ /* loopback_nocsum: Enable NO Csum on packets sent on loopback */
#define SCTPCTL_LOOPBACK_NOCSUM_DESC "Enable NO Csum on packets sent on loopback" #define SCTPCTL_LOOPBACK_NOCSUM_DESC "Enable NO Csum on packets sent on loopback"
#define SCTPCTL_LOOPBACK_NOCSUM_MIN 0 #define SCTPCTL_LOOPBACK_NOCSUM_MIN 0
@ -235,12 +236,11 @@ struct sctp_sysctl {
#define SCTPCTL_MAXBURST_DEFAULT SCTP_DEF_MAX_BURST #define SCTPCTL_MAXBURST_DEFAULT SCTP_DEF_MAX_BURST
/* fr_maxburst: Default max burst for sctp endpoints when fast retransmitting */ /* fr_maxburst: Default max burst for sctp endpoints when fast retransmitting */
#define SCTPCTL_FRMAXBURST_DESC "Default fr max burst for sctp endpoints" #define SCTPCTL_FRMAXBURST_DESC "Default max burst for SCTP endpoints when fast retransmitting"
#define SCTPCTL_FRMAXBURST_MIN 0 #define SCTPCTL_FRMAXBURST_MIN 0
#define SCTPCTL_FRMAXBURST_MAX 0xFFFFFFFF #define SCTPCTL_FRMAXBURST_MAX 0xFFFFFFFF
#define SCTPCTL_FRMAXBURST_DEFAULT SCTP_DEF_FRMAX_BURST #define SCTPCTL_FRMAXBURST_DEFAULT SCTP_DEF_FRMAX_BURST
/* maxchunks: Default max chunks on queue per asoc */ /* maxchunks: Default max chunks on queue per asoc */
#define SCTPCTL_MAXCHUNKS_DESC "Default max chunks on queue per asoc" #define SCTPCTL_MAXCHUNKS_DESC "Default max chunks on queue per asoc"
#define SCTPCTL_MAXCHUNKS_MIN 0 #define SCTPCTL_MAXCHUNKS_MIN 0
@ -266,7 +266,7 @@ struct sctp_sysctl {
#define SCTPCTL_MIN_SPLIT_POINT_DEFAULT SCTP_DEFAULT_SPLIT_POINT_MIN #define SCTPCTL_MIN_SPLIT_POINT_DEFAULT SCTP_DEFAULT_SPLIT_POINT_MIN
/* chunkscale: Tunable for Scaling of number of chunks and messages */ /* chunkscale: Tunable for Scaling of number of chunks and messages */
#define SCTPCTL_CHUNKSCALE_DESC "Tunable for Scaling of number of chunks and messages" #define SCTPCTL_CHUNKSCALE_DESC "Tunable for scaling of number of chunks and messages"
#define SCTPCTL_CHUNKSCALE_MIN 1 #define SCTPCTL_CHUNKSCALE_MIN 1
#define SCTPCTL_CHUNKSCALE_MAX 0xFFFFFFFF #define SCTPCTL_CHUNKSCALE_MAX 0xFFFFFFFF
#define SCTPCTL_CHUNKSCALE_DEFAULT SCTP_CHUNKQUEUE_SCALE #define SCTPCTL_CHUNKSCALE_DEFAULT SCTP_CHUNKQUEUE_SCALE
@ -308,10 +308,10 @@ struct sctp_sysctl {
#define SCTPCTL_PMTU_RAISE_TIME_DEFAULT SCTP_DEF_PMTU_RAISE_SEC #define SCTPCTL_PMTU_RAISE_TIME_DEFAULT SCTP_DEF_PMTU_RAISE_SEC
/* shutdown_guard_time: Default shutdown guard timer in seconds */ /* shutdown_guard_time: Default shutdown guard timer in seconds */
#define SCTPCTL_SHUTDOWN_GUARD_TIME_DESC "Default shutdown guard timer in seconds" #define SCTPCTL_SHUTDOWN_GUARD_TIME_DESC "Shutdown guard timer in seconds (0 means 5 times RTO.Max)"
#define SCTPCTL_SHUTDOWN_GUARD_TIME_MIN 0 #define SCTPCTL_SHUTDOWN_GUARD_TIME_MIN 0
#define SCTPCTL_SHUTDOWN_GUARD_TIME_MAX 0xFFFFFFFF #define SCTPCTL_SHUTDOWN_GUARD_TIME_MAX 0xFFFFFFFF
#define SCTPCTL_SHUTDOWN_GUARD_TIME_DEFAULT SCTP_DEF_MAX_SHUTDOWN_SEC #define SCTPCTL_SHUTDOWN_GUARD_TIME_DEFAULT 0
/* secret_lifetime: Default secret lifetime in seconds */ /* secret_lifetime: Default secret lifetime in seconds */
#define SCTPCTL_SECRET_LIFETIME_DESC "Default secret lifetime in seconds" #define SCTPCTL_SECRET_LIFETIME_DESC "Default secret lifetime in seconds"
@ -343,14 +343,14 @@ struct sctp_sysctl {
#define SCTPCTL_INIT_RTO_MAX_MAX 0xFFFFFFFF #define SCTPCTL_INIT_RTO_MAX_MAX 0xFFFFFFFF
#define SCTPCTL_INIT_RTO_MAX_DEFAULT SCTP_RTO_UPPER_BOUND #define SCTPCTL_INIT_RTO_MAX_DEFAULT SCTP_RTO_UPPER_BOUND
/* valid_cookie_life: Default cookie lifetime in sec */ /* valid_cookie_life: Default cookie lifetime in ms */
#define SCTPCTL_VALID_COOKIE_LIFE_DESC "Default cookie lifetime in seconds" #define SCTPCTL_VALID_COOKIE_LIFE_DESC "Default cookie lifetime in ms"
#define SCTPCTL_VALID_COOKIE_LIFE_MIN 0 #define SCTPCTL_VALID_COOKIE_LIFE_MIN SCTP_MIN_COOKIE_LIFE
#define SCTPCTL_VALID_COOKIE_LIFE_MAX 0xFFFFFFFF #define SCTPCTL_VALID_COOKIE_LIFE_MAX SCTP_MAX_COOKIE_LIFE
#define SCTPCTL_VALID_COOKIE_LIFE_DEFAULT SCTP_DEFAULT_COOKIE_LIFE #define SCTPCTL_VALID_COOKIE_LIFE_DEFAULT SCTP_DEFAULT_COOKIE_LIFE
/* init_rtx_max: Default maximum number of retransmission for INIT chunks */ /* init_rtx_max: Default maximum number of retransmission for INIT chunks */
#define SCTPCTL_INIT_RTX_MAX_DESC "Default maximum number of retransmission for INIT chunks" #define SCTPCTL_INIT_RTX_MAX_DESC "Default maximum number of retransmissions for INIT chunks"
#define SCTPCTL_INIT_RTX_MAX_MIN 0 #define SCTPCTL_INIT_RTX_MAX_MIN 0
#define SCTPCTL_INIT_RTX_MAX_MAX 0xFFFFFFFF #define SCTPCTL_INIT_RTX_MAX_MAX 0xFFFFFFFF
#define SCTPCTL_INIT_RTX_MAX_DEFAULT SCTP_DEF_MAX_INIT #define SCTPCTL_INIT_RTX_MAX_DEFAULT SCTP_DEF_MAX_INIT
@ -403,8 +403,8 @@ struct sctp_sysctl {
#define SCTPCTL_CMT_USE_DAC_MAX 1 #define SCTPCTL_CMT_USE_DAC_MAX 1
#define SCTPCTL_CMT_USE_DAC_DEFAULT 0 #define SCTPCTL_CMT_USE_DAC_DEFAULT 0
/* cwnd_maxburst: Use a CWND adjusting maxburst */ /* cwnd_maxburst: Use a CWND adjusting to implement maxburst */
#define SCTPCTL_CWND_MAXBURST_DESC "Use a CWND adjusting maxburst" #define SCTPCTL_CWND_MAXBURST_DESC "Adjust congestion control window to limit maximum burst when sending"
#define SCTPCTL_CWND_MAXBURST_MIN 0 #define SCTPCTL_CWND_MAXBURST_MIN 0
#define SCTPCTL_CWND_MAXBURST_MAX 1 #define SCTPCTL_CWND_MAXBURST_MAX 1
#define SCTPCTL_CWND_MAXBURST_DEFAULT 1 #define SCTPCTL_CWND_MAXBURST_DEFAULT 1
@ -440,17 +440,11 @@ struct sctp_sysctl {
#define SCTPCTL_HB_MAX_BURST_DEFAULT SCTP_DEF_HBMAX_BURST #define SCTPCTL_HB_MAX_BURST_DEFAULT SCTP_DEF_HBMAX_BURST
/* abort_at_limit: When one-2-one hits qlimit abort */ /* abort_at_limit: When one-2-one hits qlimit abort */
#define SCTPCTL_ABORT_AT_LIMIT_DESC "When one-2-one hits qlimit abort" #define SCTPCTL_ABORT_AT_LIMIT_DESC "Abort when one-to-one hits qlimit"
#define SCTPCTL_ABORT_AT_LIMIT_MIN 0 #define SCTPCTL_ABORT_AT_LIMIT_MIN 0
#define SCTPCTL_ABORT_AT_LIMIT_MAX 1 #define SCTPCTL_ABORT_AT_LIMIT_MAX 1
#define SCTPCTL_ABORT_AT_LIMIT_DEFAULT 0 #define SCTPCTL_ABORT_AT_LIMIT_DEFAULT 0
/* strict_data_order: Enforce strict data ordering, abort if control inside data */
#define SCTPCTL_STRICT_DATA_ORDER_DESC "Enforce strict data ordering, abort if control inside data"
#define SCTPCTL_STRICT_DATA_ORDER_MIN 0
#define SCTPCTL_STRICT_DATA_ORDER_MAX 1
#define SCTPCTL_STRICT_DATA_ORDER_DEFAULT 0
/* min_residual: min residual in a data fragment leftover */ /* min_residual: min residual in a data fragment leftover */
#define SCTPCTL_MIN_RESIDUAL_DESC "Minimum residual data chunk in second part of split" #define SCTPCTL_MIN_RESIDUAL_DESC "Minimum residual data chunk in second part of split"
#define SCTPCTL_MIN_RESIDUAL_MIN 20 #define SCTPCTL_MIN_RESIDUAL_MIN 20
@ -458,7 +452,7 @@ struct sctp_sysctl {
#define SCTPCTL_MIN_RESIDUAL_DEFAULT 1452 #define SCTPCTL_MIN_RESIDUAL_DEFAULT 1452
/* max_retran_chunk: max chunk retransmissions */ /* max_retran_chunk: max chunk retransmissions */
#define SCTPCTL_MAX_RETRAN_CHUNK_DESC "Maximum times an unlucky chunk can be retran'd before assoc abort" #define SCTPCTL_MAX_RETRAN_CHUNK_DESC "Maximum times an unlucky chunk can be retransmitted before assoc abort"
#define SCTPCTL_MAX_RETRAN_CHUNK_MIN 0 #define SCTPCTL_MAX_RETRAN_CHUNK_MIN 0
#define SCTPCTL_MAX_RETRAN_CHUNK_MAX 65535 #define SCTPCTL_MAX_RETRAN_CHUNK_MAX 65535
#define SCTPCTL_MAX_RETRAN_CHUNK_DEFAULT 30 #define SCTPCTL_MAX_RETRAN_CHUNK_DEFAULT 30
@ -503,74 +497,80 @@ struct sctp_sysctl {
#define SCTPCTL_UDP_TUNNELING_PORT_DESC "Set the SCTP/UDP tunneling port" #define SCTPCTL_UDP_TUNNELING_PORT_DESC "Set the SCTP/UDP tunneling port"
#define SCTPCTL_UDP_TUNNELING_PORT_MIN 0 #define SCTPCTL_UDP_TUNNELING_PORT_MIN 0
#define SCTPCTL_UDP_TUNNELING_PORT_MAX 65535 #define SCTPCTL_UDP_TUNNELING_PORT_MAX 65535
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
#define SCTPCTL_UDP_TUNNELING_PORT_DEFAULT 0 #define SCTPCTL_UDP_TUNNELING_PORT_DEFAULT 0
#else #else
#define SCTPCTL_UDP_TUNNELING_PORT_DEFAULT SCTP_OVER_UDP_TUNNELING_PORT #define SCTPCTL_UDP_TUNNELING_PORT_DEFAULT SCTP_OVER_UDP_TUNNELING_PORT
#endif #endif
/* Enable sending of the SACK-IMMEDIATELY bit */ /* Enable sending of the SACK-IMMEDIATELY bit */
#define SCTPCTL_SACK_IMMEDIATELY_ENABLE_DESC "Enable sending of the SACK-IMMEDIATELY-bit." #define SCTPCTL_SACK_IMMEDIATELY_ENABLE_DESC "Enable sending of the SACK-IMMEDIATELY-bit"
#define SCTPCTL_SACK_IMMEDIATELY_ENABLE_MIN 0 #define SCTPCTL_SACK_IMMEDIATELY_ENABLE_MIN 0
#define SCTPCTL_SACK_IMMEDIATELY_ENABLE_MAX 1 #define SCTPCTL_SACK_IMMEDIATELY_ENABLE_MAX 1
#define SCTPCTL_SACK_IMMEDIATELY_ENABLE_DEFAULT SCTPCTL_SACK_IMMEDIATELY_ENABLE_MIN #define SCTPCTL_SACK_IMMEDIATELY_ENABLE_DEFAULT SCTPCTL_SACK_IMMEDIATELY_ENABLE_MAX
/* Enable sending of the NAT-FRIENDLY message */ /* Enable sending of the NAT-FRIENDLY message */
#define SCTPCTL_NAT_FRIENDLY_INITS_DESC "Enable sending of the nat-friendly SCTP option on INITs." #define SCTPCTL_NAT_FRIENDLY_INITS_DESC "Enable sending of the nat-friendly SCTP option on INITs"
#define SCTPCTL_NAT_FRIENDLY_INITS_MIN 0 #define SCTPCTL_NAT_FRIENDLY_INITS_MIN 0
#define SCTPCTL_NAT_FRIENDLY_INITS_MAX 1 #define SCTPCTL_NAT_FRIENDLY_INITS_MAX 1
#define SCTPCTL_NAT_FRIENDLY_INITS_DEFAULT SCTPCTL_NAT_FRIENDLY_INITS_MIN #define SCTPCTL_NAT_FRIENDLY_INITS_DEFAULT SCTPCTL_NAT_FRIENDLY_INITS_MIN
/* Vtag time wait in seconds */ /* Vtag time wait in seconds */
#define SCTPCTL_TIME_WAIT_DESC "Vtag time wait time in seconds, 0 disables it." #define SCTPCTL_TIME_WAIT_DESC "Vtag time wait time in seconds, 0 disables it"
#define SCTPCTL_TIME_WAIT_MIN 0 #define SCTPCTL_TIME_WAIT_MIN 0
#define SCTPCTL_TIME_WAIT_MAX 0xffffffff #define SCTPCTL_TIME_WAIT_MAX 0xffffffff
#define SCTPCTL_TIME_WAIT_DEFAULT SCTP_TIME_WAIT #define SCTPCTL_TIME_WAIT_DEFAULT SCTP_TIME_WAIT
/* Enable Send/Receive buffer splitting */ /* Enable Send/Receive buffer splitting */
#define SCTPCTL_BUFFER_SPLITTING_DESC "Enable send/receive buffer splitting." #define SCTPCTL_BUFFER_SPLITTING_DESC "Enable send/receive buffer splitting"
#define SCTPCTL_BUFFER_SPLITTING_MIN 0 #define SCTPCTL_BUFFER_SPLITTING_MIN 0
#define SCTPCTL_BUFFER_SPLITTING_MAX 0x3 #define SCTPCTL_BUFFER_SPLITTING_MAX 0x3
#define SCTPCTL_BUFFER_SPLITTING_DEFAULT SCTPCTL_BUFFER_SPLITTING_MIN #define SCTPCTL_BUFFER_SPLITTING_DEFAULT SCTPCTL_BUFFER_SPLITTING_MIN
/* Initial congestion window in MTU */ /* Initial congestion window in MTUs */
#define SCTPCTL_INITIAL_CWND_DESC "Initial congestion window in MTUs" #define SCTPCTL_INITIAL_CWND_DESC "Defines the initial congestion window size in MTUs"
#define SCTPCTL_INITIAL_CWND_MIN 0 #define SCTPCTL_INITIAL_CWND_MIN 0
#define SCTPCTL_INITIAL_CWND_MAX 0xffffffff #define SCTPCTL_INITIAL_CWND_MAX 0xffffffff
#define SCTPCTL_INITIAL_CWND_DEFAULT 3 #define SCTPCTL_INITIAL_CWND_DEFAULT 3
/* rttvar smooth avg for bw calc */ /* rttvar smooth avg for bw calc */
#define SCTPCTL_RTTVAR_BW_DESC "Shift amount for bw smoothing on rtt calc" #define SCTPCTL_RTTVAR_BW_DESC "Shift amount DCCC uses for bw smoothing on rtt calc"
#define SCTPCTL_RTTVAR_BW_MIN 0 #define SCTPCTL_RTTVAR_BW_MIN 0
#define SCTPCTL_RTTVAR_BW_MAX 32 #define SCTPCTL_RTTVAR_BW_MAX 32
#define SCTPCTL_RTTVAR_BW_DEFAULT 4 #define SCTPCTL_RTTVAR_BW_DEFAULT 4
/* rttvar smooth avg for bw calc */ /* rttvar smooth avg for bw calc */
#define SCTPCTL_RTTVAR_RTT_DESC "Shift amount for rtt smoothing on rtt calc" #define SCTPCTL_RTTVAR_RTT_DESC "Shift amount DCCC uses for rtt smoothing on rtt calc"
#define SCTPCTL_RTTVAR_RTT_MIN 0 #define SCTPCTL_RTTVAR_RTT_MIN 0
#define SCTPCTL_RTTVAR_RTT_MAX 32 #define SCTPCTL_RTTVAR_RTT_MAX 32
#define SCTPCTL_RTTVAR_RTT_DEFAULT 5 #define SCTPCTL_RTTVAR_RTT_DEFAULT 5
#define SCTPCTL_RTTVAR_EQRET_DESC "What to return when rtt and bw are unchanged" #define SCTPCTL_RTTVAR_EQRET_DESC "Whether DCCC increases cwnd when the rtt and bw are unchanged"
#define SCTPCTL_RTTVAR_EQRET_MIN 0 #define SCTPCTL_RTTVAR_EQRET_MIN 0
#define SCTPCTL_RTTVAR_EQRET_MAX 1 #define SCTPCTL_RTTVAR_EQRET_MAX 1
#define SCTPCTL_RTTVAR_EQRET_DEFAULT 0 #define SCTPCTL_RTTVAR_EQRET_DEFAULT 0
#define SCTPCTL_RTTVAR_STEADYS_DESC "How many the sames it takes to try step down of cwnd" #define SCTPCTL_RTTVAR_STEADYS_DESC "Number of identical bw measurements DCCC takes to try step down of cwnd"
#define SCTPCTL_RTTVAR_STEADYS_MIN 0 #define SCTPCTL_RTTVAR_STEADYS_MIN 0
#define SCTPCTL_RTTVAR_STEADYS_MAX 0xFFFF #define SCTPCTL_RTTVAR_STEADYS_MAX 0xFFFF
#define SCTPCTL_RTTVAR_STEADYS_DEFAULT 20 /* 0 means disable feature */ #define SCTPCTL_RTTVAR_STEADYS_DEFAULT 20 /* 0 means disable feature */
#define SCTPCTL_RTTVAR_DCCCECN_DESC "Enable for RTCC CC datacenter ECN" #define SCTPCTL_RTTVAR_DCCCECN_DESC "Enable ECN for DCCC."
#define SCTPCTL_RTTVAR_DCCCECN_MIN 0 #define SCTPCTL_RTTVAR_DCCCECN_MIN 0
#define SCTPCTL_RTTVAR_DCCCECN_MAX 1 #define SCTPCTL_RTTVAR_DCCCECN_MAX 1
#define SCTPCTL_RTTVAR_DCCCECN_DEFAULT 1 /* 0 means disable feature */ #define SCTPCTL_RTTVAR_DCCCECN_DEFAULT 1 /* 0 means disable feature */
#define SCTPCTL_BLACKHOLE_DESC "Enable SCTP blackholing" #define SCTPCTL_BLACKHOLE_DESC "Enable SCTP blackholing, see blackhole(4) for more details"
#define SCTPCTL_BLACKHOLE_MIN 0 #define SCTPCTL_BLACKHOLE_MIN 0
#define SCTPCTL_BLACKHOLE_MAX 2 #define SCTPCTL_BLACKHOLE_MAX 2
#define SCTPCTL_BLACKHOLE_DEFAULT SCTPCTL_BLACKHOLE_MIN #define SCTPCTL_BLACKHOLE_DEFAULT SCTPCTL_BLACKHOLE_MIN
/* sendall_limit: Maximum message with SCTP_SENDALL */
#define SCTPCTL_SENDALL_LIMIT_DESC "Maximum size of a message send with SCTP_SENDALL"
#define SCTPCTL_SENDALL_LIMIT_MIN 0
#define SCTPCTL_SENDALL_LIMIT_MAX 0xFFFFFFFF
#define SCTPCTL_SENDALL_LIMIT_DEFAULT 1432
#define SCTPCTL_DIAG_INFO_CODE_DESC "Diagnostic information error cause code" #define SCTPCTL_DIAG_INFO_CODE_DESC "Diagnostic information error cause code"
#define SCTPCTL_DIAG_INFO_CODE_MIN 0 #define SCTPCTL_DIAG_INFO_CODE_MIN 0
#define SCTPCTL_DIAG_INFO_CODE_MAX 65535 #define SCTPCTL_DIAG_INFO_CODE_MAX 65535
@ -584,7 +584,7 @@ struct sctp_sysctl {
#define SCTPCTL_DEBUG_DEFAULT 0 #define SCTPCTL_DEBUG_DEFAULT 0
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
#define SCTPCTL_MAIN_TIMER_DESC "Main timer interval in ms" #define SCTPCTL_MAIN_TIMER_DESC "Main timer interval in ms"
#define SCTPCTL_MAIN_TIMER_MIN 1 #define SCTPCTL_MAIN_TIMER_MIN 1
#define SCTPCTL_MAIN_TIMER_MAX 0xFFFFFFFF #define SCTPCTL_MAIN_TIMER_MAX 0xFFFFFFFF
@ -594,16 +594,12 @@ struct sctp_sysctl {
#define SCTPCTL_IGNORE_VMWARE_INTERFACES_MIN 0 #define SCTPCTL_IGNORE_VMWARE_INTERFACES_MIN 0
#define SCTPCTL_IGNORE_VMWARE_INTERFACES_MAX 1 #define SCTPCTL_IGNORE_VMWARE_INTERFACES_MAX 1
#define SCTPCTL_IGNORE_VMWARE_INTERFACES_DEFAULT SCTPCTL_IGNORE_VMWARE_INTERFACES_MAX #define SCTPCTL_IGNORE_VMWARE_INTERFACES_DEFAULT SCTPCTL_IGNORE_VMWARE_INTERFACES_MAX
#endif
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) #define SCTPCTL_OUTPUT_UNLOCKED_DESC "Unlock socket when sending packets down to IP"
#define SCTPCTL_OUTPUT_UNLOCKED_DESC "Unlock socket when sending packets down to IP."
#define SCTPCTL_OUTPUT_UNLOCKED_MIN 0 #define SCTPCTL_OUTPUT_UNLOCKED_MIN 0
#define SCTPCTL_OUTPUT_UNLOCKED_MAX 1 #define SCTPCTL_OUTPUT_UNLOCKED_MAX 1
#define SCTPCTL_OUTPUT_UNLOCKED_DEFAULT SCTPCTL_OUTPUT_UNLOCKED_MIN #define SCTPCTL_OUTPUT_UNLOCKED_DEFAULT SCTPCTL_OUTPUT_UNLOCKED_MIN
#endif
#if defined(__APPLE__)
#define SCTPCTL_ADDR_WATCHDOG_LIMIT_DESC "Address watchdog limit" #define SCTPCTL_ADDR_WATCHDOG_LIMIT_DESC "Address watchdog limit"
#define SCTPCTL_ADDR_WATCHDOG_LIMIT_MIN 0 #define SCTPCTL_ADDR_WATCHDOG_LIMIT_MIN 0
#define SCTPCTL_ADDR_WATCHDOG_LIMIT_MAX 0xFFFFFFFF #define SCTPCTL_ADDR_WATCHDOG_LIMIT_MAX 0xFFFFFFFF
@ -613,8 +609,8 @@ struct sctp_sysctl {
#define SCTPCTL_VTAG_WATCHDOG_LIMIT_MIN 0 #define SCTPCTL_VTAG_WATCHDOG_LIMIT_MIN 0
#define SCTPCTL_VTAG_WATCHDOG_LIMIT_MAX 0xFFFFFFFF #define SCTPCTL_VTAG_WATCHDOG_LIMIT_MAX 0xFFFFFFFF
#define SCTPCTL_VTAG_WATCHDOG_LIMIT_DEFAULT SCTPCTL_VTAG_WATCHDOG_LIMIT_MIN #define SCTPCTL_VTAG_WATCHDOG_LIMIT_DEFAULT SCTPCTL_VTAG_WATCHDOG_LIMIT_MIN
#endif
#endif
#if defined(_KERNEL) || defined(__Userspace__) #if defined(_KERNEL) || defined(__Userspace__)
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Userspace__) #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Userspace__)
#if defined(SYSCTL_DECL) #if defined(SYSCTL_DECL)
@ -623,7 +619,7 @@ SYSCTL_DECL(_net_inet_sctp);
#endif #endif
void sctp_init_sysctls(void); void sctp_init_sysctls(void);
#if defined(__Windows__) #if defined(_WIN32) && !defined(__Userspace__)
void sctp_finish_sysctls(void); void sctp_finish_sysctls(void);
#endif #endif

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,16 +32,16 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 279841 2015-03-10 09:16:31Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 365071 2020-09-01 21:19:14Z mjg $");
#endif #endif
#define _IP_VHL #define _IP_VHL
#include <netinet/sctp_os.h> #include <netinet/sctp_os.h>
#include <netinet/sctp_pcb.h> #include <netinet/sctp_pcb.h>
#ifdef INET6 #ifdef INET6
#if defined(__Userspace_os_FreeBSD) #if defined(__FreeBSD__) && defined(__Userspace__)
#include <netinet6/sctp6_var.h> #include <netinet6/sctp6_var.h>
#endif #endif
#endif #endif
@ -55,15 +57,11 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 279841 2015-03-10 09:16:31Z tu
#include <netinet/sctp.h> #include <netinet/sctp.h>
#include <netinet/sctp_uio.h> #include <netinet/sctp_uio.h>
#if defined(INET) || defined(INET6) #if defined(INET) || defined(INET6)
#if !defined(__Userspace_os_Windows) #if !(defined(_WIN32) && defined(__Userspace__))
#include <netinet/udp.h> #include <netinet/udp.h>
#endif #endif
#endif #endif
#if defined(__APPLE__)
#define APPLE_FILE_NO 6
#endif
void void
sctp_audit_retranmission_queue(struct sctp_association *asoc) sctp_audit_retranmission_queue(struct sctp_association *asoc)
{ {
@ -95,7 +93,7 @@ sctp_audit_retranmission_queue(struct sctp_association *asoc)
asoc->sent_queue_cnt); asoc->sent_queue_cnt);
} }
int static int
sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb, sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct sctp_nets *net, uint16_t threshold) struct sctp_nets *net, uint16_t threshold)
{ {
@ -120,8 +118,10 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
net->dest_state |= SCTP_ADDR_PF; net->dest_state |= SCTP_ADDR_PF;
net->last_active = sctp_get_tick_count(); net->last_active = sctp_get_tick_count();
sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED); sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3); sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net); inp, stcb, net,
SCTP_FROM_SCTP_TIMER + SCTP_LOC_1);
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
} }
} }
} }
@ -161,9 +161,9 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/* Abort notification sends a ULP notify */ /* Abort notification sends a ULP notify */
struct mbuf *op_err; struct mbuf *op_err;
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
"Association error counter exceeded"); "Association error counter exceeded");
inp->last_abort_code = SCTP_FROM_SCTP_TIMER+SCTP_LOC_1; 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, SCTP_SO_NOT_LOCKED);
return (1); return (1);
} }
@ -344,7 +344,11 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
return (NULL); return (NULL);
} }
} }
#if defined(__FreeBSD__) && !defined(__Userspace__)
if (alt->ro.ro_nh == NULL) {
#else
if (alt->ro.ro_rt == NULL) { if (alt->ro.ro_rt == NULL) {
#endif
if (alt->ro._s_addr) { if (alt->ro._s_addr) {
sctp_free_ifa(alt->ro._s_addr); sctp_free_ifa(alt->ro._s_addr);
alt->ro._s_addr = NULL; alt->ro._s_addr = NULL;
@ -352,7 +356,11 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
alt->src_addr_selected = 0; alt->src_addr_selected = 0;
} }
if (((alt->dest_state & SCTP_ADDR_REACHABLE) == SCTP_ADDR_REACHABLE) && if (((alt->dest_state & SCTP_ADDR_REACHABLE) == SCTP_ADDR_REACHABLE) &&
#if defined(__FreeBSD__) && !defined(__Userspace__)
(alt->ro.ro_nh != NULL) &&
#else
(alt->ro.ro_rt != NULL) && (alt->ro.ro_rt != NULL) &&
#endif
(!(alt->dest_state & SCTP_ADDR_UNCONFIRMED))) { (!(alt->dest_state & SCTP_ADDR_UNCONFIRMED))) {
/* Found a reachable address */ /* Found a reachable address */
break; break;
@ -401,7 +409,11 @@ sctp_backoff_on_timeout(struct sctp_tcb *stcb,
int num_marked, int num_abandoned) int num_marked, int num_abandoned)
{ {
if (net->RTO == 0) { if (net->RTO == 0) {
if (net->RTO_measured) {
net->RTO = stcb->asoc.minrto; net->RTO = stcb->asoc.minrto;
} else {
net->RTO = stcb->asoc.initial_rto;
}
} }
net->RTO <<= 1; net->RTO <<= 1;
if (net->RTO > stcb->asoc.maxrto) { if (net->RTO > stcb->asoc.maxrto) {
@ -423,14 +435,19 @@ sctp_recover_sent_list(struct sctp_tcb *stcb)
asoc = &stcb->asoc; asoc = &stcb->asoc;
TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) { TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) {
if (SCTP_TSN_GE(asoc->last_acked_seq, chk->rec.data.TSN_seq)) { if (SCTP_TSN_GE(asoc->last_acked_seq, chk->rec.data.tsn)) {
SCTP_PRINTF("Found chk:%p tsn:%x <= last_acked_seq:%x\n", SCTP_PRINTF("Found chk:%p tsn:%x <= last_acked_seq:%x\n",
(void *)chk, chk->rec.data.TSN_seq, asoc->last_acked_seq); (void *)chk, chk->rec.data.tsn, asoc->last_acked_seq);
if (chk->sent != SCTP_DATAGRAM_NR_ACKED) { if (chk->sent != SCTP_DATAGRAM_NR_ACKED) {
if (asoc->strmout[chk->rec.data.stream_number].chunks_on_queues > 0) { if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) {
asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--; asoc->strmout[chk->rec.data.sid].chunks_on_queues--;
} }
} }
if ((asoc->strmout[chk->rec.data.sid].chunks_on_queues == 0) &&
(asoc->strmout[chk->rec.data.sid].state == SCTP_STREAM_RESET_PENDING) &&
TAILQ_EMPTY(&asoc->strmout[chk->rec.data.sid].outqueue)) {
asoc->trigger_reset = 1;
}
TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next); TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
if (PR_SCTP_ENABLED(chk->flags)) { if (PR_SCTP_ENABLED(chk->flags)) {
if (asoc->pr_sctp_cnt != 0) if (asoc->pr_sctp_cnt != 0)
@ -451,7 +468,7 @@ sctp_recover_sent_list(struct sctp_tcb *stcb)
} }
SCTP_PRINTF("after recover order is as follows\n"); SCTP_PRINTF("after recover order is as follows\n");
TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) { TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
SCTP_PRINTF("chk:%p TSN:%x\n", (void *)chk, chk->rec.data.TSN_seq); SCTP_PRINTF("chk:%p TSN:%x\n", (void *)chk, chk->rec.data.tsn);
} }
} }
#endif #endif
@ -482,7 +499,6 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
uint32_t tsnlast, tsnfirst; uint32_t tsnlast, tsnfirst;
int recovery_cnt = 0; int recovery_cnt = 0;
/* none in flight now */ /* none in flight now */
audit_tf = 0; audit_tf = 0;
fir = 0; fir = 0;
@ -504,7 +520,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
} }
tv.tv_sec = cur_rto / 1000000; tv.tv_sec = cur_rto / 1000000;
tv.tv_usec = cur_rto % 1000000; tv.tv_usec = cur_rto % 1000000;
#ifndef __FreeBSD__ #if !(defined(__FreeBSD__) && !defined(__Userspace__))
timersub(&now, &tv, &min_wait); timersub(&now, &tv, &min_wait);
#else #else
min_wait = now; min_wait = now;
@ -539,10 +555,10 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
start_again: start_again:
#endif #endif
TAILQ_FOREACH_SAFE(chk, &stcb->asoc.sent_queue, sctp_next, nchk) { TAILQ_FOREACH_SAFE(chk, &stcb->asoc.sent_queue, sctp_next, nchk) {
if (SCTP_TSN_GE(stcb->asoc.last_acked_seq, chk->rec.data.TSN_seq)) { if (SCTP_TSN_GE(stcb->asoc.last_acked_seq, chk->rec.data.tsn)) {
/* Strange case our list got out of order? */ /* Strange case our list got out of order? */
SCTP_PRINTF("Our list is out of order? last_acked:%x chk:%x\n", 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_seq); (unsigned int)stcb->asoc.last_acked_seq, (unsigned int)chk->rec.data.tsn);
recovery_cnt++; recovery_cnt++;
#ifdef INVARIANTS #ifdef INVARIANTS
panic("last acked >= chk on sent-Q"); panic("last acked >= chk on sent-Q");
@ -567,7 +583,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
/* validate its been outstanding long enough */ /* validate its been outstanding long enough */
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) { if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
sctp_log_fr(chk->rec.data.TSN_seq, sctp_log_fr(chk->rec.data.tsn,
chk->sent_rcv_time.tv_sec, chk->sent_rcv_time.tv_sec,
chk->sent_rcv_time.tv_usec, chk->sent_rcv_time.tv_usec,
SCTP_FR_T3_MARK_TIME); SCTP_FR_T3_MARK_TIME);
@ -601,7 +617,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
} }
if (stcb->asoc.prsctp_supported && PR_SCTP_TTL_ENABLED(chk->flags)) { if (stcb->asoc.prsctp_supported && PR_SCTP_TTL_ENABLED(chk->flags)) {
/* Is it expired? */ /* Is it expired? */
#ifndef __FreeBSD__ #if !(defined(__FreeBSD__) && !defined(__Userspace__))
if (timercmp(&now, &chk->rec.data.timetodrop, >)) { if (timercmp(&now, &chk->rec.data.timetodrop, >)) {
#else #else
if (timevalcmp(&now, &chk->rec.data.timetodrop, >)) { if (timevalcmp(&now, &chk->rec.data.timetodrop, >)) {
@ -635,11 +651,11 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
num_mk++; num_mk++;
if (fir == 0) { if (fir == 0) {
fir = 1; fir = 1;
tsnfirst = chk->rec.data.TSN_seq; tsnfirst = chk->rec.data.tsn;
} }
tsnlast = chk->rec.data.TSN_seq; tsnlast = chk->rec.data.tsn;
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) { if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
sctp_log_fr(chk->rec.data.TSN_seq, chk->snd_count, sctp_log_fr(chk->rec.data.tsn, chk->snd_count,
0, SCTP_FR_T3_MARKED); 0, SCTP_FR_T3_MARKED);
} }
@ -654,8 +670,8 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_RSND_TO, sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_RSND_TO,
chk->whoTo->flight_size, chk->whoTo->flight_size,
chk->book_size, chk->book_size,
(uintptr_t)chk->whoTo, (uint32_t)(uintptr_t)chk->whoTo,
chk->rec.data.TSN_seq); chk->rec.data.tsn);
} }
sctp_flight_size_decrease(chk); sctp_flight_size_decrease(chk);
sctp_total_flight_decrease(stcb, chk); sctp_total_flight_decrease(stcb, chk);
@ -663,6 +679,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
stcb->asoc.peers_rwnd += SCTP_BASE_SYSCTL(sctp_peer_chunk_oh); stcb->asoc.peers_rwnd += SCTP_BASE_SYSCTL(sctp_peer_chunk_oh);
} }
chk->sent = SCTP_DATAGRAM_RESEND; chk->sent = SCTP_DATAGRAM_RESEND;
chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
SCTP_STAT_INCR(sctps_markedretrans); SCTP_STAT_INCR(sctps_markedretrans);
/* reset the TSN for striking and other FR stuff */ /* reset the TSN for striking and other FR stuff */
@ -685,7 +702,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
if (TAILQ_EMPTY(&stcb->asoc.send_queue)) { if (TAILQ_EMPTY(&stcb->asoc.send_queue)) {
chk->rec.data.fast_retran_tsn = stcb->asoc.sending_seq; chk->rec.data.fast_retran_tsn = stcb->asoc.sending_seq;
} else { } else {
chk->rec.data.fast_retran_tsn = (TAILQ_FIRST(&stcb->asoc.send_queue))->rec.data.TSN_seq; chk->rec.data.fast_retran_tsn = (TAILQ_FIRST(&stcb->asoc.send_queue))->rec.data.tsn;
} }
} }
/* CMT: Do not allow FRs on retransmitted TSNs. /* CMT: Do not allow FRs on retransmitted TSNs.
@ -715,13 +732,9 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
if (num_mk) { if (num_mk) {
SCTPDBG(SCTP_DEBUG_TIMER1, "LAST TSN marked was %x\n", SCTPDBG(SCTP_DEBUG_TIMER1, "LAST TSN marked was %x\n",
tsnlast); tsnlast);
SCTPDBG(SCTP_DEBUG_TIMER1, "Num marked for retransmission was %d peer-rwd:%ld\n", SCTPDBG(SCTP_DEBUG_TIMER1, "Num marked for retransmission was %d peer-rwd:%u\n",
num_mk, (u_long)stcb->asoc.peers_rwnd);
SCTPDBG(SCTP_DEBUG_TIMER1, "LAST TSN marked was %x\n",
tsnlast);
SCTPDBG(SCTP_DEBUG_TIMER1, "Num marked for retransmission was %d peer-rwd:%d\n",
num_mk, num_mk,
(int)stcb->asoc.peers_rwnd); stcb->asoc.peers_rwnd);
} }
#endif #endif
*num_marked = num_mk; *num_marked = num_mk;
@ -740,6 +753,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
chk->whoTo = alt; chk->whoTo = alt;
if (chk->sent != SCTP_DATAGRAM_RESEND) { if (chk->sent != SCTP_DATAGRAM_RESEND) {
chk->sent = SCTP_DATAGRAM_RESEND; chk->sent = SCTP_DATAGRAM_RESEND;
chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
cnt_mk++; cnt_mk++;
} }
@ -782,8 +796,8 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
sctp_misc_ints(SCTP_FLIGHT_LOG_UP, sctp_misc_ints(SCTP_FLIGHT_LOG_UP,
chk->whoTo->flight_size, chk->whoTo->flight_size,
chk->book_size, chk->book_size,
(uintptr_t)chk->whoTo, (uint32_t)(uintptr_t)chk->whoTo,
chk->rec.data.TSN_seq); chk->rec.data.tsn);
} }
sctp_flight_size_increase(chk); sctp_flight_size_increase(chk);
@ -795,7 +809,6 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
return (0); return (0);
} }
int int
sctp_t3rxt_timer(struct sctp_inpcb *inp, sctp_t3rxt_timer(struct sctp_inpcb *inp,
struct sctp_tcb *stcb, struct sctp_tcb *stcb,
@ -931,10 +944,14 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
net->src_addr_selected = 0; net->src_addr_selected = 0;
/* Force a route allocation too */ /* Force a route allocation too */
#if defined(__FreeBSD__) && !defined(__Userspace__)
RO_NHFREE(&net->ro);
#else
if (net->ro.ro_rt) { if (net->ro.ro_rt) {
RTFREE(net->ro.ro_rt); RTFREE(net->ro.ro_rt);
net->ro.ro_rt = NULL; net->ro.ro_rt = NULL;
} }
#endif
/* Was it our primary? */ /* Was it our primary? */
if ((stcb->asoc.primary_destination == net) && (alt != net)) { if ((stcb->asoc.primary_destination == net) && (alt != net)) {
@ -956,7 +973,7 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
* Special case for cookie-echo'ed case, we don't do output but must * Special case for cookie-echo'ed case, we don't do output but must
* await the COOKIE-ACK before retransmission * await the COOKIE-ACK before retransmission
*/ */
if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) { if (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED) {
/* /*
* Here we just reset the timer and start again since we * Here we just reset the timer and start again since we
* have not established the asoc * have not established the asoc
@ -971,7 +988,12 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
/* C3. See if we need to send a Fwd-TSN */ /* C3. See if we need to send a Fwd-TSN */
if (SCTP_TSN_GT(stcb->asoc.advanced_peer_ack_point, stcb->asoc.last_acked_seq)) { if (SCTP_TSN_GT(stcb->asoc.advanced_peer_ack_point, stcb->asoc.last_acked_seq)) {
send_forward_tsn(stcb, &stcb->asoc); send_forward_tsn(stcb, &stcb->asoc);
if (lchk) { for (; lchk != NULL; lchk = TAILQ_NEXT(lchk, sctp_next)) {
if (lchk->whoTo != NULL) {
break;
}
}
if (lchk != NULL) {
/* Assure a timer is up */ /* Assure a timer is up */
sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, lchk->whoTo); sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, lchk->whoTo);
} }
@ -998,7 +1020,7 @@ sctp_t1init_timer(struct sctp_inpcb *inp,
sctp_send_initiate(inp, stcb, SCTP_SO_NOT_LOCKED); sctp_send_initiate(inp, stcb, SCTP_SO_NOT_LOCKED);
return (0); return (0);
} }
if (SCTP_GET_STATE((&stcb->asoc)) != SCTP_STATE_COOKIE_WAIT) { if (SCTP_GET_STATE(stcb) != SCTP_STATE_COOKIE_WAIT) {
return (0); return (0);
} }
if (sctp_threshold_management(inp, stcb, net, if (sctp_threshold_management(inp, stcb, net,
@ -1046,19 +1068,19 @@ sctp_cookie_timer(struct sctp_inpcb *inp,
} }
} }
if (cookie == NULL) { if (cookie == NULL) {
if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) { if (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED) {
/* FOOBAR! */ /* FOOBAR! */
struct mbuf *op_err; struct mbuf *op_err;
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
"Cookie timer expired, but no cookie"); "Cookie timer expired, but no cookie");
inp->last_abort_code = SCTP_FROM_SCTP_TIMER+SCTP_LOC_4; 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, SCTP_SO_NOT_LOCKED);
} else { } else {
#ifdef INVARIANTS #ifdef INVARIANTS
panic("Cookie timer expires in wrong state?"); panic("Cookie timer expires in wrong state?");
#else #else
SCTP_PRINTF("Strange in state %d not cookie-echoed yet c-e timer expires?\n", SCTP_GET_STATE(&stcb->asoc)); SCTP_PRINTF("Strange in state %d not cookie-echoed yet c-e timer expires?\n", SCTP_GET_STATE(stcb));
return (0); return (0);
#endif #endif
} }
@ -1071,8 +1093,8 @@ sctp_cookie_timer(struct sctp_inpcb *inp,
return (1); return (1);
} }
/* /*
* cleared theshold management now lets backoff the address & select * Cleared threshold management, now lets backoff the address
* an alternate * and select an alternate
*/ */
stcb->asoc.dropped_special_cnt = 0; stcb->asoc.dropped_special_cnt = 0;
sctp_backoff_on_timeout(stcb, cookie->whoTo, 1, 0, 0); sctp_backoff_on_timeout(stcb, cookie->whoTo, 1, 0, 0);
@ -1087,6 +1109,7 @@ sctp_cookie_timer(struct sctp_inpcb *inp,
sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
} }
cookie->sent = SCTP_DATAGRAM_RESEND; cookie->sent = SCTP_DATAGRAM_RESEND;
cookie->flags |= CHUNK_FLAGS_FRAGMENT_OK;
/* /*
* Now call the output routine to kick out the cookie again, Note we * Now call the output routine to kick out the cookie again, Note we
* don't mark any chunks for retran so that FR will need to kick in * don't mark any chunks for retran so that FR will need to kick in
@ -1096,10 +1119,9 @@ sctp_cookie_timer(struct sctp_inpcb *inp,
} }
int int
sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
struct sctp_nets *net)
{ {
struct sctp_nets *alt; struct sctp_nets *alt, *net;
struct sctp_tmit_chunk *strrst = NULL, *chk = NULL; struct sctp_tmit_chunk *strrst = NULL, *chk = NULL;
if (stcb->asoc.stream_reset_outstanding == 0) { if (stcb->asoc.stream_reset_outstanding == 0) {
@ -1110,19 +1132,18 @@ sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if (strrst == NULL) { if (strrst == NULL) {
return (0); return (0);
} }
net = strrst->whoTo;
/* do threshold management */ /* do threshold management */
if (sctp_threshold_management(inp, stcb, strrst->whoTo, if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
stcb->asoc.max_send_times)) {
/* Assoc is over */ /* Assoc is over */
return (1); return (1);
} }
/* /*
* cleared theshold management now lets backoff the address & select * Cleared threshold management, now lets backoff the address
* an alternate * and select an alternate
*/ */
sctp_backoff_on_timeout(stcb, strrst->whoTo, 1, 0, 0); sctp_backoff_on_timeout(stcb, net, 1, 0, 0);
alt = sctp_find_alternate_net(stcb, strrst->whoTo, 0); alt = sctp_find_alternate_net(stcb, net, 0);
sctp_free_remote_addr(strrst->whoTo);
strrst->whoTo = alt; strrst->whoTo = alt;
atomic_add_int(&alt->ref_count, 1); atomic_add_int(&alt->ref_count, 1);
@ -1133,6 +1154,7 @@ sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
sctp_free_remote_addr(chk->whoTo); sctp_free_remote_addr(chk->whoTo);
if (chk->sent != SCTP_DATAGRAM_RESEND) { if (chk->sent != SCTP_DATAGRAM_RESEND) {
chk->sent = SCTP_DATAGRAM_RESEND; chk->sent = SCTP_DATAGRAM_RESEND;
chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
} }
chk->whoTo = alt; chk->whoTo = alt;
@ -1146,13 +1168,16 @@ sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
*/ */
sctp_move_chunks_from_net(stcb, net); sctp_move_chunks_from_net(stcb, net);
} }
sctp_free_remote_addr(net);
/* mark the retran info */ /* mark the retran info */
if (strrst->sent != SCTP_DATAGRAM_RESEND) if (strrst->sent != SCTP_DATAGRAM_RESEND)
sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
strrst->sent = SCTP_DATAGRAM_RESEND; strrst->sent = SCTP_DATAGRAM_RESEND;
strrst->flags |= CHUNK_FLAGS_FRAGMENT_OK;
/* restart the timer */ /* restart the timer */
sctp_timer_start(SCTP_TIMER_TYPE_STRRESET, inp, stcb, strrst->whoTo); sctp_timer_start(SCTP_TIMER_TYPE_STRRESET, inp, stcb, alt);
return (0); return (0);
} }
@ -1177,8 +1202,9 @@ sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if (asconf == NULL) { if (asconf == NULL) {
return (0); return (0);
} }
net = asconf->whoTo;
/* do threshold management */ /* do threshold management */
if (sctp_threshold_management(inp, stcb, asconf->whoTo, if (sctp_threshold_management(inp, stcb, net,
stcb->asoc.max_send_times)) { stcb->asoc.max_send_times)) {
/* Assoc is over */ /* Assoc is over */
return (1); return (1);
@ -1191,17 +1217,16 @@ sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
* Mark this peer as ASCONF incapable and cleanup. * Mark this peer as ASCONF incapable and cleanup.
*/ */
SCTPDBG(SCTP_DEBUG_TIMER1, "asconf_timer: Peer has not responded to our repeated ASCONFs\n"); SCTPDBG(SCTP_DEBUG_TIMER1, "asconf_timer: Peer has not responded to our repeated ASCONFs\n");
sctp_asconf_cleanup(stcb, net); sctp_asconf_cleanup(stcb);
return (0); return (0);
} }
/* /*
* cleared threshold management, so now backoff the net and * cleared threshold management, so now backoff the net and
* select an alternate * select an alternate
*/ */
sctp_backoff_on_timeout(stcb, asconf->whoTo, 1, 0, 0); sctp_backoff_on_timeout(stcb, net, 1, 0, 0);
alt = sctp_find_alternate_net(stcb, asconf->whoTo, 0); alt = sctp_find_alternate_net(stcb, net, 0);
if (asconf->whoTo != alt) { if (asconf->whoTo != alt) {
sctp_free_remote_addr(asconf->whoTo);
asconf->whoTo = alt; asconf->whoTo = alt;
atomic_add_int(&alt->ref_count, 1); atomic_add_int(&alt->ref_count, 1);
} }
@ -1214,6 +1239,7 @@ sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
chk->whoTo = alt; chk->whoTo = alt;
if (chk->sent != SCTP_DATAGRAM_RESEND) { if (chk->sent != SCTP_DATAGRAM_RESEND) {
chk->sent = SCTP_DATAGRAM_RESEND; chk->sent = SCTP_DATAGRAM_RESEND;
chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
} }
atomic_add_int(&alt->ref_count, 1); atomic_add_int(&alt->ref_count, 1);
@ -1228,6 +1254,7 @@ sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if (asconf->sent != SCTP_DATAGRAM_RESEND && chk->sent != SCTP_DATAGRAM_UNSENT) if (asconf->sent != SCTP_DATAGRAM_RESEND && chk->sent != SCTP_DATAGRAM_UNSENT)
sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
chk->sent = SCTP_DATAGRAM_RESEND; 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)) {
/* /*
@ -1236,10 +1263,13 @@ sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
*/ */
sctp_move_chunks_from_net(stcb, net); sctp_move_chunks_from_net(stcb, net);
} }
sctp_free_remote_addr(net);
/* mark the retran info */ /* mark the retran info */
if (asconf->sent != SCTP_DATAGRAM_RESEND) if (asconf->sent != SCTP_DATAGRAM_RESEND)
sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
asconf->sent = SCTP_DATAGRAM_RESEND; asconf->sent = SCTP_DATAGRAM_RESEND;
asconf->flags |= CHUNK_FLAGS_FRAGMENT_OK;
/* send another ASCONF if any and we can do */ /* send another ASCONF if any and we can do */
sctp_send_asconf(stcb, alt, SCTP_ADDR_NOT_LOCKED); sctp_send_asconf(stcb, alt, SCTP_ADDR_NOT_LOCKED);
@ -1249,8 +1279,7 @@ sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/* Mobility adaptation */ /* Mobility adaptation */
void void
sctp_delete_prim_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, sctp_delete_prim_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
struct sctp_nets *net SCTP_UNUSED)
{ {
if (stcb->asoc.deleted_primary == NULL) { if (stcb->asoc.deleted_primary == NULL) {
SCTPDBG(SCTP_DEBUG_ASCONF1, "delete_prim_timer: deleted_primary is not stored...\n"); SCTPDBG(SCTP_DEBUG_ASCONF1, "delete_prim_timer: deleted_primary is not stored...\n");
@ -1277,7 +1306,7 @@ sctp_shutdown_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
{ {
struct sctp_nets *alt; struct sctp_nets *alt;
/* first threshold managment */ /* first threshold management */
if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) { if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
/* Assoc is over */ /* Assoc is over */
return (1); return (1);
@ -1300,7 +1329,7 @@ sctp_shutdownack_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
{ {
struct sctp_nets *alt; struct sctp_nets *alt;
/* first threshold managment */ /* first threshold management */
if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) { if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
/* Assoc is over */ /* Assoc is over */
return (1); return (1);
@ -1424,7 +1453,7 @@ sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if ((net->last_sent_time.tv_sec > 0) || if ((net->last_sent_time.tv_sec > 0) ||
(net->last_sent_time.tv_usec > 0)) { (net->last_sent_time.tv_usec > 0)) {
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
struct timeval diff; struct timeval diff;
SCTP_GETTIME_TIMEVAL(&diff); SCTP_GETTIME_TIMEVAL(&diff);
@ -1470,7 +1499,7 @@ sctp_pathmtu_timer(struct sctp_inpcb *inp,
if (net->ro._l_addr.sa.sa_family == AF_INET6) { if (net->ro._l_addr.sa.sa_family == AF_INET6) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&net->ro._l_addr; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
/* KAME hack: embed scopeid */ /* KAME hack: embed scopeid */
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) #if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
(void)in6_embedscope(&sin6->sin6_addr, sin6, NULL, NULL); (void)in6_embedscope(&sin6->sin6_addr, sin6, NULL, NULL);
#else #else
@ -1503,7 +1532,11 @@ sctp_pathmtu_timer(struct sctp_inpcb *inp,
net->src_addr_selected = 1; net->src_addr_selected = 1;
} }
if (net->ro._s_addr) { if (net->ro._s_addr) {
#if defined(__FreeBSD__) && !defined(__Userspace__)
mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._s_addr.sa, net->ro.ro_nh);
#else
mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._s_addr.sa, net->ro.ro_rt); mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._s_addr.sa, net->ro.ro_rt);
#endif
#if defined(INET) || defined(INET6) #if defined(INET) || defined(INET6)
if (net->port) { if (net->port) {
mtu -= sizeof(struct udphdr); mtu -= sizeof(struct udphdr);
@ -1511,6 +1544,8 @@ sctp_pathmtu_timer(struct sctp_inpcb *inp,
#endif #endif
if (mtu > next_mtu) { if (mtu > next_mtu) {
net->mtu = next_mtu; net->mtu = next_mtu;
} else {
net->mtu = mtu;
} }
} }
} }
@ -1519,16 +1554,14 @@ sctp_pathmtu_timer(struct sctp_inpcb *inp,
} }
void void
sctp_autoclose_timer(struct sctp_inpcb *inp, sctp_autoclose_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
struct sctp_tcb *stcb,
struct sctp_nets *net)
{ {
struct timeval tn, *tim_touse; struct timeval tn, *tim_touse;
struct sctp_association *asoc; struct sctp_association *asoc;
int ticks_gone_by; uint32_t ticks_gone_by;
(void)SCTP_GETTIME_TIMEVAL(&tn); (void)SCTP_GETTIME_TIMEVAL(&tn);
if (stcb->asoc.sctp_autoclose_ticks && if (stcb->asoc.sctp_autoclose_ticks > 0 &&
sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) { sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) {
/* Auto close is on */ /* Auto close is on */
asoc = &stcb->asoc; asoc = &stcb->asoc;
@ -1540,9 +1573,8 @@ sctp_autoclose_timer(struct sctp_inpcb *inp,
tim_touse = &asoc->time_last_sent; tim_touse = &asoc->time_last_sent;
} }
/* Now has long enough transpired to autoclose? */ /* Now has long enough transpired to autoclose? */
ticks_gone_by = SEC_TO_TICKS(tn.tv_sec - tim_touse->tv_sec); ticks_gone_by = sctp_secs_to_ticks((uint32_t)(tn.tv_sec - tim_touse->tv_sec));
if ((ticks_gone_by > 0) && if (ticks_gone_by >= asoc->sctp_autoclose_ticks) {
(ticks_gone_by >= (int)asoc->sctp_autoclose_ticks)) {
/* /*
* autoclose time has hit, call the output routine, * autoclose time has hit, call the output routine,
* which should do nothing just to be SURE we don't * which should do nothing just to be SURE we don't
@ -1558,29 +1590,26 @@ sctp_autoclose_timer(struct sctp_inpcb *inp,
* there is nothing queued to send, so I'm * there is nothing queued to send, so I'm
* done... * done...
*/ */
if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) { if (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_SENT) {
/* only send SHUTDOWN 1st time thru */ /* only send SHUTDOWN 1st time thru */
struct sctp_nets *netp; struct sctp_nets *net;
if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) || if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
(SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) { (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab); SCTP_STAT_DECR_GAUGE32(sctps_currestab);
} }
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT); SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT);
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
sctp_stop_timers_for_shutdown(stcb); sctp_stop_timers_for_shutdown(stcb);
if (stcb->asoc.alternate) { if (stcb->asoc.alternate) {
netp = stcb->asoc.alternate; net = stcb->asoc.alternate;
} else { } else {
netp = stcb->asoc.primary_destination; net = stcb->asoc.primary_destination;
} }
sctp_send_shutdown(stcb, netp); sctp_send_shutdown(stcb, net);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
stcb->sctp_ep, stcb, stcb->sctp_ep, stcb, net);
netp);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
stcb->sctp_ep, stcb, stcb->sctp_ep, stcb, NULL);
netp);
} }
} }
} else { } else {
@ -1588,13 +1617,12 @@ sctp_autoclose_timer(struct sctp_inpcb *inp,
* No auto close at this time, reset t-o to check * No auto close at this time, reset t-o to check
* later * later
*/ */
int tmp; uint32_t tmp;
/* fool the timer startup to use the time left */ /* fool the timer startup to use the time left */
tmp = asoc->sctp_autoclose_ticks; tmp = asoc->sctp_autoclose_ticks;
asoc->sctp_autoclose_ticks -= ticks_gone_by; asoc->sctp_autoclose_ticks -= ticks_gone_by;
sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb, sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb, NULL);
net);
/* restore the real tick value */ /* restore the real tick value */
asoc->sctp_autoclose_ticks = tmp; asoc->sctp_autoclose_ticks = tmp;
} }

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.h 235828 2012-05-23 11:26:28Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.h 365071 2020-09-01 21:19:14Z mjg $");
#endif #endif
#ifndef _NETINET_SCTP_TIMER_H_ #ifndef _NETINET_SCTP_TIMER_H_
@ -44,22 +46,20 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.h 235828 2012-05-23 11:26:28Z tu
#define SCTP_RTT_VAR_SHIFT 2 #define SCTP_RTT_VAR_SHIFT 2
struct sctp_nets * struct sctp_nets *
sctp_find_alternate_net(struct sctp_tcb *, sctp_find_alternate_net(struct sctp_tcb *, struct sctp_nets *, int);
struct sctp_nets *, int mode);
int
sctp_threshold_management(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *, uint16_t);
int int
sctp_t3rxt_timer(struct sctp_inpcb *, struct sctp_tcb *, sctp_t3rxt_timer(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *); struct sctp_nets *);
int int
sctp_t1init_timer(struct sctp_inpcb *, struct sctp_tcb *, sctp_t1init_timer(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *); struct sctp_nets *);
int int
sctp_shutdown_timer(struct sctp_inpcb *, struct sctp_tcb *, sctp_shutdown_timer(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *); struct sctp_nets *);
int int
sctp_heartbeat_timer(struct sctp_inpcb *, struct sctp_tcb *, sctp_heartbeat_timer(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *); struct sctp_nets *);
@ -76,32 +76,28 @@ int
sctp_shutdownack_timer(struct sctp_inpcb *, struct sctp_tcb *, sctp_shutdownack_timer(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *); struct sctp_nets *);
int int
sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, sctp_strreset_timer(struct sctp_inpcb *, struct sctp_tcb *);
struct sctp_nets *net);
int int
sctp_asconf_timer(struct sctp_inpcb *, struct sctp_tcb *, sctp_asconf_timer(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *); struct sctp_nets *);
void void
sctp_delete_prim_timer(struct sctp_inpcb *, struct sctp_tcb *, sctp_delete_prim_timer(struct sctp_inpcb *, struct sctp_tcb *);
struct sctp_nets *);
void void
sctp_autoclose_timer(struct sctp_inpcb *, struct sctp_tcb *, sctp_autoclose_timer(struct sctp_inpcb *, struct sctp_tcb *);
struct sctp_nets *net);
void sctp_audit_retranmission_queue(struct sctp_association *); void sctp_audit_retranmission_queue(struct sctp_association *);
void sctp_iterator_timer(struct sctp_iterator *it); void sctp_iterator_timer(struct sctp_iterator *it);
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION) #if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
void sctp_slowtimo(void); void sctp_slowtimo(void);
#else #else
void sctp_gc(struct inpcbinfo *); void sctp_gc(struct inpcbinfo *);
#endif #endif
#endif #endif
#endif #endif
#endif #endif

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,21 +32,20 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_uio.h 269945 2014-08-13 15:50:16Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_uio.h 365071 2020-09-01 21:19:14Z mjg $");
#endif #endif
#ifndef _NETINET_SCTP_UIO_H_ #ifndef _NETINET_SCTP_UIO_H_
#define _NETINET_SCTP_UIO_H_ #define _NETINET_SCTP_UIO_H_
#if (defined(__APPLE__) && defined(KERNEL)) #if (defined(__APPLE__) && !defined(__Userspace__) && defined(KERNEL))
#ifndef _KERNEL #ifndef _KERNEL
#define _KERNEL #define _KERNEL
#endif #endif
#endif #endif
#if !defined(_WIN32)
#if !(defined(__Windows__)) && !defined(__Userspace_os_Windows)
#if !defined(_KERNEL) #if !defined(_KERNEL)
#include <stdint.h> #include <stdint.h>
#endif #endif
@ -52,7 +53,7 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_uio.h 269945 2014-08-13 15:50:16Z tuex
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#endif #endif
#if defined(__Windows__) #if defined(_WIN32) && !defined(__Userspace__)
#pragma warning(push) #pragma warning(push)
#pragma warning(disable: 4200) #pragma warning(disable: 4200)
#if defined(_KERNEL) #if defined(_KERNEL)
@ -108,14 +109,8 @@ struct sctp_event_subscribe {
* ancillary data structures * ancillary data structures
*/ */
struct sctp_initmsg { struct sctp_initmsg {
#if defined(__FreeBSD__) && __FreeBSD_version < 800000
/* This is a bug. Not fixed for ABI compatibility */
uint32_t sinit_num_ostreams;
uint32_t sinit_max_instreams;
#else
uint16_t sinit_num_ostreams; uint16_t sinit_num_ostreams;
uint16_t sinit_max_instreams; uint16_t sinit_max_instreams;
#endif
uint16_t sinit_max_attempts; uint16_t sinit_max_attempts;
uint16_t sinit_max_init_timeo; uint16_t sinit_max_init_timeo;
}; };
@ -133,7 +128,6 @@ struct sctp_initmsg {
* all sendrcvinfo's need a verfid for SENDING only. * all sendrcvinfo's need a verfid for SENDING only.
*/ */
#define SCTP_ALIGN_RESV_PAD 92 #define SCTP_ALIGN_RESV_PAD 92
#define SCTP_ALIGN_RESV_PAD_SHORT 76 #define SCTP_ALIGN_RESV_PAD_SHORT 76
@ -141,9 +135,6 @@ struct sctp_sndrcvinfo {
uint16_t sinfo_stream; uint16_t sinfo_stream;
uint16_t sinfo_ssn; uint16_t sinfo_ssn;
uint16_t sinfo_flags; uint16_t sinfo_flags;
#if defined(__FreeBSD__) && __FreeBSD_version < 800000
uint16_t sinfo_pr_policy;
#endif
uint32_t sinfo_ppid; uint32_t sinfo_ppid;
uint32_t sinfo_context; uint32_t sinfo_context;
uint32_t sinfo_timetolive; uint32_t sinfo_timetolive;
@ -159,24 +150,27 @@ struct sctp_extrcvinfo {
uint16_t sinfo_stream; uint16_t sinfo_stream;
uint16_t sinfo_ssn; uint16_t sinfo_ssn;
uint16_t sinfo_flags; uint16_t sinfo_flags;
#if defined(__FreeBSD__) && __FreeBSD_version < 800000
uint16_t sinfo_pr_policy;
#endif
uint32_t sinfo_ppid; uint32_t sinfo_ppid;
uint32_t sinfo_context; uint32_t sinfo_context;
uint32_t sinfo_timetolive; uint32_t sinfo_timetolive; /* should have been sinfo_pr_value */
uint32_t sinfo_tsn; uint32_t sinfo_tsn;
uint32_t sinfo_cumtsn; uint32_t sinfo_cumtsn;
sctp_assoc_t sinfo_assoc_id; sctp_assoc_t sinfo_assoc_id;
uint16_t sreinfo_next_flags; uint16_t serinfo_next_flags;
uint16_t sreinfo_next_stream; uint16_t serinfo_next_stream;
uint32_t sreinfo_next_aid; uint32_t serinfo_next_aid;
uint32_t sreinfo_next_length; uint32_t serinfo_next_length;
uint32_t sreinfo_next_ppid; uint32_t serinfo_next_ppid;
uint16_t sinfo_keynumber; uint16_t sinfo_keynumber;
uint16_t sinfo_keynumber_valid; uint16_t sinfo_keynumber_valid;
uint8_t __reserve_pad[SCTP_ALIGN_RESV_PAD_SHORT]; uint8_t __reserve_pad[SCTP_ALIGN_RESV_PAD_SHORT];
}; };
#define sinfo_pr_value sinfo_timetolive
#define sreinfo_next_flags serinfo_next_flags
#define sreinfo_next_stream serinfo_next_stream
#define sreinfo_next_aid serinfo_next_aid
#define sreinfo_next_length serinfo_next_length
#define sreinfo_next_ppid serinfo_next_ppid
struct sctp_sndinfo { struct sctp_sndinfo {
uint16_t snd_sid; uint16_t snd_sid;
@ -282,7 +276,8 @@ struct sctp_snd_all_completes {
/* The lower four bits is an enumeration of PR-SCTP policies */ /* The lower four bits is an enumeration of PR-SCTP policies */
#define SCTP_PR_SCTP_NONE 0x0000 /* Reliable transfer */ #define SCTP_PR_SCTP_NONE 0x0000 /* Reliable transfer */
#define SCTP_PR_SCTP_TTL 0x0001 /* Time based PR-SCTP */ #define SCTP_PR_SCTP_TTL 0x0001 /* Time based PR-SCTP */
#define SCTP_PR_SCTP_BUF 0x0002 /* Buffer based PR-SCTP */ #define SCTP_PR_SCTP_PRIO 0x0002 /* Buffer based PR-SCTP */
#define SCTP_PR_SCTP_BUF SCTP_PR_SCTP_PRIO /* For backwards compatibility */
#define SCTP_PR_SCTP_RTX 0x0003 /* Number of retransmissions based PR-SCTP */ #define SCTP_PR_SCTP_RTX 0x0003 /* Number of retransmissions based PR-SCTP */
#define SCTP_PR_SCTP_MAX SCTP_PR_SCTP_RTX #define SCTP_PR_SCTP_MAX SCTP_PR_SCTP_RTX
#define SCTP_PR_SCTP_ALL 0x000f /* Used for aggregated stats */ #define SCTP_PR_SCTP_ALL 0x000f /* Used for aggregated stats */
@ -346,7 +341,8 @@ struct sctp_assoc_change {
#define SCTP_ASSOC_SUPPORTS_ASCONF 0x03 #define SCTP_ASSOC_SUPPORTS_ASCONF 0x03
#define SCTP_ASSOC_SUPPORTS_MULTIBUF 0x04 #define SCTP_ASSOC_SUPPORTS_MULTIBUF 0x04
#define SCTP_ASSOC_SUPPORTS_RE_CONFIG 0x05 #define SCTP_ASSOC_SUPPORTS_RE_CONFIG 0x05
#define SCTP_ASSOC_SUPPORTS_MAX 0x05 #define SCTP_ASSOC_SUPPORTS_INTERLEAVING 0x06
#define SCTP_ASSOC_SUPPORTS_MAX 0x06
/* /*
* Address event * Address event
*/ */
@ -443,7 +439,6 @@ struct sctp_setadaption {
uint32_t ssb_adaption_ind; uint32_t ssb_adaption_ind;
}; };
/* /*
* Partial Delivery API event * Partial Delivery API event
*/ */
@ -460,7 +455,6 @@ struct sctp_pdapi_event {
/* indication values */ /* indication values */
#define SCTP_PARTIAL_DELIVERY_ABORTED 0x0001 #define SCTP_PARTIAL_DELIVERY_ABORTED 0x0001
/* /*
* authentication key event * authentication key event
*/ */
@ -480,7 +474,6 @@ struct sctp_authkey_event {
#define SCTP_AUTH_NO_AUTH 0x0002 #define SCTP_AUTH_NO_AUTH 0x0002
#define SCTP_AUTH_FREE_KEY 0x0003 #define SCTP_AUTH_FREE_KEY 0x0003
struct sctp_sender_dry_event { struct sctp_sender_dry_event {
uint16_t sender_dry_type; uint16_t sender_dry_type;
uint16_t sender_dry_flags; uint16_t sender_dry_flags;
@ -488,7 +481,6 @@ struct sctp_sender_dry_event {
sctp_assoc_t sender_dry_assoc_id; sctp_assoc_t sender_dry_assoc_id;
}; };
/* /*
* Stream reset event - subscribe to SCTP_STREAM_RESET_EVENT * Stream reset event - subscribe to SCTP_STREAM_RESET_EVENT
*/ */
@ -536,7 +528,6 @@ struct sctp_stream_change_event {
#define SCTP_STREAM_CHANGE_DENIED 0x0004 #define SCTP_STREAM_CHANGE_DENIED 0x0004
#define SCTP_STREAM_CHANGE_FAILED 0x0008 #define SCTP_STREAM_CHANGE_FAILED 0x0008
/* SCTP notification event */ /* SCTP notification event */
struct sctp_tlv { struct sctp_tlv {
uint16_t sn_type; uint16_t sn_type;
@ -611,6 +602,7 @@ struct sctp_paddrthlds {
sctp_assoc_t spt_assoc_id; sctp_assoc_t spt_assoc_id;
uint16_t spt_pathmaxrxt; uint16_t spt_pathmaxrxt;
uint16_t spt_pathpfthld; uint16_t spt_pathpfthld;
uint16_t spt_pathcpthld;
}; };
struct sctp_paddrinfo { struct sctp_paddrinfo {
@ -651,10 +643,18 @@ struct sctp_setpeerprim {
uint8_t sspp_padding[4]; uint8_t sspp_padding[4];
}; };
union sctp_sockstore {
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
#if defined(__Userspace__)
struct sockaddr_conn sconn;
#endif
struct sockaddr sa;
};
struct sctp_getaddresses { struct sctp_getaddresses {
sctp_assoc_t sget_assoc_id; sctp_assoc_t sget_assoc_id;
/* addr is filled in for N * sockaddr_storage */ union sctp_sockstore addr[];
struct sockaddr addr[1];
}; };
struct sctp_status { struct sctp_status {
@ -1001,7 +1001,7 @@ struct sctpstat {
uint32_t sctps_recvauthfailed; /* total number of auth failed */ uint32_t sctps_recvauthfailed; /* total number of auth failed */
uint32_t sctps_recvexpress; /* total fast path receives all one chunk */ uint32_t sctps_recvexpress; /* total fast path receives all one chunk */
uint32_t sctps_recvexpressm; /* total fast path multi-part data */ uint32_t sctps_recvexpressm; /* total fast path multi-part data */
uint32_t sctps_recvnocrc; uint32_t sctps_recv_spare; /* formerly sctps_recvnocrc */
uint32_t sctps_recvswcrc; uint32_t sctps_recvswcrc;
uint32_t sctps_recvhwcrc; uint32_t sctps_recvhwcrc;
@ -1018,7 +1018,7 @@ struct sctpstat {
uint32_t sctps_sendecne; /* total output ECNE chunks */ uint32_t sctps_sendecne; /* total output ECNE chunks */
uint32_t sctps_sendauth; /* total output AUTH chunks FIXME */ uint32_t sctps_sendauth; /* total output AUTH chunks FIXME */
uint32_t sctps_senderrors; /* ip_output error counter */ uint32_t sctps_senderrors; /* ip_output error counter */
uint32_t sctps_sendnocrc; uint32_t sctps_send_spare; /* formerly sctps_sendnocrc */
uint32_t sctps_sendswcrc; uint32_t sctps_sendswcrc;
uint32_t sctps_sendhwcrc; uint32_t sctps_sendhwcrc;
/* PCKDROPREP statistics: */ /* PCKDROPREP statistics: */
@ -1110,13 +1110,18 @@ struct sctpstat {
#define SCTP_STAT_INCR(_x) SCTP_STAT_INCR_BY(_x,1) #define SCTP_STAT_INCR(_x) SCTP_STAT_INCR_BY(_x,1)
#define SCTP_STAT_DECR(_x) SCTP_STAT_DECR_BY(_x,1) #define SCTP_STAT_DECR(_x) SCTP_STAT_DECR_BY(_x,1)
#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT) #if defined(__FreeBSD__) && !defined(__Userspace__)
#if defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
#define SCTP_STAT_INCR_BY(_x,_d) (SCTP_BASE_STATS[PCPU_GET(cpuid)]._x += _d) #define SCTP_STAT_INCR_BY(_x,_d) (SCTP_BASE_STATS[PCPU_GET(cpuid)]._x += _d)
#define SCTP_STAT_DECR_BY(_x,_d) (SCTP_BASE_STATS[PCPU_GET(cpuid)]._x -= _d) #define SCTP_STAT_DECR_BY(_x,_d) (SCTP_BASE_STATS[PCPU_GET(cpuid)]._x -= _d)
#else #else
#define SCTP_STAT_INCR_BY(_x,_d) atomic_add_int(&SCTP_BASE_STAT(_x), _d) #define SCTP_STAT_INCR_BY(_x,_d) atomic_add_int(&SCTP_BASE_STAT(_x), _d)
#define SCTP_STAT_DECR_BY(_x,_d) atomic_subtract_int(&SCTP_BASE_STAT(_x), _d) #define SCTP_STAT_DECR_BY(_x,_d) atomic_subtract_int(&SCTP_BASE_STAT(_x), _d)
#endif #endif
#else
#define SCTP_STAT_INCR_BY(_x,_d) atomic_add_int(&SCTP_BASE_STAT(_x), _d)
#define SCTP_STAT_DECR_BY(_x,_d) atomic_subtract_int(&SCTP_BASE_STAT(_x), _d)
#endif
/* The following macros are for handling MIB values, */ /* The following macros are for handling MIB values, */
#define SCTP_STAT_INCR_COUNTER32(_x) SCTP_STAT_INCR(_x) #define SCTP_STAT_INCR_COUNTER32(_x) SCTP_STAT_INCR(_x)
#define SCTP_STAT_INCR_COUNTER64(_x) SCTP_STAT_INCR(_x) #define SCTP_STAT_INCR_COUNTER64(_x) SCTP_STAT_INCR(_x)
@ -1125,34 +1130,14 @@ struct sctpstat {
#define SCTP_STAT_DECR_COUNTER64(_x) SCTP_STAT_DECR(_x) #define SCTP_STAT_DECR_COUNTER64(_x) SCTP_STAT_DECR(_x)
#define SCTP_STAT_DECR_GAUGE32(_x) SCTP_STAT_DECR(_x) #define SCTP_STAT_DECR_GAUGE32(_x) SCTP_STAT_DECR(_x)
#if defined(__Userspace__)
union sctp_sockstore {
#if defined(INET)
struct sockaddr_in sin;
#endif
#if defined(INET6)
struct sockaddr_in6 sin6;
#endif
struct sockaddr_conn sconn;
struct sockaddr sa;
};
#else
union sctp_sockstore {
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
struct sockaddr sa;
};
#endif
/***********************************/ /***********************************/
/* And something for us old timers */ /* And something for us old timers */
/***********************************/ /***********************************/
#ifndef __APPLE__ #if !(defined(__APPLE__) && !defined(__Userspace__))
#ifndef __Userspace__ #if !defined(__Userspace__)
#ifndef ntohll #ifndef ntohll
#if defined(__Userspace_os_Linux) #if defined(__linux__)
#ifndef _BSD_SOURCE #ifndef _BSD_SOURCE
#define _BSD_SOURCE #define _BSD_SOURCE
#endif #endif
@ -1164,7 +1149,7 @@ union sctp_sockstore {
#endif #endif
#ifndef htonll #ifndef htonll
#if defined(__Userspace_os_Linux) #if defined(__linux__)
#ifndef _BSD_SOURCE #ifndef _BSD_SOURCE
#define _BSD_SOURCE #define _BSD_SOURCE
#endif #endif
@ -1178,30 +1163,33 @@ union sctp_sockstore {
#endif #endif
/***********************************/ /***********************************/
struct xsctp_inpcb { struct xsctp_inpcb {
uint32_t last; uint32_t last;
uint32_t flags; uint32_t flags;
#if defined(__FreeBSD__) && __FreeBSD_version < 1000048
uint32_t features;
#else
uint64_t features; uint64_t features;
#endif
uint32_t total_sends; uint32_t total_sends;
uint32_t total_recvs; uint32_t total_recvs;
uint32_t total_nospaces; uint32_t total_nospaces;
uint32_t fragmentation_point; uint32_t fragmentation_point;
uint16_t local_port; uint16_t local_port;
#if defined(__FreeBSD__) && !defined(__Userspace__)
uint16_t qlen_old;
uint16_t maxqlen_old;
#else
uint16_t qlen; uint16_t qlen;
uint16_t maxqlen; uint16_t maxqlen;
#if defined(__Windows__)
uint16_t padding;
#endif #endif
#if defined(__FreeBSD__) && __FreeBSD_version < 1000048 uint16_t __spare16;
uint32_t extra_padding[32]; /* future */ #if defined(__FreeBSD__) && !defined(__Userspace__)
kvaddr_t socket;
#else #else
uint32_t extra_padding[31]; /* future */ void *socket;
#endif #endif
#if defined(__FreeBSD__) && !defined(__Userspace__)
uint32_t qlen;
uint32_t maxqlen;
#endif
uint32_t extra_padding[26]; /* future */
}; };
struct xsctp_tcb { struct xsctp_tcb {
@ -1230,18 +1218,9 @@ struct xsctp_tcb {
uint16_t remote_port; /* sctpAssocEntry 4 */ uint16_t remote_port; /* sctpAssocEntry 4 */
struct sctp_timeval start_time; /* sctpAssocEntry 16 */ struct sctp_timeval start_time; /* sctpAssocEntry 16 */
struct sctp_timeval discontinuity_time; /* sctpAssocEntry 17 */ struct sctp_timeval discontinuity_time; /* sctpAssocEntry 17 */
#if defined(__FreeBSD__)
#if __FreeBSD_version >= 800000
uint32_t peers_rwnd; uint32_t peers_rwnd;
sctp_assoc_t assoc_id; /* sctpAssocEntry 1 */ sctp_assoc_t assoc_id; /* sctpAssocEntry 1 */
uint32_t extra_padding[32]; /* future */ uint32_t extra_padding[32]; /* future */
#else
#endif
#else
uint32_t peers_rwnd;
sctp_assoc_t assoc_id; /* sctpAssocEntry 1 */
uint32_t extra_padding[32]; /* future */
#endif
}; };
struct xsctp_laddr { struct xsctp_laddr {
@ -1266,17 +1245,12 @@ struct xsctp_raddr {
uint8_t heartbeat_enabled; /* sctpAssocLocalRemEntry 4 */ uint8_t heartbeat_enabled; /* sctpAssocLocalRemEntry 4 */
uint8_t potentially_failed; uint8_t potentially_failed;
struct sctp_timeval start_time; /* sctpAssocLocalRemEntry 8 */ struct sctp_timeval start_time; /* sctpAssocLocalRemEntry 8 */
#if defined(__FreeBSD__)
#if __FreeBSD_version >= 800000
uint32_t rtt; uint32_t rtt;
uint32_t heartbeat_interval; uint32_t heartbeat_interval;
uint32_t extra_padding[31]; /* future */ uint32_t ssthresh;
#endif uint16_t encaps_port;
#else uint16_t state;
uint32_t rtt; uint32_t extra_padding[29]; /* future */
uint32_t heartbeat_interval;
uint32_t extra_padding[31]; /* future */
#endif
}; };
#define SCTP_MAX_LOGGING_SIZE 30000 #define SCTP_MAX_LOGGING_SIZE 30000
@ -1303,19 +1277,14 @@ int
sctp_lower_sosend(struct socket *so, sctp_lower_sosend(struct socket *so,
struct sockaddr *addr, struct sockaddr *addr,
struct uio *uio, struct uio *uio,
#if defined(__Panda__)
pakhandle_type i_pak,
pakhandle_type i_control,
#else
struct mbuf *i_pak, struct mbuf *i_pak,
struct mbuf *control, struct mbuf *control,
#endif
int flags, int flags,
struct sctp_sndrcvinfo *srcv struct sctp_sndrcvinfo *srcv
#if !(defined(__Panda__) || defined(__Userspace__)) #if !defined(__Userspace__)
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 #if defined(__FreeBSD__)
,struct thread *p ,struct thread *p
#elif defined(__Windows__) #elif defined(_WIN32)
, PKTHREAD p , PKTHREAD p
#else #else
,struct proc *p ,struct proc *p
@ -1326,11 +1295,7 @@ sctp_lower_sosend(struct socket *so,
int int
sctp_sorecvmsg(struct socket *so, sctp_sorecvmsg(struct socket *so,
struct uio *uio, struct uio *uio,
#if defined(__Panda__)
particletype **mp,
#else
struct mbuf **mp, struct mbuf **mp,
#endif
struct sockaddr *from, struct sockaddr *from,
int fromlen, int fromlen,
int *msg_flags, int *msg_flags,
@ -1344,45 +1309,6 @@ sctp_sorecvmsg(struct socket *so,
#if !(defined(_KERNEL)) && !(defined(__Userspace__)) #if !(defined(_KERNEL)) && !(defined(__Userspace__))
__BEGIN_DECLS __BEGIN_DECLS
#if defined(__FreeBSD__) && __FreeBSD_version < 902000
int sctp_peeloff __P((int, sctp_assoc_t));
int sctp_bindx __P((int, struct sockaddr *, int, int));
int sctp_connectx __P((int, const struct sockaddr *, int, sctp_assoc_t *));
int sctp_getaddrlen __P((sa_family_t));
int sctp_getpaddrs __P((int, sctp_assoc_t, struct sockaddr **));
void sctp_freepaddrs __P((struct sockaddr *));
int sctp_getladdrs __P((int, sctp_assoc_t, struct sockaddr **));
void sctp_freeladdrs __P((struct sockaddr *));
int sctp_opt_info __P((int, sctp_assoc_t, int, void *, socklen_t *));
/* deprecated */
ssize_t sctp_sendmsg __P((int, const void *, size_t, const struct sockaddr *,
socklen_t, uint32_t, uint32_t, uint16_t, uint32_t, uint32_t));
/* deprecated */
ssize_t sctp_send __P((int, const void *, size_t,
const struct sctp_sndrcvinfo *, int));
/* deprecated */
ssize_t sctp_sendx __P((int, const void *, size_t, struct sockaddr *,
int, struct sctp_sndrcvinfo *, int));
/* deprecated */
ssize_t sctp_sendmsgx __P((int sd, const void *, size_t, struct sockaddr *,
int, uint32_t, uint32_t, uint16_t, uint32_t, uint32_t));
sctp_assoc_t sctp_getassocid __P((int, struct sockaddr *));
/* deprecated */
ssize_t sctp_recvmsg __P((int, void *, size_t, struct sockaddr *, socklen_t *,
struct sctp_sndrcvinfo *, int *));
ssize_t sctp_sendv __P((int, const struct iovec *, int, struct sockaddr *,
int, void *, socklen_t, unsigned int, int));
ssize_t sctp_recvv __P((int, const struct iovec *, int, struct sockaddr *,
socklen_t *, void *, socklen_t *, unsigned int *, int *));
#else
int sctp_peeloff(int, sctp_assoc_t); int sctp_peeloff(int, sctp_assoc_t);
int sctp_bindx(int, struct sockaddr *, int, int); int sctp_bindx(int, struct sockaddr *, int, int);
int sctp_connectx(int, const struct sockaddr *, int, sctp_assoc_t *); int sctp_connectx(int, const struct sockaddr *, int, sctp_assoc_t *);
@ -1420,7 +1346,6 @@ ssize_t sctp_sendv(int, const struct iovec *, int, struct sockaddr *,
ssize_t sctp_recvv(int, const struct iovec *, int, struct sockaddr *, ssize_t sctp_recvv(int, const struct iovec *, int, struct sockaddr *,
socklen_t *, void *, socklen_t *, unsigned int *, int *); socklen_t *, void *, socklen_t *, unsigned int *, int *);
#endif
__END_DECLS __END_DECLS
#endif /* !_KERNEL */ #endif /* !_KERNEL */

View file

@ -31,18 +31,78 @@
#include <netinet/sctp_pcb.h> #include <netinet/sctp_pcb.h>
#include <sys/timeb.h> #include <sys/timeb.h>
#include <iphlpapi.h> #include <iphlpapi.h>
#pragma comment(lib, "IPHLPAPI.lib") #if !defined(__MINGW32__)
#pragma comment(lib, "iphlpapi.lib")
#endif
#endif #endif
#include <netinet/sctp_os_userspace.h> #include <netinet/sctp_os_userspace.h>
#if defined(__FreeBSD__)
#include <pthread_np.h>
#endif
#if !defined(_WIN32) && !defined(__Userspace_os_NaCl) #if defined(__linux__)
#include <sys/prctl.h>
#endif
#if defined(_WIN32)
/* Adapter to translate Unix thread start routines to Windows thread start
* routines.
*/
#if defined(__MINGW32__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
static DWORD WINAPI
sctp_create_thread_adapter(void *arg) {
start_routine_t start_routine = (start_routine_t)arg;
return start_routine(NULL) == NULL;
}
int
sctp_userspace_thread_create(userland_thread_t *thread, start_routine_t start_routine)
{
*thread = CreateThread(NULL, 0, sctp_create_thread_adapter,
(void *)start_routine, 0, NULL);
if (*thread == NULL)
return GetLastError();
return 0;
}
#if defined(__MINGW32__)
#pragma GCC diagnostic pop
#endif
#else
int
sctp_userspace_thread_create(userland_thread_t *thread, start_routine_t start_routine)
{
return pthread_create(thread, NULL, start_routine, NULL);
}
#endif
void
sctp_userspace_set_threadname(const char *name)
{
#if defined(__APPLE__)
pthread_setname_np(name);
#endif
#if defined(__linux__)
prctl(PR_SET_NAME, name);
#endif
#if defined(__FreeBSD__)
pthread_set_name_np(pthread_self(), name);
#endif
}
#if !defined(_WIN32) && !defined(__native_client__)
int int
sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af) sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
{ {
struct ifreq ifr; struct ifreq ifr;
int fd; int fd;
if_indextoname(if_index, ifr.ifr_name); memset(&ifr, 0, sizeof(struct ifreq));
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? */ /* 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) if ((fd = socket(af, SOCK_DGRAM, 0)) < 0)
return (0); return (0);
@ -52,10 +112,13 @@ sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
} }
close(fd); close(fd);
return ifr.ifr_mtu; return ifr.ifr_mtu;
} else {
return (0);
}
} }
#endif #endif
#if defined(__Userspace_os_NaCl) #if defined(__native_client__)
int int
sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af) sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
{ {
@ -63,132 +126,86 @@ sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
} }
#endif #endif
#if defined(__APPLE__) || defined(__DragonFly__) || defined(__linux__) || defined(__native_client__) || defined(__NetBSD__) || defined(_WIN32) || defined(__Fuchsia__) || defined(__EMSCRIPTEN__)
int
timingsafe_bcmp(const void *b1, const void *b2, size_t n)
{
const unsigned char *p1 = b1, *p2 = b2;
int ret = 0;
for (; n > 0; n--)
ret |= *p1++ ^ *p2++;
return (ret != 0);
}
#endif
#ifdef _WIN32 #ifdef _WIN32
int int
sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af) sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
{ {
PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt; PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt;
DWORD AdapterAddrsSize, Err; DWORD AdapterAddrsSize, Err;
int ret;
ret = 0;
AdapterAddrsSize = 0; AdapterAddrsSize = 0;
pAdapterAddrs = NULL;
if ((Err = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &AdapterAddrsSize)) != 0) { if ((Err = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &AdapterAddrsSize)) != 0) {
if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) { if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) {
SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersAddresses() sizing failed with error code %d, AdapterAddrsSize = %d\n", Err, AdapterAddrsSize); SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersAddresses() sizing failed with error code %d, AdapterAddrsSize = %d\n", Err, AdapterAddrsSize);
return (-1); ret = -1;
goto cleanup;
} }
} }
if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) { if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) {
SCTPDBG(SCTP_DEBUG_USR, "Memory allocation error!\n"); SCTPDBG(SCTP_DEBUG_USR, "Memory allocation error!\n");
return (-1); ret = -1;
goto cleanup;
} }
if ((Err = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) { if ((Err = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) {
SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersAddresses() failed with error code %d\n", Err); SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersAddresses() failed with error code %d\n", Err);
return (-1); ret = -1;
goto cleanup;
} }
for (pAdapt = pAdapterAddrs; pAdapt; pAdapt = pAdapt->Next) { for (pAdapt = pAdapterAddrs; pAdapt; pAdapt = pAdapt->Next) {
if (pAdapt->IfIndex == if_index) if (pAdapt->IfIndex == if_index) {
return (pAdapt->Mtu); ret = pAdapt->Mtu;
break;
} }
return (0); }
cleanup:
if (pAdapterAddrs != NULL) {
GlobalFree(pAdapterAddrs);
}
return (ret);
} }
void void
getwintimeofday(struct timeval *tv) getwintimeofday(struct timeval *tv)
{ {
struct timeb tb; FILETIME filetime;
ULARGE_INTEGER ularge;
ftime(&tb); GetSystemTimeAsFileTime(&filetime);
tv->tv_sec = (long)tb.time; ularge.LowPart = filetime.dwLowDateTime;
tv->tv_usec = (long)(tb.millitm) * 1000L; ularge.HighPart = filetime.dwHighDateTime;
} /* Change base from Jan 1 1601 00:00:00 to Jan 1 1970 00:00:00 */
#if defined(__MINGW32__)
int ularge.QuadPart -= 116444736000000000ULL;
Win_getifaddrs(struct ifaddrs** interfaces) #else
{ ularge.QuadPart -= 116444736000000000UI64;
#if defined(INET) || defined(INET6)
DWORD Err, AdapterAddrsSize;
int count;
PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt;
struct ifaddrs *ifa;
#endif #endif
#if defined(INET) /*
struct sockaddr_in *addr; * ularge.QuadPart is now the number of 100-nanosecond intervals
* since Jan 1 1970 00:00:00.
*/
#if defined(__MINGW32__)
tv->tv_sec = (long)(ularge.QuadPart / 10000000ULL);
tv->tv_usec = (long)((ularge.QuadPart % 10000000ULL) / 10ULL);
#else
tv->tv_sec = (long)(ularge.QuadPart / 10000000UI64);
tv->tv_usec = (long)((ularge.QuadPart % 10000000UI64) / 10UI64);
#endif #endif
#if defined(INET6)
struct sockaddr_in6 *addr6;
#endif
#if defined(INET) || defined(INET6)
count = 0;
#endif
#if defined(INET)
AdapterAddrsSize = 0;
if ((Err = GetAdaptersAddresses(AF_INET, 0, NULL, NULL, &AdapterAddrsSize)) != 0) {
if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) {
SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersV4Addresses() sizing failed with error code %d and AdapterAddrsSize = %d\n", Err, AdapterAddrsSize);
return (-1);
}
}
/* Allocate memory from sizing information */
if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) {
SCTPDBG(SCTP_DEBUG_USR, "Memory allocation error!\n");
return (-1);
}
/* Get actual adapter information */
if ((Err = GetAdaptersAddresses(AF_INET, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) {
SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersV4Addresses() failed with error code %d\n", Err);
return (-1);
}
/* Enumerate through each returned adapter and save its information */
for (pAdapt = pAdapterAddrs, count; pAdapt; pAdapt = pAdapt->Next, count++) {
addr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
ifa = (struct ifaddrs *)malloc(sizeof(struct ifaddrs));
if ((addr == NULL) || (ifa == NULL)) {
SCTPDBG(SCTP_DEBUG_USR, "Can't allocate memory\n");
return (-1);
}
ifa->ifa_name = _strdup(pAdapt->AdapterName);
ifa->ifa_flags = pAdapt->Flags;
ifa->ifa_addr = (struct sockaddr *)addr;
memcpy(addr, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in));
interfaces[count] = ifa;
}
#endif
#if defined(INET6)
if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) {
AdapterAddrsSize = 0;
if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, NULL, &AdapterAddrsSize)) != 0) {
if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) {
SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersV6Addresses() sizing failed with error code %d AdapterAddrsSize = %d\n", Err, AdapterAddrsSize);
return (-1);
}
}
/* Allocate memory from sizing information */
if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) {
SCTPDBG(SCTP_DEBUG_USR, "Memory allocation error!\n");
return (-1);
}
/* Get actual adapter information */
if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) {
SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersV6Addresses() failed with error code %d\n", Err);
return (-1);
}
/* Enumerate through each returned adapter and save its information */
for (pAdapt = pAdapterAddrs, count; pAdapt; pAdapt = pAdapt->Next, count++) {
addr6 = (struct sockaddr_in6 *)malloc(sizeof(struct sockaddr_in6));
ifa = (struct ifaddrs *)malloc(sizeof(struct ifaddrs));
if ((addr6 == NULL) || (ifa == NULL)) {
SCTPDBG(SCTP_DEBUG_USR, "Can't allocate memory\n");
return (-1);
}
ifa->ifa_name = _strdup(pAdapt->AdapterName);
ifa->ifa_flags = pAdapt->Flags;
ifa->ifa_addr = (struct sockaddr *)addr6;
memcpy(addr6, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in6));
interfaces[count] = ifa;
}
}
#endif
return (0);
} }
int int

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_var.h 275427 2014-12-02 20:29:29Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctp_var.h 365071 2020-09-01 21:19:14Z mjg $");
#endif #endif
#ifndef _NETINET_SCTP_VAR_H_ #ifndef _NETINET_SCTP_VAR_H_
@ -42,11 +44,10 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_var.h 275427 2014-12-02 20:29:29Z tuex
#if defined(_KERNEL) || defined(__Userspace__) #if defined(_KERNEL) || defined(__Userspace__)
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) #if !defined(__Userspace__)
extern struct pr_usrreqs sctp_usrreqs; extern struct pr_usrreqs sctp_usrreqs;
#endif #endif
#define sctp_feature_on(inp, feature) (inp->sctp_features |= feature) #define sctp_feature_on(inp, feature) (inp->sctp_features |= feature)
#define sctp_feature_off(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) #define sctp_is_feature_on(inp, feature) ((inp->sctp_features & feature) == feature)
@ -90,7 +91,7 @@ extern struct pr_usrreqs sctp_usrreqs;
#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) > (sb)->sb_cc) ? (sctp_maxspace(sb) - (sb)->sb_cc) : 0))
#define sctp_sbspace_sub(a,b) ((a > b) ? (a - b) : 0) #define sctp_sbspace_sub(a,b) (((a) > (b)) ? ((a) - (b)) : 0)
/* /*
* I tried to cache the readq entries at one point. But the reality * I tried to cache the readq entries at one point. But the reality
@ -101,11 +102,19 @@ extern struct pr_usrreqs sctp_usrreqs;
* an mbuf cache as well so it is not really worth doing, at least * an mbuf cache as well so it is not really worth doing, at least
* right now :-D * right now :-D
*/ */
#ifdef INVARIANTS
#define sctp_free_a_readq(_stcb, _readq) { \
if ((_readq)->on_strm_q) \
panic("On strm q stcb:%p readq:%p", (_stcb), (_readq)); \
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), (_readq)); \
SCTP_DECR_READQ_COUNT(); \
}
#else
#define sctp_free_a_readq(_stcb, _readq) { \ #define sctp_free_a_readq(_stcb, _readq) { \
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), (_readq)); \ SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), (_readq)); \
SCTP_DECR_READQ_COUNT(); \ SCTP_DECR_READQ_COUNT(); \
} }
#endif
#define sctp_alloc_a_readq(_stcb, _readq) { \ #define sctp_alloc_a_readq(_stcb, _readq) { \
(_readq) = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_readq), struct sctp_queued_to_read); \ (_readq) = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_readq), struct sctp_queued_to_read); \
@ -176,17 +185,11 @@ extern struct pr_usrreqs sctp_usrreqs;
} \ } \
} }
#if defined(__FreeBSD__) && __FreeBSD_version > 500000 #if defined(__FreeBSD__) && !defined(__Userspace__)
#define sctp_free_remote_addr(__net) { \ #define sctp_free_remote_addr(__net) { \
if ((__net)) { \ if ((__net)) { \
if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&(__net)->ref_count)) { \ if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&(__net)->ref_count)) { \
(void)SCTP_OS_TIMER_STOP(&(__net)->rxt_timer.timer); \ RO_NHFREE(&(__net)->ro); \
(void)SCTP_OS_TIMER_STOP(&(__net)->pmtu_timer.timer); \
if ((__net)->ro.ro_rt) { \
RTFREE((__net)->ro.ro_rt); \
(__net)->ro.ro_rt = NULL; \
} \
if ((__net)->src_addr_selected) { \ if ((__net)->src_addr_selected) { \
sctp_free_ifa((__net)->ro._s_addr); \ sctp_free_ifa((__net)->ro._s_addr); \
(__net)->ro._s_addr = NULL; \ (__net)->ro._s_addr = NULL; \
@ -222,15 +225,10 @@ extern struct pr_usrreqs sctp_usrreqs;
SCTP_BUF_TYPE(m) != MT_OOBDATA) \ SCTP_BUF_TYPE(m) != MT_OOBDATA) \
atomic_add_int(&(sb)->sb_ctl,SCTP_BUF_LEN((m))); \ atomic_add_int(&(sb)->sb_ctl,SCTP_BUF_LEN((m))); \
} }
#else /* FreeBSD Version <= 500000 or non-FreeBSD */ #else /* FreeBSD Version <= 500000 or non-FreeBSD */
#define sctp_free_remote_addr(__net) { \ #define sctp_free_remote_addr(__net) { \
if ((__net)) { \ if ((__net)) { \
if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&(__net)->ref_count)) { \ if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&(__net)->ref_count)) { \
(void)SCTP_OS_TIMER_STOP(&(__net)->rxt_timer.timer); \
(void)SCTP_OS_TIMER_STOP(&(__net)->pmtu_timer.timer); \
(void)SCTP_OS_TIMER_STOP(&(__net)->hb_timer.timer); \
if ((__net)->ro.ro_rt) { \ if ((__net)->ro.ro_rt) { \
RTFREE((__net)->ro.ro_rt); \ RTFREE((__net)->ro.ro_rt); \
(__net)->ro.ro_rt = NULL; \ (__net)->ro.ro_rt = NULL; \
@ -247,31 +245,6 @@ extern struct pr_usrreqs sctp_usrreqs;
} \ } \
} }
#if defined(__Panda__)
#define sctp_sbfree(ctl, stcb, sb, m) { \
if ((sb)->sb_cc >= (uint32_t)SCTP_BUF_LEN((m))) { \
atomic_subtract_int(&(sb)->sb_cc, SCTP_BUF_LEN((m))); \
} else { \
(sb)->sb_cc = 0; \
} \
if (((ctl)->do_not_ref_stcb == 0) && stcb) { \
if ((stcb)->asoc.sb_cc >= (uint32_t)SCTP_BUF_LEN((m))) { \
atomic_subtract_int(&(stcb)->asoc.sb_cc, SCTP_BUF_LEN((m))); \
} else { \
(stcb)->asoc.sb_cc = 0; \
} \
} \
}
#define sctp_sballoc(stcb, sb, m) { \
atomic_add_int(&(sb)->sb_cc, SCTP_BUF_LEN((m))); \
if (stcb) { \
atomic_add_int(&(stcb)->asoc.sb_cc, SCTP_BUF_LEN((m))); \
} \
}
#else
#define sctp_sbfree(ctl, stcb, sb, m) { \ #define sctp_sbfree(ctl, stcb, sb, m) { \
SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_cc, SCTP_BUF_LEN((m))); \ SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_cc, SCTP_BUF_LEN((m))); \
SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_mbcnt, MSIZE); \ SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_mbcnt, MSIZE); \
@ -290,7 +263,6 @@ extern struct pr_usrreqs sctp_usrreqs;
} \ } \
} }
#endif #endif
#endif
#define sctp_ucount_incr(val) { \ #define sctp_ucount_incr(val) { \
val++; \ val++; \
@ -331,7 +303,7 @@ extern struct pr_usrreqs sctp_usrreqs;
if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \ if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
stcb->asoc.fs_index = 0;\ stcb->asoc.fs_index = 0;\
stcb->asoc.fslog[stcb->asoc.fs_index].total_flight = stcb->asoc.total_flight; \ stcb->asoc.fslog[stcb->asoc.fs_index].total_flight = stcb->asoc.total_flight; \
stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.TSN_seq; \ stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.tsn; \
stcb->asoc.fslog[stcb->asoc.fs_index].book = tp1->book_size; \ stcb->asoc.fslog[stcb->asoc.fs_index].book = tp1->book_size; \
stcb->asoc.fslog[stcb->asoc.fs_index].sent = tp1->sent; \ stcb->asoc.fslog[stcb->asoc.fs_index].sent = tp1->sent; \
stcb->asoc.fslog[stcb->asoc.fs_index].incr = 0; \ stcb->asoc.fslog[stcb->asoc.fs_index].incr = 0; \
@ -352,7 +324,7 @@ extern struct pr_usrreqs sctp_usrreqs;
if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \ if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
stcb->asoc.fs_index = 0;\ stcb->asoc.fs_index = 0;\
stcb->asoc.fslog[stcb->asoc.fs_index].total_flight = stcb->asoc.total_flight; \ stcb->asoc.fslog[stcb->asoc.fs_index].total_flight = stcb->asoc.total_flight; \
stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.TSN_seq; \ stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.tsn; \
stcb->asoc.fslog[stcb->asoc.fs_index].book = tp1->book_size; \ stcb->asoc.fslog[stcb->asoc.fs_index].book = tp1->book_size; \
stcb->asoc.fslog[stcb->asoc.fs_index].sent = tp1->sent; \ stcb->asoc.fslog[stcb->asoc.fs_index].sent = tp1->sent; \
stcb->asoc.fslog[stcb->asoc.fs_index].incr = 1; \ stcb->asoc.fslog[stcb->asoc.fs_index].incr = 1; \
@ -391,39 +363,30 @@ struct sctp_inpcb;
struct sctp_tcb; struct sctp_tcb;
struct sctphdr; struct sctphdr;
#if defined(__FreeBSD__) || defined(_WIN32) || defined(__Userspace__)
#if (defined(__FreeBSD__) && __FreeBSD_version > 690000) || defined(__Windows__) || defined(__Userspace__)
void sctp_close(struct socket *so); void sctp_close(struct socket *so);
#else #else
int sctp_detach(struct socket *so); int sctp_detach(struct socket *so);
#endif #endif
int sctp_disconnect(struct socket *so); int sctp_disconnect(struct socket *so);
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) #if !defined(__Userspace__)
#if defined(__FreeBSD__) && __FreeBSD_version < 902000 #if defined(__APPLE__) && !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION) && !defined(APPLE_ELCAPITAN)
void sctp_ctlinput __P((int, struct sockaddr *, void *)); void sctp_ctlinput(int, struct sockaddr *, void *, struct ifnet * SCTP_UNUSED);
int sctp_ctloutput __P((struct socket *, struct sockopt *));
#ifdef INET
void sctp_input_with_port __P((struct mbuf *, int, uint16_t));
void sctp_input __P((struct mbuf *, int));
#endif
void sctp_pathmtu_adjustment __P((struct sctp_tcb *, uint16_t));
#else #else
void sctp_ctlinput(int, struct sockaddr *, void *); void sctp_ctlinput(int, struct sockaddr *, void *);
#endif
int sctp_ctloutput(struct socket *, struct sockopt *); int sctp_ctloutput(struct socket *, struct sockopt *);
#ifdef INET #ifdef INET
void sctp_input_with_port(struct mbuf *, int, uint16_t); void sctp_input_with_port(struct mbuf *, int, uint16_t);
#if defined(__FreeBSD__) && __FreeBSD_version >= 1100020 #if defined(__FreeBSD__) && !defined(__Userspace__)
int sctp_input(struct mbuf **, int *, int); int sctp_input(struct mbuf **, int *, int);
#else #else
void sctp_input(struct mbuf *, int); void sctp_input(struct mbuf *, int);
#endif #endif
#endif #endif
void sctp_pathmtu_adjustment(struct sctp_tcb *, uint16_t); void sctp_pathmtu_adjustment(struct sctp_tcb *, uint16_t);
#endif
#else #else
#if defined(__Panda__) #if defined(__Userspace__)
void sctp_input(pakhandle_type i_pak);
#elif defined(__Userspace__)
void sctp_pathmtu_adjustment(struct sctp_tcb *, uint16_t); void sctp_pathmtu_adjustment(struct sctp_tcb *, uint16_t);
#else #else
void sctp_input(struct mbuf *,...); void sctp_input(struct mbuf *,...);
@ -431,75 +394,49 @@ void sctp_input(struct mbuf *,...);
void *sctp_ctlinput(int, struct sockaddr *, void *); void *sctp_ctlinput(int, struct sockaddr *, void *);
int sctp_ctloutput(int, struct socket *, int, int, struct mbuf **); int sctp_ctloutput(int, struct socket *, int, int, struct mbuf **);
#endif #endif
#if defined(__FreeBSD__) && __FreeBSD_version < 902000
void sctp_drain __P((void));
#else
void sctp_drain(void); void sctp_drain(void);
#endif
#if defined(__Userspace__) #if defined(__Userspace__)
void sctp_init(uint16_t, void sctp_init(uint16_t,
int (*)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df), int (*)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
void (*)(const char *, ...)); void (*)(const char *, ...), int start_threads);
#elif defined(__FreeBSD__) && __FreeBSD_version < 902000
void sctp_init __P((void));
#elif defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) &&!defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION)) #elif defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) &&!defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
void sctp_init(struct protosw *pp, struct domain *dp); void sctp_init(struct protosw *pp, struct domain *dp);
#else #else
void sctp_init(void); void sctp_init(void);
void sctp_notify(struct sctp_inpcb *, struct sctp_tcb *, struct sctp_nets *,
uint8_t, uint8_t, uint16_t, uint32_t);
#endif #endif
#if !defined(__FreeBSD__) && !defined(__Userspace__)
void sctp_finish(void); void sctp_finish(void);
#if defined(__FreeBSD__) || defined(__Windows__) || defined(__Userspace__) #endif
#if defined(__FreeBSD__) || defined(_WIN32) || defined(__Userspace__)
int sctp_flush(struct socket *, int); int sctp_flush(struct socket *, int);
#endif #endif
#if defined(__FreeBSD__) && __FreeBSD_version < 902000
int sctp_shutdown __P((struct socket *));
void sctp_notify __P((struct sctp_inpcb *, struct ip *ip, struct sctphdr *,
struct sockaddr *, struct sctp_tcb *,
struct sctp_nets *));
#else
int sctp_shutdown(struct socket *); int sctp_shutdown(struct socket *);
void sctp_notify(struct sctp_inpcb *, struct ip *ip, struct sctphdr *,
struct sockaddr *, struct sctp_tcb *,
struct sctp_nets *);
#endif
int sctp_bindx(struct socket *, int, struct sockaddr_storage *, int sctp_bindx(struct socket *, int, struct sockaddr_storage *,
int, int, struct proc *); int, int, struct proc *);
/* can't use sctp_assoc_t here */ /* can't use sctp_assoc_t here */
int sctp_peeloff(struct socket *, struct socket *, int, caddr_t, int *); int sctp_peeloff(struct socket *, struct socket *, int, caddr_t, int *);
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) #if !defined(__Userspace__)
int sctp_ingetaddr(struct socket *, struct sockaddr **); int sctp_ingetaddr(struct socket *, struct sockaddr **);
#elif defined(__Panda__)
int sctp_ingetaddr(struct socket *, struct sockaddr *);
#else #else
int sctp_ingetaddr(struct socket *, struct mbuf *); int sctp_ingetaddr(struct socket *, struct mbuf *);
#endif #endif
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) #if !defined(__Userspace__)
int sctp_peeraddr(struct socket *, struct sockaddr **); int sctp_peeraddr(struct socket *, struct sockaddr **);
#elif defined(__Panda__)
int sctp_peeraddr(struct socket *, struct sockaddr *);
#else #else
int sctp_peeraddr(struct socket *, struct mbuf *); int sctp_peeraddr(struct socket *, struct mbuf *);
#endif #endif
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 #if defined(__FreeBSD__) && !defined(__Userspace__)
#if __FreeBSD_version >= 700000
int sctp_listen(struct socket *, int, struct thread *); int sctp_listen(struct socket *, int, struct thread *);
#else #elif defined(_WIN32) && !defined(__Userspace__)
int sctp_listen(struct socket *, struct thread *);
#endif
#elif defined(__Windows__)
int sctp_listen(struct socket *, int, PKTHREAD); int sctp_listen(struct socket *, int, PKTHREAD);
#elif defined(__Userspace__) #elif defined(__Userspace__)
int sctp_listen(struct socket *, int, struct proc *); int sctp_listen(struct socket *, int, struct proc *);
#else #else
int sctp_listen(struct socket *, struct proc *); int sctp_listen(struct socket *, struct proc *);
#endif #endif
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__)
int sctp_accept(struct socket *, struct sockaddr **); int sctp_accept(struct socket *, struct sockaddr **);
#elif defined(__Panda__)
int sctp_accept(struct socket *, struct sockaddr *, int *, void *, int *);
#else
int sctp_accept(struct socket *, struct mbuf *);
#endif
#endif /* _KERNEL */ #endif /* _KERNEL */

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctputil.h 276914 2015-01-10 20:49:57Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet/sctputil.h 365071 2020-09-01 21:19:14Z mjg $");
#endif #endif
#ifndef _NETINET_SCTP_UTIL_H_ #ifndef _NETINET_SCTP_UTIL_H_
@ -55,17 +57,19 @@ void sctp_m_freem(struct mbuf *m);
#define sctp_m_freem m_freem #define sctp_m_freem m_freem
#endif #endif
#if defined(SCTP_LOCAL_TRACE_BUF) || defined(__APPLE__) #if defined(SCTP_LOCAL_TRACE_BUF)
void void
sctp_log_trace(uint32_t fr, const char *str SCTP_UNUSED, uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e, uint32_t f); sctp_log_trace(uint32_t fr, const char *str SCTP_UNUSED, uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e, uint32_t f);
#endif #endif
#define sctp_get_associd(stcb) ((sctp_assoc_t)stcb->asoc.assoc_id) #define sctp_get_associd(stcb) ((sctp_assoc_t)stcb->asoc.assoc_id)
/* /*
* Function prototypes * Function prototypes
*/ */
int32_t
sctp_map_assoc_state(int);
uint32_t uint32_t
sctp_get_ifa_hash_val(struct sockaddr *addr); sctp_get_ifa_hash_val(struct sockaddr *addr);
@ -79,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); 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); int sctp_init_asoc(struct sctp_inpcb *, struct sctp_tcb *, uint32_t, uint32_t, uint16_t);
void sctp_fill_random_store(struct sctp_pcb *); void sctp_fill_random_store(struct sctp_pcb *);
@ -89,6 +93,14 @@ sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin,
void void
sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, uint32_t sending_tsn, uint32_t recv_tsn, int flag); 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 void
sctp_timer_start(int, struct sctp_inpcb *, struct sctp_tcb *, sctp_timer_start(int, struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *); struct sctp_nets *);
@ -103,6 +115,21 @@ sctp_dynamic_set_primary(struct sockaddr *sa, uint32_t vrf_id);
void void
sctp_mtu_size_reset(struct sctp_inpcb *, struct sctp_association *, uint32_t); 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
#if !(defined(__APPLE__) && !defined(__Userspace__))
SCTP_UNUSED
#endif
);
#if defined(__Userspace__)
void sctp_invoke_recv_callback(struct sctp_inpcb *,
struct sctp_tcb *,
struct sctp_queued_to_read *,
int);
#endif
void void
sctp_add_to_readq(struct sctp_inpcb *inp, sctp_add_to_readq(struct sctp_inpcb *inp,
struct sctp_tcb *stcb, struct sctp_tcb *stcb,
@ -110,21 +137,7 @@ sctp_add_to_readq(struct sctp_inpcb *inp,
struct sockbuf *sb, struct sockbuf *sb,
int end, int end,
int inpread_locked, int inpread_locked,
int so_locked int so_locked);
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif
);
int
sctp_append_to_readq(struct sctp_inpcb *inp,
struct sctp_tcb *stcb,
struct sctp_queued_to_read *control,
struct mbuf *m,
int end,
int new_cumack,
struct sockbuf *sb);
void sctp_iterator_worker(void); void sctp_iterator_worker(void);
@ -134,9 +147,9 @@ uint32_t sctp_get_next_mtu(uint32_t);
void void
sctp_timeout_handler(void *); sctp_timeout_handler(void *);
uint32_t int
sctp_calculate_rto(struct sctp_tcb *, struct sctp_association *, sctp_calculate_rto(struct sctp_tcb *, struct sctp_association *,
struct sctp_nets *, struct timeval *, int, int); struct sctp_nets *, struct timeval *, int);
uint32_t sctp_calculate_len(struct mbuf *); uint32_t sctp_calculate_len(struct mbuf *);
@ -152,70 +165,55 @@ sctp_add_pad_tombuf(struct mbuf *, int);
struct mbuf * struct mbuf *
sctp_pad_lastmbuf(struct mbuf *, int, struct mbuf *); sctp_pad_lastmbuf(struct mbuf *, int, struct mbuf *);
void sctp_ulp_notify(uint32_t, struct sctp_tcb *, uint32_t, void *, int void sctp_ulp_notify(uint32_t, struct sctp_tcb *, uint32_t, void *, int);
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif
);
void void
sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp, sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp,
struct sctp_inpcb *new_inp, struct sctp_inpcb *new_inp,
struct sctp_tcb *stcb, int waitflags); struct sctp_tcb *stcb, int waitflags);
void sctp_stop_timers_for_shutdown(struct sctp_tcb *); void sctp_stop_timers_for_shutdown(struct sctp_tcb *);
void sctp_report_all_outbound(struct sctp_tcb *, uint16_t, int, int /* Stop all timers for association and remote addresses. */
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) void sctp_stop_association_timers(struct sctp_tcb *, bool);
SCTP_UNUSED
#endif void sctp_report_all_outbound(struct sctp_tcb *, uint16_t, int);
);
int sctp_expand_mapping_array(struct sctp_association *, uint32_t); int sctp_expand_mapping_array(struct sctp_association *, uint32_t);
void sctp_abort_notification(struct sctp_tcb *, uint8_t, uint16_t, void sctp_abort_notification(struct sctp_tcb *, uint8_t, uint16_t,
struct sctp_abort_chunk *, int struct sctp_abort_chunk *, int);
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif
);
/* We abort responding to an IP packet for some reason */ /* We abort responding to an IP packet for some reason */
void void
sctp_abort_association(struct sctp_inpcb *, struct sctp_tcb *, struct mbuf *, sctp_abort_association(struct sctp_inpcb *, struct sctp_tcb *, struct mbuf *,
int, struct sockaddr *, struct sockaddr *, int, struct sockaddr *, struct sockaddr *,
struct sctphdr *, struct mbuf *, struct sctphdr *, struct mbuf *,
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
uint8_t, uint32_t, uint8_t, uint32_t,
#endif #endif
uint32_t, uint16_t); uint32_t, uint16_t);
/* We choose to abort via user input */ /* We choose to abort via user input */
void void
sctp_abort_an_association(struct sctp_inpcb *, struct sctp_tcb *, sctp_abort_an_association(struct sctp_inpcb *, struct sctp_tcb *,
struct mbuf *, int struct mbuf *, int);
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif
);
void sctp_handle_ootb(struct mbuf *, int, int, void sctp_handle_ootb(struct mbuf *, int, int,
struct sockaddr *, struct sockaddr *, struct sockaddr *, struct sockaddr *,
struct sctphdr *, struct sctp_inpcb *, struct sctphdr *, struct sctp_inpcb *,
struct mbuf *, struct mbuf *,
#if defined(__FreeBSD__) #if defined(__FreeBSD__) && !defined(__Userspace__)
uint8_t, uint32_t, uint8_t, uint32_t, uint16_t,
#endif #endif
uint32_t, uint16_t); uint32_t, uint16_t);
int sctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr, int sctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr,
int totaddr, int *error); int totaddr, int *error);
struct sctp_tcb * int
sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr, sctp_connectx_helper_find(struct sctp_inpcb *, struct sockaddr *,
int *totaddr, int *num_v4, int *num_v6, int *error, int limit, int *bad_addr); unsigned int, unsigned int *, unsigned int *, unsigned int);
int sctp_is_there_an_abort_here(struct mbuf *, int, uint32_t *); int sctp_is_there_an_abort_here(struct mbuf *, int, uint32_t *);
#ifdef INET6 #ifdef INET6
@ -266,20 +264,15 @@ void sctp_print_address(struct sockaddr *);
int int
sctp_release_pr_sctp_chunk(struct sctp_tcb *, struct sctp_tmit_chunk *, sctp_release_pr_sctp_chunk(struct sctp_tcb *, struct sctp_tmit_chunk *,
uint8_t, int uint8_t, int);
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif
);
struct mbuf *sctp_generate_cause(uint16_t, char *); struct mbuf *sctp_generate_cause(uint16_t, char *);
struct mbuf *sctp_generate_no_user_data_cause(uint32_t); struct mbuf *sctp_generate_no_user_data_cause(uint32_t);
void sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp, void sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
struct sockaddr *sa, sctp_assoc_t assoc_id, struct sockaddr *sa, uint32_t vrf_id, int *error,
uint32_t vrf_id, int *error, void *p); void *p);
void sctp_bindx_delete_address(struct sctp_inpcb *inp, void sctp_bindx_delete_address(struct sctp_inpcb *inp, struct sockaddr *sa,
struct sockaddr *sa, sctp_assoc_t assoc_id,
uint32_t vrf_id, int *error); uint32_t vrf_id, int *error);
int sctp_local_addr_count(struct sctp_tcb *stcb); int sctp_local_addr_count(struct sctp_tcb *stcb);
@ -342,11 +335,11 @@ do { \
} while (0) } while (0)
/* functions to start/stop udp tunneling */ /* functions to start/stop udp tunneling */
#if defined(__APPLE__) || defined(__FreeBSD__) #if (defined(__APPLE__) || defined(__FreeBSD__)) && !defined(__Userspace__)
void sctp_over_udp_stop(void); void sctp_over_udp_stop(void);
int sctp_over_udp_start(void); int sctp_over_udp_start(void);
#endif #endif
#if defined(__Windows__) #if defined(_WIN32) && !defined(__Userspace__)
void sctp_over_udp_restart(void); void sctp_over_udp_restart(void);
#endif #endif
@ -368,7 +361,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); void sctp_log_nagle_event(struct sctp_tcb *stcb, int action);
#ifdef SCTP_MBUF_LOGGING #ifdef SCTP_MBUF_LOGGING
void void
sctp_log_mb(struct mbuf *m, int from); sctp_log_mb(struct mbuf *m, int from);
@ -392,7 +384,7 @@ void sctp_log_closing(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int16_t loc
void sctp_log_lock(struct sctp_inpcb *inp, struct sctp_tcb *stcb, uint8_t from); void sctp_log_lock(struct sctp_inpcb *inp, struct sctp_tcb *stcb, uint8_t from);
void sctp_log_maxburst(struct sctp_tcb *stcb, struct sctp_nets *, int, int, uint8_t); void sctp_log_maxburst(struct sctp_tcb *stcb, struct sctp_nets *, int, int, uint8_t);
void sctp_log_block(uint8_t, struct sctp_association *, int); void sctp_log_block(uint8_t, struct sctp_association *, ssize_t);
void sctp_log_rwnd(uint8_t, uint32_t, uint32_t, uint32_t); void sctp_log_rwnd(uint8_t, uint32_t, uint32_t, uint32_t);
void sctp_log_rwnd_set(uint8_t, uint32_t, uint32_t, uint32_t, uint32_t); void sctp_log_rwnd_set(uint8_t, uint32_t, uint32_t, uint32_t, uint32_t);
int sctp_fill_stat_log(void *, size_t *); int sctp_fill_stat_log(void *, size_t *);
@ -402,7 +394,6 @@ void sctp_log_map(uint32_t, uint32_t, uint32_t, int);
void sctp_print_mapping_array(struct sctp_association *asoc); void sctp_print_mapping_array(struct sctp_association *asoc);
void sctp_clr_stat_log(void); void sctp_clr_stat_log(void);
#ifdef SCTP_AUDITING_ENABLED #ifdef SCTP_AUDITING_ENABLED
void void
sctp_auditing(int, struct sctp_inpcb *, struct sctp_tcb *, sctp_auditing(int, struct sctp_inpcb *, struct sctp_tcb *,
@ -410,5 +401,17 @@ sctp_auditing(int, struct sctp_inpcb *, struct sctp_tcb *,
void sctp_audit_log(uint8_t, uint8_t); void sctp_audit_log(uint8_t, uint8_t);
#endif #endif
uint32_t sctp_min_mtu(uint32_t, uint32_t, uint32_t);
#if defined(__FreeBSD__) && !defined(__Userspace__)
void sctp_hc_set_mtu(union sctp_sockstore *, uint16_t, uint32_t);
uint32_t sctp_hc_get_mtu(union sctp_sockstore *, uint16_t);
#endif
void sctp_set_state(struct sctp_tcb *, int);
void sctp_add_substate(struct sctp_tcb *, int);
uint32_t sctp_ticks_to_msecs(uint32_t);
uint32_t sctp_msecs_to_ticks(uint32_t);
uint32_t sctp_ticks_to_secs(uint32_t);
uint32_t sctp_secs_to_ticks(uint32_t);
#endif /* _KERNEL */ #endif /* _KERNEL */
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,6 @@
/*- /*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@ -30,9 +32,9 @@
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_var.h 243186 2012-11-17 20:04:04Z tuexen $"); __FBSDID("$FreeBSD: head/sys/netinet6/sctp6_var.h 317457 2017-04-26 19:26:40Z tuexen $");
#endif #endif
#ifndef _NETINET6_SCTP6_VAR_H_ #ifndef _NETINET6_SCTP6_VAR_H_
@ -42,47 +44,38 @@ __FBSDID("$FreeBSD: head/sys/netinet6/sctp6_var.h 243186 2012-11-17 20:04:04Z tu
#ifdef INET #ifdef INET
extern void in6_sin6_2_sin(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 *); extern void in6_sin6_2_sin_in_sock(struct sockaddr *);
extern void in6_sin_2_v4mapsin6(struct sockaddr_in *, struct sockaddr_in6 *); extern void in6_sin_2_v4mapsin6(const struct sockaddr_in *, struct sockaddr_in6 *);
#endif #endif
#endif #endif
#if defined(_KERNEL) #if defined(_KERNEL)
#if defined(__FreeBSD__) || (__APPLE__) || defined(__Windows__) #if !defined(__Userspace__)
SYSCTL_DECL(_net_inet6_sctp6); SYSCTL_DECL(_net_inet6_sctp6);
extern struct pr_usrreqs sctp6_usrreqs; extern struct pr_usrreqs sctp6_usrreqs;
#else #else
int sctp6_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *); int sctp6_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *);
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(__Userspace__)
int sctp6_input(struct mbuf **, int *); int sctp6_input(struct mbuf **, int *);
int sctp6_input_with_port(struct mbuf **, int *, uint16_t); int sctp6_input_with_port(struct mbuf **, int *, uint16_t);
#elif defined(__Panda__)
int sctp6_input (pakhandle_type *);
#elif defined(__FreeBSD__) && __FreeBSD_version < 902000
int sctp6_input __P((struct mbuf **, int *, int));
int sctp6_input_with_port __P((struct mbuf **, int *, uint16_t));
#else #else
int sctp6_input(struct mbuf **, int *, int); int sctp6_input(struct mbuf **, int *, int);
int sctp6_input_with_port(struct mbuf **, int *, uint16_t); int sctp6_input_with_port(struct mbuf **, int *, uint16_t);
#endif #endif
#if defined(__FreeBSD__) && __FreeBSD_version < 902000
int sctp6_output
__P((struct sctp_inpcb *, struct mbuf *, struct sockaddr *,
struct mbuf *, struct proc *));
void sctp6_ctlinput __P((int, struct sockaddr *, void *));
#else
int sctp6_output(struct sctp_inpcb *, struct mbuf *, struct sockaddr *, int sctp6_output(struct sctp_inpcb *, struct mbuf *, struct sockaddr *,
struct mbuf *, struct proc *); struct mbuf *, struct proc *);
#if defined(__APPLE__) && !defined(__Userspace__) && !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION) && !defined(APPLE_ELCAPITAN)
void sctp6_ctlinput(int, struct sockaddr *, void *, struct ifnet * SCTP_UNUSED);
#else
void sctp6_ctlinput(int, struct sockaddr *, void *); void sctp6_ctlinput(int, struct sockaddr *, void *);
#endif #endif
#if !(defined(__FreeBSD__) || defined(__APPLE__)) #if !((defined(__FreeBSD__) || defined(__APPLE__)) && !defined(__Userspace__))
extern void in6_sin_2_v4mapsin6(struct sockaddr_in *, struct sockaddr_in6 *); 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(struct sockaddr_in *, struct sockaddr_in6 *);
extern void in6_sin6_2_sin_in_sock(struct sockaddr *); extern void in6_sin6_2_sin_in_sock(struct sockaddr *);
#endif #endif
extern void sctp6_notify(struct sctp_inpcb *, struct icmp6_hdr *, void sctp6_notify(struct sctp_inpcb *, struct sctp_tcb *, struct sctp_nets *,
struct sctphdr *, struct sockaddr *, uint8_t, uint8_t, uint32_t);
struct sctp_tcb *, struct sctp_nets *);
#endif #endif
#endif #endif

View file

@ -42,8 +42,8 @@
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#if defined(__Userspace_os_Darwin) || defined (__Userspace_os_Windows) #if defined(__APPLE__) || defined(_WIN32)
#if defined (__Userspace_os_Windows) #if defined(_WIN32)
#define atomic_add_int(addr, val) InterlockedExchangeAdd((LPLONG)addr, (LONG)val) #define atomic_add_int(addr, val) InterlockedExchangeAdd((LPLONG)addr, (LONG)val)
#define atomic_fetchadd_int(addr, val) InterlockedExchangeAdd((LPLONG)addr, (LONG)val) #define atomic_fetchadd_int(addr, val) InterlockedExchangeAdd((LPLONG)addr, (LONG)val)
#define atomic_subtract_int(addr, val) InterlockedExchangeAdd((LPLONG)addr,-((LONG)val)) #define atomic_subtract_int(addr, val) InterlockedExchangeAdd((LPLONG)addr,-((LONG)val))
@ -76,11 +76,11 @@
*addr = 0; \ *addr = 0; \
} \ } \
} }
#if defined(__Userspace_os_Windows)
static void atomic_init() {} /* empty when we are not using atomic_mtx */
#else
static inline void atomic_init() {} /* empty when we are not using atomic_mtx */
#endif #endif
#if defined(_WIN32)
static void atomic_init(void) {} /* empty when we are not using atomic_mtx */
#else
static inline void atomic_init(void) {} /* empty when we are not using atomic_mtx */
#endif #endif
#else #else
@ -132,7 +132,7 @@ static inline void atomic_init() {} /* empty when we are not using atomic_mtx */
} \ } \
} }
#endif #endif
static inline void atomic_init() {} /* empty when we are not using atomic_mtx */ static inline void atomic_init(void) {} /* empty when we are not using atomic_mtx */
#endif #endif
#if 0 /* using libatomic_ops */ #if 0 /* using libatomic_ops */
@ -173,7 +173,7 @@ static inline void atomic_init() {} /* empty when we are not using atomic_mtx */
extern userland_mutex_t atomic_mtx; extern userland_mutex_t atomic_mtx;
#if defined (__Userspace_os_Windows) #if defined(_WIN32)
static inline void atomic_init() { static inline void atomic_init() {
InitializeCriticalSection(&atomic_mtx); InitializeCriticalSection(&atomic_mtx);
} }
@ -188,16 +188,31 @@ static inline void atomic_unlock() {
} }
#else #else
static inline void atomic_init() { static inline void atomic_init() {
(void)pthread_mutex_init(&atomic_mtx, NULL); pthread_mutexattr_t mutex_attr;
pthread_mutexattr_init(&mutex_attr);
#ifdef INVARIANTS
pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
pthread_mutex_init(&accept_mtx, &mutex_attr);
pthread_mutexattr_destroy(&mutex_attr);
} }
static inline void atomic_destroy() { static inline void atomic_destroy() {
(void)pthread_mutex_destroy(&atomic_mtx); (void)pthread_mutex_destroy(&atomic_mtx);
} }
static inline void atomic_lock() { static inline void atomic_lock() {
#ifdef INVARIANTS
KASSERT(pthread_mutex_lock(&atomic_mtx) == 0, ("atomic_lock: atomic_mtx already locked"))
#else
(void)pthread_mutex_lock(&atomic_mtx); (void)pthread_mutex_lock(&atomic_mtx);
#endif
} }
static inline void atomic_unlock() { static inline void atomic_unlock() {
#ifdef INVARIANTS
KASSERT(pthread_mutex_unlock(&atomic_mtx) == 0, ("atomic_unlock: atomic_mtx not locked"))
#else
(void)pthread_mutex_unlock(&atomic_mtx); (void)pthread_mutex_unlock(&atomic_mtx);
#endif
} }
#endif #endif
/* /*

View file

@ -30,18 +30,23 @@
/* __Userspace__ */ /* __Userspace__ */
#include <stdlib.h> #if defined(_WIN32)
#if !defined (__Userspace_os_Windows) #if !defined(_CRT_RAND_S) && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
#define _CRT_RAND_S
#endif
#else
#include <stdint.h> #include <stdint.h>
#include <netinet/sctp_os_userspace.h> #include <netinet/sctp_os_userspace.h>
#endif #endif
#ifdef INVARIANTS
#include <netinet/sctp_pcb.h>
#endif
#include <user_environment.h> #include <user_environment.h>
#include <sys/types.h> #include <sys/types.h>
/* #include <sys/param.h> defines MIN */ /* #include <sys/param.h> defines MIN */
#if !defined(MIN) #if !defined(MIN)
#define MIN(arg1,arg2) ((arg1) < (arg2) ? (arg1) : (arg2)) #define MIN(arg1,arg2) ((arg1) < (arg2) ? (arg1) : (arg2))
#endif #endif
#include <string.h>
#define uHZ 1000 #define uHZ 1000
@ -60,37 +65,320 @@ u_short ip_id = 0; /*__Userspace__ TODO Should it be initialized to zero? */
*/ */
userland_mutex_t atomic_mtx; userland_mutex_t atomic_mtx;
/* Source: /usr/src/sys/dev/random/harvest.c */
static int read_random_phony(void *, int);
static int (*read_func)(void *, int) = read_random_phony;
/* Userland-visible version of read_random */
int
read_random(void *buf, int count)
{
return ((*read_func)(buf, count));
}
/* If the entropy device is not loaded, make a token effort to /* If the entropy device is not loaded, make a token effort to
* provide _some_ kind of randomness. This should only be used * provide _some_ kind of randomness. This should only be used
* inside other RNG's, like arc4random(9). * inside other RNG's, like arc4random(9).
*/ */
static int #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
read_random_phony(void *buf, int count) #include <string.h>
void
init_random(void)
{ {
uint32_t randval; return;
int size, i;
/* srandom() is called in kern/init_main.c:proc0_post() */
/* 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); void
read_random(void *buf, size_t size)
{
memset(buf, 'A', size);
return;
} }
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;
}
void
read_random(void *buf, size_t size)
{
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;
}
void
finish_random(void)
{
return;
}
#elif (defined(__ANDROID__) && (__ANDROID_API__ < 28)) || 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
#error "Unknown platform. Please provide platform specific RNG."
#endif

View file

@ -33,12 +33,12 @@
/* __Userspace__ */ /* __Userspace__ */
#include <sys/types.h> #include <sys/types.h>
#ifdef __Userspace_os_FreeBSD #ifdef __FreeBSD__
#ifndef _SYS_MUTEX_H_ #ifndef _SYS_MUTEX_H_
#include <sys/mutex.h> #include <sys/mutex.h>
#endif #endif
#endif #endif
#if defined (__Userspace_os_Windows) #if defined(_WIN32)
#include "netinet/sctp_os_userspace.h" #include "netinet/sctp_os_userspace.h"
#endif #endif
@ -54,7 +54,7 @@ extern int maxsockets;
extern int hz; extern int hz;
/* The following two ints define a range of available ephermal ports. */ /* The following two ints define a range of available ephemeral ports. */
extern int ipport_firstauto, ipport_lastauto; extern int ipport_firstauto, ipport_lastauto;
/* nmbclusters is used in sctp_usrreq.c (e.g., sctp_init). In the FreeBSD kernel, /* nmbclusters is used in sctp_usrreq.c (e.g., sctp_init). In the FreeBSD kernel,
@ -62,12 +62,14 @@ extern int ipport_firstauto, ipport_lastauto;
*/ */
extern int nmbclusters; extern int nmbclusters;
#if !defined (__Userspace_os_Windows) #if !defined(_MSC_VER) && !defined(__MINGW32__)
#define min(a,b) ((a)>(b)?(b):(a)) #define min(a,b) (((a)>(b))?(b):(a))
#define max(a,b) ((a)>(b)?(a):(b)) #define max(a,b) (((a)>(b))?(a):(b))
#endif #endif
extern int read_random(void *buf, int count); void init_random(void);
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 */ /* errno's may differ per OS. errno.h now included in sctp_os_userspace.h */
/* Source: /usr/src/sys/sys/errno.h */ /* Source: /usr/src/sys/sys/errno.h */
@ -82,23 +84,34 @@ extern int read_random(void *buf, int count);
/* Source ip_output.c. extern'd in ip_var.h */ /* Source ip_output.c. extern'd in ip_var.h */
extern u_short ip_id; extern u_short ip_id;
#if defined(__Userspace_os_Linux) #if defined(__linux__)
#define IPV6_VERSION 0x60 #define IPV6_VERSION 0x60
#endif #endif
#if defined(INVARIANTS)
#define panic(args...) \
do { \
SCTP_PRINTF(args);\
exit(1); \
} while (0)
#endif
#if defined(INVARIANTS) #if defined(INVARIANTS)
#include <stdlib.h>
#if defined(_WIN32)
static inline void __declspec(noreturn)
#else
static inline void __attribute__((__noreturn__))
#endif
terminate_non_graceful(void) {
abort();
}
#define panic(...) \
do { \
SCTP_PRINTF("%s(): ", __func__); \
SCTP_PRINTF(__VA_ARGS__); \
SCTP_PRINTF("\n"); \
terminate_non_graceful(); \
} while (0)
#define KASSERT(cond, args) \ #define KASSERT(cond, args) \
do { \ do { \
if (!(cond)) { \ if (!(cond)) { \
printf args ;\ panic args ; \
exit(1); \
} \ } \
} while (0) } while (0)
#else #else

View file

@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -35,8 +35,6 @@
#include <user_route.h> /* was <net/route.h> */ #include <user_route.h> /* was <net/route.h> */
#define in6pcb inpcb /* for KAME src sync over BSD*'s */
#define in6p_sp inp_sp /* for KAME src sync over BSD*'s */
struct inpcbpolicy; struct inpcbpolicy;
/* /*
@ -56,7 +54,7 @@ LIST_HEAD(inpcbporthead, inpcbport);
* the following structure. * the following structure.
*/ */
struct in_addr_4in6 { struct in_addr_4in6 {
u_int32_t ia46_pad32[3]; uint32_t ia46_pad32[3];
struct in_addr ia46_addr4; struct in_addr ia46_addr4;
}; };
@ -65,8 +63,8 @@ struct in_addr_4in6 {
* some extra padding to accomplish this. * some extra padding to accomplish this.
*/ */
struct in_endpoints { struct in_endpoints {
u_int16_t ie_fport; /* foreign port */ uint16_t ie_fport; /* foreign port */
u_int16_t ie_lport; /* local port */ uint16_t ie_lport; /* local port */
/* protocol dependent part, local and foreign addr */ /* protocol dependent part, local and foreign addr */
union { union {
/* foreign host table entry */ /* foreign host table entry */
@ -89,13 +87,13 @@ struct in_endpoints {
* references. * references.
*/ */
struct in_conninfo { struct in_conninfo {
u_int8_t inc_flags; uint8_t inc_flags;
u_int8_t inc_len; uint8_t inc_len;
u_int16_t inc_pad; /* XXX alignment for in_endpoints */ uint16_t inc_pad; /* XXX alignment for in_endpoints */
/* protocol dependent part */ /* protocol dependent part */
struct in_endpoints inc_ie; struct in_endpoints inc_ie;
}; };
#define inc_isipv6 inc_flags /* temp compatability */ #define inc_isipv6 inc_flags /* temp compatibility */
#define inc_fport inc_ie.ie_fport #define inc_fport inc_ie.ie_fport
#define inc_lport inc_ie.ie_lport #define inc_lport inc_ie.ie_lport
#define inc_faddr inc_ie.ie_faddr #define inc_faddr inc_ie.ie_faddr
@ -112,7 +110,7 @@ struct inpcb {
struct inpcbinfo *inp_pcbinfo; /* PCB list info */ struct inpcbinfo *inp_pcbinfo; /* PCB list info */
struct socket *inp_socket; /* back pointer to socket */ struct socket *inp_socket; /* back pointer to socket */
u_int32_t inp_flow; uint32_t inp_flow;
int inp_flags; /* generic IP/datagram flags */ int inp_flags; /* generic IP/datagram flags */
u_char inp_vflag; /* IP version flag (v4/v6) */ u_char inp_vflag; /* IP version flag (v4/v6) */
@ -326,13 +324,11 @@ struct inpcbinfo {
#define INPLOOKUP_WILDCARD 1 #define INPLOOKUP_WILDCARD 1
#define sotoinpcb(so) ((struct inpcb *)(so)->so_pcb) #define sotoinpcb(so) ((struct inpcb *)(so)->so_pcb)
#define sotoin6pcb(so) sotoinpcb(so) /* for KAME src sync over BSD*'s */
#define INP_SOCKAF(so) so->so_proto->pr_domain->dom_family #define INP_SOCKAF(so) so->so_proto->pr_domain->dom_family
#define INP_CHECK_SOCKAF(so, af) (INP_SOCKAF(so) == af) #define INP_CHECK_SOCKAF(so, af) (INP_SOCKAF(so) == af)
/* #ifdef _KERNEL */
extern int ipport_reservedhigh; extern int ipport_reservedhigh;
extern int ipport_reservedlow; extern int ipport_reservedlow;
extern int ipport_lowfirstauto; extern int ipport_lowfirstauto;
@ -373,6 +369,5 @@ void ipport_tick(void *xtp);
*/ */
void db_print_inpcb(struct inpcb *inp, const char *name, int indent); void db_print_inpcb(struct inpcb *inp, const char *name, int indent);
/* #endif _KERNEL */
#endif /* !_NETINET_IN_PCB_H_ */ #endif /* !_NETINET_IN_PCB_H_ */

View file

@ -39,7 +39,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -60,16 +60,16 @@
#ifndef _USER_IP6_VAR_H_ #ifndef _USER_IP6_VAR_H_
#define _USER_IP6_VAR_H_ #define _USER_IP6_VAR_H_
#if defined(__Userspace_os_Windows) #if defined(_WIN32)
struct ip6_hdr { struct ip6_hdr {
union { union {
struct ip6_hdrctl { struct ip6_hdrctl {
u_int32_t ip6_un1_flow; /* 20 bits of flow-ID */ uint32_t ip6_un1_flow; /* 20 bits of flow-ID */
u_int16_t ip6_un1_plen; /* payload length */ uint16_t ip6_un1_plen; /* payload length */
u_int8_t ip6_un1_nxt; /* next header */ uint8_t ip6_un1_nxt; /* next header */
u_int8_t ip6_un1_hlim; /* hop limit */ uint8_t ip6_un1_hlim; /* hop limit */
} ip6_un1; } ip6_un1;
u_int8_t ip6_un2_vfc; /* 4 bits version, top 4 bits class */ uint8_t ip6_un2_vfc; /* 4 bits version, top 4 bits class */
} ip6_ctlun; } ip6_ctlun;
struct in6_addr ip6_src; /* source address */ struct in6_addr ip6_src; /* source address */
struct in6_addr ip6_dst; /* destination address */ struct in6_addr ip6_dst; /* destination address */
@ -84,18 +84,16 @@ struct ip6_hdr {
#define IPV6_VERSION 0x60 #define IPV6_VERSION 0x60
#endif #endif
#if defined(__Userspace_os_Windows) #if defined(_WIN32)
#define s6_addr16 u.Word #define s6_addr16 u.Word
#endif #endif
#if !defined(__Userspace_os_Windows) #if !defined(_WIN32) && !defined(__linux__) && !defined(__EMSCRIPTEN__)
#if !defined(__Userspace_os_Linux)
#define s6_addr8 __u6_addr.__u6_addr8 #define s6_addr8 __u6_addr.__u6_addr8
#define s6_addr16 __u6_addr.__u6_addr16 #define s6_addr16 __u6_addr.__u6_addr16
#define s6_addr32 __u6_addr.__u6_addr32 #define s6_addr32 __u6_addr.__u6_addr32
#endif #endif
#endif
#if !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_OpenBSD) && !defined(__Userspace_os_DragonFly) #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__)
struct route_in6 { struct route_in6 {
struct rtentry *ro_rt; struct rtentry *ro_rt;
struct llentry *ro_lle; struct llentry *ro_lle;

View file

@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -40,8 +40,8 @@
* Internal of an ICMP Router Advertisement * Internal of an ICMP Router Advertisement
*/ */
struct icmp_ra_addr { struct icmp_ra_addr {
u_int32_t ira_addr; uint32_t ira_addr;
u_int32_t ira_preference; uint32_t ira_preference;
}; };
/* /*
@ -53,19 +53,19 @@ struct icmphdr {
u_short icmp_cksum; /* ones complement cksum of struct */ u_short icmp_cksum; /* ones complement cksum of struct */
}; };
#if defined(__Userspace_os_Windows) #if defined(_WIN32)
#pragma pack (push, 1) #pragma pack (push, 1)
struct icmp6_hdr { struct icmp6_hdr {
u_int8_t icmp6_type; uint8_t icmp6_type;
u_int8_t icmp6_code; uint8_t icmp6_code;
u_int16_t icmp6_cksum; uint16_t icmp6_cksum;
union { union {
u_int32_t icmp6_un_data32[1]; uint32_t icmp6_un_data32[1];
u_int16_t icmp6_un_data16[2]; uint16_t icmp6_un_data16[2];
u_int8_t icmp6_un_data8[4]; uint8_t icmp6_un_data8[4];
} icmp6_dataun; } icmp6_dataun;
}; };
#pragma pack() #pragma pack(pop)
#define icmp6_data32 icmp6_dataun.icmp6_un_data32 #define icmp6_data32 icmp6_dataun.icmp6_un_data32
#define icmp6_mtu icmp6_data32[0] #define icmp6_mtu icmp6_data32[0]
@ -98,7 +98,7 @@ struct icmp {
struct ih_rtradv { struct ih_rtradv {
u_char irt_num_addrs; u_char irt_num_addrs;
u_char irt_wpa; u_char irt_wpa;
u_int16_t irt_lifetime; uint16_t irt_lifetime;
} ih_rtradv; } ih_rtradv;
} icmp_hun; } icmp_hun;
#define icmp_pptr icmp_hun.ih_pptr #define icmp_pptr icmp_hun.ih_pptr
@ -126,7 +126,7 @@ struct icmp {
/* options and then 64 bits of data */ /* options and then 64 bits of data */
} id_ip; } id_ip;
struct icmp_ra_addr id_radv; struct icmp_ra_addr id_radv;
u_int32_t id_mask; uint32_t id_mask;
char id_data[1]; char id_data[1];
} icmp_dun; } icmp_dun;
#define icmp_otime icmp_dun.id_ts.its_otime #define icmp_otime icmp_dun.id_ts.its_otime

View file

@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -37,11 +37,11 @@
/*__Userspace__*/ /*__Userspace__*/
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
#if !defined (__Userspace_os_Windows) #if !defined(_WIN32)
#include <strings.h> #include <strings.h>
#include <stdint.h> #include <stdint.h>
#else #else
#if defined(_MSC_VER) && _MSC_VER >= 1600 #if (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__MSVCRT_VERSION__) && __MSVCRT_VERSION__ >= 1400)
#include <stdint.h> #include <stdint.h>
#elif defined(SCTP_STDINT_INCLUDE) #elif defined(SCTP_STDINT_INCLUDE)
#include SCTP_STDINT_INCLUDE #include SCTP_STDINT_INCLUDE
@ -200,67 +200,4 @@ Start copy: Copied code for __Userspace__ */
} \ } \
} while (0); } while (0);
/* End copy: Copied code for __Userspace__ */
#if 0
#ifdef _KERNEL
#define MALLOC_DEFINE(type, shortdesc, longdesc) \
struct malloc_type type[1] = { \
{ NULL, 0, 0, 0, 0, 0, M_MAGIC, shortdesc, NULL, NULL, \
NULL, 0, NULL, NULL, 0, 0 } \
}; \
SYSINIT(type##_init, SI_SUB_KMEM, SI_ORDER_SECOND, malloc_init, \
type); \
SYSUNINIT(type##_uninit, SI_SUB_KMEM, SI_ORDER_ANY, \
malloc_uninit, type)
#define MALLOC_DECLARE(type) \
extern struct malloc_type type[1]
MALLOC_DECLARE(M_CACHE);
MALLOC_DECLARE(M_DEVBUF);
MALLOC_DECLARE(M_TEMP);
MALLOC_DECLARE(M_IP6OPT); /* for INET6 */
MALLOC_DECLARE(M_IP6NDP); /* for INET6 */
/*
* Deprecated macro versions of not-quite-malloc() and free().
*/
#define MALLOC(space, cast, size, type, flags) \
((space) = (cast)malloc((u_long)(size), (type), (flags)))
#define FREE(addr, type) free((addr), (type))
/*
* XXX this should be declared in <sys/uio.h>, but that tends to fail
* because <sys/uio.h> is included in a header before the source file
* has a chance to include <sys/malloc.h> to get MALLOC_DECLARE() defined.
*/
MALLOC_DECLARE(M_IOV);
extern struct mtx malloc_mtx;
/* XXX struct malloc_type is unused for contig*(). */
void contigfree(void *addr, unsigned long size, struct malloc_type *type);
void *contigmalloc(unsigned long size, struct malloc_type *type, int flags,
vm_paddr_t low, vm_paddr_t high, unsigned long alignment,
unsigned long boundary);
void free(void *addr, struct malloc_type *type);
void *malloc(unsigned long size, struct malloc_type *type, int flags);
void malloc_init(void *);
int malloc_last_fail(void);
void malloc_type_allocated(struct malloc_type *type, unsigned long size);
void malloc_type_freed(struct malloc_type *type, unsigned long size);
void malloc_uninit(void *);
void *realloc(void *addr, unsigned long size, struct malloc_type *type,
int flags);
void *reallocf(void *addr, unsigned long size, struct malloc_type *type,
int flags);
#endif /* _KERNEL */
#endif
#endif /* !_SYS_MALLOC_H_ */ #endif /* !_SYS_MALLOC_H_ */

View file

@ -46,7 +46,6 @@
#include "user_atomic.h" #include "user_atomic.h"
#include "netinet/sctp_pcb.h" #include "netinet/sctp_pcb.h"
struct mbstat mbstat;
#define KIPC_MAX_LINKHDR 4 /* int: max length of link header (see sys/sysclt.h) */ #define KIPC_MAX_LINKHDR 4 /* int: max length of link header (see sys/sysclt.h) */
#define KIPC_MAX_PROTOHDR 5 /* int: max length of network header (see sys/sysclt.h)*/ #define KIPC_MAX_PROTOHDR 5 /* int: max length of network header (see sys/sysclt.h)*/
int max_linkhdr = KIPC_MAX_LINKHDR; int max_linkhdr = KIPC_MAX_LINKHDR;
@ -121,7 +120,7 @@ m_get(int how, short type)
mbuf_mb_args.type = type; mbuf_mb_args.type = type;
#endif #endif
/* Mbuf master zone, zone_mbuf, has already been /* Mbuf master zone, zone_mbuf, has already been
* created in mbuf_init() */ * created in mbuf_initialize() */
mret = SCTP_ZONE_GET(zone_mbuf, struct mbuf); mret = SCTP_ZONE_GET(zone_mbuf, struct mbuf);
#if defined(SCTP_SIMPLE_ALLOCATOR) #if defined(SCTP_SIMPLE_ALLOCATOR)
mb_ctor_mbuf(mret, &mbuf_mb_args, 0); mb_ctor_mbuf(mret, &mbuf_mb_args, 0);
@ -204,26 +203,29 @@ m_free(struct mbuf *m)
} }
static int clust_constructor_dup(caddr_t m_clust, struct mbuf* m) static void
clust_constructor_dup(caddr_t m_clust, struct mbuf* m)
{ {
u_int *refcnt; u_int *refcnt;
int type, size; int type, size;
if (m == NULL) {
return;
}
/* Assigning cluster of MCLBYTES. TODO: Add jumbo frame functionality */ /* Assigning cluster of MCLBYTES. TODO: Add jumbo frame functionality */
type = EXT_CLUSTER; type = EXT_CLUSTER;
size = MCLBYTES; size = MCLBYTES;
refcnt = SCTP_ZONE_GET(zone_ext_refcnt, u_int); refcnt = SCTP_ZONE_GET(zone_ext_refcnt, u_int);
/*refcnt = (u_int *)umem_cache_alloc(zone_ext_refcnt, UMEM_DEFAULT);*/ /*refcnt = (u_int *)umem_cache_alloc(zone_ext_refcnt, UMEM_DEFAULT);*/
if (refcnt == NULL) {
#if !defined(SCTP_SIMPLE_ALLOCATOR) #if !defined(SCTP_SIMPLE_ALLOCATOR)
if (refcnt == NULL) {
umem_reap(); umem_reap();
#endif
refcnt = SCTP_ZONE_GET(zone_ext_refcnt, u_int); refcnt = SCTP_ZONE_GET(zone_ext_refcnt, u_int);
/*refcnt = (u_int *)umem_cache_alloc(zone_ext_refcnt, UMEM_DEFAULT);*/ /*refcnt = (u_int *)umem_cache_alloc(zone_ext_refcnt, UMEM_DEFAULT);*/
} }
#endif
*refcnt = 1; *refcnt = 1;
if (m != NULL) {
m->m_ext.ext_buf = (caddr_t)m_clust; m->m_ext.ext_buf = (caddr_t)m_clust;
m->m_data = m->m_ext.ext_buf; m->m_data = m->m_ext.ext_buf;
m->m_flags |= M_EXT; m->m_flags |= M_EXT;
@ -232,12 +234,9 @@ static int clust_constructor_dup(caddr_t m_clust, struct mbuf* m)
m->m_ext.ext_size = size; m->m_ext.ext_size = size;
m->m_ext.ext_type = type; m->m_ext.ext_type = type;
m->m_ext.ref_cnt = refcnt; m->m_ext.ref_cnt = refcnt;
return;
} }
return (0);
}
/* __Userspace__ */ /* __Userspace__ */
void void
@ -245,18 +244,18 @@ m_clget(struct mbuf *m, int how)
{ {
caddr_t mclust_ret; caddr_t mclust_ret;
#if defined(SCTP_SIMPLE_ALLOCATOR) #if defined(SCTP_SIMPLE_ALLOCATOR)
struct clust_args clust_mb_args; struct clust_args clust_mb_args_l;
#endif #endif
if (m->m_flags & M_EXT) { if (m->m_flags & M_EXT) {
SCTPDBG(SCTP_DEBUG_USR, "%s: %p mbuf already has cluster\n", __func__, (void *)m); SCTPDBG(SCTP_DEBUG_USR, "%s: %p mbuf already has cluster\n", __func__, (void *)m);
} }
m->m_ext.ext_buf = (char *)NULL; m->m_ext.ext_buf = (char *)NULL;
#if defined(SCTP_SIMPLE_ALLOCATOR) #if defined(SCTP_SIMPLE_ALLOCATOR)
clust_mb_args.parent_mbuf = m; clust_mb_args_l.parent_mbuf = m;
#endif #endif
mclust_ret = SCTP_ZONE_GET(zone_clust, char); mclust_ret = SCTP_ZONE_GET(zone_clust, char);
#if defined(SCTP_SIMPLE_ALLOCATOR) #if defined(SCTP_SIMPLE_ALLOCATOR)
mb_ctor_clust(mclust_ret, &clust_mb_args, 0); mb_ctor_clust(mclust_ret, &clust_mb_args_l, 0);
#endif #endif
/*mclust_ret = umem_cache_alloc(zone_clust, UMEM_DEFAULT);*/ /*mclust_ret = umem_cache_alloc(zone_clust, UMEM_DEFAULT);*/
/* /*
@ -272,9 +271,9 @@ m_clget(struct mbuf *m, int how)
mclust_ret = SCTP_ZONE_GET(zone_clust, char); mclust_ret = SCTP_ZONE_GET(zone_clust, char);
#endif #endif
/*mclust_ret = umem_cache_alloc(zone_clust, UMEM_DEFAULT);*/ /*mclust_ret = umem_cache_alloc(zone_clust, UMEM_DEFAULT);*/
if (NULL == mclust_ret) { /* if (NULL == mclust_ret) { */
SCTPDBG(SCTP_DEBUG_USR, "Memory allocation failure in %s\n", __func__); SCTPDBG(SCTP_DEBUG_USR, "Memory allocation failure in %s\n", __func__);
} /* } */
} }
#if USING_MBUF_CONSTRUCTOR #if USING_MBUF_CONSTRUCTOR
@ -286,6 +285,166 @@ m_clget(struct mbuf *m, int how)
#endif #endif
} }
struct mbuf *
m_getm2(struct mbuf *m, int len, int how, short type, int flags, int allonebuf)
{
struct mbuf *mb, *nm = NULL, *mtail = NULL;
int size, mbuf_threshold, space_needed = len;
KASSERT(len >= 0, ("%s: len is < 0", __func__));
/* Validate flags. */
flags &= (M_PKTHDR | M_EOR);
/* Packet header mbuf must be first in chain. */
if ((flags & M_PKTHDR) && m != NULL) {
flags &= ~M_PKTHDR;
}
if (allonebuf == 0)
mbuf_threshold = SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count);
else
mbuf_threshold = 1;
/* Loop and append maximum sized mbufs to the chain tail. */
while (len > 0) {
if ((!allonebuf && len >= MCLBYTES) || (len > (int)(((mbuf_threshold - 1) * MLEN) + MHLEN))) {
mb = m_gethdr(how, type);
MCLGET(mb, how);
size = MCLBYTES;
/* SCTP_BUF_LEN(mb) = MCLBYTES; */
} else if (flags & M_PKTHDR) {
mb = m_gethdr(how, type);
if (len < MHLEN) {
size = len;
} else {
size = MHLEN;
}
} else {
mb = m_get(how, type);
if (len < MLEN) {
size = len;
} else {
size = MLEN;
}
}
/* Fail the whole operation if one mbuf can't be allocated. */
if (mb == NULL) {
if (nm != NULL)
m_freem(nm);
return (NULL);
}
if (allonebuf != 0 && size < space_needed) {
m_freem(mb);
return (NULL);
}
/* Book keeping. */
len -= size;
if (mtail != NULL)
mtail->m_next = mb;
else
nm = mb;
mtail = mb;
flags &= ~M_PKTHDR; /* Only valid on the first mbuf. */
}
if (flags & M_EOR) {
mtail->m_flags |= M_EOR; /* Only valid on the last mbuf. */
}
/* If mbuf was supplied, append new chain to the end of it. */
if (m != NULL) {
for (mtail = m; mtail->m_next != NULL; mtail = mtail->m_next);
mtail->m_next = nm;
mtail->m_flags &= ~M_EOR;
} else {
m = nm;
}
return (m);
}
/*
* Copy the contents of uio into a properly sized mbuf chain.
*/
struct mbuf *
m_uiotombuf(struct uio *uio, int how, int len, int align, int flags)
{
struct mbuf *m, *mb;
int error, length;
ssize_t total;
int progress = 0;
/*
* len can be zero or an arbitrary large value bound by
* the total data supplied by the uio.
*/
if (len > 0)
total = min(uio->uio_resid, len);
else
total = uio->uio_resid;
/*
* The smallest unit returned by m_getm2() is a single mbuf
* with pkthdr. We can't align past it.
*/
if (align >= MHLEN)
return (NULL);
/*
* Give us the full allocation or nothing.
* If len is zero return the smallest empty mbuf.
*/
m = m_getm2(NULL, (int)max(total + align, 1), how, MT_DATA, flags, 0);
if (m == NULL)
return (NULL);
m->m_data += align;
/* Fill all mbufs with uio data and update header information. */
for (mb = m; mb != NULL; mb = mb->m_next) {
length = (int)min(M_TRAILINGSPACE(mb), total - progress);
error = uiomove(mtod(mb, void *), length, uio);
if (error) {
m_freem(m);
return (NULL);
}
mb->m_len = length;
progress += length;
if (flags & M_PKTHDR)
m->m_pkthdr.len += length;
}
KASSERT(progress == total, ("%s: progress != total", __func__));
return (m);
}
u_int
m_length(struct mbuf *m0, struct mbuf **last)
{
struct mbuf *m;
u_int len;
len = 0;
for (m = m0; m != NULL; m = m->m_next) {
len += m->m_len;
if (m->m_next == NULL)
break;
}
if (last != NULL)
*last = m;
return (len);
}
struct mbuf *
m_last(struct mbuf *m)
{
while (m->m_next) {
m = m->m_next;
}
return (m);
}
/* /*
* Unlink a tag from the list of tags associated with an mbuf. * Unlink a tag from the list of tags associated with an mbuf.
*/ */
@ -313,7 +472,7 @@ m_tag_free(struct m_tag *t)
* XXX probably should be called m_tag_init, but that was already taken. * XXX probably should be called m_tag_init, but that was already taken.
*/ */
static __inline void static __inline void
m_tag_setup(struct m_tag *t, u_int32_t cookie, int type, int len) m_tag_setup(struct m_tag *t, uint32_t cookie, int type, int len)
{ {
t->m_tag_id = type; t->m_tag_id = type;
@ -327,12 +486,8 @@ m_tag_setup(struct m_tag *t, u_int32_t cookie, int type, int len)
/************ End functions to substitute umem_cache_alloc and umem_cache_free **************/ /************ End functions to substitute umem_cache_alloc and umem_cache_free **************/
/* __Userspace__
* TODO: mbuf_init must be called in the initialization routines
* of userspace stack.
*/
void void
mbuf_init(void *dummy) mbuf_initialize(void *dummy)
{ {
/* /*
@ -351,7 +506,7 @@ mbuf_init(void *dummy)
#else #else
zone_mbuf = umem_cache_create(MBUF_MEM_NAME, MSIZE, 0, zone_mbuf = umem_cache_create(MBUF_MEM_NAME, MSIZE, 0,
mb_ctor_mbuf, mb_dtor_mbuf, NULL, mb_ctor_mbuf, mb_dtor_mbuf, NULL,
NUULL, NULL,
NULL, 0); NULL, 0);
#endif #endif
/*zone_ext_refcnt = umem_cache_create(MBUF_EXTREFCNT_MEM_NAME, sizeof(u_int), 0, /*zone_ext_refcnt = umem_cache_create(MBUF_EXTREFCNT_MEM_NAME, sizeof(u_int), 0,
@ -380,26 +535,6 @@ mbuf_init(void *dummy)
* *
*/ */
/*
* [Re]set counters and local statistics knobs.
*
*/
mbstat.m_mbufs = 0;
mbstat.m_mclusts = 0;
mbstat.m_drain = 0;
mbstat.m_msize = MSIZE;
mbstat.m_mclbytes = MCLBYTES;
mbstat.m_minclsize = MINCLSIZE;
mbstat.m_mlen = MLEN;
mbstat.m_mhlen = MHLEN;
mbstat.m_numtypes = MT_NTYPES;
mbstat.m_mcfail = mbstat.m_mpfail = 0;
mbstat.sf_iocnt = 0;
mbstat.sf_allocwait = mbstat.sf_allocfail = 0;
} }
@ -732,11 +867,10 @@ m_pullup(struct mbuf *n, int len)
if (n->m_flags & M_PKTHDR) if (n->m_flags & M_PKTHDR)
M_MOVE_PKTHDR(m, n); M_MOVE_PKTHDR(m, n);
} }
space = &m->m_dat[MLEN] - (m->m_data + m->m_len); space = (int)(&m->m_dat[MLEN] - (m->m_data + m->m_len));
do { do {
count = min(min(max(len, max_protohdr), space), n->m_len); count = min(min(max(len, max_protohdr), space), n->m_len);
bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len, memcpy(mtod(m, caddr_t) + m->m_len,mtod(n, caddr_t), (u_int)count);
(u_int)count);
len -= count; len -= count;
m->m_len += count; m->m_len += count;
n->m_len -= count; n->m_len -= count;
@ -754,7 +888,6 @@ m_pullup(struct mbuf *n, int len)
return (m); return (m);
bad: bad:
m_freem(n); m_freem(n);
mbstat.m_mpfail++; /* XXX: No consistency. */
return (NULL); return (NULL);
} }
@ -890,19 +1023,17 @@ m_pulldown(struct mbuf *m, int off, int len, int *offp)
* easy cases first. * easy cases first.
* we need to use m_copydata() to get data from <n->m_next, 0>. * we need to use m_copydata() to get data from <n->m_next, 0>.
*/ */
if ((off == 0 || offp) && M_TRAILINGSPACE(n) >= tlen if ((off == 0 || offp) && (M_TRAILINGSPACE(n) >= tlen) && writable) {
&& writable) {
m_copydata(n->m_next, 0, tlen, mtod(n, caddr_t) + n->m_len); m_copydata(n->m_next, 0, tlen, mtod(n, caddr_t) + n->m_len);
n->m_len += tlen; n->m_len += tlen;
m_adj(n->m_next, tlen); m_adj(n->m_next, tlen);
goto ok; goto ok;
} }
if ((off == 0 || offp) && M_LEADINGSPACE(n->m_next) >= hlen if ((off == 0 || offp) && (M_LEADINGSPACE(n->m_next) >= hlen) && writable) {
&& writable) {
n->m_next->m_data -= hlen; n->m_next->m_data -= hlen;
n->m_next->m_len += hlen; n->m_next->m_len += hlen;
bcopy(mtod(n, caddr_t) + off, mtod(n->m_next, caddr_t), hlen); memcpy( mtod(n->m_next, caddr_t), mtod(n, caddr_t) + off,hlen);
n->m_len -= hlen; n->m_len -= hlen;
n = n->m_next; n = n->m_next;
off = 0; off = 0;
@ -924,7 +1055,7 @@ m_pulldown(struct mbuf *m, int off, int len, int *offp)
} }
/* get hlen from <n, off> into <o, 0> */ /* get hlen from <n, off> into <o, 0> */
o->m_len = hlen; o->m_len = hlen;
bcopy(mtod(n, caddr_t) + off, mtod(o, caddr_t), hlen); memcpy(mtod(o, caddr_t), mtod(n, caddr_t) + off, hlen);
n->m_len -= hlen; n->m_len -= hlen;
/* get tlen from <n->m_next, 0> into <o, hlen> */ /* get tlen from <n->m_next, 0> into <o, hlen> */
m_copydata(n->m_next, 0, tlen, mtod(o, caddr_t) + o->m_len); m_copydata(n->m_next, 0, tlen, mtod(o, caddr_t) + o->m_len);
@ -992,7 +1123,13 @@ m_copym(struct mbuf *m, int off0, int len, int wait)
KASSERT(off >= 0, ("m_copym, negative off %d", off)); KASSERT(off >= 0, ("m_copym, negative off %d", off));
KASSERT(len >= 0, ("m_copym, negative len %d", len)); KASSERT(len >= 0, ("m_copym, negative len %d", len));
KASSERT(m != NULL, ("m_copym, m is NULL"));
#if !defined(INVARIANTS)
if (m == NULL) {
return (NULL);
}
#endif
if (off == 0 && m->m_flags & M_PKTHDR) if (off == 0 && m->m_flags & M_PKTHDR)
copyhdr = 1; copyhdr = 1;
while (off > 0) { while (off > 0) {
@ -1030,21 +1167,17 @@ m_copym(struct mbuf *m, int off0, int len, int wait)
n->m_data = m->m_data + off; n->m_data = m->m_data + off;
mb_dupcl(n, m); mb_dupcl(n, m);
} else } else
bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t), memcpy(mtod(n, caddr_t), mtod(m, caddr_t) + off, (u_int)n->m_len);
(u_int)n->m_len);
if (len != M_COPYALL) if (len != M_COPYALL)
len -= n->m_len; len -= n->m_len;
off = 0; off = 0;
m = m->m_next; m = m->m_next;
np = &n->m_next; np = &n->m_next;
} }
if (top == NULL)
mbstat.m_mcfail++; /* XXX: No consistency. */
return (top); return (top);
nospace: nospace:
m_freem(top); m_freem(top);
mbstat.m_mcfail++; /* XXX: No consistency. */
return (NULL); return (NULL);
} }
@ -1080,6 +1213,8 @@ int
m_dup_pkthdr(struct mbuf *to, struct mbuf *from, int how) m_dup_pkthdr(struct mbuf *to, struct mbuf *from, int how)
{ {
KASSERT(to, ("m_dup_pkthdr: to is NULL"));
KASSERT(from, ("m_dup_pkthdr: from is NULL"));
to->m_flags = (from->m_flags & M_COPYFLAGS) | (to->m_flags & M_EXT); to->m_flags = (from->m_flags & M_COPYFLAGS) | (to->m_flags & M_EXT);
if ((to->m_flags & M_EXT) == 0) if ((to->m_flags & M_EXT) == 0)
to->m_data = to->m_pktdat; to->m_data = to->m_pktdat;
@ -1098,13 +1233,13 @@ m_tag_copy(struct m_tag *t, int how)
p = m_tag_alloc(t->m_tag_cookie, t->m_tag_id, t->m_tag_len, how); p = m_tag_alloc(t->m_tag_cookie, t->m_tag_id, t->m_tag_len, how);
if (p == NULL) if (p == NULL)
return (NULL); return (NULL);
bcopy(t + 1, p + 1, t->m_tag_len); /* Copy the data */ memcpy(p + 1, t + 1, t->m_tag_len); /* Copy the data */
return p; return p;
} }
/* Get a packet tag structure along with specified data following. */ /* Get a packet tag structure along with specified data following. */
struct m_tag * struct m_tag *
m_tag_alloc(u_int32_t cookie, int type, int len, int wait) m_tag_alloc(uint32_t cookie, int type, int len, int wait)
{ {
struct m_tag *t; struct m_tag *t;
@ -1146,7 +1281,7 @@ m_copyback(struct mbuf *m0, int off, int len, caddr_t cp)
n = m_get(M_NOWAIT, m->m_type); n = m_get(M_NOWAIT, m->m_type);
if (n == NULL) if (n == NULL)
goto out; goto out;
bzero(mtod(n, caddr_t), MLEN); memset(mtod(n, caddr_t), 0, MLEN);
n->m_len = min(MLEN, len + off); n->m_len = min(MLEN, len + off);
m->m_next = n; m->m_next = n;
} }
@ -1154,7 +1289,7 @@ m_copyback(struct mbuf *m0, int off, int len, caddr_t cp)
} }
while (len > 0) { while (len > 0) {
mlen = min (m->m_len - off, len); mlen = min (m->m_len - off, len);
bcopy(cp, off + mtod(m, caddr_t), (u_int)mlen); memcpy(off + mtod(m, caddr_t), cp, (u_int)mlen);
cp += mlen; cp += mlen;
len -= mlen; len -= mlen;
mlen += off; mlen += off;
@ -1230,7 +1365,7 @@ m_copydata(const struct mbuf *m, int off, int len, caddr_t cp)
while (len > 0) { while (len > 0) {
KASSERT(m != NULL, ("m_copydata, length > size of mbuf chain")); KASSERT(m != NULL, ("m_copydata, length > size of mbuf chain"));
count = min(m->m_len - off, len); count = min(m->m_len - off, len);
bcopy(mtod(m, caddr_t) + off, cp, count); memcpy(cp, mtod(m, caddr_t) + off, count);
len -= count; len -= count;
cp += count; cp += count;
off = 0; off = 0;
@ -1257,7 +1392,7 @@ m_cat(struct mbuf *m, struct mbuf *n)
return; return;
} }
/* splat the data from one into the other */ /* splat the data from one into the other */
bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len, (u_int)n->m_len); memcpy(mtod(m, caddr_t) + m->m_len, mtod(n, caddr_t), (u_int)n->m_len);
m->m_len += n->m_len; m->m_len += n->m_len;
n = m_free(n); n = m_free(n);
} }
@ -1400,7 +1535,7 @@ extpacket:
n->m_data = m->m_data + len; n->m_data = m->m_data + len;
mb_dupcl(n, m); mb_dupcl(n, m);
} else { } else {
bcopy(mtod(m, caddr_t) + len, mtod(n, caddr_t), remain); memcpy(mtod(n, caddr_t), mtod(m, caddr_t) + len, remain);
} }
n->m_len = remain; n->m_len = remain;
m->m_len = len; m->m_len = len;
@ -1421,7 +1556,7 @@ pack_send_buffer(caddr_t buffer, struct mbuf* mb){
do { do {
count_to_copy = mb->m_len; count_to_copy = mb->m_len;
bcopy(mtod(mb, caddr_t), buffer+offset, count_to_copy); memcpy(buffer+offset, mtod(mb, caddr_t), count_to_copy);
offset += count_to_copy; offset += count_to_copy;
total_count_copied += count_to_copy; total_count_copied += count_to_copy;
mb = mb->m_next; mb = mb->m_next;

View file

@ -55,10 +55,13 @@ struct mbuf * m_gethdr(int how, short type);
struct mbuf * m_get(int how, short type); struct mbuf * m_get(int how, short type);
struct mbuf * m_free(struct mbuf *m); struct mbuf * m_free(struct mbuf *m);
void m_clget(struct mbuf *m, int how); void m_clget(struct mbuf *m, int how);
struct mbuf * m_getm2(struct mbuf *m, int len, int how, short type, int flags, int allonebuf);
struct mbuf *m_uiotombuf(struct uio *uio, int how, int len, int align, int flags);
u_int m_length(struct mbuf *m0, struct mbuf **last);
struct mbuf *m_last(struct mbuf *m);
/* mbuf initialization function */ /* mbuf initialization function */
void mbuf_init(void *); void mbuf_initialize(void *);
#define M_MOVE_PKTHDR(to, from) m_move_pkthdr((to), (from)) #define M_MOVE_PKTHDR(to, from) m_move_pkthdr((to), (from))
#define MGET(m, how, type) ((m) = m_get((how), (type))) #define MGET(m, how, type) ((m) = m_get((how), (type)))
@ -107,7 +110,7 @@ void m_cat(struct mbuf *m, struct mbuf *n);
void m_adj(struct mbuf *, int); void m_adj(struct mbuf *, int);
void mb_free_ext(struct mbuf *); void mb_free_ext(struct mbuf *);
void m_freem(struct mbuf *); void m_freem(struct mbuf *);
struct m_tag *m_tag_alloc(u_int32_t, int, int, int); struct m_tag *m_tag_alloc(uint32_t, int, int, int);
struct mbuf *m_copym(struct mbuf *, int, int, int); struct mbuf *m_copym(struct mbuf *, int, int, int);
void m_copyback(struct mbuf *, int, int, caddr_t); void m_copyback(struct mbuf *, int, int, caddr_t);
struct mbuf *m_pullup(struct mbuf *, int); struct mbuf *m_pullup(struct mbuf *, int);
@ -125,35 +128,6 @@ void m_copydata(const struct mbuf *, int, int, caddr_t);
#define MT_NOINIT 255 /* Not a type but a flag to allocate #define MT_NOINIT 255 /* Not a type but a flag to allocate
a non-initialized mbuf */ a non-initialized mbuf */
/*
* General mbuf allocator statistics structure.
* __Userspace__ mbstat may be useful for gathering statistics.
* In the kernel many of these statistics are no longer used as
* they track allocator statistics through kernel UMA's built in statistics mechanism.
*/
struct mbstat {
u_long m_mbufs; /* XXX */
u_long m_mclusts; /* XXX */
u_long m_drain; /* times drained protocols for space */
u_long m_mcfail; /* XXX: times m_copym failed */
u_long m_mpfail; /* XXX: times m_pullup failed */
u_long m_msize; /* length of an mbuf */
u_long m_mclbytes; /* length of an mbuf cluster */
u_long m_minclsize; /* min length of data to allocate a cluster */
u_long m_mlen; /* length of data in an mbuf */
u_long m_mhlen; /* length of data in a header mbuf */
/* Number of mbtypes (gives # elems in mbtypes[] array: */
short m_numtypes;
/* XXX: Sendfile stats should eventually move to their own struct */
u_long sf_iocnt; /* times sendfile had to do disk I/O */
u_long sf_allocfail; /* times sfbuf allocation failed */
u_long sf_allocwait; /* times sfbuf allocation had to wait */
};
/* /*
* Mbufs are of a single size, MSIZE (sys/param.h), which includes overhead. * 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 * An mbuf may add a single "mbuf cluster" of size MCLBYTES (also in
@ -187,9 +161,9 @@ struct m_hdr {
*/ */
struct m_tag { struct m_tag {
SLIST_ENTRY(m_tag) m_tag_link; /* List of packet tags */ SLIST_ENTRY(m_tag) m_tag_link; /* List of packet tags */
u_int16_t m_tag_id; /* Tag ID */ uint16_t m_tag_id; /* Tag ID */
u_int16_t m_tag_len; /* Length of data */ uint16_t m_tag_len; /* Length of data */
u_int32_t m_tag_cookie; /* ABI/Module ID */ uint32_t m_tag_cookie; /* ABI/Module ID */
void (*m_tag_free)(struct m_tag *); void (*m_tag_free)(struct m_tag *);
}; };
@ -204,8 +178,8 @@ struct pkthdr {
/* variables for hardware checksum */ /* variables for hardware checksum */
int csum_flags; /* flags regarding checksum */ int csum_flags; /* flags regarding checksum */
int csum_data; /* data field used by csum routines */ int csum_data; /* data field used by csum routines */
u_int16_t tso_segsz; /* TSO segment size */ uint16_t tso_segsz; /* TSO segment size */
u_int16_t ether_vtag; /* Ethernet 802.1p+q vlan tag */ uint16_t ether_vtag; /* Ethernet 802.1p+q vlan tag */
SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */ SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */
}; };
@ -267,7 +241,6 @@ struct mbuf {
#define M_PROTO3 0x0040 /* protocol-specific */ #define M_PROTO3 0x0040 /* protocol-specific */
#define M_PROTO4 0x0080 /* protocol-specific */ #define M_PROTO4 0x0080 /* protocol-specific */
#define M_PROTO5 0x0100 /* protocol-specific */ #define M_PROTO5 0x0100 /* protocol-specific */
#define M_SKIP_FIREWALL 0x4000 /* skip firewall processing */
#define M_FREELIST 0x8000 /* mbuf is on the free list */ #define M_FREELIST 0x8000 /* mbuf is on the free list */
@ -275,7 +248,7 @@ struct mbuf {
* Flags copied when copying m_pkthdr. * Flags copied when copying m_pkthdr.
*/ */
#define M_COPYFLAGS (M_PKTHDR|M_EOR|M_RDONLY|M_PROTO1|M_PROTO1|M_PROTO2|\ #define M_COPYFLAGS (M_PKTHDR|M_EOR|M_RDONLY|M_PROTO1|M_PROTO1|M_PROTO2|\
M_PROTO3|M_PROTO4|M_PROTO5|M_SKIP_FIREWALL|\ M_PROTO3|M_PROTO4|M_PROTO5|\
M_BCAST|M_MCAST|M_FRAG|M_FIRSTFRAG|M_LASTFRAG|\ M_BCAST|M_MCAST|M_FRAG|M_FIRSTFRAG|M_LASTFRAG|\
M_VLANTAG|M_PROMISC) M_VLANTAG|M_PROMISC)
@ -350,9 +323,6 @@ void m_tag_free_default(struct m_tag *);
extern int max_linkhdr; /* Largest link-level header */ extern int max_linkhdr; /* Largest link-level header */
extern int max_protohdr; /* Size of largest protocol layer header. See user_mbuf.c */ extern int max_protohdr; /* Size of largest protocol layer header. See user_mbuf.c */
extern struct mbstat mbstat; /* General mbuf stats/infos */
/* /*
* Evaluate TRUE if it's safe to write to the mbuf m's data region (this can * Evaluate TRUE if it's safe to write to the mbuf m's data region (this can
* be both the local data payload, or an external buffer area, depending on * be both the local data payload, or an external buffer area, depending on
@ -371,9 +341,9 @@ extern struct mbstat mbstat; /* General mbuf stats/infos */
* of checking writability of the mbuf data area rests solely with the caller. * of checking writability of the mbuf data area rests solely with the caller.
*/ */
#define M_LEADINGSPACE(m) \ #define M_LEADINGSPACE(m) \
((m)->m_flags & M_EXT ? \ (((m)->m_flags & M_EXT) ? \
(M_WRITABLE(m) ? (m)->m_data - (m)->m_ext.ext_buf : 0): \ (M_WRITABLE(m) ? (m)->m_data - (m)->m_ext.ext_buf : 0): \
(m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat : \ ((m)->m_flags & M_PKTHDR)? (m)->m_data - (m)->m_pktdat : \
(m)->m_data - (m)->m_dat) (m)->m_data - (m)->m_dat)
/* /*
@ -383,7 +353,7 @@ extern struct mbstat mbstat; /* General mbuf stats/infos */
* of checking writability of the mbuf data area rests solely with the caller. * of checking writability of the mbuf data area rests solely with the caller.
*/ */
#define M_TRAILINGSPACE(m) \ #define M_TRAILINGSPACE(m) \
((m)->m_flags & M_EXT ? \ (((m)->m_flags & M_EXT) ? \
(M_WRITABLE(m) ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size \ (M_WRITABLE(m) ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size \
- ((m)->m_data + (m)->m_len) : 0) : \ - ((m)->m_data + (m)->m_len) : 0) : \
&(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len)) &(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len))
@ -435,4 +405,9 @@ extern struct mbstat mbstat; /* General mbuf stats/infos */
(m)->m_data += (MHLEN - (len)) & ~(sizeof(long) - 1); \ (m)->m_data += (MHLEN - (len)) & ~(sizeof(long) - 1); \
} while (0) } while (0)
#define M_SIZE(m) \
(((m)->m_flags & M_EXT) ? (m)->m_ext.ext_size : \
((m)->m_flags & M_PKTHDR) ? MHLEN : \
MLEN)
#endif #endif

View file

@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -144,7 +144,7 @@ struct name { \
#define SLIST_HEAD_INITIALIZER(head) \ #define SLIST_HEAD_INITIALIZER(head) \
{ NULL } { NULL }
#if defined (__Userspace_os_Windows) #if defined(_WIN32)
#if defined(SLIST_ENTRY) #if defined(SLIST_ENTRY)
#undef SLIST_ENTRY #undef SLIST_ENTRY
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *

File diff suppressed because it is too large Load diff

View file

@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -33,7 +33,7 @@
#ifndef _USER_SOCKETVAR_H_ #ifndef _USER_SOCKETVAR_H_
#define _USER_SOCKETVAR_H_ #define _USER_SOCKETVAR_H_
#if defined(__Userspace_os_Darwin) #if defined(__APPLE__)
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#endif #endif
@ -42,7 +42,7 @@
/* #include <sys/_lock.h> was 0 byte file */ /* #include <sys/_lock.h> was 0 byte file */
/* #include <sys/_mutex.h> was 0 byte file */ /* #include <sys/_mutex.h> was 0 byte file */
/* #include <sys/_sx.h> */ /*__Userspace__ alternative?*/ /* #include <sys/_sx.h> */ /*__Userspace__ alternative?*/
#if !defined(__Userspace_os_DragonFly) && !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_NetBSD) && !defined(__Userspace_os_Windows) && !defined(__Userspace_os_NaCl) #if !defined(__DragonFly__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(_WIN32) && !defined(__native_client__)
#include <sys/uio.h> #include <sys/uio.h>
#endif #endif
#define SOCK_MAXADDRLEN 255 #define SOCK_MAXADDRLEN 255
@ -54,16 +54,16 @@
#define SS_CANTRCVMORE 0x020 #define SS_CANTRCVMORE 0x020
#define SS_CANTSENDMORE 0x010 #define SS_CANTSENDMORE 0x010
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) || defined (__Userspace_os_Windows) || defined(__Userspace_os_NaCl) #if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(_WIN32) || defined(__native_client__)
#define UIO_MAXIOV 1024 #define UIO_MAXIOV 1024
#define ERESTART (-1) #define ERESTART (-1)
#endif #endif
#if !defined(__Userspace_os_Darwin) && !defined(__Userspace_os_NetBSD) && !defined(__Userspace_os_OpenBSD) #if !defined(__APPLE__) && !defined(__NetBSD__) && !defined(__OpenBSD__)
enum uio_rw { UIO_READ, UIO_WRITE }; enum uio_rw { UIO_READ, UIO_WRITE };
#endif #endif
#if !defined(__Userspace_os_NetBSD) && !defined(__Userspace_os_OpenBSD) #if !defined(__NetBSD__) && !defined(__OpenBSD__)
/* Segment flag values. */ /* Segment flag values. */
enum uio_seg { enum uio_seg {
UIO_USERSPACE, /* from user data space */ UIO_USERSPACE, /* from user data space */
@ -86,7 +86,7 @@ struct uio {
struct iovec *uio_iov; /* scatter/gather list */ struct iovec *uio_iov; /* scatter/gather list */
int uio_iovcnt; /* length of scatter/gather list */ int uio_iovcnt; /* length of scatter/gather list */
off_t uio_offset; /* offset in target object */ off_t uio_offset; /* offset in target object */
int uio_resid; /* remaining bytes to process */ ssize_t uio_resid; /* remaining bytes to process */
enum uio_seg uio_segflg; /* address space */ enum uio_seg uio_segflg; /* address space */
enum uio_rw uio_rw; /* operation */ enum uio_rw uio_rw; /* operation */
}; };
@ -100,9 +100,11 @@ struct uio {
* handle on protocol and pointer to protocol * handle on protocol and pointer to protocol
* private data and error information. * private data and error information.
*/ */
#if defined (__Userspace_os_Windows) #if defined(_WIN32)
#define AF_ROUTE 17 #define AF_ROUTE 17
#if !defined(__MINGW32__)
typedef __int32 pid_t; typedef __int32 pid_t;
#endif
typedef unsigned __int32 uid_t; typedef unsigned __int32 uid_t;
enum sigType { enum sigType {
SIGNAL = 0, SIGNAL = 0,
@ -235,7 +237,7 @@ struct socket {
* avoid defining a lock order between listen and accept sockets * avoid defining a lock order between listen and accept sockets
* until such time as it proves to be a good idea. * until such time as it proves to be a good idea.
*/ */
#if defined(__Userspace_os_Windows) #if defined(_WIN32)
extern userland_mutex_t accept_mtx; extern userland_mutex_t accept_mtx;
extern userland_cond_t accept_cond; extern userland_cond_t accept_cond;
#define ACCEPT_LOCK_ASSERT() #define ACCEPT_LOCK_ASSERT()
@ -248,10 +250,17 @@ extern userland_cond_t accept_cond;
#define ACCEPT_UNLOCK_ASSERT() #define ACCEPT_UNLOCK_ASSERT()
#else #else
extern userland_mutex_t accept_mtx; extern userland_mutex_t accept_mtx;
extern userland_cond_t accept_cond; extern userland_cond_t accept_cond;
#define ACCEPT_LOCK_ASSERT() KASSERT(pthread_mutex_trylock(&accept_mtx) == EBUSY, ("%s: accept_mtx not locked", __func__)) #ifdef INVARIANTS
#define ACCEPT_LOCK() KASSERT(pthread_mutex_lock(&accept_mtx) == 0, ("%s: accept_mtx already locked", __func__))
#define ACCEPT_UNLOCK() KASSERT(pthread_mutex_unlock(&accept_mtx) == 0, ("%s: accept_mtx not locked", __func__))
#else
#define ACCEPT_LOCK() (void)pthread_mutex_lock(&accept_mtx) #define ACCEPT_LOCK() (void)pthread_mutex_lock(&accept_mtx)
#define ACCEPT_UNLOCK() (void)pthread_mutex_unlock(&accept_mtx) #define ACCEPT_UNLOCK() (void)pthread_mutex_unlock(&accept_mtx)
#endif
#define ACCEPT_LOCK_ASSERT() \
KASSERT(pthread_mutex_trylock(&accept_mtx) == EBUSY, ("%s: accept_mtx not locked", __func__))
#define ACCEPT_UNLOCK_ASSERT() do { \ #define ACCEPT_UNLOCK_ASSERT() do { \
KASSERT(pthread_mutex_trylock(&accept_mtx) == 0, ("%s: accept_mtx locked", __func__)); \ KASSERT(pthread_mutex_trylock(&accept_mtx) == 0, ("%s: accept_mtx locked", __func__)); \
(void)pthread_mutex_unlock(&accept_mtx); \ (void)pthread_mutex_unlock(&accept_mtx); \
@ -263,7 +272,7 @@ extern userland_cond_t accept_cond;
* buffer. * buffer.
*/ */
#define SOCKBUF_MTX(_sb) (&(_sb)->sb_mtx) #define SOCKBUF_MTX(_sb) (&(_sb)->sb_mtx)
#if defined (__Userspace_os_Windows) #if defined(_WIN32)
#define SOCKBUF_LOCK_INIT(_sb, _name) \ #define SOCKBUF_LOCK_INIT(_sb, _name) \
InitializeCriticalSection(SOCKBUF_MTX(_sb)) InitializeCriticalSection(SOCKBUF_MTX(_sb))
#define SOCKBUF_LOCK_DESTROY(_sb) DeleteCriticalSection(SOCKBUF_MTX(_sb)) #define SOCKBUF_LOCK_DESTROY(_sb) DeleteCriticalSection(SOCKBUF_MTX(_sb))
@ -273,8 +282,19 @@ extern userland_cond_t accept_cond;
#define SOCK_COND_DESTROY(_so) DeleteConditionVariable((&(_so)->timeo_cond)) #define SOCK_COND_DESTROY(_so) DeleteConditionVariable((&(_so)->timeo_cond))
#define SOCK_COND(_so) (&(_so)->timeo_cond) #define SOCK_COND(_so) (&(_so)->timeo_cond)
#else #else
#ifdef INVARIANTS
#define SOCKBUF_LOCK_INIT(_sb, _name) do { \
pthread_mutexattr_t mutex_attr; \
\
pthread_mutexattr_init(&mutex_attr); \
pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ERRORCHECK); \
pthread_mutex_init(SOCKBUF_MTX(_sb), &mutex_attr); \
pthread_mutexattr_destroy(&mutex_attr); \
} while (0)
#else
#define SOCKBUF_LOCK_INIT(_sb, _name) \ #define SOCKBUF_LOCK_INIT(_sb, _name) \
pthread_mutex_init(SOCKBUF_MTX(_sb), NULL) pthread_mutex_init(SOCKBUF_MTX(_sb), NULL)
#endif
#define SOCKBUF_LOCK_DESTROY(_sb) pthread_mutex_destroy(SOCKBUF_MTX(_sb)) #define SOCKBUF_LOCK_DESTROY(_sb) pthread_mutex_destroy(SOCKBUF_MTX(_sb))
#define SOCKBUF_COND_INIT(_sb) pthread_cond_init((&(_sb)->sb_cond), NULL) #define SOCKBUF_COND_INIT(_sb) pthread_cond_init((&(_sb)->sb_cond), NULL)
#define SOCKBUF_COND_DESTROY(_sb) pthread_cond_destroy((&(_sb)->sb_cond)) #define SOCKBUF_COND_DESTROY(_sb) pthread_cond_destroy((&(_sb)->sb_cond))
@ -347,338 +367,11 @@ extern userland_cond_t accept_cond;
#define SQ_COMP 0x1000 /* unaccepted, complete connection */ #define SQ_COMP 0x1000 /* unaccepted, complete connection */
/* /*
* Externalized form of struct socket used by the sysctl(3) interface. * Socket event flags
*/ */
struct xsocket { #define SCTP_EVENT_READ 0x0001 /* socket is readable */
size_t xso_len; /* length of this structure */ #define SCTP_EVENT_WRITE 0x0002 /* socket is writeable */
struct socket *xso_so; /* makes a convenient handle sometimes */ #define SCTP_EVENT_ERROR 0x0004 /* socket has an error state */
short so_type;
short so_options;
short so_linger;
short so_state;
caddr_t so_pcb; /* another convenient handle */
int xso_protocol;
int xso_family;
u_short so_qlen;
u_short so_incqlen;
u_short so_qlimit;
short so_timeo;
u_short so_error;
pid_t so_pgid;
u_long so_oobmark;
struct xsockbuf {
u_int sb_cc;
u_int sb_hiwat;
u_int sb_mbcnt;
u_int sb_mbmax;
int sb_lowat;
int sb_timeo;
short sb_flags;
} so_rcv, so_snd;
uid_t so_uid; /* XXX */
};
#if defined(_KERNEL)
/*
* Macros for sockets and socket buffering.
*/
/*
* Do we need to notify the other side when I/O is possible?
*/
#define sb_notify(sb) (((sb)->sb_flags & (SB_WAIT | SB_SEL | SB_ASYNC | \
SB_UPCALL | SB_AIO | SB_KNOTE)) != 0)
/*
* How much space is there in a socket buffer (so->so_snd or so->so_rcv)?
* This is problematical if the fields are unsigned, as the space might
* still be negative (cc > hiwat or mbcnt > mbmax). Should detect
* overflow and return 0. Should use "lmin" but it doesn't exist now.
*/
#define sbspace(sb) \
((long) imin((int)((sb)->sb_hiwat - (sb)->sb_cc), \
(int)((sb)->sb_mbmax - (sb)->sb_mbcnt)))
/* do we have to send all at once on a socket? */
#define sosendallatonce(so) \
((so)->so_proto->pr_flags & PR_ATOMIC)
/* can we read something from so? */
#define soreadable(so) \
((so)->so_rcv.sb_cc >= (so)->so_rcv.sb_lowat || \
((so)->so_rcv.sb_state & SBS_CANTRCVMORE) || \
!TAILQ_EMPTY(&(so)->so_comp) || (so)->so_error)
/* can we write something to so? */
#define sowriteable(so) \
((sbspace(&(so)->so_snd) >= (so)->so_snd.sb_lowat && \
(((so)->so_state&SS_ISCONNECTED) || \
((so)->so_proto->pr_flags&PR_CONNREQUIRED)==0)) || \
((so)->so_snd.sb_state & SBS_CANTSENDMORE) || \
(so)->so_error)
/* adjust counters in sb reflecting allocation of m */
#define sballoc(sb, m) { \
(sb)->sb_cc += (m)->m_len; \
if ((m)->m_type != MT_DATA && (m)->m_type != MT_OOBDATA) \
(sb)->sb_ctl += (m)->m_len; \
(sb)->sb_mbcnt += MSIZE; \
if ((m)->m_flags & M_EXT) \
(sb)->sb_mbcnt += (m)->m_ext.ext_size; \
}
/* adjust counters in sb reflecting freeing of m */
#define sbfree(sb, m) { \
(sb)->sb_cc -= (m)->m_len; \
if ((m)->m_type != MT_DATA && (m)->m_type != MT_OOBDATA) \
(sb)->sb_ctl -= (m)->m_len; \
(sb)->sb_mbcnt -= MSIZE; \
if ((m)->m_flags & M_EXT) \
(sb)->sb_mbcnt -= (m)->m_ext.ext_size; \
if ((sb)->sb_sndptr == (m)) { \
(sb)->sb_sndptr = NULL; \
(sb)->sb_sndptroff = 0; \
} \
if ((sb)->sb_sndptroff != 0) \
(sb)->sb_sndptroff -= (m)->m_len; \
}
/*
* soref()/sorele() ref-count the socket structure. Note that you must
* still explicitly close the socket, but the last ref count will free
* the structure.
*/
#define soref(so) do { \
SOCK_LOCK_ASSERT(so); \
++(so)->so_count; \
} while (0)
#define sorele(so) do { \
ACCEPT_LOCK_ASSERT(); \
SOCK_LOCK_ASSERT(so); \
KASSERT((so)->so_count > 0, ("sorele")); \
if (--(so)->so_count == 0) \
sofree(so); \
else { \
SOCK_UNLOCK(so); \
ACCEPT_UNLOCK(); \
} \
} while (0)
#define sotryfree(so) do { \
ACCEPT_LOCK_ASSERT(); \
SOCK_LOCK_ASSERT(so); \
if ((so)->so_count == 0) \
sofree(so); \
else { \
SOCK_UNLOCK(so); \
ACCEPT_UNLOCK(); \
} \
} while(0)
/*
* In sorwakeup() and sowwakeup(), acquire the socket buffer lock to
* avoid a non-atomic test-and-wakeup. However, sowakeup is
* responsible for releasing the lock if it is called. We unlock only
* if we don't call into sowakeup. If any code is introduced that
* directly invokes the underlying sowakeup() primitives, it must
* maintain the same semantics.
*/
#define sorwakeup_locked(so) do { \
SOCKBUF_LOCK_ASSERT(&(so)->so_rcv); \
if (sb_notify(&(so)->so_rcv)) \
sowakeup((so), &(so)->so_rcv); \
else \
SOCKBUF_UNLOCK(&(so)->so_rcv); \
} while (0)
#define sorwakeup(so) do { \
SOCKBUF_LOCK(&(so)->so_rcv); \
sorwakeup_locked(so); \
} while (0)
#define sowwakeup_locked(so) do { \
SOCKBUF_LOCK_ASSERT(&(so)->so_snd); \
if (sb_notify(&(so)->so_snd)) \
sowakeup((so), &(so)->so_snd); \
else \
SOCKBUF_UNLOCK(&(so)->so_snd); \
} while (0)
#define sowwakeup(so) do { \
SOCKBUF_LOCK(&(so)->so_snd); \
sowwakeup_locked(so); \
} while (0)
/*
* Argument structure for sosetopt et seq. This is in the KERNEL
* section because it will never be visible to user code.
*/
enum sopt_dir { SOPT_GET, SOPT_SET };
struct sockopt {
enum sopt_dir sopt_dir; /* is this a get or a set? */
int sopt_level; /* second arg of [gs]etsockopt */
int sopt_name; /* third arg of [gs]etsockopt */
void *sopt_val; /* fourth arg of [gs]etsockopt */
size_t sopt_valsize; /* (almost) fifth arg of [gs]etsockopt */
struct thread *sopt_td; /* calling thread or null if kernel */
};
struct accept_filter {
char accf_name[16];
void (*accf_callback)
(struct socket *so, void *arg, int waitflag);
void * (*accf_create)
(struct socket *so, char *arg);
void (*accf_destroy)
(struct socket *so);
SLIST_ENTRY(accept_filter) accf_next;
};
extern int maxsockets;
extern u_long sb_max;
extern struct uma_zone *socket_zone;
extern so_gen_t so_gencnt;
struct mbuf;
struct sockaddr;
struct ucred;
struct uio;
/*
* From uipc_socket and friends
*/
int do_getopt_accept_filter(struct socket *so, struct sockopt *sopt);
int do_setopt_accept_filter(struct socket *so, struct sockopt *sopt);
int so_setsockopt(struct socket *so, int level, int optname,
void *optval, size_t optlen);
int sockargs(struct mbuf **mp, caddr_t buf, int buflen, int type);
int getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len);
void sbappend(struct sockbuf *sb, struct mbuf *m);
void sbappend_locked(struct sockbuf *sb, struct mbuf *m);
void sbappendstream(struct sockbuf *sb, struct mbuf *m);
void sbappendstream_locked(struct sockbuf *sb, struct mbuf *m);
int sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa,
struct mbuf *m0, struct mbuf *control);
int sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa,
struct mbuf *m0, struct mbuf *control);
int sbappendcontrol(struct sockbuf *sb, struct mbuf *m0,
struct mbuf *control);
int sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
struct mbuf *control);
void sbappendrecord(struct sockbuf *sb, struct mbuf *m0);
void sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0);
void sbcheck(struct sockbuf *sb);
void sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n);
struct mbuf *
sbcreatecontrol(caddr_t p, int size, int type, int level);
void sbdestroy(struct sockbuf *sb, struct socket *so);
void sbdrop(struct sockbuf *sb, int len);
void sbdrop_locked(struct sockbuf *sb, int len);
void sbdroprecord(struct sockbuf *sb);
void sbdroprecord_locked(struct sockbuf *sb);
void sbflush(struct sockbuf *sb);
void sbflush_locked(struct sockbuf *sb);
void sbrelease(struct sockbuf *sb, struct socket *so);
void sbrelease_locked(struct sockbuf *sb, struct socket *so);
int sbreserve(struct sockbuf *sb, u_long cc, struct socket *so,
struct thread *td);
int sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so,
struct thread *td);
struct mbuf *
sbsndptr(struct sockbuf *sb, u_int off, u_int len, u_int *moff);
void sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb);
int sbwait(struct sockbuf *sb);
int sblock(struct sockbuf *sb, int flags);
void sbunlock(struct sockbuf *sb);
void soabort(struct socket *so);
int soaccept(struct socket *so, struct sockaddr **nam);
int socheckuid(struct socket *so, uid_t uid);
int sobind(struct socket *so, struct sockaddr *nam, struct thread *td);
void socantrcvmore(struct socket *so);
void socantrcvmore_locked(struct socket *so);
void socantsendmore(struct socket *so);
void socantsendmore_locked(struct socket *so);
int soclose(struct socket *so);
int soconnect(struct socket *so, struct sockaddr *nam, struct thread *td);
int soconnect2(struct socket *so1, struct socket *so2);
int socow_setup(struct mbuf *m0, struct uio *uio);
int socreate(int dom, struct socket **aso, int type, int proto,
struct ucred *cred, struct thread *td);
int sodisconnect(struct socket *so);
struct sockaddr *sodupsockaddr(const struct sockaddr *sa, int mflags);
void sofree(struct socket *so);
int sogetopt(struct socket *so, struct sockopt *sopt);
void sohasoutofband(struct socket *so);
void soisconnected(struct socket *so);
void soisconnecting(struct socket *so);
void soisdisconnected(struct socket *so);
void soisdisconnecting(struct socket *so);
int solisten(struct socket *so, int backlog, struct thread *td);
void solisten_proto(struct socket *so, int backlog);
int solisten_proto_check(struct socket *so);
struct socket *
sonewconn(struct socket *head, int connstatus);
int sooptcopyin(struct sockopt *sopt, void *buf, size_t len, size_t minlen);
int sooptcopyout(struct sockopt *sopt, const void *buf, size_t len);
/* XXX; prepare mbuf for (__FreeBSD__ < 3) routines. */
int soopt_getm(struct sockopt *sopt, struct mbuf **mp);
int soopt_mcopyin(struct sockopt *sopt, struct mbuf *m);
int soopt_mcopyout(struct sockopt *sopt, struct mbuf *m);
int sopoll(struct socket *so, int events, struct ucred *active_cred,
struct thread *td);
int sopoll_generic(struct socket *so, int events,
struct ucred *active_cred, struct thread *td);
int soreceive(struct socket *so, struct sockaddr **paddr, struct uio *uio,
struct mbuf **mp0, struct mbuf **controlp, int *flagsp);
int soreceive_generic(struct socket *so, struct sockaddr **paddr,
struct uio *uio, struct mbuf **mp0, struct mbuf **controlp,
int *flagsp);
int soreserve(struct socket *so, u_long sndcc, u_long rcvcc);
void sorflush(struct socket *so);
int sosend(struct socket *so, struct sockaddr *addr, struct uio *uio,
struct mbuf *top, struct mbuf *control, int flags,
struct thread *td);
int sosend_dgram(struct socket *so, struct sockaddr *addr,
struct uio *uio, struct mbuf *top, struct mbuf *control,
int flags, struct thread *td);
int sosend_generic(struct socket *so, struct sockaddr *addr,
struct uio *uio, struct mbuf *top, struct mbuf *control,
int flags, struct thread *td);
int sosetopt(struct socket *so, struct sockopt *sopt);
int soshutdown(struct socket *so, int how);
void sotoxsocket(struct socket *so, struct xsocket *xso);
void sowakeup(struct socket *so, struct sockbuf *sb);
#ifdef SOCKBUF_DEBUG
void sblastrecordchk(struct sockbuf *, const char *, int);
#define SBLASTRECORDCHK(sb) sblastrecordchk((sb), __FILE__, __LINE__)
void sblastmbufchk(struct sockbuf *, const char *, int);
#define SBLASTMBUFCHK(sb) sblastmbufchk((sb), __FILE__, __LINE__)
#else
#define SBLASTRECORDCHK(sb) /* nothing */
#define SBLASTMBUFCHK(sb) /* nothing */
#endif /* SOCKBUF_DEBUG */
/*
* Accept filter functions (duh).
*/
int accept_filt_add(struct accept_filter *filt);
int accept_filt_del(char *name);
struct accept_filter *accept_filt_get(char *name);
#ifdef ACCEPT_FILTER_MOD
#ifdef SYSCTL_DECL
SYSCTL_DECL(_net_inet_accf);
#endif
int accept_filt_generic_mod_event(module_t mod, int event, void *data);
#endif
#endif /* _KERNEL */
/*-------------------------------------------------------------*/ /*-------------------------------------------------------------*/
@ -690,7 +383,6 @@ int accept_filt_generic_mod_event(module_t mod, int event, void *data);
* above into, avoiding having to port the entire thing at once... * above into, avoiding having to port the entire thing at once...
* For function prototypes, the full bodies are in user_socket.c . * For function prototypes, the full bodies are in user_socket.c .
*/ */
#if defined(__Userspace__)
/* ---------------------------------------------------------- */ /* ---------------------------------------------------------- */
/* --- function prototypes (implemented in user_socket.c) --- */ /* --- function prototypes (implemented in user_socket.c) --- */
@ -701,6 +393,7 @@ void soisconnected(struct socket *so);
struct socket * sonewconn(struct socket *head, int connstatus); struct socket * sonewconn(struct socket *head, int connstatus);
void socantrcvmore(struct socket *so); void socantrcvmore(struct socket *so);
void socantsendmore(struct socket *so); void socantsendmore(struct socket *so);
void sofree(struct socket *so);
@ -764,9 +457,7 @@ extern int sctp_listen(struct socket *so, int backlog, struct proc *p);
extern void socantrcvmore_locked(struct socket *so); extern void socantrcvmore_locked(struct socket *so);
extern int sctp_bind(struct socket *so, struct sockaddr *addr); extern int sctp_bind(struct socket *so, struct sockaddr *addr);
extern int sctp6_bind(struct socket *so, struct sockaddr *addr, void *proc); extern int sctp6_bind(struct socket *so, struct sockaddr *addr, void *proc);
#if defined(__Userspace__)
extern int sctpconn_bind(struct socket *so, struct sockaddr *addr); extern int sctpconn_bind(struct socket *so, struct sockaddr *addr);
#endif
extern int sctp_accept(struct socket *so, struct sockaddr **addr); extern int sctp_accept(struct socket *so, struct sockaddr **addr);
extern int sctp_attach(struct socket *so, int proto, uint32_t vrf_id); extern int sctp_attach(struct socket *so, int proto, uint32_t vrf_id);
extern int sctp6_attach(struct socket *so, int proto, uint32_t vrf_id); extern int sctp6_attach(struct socket *so, int proto, uint32_t vrf_id);
@ -785,9 +476,7 @@ extern int soconnect(struct socket *so, struct sockaddr *nam);
extern int sctp_disconnect(struct socket *so); extern int sctp_disconnect(struct socket *so);
extern int sctp_connect(struct socket *so, struct sockaddr *addr); extern int sctp_connect(struct socket *so, struct sockaddr *addr);
extern int sctp6_connect(struct socket *so, struct sockaddr *addr); extern int sctp6_connect(struct socket *so, struct sockaddr *addr);
#if defined(__Userspace__)
extern int sctpconn_connect(struct socket *so, struct sockaddr *addr); extern int sctpconn_connect(struct socket *so, struct sockaddr *addr);
#endif
extern void sctp_finish(void); extern void sctp_finish(void);
/* ------------------------------------------------ */ /* ------------------------------------------------ */
@ -835,8 +524,4 @@ extern void sctp_finish(void);
sowwakeup_locked(so); \ sowwakeup_locked(so); \
} while (0) } while (0)
#endif /* __Userspace__ */
#endif /* !_SYS_SOCKETVAR_H_ */ #endif /* !_SYS_SOCKETVAR_H_ */

View file

@ -83,16 +83,14 @@ struct uma_zone {
/* Prototype */ /* Prototype */
uma_zone_t uma_zone_t
uma_zcreate(char *name, size_t size, uma_ctor ctor, uma_dtor dtor, uma_zcreate(char *name, size_t size, uma_ctor ctor, uma_dtor dtor,
uma_init uminit, uma_fini fini, int align, u_int32_t flags); uma_init uminit, uma_fini fini, int align, uint32_t flags);
#define uma_zone_set_max(zone, number) /* stub TODO __Userspace__ */ #define uma_zone_set_max(zone, number) /* stub TODO __Userspace__ */
uma_zone_t uma_zone_t
uma_zcreate(char *name, size_t size, uma_ctor ctor, uma_dtor dtor, uma_zcreate(char *name, size_t size, uma_ctor ctor, uma_dtor dtor,
uma_init uminit, uma_fini fini, int align, u_int32_t flags) uma_init uminit, uma_fini fini, int align, uint32_t flags) {
{
return NULL; /* stub TODO __Userspace__. Also place implementation in a separate .c file */ return NULL; /* stub TODO __Userspace__. Also place implementation in a separate .c file */
} }
#endif #endif

View file

@ -67,11 +67,21 @@ extern "C" {
#define uint8_t unsigned __int8 #define uint8_t unsigned __int8
#define uint16_t unsigned __int16 #define uint16_t unsigned __int16
#define uint32_t unsigned __int32 #define uint32_t unsigned __int32
#define uint64_t unsigned __int64
#define int16_t __int16 #define int16_t __int16
#define int32_t __int32 #define int32_t __int32
#endif #endif
#ifndef ssize_t
#ifdef _WIN64
#define ssize_t __int64 #define ssize_t __int64
#elif defined _WIN32
#define ssize_t int
#else
#error "Unknown platform!"
#endif
#endif
#define MSG_EOR 0x8 #define MSG_EOR 0x8
#ifndef EWOULDBLOCK #ifndef EWOULDBLOCK
#define EWOULDBLOCK WSAEWOULDBLOCK #define EWOULDBLOCK WSAEWOULDBLOCK
@ -86,6 +96,25 @@ extern "C" {
typedef uint32_t sctp_assoc_t; typedef uint32_t sctp_assoc_t;
#if defined(_WIN32) && defined(_MSC_VER)
#pragma pack (push, 1)
#define SCTP_PACKED
#else
#define SCTP_PACKED __attribute__((packed))
#endif
struct sctp_common_header {
uint16_t source_port;
uint16_t destination_port;
uint32_t verification_tag;
uint32_t crc32c;
} SCTP_PACKED;
#if defined(_WIN32) && defined(_MSC_VER)
#pragma pack(pop)
#endif
#undef SCTP_PACKED
#define AF_CONN 123 #define AF_CONN 123
/* The definition of struct sockaddr_conn MUST be in /* The definition of struct sockaddr_conn MUST be in
* tune with other sockaddr_* structures. * tune with other sockaddr_* structures.
@ -107,12 +136,8 @@ struct sockaddr_conn {
#endif #endif
union sctp_sockstore { union sctp_sockstore {
#if defined(INET)
struct sockaddr_in sin; struct sockaddr_in sin;
#endif
#if defined(INET6)
struct sockaddr_in6 sin6; struct sockaddr_in6 sin6;
#endif
struct sockaddr_conn sconn; struct sockaddr_conn sconn;
struct sockaddr sa; struct sockaddr sa;
}; };
@ -121,6 +146,10 @@ union sctp_sockstore {
#define SCTP_CURRENT_ASSOC 1 #define SCTP_CURRENT_ASSOC 1
#define SCTP_ALL_ASSOC 2 #define SCTP_ALL_ASSOC 2
#define SCTP_EVENT_READ 0x0001
#define SCTP_EVENT_WRITE 0x0002
#define SCTP_EVENT_ERROR 0x0004
/*** Structures and definitions to use the socket API ***/ /*** Structures and definitions to use the socket API ***/
#define SCTP_ALIGN_RESV_PAD 92 #define SCTP_ALIGN_RESV_PAD 92
@ -257,7 +286,8 @@ struct sctp_assoc_change {
#define SCTP_ASSOC_SUPPORTS_ASCONF 0x03 #define SCTP_ASSOC_SUPPORTS_ASCONF 0x03
#define SCTP_ASSOC_SUPPORTS_MULTIBUF 0x04 #define SCTP_ASSOC_SUPPORTS_MULTIBUF 0x04
#define SCTP_ASSOC_SUPPORTS_RE_CONFIG 0x05 #define SCTP_ASSOC_SUPPORTS_RE_CONFIG 0x05
#define SCTP_ASSOC_SUPPORTS_MAX 0x05 #define SCTP_ASSOC_SUPPORTS_INTERLEAVING 0x06
#define SCTP_ASSOC_SUPPORTS_MAX 0x06
/* Address event */ /* Address event */
struct sctp_paddr_change { struct sctp_paddr_change {
@ -286,7 +316,7 @@ struct sctp_remote_error {
uint32_t sre_length; uint32_t sre_length;
uint16_t sre_error; uint16_t sre_error;
sctp_assoc_t sre_assoc_id; sctp_assoc_t sre_assoc_id;
uint8_t sre_data[4]; uint8_t sre_data[];
}; };
/* shutdown event */ /* shutdown event */
@ -451,6 +481,8 @@ struct sctp_event_subscribe {
/* Flags that go into the sinfo->sinfo_flags field */ /* Flags that go into the sinfo->sinfo_flags field */
#define SCTP_DATA_LAST_FRAG 0x0001 /* tail part of the message could not be sent */
#define SCTP_DATA_NOT_FRAG 0x0003 /* complete message could not be sent */
#define SCTP_NOTIFICATION 0x0010 /* next message is a notification */ #define SCTP_NOTIFICATION 0x0010 /* next message is a notification */
#define SCTP_COMPLETE 0x0020 /* next message is complete */ #define SCTP_COMPLETE 0x0020 /* next message is complete */
#define SCTP_EOF 0x0100 /* Start shutdown procedures */ #define SCTP_EOF 0x0100 /* Start shutdown procedures */
@ -520,9 +552,21 @@ struct sctp_event_subscribe {
#define SCTP_DEFAULT_SNDINFO 0x00000021 #define SCTP_DEFAULT_SNDINFO 0x00000021
#define SCTP_DEFAULT_PRINFO 0x00000022 #define SCTP_DEFAULT_PRINFO 0x00000022
#define SCTP_REMOTE_UDP_ENCAPS_PORT 0x00000024 #define SCTP_REMOTE_UDP_ENCAPS_PORT 0x00000024
#define SCTP_ECN_SUPPORTED 0x00000025
#define SCTP_PR_SUPPORTED 0x00000026
#define SCTP_AUTH_SUPPORTED 0x00000027
#define SCTP_ASCONF_SUPPORTED 0x00000028
#define SCTP_RECONFIG_SUPPORTED 0x00000029
#define SCTP_NRSACK_SUPPORTED 0x00000030
#define SCTP_PKTDROP_SUPPORTED 0x00000031
#define SCTP_MAX_CWND 0x00000032
#define SCTP_ENABLE_STREAM_RESET 0x00000900 /* struct sctp_assoc_value */ #define SCTP_ENABLE_STREAM_RESET 0x00000900 /* struct sctp_assoc_value */
/* Pluggable Stream Scheduling Socket option */
#define SCTP_PLUGGABLE_SS 0x00001203
#define SCTP_SS_VALUE 0x00001204
/* /*
* read-only options * read-only options
*/ */
@ -533,6 +577,9 @@ struct sctp_event_subscribe {
#define SCTP_LOCAL_AUTH_CHUNKS 0x00000103 #define SCTP_LOCAL_AUTH_CHUNKS 0x00000103
#define SCTP_GET_ASSOC_NUMBER 0x00000104 #define SCTP_GET_ASSOC_NUMBER 0x00000104
#define SCTP_GET_ASSOC_ID_LIST 0x00000105 #define SCTP_GET_ASSOC_ID_LIST 0x00000105
#define SCTP_TIMEOUTS 0x00000106
#define SCTP_PR_STREAM_STATUS 0x00000107
#define SCTP_PR_ASSOC_STATUS 0x00000108
/* /*
* write-only options * write-only options
@ -778,6 +825,12 @@ struct sctp_cc_option {
struct sctp_assoc_value aid_value; struct sctp_assoc_value aid_value;
}; };
struct sctp_stream_value {
sctp_assoc_t assoc_id;
uint16_t stream_id;
uint16_t stream_value;
};
struct sctp_timeouts { struct sctp_timeouts {
sctp_assoc_t stimo_assoc_id; sctp_assoc_t stimo_assoc_id;
uint32_t stimo_init; uint32_t stimo_init;
@ -789,6 +842,13 @@ struct sctp_timeouts {
uint32_t stimo_shutdownack; uint32_t stimo_shutdownack;
}; };
struct sctp_prstatus {
sctp_assoc_t sprstat_assoc_id;
uint16_t sprstat_sid;
uint16_t sprstat_policy;
uint64_t sprstat_abandoned_unsent;
uint64_t sprstat_abandoned_sent;
};
/* Standard TCP Congestion Control */ /* Standard TCP Congestion Control */
#define SCTP_CC_RFC2581 0x00000000 #define SCTP_CC_RFC2581 0x00000000
@ -835,11 +895,16 @@ usrsctp_init(uint16_t,
int (*)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df), int (*)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
void (*)(const char *format, ...)); void (*)(const char *format, ...));
void
usrsctp_init_nothreads(uint16_t,
int (*)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
void (*)(const char *format, ...));
struct socket * struct socket *
usrsctp_socket(int domain, int type, int protocol, usrsctp_socket(int domain, int type, int protocol,
int (*receive_cb)(struct socket *sock, union sctp_sockstore addr, void *data, int (*receive_cb)(struct socket *sock, union sctp_sockstore addr, void *data,
size_t datalen, struct sctp_rcvinfo, int flags, void *ulp_info), 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, uint32_t sb_threshold,
void *ulp_info); void *ulp_info);
@ -857,6 +922,13 @@ usrsctp_getsockopt(struct socket *so,
void *option_value, void *option_value,
socklen_t *option_len); socklen_t *option_len);
int
usrsctp_opt_info(struct socket *so,
sctp_assoc_t id,
int opt,
void *arg,
socklen_t *size);
int int
usrsctp_getpaddrs(struct socket *so, usrsctp_getpaddrs(struct socket *so,
sctp_assoc_t id, sctp_assoc_t id,
@ -934,6 +1006,9 @@ usrsctp_connectx(struct socket *so,
void void
usrsctp_close(struct socket *so); usrsctp_close(struct socket *so);
sctp_assoc_t
usrsctp_getassocid(struct socket *, struct sockaddr *);
int int
usrsctp_finish(void); usrsctp_finish(void);
@ -958,17 +1033,49 @@ usrsctp_deregister_address(void *);
int int
usrsctp_set_ulpinfo(struct socket *, void *); usrsctp_set_ulpinfo(struct socket *, void *);
int
usrsctp_get_ulpinfo(struct socket *, void **);
int
usrsctp_set_upcall(struct socket *so,
void (*upcall)(struct socket *, void *, int),
void *arg);
int
usrsctp_get_events(struct socket *so);
void
usrsctp_handle_timers(uint32_t elapsed_milliseconds);
#define SCTP_DUMP_OUTBOUND 1 #define SCTP_DUMP_OUTBOUND 1
#define SCTP_DUMP_INBOUND 0 #define SCTP_DUMP_INBOUND 0
char * char *
usrsctp_dumppacket(void *, size_t, int); usrsctp_dumppacket(const void *, size_t, int);
void void
usrsctp_freedumpbuffer(char *); usrsctp_freedumpbuffer(char *);
void
usrsctp_enable_crc32c_offload(void);
void
usrsctp_disable_crc32c_offload(void);
uint32_t
usrsctp_crc32c(void *, size_t);
#define USRSCTP_TUNABLE_DECL(__field) \
int usrsctp_tunable_set_ ## __field(uint32_t value);\
uint32_t usrsctp_sysctl_get_ ## __field(void);
USRSCTP_TUNABLE_DECL(sctp_hashtblsize)
USRSCTP_TUNABLE_DECL(sctp_pcbtblsize)
USRSCTP_TUNABLE_DECL(sctp_chunkscale)
#define USRSCTP_SYSCTL_DECL(__field) \ #define USRSCTP_SYSCTL_DECL(__field) \
void usrsctp_sysctl_set_ ## __field(uint32_t value);\ int usrsctp_sysctl_set_ ## __field(uint32_t value);\
uint32_t usrsctp_sysctl_get_ ## __field(void); uint32_t usrsctp_sysctl_get_ ## __field(void);
USRSCTP_SYSCTL_DECL(sctp_sendspace) USRSCTP_SYSCTL_DECL(sctp_sendspace)
@ -982,17 +1089,11 @@ USRSCTP_SYSCTL_DECL(sctp_asconf_enable)
USRSCTP_SYSCTL_DECL(sctp_reconfig_enable) USRSCTP_SYSCTL_DECL(sctp_reconfig_enable)
USRSCTP_SYSCTL_DECL(sctp_nrsack_enable) USRSCTP_SYSCTL_DECL(sctp_nrsack_enable)
USRSCTP_SYSCTL_DECL(sctp_pktdrop_enable) USRSCTP_SYSCTL_DECL(sctp_pktdrop_enable)
USRSCTP_SYSCTL_DECL(sctp_strict_sacks)
#if !defined(SCTP_WITH_NO_CSUM)
USRSCTP_SYSCTL_DECL(sctp_no_csum_on_loopback) USRSCTP_SYSCTL_DECL(sctp_no_csum_on_loopback)
#endif
USRSCTP_SYSCTL_DECL(sctp_peer_chunk_oh) USRSCTP_SYSCTL_DECL(sctp_peer_chunk_oh)
USRSCTP_SYSCTL_DECL(sctp_max_burst_default) USRSCTP_SYSCTL_DECL(sctp_max_burst_default)
USRSCTP_SYSCTL_DECL(sctp_max_chunks_on_queue) USRSCTP_SYSCTL_DECL(sctp_max_chunks_on_queue)
USRSCTP_SYSCTL_DECL(sctp_hashtblsize)
USRSCTP_SYSCTL_DECL(sctp_pcbtblsize)
USRSCTP_SYSCTL_DECL(sctp_min_split_point) USRSCTP_SYSCTL_DECL(sctp_min_split_point)
USRSCTP_SYSCTL_DECL(sctp_chunkscale)
USRSCTP_SYSCTL_DECL(sctp_delayed_sack_time_default) USRSCTP_SYSCTL_DECL(sctp_delayed_sack_time_default)
USRSCTP_SYSCTL_DECL(sctp_sack_freq_default) USRSCTP_SYSCTL_DECL(sctp_sack_freq_default)
USRSCTP_SYSCTL_DECL(sctp_system_free_resc_limit) USRSCTP_SYSCTL_DECL(sctp_system_free_resc_limit)
@ -1021,7 +1122,6 @@ USRSCTP_SYSCTL_DECL(sctp_mbuf_threshold_count)
USRSCTP_SYSCTL_DECL(sctp_do_drain) USRSCTP_SYSCTL_DECL(sctp_do_drain)
USRSCTP_SYSCTL_DECL(sctp_hb_maxburst) USRSCTP_SYSCTL_DECL(sctp_hb_maxburst)
USRSCTP_SYSCTL_DECL(sctp_abort_if_one_2_one_hits_limit) USRSCTP_SYSCTL_DECL(sctp_abort_if_one_2_one_hits_limit)
USRSCTP_SYSCTL_DECL(sctp_strict_data_order)
USRSCTP_SYSCTL_DECL(sctp_min_residual) USRSCTP_SYSCTL_DECL(sctp_min_residual)
USRSCTP_SYSCTL_DECL(sctp_max_retran_chunk) USRSCTP_SYSCTL_DECL(sctp_max_retran_chunk)
USRSCTP_SYSCTL_DECL(sctp_logging_level) USRSCTP_SYSCTL_DECL(sctp_logging_level)
@ -1034,6 +1134,7 @@ USRSCTP_SYSCTL_DECL(sctp_udp_tunneling_port)
USRSCTP_SYSCTL_DECL(sctp_enable_sack_immediately) USRSCTP_SYSCTL_DECL(sctp_enable_sack_immediately)
USRSCTP_SYSCTL_DECL(sctp_vtag_time_wait) USRSCTP_SYSCTL_DECL(sctp_vtag_time_wait)
USRSCTP_SYSCTL_DECL(sctp_blackhole) USRSCTP_SYSCTL_DECL(sctp_blackhole)
USRSCTP_SYSCTL_DECL(sctp_sendall_limit)
USRSCTP_SYSCTL_DECL(sctp_diag_info_code) USRSCTP_SYSCTL_DECL(sctp_diag_info_code)
USRSCTP_SYSCTL_DECL(sctp_fr_max_burst_default) USRSCTP_SYSCTL_DECL(sctp_fr_max_burst_default)
USRSCTP_SYSCTL_DECL(sctp_path_pf_threshold) USRSCTP_SYSCTL_DECL(sctp_path_pf_threshold)
@ -1099,7 +1200,7 @@ struct sctpstat {
uint32_t sctps_recvauthfailed; /* total number of auth failed */ uint32_t sctps_recvauthfailed; /* total number of auth failed */
uint32_t sctps_recvexpress; /* total fast path receives all one chunk */ uint32_t sctps_recvexpress; /* total fast path receives all one chunk */
uint32_t sctps_recvexpressm; /* total fast path multi-part data */ uint32_t sctps_recvexpressm; /* total fast path multi-part data */
uint32_t sctps_recvnocrc; uint32_t sctps_recv_spare; /* formerly sctps_recvnocrc */
uint32_t sctps_recvswcrc; uint32_t sctps_recvswcrc;
uint32_t sctps_recvhwcrc; uint32_t sctps_recvhwcrc;
@ -1116,7 +1217,7 @@ struct sctpstat {
uint32_t sctps_sendecne; /* total output ECNE chunks */ uint32_t sctps_sendecne; /* total output ECNE chunks */
uint32_t sctps_sendauth; /* total output AUTH chunks FIXME */ uint32_t sctps_sendauth; /* total output AUTH chunks FIXME */
uint32_t sctps_senderrors; /* ip_output error counter */ uint32_t sctps_senderrors; /* ip_output error counter */
uint32_t sctps_sendnocrc; uint32_t sctps_send_spare; /* formerly sctps_sendnocrc */
uint32_t sctps_sendswcrc; uint32_t sctps_sendswcrc;
uint32_t sctps_sendhwcrc; uint32_t sctps_sendhwcrc;
/* PCKDROPREP statistics: */ /* PCKDROPREP statistics: */

View file

@ -1,33 +0,0 @@
#!/bin/bash
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# assume $1 is the directory with a SVN checkout of the libsctp source
#
# sctp usrlib source is available (via svn) at:
# svn co https://sctp-refimpl.googlecode.com/svn/trunk sctpSVN
#
# also assumes we've made *NO* changes to the SCTP sources! If we do, we have to merge by
# hand after this process, or use a more complex one.
#
# For example, one could update an sctp library import head, and merge back to default. Or keep a
# separate repo with this in it, and pull from there to m-c and merge.
if [ "$1" ] ; then
export date=`date`
export revision=`(cd $1; svnversion -n)`
cp $1/KERN/usrsctp/usrsctplib/*.c $1/KERN/usrsctp/usrsctplib/*.h netwerk/sctp/src
cp $1/KERN/usrsctp/usrsctplib/netinet/*.c $1/KERN/usrsctp/usrsctplib/netinet/*.h netwerk/sctp/src/netinet
cp $1/KERN/usrsctp/usrsctplib/netinet6/*.c $1/KERN/usrsctp/usrsctplib/netinet6/*.h netwerk/sctp/src/netinet6
hg addremove netwerk/sctp/src --include "**.c" --include "**.h" --similarity 90
echo "sctp updated to version $revision from SVN on $date" >> netwerk/sctp/sctp_update.log
echo "sctp updated to version $revision from SVN on $date"
echo "WARNING: reapply any local patches!"
else
echo "usage: $0 path_to_sctpSVN_directory"
echo "run from the root of your m-c clone"
fi