diff --git a/dom/bindings/Errors.msg b/dom/bindings/Errors.msg index db689e5bc0..a2661597b3 100644 --- a/dom/bindings/Errors.msg +++ b/dom/bindings/Errors.msg @@ -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.") diff --git a/dom/html/HTMLFormElement.cpp b/dom/html/HTMLFormElement.cpp index f44077c54e..a5f2442489 100644 --- a/dom/html/HTMLFormElement.cpp +++ b/dom/html/HTMLFormElement.cpp @@ -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 fc = do_QueryObject(aSubmitter); + + // 1.1. If submitter is not a submit button, then throw a TypeError. + if (!fc || !fc->IsSubmitControl()) { + aRv.ThrowTypeError(); + 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 presShell = GetComposedDoc()->GetShell(); + if (MOZ_LIKELY(presShell)) { + presShell->HandleDOMEventWithTarget(this, &event, &status); + } +} + NS_IMETHODIMP HTMLFormElement::Reset() { diff --git a/dom/html/HTMLFormElement.h b/dom/html/HTMLFormElement.h index b0d355d5a7..e752fd5a82 100644 --- a/dom/html/HTMLFormElement.h +++ b/dom/html/HTMLFormElement.h @@ -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() diff --git a/dom/webidl/HTMLFormElement.webidl b/dom/webidl/HTMLFormElement.webidl index 064fe9fade..a1407a718e 100644 --- a/dom/webidl/HTMLFormElement.webidl +++ b/dom/webidl/HTMLFormElement.webidl @@ -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(); diff --git a/gfx/cairo/cairo/src/cairoint.h b/gfx/cairo/cairo/src/cairoint.h index f5dc0da817..e9d3b3ce55 100644 --- a/gfx/cairo/cairo/src/cairoint.h +++ b/gfx/cairo/cairo/src/cairoint.h @@ -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); diff --git a/gfx/cairo/cairo/src/moz.build b/gfx/cairo/cairo/src/moz.build index d2536e10f4..e39e638836 100644 --- a/gfx/cairo/cairo/src/moz.build +++ b/gfx/cairo/cairo/src/moz.build @@ -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', diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 85546f994d..9dd2afc55c 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -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); diff --git a/netwerk/sctp/sctp_update.log b/netwerk/sctp/sctp_update.log index 92f7884f20..1d7e8b4800 100644 --- a/netwerk/sctp/sctp_update.log +++ b/netwerk/sctp/sctp_update.log @@ -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 diff --git a/netwerk/sctp/src/README.sctp b/netwerk/sctp/src/README.sctp index dd73ec45d6..35f5811171 100644 --- a/netwerk/sctp/src/README.sctp +++ b/netwerk/sctp/src/README.sctp @@ -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: diff --git a/netwerk/sctp/src/netinet/sctp.h b/netwerk/sctp/src/netinet/sctp.h index 203f6f1f6a..cef07e0e59 100644 --- a/netwerk/sctp/src/netinet/sctp.h +++ b/netwerk/sctp/src/netinet/sctp.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__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 diff --git a/netwerk/sctp/src/netinet/sctp_asconf.c b/netwerk/sctp/src/netinet/sctp_asconf.c index 6c5d296893..e861747f61 100644 --- a/netwerk/sctp/src/netinet/sctp_asconf.c +++ b/netwerk/sctp/src/netinet/sctp_asconf.c @@ -40,11 +40,6 @@ #endif #endif -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #include #include #include @@ -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); } } diff --git a/netwerk/sctp/src/netinet/sctp_asconf.h b/netwerk/sctp/src/netinet/sctp_asconf.h index 318b26b168..a7429aeca4 100644 --- a/netwerk/sctp/src/netinet/sctp_asconf.h +++ b/netwerk/sctp/src/netinet/sctp_asconf.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #ifndef _NETINET_SCTP_ASCONF_H_ #define _NETINET_SCTP_ASCONF_H_ diff --git a/netwerk/sctp/src/netinet/sctp_auth.c b/netwerk/sctp/src/netinet/sctp_auth.c index 39a0f5014a..6fc3807cc1 100644 --- a/netwerk/sctp/src/netinet/sctp_auth.c +++ b/netwerk/sctp/src/netinet/sctp_auth.c @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #include #include #include @@ -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); } /*- diff --git a/netwerk/sctp/src/netinet/sctp_auth.h b/netwerk/sctp/src/netinet/sctp_auth.h index 718b2f5ba9..00682ae78e 100644 --- a/netwerk/sctp/src/netinet/sctp_auth.h +++ b/netwerk/sctp/src/netinet/sctp_auth.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__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, diff --git a/netwerk/sctp/src/netinet/sctp_bsd_addr.c b/netwerk/sctp/src/netinet/sctp_bsd_addr.c index 0697972507..3e0df08f13 100644 --- a/netwerk/sctp/src/netinet/sctp_bsd_addr.c +++ b/netwerk/sctp/src/netinet/sctp_bsd_addr.c @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #include #include #include @@ -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 diff --git a/netwerk/sctp/src/netinet/sctp_bsd_addr.h b/netwerk/sctp/src/netinet/sctp_bsd_addr.h index bbbc933adc..5e8549eec5 100644 --- a/netwerk/sctp/src/netinet/sctp_bsd_addr.h +++ b/netwerk/sctp/src/netinet/sctp_bsd_addr.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #ifndef _NETINET_SCTP_BSD_ADDR_H_ #define _NETINET_SCTP_BSD_ADDR_H_ diff --git a/netwerk/sctp/src/netinet/sctp_callout.h b/netwerk/sctp/src/netinet/sctp_callout.h index 81fd8530d1..2a78e414fb 100644 --- a/netwerk/sctp/src/netinet/sctp_callout.h +++ b/netwerk/sctp/src/netinet/sctp_callout.h @@ -30,11 +30,6 @@ * SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #ifndef _NETINET_SCTP_CALLOUT_ #define _NETINET_SCTP_CALLOUT_ diff --git a/netwerk/sctp/src/netinet/sctp_cc_functions.c b/netwerk/sctp/src/netinet/sctp_cc_functions.c index bf2ba8ab54..77193d8f9d 100644 --- a/netwerk/sctp/src/netinet/sctp_cc_functions.c +++ b/netwerk/sctp/src/netinet/sctp_cc_functions.c @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #include #include #include @@ -54,10 +49,20 @@ __FBSDID("$FreeBSD$"); #include #endif +#if defined(_WIN32) && defined(__MINGW32__) +#include +#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; diff --git a/netwerk/sctp/src/netinet/sctp_constants.h b/netwerk/sctp/src/netinet/sctp_constants.h index ca2ed70b59..69953e9b9e 100644 --- a/netwerk/sctp/src/netinet/sctp_constants.h +++ b/netwerk/sctp/src/netinet/sctp_constants.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__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. diff --git a/netwerk/sctp/src/netinet/sctp_crc32.c b/netwerk/sctp/src/netinet/sctp_crc32.c index 51b4e49d2e..0370fb1381 100644 --- a/netwerk/sctp/src/netinet/sctp_crc32.c +++ b/netwerk/sctp/src/netinet/sctp_crc32.c @@ -34,8 +34,6 @@ #if defined(__FreeBSD__) && !defined(__Userspace__) #include -__FBSDID("$FreeBSD$"); - #include "opt_sctp.h" #include diff --git a/netwerk/sctp/src/netinet/sctp_crc32.h b/netwerk/sctp/src/netinet/sctp_crc32.h index 18be779d62..e8315dc345 100644 --- a/netwerk/sctp/src/netinet/sctp_crc32.h +++ b/netwerk/sctp/src/netinet/sctp_crc32.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #ifndef _NETINET_SCTP_CRC32_H_ #define _NETINET_SCTP_CRC32_H_ diff --git a/netwerk/sctp/src/netinet/sctp_header.h b/netwerk/sctp/src/netinet/sctp_header.h index 64a27eccf6..7a5ab643c0 100644 --- a/netwerk/sctp/src/netinet/sctp_header.h +++ b/netwerk/sctp/src/netinet/sctp_header.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__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 diff --git a/netwerk/sctp/src/netinet/sctp_indata.c b/netwerk/sctp/src/netinet/sctp_indata.c index cc8aed3410..b94772438e 100644 --- a/netwerk/sctp/src/netinet/sctp_indata.c +++ b/netwerk/sctp/src/netinet/sctp_indata.c @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #include #if defined(__FreeBSD__) && !defined(__Userspace__) #include @@ -58,6 +53,9 @@ __FBSDID("$FreeBSD$"); #if defined(__FreeBSD__) && !defined(__Userspace__) #include #endif +#if defined(_WIN32) && defined(__MINGW32__) +#include +#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)) { diff --git a/netwerk/sctp/src/netinet/sctp_indata.h b/netwerk/sctp/src/netinet/sctp_indata.h index c9b71054d3..523d4f6d34 100644 --- a/netwerk/sctp/src/netinet/sctp_indata.h +++ b/netwerk/sctp/src/netinet/sctp_indata.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #ifndef _NETINET_SCTP_INDATA_H_ #define _NETINET_SCTP_INDATA_H_ diff --git a/netwerk/sctp/src/netinet/sctp_input.c b/netwerk/sctp/src/netinet/sctp_input.c index 651d078ab7..97561ee46e 100644 --- a/netwerk/sctp/src/netinet/sctp_input.c +++ b/netwerk/sctp/src/netinet/sctp_input.c @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #include #include #include @@ -62,6 +57,9 @@ __FBSDID("$FreeBSD$"); #if defined(__FreeBSD__) && !defined(__Userspace__) #include #endif +#if defined(_WIN32) && defined(__MINGW32__) +#include +#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 { diff --git a/netwerk/sctp/src/netinet/sctp_input.h b/netwerk/sctp/src/netinet/sctp_input.h index d2cd215761..acb2097316 100644 --- a/netwerk/sctp/src/netinet/sctp_input.h +++ b/netwerk/sctp/src/netinet/sctp_input.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #ifndef _NETINET_SCTP_INPUT_H_ #define _NETINET_SCTP_INPUT_H_ diff --git a/netwerk/sctp/src/netinet/sctp_lock_userspace.h b/netwerk/sctp/src/netinet/sctp_lock_userspace.h index f3b9b3d961..16c4a33979 100644 --- a/netwerk/sctp/src/netinet/sctp_lock_userspace.h +++ b/netwerk/sctp/src/netinet/sctp_lock_userspace.h @@ -33,11 +33,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__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) diff --git a/netwerk/sctp/src/netinet/sctp_os.h b/netwerk/sctp/src/netinet/sctp_os.h index dae612bc57..0a12db9bcb 100644 --- a/netwerk/sctp/src/netinet/sctp_os.h +++ b/netwerk/sctp/src/netinet/sctp_os.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #ifndef _NETINET_SCTP_OS_H_ #define _NETINET_SCTP_OS_H_ diff --git a/netwerk/sctp/src/netinet/sctp_os_userspace.h b/netwerk/sctp/src/netinet/sctp_os_userspace.h index 05f655aa94..c0a1b6f64f 100644 --- a/netwerk/sctp/src/netinet/sctp_os_userspace.h +++ b/netwerk/sctp/src/netinet/sctp_os_userspace.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 -#include -/* #include was a 0 byte file */ #include #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); diff --git a/netwerk/sctp/src/netinet/sctp_output.c b/netwerk/sctp/src/netinet/sctp_output.c index aa0aae260f..c853c66f96 100644 --- a/netwerk/sctp/src/netinet/sctp_output.c +++ b/netwerk/sctp/src/netinet/sctp_output.c @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #include #if defined(__FreeBSD__) && !defined(__Userspace__) #include @@ -79,6 +74,9 @@ __FBSDID("$FreeBSD$"); #if defined(__Userspace__) && defined(INET6) #include #endif +#if defined(_WIN32) && defined(__MINGW32__) +#include +#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); } diff --git a/netwerk/sctp/src/netinet/sctp_output.h b/netwerk/sctp/src/netinet/sctp_output.h index 56858d880e..a51a92a85e 100644 --- a/netwerk/sctp/src/netinet/sctp_output.h +++ b/netwerk/sctp/src/netinet/sctp_output.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__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 diff --git a/netwerk/sctp/src/netinet/sctp_pcb.c b/netwerk/sctp/src/netinet/sctp_pcb.c index 233ba5dbf3..c58db02ec2 100644 --- a/netwerk/sctp/src/netinet/sctp_pcb.c +++ b/netwerk/sctp/src/netinet/sctp_pcb.c @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #include #if defined(__FreeBSD__) && !defined(__Userspace__) #include @@ -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; diff --git a/netwerk/sctp/src/netinet/sctp_pcb.h b/netwerk/sctp/src/netinet/sctp_pcb.h index 71c21886fe..3d893bc436 100644 --- a/netwerk/sctp/src/netinet/sctp_pcb.h +++ b/netwerk/sctp/src/netinet/sctp_pcb.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__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 *); diff --git a/netwerk/sctp/src/netinet/sctp_peeloff.c b/netwerk/sctp/src/netinet/sctp_peeloff.c index 548c3d82b2..2e74db048b 100644 --- a/netwerk/sctp/src/netinet/sctp_peeloff.c +++ b/netwerk/sctp/src/netinet/sctp_peeloff.c @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #include #include #include diff --git a/netwerk/sctp/src/netinet/sctp_peeloff.h b/netwerk/sctp/src/netinet/sctp_peeloff.h index c22bfca929..3011fa3517 100644 --- a/netwerk/sctp/src/netinet/sctp_peeloff.h +++ b/netwerk/sctp/src/netinet/sctp_peeloff.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #ifndef _NETINET_SCTP_PEELOFF_H_ #define _NETINET_SCTP_PEELOFF_H_ #if defined(HAVE_SCTP_PEELOFF_SOCKOPT) diff --git a/netwerk/sctp/src/netinet/sctp_process_lock.h b/netwerk/sctp/src/netinet/sctp_process_lock.h index 165c6e4eab..feaa2c6acd 100644 --- a/netwerk/sctp/src/netinet/sctp_process_lock.h +++ b/netwerk/sctp/src/netinet/sctp_process_lock.h @@ -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)) diff --git a/netwerk/sctp/src/netinet/sctp_sha1.h b/netwerk/sctp/src/netinet/sctp_sha1.h index 9ff4ff7bdc..580110e16c 100644 --- a/netwerk/sctp/src/netinet/sctp_sha1.h +++ b/netwerk/sctp/src/netinet/sctp_sha1.h @@ -32,12 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - - #ifndef __NETINET_SCTP_SHA1_H__ #define __NETINET_SCTP_SHA1_H__ diff --git a/netwerk/sctp/src/netinet/sctp_ss_functions.c b/netwerk/sctp/src/netinet/sctp_ss_functions.c index 0bc083b580..07060c3806 100644 --- a/netwerk/sctp/src/netinet/sctp_ss_functions.c +++ b/netwerk/sctp/src/netinet/sctp_ss_functions.c @@ -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 -__FBSDID("$FreeBSD$"); -#endif - +#include #include -#if defined(__Userspace__) -#include -#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, diff --git a/netwerk/sctp/src/netinet/sctp_structs.h b/netwerk/sctp/src/netinet/sctp_structs.h index e96c2c0e2a..894137ae5d 100644 --- a/netwerk/sctp/src/netinet/sctp_structs.h +++ b/netwerk/sctp/src/netinet/sctp_structs.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__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; diff --git a/netwerk/sctp/src/netinet/sctp_sysctl.c b/netwerk/sctp/src/netinet/sctp_sysctl.c index ffbe49e080..f1fc2acff7 100644 --- a/netwerk/sctp/src/netinet/sctp_sysctl.c +++ b/netwerk/sctp/src/netinet/sctp_sysctl.c @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #include #include #include @@ -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)"); diff --git a/netwerk/sctp/src/netinet/sctp_sysctl.h b/netwerk/sctp/src/netinet/sctp_sysctl.h index 9dc40c800d..fb77a3aeb5 100644 --- a/netwerk/sctp/src/netinet/sctp_sysctl.h +++ b/netwerk/sctp/src/netinet/sctp_sysctl.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #ifndef _NETINET_SCTP_SYSCTL_H_ #define _NETINET_SCTP_SYSCTL_H_ diff --git a/netwerk/sctp/src/netinet/sctp_timer.c b/netwerk/sctp/src/netinet/sctp_timer.c index aa44dad688..52cb95f26d 100644 --- a/netwerk/sctp/src/netinet/sctp_timer.c +++ b/netwerk/sctp/src/netinet/sctp_timer.c @@ -32,16 +32,11 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #define _IP_VHL #include #include -#ifdef INET6 #if defined(__FreeBSD__) && defined(__Userspace__) +#ifdef INET6 #include #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, diff --git a/netwerk/sctp/src/netinet/sctp_timer.h b/netwerk/sctp/src/netinet/sctp_timer.h index 0fe9c03b05..166e86620f 100644 --- a/netwerk/sctp/src/netinet/sctp_timer.h +++ b/netwerk/sctp/src/netinet/sctp_timer.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #ifndef _NETINET_SCTP_TIMER_H_ #define _NETINET_SCTP_TIMER_H_ diff --git a/netwerk/sctp/src/netinet/sctp_uio.h b/netwerk/sctp/src/netinet/sctp_uio.h index eee2d6447c..053d1cb16b 100644 --- a/netwerk/sctp/src/netinet/sctp_uio.h +++ b/netwerk/sctp/src/netinet/sctp_uio.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__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 */ diff --git a/netwerk/sctp/src/netinet/sctp_userspace.c b/netwerk/sctp/src/netinet/sctp_userspace.c index 8e283581b1..71888901fe 100644 --- a/netwerk/sctp/src/netinet/sctp_userspace.c +++ b/netwerk/sctp/src/netinet/sctp_userspace.c @@ -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 diff --git a/netwerk/sctp/src/netinet/sctp_usrreq.c b/netwerk/sctp/src/netinet/sctp_usrreq.c index 254aea3669..1f87682876 100644 --- a/netwerk/sctp/src/netinet/sctp_usrreq.c +++ b/netwerk/sctp/src/netinet/sctp_usrreq.c @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #include #if defined(__FreeBSD__) && !defined(__Userspace__) #include @@ -67,6 +62,9 @@ __FBSDID("$FreeBSD$"); #if defined(HAVE_SCTP_PEELOFF_SOCKOPT) #include #endif /* HAVE_SCTP_PEELOFF_SOCKOPT */ +#if defined(_WIN32) && defined(__MINGW32__) +#include +#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, \ diff --git a/netwerk/sctp/src/netinet/sctp_var.h b/netwerk/sctp/src/netinet/sctp_var.h index de26bb1d39..ab67402219 100644 --- a/netwerk/sctp/src/netinet/sctp_var.h +++ b/netwerk/sctp/src/netinet/sctp_var.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__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) diff --git a/netwerk/sctp/src/netinet/sctputil.c b/netwerk/sctp/src/netinet/sctputil.c index 7c9e2edfe5..6eac93ece3 100644 --- a/netwerk/sctp/src/netinet/sctputil.c +++ b/netwerk/sctp/src/netinet/sctputil.c @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #include #include #include @@ -70,6 +65,9 @@ __FBSDID("$FreeBSD$"); #include #endif #endif +#if defined(_WIN32) && defined(__MINGW32__) +#include +#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, diff --git a/netwerk/sctp/src/netinet/sctputil.h b/netwerk/sctp/src/netinet/sctputil.h index 74140b99d2..5e0fc81f9a 100644 --- a/netwerk/sctp/src/netinet/sctputil.h +++ b/netwerk/sctp/src/netinet/sctputil.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__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) diff --git a/netwerk/sctp/src/netinet6/sctp6_usrreq.c b/netwerk/sctp/src/netinet6/sctp6_usrreq.c index a4606e51a8..2960c98269 100644 --- a/netwerk/sctp/src/netinet6/sctp6_usrreq.c +++ b/netwerk/sctp/src/netinet6/sctp6_usrreq.c @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #include #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, diff --git a/netwerk/sctp/src/netinet6/sctp6_var.h b/netwerk/sctp/src/netinet6/sctp6_var.h index e4d737b211..8bfef64ca3 100644 --- a/netwerk/sctp/src/netinet6/sctp6_var.h +++ b/netwerk/sctp/src/netinet6/sctp6_var.h @@ -32,11 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -__FBSDID("$FreeBSD$"); -#endif - #ifndef _NETINET6_SCTP6_VAR_H_ #define _NETINET6_SCTP6_VAR_H_ diff --git a/netwerk/sctp/src/user_atomic.h b/netwerk/sctp/src/user_atomic.h index 9f0ac0f82c..6a59587efc 100644 --- a/netwerk/sctp/src/user_atomic.h +++ b/netwerk/sctp/src/user_atomic.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 diff --git a/netwerk/sctp/src/user_environment.c b/netwerk/sctp/src/user_environment.c index c0b87b5187..a007597b61 100644 --- a/netwerk/sctp/src/user_environment.c +++ b/netwerk/sctp/src/user_environment.c @@ -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 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; } } diff --git a/netwerk/sctp/src/user_mbuf.c b/netwerk/sctp/src/user_mbuf.c index 85badc0fa5..f49d11c16a 100644 --- a/netwerk/sctp/src/user_mbuf.c +++ b/netwerk/sctp/src/user_mbuf.c @@ -35,6 +35,10 @@ * */ +#if defined(_WIN32) && defined(__MINGW32__) +#include +#endif + #include #include /* #include This defines MSIZE 256 */ diff --git a/netwerk/sctp/src/user_recv_thread.c b/netwerk/sctp/src/user_recv_thread.c index 66be13d749..497d2b6960 100644 --- a/netwerk/sctp/src/user_recv_thread.c +++ b/netwerk/sctp/src/user_recv_thread.c @@ -56,7 +56,7 @@ #endif #endif #endif -#if defined(HAVE_NET_ROUTE_H) +#if defined(HAVE_NET_ROUTE_H) || defined(__FreeBSD__) || defined(__DragonFly__) # include #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); } diff --git a/netwerk/sctp/src/user_socket.c b/netwerk/sctp/src/user_socket.c index ce9daed2aa..163db3428e 100644 --- a/netwerk/sctp/src/user_socket.c +++ b/netwerk/sctp/src/user_socket.c @@ -60,9 +60,12 @@ #endif userland_mutex_t accept_mtx; userland_cond_t accept_cond; -#ifdef _WIN32 +#if defined(_WIN32) #include #include +#if !defined(_MSC_VER) +#include +#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 diff --git a/netwerk/sctp/src/user_socketvar.h b/netwerk/sctp/src/user_socketvar.h index e8eccc7fb1..04c806a88f 100644 --- a/netwerk/sctp/src/user_socketvar.h +++ b/netwerk/sctp/src/user_socketvar.h @@ -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(); \ } \ diff --git a/netwerk/sctp/src/usrsctp.h b/netwerk/sctp/src/usrsctp.h index 4c135a171d..93e89b386c 100644 --- a/netwerk/sctp/src/usrsctp.h +++ b/netwerk/sctp/src/usrsctp.h @@ -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