зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1855349 - Update usrsctp to a0cbf4681474fab1e89d9e9e2d5c3694fce50359. r=webrtc-reviewers,bwc
Depends on D189326 Differential Revision: https://phabricator.services.mozilla.com/D189327
This commit is contained in:
Родитель
a5a8d0cbd1
Коммит
7c90190c85
|
@ -10,8 +10,8 @@ origin:
|
|||
|
||||
url: https://github.com/sctplab/usrsctp/blob/master/Manual.md
|
||||
|
||||
release: f9f95023816b61a2f257d2fb77658dceaea7213f (2023-03-18T22:38:54Z).
|
||||
revision: f9f95023816b61a2f257d2fb77658dceaea7213f
|
||||
release: a0cbf4681474fab1e89d9e9e2d5c3694fce50359 (2023-09-13T13:37:16Z).
|
||||
revision: a0cbf4681474fab1e89d9e9e2d5c3694fce50359
|
||||
|
||||
license: BSD-3-Clause
|
||||
|
||||
|
|
|
@ -32,17 +32,15 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_H_
|
||||
#define _NETINET_SCTP_H_
|
||||
|
||||
#if defined(__APPLE__) || defined(__linux__)
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
|
@ -199,8 +197,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 +324,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
|
||||
|
|
|
@ -32,19 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Needed for unified build so that rand_s is available to all unified
|
||||
// sources.
|
||||
#if !defined(_CRT_RAND_S) && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
|
||||
#define _CRT_RAND_S
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
#include <netinet/sctp_var.h>
|
||||
#include <netinet/sctp_sysctl.h>
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_ASCONF_H_
|
||||
#define _NETINET_SCTP_ASCONF_H_
|
||||
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
#include <netinet/sctp.h>
|
||||
#include <netinet/sctp_header.h>
|
||||
|
@ -580,7 +575,7 @@ sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id, int so_locked)
|
|||
if ((skey->refcount <= 2) && (skey->deactivated)) {
|
||||
/* notify ULP that key is no longer used */
|
||||
sctp_ulp_notify(SCTP_NOTIFY_AUTH_FREE_KEY, stcb,
|
||||
key_id, 0, so_locked);
|
||||
0, &key_id, so_locked);
|
||||
SCTPDBG(SCTP_DEBUG_AUTH2,
|
||||
"%s: stcb %p key %u no longer used, %d\n",
|
||||
__func__, (void *)stcb, key_id, skey->refcount);
|
||||
|
@ -1339,8 +1334,8 @@ sctp_deact_sharedkey(struct sctp_tcb *stcb, uint16_t keyid)
|
|||
/* are there other refcount holders on the key? */
|
||||
if (skey->refcount == 1) {
|
||||
/* no other users, send a notification for this key */
|
||||
sctp_ulp_notify(SCTP_NOTIFY_AUTH_FREE_KEY, stcb, keyid, 0,
|
||||
SCTP_SO_LOCKED);
|
||||
sctp_ulp_notify(SCTP_NOTIFY_AUTH_FREE_KEY, stcb, 0, &keyid,
|
||||
SCTP_SO_LOCKED);
|
||||
}
|
||||
|
||||
/* mark the key as deactivated */
|
||||
|
@ -1684,15 +1679,10 @@ sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *auth,
|
|||
return (-1);
|
||||
}
|
||||
/* generate a notification if this is a new key id */
|
||||
if (stcb->asoc.authinfo.recv_keyid != shared_key_id)
|
||||
/*
|
||||
* sctp_ulp_notify(SCTP_NOTIFY_AUTH_NEW_KEY, stcb,
|
||||
* shared_key_id, (void
|
||||
* *)stcb->asoc.authinfo.recv_keyid);
|
||||
*/
|
||||
sctp_notify_authentication(stcb, SCTP_AUTH_NEW_KEY,
|
||||
shared_key_id, stcb->asoc.authinfo.recv_keyid,
|
||||
SCTP_SO_NOT_LOCKED);
|
||||
if (stcb->asoc.authinfo.recv_keyid != shared_key_id) {
|
||||
sctp_ulp_notify(SCTP_NOTIFY_AUTH_NEW_KEY, stcb, 0,
|
||||
&shared_key_id, SCTP_SO_NOT_LOCKED);
|
||||
}
|
||||
/* compute a new recv assoc key and cache it */
|
||||
if (stcb->asoc.authinfo.recv_key != NULL)
|
||||
sctp_free_key(stcb->asoc.authinfo.recv_key);
|
||||
|
@ -1735,27 +1725,22 @@ sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *auth,
|
|||
*/
|
||||
void
|
||||
sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
|
||||
uint16_t keyid, uint16_t alt_keyid, int so_locked)
|
||||
uint16_t keyid, int so_locked)
|
||||
{
|
||||
struct mbuf *m_notify;
|
||||
struct sctp_authkey_event *auth;
|
||||
struct sctp_queued_to_read *control;
|
||||
|
||||
if ((stcb == NULL) ||
|
||||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
|
||||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
|
||||
(stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)
|
||||
) {
|
||||
/* If the socket is gone we are out of here */
|
||||
return;
|
||||
}
|
||||
KASSERT(stcb != NULL, ("stcb == NULL"));
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
|
||||
|
||||
if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_AUTHEVNT))
|
||||
/* event not enabled */
|
||||
return;
|
||||
|
||||
m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_authkey_event),
|
||||
0, M_NOWAIT, 1, MT_HEADER);
|
||||
0, M_NOWAIT, 1, MT_HEADER);
|
||||
if (m_notify == NULL)
|
||||
/* no space left */
|
||||
return;
|
||||
|
@ -1767,7 +1752,12 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
|
|||
auth->auth_flags = 0;
|
||||
auth->auth_length = sizeof(*auth);
|
||||
auth->auth_keynumber = keyid;
|
||||
auth->auth_altkeynumber = alt_keyid;
|
||||
/* XXXMT: The following is BSD specific. */
|
||||
if (indication == SCTP_AUTH_NEW_KEY) {
|
||||
auth->auth_altkeynumber = stcb->asoc.authinfo.recv_keyid;
|
||||
} else {
|
||||
auth->auth_altkeynumber = 0;
|
||||
}
|
||||
auth->auth_indication = indication;
|
||||
auth->auth_assoc_id = sctp_get_associd(stcb);
|
||||
|
||||
|
@ -1787,7 +1777,8 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
|
|||
/* not that we need this */
|
||||
control->tail_mbuf = m_notify;
|
||||
sctp_add_to_readq(stcb->sctp_ep, stcb, control,
|
||||
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, so_locked);
|
||||
&stcb->sctp_socket->so_rcv, 1,
|
||||
SCTP_READ_LOCK_HELD, so_locked);
|
||||
}
|
||||
|
||||
/*-
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_AUTH_H_
|
||||
#define _NETINET_SCTP_AUTH_H_
|
||||
|
||||
|
@ -199,7 +194,7 @@ extern struct mbuf *sctp_add_auth_chunk(struct mbuf *m, struct mbuf **m_end,
|
|||
extern int sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *ch,
|
||||
struct mbuf *m, uint32_t offset);
|
||||
extern void sctp_notify_authentication(struct sctp_tcb *stcb,
|
||||
uint32_t indication, uint16_t keyid, uint16_t alt_keyid, int so_locked);
|
||||
uint32_t indication, uint16_t keyid, int so_locked);
|
||||
extern int sctp_validate_init_auth_params(struct mbuf *m, int offset,
|
||||
int limit);
|
||||
extern void sctp_initialize_auth_params(struct sctp_inpcb *inp,
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
#include <netinet/sctp_var.h>
|
||||
#include <netinet/sctp_pcb.h>
|
||||
|
@ -304,7 +299,14 @@ sctp_is_vmware_interface(struct ifnet *ifn)
|
|||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(__Userspace__)
|
||||
#define SCTP_BSD_FREE(x) HeapFree(GetProcessHeap(), 0, (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__)
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_BSD_ADDR_H_
|
||||
#define _NETINET_SCTP_BSD_ADDR_H_
|
||||
|
||||
|
|
|
@ -30,11 +30,6 @@
|
|||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_CALLOUT_
|
||||
#define _NETINET_SCTP_CALLOUT_
|
||||
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
#include <netinet/sctp_var.h>
|
||||
#include <netinet/sctp_sysctl.h>
|
||||
|
@ -58,6 +53,12 @@ __FBSDID("$FreeBSD$");
|
|||
#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 +104,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 +198,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 +262,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 +278,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 +301,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 +327,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 +341,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 +373,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 +417,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 +434,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 +451,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 +466,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 +491,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 +505,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 +527,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 +541,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 +576,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 +589,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 +603,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 +627,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 +714,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 +763,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 +876,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 +885,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 +985,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 +1049,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 +1083,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 +1162,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 +1216,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 +1337,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 +1362,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 +1426,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 +1438,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 +1487,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 +1499,11 @@ sctp_set_rtcc_initial_cc_param(struct sctp_tcb *stcb,
|
|||
(((uint32_t)(stcb->sctp_ep->sctp_lport)) << 16) |
|
||||
(stcb->rport);
|
||||
SDT_PROBE5(sctp, cwnd, net, rttvar,
|
||||
vtag,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
probepoint);
|
||||
vtag,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
probepoint);
|
||||
#endif
|
||||
net->cc_mod.rtcc.lbw_rtt = 0;
|
||||
net->cc_mod.rtcc.cwnd_at_bw_set = 0;
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_CONSTANTS_H_
|
||||
#define _NETINET_SCTP_CONSTANTS_H_
|
||||
|
||||
|
@ -727,12 +722,14 @@ extern void getwintimeofday(struct timeval *tv);
|
|||
#define SCTP_NOTIFY_STR_RESET_FAILED_IN 20
|
||||
#define SCTP_NOTIFY_STR_RESET_DENIED_OUT 21
|
||||
#define SCTP_NOTIFY_STR_RESET_DENIED_IN 22
|
||||
#define SCTP_NOTIFY_AUTH_NEW_KEY 23
|
||||
#define SCTP_NOTIFY_AUTH_FREE_KEY 24
|
||||
#define SCTP_NOTIFY_NO_PEER_AUTH 25
|
||||
#define SCTP_NOTIFY_SENDER_DRY 26
|
||||
#define SCTP_NOTIFY_REMOTE_ERROR 27
|
||||
#define SCTP_NOTIFY_ASSOC_TIMEDOUT 28
|
||||
#define SCTP_NOTIFY_STR_RESET_ADD 23
|
||||
#define SCTP_NOTIFY_STR_RESET_TSN 24
|
||||
#define SCTP_NOTIFY_AUTH_NEW_KEY 25
|
||||
#define SCTP_NOTIFY_AUTH_FREE_KEY 26
|
||||
#define SCTP_NOTIFY_NO_PEER_AUTH 27
|
||||
#define SCTP_NOTIFY_SENDER_DRY 28
|
||||
#define SCTP_NOTIFY_REMOTE_ERROR 29
|
||||
#define SCTP_NOTIFY_ASSOC_TIMEDOUT 30
|
||||
|
||||
/* This is the value for messages that are NOT completely
|
||||
* copied down where we will start to split the message.
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_sctp.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_CRC32_H_
|
||||
#define _NETINET_SCTP_CRC32_H_
|
||||
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_HEADER_H_
|
||||
#define _NETINET_SCTP_HEADER_H_
|
||||
|
||||
|
@ -226,7 +221,7 @@ struct sctp_state_cookie { /* this is our definition... */
|
|||
|
||||
uint8_t ipv4_scope; /* IPv4 private addr scope */
|
||||
uint8_t loopback_scope; /* loopback scope information */
|
||||
uint8_t zero_checksum; /* copy of the inp value */
|
||||
uint8_t rcv_edmid; /* copy of the inp value */
|
||||
uint8_t reserved[SCTP_RESERVE_SPACE]; /* Align to 64 bits */
|
||||
/*
|
||||
* at the end is tacked on the INIT chunk and the INIT-ACK chunk
|
||||
|
@ -539,6 +534,13 @@ struct sctp_auth_chunk {
|
|||
uint8_t hmac[];
|
||||
} SCTP_PACKED;
|
||||
|
||||
/* Zero checksum support draft-ietf-tsvwg-sctp-zero-checksum */
|
||||
|
||||
struct sctp_zero_checksum_acceptable {
|
||||
struct sctp_paramhdr ph;
|
||||
uint32_t edmid;
|
||||
} SCTP_PACKED;
|
||||
|
||||
/*
|
||||
* we pre-reserve enough room for a ECNE or CWR AND a SACK with no missing
|
||||
* pieces. If ENCE is missing we could have a couple of blocks. This way we
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/proc.h>
|
||||
|
@ -1311,16 +1306,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 +1365,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);
|
||||
}
|
||||
|
@ -5562,9 +5560,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 +5739,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 +5762,11 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
|
|||
#endif
|
||||
}
|
||||
control->on_strm_q = 0;
|
||||
stcb->asoc.control_pdapi = control;
|
||||
sctp_ulp_notify(SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION,
|
||||
stcb,
|
||||
SCTP_PARTIAL_DELIVERY_ABORTED,
|
||||
(void *)&str_seq,
|
||||
SCTP_SO_NOT_LOCKED);
|
||||
stcb->asoc.control_pdapi = sv;
|
||||
(void *)control,
|
||||
SCTP_SO_NOT_LOCKED);
|
||||
break;
|
||||
} else if ((control->sinfo_stream == sid) &&
|
||||
SCTP_MID_GT(asoc->idata_supported, control->mid, mid)) {
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_INDATA_H_
|
||||
#define _NETINET_SCTP_INDATA_H_
|
||||
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
#include <netinet/sctp_var.h>
|
||||
#include <netinet/sctp_sysctl.h>
|
||||
|
@ -910,22 +905,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 +963,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 +976,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 +990,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 +1020,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 +1046,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 +1080,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 +1215,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 +1231,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 +1607,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 +1862,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 +1932,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 +2039,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 +2276,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 +2417,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);
|
||||
|
@ -3177,16 +3139,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 +3184,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 +3233,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 +3909,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 +3966,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 +4099,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 +4265,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++;
|
||||
|
@ -5845,9 +5811,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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_INPUT_H_
|
||||
#define _NETINET_SCTP_INPUT_H_
|
||||
|
||||
|
|
|
@ -33,11 +33,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_LOCK_EMPTY_H_
|
||||
#define _NETINET_SCTP_LOCK_EMPTY_H_
|
||||
|
||||
|
@ -92,10 +87,11 @@ __FBSDID("$FreeBSD$");
|
|||
#define SCTP_IP_PKTLOG_UNLOCK()
|
||||
#define SCTP_IP_PKTLOG_DESTROY()
|
||||
|
||||
#define SCTP_INP_READ_INIT(_inp)
|
||||
#define SCTP_INP_READ_DESTROY(_inp)
|
||||
#define SCTP_INP_READ_LOCK_INIT(_inp)
|
||||
#define SCTP_INP_READ_LOCK_DESTROY(_inp)
|
||||
#define SCTP_INP_READ_LOCK(_inp)
|
||||
#define SCTP_INP_READ_UNLOCK(_inp)
|
||||
#define SCTP_INP_READ_LOCK_ASSERT(_inp)
|
||||
|
||||
#define SCTP_INP_LOCK_INIT(_inp)
|
||||
#define SCTP_ASOC_CREATE_LOCK_INIT(_inp)
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_OS_H_
|
||||
#define _NETINET_SCTP_OS_H_
|
||||
|
||||
|
|
|
@ -523,8 +523,6 @@ struct sx {int dummy;};
|
|||
#endif
|
||||
#if defined(__FreeBSD__)
|
||||
#include <netinet6/in6_pcb.h>
|
||||
#include <netinet6/ip6protosw.h>
|
||||
/* #include <netinet6/nd6.h> was a 0 byte file */
|
||||
#include <netinet6/scope6_var.h>
|
||||
#endif
|
||||
#endif /* INET6 */
|
||||
|
@ -962,6 +960,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; \
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/proc.h>
|
||||
|
@ -5070,6 +5065,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 +5166,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;
|
||||
}
|
||||
|
||||
|
@ -5493,7 +5490,7 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
|
|||
break;
|
||||
case SCTP_HAS_NAT_SUPPORT:
|
||||
*nat_friendly = 1;
|
||||
/* fall through */
|
||||
/* FALLTHROUGH */
|
||||
case SCTP_PRSCTP_SUPPORTED:
|
||||
if (padded_size != sizeof(struct sctp_paramhdr)) {
|
||||
SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error prsctp/nat support %d\n", plen);
|
||||
|
@ -5962,6 +5959,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;
|
||||
|
@ -6350,9 +6348,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 +6475,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;
|
||||
}
|
||||
|
||||
|
@ -7293,7 +7296,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 +7337,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7868,7 +7869,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 +9021,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 +9362,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 +10113,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 +10411,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 +10429,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 +11525,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 +11547,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 +11619,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 +11643,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 +11657,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 +11679,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) {
|
||||
|
@ -14695,8 +14743,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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_OUTPUT_H_
|
||||
#define _NETINET_SCTP_OUTPUT_H_
|
||||
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/proc.h>
|
||||
|
@ -2797,7 +2792,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 +2916,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 +3969,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 +4021,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 +4178,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 +4274,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);
|
||||
|
@ -5535,28 +5528,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);
|
||||
|
@ -7413,12 +7397,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 */
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_PCB_H_
|
||||
#define _NETINET_SCTP_PCB_H_
|
||||
|
||||
|
@ -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
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
#include <netinet/sctp_pcb.h>
|
||||
#include <netinet/sctputil.h>
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_PEELOFF_H_
|
||||
#define _NETINET_SCTP_PEELOFF_H_
|
||||
#if defined(HAVE_SCTP_PEELOFF_SOCKOPT)
|
||||
|
|
|
@ -98,10 +98,11 @@
|
|||
#define SCTP_ASOC_CREATE_LOCK(_inp)
|
||||
#define SCTP_ASOC_CREATE_UNLOCK(_inp)
|
||||
|
||||
#define SCTP_INP_READ_INIT(_inp)
|
||||
#define SCTP_INP_READ_DESTROY(_inp)
|
||||
#define SCTP_INP_READ_LOCK_INIT(_inp)
|
||||
#define SCTP_INP_READ_LOCK_DESTROY(_inp)
|
||||
#define SCTP_INP_READ_LOCK(_inp)
|
||||
#define SCTP_INP_READ_UNLOCK(_inp)
|
||||
#define SCTP_INP_READ_LOCK_ASSERT(_inp)
|
||||
|
||||
/* Lock for TCB */
|
||||
#define SCTP_TCB_LOCK_INIT(_tcb)
|
||||
|
@ -180,14 +181,15 @@
|
|||
* we want to change something at the endpoint level for example random_store
|
||||
* or cookie secrets we lock the INP level.
|
||||
*/
|
||||
#define SCTP_INP_READ_INIT(_inp) \
|
||||
#define SCTP_INP_READ_LOCK_INIT(_inp) \
|
||||
InitializeCriticalSection(&(_inp)->inp_rdata_mtx)
|
||||
#define SCTP_INP_READ_DESTROY(_inp) \
|
||||
#define SCTP_INP_READ_LOCK_DESTROY(_inp) \
|
||||
DeleteCriticalSection(&(_inp)->inp_rdata_mtx)
|
||||
#define SCTP_INP_READ_LOCK(_inp) \
|
||||
EnterCriticalSection(&(_inp)->inp_rdata_mtx)
|
||||
#define SCTP_INP_READ_UNLOCK(_inp) \
|
||||
LeaveCriticalSection(&(_inp)->inp_rdata_mtx)
|
||||
#define SCTP_INP_READ_LOCK_ASSERT(_inp)
|
||||
|
||||
#define SCTP_INP_LOCK_INIT(_inp) \
|
||||
InitializeCriticalSection(&(_inp)->inp_mtx)
|
||||
|
@ -335,9 +337,9 @@
|
|||
* we want to change something at the endpoint level for example random_store
|
||||
* or cookie secrets we lock the INP level.
|
||||
*/
|
||||
#define SCTP_INP_READ_INIT(_inp) \
|
||||
#define SCTP_INP_READ_LOCK_INIT(_inp) \
|
||||
(void)pthread_mutex_init(&(_inp)->inp_rdata_mtx, &SCTP_BASE_VAR(mtx_attr))
|
||||
#define SCTP_INP_READ_DESTROY(_inp) \
|
||||
#define SCTP_INP_READ_LOCK_DESTROY(_inp) \
|
||||
(void)pthread_mutex_destroy(&(_inp)->inp_rdata_mtx)
|
||||
#ifdef INVARIANTS
|
||||
#define SCTP_INP_READ_LOCK(_inp) \
|
||||
|
@ -350,6 +352,8 @@
|
|||
#define SCTP_INP_READ_UNLOCK(_inp) \
|
||||
(void)pthread_mutex_unlock(&(_inp)->inp_rdata_mtx)
|
||||
#endif
|
||||
#define SCTP_INP_READ_LOCK_ASSERT(_inp) \
|
||||
KASSERT(pthread_mutex_trylock(&(_inp)->inp_rdata_mtx) == EBUSY, ("%s:%d: inp_rdata_mtx not locked", __FILE__, __LINE__))
|
||||
|
||||
#define SCTP_INP_LOCK_INIT(_inp) \
|
||||
(void)pthread_mutex_init(&(_inp)->inp_mtx, &SCTP_BASE_VAR(mtx_attr))
|
||||
|
|
|
@ -80,25 +80,7 @@ sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx)
|
|||
{
|
||||
SHA1_Final(digest, &ctx->sha_ctx);
|
||||
}
|
||||
#elif defined(SCTP_USE_MBEDTLS_SHA1)
|
||||
void
|
||||
sctp_sha1_init(struct sctp_sha1_context *ctx)
|
||||
{
|
||||
mbedtls_sha1_init(&ctx->sha1_ctx);
|
||||
mbedtls_sha1_starts_ret(&ctx->sha1_ctx);
|
||||
}
|
||||
|
||||
void
|
||||
sctp_sha1_update(struct sctp_sha1_context *ctx, const unsigned char *ptr, unsigned int siz)
|
||||
{
|
||||
mbedtls_sha1_update_ret(&ctx->sha1_ctx, ptr, siz);
|
||||
}
|
||||
|
||||
void
|
||||
sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx)
|
||||
{
|
||||
mbedtls_sha1_finish_ret(&ctx->sha1_ctx, digest);
|
||||
}
|
||||
#else
|
||||
|
||||
#include <string.h>
|
||||
|
|
|
@ -32,12 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __NETINET_SCTP_SHA1_H__
|
||||
#define __NETINET_SCTP_SHA1_H__
|
||||
|
||||
|
@ -46,8 +40,6 @@ __FBSDID("$FreeBSD$");
|
|||
#include <pk11pub.h>
|
||||
#elif defined(SCTP_USE_OPENSSL_SHA1)
|
||||
#include <openssl/sha.h>
|
||||
#elif defined(SCTP_USE_MBEDTLS_SHA1)
|
||||
#include <mbedtls/sha1.h>
|
||||
#endif
|
||||
|
||||
struct sctp_sha1_context {
|
||||
|
@ -55,8 +47,6 @@ struct sctp_sha1_context {
|
|||
struct PK11Context *pk11_ctx;
|
||||
#elif defined(SCTP_USE_OPENSSL_SHA1)
|
||||
SHA_CTX sha_ctx;
|
||||
#elif defined(SCTP_USE_MBEDTLS_SHA1)
|
||||
mbedtls_sha1_context sha1_ctx;
|
||||
#else
|
||||
unsigned int A;
|
||||
unsigned int B;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2010-2012, by Michael Tuexen. All rights reserved.
|
||||
* Copyright (c) 2010-2012, by Randall Stewart. All rights reserved.
|
||||
|
@ -28,15 +28,8 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
#include <netinet/sctp_pcb.h>
|
||||
#if defined(__Userspace__)
|
||||
#include <netinet/sctp_os_userspace.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Default simple round-robin algorithm.
|
||||
|
@ -975,7 +968,7 @@ const struct sctp_ss_functions sctp_ss_functions[] = {
|
|||
.sctp_ss_is_user_msgs_incomplete = sctp_ss_default_is_user_msgs_incomplete
|
||||
#endif
|
||||
},
|
||||
/* SCTP_SS_ROUND_ROBIN */
|
||||
/* SCTP_SS_RR */
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
sctp_ss_default_init,
|
||||
|
@ -1005,7 +998,7 @@ const struct sctp_ss_functions sctp_ss_functions[] = {
|
|||
.sctp_ss_is_user_msgs_incomplete = sctp_ss_default_is_user_msgs_incomplete
|
||||
#endif
|
||||
},
|
||||
/* SCTP_SS_ROUND_ROBIN_PACKET */
|
||||
/* SCTP_SS_RR_PKT */
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
sctp_ss_default_init,
|
||||
|
@ -1035,7 +1028,7 @@ const struct sctp_ss_functions sctp_ss_functions[] = {
|
|||
.sctp_ss_is_user_msgs_incomplete = sctp_ss_default_is_user_msgs_incomplete
|
||||
#endif
|
||||
},
|
||||
/* SCTP_SS_PRIORITY */
|
||||
/* SCTP_SS_PRIO */
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
sctp_ss_default_init,
|
||||
|
@ -1065,7 +1058,7 @@ const struct sctp_ss_functions sctp_ss_functions[] = {
|
|||
.sctp_ss_is_user_msgs_incomplete = sctp_ss_default_is_user_msgs_incomplete
|
||||
#endif
|
||||
},
|
||||
/* SCTP_SS_FAIR_BANDWITH */
|
||||
/* SCTP_SS_FB */
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
sctp_ss_default_init,
|
||||
|
@ -1095,7 +1088,7 @@ const struct sctp_ss_functions sctp_ss_functions[] = {
|
|||
.sctp_ss_is_user_msgs_incomplete = sctp_ss_default_is_user_msgs_incomplete
|
||||
#endif
|
||||
},
|
||||
/* SCTP_SS_FIRST_COME */
|
||||
/* SCTP_SS_FCFS */
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
sctp_ss_fcfs_init,
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_STRUCTS_H_
|
||||
#define _NETINET_SCTP_STRUCTS_H_
|
||||
|
||||
|
@ -1008,15 +1003,6 @@ struct sctp_association {
|
|||
uint32_t fast_recovery_tsn;
|
||||
uint32_t sat_t3_recovery_tsn;
|
||||
uint32_t tsn_last_delivered;
|
||||
/*
|
||||
* For the pd-api we should re-write this a bit more efficient. We
|
||||
* could have multiple sctp_queued_to_read's that we are building at
|
||||
* once. Now we only do this when we get ready to deliver to the
|
||||
* socket buffer. Note that we depend on the fact that the struct is
|
||||
* "stuck" on the read queue until we finish all the pd-api.
|
||||
*/
|
||||
struct sctp_queued_to_read *control_pdapi;
|
||||
|
||||
uint32_t tsn_of_pdapi_last_delivered;
|
||||
uint32_t pdapi_ppid;
|
||||
uint32_t context;
|
||||
|
@ -1234,12 +1220,9 @@ struct sctp_association {
|
|||
uint8_t pktdrop_supported;
|
||||
uint8_t idata_supported;
|
||||
|
||||
/* Zero checksum supported information:
|
||||
* 0: disabled
|
||||
* 1: enabled for rcv
|
||||
* 2: enabled for snd/rcv
|
||||
*/
|
||||
uint8_t zero_checksum;
|
||||
/* Zero checksum supported information */
|
||||
uint8_t rcv_edmid;
|
||||
uint8_t snd_edmid;
|
||||
|
||||
/* Did the peer make the stream config (add out) request */
|
||||
uint8_t peer_req_out;
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
#include <netinet/sctp.h>
|
||||
#include <netinet/sctp_constants.h>
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_SYSCTL_H_
|
||||
#define _NETINET_SCTP_SYSCTL_H_
|
||||
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#define _IP_VHL
|
||||
#include <netinet/sctp_os.h>
|
||||
#include <netinet/sctp_pcb.h>
|
||||
|
@ -97,7 +92,10 @@ static int
|
|||
sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
struct sctp_nets *net, uint16_t threshold)
|
||||
{
|
||||
if (net) {
|
||||
KASSERT(stcb != NULL, ("stcb is NULL"));
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
if (net != NULL) {
|
||||
net->error_count++;
|
||||
SCTPDBG(SCTP_DEBUG_TIMER4, "Error count for %p now %d thresh:%d\n",
|
||||
(void *)net, net->error_count,
|
||||
|
@ -124,11 +122,6 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (stcb == NULL)
|
||||
return (0);
|
||||
|
||||
if (net) {
|
||||
if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0) {
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
|
||||
sctp_misc_ints(SCTP_THRESHOLD_INCR,
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_TIMER_H_
|
||||
#define _NETINET_SCTP_TIMER_H_
|
||||
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_UIO_H_
|
||||
#define _NETINET_SCTP_UIO_H_
|
||||
|
||||
|
@ -810,6 +805,10 @@ struct sctp_get_nonce_values {
|
|||
uint32_t gn_local_tag;
|
||||
};
|
||||
|
||||
/* Values for SCTP_ACCEPT_ZERO_CHECKSUM */
|
||||
#define SCTP_EDMID_NONE 0
|
||||
#define SCTP_EDMID_LOWER_LAYER_DTLS 1
|
||||
|
||||
/* Debugging logs */
|
||||
struct sctp_str_log {
|
||||
void *stcb; /* FIXME: LP64 issue */
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/proc.h>
|
||||
|
@ -661,13 +656,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 +717,7 @@ sctp_abort(struct socket *so)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef INET
|
||||
#if defined(__Userspace__)
|
||||
int
|
||||
#else
|
||||
|
@ -902,24 +895,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 +947,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 +957,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 +989,7 @@ sctp_detach(struct socket *so)
|
|||
goto sctp_must_try_again;
|
||||
}
|
||||
}
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
return;
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1136,7 +1115,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 +1128,212 @@ 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 {
|
||||
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 +1435,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 +1462,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 +2400,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 +2427,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 +4810,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 +4859,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 +7792,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_VAR_H_
|
||||
#define _NETINET_SCTP_VAR_H_
|
||||
|
||||
|
@ -207,7 +202,7 @@ extern struct pr_usrreqs sctp_usrreqs;
|
|||
}
|
||||
|
||||
#define sctp_sbfree(ctl, stcb, sb, m) { \
|
||||
SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_cc, SCTP_BUF_LEN((m))); \
|
||||
SCTP_SB_DECR(sb, SCTP_BUF_LEN((m))); \
|
||||
SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_mbcnt, MSIZE); \
|
||||
if (((ctl)->do_not_ref_stcb == 0) && stcb) {\
|
||||
SCTP_SAVE_ATOMIC_DECREMENT(&(stcb)->asoc.sb_cc, SCTP_BUF_LEN((m))); \
|
||||
|
@ -219,7 +214,7 @@ extern struct pr_usrreqs sctp_usrreqs;
|
|||
}
|
||||
|
||||
#define sctp_sballoc(stcb, sb, m) { \
|
||||
atomic_add_int(&(sb)->sb_cc,SCTP_BUF_LEN((m))); \
|
||||
SCTP_SB_INCR(sb, SCTP_BUF_LEN((m))); \
|
||||
atomic_add_int(&(sb)->sb_mbcnt, MSIZE); \
|
||||
if (stcb) { \
|
||||
atomic_add_int(&(stcb)->asoc.sb_cc, SCTP_BUF_LEN((m))); \
|
||||
|
@ -250,7 +245,7 @@ extern struct pr_usrreqs sctp_usrreqs;
|
|||
}
|
||||
|
||||
#define sctp_sbfree(ctl, stcb, sb, m) { \
|
||||
SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_cc, SCTP_BUF_LEN((m))); \
|
||||
SCTP_SB_DECR(sb, SCTP_BUF_LEN((m))); \
|
||||
SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_mbcnt, MSIZE); \
|
||||
if (((ctl)->do_not_ref_stcb == 0) && stcb) { \
|
||||
SCTP_SAVE_ATOMIC_DECREMENT(&(stcb)->asoc.sb_cc, SCTP_BUF_LEN((m))); \
|
||||
|
@ -259,7 +254,7 @@ extern struct pr_usrreqs sctp_usrreqs;
|
|||
}
|
||||
|
||||
#define sctp_sballoc(stcb, sb, m) { \
|
||||
atomic_add_int(&(sb)->sb_cc, SCTP_BUF_LEN((m))); \
|
||||
SCTP_SB_INCR(sb, SCTP_BUF_LEN((m))); \
|
||||
atomic_add_int(&(sb)->sb_mbcnt, MSIZE); \
|
||||
if (stcb) { \
|
||||
atomic_add_int(&(stcb)->asoc.sb_cc, SCTP_BUF_LEN((m))); \
|
||||
|
@ -372,6 +367,11 @@ void sctp_close(struct socket *so);
|
|||
#else
|
||||
int sctp_detach(struct socket *so);
|
||||
#endif
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
void sctp_abort(struct socket *so);
|
||||
#else
|
||||
int sctp_abort(struct socket *so);
|
||||
#endif
|
||||
int sctp_disconnect(struct socket *so);
|
||||
#if !defined(__Userspace__)
|
||||
#if defined(__APPLE__) && !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION) && !defined(APPLE_ELCAPITAN)
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
#include <netinet/sctp_pcb.h>
|
||||
#include <netinet/sctputil.h>
|
||||
|
@ -1178,7 +1173,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;
|
||||
|
@ -3247,9 +3243,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 +3255,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 +3338,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 +3350,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 +3375,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 +3388,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 +3410,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 +3460,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 +3500,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 +3516,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 +3632,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 +3647,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 +3732,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 +3782,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 +3818,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 +3845,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 +3874,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 +3910,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 +3943,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 +3994,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 +4031,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 +4053,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 +4085,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 +4107,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 +4174,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 +4189,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 +4240,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 +4250,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 +4278,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 +4297,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 +4315,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 +4323,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 +4350,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 +4381,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 +4425,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 +5553,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6757,7 +6763,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);
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_UTIL_H_
|
||||
#define _NETINET_SCTP_UTIL_H_
|
||||
|
||||
|
@ -87,12 +82,6 @@ int sctp_init_asoc(struct sctp_inpcb *, struct sctp_tcb *, uint32_t, uint32_t, u
|
|||
|
||||
void sctp_fill_random_store(struct sctp_pcb *);
|
||||
|
||||
void
|
||||
sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin,
|
||||
uint16_t numberout, int flag);
|
||||
void
|
||||
sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, uint32_t sending_tsn, uint32_t recv_tsn, int flag);
|
||||
|
||||
/*
|
||||
* NOTE: sctp_timer_start() will increment the reference count of any relevant
|
||||
* structure the timer is referencing, in order to prevent a race condition
|
||||
|
@ -288,11 +277,7 @@ do { \
|
|||
} \
|
||||
if (stcb->sctp_socket && ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \
|
||||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \
|
||||
if (stcb->sctp_socket->so_snd.sb_cc >= sp->length) { \
|
||||
atomic_subtract_int(&stcb->sctp_socket->so_snd.sb_cc,sp->length); \
|
||||
} else { \
|
||||
stcb->sctp_socket->so_snd.sb_cc = 0; \
|
||||
} \
|
||||
SCTP_SB_DECR(&stcb->sctp_socket->so_snd, sp->length); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
@ -303,7 +288,7 @@ do { \
|
|||
if ((stcb->sctp_socket != NULL) && \
|
||||
((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \
|
||||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \
|
||||
atomic_add_int(&stcb->sctp_socket->so_snd.sb_cc,sz); \
|
||||
SCTP_SB_INCR(&stcb->sctp_socket->so_snd, sz); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
#ifdef INET6
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
|
@ -732,73 +727,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 +938,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,
|
||||
|
@ -1742,7 +1661,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 +1671,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 +1694,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 +1702,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 +1715,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 +1723,7 @@ struct pr_usrreqs sctp6_usrreqs = {
|
|||
pru_connect2_notsupp,
|
||||
NULL,
|
||||
NULL,
|
||||
sctp6_disconnect,
|
||||
sctp_disconnect,
|
||||
sctp_listen,
|
||||
sctp6_getpeeraddr,
|
||||
NULL,
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET6_SCTP6_VAR_H_
|
||||
#define _NETINET6_SCTP6_VAR_H_
|
||||
|
||||
|
|
|
@ -30,15 +30,6 @@
|
|||
|
||||
#ifndef _USER_ENVIRONMENT_H_
|
||||
#define _USER_ENVIRONMENT_H_
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Needed for unified build so that rand_s is available to all unified
|
||||
// sources.
|
||||
#if !defined(_CRT_RAND_S) && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
|
||||
#define _CRT_RAND_S
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* __Userspace__ */
|
||||
#include <sys/types.h>
|
||||
|
||||
|
|
|
@ -308,22 +308,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);
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче