Bug 1297418: update usrsctp to rev 7737b4a5 from upstream rs=jesup

Green light from Michael Tuexen to take this rev from upstream by email
This commit is contained in:
Randell Jesup 2017-11-29 14:56:02 -05:00
Родитель 6b32e1e8f7
Коммит c018787ec1
56 изменённых файлов: 8716 добавлений и 6606 удалений

Просмотреть файл

@ -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 9168 from SVN on Tue Mar 3 12:11:40 EST 2015
sctp updated to version 9209 from SVN on Tue Mar 24 18:11:59 EDT 2015
sctp updated to version 0e076261b832121cf120ddc04aaff87ac3a34d30 from git on Tue Nov 28 15:20:51 EST 2017

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 279859 2015-03-10 19:49:25Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 323657 2017-09-16 21:26:06Z tuexen $");
#endif
#ifndef _NETINET_SCTP_H_
@ -202,6 +204,9 @@ struct sctp_paramhdr {
#define SCTP_PLUGGABLE_SS 0x00001203
#define SCTP_SS_VALUE 0x00001204
#define SCTP_CC_OPTION 0x00001205 /* Options for CC modules */
/* For I-DATA */
#define SCTP_INTERLEAVING_SUPPORTED 0x00001206
/* read only */
#define SCTP_GET_SNDBUF_USE 0x00001101
#define SCTP_GET_STAT_LOG 0x00001103
@ -402,33 +407,32 @@ struct sctp_error_cause {
} SCTP_PACKED;
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 reserved;
} SCTP_PACKED;
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 */
/* uint16_t param_type's follow */
uint16_t type[];
} SCTP_PACKED;
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 */
} SCTP_PACKED;
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;
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;
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 */
} SCTP_PACKED;
@ -437,6 +441,11 @@ struct sctp_error_no_user_data {
uint32_t tsn; /* TSN of the empty data chunk */
} 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
* can find them.
@ -462,6 +471,7 @@ struct sctp_error_no_user_data {
/* EY nr_sack chunk id*/
#define SCTP_NR_SELECTIVE_ACK 0x10
/************0x40 series ***********/
#define SCTP_IDATA 0x40
/************0x80 series ***********/
/* RFC5061 */
#define SCTP_ASCONF_ACK 0x80
@ -477,7 +487,7 @@ struct sctp_error_no_user_data {
#define SCTP_FORWARD_CUM_TSN 0xc0
/* RFC5061 */
#define SCTP_ASCONF 0xc1
#define SCTP_IFORWARD_CUM_TSN 0xc2
/* ABORT and SHUTDOWN COMPLETE FLAG */
#define SCTP_HAD_NO_TCB 0x01
@ -561,7 +571,6 @@ struct sctp_error_no_user_data {
#define SCTP_PCB_FLAGS_INTERLEAVE_STRMS 0x0000000000000010
#define SCTP_PCB_FLAGS_DO_ASCONF 0x0000000000000020
#define SCTP_PCB_FLAGS_AUTO_ASCONF 0x0000000000000040
#define SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE 0x0000000000000080
/* socket options */
#define SCTP_PCB_FLAGS_NODELAY 0x0000000000000100
#define SCTP_PCB_FLAGS_AUTOCLOSE 0x0000000000000200
@ -601,7 +610,7 @@ struct sctp_error_no_user_data {
#define SCTP_SMALLEST_PMTU 512 /* smallest pmtu allowed when disabling PMTU discovery */
#if defined(__Userspace_os_Windows)
#pragma pack()
#pragma pack(pop)
#endif
#undef SCTP_PACKED

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 277347 2015-01-18 20:53:20Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 324056 2017-09-27 13:05:23Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -187,7 +189,7 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
}
v4addr = (struct sctp_ipv4addr_param *)ph;
sin = &store.sin;
bzero(sin, sizeof(*sin));
memset(sin, 0, sizeof(*sin));
sin->sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
sin->sin_len = sizeof(struct sockaddr_in);
@ -212,7 +214,7 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
}
v6addr = (struct sctp_ipv6addr_param *)ph;
sin6 = &store.sin6;
bzero(sin6, sizeof(*sin6));
memset(sin6, 0, sizeof(*sin6));
sin6->sin6_family = AF_INET6;
#ifdef HAVE_SIN6_LEN
sin6->sin6_len = sizeof(struct sockaddr_in6);
@ -248,7 +250,8 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
m_reply = sctp_asconf_error_response(aph->correlation_id,
SCTP_CAUSE_INVALID_PARAM, (uint8_t *) aph,
aparam_length);
} else if (sctp_add_remote_addr(stcb, sa, &net, SCTP_DONOT_SETSCOPE,
} else if (sctp_add_remote_addr(stcb, sa, &net, stcb->asoc.port,
SCTP_DONOT_SETSCOPE,
SCTP_ADDR_DYNAMIC_ADDED) != 0) {
SCTPDBG(SCTP_DEBUG_ASCONF1,
"process_asconf_add_ip: error adding address\n");
@ -341,7 +344,7 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
}
v4addr = (struct sctp_ipv4addr_param *)ph;
sin = &store.sin;
bzero(sin, sizeof(*sin));
memset(sin, 0, sizeof(*sin));
sin->sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
sin->sin_len = sizeof(struct sockaddr_in);
@ -363,7 +366,7 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
}
v6addr = (struct sctp_ipv6addr_param *)ph;
sin6 = &store.sin6;
bzero(sin6, sizeof(*sin6));
memset(sin6, 0, sizeof(*sin6));
sin6->sin6_family = AF_INET6;
#ifdef HAVE_SIN6_LEN
sin6->sin6_len = sizeof(struct sockaddr_in6);
@ -476,7 +479,7 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
}
v4addr = (struct sctp_ipv4addr_param *)ph;
sin = &store.sin;
bzero(sin, sizeof(*sin));
memset(sin, 0, sizeof(*sin));
sin->sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
sin->sin_len = sizeof(struct sockaddr_in);
@ -496,7 +499,7 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
}
v6addr = (struct sctp_ipv6addr_param *)ph;
sin6 = &store.sin6;
bzero(sin6, sizeof(*sin6));
memset(sin6, 0, sizeof(*sin6));
sin6->sin6_family = AF_INET6;
#ifdef HAVE_SIN6_LEN
sin6->sin6_len = sizeof(struct sockaddr_in6);
@ -560,7 +563,9 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
(stcb->asoc.primary_destination->dest_state &
SCTP_ADDR_UNCONFIRMED) == 0) {
sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED, stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_TIMER+SCTP_LOC_7);
sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED,
stcb->sctp_ep, stcb, NULL,
SCTP_FROM_SCTP_ASCONF + SCTP_LOC_1);
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
SCTP_MOBILITY_FASTHANDOFF)) {
sctp_assoc_immediate_retrans(stcb,
@ -930,7 +935,7 @@ sctp_asconf_cleanup(struct sctp_tcb *stcb, struct sctp_nets *net)
* clear out any existing asconfs going out
*/
sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_ASCONF+SCTP_LOC_2);
SCTP_FROM_SCTP_ASCONF + SCTP_LOC_2);
stcb->asoc.asconf_seq_out_acked = stcb->asoc.asconf_seq_out;
/* remove the old ASCONF on our outbound queue */
sctp_toss_old_asconf(stcb);
@ -998,7 +1003,7 @@ sctp_assoc_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *dstnet)
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &stcb->asoc.primary_destination->ro._l_addr.sa);
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb,
stcb->asoc.deleted_primary,
SCTP_FROM_SCTP_TIMER+SCTP_LOC_8);
SCTP_FROM_SCTP_ASCONF + SCTP_LOC_3);
stcb->asoc.num_send_timers_up--;
if (stcb->asoc.num_send_timers_up < 0) {
stcb->asoc.num_send_timers_up = 0;
@ -1038,7 +1043,7 @@ sctp_net_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *net)
SCTPDBG(SCTP_DEBUG_ASCONF1, "net_immediate_retrans: RTO is %d\n", net->RTO);
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_TIMER+SCTP_LOC_5);
SCTP_FROM_SCTP_ASCONF + SCTP_LOC_4);
stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
net->error_count = 0;
TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
@ -1114,7 +1119,8 @@ sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
nexthop, the path will not be changed.
*/
SCTP_RTALLOC((sctp_route_t *)&net->ro,
stcb->sctp_ep->def_vrf_id);
stcb->sctp_ep->def_vrf_id,
stcb->sctp_ep->fibnum);
if (net->ro.ro_rt == NULL)
continue;
@ -1334,6 +1340,7 @@ sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
{
uint32_t status;
int pending_delete_queued = 0;
int last;
/* see if peer supports ASCONF */
if (stcb->asoc.asconf_supported == 0) {
@ -1344,8 +1351,13 @@ sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
* if this is deleting the last address from the assoc, mark it as
* pending.
*/
if ((type == SCTP_DEL_IP_ADDRESS) && !stcb->asoc.asconf_del_pending &&
(sctp_local_addr_count(stcb) < 2)) {
if ((type == SCTP_DEL_IP_ADDRESS) && !stcb->asoc.asconf_del_pending) {
if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
last = (sctp_local_addr_count(stcb) == 0);
} else {
last = (sctp_local_addr_count(stcb) == 1);
}
if (last) {
/* set the pending delete info only */
stcb->asoc.asconf_del_pending = 1;
stcb->asoc.asconf_addr_del_pending = ifa;
@ -1354,6 +1366,7 @@ sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
"asconf_queue_add: mark delete last address pending\n");
return (-1);
}
}
/* queue an asconf parameter */
status = sctp_asconf_queue_mgmt(stcb, ifa, type);
@ -1680,8 +1693,14 @@ sctp_handle_asconf_ack(struct mbuf *m, int offset,
* abort the asoc, since someone probably just hijacked us...
*/
if (serial_num == (asoc->asconf_seq_out + 1)) {
struct mbuf *op_err;
char msg[SCTP_DIAG_INFO_LEN];
SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got unexpected next serial number! Aborting asoc!\n");
sctp_abort_an_association(stcb->sctp_ep, stcb, NULL, SCTP_SO_NOT_LOCKED);
snprintf(msg, sizeof(msg), "Never sent serial number %8.8x",
serial_num);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
*abort_no_unlock = 1;
return;
}
@ -1695,7 +1714,7 @@ sctp_handle_asconf_ack(struct mbuf *m, int offset,
if (serial_num == asoc->asconf_seq_out - 1) {
/* stop our timer */
sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_ASCONF+SCTP_LOC_3);
SCTP_FROM_SCTP_ASCONF + SCTP_LOC_5);
}
/* process the ASCONF-ACK contents */
@ -1990,7 +2009,8 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
* sent when the state goes open.
*/
if (status == 0 &&
SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
(SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED))) {
#ifdef SCTP_TIMER_BASED_ASCONF
sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp,
stcb, stcb->asoc.primary_destination);
@ -2242,7 +2262,8 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
* count of queued params. If in the non-open state,
* these get sent when the assoc goes open.
*/
if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
(SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
if (status >= 0) {
num_queued++;
}
@ -2303,7 +2324,8 @@ sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
"set_primary_ip_address_sa: queued on tcb=%p, ",
(void *)stcb);
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
(SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
#ifdef SCTP_TIMER_BASED_ASCONF
sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
stcb->sctp_ep, stcb,
@ -2321,38 +2343,6 @@ sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
return (0);
}
void
sctp_set_primary_ip_address(struct sctp_ifa *ifa)
{
struct sctp_inpcb *inp;
/* go through all our PCB's */
LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) {
struct sctp_tcb *stcb;
/* process for all associations for this endpoint */
LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
/* queue an ASCONF:SET_PRIM_ADDR to be sent */
if (!sctp_asconf_queue_add(stcb, ifa,
SCTP_SET_PRIM_ADDR)) {
/* set primary queuing succeeded */
SCTPDBG(SCTP_DEBUG_ASCONF1, "set_primary_ip_address: queued on stcb=%p, ",
(void *)stcb);
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &ifa->address.sa);
if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
#ifdef SCTP_TIMER_BASED_ASCONF
sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
stcb->sctp_ep, stcb,
stcb->asoc.primary_destination);
#else
sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
#endif
}
}
} /* for each stcb */
} /* for each inp */
}
int
sctp_is_addr_pending(struct sctp_tcb *stcb, struct sctp_ifa *sctp_ifa)
{
@ -2615,7 +2605,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
SCTP_BUF_LEN(m_asconf_chk) = sizeof(struct sctp_asconf_chunk);
SCTP_BUF_LEN(m_asconf) = 0;
acp = mtod(m_asconf_chk, struct sctp_asconf_chunk *);
bzero(acp, sizeof(struct sctp_asconf_chunk));
memset(acp, 0, sizeof(struct sctp_asconf_chunk));
/* save pointers to lookup address and asconf params */
lookup_ptr = (caddr_t)(acp + 1); /* after the header */
ptr = mtod(m_asconf, caddr_t); /* beginning of cluster */
@ -2748,7 +2738,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
/* XXX for now, we send a IPv4 address of 0.0.0.0 */
lookup->ph.param_type = htons(SCTP_IPV4_ADDRESS);
lookup->ph.param_length = htons(SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param)));
bzero(lookup->addr, sizeof(struct in_addr));
memset(lookup->addr, 0, sizeof(struct in_addr));
SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param));
}
}
@ -3250,6 +3240,7 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
} else {
struct sctp_asconf_iterator *asc;
struct sctp_laddr *wi;
int ret;
SCTP_MALLOC(asc, struct sctp_asconf_iterator *,
sizeof(struct sctp_asconf_iterator),
@ -3271,7 +3262,7 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
wi->action = type;
atomic_add_int(&ifa->refcount, 1);
LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr);
(void)sctp_initiate_iterator(sctp_asconf_iterator_ep,
ret = sctp_initiate_iterator(sctp_asconf_iterator_ep,
sctp_asconf_iterator_stcb,
sctp_asconf_iterator_ep_end,
SCTP_PCB_ANY_FLAGS,
@ -3279,6 +3270,12 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
SCTP_ASOC_ANY_STATE,
(void *)asc, 0,
sctp_asconf_iterator_end, inp, 0);
if (ret) {
SCTP_PRINTF("Failed to initiate iterator for addr_mgmt_ep_sa\n");
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EFAULT);
sctp_asconf_iterator_end(asc, 0);
return (EFAULT);
}
}
return (0);
} else {

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 324056 2017-09-27 13:05:23Z tuexen $");
#endif
#ifndef _NETINET_SCTP_ASCONF_H_
@ -72,9 +74,6 @@ extern int32_t
sctp_set_primary_ip_address_sa(struct sctp_tcb *,
struct sockaddr *);
extern void
sctp_set_primary_ip_address(struct sctp_ifa *ifa);
extern void
sctp_check_address_list(struct sctp_tcb *, struct mbuf *, int, int,
struct sockaddr *, uint16_t, uint16_t, uint16_t, uint16_t);

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.c 271673 2014-09-16 14:20:33Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.c 324971 2017-10-25 09:12:22Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -55,7 +57,7 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.c 271673 2014-09-16 14:20:33Z tue
void
sctp_clear_chunklist(sctp_auth_chklist_t *chklist)
{
bzero(chklist, sizeof(*chklist));
memset(chklist, 0, sizeof(*chklist));
/* chklist->num_chunks = 0; */
}
@ -94,7 +96,7 @@ sctp_copy_chunklist(sctp_auth_chklist_t *list)
if (new_list == NULL)
return (NULL);
/* copy it */
bcopy(list, new_list, sizeof(*new_list));
memcpy(new_list, list, sizeof(*new_list));
return (new_list);
}
@ -340,7 +342,7 @@ sctp_set_key(uint8_t *key, uint32_t keylen)
/* out of memory */
return (NULL);
}
bcopy(key, new_key->key, keylen);
memcpy(new_key->key, key, keylen);
return (new_key);
}
@ -429,28 +431,28 @@ sctp_compute_hashkey(sctp_key_t *key1, sctp_key_t *key2, sctp_key_t *shared)
if (sctp_compare_key(key1, key2) <= 0) {
/* key is shared + key1 + key2 */
if (sctp_get_keylen(shared)) {
bcopy(shared->key, key_ptr, shared->keylen);
memcpy(key_ptr, shared->key, shared->keylen);
key_ptr += shared->keylen;
}
if (sctp_get_keylen(key1)) {
bcopy(key1->key, key_ptr, key1->keylen);
memcpy(key_ptr, key1->key, key1->keylen);
key_ptr += key1->keylen;
}
if (sctp_get_keylen(key2)) {
bcopy(key2->key, key_ptr, key2->keylen);
memcpy(key_ptr, key2->key, key2->keylen);
}
} else {
/* key is shared + key2 + key1 */
if (sctp_get_keylen(shared)) {
bcopy(shared->key, key_ptr, shared->keylen);
memcpy(key_ptr, shared->key, shared->keylen);
key_ptr += shared->keylen;
}
if (sctp_get_keylen(key2)) {
bcopy(key2->key, key_ptr, key2->keylen);
memcpy(key_ptr, key2->key, key2->keylen);
key_ptr += key2->keylen;
}
if (sctp_get_keylen(key1)) {
bcopy(key1->key, key_ptr, key1->keylen);
memcpy(key_ptr, key1->key, key1->keylen);
}
}
return (new_key);
@ -544,7 +546,7 @@ sctp_insert_sharedkey(struct sctp_keyhead *shared_keys,
}
}
/* shouldn't reach here */
return (0);
return (EINVAL);
}
void
@ -560,7 +562,7 @@ sctp_auth_key_acquire(struct sctp_tcb *stcb, uint16_t key_id)
atomic_add_int(&skey->refcount, 1);
SCTPDBG(SCTP_DEBUG_AUTH2,
"%s: stcb %p key %u refcount acquire to %d\n",
__FUNCTION__, (void *)stcb, key_id, skey->refcount);
__func__, (void *)stcb, key_id, skey->refcount);
}
}
@ -578,20 +580,20 @@ sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id, int so_locked
/* decrement the ref count */
if (skey) {
sctp_free_sharedkey(skey);
SCTPDBG(SCTP_DEBUG_AUTH2,
"%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 */
if ((skey->refcount <= 1) && (skey->deactivated)) {
if ((skey->refcount <= 2) && (skey->deactivated)) {
/* notify ULP that key is no longer used */
sctp_ulp_notify(SCTP_NOTIFY_AUTH_FREE_KEY, stcb,
key_id, 0, so_locked);
SCTPDBG(SCTP_DEBUG_AUTH2,
"%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,10 +626,13 @@ sctp_copy_skeylist(const struct sctp_keyhead *src, struct sctp_keyhead *dest)
LIST_FOREACH(skey, src, next) {
new_skey = sctp_copy_sharedkey(skey);
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++;
}
}
}
return (count);
}
@ -772,7 +777,7 @@ sctp_serialize_hmaclist(sctp_hmaclist_t *list, uint8_t *ptr)
for (i = 0; i < list->num_algo; 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);
}
return (list->num_algo * sizeof(hmac_id));
@ -803,7 +808,7 @@ sctp_alloc_authinfo(void)
/* out of memory */
return (NULL);
}
bzero(new_authinfo, sizeof(*new_authinfo));
memset(new_authinfo, 0, sizeof(*new_authinfo));
return (new_authinfo);
}
@ -974,10 +979,10 @@ sctp_hmac(uint16_t hmac_algo, uint8_t *key, uint32_t keylen,
key = temp;
}
/* initialize the inner/outer pads with the key and "append" zeroes */
bzero(ipad, blocklen);
bzero(opad, blocklen);
bcopy(key, ipad, keylen);
bcopy(key, opad, keylen);
memset(ipad, 0, blocklen);
memset(opad, 0, blocklen);
memcpy(ipad, key, keylen);
memcpy(opad, key, keylen);
/* XOR the key with ipad and opad values */
for (i = 0; i < blocklen; i++) {
@ -1034,10 +1039,10 @@ sctp_hmac_m(uint16_t hmac_algo, uint8_t *key, uint32_t keylen,
key = temp;
}
/* initialize the inner/outer pads with the key and "append" zeroes */
bzero(ipad, blocklen);
bzero(opad, blocklen);
bcopy(key, ipad, keylen);
bcopy(key, opad, keylen);
memset(ipad, 0, blocklen);
memset(opad, 0, blocklen);
memcpy(ipad, key, keylen);
memcpy(opad, key, keylen);
/* XOR the key with ipad and opad values */
for (i = 0; i < blocklen; i++) {
@ -1145,7 +1150,7 @@ sctp_compute_hmac(uint16_t hmac_algo, sctp_key_t *key, uint8_t *text,
sctp_hmac_final(hmac_algo, &ctx, temp);
/* save the hashed key as the new key */
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,
digest));
@ -1179,7 +1184,7 @@ sctp_compute_hmac_m(uint16_t hmac_algo, sctp_key_t *key, struct mbuf *m,
sctp_hmac_final(hmac_algo, &ctx, temp);
/* save the hashed key as the new key */
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));
}
@ -1457,7 +1462,7 @@ sctp_auth_get_cookie_params(struct sctp_tcb *stcb, struct mbuf *m,
if (plen > sizeof(random_store))
break;
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)
return;
/* save the random and length for the key */
@ -1470,7 +1475,7 @@ sctp_auth_get_cookie_params(struct sctp_tcb *stcb, struct mbuf *m,
if (plen > sizeof(hmacs_store))
break;
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)
return;
/* save the hmacs list and num for the key */
@ -1492,7 +1497,7 @@ sctp_auth_get_cookie_params(struct sctp_tcb *stcb, struct mbuf *m,
if (plen > sizeof(chunks_store))
break;
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)
return;
chunks = (struct sctp_auth_chunk_list *)phdr;
@ -1524,17 +1529,17 @@ sctp_auth_get_cookie_params(struct sctp_tcb *stcb, struct mbuf *m,
/* copy in the RANDOM */
if (p_random != NULL) {
keylen = sizeof(*p_random) + random_len;
bcopy(p_random, new_key->key, keylen);
memcpy(new_key->key, p_random, keylen);
}
/* append in the AUTH chunks */
if (chunks != NULL) {
bcopy(chunks, new_key->key + keylen,
memcpy(new_key->key + keylen, chunks,
sizeof(*chunks) + num_chunks);
keylen += sizeof(*chunks) + num_chunks;
}
/* append in the HMACs */
if (hmacs != NULL) {
bcopy(hmacs, new_key->key + keylen,
memcpy(new_key->key + keylen, hmacs,
sizeof(*hmacs) + hmacs_len);
}
}
@ -1573,7 +1578,7 @@ sctp_fill_hmac_digest_m(struct mbuf *m, uint32_t auth_offset,
/* zero the digest + chunk padding */
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? */
if ((keyid != stcb->asoc.authinfo.assoc_keyid) ||
@ -1612,7 +1617,7 @@ sctp_fill_hmac_digest_m(struct mbuf *m, uint32_t auth_offset,
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;
uint8_t *data;
@ -1630,11 +1635,11 @@ sctp_bzero_m(struct mbuf *m, uint32_t m_offset, uint32_t size)
/* now use the rest of the mbuf chain */
while ((m_tmp != NULL) && (size > 0)) {
data = mtod(m_tmp, uint8_t *) + m_offset;
if (size > (uint32_t) SCTP_BUF_LEN(m_tmp)) {
bzero(data, SCTP_BUF_LEN(m_tmp));
size -= SCTP_BUF_LEN(m_tmp);
if (size > (uint32_t)(SCTP_BUF_LEN(m_tmp) - m_offset)) {
memset(data, 0, SCTP_BUF_LEN(m_tmp) - m_offset);
size -= SCTP_BUF_LEN(m_tmp) - m_offset;
} else {
bzero(data, size);
memset(data, 0, size);
size = 0;
}
/* clear the offset since it's only for the first mbuf */
@ -1678,8 +1683,8 @@ sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *auth,
/* is the indicated HMAC supported? */
if (!sctp_auth_is_supported_hmac(stcb->asoc.local_hmacs, hmac_id)) {
struct mbuf *m_err;
struct sctp_auth_invalid_hmac *err;
struct mbuf *op_err;
struct sctp_error_auth_invalid_hmac *cause;
SCTP_STAT_INCR(sctps_recvivalhmacid);
SCTPDBG(SCTP_DEBUG_AUTH1,
@ -1689,20 +1694,19 @@ sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *auth,
* report this in an Error Chunk: Unsupported HMAC
* Identifier
*/
m_err = sctp_get_mbuf_for_msg(sizeof(*err), 0, M_NOWAIT,
1, MT_HEADER);
if (m_err != NULL) {
op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_error_auth_invalid_hmac),
0, M_NOWAIT, 1, MT_HEADER);
if (op_err != NULL) {
/* 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 */
err = mtod(m_err, struct sctp_auth_invalid_hmac *);
bzero(err, sizeof(*err));
err->ph.param_type = htons(SCTP_CAUSE_UNSUPPORTED_HMACID);
err->ph.param_length = htons(sizeof(*err));
err->hmac_id = ntohs(hmac_id);
SCTP_BUF_LEN(m_err) = sizeof(*err);
cause = mtod(op_err, struct sctp_error_auth_invalid_hmac *);
cause->cause.code = htons(SCTP_CAUSE_UNSUPPORTED_HMACID);
cause->cause.length = htons(sizeof(struct sctp_error_auth_invalid_hmac));
cause->hmac_id = ntohs(hmac_id);
SCTP_BUF_LEN(op_err) = sizeof(struct sctp_error_auth_invalid_hmac);
/* queue it */
sctp_queue_op_err(stcb, m_err);
sctp_queue_op_err(stcb, op_err);
}
return (-1);
}
@ -1752,8 +1756,8 @@ sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *auth,
return (-1);
}
/* save a copy of the digest, zero the pseudo header, and validate */
bcopy(auth->hmac, digest, digestlen);
sctp_bzero_m(m, offset + sizeof(*auth), SCTP_SIZE32(digestlen));
memcpy(digest, auth->hmac, digestlen);
sctp_zero_m(m, offset + sizeof(*auth), SCTP_SIZE32(digestlen));
(void)sctp_compute_hmac_m(hmac_id, stcb->asoc.authinfo.recv_key,
m, offset, computed_digest);
@ -1823,8 +1827,8 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
sctp_m_freem(m_notify);
return;
}
control->spec_flags = M_NOTIFICATION;
control->length = SCTP_BUF_LEN(m_notify);
control->spec_flags = M_NOTIFICATION;
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb, control,
@ -1840,7 +1844,7 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
int
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;
int peer_supports_asconf = 0;
int peer_supports_auth = 0;
@ -1849,7 +1853,7 @@ sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
uint8_t saw_asconf_ack = 0;
/* 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) {
ptype = ntohs(phdr->param_type);
plen = ntohs(phdr->param_length);
@ -1863,11 +1867,15 @@ sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
if (ptype == SCTP_SUPPORTED_CHUNK_EXT) {
/* A supported extension chunk */
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;
if (plen > sizeof(local_store)) {
break;
}
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) {
return (-1);
}
@ -1885,7 +1893,6 @@ sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
}
}
} else if (ptype == SCTP_RANDOM) {
got_random = 1;
/* enforce the random length */
if (plen != (sizeof(struct sctp_auth_random) +
SCTP_AUTH_RANDOM_SIZE_REQUIRED)) {
@ -1893,20 +1900,23 @@ sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
"SCTP: invalid RANDOM len\n");
return (-1);
}
got_random = 1;
} else if (ptype == SCTP_HMAC_LIST) {
uint8_t store[SCTP_PARAM_BUFFER_SIZE];
struct sctp_auth_hmac_algo *hmacs;
uint8_t store[SCTP_PARAM_BUFFER_SIZE];
int num_hmacs;
if (plen > sizeof(store))
if (plen > sizeof(store)) {
break;
}
phdr = sctp_get_next_param(m, offset,
(struct sctp_paramhdr *)store, min(plen,sizeof(store)));
if (phdr == NULL)
(struct sctp_paramhdr *)store,
plen);
if (phdr == NULL) {
return (-1);
}
hmacs = (struct sctp_auth_hmac_algo *)phdr;
num_hmacs = (plen - sizeof(*hmacs)) /
sizeof(hmacs->hmac_ids[0]);
num_hmacs = (plen - sizeof(*hmacs)) / sizeof(hmacs->hmac_ids[0]);
/* validate the hmac list */
if (sctp_verify_hmac_param(hmacs, num_hmacs)) {
SCTPDBG(SCTP_DEBUG_AUTH1,
@ -1915,16 +1925,19 @@ sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
}
got_hmacs = 1;
} else if (ptype == SCTP_CHUNK_LIST) {
int i, num_chunks;
struct sctp_auth_chunk_list *chunks;
uint8_t chunks_store[SCTP_SMALL_CHUNK_STORE];
/* did the peer send a non-empty chunk list? */
struct sctp_auth_chunk_list *chunks = NULL;
int i, num_chunks;
if (plen > sizeof(chunks_store)) {
break;
}
phdr = sctp_get_next_param(m, offset,
(struct sctp_paramhdr *)chunks_store,
min(plen,sizeof(chunks_store)));
if (phdr == NULL)
plen);
if (phdr == NULL) {
return (-1);
}
/*-
* Flip through the list and mark that the
* peer supports asconf/asconf_ack.
@ -1947,8 +1960,8 @@ sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
if (offset >= limit) {
break;
}
phdr = sctp_get_next_param(m, offset, &parm_buf,
sizeof(parm_buf));
phdr = sctp_get_next_param(m, offset, &param_buf,
sizeof(param_buf));
}
/* validate authentication required parameters */
if (got_random && got_hmacs) {

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 310590 2016-12-26 11:06:41Z tuexen $");
#endif
#ifndef _NETINET_SCTP_AUTH_H_

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 310590 2016-12-26 11:06:41Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -129,6 +131,9 @@ static void
#endif
sctp_iterator_thread(void *v SCTP_UNUSED)
{
#if defined(__Userspace__)
sctp_userspace_set_threadname("SCTP iterator");
#endif
SCTP_IPI_ITERATOR_WQ_LOCK();
/* In FreeBSD this thread never terminates. */
#if defined(__FreeBSD__)
@ -201,11 +206,7 @@ sctp_startup_iterator(void)
#elif defined(__APPLE__)
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
if (sctp_userspace_thread_create(&sctp_it_ctl.thread_proc, &sctp_iterator_thread)) {
SCTP_PRINTF("ERROR: Creating sctp_iterator_thread failed.\n");
}
#endif
@ -312,11 +313,18 @@ sctp_is_vmware_interface(struct ifnet *ifn)
#endif
#if defined(__Userspace_os_Windows)
#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
sctp_init_ifns_for_vrf(int vrfid)
{
#if defined(INET) || defined(INET6)
struct ifaddrs *ifa;
struct sctp_ifa *sctp_ifa;
DWORD Err, AdapterAddrsSize;
PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt;
@ -342,6 +350,7 @@ sctp_init_ifns_for_vrf(int vrfid)
/* Get actual adapter information */
if ((Err = GetAdaptersAddresses(AF_INET, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) {
SCTP_PRINTF("GetAdaptersV4Addresses() failed with error code %d\n", Err);
FREE(pAdapterAddrs);
return;
}
/* Enumerate through each returned adapter and save its information */
@ -351,20 +360,14 @@ sctp_init_ifns_for_vrf(int vrfid)
if (IN4_ISLINKLOCAL_ADDRESS(&(((struct sockaddr_in *)(pUnicast->Address.lpSockaddr))->sin_addr))) {
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,
ifa,
NULL,
pAdapt->IfIndex,
(pAdapt->IfType == IF_TYPE_IEEE80211)?MIB_IF_TYPE_ETHERNET:pAdapt->IfType,
ifa->ifa_name,
(void *)ifa,
ifa->ifa_addr,
ifa->ifa_flags,
pAdapt->AdapterName,
NULL,
pUnicast->Address.lpSockaddr,
pAdapt->Flags,
0);
if (sctp_ifa) {
sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
@ -372,8 +375,7 @@ sctp_init_ifns_for_vrf(int vrfid)
}
}
}
if (pAdapterAddrs)
GlobalFree(pAdapterAddrs);
FREE(pAdapterAddrs);
#endif
#ifdef INET6
AdapterAddrsSize = 0;
@ -393,25 +395,21 @@ sctp_init_ifns_for_vrf(int vrfid)
/* Get actual adapter information */
if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) {
SCTP_PRINTF("GetAdaptersV6Addresses() failed with error code %d\n", Err);
FREE(pAdapterAddrs);
return;
}
/* Enumerate through each returned adapter and save its information */
for (pAdapt = pAdapterAddrs; pAdapt; pAdapt = pAdapt->Next) {
if (pAdapt->IfType == IF_TYPE_IEEE80211 || pAdapt->IfType == IF_TYPE_ETHERNET_CSMACD) {
for (pUnicast = pAdapt->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
ifa = (struct ifaddrs*)malloc(sizeof(struct ifaddrs));
ifa->ifa_name = _strdup(pAdapt->AdapterName);
ifa->ifa_flags = pAdapt->Flags;
ifa->ifa_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in6));
memcpy(ifa->ifa_addr, pUnicast->Address.lpSockaddr, sizeof(struct sockaddr_in6));
sctp_ifa = sctp_add_addr_to_vrf(0,
ifa,
NULL,
pAdapt->Ipv6IfIndex,
(pAdapt->IfType == IF_TYPE_IEEE80211)?MIB_IF_TYPE_ETHERNET:pAdapt->IfType,
ifa->ifa_name,
(void *)ifa,
ifa->ifa_addr,
ifa->ifa_flags,
pAdapt->AdapterName,
NULL,
pUnicast->Address.lpSockaddr,
pAdapt->Flags,
0);
if (sctp_ifa) {
sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
@ -419,8 +417,7 @@ sctp_init_ifns_for_vrf(int vrfid)
}
}
}
if (pAdapterAddrs)
GlobalFree(pAdapterAddrs);
FREE(pAdapterAddrs);
#endif
}
#elif defined(__Userspace__)
@ -429,15 +426,15 @@ sctp_init_ifns_for_vrf(int vrfid)
{
#if defined(INET) || defined(INET6)
int rc;
struct ifaddrs *ifa = NULL;
struct ifaddrs *ifa, *ifas;
struct sctp_ifa *sctp_ifa;
uint32_t ifa_flags;
rc = getifaddrs(&g_interfaces);
rc = getifaddrs(&ifas);
if (rc != 0) {
return;
}
for (ifa = g_interfaces; ifa; ifa = ifa->ifa_next) {
for (ifa = ifas; ifa; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL) {
continue;
}
@ -472,11 +469,11 @@ sctp_init_ifns_for_vrf(int vrfid)
#endif
ifa_flags = 0;
sctp_ifa = sctp_add_addr_to_vrf(vrfid,
ifa,
NULL,
if_nametoindex(ifa->ifa_name),
0,
ifa->ifa_name,
(void *)ifa,
NULL,
ifa->ifa_addr,
ifa_flags,
0);
@ -484,6 +481,7 @@ sctp_init_ifns_for_vrf(int vrfid)
sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
}
}
freeifaddrs(ifas);
#endif
}
#endif
@ -549,11 +547,11 @@ sctp_init_ifns_for_vrf(int vrfid)
}
snprintf(name, SCTP_IFNAMSIZ, "%s%d", ifnet_name(ifn), ifnet_unit(ifn));
sctp_ifa = sctp_add_addr_to_vrf(vrfid,
(void *)ifn,
(void *)ifn, /* XXX */
ifnet_index(ifn),
ifnet_type(ifn),
name,
(void *)ifa,
(void *)ifa, /* XXX */
ifa->ifa_addr,
ifa_flags,
0);
@ -585,7 +583,7 @@ sctp_init_ifns_for_vrf(int vrfid)
#endif
IFNET_RLOCK();
TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_list) {
TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_link) {
if (sctp_is_desired_interface_type(ifn) == 0) {
/* non desired type */
continue;
@ -595,7 +593,7 @@ sctp_init_ifns_for_vrf(int vrfid)
#else
IF_ADDR_LOCK(ifn);
#endif
TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
TAILQ_FOREACH(ifa, &ifn->if_addrhead, ifa_link) {
if (ifa->ifa_addr == NULL) {
continue;
}
@ -680,10 +678,14 @@ sctp_addr_change(struct ifaddr *ifa, int cmd)
return;
#else
uint32_t ifa_flags = 0;
if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) {
return;
}
/* BSD only has one VRF, if this changes
* we will need to hook in the right
* things here to get the id to pass to
* the address managment routine.
* the address management routine.
*/
if (SCTP_BASE_VAR(first_time) == 0) {
/* Special test to see if my ::1 will showup with this */
@ -758,11 +760,11 @@ sctp_add_or_del_interfaces(int (*pred)(struct ifnet *), int add)
struct ifaddr *ifa;
IFNET_RLOCK();
TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_list) {
TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_link) {
if (!(*pred)(ifn)) {
continue;
}
TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
TAILQ_FOREACH(ifa, &ifn->if_addrhead, ifa_link) {
sctp_addr_change(ifa, add ? RTM_ADD : RTM_DELETE);
}
}
@ -829,10 +831,6 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
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);

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 310590 2016-12-26 11:06:41Z tuexen $");
#endif
#ifndef _NETINET_SCTP_BSD_ADDR_H_

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -56,11 +58,20 @@
* Callout/Timer routines for OS that doesn't have them
*/
#if defined(__APPLE__) || defined(__Userspace__)
int ticks = 0;
static int ticks = 0;
#else
extern int ticks;
#endif
int sctp_get_tick_count(void) {
int ret;
SCTP_TIMERQ_LOCK();
ret = ticks;
SCTP_TIMERQ_UNLOCK();
return ret;
}
/*
* SCTP_TIMERQ_LOCK protects:
* - SCTP_BASE_INFO(callqueue)
@ -71,7 +82,7 @@ static sctp_os_timer_t *sctp_os_timer_next = NULL;
void
sctp_os_timer_init(sctp_os_timer_t *c)
{
bzero(c, sizeof(*c));
memset(c, 0, sizeof(*c));
}
void
@ -178,6 +189,7 @@ sctp_timeout(void *arg SCTP_UNUSED)
void *
user_sctp_timer_iterate(void *arg)
{
sctp_userspace_set_threadname("SCTP timer");
for (;;) {
#if defined (__Userspace_os_Windows)
Sleep(TIMEOUT_INTERVAL);
@ -203,18 +215,12 @@ sctp_start_timer(void)
* No need to do SCTP_TIMERQ_LOCK_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;
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) {
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);
}
#endif
}
#endif

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -57,15 +59,20 @@ __FBSDID("$FreeBSD$");
#define SCTP_TIMERQ_LOCK_INIT() InitializeCriticalSection(&SCTP_BASE_VAR(timer_mtx))
#define SCTP_TIMERQ_LOCK_DESTROY() DeleteCriticalSection(&SCTP_BASE_VAR(timer_mtx))
#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_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))
#endif
extern int ticks;
#endif
int sctp_get_tick_count(void);
TAILQ_HEAD(calloutlist, sctp_callout);
struct sctp_callout {

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 310590 2016-12-26 11:06:41Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -100,7 +102,7 @@ sctp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net)
sctp_enforce_cwnd_limit(assoc, net);
net->ssthresh = assoc->peers_rwnd;
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
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,
0, net->cwnd);
#endif
@ -195,7 +197,7 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb,
net->cwnd = net->ssthresh;
sctp_enforce_cwnd_limit(asoc, net);
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
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,
old_cwnd, net->cwnd);
#endif
@ -212,7 +214,7 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb,
/* Mark end of the window */
asoc->fast_recovery_tsn = asoc->sending_seq - 1;
} else {
asoc->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1;
asoc->fast_recovery_tsn = lchk->rec.data.tsn - 1;
}
/*
@ -225,11 +227,12 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb,
/* Mark end of the window */
net->fast_recovery_tsn = asoc->sending_seq - 1;
} 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,
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,
stcb->sctp_ep, stcb, net);
}
@ -244,7 +247,7 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb,
}
/* 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_GAINING 3 /* Gaining, step down possible */
@ -275,7 +278,7 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
/* Probe point 5 */
probepoint |= ((5 << 16) | 1);
SDT_PROBE(sctp, cwnd, net, rttvar,
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -298,7 +301,7 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
oth |= net->cc_mod.rtcc.step_cnt;
oth <<= 16;
oth |= net->cc_mod.rtcc.last_step_state;
SDT_PROBE(sctp, cwnd, net, rttstep,
SDT_PROBE5(sctp, cwnd, net, rttstep,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -324,7 +327,7 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
/* Probe point 6 */
probepoint |= ((6 << 16) | 0);
SDT_PROBE(sctp, cwnd, net, rttvar,
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -338,7 +341,7 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
oth |= net->cc_mod.rtcc.step_cnt;
oth <<= 16;
oth |= net->cc_mod.rtcc.last_step_state;
SDT_PROBE(sctp, cwnd, net, rttstep,
SDT_PROBE5(sctp, cwnd, net, rttstep,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -370,7 +373,7 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
/* Probe point 7 */
probepoint |= ((7 << 16) | net->cc_mod.rtcc.ret_from_eq);
SDT_PROBE(sctp, cwnd, net, rttvar,
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -431,7 +434,7 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
/* PROBE POINT 1 */
probepoint |= ((1 << 16) | 1);
SDT_PROBE(sctp, cwnd, net, rttvar,
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -448,7 +451,7 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
/* Probe point 2 */
probepoint |= ((2 << 16) | 0);
SDT_PROBE(sctp, cwnd, net, rttvar,
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -463,7 +466,7 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
oth |= net->cc_mod.rtcc.step_cnt;
oth <<= 16;
oth |= net->cc_mod.rtcc.last_step_state;
SDT_PROBE(sctp, cwnd, net, rttstep,
SDT_PROBE5(sctp, cwnd, net, rttstep,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -488,7 +491,7 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
/* Probe point 3 */
probepoint |= ((3 << 16) | 0);
SDT_PROBE(sctp, cwnd, net, rttvar,
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -502,7 +505,7 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
oth |= net->cc_mod.rtcc.step_cnt;
oth <<= 16;
oth |= net->cc_mod.rtcc.last_step_state;
SDT_PROBE(sctp, cwnd, net, rttstep,
SDT_PROBE5(sctp, cwnd, net, rttstep,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -524,7 +527,7 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
/* Probe point 4 */
probepoint |= ((4 << 16) | 0);
SDT_PROBE(sctp, cwnd, net, rttvar,
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -538,7 +541,7 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
oth |= net->cc_mod.rtcc.step_cnt;
oth <<= 16;
oth |= net->cc_mod.rtcc.last_step_state;
SDT_PROBE(sctp, cwnd, net, rttstep,
SDT_PROBE5(sctp, cwnd, net, rttstep,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -586,7 +589,7 @@ cc_bw_increase(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
/* PROBE POINT 0 */
probepoint = (((uint64_t)net->cwnd) << 32);
SDT_PROBE(sctp, cwnd, net, rttvar,
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -600,7 +603,7 @@ cc_bw_increase(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
oth |= net->cc_mod.rtcc.step_cnt;
oth <<= 16;
oth |= net->cc_mod.rtcc.last_step_state;
SDT_PROBE(sctp, cwnd, net, rttstep,
SDT_PROBE5(sctp, cwnd, net, rttstep,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -617,7 +620,7 @@ cc_bw_increase(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
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
*/
static int
@ -711,7 +714,7 @@ cc_bw_limit(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw)
#endif
}
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
SDT_PROBE(sctp, cwnd, net, rttvar,
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((nbw << 32) | inst_bw),
((net->cc_mod.rtcc.lbw_rtt << 32) | rtt),
@ -885,7 +888,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
(((uint32_t)(stcb->sctp_ep->sctp_lport)) << 16) |
(stcb->rport);
SDT_PROBE(sctp, cwnd, net, rttvar,
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
nbw,
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -985,7 +988,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
SCTP_CWND_LOG_FROM_SS);
}
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
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,
@ -1049,7 +1052,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
net->cwnd += incr;
sctp_enforce_cwnd_limit(asoc, net);
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
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,
@ -1090,7 +1093,7 @@ sctp_cwnd_update_exit_pf_common(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_n
#endif
net->cwnd = net->mtu;
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
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,
old_cwnd, net->cwnd);
#endif
@ -1163,7 +1166,7 @@ sctp_cwnd_update_after_timeout(struct sctp_tcb *stcb, struct sctp_nets *net)
net->cwnd = net->mtu;
net->partial_bytes_acked = 0;
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
SDT_PROBE(sctp, cwnd, net, to,
SDT_PROBE5(sctp, cwnd, net, to,
stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net,
@ -1198,7 +1201,7 @@ 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);
}
} 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->cwnd -= (net->mtu * num_pkt_lost);
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
@ -1218,7 +1221,7 @@ sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets *
}
net->cwnd = net->ssthresh;
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
SDT_PROBE(sctp, cwnd, net, ecn,
SDT_PROBE5(sctp, cwnd, net, ecn,
stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net,
@ -1339,7 +1342,7 @@ sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb,
if (net->cwnd - old_cwnd != 0) {
/* log only changes */
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
SDT_PROBE(sctp, cwnd, net, pd,
SDT_PROBE5(sctp, cwnd, net, pd,
stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net,
@ -1364,7 +1367,7 @@ sctp_cwnd_update_after_output(struct sctp_tcb *stcb,
net->cwnd = (net->flight_size + (burst_limit * net->mtu));
sctp_enforce_cwnd_limit(&stcb->asoc, net);
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
SDT_PROBE(sctp, cwnd, net, bl,
SDT_PROBE5(sctp, cwnd, net, bl,
stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net,
@ -1381,7 +1384,7 @@ sctp_cwnd_update_after_sack(struct sctp_tcb *stcb,
struct sctp_association *asoc,
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);
}
@ -1389,13 +1392,13 @@ static void
sctp_cwnd_update_after_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net,
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);
}
/* Here starts the RTCCVAR type CC invented by RRS which
* 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.
*/
static void
@ -1442,7 +1445,7 @@ sctp_cwnd_new_rtcc_transmission_begins(struct sctp_tcb *stcb,
probepoint = (((uint64_t)net->cwnd) << 32);
/* Probe point 8 */
probepoint |= ((8 << 16) | 0);
SDT_PROBE(sctp, cwnd, net, rttvar,
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((net->cc_mod.rtcc.lbw << 32) | 0),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
@ -1503,7 +1506,7 @@ sctp_set_rtcc_initial_cc_param(struct sctp_tcb *stcb,
vtag = (net->rtt << 32) |
(((uint32_t)(stcb->sctp_ep->sctp_lport)) << 16) |
(stcb->rport);
SDT_PROBE(sctp, cwnd, net, rttvar,
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
0,
0,
@ -1600,7 +1603,7 @@ sctp_cwnd_update_rtcc_after_sack(struct sctp_tcb *stcb,
struct sctp_association *asoc,
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);
}
@ -1616,13 +1619,13 @@ sctp_rtt_rtcc_calculated(struct sctp_tcb *stcb SCTP_UNUSED,
struct sctp_hs_raise_drop {
int32_t cwnd;
int32_t increase;
int32_t drop_percent;
int8_t increase;
int8_t drop_percent;
};
#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 */
{118, 2, 44}, /* 1 */
{221, 3, 41}, /* 2 */
@ -1722,7 +1725,7 @@ sctp_hs_cwnd_increase(struct sctp_tcb *stcb, struct sctp_nets *net)
}
}
net->last_hs_used = indx;
incr = ((sctp_cwnd_adjust[indx].increase) << 10);
incr = (((int32_t)sctp_cwnd_adjust[indx].increase) << 10);
net->cwnd += incr;
}
sctp_enforce_cwnd_limit(&stcb->asoc, net);
@ -1748,7 +1751,7 @@ sctp_hs_cwnd_decrease(struct sctp_tcb *stcb, struct sctp_nets *net)
} else {
/* drop by the proper amount */
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;
/* now where are we */
indx = net->last_hs_used;
@ -1805,7 +1808,7 @@ sctp_hs_cwnd_update_after_fr(struct sctp_tcb *stcb,
/* Mark end of the window */
asoc->fast_recovery_tsn = asoc->sending_seq - 1;
} else {
asoc->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1;
asoc->fast_recovery_tsn = lchk->rec.data.tsn - 1;
}
/*
@ -1818,11 +1821,12 @@ sctp_hs_cwnd_update_after_fr(struct sctp_tcb *stcb,
/* Mark end of the window */
net->fast_recovery_tsn = asoc->sending_seq - 1;
} 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,
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,
stcb->sctp_ep, stcb, net);
}
@ -2331,7 +2335,7 @@ sctp_htcp_cwnd_update_after_fr(struct sctp_tcb *stcb,
/* Mark end of the window */
asoc->fast_recovery_tsn = asoc->sending_seq - 1;
} else {
asoc->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1;
asoc->fast_recovery_tsn = lchk->rec.data.tsn - 1;
}
/*
@ -2344,11 +2348,12 @@ sctp_htcp_cwnd_update_after_fr(struct sctp_tcb *stcb,
/* Mark end of the window */
net->fast_recovery_tsn = asoc->sending_seq - 1;
} 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,
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,
stcb->sctp_ep, stcb, net);
}
@ -2403,7 +2408,7 @@ 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)
sctp_set_initial_cc_param,

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 324615 2017-10-14 10:02:59Z tuexen $");
#endif
#ifndef _NETINET_SCTP_CONSTANTS_H_
@ -71,6 +73,10 @@ extern void getwintimeofday(struct timeval *tv);
*/
#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 */
#define SCTP_COUNT_LIMIT 40
@ -98,10 +104,6 @@ extern void getwintimeofday(struct timeval *tv);
*/
#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 */
#define ALPHA_BASE (1<<7) /* 1.0 with shift << 7 */
#define BETA_MIN (1<<6) /* 0.5 with shift << 7 */
@ -276,7 +278,7 @@ extern void getwintimeofday(struct timeval *tv);
#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
* 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
@ -346,6 +348,7 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_RTT_FROM_NON_DATA 0
#define SCTP_RTT_FROM_DATA 1
#define PR_SCTP_UNORDERED_FLAG 0x0001
/* IP hdr (20/40) + 12+2+2 (enet) + sctp common 12 */
#define SCTP_FIRST_MBUF_RESV 68
@ -387,8 +390,8 @@ extern void getwintimeofday(struct timeval *tv);
/* align to 32-bit sizes */
#define SCTP_SIZE32(x) ((((x) + 3) >> 2) << 2)
#define IS_SCTP_CONTROL(a) ((a)->chunk_type != SCTP_DATA)
#define IS_SCTP_DATA(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) || ((a)->chunk_type == SCTP_IDATA))
/* SCTP parameter types */
@ -466,7 +469,7 @@ extern void getwintimeofday(struct timeval *tv);
/*
* 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_INUSE 0x0001
@ -517,7 +520,7 @@ extern void getwintimeofday(struct timeval *tv);
/* Maximum the mapping array will grow to (TSN mapping array) */
#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
/* how much we grow the mapping array each call */
#define SCTP_MAPPING_ARRAY_INCR 32
@ -558,11 +561,9 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_TIMER_TYPE_INPKILL 15
#define SCTP_TIMER_TYPE_ASOCKILL 16
#define SCTP_TIMER_TYPE_ADDR_WQ 17
#define SCTP_TIMER_TYPE_ZERO_COPY 18
#define SCTP_TIMER_TYPE_ZCOPY_SENDQ 19
#define SCTP_TIMER_TYPE_PRIM_DELETED 20
#define SCTP_TIMER_TYPE_PRIM_DELETED 18
/* add new timers here - and increment LAST */
#define SCTP_TIMER_TYPE_LAST 21
#define SCTP_TIMER_TYPE_LAST 19
#define SCTP_IS_TIMER_TYPE_VALID(t) (((t) > SCTP_TIMER_TYPE_NONE) && \
((t) < SCTP_TIMER_TYPE_LAST))
@ -628,10 +629,6 @@ extern void getwintimeofday(struct timeval *tv);
/* 30 seconds + RTO (in ms) */
#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
* ticks the current secret will live.
@ -654,7 +651,7 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_DEF_PMTU_RAISE_SEC 600 /* 10 min between raise attempts */
/* How many streams I request initally by default */
/* How many streams I request initially by default */
#define SCTP_OSTREAM_INITIAL 10
#define SCTP_ISTREAM_INITIAL 2048
@ -777,7 +774,7 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_DEFAULT_SPLIT_POINT_MIN 2904
/* Maximum length of diagnostic information in error causes */
#define SCTP_DIAG_INFO_LEN 64
#define SCTP_DIAG_INFO_LEN 128
/* ABORT CODES and other tell-tale location
* codes are generated by adding the below
@ -797,6 +794,7 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_FROM_SCTP_PEELOFF 0xa0000000
#define SCTP_FROM_SCTP_PANDA 0xb0000000
#define SCTP_FROM_SCTP_SYSCTL 0xc0000000
#define SCTP_FROM_SCTP_CC_FUNCTIONS 0xd0000000
/* Location ID's */
#define SCTP_LOC_1 0x00000001
@ -832,6 +830,8 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_LOC_31 0x0000001f
#define SCTP_LOC_32 0x00000020
#define SCTP_LOC_33 0x00000021
#define SCTP_LOC_34 0x00000022
#define SCTP_LOC_35 0x00000023
/* Free assoc codes */
@ -908,12 +908,20 @@ extern void getwintimeofday(struct timeval *tv);
/* modular comparison */
/* 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))))
#define SCTP_SSN_GE(a, b) (SCTP_SSN_GT(a, b) || (a == b))
#define SCTP_TSN_GT(a, b) (((a < b) && ((uint32_t)(b - a) > (1U<<31))) || \
#define SCTP_UINT16_GE(a, b) (SCTP_UINT16_GT(a, b) || (a == b))
#define SCTP_UINT32_GT(a, b) (((a < b) && ((uint32_t)(b - a) > (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 */
#define SCTP_IS_TSN_PRESENT(arry, gap) ((arry[(gap >> 3)] >> (gap & 0x07)) & 0x01)
@ -936,7 +944,7 @@ extern void getwintimeofday(struct timeval *tv);
* 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 *
* 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
/*
@ -984,9 +992,6 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_SO_NOT_LOCKED 0
#define SCTP_HOLDS_LOCK 1
#define SCTP_NOT_LOCKED 0
/*-
* For address locks, do we hold the lock?
*/
@ -1002,10 +1007,7 @@ extern void getwintimeofday(struct timeval *tv);
(((uint8_t *)&(a)->s_addr)[1] == 168)))
#define IN4_ISLOOPBACK_ADDRESS(a) \
((((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))
(((uint8_t *)&(a)->s_addr)[0] == 127)
#define IN4_ISLINKLOCAL_ADDRESS(a) \
((((uint8_t *)&(a)->s_addr)[0] == 169) && \

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 310590 2016-12-26 11:06:41Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -94,7 +96,7 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_crc32.c 235828 2012-05-23 11:26:28Z tu
* 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,
0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
@ -150,7 +152,7 @@ static uint32_t sctp_crc_tableil8_o32[256] =
* 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,
0x9D14C3B8, 0x8EB65BCF, 0xBA51F356, 0xA9F36B21, 0xD39EA264, 0xC03C3A13, 0xF4DB928A, 0xE7790AFD,
@ -206,7 +208,7 @@ static uint32_t sctp_crc_tableil8_o40[256] =
* 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,
0x38513EC5, 0x9D10ACBB, 0x773E6CC8, 0xD27FFEB6, 0xA68F9ADF, 0x03CE08A1, 0xE9E0C8D2, 0x4CA15AAC,
@ -262,7 +264,7 @@ static uint32_t sctp_crc_tableil8_o48[256] =
* 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,
0xF64463E6, 0x2B01C95E, 0x49234067, 0x9466EADF, 0x8D665215, 0x5023F8AD, 0x32017194, 0xEF44DB2C,
@ -318,7 +320,7 @@ static uint32_t sctp_crc_tableil8_o56[256] =
* 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,
0xC5670B91, 0xFD76643D, 0xB545D4C9, 0x8D54BB65, 0x2522B521, 0x1D33DA8D, 0x55006A79, 0x6D1105D5,
@ -374,7 +376,7 @@ static uint32_t sctp_crc_tableil8_o64[256] =
* 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,
0x6006181F, 0x8F367306, 0xBB8AB8DC, 0x54BAD3C5, 0xD2F32F68, 0x3DC34471, 0x097F8FAB, 0xE64FE4B2,
@ -430,7 +432,7 @@ uint32_t sctp_crc_tableil8_o72[256] =
* 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,
0x4E2DFD53, 0x262ED19B, 0x9E2BA4C3, 0xF628880B, 0xEBCD3882, 0x83CE144A, 0x3BCB6112, 0x53C84DDA,
@ -486,7 +488,7 @@ static uint32_t sctp_crc_tableil8_o80[256] =
* 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,
0x423B04DA, 0x0B0779FD, 0xD043FE94, 0x997F83B3, 0x632686B7, 0x2A1AFB90, 0xF15E7CF9, 0xB86201DE,
@ -613,7 +615,7 @@ multitable_crc32c(uint32_t crc32c,
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,
0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
@ -696,8 +698,11 @@ singletable_crc32c(uint32_t crc32c,
return (crc32c);
}
#if defined(__Userspace__)
uint32_t
#else
static uint32_t
#endif
calculate_crc32c(uint32_t crc32c,
const unsigned char *buffer,
unsigned int length)
@ -710,7 +715,11 @@ calculate_crc32c(uint32_t crc32c,
}
#endif /* FreeBSD < 80000 || other OS */
#if defined(__Userspace__)
uint32_t
#else
static uint32_t
#endif
sctp_finalize_crc32c(uint32_t crc32c)
{
uint32_t result;

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 309607 2016-12-06 10:21:25Z tuexen $");
#endif
#ifndef _NETINET_SCTP_CRC32_H_
@ -48,6 +50,8 @@ void sctp_delayed_cksum(struct mbuf *, uint32_t offset);
#endif /* _KERNEL */
#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);
#endif
#endif

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 309682 2016-12-07 19:30:59Z tuexen $");
#endif
#ifndef _NETINET_SCTP_HEADER_H_
@ -153,9 +155,9 @@ struct sctp_supported_chunk_types_param {
*/
struct sctp_data {
uint32_t tsn;
uint16_t stream_id;
uint16_t stream_sequence;
uint32_t protocol_id;
uint16_t sid;
uint16_t ssn;
uint32_t ppid;
/* user data follows */
} SCTP_PACKED;
@ -164,6 +166,23 @@ struct sctp_data_chunk {
struct sctp_data dp;
} 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
*/
@ -220,34 +239,6 @@ struct sctp_state_cookie { /* this is our definition... */
*/
} 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 */
struct sctp_state_cookie_param {
struct sctp_paramhdr ph;
@ -388,28 +379,11 @@ struct sctp_shutdown_complete_chunk {
struct sctp_chunkhdr ch;
} 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_paramhdr ph;
uint32_t indication;
} 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
*/
@ -437,10 +411,16 @@ struct sctp_forward_tsn_chunk {
} SCTP_PACKED;
struct sctp_strseq {
uint16_t stream;
uint16_t sequence;
uint16_t sid;
uint16_t ssn;
} SCTP_PACKED;
struct sctp_strseq_mid {
uint16_t sid;
uint16_t flags;
uint32_t mid;
};
struct sctp_forward_tsn_msg {
struct sctphdr sh;
struct sctp_forward_tsn_chunk msg;
@ -572,12 +552,6 @@ struct sctp_auth_chunk {
uint8_t hmac[];
} 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
* pieces. If ENCE is missing we could have a couple of blocks. This way we
@ -631,7 +605,7 @@ struct sctp_auth_invalid_hmac {
#include <packoff.h>
#endif
#if defined(__Userspace_os_Windows)
#pragma pack ()
#pragma pack(pop)
#endif
#undef SCTP_PACKED
#endif /* !__sctp_header_h__ */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 310590 2016-12-26 11:06:41Z tuexen $");
#endif
#ifndef _NETINET_SCTP_INDATA_H_
@ -44,36 +46,31 @@ struct sctp_queued_to_read *
sctp_build_readq_entry(struct sctp_tcb *stcb,
struct sctp_nets *net,
uint32_t tsn, uint32_t ppid,
uint32_t context, uint16_t stream_no,
uint16_t stream_seq, uint8_t flags,
uint32_t context, uint16_t sid,
uint32_t mid, uint8_t flags,
struct mbuf *dm);
#define sctp_build_readq_entry_mac(_ctl, in_it, context, net, tsn, ppid, stream_no, stream_seq, flags, dm) do { \
#define sctp_build_readq_entry_mac(_ctl, in_it, context, net, tsn, ppid, sid, flags, dm, tfsn, mid) do { \
if (_ctl) { \
atomic_add_int(&((net)->ref_count), 1); \
(_ctl)->sinfo_stream = stream_no; \
(_ctl)->sinfo_ssn = stream_seq; \
memset(_ctl, 0, sizeof(struct sctp_queued_to_read)); \
(_ctl)->sinfo_stream = sid; \
TAILQ_INIT(&_ctl->reasm); \
(_ctl)->top_fsn = tfsn; \
(_ctl)->mid = mid; \
(_ctl)->sinfo_flags = (flags << 8); \
(_ctl)->sinfo_ppid = ppid; \
(_ctl)->sinfo_context = context; \
(_ctl)->sinfo_timetolive = 0; \
(_ctl)->fsn_included = 0xffffffff; \
(_ctl)->top_fsn = 0xffffffff; \
(_ctl)->sinfo_tsn = tsn; \
(_ctl)->sinfo_cumtsn = tsn; \
(_ctl)->sinfo_assoc_id = sctp_get_associd((in_it)); \
(_ctl)->length = 0; \
(_ctl)->held_length = 0; \
(_ctl)->whoFrom = net; \
(_ctl)->data = dm; \
(_ctl)->tail_mbuf = NULL; \
(_ctl)->aux_data = NULL; \
(_ctl)->stcb = (in_it); \
(_ctl)->port_from = (in_it)->rport; \
(_ctl)->spec_flags = 0; \
(_ctl)->do_not_ref_stcb = 0; \
(_ctl)->end_added = 0; \
(_ctl)->pdapi_aborted = 0; \
(_ctl)->some_taken = 0; \
} \
} while (0)
@ -114,14 +111,8 @@ sctp_update_acked(struct sctp_tcb *, struct sctp_shutdown_chunk *, 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_nets *, uint32_t *,
#if defined(__FreeBSD__)
uint8_t, uint32_t,
#endif
uint32_t, uint16_t);
struct sctp_nets *, uint32_t *);
void sctp_slide_mapping_arrays(struct sctp_tcb *stcb);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 310590 2016-12-26 11:06:41Z tuexen $");
#endif
#ifndef _NETINET_SCTP_INPUT_H_
@ -48,7 +50,7 @@ sctp_common_input_processing(struct mbuf **, int, int, int,
#endif
uint8_t,
#if defined(__FreeBSD__)
uint8_t, uint32_t,
uint8_t, uint32_t, uint16_t,
#endif
uint32_t, uint16_t);

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2006-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2011, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2011, by Michael Tuexen. All rights reserved.
@ -274,7 +276,7 @@ typedef char* caddr_t;
#else /* !defined(Userspace_os_Windows) */
#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(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Linux) || defined(__Userspace_os_NetBSD) || defined(__Userspace_os_OpenBSD) || defined(__Userspace_os_NaCl) || defined(__Userspace_os_Fuchsia)
#include <pthread.h>
#endif
typedef pthread_mutex_t userland_mutex_t;
@ -345,7 +347,7 @@ struct udphdr {
};
struct iovec {
unsigned long len;
size_t len;
char *buf;
};
@ -463,7 +465,7 @@ struct sx {int dummy;};
#include <sys/priv.h>
#endif
/* #include <sys/random.h> */
/* #include <sys/limits.h> */
#include <limits.h>
/* #include <machine/cpu.h> */
#if defined(__Userspace_os_Darwin)
@ -530,7 +532,6 @@ struct sx {int dummy;};
#endif
#if !defined(__Userspace_os_Windows)
#include <netinet/ip6.h>
#include <netinet/icmp6.h>
#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)
#include "user_ip6_var.h"
@ -763,14 +764,6 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT);
umem_cache_destroy(zone);
#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.
*/
@ -810,8 +803,6 @@ sctp_hashfreedestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask);
/*__Userspace__ defining KTR_SUBSYS 1 as done in sctp_os_macosx.h */
#define KTR_SUBSYS 1
#define sctp_get_tick_count() (ticks)
/* The packed define for 64 bit platforms */
#if !defined(__Userspace_os_Windows)
#define SCTP_PACKED __attribute__((packed))
@ -888,7 +879,7 @@ static inline void sctp_userspace_rtalloc(sctp_route_t *ro)
* 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 */
static inline void sctp_userspace_rtfree(sctp_rtentry_t *rt)
@ -949,13 +940,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_RELEASE_HEADER(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)
@ -1007,11 +991,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_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_SHA1_CTX struct sctp_sha1_context
@ -1044,12 +1023,22 @@ int sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af);
struct sockaddr_conn {
#ifdef HAVE_SCONN_LEN
uint8_t sconn_len;
#endif
uint8_t sconn_family;
#else
uint16_t sconn_family;
#endif
uint16_t sconn_port;
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.
*/
@ -1127,7 +1116,7 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int a
#endif
#define I_AM_HERE \
do { \
SCTP_PRINTF("%s:%d at %s\n", __FILE__, __LINE__ , __FUNCTION__); \
SCTP_PRINTF("%s:%d at %s\n", __FILE__, __LINE__ , __func__); \
} while (0)
#ifndef timevalsub
@ -1168,4 +1157,6 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int a
((tvp)->tv_sec cmp (uvp)->tv_sec))
#endif
#define SCTP_IS_LISTENING(inp) ((inp->sctp_flags & SCTP_PCB_FLAGS_ACCEPTING) != 0)
#endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 323861 2017-09-21 11:56:31Z tuexen $");
#endif
#ifndef _NETINET_SCTP_OUTPUT_H_
@ -83,14 +85,15 @@ void sctp_send_initiate(struct sctp_inpcb *, struct sctp_tcb *, int
);
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,
struct sockaddr *, struct sockaddr *,
struct sctphdr *, struct sctp_init_chunk *,
#if defined(__FreeBSD__)
uint8_t, uint32_t,
#endif
uint32_t, uint16_t, int);
uint32_t, uint16_t);
struct mbuf *
sctp_arethere_unrecognized_parameters(struct mbuf *, int, int *,
@ -122,7 +125,7 @@ void sctp_send_shutdown_complete(struct sctp_tcb *, struct sctp_nets *, int);
void sctp_send_shutdown_complete2(struct sockaddr *, struct sockaddr *,
struct sctphdr *,
#if defined(__FreeBSD__)
uint8_t, uint32_t,
uint8_t, uint32_t, uint16_t,
#endif
uint32_t, uint16_t);
@ -140,6 +143,11 @@ void sctp_fix_ecn_echo(struct sctp_association *);
void sctp_move_chunks_from_net(struct sctp_tcb *stcb, struct sctp_nets *net);
#define SCTP_DATA_CHUNK_OVERHEAD(stcb) ((stcb)->asoc.idata_supported ? \
sizeof(struct sctp_idata_chunk) : \
sizeof(struct sctp_data_chunk))
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
int
sctp_output(struct sctp_inpcb *, struct mbuf *, struct sockaddr *,
@ -197,32 +205,35 @@ 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);
sctp_add_stream_reset_result(struct sctp_tmit_chunk *, uint32_t, uint32_t);
void
sctp_add_stream_reset_result(struct sctp_tmit_chunk *, uint32_t, uint32_t);
sctp_send_deferred_reset_response(struct sctp_tcb *,
struct sctp_stream_reset_list *,
int);
void
sctp_add_stream_reset_result_tsn(struct sctp_tmit_chunk *,
uint32_t, uint32_t, uint32_t, uint32_t);
int
sctp_send_stream_reset_out_if_possible(struct sctp_tcb *, 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);
void
sctp_send_abort(struct mbuf *, int, struct sockaddr *, struct sockaddr *,
struct sctphdr *, uint32_t, struct mbuf *,
#if defined(__FreeBSD__)
uint8_t, uint32_t,
uint8_t, uint32_t, uint16_t,
#endif
uint32_t, uint16_t);
void sctp_send_operr_to(struct sockaddr *, struct sockaddr *,
struct sctphdr *, uint32_t, struct mbuf *,
#if defined(__FreeBSD__)
uint8_t, uint32_t,
uint8_t, uint32_t, uint16_t,
#endif
uint32_t, uint16_t);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 325370 2017-11-03 20:46:12Z tuexen $");
#endif
#ifndef _NETINET_SCTP_PCB_H_
@ -109,7 +111,7 @@ struct sctp_ifa {
* appropriate locks. This is for V6.
*/
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 localifa_flags;
uint32_t vrf_id; /* vrf_id of this addr (for deleting) */
@ -311,25 +313,37 @@ struct sctp_base_info {
userland_thread_t timer_thread;
uint8_t timer_thread_should_exit;
#if !defined(__Userspace_os_Windows)
pthread_mutexattr_t mtx_attr;
#if defined(INET) || defined(INET6)
int userspace_route;
userland_thread_t recvthreadroute;
#endif
#endif
#ifdef INET
#if defined(__Userspace_os_Windows)
SOCKET userspace_rawsctp;
SOCKET userspace_udpsctp;
#else
int userspace_rawsctp;
int userspace_udpsctp;
#endif
userland_thread_t recvthreadraw;
userland_thread_t recvthreadudp;
#endif
#ifdef INET6
#if defined(__Userspace_os_Windows)
SOCKET userspace_rawsctp6;
SOCKET userspace_udpsctp6;
#else
int userspace_rawsctp6;
int userspace_udpsctp6;
#endif
userland_thread_t recvthreadraw6;
userland_thread_t recvthreadudp6;
#endif
int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df);
void (*debug_printf)(const char *format, ...);
int crc32c_offloaded;
#endif
};
@ -361,6 +375,7 @@ struct sctp_pcb {
sctp_auth_chklist_t *local_auth_chunks;
sctp_hmaclist_t *local_hmacs;
uint16_t default_keyid;
uint32_t default_mtu;
/* various thresholds */
/* Max times I will init at a guy */
@ -388,10 +403,6 @@ struct sctp_pcb {
*/
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;
/* defaults to 0 */
int auto_close_time;
@ -433,7 +444,7 @@ struct sctp_pcbtsn_rlog {
struct sctp_inpcb {
/*-
* 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 {
struct inpcb inp;
@ -484,6 +495,7 @@ struct sctp_inpcb {
uint8_t ecn_supported;
uint8_t prsctp_supported;
uint8_t auth_supported;
uint8_t idata_supported;
uint8_t asconf_supported;
uint8_t reconfig_supported;
uint8_t nrsack_supported;
@ -564,6 +576,7 @@ struct sctp_inpcb {
uint32_t i_am_here_line;
#endif
uint32_t def_vrf_id;
uint16_t fibnum;
#ifdef SCTP_MVRF
uint32_t *m_vrf_ids;
uint32_t num_vrfs;
@ -793,16 +806,16 @@ void sctp_inpcb_free(struct sctp_inpcb *, int, int);
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
struct sctp_tcb *
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__)
struct sctp_tcb *
sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *,
int *, uint32_t, uint32_t, PKTHREAD);
int *, uint32_t, uint32_t, uint16_t, uint16_t, PKTHREAD);
#else
/* proc will be NULL for __Userspace__ */
struct sctp_tcb *
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 *);
#endif
int sctp_free_assoc(struct sctp_inpcb *, struct sctp_tcb *, int, int);
@ -817,13 +830,9 @@ 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);
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 *);
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 *);
@ -838,7 +847,7 @@ void sctp_del_local_addr_restricted(struct sctp_tcb *, struct sctp_ifa *);
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
sctp_set_primary_addr(struct sctp_tcb *, struct sockaddr *,
@ -846,11 +855,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 *);
/* void sctp_drain(void); */
int sctp_destination_is_reachable(struct sctp_tcb *, struct sockaddr *);
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
* indicates run on ONLY assoc's of the specified endpoint.
@ -871,10 +883,5 @@ sctp_queue_to_mcore(struct mbuf *m, int off, int cpu_to_use);
#endif
#ifdef INVARIANTS
void
sctp_validate_no_locks(struct sctp_inpcb *inp);
#endif
#endif /* _KERNEL */
#endif /* !__sctp_pcb_h__ */

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -277,11 +279,13 @@ sctp_get_peeloff(struct socket *head, sctp_assoc_t assoc_id, int *error)
sctp_feature_off(n_inp, SCTP_PCB_FLAGS_AUTOCLOSE);
n_inp->sctp_ep.auto_close_time = 0;
sctp_timer_stop(SCTP_TIMER_TYPE_AUTOCLOSE, n_inp, stcb, NULL,
SCTP_FROM_SCTP_PEELOFF+SCTP_LOC_1);
SCTP_FROM_SCTP_PEELOFF + SCTP_LOC_1);
}
/* Turn off any non-blocking semantic. */
SOCK_LOCK(newso);
SCTP_CLEAR_SO_NBIO(newso);
newso->so_state |= SS_ISCONNECTED;
SOCK_UNLOCK(newso);
/* We remove it right away */
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__)

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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
#ifndef _NETINET_SCTP_PEELOFF_H_

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -164,63 +166,51 @@
#define SCTP_INP_LOCK_INIT(_inp) \
InitializeCriticalSection(&(_inp)->inp_mtx)
#define SCTP_ASOC_CREATE_LOCK_INIT(_inp) \
InitializeCriticalSection(&(_inp)->inp_create_mtx)
#define SCTP_INP_LOCK_DESTROY(_inp) \
DeleteCriticalSection(&(_inp)->inp_mtx)
#define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp) \
DeleteCriticalSection(&(_inp)->inp_create_mtx)
#ifdef SCTP_LOCK_LOGGING
#define SCTP_INP_RLOCK(_inp) do { \
if(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) sctp_log_lock(_inp, (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); \
} while (0)
#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); \
} while (0)
#else
#define SCTP_INP_RLOCK(_inp) do { \
EnterCriticalSection(&(_inp)->inp_mtx); \
} while (0)
#define SCTP_INP_WLOCK(_inp) do { \
EnterCriticalSection(&(_inp)->inp_mtx); \
} while (0)
#define SCTP_INP_RLOCK(_inp) \
EnterCriticalSection(&(_inp)->inp_mtx)
#define SCTP_INP_WLOCK(_inp) \
EnterCriticalSection(&(_inp)->inp_mtx)
#endif
#define SCTP_TCB_SEND_LOCK_INIT(_tcb) \
InitializeCriticalSection(&(_tcb)->tcb_send_mtx)
#define SCTP_TCB_SEND_LOCK_DESTROY(_tcb) \
DeleteCriticalSection(&(_tcb)->tcb_send_mtx)
#define SCTP_TCB_SEND_LOCK(_tcb) do { \
EnterCriticalSection(&(_tcb)->tcb_send_mtx); \
} while (0)
#define SCTP_TCB_SEND_LOCK(_tcb) \
EnterCriticalSection(&(_tcb)->tcb_send_mtx)
#define SCTP_TCB_SEND_UNLOCK(_tcb) \
LeaveCriticalSection(&(_tcb)->tcb_send_mtx)
#define SCTP_INP_INCR_REF(_inp) atomic_add_int(&((_inp)->refcount), 1)
#define SCTP_INP_DECR_REF(_inp) atomic_add_int(&((_inp)->refcount), -1)
#define SCTP_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
#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); \
} while (0)
#else
#define SCTP_ASOC_CREATE_LOCK(_inp) do { \
EnterCriticalSection(&(_inp)->inp_create_mtx); \
} while (0)
#define SCTP_ASOC_CREATE_LOCK(_inp) \
EnterCriticalSection(&(_inp)->inp_create_mtx)
#endif
#define SCTP_INP_RUNLOCK(_inp) \
@ -240,65 +230,81 @@
#define SCTP_TCB_LOCK_INIT(_tcb) \
InitializeCriticalSection(&(_tcb)->tcb_mtx)
#define SCTP_TCB_LOCK_DESTROY(_tcb) \
DeleteCriticalSection(&(_tcb)->tcb_mtx)
#ifdef SCTP_LOCK_LOGGING
#define SCTP_TCB_LOCK(_tcb) do { \
if(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) sctp_log_lock(_tcb->sctp_ep, _tcb, SCTP_LOG_LOCK_TCB); \
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); \
} while (0)
#else
#define SCTP_TCB_LOCK(_tcb) do { \
EnterCriticalSection(&(_tcb)->tcb_mtx); \
} while (0)
#define SCTP_TCB_LOCK(_tcb) \
EnterCriticalSection(&(_tcb)->tcb_mtx)
#endif
#define SCTP_TCB_TRYLOCK(_tcb) ((TryEnterCriticalSection(&(_tcb)->tcb_mtx)))
#define SCTP_TCB_UNLOCK(_tcb) do { \
LeaveCriticalSection(&(_tcb)->tcb_mtx); \
} while (0)
#define SCTP_TCB_UNLOCK(_tcb) \
LeaveCriticalSection(&(_tcb)->tcb_mtx)
#define SCTP_TCB_LOCK_ASSERT(_tcb)
#else /* all Userspaces except Windows */
#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() \
(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() \
(void)pthread_mutex_lock(&SCTP_BASE_INFO(wq_addr_mtx))
#define SCTP_WQ_ADDR_UNLOCK() \
(void)pthread_mutex_unlock(&SCTP_BASE_INFO(wq_addr_mtx))
#endif
#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() \
(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() \
(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() \
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_RUNLOCK() \
(void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_WUNLOCK() \
(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() \
(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() \
(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() \
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_pktlog_mtx))
#define SCTP_IP_PKTLOG_UNLOCK() \
(void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_pktlog_mtx))
#endif
/*
@ -307,88 +313,120 @@
* or cookie secrets we lock the INP level.
*/
#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) \
(void)pthread_mutex_destroy(&(_inp)->inp_rdata_mtx)
#define SCTP_INP_READ_LOCK(_inp) do { \
(void)pthread_mutex_lock(&(_inp)->inp_rdata_mtx); \
} while (0)
#ifdef INVARIANTS
#define SCTP_INP_READ_LOCK(_inp) \
KASSERT(pthread_mutex_lock(&(_inp)->inp_rdata_mtx) == 0, ("%s: inp_rdata_mtx already locked", __func__))
#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) \
(void)pthread_mutex_unlock(&(_inp)->inp_rdata_mtx)
#endif
#define SCTP_INP_LOCK_INIT(_inp) \
(void)pthread_mutex_init(&(_inp)->inp_mtx, NULL)
#define SCTP_ASOC_CREATE_LOCK_INIT(_inp) \
(void)pthread_mutex_init(&(_inp)->inp_create_mtx, NULL)
(void)pthread_mutex_init(&(_inp)->inp_mtx, &SCTP_BASE_VAR(mtx_attr))
#define SCTP_INP_LOCK_DESTROY(_inp) \
(void)pthread_mutex_destroy(&(_inp)->inp_mtx)
#define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp) \
(void)pthread_mutex_destroy(&(_inp)->inp_create_mtx)
#ifdef INVARIANTS
#ifdef SCTP_LOCK_LOGGING
#define SCTP_INP_RLOCK(_inp) do { \
if(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_INP);\
(void)pthread_mutex_lock(&(_inp)->inp_mtx); \
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_INP); \
KASSERT(pthread_mutex_lock(&(_inp)->inp_mtx) == 0, ("%s: inp_mtx already locked", __func__)) \
} while (0)
#define SCTP_INP_WLOCK(_inp) do { \
sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_INP);\
(void)pthread_mutex_lock(&(_inp)->inp_mtx); \
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_INP); \
KASSERT(pthread_mutex_lock(&(_inp)->inp_mtx) == 0, ("%s: inp_mtx already locked", __func__))
} while (0)
#else
#define SCTP_INP_RLOCK(_inp) do { \
(void)pthread_mutex_lock(&(_inp)->inp_mtx); \
} while (0)
#define SCTP_INP_WLOCK(_inp) do { \
(void)pthread_mutex_lock(&(_inp)->inp_mtx); \
} while (0)
#define SCTP_INP_RLOCK(_inp) \
KASSERT(pthread_mutex_lock(&(_inp)->inp_mtx) == 0, ("%s: inp_mtx already locked", __func__))
#define SCTP_INP_WLOCK(_inp) \
KASSERT(pthread_mutex_lock(&(_inp)->inp_mtx) == 0, ("%s: inp_mtx already locked", __func__))
#endif
#define SCTP_TCB_SEND_LOCK_INIT(_tcb) \
(void)pthread_mutex_init(&(_tcb)->tcb_send_mtx, NULL)
#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)
#define SCTP_INP_RUNLOCK(_inp) \
KASSERT(pthread_mutex_unlock(&(_inp)->inp_mtx) == 0, ("%s: inp_mtx not locked", __func__))
#define SCTP_INP_WUNLOCK(_inp) \
KASSERT(pthread_mutex_unlock(&(_inp)->inp_mtx) == 0, ("%s: inp_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, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_CREATE); \
(void)pthread_mutex_lock(&(_inp)->inp_create_mtx); \
#define SCTP_INP_RLOCK(_inp) do { \
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
sctp_log_lock(_inp, NULL, SCTP_LOG_LOCK_INP); \
(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)
#else
#define SCTP_ASOC_CREATE_LOCK(_inp) do { \
(void)pthread_mutex_lock(&(_inp)->inp_create_mtx); \
} while (0)
#define SCTP_INP_RLOCK(_inp) \
(void)pthread_mutex_lock(&(_inp)->inp_mtx)
#define SCTP_INP_WLOCK(_inp) \
(void)pthread_mutex_lock(&(_inp)->inp_mtx)
#endif
#define SCTP_INP_RUNLOCK(_inp) \
(void)pthread_mutex_unlock(&(_inp)->inp_mtx)
#define SCTP_INP_WUNLOCK(_inp) \
(void)pthread_mutex_unlock(&(_inp)->inp_mtx)
#endif
#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) \
(void)pthread_mutex_unlock(&(_inp)->inp_create_mtx)
#endif
/*
* For the majority of things (once we have found the association) we will
* lock the actual association mutex. This will protect all the assoiciation
@ -398,28 +436,38 @@
*/
#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) \
(void)pthread_mutex_destroy(&(_tcb)->tcb_mtx)
#ifdef INVARIANTS
#ifdef SCTP_LOCK_LOGGING
#define SCTP_TCB_LOCK(_tcb) do { \
if(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) sctp_log_lock(_tcb->sctp_ep, _tcb, SCTP_LOG_LOCK_TCB); \
(void)pthread_mutex_lock(&(_tcb)->tcb_mtx); \
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) \
sctp_log_lock(_tcb->sctp_ep, _tcb, SCTP_LOG_LOCK_TCB); \
KASSERT(pthread_mutex_lock(&(_tcb)->tcb_mtx) == 0, ("%s: tcb_mtx already locked", __func__)) \
} while (0)
#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 { \
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); \
} while (0)
#else
#define SCTP_TCB_LOCK(_tcb) \
(void)pthread_mutex_lock(&(_tcb)->tcb_mtx)
#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_LOCK_ASSERT(_tcb)
#endif
#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 /* SCTP_PER_SOCKET_LOCKING */
@ -434,29 +482,36 @@
#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 */
/* socket locks */
#if defined(__Userspace__)
#if defined(__Userspace_os_Windows)
#define SOCKBUF_LOCK_ASSERT(_so_buf)
#define SOCKBUF_LOCK(_so_buf) EnterCriticalSection(&(_so_buf)->sb_mtx)
#define SOCKBUF_UNLOCK(_so_buf) LeaveCriticalSection(&(_so_buf)->sb_mtx)
#define SOCK_LOCK(_so) SOCKBUF_LOCK(&(_so)->so_rcv)
#define SOCK_UNLOCK(_so) SOCKBUF_UNLOCK(&(_so)->so_rcv)
#define SOCKBUF_LOCK(_so_buf) \
EnterCriticalSection(&(_so_buf)->sb_mtx)
#define SOCKBUF_UNLOCK(_so_buf) \
LeaveCriticalSection(&(_so_buf)->sb_mtx)
#define SOCK_LOCK(_so) \
SOCKBUF_LOCK(&(_so)->so_rcv)
#define SOCK_UNLOCK(_so) \
SOCKBUF_UNLOCK(&(_so)->so_rcv)
#else
#define SOCKBUF_LOCK_ASSERT(_so_buf) KASSERT(pthread_mutex_trylock(SOCKBUF_MTX(_so_buf)) == EBUSY, ("%s: socket buffer not locked", __func__))
#define SOCKBUF_LOCK(_so_buf) pthread_mutex_lock(SOCKBUF_MTX(_so_buf))
#define SOCKBUF_UNLOCK(_so_buf) pthread_mutex_unlock(SOCKBUF_MTX(_so_buf))
#define SOCK_LOCK(_so) SOCKBUF_LOCK(&(_so)->so_rcv)
#define SOCK_UNLOCK(_so) SOCKBUF_UNLOCK(&(_so)->so_rcv)
#define SOCKBUF_LOCK_ASSERT(_so_buf) \
KASSERT(pthread_mutex_trylock(SOCKBUF_MTX(_so_buf)) == EBUSY, ("%s: socket buffer not locked", __func__))
#ifdef INVARIANTS
#define SOCKBUF_LOCK(_so_buf) \
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
#else
#define SOCK_LOCK(_so)
#define SOCK_UNLOCK(_so)
#define SOCKBUF_LOCK(_so_buf)
#define SOCKBUF_UNLOCK(_so_buf)
#define SOCKBUF_LOCK_ASSERT(_so_buf)
#define SOCK_LOCK(_so) \
SOCKBUF_LOCK(&(_so)->so_rcv)
#define SOCK_UNLOCK(_so) \
SOCKBUF_UNLOCK(&(_so)->so_rcv)
#endif
#define SCTP_STATLOG_INIT_LOCK()
@ -470,18 +525,12 @@
InitializeCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_DESTROY() \
DeleteCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_RLOCK() \
do { \
EnterCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx)); \
} while (0)
EnterCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_RUNLOCK() \
LeaveCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_WLOCK() \
do { \
EnterCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx)); \
} while (0)
EnterCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_WUNLOCK() \
LeaveCriticalSection(&SCTP_BASE_INFO(ipi_addr_mtx))
@ -489,154 +538,122 @@
/* iterator locks */
#define SCTP_ITERATOR_LOCK_INIT() \
InitializeCriticalSection(&sctp_it_ctl.it_mtx)
#define SCTP_ITERATOR_LOCK_DESTROY() \
DeleteCriticalSection(&sctp_it_ctl.it_mtx)
#define SCTP_ITERATOR_LOCK() \
do { \
EnterCriticalSection(&sctp_it_ctl.it_mtx); \
} while (0)
EnterCriticalSection(&sctp_it_ctl.it_mtx)
#define SCTP_ITERATOR_UNLOCK() \
LeaveCriticalSection(&sctp_it_ctl.it_mtx)
#define SCTP_ITERATOR_LOCK_DESTROY() \
DeleteCriticalSection(&sctp_it_ctl.it_mtx)
#define SCTP_IPI_ITERATOR_WQ_INIT() \
InitializeCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx)
#define SCTP_IPI_ITERATOR_WQ_DESTROY() \
DeleteCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx)
#define SCTP_IPI_ITERATOR_WQ_LOCK() \
do { \
EnterCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx); \
} while (0)
EnterCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx)
#define SCTP_IPI_ITERATOR_WQ_UNLOCK() \
LeaveCriticalSection(&sctp_it_ctl.ipi_iterator_wq_mtx)
#else /* end of __Userspace_os_Windows */
/* address list locks */
#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() \
(void)pthread_mutex_destroy(&SCTP_BASE_INFO(ipi_addr_mtx))
#ifdef INVARIANTS
#define SCTP_IPI_ADDR_RLOCK() \
do { \
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_addr_mtx)); \
} while (0)
KASSERT(pthread_mutex_lock(&SCTP_BASE_INFO(ipi_addr_mtx)) == 0, ("%s: ipi_addr_mtx already locked", __func__))
#define SCTP_IPI_ADDR_RUNLOCK() \
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__))
#else
#define SCTP_IPI_ADDR_RLOCK() \
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_RUNLOCK() \
(void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_WLOCK() \
do { \
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_addr_mtx)); \
} while (0)
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_addr_mtx))
#define SCTP_IPI_ADDR_WUNLOCK() \
(void)pthread_mutex_unlock(&SCTP_BASE_INFO(ipi_addr_mtx))
#endif
/* iterator locks */
#define SCTP_ITERATOR_LOCK_INIT() \
(void)pthread_mutex_init(&sctp_it_ctl.it_mtx, NULL)
#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)
(void)pthread_mutex_init(&sctp_it_ctl.it_mtx, &SCTP_BASE_VAR(mtx_attr))
#define SCTP_ITERATOR_LOCK_DESTROY() \
(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() \
(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() \
(void)pthread_mutex_destroy(&sctp_it_ctl.ipi_iterator_wq_mtx)
#ifdef INVARIANTS
#define SCTP_IPI_ITERATOR_WQ_LOCK() \
do { \
(void)pthread_mutex_lock(&sctp_it_ctl.ipi_iterator_wq_mtx); \
} while (0)
KASSERT(pthread_mutex_lock(&sctp_it_ctl.ipi_iterator_wq_mtx) == 0, ("%s: ipi_iterator_wq_mtx already locked", __func__))
#define SCTP_IPI_ITERATOR_WQ_UNLOCK() \
KASSERT(pthread_mutex_unlock(&sctp_it_ctl.ipi_iterator_wq_mtx) == 0, ("%s: ipi_iterator_wq_mtx not locked", __func__))
#else
#define SCTP_IPI_ITERATOR_WQ_LOCK() \
(void)pthread_mutex_lock(&sctp_it_ctl.ipi_iterator_wq_mtx)
#define SCTP_IPI_ITERATOR_WQ_UNLOCK() \
(void)pthread_mutex_unlock(&sctp_it_ctl.ipi_iterator_wq_mtx)
#endif
#endif
#define SCTP_INCR_EP_COUNT() \
do { \
atomic_add_int(&SCTP_BASE_INFO(ipi_count_ep), 1); \
} while (0)
atomic_add_int(&SCTP_BASE_INFO(ipi_count_ep), 1)
#define SCTP_DECR_EP_COUNT() \
do { \
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_ep), 1); \
} while (0)
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_ep), 1)
#define SCTP_INCR_ASOC_COUNT() \
do { \
atomic_add_int(&SCTP_BASE_INFO(ipi_count_asoc), 1); \
} while (0)
atomic_add_int(&SCTP_BASE_INFO(ipi_count_asoc), 1)
#define SCTP_DECR_ASOC_COUNT() \
do { \
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_asoc), 1); \
} while (0)
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_asoc), 1)
#define SCTP_INCR_LADDR_COUNT() \
do { \
atomic_add_int(&SCTP_BASE_INFO(ipi_count_laddr), 1); \
} while (0)
atomic_add_int(&SCTP_BASE_INFO(ipi_count_laddr), 1)
#define SCTP_DECR_LADDR_COUNT() \
do { \
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_laddr), 1); \
} while (0)
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_laddr), 1)
#define SCTP_INCR_RADDR_COUNT() \
do { \
atomic_add_int(&SCTP_BASE_INFO(ipi_count_raddr), 1); \
} while (0)
atomic_add_int(&SCTP_BASE_INFO(ipi_count_raddr), 1)
#define SCTP_DECR_RADDR_COUNT() \
do { \
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_raddr), 1); \
} while (0)
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_raddr), 1)
#define SCTP_INCR_CHK_COUNT() \
do { \
atomic_add_int(&SCTP_BASE_INFO(ipi_count_chunk), 1); \
} while (0)
atomic_add_int(&SCTP_BASE_INFO(ipi_count_chunk), 1)
#define SCTP_DECR_CHK_COUNT() \
do { \
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_chunk), 1); \
} while (0)
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_chunk), 1)
#define SCTP_INCR_READQ_COUNT() \
do { \
atomic_add_int(&SCTP_BASE_INFO(ipi_count_readq), 1); \
} while (0)
atomic_add_int(&SCTP_BASE_INFO(ipi_count_readq), 1)
#define SCTP_DECR_READQ_COUNT() \
do { \
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_readq), 1); \
} while (0)
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_readq), 1)
#define SCTP_INCR_STRMOQ_COUNT() \
do { \
atomic_add_int(&SCTP_BASE_INFO(ipi_count_strmoq), 1); \
} while (0)
atomic_add_int(&SCTP_BASE_INFO(ipi_count_strmoq), 1)
#define SCTP_DECR_STRMOQ_COUNT() \
do { \
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_strmoq), 1); \
} while (0)
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_strmoq), 1)
#endif

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2013, by Michael Tuexen. All rights reserved.

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.

Просмотреть файл

@ -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 Randall Stewart. All rights reserved.
* Copyright (c) 2010-2012, by Robin Seggelmann. All rights reserved.
@ -28,7 +30,7 @@
#ifdef __FreeBSD__
#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 326180 2017-11-24 19:38:59Z tuexen $");
#endif
#include <netinet/sctp_pcb.h>
@ -57,7 +59,9 @@ sctp_ss_default_init(struct sctp_tcb *stcb, struct sctp_association *asoc,
{
uint16_t i;
TAILQ_INIT(&asoc->ss_data.out_wheel);
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,
* the scheduler of an existing association has
@ -79,13 +83,13 @@ sctp_ss_default_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (holds_lock == 0) {
SCTP_TCB_SEND_LOCK(stcb);
}
while (!TAILQ_EMPTY(&asoc->ss_data.out_wheel)) {
struct sctp_stream_out *strq = TAILQ_FIRST(&asoc->ss_data.out_wheel);
TAILQ_REMOVE(&asoc->ss_data.out_wheel, TAILQ_FIRST(&asoc->ss_data.out_wheel), ss_params.rr.next_spoke);
while (!TAILQ_EMPTY(&asoc->ss_data.out.wheel)) {
struct sctp_stream_out *strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
TAILQ_REMOVE(&asoc->ss_data.out.wheel, TAILQ_FIRST(&asoc->ss_data.out.wheel), ss_params.rr.next_spoke);
strq->ss_params.rr.next_spoke.tqe_next = 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) {
SCTP_TCB_SEND_UNLOCK(stcb);
}
@ -93,8 +97,16 @@ sctp_ss_default_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
}
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_prev = NULL;
return;
@ -112,7 +124,7 @@ sctp_ss_default_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (!TAILQ_EMPTY(&strq->outqueue) &&
(strq->ss_params.rr.next_spoke.tqe_next == 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);
}
if (holds_lock == 0) {
@ -124,7 +136,7 @@ sctp_ss_default_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
static int
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);
} else {
return (0);
@ -143,19 +155,19 @@ sctp_ss_default_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (TAILQ_EMPTY(&strq->outqueue) &&
(strq->ss_params.rr.next_spoke.tqe_next != NULL ||
strq->ss_params.rr.next_spoke.tqe_prev != NULL)) {
if (asoc->last_out_stream == strq) {
asoc->last_out_stream = TAILQ_PREV(asoc->last_out_stream,
if (asoc->ss_data.last_out_stream == strq) {
asoc->ss_data.last_out_stream = TAILQ_PREV(asoc->ss_data.last_out_stream,
sctpwheel_listhead,
ss_params.rr.next_spoke);
if (asoc->last_out_stream == NULL) {
asoc->last_out_stream = TAILQ_LAST(&asoc->ss_data.out_wheel,
if (asoc->ss_data.last_out_stream == NULL) {
asoc->ss_data.last_out_stream = TAILQ_LAST(&asoc->ss_data.out.wheel,
sctpwheel_listhead);
}
if (asoc->last_out_stream == strq) {
asoc->last_out_stream = NULL;
if (asoc->ss_data.last_out_stream == strq) {
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_prev = NULL;
}
@ -172,15 +184,18 @@ sctp_ss_default_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net,
{
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:
/* Find the next stream to use */
if (strqt == NULL) {
strq = TAILQ_FIRST(&asoc->ss_data.out_wheel);
strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
} else {
strq = TAILQ_NEXT(strqt, ss_params.rr.next_spoke);
if (strq == NULL) {
strq = TAILQ_FIRST(&asoc->ss_data.out_wheel);
strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
}
}
@ -200,7 +215,7 @@ default_again:
if (TAILQ_FIRST(&strq->outqueue) &&
TAILQ_FIRST(&strq->outqueue)->net != NULL &&
TAILQ_FIRST(&strq->outqueue)->net != net) {
if (strq == asoc->last_out_stream) {
if (strq == asoc->ss_data.last_out_stream) {
return (NULL);
} else {
strqt = strq;
@ -212,11 +227,25 @@ default_again:
}
static void
sctp_ss_default_scheduled(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net SCTP_UNUSED,
struct sctp_association *asoc SCTP_UNUSED,
struct sctp_stream_out *strq, int moved_how_much SCTP_UNUSED)
sctp_ss_default_scheduled(struct sctp_tcb *stcb,
struct sctp_nets *net 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;
}
@ -244,6 +273,26 @@ sctp_ss_default_set_value(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_associa
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.
* Always interates the streams in ascending order.
@ -261,17 +310,17 @@ sctp_ss_rr_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (!TAILQ_EMPTY(&strq->outqueue) &&
(strq->ss_params.rr.next_spoke.tqe_next == NULL) &&
(strq->ss_params.rr.next_spoke.tqe_prev == NULL)) {
if (TAILQ_EMPTY(&asoc->ss_data.out_wheel)) {
TAILQ_INSERT_HEAD(&asoc->ss_data.out_wheel, strq, ss_params.rr.next_spoke);
if (TAILQ_EMPTY(&asoc->ss_data.out.wheel)) {
TAILQ_INSERT_HEAD(&asoc->ss_data.out.wheel, strq, ss_params.rr.next_spoke);
} else {
strqt = TAILQ_FIRST(&asoc->ss_data.out_wheel);
while (strqt != NULL && (strqt->stream_no < strq->stream_no)) {
strqt = TAILQ_FIRST(&asoc->ss_data.out.wheel);
while (strqt != NULL && (strqt->sid < strq->sid)) {
strqt = TAILQ_NEXT(strqt, ss_params.rr.next_spoke);
}
if (strqt != NULL) {
TAILQ_INSERT_BEFORE(strqt, strq, ss_params.rr.next_spoke);
} 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 +339,7 @@ static struct sctp_stream_out *
sctp_ss_rrp_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net SCTP_UNUSED,
struct sctp_association *asoc)
{
return (asoc->last_out_stream);
return (asoc->ss_data.last_out_stream);
}
static void
@ -299,15 +348,15 @@ sctp_ss_rrp_packet_done(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net
{
struct sctp_stream_out *strq, *strqt;
strqt = asoc->last_out_stream;
strqt = asoc->ss_data.last_out_stream;
rrp_again:
/* Find the next stream to use */
if (strqt == NULL) {
strq = TAILQ_FIRST(&asoc->ss_data.out_wheel);
strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
} else {
strq = TAILQ_NEXT(strqt, ss_params.rr.next_spoke);
if (strq == NULL) {
strq = TAILQ_FIRST(&asoc->ss_data.out_wheel);
strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
}
}
@ -327,7 +376,7 @@ rrp_again:
if (TAILQ_FIRST(&strq->outqueue) &&
TAILQ_FIRST(&strq->outqueue)->net != NULL &&
TAILQ_FIRST(&strq->outqueue)->net != net) {
if (strq == asoc->last_out_stream) {
if (strq == asoc->ss_data.last_out_stream) {
strq = NULL;
} else {
strqt = strq;
@ -335,7 +384,7 @@ rrp_again:
}
}
}
asoc->last_out_stream = strq;
asoc->ss_data.last_out_stream = strq;
return;
}
@ -351,17 +400,17 @@ sctp_ss_prio_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (holds_lock == 0) {
SCTP_TCB_SEND_LOCK(stcb);
}
while (!TAILQ_EMPTY(&asoc->ss_data.out_wheel)) {
struct sctp_stream_out *strq = TAILQ_FIRST(&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);
if (clear_values) {
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, TAILQ_FIRST(&asoc->ss_data.out.wheel), ss_params.prio.next_spoke);
strq->ss_params.prio.next_spoke.tqe_next = 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) {
SCTP_TCB_SEND_UNLOCK(stcb);
}
@ -369,8 +418,16 @@ sctp_ss_prio_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
}
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_prev = NULL;
if (with_strq != NULL) {
@ -395,17 +452,17 @@ sctp_ss_prio_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (!TAILQ_EMPTY(&strq->outqueue) &&
(strq->ss_params.prio.next_spoke.tqe_next == NULL) &&
(strq->ss_params.prio.next_spoke.tqe_prev == NULL)) {
if (TAILQ_EMPTY(&asoc->ss_data.out_wheel)) {
TAILQ_INSERT_HEAD(&asoc->ss_data.out_wheel, strq, ss_params.prio.next_spoke);
if (TAILQ_EMPTY(&asoc->ss_data.out.wheel)) {
TAILQ_INSERT_HEAD(&asoc->ss_data.out.wheel, strq, ss_params.prio.next_spoke);
} 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) {
strqt = TAILQ_NEXT(strqt, ss_params.prio.next_spoke);
}
if (strqt != NULL) {
TAILQ_INSERT_BEFORE(strqt, strq, ss_params.prio.next_spoke);
} 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 +484,18 @@ sctp_ss_prio_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (TAILQ_EMPTY(&strq->outqueue) &&
(strq->ss_params.prio.next_spoke.tqe_next != NULL ||
strq->ss_params.prio.next_spoke.tqe_prev != NULL)) {
if (asoc->last_out_stream == strq) {
asoc->last_out_stream = TAILQ_PREV(asoc->last_out_stream, sctpwheel_listhead,
if (asoc->ss_data.last_out_stream == strq) {
asoc->ss_data.last_out_stream = TAILQ_PREV(asoc->ss_data.last_out_stream, sctpwheel_listhead,
ss_params.prio.next_spoke);
if (asoc->last_out_stream == NULL) {
asoc->last_out_stream = TAILQ_LAST(&asoc->ss_data.out_wheel,
if (asoc->ss_data.last_out_stream == NULL) {
asoc->ss_data.last_out_stream = TAILQ_LAST(&asoc->ss_data.out.wheel,
sctpwheel_listhead);
}
if (asoc->last_out_stream == strq) {
asoc->last_out_stream = NULL;
if (asoc->ss_data.last_out_stream == strq) {
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_prev = NULL;
}
@ -454,18 +511,18 @@ sctp_ss_prio_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net,
{
struct sctp_stream_out *strq, *strqt, *strqn;
strqt = asoc->last_out_stream;
strqt = asoc->ss_data.last_out_stream;
prio_again:
/* Find the next stream to use */
if (strqt == NULL) {
strq = TAILQ_FIRST(&asoc->ss_data.out_wheel);
strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
} else {
strqn = TAILQ_NEXT(strqt, ss_params.prio.next_spoke);
if (strqn != NULL &&
strqn->ss_params.prio.priority == strqt->ss_params.prio.priority) {
strq = strqn;
} else {
strq = TAILQ_FIRST(&asoc->ss_data.out_wheel);
strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
}
}
@ -485,7 +542,7 @@ prio_again:
if (TAILQ_FIRST(&strq->outqueue) &&
TAILQ_FIRST(&strq->outqueue)->net != NULL &&
TAILQ_FIRST(&strq->outqueue)->net != net) {
if (strq == asoc->last_out_stream) {
if (strq == asoc->ss_data.last_out_stream) {
return (NULL);
} else {
strqt = strq;
@ -531,16 +588,16 @@ sctp_ss_fb_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (holds_lock == 0) {
SCTP_TCB_SEND_LOCK(stcb);
}
while (!TAILQ_EMPTY(&asoc->ss_data.out_wheel)) {
struct sctp_stream_out *strq = TAILQ_FIRST(&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);
if (clear_values) {
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, TAILQ_FIRST(&asoc->ss_data.out.wheel), ss_params.fb.next_spoke);
strq->ss_params.fb.next_spoke.tqe_next = 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) {
SCTP_TCB_SEND_UNLOCK(stcb);
}
@ -548,8 +605,16 @@ sctp_ss_fb_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
}
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_prev = NULL;
if (with_strq != NULL) {
@ -573,7 +638,7 @@ sctp_ss_fb_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
(strq->ss_params.fb.next_spoke.tqe_prev == NULL)) {
if (strq->ss_params.fb.rounds < 0)
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) {
SCTP_TCB_SEND_UNLOCK(stcb);
@ -593,18 +658,18 @@ sctp_ss_fb_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (TAILQ_EMPTY(&strq->outqueue) &&
(strq->ss_params.fb.next_spoke.tqe_next != NULL ||
strq->ss_params.fb.next_spoke.tqe_prev != NULL)) {
if (asoc->last_out_stream == strq) {
asoc->last_out_stream = TAILQ_PREV(asoc->last_out_stream, sctpwheel_listhead,
if (asoc->ss_data.last_out_stream == strq) {
asoc->ss_data.last_out_stream = TAILQ_PREV(asoc->ss_data.last_out_stream, sctpwheel_listhead,
ss_params.fb.next_spoke);
if (asoc->last_out_stream == NULL) {
asoc->last_out_stream = TAILQ_LAST(&asoc->ss_data.out_wheel,
if (asoc->ss_data.last_out_stream == NULL) {
asoc->ss_data.last_out_stream = TAILQ_LAST(&asoc->ss_data.out.wheel,
sctpwheel_listhead);
}
if (asoc->last_out_stream == strq) {
asoc->last_out_stream = NULL;
if (asoc->ss_data.last_out_stream == strq) {
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_prev = NULL;
}
@ -620,11 +685,11 @@ sctp_ss_fb_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net,
{
struct sctp_stream_out *strq = NULL, *strqt;
if (asoc->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);
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 {
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 {
if ((strqt != NULL) &&
@ -641,22 +706,33 @@ sctp_ss_fb_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net,
if (strqt != NULL) {
strqt = TAILQ_NEXT(strqt, ss_params.fb.next_spoke);
} else {
strqt = TAILQ_FIRST(&asoc->ss_data.out_wheel);
strqt = TAILQ_FIRST(&asoc->ss_data.out.wheel);
}
} while (strqt != strq);
return (strq);
}
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,
int moved_how_much SCTP_UNUSED)
{
struct sctp_stream_queue_pending *sp;
struct sctp_stream_out *strqt;
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;
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;
if (strqt->ss_params.fb.rounds < 0)
strqt->ss_params.fb.rounds = 0;
@ -666,7 +742,7 @@ sctp_ss_fb_scheduled(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net SC
} else {
strq->ss_params.fb.rounds = -1;
}
asoc->last_out_stream = strq;
asoc->ss_data.last_out_stream = strq;
return;
}
@ -687,7 +763,7 @@ sctp_ss_fcfs_init(struct sctp_tcb *stcb, struct sctp_association *asoc,
struct sctp_stream_queue_pending *sp;
uint16_t i;
TAILQ_INIT(&asoc->ss_data.out_list);
TAILQ_INIT(&asoc->ss_data.out.list);
/*
* If there is data in the stream queues already,
* the scheduler of an existing association has
@ -723,8 +799,8 @@ sctp_ss_fcfs_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (holds_lock == 0) {
SCTP_TCB_SEND_LOCK(stcb);
}
while (!TAILQ_EMPTY(&asoc->ss_data.out_list)) {
TAILQ_REMOVE(&asoc->ss_data.out_list, TAILQ_FIRST(&asoc->ss_data.out_list), ss_next);
while (!TAILQ_EMPTY(&asoc->ss_data.out.list)) {
TAILQ_REMOVE(&asoc->ss_data.out.list, TAILQ_FIRST(&asoc->ss_data.out.list), ss_next);
}
if (holds_lock == 0) {
SCTP_TCB_SEND_UNLOCK(stcb);
@ -734,9 +810,16 @@ sctp_ss_fcfs_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
}
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;
}
}
return;
}
@ -750,7 +833,7 @@ sctp_ss_fcfs_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
}
if (sp && (sp->ss_next.tqe_next == 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) {
SCTP_TCB_SEND_UNLOCK(stcb);
@ -761,7 +844,7 @@ sctp_ss_fcfs_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
static int
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);
} else {
return (0);
@ -779,7 +862,7 @@ sctp_ss_fcfs_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (sp &&
((sp->ss_next.tqe_next != 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);
}
if (holds_lock == 0) {
SCTP_TCB_SEND_UNLOCK(stcb);
@ -795,10 +878,10 @@ sctp_ss_fcfs_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net,
struct sctp_stream_out *strq;
struct sctp_stream_queue_pending *sp;
sp = TAILQ_FIRST(&asoc->ss_data.out_list);
sp = TAILQ_FIRST(&asoc->ss_data.out.list);
default_again:
if (sp != NULL) {
strq = &asoc->strmout[sp->stream];
strq = &asoc->strmout[sp->sid];
} else {
strq = NULL;
}
@ -827,7 +910,7 @@ default_again:
return (strq);
}
struct sctp_ss_functions sctp_ss_functions[] = {
const struct sctp_ss_functions sctp_ss_functions[] = {
/* SCTP_SS_DEFAULT */
{
#if defined(__Windows__) || defined(__Userspace_os_Windows)
@ -841,7 +924,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
sctp_ss_default_scheduled,
sctp_ss_default_packet_done,
sctp_ss_default_get_value,
sctp_ss_default_set_value
sctp_ss_default_set_value,
sctp_ss_default_is_user_msgs_incomplete
#else
.sctp_ss_init = sctp_ss_default_init,
.sctp_ss_clear = sctp_ss_default_clear,
@ -853,7 +937,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
.sctp_ss_scheduled = sctp_ss_default_scheduled,
.sctp_ss_packet_done = sctp_ss_default_packet_done,
.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
},
/* SCTP_SS_ROUND_ROBIN */
@ -869,7 +954,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
sctp_ss_default_scheduled,
sctp_ss_default_packet_done,
sctp_ss_default_get_value,
sctp_ss_default_set_value
sctp_ss_default_set_value,
sctp_ss_default_is_user_msgs_incomplete
#else
.sctp_ss_init = sctp_ss_default_init,
.sctp_ss_clear = sctp_ss_default_clear,
@ -881,7 +967,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
.sctp_ss_scheduled = sctp_ss_default_scheduled,
.sctp_ss_packet_done = sctp_ss_default_packet_done,
.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
},
/* SCTP_SS_ROUND_ROBIN_PACKET */
@ -897,7 +984,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
sctp_ss_default_scheduled,
sctp_ss_rrp_packet_done,
sctp_ss_default_get_value,
sctp_ss_default_set_value
sctp_ss_default_set_value,
sctp_ss_default_is_user_msgs_incomplete
#else
.sctp_ss_init = sctp_ss_default_init,
.sctp_ss_clear = sctp_ss_default_clear,
@ -909,7 +997,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
.sctp_ss_scheduled = sctp_ss_default_scheduled,
.sctp_ss_packet_done = sctp_ss_rrp_packet_done,
.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
},
/* SCTP_SS_PRIORITY */
@ -925,7 +1014,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
sctp_ss_default_scheduled,
sctp_ss_default_packet_done,
sctp_ss_prio_get_value,
sctp_ss_prio_set_value
sctp_ss_prio_set_value,
sctp_ss_default_is_user_msgs_incomplete
#else
.sctp_ss_init = sctp_ss_default_init,
.sctp_ss_clear = sctp_ss_prio_clear,
@ -937,7 +1027,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
.sctp_ss_scheduled = sctp_ss_default_scheduled,
.sctp_ss_packet_done = sctp_ss_default_packet_done,
.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
},
/* SCTP_SS_FAIR_BANDWITH */
@ -953,7 +1044,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
sctp_ss_fb_scheduled,
sctp_ss_default_packet_done,
sctp_ss_default_get_value,
sctp_ss_default_set_value
sctp_ss_default_set_value,
sctp_ss_default_is_user_msgs_incomplete
#else
.sctp_ss_init = sctp_ss_default_init,
.sctp_ss_clear = sctp_ss_fb_clear,
@ -965,7 +1057,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
.sctp_ss_scheduled = sctp_ss_fb_scheduled,
.sctp_ss_packet_done = sctp_ss_default_packet_done,
.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
},
/* SCTP_SS_FIRST_COME */
@ -981,7 +1074,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
sctp_ss_default_scheduled,
sctp_ss_default_packet_done,
sctp_ss_default_get_value,
sctp_ss_default_set_value
sctp_ss_default_set_value,
sctp_ss_default_is_user_msgs_incomplete
#else
.sctp_ss_init = sctp_ss_fcfs_init,
.sctp_ss_clear = sctp_ss_fcfs_clear,
@ -993,7 +1087,8 @@ struct sctp_ss_functions sctp_ss_functions[] = {
.sctp_ss_scheduled = sctp_ss_default_scheduled,
.sctp_ss_packet_done = sctp_ss_default_packet_done,
.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
}
};

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 325370 2017-11-03 20:46:12Z tuexen $");
#endif
#ifndef _NETINET_SCTP_STRUCTS_H_
@ -80,6 +82,7 @@ TAILQ_HEAD(sctpnetlisthead, sctp_nets);
struct sctp_stream_reset_list {
TAILQ_ENTRY(sctp_stream_reset_list) next_resp;
uint32_t seq;
uint32_t tsn;
uint32_t number_entries;
uint16_t list_of_streams[];
@ -227,6 +230,7 @@ struct iterator_control {
struct sctp_net_route {
sctp_rtentry_t *ro_rt;
#if defined(__FreeBSD__)
#if __FreeBSD_version < 1100093
#if __FreeBSD_version >= 800000
void *ro_lle;
#endif
@ -234,6 +238,16 @@ struct sctp_net_route {
void *ro_ia;
int ro_flags;
#endif
#else
#if __FreeBSD_version >= 1100116
struct llentry *ro_lle;
#endif
char *ro_prepend;
uint16_t ro_plen;
uint16_t ro_flags;
uint16_t ro_mtu;
uint16_t spare;
#endif
#endif
#if defined(__APPLE__)
#if !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION)
@ -434,10 +448,10 @@ struct sctp_nets {
struct sctp_data_chunkrec {
uint32_t TSN_seq; /* the TSN of this transmit */
uint16_t stream_seq; /* the stream sequence number of this transmit */
uint16_t stream_number; /* the stream number of this guy */
uint32_t payloadtype;
uint32_t tsn; /* the TSN of this transmit */
uint32_t mid; /* the message identifier of this transmit */
uint16_t sid; /* the stream number of this guy */
uint32_t ppid;
uint32_t context; /* from send */
uint32_t cwnd_at_send;
/*
@ -446,6 +460,7 @@ struct sctp_data_chunkrec {
*/
uint32_t fast_retran_tsn; /* sending_seq at the time of FR */
struct timeval timetodrop; /* time we drop it from queue */
uint32_t fsn; /* Fragment Sequence Number */
uint8_t doing_fast_retransmit;
uint8_t rcv_flags; /* flags pulled from data chunk on inbound for
* outbound holds sending flags for PR-SCTP.
@ -498,14 +513,8 @@ struct sctp_tmit_chunk {
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 */
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
* EOR */
uint32_t sinfo_ppid; /* off the wire */
@ -515,8 +524,11 @@ struct sctp_queued_to_read { /* sinfo structure Pluse more */
uint32_t sinfo_cumtsn; /* Use this in reassembly as last TSN */
sctp_assoc_t sinfo_assoc_id; /* our assoc id */
/* Non sinfo stuff */
uint32_t mid; /* Fragment Index */
uint32_t length; /* length of data */
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 mbuf *data; /* front of the mbuf chain of data with
* PKT_HDR */
@ -524,14 +536,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 sctp_tcb *stcb; /* assoc, used for window update */
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 spec_flags; /* Flags to hold the notification field */
uint8_t do_not_ref_stcb;
uint8_t end_added;
uint8_t pdapi_aborted;
uint8_t pdapi_started;
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
* stream queues. Data will be pulled off from
* the front of the mbuf data and chunk-ified
@ -557,12 +579,13 @@ struct sctp_stream_queue_pending {
struct sctp_nets *net;
TAILQ_ENTRY (sctp_stream_queue_pending) next;
TAILQ_ENTRY (sctp_stream_queue_pending) ss_next;
uint32_t fsn;
uint32_t length;
uint32_t timetolive;
uint32_t ppid;
uint32_t context;
uint16_t sinfo_flags;
uint16_t stream;
uint16_t sid;
uint16_t act_flags;
uint16_t auth_keyid;
uint8_t holds_key_ref;
@ -580,14 +603,17 @@ struct sctp_stream_queue_pending {
TAILQ_HEAD(sctpwheelunrel_listhead, sctp_stream_in);
struct sctp_stream_in {
struct sctp_readhead inqueue;
uint16_t stream_no;
uint16_t last_sequence_delivered; /* used for re-order */
struct sctp_readhead uno_inqueue;
uint32_t last_mid_delivered; /* used for re-order */
uint16_t sid;
uint8_t delivery_started;
uint8_t pd_api_started;
};
TAILQ_HEAD(sctpwheel_listhead, sctp_stream_out);
TAILQ_HEAD(sctplist_listhead, sctp_stream_queue_pending);
/* Round-robin schedulers */
struct ss_rr {
/* next link in wheel */
@ -614,9 +640,14 @@ struct ss_fb {
* This union holds all data necessary for
* different stream schedulers.
*/
union scheduling_data {
struct sctpwheel_listhead out_wheel;
struct sctplist_listhead out_list;
struct scheduling_data {
struct sctp_stream_out *locked_on_sending;
/* circular looking for output selection */
struct sctp_stream_out *last_out_stream;
union {
struct sctpwheel_listhead wheel;
struct sctplist_listhead list;
} out;
};
/*
@ -629,11 +660,20 @@ union scheduling_parameters {
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 */
struct sctp_stream_out {
struct sctp_streamhead outqueue;
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)
uint32_t abandoned_unsent[SCTP_PR_SCTP_MAX + 1];
uint32_t abandoned_sent[SCTP_PR_SCTP_MAX + 1];
@ -642,9 +682,14 @@ struct sctp_stream_out {
uint32_t abandoned_unsent[1];
uint32_t abandoned_sent[1];
#endif
uint16_t stream_no;
uint16_t next_sequence_send; /* next one I expect to send out */
/* For associations using DATA chunks, the lower 16-bit of
* 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 state;
};
/* used to keep track of the addresses yet to try to add/delete */
@ -674,12 +719,13 @@ struct sctp_scoping {
struct sctp_tsn_log {
void *stcb;
uint32_t tsn;
uint32_t seq;
uint16_t strm;
uint16_t seq;
uint16_t sz;
uint16_t flgs;
uint16_t in_pos;
uint16_t in_out;
uint16_t resv;
};
#define SCTP_FS_SPEC_LOG_SIZE 200
@ -755,7 +801,7 @@ struct sctp_ss_functions {
int holds_lock);
void (*sctp_ss_clear)(struct sctp_tcb *stcb, struct sctp_association *asoc,
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,
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);
@ -771,6 +817,7 @@ struct sctp_ss_functions {
struct sctp_stream_out *strq, uint16_t *value);
int (*sctp_ss_set_value)(struct sctp_tcb *stcb, struct sctp_association *asoc,
struct sctp_stream_out *strq, uint16_t value);
int (*sctp_ss_is_user_msgs_incomplete)(struct sctp_tcb *stcb, struct sctp_association *asoc);
};
/* used to save ASCONF chunks for retransmission */
@ -850,20 +897,8 @@ struct sctp_association {
struct sctpchunk_listhead sent_queue;
struct sctpchunk_listhead send_queue;
/* re-assembly queue for fragmented chunks on the inbound path */
struct sctpchunk_listhead reasmqueue;
/* Scheduling queues */
union 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;
struct scheduling_data ss_data;
/* If an iterator is looking at me, this is it */
struct sctp_iterator *stcb_starting_point_for_iterator;
@ -896,8 +931,6 @@ struct sctp_association {
/* last place I got a control 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
@ -918,7 +951,6 @@ struct sctp_association {
uint32_t stream_scheduling_module;
uint32_t vrf_id;
uint32_t cookie_preserve_req;
/* ASCONF next seq I am sending out, inits at init-tsn */
uint32_t asconf_seq_out;
@ -992,7 +1024,7 @@ struct sctp_association {
uint32_t sat_t3_recovery_tsn;
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
* 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
@ -1125,6 +1157,7 @@ struct sctp_association {
uint32_t chunks_on_out_queue; /* total chunks floating around,
* locked by send socket buffer */
uint32_t peers_adaptation;
uint32_t default_mtu;
uint16_t peer_hmac_id; /* peer HMAC id to send */
/*
@ -1198,7 +1231,7 @@ struct sctp_association {
uint8_t hb_random_idx;
uint8_t default_dscp;
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
* together to cross check against the bit that we have yet to
@ -1214,17 +1247,16 @@ struct sctp_association {
uint8_t reconfig_supported;
uint8_t nrsack_supported;
uint8_t pktdrop_supported;
uint8_t idata_supported;
/* Did the peer make the stream config (add out) request */
uint8_t peer_req_out;
uint8_t local_strreset_support;
uint8_t peer_supports_nat;
struct sctp_scoping scope;
/* flags to handle send alternate net tracking */
uint8_t used_alt_onsack;
uint8_t used_alt_asconfack;
uint8_t fast_retran_loss_recovery;
uint8_t sat_t3_loss_recovery;

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 323505 2017-09-12 21:08:50Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -72,7 +74,6 @@ sctp_init_sysctls()
SCTP_BASE_SYSCTL(sctp_reconfig_enable) = SCTPCTL_RECONFIG_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_strict_sacks) = SCTPCTL_STRICT_SACKS_DEFAULT;
#if !(defined(__FreeBSD__) && __FreeBSD_version >= 800000)
#if !defined(SCTP_WITH_NO_CSUM)
SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) = SCTPCTL_LOOPBACK_NOCSUM_DEFAULT;
@ -115,7 +116,6 @@ sctp_init_sysctls()
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_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_max_retran_chunk) = SCTPCTL_MAX_RETRAN_CHUNK_DEFAULT;
SCTP_BASE_SYSCTL(sctp_logging_level) = SCTPCTL_LOGGING_LEVEL_DEFAULT;
@ -330,9 +330,6 @@ sctp_sysctl_copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *st
if (ipv6_addr_legal) {
struct sockaddr_in6 *sin6;
#if defined(SCTP_EMBEDDED_V6_SCOPE) && !defined(SCTP_KAME)
struct sockaddr_in6 lsa6;
#endif
sin6 = &sctp_ifa->address.sin6;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
continue;
@ -345,21 +342,6 @@ sctp_sysctl_copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *st
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
if (local_scope == 0)
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)))
continue;
@ -518,14 +500,44 @@ sctp_sysctl_handle_assoclist(SYSCTL_HANDLER_ARGS)
xinpcb.total_recvs = inp->total_recvs;
xinpcb.total_nospaces = inp->total_nospaces;
xinpcb.fragmentation_point = inp->sctp_frag_point;
#if !(defined(__FreeBSD__) && (__FreeBSD_version < 1001517))
xinpcb.socket = inp->sctp_socket;
#endif
so = inp->sctp_socket;
if ((so == NULL) ||
(!SCTP_IS_LISTENING(inp)) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
xinpcb.qlen = 0;
xinpcb.maxqlen = 0;
} else {
#if defined(__FreeBSD__) && __FreeBSD_version >= 1200034
xinpcb.qlen = so->sol_qlen;
#else
xinpcb.qlen = so->so_qlen;
#endif
#if defined(__FreeBSD__) && __FreeBSD_version > 1100096
#if __FreeBSD_version >= 1200034
xinpcb.qlen_old = so->sol_qlen > USHRT_MAX ?
USHRT_MAX : (uint16_t) so->sol_qlen;
#else
xinpcb.qlen_old = so->so_qlen > USHRT_MAX ?
USHRT_MAX : (uint16_t) so->so_qlen;
#endif
#endif
#if defined(__FreeBSD__) && __FreeBSD_version >= 1200034
xinpcb.maxqlen = so->sol_qlimit;
#else
xinpcb.maxqlen = so->so_qlimit;
#endif
#if defined(__FreeBSD__) && __FreeBSD_version > 1100096
#if __FreeBSD_version >= 1200034
xinpcb.maxqlen_old = so->sol_qlimit > USHRT_MAX ?
USHRT_MAX : (uint16_t) so->sol_qlimit;
#else
xinpcb.maxqlen_old = so->so_qlimit > USHRT_MAX ?
USHRT_MAX : (uint16_t) so->so_qlimit;
#endif
#endif
}
SCTP_INP_INCR_REF(inp);
SCTP_INP_RUNLOCK(inp);
@ -552,7 +564,7 @@ sctp_sysctl_handle_assoclist(SYSCTL_HANDLER_ARGS)
if (stcb->asoc.primary_destination != NULL)
xstcb.primary_addr = stcb->asoc.primary_destination->ro._l_addr;
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 */
@ -618,10 +630,28 @@ sctp_sysctl_handle_assoclist(SYSCTL_HANDLER_ARGS)
#if __FreeBSD_version >= 800000
xraddr.rtt = net->rtt / 1000;
xraddr.heartbeat_interval = net->heart_beat_delay;
xraddr.ssthresh = net->ssthresh;
xraddr.encaps_port = net->port;
if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
xraddr.state = SCTP_UNCONFIRMED;
} else if (net->dest_state & SCTP_ADDR_REACHABLE) {
xraddr.state = SCTP_ACTIVE;
} else {
xraddr.state = SCTP_INACTIVE;
}
#endif
#else
xraddr.rtt = net->rtt / 1000;
xraddr.heartbeat_interval = net->heart_beat_delay;
xraddr.ssthresh = net->ssthresh;
xraddr.encaps_port = net->port;
if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
xraddr.state = SCTP_UNCONFIRMED;
} else if (net->dest_state & SCTP_ADDR_REACHABLE) {
xraddr.state = SCTP_ACTIVE;
} else {
xraddr.state = SCTP_INACTIVE;
}
#endif
xraddr.start_time.tv_sec = (uint32_t)net->start_time.tv_sec;
xraddr.start_time.tv_usec = (uint32_t)net->start_time.tv_usec;
@ -1208,7 +1238,6 @@ 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(nrsack_enable, sctp_nrsack_enable, SCTPCTL_NRSACK_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__)
#if !defined(SCTP_WITH_NO_CSUM)
SCTP_UINT_SYSCTL(loopback_nocsum, sctp_no_csum_on_loopback, SCTPCTL_LOOPBACK_NOCSUM)
@ -1251,7 +1280,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(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(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(max_retran_chunk, sctp_max_retran_chunk, SCTPCTL_MAX_RETRAN_CHUNK)
SCTP_UINT_SYSCTL(log_level, sctp_logging_level, SCTPCTL_LOGGING_LEVEL)
@ -1320,7 +1348,6 @@ 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_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_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);
#endif
@ -1361,7 +1388,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_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_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_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);
@ -1432,10 +1458,6 @@ sysctl_setup_sctp(void)
&SCTP_BASE_SYSCTL(sctp_pktdrop_enable), 0, sctp_sysctl_handle_int,
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,
&SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback), 0, sctp_sysctl_handle_int,
@ -1590,10 +1612,6 @@ sysctl_setup_sctp(void)
&SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit), 0, sctp_sysctl_handle_int,
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,
&SCTP_BASE_SYSCTL(sctp_min_residual), 0, sctp_sysctl_handle_int,
SCTPCTL_MIN_RESIDUAL_DESC);

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 299543 2016-05-12 16:34:59Z tuexen $");
#endif
#ifndef _NETINET_SCTP_SYSCTL_H_
@ -54,7 +56,6 @@ struct sctp_sysctl {
uint32_t sctp_nrsack_enable;
uint32_t sctp_pktdrop_enable;
uint32_t sctp_fr_max_burst_default;
uint32_t sctp_strict_sacks;
#if !(defined(__FreeBSD__) && __FreeBSD_version >= 800000)
#if !defined(SCTP_WITH_NO_CSUM)
uint32_t sctp_no_csum_on_loopback;
@ -96,7 +97,6 @@ struct sctp_sysctl {
uint32_t sctp_do_drain;
uint32_t sctp_hb_maxburst;
uint32_t sctp_abort_if_one_2_one_hits_limit;
uint32_t sctp_strict_data_order;
uint32_t sctp_min_residual;
uint32_t sctp_max_retran_chunk;
uint32_t sctp_logging_level;
@ -148,13 +148,21 @@ struct sctp_sysctl {
#define SCTPCTL_MAXDGRAM_DESC "Maximum outgoing SCTP buffer size"
#define SCTPCTL_MAXDGRAM_MIN 0
#define SCTPCTL_MAXDGRAM_MAX 0xFFFFFFFF
#if defined(__Userspace__)
#define SCTPCTL_MAXDGRAM_DEFAULT SB_MAX
#else
#define SCTPCTL_MAXDGRAM_DEFAULT 262144 /* 256k */
#endif
/* recvspace: Maximum incoming SCTP buffer size */
#define SCTPCTL_RECVSPACE_DESC "Maximum incoming SCTP buffer size"
#define SCTPCTL_RECVSPACE_MIN 0
#define SCTPCTL_RECVSPACE_MAX 0xFFFFFFFF
#if defined(__Userspace__)
#define SCTPCTL_RECVSPACE_DEFAULT SB_RAW
#else
#define SCTPCTL_RECVSPACE_DEFAULT 262144 /* 256k */
#endif
/* autoasconf: Enable SCTP Auto-ASCONF */
#define SCTPCTL_AUTOASCONF_DESC "Enable SCTP Auto-ASCONF"
@ -210,12 +218,6 @@ struct sctp_sysctl {
#define SCTPCTL_PKTDROP_ENABLE_MAX 1
#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 */
#define SCTPCTL_LOOPBACK_NOCSUM_DESC "Enable NO Csum on packets sent on loopback"
#define SCTPCTL_LOOPBACK_NOCSUM_MIN 0
@ -308,10 +310,10 @@ struct sctp_sysctl {
#define SCTPCTL_PMTU_RAISE_TIME_DEFAULT SCTP_DEF_PMTU_RAISE_SEC
/* 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_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 */
#define SCTPCTL_SECRET_LIFETIME_DESC "Default secret lifetime in seconds"
@ -445,12 +447,6 @@ struct sctp_sysctl {
#define SCTPCTL_ABORT_AT_LIMIT_MAX 1
#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 */
#define SCTPCTL_MIN_RESIDUAL_DESC "Minimum residual data chunk in second part of split"
#define SCTPCTL_MIN_RESIDUAL_MIN 20
@ -513,7 +509,7 @@ struct sctp_sysctl {
#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_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 */
#define SCTPCTL_NAT_FRIENDLY_INITS_DESC "Enable sending of the nat-friendly SCTP option on INITs."
@ -566,7 +562,7 @@ struct sctp_sysctl {
#define SCTPCTL_RTTVAR_DCCCECN_MAX 1
#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_MAX 2
#define SCTPCTL_BLACKHOLE_DEFAULT SCTPCTL_BLACKHOLE_MIN

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 317592 2017-04-29 09:57:27Z tuexen $");
#endif
#define _IP_VHL
@ -95,7 +97,7 @@ sctp_audit_retranmission_queue(struct sctp_association *asoc)
asoc->sent_queue_cnt);
}
int
static int
sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct sctp_nets *net, uint16_t threshold)
{
@ -120,8 +122,10 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
net->dest_state |= SCTP_ADDR_PF;
net->last_active = sctp_get_tick_count();
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_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
inp, stcb, net,
SCTP_FROM_SCTP_TIMER + SCTP_LOC_1);
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
}
}
}
@ -161,9 +165,9 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/* Abort notification sends a ULP notify */
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");
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);
return (1);
}
@ -401,7 +405,11 @@ sctp_backoff_on_timeout(struct sctp_tcb *stcb,
int num_marked, int num_abandoned)
{
if (net->RTO == 0) {
if (net->RTO_measured) {
net->RTO = stcb->asoc.minrto;
} else {
net->RTO = stcb->asoc.initial_rto;
}
}
net->RTO <<= 1;
if (net->RTO > stcb->asoc.maxrto) {
@ -423,14 +431,19 @@ sctp_recover_sent_list(struct sctp_tcb *stcb)
asoc = &stcb->asoc;
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",
(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 (asoc->strmout[chk->rec.data.stream_number].chunks_on_queues > 0) {
asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--;
if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) {
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);
if (PR_SCTP_ENABLED(chk->flags)) {
if (asoc->pr_sctp_cnt != 0)
@ -451,7 +464,7 @@ sctp_recover_sent_list(struct sctp_tcb *stcb)
}
SCTP_PRINTF("after recover order is as follows\n");
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
@ -539,10 +552,10 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
start_again:
#endif
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? */
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++;
#ifdef INVARIANTS
panic("last acked >= chk on sent-Q");
@ -567,7 +580,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
/* validate its been outstanding long enough */
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
sctp_log_fr(chk->rec.data.TSN_seq,
sctp_log_fr(chk->rec.data.tsn,
chk->sent_rcv_time.tv_sec,
chk->sent_rcv_time.tv_usec,
SCTP_FR_T3_MARK_TIME);
@ -635,11 +648,11 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
num_mk++;
if (fir == 0) {
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) {
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);
}
@ -654,8 +667,8 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_RSND_TO,
chk->whoTo->flight_size,
chk->book_size,
(uintptr_t)chk->whoTo,
chk->rec.data.TSN_seq);
(uint32_t)(uintptr_t)chk->whoTo,
chk->rec.data.tsn);
}
sctp_flight_size_decrease(chk);
sctp_total_flight_decrease(stcb, chk);
@ -663,6 +676,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
stcb->asoc.peers_rwnd += SCTP_BASE_SYSCTL(sctp_peer_chunk_oh);
}
chk->sent = SCTP_DATAGRAM_RESEND;
chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
SCTP_STAT_INCR(sctps_markedretrans);
/* reset the TSN for striking and other FR stuff */
@ -685,7 +699,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
if (TAILQ_EMPTY(&stcb->asoc.send_queue)) {
chk->rec.data.fast_retran_tsn = stcb->asoc.sending_seq;
} 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.
@ -715,13 +729,9 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
if (num_mk) {
SCTPDBG(SCTP_DEBUG_TIMER1, "LAST TSN marked was %x\n",
tsnlast);
SCTPDBG(SCTP_DEBUG_TIMER1, "Num marked for retransmission was %d peer-rwd:%ld\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",
SCTPDBG(SCTP_DEBUG_TIMER1, "Num marked for retransmission was %d peer-rwd:%u\n",
num_mk,
(int)stcb->asoc.peers_rwnd);
stcb->asoc.peers_rwnd);
}
#endif
*num_marked = num_mk;
@ -740,6 +750,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
chk->whoTo = alt;
if (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);
cnt_mk++;
}
@ -782,8 +793,8 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
sctp_misc_ints(SCTP_FLIGHT_LOG_UP,
chk->whoTo->flight_size,
chk->book_size,
(uintptr_t)chk->whoTo,
chk->rec.data.TSN_seq);
(uint32_t)(uintptr_t)chk->whoTo,
chk->rec.data.tsn);
}
sctp_flight_size_increase(chk);
@ -1050,9 +1061,9 @@ sctp_cookie_timer(struct sctp_inpcb *inp,
/* FOOBAR! */
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");
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);
} else {
#ifdef INVARIANTS
@ -1071,8 +1082,8 @@ sctp_cookie_timer(struct sctp_inpcb *inp,
return (1);
}
/*
* cleared theshold management now lets backoff the address & select
* an alternate
* Cleared threshold management, now lets backoff the address
* and select an alternate
*/
stcb->asoc.dropped_special_cnt = 0;
sctp_backoff_on_timeout(stcb, cookie->whoTo, 1, 0, 0);
@ -1087,6 +1098,7 @@ sctp_cookie_timer(struct sctp_inpcb *inp,
sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
}
cookie->sent = SCTP_DATAGRAM_RESEND;
cookie->flags |= CHUNK_FLAGS_FRAGMENT_OK;
/*
* 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
@ -1117,8 +1129,8 @@ sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
return (1);
}
/*
* cleared theshold management now lets backoff the address & select
* an alternate
* Cleared threshold management, now lets backoff the address
* and select an alternate
*/
sctp_backoff_on_timeout(stcb, strrst->whoTo, 1, 0, 0);
alt = sctp_find_alternate_net(stcb, strrst->whoTo, 0);
@ -1133,6 +1145,7 @@ sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
sctp_free_remote_addr(chk->whoTo);
if (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);
}
chk->whoTo = alt;
@ -1150,6 +1163,7 @@ sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if (strrst->sent != SCTP_DATAGRAM_RESEND)
sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
strrst->sent = SCTP_DATAGRAM_RESEND;
strrst->flags |= CHUNK_FLAGS_FRAGMENT_OK;
/* restart the timer */
sctp_timer_start(SCTP_TIMER_TYPE_STRRESET, inp, stcb, strrst->whoTo);
@ -1214,6 +1228,7 @@ sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
chk->whoTo = alt;
if (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);
}
atomic_add_int(&alt->ref_count, 1);
@ -1228,6 +1243,7 @@ sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if (asconf->sent != SCTP_DATAGRAM_RESEND && chk->sent != SCTP_DATAGRAM_UNSENT)
sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
chk->sent = SCTP_DATAGRAM_RESEND;
chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
}
if (!(net->dest_state & SCTP_ADDR_REACHABLE)) {
/*
@ -1240,6 +1256,7 @@ sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if (asconf->sent != SCTP_DATAGRAM_RESEND)
sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
asconf->sent = SCTP_DATAGRAM_RESEND;
asconf->flags |= CHUNK_FLAGS_FRAGMENT_OK;
/* send another ASCONF if any and we can do */
sctp_send_asconf(stcb, alt, SCTP_ADDR_NOT_LOCKED);
@ -1277,7 +1294,7 @@ sctp_shutdown_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
{
struct sctp_nets *alt;
/* first threshold managment */
/* first threshold management */
if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
/* Assoc is over */
return (1);
@ -1300,7 +1317,7 @@ sctp_shutdownack_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
{
struct sctp_nets *alt;
/* first threshold managment */
/* first threshold management */
if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
/* Assoc is over */
return (1);
@ -1511,6 +1528,8 @@ sctp_pathmtu_timer(struct sctp_inpcb *inp,
#endif
if (mtu > next_mtu) {
net->mtu = next_mtu;
} else {
net->mtu = mtu;
}
}
}

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 295709 2016-02-17 18:04:22Z tuexen $");
#endif
#ifndef _NETINET_SCTP_TIMER_H_
@ -47,10 +49,6 @@ struct sctp_nets *
sctp_find_alternate_net(struct sctp_tcb *,
struct sctp_nets *, int mode);
int
sctp_threshold_management(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *, uint16_t);
int
sctp_t3rxt_timer(struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *);

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 323505 2017-09-12 21:08:50Z tuexen $");
#endif
#ifndef _NETINET_SCTP_UIO_H_
@ -164,19 +166,25 @@ struct sctp_extrcvinfo {
#endif
uint32_t sinfo_ppid;
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_cumtsn;
sctp_assoc_t sinfo_assoc_id;
uint16_t sreinfo_next_flags;
uint16_t sreinfo_next_stream;
uint32_t sreinfo_next_aid;
uint32_t sreinfo_next_length;
uint32_t sreinfo_next_ppid;
uint16_t serinfo_next_flags;
uint16_t serinfo_next_stream;
uint32_t serinfo_next_aid;
uint32_t serinfo_next_length;
uint32_t serinfo_next_ppid;
uint16_t sinfo_keynumber;
uint16_t sinfo_keynumber_valid;
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 {
uint16_t snd_sid;
@ -282,7 +290,8 @@ struct sctp_snd_all_completes {
/* The lower four bits is an enumeration of PR-SCTP policies */
#define SCTP_PR_SCTP_NONE 0x0000 /* Reliable transfer */
#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_MAX SCTP_PR_SCTP_RTX
#define SCTP_PR_SCTP_ALL 0x000f /* Used for aggregated stats */
@ -346,7 +355,8 @@ struct sctp_assoc_change {
#define SCTP_ASSOC_SUPPORTS_ASCONF 0x03
#define SCTP_ASSOC_SUPPORTS_MULTIBUF 0x04
#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
*/
@ -611,6 +621,7 @@ struct sctp_paddrthlds {
sctp_assoc_t spt_assoc_id;
uint16_t spt_pathmaxrxt;
uint16_t spt_pathpfthld;
uint16_t spt_pathcpthld;
};
struct sctp_paddrinfo {
@ -1192,15 +1203,41 @@ struct xsctp_inpcb {
uint32_t total_nospaces;
uint32_t fragmentation_point;
uint16_t local_port;
#if defined(__FreeBSD__) && __FreeBSD_version > 1100096
uint16_t qlen_old;
uint16_t maxqlen_old;
#else
uint16_t qlen;
uint16_t maxqlen;
#endif
#if defined(__Windows__)
uint16_t padding;
#endif
#if !(defined(__FreeBSD__) && (__FreeBSD_version < 1001517))
void *socket;
#endif
#if defined(__FreeBSD__) && __FreeBSD_version > 1100096
uint32_t qlen;
uint32_t maxqlen;
#endif
#if defined(__FreeBSD__) && __FreeBSD_version < 1000048
uint32_t extra_padding[32]; /* future */
#else
#elif defined(__FreeBSD__) && (__FreeBSD_version < 1001517)
uint32_t extra_padding[31]; /* future */
#else
#if defined(__LP64__)
#if defined(__FreeBSD__) && __FreeBSD_version > 1100096
uint32_t extra_padding[27]; /* future */
#else
uint32_t extra_padding[29]; /* future */
#endif
#else
#if defined(__FreeBSD__) && __FreeBSD_version > 1100096
uint32_t extra_padding[28]; /* future */
#else
uint32_t extra_padding[30]; /* future */
#endif
#endif
#endif
};
@ -1270,12 +1307,18 @@ struct xsctp_raddr {
#if __FreeBSD_version >= 800000
uint32_t rtt;
uint32_t heartbeat_interval;
uint32_t extra_padding[31]; /* future */
uint32_t ssthresh;
uint16_t encaps_port;
uint16_t state;
uint32_t extra_padding[29]; /* future */
#endif
#else
uint32_t rtt;
uint32_t heartbeat_interval;
uint32_t extra_padding[31]; /* future */
uint32_t ssthresh;
uint16_t encaps_port;
uint16_t state;
uint32_t extra_padding[29]; /* future */
#endif
};

Просмотреть файл

@ -34,6 +34,54 @@
#pragma comment(lib, "IPHLPAPI.lib")
#endif
#include <netinet/sctp_os_userspace.h>
#if defined(__Userspace_os_FreeBSD)
#include <pthread_np.h>
#endif
#if defined(__Userspace_os_Linux)
#include <sys/prctl.h>
#endif
#if defined(__Userspace_os_Windows)
/* Adapter to translate Unix thread start routines to Windows thread start
* routines.
*/
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;
}
#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(__Userspace_os_Darwin)
pthread_setname_np(name);
#endif
#if defined(__Userspace_os_Linux)
prctl(PR_SET_NAME, name);
#endif
#if defined(__Userspace_os_FreeBSD)
pthread_set_name_np(pthread_self(), name);
#endif
}
#if !defined(_WIN32) && !defined(__Userspace_os_NaCl)
int
@ -42,7 +90,8 @@ sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
struct ifreq ifr;
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? */
if ((fd = socket(af, SOCK_DGRAM, 0)) < 0)
return (0);
@ -52,6 +101,9 @@ sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
}
close(fd);
return ifr.ifr_mtu;
} else {
return (0);
}
}
#endif
@ -69,27 +121,39 @@ sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
{
PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt;
DWORD AdapterAddrsSize, Err;
int ret;
ret = 0;
AdapterAddrsSize = 0;
pAdapterAddrs = NULL;
if ((Err = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &AdapterAddrsSize)) != 0) {
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);
return (-1);
ret = -1;
goto cleanup;
}
}
if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) {
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) {
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) {
if (pAdapt->IfIndex == if_index)
return (pAdapt->Mtu);
if (pAdapt->IfIndex == if_index) {
ret = pAdapt->Mtu;
break;
}
return (0);
}
cleanup:
if (pAdapterAddrs != NULL) {
GlobalFree(pAdapterAddrs);
}
return (ret);
}
void
@ -102,95 +166,6 @@ getwintimeofday(struct timeval *tv)
tv->tv_usec = (long)(tb.millitm) * 1000L;
}
int
Win_getifaddrs(struct ifaddrs** interfaces)
{
#if defined(INET) || defined(INET6)
DWORD Err, AdapterAddrsSize;
int count;
PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt;
struct ifaddrs *ifa;
#endif
#if defined(INET)
struct sockaddr_in *addr;
#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
win_if_nametoindex(const char *ifname)
{

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 317457 2017-04-26 19:26:40Z tuexen $");
#endif
#ifndef _NETINET_SCTP_VAR_H_
@ -90,7 +92,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_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
@ -101,11 +103,19 @@ extern struct pr_usrreqs sctp_usrreqs;
* an mbuf cache as well so it is not really worth doing, at least
* 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) { \
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), (_readq)); \
SCTP_DECR_READQ_COUNT(); \
}
#endif
#define sctp_alloc_a_readq(_stcb, _readq) { \
(_readq) = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_readq), struct sctp_queued_to_read); \
@ -183,6 +193,7 @@ extern struct pr_usrreqs sctp_usrreqs;
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) { \
RTFREE((__net)->ro.ro_rt); \
(__net)->ro.ro_rt = NULL; \
@ -215,7 +226,7 @@ extern struct pr_usrreqs sctp_usrreqs;
atomic_add_int(&(sb)->sb_cc,SCTP_BUF_LEN((m))); \
atomic_add_int(&(sb)->sb_mbcnt, MSIZE); \
if (stcb) { \
atomic_add_int(&(stcb)->asoc.sb_cc,SCTP_BUF_LEN((m))); \
atomic_add_int(&(stcb)->asoc.sb_cc, SCTP_BUF_LEN((m))); \
atomic_add_int(&(stcb)->asoc.my_rwnd_control_len, MSIZE); \
} \
if (SCTP_BUF_TYPE(m) != MT_DATA && SCTP_BUF_TYPE(m) != MT_HEADER && \
@ -331,7 +342,7 @@ extern struct pr_usrreqs sctp_usrreqs;
if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
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].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].sent = tp1->sent; \
stcb->asoc.fslog[stcb->asoc.fs_index].incr = 0; \
@ -352,7 +363,7 @@ extern struct pr_usrreqs sctp_usrreqs;
if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
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].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].sent = tp1->sent; \
stcb->asoc.fslog[stcb->asoc.fs_index].incr = 1; \
@ -446,21 +457,19 @@ void sctp_init __P((void));
void sctp_init(struct protosw *pp, struct domain *dp);
#else
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
#if !defined(__FreeBSD__)
void sctp_finish(void);
#endif
#if defined(__FreeBSD__) || defined(__Windows__) || defined(__Userspace__)
int sctp_flush(struct socket *, int);
#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 *);
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, int, struct proc *);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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 324615 2017-10-14 10:02:59Z tuexen $");
#endif
#ifndef _NETINET_SCTP_UTIL_H_
@ -66,6 +68,9 @@ sctp_log_trace(uint32_t fr, const char *str SCTP_UNUSED, uint32_t a, uint32_t b,
/*
* Function prototypes
*/
int32_t
sctp_map_assoc_state(int);
uint32_t
sctp_get_ifa_hash_val(struct sockaddr *addr);
@ -79,7 +84,7 @@ uint32_t sctp_select_initial_TSN(struct sctp_pcb *);
uint32_t sctp_select_a_tag(struct sctp_inpcb *, uint16_t lport, uint16_t rport, int);
int sctp_init_asoc(struct sctp_inpcb *, struct sctp_tcb *, uint32_t, uint32_t);
int sctp_init_asoc(struct sctp_inpcb *, struct sctp_tcb *, uint32_t, uint32_t, uint16_t);
void sctp_fill_random_store(struct sctp_pcb *);
@ -103,6 +108,21 @@ sctp_dynamic_set_primary(struct sockaddr *sa, uint32_t vrf_id);
void
sctp_mtu_size_reset(struct sctp_inpcb *, struct sctp_association *, uint32_t);
void
sctp_wakeup_the_read_socket(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
int so_locked
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
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
sctp_add_to_readq(struct sctp_inpcb *inp,
struct sctp_tcb *stcb,
@ -116,16 +136,6 @@ sctp_add_to_readq(struct sctp_inpcb *inp,
#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);
uint32_t sctp_get_prev_mtu(uint32_t);
@ -136,7 +146,7 @@ sctp_timeout_handler(void *);
uint32_t
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 *);
@ -206,7 +216,7 @@ void sctp_handle_ootb(struct mbuf *, int, int,
struct sctphdr *, struct sctp_inpcb *,
struct mbuf *,
#if defined(__FreeBSD__)
uint8_t, uint32_t,
uint8_t, uint32_t, uint16_t,
#endif
uint32_t, uint16_t);
@ -215,7 +225,8 @@ int sctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr,
struct sctp_tcb *
sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr,
int *totaddr, int *num_v4, int *num_v6, int *error, int limit, int *bad_addr);
unsigned int *totaddr, unsigned int *num_v4, unsigned int *num_v6,
int *error, unsigned int limit, int *bad_addr);
int sctp_is_there_an_abort_here(struct mbuf *, int, uint32_t *);
#ifdef INET6
@ -392,7 +403,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_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 *, size_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);
int sctp_fill_stat_log(void *, size_t *);
@ -409,6 +420,11 @@ sctp_auditing(int, struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *);
void sctp_audit_log(uint8_t, uint8_t);
#endif
uint32_t sctp_min_mtu(uint32_t, uint32_t, uint32_t);
#if defined(__FreeBSD__)
void sctp_hc_set_mtu(union sctp_sockstore *, uint16_t, uint32_t);
uint32_t sctp_hc_get_mtu(union sctp_sockstore *, uint16_t);
#endif
#endif /* _KERNEL */
#endif

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 276914 2015-01-10 20:49:57Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 325370 2017-11-03 20:46:12Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -43,9 +45,7 @@ __FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 276914 2015-01-10 20:49:57Z
#include <netinet/sctp_pcb.h>
#include <netinet/sctp_header.h>
#include <netinet/sctp_var.h>
#ifdef INET6
#include <netinet6/sctp6_var.h>
#endif
#include <netinet/sctp_sysctl.h>
#include <netinet/sctp_output.h>
#include <netinet/sctp_uio.h>
@ -59,19 +59,13 @@ __FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 276914 2015-01-10 20:49:57Z
#include <netinet/sctp_bsd_addr.h>
#include <netinet/sctp_crc32.h>
#if !defined(__Userspace_os_Windows)
#include <netinet/icmp6.h>
#include <netinet/udp.h>
#endif
#if defined(__APPLE__)
#define APPLE_FILE_NO 9
#endif
#ifdef IPSEC
#include <netipsec/ipsec.h>
#ifdef INET6
#include <netipsec/ipsec6.h>
#endif /* INET6 */
#endif /* IPSEC */
#if !defined(__Userspace__)
extern struct protosw inetsw[];
#endif
@ -86,7 +80,7 @@ in6_sin6_2_sin(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
#if defined(__Userspace_os_Windows)
uint32_t temp;
#endif
bzero(sin, sizeof(*sin));
memset(sin, 0, sizeof(*sin));
#ifdef HAVE_SIN_LEN
sin->sin_len = sizeof(struct sockaddr_in);
#endif
@ -117,7 +111,7 @@ in6_sin6_2_sin_in_sock(struct sockaddr *nam)
void
in6_sin_2_v4mapsin6(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
{
bzero(sin6, sizeof(struct sockaddr_in6));
memset(sin6, 0, sizeof(struct sockaddr_in6));
sin6->sin6_family = AF_INET6;
#ifdef HAVE_SIN6_LEN
sin6->sin6_len = sizeof(struct sockaddr_in6);
@ -163,6 +157,7 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
#if defined(__FreeBSD__)
uint32_t mflowid;
uint8_t mflowtype;
uint16_t fibnum;
#endif
#if !(defined(__APPLE__) || defined (__FreeBSD__))
uint16_t port = 0;
@ -233,7 +228,8 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
#if defined(__FreeBSD__)
mflowid = m->m_pkthdr.flowid;
mflowtype = M_HASHTYPE_GET(m);
#endif
fibnum = M_GETFIB(m);
#endif
SCTP_STAT_INCR(sctps_recvpackets);
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
/* Get IP, SCTP, and first chunk header together in the first mbuf. */
@ -324,7 +320,7 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
#endif
ecn_bits,
#if defined(__FreeBSD__)
mflowtype, mflowid,
mflowtype, mflowid, fibnum,
#endif
vrf_id, port);
out:
@ -350,157 +346,39 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto SCTP_UNUSED)
}
#endif
#if defined(__Panda__)
void
#else
static void
#endif
sctp6_notify_mbuf(struct sctp_inpcb *inp, struct icmp6_hdr *icmp6,
struct sctphdr *sh, struct sctp_tcb *stcb, struct sctp_nets *net)
{
uint32_t nxtsz;
if ((inp == NULL) || (stcb == NULL) || (net == NULL) ||
(icmp6 == NULL) || (sh == NULL)) {
goto out;
}
/* First do we even look at it? */
if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag))
goto out;
if (icmp6->icmp6_type != ICMP6_PACKET_TOO_BIG) {
/* not PACKET TO BIG */
goto out;
}
/*
* ok we need to look closely. We could even get smarter and look at
* anyone that we sent to in case we get a different ICMP that tells
* us there is no way to reach a host, but for this impl, all we
* care about is MTU discovery.
*/
nxtsz = ntohl(icmp6->icmp6_mtu);
/* Stop any PMTU timer */
sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, NULL, SCTP_FROM_SCTP6_USRREQ+SCTP_LOC_1);
/* Adjust destination size limit */
if (net->mtu > nxtsz) {
net->mtu = nxtsz;
if (net->port) {
net->mtu -= sizeof(struct udphdr);
}
}
/* now what about the ep? */
if (stcb->asoc.smallest_mtu > nxtsz) {
struct sctp_tmit_chunk *chk;
/* Adjust that too */
stcb->asoc.smallest_mtu = nxtsz;
/* now off to subtract IP_DF flag if needed */
TAILQ_FOREACH(chk, &stcb->asoc.send_queue, sctp_next) {
if ((uint32_t) (chk->send_size + IP_HDR_SIZE) > nxtsz) {
chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
}
}
TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
if ((uint32_t) (chk->send_size + IP_HDR_SIZE) > nxtsz) {
/*
* For this guy we also mark for immediate
* resend since we sent to big of chunk
*/
chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
if (chk->sent != SCTP_DATAGRAM_RESEND)
stcb->asoc.sent_queue_retran_cnt++;
chk->sent = SCTP_DATAGRAM_RESEND;
chk->rec.data.doing_fast_retransmit = 0;
chk->sent = SCTP_DATAGRAM_RESEND;
/* Clear any time so NO RTT is being done */
chk->sent_rcv_time.tv_sec = 0;
chk->sent_rcv_time.tv_usec = 0;
stcb->asoc.total_flight -= chk->send_size;
net->flight_size -= chk->send_size;
}
}
}
sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, NULL);
out:
if (stcb) {
SCTP_TCB_UNLOCK(stcb);
}
}
#endif
void
sctp6_notify(struct sctp_inpcb *inp,
struct icmp6_hdr *icmph,
struct sctphdr *sh,
struct sockaddr *to,
struct sctp_tcb *stcb,
struct sctp_nets *net)
struct sctp_nets *net,
uint8_t icmp6_type,
uint8_t icmp6_code,
uint32_t next_mtu)
{
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
struct socket *so;
#endif
int timer_stopped;
/* protection */
if ((inp == NULL) || (stcb == NULL) || (net == NULL) ||
(sh == NULL) || (to == NULL)) {
if (stcb)
SCTP_TCB_UNLOCK(stcb);
return;
}
/* First job is to verify the vtag matches what I would send */
if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) {
SCTP_TCB_UNLOCK(stcb);
return;
}
if (icmph->icmp6_type != ICMP_UNREACH) {
/* We only care about unreachable */
SCTP_TCB_UNLOCK(stcb);
return;
}
if ((icmph->icmp6_code == ICMP_UNREACH_NET) ||
(icmph->icmp6_code == ICMP_UNREACH_HOST) ||
(icmph->icmp6_code == ICMP_UNREACH_NET_UNKNOWN) ||
(icmph->icmp6_code == ICMP_UNREACH_HOST_UNKNOWN) ||
(icmph->icmp6_code == ICMP_UNREACH_ISOLATED) ||
(icmph->icmp6_code == ICMP_UNREACH_NET_PROHIB) ||
(icmph->icmp6_code == ICMP_UNREACH_HOST_PROHIB) ||
#if defined(__Panda__)
(icmph->icmp6_code == ICMP_UNREACH_ADMIN)) {
#elif defined(__Userspace_os_NetBSD)
(icmph->icmp6_code == ICMP_UNREACH_ADMIN_PROHIBIT)) {
#else
(icmph->icmp6_code == ICMP_UNREACH_FILTER_PROHIB)) {
#endif
/*
* Hmm reachablity problems we must examine closely. If its
* not reachable, we may have lost a network. Or if there is
* NO protocol at the other end named SCTP. well we consider
* it a OOTB abort.
*/
switch (icmp6_type) {
case ICMP6_DST_UNREACH:
if ((icmp6_code == ICMP6_DST_UNREACH_NOROUTE) ||
(icmp6_code == ICMP6_DST_UNREACH_ADMIN) ||
(icmp6_code == ICMP6_DST_UNREACH_BEYONDSCOPE) ||
(icmp6_code == ICMP6_DST_UNREACH_ADDR)) {
/* Mark the net unreachable. */
if (net->dest_state & SCTP_ADDR_REACHABLE) {
/* Ok that destination is NOT reachable */
/* Ok that destination is not reachable */
net->dest_state &= ~SCTP_ADDR_REACHABLE;
net->dest_state &= ~SCTP_ADDR_PF;
sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
stcb, 0, (void *)net, SCTP_SO_NOT_LOCKED);
}
}
SCTP_TCB_UNLOCK(stcb);
} else if ((icmph->icmp6_code == ICMP_UNREACH_PROTOCOL) ||
(icmph->icmp6_code == ICMP_UNREACH_PORT)) {
/*
* Here the peer is either playing tricks on us,
* including an address that belongs to someone who
* does not support SCTP OR was a userland
* implementation that shutdown and now is dead. In
* either case treat it like a OOTB abort with no
* TCB
*/
break;
case ICMP6_PARAM_PROB:
/* Treat it like an ABORT. */
if (icmp6_code == ICMP6_PARAMPROB_NEXTHEADER) {
sctp_abort_notification(stcb, 1, 0, NULL, SCTP_SO_NOT_LOCKED);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
so = SCTP_INP_SO(inp);
@ -510,119 +388,211 @@ sctp6_notify(struct sctp_inpcb *inp,
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
#endif
(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ+SCTP_LOC_2);
(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_2);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
/* SCTP_TCB_UNLOCK(stcb); MT: I think this is not needed.*/
#endif
/* no need to unlock here, since the TCB is gone */
} else {
SCTP_TCB_UNLOCK(stcb);
}
break;
case ICMP6_PACKET_TOO_BIG:
if ((net->dest_state & SCTP_ADDR_NO_PMTUD) == 0) {
SCTP_TCB_UNLOCK(stcb);
break;
}
if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
timer_stopped = 1;
sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_1);
} else {
timer_stopped = 0;
}
/* Update the path MTU. */
if (net->port) {
next_mtu -= sizeof(struct udphdr);
}
if (net->mtu > next_mtu) {
net->mtu = next_mtu;
}
/* Update the association MTU */
if (stcb->asoc.smallest_mtu > next_mtu) {
sctp_pathmtu_adjustment(stcb, next_mtu);
}
/* Finally, start the PMTU timer if it was running before. */
if (timer_stopped) {
sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
}
SCTP_TCB_UNLOCK(stcb);
break;
default:
SCTP_TCB_UNLOCK(stcb);
break;
}
}
#if !defined(__Panda__) && !defined(__Userspace__)
void
sctp6_ctlinput(int cmd, struct sockaddr *pktdst, void *d)
{
struct ip6ctlparam *ip6cp;
struct sctp_inpcb *inp;
struct sctp_tcb *stcb;
struct sctp_nets *net;
struct sctphdr sh;
struct ip6ctlparam *ip6cp = NULL;
uint32_t vrf_id;
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__)
vrf_id = SCTP_DEFAULT_VRFID;
#endif
struct sockaddr_in6 src, dst;
#ifdef HAVE_SA_LEN
if (pktdst->sa_family != AF_INET6 ||
pktdst->sa_len != sizeof(struct sockaddr_in6))
pktdst->sa_len != sizeof(struct sockaddr_in6)) {
#else
if (pktdst->sa_family != AF_INET6)
if (pktdst->sa_family != AF_INET6) {
#endif
return;
}
if ((unsigned)cmd >= PRC_NCMDS)
if ((unsigned)cmd >= PRC_NCMDS) {
return;
}
if (PRC_IS_REDIRECT(cmd)) {
d = NULL;
} else if (inet6ctlerrmap[cmd] == 0) {
return;
}
/* if the parameter is from icmp6, decode it. */
/* If the parameter is from icmp6, decode it. */
if (d != NULL) {
ip6cp = (struct ip6ctlparam *)d;
} else {
ip6cp = (struct ip6ctlparam *)NULL;
}
if (ip6cp) {
if (ip6cp != NULL) {
/*
* XXX: We assume that when IPV6 is non NULL, M and OFF are
* valid.
*/
/* check if we can safely examine src and dst ports */
struct sctp_inpcb *inp = NULL;
struct sctp_tcb *stcb = NULL;
struct sctp_nets *net = NULL;
struct sockaddr_in6 final;
if (ip6cp->ip6c_m == NULL)
if (ip6cp->ip6c_m == NULL) {
return;
}
bzero(&sh, sizeof(sh));
bzero(&final, sizeof(final));
/* Check if we can safely examine the ports and the
* verification tag of the SCTP common header.
*/
if (ip6cp->ip6c_m->m_pkthdr.len <
(int32_t)(ip6cp->ip6c_off + offsetof(struct sctphdr, checksum))) {
return;
}
/* Copy out the port numbers and the verification tag. */
memset(&sh, 0, sizeof(sh));
m_copydata(ip6cp->ip6c_m,
ip6cp->ip6c_off,
sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t),
(caddr_t)&sh);
memset(&src, 0, sizeof(struct sockaddr_in6));
src.sin6_family = AF_INET6;
#ifdef HAVE_SIN6_LEN
src.sin6_len = sizeof(struct sockaddr_in6);
#endif
src.sin6_port = sh.src_port;
src.sin6_addr = ip6cp->ip6c_ip6->ip6_src;
#if defined(__FreeBSD__)
if (in6_setscope(&src.sin6_addr, ip6cp->ip6c_m->m_pkthdr.rcvif, NULL) != 0) {
return;
}
#endif
memset(&dst, 0, sizeof(struct sockaddr_in6));
dst.sin6_family = AF_INET6;
#ifdef HAVE_SIN6_LEN
dst.sin6_len = sizeof(struct sockaddr_in6);
#endif
dst.sin6_port = sh.dest_port;
dst.sin6_addr = ip6cp->ip6c_ip6->ip6_dst;
#if defined(__FreeBSD__)
if (in6_setscope(&dst.sin6_addr, ip6cp->ip6c_m->m_pkthdr.rcvif, NULL) != 0) {
return;
}
#endif
inp = NULL;
net = NULL;
m_copydata(ip6cp->ip6c_m, ip6cp->ip6c_off, sizeof(sh),
(caddr_t)&sh);
ip6cp->ip6c_src->sin6_port = sh.src_port;
#ifdef HAVE_SIN6_LEN
final.sin6_len = sizeof(final);
#endif
final.sin6_family = AF_INET6;
#if defined(__FreeBSD__) && __FreeBSD_cc_version < 440000
final.sin6_addr = *ip6cp->ip6c_finaldst;
#else
final.sin6_addr = ((struct sockaddr_in6 *)pktdst)->sin6_addr;
#endif /* __FreeBSD_cc_version */
final.sin6_port = sh.dest_port;
stcb = sctp_findassociation_addr_sa((struct sockaddr *)&final,
(struct sockaddr *)ip6cp->ip6c_src,
&inp, &net, 1, vrf_id);
/* inp's ref-count increased && stcb locked */
if (stcb != NULL && inp && (inp->sctp_socket != NULL)) {
if (cmd == PRC_MSGSIZE) {
sctp6_notify_mbuf(inp,
ip6cp->ip6c_icmp6,
&sh,
stcb,
net);
/* inp's ref-count reduced && stcb unlocked */
} else {
sctp6_notify(inp, ip6cp->ip6c_icmp6, &sh,
(struct sockaddr *)&final,
stcb, net);
/* inp's ref-count reduced && stcb unlocked */
stcb = sctp_findassociation_addr_sa((struct sockaddr *)&dst,
(struct sockaddr *)&src,
&inp, &net, 1, SCTP_DEFAULT_VRFID);
if ((stcb != NULL) &&
(net != NULL) &&
(inp != NULL)) {
/* Check the verification tag */
if (ntohl(sh.v_tag) != 0) {
/*
* This must be the verification tag used for
* sending out packets. We don't consider
* packets reflecting the verification tag.
*/
if (ntohl(sh.v_tag) != stcb->asoc.peer_vtag) {
SCTP_TCB_UNLOCK(stcb);
return;
}
} else {
#if !defined(__Windows__)
if (PRC_IS_REDIRECT(cmd) && inp) {
#if defined(__FreeBSD__)
if (ip6cp->ip6c_m->m_pkthdr.len >=
ip6cp->ip6c_off + sizeof(struct sctphdr) +
sizeof(struct sctp_chunkhdr) +
offsetof(struct sctp_init, a_rwnd)) {
/*
* In this case we can check if we
* got an INIT chunk and if the
* initiate tag matches.
*/
uint32_t initiate_tag;
uint8_t chunk_type;
m_copydata(ip6cp->ip6c_m,
ip6cp->ip6c_off +
sizeof(struct sctphdr),
sizeof(uint8_t),
(caddr_t)&chunk_type);
m_copydata(ip6cp->ip6c_m,
ip6cp->ip6c_off +
sizeof(struct sctphdr) +
sizeof(struct sctp_chunkhdr),
sizeof(uint32_t),
(caddr_t)&initiate_tag);
if ((chunk_type != SCTP_INITIATION) ||
(ntohl(initiate_tag) != stcb->asoc.my_vtag)) {
SCTP_TCB_UNLOCK(stcb);
return;
}
} else {
SCTP_TCB_UNLOCK(stcb);
return;
}
#else
SCTP_TCB_UNLOCK(stcb);
return;
#endif
}
sctp6_notify(inp, stcb, net,
ip6cp->ip6c_icmp6->icmp6_type,
ip6cp->ip6c_icmp6->icmp6_code,
ntohl(ip6cp->ip6c_icmp6->icmp6_mtu));
} else {
#if defined(__FreeBSD__) && __FreeBSD_version < 500000
if (PRC_IS_REDIRECT(cmd) && (inp != NULL)) {
in6_rtchange((struct in6pcb *)inp,
inet6ctlerrmap[cmd]);
}
#endif
if (inp) {
if ((stcb == NULL) && (inp != NULL)) {
/* reduce inp's ref-count */
SCTP_INP_WLOCK(inp);
SCTP_INP_DECR_REF(inp);
SCTP_INP_WUNLOCK(inp);
}
if (stcb)
if (stcb) {
SCTP_TCB_UNLOCK(stcb);
}
}
}
}
#endif
@ -829,10 +799,6 @@ sctp6_attach(struct socket *so, int proto SCTP_UNUSED, struct proc *p SCTP_UNUSE
*/
inp6->inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
#endif
/*
* Hmm what about the IPSEC stuff that is missing here but in
* sctp_attach()?
*/
SCTP_INP_WUNLOCK(inp);
return (0);
}
@ -1287,7 +1253,7 @@ sctp6_connect(struct socket *so, struct mbuf *nam, struct proc *p)
if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
stcb = LIST_FIRST(&inp->sctp_asoc_list);
if (stcb) {
SCTP_TCB_UNLOCK(stcb);
SCTP_TCB_LOCK(stcb);
}
SCTP_INP_RUNLOCK(inp);
} else {
@ -1311,7 +1277,9 @@ sctp6_connect(struct socket *so, struct mbuf *nam, struct proc *p)
return (EALREADY);
}
/* We are GOOD to go */
stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id, p);
stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id,
inp->sctp_ep.pre_open_stream_count,
inp->sctp_ep.port, p);
SCTP_ASOC_CREATE_UNLOCK(inp);
if (stcb == NULL) {
/* Gak! no memory */
@ -1363,10 +1331,10 @@ sctp6_getaddr(struct socket *so, struct mbuf *nam)
if (sin6 == NULL)
return (ENOMEM);
#elif defined(__Panda__)
bzero(sin6, sizeof(*sin6));
memset(sin6, 0, sizeof(*sin6));
#else
SCTP_BUF_LEN(nam) = sizeof(*sin6);
bzero(sin6, sizeof(*sin6));
memset(sin6, 0, sizeof(*sin6));
#endif
sin6->sin6_family = AF_INET6;
#ifdef HAVE_SIN6_LEN
@ -1392,7 +1360,12 @@ sctp6_getaddr(struct socket *so, struct mbuf *nam)
int fnd;
stcb = LIST_FIRST(&inp->sctp_asoc_list);
if (stcb == NULL) {
goto notConn6;
SCTP_INP_RUNLOCK(inp);
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__)
SCTP_FREE_SONAME(sin6);
#endif
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
return (ENOENT);
}
fnd = 0;
sin_a6 = NULL;
@ -1409,7 +1382,12 @@ sctp6_getaddr(struct socket *so, struct mbuf *nam)
}
if ((!fnd) || (sin_a6 == NULL)) {
/* punt */
goto notConn6;
SCTP_INP_RUNLOCK(inp);
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__)
SCTP_FREE_SONAME(sin6);
#endif
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
return (ENOENT);
}
vrf_id = inp->def_vrf_id;
sctp_ifa = sctp_source_address_selection(inp, stcb, (sctp_route_t *)&net->ro, net, 0, vrf_id);
@ -1418,7 +1396,6 @@ sctp6_getaddr(struct socket *so, struct mbuf *nam)
}
} else {
/* For the bound all case you get back 0 */
notConn6:
memset(&sin6->sin6_addr, 0, sizeof(sin6->sin6_addr));
}
} else {
@ -1571,9 +1548,6 @@ sctp6_peeraddr(struct socket *so, struct mbuf *nam)
static int
sctp6_in6getaddr(struct socket *so, struct sockaddr **nam)
{
#ifdef INET
struct sockaddr *addr;
#endif
#elif defined(__Panda__)
int
sctp6_in6getaddr(struct socket *so, struct sockaddr *nam, uint32_t *namelen)
@ -1606,21 +1580,31 @@ sctp6_in6getaddr(struct socket *so, struct mbuf *nam)
error = sctp6_getaddr(so, nam);
#ifdef INET
if (error) {
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__)
struct sockaddr_in6 *sin6;
#else
struct sockaddr_in6 sin6;
#endif
/* try v4 next if v6 failed */
error = sctp_ingetaddr(so, nam);
if (error) {
return (error);
}
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__)
addr = *nam;
#endif
/* if I'm V6ONLY, convert it to v4-mapped */
if (SCTP_IPV6_V6ONLY(inp6)) {
struct sockaddr_in6 sin6;
in6_sin_2_v4mapsin6((struct sockaddr_in *)addr, &sin6);
memcpy(addr, &sin6, sizeof(struct sockaddr_in6));
SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
if (sin6 == NULL) {
SCTP_FREE_SONAME(*nam);
return (ENOMEM);
}
in6_sin_2_v4mapsin6((struct sockaddr_in *)*nam, sin6);
SCTP_FREE_SONAME(*nam);
*nam = (struct sockaddr *)sin6;
#else
in6_sin_2_v4mapsin6((struct sockaddr_in *)addr, &sin6);
SCTP_BUF_LEN(nam) = sizeof(struct sockaddr_in6);
memcpy(addr, &sin6, sizeof(struct sockaddr_in6));
#endif
}
#endif
#if defined(__Panda__)
@ -1634,9 +1618,6 @@ sctp6_in6getaddr(struct socket *so, struct mbuf *nam)
static int
sctp6_getpeeraddr(struct socket *so, struct sockaddr **nam)
{
#ifdef INET
struct sockaddr *addr;
#endif
#elif defined(__Panda__)
int
sctp6_getpeeraddr(struct socket *so, struct sockaddr *nam, uint32_t *namelen)
@ -1671,21 +1652,31 @@ sctp6_getpeeraddr(struct socket *so, struct mbuf *nam)
error = sctp6_peeraddr(so, nam);
#ifdef INET
if (error) {
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__)
struct sockaddr_in6 *sin6;
#else
struct sockaddr_in6 sin6;
#endif
/* try v4 next if v6 failed */
error = sctp_peeraddr(so, nam);
if (error) {
return (error);
}
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__)
addr = *nam;
#endif
/* if I'm V6ONLY, convert it to v4-mapped */
if (SCTP_IPV6_V6ONLY(inp6)) {
struct sockaddr_in6 sin6;
in6_sin_2_v4mapsin6((struct sockaddr_in *)addr, &sin6);
memcpy(addr, &sin6, sizeof(struct sockaddr_in6));
SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
if (sin6 == NULL) {
SCTP_FREE_SONAME(*nam);
return (ENOMEM);
}
in6_sin_2_v4mapsin6((struct sockaddr_in *)*nam, sin6);
SCTP_FREE_SONAME(*nam);
*nam = (struct sockaddr *)sin6;
#else
in6_sin_2_v4mapsin6((struct sockaddr_in *)addr, &sin6);
SCTP_BUF_LEN(nam) = sizeof(struct sockaddr_in6);
memcpy(addr, &sin6, sizeof(struct sockaddr_in6));
#endif
}
#endif
#if defined(__Panda__)

Просмотреть файл

@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 Michael Tuexen. All rights reserved.
@ -32,7 +34,7 @@
#ifdef __FreeBSD__
#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
#ifndef _NETINET6_SCTP6_VAR_H_
@ -81,8 +83,7 @@ extern void in6_sin_2_v4mapsin6(struct sockaddr_in *, struct sockaddr_in6 *);
extern void in6_sin6_2_sin(struct sockaddr_in *, struct sockaddr_in6 *);
extern void in6_sin6_2_sin_in_sock(struct sockaddr *);
#endif
extern void sctp6_notify(struct sctp_inpcb *, struct icmp6_hdr *,
struct sctphdr *, struct sockaddr *,
struct sctp_tcb *, struct sctp_nets *);
void sctp6_notify(struct sctp_inpcb *, struct sctp_tcb *, struct sctp_nets *,
uint8_t, uint8_t, uint32_t);
#endif
#endif

Просмотреть файл

@ -76,12 +76,12 @@
*addr = 0; \
} \
}
#endif
#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
#else
/* Using gcc built-in functions for atomic memory operations
@ -188,16 +188,31 @@ static inline void atomic_unlock() {
}
#else
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() {
(void)pthread_mutex_destroy(&atomic_mtx);
}
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);
#endif
}
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);
#endif
}
#endif
/*

Просмотреть файл

@ -60,22 +60,20 @@ u_short ip_id = 0; /*__Userspace__ TODO Should it be initialized to zero? */
*/
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
* provide _some_ kind of randomness. This should only be used
* inside other RNG's, like arc4random(9).
*/
#if defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Darwin)
static int
read_random_phony(void *buf, int count)
{
if (count >= 0) {
arc4random_buf(buf, count);
}
return (count);
}
#else
static int
read_random_phony(void *buf, int count)
{
@ -93,4 +91,14 @@ read_random_phony(void *buf, int count)
return (count);
}
#endif
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));
}

Просмотреть файл

@ -85,20 +85,27 @@ extern u_short ip_id;
#if defined(__Userspace_os_Linux)
#define IPV6_VERSION 0x60
#endif
#if defined(INVARIANTS)
#define panic(args...) \
do { \
SCTP_PRINTF(args);\
exit(1); \
} while (0)
#endif
#if defined(INVARIANTS)
#include <stdlib.h>
static inline void
terminate_non_graceful(void) {
abort();
}
#define panic(...) \
do { \
SCTP_PRINTF("%s(): ", __FUNCTION__);\
SCTP_PRINTF(__VA_ARGS__); \
SCTP_PRINTF("\n"); \
terminate_non_graceful(); \
} while (0)
#define KASSERT(cond, args) \
do { \
if (!(cond)) { \
printf args ;\
exit(1); \
panic args ; \
} \
} while (0)
#else

Просмотреть файл

@ -65,7 +65,7 @@ struct icmp6_hdr {
u_int8_t icmp6_un_data8[4];
} icmp6_dataun;
};
#pragma pack()
#pragma pack(pop)
#define icmp6_data32 icmp6_dataun.icmp6_un_data32
#define icmp6_mtu icmp6_data32[0]

Просмотреть файл

@ -195,7 +195,7 @@ Start copy: Copied code for __Userspace__ */
#define MALLOC(space, cast, size, type, flags) \
((space) = (cast)malloc((u_long)(size))); \
do { \
if(flags & M_ZERO) { \
if (flags & M_ZERO) { \
memset(space,0,size); \
} \
} while (0);

Просмотреть файл

@ -121,7 +121,7 @@ m_get(int how, short type)
mbuf_mb_args.type = type;
#endif
/* Mbuf master zone, zone_mbuf, has already been
* created in mbuf_init() */
* created in mbuf_initialize() */
mret = SCTP_ZONE_GET(zone_mbuf, struct mbuf);
#if defined(SCTP_SIMPLE_ALLOCATOR)
mb_ctor_mbuf(mret, &mbuf_mb_args, 0);
@ -204,26 +204,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;
int type, size;
if (m == NULL) {
return;
}
/* Assigning cluster of MCLBYTES. TODO: Add jumbo frame functionality */
type = EXT_CLUSTER;
size = MCLBYTES;
refcnt = SCTP_ZONE_GET(zone_ext_refcnt, u_int);
/*refcnt = (u_int *)umem_cache_alloc(zone_ext_refcnt, UMEM_DEFAULT);*/
if (refcnt == NULL) {
#if !defined(SCTP_SIMPLE_ALLOCATOR)
if (refcnt == NULL) {
umem_reap();
#endif
refcnt = SCTP_ZONE_GET(zone_ext_refcnt, u_int);
/*refcnt = (u_int *)umem_cache_alloc(zone_ext_refcnt, UMEM_DEFAULT);*/
}
#endif
*refcnt = 1;
if (m != NULL) {
m->m_ext.ext_buf = (caddr_t)m_clust;
m->m_data = m->m_ext.ext_buf;
m->m_flags |= M_EXT;
@ -232,31 +235,28 @@ static int clust_constructor_dup(caddr_t m_clust, struct mbuf* m)
m->m_ext.ext_size = size;
m->m_ext.ext_type = type;
m->m_ext.ref_cnt = refcnt;
}
return (0);
return;
}
/* __Userspace__ */
void
m_clget(struct mbuf *m, int how)
{
caddr_t mclust_ret;
#if defined(SCTP_SIMPLE_ALLOCATOR)
struct clust_args clust_mb_args;
struct clust_args clust_mb_args_l;
#endif
if (m->m_flags & M_EXT) {
SCTPDBG(SCTP_DEBUG_USR, "%s: %p mbuf already has cluster\n", __func__, (void *)m);
}
m->m_ext.ext_buf = (char *)NULL;
#if defined(SCTP_SIMPLE_ALLOCATOR)
clust_mb_args.parent_mbuf = m;
clust_mb_args_l.parent_mbuf = m;
#endif
mclust_ret = SCTP_ZONE_GET(zone_clust, char);
#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
/*mclust_ret = umem_cache_alloc(zone_clust, UMEM_DEFAULT);*/
/*
@ -327,12 +327,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 **************/
/* __Userspace__
* TODO: mbuf_init must be called in the initialization routines
* of userspace stack.
*/
void
mbuf_init(void *dummy)
mbuf_initialize(void *dummy)
{
/*
@ -732,11 +728,10 @@ m_pullup(struct mbuf *n, int len)
if (n->m_flags & M_PKTHDR)
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 {
count = min(min(max(len, max_protohdr), space), n->m_len);
bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
(u_int)count);
memcpy(mtod(m, caddr_t) + m->m_len,mtod(n, caddr_t), (u_int)count);
len -= count;
m->m_len += count;
n->m_len -= count;
@ -902,7 +897,7 @@ m_pulldown(struct mbuf *m, int off, int len, int *offp)
&& writable) {
n->m_next->m_data -= 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 = n->m_next;
off = 0;
@ -924,7 +919,7 @@ m_pulldown(struct mbuf *m, int off, int len, int *offp)
}
/* get hlen from <n, off> into <o, 0> */
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;
/* get tlen from <n->m_next, 0> into <o, hlen> */
m_copydata(n->m_next, 0, tlen, mtod(o, caddr_t) + o->m_len);
@ -1030,8 +1025,7 @@ m_copym(struct mbuf *m, int off0, int len, int wait)
n->m_data = m->m_data + off;
mb_dupcl(n, m);
} else
bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t),
(u_int)n->m_len);
memcpy(mtod(n, caddr_t), mtod(m, caddr_t) + off, (u_int)n->m_len);
if (len != M_COPYALL)
len -= n->m_len;
off = 0;
@ -1080,6 +1074,8 @@ int
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);
if ((to->m_flags & M_EXT) == 0)
to->m_data = to->m_pktdat;
@ -1098,7 +1094,7 @@ 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);
if (p == 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;
}
@ -1146,7 +1142,7 @@ m_copyback(struct mbuf *m0, int off, int len, caddr_t cp)
n = m_get(M_NOWAIT, m->m_type);
if (n == NULL)
goto out;
bzero(mtod(n, caddr_t), MLEN);
memset(mtod(n, caddr_t), 0, MLEN);
n->m_len = min(MLEN, len + off);
m->m_next = n;
}
@ -1154,7 +1150,7 @@ m_copyback(struct mbuf *m0, int off, int len, caddr_t cp)
}
while (len > 0) {
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;
len -= mlen;
mlen += off;
@ -1198,7 +1194,7 @@ m_prepend(struct mbuf *m, int len, int how)
M_MOVE_PKTHDR(mn, m);
mn->m_next = m;
m = mn;
if(m->m_flags & M_PKTHDR) {
if (m->m_flags & M_PKTHDR) {
if (len < MHLEN)
MH_ALIGN(m, len);
} else {
@ -1230,7 +1226,7 @@ m_copydata(const struct mbuf *m, int off, int len, caddr_t cp)
while (len > 0) {
KASSERT(m != NULL, ("m_copydata, length > size of mbuf chain"));
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;
cp += count;
off = 0;
@ -1257,7 +1253,7 @@ m_cat(struct mbuf *m, struct mbuf *n)
return;
}
/* 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;
n = m_free(n);
}
@ -1400,7 +1396,7 @@ extpacket:
n->m_data = m->m_data + len;
mb_dupcl(n, m);
} 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;
m->m_len = len;
@ -1421,7 +1417,7 @@ pack_send_buffer(caddr_t buffer, struct mbuf* mb){
do {
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;
total_count_copied += count_to_copy;
mb = mb->m_next;

Просмотреть файл

@ -58,7 +58,7 @@ void m_clget(struct mbuf *m, int how);
/* mbuf initialization function */
void mbuf_init(void *);
void mbuf_initialize(void *);
#define M_MOVE_PKTHDR(to, from) m_move_pkthdr((to), (from))
#define MGET(m, how, type) ((m) = m_get((how), (type)))
@ -267,7 +267,6 @@ struct mbuf {
#define M_PROTO3 0x0040 /* protocol-specific */
#define M_PROTO4 0x0080 /* 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 */
@ -275,7 +274,7 @@ struct mbuf {
* Flags copied when copying m_pkthdr.
*/
#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_VLANTAG|M_PROMISC)

Просмотреть файл

@ -92,51 +92,36 @@ static void
sctp_handle_ifamsg(unsigned char type, unsigned short index, struct sockaddr *sa)
{
int rc;
struct ifaddrs *ifa, *found_ifa = NULL;
struct ifaddrs *ifa, *ifas;
/* handle only the types we want */
if ((type != RTM_NEWADDR) && (type != RTM_DELADDR)) {
return;
}
rc = getifaddrs(&g_interfaces);
rc = getifaddrs(&ifas);
if (rc != 0) {
return;
}
for (ifa = g_interfaces; ifa; ifa = ifa->ifa_next) {
for (ifa = ifas; ifa; ifa = ifa->ifa_next) {
if (index == if_nametoindex(ifa->ifa_name)) {
found_ifa = ifa;
break;
}
}
if (found_ifa == NULL) {
if (ifa == NULL) {
freeifaddrs(ifas);
return;
}
switch (sa->sa_family) {
#ifdef INET
case AF_INET:
ifa->ifa_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in));
memcpy(ifa->ifa_addr, sa, sizeof(struct sockaddr_in));
break;
#endif
#ifdef INET6
case AF_INET6:
ifa->ifa_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in6));
memcpy(ifa->ifa_addr, sa, sizeof(struct sockaddr_in6));
break;
#endif
default:
SCTPDBG(SCTP_DEBUG_USR, "Address family %d not supported.\n", sa->sa_family);
}
/* relay the appropriate address change to the base code */
if (type == RTM_NEWADDR) {
(void)sctp_add_addr_to_vrf(SCTP_DEFAULT_VRFID, ifa, if_nametoindex(ifa->ifa_name),
(void)sctp_add_addr_to_vrf(SCTP_DEFAULT_VRFID,
NULL,
if_nametoindex(ifa->ifa_name),
0,
ifa->ifa_name,
(void *)ifa,
ifa->ifa_addr,
NULL,
sa,
0,
1);
} else {
@ -144,6 +129,7 @@ sctp_handle_ifamsg(unsigned char type, unsigned short index, struct sockaddr *sa
if_nametoindex(ifa->ifa_name),
ifa->ifa_name);
}
freeifaddrs(ifas);
}
static void *
@ -154,8 +140,10 @@ recv_function_route(void *arg)
char rt_buffer[1024];
struct sockaddr *sa, *rti_info[RTAX_MAX];
sctp_userspace_set_threadname("SCTP addr mon");
while (1) {
bzero(rt_buffer, sizeof(rt_buffer));
memset(rt_buffer, 0, sizeof(rt_buffer));
ret = recv(SCTP_BASE_VAR(userspace_route), rt_buffer, sizeof(rt_buffer), 0);
if (ret > 0) {
@ -237,7 +225,7 @@ recv_function_route(void *arg)
if (nh->nlmsg_type == RTM_NEWADDR || nh->nlmsg_type == RTM_DELADDR) {
rtmsg = (struct ifaddrmsg *)NLMSG_DATA(nh);
rtatp = (struct rtattr *)IFA_RTA(rtmsg);
if(rtatp->rta_type == IFA_ADDRESS) {
if (rtatp->rta_type == IFA_ADDRESS) {
inp = (struct in_addr *)RTA_DATA(rtatp);
switch (rtmsg->ifa_family) {
#ifdef INET
@ -285,27 +273,30 @@ recv_function_raw(void *arg)
struct sctp_chunkhdr *ch;
struct sockaddr_in src, dst;
#if !defined(__Userspace_os_Windows)
unsigned int ncounter;
struct msghdr msg;
struct iovec recv_iovec[MAXLEN_MBUF_CHAIN];
#else
WSABUF recv_iovec[MAXLEN_MBUF_CHAIN];
int nResult, m_ErrorCode;
DWORD flags;
DWORD ncounter;
struct sockaddr_in from;
int fromlen;
#endif
/*Initially the entire set of mbufs is to be allocated.
to_fill indicates this amount. */
int to_fill = MAXLEN_MBUF_CHAIN;
/* iovlen is the size of each mbuf in the chain */
int i, n, ncounter = 0;
int iovlen = MCLBYTES;
int i, n;
unsigned int iovlen = MCLBYTES;
int want_ext = (iovlen > MLEN)? 1 : 0;
int want_header = 0;
bzero((void *)&src, sizeof(struct sockaddr_in));
bzero((void *)&dst, sizeof(struct sockaddr_in));
sctp_userspace_set_threadname("SCTP/IP4 rcv");
memset(&src, 0, sizeof(struct sockaddr_in));
memset(&dst, 0, sizeof(struct sockaddr_in));
recvmbuf = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN);
@ -329,9 +320,9 @@ recv_function_raw(void *arg)
flags = 0;
ncounter = 0;
fromlen = sizeof(struct sockaddr_in);
bzero((void *)&from, sizeof(struct sockaddr_in));
memset(&from, 0, sizeof(struct sockaddr_in));
nResult = WSARecvFrom(SCTP_BASE_VAR(userspace_rawsctp), recv_iovec, MAXLEN_MBUF_CHAIN, (LPDWORD)&ncounter, (LPDWORD)&flags, (struct sockaddr*)&from, &fromlen, NULL, NULL);
nResult = WSARecvFrom(SCTP_BASE_VAR(userspace_rawsctp), recv_iovec, MAXLEN_MBUF_CHAIN, &ncounter, &flags, (struct sockaddr *)&from, &fromlen, NULL, NULL);
if (nResult != 0) {
m_ErrorCode = WSAGetLastError();
if (m_ErrorCode == WSAETIMEDOUT) {
@ -343,7 +334,7 @@ recv_function_raw(void *arg)
}
n = ncounter;
#else
bzero((void *)&msg, sizeof(struct msghdr));
memset(&msg, 0, sizeof(struct msghdr));
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = recv_iovec;
@ -363,20 +354,20 @@ recv_function_raw(void *arg)
SCTP_STAT_INCR(sctps_recvpackets);
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
if (n <= iovlen) {
if ((unsigned int)n <= iovlen) {
SCTP_BUF_LEN(recvmbuf[0]) = n;
(to_fill)++;
} else {
i = 0;
SCTP_BUF_LEN(recvmbuf[0]) = iovlen;
ncounter -= iovlen;
ncounter -= min(ncounter, iovlen);
(to_fill)++;
do {
recvmbuf[i]->m_next = recvmbuf[i+1];
SCTP_BUF_LEN(recvmbuf[i]->m_next) = min(ncounter, iovlen);
i++;
ncounter -= iovlen;
ncounter -= min(ncounter, iovlen);
(to_fill)++;
} while (ncounter > 0);
}
@ -406,10 +397,12 @@ recv_function_raw(void *arg)
/* SCTP does not allow broadcasts or multicasts */
if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) {
return (NULL);
m_freem(recvmbuf[0]);
continue;
}
if (SCTP_IS_IT_BROADCAST(dst.sin_addr, recvmbuf[0])) {
return (NULL);
m_freem(recvmbuf[0]);
continue;
}
port = 0;
@ -417,7 +410,10 @@ recv_function_raw(void *arg)
#if defined(SCTP_WITH_NO_CSUM)
SCTP_STAT_INCR(sctps_recvnocrc);
#else
if (src.sin_addr.s_addr == dst.sin_addr.s_addr) {
if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
((IN4_ISLOOPBACK_ADDRESS(&src.sin_addr) &&
IN4_ISLOOPBACK_ADDRESS(&dst.sin_addr)) ||
(src.sin_addr.s_addr == dst.sin_addr.s_addr))) {
compute_crc = 0;
SCTP_STAT_INCR(sctps_recvnocrc);
} else {
@ -454,6 +450,7 @@ recv_function_raw6(void *arg)
{
struct mbuf **recvmbuf6;
#if !defined(__Userspace_os_Windows)
unsigned int ncounter = 0;
struct iovec recv_iovec[MAXLEN_MBUF_CHAIN];
struct msghdr msg;
struct cmsghdr *cmsgptr;
@ -462,6 +459,7 @@ recv_function_raw6(void *arg)
WSABUF recv_iovec[MAXLEN_MBUF_CHAIN];
int nResult, m_ErrorCode;
DWORD flags;
DWORD ncounter = 0;
struct sockaddr_in6 from;
int fromlen;
GUID WSARecvMsg_GUID = WSAID_WSARECVMSG;
@ -474,19 +472,20 @@ recv_function_raw6(void *arg)
struct sctphdr *sh;
int offset;
struct sctp_chunkhdr *ch;
/*Initially the entire set of mbufs is to be allocated.
to_fill indicates this amount. */
int to_fill = MAXLEN_MBUF_CHAIN;
/* iovlen is the size of each mbuf in the chain */
int i, n, ncounter = 0;
int i, n;
#if !defined(SCTP_WITH_NO_CSUM)
int compute_crc = 1;
#endif
int iovlen = MCLBYTES;
unsigned int iovlen = MCLBYTES;
int want_ext = (iovlen > MLEN)? 1 : 0;
int want_header = 0;
sctp_userspace_set_threadname("SCTP/IP6 rcv");
recvmbuf6 = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN);
for (;;) {
@ -509,7 +508,7 @@ recv_function_raw6(void *arg)
flags = 0;
ncounter = 0;
fromlen = sizeof(struct sockaddr_in6);
bzero((void *)&from, sizeof(struct sockaddr_in6));
memset(&from, 0, sizeof(struct sockaddr_in6));
nResult = WSAIoctl(SCTP_BASE_VAR(userspace_rawsctp6), SIO_GET_EXTENSION_FUNCTION_POINTER,
&WSARecvMsg_GUID, sizeof WSARecvMsg_GUID,
&WSARecvMsg, sizeof WSARecvMsg,
@ -533,10 +532,10 @@ recv_function_raw6(void *arg)
}
n = ncounter;
#else
bzero((void *)&msg, sizeof(struct msghdr));
bzero((void *)&src, sizeof(struct sockaddr_in6));
bzero((void *)&dst, sizeof(struct sockaddr_in6));
bzero((void *)cmsgbuf, CMSG_SPACE(sizeof (struct in6_pktinfo)));
memset(&msg, 0, sizeof(struct msghdr));
memset(&src, 0, sizeof(struct sockaddr_in6));
memset(&dst, 0, sizeof(struct sockaddr_in6));
memset(cmsgbuf, 0, CMSG_SPACE(sizeof (struct in6_pktinfo)));
msg.msg_name = (void *)&src;
msg.msg_namelen = sizeof(struct sockaddr_in6);
msg.msg_iov = recv_iovec;
@ -558,20 +557,20 @@ recv_function_raw6(void *arg)
SCTP_STAT_INCR(sctps_recvpackets);
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
if (n <= iovlen) {
if ((unsigned int)n <= iovlen) {
SCTP_BUF_LEN(recvmbuf6[0]) = n;
(to_fill)++;
} else {
i = 0;
SCTP_BUF_LEN(recvmbuf6[0]) = iovlen;
ncounter -= iovlen;
ncounter -= min(ncounter, iovlen);
(to_fill)++;
do {
recvmbuf6[i]->m_next = recvmbuf6[i+1];
SCTP_BUF_LEN(recvmbuf6[i]->m_next) = min(ncounter, iovlen);
i++;
ncounter -= iovlen;
ncounter -= min(ncounter, iovlen);
(to_fill)++;
} while (ncounter > 0);
}
@ -586,6 +585,12 @@ recv_function_raw6(void *arg)
}
}
/* SCTP does not allow broadcasts or multicasts */
if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) {
m_freem(recvmbuf6[0]);
continue;
}
sh = mtod(recvmbuf6[0], struct sctphdr *);
ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
offset = sizeof(struct sctphdr);
@ -644,8 +649,8 @@ recv_function_udp(void *arg)
to_fill indicates this amount. */
int to_fill = MAXLEN_MBUF_CHAIN;
/* iovlen is the size of each mbuf in the chain */
int i, n, ncounter, offset;
int iovlen = MCLBYTES;
int i, n, offset;
unsigned int iovlen = MCLBYTES;
int want_ext = (iovlen > MLEN)? 1 : 0;
int want_header = 0;
struct sctphdr *sh;
@ -661,6 +666,7 @@ recv_function_udp(void *arg)
int compute_crc = 1;
#endif
#if !defined(__Userspace_os_Windows)
unsigned int ncounter;
struct iovec iov[MAXLEN_MBUF_CHAIN];
struct msghdr msg;
struct cmsghdr *cmsgptr;
@ -672,8 +678,11 @@ recv_function_udp(void *arg)
WSAMSG msg;
int nResult, m_ErrorCode;
WSACMSGHDR *cmsgptr;
DWORD ncounter;
#endif
sctp_userspace_set_threadname("SCTP/UDP/IP4 rcv");
udprecvmbuf = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN);
while (1) {
@ -693,13 +702,13 @@ recv_function_udp(void *arg)
}
to_fill = 0;
#if !defined(__Userspace_os_Windows)
bzero((void *)&msg, sizeof(struct msghdr));
memset(&msg, 0, sizeof(struct msghdr));
#else
bzero((void *)&msg, sizeof(WSAMSG));
memset(&msg, 0, sizeof(WSAMSG));
#endif
bzero((void *)&src, sizeof(struct sockaddr_in));
bzero((void *)&dst, sizeof(struct sockaddr_in));
bzero((void *)cmsgbuf, sizeof(cmsgbuf));
memset(&src, 0, sizeof(struct sockaddr_in));
memset(&dst, 0, sizeof(struct sockaddr_in));
memset(cmsgbuf, 0, sizeof(cmsgbuf));
#if !defined(__Userspace_os_Windows)
msg.msg_name = (void *)&src;
@ -748,20 +757,20 @@ recv_function_udp(void *arg)
SCTP_STAT_INCR(sctps_recvpackets);
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
if (n <= iovlen) {
if ((unsigned int)n <= iovlen) {
SCTP_BUF_LEN(udprecvmbuf[0]) = n;
(to_fill)++;
} else {
i = 0;
SCTP_BUF_LEN(udprecvmbuf[0]) = iovlen;
ncounter -= iovlen;
ncounter -= min(ncounter, iovlen);
(to_fill)++;
do {
udprecvmbuf[i]->m_next = udprecvmbuf[i+1];
SCTP_BUF_LEN(udprecvmbuf[i]->m_next) = min(ncounter, iovlen);
i++;
ncounter -= iovlen;
ncounter -= min(ncounter, iovlen);
(to_fill)++;
} while (ncounter > 0);
}
@ -796,10 +805,12 @@ recv_function_udp(void *arg)
/* SCTP does not allow broadcasts or multicasts */
if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) {
return (NULL);
m_freem(udprecvmbuf[0]);
continue;
}
if (SCTP_IS_IT_BROADCAST(dst.sin_addr, udprecvmbuf[0])) {
return (NULL);
m_freem(udprecvmbuf[0]);
continue;
}
/*offset = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);*/
@ -852,8 +863,8 @@ recv_function_udp6(void *arg)
to_fill indicates this amount. */
int to_fill = MAXLEN_MBUF_CHAIN;
/* iovlen is the size of each mbuf in the chain */
int i, n, ncounter, offset;
int iovlen = MCLBYTES;
int i, n, offset;
unsigned int iovlen = MCLBYTES;
int want_ext = (iovlen > MLEN)? 1 : 0;
int want_header = 0;
struct sockaddr_in6 src, dst;
@ -865,6 +876,7 @@ recv_function_udp6(void *arg)
int compute_crc = 1;
#endif
#if !defined(__Userspace_os_Windows)
unsigned int ncounter;
struct iovec iov[MAXLEN_MBUF_CHAIN];
struct msghdr msg;
struct cmsghdr *cmsgptr;
@ -875,9 +887,12 @@ recv_function_udp6(void *arg)
WSABUF iov[MAXLEN_MBUF_CHAIN];
WSAMSG msg;
int nResult, m_ErrorCode;
DWORD ncounter;
WSACMSGHDR *cmsgptr;
#endif
sctp_userspace_set_threadname("SCTP/UDP/IP6 rcv");
udprecvmbuf6 = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN);
while (1) {
for (i = 0; i < to_fill; i++) {
@ -897,13 +912,13 @@ recv_function_udp6(void *arg)
to_fill = 0;
#if !defined(__Userspace_os_Windows)
bzero((void *)&msg, sizeof(struct msghdr));
memset(&msg, 0, sizeof(struct msghdr));
#else
bzero((void *)&msg, sizeof(WSAMSG));
memset(&msg, 0, sizeof(WSAMSG));
#endif
bzero((void *)&src, sizeof(struct sockaddr_in6));
bzero((void *)&dst, sizeof(struct sockaddr_in6));
bzero((void *)cmsgbuf, CMSG_SPACE(sizeof (struct in6_pktinfo)));
memset(&src, 0, sizeof(struct sockaddr_in6));
memset(&dst, 0, sizeof(struct sockaddr_in6));
memset(cmsgbuf, 0, CMSG_SPACE(sizeof (struct in6_pktinfo)));
#if !defined(__Userspace_os_Windows)
msg.msg_name = (void *)&src;
@ -956,20 +971,20 @@ recv_function_udp6(void *arg)
SCTP_STAT_INCR(sctps_recvpackets);
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
if (n <= iovlen) {
if ((unsigned int)n <= iovlen) {
SCTP_BUF_LEN(udprecvmbuf6[0]) = n;
(to_fill)++;
} else {
i = 0;
SCTP_BUF_LEN(udprecvmbuf6[0]) = iovlen;
ncounter -= iovlen;
ncounter -= min(ncounter, iovlen);
(to_fill)++;
do {
udprecvmbuf6[i]->m_next = udprecvmbuf6[i+1];
SCTP_BUF_LEN(udprecvmbuf6[i]->m_next) = min(ncounter, iovlen);
i++;
ncounter -= iovlen;
ncounter -= min(ncounter, iovlen);
(to_fill)++;
} while (ncounter > 0);
}
@ -990,7 +1005,8 @@ recv_function_udp6(void *arg)
/* SCTP does not allow broadcasts or multicasts */
if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) {
return (NULL);
m_freem(udprecvmbuf6[0]);
continue;
}
sh = mtod(udprecvmbuf6[0], struct sctphdr *);
@ -1034,8 +1050,13 @@ recv_function_udp6(void *arg)
}
#endif
#if defined (__Userspace_os_Windows)
static void
setReceiveBufferSize(SOCKET sfd, int new_size)
#else
static void
setReceiveBufferSize(int sfd, int new_size)
#endif
{
int ch = new_size;
@ -1049,8 +1070,13 @@ setReceiveBufferSize(int sfd, int new_size)
return;
}
#if defined (__Userspace_os_Windows)
static void
setSendBufferSize(SOCKET sfd, int new_size)
#else
static void
setSendBufferSize(int sfd, int new_size)
#endif
{
int ch = new_size;
@ -1081,6 +1107,7 @@ recv_thread_init(void)
#if !defined(__Userspace_os_Windows)
struct timeval timeout;
memset(&timeout, 0, sizeof(struct timeval));
timeout.tv_sec = (SOCKET_TIMEOUT / 1000);
timeout.tv_usec = (SOCKET_TIMEOUT % 1000) * 1000;
#else
@ -1088,7 +1115,7 @@ recv_thread_init(void)
#endif
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
if (SCTP_BASE_VAR(userspace_route) == -1) {
if ((SCTP_BASE_VAR(userspace_route) = socket(AF_ROUTE, SOCK_RAW, 0)) < 0) {
if ((SCTP_BASE_VAR(userspace_route) = socket(AF_ROUTE, SOCK_RAW, 0)) == -1) {
SCTPDBG(SCTP_DEBUG_USR, "Can't create routing socket (errno = %d).\n", errno);
}
#if 0
@ -1127,7 +1154,7 @@ recv_thread_init(void)
#endif
#if defined(INET)
if (SCTP_BASE_VAR(userspace_rawsctp) == -1) {
if ((SCTP_BASE_VAR(userspace_rawsctp) = socket(AF_INET, SOCK_RAW, IPPROTO_SCTP)) < 0) {
if ((SCTP_BASE_VAR(userspace_rawsctp) = socket(AF_INET, SOCK_RAW, IPPROTO_SCTP)) == -1) {
#if defined(__Userspace_os_Windows)
SCTPDBG(SCTP_DEBUG_USR, "Can't create raw socket for IPv4 (errno = %d).\n", WSAGetLastError());
#else
@ -1178,7 +1205,7 @@ recv_thread_init(void)
}
}
if (SCTP_BASE_VAR(userspace_udpsctp) == -1) {
if ((SCTP_BASE_VAR(userspace_udpsctp) = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
if ((SCTP_BASE_VAR(userspace_udpsctp) = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
#if defined(__Userspace_os_Windows)
SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/UDP/IPv4 (errno = %d).\n", WSAGetLastError());
#else
@ -1242,7 +1269,7 @@ recv_thread_init(void)
#endif
#if defined(INET6)
if (SCTP_BASE_VAR(userspace_rawsctp6) == -1) {
if ((SCTP_BASE_VAR(userspace_rawsctp6) = socket(AF_INET6, SOCK_RAW, IPPROTO_SCTP)) < 0) {
if ((SCTP_BASE_VAR(userspace_rawsctp6) = socket(AF_INET6, SOCK_RAW, IPPROTO_SCTP)) == -1) {
#if defined(__Userspace_os_Windows)
SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError());
#else
@ -1315,7 +1342,7 @@ recv_thread_init(void)
}
}
if (SCTP_BASE_VAR(userspace_udpsctp6) == -1) {
if ((SCTP_BASE_VAR(userspace_udpsctp6) = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
if ((SCTP_BASE_VAR(userspace_udpsctp6) = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
#if defined(__Userspace_os_Windows)
SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError());
#else
@ -1386,13 +1413,12 @@ recv_thread_init(void)
}
}
#endif
#if !defined(__Userspace_os_Windows)
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
#if defined(INET) || defined(INET6)
if (SCTP_BASE_VAR(userspace_route) != -1) {
int rc;
if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadroute), NULL, &recv_function_route, NULL))) {
if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadroute), &recv_function_route))) {
SCTPDBG(SCTP_DEBUG_USR, "Can't start routing thread (%d).\n", rc);
close(SCTP_BASE_VAR(userspace_route));
SCTP_BASE_VAR(userspace_route) = -1;
@ -1404,76 +1430,58 @@ recv_thread_init(void)
if (SCTP_BASE_VAR(userspace_rawsctp) != -1) {
int rc;
if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadraw), NULL, &recv_function_raw, NULL))) {
if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadraw), &recv_function_raw))) {
SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv4 recv thread (%d).\n", rc);
close(SCTP_BASE_VAR(userspace_rawsctp));
SCTP_BASE_VAR(userspace_rawsctp) = -1;
}
}
if (SCTP_BASE_VAR(userspace_udpsctp) != -1) {
int rc;
if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadudp), NULL, &recv_function_udp, NULL))) {
SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv4 recv thread (%d).\n", rc);
close(SCTP_BASE_VAR(userspace_udpsctp));
SCTP_BASE_VAR(userspace_udpsctp) = -1;
}
}
#endif
#if defined(INET6)
if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) {
int rc;
if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadraw6), NULL, &recv_function_raw6, NULL))) {
SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv6 recv thread (%d).\n", rc);
close(SCTP_BASE_VAR(userspace_rawsctp6));
SCTP_BASE_VAR(userspace_rawsctp6) = -1;
}
}
if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) {
int rc;
if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadudp6), NULL, &recv_function_udp6, NULL))) {
SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv6 recv thread (%d).\n", rc);
close(SCTP_BASE_VAR(userspace_udpsctp6));
SCTP_BASE_VAR(userspace_udpsctp6) = -1;
}
}
#endif
#else
#if defined(INET)
if (SCTP_BASE_VAR(userspace_rawsctp) != -1) {
if ((SCTP_BASE_VAR(recvthreadraw) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&recv_function_raw, NULL, 0, NULL)) == NULL) {
SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv4 recv thread.\n");
#if defined(__Userspace_os_Windows)
closesocket(SCTP_BASE_VAR(userspace_rawsctp));
#else
close(SCTP_BASE_VAR(userspace_rawsctp));
#endif
SCTP_BASE_VAR(userspace_rawsctp) = -1;
}
}
if (SCTP_BASE_VAR(userspace_udpsctp) != -1) {
if ((SCTP_BASE_VAR(recvthreadudp) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&recv_function_udp, NULL, 0, NULL)) == NULL) {
SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv4 recv thread.\n");
int rc;
if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadudp), &recv_function_udp))) {
SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv4 recv thread (%d).\n", rc);
#if defined(__Userspace_os_Windows)
closesocket(SCTP_BASE_VAR(userspace_udpsctp));
#else
close(SCTP_BASE_VAR(userspace_udpsctp));
#endif
SCTP_BASE_VAR(userspace_udpsctp) = -1;
}
}
#endif
#if defined(INET6)
if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) {
if ((SCTP_BASE_VAR(recvthreadraw6) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&recv_function_raw6, NULL, 0, NULL)) == NULL) {
SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv6 recv thread.\n");
int rc;
if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadraw6), &recv_function_raw6))) {
SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv6 recv thread (%d).\n", rc);
#if defined(__Userspace_os_Windows)
closesocket(SCTP_BASE_VAR(userspace_rawsctp6));
#else
close(SCTP_BASE_VAR(userspace_rawsctp6));
#endif
SCTP_BASE_VAR(userspace_rawsctp6) = -1;
}
}
if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) {
if ((SCTP_BASE_VAR(recvthreadudp6) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&recv_function_udp6, NULL, 0, NULL)) == NULL) {
SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv6 recv thread.\n");
int rc;
if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadudp6), &recv_function_udp6))) {
SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv6 recv thread (%d).\n", rc);
#if defined(__Userspace_os_Windows)
closesocket(SCTP_BASE_VAR(userspace_udpsctp6));
#else
close(SCTP_BASE_VAR(userspace_udpsctp6));
#endif
SCTP_BASE_VAR(userspace_udpsctp6) = -1;
}
}
#endif
#endif
}
void

Просмотреть файл

@ -39,9 +39,13 @@
#include <netinet/sctp_sysctl.h>
#include <netinet/sctp_input.h>
#include <netinet/sctp_peeloff.h>
#include <netinet/sctp_crc32.h>
#ifdef INET6
#include <netinet6/sctp6_var.h>
#endif
#if defined(__Userspace_os_FreeBSD)
#include <sys/param.h>
#endif
#if defined(__Userspace_os_Linux)
#define __FAVOR_BSD /* (on Ubuntu at least) enables UDP header field names like BSD in RFC 768 */
#endif
@ -67,7 +71,8 @@ MALLOC_DEFINE(M_SONAME, "sctp_soname", "sctp soname");
/* Prototypes */
extern int sctp_sosend(struct socket *so, struct sockaddr *addr, struct uio *uio,
struct mbuf *top, struct mbuf *control, int flags,
/* proc is a dummy in __Userspace__ and will not be passed to sctp_lower_sosend */ struct proc *p);
/* proc is a dummy in __Userspace__ and will not be passed to sctp_lower_sosend */
struct proc *p);
extern int sctp_attach(struct socket *so, int proto, uint32_t vrf_id);
extern int sctpconn_attach(struct socket *so, int proto, uint32_t vrf_id);
@ -77,6 +82,28 @@ usrsctp_init(uint16_t port,
int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
void (*debug_printf)(const char *format, ...))
{
#if defined(__Userspace_os_Windows)
#if defined(INET) || defined(INET6)
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
SCTP_PRINTF("WSAStartup failed\n");
exit (-1);
}
#endif
InitializeConditionVariable(&accept_cond);
InitializeCriticalSection(&accept_mtx);
#else
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);
pthread_cond_init(&accept_cond, NULL);
#endif
sctp_init(port, conn_output, debug_printf);
}
@ -274,11 +301,9 @@ sofree(struct socket *so)
/* Taken from /src/sys/kern/uipc_socket.c */
int
soabort(so)
struct socket *so;
void
soabort(struct socket *so)
{
int error;
#if defined(INET6)
struct sctp_inpcb *inp;
#endif
@ -286,24 +311,18 @@ soabort(so)
#if defined(INET6)
inp = (struct sctp_inpcb *)so->so_pcb;
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
error = sctp6_abort(so);
sctp6_abort(so);
} else {
#if defined(INET)
error = sctp_abort(so);
#else
error = EAFNOSUPPORT;
sctp_abort(so);
#endif
}
#elif defined(INET)
error = sctp_abort(so);
#else
error = EAFNOSUPPORT;
sctp_abort(so);
#endif
if (error) {
ACCEPT_LOCK();
SOCK_LOCK(so);
sofree(so);
return error;
}
return (0);
}
@ -509,7 +528,7 @@ sonewconn(struct socket *head, int connstatus)
/*
* Keep removing sockets from the head until there's room for
* us to insert on the tail. In pre-locking revisions, this
* was a simple if(), but as we could be racing with other
* was a simple if (), but as we could be racing with other
* threads and soabort() requires dropping locks, we must
* loop waiting for the condition to be true.
*/
@ -563,13 +582,13 @@ struct sctp_generic_recvmsg_args {
Source: /src/sys/gnu/fs/xfs/FreeBSD/xfs_ioctl.c
*/
static __inline__ int
copy_to_user(void *dst, void *src, int len) {
copy_to_user(void *dst, void *src, size_t len) {
memcpy(dst, src, len);
return 0;
}
static __inline__ int
copy_from_user(void *dst, void *src, int len) {
copy_from_user(void *dst, void *src, size_t len) {
memcpy(dst, src, len);
return 0;
}
@ -613,7 +632,7 @@ int
uiomove(void *cp, int n, struct uio *uio)
{
struct iovec *iov;
int cnt;
size_t cnt;
int error = 0;
if ((uio->uio_rw != UIO_READ) &&
@ -629,7 +648,7 @@ uiomove(void *cp, int n, struct uio *uio)
uio->uio_iovcnt--;
continue;
}
if (cnt > n)
if (cnt > (size_t)n)
cnt = n;
switch (uio->uio_segflg) {
@ -645,17 +664,17 @@ uiomove(void *cp, int n, struct uio *uio)
case UIO_SYSSPACE:
if (uio->uio_rw == UIO_READ)
bcopy(cp, iov->iov_base, cnt);
memcpy(iov->iov_base, cp, cnt);
else
bcopy(iov->iov_base, cp, cnt);
memcpy(cp, iov->iov_base, cnt);
break;
}
iov->iov_base = (char *)iov->iov_base + cnt;
iov->iov_len -= cnt;
uio->uio_resid -= cnt;
uio->uio_offset += cnt;
uio->uio_offset += (off_t)cnt;
cp = (char *)cp + cnt;
n -= cnt;
n -= (int)cnt;
}
out:
return (error);
@ -689,6 +708,52 @@ getsockaddr(namp, uaddr, len)
return (error);
}
int
usrsctp_getsockopt(struct socket *so, int level, int option_name,
void *option_value, socklen_t *option_len);
sctp_assoc_t
usrsctp_getassocid(struct socket *sock, struct sockaddr *sa)
{
struct sctp_paddrinfo sp;
socklen_t siz;
#ifndef HAVE_SA_LEN
size_t sa_len;
#endif
/* First get the assoc id */
siz = sizeof(sp);
memset(&sp, 0, sizeof(sp));
#ifdef HAVE_SA_LEN
memcpy((caddr_t)&sp.spinfo_address, sa, sa->sa_len);
#else
switch (sa->sa_family) {
#ifdef INET
case AF_INET:
sa_len = sizeof(struct sockaddr_in);
break;
#endif
#ifdef INET6
case AF_INET6:
sa_len = sizeof(struct sockaddr_in6);
break;
#endif
case AF_CONN:
sa_len = sizeof(struct sockaddr_conn);
break;
default:
sa_len = 0;
break;
}
memcpy((caddr_t)&sp.spinfo_address, sa, sa_len);
#endif
if (usrsctp_getsockopt(sock, IPPROTO_SCTP, SCTP_GET_PEER_ADDR_INFO, &sp, &siz) != 0) {
/* We depend on the fact that 0 can never be returned */
return ((sctp_assoc_t) 0);
}
return (sp.spinfo_assoc_id);
}
/* Taken from /src/lib/libc/net/sctp_sys_calls.c
* and modified for __Userspace__
@ -720,7 +785,7 @@ userspace_sctp_sendmsg(struct socket *so,
/* Perform error checks on destination (to) */
if (tolen > SOCK_MAXADDRLEN){
if (tolen > SOCK_MAXADDRLEN) {
errno = ENAMETOOLONG;
return (-1);
}
@ -729,6 +794,10 @@ userspace_sctp_sendmsg(struct socket *so,
errno = EINVAL;
return (-1);
}
if (data == NULL) {
errno = EFAULT;
return (-1);
}
/* Adding the following as part of defensive programming, in case the application
does not do it when preparing the destination address.*/
#ifdef HAVE_SA_LEN
@ -770,12 +839,18 @@ usrsctp_sendv(struct socket *so,
struct uio auio;
struct iovec iov[1];
int use_sinfo;
sctp_assoc_t *assoc_id;
if (so == NULL) {
errno = EBADF;
return (-1);
}
if (data == NULL) {
errno = EFAULT;
return (-1);
}
memset(&sinfo, 0, sizeof(struct sctp_sndrcvinfo));
assoc_id = NULL;
use_sinfo = 0;
switch (infotype) {
case SCTP_SENDV_NOINFO:
@ -794,6 +869,7 @@ usrsctp_sendv(struct socket *so,
sinfo.sinfo_ppid = ((struct sctp_sndinfo *)info)->snd_ppid;
sinfo.sinfo_context = ((struct sctp_sndinfo *)info)->snd_context;
sinfo.sinfo_assoc_id = ((struct sctp_sndinfo *)info)->snd_assoc_id;
assoc_id = &(((struct sctp_sndinfo *)info)->snd_assoc_id);
use_sinfo = 1;
break;
case SCTP_SENDV_PRINFO:
@ -820,6 +896,7 @@ usrsctp_sendv(struct socket *so,
sinfo.sinfo_ppid = ((struct sctp_sendv_spa *)info)->sendv_sndinfo.snd_ppid;
sinfo.sinfo_context = ((struct sctp_sendv_spa *)info)->sendv_sndinfo.snd_context;
sinfo.sinfo_assoc_id = ((struct sctp_sendv_spa *)info)->sendv_sndinfo.snd_assoc_id;
assoc_id = &(((struct sctp_sendv_spa *)info)->sendv_sndinfo.snd_assoc_id);
} else {
sinfo.sinfo_flags = 0;
sinfo.sinfo_stream = 0;
@ -856,6 +933,9 @@ usrsctp_sendv(struct socket *so,
auio.uio_resid = len;
errno = sctp_lower_sosend(so, to, &auio, NULL, NULL, flags, use_sinfo ? &sinfo : NULL);
if (errno == 0) {
if ((to != NULL) && (assoc_id != NULL)) {
*assoc_id = usrsctp_getassocid(so, to);
}
return (len - auio.uio_resid);
} else {
return (-1);
@ -881,7 +961,7 @@ userspace_sctp_sendmbuf(struct socket *so,
struct iovec iov[1]; */
int error = 0;
int uflags = 0;
int retvalsendmsg;
ssize_t retval;
sinfo->sinfo_ppid = ppid;
sinfo->sinfo_flags = flags;
@ -911,16 +991,16 @@ userspace_sctp_sendmbuf(struct socket *so,
sendmsg_return:
/* TODO: Needs a condition for non-blocking when error is EWOULDBLOCK */
if (0 == error)
retvalsendmsg = len;
else if(error == EWOULDBLOCK) {
retval = len;
else if (error == EWOULDBLOCK) {
errno = EWOULDBLOCK;
retvalsendmsg = (-1);
retval = -1;
} else {
SCTP_PRINTF("%s: error = %d\n", __func__, error);
errno = error;
retvalsendmsg = (-1);
retval = -1;
}
return retvalsendmsg;
return (retval);
}
@ -946,7 +1026,8 @@ userspace_sctp_recvmsg(struct socket *so,
struct iovec *tiov;
int iovlen = 1;
int error = 0;
int ulen, i, retval;
ssize_t ulen;
int i;
socklen_t fromlen;
iov[0].iov_base = dbuf;
@ -977,7 +1058,7 @@ userspace_sctp_recvmsg(struct socket *so,
(struct sctp_sndrcvinfo *)sinfo, 1);
if (error) {
if (auio.uio_resid != (int)ulen &&
if ((auio.uio_resid != ulen) &&
(error == EINTR ||
#if !defined(__Userspace_os_NetBSD)
error == ERESTART ||
@ -1009,10 +1090,9 @@ userspace_sctp_recvmsg(struct socket *so,
*fromlenp = fromlen;
}
}
if (error == 0){
if (error == 0) {
/* ready return value */
retval = (int)ulen - auio.uio_resid;
return (retval);
return (ulen - auio.uio_resid);
} else {
SCTP_PRINTF("%s: error = %d\n", __func__, error);
return (-1);
@ -1034,7 +1114,8 @@ usrsctp_recvv(struct socket *so,
struct iovec iov[SCTP_SMALL_IOVEC_SIZE];
struct iovec *tiov;
int iovlen = 1;
int ulen, i;
ssize_t ulen;
int i;
socklen_t fromlen;
struct sctp_rcvinfo *rcv;
struct sctp_recvv_rn *rn;
@ -1070,7 +1151,7 @@ usrsctp_recvv(struct socket *so,
from, fromlen, msg_flags,
(struct sctp_sndrcvinfo *)&seinfo, 1);
if (errno) {
if (auio.uio_resid != (int)ulen &&
if ((auio.uio_resid != ulen) &&
(errno == EINTR ||
#if !defined(__Userspace_os_NetBSD)
errno == ERESTART ||
@ -1155,7 +1236,7 @@ usrsctp_recvv(struct socket *so,
}
if (errno == 0) {
/* ready return value */
return ((int)ulen - auio.uio_resid);
return (ulen - auio.uio_resid);
} else {
return (-1);
}
@ -1336,7 +1417,7 @@ usrsctp_socket(int domain, int type, int protocol,
{
struct socket *so;
if ((protocol = IPPROTO_SCTP) && (SCTP_BASE_VAR(sctp_pcb_initialized) == 0)) {
if ((protocol == IPPROTO_SCTP) && (SCTP_BASE_VAR(sctp_pcb_initialized) == 0)) {
errno = EPROTONOSUPPORT;
return (NULL);
}
@ -1851,7 +1932,7 @@ accept1(struct socket *so, struct sockaddr *aname, socklen_t *anamelen, struct s
struct socket *
usrsctp_accept(struct socket *so, struct sockaddr *aname, socklen_t *anamelen)
{
struct socket *accept_return_sock;
struct socket *accept_return_sock = NULL;
errno = accept1(so, aname, anamelen, &accept_return_sock);
if (errno) {
@ -2153,6 +2234,16 @@ usrsctp_finish(void)
return (-1);
}
sctp_finish();
#if defined(__Userspace_os_Windows)
DeleteConditionVariable(&accept_cond);
DeleteCriticalSection(&accept_mtx);
#if defined(INET) || defined(INET6)
WSACleanup();
#endif
#else
pthread_cond_destroy(&accept_cond);
pthread_mutex_destroy(&accept_mtx);
#endif
return (0);
}
@ -2344,6 +2435,121 @@ userspace_getsockopt(struct socket *so, int level, int option_name,
return (usrsctp_getsockopt(so, level, option_name, option_value, option_len));
}
int
usrsctp_opt_info(struct socket *so, sctp_assoc_t id, int opt, void *arg, socklen_t *size)
{
if (arg == NULL) {
errno = EINVAL;
return (-1);
}
if ((id == SCTP_CURRENT_ASSOC) ||
(id == SCTP_ALL_ASSOC)) {
errno = EINVAL;
return (-1);
}
switch (opt) {
case SCTP_RTOINFO:
((struct sctp_rtoinfo *)arg)->srto_assoc_id = id;
break;
case SCTP_ASSOCINFO:
((struct sctp_assocparams *)arg)->sasoc_assoc_id = id;
break;
case SCTP_DEFAULT_SEND_PARAM:
((struct sctp_assocparams *)arg)->sasoc_assoc_id = id;
break;
case SCTP_PRIMARY_ADDR:
((struct sctp_setprim *)arg)->ssp_assoc_id = id;
break;
case SCTP_PEER_ADDR_PARAMS:
((struct sctp_paddrparams *)arg)->spp_assoc_id = id;
break;
case SCTP_MAXSEG:
((struct sctp_assoc_value *)arg)->assoc_id = id;
break;
case SCTP_AUTH_KEY:
((struct sctp_authkey *)arg)->sca_assoc_id = id;
break;
case SCTP_AUTH_ACTIVE_KEY:
((struct sctp_authkeyid *)arg)->scact_assoc_id = id;
break;
case SCTP_DELAYED_SACK:
((struct sctp_sack_info *)arg)->sack_assoc_id = id;
break;
case SCTP_CONTEXT:
((struct sctp_assoc_value *)arg)->assoc_id = id;
break;
case SCTP_STATUS:
((struct sctp_status *)arg)->sstat_assoc_id = id;
break;
case SCTP_GET_PEER_ADDR_INFO:
((struct sctp_paddrinfo *)arg)->spinfo_assoc_id = id;
break;
case SCTP_PEER_AUTH_CHUNKS:
((struct sctp_authchunks *)arg)->gauth_assoc_id = id;
break;
case SCTP_LOCAL_AUTH_CHUNKS:
((struct sctp_authchunks *)arg)->gauth_assoc_id = id;
break;
case SCTP_TIMEOUTS:
((struct sctp_timeouts *)arg)->stimo_assoc_id = id;
break;
case SCTP_EVENT:
((struct sctp_event *)arg)->se_assoc_id = id;
break;
case SCTP_DEFAULT_SNDINFO:
((struct sctp_sndinfo *)arg)->snd_assoc_id = id;
break;
case SCTP_DEFAULT_PRINFO:
((struct sctp_default_prinfo *)arg)->pr_assoc_id = id;
break;
case SCTP_PEER_ADDR_THLDS:
((struct sctp_paddrthlds *)arg)->spt_assoc_id = id;
break;
case SCTP_REMOTE_UDP_ENCAPS_PORT:
((struct sctp_udpencaps *)arg)->sue_assoc_id = id;
break;
case SCTP_ECN_SUPPORTED:
((struct sctp_assoc_value *)arg)->assoc_id = id;
break;
case SCTP_PR_SUPPORTED:
((struct sctp_assoc_value *)arg)->assoc_id = id;
break;
case SCTP_AUTH_SUPPORTED:
((struct sctp_assoc_value *)arg)->assoc_id = id;
break;
case SCTP_ASCONF_SUPPORTED:
((struct sctp_assoc_value *)arg)->assoc_id = id;
break;
case SCTP_RECONFIG_SUPPORTED:
((struct sctp_assoc_value *)arg)->assoc_id = id;
break;
case SCTP_NRSACK_SUPPORTED:
((struct sctp_assoc_value *)arg)->assoc_id = id;
break;
case SCTP_PKTDROP_SUPPORTED:
((struct sctp_assoc_value *)arg)->assoc_id = id;
break;
case SCTP_MAX_BURST:
((struct sctp_assoc_value *)arg)->assoc_id = id;
break;
case SCTP_ENABLE_STREAM_RESET:
((struct sctp_assoc_value *)arg)->assoc_id = id;
break;
case SCTP_PR_STREAM_STATUS:
((struct sctp_prstatus *)arg)->sprstat_assoc_id = id;
break;
case SCTP_PR_ASSOC_STATUS:
((struct sctp_prstatus *)arg)->sprstat_assoc_id = id;
break;
case SCTP_MAX_CWND:
((struct sctp_assoc_value *)arg)->assoc_id = id;
break;
default:
break;
}
return (usrsctp_getsockopt(so, IPPROTO_SCTP, opt, arg, size));
}
int
usrsctp_set_ulpinfo(struct socket *so, void *ulp_info)
{
@ -2460,6 +2666,24 @@ usrsctp_bindx(struct socket *so, struct sockaddr *addrs, int addrcnt, int flags)
gaddrs->sget_assoc_id = 0;
#ifdef HAVE_SA_LEN
memcpy(gaddrs->addr, sa, sa->sa_len);
#if defined(INET) || defined(INET6)
if ((i == 0) && (sport != 0)) {
switch (gaddrs->addr->sa_family) {
#ifdef INET
case AF_INET:
sin = (struct sockaddr_in *)gaddrs->addr;
sin->sin_port = sport;
break;
#endif
#ifdef INET6
case AF_INET6:
sin6 = (struct sockaddr_in6 *)gaddrs->addr;
sin6->sin6_port = sport;
break;
#endif
}
}
#endif
if (usrsctp_setsockopt(so, IPPROTO_SCTP, flags, gaddrs, (socklen_t)argsz) != 0) {
free(gaddrs);
return (-1);
@ -2548,9 +2772,13 @@ usrsctp_connectx(struct socket *so,
return (-1);
}
#endif
len += sizeof(struct sockaddr_in);
if (len > SCTP_STACK_BUF_SIZE) {
errno = ENOMEM;
return (-1);
}
memcpy(cpto, at, sizeof(struct sockaddr_in));
cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in));
len += sizeof(struct sockaddr_in);
at = (struct sockaddr *)((caddr_t)at + sizeof(struct sockaddr_in));
break;
#endif
@ -2564,18 +2792,30 @@ usrsctp_connectx(struct socket *so,
#endif
#ifdef INET
if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)at)->sin6_addr)) {
len += sizeof(struct sockaddr_in);
if (len > SCTP_STACK_BUF_SIZE) {
errno = ENOMEM;
return (-1);
}
in6_sin6_2_sin((struct sockaddr_in *)cpto, (struct sockaddr_in6 *)at);
cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in));
len += sizeof(struct sockaddr_in);
} else {
len += sizeof(struct sockaddr_in6);
if (len > SCTP_STACK_BUF_SIZE) {
errno = ENOMEM;
return (-1);
}
memcpy(cpto, at, sizeof(struct sockaddr_in6));
cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in6));
len += sizeof(struct sockaddr_in6);
}
#else
len += sizeof(struct sockaddr_in6);
if (len > SCTP_STACK_BUF_SIZE) {
errno = ENOMEM;
return (-1);
}
memcpy(cpto, at, sizeof(struct sockaddr_in6));
cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in6));
len += sizeof(struct sockaddr_in6);
#endif
at = (struct sockaddr *)((caddr_t)at + sizeof(struct sockaddr_in6));
break;
@ -2584,18 +2824,8 @@ usrsctp_connectx(struct socket *so,
errno = EINVAL;
return (-1);
}
if (len > (sizeof(buf) - sizeof(int))) {
/* Never enough memory */
errno = E2BIG;
return (-1);
}
cnt++;
}
/* do we have any? */
if (cnt == 0) {
errno = EINVAL;
return (-1);
}
aa = (int *)buf;
*aa = cnt;
ret = usrsctp_setsockopt(so, IPPROTO_SCTP, SCTP_CONNECT_X, (void *)buf, (socklen_t)len);
@ -2789,7 +3019,7 @@ sctp_userspace_ip_output(int *result, struct mbuf *o_pak,
struct sockaddr_in dst;
#if defined (__Userspace_os_Windows)
WSAMSG win_msg_hdr;
int win_sent_len;
DWORD win_sent_len;
WSABUF send_iovec[MAXLEN_MBUF_CHAIN];
WSABUF winbuf;
#else
@ -2833,7 +3063,7 @@ sctp_userspace_ip_output(int *result, struct mbuf *o_pak,
SCTP_PRINTF("Why did the SCTP implementation did not choose a source address?\n");
}
/* TODO need to worry about ro->ro_dst as in ip_output? */
#if defined(__Userspace_os_Linux) || defined (__Userspace_os_Windows)
#if defined(__Userspace_os_Linux) || defined (__Userspace_os_Windows) || (defined(__Userspace_os_FreeBSD) && (__FreeBSD_version >= 1100030))
/* need to put certain fields into network order for Linux */
ip->ip_len = htons(ip->ip_len);
ip->ip_off = 0;
@ -2885,12 +3115,12 @@ sctp_userspace_ip_output(int *result, struct mbuf *o_pak,
msg_hdr.msg_controllen = 0;
msg_hdr.msg_flags = 0;
if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp) > -1)) {
if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp) != -1)) {
if ((res = sendmsg(SCTP_BASE_VAR(userspace_rawsctp), &msg_hdr, MSG_DONTWAIT)) != send_len) {
*result = errno;
}
}
if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp) > -1)) {
if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp) != -1)) {
if ((res = sendmsg(SCTP_BASE_VAR(userspace_udpsctp), &msg_hdr, MSG_DONTWAIT)) != send_len) {
*result = errno;
}
@ -2905,14 +3135,14 @@ sctp_userspace_ip_output(int *result, struct mbuf *o_pak,
win_msg_hdr.Control = winbuf;
win_msg_hdr.dwFlags = 0;
if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp) > -1)) {
if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp) != -1)) {
if (WSASendTo(SCTP_BASE_VAR(userspace_rawsctp), (LPWSABUF) send_iovec, iovcnt, &win_sent_len, win_msg_hdr.dwFlags, win_msg_hdr.name, (int) win_msg_hdr.namelen, NULL, NULL) != 0) {
*result = WSAGetLastError();
} else if (win_sent_len != send_len) {
*result = WSAGetLastError();
}
}
if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp) > -1)) {
if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp) != -1)) {
if (WSASendTo(SCTP_BASE_VAR(userspace_udpsctp), (LPWSABUF) send_iovec, iovcnt, &win_sent_len, win_msg_hdr.dwFlags, win_msg_hdr.name, (int) win_msg_hdr.namelen, NULL, NULL) != 0) {
*result = WSAGetLastError();
} else if (win_sent_len != send_len) {
@ -2944,7 +3174,7 @@ void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak,
struct sockaddr_in6 dst;
#if defined (__Userspace_os_Windows)
WSAMSG win_msg_hdr;
int win_sent_len;
DWORD win_sent_len;
WSABUF send_iovec[MAXLEN_MBUF_CHAIN];
WSABUF winbuf;
#else
@ -3043,12 +3273,12 @@ void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak,
msg_hdr.msg_controllen = 0;
msg_hdr.msg_flags = 0;
if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp6) > -1)) {
if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp6) != -1)) {
if ((res = sendmsg(SCTP_BASE_VAR(userspace_rawsctp6), &msg_hdr, MSG_DONTWAIT)) != send_len) {
*result = errno;
}
}
if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp6) > -1)) {
if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp6) != -1)) {
if ((res = sendmsg(SCTP_BASE_VAR(userspace_udpsctp6), &msg_hdr, MSG_DONTWAIT)) != send_len) {
*result = errno;
}
@ -3063,14 +3293,14 @@ void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak,
win_msg_hdr.Control = winbuf;
win_msg_hdr.dwFlags = 0;
if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp6) > -1)) {
if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp6) != -1)) {
if (WSASendTo(SCTP_BASE_VAR(userspace_rawsctp6), (LPWSABUF) send_iovec, iovcnt, &win_sent_len, win_msg_hdr.dwFlags, win_msg_hdr.name, (int) win_msg_hdr.namelen, NULL, NULL) != 0) {
*result = WSAGetLastError();
} else if (win_sent_len != send_len) {
*result = WSAGetLastError();
}
}
if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp6) > -1)) {
if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp6) != -1)) {
if (WSASendTo(SCTP_BASE_VAR(userspace_udpsctp6), (LPWSABUF) send_iovec, iovcnt, &win_sent_len, win_msg_hdr.dwFlags, win_msg_hdr.name, (int) win_msg_hdr.namelen, NULL, NULL) != 0) {
*result = WSAGetLastError();
} else if (win_sent_len != send_len) {
@ -3130,7 +3360,7 @@ usrsctp_deregister_address(void *addr)
#define TRAILER "# SCTP_PACKET\n"
char *
usrsctp_dumppacket(void *buf, size_t len, int outbound)
usrsctp_dumppacket(const void *buf, size_t len, int outbound)
{
size_t i, pos;
char *dump_buf, *packet;
@ -3198,6 +3428,29 @@ usrsctp_freedumpbuffer(char *buf)
free(buf);
}
void
usrsctp_enable_crc32c_offload(void)
{
SCTP_BASE_VAR(crc32c_offloaded) = 1;
}
void
usrsctp_disable_crc32c_offload(void)
{
SCTP_BASE_VAR(crc32c_offloaded) = 0;
}
/* Compute the CRC32C in network byte order */
uint32_t
usrsctp_crc32c(void *buffer, size_t length)
{
uint32_t base = 0xffffffff;
base = calculate_crc32c(0xffffffff, (unsigned char *)buffer, (unsigned int) length);
base = sctp_finalize_crc32c(base);
return (base);
}
void
usrsctp_conninput(void *addr, const void *buffer, size_t length, uint8_t ecn_bits)
{
@ -3220,10 +3473,10 @@ usrsctp_conninput(void *addr, const void *buffer, size_t length, uint8_t ecn_bit
dst.sconn_len = sizeof(struct sockaddr_conn);
#endif
dst.sconn_addr = addr;
if ((m = sctp_get_mbuf_for_msg(length, 1, M_NOWAIT, 0, MT_DATA)) == NULL) {
if ((m = sctp_get_mbuf_for_msg((unsigned int)length, 1, M_NOWAIT, 0, MT_DATA)) == NULL) {
return;
}
m_copyback(m, 0, length, (caddr_t)buffer);
m_copyback(m, 0, (int)length, (caddr_t)buffer);
if (SCTP_BUF_LEN(m) < (int)(sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr))) {
if ((m = m_pullup(m, sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr))) == NULL) {
SCTP_STAT_INCR(sctps_hdrops);
@ -3234,12 +3487,12 @@ usrsctp_conninput(void *addr, const void *buffer, size_t length, uint8_t ecn_bit
ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
src.sconn_port = sh->src_port;
dst.sconn_port = sh->dest_port;
sctp_common_input_processing(&m, 0, sizeof(struct sctphdr), length,
sctp_common_input_processing(&m, 0, sizeof(struct sctphdr), (int)length,
(struct sockaddr *)&src,
(struct sockaddr *)&dst,
sh, ch,
#if !defined(SCTP_WITH_NO_CSUM)
1,
SCTP_BASE_VAR(crc32c_offloaded) == 1 ? 0 : 1,
#endif
ecn_bits,
SCTP_DEFAULT_VRFID, 0);
@ -3266,7 +3519,6 @@ USRSCTP_SYSCTL_SET_DEF(sctp_asconf_enable)
USRSCTP_SYSCTL_SET_DEF(sctp_reconfig_enable)
USRSCTP_SYSCTL_SET_DEF(sctp_nrsack_enable)
USRSCTP_SYSCTL_SET_DEF(sctp_pktdrop_enable)
USRSCTP_SYSCTL_SET_DEF(sctp_strict_sacks)
#if !defined(SCTP_WITH_NO_CSUM)
USRSCTP_SYSCTL_SET_DEF(sctp_no_csum_on_loopback)
#endif
@ -3294,6 +3546,7 @@ USRSCTP_SYSCTL_SET_DEF(sctp_init_rtx_max_default)
USRSCTP_SYSCTL_SET_DEF(sctp_assoc_rtx_max_default)
USRSCTP_SYSCTL_SET_DEF(sctp_path_rtx_max_default)
USRSCTP_SYSCTL_SET_DEF(sctp_add_more_threshold)
USRSCTP_SYSCTL_SET_DEF(sctp_nr_incoming_streams_default)
USRSCTP_SYSCTL_SET_DEF(sctp_nr_outgoing_streams_default)
USRSCTP_SYSCTL_SET_DEF(sctp_cmt_on_off)
USRSCTP_SYSCTL_SET_DEF(sctp_cmt_use_dac)
@ -3304,7 +3557,6 @@ USRSCTP_SYSCTL_SET_DEF(sctp_mbuf_threshold_count)
USRSCTP_SYSCTL_SET_DEF(sctp_do_drain)
USRSCTP_SYSCTL_SET_DEF(sctp_hb_maxburst)
USRSCTP_SYSCTL_SET_DEF(sctp_abort_if_one_2_one_hits_limit)
USRSCTP_SYSCTL_SET_DEF(sctp_strict_data_order)
USRSCTP_SYSCTL_SET_DEF(sctp_min_residual)
USRSCTP_SYSCTL_SET_DEF(sctp_max_retran_chunk)
USRSCTP_SYSCTL_SET_DEF(sctp_logging_level)
@ -3348,7 +3600,6 @@ USRSCTP_SYSCTL_GET_DEF(sctp_asconf_enable)
USRSCTP_SYSCTL_GET_DEF(sctp_reconfig_enable)
USRSCTP_SYSCTL_GET_DEF(sctp_nrsack_enable)
USRSCTP_SYSCTL_GET_DEF(sctp_pktdrop_enable)
USRSCTP_SYSCTL_GET_DEF(sctp_strict_sacks)
#if !defined(SCTP_WITH_NO_CSUM)
USRSCTP_SYSCTL_GET_DEF(sctp_no_csum_on_loopback)
#endif
@ -3376,6 +3627,7 @@ USRSCTP_SYSCTL_GET_DEF(sctp_init_rtx_max_default)
USRSCTP_SYSCTL_GET_DEF(sctp_assoc_rtx_max_default)
USRSCTP_SYSCTL_GET_DEF(sctp_path_rtx_max_default)
USRSCTP_SYSCTL_GET_DEF(sctp_add_more_threshold)
USRSCTP_SYSCTL_GET_DEF(sctp_nr_incoming_streams_default)
USRSCTP_SYSCTL_GET_DEF(sctp_nr_outgoing_streams_default)
USRSCTP_SYSCTL_GET_DEF(sctp_cmt_on_off)
USRSCTP_SYSCTL_GET_DEF(sctp_cmt_use_dac)
@ -3386,7 +3638,6 @@ USRSCTP_SYSCTL_GET_DEF(sctp_mbuf_threshold_count)
USRSCTP_SYSCTL_GET_DEF(sctp_do_drain)
USRSCTP_SYSCTL_GET_DEF(sctp_hb_maxburst)
USRSCTP_SYSCTL_GET_DEF(sctp_abort_if_one_2_one_hits_limit)
USRSCTP_SYSCTL_GET_DEF(sctp_strict_data_order)
USRSCTP_SYSCTL_GET_DEF(sctp_min_residual)
USRSCTP_SYSCTL_GET_DEF(sctp_max_retran_chunk)
USRSCTP_SYSCTL_GET_DEF(sctp_logging_level)

Просмотреть файл

@ -86,7 +86,7 @@ struct uio {
struct iovec *uio_iov; /* scatter/gather list */
int uio_iovcnt; /* length of scatter/gather list */
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_rw uio_rw; /* operation */
};
@ -248,14 +248,21 @@ extern userland_cond_t accept_cond;
#define ACCEPT_UNLOCK_ASSERT()
#else
extern userland_mutex_t accept_mtx;
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_UNLOCK() (void)pthread_mutex_unlock(&accept_mtx)
#define ACCEPT_UNLOCK_ASSERT() do{ \
#endif
#define ACCEPT_LOCK_ASSERT() \
KASSERT(pthread_mutex_trylock(&accept_mtx) == EBUSY, ("%s: accept_mtx not locked", __func__))
#define ACCEPT_UNLOCK_ASSERT() do { \
KASSERT(pthread_mutex_trylock(&accept_mtx) == 0, ("%s: accept_mtx locked", __func__)); \
(void)pthread_mutex_unlock(&accept_mtx); \
} while (0)
} while (0)
#endif
/*
@ -273,8 +280,19 @@ extern userland_cond_t accept_cond;
#define SOCK_COND_DESTROY(_so) DeleteConditionVariable((&(_so)->timeo_cond))
#define SOCK_COND(_so) (&(_so)->timeo_cond)
#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) \
pthread_mutex_init(SOCKBUF_MTX(_sb), NULL)
#endif
#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_DESTROY(_sb) pthread_cond_destroy((&(_sb)->sb_cond))

Просмотреть файл

@ -67,6 +67,7 @@ extern "C" {
#define uint8_t unsigned __int8
#define uint16_t unsigned __int16
#define uint32_t unsigned __int32
#define uint64_t unsigned __int64
#define int16_t __int16
#define int32_t __int32
#endif
@ -86,6 +87,25 @@ extern "C" {
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
/* The definition of struct sockaddr_conn MUST be in
* tune with other sockaddr_* structures.
@ -523,6 +543,10 @@ struct sctp_event_subscribe {
#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
*/
@ -533,6 +557,9 @@ struct sctp_event_subscribe {
#define SCTP_LOCAL_AUTH_CHUNKS 0x00000103
#define SCTP_GET_ASSOC_NUMBER 0x00000104
#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
@ -778,6 +805,12 @@ struct sctp_cc_option {
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 {
sctp_assoc_t stimo_assoc_id;
uint32_t stimo_init;
@ -789,6 +822,13 @@ struct sctp_timeouts {
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 */
#define SCTP_CC_RFC2581 0x00000000
@ -857,6 +897,13 @@ usrsctp_getsockopt(struct socket *so,
void *option_value,
socklen_t *option_len);
int
usrsctp_opt_info(struct socket *so,
sctp_assoc_t id,
int opt,
void *arg,
socklen_t *size);
int
usrsctp_getpaddrs(struct socket *so,
sctp_assoc_t id,
@ -934,6 +981,9 @@ usrsctp_connectx(struct socket *so,
void
usrsctp_close(struct socket *so);
sctp_assoc_t
usrsctp_getassocid(struct socket *, struct sockaddr *);
int
usrsctp_finish(void);
@ -962,11 +1012,20 @@ usrsctp_set_ulpinfo(struct socket *, void *);
#define SCTP_DUMP_INBOUND 0
char *
usrsctp_dumppacket(void *, size_t, int);
usrsctp_dumppacket(const void *, size_t, int);
void
usrsctp_freedumpbuffer(char *);
void
usrsctp_enable_crc32c_offload(void);
void
usrsctp_disable_crc32c_offload(void);
uint32_t
usrsctp_crc32c(void *, size_t);
#define USRSCTP_SYSCTL_DECL(__field) \
void usrsctp_sysctl_set_ ## __field(uint32_t value);\
uint32_t usrsctp_sysctl_get_ ## __field(void);
@ -982,7 +1041,6 @@ USRSCTP_SYSCTL_DECL(sctp_asconf_enable)
USRSCTP_SYSCTL_DECL(sctp_reconfig_enable)
USRSCTP_SYSCTL_DECL(sctp_nrsack_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)
#endif
@ -1021,7 +1079,6 @@ USRSCTP_SYSCTL_DECL(sctp_mbuf_threshold_count)
USRSCTP_SYSCTL_DECL(sctp_do_drain)
USRSCTP_SYSCTL_DECL(sctp_hb_maxburst)
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_max_retran_chunk)
USRSCTP_SYSCTL_DECL(sctp_logging_level)