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:
Chris Peterson 2023-09-28 23:09:29 +00:00
Родитель a5a8d0cbd1
Коммит 7c90190c85
46 изменённых файлов: 895 добавлений и 1155 удалений

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

@ -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