Merge remote-tracking branch 'origin/tracking' into custom

This commit is contained in:
2026-02-24 09:17:34 +08:00
58 changed files with 1393 additions and 1586 deletions
+1
View File
@@ -111,3 +111,4 @@ MSG_DEF(MSG_PMO_INVALID_MEMBERS, 0, JSEXN_TYPEERR, "PerformanceMeasureOptions ca
MSG_DEF(MSG_PMO_CONSTRUCTOR_INACCESSIBLE, 0, JSEXN_TYPEERR, "Can't access PerformanceMark constructor, performance is null.")
MSG_DEF(MSG_PMO_UNEXPECTED_START_TIME, 0, JSEXN_TYPEERR, "Expected startTime >= 0.")
MSG_DEF(MSG_PMO_INVALID_ATTR_FOR_NON_GLOBAL, 1, JSEXN_TYPEERR, "Cannot get PerformanceTiming attribute values for non-Window global object. Given: {0}.")
MSG_DEF(MSG_NOT_SUBMIT_BUTTON, 0, JSEXN_TYPEERR, "The submitter is not a submit button.")
+35
View File
@@ -276,6 +276,41 @@ HTMLFormElement::Submit()
return rv.StealNSResult();
}
// https://html.spec.whatwg.org/multipage/forms.html#dom-form-requestsubmit
void
HTMLFormElement::RequestSubmit(nsGenericHTMLElement* aSubmitter,
ErrorResult& aRv) {
// 1. If submitter is not null, then:
if (aSubmitter) {
nsCOMPtr<nsIFormControl> fc = do_QueryObject(aSubmitter);
// 1.1. If submitter is not a submit button, then throw a TypeError.
if (!fc || !fc->IsSubmitControl()) {
aRv.ThrowTypeError<MSG_NOT_SUBMIT_BUTTON>();
return;
}
// 1.2. If submitter's form owner is not this form element, then throw a
// "NotFoundError" DOMException.
if (fc->GetFormElement() != this) {
aRv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
return;
}
}
// 2. Otherwise, set submitter to this form element.
// 3. Submit this form element, from submitter.
// We go through the presShell here for the corner case a submit event
// is pending while the window is being destroyed.
InternalFormEvent event(true, eFormSubmit);
event.mOriginator = aSubmitter;
nsEventStatus status = nsEventStatus_eIgnore;
nsCOMPtr<nsIPresShell> presShell = GetComposedDoc()->GetShell();
if (MOZ_LIKELY(presShell)) {
presShell->HandleDOMEventWithTarget(this, &event, &status);
}
}
NS_IMETHODIMP
HTMLFormElement::Reset()
{
+13
View File
@@ -391,6 +391,19 @@ public:
void Submit(ErrorResult& aRv);
/**
* Requests to submit the form. Unlike submit(), this method includes
* interactive constraint validation and firing a submit event,
* either of which can cancel submission.
*
* @param aSubmitter The submitter argument can be used to point to a specific
* submit button.
* @param aRv An ErrorResult.
* @see
* https://html.spec.whatwg.org/multipage/forms.html#dom-form-requestsubmit
*/
void RequestSubmit(nsGenericHTMLElement* aSubmitter, ErrorResult& aRv);
// XPCOM Reset() is OK
bool CheckValidity()
+2
View File
@@ -43,6 +43,8 @@ interface HTMLFormElement : HTMLElement {
[Throws]
void submit();
[Pref="dom.forms.requestsubmit.enabled", Throws]
void requestSubmit(optional HTMLElement? submitter = null);
[CEReactions]
void reset();
boolean checkValidity();
+1 -1
View File
@@ -148,7 +148,7 @@ _cairo_popcount (uint32_t mask)
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
return __builtin_popcount (mask);
#else
register int y;
int y;
y = (mask >> 1) &033333333333;
y = mask - y - ((y >>1) & 033333333333);
+18 -2
View File
@@ -215,9 +215,25 @@ if CONFIG['MOZ_TREE_FREETYPE']:
# Suppress warnings in third-party code.
if CONFIG['_MSC_VER']:
CFLAGS += [
'-wd4005',
'-wd4146',
'-wd4005', # 'WIN32_LEAN_AND_MEAN' : macro redefinition
'-wd4018', # '>' : signed/unsigned mismatch
'-wd4047', # different levels of indirection
'-wd4101', # unreferenced local variable
'-wd4133', # 'function' : incompatible types
'-wd4146', # unary minus operator applied to unsigned type
'-wd4311', # 'variable' : pointer truncation from 'type' to 'type'
'-wd4477', # format string '%s' requires an argument of type 'type'
'-wd4996', # The compiler encountered a deprecated declaration.
'-wd5286', # implicit conversion between enum types
'-wd5287', # operands are different enum types
]
CXXFLAGS += [
'-wd4005', # 'WIN32_LEAN_AND_MEAN' : macro redefinition
'-wd4018', # '>' : signed/unsigned mismatch
'-wd4146', # unary minus operator applied to unsigned type
'-wd4828', # illegal in the current source character set
'-wd4838', # requires a narrowing conversion
]
if CONFIG['GNU_CC'] or CONFIG['CLANG_CL']:
CFLAGS += [
'-Wno-enum-compare',
+3
View File
@@ -1195,6 +1195,9 @@ pref("dom.forms.autocomplete.experimental", false);
// Enables requestAutocomplete DOM API on forms.
pref("dom.forms.requestAutocomplete", false);
// Enables requestSubmit DOM API on forms.
pref("dom.forms.requestsubmit.enabled", true);
// Enable Directory API. By default, disabled.
pref("dom.input.dirpicker", false);
+2
View File
@@ -19,3 +19,5 @@ sctp updated to version 9209 from SVN on Tue Mar 24 18:11:59 EDT 2015
sctp updated to version 0e076261b832121cf120ddc04aaff87ac3a34d30 from git on Tue Nov 28 15:20:51 EST 2017
sctp updated to version ea345b6d0c8a0f8701cf49445dba5ec8d34e2305 from git on Tue 30 Jun 14:01:18 CEST 2020
sctp updated to version 8e12cd9e01fc94d2e84ea1afa351c845966e116e from git on Mon Oct 17 10:23:01 CDT 2022
sctp updated to version 0.9.5.0 from https://github.com/sctplab/usrsctp/releases/tag/0.9.5.0 on Sat Aug 26 21:54:00 EDT 2023
sctp updated to commit fd070e05a7474f38c7fecdf4d4b6005d2547ee00 from https://github.com/sctplab/usrsctp/commit/fd070e05a7474f38c7fecdf4d4b6005d2547ee00 on Wed Feb 18 18:05:35 EST 2026
+2 -2
View File
@@ -1,5 +1,5 @@
This code is imported from the usrsctp library. The current code is version
8e12cd9e01fc94d2e84ea1afa351c845966e116e from git.
This code is imported from the usrsctp library. The current code is based on
master commit fd070e05a7474f38c7fecdf4d4b6005d2547ee00 (2025-10-16).
The project is accessed on GitHub at the following location:
+16 -12
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_H_
#define _NETINET_SCTP_H_
@@ -199,8 +194,11 @@ struct sctp_paramhdr {
/* JRS - Pluggable Congestion Control Socket option */
#define SCTP_PLUGGABLE_CC 0x00001202
/* RS - Pluggable Stream Scheduling Socket option */
#define SCTP_PLUGGABLE_SS 0x00001203
#define SCTP_SS_VALUE 0x00001204
#define SCTP_STREAM_SCHEDULER 0x00001203
#define SCTP_STREAM_SCHEDULER_VALUE 0x00001204
/* The next two are for backwards compatibility. */
#define SCTP_PLUGGABLE_SS SCTP_STREAM_SCHEDULER
#define SCTP_SS_VALUE SCTP_STREAM_SCHEDULER_VALUE
#define SCTP_CC_OPTION 0x00001205 /* Options for CC modules */
/* For I-DATA */
#define SCTP_INTERLEAVING_SUPPORTED 0x00001206
@@ -323,15 +321,21 @@ struct sctp_paramhdr {
/* Default simple round-robin */
#define SCTP_SS_DEFAULT 0x00000000
/* Real round-robin */
#define SCTP_SS_ROUND_ROBIN 0x00000001
#define SCTP_SS_RR 0x00000001
/* Real round-robin per packet */
#define SCTP_SS_ROUND_ROBIN_PACKET 0x00000002
#define SCTP_SS_RR_PKT 0x00000002
/* Priority */
#define SCTP_SS_PRIORITY 0x00000003
#define SCTP_SS_PRIO 0x00000003
/* Fair Bandwidth */
#define SCTP_SS_FAIR_BANDWITH 0x00000004
#define SCTP_SS_FB 0x00000004
/* First-come, first-serve */
#define SCTP_SS_FIRST_COME 0x00000005
#define SCTP_SS_FCFS 0x00000005
/* The next five are for backwards compatibility. */
#define SCTP_SS_ROUND_ROBIN SCTP_SS_RR
#define SCTP_SS_ROUND_ROBIN_PACKET SCTP_SS_RR_PKT
#define SCTP_SS_PRIORITY SCTP_SS_PRIO
#define SCTP_SS_FAIR_BANDWITH SCTP_SS_FB
#define SCTP_SS_FIRST_COME SCTP_SS_FCFS
/* fragment interleave constants
* setting must be one of these or
+3 -8
View File
@@ -40,11 +40,6 @@
#endif
#endif
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
#include <netinet/sctp_var.h>
#include <netinet/sctp_sysctl.h>
@@ -1360,13 +1355,13 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
#ifdef SCTP_DEBUG
if (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_ASCONF2) {
if (type == SCTP_ADD_IP_ADDRESS) {
SCTP_PRINTF("asconf_queue_mgmt: inserted asconf ADD_IP_ADDRESS: ");
SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: inserted asconf ADD_IP_ADDRESS: ");
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
} else if (type == SCTP_DEL_IP_ADDRESS) {
SCTP_PRINTF("asconf_queue_mgmt: appended asconf DEL_IP_ADDRESS: ");
SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: appended asconf DEL_IP_ADDRESS: ");
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
} else {
SCTP_PRINTF("asconf_queue_mgmt: appended asconf SET_PRIM_ADDR: ");
SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: appended asconf SET_PRIM_ADDR: ");
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
}
}
-5
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_ASCONF_H_
#define _NETINET_SCTP_ASCONF_H_
+20 -29
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
#include <netinet/sctp.h>
#include <netinet/sctp_header.h>
@@ -580,7 +575,7 @@ sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id, int so_locked)
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);
0, &key_id, so_locked);
SCTPDBG(SCTP_DEBUG_AUTH2,
"%s: stcb %p key %u no longer used, %d\n",
__func__, (void *)stcb, key_id, skey->refcount);
@@ -1339,8 +1334,8 @@ sctp_deact_sharedkey(struct sctp_tcb *stcb, uint16_t keyid)
/* are there other refcount holders on the key? */
if (skey->refcount == 1) {
/* no other users, send a notification for this key */
sctp_ulp_notify(SCTP_NOTIFY_AUTH_FREE_KEY, stcb, keyid, 0,
SCTP_SO_LOCKED);
sctp_ulp_notify(SCTP_NOTIFY_AUTH_FREE_KEY, stcb, 0, &keyid,
SCTP_SO_LOCKED);
}
/* mark the key as deactivated */
@@ -1684,15 +1679,10 @@ sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *auth,
return (-1);
}
/* generate a notification if this is a new key id */
if (stcb->asoc.authinfo.recv_keyid != shared_key_id)
/*
* sctp_ulp_notify(SCTP_NOTIFY_AUTH_NEW_KEY, stcb,
* shared_key_id, (void
* *)stcb->asoc.authinfo.recv_keyid);
*/
sctp_notify_authentication(stcb, SCTP_AUTH_NEW_KEY,
shared_key_id, stcb->asoc.authinfo.recv_keyid,
SCTP_SO_NOT_LOCKED);
if (stcb->asoc.authinfo.recv_keyid != shared_key_id) {
sctp_ulp_notify(SCTP_NOTIFY_AUTH_NEW_KEY, stcb, 0,
&shared_key_id, SCTP_SO_NOT_LOCKED);
}
/* compute a new recv assoc key and cache it */
if (stcb->asoc.authinfo.recv_key != NULL)
sctp_free_key(stcb->asoc.authinfo.recv_key);
@@ -1735,27 +1725,22 @@ sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *auth,
*/
void
sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
uint16_t keyid, uint16_t alt_keyid, int so_locked)
uint16_t keyid, int so_locked)
{
struct mbuf *m_notify;
struct sctp_authkey_event *auth;
struct sctp_queued_to_read *control;
if ((stcb == NULL) ||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
(stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)
) {
/* If the socket is gone we are out of here */
return;
}
KASSERT(stcb != NULL, ("stcb == NULL"));
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_AUTHEVNT))
/* event not enabled */
return;
m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_authkey_event),
0, M_NOWAIT, 1, MT_HEADER);
0, M_NOWAIT, 1, MT_HEADER);
if (m_notify == NULL)
/* no space left */
return;
@@ -1767,7 +1752,12 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
auth->auth_flags = 0;
auth->auth_length = sizeof(*auth);
auth->auth_keynumber = keyid;
auth->auth_altkeynumber = alt_keyid;
/* XXXMT: The following is BSD specific. */
if (indication == SCTP_AUTH_NEW_KEY) {
auth->auth_altkeynumber = stcb->asoc.authinfo.recv_keyid;
} else {
auth->auth_altkeynumber = 0;
}
auth->auth_indication = indication;
auth->auth_assoc_id = sctp_get_associd(stcb);
@@ -1787,7 +1777,8 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb, control,
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, so_locked);
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_HELD, so_locked);
}
/*-
+1 -6
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_AUTH_H_
#define _NETINET_SCTP_AUTH_H_
@@ -199,7 +194,7 @@ extern struct mbuf *sctp_add_auth_chunk(struct mbuf *m, struct mbuf **m_end,
extern int sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *ch,
struct mbuf *m, uint32_t offset);
extern void sctp_notify_authentication(struct sctp_tcb *stcb,
uint32_t indication, uint16_t keyid, uint16_t alt_keyid, int so_locked);
uint32_t indication, uint16_t keyid, int so_locked);
extern int sctp_validate_init_auth_params(struct mbuf *m, int offset,
int limit);
extern void sctp_initialize_auth_params(struct sctp_inpcb *inp,
+15 -14
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
#include <netinet/sctp_var.h>
#include <netinet/sctp_pcb.h>
@@ -304,7 +299,14 @@ sctp_is_vmware_interface(struct ifnet *ifn)
#endif
#if defined(_WIN32) && defined(__Userspace__)
#define SCTP_BSD_FREE(x) if((x)) GlobalFree((x))
#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)
{
@@ -334,7 +336,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);
SCTP_BSD_FREE(pAdapterAddrs);
FREE(pAdapterAddrs);
return;
}
/* Enumerate through each returned adapter and save its information */
@@ -359,7 +361,7 @@ sctp_init_ifns_for_vrf(int vrfid)
}
}
}
SCTP_BSD_FREE(pAdapterAddrs);
FREE(pAdapterAddrs);
#endif
#ifdef INET6
AdapterAddrsSize = 0;
@@ -379,7 +381,7 @@ 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);
SCTP_BSD_FREE(pAdapterAddrs);
FREE(pAdapterAddrs);
return;
}
/* Enumerate through each returned adapter and save its information */
@@ -401,7 +403,7 @@ sctp_init_ifns_for_vrf(int vrfid)
}
}
}
SCTP_BSD_FREE(pAdapterAddrs);
FREE(pAdapterAddrs);
#endif
}
#elif defined(__Userspace__)
@@ -711,12 +713,11 @@ sctp_addr_change(struct ifaddr *ifa, int cmd)
(void *)ifa, ifa->ifa_addr, ifa_flags, 1);
} else {
sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, ifa->ifa_addr,
(void *)ifa->ifa_ifp,
#if defined(__APPLE__) && !defined(__Userspace__)
ifnet_index(ifa->ifa_ifp),
ifnet_name(ifa->ifa_ifp));
ifnet_index(ifa->ifa_ifp));
#else
ifa->ifa_ifp->if_index,
ifa->ifa_ifp->if_xname);
ifa->ifa_ifp->if_index);
#endif
/* We don't bump refcount here so when it completes
-5
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_BSD_ADDR_H_
#define _NETINET_SCTP_BSD_ADDR_H_
-5
View File
@@ -30,11 +30,6 @@
* SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_CALLOUT_
#define _NETINET_SCTP_CALLOUT_
+138 -133
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
#include <netinet/sctp_var.h>
#include <netinet/sctp_sysctl.h>
@@ -54,10 +49,20 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_kdtrace.h>
#endif
#if defined(_WIN32) && defined(__MINGW32__)
#include <minmax.h>
#endif
#define SHIFT_MPTCP_MULTI_N 40
#define SHIFT_MPTCP_MULTI_Z 16
#define SHIFT_MPTCP_MULTI 8
#ifdef KDTRACE_HOOKS
#define __dtrace
#else
#define __dtrace __unused
#endif
static void
sctp_enforce_cwnd_limit(struct sctp_association *assoc, struct sctp_nets *net)
{
@@ -103,8 +108,8 @@ sctp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net)
net->ssthresh = assoc->peers_rwnd;
#if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE5(sctp, cwnd, net, init,
stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net,
0, net->cwnd);
stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net,
0, net->cwnd);
#endif
if (SCTP_BASE_SYSCTL(sctp_logging_level) &
(SCTP_CWND_MONITOR_ENABLE|SCTP_CWND_LOGGING_ENABLE)) {
@@ -197,8 +202,8 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb,
sctp_enforce_cwnd_limit(asoc, net);
#if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE5(sctp, cwnd, net, fr,
stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net,
old_cwnd, net->cwnd);
stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net,
old_cwnd, net->cwnd);
#endif
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd),
@@ -261,7 +266,7 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
#endif
{
#if defined(__FreeBSD__) && !defined(__Userspace__)
uint64_t oth, probepoint;
uint64_t oth __dtrace, probepoint __dtrace;
#endif
#if defined(__FreeBSD__) && !defined(__Userspace__)
@@ -277,11 +282,11 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
/* Probe point 5 */
probepoint |= ((5 << 16) | 1);
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
#endif
if ((net->cc_mod.rtcc.steady_step) && (inst_ind != SCTP_INST_LOOSING)) {
if (net->cc_mod.rtcc.last_step_state == 5)
@@ -300,11 +305,11 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
oth <<= 16;
oth |= net->cc_mod.rtcc.last_step_state;
SDT_PROBE5(sctp, cwnd, net, rttstep,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
oth,
probepoint);
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
oth,
probepoint);
#endif
if (net->cwnd > (4 * net->mtu)) {
net->cwnd -= net->mtu;
@@ -326,11 +331,11 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
/* Probe point 6 */
probepoint |= ((6 << 16) | 0);
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
#endif
if (net->cc_mod.rtcc.steady_step) {
#if defined(__FreeBSD__) && !defined(__Userspace__)
@@ -340,11 +345,11 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
oth <<= 16;
oth |= net->cc_mod.rtcc.last_step_state;
SDT_PROBE5(sctp, cwnd, net, rttstep,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
oth,
probepoint);
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
oth,
probepoint);
#endif
if ((net->cc_mod.rtcc.last_step_state == 5) &&
(net->cc_mod.rtcc.step_cnt > net->cc_mod.rtcc.steady_step)) {
@@ -372,11 +377,11 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb
/* Probe point 7 */
probepoint |= ((7 << 16) | net->cc_mod.rtcc.ret_from_eq);
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
#endif
if ((net->cc_mod.rtcc.steady_step) && (inst_ind != SCTP_INST_LOOSING)) {
if (net->cc_mod.rtcc.last_step_state == 5)
@@ -416,7 +421,7 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
#endif
{
#if defined(__FreeBSD__) && !defined(__Userspace__)
uint64_t oth, probepoint;
uint64_t oth __dtrace, probepoint __dtrace;
#endif
/* Bandwidth decreased.*/
@@ -433,11 +438,11 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
/* PROBE POINT 1 */
probepoint |= ((1 << 16) | 1);
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
#endif
if (net->cc_mod.rtcc.ret_from_eq) {
/* Switch over to CA if we are less aggressive */
@@ -450,11 +455,11 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
/* Probe point 2 */
probepoint |= ((2 << 16) | 0);
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
#endif
/* Someone else - fight for more? */
if (net->cc_mod.rtcc.steady_step) {
@@ -465,10 +470,10 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
oth <<= 16;
oth |= net->cc_mod.rtcc.last_step_state;
SDT_PROBE5(sctp, cwnd, net, rttstep,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
oth,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
oth,
probepoint);
#endif
/* Did we voluntarily give up some? if so take
@@ -490,11 +495,11 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
/* Probe point 3 */
probepoint |= ((3 << 16) | 0);
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
#endif
if (net->cc_mod.rtcc.steady_step) {
#if defined(__FreeBSD__) && !defined(__Userspace__)
@@ -504,11 +509,11 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
oth <<= 16;
oth |= net->cc_mod.rtcc.last_step_state;
SDT_PROBE5(sctp, cwnd, net, rttstep,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
oth,
probepoint);
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
oth,
probepoint);
#endif
if ((net->cc_mod.rtcc.vol_reduce) &&
(inst_ind != SCTP_INST_GAINING)) {
@@ -526,11 +531,11 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
/* Probe point 4 */
probepoint |= ((4 << 16) | 0);
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
#endif
if (net->cc_mod.rtcc.steady_step) {
#if defined(__FreeBSD__) && !defined(__Userspace__)
@@ -540,11 +545,11 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
oth <<= 16;
oth |= net->cc_mod.rtcc.last_step_state;
SDT_PROBE5(sctp, cwnd, net, rttstep,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
oth,
probepoint);
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
oth,
probepoint);
#endif
if ((net->cc_mod.rtcc.vol_reduce) &&
(inst_ind != SCTP_INST_GAINING)) {
@@ -575,7 +580,7 @@ cc_bw_increase(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
#endif
{
#if defined(__FreeBSD__) && !defined(__Userspace__)
uint64_t oth, probepoint;
uint64_t oth __dtrace, probepoint __dtrace;
#endif
/* BW increased, so update and
@@ -588,11 +593,11 @@ cc_bw_increase(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
/* PROBE POINT 0 */
probepoint = (((uint64_t)net->cwnd) << 32);
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
#endif
if (net->cc_mod.rtcc.steady_step) {
#if defined(__FreeBSD__) && !defined(__Userspace__)
@@ -602,11 +607,11 @@ cc_bw_increase(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_
oth <<= 16;
oth |= net->cc_mod.rtcc.last_step_state;
SDT_PROBE5(sctp, cwnd, net, rttstep,
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
oth,
probepoint);
vtag,
((net->cc_mod.rtcc.lbw << 32) | nbw),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
oth,
probepoint);
#endif
net->cc_mod.rtcc.last_step_state = 0;
net->cc_mod.rtcc.step_cnt = 0;
@@ -626,7 +631,7 @@ cc_bw_limit(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw)
{
uint64_t bw_offset, rtt_offset;
#if defined(__FreeBSD__) && !defined(__Userspace__)
uint64_t probepoint, rtt, vtag;
uint64_t probepoint __dtrace, rtt, vtag;
#endif
uint64_t bytes_for_this_rtt, inst_bw;
uint64_t div, inst_off;
@@ -713,11 +718,11 @@ cc_bw_limit(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw)
}
#if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((nbw << 32) | inst_bw),
((net->cc_mod.rtcc.lbw_rtt << 32) | rtt),
net->flight_size,
probepoint);
vtag,
((nbw << 32) | inst_bw),
((net->cc_mod.rtcc.lbw_rtt << 32) | rtt),
net->flight_size,
probepoint);
#endif
} else {
/* No rtt measurement, use last one */
@@ -762,7 +767,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
{
struct sctp_nets *net;
#if defined(__FreeBSD__) && !defined(__Userspace__)
int old_cwnd;
int old_cwnd __dtrace;
#endif
uint32_t t_ssthresh, incr;
uint64_t t_ucwnd_sbw;
@@ -875,7 +880,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
}
} else {
#if defined(__FreeBSD__) && !defined(__Userspace__)
uint64_t vtag, probepoint;
uint64_t vtag __dtrace, probepoint __dtrace;
probepoint = (((uint64_t)net->cwnd) << 32);
probepoint |= ((0xa << 16) | 0);
@@ -884,11 +889,11 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
(stcb->rport);
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
nbw,
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
vtag,
nbw,
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
#endif
net->cc_mod.rtcc.lbw = nbw;
net->cc_mod.rtcc.lbw_rtt = net->rtt;
@@ -984,10 +989,10 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
}
#if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE5(sctp, cwnd, net, ack,
stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net,
old_cwnd, net->cwnd);
stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net,
old_cwnd, net->cwnd);
#endif
} else {
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
@@ -1048,10 +1053,10 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
sctp_enforce_cwnd_limit(asoc, net);
#if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE5(sctp, cwnd, net, ack,
stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net,
old_cwnd, net->cwnd);
stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net,
old_cwnd, net->cwnd);
#endif
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
sctp_log_cwnd(stcb, net, net->mtu,
@@ -1082,15 +1087,15 @@ sctp_cwnd_update_exit_pf_common(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_n
#endif
{
#if defined(__FreeBSD__) && !defined(__Userspace__)
int old_cwnd;
int old_cwnd __dtrace;
old_cwnd = net->cwnd;
#endif
net->cwnd = net->mtu;
#if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE5(sctp, cwnd, net, ack,
stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net,
old_cwnd, net->cwnd);
stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net,
old_cwnd, net->cwnd);
#endif
SCTPDBG(SCTP_DEBUG_INDATA1, "Destination %p moved from PF to reachable with cwnd %d.\n",
(void *)net, net->cwnd);
@@ -1161,10 +1166,10 @@ sctp_cwnd_update_after_timeout(struct sctp_tcb *stcb, struct sctp_nets *net)
net->partial_bytes_acked = 0;
#if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE5(sctp, cwnd, net, to,
stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net,
old_cwnd, net->cwnd);
stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net,
old_cwnd, net->cwnd);
#endif
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
sctp_log_cwnd(stcb, net, net->cwnd - old_cwnd, SCTP_CWND_LOG_FROM_RTX);
@@ -1215,10 +1220,10 @@ sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets *
net->cwnd = net->ssthresh;
#if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE5(sctp, cwnd, net, ecn,
stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net,
old_cwnd, net->cwnd);
stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net,
old_cwnd, net->cwnd);
#endif
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SAT);
@@ -1336,10 +1341,10 @@ sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb,
/* log only changes */
#if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE5(sctp, cwnd, net, pd,
stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net,
old_cwnd, net->cwnd);
stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net,
old_cwnd, net->cwnd);
#endif
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd),
@@ -1361,10 +1366,10 @@ sctp_cwnd_update_after_output(struct sctp_tcb *stcb,
sctp_enforce_cwnd_limit(&stcb->asoc, net);
#if defined(__FreeBSD__) && !defined(__Userspace__)
SDT_PROBE5(sctp, cwnd, net, bl,
stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net,
old_cwnd, net->cwnd);
stcb->asoc.my_vtag,
((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
net,
old_cwnd, net->cwnd);
#endif
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_BRST);
@@ -1425,7 +1430,7 @@ sctp_cwnd_new_rtcc_transmission_begins(struct sctp_tcb *stcb,
struct sctp_nets *net)
{
#if defined(__FreeBSD__) && !defined(__Userspace__)
uint64_t vtag, probepoint;
uint64_t vtag __dtrace, probepoint __dtrace;
#endif
if (net->cc_mod.rtcc.lbw) {
@@ -1437,11 +1442,11 @@ sctp_cwnd_new_rtcc_transmission_begins(struct sctp_tcb *stcb,
/* Probe point 8 */
probepoint |= ((8 << 16) | 0);
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
((net->cc_mod.rtcc.lbw << 32) | 0),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
vtag,
((net->cc_mod.rtcc.lbw << 32) | 0),
((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
net->flight_size,
probepoint);
#endif
net->cc_mod.rtcc.lbw_rtt = 0;
net->cc_mod.rtcc.cwnd_at_bw_set = 0;
@@ -1486,7 +1491,7 @@ sctp_set_rtcc_initial_cc_param(struct sctp_tcb *stcb,
struct sctp_nets *net)
{
#if defined(__FreeBSD__) && !defined(__Userspace__)
uint64_t vtag, probepoint;
uint64_t vtag __dtrace, probepoint __dtrace;
#endif
sctp_set_initial_cc_param(stcb, net);
@@ -1498,11 +1503,11 @@ sctp_set_rtcc_initial_cc_param(struct sctp_tcb *stcb,
(((uint32_t)(stcb->sctp_ep->sctp_lport)) << 16) |
(stcb->rport);
SDT_PROBE5(sctp, cwnd, net, rttvar,
vtag,
0,
0,
0,
probepoint);
vtag,
0,
0,
0,
probepoint);
#endif
net->cc_mod.rtcc.lbw_rtt = 0;
net->cc_mod.rtcc.cwnd_at_bw_set = 0;
+8 -11
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_CONSTANTS_H_
#define _NETINET_SCTP_CONSTANTS_H_
@@ -727,12 +722,14 @@ extern void getwintimeofday(struct timeval *tv);
#define SCTP_NOTIFY_STR_RESET_FAILED_IN 20
#define SCTP_NOTIFY_STR_RESET_DENIED_OUT 21
#define SCTP_NOTIFY_STR_RESET_DENIED_IN 22
#define SCTP_NOTIFY_AUTH_NEW_KEY 23
#define SCTP_NOTIFY_AUTH_FREE_KEY 24
#define SCTP_NOTIFY_NO_PEER_AUTH 25
#define SCTP_NOTIFY_SENDER_DRY 26
#define SCTP_NOTIFY_REMOTE_ERROR 27
#define SCTP_NOTIFY_ASSOC_TIMEDOUT 28
#define SCTP_NOTIFY_STR_RESET_ADD 23
#define SCTP_NOTIFY_STR_RESET_TSN 24
#define SCTP_NOTIFY_AUTH_NEW_KEY 25
#define SCTP_NOTIFY_AUTH_FREE_KEY 26
#define SCTP_NOTIFY_NO_PEER_AUTH 27
#define SCTP_NOTIFY_SENDER_DRY 28
#define SCTP_NOTIFY_REMOTE_ERROR 29
#define SCTP_NOTIFY_ASSOC_TIMEDOUT 30
/* This is the value for messages that are NOT completely
* copied down where we will start to split the message.
-2
View File
@@ -34,8 +34,6 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_sctp.h"
#include <sys/param.h>
-5
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_CRC32_H_
#define _NETINET_SCTP_CRC32_H_
+9 -7
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_HEADER_H_
#define _NETINET_SCTP_HEADER_H_
@@ -98,7 +93,7 @@ struct sctp_supported_addr_param {
/* heartbeat info parameter */
struct sctp_heartbeat_info_param {
struct sctp_paramhdr ph;
uint32_t time_value_1;
time_t time_value_1;
uint32_t time_value_2;
uint32_t random_value1;
uint32_t random_value2;
@@ -226,7 +221,7 @@ struct sctp_state_cookie { /* this is our definition... */
uint8_t ipv4_scope; /* IPv4 private addr scope */
uint8_t loopback_scope; /* loopback scope information */
uint8_t zero_checksum; /* copy of the inp value */
uint8_t rcv_edmid; /* copy of the inp value */
uint8_t reserved[SCTP_RESERVE_SPACE]; /* Align to 64 bits */
/*
* at the end is tacked on the INIT chunk and the INIT-ACK chunk
@@ -539,6 +534,13 @@ struct sctp_auth_chunk {
uint8_t hmac[];
} SCTP_PACKED;
/* Zero checksum support draft-ietf-tsvwg-sctp-zero-checksum */
struct sctp_zero_checksum_acceptable {
struct sctp_paramhdr ph;
uint32_t edmid;
} 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
+55 -54
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/proc.h>
@@ -58,6 +53,9 @@ __FBSDID("$FreeBSD$");
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <netinet/sctp_lock_bsd.h>
#endif
#if defined(_WIN32) && defined(__MINGW32__)
#include <minmax.h>
#endif
/*
* NOTES: On the outbound side of things I need to check the sack timer to
* see if I should generate a sack into the chunk queue (if I have data to
@@ -783,21 +781,6 @@ sctp_build_readq_entry_from_ctl(struct sctp_queued_to_read *nc, struct sctp_queu
nc->do_not_ref_stcb = control->do_not_ref_stcb;
}
static void
sctp_reset_a_control(struct sctp_queued_to_read *control,
struct sctp_inpcb *inp, uint32_t tsn)
{
control->fsn_included = tsn;
if (control->on_read_q) {
/*
* We have to purge it from there,
* hopefully this will work :-)
*/
TAILQ_REMOVE(&inp->read_queue, control, next);
control->on_read_q = 0;
}
}
static int
sctp_handle_old_unordered_data(struct sctp_tcb *stcb,
struct sctp_association *asoc,
@@ -1311,16 +1294,18 @@ sctp_add_chk_to_control(struct sctp_queued_to_read *control,
* data from the chk onto the control and free
* up the chunk resources.
*/
uint32_t added=0;
int i_locked = 0;
uint32_t added = 0;
bool i_locked = false;
if (control->on_read_q && (hold_rlock == 0)) {
/*
* Its being pd-api'd so we must
* do some locks.
*/
SCTP_INP_READ_LOCK(stcb->sctp_ep);
i_locked = 1;
if (control->on_read_q) {
if (hold_rlock == 0) {
/* Its being pd-api'd so we must do some locks. */
SCTP_INP_READ_LOCK(stcb->sctp_ep);
i_locked = true;
}
if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ) {
goto out;
}
}
if (control->data == NULL) {
control->data = chk->data;
@@ -1368,6 +1353,7 @@ sctp_add_chk_to_control(struct sctp_queued_to_read *control,
control->end_added = 1;
control->last_frag_seen = 1;
}
out:
if (i_locked) {
SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
}
@@ -1377,7 +1363,7 @@ sctp_add_chk_to_control(struct sctp_queued_to_read *control,
/*
* Dump onto the re-assembly queue, in its proper place. After dumping on the
* queue, see if anthing can be delivered. If so pull it off (or as much as
* queue, see if anything can be delivered. If so pull it off (or as much as
* we can. If we run out of space then we must dump what we can and set the
* appropriate flag to say we queued what we could.
*/
@@ -1925,7 +1911,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
SCTP_SNPRINTF(msg, sizeof(msg), "Duplicate MID=%8.8x detected.", mid);
goto err_out;
} else {
if ((tsn == control->fsn_included + 1) &&
if ((control->first_frag_seen) &&
(tsn == control->fsn_included + 1) &&
(control->end_added == 0)) {
SCTP_SNPRINTF(msg, sizeof(msg),
"Illegal message sequence, missing end for MID: %8.8x",
@@ -5310,13 +5297,17 @@ sctp_update_acked(struct sctp_tcb *stcb, struct sctp_shutdown_chunk *cp, int *ab
static void
sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
struct sctp_stream_in *strmin)
struct sctp_stream_in *strmin)
{
struct sctp_queued_to_read *control, *ncontrol;
struct sctp_association *asoc;
uint32_t mid;
int need_reasm_check = 0;
KASSERT(stcb != NULL, ("stcb == NULL"));
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
asoc = &stcb->asoc;
mid = strmin->last_mid_delivered;
/*
@@ -5354,11 +5345,9 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
/* deliver it to at least the delivery-q */
if (stcb->sctp_socket) {
sctp_mark_non_revokable(asoc, control->sinfo_tsn);
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
&stcb->sctp_socket->so_rcv,
1, SCTP_READ_LOCK_HELD,
SCTP_SO_NOT_LOCKED);
sctp_add_to_readq(stcb->sctp_ep, stcb, control,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_HELD, SCTP_SO_NOT_LOCKED);
}
} else {
/* Its a fragmented message */
@@ -5424,10 +5413,9 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
strmin->last_mid_delivered = control->mid;
if (stcb->sctp_socket) {
sctp_mark_non_revokable(asoc, control->sinfo_tsn);
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_HELD, SCTP_SO_NOT_LOCKED);
sctp_add_to_readq(stcb->sctp_ep, stcb, control,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_HELD, SCTP_SO_NOT_LOCKED);
}
mid = strmin->last_mid_delivered + 1;
} else {
@@ -5450,8 +5438,8 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
static void
sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb,
struct sctp_association *asoc, struct sctp_stream_in *strm,
struct sctp_queued_to_read *control, int ordered, uint32_t cumtsn)
struct sctp_association *asoc, struct sctp_stream_in *strm,
struct sctp_queued_to_read *control, int ordered, uint32_t cumtsn)
{
struct sctp_tmit_chunk *chk, *nchk;
@@ -5463,6 +5451,11 @@ sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb,
* delivery function... to see if it can be delivered... But
* for now we just dump everything on the queue.
*/
KASSERT(stcb != NULL, ("stcb == NULL"));
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
if (!asoc->idata_supported && !ordered &&
control->first_frag_seen &&
SCTP_TSN_GT(control->fsn_included, cumtsn)) {
@@ -5493,17 +5486,30 @@ sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb,
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
}
if (!TAILQ_EMPTY(&control->reasm)) {
/* This has to be old data, unordered */
KASSERT(!asoc->idata_supported,
("Reassembly queue not empty for I-DATA"));
KASSERT(!ordered,
("Reassembly queue not empty for ordered data"));
if (control->data) {
sctp_m_freem(control->data);
control->data = NULL;
}
sctp_reset_a_control(control, stcb->sctp_ep, cumtsn);
control->fsn_included = 0xffffffff;
control->first_frag_seen = 0;
control->last_frag_seen = 0;
if (control->on_read_q) {
/*
* We have to purge it from there,
* hopefully this will work :-)
*/
TAILQ_REMOVE(&stcb->sctp_ep->read_queue, control, next);
control->on_read_q = 0;
}
chk = TAILQ_FIRST(&control->reasm);
if (chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) {
TAILQ_REMOVE(&control->reasm, chk, sctp_next);
sctp_add_chk_to_control(control, strm, stcb, asoc,
chk, SCTP_READ_LOCK_HELD);
chk, SCTP_READ_LOCK_HELD);
}
sctp_deliver_reasm_check(stcb, asoc, strm, SCTP_READ_LOCK_HELD);
return;
@@ -5562,9 +5568,8 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
struct sctp_association *asoc;
uint32_t new_cum_tsn, gap;
unsigned int i, fwd_sz, m_size;
uint32_t str_seq;
struct sctp_stream_in *strm;
struct sctp_queued_to_read *control, *ncontrol, *sv;
struct sctp_queued_to_read *control, *ncontrol;
asoc = &stcb->asoc;
if ((fwd_sz = ntohs(fwd->ch.chunk_length)) < sizeof(struct sctp_forward_tsn_chunk)) {
@@ -5742,9 +5747,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
TAILQ_FOREACH(control, &stcb->sctp_ep->read_queue, next) {
if ((control->sinfo_stream == sid) &&
(SCTP_MID_EQ(asoc->idata_supported, control->mid, mid))) {
str_seq = (sid << 16) | (0x0000ffff & mid);
control->pdapi_aborted = 1;
sv = stcb->asoc.control_pdapi;
control->end_added = 1;
if (control->on_strm_q == SCTP_ON_ORDERED) {
TAILQ_REMOVE(&strm->inqueue, control, next_instrm);
@@ -5767,13 +5770,11 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
#endif
}
control->on_strm_q = 0;
stcb->asoc.control_pdapi = control;
sctp_ulp_notify(SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION,
stcb,
SCTP_PARTIAL_DELIVERY_ABORTED,
(void *)&str_seq,
SCTP_SO_NOT_LOCKED);
stcb->asoc.control_pdapi = sv;
(void *)control,
SCTP_SO_NOT_LOCKED);
break;
} else if ((control->sinfo_stream == sid) &&
SCTP_MID_GT(asoc->idata_supported, control->mid, mid)) {
-5
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_INDATA_H_
#define _NETINET_SCTP_INDATA_H_
+127 -147
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
#include <netinet/sctp_var.h>
#include <netinet/sctp_sysctl.h>
@@ -62,6 +57,9 @@ __FBSDID("$FreeBSD$");
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/smp.h>
#endif
#if defined(_WIN32) && defined(__MINGW32__)
#include <minmax.h>
#endif
static void
sctp_stop_all_cookie_timers(struct sctp_tcb *stcb)
@@ -427,7 +425,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
op_err = sctp_arethere_unrecognized_parameters(m,
(offset + sizeof(struct sctp_init_chunk)),
&abort_flag, (struct sctp_chunkhdr *)cp,
&nat_friendly, &cookie_found);
&nat_friendly, &cookie_found, NULL);
if (abort_flag) {
/* Send an abort and notify peer */
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
@@ -910,22 +908,51 @@ sctp_start_net_timers(struct sctp_tcb *stcb)
}
}
static void
sctp_check_data_from_peer(struct sctp_tcb *stcb, int *abort_flag)
{
char msg[SCTP_DIAG_INFO_LEN];
struct sctp_association *asoc;
struct mbuf *op_err;
unsigned int i;
*abort_flag = 0;
asoc = &stcb->asoc;
if (SCTP_TSN_GT(asoc->highest_tsn_inside_map, asoc->cumulative_tsn) ||
SCTP_TSN_GT(asoc->highest_tsn_inside_nr_map, asoc->cumulative_tsn)) {
SCTP_SNPRINTF(msg, sizeof(msg), "Missing TSN");
*abort_flag = 1;
}
if (!*abort_flag) {
for (i = 0; i < asoc->streamincnt; i++) {
if (!TAILQ_EMPTY(&asoc->strmin[i].inqueue) ||
!TAILQ_EMPTY(&asoc->strmin[i].uno_inqueue)) {
SCTP_SNPRINTF(msg, sizeof(msg), "Missing user data");
*abort_flag = 1;
break;
}
}
}
if (*abort_flag) {
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INPUT + SCTP_LOC_9;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
}
}
static void
sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
struct sctp_tcb *stcb, struct sctp_nets *net, int *abort_flag)
{
struct sctp_association *asoc;
int some_on_streamwheel;
int old_state;
#if defined(__APPLE__) && !defined(__Userspace__)
struct socket *so;
#endif
SCTPDBG(SCTP_DEBUG_INPUT2,
"sctp_handle_shutdown: handling SHUTDOWN\n");
SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_shutdown: handling SHUTDOWN\n");
if (stcb == NULL)
return;
asoc = &stcb->asoc;
if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
(SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
return;
@@ -939,56 +966,10 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
if (*abort_flag) {
return;
}
if (asoc->control_pdapi) {
/* With a normal shutdown
* we assume the end of last record.
*/
SCTP_INP_READ_LOCK(stcb->sctp_ep);
if (asoc->control_pdapi->on_strm_q) {
struct sctp_stream_in *strm;
strm = &asoc->strmin[asoc->control_pdapi->sinfo_stream];
if (asoc->control_pdapi->on_strm_q == SCTP_ON_UNORDERED) {
/* Unordered */
TAILQ_REMOVE(&strm->uno_inqueue, asoc->control_pdapi, next_instrm);
asoc->control_pdapi->on_strm_q = 0;
} else if (asoc->control_pdapi->on_strm_q == SCTP_ON_ORDERED) {
/* Ordered */
TAILQ_REMOVE(&strm->inqueue, asoc->control_pdapi, next_instrm);
asoc->control_pdapi->on_strm_q = 0;
#ifdef INVARIANTS
} else {
panic("Unknown state on ctrl:%p on_strm_q:%d",
asoc->control_pdapi,
asoc->control_pdapi->on_strm_q);
#endif
}
}
asoc->control_pdapi->end_added = 1;
asoc->control_pdapi->pdapi_aborted = 1;
asoc->control_pdapi = NULL;
SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
#if defined(__APPLE__) && !defined(__Userspace__)
so = SCTP_INP_SO(stcb->sctp_ep);
atomic_add_int(&stcb->asoc.refcnt, 1);
SCTP_TCB_UNLOCK(stcb);
SCTP_SOCKET_LOCK(so, 1);
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
/* assoc was freed while we were unlocked */
SCTP_SOCKET_UNLOCK(so, 1);
return;
}
#endif
if (stcb->sctp_socket) {
sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
}
#if defined(__APPLE__) && !defined(__Userspace__)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
sctp_check_data_from_peer(stcb, abort_flag);
if (*abort_flag) {
return;
}
/* goto SHUTDOWN_RECEIVED state to block new requests */
if (stcb->sctp_socket) {
if ((SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
(SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_ACK_SENT) &&
@@ -998,7 +979,7 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
sctp_ulp_notify(SCTP_NOTIFY_PEER_SHUTDOWN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
/* reset time */
(void)SCTP_GETTIME_TIMEVAL(&asoc->time_entered);
(void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
}
}
if (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_SENT) {
@@ -1012,8 +993,8 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
/* Now is there unsent data on a stream somewhere? */
some_on_streamwheel = sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED);
if (!TAILQ_EMPTY(&asoc->send_queue) ||
!TAILQ_EMPTY(&asoc->sent_queue) ||
if (!TAILQ_EMPTY(&stcb->asoc.send_queue) ||
!TAILQ_EMPTY(&stcb->asoc.sent_queue) ||
some_on_streamwheel) {
/* By returning we will push more data out */
return;
@@ -1042,18 +1023,18 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp SCTP_UNUSED,
struct sctp_tcb *stcb,
struct sctp_nets *net)
{
struct sctp_association *asoc;
int abort_flag;
#if defined(__APPLE__) && !defined(__Userspace__)
struct socket *so;
so = SCTP_INP_SO(stcb->sctp_ep);
#endif
SCTPDBG(SCTP_DEBUG_INPUT2,
"sctp_handle_shutdown_ack: handling SHUTDOWN ACK\n");
if (stcb == NULL)
"sctp_handle_shutdown_ack: handling SHUTDOWN ACK\n");
if (stcb == NULL) {
return;
}
asoc = &stcb->asoc;
/* process according to association state */
if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
(SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
@@ -1068,35 +1049,13 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp SCTP_UNUSED,
SCTP_TCB_UNLOCK(stcb);
return;
}
if (asoc->control_pdapi) {
/* With a normal shutdown
* we assume the end of last record.
*/
SCTP_INP_READ_LOCK(stcb->sctp_ep);
asoc->control_pdapi->end_added = 1;
asoc->control_pdapi->pdapi_aborted = 1;
asoc->control_pdapi = NULL;
SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
#if defined(__APPLE__) && !defined(__Userspace__)
atomic_add_int(&stcb->asoc.refcnt, 1);
SCTP_TCB_UNLOCK(stcb);
SCTP_SOCKET_LOCK(so, 1);
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
/* assoc was freed while we were unlocked */
SCTP_SOCKET_UNLOCK(so, 1);
return;
}
#endif
sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
#if defined(__APPLE__) && !defined(__Userspace__)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
sctp_check_data_from_peer(stcb, &abort_flag);
if (abort_flag) {
return;
}
#ifdef INVARIANTS
if (!TAILQ_EMPTY(&asoc->send_queue) ||
!TAILQ_EMPTY(&asoc->sent_queue) ||
if (!TAILQ_EMPTY(&stcb->asoc.send_queue) ||
!TAILQ_EMPTY(&stcb->asoc.sent_queue) ||
sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED)) {
panic("Queues are not empty when handling SHUTDOWN-ACK");
}
@@ -1124,7 +1083,7 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp SCTP_UNUSED,
atomic_subtract_int(&stcb->asoc.refcnt, 1);
#endif
(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
SCTP_FROM_SCTP_INPUT + SCTP_LOC_11);
SCTP_FROM_SCTP_INPUT + SCTP_LOC_11);
#if defined(__APPLE__) && !defined(__Userspace__)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
@@ -1259,18 +1218,13 @@ sctp_handle_error(struct sctp_chunkhdr *ch,
*/
if ((cause_length >= sizeof(struct sctp_error_stale_cookie)) &&
(SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
struct timeval now;
struct sctp_error_stale_cookie *stale_cookie;
uint64_t stale_time;
stale_cookie = (struct sctp_error_stale_cookie *)cause;
/* stable_time is in usec, convert to msec. */
asoc->cookie_preserve_req = ntohl(stale_cookie->stale_time) / 1000;
/* Double it to be more robust on RTX. */
asoc->cookie_preserve_req *= 2;
asoc->stale_cookie_count++;
if (asoc->stale_cookie_count >
asoc->max_init_times) {
if (asoc->stale_cookie_count > asoc->max_init_times) {
sctp_abort_notification(stcb, false, true, 0, NULL, SCTP_SO_NOT_LOCKED);
/* now free the asoc */
#if defined(__APPLE__) && !defined(__Userspace__)
so = SCTP_INP_SO(stcb->sctp_ep);
atomic_add_int(&stcb->asoc.refcnt, 1);
@@ -1280,16 +1234,41 @@ sctp_handle_error(struct sctp_chunkhdr *ch,
atomic_subtract_int(&stcb->asoc.refcnt, 1);
#endif
(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
SCTP_FROM_SCTP_INPUT + SCTP_LOC_12);
SCTP_FROM_SCTP_INPUT + SCTP_LOC_12);
#if defined(__APPLE__) && !defined(__Userspace__)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
return (-1);
}
/* blast back to INIT state */
stale_cookie = (struct sctp_error_stale_cookie *)cause;
stale_time = ntohl(stale_cookie->stale_time);
if (stale_time == 0) {
/* Use an RTT as an approximation. */
(void)SCTP_GETTIME_TIMEVAL(&now);
timevalsub(&now, &asoc->time_entered);
stale_time = (uint64_t)1000000 * (uint64_t)now.tv_sec + (uint64_t)now.tv_usec;
if (stale_time == 0) {
stale_time = 1;
}
}
/*
* stale_time is in usec, convert it to msec.
* Round upwards, to ensure that it is non-zero.
*/
stale_time = (stale_time + 999) / 1000;
/* Double it, to be more robust on RTX. */
stale_time = 2 * stale_time;
asoc->cookie_preserve_req = (uint32_t)stale_time;
if (asoc->overall_error_count == 0) {
sctp_calculate_rto(stcb, asoc, net, &asoc->time_entered,
SCTP_RTT_FROM_NON_DATA);
}
asoc->overall_error_count = 0;
/* Blast back to INIT state */
sctp_toss_old_cookies(stcb, &stcb->asoc);
SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
sctp_stop_all_cookie_timers(stcb);
SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
(void)SCTP_GETTIME_TIMEVAL(&asoc->time_entered);
sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
}
break;
@@ -1631,10 +1610,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
SCTP_STAT_INCR_COUNTER32(sctps_collisionestab);
SCTP_SET_STATE(stcb, SCTP_STATE_OPEN);
if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
stcb->sctp_ep, stcb, NULL);
}
SCTP_STAT_INCR_GAUGE32(sctps_currestab);
sctp_stop_all_cookie_timers(stcb);
if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
@@ -1890,10 +1865,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
SCTP_STAT_INCR_COUNTER32(sctps_collisionestab);
}
SCTP_SET_STATE(stcb, SCTP_STATE_OPEN);
if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
stcb->sctp_ep, stcb, NULL);
}
sctp_stop_all_cookie_timers(stcb);
sctp_toss_old_cookies(stcb, asoc);
sctp_send_cookie_ack(stcb);
@@ -1964,8 +1935,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
}
if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
SCTP_SET_STATE(stcb, SCTP_STATE_OPEN);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
stcb->sctp_ep, stcb, NULL);
} else if (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_SENT) {
/* move to OPEN state, if not in SHUTDOWN_SENT */
@@ -2073,7 +2042,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
}
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asconf_ack), aack);
}
asoc->zero_checksum = cookie->zero_checksum;
asoc->rcv_edmid = cookie->rcv_edmid;
/* process the INIT-ACK info (my info) */
asoc->my_vtag = ntohl(initack_cp->init.initiate_tag);
@@ -2310,7 +2279,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
#endif
return (NULL);
}
asoc->zero_checksum = cookie->zero_checksum;
asoc->rcv_edmid = cookie->rcv_edmid;
/* process the INIT-ACK info (my info) */
asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
@@ -2451,10 +2420,6 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
/* update current state */
SCTPDBG(SCTP_DEBUG_INPUT2, "moving to OPEN state\n");
SCTP_SET_STATE(stcb, SCTP_STATE_OPEN);
if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
stcb->sctp_ep, stcb, NULL);
}
sctp_stop_all_cookie_timers(stcb);
SCTP_STAT_INCR_COUNTER32(sctps_passiveestab);
SCTP_STAT_INCR_GAUGE32(sctps_currestab);
@@ -2673,7 +2638,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
}
ep = &(*inp_p)->sctp_ep;
/* which cookie is it? */
if ((cookie->time_entered.tv_sec < (long)ep->time_of_secret_change) &&
if ((cookie->time_entered.tv_sec < ep->time_of_secret_change) &&
(ep->current_secret_number != ep->last_secret_number)) {
/* it's the old cookie */
(void)sctp_hmac_m(SCTP_HMAC,
@@ -2696,7 +2661,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
/* compare the received digest with the computed digest */
if (timingsafe_bcmp(calc_sig, sig, SCTP_SIGNATURE_SIZE) != 0) {
/* try the old cookie? */
if ((cookie->time_entered.tv_sec == (long)ep->time_of_secret_change) &&
if ((cookie->time_entered.tv_sec == ep->time_of_secret_change) &&
(ep->current_secret_number != ep->last_secret_number)) {
/* compute digest with old */
(void)sctp_hmac_m(SCTP_HMAC,
@@ -3177,16 +3142,13 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED,
__LINE__);
}
sctp_stop_all_cookie_timers(stcb);
sctp_toss_old_cookies(stcb, asoc);
/* process according to association state */
if (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED) {
/* state change only needed when I am in right state */
SCTPDBG(SCTP_DEBUG_INPUT2, "moving to OPEN state\n");
SCTP_SET_STATE(stcb, SCTP_STATE_OPEN);
sctp_start_net_timers(stcb);
if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
stcb->sctp_ep, stcb, NULL);
}
/* update RTO */
SCTP_STAT_INCR_COUNTER32(sctps_activeestab);
SCTP_STAT_INCR_GAUGE32(sctps_currestab);
@@ -3225,6 +3187,21 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED,
#endif
}
if ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) &&
TAILQ_EMPTY(&asoc->send_queue) &&
TAILQ_EMPTY(&asoc->sent_queue) &&
(asoc->stream_queue_cnt == 0)) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT);
sctp_stop_timers_for_shutdown(stcb);
sctp_send_shutdown(stcb, net);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
stcb->sctp_ep, stcb, net);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
stcb->sctp_ep, stcb, NULL);
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
}
if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
/* We don't need to do the asconf thing,
* nor hb or autoclose if the socket is closed.
@@ -3259,8 +3236,6 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED,
}
}
closed_socket:
/* Toss the cookie if I can */
sctp_toss_old_cookies(stcb, asoc);
/* Restart the timer if we have pending data */
TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
if (chk->whoTo != NULL) {
@@ -3937,23 +3912,19 @@ sctp_handle_stream_reset_response(struct sctp_tcb *stcb,
asoc->strmout[i].state = SCTP_STREAM_OPEN;
}
asoc->streamoutcnt += num_stream;
sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt, 0);
sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_ADD, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
} else if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt,
SCTP_STREAM_CHANGE_DENIED);
sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_ADD, stcb, SCTP_STREAM_CHANGE_DENIED, NULL, SCTP_SO_NOT_LOCKED);
} else {
sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt,
SCTP_STREAM_CHANGE_FAILED);
sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_ADD, stcb, SCTP_STREAM_CHANGE_FAILED, NULL, SCTP_SO_NOT_LOCKED);
}
} else if (type == SCTP_STR_RESET_ADD_IN_STREAMS) {
if (asoc->stream_reset_outstanding)
asoc->stream_reset_outstanding--;
if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt,
SCTP_STREAM_CHANGE_DENIED);
sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_ADD, stcb, SCTP_STREAM_CHANGE_DENIED, NULL, SCTP_SO_NOT_LOCKED);
} else if (action != SCTP_STREAM_RESET_RESULT_PERFORMED) {
sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt,
SCTP_STREAM_CHANGE_FAILED);
sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_ADD, stcb, SCTP_STREAM_CHANGE_DENIED, NULL, SCTP_SO_NOT_LOCKED);
}
} else if (type == SCTP_STR_RESET_TSN_REQUEST) {
/**
@@ -3998,13 +3969,11 @@ sctp_handle_stream_reset_response(struct sctp_tcb *stcb,
sctp_reset_out_streams(stcb, 0, (uint16_t *) NULL);
sctp_reset_in_stream(stcb, 0, (uint16_t *) NULL);
sctp_notify_stream_reset_tsn(stcb, stcb->asoc.sending_seq, (stcb->asoc.mapping_array_base_tsn + 1), 0);
sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_TSN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
} else if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
sctp_notify_stream_reset_tsn(stcb, stcb->asoc.sending_seq, (stcb->asoc.mapping_array_base_tsn + 1),
SCTP_ASSOC_RESET_DENIED);
sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_TSN, stcb, SCTP_ASSOC_RESET_DENIED, NULL, SCTP_SO_NOT_LOCKED);
} else {
sctp_notify_stream_reset_tsn(stcb, stcb->asoc.sending_seq, (stcb->asoc.mapping_array_base_tsn + 1),
SCTP_ASSOC_RESET_FAILED);
sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_TSN, stcb, SCTP_ASSOC_RESET_FAILED, NULL, SCTP_SO_NOT_LOCKED);
}
}
/* get rid of the request and get the request flags */
@@ -4133,7 +4102,7 @@ sctp_handle_str_reset_request_tsn(struct sctp_tcb *stcb,
sctp_reset_out_streams(stcb, 0, (uint16_t *) NULL);
sctp_reset_in_stream(stcb, 0, (uint16_t *) NULL);
asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
sctp_notify_stream_reset_tsn(stcb, asoc->sending_seq, (asoc->mapping_array_base_tsn + 1), 0);
sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_TSN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
}
sctp_add_stream_reset_result_tsn(chk, seq, asoc->last_reset_action[0],
asoc->last_sending_seq[0], asoc->last_base_tsnsent[0]);
@@ -4299,7 +4268,7 @@ sctp_handle_str_reset_add_strm(struct sctp_tcb *stcb, struct sctp_tmit_chunk *ch
/* update the size */
stcb->asoc.streamincnt = num_stream;
stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt, 0);
sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_ADD, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
}
sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
asoc->str_reset_seq_in++;
@@ -4658,6 +4627,8 @@ sctp_handle_packet_dropped(struct sctp_pktdrop_chunk *cp,
SCTP_STAT_INCR(sctps_pdrpmbda);
}
} else {
desc.tsn_ifany = htonl(0);
memset(desc.data_bytes, 0, SCTP_NUM_DB_TO_VERIFY);
if (pktdrp_flags & SCTP_FROM_MIDDLE_BOX) {
SCTP_STAT_INCR(sctps_pdrpmbct);
}
@@ -5845,9 +5816,14 @@ validate_cksum:
stcb = sctp_findassociation_addr(m, offset, src, dst,
sh, ch, &inp, &net, vrf_id);
stcb_looked_up = true;
if ((stcb == NULL) || (stcb->asoc.zero_checksum == 0)) {
if (stcb == NULL) {
goto validate_cksum;
}
if (stcb->asoc.rcv_edmid == SCTP_EDMID_NONE) {
goto validate_cksum;
}
KASSERT(stcb->asoc.rcv_edmid == SCTP_EDMID_LOWER_LAYER_DTLS,
("Unexpected EDMID %u", stcb->asoc.rcv_edmid));
SCTP_STAT_INCR(sctps_recvzerocrc);
}
}
@@ -6369,7 +6345,11 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
}
ecn_bits = ip->ip_tos;
#if defined(__FreeBSD__) && !defined(__Userspace__)
if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) {
if (m->m_pkthdr.csum_flags & (CSUM_SCTP_VALID | CSUM_IP_SCTP)) {
/*
* Packet with CSUM_IP_SCTP were sent from local host using
* checksum offloading. Checksum not required.
*/
SCTP_STAT_INCR(sctps_recvhwcrc);
compute_crc = 0;
} else {
-5
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_INPUT_H_
#define _NETINET_SCTP_INPUT_H_
@@ -33,11 +33,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_LOCK_EMPTY_H_
#define _NETINET_SCTP_LOCK_EMPTY_H_
@@ -92,10 +87,11 @@ __FBSDID("$FreeBSD$");
#define SCTP_IP_PKTLOG_UNLOCK()
#define SCTP_IP_PKTLOG_DESTROY()
#define SCTP_INP_READ_INIT(_inp)
#define SCTP_INP_READ_DESTROY(_inp)
#define SCTP_INP_READ_LOCK_INIT(_inp)
#define SCTP_INP_READ_LOCK_DESTROY(_inp)
#define SCTP_INP_READ_LOCK(_inp)
#define SCTP_INP_READ_UNLOCK(_inp)
#define SCTP_INP_READ_LOCK_ASSERT(_inp)
#define SCTP_INP_LOCK_INIT(_inp)
#define SCTP_ASOC_CREATE_LOCK_INIT(_inp)
-5
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_OS_H_
#define _NETINET_SCTP_OS_H_
+22 -3
View File
@@ -94,7 +94,7 @@ typedef unsigned __int8 uint8_t;
typedef __int8 int8_t;
#endif
#ifndef _SIZE_T_DEFINED
#typedef __int32 size_t;
typedef __int32 size_t;
#endif
typedef unsigned __int32 u_int;
typedef unsigned char u_char;
@@ -275,6 +275,12 @@ typedef char* caddr_t;
#define SCTP_GET_IF_INDEX_FROM_ROUTE(ro) 1 /* compiles... TODO use routing socket to determine */
#if defined(__APPLE__) && defined(__POWERPC__)
#ifndef WORDS_BIGENDIAN
#define WORDS_BIGENDIAN
#endif
#endif
#define BIG_ENDIAN 1
#define LITTLE_ENDIAN 0
#ifdef WORDS_BIGENDIAN
@@ -523,8 +529,6 @@ struct sx {int dummy;};
#endif
#if defined(__FreeBSD__)
#include <netinet6/in6_pcb.h>
#include <netinet6/ip6protosw.h>
/* #include <netinet6/nd6.h> was a 0 byte file */
#include <netinet6/scope6_var.h>
#endif
#endif /* INET6 */
@@ -962,6 +966,14 @@ int sctp_userspace_get_mtu_from_ifn(uint32_t if_index);
#define SCTP_SOWAKEUP(so) wakeup(&(so)->so_timeo, so)
/* number of bytes ready to read */
#define SCTP_SBAVAIL(sb) (sb)->sb_cc
#define SCTP_SB_INCR(sb, incr) \
{ \
atomic_add_int(&(sb)->sb_cc, incr); \
}
#define SCTP_SB_DECR(sb, decr) \
{ \
SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_cc, (int)(decr)); \
}
/* clear the socket buffer state */
#define SCTP_SB_CLEAR(sb) \
(sb).sb_cc = 0; \
@@ -1139,6 +1151,13 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int a
#define SCTP_IS_LISTENING(inp) ((inp->sctp_flags & SCTP_PCB_FLAGS_ACCEPTING) != 0)
static inline bool
in_broadcast(struct in_addr in)
{
return (in.s_addr == htonl(INADDR_BROADCAST) ||
in.s_addr == htonl(INADDR_ANY));
}
#if defined(__APPLE__) || defined(__DragonFly__) || defined(__linux__) || defined(__native_client__) || defined(__NetBSD__) || defined(_WIN32) || defined(__Fuchsia__) || defined(__EMSCRIPTEN__)
int
timingsafe_bcmp(const void *, const void *, size_t);
+154 -77
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/proc.h>
@@ -79,6 +74,9 @@ __FBSDID("$FreeBSD$");
#if defined(__Userspace__) && defined(INET6)
#include <netinet6/sctp6_var.h>
#endif
#if defined(_WIN32) && defined(__MINGW32__)
#include <minmax.h>
#endif
#if defined(__APPLE__) && !defined(__Userspace__)
#if !(defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD))
#define SCTP_MAX_LINKHDR 16
@@ -3767,8 +3765,7 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
#endif
sin.sin_port = stcb->rport;
m_copydata(control, cmsg_data_off, sizeof(struct in_addr), (caddr_t)&sin.sin_addr);
if ((sin.sin_addr.s_addr == INADDR_ANY) ||
(sin.sin_addr.s_addr == INADDR_BROADCAST) ||
if (in_broadcast(sin.sin_addr) ||
IN_MULTICAST(ntohl(sin.sin_addr.s_addr))) {
*error = EINVAL;
return (1);
@@ -3801,8 +3798,7 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
#ifdef INET
if (IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) {
in6_sin6_2_sin(&sin, &sin6);
if ((sin.sin_addr.s_addr == INADDR_ANY) ||
(sin.sin_addr.s_addr == INADDR_BROADCAST) ||
if (in_broadcast(sin.sin_addr) ||
IN_MULTICAST(ntohl(sin.sin_addr.s_addr))) {
*error = EINVAL;
return (1);
@@ -4222,7 +4218,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
ip->ip_id = htons(SCTP_IP_ID(inp)++);
#elif defined(__FreeBSD__)
/* FreeBSD has a function for ip_id's */
ip_fillid(ip);
ip_fillid(ip, V_ip_random_id);
#elif defined(__APPLE__)
#if RANDOM_IP_ID
ip->ip_id = ip_randomid();
@@ -5028,7 +5024,9 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
sctphdr->dest_port = dest_port;
sctphdr->v_tag = v_tag;
sctphdr->checksum = 0;
if (SCTP_BASE_VAR(crc32c_offloaded) == 0) {
if (use_zero_crc) {
SCTP_STAT_INCR(sctps_sendzerocrc);
} else if (SCTP_BASE_VAR(crc32c_offloaded) == 0) {
sctphdr->checksum = sctp_calculate_cksum(m, 0);
SCTP_STAT_INCR(sctps_sendswcrc);
} else {
@@ -5070,6 +5068,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked)
struct sctp_init_chunk *init;
struct sctp_supported_addr_param *sup_addr;
struct sctp_adaptation_layer_indication *ali;
struct sctp_zero_checksum_acceptable *zero_chksum;
struct sctp_supported_chunk_types_param *pr_supported;
struct sctp_paramhdr *ph;
int cnt_inits_to = 0;
@@ -5170,11 +5169,12 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked)
}
/* Zero checksum acceptable parameter */
if (stcb->asoc.zero_checksum > 0) {
parameter_len = (uint16_t)sizeof(struct sctp_paramhdr);
ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + chunk_len);
ph->param_type = htons(SCTP_ZERO_CHECKSUM_ACCEPTABLE);
ph->param_length = htons(parameter_len);
if (stcb->asoc.rcv_edmid != SCTP_EDMID_NONE) {
parameter_len = (uint16_t)sizeof(struct sctp_zero_checksum_acceptable);
zero_chksum = (struct sctp_zero_checksum_acceptable *)(mtod(m, caddr_t) + chunk_len);
zero_chksum->ph.param_type = htons(SCTP_ZERO_CHECKSUM_ACCEPTABLE);
zero_chksum->ph.param_length = htons(parameter_len);
zero_chksum->edmid = htonl(stcb->asoc.rcv_edmid);
chunk_len += parameter_len;
}
@@ -5371,7 +5371,8 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
int param_offset, int *abort_processing,
struct sctp_chunkhdr *cp,
int *nat_friendly,
int *cookie_found)
int *cookie_found,
uint32_t *edmid)
{
/*
* Given a mbuf containing an INIT or INIT-ACK with the param_offset
@@ -5387,8 +5388,8 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
* hoped that this routine may be reused in the future by new
* features.
*/
struct sctp_zero_checksum_acceptable zero_chksum, *zero_chksum_p;
struct sctp_paramhdr *phdr, params;
struct mbuf *mat, *m_tmp, *op_err, *op_err_last;
int at, limit, pad_needed;
uint16_t ptype, plen, padded_size;
@@ -5397,6 +5398,9 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
if (cookie_found != NULL) {
*cookie_found = 0;
}
if (edmid != NULL) {
*edmid = SCTP_EDMID_NONE;
}
mat = in_initpkt;
limit = ntohs(cp->chunk_length) - sizeof(struct sctp_init_chunk);
at = param_offset;
@@ -5452,6 +5456,22 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
}
at += padded_size;
break;
case SCTP_ZERO_CHECKSUM_ACCEPTABLE:
if (padded_size != sizeof(struct sctp_zero_checksum_acceptable)) {
SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error checksum acceptable %d\n", plen);
goto invalid_size;
}
if (edmid != NULL) {
phdr = sctp_get_next_param(mat, at,
(struct sctp_paramhdr *)&zero_chksum,
sizeof(struct sctp_zero_checksum_acceptable));
if (phdr != NULL) {
zero_chksum_p = (struct sctp_zero_checksum_acceptable *)phdr;
*edmid = ntohl(zero_chksum_p->edmid);
}
}
at += padded_size;
break;
case SCTP_RANDOM:
if (padded_size > (sizeof(struct sctp_auth_random) + SCTP_RANDOM_MAX_SIZE)) {
SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error random %d\n", plen);
@@ -5492,11 +5512,16 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
at += padded_size;
break;
case SCTP_HAS_NAT_SUPPORT:
if (padded_size != sizeof(struct sctp_paramhdr)) {
SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error nat support %d\n", plen);
goto invalid_size;
}
*nat_friendly = 1;
/* fall through */
at += padded_size;
break;
case SCTP_PRSCTP_SUPPORTED:
if (padded_size != sizeof(struct sctp_paramhdr)) {
SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error prsctp/nat support %d\n", plen);
SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error prsctp %d\n", plen);
goto invalid_size;
}
at += padded_size;
@@ -5962,6 +5987,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct mbuf *m, *m_tmp, *m_last, *m_cookie, *op_err;
struct sctp_init_ack_chunk *initack;
struct sctp_adaptation_layer_indication *ali;
struct sctp_zero_checksum_acceptable *zero_chksum;
struct sctp_supported_chunk_types_param *pr_supported;
struct sctp_paramhdr *ph;
union sctp_sockstore *over_addr;
@@ -5992,7 +6018,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
int nat_friendly = 0;
int error;
struct socket *so;
uint32_t edmid;
uint16_t num_ext, chunk_len, padding_len, parameter_len;
bool use_zero_crc;
if (stcb) {
asoc = &stcb->asoc;
@@ -6036,7 +6064,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
(offset + sizeof(struct sctp_init_chunk)),
&abort_flag,
(struct sctp_chunkhdr *)init_chk,
&nat_friendly, NULL);
&nat_friendly, NULL, &edmid);
if (abort_flag) {
do_a_abort:
if (op_err == NULL) {
@@ -6350,9 +6378,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
}
if (asoc != NULL) {
stc.zero_checksum = asoc->zero_checksum > 0 ? 1 : 0;
stc.rcv_edmid = asoc->rcv_edmid;
} else {
stc.zero_checksum = inp->zero_checksum;
stc.rcv_edmid = inp->rcv_edmid;
}
/* Now lets put the SCTP header in place */
initack = mtod(m, struct sctp_init_ack_chunk *);
@@ -6477,12 +6505,17 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
/* Zero checksum acceptable parameter */
if (((asoc != NULL) && (asoc->zero_checksum > 0)) ||
((asoc == NULL) && (inp->zero_checksum == 1))) {
parameter_len = (uint16_t)sizeof(struct sctp_paramhdr);
ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + chunk_len);
ph->param_type = htons(SCTP_ZERO_CHECKSUM_ACCEPTABLE);
ph->param_length = htons(parameter_len);
if (((asoc != NULL) && (asoc->rcv_edmid != SCTP_EDMID_NONE)) ||
((asoc == NULL) && (inp->rcv_edmid != SCTP_EDMID_NONE))) {
parameter_len = (uint16_t)sizeof(struct sctp_zero_checksum_acceptable);
zero_chksum = (struct sctp_zero_checksum_acceptable *)(mtod(m, caddr_t) + chunk_len);
zero_chksum->ph.param_type = htons(SCTP_ZERO_CHECKSUM_ACCEPTABLE);
zero_chksum->ph.param_length = htons(parameter_len);
if (asoc != NULL) {
zero_chksum->edmid = htonl(asoc->rcv_edmid);
} else {
zero_chksum->edmid = htonl(inp->rcv_edmid);
}
chunk_len += parameter_len;
}
@@ -6711,6 +6744,12 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
over_addr = NULL;
}
if (asoc != NULL) {
use_zero_crc = (asoc->rcv_edmid != SCTP_EDMID_NONE) && (asoc->rcv_edmid == edmid);
} else {
use_zero_crc = (inp->rcv_edmid != SCTP_EDMID_NONE) && (inp->rcv_edmid == edmid);
}
if ((error = sctp_lowlevel_chunk_output(inp, NULL, NULL, to, m, 0, NULL, 0, 0,
0, 0,
inp->sctp_lport, sh->src_port, init_chk->init.initiate_tag,
@@ -6718,7 +6757,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
#if defined(__FreeBSD__) && !defined(__Userspace__)
mflowtype, mflowid,
#endif
false, /* XXXMT: Improve this! */
use_zero_crc,
SCTP_SO_NOT_LOCKED))) {
SCTPDBG(SCTP_DEBUG_OUTPUT4, "Gak send error %d\n", error);
if (error == ENOBUFS) {
@@ -7240,7 +7279,9 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
} else {
m = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
0, M_NOWAIT, 1, MT_DATA);
SCTP_BUF_LEN(m) = sizeof(struct sctp_paramhdr);
if (m != NULL) {
SCTP_BUF_LEN(m) = sizeof(struct sctp_paramhdr);
}
}
if (m != NULL) {
struct sctp_paramhdr *ph;
@@ -7293,7 +7334,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
sctp_stop_timers_for_shutdown(stcb);
sctp_send_shutdown(stcb, net);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb,
net);
net);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb,
NULL);
added_control = 1;
@@ -7334,8 +7375,6 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
atomic_subtract_int(&stcb->asoc.refcnt, 1);
goto no_chunk_output;
}
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb,
NULL);
}
}
}
@@ -7439,18 +7478,28 @@ static int
sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m,
struct sctp_nonpad_sndrcvinfo *srcv)
{
int ret;
struct sctp_copy_all *ca;
struct mbuf *mat;
ssize_t sndlen;
int ret;
if (uio != NULL) {
#if defined(__APPLE__) && !defined(__Userspace__)
#if defined(APPLE_LEOPARD)
if (uio->uio_resid > SCTP_BASE_SYSCTL(sctp_sendall_limit)) {
sndlen = uio->uio_resid;
#else
if (uio_resid(uio) > SCTP_BASE_SYSCTL(sctp_sendall_limit)) {
sndlen = uio_resid(uio);
#endif
#else
if (uio->uio_resid > (ssize_t)SCTP_BASE_SYSCTL(sctp_sendall_limit)) {
sndlen = uio->uio_resid;
#endif
} else {
sndlen = 0;
for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) {
sndlen += SCTP_BUF_LEN(mat);
}
}
if (sndlen > (ssize_t)SCTP_BASE_SYSCTL(sctp_sendall_limit)) {
/* You must not be larger than the limit! */
return (EMSGSIZE);
}
@@ -7462,12 +7511,10 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m,
return (ENOMEM);
}
memset(ca, 0, sizeof(struct sctp_copy_all));
ca->inp = inp;
if (srcv != NULL) {
memcpy(&ca->sndrcv, srcv, sizeof(struct sctp_nonpad_sndrcvinfo));
}
/* Serialize. */
SCTP_INP_WLOCK(inp);
if ((inp->sctp_flags & SCTP_PCB_FLAGS_SND_ITERATOR_UP) != 0) {
@@ -7478,23 +7525,14 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m,
}
inp->sctp_flags |= SCTP_PCB_FLAGS_SND_ITERATOR_UP;
SCTP_INP_WUNLOCK(inp);
/*
* take off the sendall flag, it would be bad if we failed to do
* this :-0
*/
ca->sndrcv.sinfo_flags &= ~SCTP_SENDALL;
/* get length and mbuf chain */
if (uio) {
#if defined(__APPLE__) && !defined(__Userspace__)
#if defined(APPLE_LEOPARD)
ca->sndlen = uio->uio_resid;
#else
ca->sndlen = uio_resid(uio);
#endif
#else
ca->sndlen = uio->uio_resid;
#endif
ca->sndlen = sndlen;
if (uio != NULL) {
#if defined(__APPLE__) && !defined(__Userspace__)
SCTP_SOCKET_UNLOCK(SCTP_INP_SO(inp), 0);
#endif
@@ -7512,20 +7550,14 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m,
return (ENOMEM);
}
} else {
/* Gather the length of the send */
struct mbuf *mat;
ca->sndlen = 0;
for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) {
ca->sndlen += SCTP_BUF_LEN(mat);
}
ca->m = m;
}
ret = sctp_initiate_iterator(NULL, sctp_sendall_iterator, NULL,
SCTP_PCB_ANY_FLAGS, SCTP_PCB_ANY_FEATURES,
SCTP_ASOC_ANY_STATE,
(void *)ca, 0,
sctp_sendall_completes, inp, 1);
if (ret) {
SCTP_PCB_ANY_FLAGS, SCTP_PCB_ANY_FEATURES,
SCTP_ASOC_ANY_STATE,
(void *)ca, 0,
sctp_sendall_completes, inp, 1);
if (ret != 0) {
SCTP_INP_WLOCK(inp);
inp->sctp_flags &= ~SCTP_PCB_FLAGS_SND_ITERATOR_UP;
SCTP_INP_WUNLOCK(inp);
@@ -7868,7 +7900,7 @@ one_more_time:
if ((stcb->sctp_socket != NULL) &&
((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) {
atomic_subtract_int(&stcb->sctp_socket->so_snd.sb_cc, sp->length);
SCTP_SB_DECR(&stcb->sctp_socket->so_snd, sp->length);
}
if (sp->data) {
sctp_m_freem(sp->data);
@@ -9020,7 +9052,14 @@ again_one_more_time:
* flight size since this little guy
* is a control only packet.
*/
use_zero_crc = asoc->zero_checksum == 2;
switch (asoc->snd_edmid) {
case SCTP_EDMID_LOWER_LAYER_DTLS:
use_zero_crc = true;
break;
default:
use_zero_crc = false;
break;
}
if (asconf) {
sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp, stcb, net);
use_zero_crc = false;
@@ -9354,8 +9393,15 @@ again_one_more_time:
no_data_fill:
/* Is there something to send for this destination? */
if (outchain) {
switch (asoc->snd_edmid) {
case SCTP_EDMID_LOWER_LAYER_DTLS:
use_zero_crc = true;
break;
default:
use_zero_crc = false;
break;
}
/* We may need to start a control timer or two */
use_zero_crc = asoc->zero_checksum == 2;
if (asconf) {
sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp,
stcb, net);
@@ -10098,7 +10144,14 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp,
/* do we have control chunks to retransmit? */
if (m != NULL) {
/* Start a timer no matter if we succeed or fail */
use_zero_crc = asoc->zero_checksum == 2;
switch (asoc->snd_edmid) {
case SCTP_EDMID_LOWER_LAYER_DTLS:
use_zero_crc = true;
break;
default:
use_zero_crc = false;
break;
}
if (chk->rec.chunk_id.id == SCTP_COOKIE_ECHO) {
sctp_timer_start(SCTP_TIMER_TYPE_COOKIE, inp, stcb, chk->whoTo);
use_zero_crc = false;
@@ -10389,6 +10442,14 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp,
sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
tmr_started = 1;
}
switch (asoc->snd_edmid) {
case SCTP_EDMID_LOWER_LAYER_DTLS:
use_zero_crc = true;
break;
default:
use_zero_crc = false;
break;
}
/* Now lets send it, if there is anything to send :> */
if ((error = sctp_lowlevel_chunk_output(inp, stcb, net,
(struct sockaddr *)&net->ro._l_addr, m,
@@ -10399,7 +10460,7 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp,
#if defined(__FreeBSD__) && !defined(__Userspace__)
0, 0,
#endif
asoc->zero_checksum == 2,
use_zero_crc,
so_locked))) {
/* error, we could not output */
SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error);
@@ -11495,6 +11556,7 @@ sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr, int so_locked)
uint32_t auth_offset = 0;
int error;
uint16_t cause_len, chunk_len, padding_len;
bool use_zero_crc;
#if defined(__APPLE__) && !defined(__Userspace__)
if (so_locked) {
@@ -11516,6 +11578,14 @@ sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr, int so_locked)
} else {
m_out = NULL;
}
switch (stcb->asoc.snd_edmid) {
case SCTP_EDMID_LOWER_LAYER_DTLS:
use_zero_crc = true;
break;
default:
use_zero_crc = false;
break;
}
m_abort = sctp_get_mbuf_for_msg(sizeof(struct sctp_abort_chunk), 0, M_NOWAIT, 1, MT_HEADER);
if (m_abort == NULL) {
if (m_out) {
@@ -11580,7 +11650,7 @@ sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr, int so_locked)
#if defined(__FreeBSD__) && !defined(__Userspace__)
0, 0,
#endif
stcb->asoc.zero_checksum == 2,
use_zero_crc,
so_locked))) {
SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error);
if (error == ENOBUFS) {
@@ -11604,6 +11674,7 @@ sctp_send_shutdown_complete(struct sctp_tcb *stcb,
uint32_t vtag;
int error;
uint8_t flags;
bool use_zero_crc;
m_shutdown_comp = sctp_get_mbuf_for_msg(sizeof(struct sctp_chunkhdr), 0, M_NOWAIT, 1, MT_HEADER);
if (m_shutdown_comp == NULL) {
@@ -11617,6 +11688,14 @@ sctp_send_shutdown_complete(struct sctp_tcb *stcb,
flags = 0;
vtag = stcb->asoc.peer_vtag;
}
switch (stcb->asoc.snd_edmid) {
case SCTP_EDMID_LOWER_LAYER_DTLS:
use_zero_crc = true;
break;
default:
use_zero_crc = false;
break;
}
shutdown_complete = mtod(m_shutdown_comp, struct sctp_shutdown_complete_chunk *);
shutdown_complete->ch.chunk_type = SCTP_SHUTDOWN_COMPLETE;
shutdown_complete->ch.chunk_flags = flags;
@@ -11631,7 +11710,7 @@ sctp_send_shutdown_complete(struct sctp_tcb *stcb,
#if defined(__FreeBSD__) && !defined(__Userspace__)
0, 0,
#endif
stcb->asoc.zero_checksum == 2,
use_zero_crc,
SCTP_SO_NOT_LOCKED))) {
SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error);
if (error == ENOBUFS) {
@@ -11780,7 +11859,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
#if defined(__Userspace__)
ip->ip_id = htons(ip_id++);
#elif defined(__FreeBSD__)
ip_fillid(ip);
ip_fillid(ip, V_ip_random_id);
#elif defined(__APPLE__)
#if RANDOM_IP_ID
ip->ip_id = ip_randomid();
@@ -14695,8 +14774,6 @@ dataless_eof:
error = ECONNABORTED;
goto out;
}
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb,
NULL);
sctp_feature_off(inp, SCTP_PCB_FLAGS_NODELAY);
}
}
@@ -14998,9 +15075,9 @@ sctp_v4src_match_nexthop(struct sctp_ifa *sifa, sctp_route_t *ro)
mask = (struct sockaddr_in *)(ifa->ifa_netmask);
sin = &sifa->address.sin;
srcnetaddr.s_addr = (sin->sin_addr.s_addr & mask->sin_addr.s_addr);
SCTPDBG(SCTP_DEBUG_OUTPUT1, "match_nexthop4: src address is ");
SCTPDBG(SCTP_DEBUG_OUTPUT2, "match_nexthop4: src address is ");
SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, &sifa->address.sa);
SCTPDBG(SCTP_DEBUG_OUTPUT1, "network address is %x\n", srcnetaddr.s_addr);
SCTPDBG(SCTP_DEBUG_OUTPUT2, "network address is %x\n", srcnetaddr.s_addr);
#if defined(__FreeBSD__)
sin = &ro->ro_nh->gw4_sa;
@@ -15008,13 +15085,13 @@ sctp_v4src_match_nexthop(struct sctp_ifa *sifa, sctp_route_t *ro)
sin = (struct sockaddr_in *)ro->ro_rt->rt_gateway;
#endif
gwnetaddr.s_addr = (sin->sin_addr.s_addr & mask->sin_addr.s_addr);
SCTPDBG(SCTP_DEBUG_OUTPUT1, "match_nexthop4: nexthop is ");
SCTPDBG(SCTP_DEBUG_OUTPUT2, "match_nexthop4: nexthop is ");
#if defined(__FreeBSD__)
SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, &ro->ro_nh->gw_sa);
#else
SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, ro->ro_rt->rt_gateway);
#endif
SCTPDBG(SCTP_DEBUG_OUTPUT1, "network address is %x\n", gwnetaddr.s_addr);
SCTPDBG(SCTP_DEBUG_OUTPUT2, "network address is %x\n", gwnetaddr.s_addr);
if (srcnetaddr.s_addr == gwnetaddr.s_addr) {
return (1);
}
+3 -6
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_OUTPUT_H_
#define _NETINET_SCTP_OUTPUT_H_
@@ -89,7 +84,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *, struct sctp_tcb *,
struct mbuf *
sctp_arethere_unrecognized_parameters(struct mbuf *, int, int *,
struct sctp_chunkhdr *, int *, int *);
struct sctp_chunkhdr *, int *, int *,
uint32_t *);
void sctp_queue_op_err(struct sctp_tcb *, struct mbuf *);
int
+133 -252
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/proc.h>
@@ -256,20 +251,18 @@ sctp_find_ifn(void *ifn, uint32_t ifn_index)
struct sctp_ifn *sctp_ifnp;
struct sctp_ifnlist *hash_ifn_head;
/* We assume the lock is held for the addresses
* if that's wrong problems could occur :-)
*/
SCTP_IPI_ADDR_LOCK_ASSERT();
#if defined(__FreeBSD__) && !defined(__Userspace__)
KASSERT(ifn != NULL, ("sctp_find_ifn(NULL, %u) called", ifn_index));
#endif
hash_ifn_head = &SCTP_BASE_INFO(vrf_ifn_hash)[(ifn_index & SCTP_BASE_INFO(vrf_ifn_hashmark))];
LIST_FOREACH(sctp_ifnp, hash_ifn_head, next_bucket) {
if (sctp_ifnp->ifn_index == ifn_index) {
return (sctp_ifnp);
}
if (sctp_ifnp->ifn_p && ifn && (sctp_ifnp->ifn_p == ifn)) {
return (sctp_ifnp);
if (sctp_ifnp->ifn_index == ifn_index &&
sctp_ifnp->ifn_p == ifn) {
break;
}
}
return (NULL);
return (sctp_ifnp);
}
struct sctp_vrf *
@@ -291,10 +284,10 @@ void
sctp_free_vrf(struct sctp_vrf *vrf)
{
if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&vrf->refcount)) {
if (vrf->vrf_addr_hash) {
SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark);
vrf->vrf_addr_hash = NULL;
}
if (vrf->vrf_addr_hash) {
SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark);
vrf->vrf_addr_hash = NULL;
}
/* We zero'd the count */
LIST_REMOVE(vrf, next_vrf);
SCTP_FREE(vrf, SCTP_M_VRF);
@@ -302,7 +295,7 @@ sctp_free_vrf(struct sctp_vrf *vrf)
}
}
void
static void
sctp_free_ifn(struct sctp_ifn *sctp_ifnp)
{
if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&sctp_ifnp->refcount)) {
@@ -315,17 +308,6 @@ sctp_free_ifn(struct sctp_ifn *sctp_ifnp)
}
}
void
sctp_update_ifn_mtu(uint32_t ifn_index, uint32_t mtu)
{
struct sctp_ifn *sctp_ifnp;
sctp_ifnp = sctp_find_ifn((void *)NULL, ifn_index);
if (sctp_ifnp != NULL) {
sctp_ifnp->ifn_mtu = mtu;
}
}
void
sctp_free_ifa(struct sctp_ifa *sctp_ifap)
{
@@ -340,123 +322,30 @@ sctp_free_ifa(struct sctp_ifa *sctp_ifap)
}
static void
sctp_delete_ifn(struct sctp_ifn *sctp_ifnp, int hold_addr_lock)
sctp_delete_ifn(struct sctp_ifn *sctp_ifnp)
{
struct sctp_ifn *found;
found = sctp_find_ifn(sctp_ifnp->ifn_p, sctp_ifnp->ifn_index);
if (found == NULL) {
SCTP_IPI_ADDR_WLOCK_ASSERT();
if (sctp_find_ifn(sctp_ifnp->ifn_p, sctp_ifnp->ifn_index) == NULL) {
/* Not in the list.. sorry */
return;
}
if (hold_addr_lock == 0) {
SCTP_IPI_ADDR_WLOCK();
} else {
SCTP_IPI_ADDR_WLOCK_ASSERT();
}
LIST_REMOVE(sctp_ifnp, next_bucket);
LIST_REMOVE(sctp_ifnp, next_ifn);
if (hold_addr_lock == 0) {
SCTP_IPI_ADDR_WUNLOCK();
}
/* Take away the reference, and possibly free it */
sctp_free_ifn(sctp_ifnp);
}
void
sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr,
const char *if_name, uint32_t ifn_index)
{
struct sctp_vrf *vrf;
struct sctp_ifa *sctp_ifap;
SCTP_IPI_ADDR_RLOCK();
vrf = sctp_find_vrf(vrf_id);
if (vrf == NULL) {
SCTPDBG(SCTP_DEBUG_PCB4, "Can't find vrf_id 0x%x\n", vrf_id);
goto out;
}
sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED);
if (sctp_ifap == NULL) {
SCTPDBG(SCTP_DEBUG_PCB4, "Can't find sctp_ifap for address\n");
goto out;
}
if (sctp_ifap->ifn_p == NULL) {
SCTPDBG(SCTP_DEBUG_PCB4, "IFA has no IFN - can't mark unusable\n");
goto out;
}
if (if_name) {
if (strncmp(if_name, sctp_ifap->ifn_p->ifn_name, SCTP_IFNAMSIZ) != 0) {
SCTPDBG(SCTP_DEBUG_PCB4, "IFN %s of IFA not the same as %s\n",
sctp_ifap->ifn_p->ifn_name, if_name);
goto out;
}
} else {
if (sctp_ifap->ifn_p->ifn_index != ifn_index) {
SCTPDBG(SCTP_DEBUG_PCB4, "IFA owned by ifn_index:%d down command for ifn_index:%d - ignored\n",
sctp_ifap->ifn_p->ifn_index, ifn_index);
goto out;
}
}
sctp_ifap->localifa_flags &= (~SCTP_ADDR_VALID);
sctp_ifap->localifa_flags |= SCTP_ADDR_IFA_UNUSEABLE;
out:
SCTP_IPI_ADDR_RUNLOCK();
}
void
sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr,
const char *if_name, uint32_t ifn_index)
{
struct sctp_vrf *vrf;
struct sctp_ifa *sctp_ifap;
SCTP_IPI_ADDR_RLOCK();
vrf = sctp_find_vrf(vrf_id);
if (vrf == NULL) {
SCTPDBG(SCTP_DEBUG_PCB4, "Can't find vrf_id 0x%x\n", vrf_id);
goto out;
}
sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED);
if (sctp_ifap == NULL) {
SCTPDBG(SCTP_DEBUG_PCB4, "Can't find sctp_ifap for address\n");
goto out;
}
if (sctp_ifap->ifn_p == NULL) {
SCTPDBG(SCTP_DEBUG_PCB4, "IFA has no IFN - can't mark unusable\n");
goto out;
}
if (if_name) {
if (strncmp(if_name, sctp_ifap->ifn_p->ifn_name, SCTP_IFNAMSIZ) != 0) {
SCTPDBG(SCTP_DEBUG_PCB4, "IFN %s of IFA not the same as %s\n",
sctp_ifap->ifn_p->ifn_name, if_name);
goto out;
}
} else {
if (sctp_ifap->ifn_p->ifn_index != ifn_index) {
SCTPDBG(SCTP_DEBUG_PCB4, "IFA owned by ifn_index:%d down command for ifn_index:%d - ignored\n",
sctp_ifap->ifn_p->ifn_index, ifn_index);
goto out;
}
}
sctp_ifap->localifa_flags &= (~SCTP_ADDR_IFA_UNUSEABLE);
sctp_ifap->localifa_flags |= SCTP_ADDR_VALID;
out:
SCTP_IPI_ADDR_RUNLOCK();
}
/*-
* Add an ifa to an ifn.
* Register the interface as necessary.
* NOTE: ADDR write lock MUST be held.
*/
static void
sctp_add_ifa_to_ifn(struct sctp_ifn *sctp_ifnp, struct sctp_ifa *sctp_ifap)
{
int ifa_af;
SCTP_IPI_ADDR_WLOCK_ASSERT();
LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa);
sctp_ifap->ifn_p = sctp_ifnp;
atomic_add_int(&sctp_ifap->ifn_p->refcount, 1);
@@ -487,11 +376,11 @@ sctp_add_ifa_to_ifn(struct sctp_ifn *sctp_ifnp, struct sctp_ifa *sctp_ifap)
* Remove an ifa from its ifn.
* If no more addresses exist, remove the ifn too. Otherwise, re-register
* the interface based on the remaining address families left.
* NOTE: ADDR write lock MUST be held.
*/
static void
sctp_remove_ifa_from_ifn(struct sctp_ifa *sctp_ifap)
{
SCTP_IPI_ADDR_WLOCK_ASSERT();
LIST_REMOVE(sctp_ifap, next_ifa);
if (sctp_ifap->ifn_p) {
/* update address counts */
@@ -513,7 +402,7 @@ sctp_remove_ifa_from_ifn(struct sctp_ifa *sctp_ifap)
if (LIST_EMPTY(&sctp_ifap->ifn_p->ifalist)) {
/* remove the ifn, possibly freeing it */
sctp_delete_ifn(sctp_ifap->ifn_p, SCTP_ADDR_LOCKED);
sctp_delete_ifn(sctp_ifap->ifn_p);
} else {
/* re-register address family type, if needed */
if ((sctp_ifap->ifn_p->num_v6 == 0) &&
@@ -532,9 +421,9 @@ sctp_remove_ifa_from_ifn(struct sctp_ifa *sctp_ifap)
struct sctp_ifa *
sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
uint32_t ifn_type, const char *if_name, void *ifa,
struct sockaddr *addr, uint32_t ifa_flags,
int dynamic_add)
uint32_t ifn_type, const char *if_name, void *ifa,
struct sockaddr *addr, uint32_t ifa_flags,
int dynamic_add)
{
struct sctp_vrf *vrf;
struct sctp_ifn *sctp_ifnp, *new_sctp_ifnp;
@@ -542,7 +431,6 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
struct sctp_ifalist *hash_addr_head;
struct sctp_ifnlist *hash_ifn_head;
uint32_t hash_of_addr;
int new_ifn_af = 0;
#ifdef SCTP_DEBUG
SCTPDBG(SCTP_DEBUG_PCB4, "vrf_id 0x%x: adding address: ", vrf_id);
@@ -605,59 +493,64 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
LIST_INSERT_HEAD(hash_ifn_head, sctp_ifnp, next_bucket);
LIST_INSERT_HEAD(&vrf->ifnlist, sctp_ifnp, next_ifn);
atomic_add_int(&SCTP_BASE_INFO(ipi_count_ifns), 1);
new_ifn_af = 1;
}
sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED);
if (sctp_ifap) {
/* Hmm, it already exists? */
if ((sctp_ifap->ifn_p) &&
(sctp_ifap->ifn_p->ifn_index == ifn_index)) {
SCTPDBG(SCTP_DEBUG_PCB4, "Using existing ifn %s (0x%x) for ifa %p\n",
sctp_ifap->ifn_p->ifn_name, ifn_index,
(void *)sctp_ifap);
if (new_ifn_af) {
/* Remove the created one that we don't want */
sctp_delete_ifn(sctp_ifnp, SCTP_ADDR_LOCKED);
}
if (sctp_ifap->localifa_flags & SCTP_BEING_DELETED) {
/* easy to solve, just switch back to active */
SCTPDBG(SCTP_DEBUG_PCB4, "Clearing deleted ifa flag\n");
sctp_ifap->localifa_flags = SCTP_ADDR_VALID;
sctp_ifap->ifn_p = sctp_ifnp;
atomic_add_int(&sctp_ifap->ifn_p->refcount, 1);
}
exit_stage_left:
SCTP_IPI_ADDR_WUNLOCK();
if (new_sctp_ifnp != NULL) {
SCTP_FREE(new_sctp_ifnp, SCTP_M_IFN);
}
SCTP_FREE(new_sctp_ifap, SCTP_M_IFA);
return (sctp_ifap);
} else {
if (sctp_ifap->ifn_p) {
if (sctp_ifap != NULL) {
/* The address being added is already or still known. */
if (sctp_ifap->ifn_p != NULL) {
if (sctp_ifap->ifn_p->ifn_index == ifn_index &&
sctp_ifap->ifn_p->ifn_p == ifn) {
SCTPDBG(SCTP_DEBUG_PCB4,
"Using existing ifn %s (0x%x) for ifa %p\n",
sctp_ifap->ifn_p->ifn_name, ifn_index,
(void *)sctp_ifap);
if (new_sctp_ifnp == NULL) {
/* Remove the created one not used. */
sctp_delete_ifn(sctp_ifnp);
}
if (sctp_ifap->localifa_flags & SCTP_BEING_DELETED) {
/* Switch back to active. */
SCTPDBG(SCTP_DEBUG_PCB4,
"Clearing deleted ifa flag\n");
sctp_ifap->localifa_flags = SCTP_ADDR_VALID;
sctp_ifap->ifn_p = sctp_ifnp;
atomic_add_int(&sctp_ifap->ifn_p->refcount, 1);
}
} else {
/*
* The last IFN gets the address, remove the
* old one
* old one.
*/
SCTPDBG(SCTP_DEBUG_PCB4, "Moving ifa %p from %s (0x%x) to %s (0x%x)\n",
(void *)sctp_ifap, sctp_ifap->ifn_p->ifn_name,
sctp_ifap->ifn_p->ifn_index, if_name,
ifn_index);
SCTPDBG(SCTP_DEBUG_PCB4,
"Moving ifa %p from %s (0x%x) to %s (0x%x)\n",
(void *)sctp_ifap,
sctp_ifap->ifn_p->ifn_name,
sctp_ifap->ifn_p->ifn_index, if_name,
ifn_index);
/* remove the address from the old ifn */
sctp_remove_ifa_from_ifn(sctp_ifap);
/* move the address over to the new ifn */
sctp_add_ifa_to_ifn(sctp_ifnp, sctp_ifap);
goto exit_stage_left;
} else {
/* repair ifnp which was NULL ? */
sctp_ifap->localifa_flags = SCTP_ADDR_VALID;
SCTPDBG(SCTP_DEBUG_PCB4, "Repairing ifn %p for ifa %p\n",
(void *)sctp_ifnp, (void *)sctp_ifap);
sctp_add_ifa_to_ifn(sctp_ifnp, sctp_ifap);
}
goto exit_stage_left;
} else {
/* Repair ifn_p, which was NULL... */
sctp_ifap->localifa_flags = SCTP_ADDR_VALID;
SCTPDBG(SCTP_DEBUG_PCB4,
"Repairing ifn %p for ifa %p\n",
(void *)sctp_ifnp, (void *)sctp_ifap);
sctp_add_ifa_to_ifn(sctp_ifnp, sctp_ifap);
}
SCTP_IPI_ADDR_WUNLOCK();
if (new_sctp_ifnp != NULL) {
SCTP_FREE(new_sctp_ifnp, SCTP_M_IFN);
}
SCTP_FREE(new_sctp_ifap, SCTP_M_IFA);
return (sctp_ifap);
}
KASSERT(sctp_ifnp != NULL,
("sctp_add_addr_to_vrf: sctp_ifnp == NULL"));
KASSERT(sctp_ifap == NULL,
("sctp_add_addr_to_vrf: sctp_ifap (%p) != NULL", sctp_ifap));
sctp_ifap = new_sctp_ifap;
memset(sctp_ifap, 0, sizeof(struct sctp_ifa));
sctp_ifap->ifn_p = sctp_ifnp;
@@ -706,8 +599,8 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
sctp_ifap->src_is_priv = 1;
}
sctp_ifnp->num_v4++;
if (new_ifn_af)
new_ifn_af = AF_INET;
if (new_sctp_ifnp == NULL)
sctp_ifnp->registered_af = AF_INET;
break;
}
#endif
@@ -726,19 +619,18 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
sctp_ifap->src_is_priv = 1;
}
sctp_ifnp->num_v6++;
if (new_ifn_af)
new_ifn_af = AF_INET6;
if (new_sctp_ifnp == NULL)
sctp_ifnp->registered_af = AF_INET6;
break;
}
#endif
#if defined(__Userspace__)
case AF_CONN:
if (new_ifn_af)
new_ifn_af = AF_CONN;
if (new_sctp_ifnp == NULL)
sctp_ifnp->registered_af = AF_CONN;
break;
#endif
default:
new_ifn_af = 0;
break;
}
hash_of_addr = sctp_get_ifa_hash_val(&sctp_ifap->address.sa);
@@ -754,9 +646,6 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
sctp_ifnp->ifa_count++;
vrf->total_ifa_count++;
atomic_add_int(&SCTP_BASE_INFO(ipi_count_ifas), 1);
if (new_ifn_af) {
sctp_ifnp->registered_af = new_ifn_af;
}
SCTP_IPI_ADDR_WUNLOCK();
if (new_sctp_ifnp != NULL) {
SCTP_FREE(new_sctp_ifnp, SCTP_M_IFN);
@@ -777,8 +666,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
*/
SCTPDBG(SCTP_DEBUG_PCB4, "Lost an address change?\n");
/* Opps, must decrement the count */
sctp_del_addr_from_vrf(vrf_id, addr, ifn_index,
if_name);
sctp_del_addr_from_vrf(vrf_id, addr, ifn, ifn_index);
return (NULL);
}
SCTP_INCR_LADDR_COUNT();
@@ -803,16 +691,17 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
void
sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr,
uint32_t ifn_index, const char *if_name)
void *ifn, uint32_t ifn_index)
{
struct sctp_vrf *vrf;
struct sctp_ifa *sctp_ifap = NULL;
struct sctp_ifa *sctp_ifap;
SCTP_IPI_ADDR_WLOCK();
vrf = sctp_find_vrf(vrf_id);
if (vrf == NULL) {
SCTPDBG(SCTP_DEBUG_PCB4, "Can't find vrf_id 0x%x\n", vrf_id);
goto out_now;
SCTP_IPI_ADDR_WUNLOCK();
return;
}
#ifdef SCTP_DEBUG
@@ -820,31 +709,15 @@ sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr,
SCTPDBG_ADDR(SCTP_DEBUG_PCB4, addr);
#endif
sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED);
if (sctp_ifap) {
if (sctp_ifap != NULL) {
/* Validate the delete */
if (sctp_ifap->ifn_p) {
int valid = 0;
/*-
* The name has priority over the ifn_index
* if its given.
*/
if (if_name) {
if (strncmp(if_name, sctp_ifap->ifn_p->ifn_name, SCTP_IFNAMSIZ) == 0) {
/* They match its a correct delete */
valid = 1;
}
}
if (!valid) {
/* last ditch check ifn_index */
if (ifn_index == sctp_ifap->ifn_p->ifn_index) {
valid = 1;
}
}
if (!valid) {
SCTPDBG(SCTP_DEBUG_PCB4, "ifn:%d ifname:%s does not match addresses\n",
ifn_index, ((if_name == NULL) ? "NULL" : if_name));
SCTPDBG(SCTP_DEBUG_PCB4, "ifn:%d ifname:%s - ignoring delete\n",
sctp_ifap->ifn_p->ifn_index, sctp_ifap->ifn_p->ifn_name);
if (ifn_index != sctp_ifap->ifn_p->ifn_index ||
ifn != sctp_ifap->ifn_p->ifn_p) {
SCTPDBG(SCTP_DEBUG_PCB4, "ifn:%d (%p) ifname:%s - ignoring delete\n",
sctp_ifap->ifn_p->ifn_index,
sctp_ifap->ifn_p->ifn_p,
sctp_ifap->ifn_p->ifn_name);
SCTP_IPI_ADDR_WUNLOCK();
return;
}
@@ -866,13 +739,12 @@ sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr,
else {
SCTPDBG(SCTP_DEBUG_PCB4, "Del Addr-ifn:%d Could not find address:",
ifn_index);
SCTPDBG_ADDR(SCTP_DEBUG_PCB1, addr);
SCTPDBG_ADDR(SCTP_DEBUG_PCB4, addr);
}
#endif
out_now:
SCTP_IPI_ADDR_WUNLOCK();
if (sctp_ifap) {
if (sctp_ifap != NULL) {
struct sctp_laddr *wi;
wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
@@ -2797,7 +2669,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
inp->nrsack_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_nrsack_enable);
inp->pktdrop_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_pktdrop_enable);
inp->idata_supported = 0;
inp->zero_checksum = 0;
inp->rcv_edmid = SCTP_EDMID_NONE;
#if defined(__FreeBSD__) && !defined(__Userspace__)
inp->fibnum = so->so_fibnum;
@@ -2921,7 +2793,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
rw_init_flags(&inp->ip_inp.inp.inp_lock, "sctpinp",
RW_RECURSE | RW_DUPOK);
#endif
SCTP_INP_READ_INIT(inp);
SCTP_INP_READ_LOCK_INIT(inp);
SCTP_ASOC_CREATE_LOCK_INIT(inp);
/* lock the new ep */
SCTP_INP_WLOCK(inp);
@@ -3974,7 +3846,6 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
continue;
}
if ((stcb->asoc.size_on_reasm_queue > 0) ||
(stcb->asoc.control_pdapi) ||
(stcb->asoc.size_on_all_streams > 0) ||
((so != NULL) && (SCTP_SBAVAIL(&so->so_rcv) > 0))) {
/* Left with Data unread */
@@ -4027,7 +3898,6 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
} else {
/* mark into shutdown pending */
SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb, NULL);
if ((*stcb->asoc.ss_functions.sctp_ss_is_user_msgs_incomplete)(stcb, &stcb->asoc)) {
SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_PARTIAL_MSG_LEFT);
}
@@ -4185,7 +4055,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
TAILQ_REMOVE(&inp->read_queue, sq, next);
sctp_free_remote_addr(sq->whoFrom);
if (so)
so->so_rcv.sb_cc -= sq->length;
SCTP_SB_DECR(&so->so_rcv, sq->length);
if (sq->data) {
sctp_m_freem(sq->data);
sq->data = NULL;
@@ -4281,7 +4151,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
INP_LOCK_DESTROY(&inp->ip_inp.inp);
#endif
SCTP_INP_LOCK_DESTROY(inp);
SCTP_INP_READ_DESTROY(inp);
SCTP_INP_READ_LOCK_DESTROY(inp);
SCTP_ASOC_CREATE_LOCK_DESTROY(inp);
#if !(defined(__APPLE__) && !defined(__Userspace__))
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
@@ -4990,8 +4860,7 @@ sctp_aloc_assoc_locked(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
sin = (struct sockaddr_in *)firstaddr;
if ((ntohs(sin->sin_port) == 0) ||
(sin->sin_addr.s_addr == INADDR_ANY) ||
(sin->sin_addr.s_addr == INADDR_BROADCAST) ||
in_broadcast(sin->sin_addr) ||
IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) ||
#if defined(__Userspace__)
((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) ||
@@ -5117,7 +4986,6 @@ sctp_aloc_assoc_locked(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
LIST_REMOVE(stcb, sctp_asocs);
LIST_REMOVE(stcb, sctp_tcbasocidhash);
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
SCTP_INP_WUNLOCK(inp);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
*error = ENOBUFS;
return (NULL);
@@ -5310,7 +5178,7 @@ sctp_del_remote_addr(struct sctp_tcb *stcb, struct sockaddr *remaddr)
}
static bool
sctp_is_in_timewait(uint32_t tag, uint16_t lport, uint16_t rport, uint32_t now)
sctp_is_in_timewait(uint32_t tag, uint16_t lport, uint16_t rport, time_t now)
{
struct sctpvtaghead *chain;
struct sctp_tagblock *twait_block;
@@ -5332,7 +5200,7 @@ sctp_is_in_timewait(uint32_t tag, uint16_t lport, uint16_t rport, uint32_t now)
}
static void
sctp_set_vtag_block(struct sctp_timewait *vtag_block, uint32_t time,
sctp_set_vtag_block(struct sctp_timewait *vtag_block, time_t time,
uint32_t tag, uint16_t lport, uint16_t rport)
{
vtag_block->tv_sec_at_expire = time;
@@ -5347,13 +5215,13 @@ sctp_add_vtag_to_timewait(uint32_t tag, uint16_t lport, uint16_t rport)
struct sctpvtaghead *chain;
struct sctp_tagblock *twait_block;
struct timeval now;
uint32_t time;
time_t time;
int i;
bool set;
SCTP_INP_INFO_WLOCK_ASSERT();
(void)SCTP_GETTIME_TIMEVAL(&now);
time = (uint32_t)now.tv_sec + SCTP_BASE_SYSCTL(sctp_vtag_time_wait);
time = now.tv_sec + SCTP_BASE_SYSCTL(sctp_vtag_time_wait);
chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
set = false;
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
@@ -5365,7 +5233,7 @@ sctp_add_vtag_to_timewait(uint32_t tag, uint16_t lport, uint16_t rport)
continue;
}
if ((twait_block->vtag_block[i].v_tag != 0) &&
(twait_block->vtag_block[i].tv_sec_at_expire < (uint32_t)now.tv_sec)) {
(twait_block->vtag_block[i].tv_sec_at_expire < now.tv_sec)) {
if (set) {
/* Audit expires this guy */
sctp_set_vtag_block(twait_block->vtag_block + i, 0, 0, 0, 0);
@@ -5535,28 +5403,19 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
* will be now.
*/
if (sq->end_added == 0) {
/* Held for PD-API clear that. */
/* Held for PD-API, clear that. */
sq->pdapi_aborted = 1;
sq->held_length = 0;
if (sctp_stcb_is_feature_on(inp, stcb, SCTP_PCB_FLAGS_PDAPIEVNT) && (so != NULL)) {
/*
* Need to add a PD-API aborted indication.
* Setting the control_pdapi assures that it will
* be added right after this msg.
*/
uint32_t strseq;
stcb->asoc.control_pdapi = sq;
strseq = (sq->sinfo_stream << 16) | (sq->mid & 0x0000ffff);
sctp_ulp_notify(SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION,
stcb,
SCTP_PARTIAL_DELIVERY_ABORTED,
(void *)&strseq,
(void *)sq,
SCTP_SO_LOCKED);
stcb->asoc.control_pdapi = NULL;
}
/* Add an end to wake them */
sq->end_added = 1;
}
/* Add an end to wake them */
sq->end_added = 1;
}
}
SCTP_INP_READ_UNLOCK(inp);
@@ -5637,7 +5496,9 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
SOCKBUF_LOCK(&so->so_rcv);
so->so_state &= ~(SS_ISCONNECTING |
SS_ISDISCONNECTING |
#if !(defined(__FreeBSD__) && !defined(__Userspace__))
SS_ISCONFIRMING |
#endif
SS_ISCONNECTED);
so->so_state |= SS_ISDISCONNECTED;
#if defined(__APPLE__) && !defined(__Userspace__)
@@ -6529,6 +6390,13 @@ sctp_netisr_hdlr(struct mbuf *m, uintptr_t source)
}
#endif
#endif
#if defined(__FreeBSD__) && !defined(__Userspace__)
#define VALIDATE_LOADER_TUNABLE(var_name, prefix) \
if (SCTP_BASE_SYSCTL(var_name) < prefix##_MIN || \
SCTP_BASE_SYSCTL(var_name) > prefix##_MAX) \
SCTP_BASE_SYSCTL(var_name) = prefix##_DEFAULT
#endif
void
#if defined(__Userspace__)
@@ -6621,6 +6489,9 @@ sctp_pcb_init(void)
TUNABLE_INT_FETCH("net.inet.sctp.tcbhashsize", &SCTP_BASE_SYSCTL(sctp_hashtblsize));
TUNABLE_INT_FETCH("net.inet.sctp.pcbhashsize", &SCTP_BASE_SYSCTL(sctp_pcbtblsize));
TUNABLE_INT_FETCH("net.inet.sctp.chunkscale", &SCTP_BASE_SYSCTL(sctp_chunkscale));
VALIDATE_LOADER_TUNABLE(sctp_hashtblsize, SCTPCTL_TCBHASHSIZE);
VALIDATE_LOADER_TUNABLE(sctp_pcbtblsize, SCTPCTL_PCBHASHSIZE);
VALIDATE_LOADER_TUNABLE(sctp_chunkscale, SCTPCTL_CHUNKSCALE);
#endif
SCTP_BASE_INFO(sctp_asochash) = SCTP_HASH_INIT((SCTP_BASE_SYSCTL(sctp_hashtblsize) * 31),
&SCTP_BASE_INFO(hashasocmark));
@@ -7166,8 +7037,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
/* Skip multi-cast addresses */
goto next_param;
}
if ((sin.sin_addr.s_addr == INADDR_BROADCAST) ||
(sin.sin_addr.s_addr == INADDR_ANY)) {
if (in_broadcast(sin.sin_addr)) {
goto next_param;
}
sa = (struct sockaddr *)&sin;
@@ -7413,12 +7283,22 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
/* Peer supports pr-sctp */
peer_supports_prsctp = 1;
} else if (ptype == SCTP_ZERO_CHECKSUM_ACCEPTABLE) {
/*
* Only send zero checksums if the upper layer has
* also enabled the support for this.
*/
if (stcb->asoc.zero_checksum == 1) {
stcb->asoc.zero_checksum = 2;
struct sctp_zero_checksum_acceptable zero_chksum, *zero_chksum_p;
phdr = sctp_get_next_param(m, offset,
(struct sctp_paramhdr *)&zero_chksum,
sizeof(struct sctp_zero_checksum_acceptable));
if (phdr != NULL) {
/*
* Only send zero checksums if the upper layer
* has enabled the support for the same method
* as allowed by the peer.
*/
zero_chksum_p = (struct sctp_zero_checksum_acceptable *)phdr;
if ((ntohl(zero_chksum_p->edmid) != SCTP_EDMID_NONE) &&
(ntohl(zero_chksum_p->edmid) == stcb->asoc.rcv_edmid)) {
stcb->asoc.snd_edmid = stcb->asoc.rcv_edmid;
}
}
} else if (ptype == SCTP_SUPPORTED_CHUNK_EXT) {
/* A supported extension chunk */
@@ -7754,7 +7634,7 @@ sctp_is_vtag_good(uint32_t tag, uint16_t lport, uint16_t rport, struct timeval *
return (false);
}
}
return (!sctp_is_in_timewait(tag, lport, rport, (uint32_t)now->tv_sec));
return (!sctp_is_in_timewait(tag, lport, rport, now->tv_sec));
}
static void
@@ -7960,10 +7840,11 @@ sctp_drain_mbufs(struct sctp_tcb *stcb)
#if defined(__FreeBSD__) && !defined(__Userspace__)
static void
sctp_drain(void *arg __unused, int flags __unused)
#else
void
#endif
sctp_drain(void)
#endif
{
#if defined(__FreeBSD__) && !defined(__Userspace__)
struct epoch_tracker et;
+8 -28
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_PCB_H_
#define _NETINET_SCTP_PCB_H_
@@ -136,10 +131,10 @@ struct sctp_block_entry {
};
struct sctp_timewait {
uint32_t tv_sec_at_expire; /* the seconds from boot to expire */
uint32_t v_tag; /* the vtag that can not be reused */
uint16_t lport; /* the local port used in vtag */
uint16_t rport; /* the remote port used in vtag */
time_t tv_sec_at_expire; /* the seconds from boot to expire */
uint32_t v_tag; /* the vtag that can not be reused */
uint16_t lport; /* the local port used in vtag */
uint16_t rport; /* the remote port used in vtag */
};
struct sctp_tagblock {
@@ -352,8 +347,8 @@ struct sctp_base_info {
* access /dev/random.
*/
struct sctp_pcb {
unsigned int time_of_secret_change; /* number of seconds from
* timeval.tv_sec */
time_t time_of_secret_change; /* number of seconds from
* timeval.tv_sec */
uint32_t secret_key[SCTP_HOW_MANY_SECRETS][SCTP_NUMBER_OF_SECRETS];
unsigned int size_of_a_cookie;
@@ -496,7 +491,7 @@ struct sctp_inpcb {
uint8_t reconfig_supported;
uint8_t nrsack_supported;
uint8_t pktdrop_supported;
uint8_t zero_checksum;
uint8_t rcv_edmid;
struct sctp_nonpad_sndrcvinfo def_send;
/*-
* These three are here for the sosend_dgram
@@ -686,18 +681,6 @@ struct sctp_vrf *sctp_allocate_vrf(int vrfid);
struct sctp_vrf *sctp_find_vrf(uint32_t vrfid);
void sctp_free_vrf(struct sctp_vrf *vrf);
/*-
* Change address state, can be used if
* O/S supports telling transports about
* changes to IFA/IFN's (link layer triggers).
* If a ifn goes down, we will do src-addr-selection
* and NOT use that, as a source address. This does
* not stop the routing system from routing out
* that interface, but we won't put it as a source.
*/
void sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr, const char *if_name, uint32_t ifn_index);
void sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr, const char *if_name, uint32_t ifn_index);
struct sctp_ifa *
sctp_add_addr_to_vrf(uint32_t vrfid,
void *ifn, uint32_t ifn_index, uint32_t ifn_type,
@@ -705,13 +688,10 @@ sctp_add_addr_to_vrf(uint32_t vrfid,
void *ifa, struct sockaddr *addr, uint32_t ifa_flags,
int dynamic_add);
void sctp_update_ifn_mtu(uint32_t ifn_index, uint32_t mtu);
void sctp_free_ifn(struct sctp_ifn *sctp_ifnp);
void sctp_free_ifa(struct sctp_ifa *sctp_ifap);
void sctp_del_addr_from_vrf(uint32_t vrfid, struct sockaddr *addr,
uint32_t ifn_index, const char *if_name);
void *ifn, uint32_t ifn_index);
struct sctp_nets *sctp_findnet(struct sctp_tcb *, struct sockaddr *);
-5
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
#include <netinet/sctp_pcb.h>
#include <netinet/sctputil.h>
-5
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_PEELOFF_H_
#define _NETINET_SCTP_PEELOFF_H_
#if defined(HAVE_SCTP_PEELOFF_SOCKOPT)
+10 -6
View File
@@ -98,10 +98,11 @@
#define SCTP_ASOC_CREATE_LOCK(_inp)
#define SCTP_ASOC_CREATE_UNLOCK(_inp)
#define SCTP_INP_READ_INIT(_inp)
#define SCTP_INP_READ_DESTROY(_inp)
#define SCTP_INP_READ_LOCK_INIT(_inp)
#define SCTP_INP_READ_LOCK_DESTROY(_inp)
#define SCTP_INP_READ_LOCK(_inp)
#define SCTP_INP_READ_UNLOCK(_inp)
#define SCTP_INP_READ_LOCK_ASSERT(_inp)
/* Lock for TCB */
#define SCTP_TCB_LOCK_INIT(_tcb)
@@ -180,14 +181,15 @@
* we want to change something at the endpoint level for example random_store
* or cookie secrets we lock the INP level.
*/
#define SCTP_INP_READ_INIT(_inp) \
#define SCTP_INP_READ_LOCK_INIT(_inp) \
InitializeCriticalSection(&(_inp)->inp_rdata_mtx)
#define SCTP_INP_READ_DESTROY(_inp) \
#define SCTP_INP_READ_LOCK_DESTROY(_inp) \
DeleteCriticalSection(&(_inp)->inp_rdata_mtx)
#define SCTP_INP_READ_LOCK(_inp) \
EnterCriticalSection(&(_inp)->inp_rdata_mtx)
#define SCTP_INP_READ_UNLOCK(_inp) \
LeaveCriticalSection(&(_inp)->inp_rdata_mtx)
#define SCTP_INP_READ_LOCK_ASSERT(_inp)
#define SCTP_INP_LOCK_INIT(_inp) \
InitializeCriticalSection(&(_inp)->inp_mtx)
@@ -335,9 +337,9 @@
* we want to change something at the endpoint level for example random_store
* or cookie secrets we lock the INP level.
*/
#define SCTP_INP_READ_INIT(_inp) \
#define SCTP_INP_READ_LOCK_INIT(_inp) \
(void)pthread_mutex_init(&(_inp)->inp_rdata_mtx, &SCTP_BASE_VAR(mtx_attr))
#define SCTP_INP_READ_DESTROY(_inp) \
#define SCTP_INP_READ_LOCK_DESTROY(_inp) \
(void)pthread_mutex_destroy(&(_inp)->inp_rdata_mtx)
#ifdef INVARIANTS
#define SCTP_INP_READ_LOCK(_inp) \
@@ -350,6 +352,8 @@
#define SCTP_INP_READ_UNLOCK(_inp) \
(void)pthread_mutex_unlock(&(_inp)->inp_rdata_mtx)
#endif
#define SCTP_INP_READ_LOCK_ASSERT(_inp) \
KASSERT(pthread_mutex_trylock(&(_inp)->inp_rdata_mtx) == EBUSY, ("%s:%d: inp_rdata_mtx not locked", __FILE__, __LINE__))
#define SCTP_INP_LOCK_INIT(_inp) \
(void)pthread_mutex_init(&(_inp)->inp_mtx, &SCTP_BASE_VAR(mtx_attr))
-6
View File
@@ -32,12 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef __NETINET_SCTP_SHA1_H__
#define __NETINET_SCTP_SHA1_H__
+7 -14
View File
@@ -1,5 +1,5 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2010-2012, by Michael Tuexen. All rights reserved.
* Copyright (c) 2010-2012, by Randall Stewart. All rights reserved.
@@ -28,15 +28,8 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
#include <netinet/sctp_pcb.h>
#if defined(__Userspace__)
#include <netinet/sctp_os_userspace.h>
#endif
/*
* Default simple round-robin algorithm.
@@ -975,7 +968,7 @@ const struct sctp_ss_functions sctp_ss_functions[] = {
.sctp_ss_is_user_msgs_incomplete = sctp_ss_default_is_user_msgs_incomplete
#endif
},
/* SCTP_SS_ROUND_ROBIN */
/* SCTP_SS_RR */
{
#if defined(_WIN32)
sctp_ss_default_init,
@@ -1005,7 +998,7 @@ const struct sctp_ss_functions sctp_ss_functions[] = {
.sctp_ss_is_user_msgs_incomplete = sctp_ss_default_is_user_msgs_incomplete
#endif
},
/* SCTP_SS_ROUND_ROBIN_PACKET */
/* SCTP_SS_RR_PKT */
{
#if defined(_WIN32)
sctp_ss_default_init,
@@ -1035,7 +1028,7 @@ const struct sctp_ss_functions sctp_ss_functions[] = {
.sctp_ss_is_user_msgs_incomplete = sctp_ss_default_is_user_msgs_incomplete
#endif
},
/* SCTP_SS_PRIORITY */
/* SCTP_SS_PRIO */
{
#if defined(_WIN32)
sctp_ss_default_init,
@@ -1065,7 +1058,7 @@ const struct sctp_ss_functions sctp_ss_functions[] = {
.sctp_ss_is_user_msgs_incomplete = sctp_ss_default_is_user_msgs_incomplete
#endif
},
/* SCTP_SS_FAIR_BANDWITH */
/* SCTP_SS_FB */
{
#if defined(_WIN32)
sctp_ss_default_init,
@@ -1095,7 +1088,7 @@ const struct sctp_ss_functions sctp_ss_functions[] = {
.sctp_ss_is_user_msgs_incomplete = sctp_ss_default_is_user_msgs_incomplete
#endif
},
/* SCTP_SS_FIRST_COME */
/* SCTP_SS_FCFS */
{
#if defined(_WIN32)
sctp_ss_fcfs_init,
+3 -20
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_STRUCTS_H_
#define _NETINET_SCTP_STRUCTS_H_
@@ -1008,15 +1003,6 @@ struct sctp_association {
uint32_t fast_recovery_tsn;
uint32_t sat_t3_recovery_tsn;
uint32_t tsn_last_delivered;
/*
* 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
* "stuck" on the read queue until we finish all the pd-api.
*/
struct sctp_queued_to_read *control_pdapi;
uint32_t tsn_of_pdapi_last_delivered;
uint32_t pdapi_ppid;
uint32_t context;
@@ -1234,12 +1220,9 @@ struct sctp_association {
uint8_t pktdrop_supported;
uint8_t idata_supported;
/* Zero checksum supported information:
* 0: disabled
* 1: enabled for rcv
* 2: enabled for snd/rcv
*/
uint8_t zero_checksum;
/* Zero checksum supported information */
uint8_t rcv_edmid;
uint8_t snd_edmid;
/* Did the peer make the stream config (add out) request */
uint8_t peer_req_out;
+96 -82
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
#include <netinet/sctp.h>
#include <netinet/sctp_constants.h>
@@ -1110,6 +1105,14 @@ sctp_sysctl_handle_trace_log_clear(SYSCTL_HANDLER_ARGS)
#if (defined(__APPLE__) || defined(__FreeBSD__)) && !defined(__Userspace__)
#if defined(__FreeBSD__)
#define SCTP_UINT_SYSCTL(mib_name, var_name, prefix) \
SCTP_UINT_SYSCTL_FLAG(mib_name, var_name, prefix, \
CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RW)
#define SCTP_UINT_SYSCTL_TUN(mib_name, var_name, prefix) \
SCTP_UINT_SYSCTL_FLAG(mib_name, var_name, prefix, \
CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RWTUN|CTLFLAG_NOFETCH)
#define SCTP_UINT_SYSCTL_FLAG(mib_name, var_name, prefix, flags) \
static int \
sctp_sysctl_handle_##mib_name(SYSCTL_HANDLER_ARGS) \
{ \
@@ -1128,9 +1131,14 @@ sctp_sysctl_handle_trace_log_clear(SYSCTL_HANDLER_ARGS)
} \
return (error); \
} \
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, mib_name, \
CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RW, NULL, 0, \
sctp_sysctl_handle_##mib_name, "UI", prefix##_DESC);
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, mib_name, flags, NULL, 0, \
sctp_sysctl_handle_##mib_name, "IU", prefix##_DESC)
#define SCTP_UINT_SYSCTL_RDTUN(mib_name, var_name, prefix) \
SYSCTL_UINT(_net_inet_sctp, OID_AUTO, mib_name, \
CTLFLAG_VNET|CTLFLAG_RDTUN|CTLFLAG_NOFETCH, \
&VNET_NAME(system_base_info.sctpsysctl.var_name), 0, \
prefix##_DESC)
#else
#define SCTP_UINT_SYSCTL(mib_name, var_name, prefix) \
static int \
@@ -1156,7 +1164,7 @@ sctp_sysctl_handle_trace_log_clear(SYSCTL_HANDLER_ARGS)
} \
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, mib_name, \
CTLTYPE_INT | CTLFLAG_RW, NULL, 0, \
sctp_sysctl_handle_##mib_name, "I", prefix##_DESC);
sctp_sysctl_handle_##mib_name, "I", prefix##_DESC)
#define CTLTYPE_UINT CTLTYPE_INT
#define CTLFLAG_VNET 0
#endif
@@ -1165,66 +1173,72 @@ sctp_sysctl_handle_trace_log_clear(SYSCTL_HANDLER_ARGS)
* sysctl definitions
*/
SCTP_UINT_SYSCTL(sendspace, sctp_sendspace, SCTPCTL_MAXDGRAM)
SCTP_UINT_SYSCTL(recvspace, sctp_recvspace, SCTPCTL_RECVSPACE)
SCTP_UINT_SYSCTL(auto_asconf, sctp_auto_asconf, SCTPCTL_AUTOASCONF)
SCTP_UINT_SYSCTL(ecn_enable, sctp_ecn_enable, SCTPCTL_ECN_ENABLE)
SCTP_UINT_SYSCTL(pr_enable, sctp_pr_enable, SCTPCTL_PR_ENABLE)
SCTP_UINT_SYSCTL(sendspace, sctp_sendspace, SCTPCTL_MAXDGRAM);
SCTP_UINT_SYSCTL(recvspace, sctp_recvspace, SCTPCTL_RECVSPACE);
SCTP_UINT_SYSCTL(auto_asconf, sctp_auto_asconf, SCTPCTL_AUTOASCONF);
SCTP_UINT_SYSCTL(ecn_enable, sctp_ecn_enable, SCTPCTL_ECN_ENABLE);
SCTP_UINT_SYSCTL(pr_enable, sctp_pr_enable, SCTPCTL_PR_ENABLE);
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, auth_enable, CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RW,
NULL, 0, sctp_sysctl_handle_auth, "IU", SCTPCTL_AUTH_ENABLE_DESC);
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, asconf_enable, CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RW,
NULL, 0, sctp_sysctl_handle_asconf, "IU", SCTPCTL_ASCONF_ENABLE_DESC);
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(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);
#if defined(__APPLE__) && !defined(__Userspace__)
SCTP_UINT_SYSCTL(loopback_nocsum, sctp_no_csum_on_loopback, SCTPCTL_LOOPBACK_NOCSUM)
SCTP_UINT_SYSCTL(loopback_nocsum, sctp_no_csum_on_loopback, SCTPCTL_LOOPBACK_NOCSUM);
#endif
SCTP_UINT_SYSCTL(peer_chkoh, sctp_peer_chunk_oh, SCTPCTL_PEER_CHKOH)
SCTP_UINT_SYSCTL(maxburst, sctp_max_burst_default, SCTPCTL_MAXBURST)
SCTP_UINT_SYSCTL(fr_maxburst, sctp_fr_max_burst_default, SCTPCTL_FRMAXBURST)
SCTP_UINT_SYSCTL(maxchunks, sctp_max_chunks_on_queue, SCTPCTL_MAXCHUNKS)
SCTP_UINT_SYSCTL(tcbhashsize, sctp_hashtblsize, SCTPCTL_TCBHASHSIZE)
SCTP_UINT_SYSCTL(pcbhashsize, sctp_pcbtblsize, SCTPCTL_PCBHASHSIZE)
SCTP_UINT_SYSCTL(min_split_point, sctp_min_split_point, SCTPCTL_MIN_SPLIT_POINT)
SCTP_UINT_SYSCTL(chunkscale, sctp_chunkscale, SCTPCTL_CHUNKSCALE)
SCTP_UINT_SYSCTL(delayed_sack_time, sctp_delayed_sack_time_default, SCTPCTL_DELAYED_SACK_TIME)
SCTP_UINT_SYSCTL(sack_freq, sctp_sack_freq_default, SCTPCTL_SACK_FREQ)
SCTP_UINT_SYSCTL(sys_resource, sctp_system_free_resc_limit, SCTPCTL_SYS_RESOURCE)
SCTP_UINT_SYSCTL(asoc_resource, sctp_asoc_free_resc_limit, SCTPCTL_ASOC_RESOURCE)
SCTP_UINT_SYSCTL(heartbeat_interval, sctp_heartbeat_interval_default, SCTPCTL_HEARTBEAT_INTERVAL)
SCTP_UINT_SYSCTL(pmtu_raise_time, sctp_pmtu_raise_time_default, SCTPCTL_PMTU_RAISE_TIME)
SCTP_UINT_SYSCTL(shutdown_guard_time, sctp_shutdown_guard_time_default, SCTPCTL_SHUTDOWN_GUARD_TIME)
SCTP_UINT_SYSCTL(secret_lifetime, sctp_secret_lifetime_default, SCTPCTL_SECRET_LIFETIME)
SCTP_UINT_SYSCTL(rto_max, sctp_rto_max_default, SCTPCTL_RTO_MAX)
SCTP_UINT_SYSCTL(rto_min, sctp_rto_min_default, SCTPCTL_RTO_MIN)
SCTP_UINT_SYSCTL(rto_initial, sctp_rto_initial_default, SCTPCTL_RTO_INITIAL)
SCTP_UINT_SYSCTL(init_rto_max, sctp_init_rto_max_default, SCTPCTL_INIT_RTO_MAX)
SCTP_UINT_SYSCTL(valid_cookie_life, sctp_valid_cookie_life_default, SCTPCTL_VALID_COOKIE_LIFE)
SCTP_UINT_SYSCTL(init_rtx_max, sctp_init_rtx_max_default, SCTPCTL_INIT_RTX_MAX)
SCTP_UINT_SYSCTL(assoc_rtx_max, sctp_assoc_rtx_max_default, SCTPCTL_ASSOC_RTX_MAX)
SCTP_UINT_SYSCTL(path_rtx_max, sctp_path_rtx_max_default, SCTPCTL_PATH_RTX_MAX)
SCTP_UINT_SYSCTL(path_pf_threshold, sctp_path_pf_threshold, SCTPCTL_PATH_PF_THRESHOLD)
SCTP_UINT_SYSCTL(add_more_on_output, sctp_add_more_threshold, SCTPCTL_ADD_MORE_ON_OUTPUT)
SCTP_UINT_SYSCTL(incoming_streams, sctp_nr_incoming_streams_default, SCTPCTL_INCOMING_STREAMS)
SCTP_UINT_SYSCTL(outgoing_streams, sctp_nr_outgoing_streams_default, SCTPCTL_OUTGOING_STREAMS)
SCTP_UINT_SYSCTL(cmt_on_off, sctp_cmt_on_off, SCTPCTL_CMT_ON_OFF)
SCTP_UINT_SYSCTL(cmt_use_dac, sctp_cmt_use_dac, SCTPCTL_CMT_USE_DAC)
SCTP_UINT_SYSCTL(cwnd_maxburst, sctp_use_cwnd_based_maxburst, SCTPCTL_CWND_MAXBURST)
SCTP_UINT_SYSCTL(nat_friendly, sctp_nat_friendly, SCTPCTL_NAT_FRIENDLY)
SCTP_UINT_SYSCTL(abc_l_var, sctp_L2_abc_variable, SCTPCTL_ABC_L_VAR)
SCTP_UINT_SYSCTL(max_chained_mbufs, sctp_mbuf_threshold_count, SCTPCTL_MAX_CHAINED_MBUFS)
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(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)
SCTP_UINT_SYSCTL(default_cc_module, sctp_default_cc_module, SCTPCTL_DEFAULT_CC_MODULE)
SCTP_UINT_SYSCTL(default_ss_module, sctp_default_ss_module, SCTPCTL_DEFAULT_SS_MODULE)
SCTP_UINT_SYSCTL(default_frag_interleave, sctp_default_frag_interleave, SCTPCTL_DEFAULT_FRAG_INTERLEAVE)
SCTP_UINT_SYSCTL(mobility_base, sctp_mobility_base, SCTPCTL_MOBILITY_BASE)
SCTP_UINT_SYSCTL(mobility_fasthandoff, sctp_mobility_fasthandoff, SCTPCTL_MOBILITY_FASTHANDOFF)
SCTP_UINT_SYSCTL(peer_chkoh, sctp_peer_chunk_oh, SCTPCTL_PEER_CHKOH);
SCTP_UINT_SYSCTL(maxburst, sctp_max_burst_default, SCTPCTL_MAXBURST);
SCTP_UINT_SYSCTL(fr_maxburst, sctp_fr_max_burst_default, SCTPCTL_FRMAXBURST);
SCTP_UINT_SYSCTL(maxchunks, sctp_max_chunks_on_queue, SCTPCTL_MAXCHUNKS);
#if defined(__FreeBSD__) && !defined(__Userspace__)
SCTP_UINT_SYSCTL_RDTUN(tcbhashsize, sctp_hashtblsize, SCTPCTL_TCBHASHSIZE);
SCTP_UINT_SYSCTL_TUN(pcbhashsize, sctp_pcbtblsize, SCTPCTL_PCBHASHSIZE);
SCTP_UINT_SYSCTL_RDTUN(chunkscale, sctp_chunkscale, SCTPCTL_CHUNKSCALE);
#else
SCTP_UINT_SYSCTL(tcbhashsize, sctp_hashtblsize, SCTPCTL_TCBHASHSIZE);
SCTP_UINT_SYSCTL(pcbhashsize, sctp_pcbtblsize, SCTPCTL_PCBHASHSIZE);
SCTP_UINT_SYSCTL(chunkscale, sctp_chunkscale, SCTPCTL_CHUNKSCALE);
#endif
SCTP_UINT_SYSCTL(min_split_point, sctp_min_split_point, SCTPCTL_MIN_SPLIT_POINT);
SCTP_UINT_SYSCTL(delayed_sack_time, sctp_delayed_sack_time_default, SCTPCTL_DELAYED_SACK_TIME);
SCTP_UINT_SYSCTL(sack_freq, sctp_sack_freq_default, SCTPCTL_SACK_FREQ);
SCTP_UINT_SYSCTL(sys_resource, sctp_system_free_resc_limit, SCTPCTL_SYS_RESOURCE);
SCTP_UINT_SYSCTL(asoc_resource, sctp_asoc_free_resc_limit, SCTPCTL_ASOC_RESOURCE);
SCTP_UINT_SYSCTL(heartbeat_interval, sctp_heartbeat_interval_default, SCTPCTL_HEARTBEAT_INTERVAL);
SCTP_UINT_SYSCTL(pmtu_raise_time, sctp_pmtu_raise_time_default, SCTPCTL_PMTU_RAISE_TIME);
SCTP_UINT_SYSCTL(shutdown_guard_time, sctp_shutdown_guard_time_default, SCTPCTL_SHUTDOWN_GUARD_TIME);
SCTP_UINT_SYSCTL(secret_lifetime, sctp_secret_lifetime_default, SCTPCTL_SECRET_LIFETIME);
SCTP_UINT_SYSCTL(rto_max, sctp_rto_max_default, SCTPCTL_RTO_MAX);
SCTP_UINT_SYSCTL(rto_min, sctp_rto_min_default, SCTPCTL_RTO_MIN);
SCTP_UINT_SYSCTL(rto_initial, sctp_rto_initial_default, SCTPCTL_RTO_INITIAL);
SCTP_UINT_SYSCTL(init_rto_max, sctp_init_rto_max_default, SCTPCTL_INIT_RTO_MAX);
SCTP_UINT_SYSCTL(valid_cookie_life, sctp_valid_cookie_life_default, SCTPCTL_VALID_COOKIE_LIFE);
SCTP_UINT_SYSCTL(init_rtx_max, sctp_init_rtx_max_default, SCTPCTL_INIT_RTX_MAX);
SCTP_UINT_SYSCTL(assoc_rtx_max, sctp_assoc_rtx_max_default, SCTPCTL_ASSOC_RTX_MAX);
SCTP_UINT_SYSCTL(path_rtx_max, sctp_path_rtx_max_default, SCTPCTL_PATH_RTX_MAX);
SCTP_UINT_SYSCTL(path_pf_threshold, sctp_path_pf_threshold, SCTPCTL_PATH_PF_THRESHOLD);
SCTP_UINT_SYSCTL(add_more_on_output, sctp_add_more_threshold, SCTPCTL_ADD_MORE_ON_OUTPUT);
SCTP_UINT_SYSCTL(incoming_streams, sctp_nr_incoming_streams_default, SCTPCTL_INCOMING_STREAMS);
SCTP_UINT_SYSCTL(outgoing_streams, sctp_nr_outgoing_streams_default, SCTPCTL_OUTGOING_STREAMS);
SCTP_UINT_SYSCTL(cmt_on_off, sctp_cmt_on_off, SCTPCTL_CMT_ON_OFF);
SCTP_UINT_SYSCTL(cmt_use_dac, sctp_cmt_use_dac, SCTPCTL_CMT_USE_DAC);
SCTP_UINT_SYSCTL(cwnd_maxburst, sctp_use_cwnd_based_maxburst, SCTPCTL_CWND_MAXBURST);
SCTP_UINT_SYSCTL(nat_friendly, sctp_nat_friendly, SCTPCTL_NAT_FRIENDLY);
SCTP_UINT_SYSCTL(abc_l_var, sctp_L2_abc_variable, SCTPCTL_ABC_L_VAR);
SCTP_UINT_SYSCTL(max_chained_mbufs, sctp_mbuf_threshold_count, SCTPCTL_MAX_CHAINED_MBUFS);
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(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);
SCTP_UINT_SYSCTL(default_cc_module, sctp_default_cc_module, SCTPCTL_DEFAULT_CC_MODULE);
SCTP_UINT_SYSCTL(default_ss_module, sctp_default_ss_module, SCTPCTL_DEFAULT_SS_MODULE);
SCTP_UINT_SYSCTL(default_frag_interleave, sctp_default_frag_interleave, SCTPCTL_DEFAULT_FRAG_INTERLEAVE);
SCTP_UINT_SYSCTL(mobility_base, sctp_mobility_base, SCTPCTL_MOBILITY_BASE);
SCTP_UINT_SYSCTL(mobility_fasthandoff, sctp_mobility_fasthandoff, SCTPCTL_MOBILITY_FASTHANDOFF);
#if defined(SCTP_LOCAL_TRACE_BUF)
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, log, CTLFLAG_VNET|CTLTYPE_STRUCT|CTLFLAG_RD,
NULL, 0, sctp_sysctl_handle_trace_log, "S,sctplog", "SCTP logging (struct sctp_log)");
@@ -1233,32 +1247,32 @@ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, clear_trace, CTLFLAG_VNET|CTLTYPE_UINT | C
#endif
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, udp_tunneling_port, CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RW,
NULL, 0, sctp_sysctl_handle_udp_tunneling, "IU", SCTPCTL_UDP_TUNNELING_PORT_DESC);
SCTP_UINT_SYSCTL(enable_sack_immediately, sctp_enable_sack_immediately, SCTPCTL_SACK_IMMEDIATELY_ENABLE)
SCTP_UINT_SYSCTL(nat_friendly_init, sctp_inits_include_nat_friendly, SCTPCTL_NAT_FRIENDLY_INITS)
SCTP_UINT_SYSCTL(vtag_time_wait, sctp_vtag_time_wait, SCTPCTL_TIME_WAIT)
SCTP_UINT_SYSCTL(buffer_splitting, sctp_buffer_splitting, SCTPCTL_BUFFER_SPLITTING)
SCTP_UINT_SYSCTL(initial_cwnd, sctp_initial_cwnd, SCTPCTL_INITIAL_CWND)
SCTP_UINT_SYSCTL(rttvar_bw, sctp_rttvar_bw, SCTPCTL_RTTVAR_BW)
SCTP_UINT_SYSCTL(rttvar_rtt, sctp_rttvar_rtt, SCTPCTL_RTTVAR_RTT)
SCTP_UINT_SYSCTL(rttvar_eqret, sctp_rttvar_eqret, SCTPCTL_RTTVAR_EQRET)
SCTP_UINT_SYSCTL(rttvar_steady_step, sctp_steady_step, SCTPCTL_RTTVAR_STEADYS)
SCTP_UINT_SYSCTL(use_dcccecn, sctp_use_dccc_ecn, SCTPCTL_RTTVAR_DCCCECN)
SCTP_UINT_SYSCTL(blackhole, sctp_blackhole, SCTPCTL_BLACKHOLE)
SCTP_UINT_SYSCTL(sendall_limit, sctp_sendall_limit, SCTPCTL_SENDALL_LIMIT)
SCTP_UINT_SYSCTL(diag_info_code, sctp_diag_info_code, SCTPCTL_DIAG_INFO_CODE)
SCTP_UINT_SYSCTL(ootb_with_zero_cksum, sctp_ootb_with_zero_cksum, SCTPCTL_OOTB_WITH_ZERO_CKSUM)
SCTP_UINT_SYSCTL(enable_sack_immediately, sctp_enable_sack_immediately, SCTPCTL_SACK_IMMEDIATELY_ENABLE);
SCTP_UINT_SYSCTL(nat_friendly_init, sctp_inits_include_nat_friendly, SCTPCTL_NAT_FRIENDLY_INITS);
SCTP_UINT_SYSCTL(vtag_time_wait, sctp_vtag_time_wait, SCTPCTL_TIME_WAIT);
SCTP_UINT_SYSCTL(buffer_splitting, sctp_buffer_splitting, SCTPCTL_BUFFER_SPLITTING);
SCTP_UINT_SYSCTL(initial_cwnd, sctp_initial_cwnd, SCTPCTL_INITIAL_CWND);
SCTP_UINT_SYSCTL(rttvar_bw, sctp_rttvar_bw, SCTPCTL_RTTVAR_BW);
SCTP_UINT_SYSCTL(rttvar_rtt, sctp_rttvar_rtt, SCTPCTL_RTTVAR_RTT);
SCTP_UINT_SYSCTL(rttvar_eqret, sctp_rttvar_eqret, SCTPCTL_RTTVAR_EQRET);
SCTP_UINT_SYSCTL(rttvar_steady_step, sctp_steady_step, SCTPCTL_RTTVAR_STEADYS);
SCTP_UINT_SYSCTL(use_dcccecn, sctp_use_dccc_ecn, SCTPCTL_RTTVAR_DCCCECN);
SCTP_UINT_SYSCTL(blackhole, sctp_blackhole, SCTPCTL_BLACKHOLE);
SCTP_UINT_SYSCTL(sendall_limit, sctp_sendall_limit, SCTPCTL_SENDALL_LIMIT);
SCTP_UINT_SYSCTL(diag_info_code, sctp_diag_info_code, SCTPCTL_DIAG_INFO_CODE);
SCTP_UINT_SYSCTL(ootb_with_zero_cksum, sctp_ootb_with_zero_cksum, SCTPCTL_OOTB_WITH_ZERO_CKSUM);
#ifdef SCTP_DEBUG
SCTP_UINT_SYSCTL(debug, sctp_debug_on, SCTPCTL_DEBUG)
SCTP_UINT_SYSCTL(debug, sctp_debug_on, SCTPCTL_DEBUG);
#endif
#if defined(__APPLE__) && !defined(__Userspace__)
SCTP_UINT_SYSCTL(main_timer, sctp_main_timer, SCTPCTL_MAIN_TIMER)
SCTP_UINT_SYSCTL(main_timer, sctp_main_timer, SCTPCTL_MAIN_TIMER);
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, ignore_vmware_interfaces, CTLTYPE_UINT|CTLFLAG_RW,
NULL, 0, sctp_sysctl_handle_vmware_interfaces, "IU", SCTPCTL_IGNORE_VMWARE_INTERFACES_DESC);
SCTP_UINT_SYSCTL(addr_watchdog_limit, sctp_addr_watchdog_limit, SCTPCTL_ADDR_WATCHDOG_LIMIT)
SCTP_UINT_SYSCTL(vtag_watchdog_limit, sctp_vtag_watchdog_limit, SCTPCTL_VTAG_WATCHDOG_LIMIT)
SCTP_UINT_SYSCTL(addr_watchdog_limit, sctp_addr_watchdog_limit, SCTPCTL_ADDR_WATCHDOG_LIMIT);
SCTP_UINT_SYSCTL(vtag_watchdog_limit, sctp_vtag_watchdog_limit, SCTPCTL_VTAG_WATCHDOG_LIMIT);
#endif
#if defined(__APPLE__) && !defined(__Userspace__)
SCTP_UINT_SYSCTL(output_unlocked, sctp_output_unlocked, SCTPCTL_OUTPUT_UNLOCKED)
SCTP_UINT_SYSCTL(output_unlocked, sctp_output_unlocked, SCTPCTL_OUTPUT_UNLOCKED);
#endif
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, stats, CTLFLAG_VNET|CTLTYPE_STRUCT|CTLFLAG_RW,
NULL, 0, sctp_sysctl_handle_stats, "S,sctpstat", "SCTP statistics (struct sctp_stat)");
-5
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_SYSCTL_H_
#define _NETINET_SCTP_SYSCTL_H_
+5 -12
View File
@@ -32,16 +32,11 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#define _IP_VHL
#include <netinet/sctp_os.h>
#include <netinet/sctp_pcb.h>
#ifdef INET6
#if defined(__FreeBSD__) && defined(__Userspace__)
#ifdef INET6
#include <netinet6/sctp6_var.h>
#endif
#endif
@@ -97,7 +92,10 @@ static int
sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct sctp_nets *net, uint16_t threshold)
{
if (net) {
KASSERT(stcb != NULL, ("stcb is NULL"));
SCTP_TCB_LOCK_ASSERT(stcb);
if (net != NULL) {
net->error_count++;
SCTPDBG(SCTP_DEBUG_TIMER4, "Error count for %p now %d thresh:%d\n",
(void *)net, net->error_count,
@@ -124,11 +122,6 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
}
}
}
if (stcb == NULL)
return (0);
if (net) {
if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0) {
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_INCR,
-5
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_TIMER_H_
#define _NETINET_SCTP_TIMER_H_
+4 -5
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_UIO_H_
#define _NETINET_SCTP_UIO_H_
@@ -810,6 +805,10 @@ struct sctp_get_nonce_values {
uint32_t gn_local_tag;
};
/* Values for SCTP_ACCEPT_ZERO_CHECKSUM */
#define SCTP_EDMID_NONE 0
#define SCTP_EDMID_LOWER_LAYER_DTLS 1
/* Debugging logs */
struct sctp_str_log {
void *stcb; /* FIXME: LP64 issue */
@@ -84,13 +84,8 @@ void
sctp_userspace_set_threadname(const char *name)
{
#if defined(__APPLE__)
#if(1)
/* TenFourFox: no pthread_setname_np in Tiger */
return;
#else
pthread_setname_np(name);
#endif
#endif
#if defined(__linux__)
prctl(PR_SET_NAME, name);
#endif
+206 -207
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/proc.h>
@@ -67,6 +62,9 @@ __FBSDID("$FreeBSD$");
#if defined(HAVE_SCTP_PEELOFF_SOCKOPT)
#include <netinet/sctp_peeloff.h>
#endif /* HAVE_SCTP_PEELOFF_SOCKOPT */
#if defined(_WIN32) && defined(__MINGW32__)
#include <minmax.h>
#endif
extern const struct sctp_cc_functions sctp_cc_functions[];
extern const struct sctp_ss_functions sctp_ss_functions[];
@@ -609,8 +607,9 @@ sctp_getcred(SYSCTL_HANDLER_ARGS)
/* FIX, for non-bsd is this right? */
vrf_id = SCTP_DEFAULT_VRFID;
if (req->newptr == NULL)
return (EINVAL);
error = priv_check(req->td, PRIV_NETINET_GETCRED);
if (error)
return (error);
@@ -661,13 +660,10 @@ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, getcred,
"Get the ucred of a SCTP connection");
#endif
#ifdef INET
#if defined(_WIN32) || defined(__Userspace__)
int
#elif defined(__FreeBSD__)
static void
#if defined(__FreeBSD__) && !defined(__Userspace__)
void
#else
static int
int
#endif
sctp_abort(struct socket *so)
{
@@ -725,6 +721,7 @@ sctp_abort(struct socket *so)
#endif
}
#ifdef INET
#if defined(__Userspace__)
int
#else
@@ -902,24 +899,23 @@ sctp_close(struct socket *so)
inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP;
#if defined(__Userspace__)
if (((so->so_options & SCTP_SO_LINGER) && (so->so_linger == 0)) ||
(SCTP_SBAVAIL(&so->so_rcv) > 0)) {
#else
if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) ||
(SCTP_SBAVAIL(&so->so_rcv) > 0)) {
#endif
(SCTP_SBAVAIL(&so->so_rcv) > 0)) {
#ifdef SCTP_LOG_CLOSING
sctp_log_closing(inp, NULL, 13);
#endif
SCTP_INP_WUNLOCK(inp);
sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
} else {
#ifdef SCTP_LOG_CLOSING
sctp_log_closing(inp, NULL, 14);
#endif
SCTP_INP_WUNLOCK(inp);
sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_GRACEFUL_CLOSE,
SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
}
/* The socket is now detached, no matter what
* the state of the SCTP association.
@@ -955,12 +951,8 @@ sctp_detach(struct socket *so)
inp = (struct sctp_inpcb *)so->so_pcb;
if (inp == NULL) {
#if defined(__FreeBSD__) && !defined(__Userspace__)
return;
#else
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
return (EINVAL);
#endif
}
sctp_must_try_again:
flags = inp->sctp_flags;
@@ -969,24 +961,19 @@ sctp_detach(struct socket *so)
#endif
if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
(atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) {
#if defined(__Userspace__)
if (((so->so_options & SCTP_SO_LINGER) && (so->so_linger == 0)) ||
(SCTP_SBAVAIL(&so->so_rcv) > 0)) {
#else
if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) ||
(SCTP_SBAVAIL(&so->so_rcv) > 0)) {
#endif
#ifdef SCTP_LOG_CLOSING
sctp_log_closing(inp, NULL, 13);
#endif
sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
} else {
#ifdef SCTP_LOG_CLOSING
sctp_log_closing(inp, NULL, 13);
#endif
sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_GRACEFUL_CLOSE,
SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
}
/* The socket is now detached, no matter what
* the state of the SCTP association.
@@ -1006,11 +993,7 @@ sctp_detach(struct socket *so)
goto sctp_must_try_again;
}
}
#if defined(__FreeBSD__) && !defined(__Userspace__)
return;
#else
return (0);
#endif
}
#endif
@@ -1136,7 +1119,12 @@ connected_type:
int
sctp_disconnect(struct socket *so)
{
#if defined(__FreeBSD__) && !defined(__Userspace__)
struct epoch_tracker et;
#endif
struct sctp_inpcb *inp;
struct sctp_association *asoc;
struct sctp_tcb *stcb;
inp = (struct sctp_inpcb *)so->so_pcb;
if (inp == NULL) {
@@ -1144,205 +1132,214 @@ sctp_disconnect(struct socket *so)
return (ENOTCONN);
}
SCTP_INP_RLOCK(inp);
if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
if (LIST_EMPTY(&inp->sctp_asoc_list)) {
/* No connection */
SCTP_INP_RUNLOCK(inp);
return (0);
} else {
KASSERT(inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE ||
inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL,
("Not a one-to-one style socket"));
stcb = LIST_FIRST(&inp->sctp_asoc_list);
if (stcb == NULL) {
SCTP_INP_RUNLOCK(inp);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN);
return (ENOTCONN);
}
SCTP_TCB_LOCK(stcb);
asoc = &stcb->asoc;
if (asoc->state & SCTP_STATE_ABOUT_TO_BE_FREED) {
/* We are about to be freed, out of here */
SCTP_TCB_UNLOCK(stcb);
SCTP_INP_RUNLOCK(inp);
return (0);
}
#if defined(__FreeBSD__) && !defined(__Userspace__)
struct epoch_tracker et;
#endif
struct sctp_association *asoc;
struct sctp_tcb *stcb;
stcb = LIST_FIRST(&inp->sctp_asoc_list);
if (stcb == NULL) {
SCTP_INP_RUNLOCK(inp);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
return (EINVAL);
}
SCTP_TCB_LOCK(stcb);
asoc = &stcb->asoc;
if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
/* We are about to be freed, out of here */
SCTP_TCB_UNLOCK(stcb);
SCTP_INP_RUNLOCK(inp);
return (0);
}
#if defined(__FreeBSD__) && !defined(__Userspace__)
NET_EPOCH_ENTER(et);
NET_EPOCH_ENTER(et);
#endif
#if defined(__Userspace__)
if (((so->so_options & SCTP_SO_LINGER) && (so->so_linger == 0)) ||
(SCTP_SBAVAIL(&so->so_rcv) > 0)) {
if (((so->so_options & SCTP_SO_LINGER) && (so->so_linger == 0)) ||
(SCTP_SBAVAIL(&so->so_rcv) > 0)) {
#else
if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) ||
(SCTP_SBAVAIL(&so->so_rcv) > 0)) {
if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) ||
(SCTP_SBAVAIL(&so->so_rcv) > 0)) {
#endif
if (SCTP_GET_STATE(stcb) != SCTP_STATE_COOKIE_WAIT) {
/* Left with Data unread */
struct mbuf *op_err;
if (SCTP_GET_STATE(stcb) != SCTP_STATE_COOKIE_WAIT) {
/* Left with Data unread */
struct mbuf *op_err;
op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED);
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
}
SCTP_INP_RUNLOCK(inp);
if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
(SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_3);
/* No unlock tcb assoc is gone */
op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED);
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
}
SCTP_INP_RUNLOCK(inp);
if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
(SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_3);
/* No unlock tcb assoc is gone */
#if defined(__FreeBSD__) && !defined(__Userspace__)
NET_EPOCH_EXIT(et);
NET_EPOCH_EXIT(et);
#endif
return (0);
}
if (TAILQ_EMPTY(&asoc->send_queue) &&
TAILQ_EMPTY(&asoc->sent_queue) &&
(asoc->stream_queue_cnt == 0)) {
/* there is nothing queued to send, so done */
if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete)(stcb, asoc)) {
goto abort_anyway;
}
if ((SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_SENT) &&
(SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
/* only send SHUTDOWN 1st time thru */
struct sctp_nets *netp;
return (0);
}
if (TAILQ_EMPTY(&asoc->send_queue) &&
TAILQ_EMPTY(&asoc->sent_queue) &&
(asoc->stream_queue_cnt == 0)) {
/* there is nothing queued to send, so done */
if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete)(stcb, asoc)) {
goto abort_anyway;
}
if ((SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_SENT) &&
(SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
/* only send SHUTDOWN 1st time thru */
struct sctp_nets *netp;
if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
(SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT);
sctp_stop_timers_for_shutdown(stcb);
if (stcb->asoc.alternate) {
netp = stcb->asoc.alternate;
} else {
netp = stcb->asoc.primary_destination;
}
sctp_send_shutdown(stcb,netp);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
stcb->sctp_ep, stcb, netp);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
stcb->sctp_ep, stcb, NULL);
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
}
if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
(SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT);
sctp_stop_timers_for_shutdown(stcb);
if (stcb->asoc.alternate) {
netp = stcb->asoc.alternate;
} else {
/*
* we still got (or just got) data to send,
* so set SHUTDOWN_PENDING
*/
/*
* XXX sockets draft says that SCTP_EOF
* should be sent with no data. currently,
* we will allow user data to be sent first
* and move to SHUTDOWN-PENDING
*/
SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb, NULL);
if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete)(stcb, asoc)) {
SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_PARTIAL_MSG_LEFT);
}
if (TAILQ_EMPTY(&asoc->send_queue) &&
TAILQ_EMPTY(&asoc->sent_queue) &&
(asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
struct mbuf *op_err;
abort_anyway:
op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4;
sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED);
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
(SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
SCTP_INP_RUNLOCK(inp);
(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_5);
#if defined(__FreeBSD__) && !defined(__Userspace__)
NET_EPOCH_EXIT(et);
#endif
return (0);
} else {
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
}
netp = stcb->asoc.primary_destination;
}
soisdisconnecting(so);
sctp_send_shutdown(stcb,netp);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
stcb->sctp_ep, stcb, netp);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
stcb->sctp_ep, stcb, NULL);
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
}
} else {
/*
* we still got (or just got) data to send,
* so set SHUTDOWN_PENDING
*/
/*
* XXX sockets draft says that SCTP_EOF
* should be sent with no data. currently,
* we will allow user data to be sent first
* and move to SHUTDOWN-PENDING
*/
SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING);
if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete)(stcb, asoc)) {
SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_PARTIAL_MSG_LEFT);
}
if (TAILQ_EMPTY(&asoc->send_queue) &&
TAILQ_EMPTY(&asoc->sent_queue) &&
(asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
struct mbuf *op_err;
abort_anyway:
op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4;
sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED);
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
(SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
SCTP_INP_RUNLOCK(inp);
(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_5);
#if defined(__FreeBSD__) && !defined(__Userspace__)
NET_EPOCH_EXIT(et);
#endif
SCTP_TCB_UNLOCK(stcb);
SCTP_INP_RUNLOCK(inp);
return (0);
} else {
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
}
/* not reached */
} else {
/* UDP model does not support this */
SCTP_INP_RUNLOCK(inp);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
return (EOPNOTSUPP);
}
soisdisconnecting(so);
#if defined(__FreeBSD__) && !defined(__Userspace__)
NET_EPOCH_EXIT(et);
#endif
SCTP_TCB_UNLOCK(stcb);
SCTP_INP_RUNLOCK(inp);
return (0);
}
#if defined(__FreeBSD__) || defined(_WIN32) || defined(__Userspace__)
int
sctp_flush(struct socket *so, int how)
{
/*
* We will just clear out the values and let
* subsequent close clear out the data, if any.
* Note if the user did a shutdown(SHUT_RD) they
* will not be able to read the data, the socket
* will block that from happening.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
struct epoch_tracker et;
#endif
struct sctp_tcb *stcb;
struct sctp_queued_to_read *control, *ncontrol;
struct sctp_inpcb *inp;
struct mbuf *m, *op_err;
bool need_to_abort = false;
/*
* For 1-to-1 style sockets, flush the read queue and trigger an
* ungraceful shutdown of the association, if and only if user messages
* are lost. Loosing notifications does not need to be signalled to the
* peer.
*/
if (how == PRU_FLUSH_WR) {
/* This function is only relevant for the read directions. */
return (0);
}
inp = (struct sctp_inpcb *)so->so_pcb;
if (inp == NULL) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
return (EINVAL);
}
SCTP_INP_RLOCK(inp);
/* For the 1 to many model this does nothing */
SCTP_INP_WLOCK(inp);
if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
SCTP_INP_RUNLOCK(inp);
/* For 1-to-many style sockets this function does nothing. */
SCTP_INP_WUNLOCK(inp);
return (0);
}
SCTP_INP_RUNLOCK(inp);
if ((how == PRU_FLUSH_RD) || (how == PRU_FLUSH_RDWR)) {
/* First make sure the sb will be happy, we don't
* use these except maybe the count
*/
SCTP_INP_WLOCK(inp);
SCTP_INP_READ_LOCK(inp);
inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_CANT_READ;
SCTP_INP_READ_UNLOCK(inp);
stcb = LIST_FIRST(&inp->sctp_asoc_list);
if (stcb != NULL) {
SCTP_TCB_LOCK(stcb);
}
SCTP_INP_READ_LOCK(inp);
inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_CANT_READ;
SOCK_LOCK(so);
TAILQ_FOREACH_SAFE(control, &inp->read_queue, next, ncontrol) {
if ((control->spec_flags & M_NOTIFICATION) == 0) {
need_to_abort = true;
}
TAILQ_REMOVE(&inp->read_queue, control, next);
control->on_read_q = 0;
for (m = control->data; m; m = SCTP_BUF_NEXT(m)) {
sctp_sbfree(control, control->stcb, &so->so_rcv, m);
}
if (control->on_strm_q == 0) {
sctp_free_remote_addr(control->whoFrom);
if (control->data) {
sctp_m_freem(control->data);
control->data = NULL;
}
sctp_free_a_readq(stcb, control);
} else {
if (stcb != NULL) {
stcb->asoc.size_on_all_streams += control->length;
}
}
}
SOCK_UNLOCK(so);
SCTP_INP_READ_UNLOCK(inp);
if (need_to_abort && (stcb != NULL)) {
inp->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6;
SCTP_INP_WUNLOCK(inp);
SOCK_LOCK(so);
op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
#if defined(__FreeBSD__) && !defined(__Userspace__)
KASSERT(!SOLISTENING(so),
("sctp_flush: called on listening socket %p", so));
NET_EPOCH_ENTER(et);
#endif
SCTP_SB_CLEAR(so->so_rcv);
SOCK_UNLOCK(so);
}
if ((how == PRU_FLUSH_WR) || (how == PRU_FLUSH_RDWR)) {
/* First make sure the sb will be happy, we don't
* use these except maybe the count
*/
SOCK_LOCK(so);
sctp_abort_an_association(inp, stcb, op_err, false, SCTP_SO_LOCKED);
#if defined(__FreeBSD__) && !defined(__Userspace__)
KASSERT(!SOLISTENING(so),
("sctp_flush: called on listening socket %p", so));
NET_EPOCH_EXIT(et);
#endif
SCTP_SB_CLEAR(so->so_snd);
SOCK_UNLOCK(so);
return (ECONNABORTED);
}
if (stcb != NULL) {
SCTP_TCB_UNLOCK(stcb);
}
SCTP_INP_WUNLOCK(inp);
return (0);
}
#endif
@@ -1444,6 +1441,8 @@ sctp_shutdown(struct socket *so)
sctp_send_shutdown(stcb, netp);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
stcb->sctp_ep, stcb, netp);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
stcb->sctp_ep, stcb, NULL);
} else {
/*
* We still got (or just got) data to send, so set
@@ -1469,7 +1468,6 @@ sctp_shutdown(struct socket *so)
return (0);
}
}
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb, NULL);
/* XXX: Why do this in the case where we have still data queued? */
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
SCTP_TCB_UNLOCK(stcb);
@@ -2408,7 +2406,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
}
break;
}
case SCTP_PLUGGABLE_SS:
case SCTP_STREAM_SCHEDULER:
{
struct sctp_assoc_value *av;
@@ -2435,7 +2433,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
}
break;
}
case SCTP_SS_VALUE:
case SCTP_STREAM_SCHEDULER_VALUE:
{
struct sctp_stream_value *av;
@@ -4818,17 +4816,17 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
}
break;
}
case SCTP_PLUGGABLE_SS:
case SCTP_STREAM_SCHEDULER:
{
struct sctp_assoc_value *av;
SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
if ((av->assoc_value != SCTP_SS_DEFAULT) &&
(av->assoc_value != SCTP_SS_ROUND_ROBIN) &&
(av->assoc_value != SCTP_SS_ROUND_ROBIN_PACKET) &&
(av->assoc_value != SCTP_SS_PRIORITY) &&
(av->assoc_value != SCTP_SS_FAIR_BANDWITH) &&
(av->assoc_value != SCTP_SS_FIRST_COME)) {
(av->assoc_value != SCTP_SS_RR) &&
(av->assoc_value != SCTP_SS_RR_PKT) &&
(av->assoc_value != SCTP_SS_PRIO) &&
(av->assoc_value != SCTP_SS_FB) &&
(av->assoc_value != SCTP_SS_FCFS)) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
error = EINVAL;
break;
@@ -4867,7 +4865,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
}
break;
}
case SCTP_SS_VALUE:
case SCTP_STREAM_SCHEDULER_VALUE:
{
struct sctp_stream_value *av;
@@ -7800,13 +7798,15 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
uint32_t *value;
SCTP_CHECK_AND_CAST(value, optval, uint32_t, optsize);
SCTP_INP_WLOCK(inp);
if (*value != 0) {
inp->zero_checksum = 1;
if ((*value == SCTP_EDMID_NONE) ||
(*value == SCTP_EDMID_LOWER_LAYER_DTLS)) {
SCTP_INP_WLOCK(inp);
inp->rcv_edmid = *value;
SCTP_INP_WUNLOCK(inp);
} else {
inp->zero_checksum = 0;
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
error = EINVAL;
}
SCTP_INP_WUNLOCK(inp);
break;
}
@@ -8895,7 +8895,6 @@ sctp_peeraddr(struct socket *so, struct mbuf *nam)
.pr_control = in_control, \
.pr_close = sctp_close, \
.pr_detach = sctp_close, \
.pr_sopoll = sopoll_generic, \
.pr_flush = sctp_flush, \
.pr_disconnect = sctp_disconnect, \
.pr_listen = sctp_listen, \
+9 -9
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_VAR_H_
#define _NETINET_SCTP_VAR_H_
@@ -207,7 +202,7 @@ extern struct pr_usrreqs sctp_usrreqs;
}
#define sctp_sbfree(ctl, stcb, sb, m) { \
SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_cc, SCTP_BUF_LEN((m))); \
SCTP_SB_DECR(sb, SCTP_BUF_LEN((m))); \
SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_mbcnt, MSIZE); \
if (((ctl)->do_not_ref_stcb == 0) && stcb) {\
SCTP_SAVE_ATOMIC_DECREMENT(&(stcb)->asoc.sb_cc, SCTP_BUF_LEN((m))); \
@@ -219,7 +214,7 @@ extern struct pr_usrreqs sctp_usrreqs;
}
#define sctp_sballoc(stcb, sb, m) { \
atomic_add_int(&(sb)->sb_cc,SCTP_BUF_LEN((m))); \
SCTP_SB_INCR(sb, SCTP_BUF_LEN((m))); \
atomic_add_int(&(sb)->sb_mbcnt, MSIZE); \
if (stcb) { \
atomic_add_int(&(stcb)->asoc.sb_cc, SCTP_BUF_LEN((m))); \
@@ -250,7 +245,7 @@ extern struct pr_usrreqs sctp_usrreqs;
}
#define sctp_sbfree(ctl, stcb, sb, m) { \
SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_cc, SCTP_BUF_LEN((m))); \
SCTP_SB_DECR(sb, SCTP_BUF_LEN((m))); \
SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_mbcnt, MSIZE); \
if (((ctl)->do_not_ref_stcb == 0) && stcb) { \
SCTP_SAVE_ATOMIC_DECREMENT(&(stcb)->asoc.sb_cc, SCTP_BUF_LEN((m))); \
@@ -259,7 +254,7 @@ extern struct pr_usrreqs sctp_usrreqs;
}
#define sctp_sballoc(stcb, sb, m) { \
atomic_add_int(&(sb)->sb_cc, SCTP_BUF_LEN((m))); \
SCTP_SB_INCR(sb, SCTP_BUF_LEN((m))); \
atomic_add_int(&(sb)->sb_mbcnt, MSIZE); \
if (stcb) { \
atomic_add_int(&(stcb)->asoc.sb_cc, SCTP_BUF_LEN((m))); \
@@ -372,6 +367,11 @@ void sctp_close(struct socket *so);
#else
int sctp_detach(struct socket *so);
#endif
#if defined(__FreeBSD__) && !defined(__Userspace__)
void sctp_abort(struct socket *so);
#else
int sctp_abort(struct socket *so);
#endif
int sctp_disconnect(struct socket *so);
#if !defined(__Userspace__)
#if defined(__APPLE__) && !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION) && !defined(APPLE_ELCAPITAN)
+216 -206
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
#include <netinet/sctp_pcb.h>
#include <netinet/sctputil.h>
@@ -70,6 +65,9 @@ __FBSDID("$FreeBSD$");
#include <netinet/icmp6.h>
#endif
#endif
#if defined(_WIN32) && defined(__MINGW32__)
#include <minmax.h>
#endif
#if defined(_WIN32) && !defined(__Userspace__)
#if !defined(SCTP_LOCAL_TRACE_BUF)
@@ -1178,7 +1176,8 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
asoc->nrsack_supported = inp->nrsack_supported;
asoc->pktdrop_supported = inp->pktdrop_supported;
asoc->idata_supported = inp->idata_supported;
asoc->zero_checksum = inp->zero_checksum;
asoc->rcv_edmid = inp->rcv_edmid;
asoc->snd_edmid = SCTP_EDMID_NONE;
asoc->sctp_cmt_pf = (uint8_t)0;
asoc->sctp_frag_point = inp->sctp_frag_point;
asoc->sctp_features = inp->sctp_features;
@@ -2397,19 +2396,19 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
} else {
to_ticks = net->RTO;
}
rndval = sctp_select_initial_TSN(&inp->sctp_ep);
jitter = rndval % to_ticks;
if (to_ticks > 1) {
to_ticks >>= 1;
}
if (jitter < (UINT32_MAX - to_ticks)) {
to_ticks += jitter;
} else {
to_ticks = UINT32_MAX;
}
if (!((net->dest_state & SCTP_ADDR_UNCONFIRMED) &&
(net->dest_state & SCTP_ADDR_REACHABLE)) &&
((net->dest_state & SCTP_ADDR_PF) == 0)) {
if (to_ticks > 1) {
rndval = sctp_select_initial_TSN(&inp->sctp_ep);
jitter = rndval % to_ticks;
to_ticks >>= 1;
if (jitter < (UINT32_MAX - to_ticks)) {
to_ticks += jitter;
} else {
to_ticks = UINT32_MAX;
}
}
if (net->heart_beat_delay < (UINT32_MAX - to_ticks)) {
to_ticks += net->heart_beat_delay;
} else {
@@ -3247,9 +3246,10 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
struct mbuf *m_notify;
struct sctp_assoc_change *sac;
struct sctp_queued_to_read *control;
struct sctp_inpcb *inp;
unsigned int notif_len;
uint16_t abort_len;
unsigned int i;
uint16_t abort_len;
#if defined(__APPLE__) && !defined(__Userspace__)
struct socket *so;
#endif
@@ -3258,10 +3258,12 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
("sctp_notify_assoc_change: ABORT chunk provided for local termination"));
KASSERT(!from_peer || !timedout,
("sctp_notify_assoc_change: timeouts can only be local"));
if (stcb == NULL) {
return;
}
if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT)) {
KASSERT(stcb != NULL, ("stcb == NULL"));
SCTP_TCB_LOCK_ASSERT(stcb);
inp = stcb->sctp_ep;
SCTP_INP_READ_LOCK_ASSERT(inp);
if (sctp_stcb_is_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT)) {
notif_len = (unsigned int)sizeof(struct sctp_assoc_change);
if (abort != NULL) {
abort_len = ntohs(abort->ch.chunk_length);
@@ -3339,10 +3341,9 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
control->spec_flags = M_NOTIFICATION;
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD,
so_locked);
sctp_add_to_readq(inp, stcb, control,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_HELD, so_locked);
} else {
sctp_m_freem(m_notify);
}
@@ -3352,8 +3353,8 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
* comes in.
*/
set_error:
if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC))) {
SOCK_LOCK(stcb->sctp_socket);
if (from_peer) {
@@ -3377,7 +3378,7 @@ set_error:
}
/* Wake ANY sleepers */
#if defined(__APPLE__) && !defined(__Userspace__)
so = SCTP_INP_SO(stcb->sctp_ep);
so = SCTP_INP_SO(inp);
if (!so_locked) {
atomic_add_int(&stcb->asoc.refcnt, 1);
SCTP_TCB_UNLOCK(stcb);
@@ -3390,8 +3391,8 @@ set_error:
}
}
#endif
if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC))) {
socantrcvmore(stcb->sctp_socket);
}
@@ -3412,11 +3413,15 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
struct sctp_paddr_change *spc;
struct sctp_queued_to_read *control;
if ((stcb == NULL) ||
sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT)) {
KASSERT(stcb != NULL, ("stcb == NULL"));
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT)) {
/* event not enabled */
return;
}
m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_paddr_change), 0, M_NOWAIT, 1, MT_DATA);
if (m_notify == NULL)
return;
@@ -3458,7 +3463,7 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
(void)sa6_recoverscope(sin6);
#else
(void)in6_recoverscope(sin6, &sin6->sin6_addr,
NULL);
NULL);
#endif
} else {
/* clear embedded scope_id for user */
@@ -3498,16 +3503,14 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
control->spec_flags = M_NOTIFICATION;
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
sctp_add_to_readq(stcb->sctp_ep, stcb, control,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_NOT_HELD,
so_locked);
SCTP_READ_LOCK_HELD, so_locked);
}
static void
sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error,
struct sctp_tmit_chunk *chk, int so_locked)
struct sctp_tmit_chunk *chk, int so_locked)
{
struct mbuf *m_notify;
struct sctp_send_failed *ssf;
@@ -3516,9 +3519,12 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error,
struct sctp_chunkhdr *chkhdr;
int notifhdr_len, chk_len, chkhdr_len, padding_len, payload_len;
if ((stcb == NULL) ||
(sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) &&
sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT))) {
KASSERT(stcb != NULL, ("stcb == NULL"));
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) &&
sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
/* event not enabled */
return;
}
@@ -3629,16 +3635,14 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error,
control->spec_flags = M_NOTIFICATION;
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
sctp_add_to_readq(stcb->sctp_ep, stcb, control,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_NOT_HELD,
so_locked);
SCTP_READ_LOCK_HELD, so_locked);
}
static void
sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
struct sctp_stream_queue_pending *sp, int so_locked)
struct sctp_stream_queue_pending *sp, int so_locked)
{
struct mbuf *m_notify;
struct sctp_send_failed *ssf;
@@ -3646,12 +3650,16 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
struct sctp_queued_to_read *control;
int notifhdr_len;
if ((stcb == NULL) ||
(sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) &&
sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT))) {
KASSERT(stcb != NULL, ("stcb == NULL"));
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) &&
sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
/* event not enabled */
return;
}
if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
notifhdr_len = sizeof(struct sctp_send_failed_event);
} else {
@@ -3727,20 +3735,23 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
control->spec_flags = M_NOTIFICATION;
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, so_locked);
sctp_add_to_readq(stcb->sctp_ep, stcb, control,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_HELD, so_locked);
}
static void
sctp_notify_adaptation_layer(struct sctp_tcb *stcb)
sctp_notify_adaptation_layer(struct sctp_tcb *stcb, int so_locked)
{
struct mbuf *m_notify;
struct sctp_adaptation_event *sai;
struct sctp_queued_to_read *control;
if ((stcb == NULL) ||
sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ADAPTATIONEVNT)) {
KASSERT(stcb != NULL, ("stcb == NULL"));
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ADAPTATIONEVNT)) {
/* event not enabled */
return;
}
@@ -3774,29 +3785,30 @@ sctp_notify_adaptation_layer(struct sctp_tcb *stcb)
control->spec_flags = M_NOTIFICATION;
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
sctp_add_to_readq(stcb->sctp_ep, stcb, control,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_HELD, so_locked);
}
/* This always must be called with the read-queue LOCKED in the INP */
static void
sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error,
uint32_t val, int so_locked)
struct sctp_queued_to_read *aborted_control,
int so_locked)
{
struct mbuf *m_notify;
struct sctp_pdapi_event *pdapi;
struct sctp_queued_to_read *control;
struct sockbuf *sb;
if ((stcb == NULL) ||
sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_PDAPIEVNT)) {
KASSERT(aborted_control != NULL, ("aborted_control is NULL"));
KASSERT(stcb != NULL, ("stcb == NULL"));
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_PDAPIEVNT)) {
/* event not enabled */
return;
}
if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ) {
return;
}
m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_pdapi_event), 0, M_NOWAIT, 1, MT_DATA);
if (m_notify == NULL)
@@ -3809,15 +3821,15 @@ sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error,
pdapi->pdapi_flags = 0;
pdapi->pdapi_length = sizeof(struct sctp_pdapi_event);
pdapi->pdapi_indication = error;
pdapi->pdapi_stream = (val >> 16);
pdapi->pdapi_seq = (val & 0x0000ffff);
pdapi->pdapi_stream = aborted_control->sinfo_stream;
pdapi->pdapi_seq = (uint16_t)aborted_control->mid;
pdapi->pdapi_assoc_id = sctp_get_associd(stcb);
SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_pdapi_event);
SCTP_BUF_NEXT(m_notify) = NULL;
control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
0, 0, stcb->asoc.context, 0, 0, 0,
m_notify);
0, 0, stcb->asoc.context, 0, 0, 0,
m_notify);
if (control == NULL) {
/* no memory */
sctp_m_freem(m_notify);
@@ -3836,12 +3848,7 @@ sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error,
sctp_sblog(sb, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0);
}
control->end_added = 1;
if (stcb->asoc.control_pdapi)
TAILQ_INSERT_AFTER(&stcb->sctp_ep->read_queue, stcb->asoc.control_pdapi, control, next);
else {
/* we really should not see this case */
TAILQ_INSERT_TAIL(&stcb->sctp_ep->read_queue, control, next);
}
TAILQ_INSERT_AFTER(&stcb->sctp_ep->read_queue, aborted_control, control, next);
if (stcb->sctp_ep && stcb->sctp_socket) {
/* This should always be the case */
#if defined(__APPLE__) && !defined(__Userspace__)
@@ -3870,12 +3877,16 @@ sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error,
}
static void
sctp_notify_shutdown_event(struct sctp_tcb *stcb)
sctp_notify_shutdown_event(struct sctp_tcb *stcb, int so_locked)
{
struct mbuf *m_notify;
struct sctp_shutdown_event *sse;
struct sctp_queued_to_read *control;
KASSERT(stcb != NULL, ("stcb == NULL"));
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
/*
* For TCP model AND UDP connected sockets we will send an error up
* when an SHUTDOWN completes
@@ -3902,6 +3913,7 @@ sctp_notify_shutdown_event(struct sctp_tcb *stcb)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
}
if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT)) {
/* event not enabled */
return;
@@ -3934,21 +3946,23 @@ sctp_notify_shutdown_event(struct sctp_tcb *stcb)
control->spec_flags = M_NOTIFICATION;
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
sctp_add_to_readq(stcb->sctp_ep, stcb, control,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_HELD, so_locked);
}
static void
sctp_notify_sender_dry_event(struct sctp_tcb *stcb,
int so_locked)
sctp_notify_sender_dry_event(struct sctp_tcb *stcb, int so_locked)
{
struct mbuf *m_notify;
struct sctp_sender_dry_event *event;
struct sctp_queued_to_read *control;
if ((stcb == NULL) ||
sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_DRYEVNT)) {
KASSERT(stcb != NULL, ("stcb == NULL"));
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_DRYEVNT)) {
/* event not enabled */
return;
}
@@ -3983,23 +3997,21 @@ sctp_notify_sender_dry_event(struct sctp_tcb *stcb,
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb, control,
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, so_locked);
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_HELD, so_locked);
}
void
sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, uint16_t numberout, int flag)
static void
sctp_notify_stream_reset_add(struct sctp_tcb *stcb, int flag, int so_locked)
{
struct mbuf *m_notify;
struct sctp_queued_to_read *control;
struct sctp_stream_change_event *stradd;
if ((stcb == NULL) ||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
(stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
/* If the socket is gone we are out of here. */
return;
}
KASSERT(stcb != NULL, ("stcb == NULL"));
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_CHANGEEVNT)) {
/* event not enabled */
return;
@@ -4022,8 +4034,8 @@ sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, uint16_t
stradd->strchange_flags = flag;
stradd->strchange_length = sizeof(struct sctp_stream_change_event);
stradd->strchange_assoc_id = sctp_get_associd(stcb);
stradd->strchange_instrms = numberin;
stradd->strchange_outstrms = numberout;
stradd->strchange_instrms = stcb->asoc.streamincnt;
stradd->strchange_outstrms = stcb->asoc.streamoutcnt;
SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_stream_change_event);
SCTP_BUF_NEXT(m_notify) = NULL;
if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
@@ -4044,25 +4056,22 @@ sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, uint16_t
control->spec_flags = M_NOTIFICATION;
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
sctp_add_to_readq(stcb->sctp_ep, stcb, control,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_HELD, so_locked);
}
void
sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, uint32_t sending_tsn, uint32_t recv_tsn, int flag)
static void
sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, int flag, int so_locked)
{
struct mbuf *m_notify;
struct sctp_queued_to_read *control;
struct sctp_assoc_reset_event *strasoc;
if ((stcb == NULL) ||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
(stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
/* If the socket is gone we are out of here. */
return;
}
KASSERT(stcb != NULL, ("stcb == NULL"));
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ASSOC_RESETEVNT)) {
/* event not enabled */
return;
@@ -4079,8 +4088,8 @@ sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, uint32_t sending_tsn, uint32
strasoc->assocreset_flags = flag;
strasoc->assocreset_length = sizeof(struct sctp_assoc_reset_event);
strasoc->assocreset_assoc_id= sctp_get_associd(stcb);
strasoc->assocreset_local_tsn = sending_tsn;
strasoc->assocreset_remote_tsn = recv_tsn;
strasoc->assocreset_local_tsn = stcb->asoc.sending_seq;
strasoc->assocreset_remote_tsn = stcb->asoc.mapping_array_base_tsn + 1;
SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_assoc_reset_event);
SCTP_BUF_NEXT(m_notify) = NULL;
if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
@@ -4101,22 +4110,25 @@ sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, uint32_t sending_tsn, uint32
control->spec_flags = M_NOTIFICATION;
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
sctp_add_to_readq(stcb->sctp_ep, stcb, control,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_HELD, so_locked);
}
static void
sctp_notify_stream_reset(struct sctp_tcb *stcb,
int number_entries, uint16_t * list, int flag)
int number_entries, uint16_t *list, int flag, int so_locked)
{
struct mbuf *m_notify;
struct sctp_queued_to_read *control;
struct sctp_stream_reset_event *strreset;
int len;
if ((stcb == NULL) ||
(sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT))) {
KASSERT(stcb != NULL, ("stcb == NULL"));
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT)) {
/* event not enabled */
return;
}
@@ -4165,13 +4177,14 @@ sctp_notify_stream_reset(struct sctp_tcb *stcb,
control->spec_flags = M_NOTIFICATION;
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
sctp_add_to_readq(stcb->sctp_ep, stcb, control,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_HELD, so_locked);
}
static void
sctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error, struct sctp_error_chunk *chunk)
sctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error,
struct sctp_error_chunk *chunk, int so_locked)
{
struct mbuf *m_notify;
struct sctp_remote_error *sre;
@@ -4179,10 +4192,14 @@ sctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error, struct sctp_erro
unsigned int notif_len;
uint16_t chunk_len;
if ((stcb == NULL) ||
sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVPEERERR)) {
KASSERT(stcb != NULL, ("stcb == NULL"));
SCTP_TCB_LOCK_ASSERT(stcb);
SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVPEERERR)) {
return;
}
if (chunk != NULL) {
chunk_len = ntohs(chunk->ch.chunk_length);
/*
@@ -4226,10 +4243,9 @@ sctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error, struct sctp_erro
control->spec_flags = M_NOTIFICATION;
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
sctp_add_to_readq(stcb->sctp_ep, stcb, control,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
SCTP_READ_LOCK_HELD, so_locked);
} else {
sctp_m_freem(m_notify);
}
@@ -4237,29 +4253,25 @@ sctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error, struct sctp_erro
void
sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
uint32_t error, void *data, int so_locked)
uint32_t error, void *data, int so_locked)
{
if ((stcb == NULL) ||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
(stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
/* If the socket is gone we are out of here */
return;
}
#if (defined(__FreeBSD__) || defined(_WIN32)) && !defined(__Userspace__)
if (stcb->sctp_socket->so_rcv.sb_state & SBS_CANTRCVMORE) {
#else
if (stcb->sctp_socket->so_state & SS_CANTRCVMORE) {
#endif
return;
}
struct sctp_inpcb *inp;
struct sctp_nets *net;
KASSERT(stcb != NULL, ("stcb == NULL"));
SCTP_TCB_LOCK_ASSERT(stcb);
inp = stcb->sctp_ep;
#if defined(__APPLE__) && !defined(__Userspace__)
if (so_locked) {
sctp_lock_assert(SCTP_INP_SO(stcb->sctp_ep));
sctp_lock_assert(SCTP_INP_SO(inp));
} else {
sctp_unlock_assert(SCTP_INP_SO(stcb->sctp_ep));
sctp_unlock_assert(SCTP_INP_SO(inp));
}
#endif
if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
return;
}
if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
(SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
if ((notification == SCTP_NOTIFY_INTERFACE_DOWN) ||
@@ -4269,6 +4281,18 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
return;
}
}
if (notification != SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION) {
SCTP_INP_READ_LOCK(inp);
}
SCTP_INP_READ_LOCK_ASSERT(inp);
if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ)) {
SCTP_INP_READ_UNLOCK(inp);
return;
}
switch (notification) {
case SCTP_NOTIFY_ASSOC_UP:
if (stcb->asoc.assoc_up_sent == 0) {
@@ -4276,17 +4300,16 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
stcb->asoc.assoc_up_sent = 1;
}
if (stcb->asoc.adaptation_needed && (stcb->asoc.adaptation_sent == 0)) {
sctp_notify_adaptation_layer(stcb);
sctp_notify_adaptation_layer(stcb, so_locked);
}
if (stcb->asoc.auth_supported == 0) {
sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0,
NULL, so_locked);
sctp_notify_authentication(stcb, SCTP_AUTH_NO_AUTH, 0, so_locked);
}
break;
case SCTP_NOTIFY_ASSOC_DOWN:
sctp_notify_assoc_change(SCTP_SHUTDOWN_COMP, stcb, error, NULL, false, false, so_locked);
#if defined(__Userspace__)
if (stcb->sctp_ep->recv_callback) {
if (inp->recv_callback) {
if (stcb->sctp_socket) {
union sctp_sockstore addr;
struct sctp_rcvinfo rcv;
@@ -4295,7 +4318,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
memset(&rcv, 0, sizeof(struct sctp_rcvinfo));
atomic_add_int(&stcb->asoc.refcnt, 1);
SCTP_TCB_UNLOCK(stcb);
stcb->sctp_ep->recv_callback(stcb->sctp_socket, addr, NULL, 0, rcv, 0, stcb->sctp_ep->ulp_info);
inp->recv_callback(stcb->sctp_socket, addr, NULL, 0, rcv, 0, inp->ulp_info);
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
}
@@ -4303,32 +4326,20 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
#endif
break;
case SCTP_NOTIFY_INTERFACE_DOWN:
{
struct sctp_nets *net;
net = (struct sctp_nets *)data;
sctp_notify_peer_addr_change(stcb, SCTP_ADDR_UNREACHABLE,
(struct sockaddr *)&net->ro._l_addr, error, so_locked);
break;
}
net = (struct sctp_nets *)data;
sctp_notify_peer_addr_change(stcb, SCTP_ADDR_UNREACHABLE,
&net->ro._l_addr.sa, error, so_locked);
break;
case SCTP_NOTIFY_INTERFACE_UP:
{
struct sctp_nets *net;
net = (struct sctp_nets *)data;
sctp_notify_peer_addr_change(stcb, SCTP_ADDR_AVAILABLE,
(struct sockaddr *)&net->ro._l_addr, error, so_locked);
break;
}
net = (struct sctp_nets *)data;
sctp_notify_peer_addr_change(stcb, SCTP_ADDR_AVAILABLE,
&net->ro._l_addr.sa, error, so_locked);
break;
case SCTP_NOTIFY_INTERFACE_CONFIRMED:
{
struct sctp_nets *net;
net = (struct sctp_nets *)data;
sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED,
(struct sockaddr *)&net->ro._l_addr, error, so_locked);
break;
}
net = (struct sctp_nets *)data;
sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED,
&net->ro._l_addr.sa, error, so_locked);
break;
case SCTP_NOTIFY_SPECIAL_SP_FAIL:
sctp_notify_send_failed2(stcb, error,
(struct sctp_stream_queue_pending *)data, so_locked);
@@ -4342,13 +4353,10 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
(struct sctp_tmit_chunk *)data, so_locked);
break;
case SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION:
{
uint32_t val;
val = *((uint32_t *)data);
sctp_notify_partial_delivery_indication(stcb, error, val, so_locked);
sctp_notify_partial_delivery_indication(stcb, error,
(struct sctp_queued_to_read *)data,
so_locked);
break;
}
case SCTP_NOTIFY_ASSOC_LOC_ABORTED:
if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
(SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
@@ -4376,35 +4384,40 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
case SCTP_NOTIFY_ASSOC_RESTART:
sctp_notify_assoc_change(SCTP_RESTART, stcb, error, NULL, false, false, so_locked);
if (stcb->asoc.auth_supported == 0) {
sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0,
NULL, so_locked);
sctp_notify_authentication(stcb, SCTP_AUTH_NO_AUTH, 0, so_locked);
}
break;
case SCTP_NOTIFY_STR_RESET_SEND:
sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), SCTP_STREAM_RESET_OUTGOING_SSN);
sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), SCTP_STREAM_RESET_OUTGOING_SSN, so_locked);
break;
case SCTP_NOTIFY_STR_RESET_RECV:
sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), SCTP_STREAM_RESET_INCOMING);
sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), SCTP_STREAM_RESET_INCOMING, so_locked);
break;
case SCTP_NOTIFY_STR_RESET_FAILED_OUT:
sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
(SCTP_STREAM_RESET_OUTGOING_SSN|SCTP_STREAM_RESET_FAILED));
(SCTP_STREAM_RESET_OUTGOING_SSN|SCTP_STREAM_RESET_FAILED), so_locked);
break;
case SCTP_NOTIFY_STR_RESET_DENIED_OUT:
sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
(SCTP_STREAM_RESET_OUTGOING_SSN|SCTP_STREAM_RESET_DENIED));
(SCTP_STREAM_RESET_OUTGOING_SSN|SCTP_STREAM_RESET_DENIED), so_locked);
break;
case SCTP_NOTIFY_STR_RESET_FAILED_IN:
sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
(SCTP_STREAM_RESET_INCOMING|SCTP_STREAM_RESET_FAILED));
(SCTP_STREAM_RESET_INCOMING|SCTP_STREAM_RESET_FAILED), so_locked);
break;
case SCTP_NOTIFY_STR_RESET_DENIED_IN:
sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
(SCTP_STREAM_RESET_INCOMING|SCTP_STREAM_RESET_DENIED));
(SCTP_STREAM_RESET_INCOMING|SCTP_STREAM_RESET_DENIED), so_locked);
break;
case SCTP_NOTIFY_STR_RESET_ADD:
sctp_notify_stream_reset_add(stcb, error, so_locked);
break;
case SCTP_NOTIFY_STR_RESET_TSN:
sctp_notify_stream_reset_tsn(stcb, error, so_locked);
break;
case SCTP_NOTIFY_ASCONF_ADD_IP:
sctp_notify_peer_addr_change(stcb, SCTP_ADDR_ADDED, data,
error, so_locked);
error, so_locked);
break;
case SCTP_NOTIFY_ASCONF_DELETE_IP:
sctp_notify_peer_addr_change(stcb, SCTP_ADDR_REMOVED, data,
@@ -4415,34 +4428,34 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
error, so_locked);
break;
case SCTP_NOTIFY_PEER_SHUTDOWN:
sctp_notify_shutdown_event(stcb);
sctp_notify_shutdown_event(stcb, so_locked);
break;
case SCTP_NOTIFY_AUTH_NEW_KEY:
sctp_notify_authentication(stcb, SCTP_AUTH_NEW_KEY, error,
(uint16_t)(uintptr_t)data,
so_locked);
sctp_notify_authentication(stcb, SCTP_AUTH_NEW_KEY,
*(uint16_t *)data, so_locked);
break;
case SCTP_NOTIFY_AUTH_FREE_KEY:
sctp_notify_authentication(stcb, SCTP_AUTH_FREE_KEY, error,
(uint16_t)(uintptr_t)data,
so_locked);
sctp_notify_authentication(stcb, SCTP_AUTH_FREE_KEY,
*(uint16_t *)data, so_locked);
break;
case SCTP_NOTIFY_NO_PEER_AUTH:
sctp_notify_authentication(stcb, SCTP_AUTH_NO_AUTH, error,
(uint16_t)(uintptr_t)data,
so_locked);
sctp_notify_authentication(stcb, SCTP_AUTH_NO_AUTH,
0, so_locked);
break;
case SCTP_NOTIFY_SENDER_DRY:
sctp_notify_sender_dry_event(stcb, so_locked);
break;
case SCTP_NOTIFY_REMOTE_ERROR:
sctp_notify_remote_error(stcb, error, data);
sctp_notify_remote_error(stcb, error, data, so_locked);
break;
default:
SCTPDBG(SCTP_DEBUG_UTIL1, "%s: unknown notification %xh (%u)\n",
__func__, notification, notification);
__func__, notification, notification);
break;
} /* end switch */
}
if (notification != SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION) {
SCTP_INP_READ_UNLOCK(inp);
}
}
void
@@ -5543,11 +5556,7 @@ sctp_free_bufspace(struct sctp_tcb *stcb, struct sctp_association *asoc,
if ((stcb->sctp_socket != NULL) &&
(((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) ||
((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)))) {
if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) {
atomic_subtract_int(&((stcb)->sctp_socket->so_snd.sb_cc), tp1->book_size);
} else {
stcb->sctp_socket->so_snd.sb_cc = 0;
}
SCTP_SB_DECR(&stcb->sctp_socket->so_snd, tp1->book_size);
}
}
@@ -6262,7 +6271,9 @@ sctp_sorecvmsg(struct socket *so,
}
so->so_state &= ~(SS_ISCONNECTING |
SS_ISDISCONNECTING |
#if !(defined(__FreeBSD__) && !defined(__Userspace__))
SS_ISCONFIRMING |
#endif
SS_ISCONNECTED);
if (error == 0) {
if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) == 0) {
@@ -6757,7 +6768,7 @@ sctp_sorecvmsg(struct socket *so,
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
sctp_sblog(&so->so_rcv, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBFREE, (int)cp_len);
}
atomic_subtract_int(&so->so_rcv.sb_cc, (int)cp_len);
SCTP_SB_DECR(&so->so_rcv, cp_len);
if ((control->do_not_ref_stcb == 0) &&
stcb) {
atomic_subtract_int(&stcb->asoc.sb_cc, (int)cp_len);
@@ -7480,8 +7491,7 @@ sctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr,
case AF_INET:
incr = sizeof(struct sockaddr_in);
sin = (struct sockaddr_in *)sa;
if ((sin->sin_addr.s_addr == INADDR_ANY) ||
(sin->sin_addr.s_addr == INADDR_BROADCAST) ||
if (in_broadcast(sin->sin_addr) ||
IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+2 -17
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_UTIL_H_
#define _NETINET_SCTP_UTIL_H_
@@ -87,12 +82,6 @@ int sctp_init_asoc(struct sctp_inpcb *, struct sctp_tcb *, uint32_t, uint32_t, u
void sctp_fill_random_store(struct sctp_pcb *);
void
sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin,
uint16_t numberout, int flag);
void
sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, uint32_t sending_tsn, uint32_t recv_tsn, int flag);
/*
* NOTE: sctp_timer_start() will increment the reference count of any relevant
* structure the timer is referencing, in order to prevent a race condition
@@ -288,11 +277,7 @@ do { \
} \
if (stcb->sctp_socket && ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \
if (stcb->sctp_socket->so_snd.sb_cc >= sp->length) { \
atomic_subtract_int(&stcb->sctp_socket->so_snd.sb_cc,sp->length); \
} else { \
stcb->sctp_socket->so_snd.sb_cc = 0; \
} \
SCTP_SB_DECR(&stcb->sctp_socket->so_snd, sp->length); \
} \
} \
} while (0)
@@ -303,7 +288,7 @@ do { \
if ((stcb->sctp_socket != NULL) && \
((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \
atomic_add_int(&stcb->sctp_socket->so_snd.sb_cc,sz); \
SCTP_SB_INCR(&stcb->sctp_socket->so_snd, sz); \
} \
} while (0)
+11 -94
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
#ifdef INET6
#if defined(__FreeBSD__) && !defined(__Userspace__)
@@ -653,7 +648,7 @@ sctp6_ctlinput(int cmd, struct sockaddr *pktdst, void *d)
#endif
/*
* this routine can probably be collasped into the one in sctp_userreq.c
* this routine can probably be collapsed into the one in sctp_userreq.c
* since they do the same thing and now we lookup with a sockaddr
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
@@ -670,11 +665,9 @@ sctp6_getcred(SYSCTL_HANDLER_ARGS)
vrf_id = SCTP_DEFAULT_VRFID;
#if defined(__FreeBSD__) && !defined(__Userspace__)
if (req->newptr == NULL)
return (EINVAL);
error = priv_check(req->td, PRIV_NETINET_GETCRED);
#else
error = suser(req->p);
#endif
if (error)
return (error);
@@ -732,73 +725,6 @@ SYSCTL_PROC(_net_inet6_sctp6, OID_AUTO, getcred,
"Get the ucred of a SCTP6 connection");
#endif
/* This is the same as the sctp_abort() could be made common */
#if defined(__Userspace__)
int
#elif defined(__FreeBSD__) || defined(_WIN32)
static void
#else
static int
#endif
sctp6_abort(struct socket *so)
{
#if defined(__FreeBSD__) && !defined(__Userspace__)
struct epoch_tracker et;
#endif
struct sctp_inpcb *inp;
uint32_t flags;
inp = (struct sctp_inpcb *)so->so_pcb;
if (inp == NULL) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
#if (defined(__FreeBSD__) || defined(_WIN32)) && !defined(__Userspace__)
return;
#else
return (EINVAL);
#endif
}
#if defined(__FreeBSD__) && !defined(__Userspace__)
NET_EPOCH_ENTER(et);
#endif
sctp_must_try_again:
flags = inp->sctp_flags;
#ifdef SCTP_LOG_CLOSING
sctp_log_closing(inp, NULL, 17);
#endif
if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
(atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) {
#ifdef SCTP_LOG_CLOSING
sctp_log_closing(inp, NULL, 16);
#endif
sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
SOCK_LOCK(so);
SCTP_SB_CLEAR(so->so_snd);
/* same for the rcv ones, they are only
* here for the accounting/select.
*/
SCTP_SB_CLEAR(so->so_rcv);
#if defined(__APPLE__) && !defined(__Userspace__)
so->so_usecount--;
#else
/* Now null out the reference, we are completely detached. */
so->so_pcb = NULL;
#endif
SOCK_UNLOCK(so);
} else {
flags = inp->sctp_flags;
if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
goto sctp_must_try_again;
}
}
#if defined(__FreeBSD__) && !defined(__Userspace__)
NET_EPOCH_EXIT(et);
return;
#else
return (0);
#endif
}
#if defined(__Userspace__)
int
sctp6_attach(struct socket *so, int proto SCTP_UNUSED, uint32_t vrf_id)
@@ -1010,15 +936,6 @@ sctp6_detach(struct socket *so)
#endif
#if !defined(__Userspace__)
static
#endif
int
sctp6_disconnect(struct socket *so)
{
return (sctp_disconnect(so));
}
int
#if defined(__FreeBSD__) && !defined(__Userspace__)
sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
@@ -1185,8 +1102,8 @@ connected_type:
* note with the current version this code will only be used
* by OpenBSD, NetBSD and FreeBSD have methods for
* re-defining sosend() to use sctp_sosend(). One can
* optionaly switch back to this code (by changing back the
* defininitions but this is not advisable.
* optionally switch back to this code (by changing back the
* definitions but this is not advisable.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
struct epoch_tracker et;
@@ -1742,7 +1659,7 @@ sctp6_getpeeraddr(struct socket *so, struct mbuf *nam)
#define SCTP6_PROTOSW \
.pr_protocol = IPPROTO_SCTP, \
.pr_ctloutput = sctp_ctloutput, \
.pr_abort = sctp6_abort, \
.pr_abort = sctp_abort, \
.pr_accept = sctp_accept, \
.pr_attach = sctp6_attach, \
.pr_bind = sctp6_bind, \
@@ -1752,7 +1669,7 @@ sctp6_getpeeraddr(struct socket *so, struct mbuf *nam)
.pr_detach = sctp6_close, \
.pr_sopoll = sopoll_generic, \
.pr_flush = sctp_flush, \
.pr_disconnect = sctp6_disconnect, \
.pr_disconnect = sctp_disconnect, \
.pr_listen = sctp_listen, \
.pr_peeraddr = sctp6_getpeeraddr, \
.pr_send = sctp6_send, \
@@ -1775,7 +1692,7 @@ struct protosw sctp6_stream_protosw = {
#else
struct pr_usrreqs sctp6_usrreqs = {
#if defined(__APPLE__) && !defined(__Userspace__)
.pru_abort = sctp6_abort,
.pru_abort = sctp_abort,
.pru_accept = sctp_accept,
.pru_attach = sctp6_attach,
.pru_bind = sctp6_bind,
@@ -1783,7 +1700,7 @@ struct pr_usrreqs sctp6_usrreqs = {
.pru_connect2 = pru_connect2_notsupp,
.pru_control = in6_control,
.pru_detach = sctp6_detach,
.pru_disconnect = sctp6_disconnect,
.pru_disconnect = sctp_disconnect,
.pru_listen = sctp_listen,
.pru_peeraddr = sctp6_getpeeraddr,
.pru_rcvd = NULL,
@@ -1796,7 +1713,7 @@ struct pr_usrreqs sctp6_usrreqs = {
.pru_soreceive = sctp_soreceive,
.pru_sopoll = sopoll
#elif defined(_WIN32) && !defined(__Userspace__)
sctp6_abort,
sctp_abort,
sctp_accept,
sctp6_attach,
sctp6_bind,
@@ -1804,7 +1721,7 @@ struct pr_usrreqs sctp6_usrreqs = {
pru_connect2_notsupp,
NULL,
NULL,
sctp6_disconnect,
sctp_disconnect,
sctp_listen,
sctp6_getpeeraddr,
NULL,
-5
View File
@@ -32,11 +32,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET6_SCTP6_VAR_H_
#define _NETINET6_SCTP6_VAR_H_
+1 -3
View File
@@ -54,9 +54,7 @@
#define atomic_add_int(addr, val) OSAtomicAdd32Barrier(val, (int32_t *)addr)
#define atomic_fetchadd_int(addr, val) OSAtomicAdd32Barrier(val, (int32_t *)addr)
#define atomic_subtract_int(addr, val) OSAtomicAdd32Barrier(-val, (int32_t *)addr)
/* TenFourFox */
#define atomic_cmpset_int(dst, exp, src) OSAtomicCompareAndSwap32Barrier(exp, src, (int *)dst)
//#define atomic_cmpset_int(dst, exp, src) OSAtomicCompareAndSwapIntBarrier(exp, src, (int *)dst)
#define atomic_cmpset_int(dst, exp, src) OSAtomicCompareAndSwapIntBarrier(exp, src, (int *)dst)
#define SCTP_DECREMENT_AND_CHECK_REFCOUNT(addr) (atomic_fetchadd_int(addr, -1) == 0)
#endif
+2 -17
View File
@@ -132,23 +132,8 @@ init_random(void)
void
read_random(void *buf, size_t size)
{
/* TenFourFox: no arc4random_buf in Tiger.
This isn't used much, so substitute a secure, if suboptimal, alternate. */
#if(0)
arc4random_buf(buf, size);
return;
#else
size_t i;
char *c = (char *)buf;
for(i=0; i<size; i++) {
/* arc4random returns int, not char. Ass-U-ME that entropy
is evenly distributed throughout the return value, so just
take the lower 8 bits in case size is not a integral number
of ints. */
c[i] = (arc4random() & 0xff);
}
return;
#endif
}
void
@@ -187,7 +172,7 @@ finish_random(void)
{
return;
}
#elif (defined(__ANDROID__) && (__ANDROID_API__ < 28)) || defined(__QNX__) || defined(__EMSCRIPTEN__)
#elif (defined(__ANDROID__) && (__ANDROID_API__ < 28)) || defined(__EMSCRIPTEN__)
#include <fcntl.h>
static int fd = -1;
@@ -382,7 +367,7 @@ read_random(void *buf, size_t size)
position = 0;
while (position < size) {
if (nacl_secure_random((char *)buf + position, size - position, &n) == 0)
if (nacl_secure_random((char *)buf + position, size - position, &n) == 0) {
position += n;
}
}
+4
View File
@@ -35,6 +35,10 @@
*
*/
#if defined(_WIN32) && defined(__MINGW32__)
#include <minmax.h>
#endif
#include <stdio.h>
#include <string.h>
/* #include <sys/param.h> This defines MSIZE 256 */
+2 -3
View File
@@ -56,7 +56,7 @@
#endif
#endif
#endif
#if defined(HAVE_NET_ROUTE_H)
#if defined(HAVE_NET_ROUTE_H) || defined(__FreeBSD__) || defined(__DragonFly__)
# include <net/route.h>
#elif defined(__APPLE__)
/* Apple SDKs for iOS, tvOS, watchOS, etc. don't ship this header */
@@ -135,8 +135,7 @@ sctp_handle_ifamsg(unsigned char type, unsigned short index, struct sockaddr *sa
1);
} else {
sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, ifa->ifa_addr,
if_nametoindex(ifa->ifa_name),
ifa->ifa_name);
NULL, if_nametoindex(ifa->ifa_name));
}
freeifaddrs(ifas);
}
+7 -18
View File
@@ -60,9 +60,12 @@
#endif
userland_mutex_t accept_mtx;
userland_cond_t accept_cond;
#ifdef _WIN32
#if defined(_WIN32)
#include <time.h>
#include <sys/timeb.h>
#if !defined(_MSC_VER)
#include <minmax.h>
#endif
#endif
MALLOC_DEFINE(M_PCB, "sctp_pcb", "sctp pcb");
@@ -308,22 +311,7 @@ sofree(struct socket *so)
void
soabort(struct socket *so)
{
#if defined(INET6)
struct sctp_inpcb *inp;
#endif
#if defined(INET6)
inp = (struct sctp_inpcb *)so->so_pcb;
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
sctp6_abort(so);
} else {
#if defined(INET)
sctp_abort(so);
#endif
}
#elif defined(INET)
sctp_abort(so);
#endif
ACCEPT_LOCK();
SOCK_LOCK(so);
sofree(so);
@@ -3169,8 +3157,7 @@ usrsctp_deregister_address(void *addr)
sconn.sconn_addr = addr;
sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID,
(struct sockaddr *)&sconn,
0xffffffff,
"conn");
NULL, 0xffffffff);
}
#define PREAMBLE_FORMAT "\n%c %02d:%02d:%02d.%06ld "
@@ -3494,6 +3481,7 @@ USRSCTP_SYSCTL_SET_DEF(sctp_steady_step, SCTPCTL_RTTVAR_STEADYS)
USRSCTP_SYSCTL_SET_DEF(sctp_use_dccc_ecn, SCTPCTL_RTTVAR_DCCCECN)
USRSCTP_SYSCTL_SET_DEF(sctp_buffer_splitting, SCTPCTL_BUFFER_SPLITTING)
USRSCTP_SYSCTL_SET_DEF(sctp_initial_cwnd, SCTPCTL_INITIAL_CWND)
USRSCTP_SYSCTL_SET_DEF(sctp_ootb_with_zero_cksum, SCTPCTL_OOTB_WITH_ZERO_CKSUM)
#ifdef SCTP_DEBUG
USRSCTP_SYSCTL_SET_DEF(sctp_debug_on, SCTPCTL_DEBUG)
#endif
@@ -3576,6 +3564,7 @@ USRSCTP_SYSCTL_GET_DEF(sctp_steady_step)
USRSCTP_SYSCTL_GET_DEF(sctp_use_dccc_ecn)
USRSCTP_SYSCTL_GET_DEF(sctp_buffer_splitting)
USRSCTP_SYSCTL_GET_DEF(sctp_initial_cwnd)
USRSCTP_SYSCTL_GET_DEF(sctp_ootb_with_zero_cksum)
#ifdef SCTP_DEBUG
USRSCTP_SYSCTL_GET_DEF(sctp_debug_on)
#endif
+11 -1
View File
@@ -404,15 +404,25 @@ void sofree(struct socket *so);
#define soref(so) do { \
SOCK_LOCK_ASSERT(so); \
++(so)->so_count; \
SCTPDBG(SCTP_DEBUG_USR, "soref(%p) -> %d, %s:%s:%d\n", \
(so), (so)->so_count, \
__func__, __FILE__, __LINE__) \
} while (0)
#define sorele(so) do { \
ACCEPT_LOCK_ASSERT(); \
SOCK_LOCK_ASSERT(so); \
KASSERT((so)->so_count > 0, ("sorele")); \
if (--(so)->so_count == 0) \
if (--(so)->so_count == 0) { \
SCTPDBG(SCTP_DEBUG_USR, "sorele(%p) -> %d, %s:%s:%d\n", \
(so), (so)->so_count, \
__func__, __FILE__, __LINE__) \
sofree(so); \
} \
else { \
SCTPDBG(SCTP_DEBUG_USR, "sorele(%p) -> %d, %s:%s:%d\n", \
(so), (so)->so_count, \
__func__, __FILE__, __LINE__) \
SOCK_UNLOCK(so); \
ACCEPT_UNLOCK(); \
} \
+5
View File
@@ -560,6 +560,7 @@ struct sctp_event_subscribe {
#define SCTP_NRSACK_SUPPORTED 0x00000030
#define SCTP_PKTDROP_SUPPORTED 0x00000031
#define SCTP_MAX_CWND 0x00000032
#define SCTP_ACCEPT_ZERO_CHECKSUM 0x00000033
#define SCTP_ENABLE_STREAM_RESET 0x00000900 /* struct sctp_assoc_value */
@@ -767,6 +768,10 @@ struct sctp_get_nonce_values {
uint32_t gn_local_tag;
};
/* Values for SCTP_ACCEPT_ZERO_CHECKSUM */
#define SCTP_EDMID_NONE 0
#define SCTP_EDMID_LOWER_LAYER_DTLS 1
/*
* Main SCTP chunk types