mirror of
https://github.com/roytam1/UXP.git
synced 2026-05-26 14:54:25 +00:00
Merge remote-tracking branch 'origin/tracking' into custom
This commit is contained in:
@@ -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.")
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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_
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*-
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
|
||||
@@ -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_
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_sctp.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
@@ -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_
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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_
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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_
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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__
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)");
|
||||
|
||||
@@ -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_
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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_
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, \
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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_
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(); \
|
||||
} \
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user