mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1139020: Update SCTP library from upstream to rev 9168 rs=jesup
This commit is contained in:
parent
583788c3a7
commit
02c76d0edf
@ -14,3 +14,4 @@ sctp updated to version 8279 from SVN on Thu Sep 20 18:19:24 EDT 2012
|
||||
sctp updated to version 8397 from SVN on Wed Jan 9 00:41:16 EST 2013
|
||||
sctp updated to version 8443 from SVN on Sun Mar 31 09:05:07 EDT 2013
|
||||
sctp updated to version 8815 from SVN on Tue Mar 4 08:50:51 EST 2014
|
||||
sctp updated to version 9168 from SVN on Tue Mar 3 12:11:40 EST 2015
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 254248 2013-08-12 13:52:15Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 269945 2014-08-13 15:50:16Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_H_
|
||||
@ -53,13 +53,13 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp.h 254248 2013-08-12 13:52:15Z tuexen $
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SCTP protocol - RFC2960.
|
||||
* SCTP protocol - RFC4960.
|
||||
*/
|
||||
struct sctphdr {
|
||||
uint16_t src_port; /* source port */
|
||||
uint16_t dest_port; /* destination port */
|
||||
uint32_t v_tag; /* verification tag of packet */
|
||||
uint32_t checksum; /* Adler32 C-Sum */
|
||||
uint32_t checksum; /* CRC32C checksum */
|
||||
/* chunks follow... */
|
||||
} SCTP_PACKED;
|
||||
|
||||
@ -131,6 +131,13 @@ struct sctp_paramhdr {
|
||||
#define SCTP_DEFAULT_PRINFO 0x00000022
|
||||
#define SCTP_PEER_ADDR_THLDS 0x00000023
|
||||
#define SCTP_REMOTE_UDP_ENCAPS_PORT 0x00000024
|
||||
#define SCTP_ECN_SUPPORTED 0x00000025
|
||||
#define SCTP_PR_SUPPORTED 0x00000026
|
||||
#define SCTP_AUTH_SUPPORTED 0x00000027
|
||||
#define SCTP_ASCONF_SUPPORTED 0x00000028
|
||||
#define SCTP_RECONFIG_SUPPORTED 0x00000029
|
||||
#define SCTP_NRSACK_SUPPORTED 0x00000030
|
||||
#define SCTP_PKTDROP_SUPPORTED 0x00000031
|
||||
|
||||
/*
|
||||
* read-only options
|
||||
@ -143,6 +150,8 @@ struct sctp_paramhdr {
|
||||
#define SCTP_GET_ASSOC_NUMBER 0x00000104 /* ro */
|
||||
#define SCTP_GET_ASSOC_ID_LIST 0x00000105 /* ro */
|
||||
#define SCTP_TIMEOUTS 0x00000106
|
||||
#define SCTP_PR_STREAM_STATUS 0x00000107
|
||||
#define SCTP_PR_ASSOC_STATUS 0x00000108
|
||||
|
||||
/*
|
||||
* user socket options: BSD implementation specific
|
||||
@ -379,6 +388,12 @@ struct sctp_paramhdr {
|
||||
/*
|
||||
* error cause parameters (user visible)
|
||||
*/
|
||||
struct sctp_gen_error_cause {
|
||||
uint16_t code;
|
||||
uint16_t length;
|
||||
uint8_t info[];
|
||||
} SCTP_PACKED;
|
||||
|
||||
struct sctp_error_cause {
|
||||
uint16_t code;
|
||||
uint16_t length;
|
||||
@ -416,6 +431,11 @@ struct sctp_error_unrecognized_chunk {
|
||||
struct sctp_chunkhdr ch;/* header from chunk in error */
|
||||
} SCTP_PACKED;
|
||||
|
||||
struct sctp_error_no_user_data {
|
||||
struct sctp_error_cause cause; /* code=SCTP_CAUSE_NO_USER_DATA */
|
||||
uint32_t tsn; /* TSN of the empty data chunk */
|
||||
} SCTP_PACKED;
|
||||
|
||||
/*
|
||||
* Main SCTP chunk types we place these here so natd and f/w's in user land
|
||||
* can find them.
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 257803 2013-11-07 17:08:09Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 277347 2015-01-18 20:53:20Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -153,7 +153,7 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
|
||||
{
|
||||
struct sctp_nets *net;
|
||||
struct mbuf *m_reply = NULL;
|
||||
struct sockaddr_storage sa_store;
|
||||
union sctp_sockstore store;
|
||||
struct sctp_paramhdr *ph;
|
||||
uint16_t param_type, aparam_length;
|
||||
#if defined(INET) || defined(INET6)
|
||||
@ -177,7 +177,7 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
|
||||
#if defined(INET) || defined(INET6)
|
||||
param_length = ntohs(ph->param_length);
|
||||
#endif
|
||||
sa = (struct sockaddr *)&sa_store;
|
||||
sa = &store.sa;
|
||||
switch (param_type) {
|
||||
#ifdef INET
|
||||
case SCTP_IPV4_ADDRESS:
|
||||
@ -186,7 +186,7 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
|
||||
return (NULL);
|
||||
}
|
||||
v4addr = (struct sctp_ipv4addr_param *)ph;
|
||||
sin = (struct sockaddr_in *)&sa_store;
|
||||
sin = &store.sin;
|
||||
bzero(sin, sizeof(*sin));
|
||||
sin->sin_family = AF_INET;
|
||||
#ifdef HAVE_SIN_LEN
|
||||
@ -211,7 +211,7 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
|
||||
return (NULL);
|
||||
}
|
||||
v6addr = (struct sctp_ipv6addr_param *)ph;
|
||||
sin6 = (struct sockaddr_in6 *)&sa_store;
|
||||
sin6 = &store.sin6;
|
||||
bzero(sin6, sizeof(*sin6));
|
||||
sin6->sin6_family = AF_INET6;
|
||||
#ifdef HAVE_SIN6_LEN
|
||||
@ -307,7 +307,7 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
|
||||
struct sctp_tcb *stcb, int response_required)
|
||||
{
|
||||
struct mbuf *m_reply = NULL;
|
||||
struct sockaddr_storage sa_store;
|
||||
union sctp_sockstore store;
|
||||
struct sctp_paramhdr *ph;
|
||||
uint16_t param_type, aparam_length;
|
||||
#if defined(INET) || defined(INET6)
|
||||
@ -331,7 +331,7 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
|
||||
#if defined(INET) || defined(INET6)
|
||||
param_length = ntohs(ph->param_length);
|
||||
#endif
|
||||
sa = (struct sockaddr *)&sa_store;
|
||||
sa = &store.sa;
|
||||
switch (param_type) {
|
||||
#ifdef INET
|
||||
case SCTP_IPV4_ADDRESS:
|
||||
@ -340,7 +340,7 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
|
||||
return (NULL);
|
||||
}
|
||||
v4addr = (struct sctp_ipv4addr_param *)ph;
|
||||
sin = (struct sockaddr_in *)&sa_store;
|
||||
sin = &store.sin;
|
||||
bzero(sin, sizeof(*sin));
|
||||
sin->sin_family = AF_INET;
|
||||
#ifdef HAVE_SIN_LEN
|
||||
@ -362,7 +362,7 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
|
||||
return (NULL);
|
||||
}
|
||||
v6addr = (struct sctp_ipv6addr_param *)ph;
|
||||
sin6 = (struct sockaddr_in6 *)&sa_store;
|
||||
sin6 = &store.sin6;
|
||||
bzero(sin6, sizeof(*sin6));
|
||||
sin6->sin6_family = AF_INET6;
|
||||
#ifdef HAVE_SIN6_LEN
|
||||
@ -429,7 +429,7 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
|
||||
aparam_length);
|
||||
} else {
|
||||
if (response_required) {
|
||||
m_reply = sctp_asconf_success_response(aph->correlation_id);
|
||||
m_reply = sctp_asconf_success_response(aph->correlation_id);
|
||||
}
|
||||
/* notify upper layer */
|
||||
sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
|
||||
@ -443,7 +443,7 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
|
||||
struct sctp_tcb *stcb, int response_required)
|
||||
{
|
||||
struct mbuf *m_reply = NULL;
|
||||
struct sockaddr_storage sa_store;
|
||||
union sctp_sockstore store;
|
||||
struct sctp_paramhdr *ph;
|
||||
uint16_t param_type, aparam_length;
|
||||
#if defined(INET) || defined(INET6)
|
||||
@ -466,7 +466,7 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
|
||||
#if defined(INET) || defined(INET6)
|
||||
param_length = ntohs(ph->param_length);
|
||||
#endif
|
||||
sa = (struct sockaddr *)&sa_store;
|
||||
sa = &store.sa;
|
||||
switch (param_type) {
|
||||
#ifdef INET
|
||||
case SCTP_IPV4_ADDRESS:
|
||||
@ -475,7 +475,7 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
|
||||
return (NULL);
|
||||
}
|
||||
v4addr = (struct sctp_ipv4addr_param *)ph;
|
||||
sin = (struct sockaddr_in *)&sa_store;
|
||||
sin = &store.sin;
|
||||
bzero(sin, sizeof(*sin));
|
||||
sin->sin_family = AF_INET;
|
||||
#ifdef HAVE_SIN_LEN
|
||||
@ -495,7 +495,7 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
|
||||
return (NULL);
|
||||
}
|
||||
v6addr = (struct sctp_ipv6addr_param *)ph;
|
||||
sin6 = (struct sockaddr_in6 *)&sa_store;
|
||||
sin6 = &store.sin6;
|
||||
bzero(sin6, sizeof(*sin6));
|
||||
sin6->sin6_family = AF_INET6;
|
||||
#ifdef HAVE_SIN6_LEN
|
||||
@ -552,11 +552,11 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
|
||||
are transmitted to the new primary destination. (by micchie)
|
||||
*/
|
||||
if ((sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_BASE) ||
|
||||
SCTP_MOBILITY_BASE) ||
|
||||
sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_FASTHANDOFF)) &&
|
||||
SCTP_MOBILITY_FASTHANDOFF)) &&
|
||||
sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_PRIM_DELETED) &&
|
||||
SCTP_MOBILITY_PRIM_DELETED) &&
|
||||
(stcb->asoc.primary_destination->dest_state &
|
||||
SCTP_ADDR_UNCONFIRMED) == 0) {
|
||||
|
||||
@ -601,7 +601,7 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
|
||||
uint32_t serial_num;
|
||||
struct mbuf *n, *m_ack, *m_result, *m_tail;
|
||||
struct sctp_asconf_ack_chunk *ack_cp;
|
||||
struct sctp_asconf_paramhdr *aph, *ack_aph;
|
||||
struct sctp_asconf_paramhdr *aph;
|
||||
struct sctp_ipv6addr_param *p_addr;
|
||||
unsigned int asconf_limit, cnt;
|
||||
int error = 0; /* did an error occur? */
|
||||
@ -686,13 +686,6 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
|
||||
}
|
||||
/* param_length is already validated in process_control... */
|
||||
offset += ntohs(p_addr->ph.param_length); /* skip lookup addr */
|
||||
|
||||
/* get pointer to first asconf param in ASCONF-ACK */
|
||||
ack_aph = (struct sctp_asconf_paramhdr *)(mtod(m_ack, caddr_t) + sizeof(struct sctp_asconf_ack_chunk));
|
||||
if (ack_aph == NULL) {
|
||||
SCTPDBG(SCTP_DEBUG_ASCONF1, "Gak in asconf2\n");
|
||||
return;
|
||||
}
|
||||
/* get pointer to first asconf param in ASCONF */
|
||||
aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, sizeof(struct sctp_asconf_paramhdr), (uint8_t *)&aparam_buf);
|
||||
if (aph == NULL) {
|
||||
@ -731,13 +724,11 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
|
||||
}
|
||||
switch (param_type) {
|
||||
case SCTP_ADD_IP_ADDRESS:
|
||||
asoc->peer_supports_asconf = 1;
|
||||
m_result = sctp_process_asconf_add_ip(src, aph, stcb,
|
||||
(cnt < SCTP_BASE_SYSCTL(sctp_hb_maxburst)), error);
|
||||
cnt++;
|
||||
break;
|
||||
case SCTP_DEL_IP_ADDRESS:
|
||||
asoc->peer_supports_asconf = 1;
|
||||
m_result = sctp_process_asconf_delete_ip(src, aph, stcb,
|
||||
error);
|
||||
break;
|
||||
@ -745,7 +736,6 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
|
||||
/* not valid in an ASCONF chunk */
|
||||
break;
|
||||
case SCTP_SET_PRIM_ADDR:
|
||||
asoc->peer_supports_asconf = 1;
|
||||
m_result = sctp_process_asconf_set_primary(src, aph,
|
||||
stcb, error);
|
||||
break;
|
||||
@ -936,8 +926,6 @@ sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
|
||||
void
|
||||
sctp_asconf_cleanup(struct sctp_tcb *stcb, struct sctp_nets *net)
|
||||
{
|
||||
/* mark peer as ASCONF incapable */
|
||||
stcb->asoc.peer_supports_asconf = 0;
|
||||
/*
|
||||
* clear out any existing asconfs going out
|
||||
*/
|
||||
@ -1099,7 +1087,7 @@ sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
|
||||
}
|
||||
/* Retransmit unacknowledged DATA chunks immediately */
|
||||
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_FASTHANDOFF)) {
|
||||
SCTP_MOBILITY_FASTHANDOFF)) {
|
||||
sctp_net_immediate_retrans(stcb, net);
|
||||
}
|
||||
/* also, SET PRIMARY is maybe already sent */
|
||||
@ -1157,7 +1145,7 @@ sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
|
||||
continue;
|
||||
/* Retransmit unacknowledged DATA chunks immediately */
|
||||
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_FASTHANDOFF)) {
|
||||
SCTP_MOBILITY_FASTHANDOFF)) {
|
||||
sctp_net_immediate_retrans(stcb, net);
|
||||
}
|
||||
/* Send SET PRIMARY for this new address */
|
||||
@ -1193,9 +1181,9 @@ sctp_asconf_addr_mgmt_ack(struct sctp_tcb *stcb, struct sctp_ifa *addr, uint32_t
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Userspace__)
|
||||
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_BASE) ||
|
||||
SCTP_MOBILITY_BASE) ||
|
||||
sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_FASTHANDOFF)) {
|
||||
SCTP_MOBILITY_FASTHANDOFF)) {
|
||||
sctp_path_check_and_react(stcb, addr);
|
||||
return;
|
||||
}
|
||||
@ -1281,7 +1269,7 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
|
||||
{
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)&ifa->address.sa;
|
||||
sin6 = &ifa->address.sin6;
|
||||
aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
|
||||
aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
|
||||
aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
|
||||
@ -1296,7 +1284,7 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
|
||||
{
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
sin= (struct sockaddr_in *)&ifa->address.sa;
|
||||
sin = &ifa->address.sin;
|
||||
aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
|
||||
aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
|
||||
aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
|
||||
@ -1348,7 +1336,7 @@ sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
|
||||
int pending_delete_queued = 0;
|
||||
|
||||
/* see if peer supports ASCONF */
|
||||
if (stcb->asoc.peer_supports_asconf == 0) {
|
||||
if (stcb->asoc.asconf_supported == 0) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -1434,13 +1422,12 @@ sctp_asconf_queue_sa_delete(struct sctp_tcb *stcb, struct sockaddr *sa)
|
||||
{
|
||||
struct sctp_ifa *ifa;
|
||||
struct sctp_asconf_addr *aa, *aa_next;
|
||||
uint32_t vrf_id;
|
||||
|
||||
if (stcb == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
/* see if peer supports ASCONF */
|
||||
if (stcb->asoc.peer_supports_asconf == 0) {
|
||||
if (stcb->asoc.asconf_supported == 0) {
|
||||
return (-1);
|
||||
}
|
||||
/* make sure the request isn't already in the queue */
|
||||
@ -1466,12 +1453,7 @@ sctp_asconf_queue_sa_delete(struct sctp_tcb *stcb, struct sockaddr *sa)
|
||||
} /* for each aa */
|
||||
|
||||
/* find any existing ifa-- NOTE ifa CAN be allowed to be NULL */
|
||||
if (stcb) {
|
||||
vrf_id = stcb->asoc.vrf_id;
|
||||
} else {
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
}
|
||||
ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
|
||||
ifa = sctp_find_ifa_by_addr(sa, stcb->asoc.vrf_id, SCTP_ADDR_NOT_LOCKED);
|
||||
|
||||
/* adding new request to the queue */
|
||||
SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
|
||||
@ -1560,7 +1542,7 @@ sctp_asconf_find_param(struct sctp_tcb *stcb, uint32_t correlation_id)
|
||||
* notifications based on the error response
|
||||
*/
|
||||
static void
|
||||
sctp_asconf_process_error(struct sctp_tcb *stcb,
|
||||
sctp_asconf_process_error(struct sctp_tcb *stcb SCTP_UNUSED,
|
||||
struct sctp_asconf_paramhdr *aph)
|
||||
{
|
||||
struct sctp_error_cause *eh;
|
||||
@ -1598,10 +1580,7 @@ sctp_asconf_process_error(struct sctp_tcb *stcb,
|
||||
switch (param_type) {
|
||||
case SCTP_ADD_IP_ADDRESS:
|
||||
case SCTP_DEL_IP_ADDRESS:
|
||||
stcb->asoc.peer_supports_asconf = 0;
|
||||
break;
|
||||
case SCTP_SET_PRIM_ADDR:
|
||||
stcb->asoc.peer_supports_asconf = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1637,8 +1616,6 @@ sctp_asconf_process_param_ack(struct sctp_tcb *stcb,
|
||||
SCTPDBG(SCTP_DEBUG_ASCONF1,
|
||||
"process_param_ack: set primary IP address\n");
|
||||
/* nothing to do... peer may start using this addr */
|
||||
if (flag == 0)
|
||||
stcb->asoc.peer_supports_asconf = 0;
|
||||
break;
|
||||
default:
|
||||
/* should NEVER happen */
|
||||
@ -1656,11 +1633,11 @@ sctp_asconf_process_param_ack(struct sctp_tcb *stcb,
|
||||
* cleanup from a bad asconf ack parameter
|
||||
*/
|
||||
static void
|
||||
sctp_asconf_ack_clear(struct sctp_tcb *stcb)
|
||||
sctp_asconf_ack_clear(struct sctp_tcb *stcb SCTP_UNUSED)
|
||||
{
|
||||
/* assume peer doesn't really know how to do asconfs */
|
||||
stcb->asoc.peer_supports_asconf = 0;
|
||||
/* XXX we could free the pending queue here */
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@ -1900,14 +1877,26 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
* this is boundall or subset bound w/ASCONF allowed
|
||||
*/
|
||||
|
||||
/* first, make sure it's a good address family */
|
||||
/* first, make sure that the address is IPv4 or IPv6 and not jailed */
|
||||
switch (ifa->address.sa.sa_family) {
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
#if defined(__FreeBSD__)
|
||||
if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
|
||||
&ifa->address.sin6.sin6_addr) != 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
#if defined(__FreeBSD__)
|
||||
if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
|
||||
&ifa->address.sin.sin_addr) != 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
@ -1938,7 +1927,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
{
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
|
||||
sin6 = &ifa->address.sin6;
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
||||
/* we skip unspecifed addresses */
|
||||
return;
|
||||
@ -1971,7 +1960,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
SCTP_IPV6_V6ONLY(inp6))
|
||||
return;
|
||||
|
||||
sin = (struct sockaddr_in *)&ifa->address.sa;
|
||||
sin = &ifa->address.sin;
|
||||
if (sin->sin_addr.s_addr == 0) {
|
||||
/* we skip unspecifed addresses */
|
||||
return;
|
||||
@ -1991,7 +1980,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
/* queue an asconf for this address add/delete */
|
||||
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
|
||||
/* does the peer do asconf? */
|
||||
if (stcb->asoc.peer_supports_asconf) {
|
||||
if (stcb->asoc.asconf_supported) {
|
||||
/* queue an asconf for this addr */
|
||||
status = sctp_asconf_queue_add(stcb, ifa, type);
|
||||
|
||||
@ -2129,11 +2118,17 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
else
|
||||
continue;
|
||||
}
|
||||
sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
|
||||
sin6 = &ifa->address.sin6;
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
||||
/* we skip unspecifed addresses */
|
||||
continue;
|
||||
}
|
||||
#if defined(__FreeBSD__)
|
||||
if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
|
||||
&sin6->sin6_addr) != 0) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
|
||||
if (stcb->asoc.scope.local_scope == 0) {
|
||||
continue;
|
||||
@ -2159,11 +2154,17 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
SCTP_IPV6_V6ONLY(inp6))
|
||||
continue;
|
||||
|
||||
sin = (struct sockaddr_in *)&ifa->address.sa;
|
||||
sin = &ifa->address.sin;
|
||||
if (sin->sin_addr.s_addr == 0) {
|
||||
/* we skip unspecifed addresses */
|
||||
continue;
|
||||
}
|
||||
#if defined(__FreeBSD__)
|
||||
if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
|
||||
&sin->sin_addr) != 0) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (stcb->asoc.scope.ipv4_local_scope == 0 &&
|
||||
IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
|
||||
continue;
|
||||
@ -2221,7 +2222,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
} else if (type == SCTP_SET_PRIM_ADDR) {
|
||||
if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
|
||||
/* must validate the ifa is in the ep */
|
||||
if (sctp_is_addr_in_ep(stcb->sctp_ep,ifa) == 0) {
|
||||
if (sctp_is_addr_in_ep(stcb->sctp_ep, ifa) == 0) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
@ -2233,7 +2234,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
}
|
||||
/* queue an asconf for this address add/delete */
|
||||
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF) &&
|
||||
stcb->asoc.peer_supports_asconf) {
|
||||
stcb->asoc.asconf_supported == 1) {
|
||||
/* queue an asconf for this addr */
|
||||
status = sctp_asconf_queue_add(stcb, ifa, type);
|
||||
/*
|
||||
@ -2284,7 +2285,7 @@ sctp_asconf_iterator_end(void *ptr, uint32_t val SCTP_UNUSED)
|
||||
int32_t
|
||||
sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
|
||||
{
|
||||
uint32_t vrf_id;
|
||||
uint32_t vrf_id;
|
||||
struct sctp_ifa *ifa;
|
||||
|
||||
/* find the ifa for the desired set primary */
|
||||
@ -2472,11 +2473,17 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
|
||||
if (stcb->asoc.scope.ipv4_addr_legal) {
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
|
||||
sin = &sctp_ifa->address.sin;
|
||||
if (sin->sin_addr.s_addr == 0) {
|
||||
/* skip unspecifed addresses */
|
||||
continue;
|
||||
}
|
||||
#if defined(__FreeBSD__)
|
||||
if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
|
||||
&sin->sin_addr) != 0) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (stcb->asoc.scope.ipv4_local_scope == 0 &&
|
||||
IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))
|
||||
continue;
|
||||
@ -2500,11 +2507,17 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
|
||||
continue;
|
||||
}
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
|
||||
sin6 = &sctp_ifa->address.sin6;
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
||||
/* we skip unspecifed addresses */
|
||||
continue;
|
||||
}
|
||||
#if defined(__FreeBSD__)
|
||||
if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
|
||||
&sin6->sin6_addr) != 0) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (stcb->asoc.scope.local_scope == 0 &&
|
||||
IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
|
||||
continue;
|
||||
@ -2762,16 +2775,13 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
struct sctp_paramhdr tmp_param, *ph;
|
||||
uint16_t plen, ptype;
|
||||
struct sctp_ifa *sctp_ifa;
|
||||
union sctp_sockstore store;
|
||||
#ifdef INET6
|
||||
struct sctp_ipv6addr_param addr6_store;
|
||||
struct sockaddr_in6 sin6;
|
||||
#endif
|
||||
#ifdef INET
|
||||
struct sctp_ipv4addr_param addr4_store;
|
||||
struct sockaddr_in sin;
|
||||
#endif
|
||||
struct sockaddr *sa;
|
||||
uint32_t vrf_id;
|
||||
|
||||
SCTPDBG(SCTP_DEBUG_ASCONF2, "processing init-ack addresses\n");
|
||||
if (stcb == NULL) /* Un-needed check for SA */
|
||||
@ -2783,25 +2793,6 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
if ((offset + sizeof(struct sctp_paramhdr)) > length) {
|
||||
return;
|
||||
}
|
||||
/* init the addresses */
|
||||
#ifdef INET6
|
||||
bzero(&sin6, sizeof(sin6));
|
||||
sin6.sin6_family = AF_INET6;
|
||||
#ifdef HAVE_SIN6_LEN
|
||||
sin6.sin6_len = sizeof(sin6);
|
||||
#endif
|
||||
sin6.sin6_port = stcb->rport;
|
||||
#endif
|
||||
|
||||
#ifdef INET
|
||||
bzero(&sin, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
#ifdef HAVE_SIN_LEN
|
||||
sin.sin_len = sizeof(sin);
|
||||
#endif
|
||||
sin.sin_port = stcb->rport;
|
||||
#endif
|
||||
|
||||
/* go through the addresses in the init-ack */
|
||||
ph = (struct sctp_paramhdr *)
|
||||
sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
|
||||
@ -2824,9 +2815,13 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
a6p == NULL) {
|
||||
return;
|
||||
}
|
||||
memcpy(&sin6.sin6_addr, a6p->addr,
|
||||
sizeof(struct in6_addr));
|
||||
sa = (struct sockaddr *)&sin6;
|
||||
memset(&store, 0, sizeof(union sctp_sockstore));
|
||||
store.sin6.sin6_family = AF_INET6;
|
||||
#ifdef HAVE_SIN6_LEN
|
||||
store.sin6.sin6_len = sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
store.sin6.sin6_port = stcb->rport;
|
||||
memcpy(&store.sin6.sin6_addr, a6p->addr, sizeof(struct in6_addr));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -2843,8 +2838,13 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
a4p == NULL) {
|
||||
return;
|
||||
}
|
||||
sin.sin_addr.s_addr = a4p->addr;
|
||||
sa = (struct sockaddr *)&sin;
|
||||
memset(&store, 0, sizeof(union sctp_sockstore));
|
||||
store.sin.sin_family = AF_INET;
|
||||
#ifdef HAVE_SIN_LEN
|
||||
store.sin.sin_len = sizeof(struct sockaddr_in);
|
||||
#endif
|
||||
store.sin.sin_port = stcb->rport;
|
||||
store.sin.sin_addr.s_addr = a4p->addr;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -2853,12 +2853,7 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
}
|
||||
|
||||
/* see if this address really (still) exists */
|
||||
if (stcb) {
|
||||
vrf_id = stcb->asoc.vrf_id;
|
||||
} else {
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
}
|
||||
sctp_ifa = sctp_find_ifa_by_addr(sa, vrf_id,
|
||||
sctp_ifa = sctp_find_ifa_by_addr(&store.sa, stcb->asoc.vrf_id,
|
||||
SCTP_ADDR_NOT_LOCKED);
|
||||
if (sctp_ifa == NULL) {
|
||||
/* address doesn't exist anymore */
|
||||
@ -2867,9 +2862,9 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
/* are ASCONFs allowed ? */
|
||||
if ((sctp_is_feature_on(stcb->sctp_ep,
|
||||
SCTP_PCB_FLAGS_DO_ASCONF)) &&
|
||||
stcb->asoc.peer_supports_asconf) {
|
||||
stcb->asoc.asconf_supported) {
|
||||
/* queue an ASCONF DEL_IP_ADDRESS */
|
||||
status = sctp_asconf_queue_sa_delete(stcb, sa);
|
||||
status = sctp_asconf_queue_sa_delete(stcb, &store.sa);
|
||||
/*
|
||||
* if queued ok, and in correct state, send
|
||||
* out the ASCONF.
|
||||
@ -2903,7 +2898,7 @@ next_addr:
|
||||
if ((offset + sizeof(struct sctp_paramhdr)) > length)
|
||||
return;
|
||||
ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
|
||||
sizeof(struct sctp_paramhdr), (uint8_t *) & tmp_param);
|
||||
sizeof(struct sctp_paramhdr), (uint8_t *)&tmp_param);
|
||||
} /* while */
|
||||
}
|
||||
|
||||
@ -3115,7 +3110,13 @@ sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
|
||||
switch (sctp_ifa->address.sa.sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
sin = (struct sockaddr_in *)&sctp_ifa->address.sin;
|
||||
sin = &sctp_ifa->address.sin;
|
||||
#if defined(__FreeBSD__)
|
||||
if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
|
||||
&sin->sin_addr) != 0) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if ((ipv4_scope == 0) &&
|
||||
(IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
|
||||
/* private address not in scope */
|
||||
@ -3125,7 +3126,13 @@ sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sin6;
|
||||
sin6 = &sctp_ifa->address.sin6;
|
||||
#if defined(__FreeBSD__)
|
||||
if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
|
||||
&sin6->sin6_addr) != 0) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if ((local_scope == 0) &&
|
||||
(IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
|
||||
continue;
|
||||
@ -3202,7 +3209,7 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
|
||||
#endif
|
||||
if (sctp_ifap) {
|
||||
ifa = sctp_ifap;
|
||||
} else if (type == SCTP_ADD_IP_ADDRESS) {
|
||||
} else if (type == SCTP_ADD_IP_ADDRESS) {
|
||||
/* For an add the address MUST be on the system */
|
||||
ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
|
||||
} else if (type == SCTP_DEL_IP_ADDRESS) {
|
||||
@ -3360,6 +3367,11 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
|
||||
TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
SCTPDBG(SCTP_DEBUG_ASCONF1,
|
||||
"sctp_asconf_send_nat_state_update: unknown address family\n");
|
||||
SCTP_FREE(aa, SCTP_M_ASC_ADDR);
|
||||
return;
|
||||
}
|
||||
SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
|
||||
SCTP_M_ASC_ADDR);
|
||||
@ -3393,6 +3405,11 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
|
||||
TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
SCTPDBG(SCTP_DEBUG_ASCONF1,
|
||||
"sctp_asconf_send_nat_state_update: unknown address family\n");
|
||||
SCTP_FREE(aa, SCTP_M_ASC_ADDR);
|
||||
return;
|
||||
}
|
||||
/* Now we must hunt the addresses and add all global addresses */
|
||||
if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
|
||||
@ -3413,6 +3430,12 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
to = &sctp_ifap->address.sin;
|
||||
#if defined(__FreeBSD__)
|
||||
if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
|
||||
&to->sin_addr) != 0) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
|
||||
continue;
|
||||
}
|
||||
@ -3424,6 +3447,12 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
to6 = &sctp_ifap->address.sin6;
|
||||
#if defined(__FreeBSD__)
|
||||
if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
|
||||
&to6->sin6_addr) != 0) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.c 257804 2013-11-07 18:50:11Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.c 271673 2014-09-16 14:20:33Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -135,11 +135,6 @@ sctp_auth_delete_chunk(uint8_t chunk, sctp_auth_chklist_t *list)
|
||||
if (list == NULL)
|
||||
return (-1);
|
||||
|
||||
/* is chunk restricted? */
|
||||
if ((chunk == SCTP_ASCONF) ||
|
||||
(chunk == SCTP_ASCONF_ACK)) {
|
||||
return (-1);
|
||||
}
|
||||
if (list->chunks[chunk] == 1) {
|
||||
list->chunks[chunk] = 0;
|
||||
list->num_chunks--;
|
||||
@ -159,16 +154,6 @@ sctp_auth_get_chklist_size(const sctp_auth_chklist_t *list)
|
||||
return (list->num_chunks);
|
||||
}
|
||||
|
||||
/*
|
||||
* set the default list of chunks requiring AUTH
|
||||
*/
|
||||
void
|
||||
sctp_auth_set_default_chunks(sctp_auth_chklist_t *list)
|
||||
{
|
||||
(void)sctp_auth_add_chunk(SCTP_ASCONF, list);
|
||||
(void)sctp_auth_add_chunk(SCTP_ASCONF_ACK, list);
|
||||
}
|
||||
|
||||
/*
|
||||
* return the current number and list of required chunks caller must
|
||||
* guarantee ptr has space for up to 256 bytes
|
||||
@ -397,9 +382,9 @@ sctp_compare_key(sctp_key_t *key1, sctp_key_t *key2)
|
||||
val1 = (i < (maxlen - key1len)) ? 0 : *(key_1++);
|
||||
val2 = (i < (maxlen - key2len)) ? 0 : *(key_2++);
|
||||
if (val1 > val2) {
|
||||
return (1);
|
||||
return (1);
|
||||
} else if (val1 < val2) {
|
||||
return (-1);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
/* keys are equal value, so check lengths */
|
||||
@ -648,7 +633,7 @@ sctp_copy_skeylist(const struct sctp_keyhead *src, struct sctp_keyhead *dest)
|
||||
|
||||
|
||||
sctp_hmaclist_t *
|
||||
sctp_alloc_hmaclist(uint8_t num_hmacs)
|
||||
sctp_alloc_hmaclist(uint16_t num_hmacs)
|
||||
{
|
||||
sctp_hmaclist_t *new_list;
|
||||
int alloc_size;
|
||||
@ -800,7 +785,7 @@ sctp_verify_hmac_param (struct sctp_auth_hmac_algo *hmacs, uint32_t num_hmacs)
|
||||
|
||||
for (i = 0; i < num_hmacs; i++) {
|
||||
if (ntohs(hmacs->hmac_ids[i]) == SCTP_AUTH_HMAC_ID_SHA1) {
|
||||
return (0);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
return (-1);
|
||||
@ -1479,8 +1464,8 @@ sctp_auth_get_cookie_params(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
p_random = (struct sctp_auth_random *)phdr;
|
||||
random_len = plen - sizeof(*p_random);
|
||||
} else if (ptype == SCTP_HMAC_LIST) {
|
||||
int num_hmacs;
|
||||
int i;
|
||||
uint16_t num_hmacs;
|
||||
uint16_t i;
|
||||
|
||||
if (plen > sizeof(hmacs_store))
|
||||
break;
|
||||
@ -1554,7 +1539,7 @@ sctp_auth_get_cookie_params(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
}
|
||||
}
|
||||
if (stcb->asoc.authinfo.random != NULL)
|
||||
sctp_free_key(stcb->asoc.authinfo.random);
|
||||
sctp_free_key(stcb->asoc.authinfo.random);
|
||||
stcb->asoc.authinfo.random = new_key;
|
||||
stcb->asoc.authinfo.random_len = random_len;
|
||||
sctp_clear_cachedkeys(stcb, stcb->asoc.authinfo.assoc_keyid);
|
||||
@ -1818,6 +1803,7 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
|
||||
|
||||
SCTP_BUF_LEN(m_notify) = 0;
|
||||
auth = mtod(m_notify, struct sctp_authkey_event *);
|
||||
memset(auth, 0, sizeof(struct sctp_authkey_event));
|
||||
auth->auth_type = SCTP_AUTHENTICATION_EVENT;
|
||||
auth->auth_flags = 0;
|
||||
auth->auth_length = sizeof(*auth);
|
||||
@ -1975,8 +1961,7 @@ sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
|
||||
"SCTP: peer sent chunk list w/o AUTH\n");
|
||||
return (-1);
|
||||
}
|
||||
if (!SCTP_BASE_SYSCTL(sctp_asconf_auth_nochk) && peer_supports_asconf &&
|
||||
!peer_supports_auth) {
|
||||
if (peer_supports_asconf && !peer_supports_auth) {
|
||||
SCTPDBG(SCTP_DEBUG_AUTH1,
|
||||
"SCTP: peer supports ASCONF but not AUTH\n");
|
||||
return (-1);
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.h 257804 2013-11-07 18:50:11Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.h 271673 2014-09-16 14:20:33Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_AUTH_H_
|
||||
@ -116,7 +116,6 @@ extern sctp_auth_chklist_t *sctp_copy_chunklist(sctp_auth_chklist_t *chklist);
|
||||
extern int sctp_auth_add_chunk(uint8_t chunk, sctp_auth_chklist_t *list);
|
||||
extern int sctp_auth_delete_chunk(uint8_t chunk, sctp_auth_chklist_t *list);
|
||||
extern size_t sctp_auth_get_chklist_size(const sctp_auth_chklist_t *list);
|
||||
extern void sctp_auth_set_default_chunks(sctp_auth_chklist_t *list);
|
||||
extern int sctp_serialize_auth_chunks(const sctp_auth_chklist_t *list,
|
||||
uint8_t *ptr);
|
||||
extern int sctp_pack_auth_chunks(const sctp_auth_chklist_t *list,
|
||||
@ -150,7 +149,7 @@ extern void sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t keyid,
|
||||
|
||||
|
||||
/* hmac list handling */
|
||||
extern sctp_hmaclist_t *sctp_alloc_hmaclist(uint8_t num_hmacs);
|
||||
extern sctp_hmaclist_t *sctp_alloc_hmaclist(uint16_t num_hmacs);
|
||||
extern void sctp_free_hmaclist(sctp_hmaclist_t *list);
|
||||
extern int sctp_auth_add_hmacid(sctp_hmaclist_t *list, uint16_t hmac_id);
|
||||
extern sctp_hmaclist_t *sctp_copy_hmaclist(sctp_hmaclist_t *list);
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 258765 2013-11-30 12:51:19Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 276914 2015-01-10 20:49:57Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -48,14 +48,9 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 258765 2013-11-30 12:51:19Z
|
||||
#include <netinet/sctp_asconf.h>
|
||||
#include <netinet/sctp_sysctl.h>
|
||||
#include <netinet/sctp_indata.h>
|
||||
#if defined(ANDROID)
|
||||
#include <unistd.h>
|
||||
#include <ifaddrs-android-ext.h>
|
||||
#else
|
||||
#if defined(__FreeBSD__)
|
||||
#include <sys/unistd.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Declare all of our malloc named types */
|
||||
#ifndef __Panda__
|
||||
@ -360,7 +355,7 @@ sctp_init_ifns_for_vrf(int vrfid)
|
||||
continue;
|
||||
}
|
||||
ifa = (struct ifaddrs*)malloc(sizeof(struct ifaddrs));
|
||||
ifa->ifa_name = strdup(pAdapt->AdapterName);
|
||||
ifa->ifa_name = _strdup(pAdapt->AdapterName);
|
||||
ifa->ifa_flags = pAdapt->Flags;
|
||||
ifa->ifa_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in));
|
||||
memcpy(ifa->ifa_addr, pUnicast->Address.lpSockaddr, sizeof(struct sockaddr_in));
|
||||
@ -408,7 +403,7 @@ sctp_init_ifns_for_vrf(int vrfid)
|
||||
if (pAdapt->IfType == IF_TYPE_IEEE80211 || pAdapt->IfType == IF_TYPE_ETHERNET_CSMACD) {
|
||||
for (pUnicast = pAdapt->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
|
||||
ifa = (struct ifaddrs*)malloc(sizeof(struct ifaddrs));
|
||||
ifa->ifa_name = strdup(pAdapt->AdapterName);
|
||||
ifa->ifa_name = _strdup(pAdapt->AdapterName);
|
||||
ifa->ifa_flags = pAdapt->Flags;
|
||||
ifa->ifa_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in6));
|
||||
memcpy(ifa->ifa_addr, pUnicast->Address.lpSockaddr, sizeof(struct sockaddr_in6));
|
||||
@ -750,7 +745,7 @@ sctp_addr_change(struct ifaddr *ifa, int cmd)
|
||||
ifa->ifa_ifp->if_index,
|
||||
ifa->ifa_ifp->if_xname);
|
||||
#endif
|
||||
|
||||
|
||||
/* We don't bump refcount here so when it completes
|
||||
* the final delete will happen.
|
||||
*/
|
||||
@ -842,24 +837,41 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
|
||||
}
|
||||
|
||||
if (SCTP_BUF_IS_EXTENDED(m) == 0) {
|
||||
sctp_m_freem(m);
|
||||
return (NULL);
|
||||
sctp_m_freem(m);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
SCTP_BUF_LEN(m) = 0;
|
||||
SCTP_BUF_NEXT(m) = SCTP_BUF_NEXT_PKT(m) = NULL;
|
||||
|
||||
#if defined(__Userspace__)
|
||||
/* __Userspace__
|
||||
* Check if anything need to be done to ensure logging works
|
||||
*/
|
||||
#endif
|
||||
#ifdef SCTP_MBUF_LOGGING
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
|
||||
if (SCTP_BUF_IS_EXTENDED(m)) {
|
||||
sctp_log_mb(m, SCTP_MBUF_IALLOC);
|
||||
sctp_log_mb(m, SCTP_MBUF_IALLOC);
|
||||
}
|
||||
#endif
|
||||
#elif defined(__FreeBSD__) && __FreeBSD_version > 1100052
|
||||
m = m_getm2(NULL, space_needed, how, type, want_header ? M_PKTHDR : 0);
|
||||
if (m == NULL) {
|
||||
/* bad, no memory */
|
||||
return (m);
|
||||
}
|
||||
if (allonebuf) {
|
||||
if (SCTP_BUF_SIZE(m) < space_needed) {
|
||||
m_freem(m);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
if (SCTP_BUF_NEXT(m)) {
|
||||
sctp_m_freem(SCTP_BUF_NEXT(m));
|
||||
SCTP_BUF_NEXT(m) = NULL;
|
||||
}
|
||||
#ifdef SCTP_MBUF_LOGGING
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
|
||||
sctp_log_mb(m, SCTP_MBUF_IALLOC);
|
||||
}
|
||||
#endif
|
||||
#elif defined(__FreeBSD__) && __FreeBSD_version > 602000
|
||||
m = m_getm2(NULL, space_needed, how, type, want_header ? M_PKTHDR : 0);
|
||||
@ -883,14 +895,12 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
|
||||
}
|
||||
}
|
||||
if (SCTP_BUF_NEXT(m)) {
|
||||
sctp_m_freem( SCTP_BUF_NEXT(m));
|
||||
sctp_m_freem(SCTP_BUF_NEXT(m));
|
||||
SCTP_BUF_NEXT(m) = NULL;
|
||||
}
|
||||
#ifdef SCTP_MBUF_LOGGING
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
|
||||
if (SCTP_BUF_IS_EXTENDED(m)) {
|
||||
sctp_log_mb(m, SCTP_MBUF_IALLOC);
|
||||
}
|
||||
sctp_log_mb(m, SCTP_MBUF_IALLOC);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
@ -951,9 +961,7 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
|
||||
SCTP_BUF_NEXT(m) = SCTP_BUF_NEXT_PKT(m) = NULL;
|
||||
#ifdef SCTP_MBUF_LOGGING
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
|
||||
if (SCTP_BUF_IS_EXTENDED(m)) {
|
||||
sctp_log_mb(m, SCTP_MBUF_IALLOC);
|
||||
}
|
||||
sctp_log_mb(m, SCTP_MBUF_IALLOC);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -64,10 +64,8 @@ extern int ticks;
|
||||
/*
|
||||
* SCTP_TIMERQ_LOCK protects:
|
||||
* - SCTP_BASE_INFO(callqueue)
|
||||
* - sctp_os_timer_current: current timer in process
|
||||
* - sctp_os_timer_next: next timer to check
|
||||
*/
|
||||
static sctp_os_timer_t *sctp_os_timer_current = NULL;
|
||||
static sctp_os_timer_t *sctp_os_timer_next = NULL;
|
||||
|
||||
void
|
||||
@ -153,11 +151,9 @@ sctp_handle_tick(int delta)
|
||||
c_func = c->c_func;
|
||||
c_arg = c->c_arg;
|
||||
c->c_flags &= ~SCTP_CALLOUT_PENDING;
|
||||
sctp_os_timer_current = c;
|
||||
SCTP_TIMERQ_UNLOCK();
|
||||
c_func(c_arg);
|
||||
SCTP_TIMERQ_LOCK();
|
||||
sctp_os_timer_current = NULL;
|
||||
c = sctp_os_timer_next;
|
||||
} else {
|
||||
c = TAILQ_NEXT(c, tqe);
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_cc_functions.c 240158 2012-09-06 07:03:56Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_cc_functions.c 271672 2014-09-16 13:48:46Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -1218,12 +1218,9 @@ sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb,
|
||||
uint32_t *bottle_bw, uint32_t *on_queue)
|
||||
{
|
||||
uint32_t bw_avail;
|
||||
int rtt;
|
||||
unsigned int incr;
|
||||
int old_cwnd = net->cwnd;
|
||||
|
||||
/* need real RTT in msd for this calc */
|
||||
rtt = net->rtt / 1000;
|
||||
/* get bottle neck bw */
|
||||
*bottle_bw = ntohl(cp->bottle_bw);
|
||||
/* and whats on queue */
|
||||
@ -1232,10 +1229,11 @@ sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb,
|
||||
* adjust the on-queue if our flight is more it could be
|
||||
* that the router has not yet gotten data "in-flight" to it
|
||||
*/
|
||||
if (*on_queue < net->flight_size)
|
||||
if (*on_queue < net->flight_size) {
|
||||
*on_queue = net->flight_size;
|
||||
/* calculate the available space */
|
||||
bw_avail = (*bottle_bw * rtt) / 1000;
|
||||
}
|
||||
/* rtt is measured in micro seconds, bottle_bw in bytes per second */
|
||||
bw_avail = (uint32_t)(((uint64_t)(*bottle_bw) * net->rtt) / (uint64_t)1000000);
|
||||
if (bw_avail > *bottle_bw) {
|
||||
/*
|
||||
* Cap the growth to no more than the bottle neck.
|
||||
@ -1253,8 +1251,8 @@ sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb,
|
||||
* else to be "added to the fire".
|
||||
*/
|
||||
int seg_inflight, seg_onqueue, my_portion;
|
||||
net->partial_bytes_acked = 0;
|
||||
|
||||
net->partial_bytes_acked = 0;
|
||||
/* how much are we over queue size? */
|
||||
incr = *on_queue - bw_avail;
|
||||
if (stcb->asoc.seen_a_sack_this_pkt) {
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_constants.h 256556 2013-10-15 20:21:27Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_constants.h 271204 2014-09-06 19:12:14Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_CONSTANTS_H_
|
||||
@ -41,20 +41,10 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_constants.h 256556 2013-10-15 20:21:27
|
||||
#if defined(__Userspace_os_Windows)
|
||||
extern void getwintimeofday(struct timeval *tv);
|
||||
#endif
|
||||
|
||||
/* IANA assigned port number for SCTP over UDP encapsulation */
|
||||
#ifdef __FreeBSD__
|
||||
/* For freebsd we cannot bind the port at
|
||||
* startup. Otherwise what will happen is
|
||||
* we really won't be bound. The user must
|
||||
* put it into the sysctl... or we need
|
||||
* to build a special timer for this to allow
|
||||
* us to wait 1 second or so after the system
|
||||
* comes up.
|
||||
*/
|
||||
#define SCTP_OVER_UDP_TUNNELING_PORT 0
|
||||
#else
|
||||
#define SCTP_OVER_UDP_TUNNELING_PORT 9899
|
||||
#endif
|
||||
|
||||
/* Number of packets to get before sack sent by default */
|
||||
#define SCTP_DEFAULT_SACK_FREQ 2
|
||||
|
||||
@ -282,42 +272,9 @@ extern void getwintimeofday(struct timeval *tv);
|
||||
/* how many addresses per assoc remote and local */
|
||||
#define SCTP_SCALE_FOR_ADDR 2
|
||||
|
||||
/* default AUTO_ASCONF mode enable(1)/disable(0) value (sysctl) */
|
||||
#if defined(__APPLE__)
|
||||
#if !defined(SCTP_APPLE_AUTO_ASCONF)
|
||||
#define SCTP_DEFAULT_AUTO_ASCONF 0
|
||||
#else
|
||||
#define SCTP_DEFAULT_AUTO_ASCONF 1
|
||||
#endif
|
||||
#else
|
||||
#define SCTP_DEFAULT_AUTO_ASCONF 1
|
||||
#endif
|
||||
|
||||
/* default MULTIPLE_ASCONF mode enable(1)/disable(0) value (sysctl) */
|
||||
#define SCTP_DEFAULT_MULTIPLE_ASCONFS 0
|
||||
|
||||
/* default MOBILITY_BASE mode enable(1)/disable(0) value (sysctl) */
|
||||
#if defined(__APPLE__)
|
||||
#if !defined(SCTP_APPLE_MOBILITY_BASE)
|
||||
#define SCTP_DEFAULT_MOBILITY_BASE 0
|
||||
#else
|
||||
#define SCTP_DEFAULT_MOBILITY_BASE 1
|
||||
#endif
|
||||
#else
|
||||
#define SCTP_DEFAULT_MOBILITY_BASE 0
|
||||
#endif
|
||||
|
||||
/* default MOBILITY_FASTHANDOFF mode enable(1)/disable(0) value (sysctl) */
|
||||
#if defined(__APPLE__)
|
||||
#if !defined(SCTP_APPLE_MOBILITY_FASTHANDOFF)
|
||||
#define SCTP_DEFAULT_MOBILITY_FASTHANDOFF 0
|
||||
#else
|
||||
#define SCTP_DEFAULT_MOBILITY_FASTHANDOFF 1
|
||||
#endif
|
||||
#else
|
||||
#define SCTP_DEFAULT_MOBILITY_FASTHANDOFF 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Theshold for rwnd updates, we have to read (sb_hiwat >>
|
||||
* SCTP_RWND_HIWAT_SHIFT) before we will look to see if we need to send a
|
||||
@ -819,6 +776,9 @@ extern void getwintimeofday(struct timeval *tv);
|
||||
*/
|
||||
#define SCTP_DEFAULT_SPLIT_POINT_MIN 2904
|
||||
|
||||
/* Maximum length of diagnostic information in error causes */
|
||||
#define SCTP_DIAG_INFO_LEN 64
|
||||
|
||||
/* ABORT CODES and other tell-tale location
|
||||
* codes are generated by adding the below
|
||||
* to the instance id.
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_header.h 240198 2012-09-07 13:36:42Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_header.h 273168 2014-10-16 15:36:04Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_HEADER_H_
|
||||
@ -94,12 +94,6 @@ struct sctp_supported_addr_param {
|
||||
uint16_t addr_type[2]; /* array of supported address types */
|
||||
} SCTP_PACKED;
|
||||
|
||||
/* ECN parameter */
|
||||
struct sctp_ecn_supported_param {
|
||||
struct sctp_paramhdr ph;/* type=SCTP_ECN_CAPABLE */
|
||||
} SCTP_PACKED;
|
||||
|
||||
|
||||
/* heartbeat info parameter */
|
||||
struct sctp_heartbeat_info_param {
|
||||
struct sctp_paramhdr ph;
|
||||
@ -474,6 +468,11 @@ struct sctp_pktdrop_chunk {
|
||||
|
||||
/**********STREAM RESET STUFF ******************/
|
||||
|
||||
struct sctp_stream_reset_request {
|
||||
struct sctp_paramhdr ph;
|
||||
uint32_t request_seq;
|
||||
} SCTP_PACKED;
|
||||
|
||||
struct sctp_stream_reset_out_request {
|
||||
struct sctp_paramhdr ph;
|
||||
uint32_t request_seq; /* monotonically increasing seq no */
|
||||
@ -488,7 +487,6 @@ struct sctp_stream_reset_in_request {
|
||||
uint16_t list_of_streams[]; /* if not all list of streams */
|
||||
} SCTP_PACKED;
|
||||
|
||||
|
||||
struct sctp_stream_reset_tsn_request {
|
||||
struct sctp_paramhdr ph;
|
||||
uint32_t request_seq;
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.h 240198 2012-09-07 13:36:42Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.h 273168 2014-10-16 15:36:04Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_INPUT_H_
|
||||
@ -52,7 +52,7 @@ sctp_common_input_processing(struct mbuf **, int, int, int,
|
||||
#endif
|
||||
uint32_t, uint16_t);
|
||||
|
||||
struct sctp_stream_reset_out_request *
|
||||
struct sctp_stream_reset_request *
|
||||
sctp_find_stream_reset(struct sctp_tcb *stcb, uint32_t seq,
|
||||
struct sctp_tmit_chunk **bchk);
|
||||
|
||||
|
@ -103,7 +103,6 @@ typedef HANDLE userland_thread_t;
|
||||
#define n_time unsigned __int32
|
||||
#define sa_family_t unsigned __int8
|
||||
#define ssize_t __int64
|
||||
#define IFNAMSIZ 64
|
||||
#define __func__ __FUNCTION__
|
||||
|
||||
#ifndef EWOULDBLOCK
|
||||
@ -220,12 +219,10 @@ typedef char* caddr_t;
|
||||
#define bzero(buf, len) memset(buf, 0, len)
|
||||
#define bcopy(srcKey, dstKey, len) memcpy(dstKey, srcKey, len)
|
||||
#if _MSC_VER < 1900
|
||||
#define snprintf(data, size, format, name) _snprintf_s(data, size, _TRUNCATE, format, name)
|
||||
#define snprintf(data, size, format, ...) _snprintf_s(data, size, _TRUNCATE, format, __VA_ARGS__)
|
||||
#endif
|
||||
#define inline __inline
|
||||
#define __inline__ __inline
|
||||
#define random() rand()
|
||||
#define srandom(s) srand(s)
|
||||
#define MSG_EOR 0x8 /* data completes record */
|
||||
#define MSG_DONTWAIT 0x80 /* this message should be nonblocking */
|
||||
|
||||
@ -267,6 +264,32 @@ typedef char* caddr_t;
|
||||
|
||||
#define SCTP_GET_IF_INDEX_FROM_ROUTE(ro) 1 /* compiles... TODO use routing socket to determine */
|
||||
|
||||
#define BIG_ENDIAN 1
|
||||
#define LITTLE_ENDIAN 0
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define BYTE_ORDER BIG_ENDIAN
|
||||
#else
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#else /* !defined(Userspace_os_Windows) */
|
||||
#include <sys/cdefs.h> /* needed? added from old __FreeBSD__ */
|
||||
#include <sys/socket.h>
|
||||
#if defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Linux) || defined(__Userspace_os_NetBSD) || defined(__Userspace_os_OpenBSD) || defined(__Userspace_os_NaCl)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
typedef pthread_mutex_t userland_mutex_t;
|
||||
typedef pthread_cond_t userland_cond_t;
|
||||
typedef pthread_t userland_thread_t;
|
||||
#endif
|
||||
|
||||
#if defined(__Userspace_os_Windows) || defined(__Userspace_os_NaCl)
|
||||
|
||||
#define IFNAMSIZ 64
|
||||
|
||||
#define random() rand()
|
||||
#define srandom(s) srand(s)
|
||||
|
||||
#define timeradd(tvp, uvp, vvp) \
|
||||
do { \
|
||||
(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
|
||||
@ -287,30 +310,57 @@ typedef char* caddr_t;
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define BIG_ENDIAN 1
|
||||
#define LITTLE_ENDIAN 0
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define BYTE_ORDER BIG_ENDIAN
|
||||
#else
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
#endif
|
||||
/*#include <packon.h>
|
||||
#pragma pack(push, 1)*/
|
||||
struct ip {
|
||||
u_char ip_hl:4, ip_v:4;
|
||||
u_char ip_tos;
|
||||
u_short ip_len;
|
||||
u_short ip_id;
|
||||
u_short ip_off;
|
||||
#define IP_RP 0x8000
|
||||
#define IP_DF 0x4000
|
||||
#define IP_MF 0x2000
|
||||
#define IP_OFFMASK 0x1fff
|
||||
u_char ip_ttl;
|
||||
u_char ip_p;
|
||||
u_short ip_sum;
|
||||
struct in_addr ip_src, ip_dst;
|
||||
};
|
||||
|
||||
struct ifaddrs {
|
||||
struct ifaddrs *ifa_next;
|
||||
char *ifa_name;
|
||||
unsigned int ifa_flags;
|
||||
struct sockaddr *ifa_addr;
|
||||
struct sockaddr *ifa_netmask;
|
||||
struct sockaddr *ifa_dstaddr;
|
||||
void *ifa_data;
|
||||
};
|
||||
|
||||
struct udphdr {
|
||||
uint16_t uh_sport;
|
||||
uint16_t uh_dport;
|
||||
uint16_t uh_ulen;
|
||||
uint16_t uh_sum;
|
||||
};
|
||||
|
||||
struct iovec {
|
||||
ULONG len;
|
||||
CHAR FAR *buf;
|
||||
unsigned long len;
|
||||
char *buf;
|
||||
};
|
||||
|
||||
#define iov_base buf
|
||||
#define iov_len len
|
||||
|
||||
struct ifa_msghdr {
|
||||
unsigned __int16 ifam_msglen;
|
||||
uint16_t ifam_msglen;
|
||||
unsigned char ifam_version;
|
||||
unsigned char ifam_type;
|
||||
__int32 ifam_addrs;
|
||||
__int32 ifam_flags;
|
||||
unsigned __int16 ifam_index;
|
||||
__int32 ifam_metric;
|
||||
uint32_t ifam_addrs;
|
||||
uint32_t ifam_flags;
|
||||
uint16_t ifam_index;
|
||||
uint32_t ifam_metric;
|
||||
};
|
||||
|
||||
struct ifdevmtu {
|
||||
@ -343,7 +393,7 @@ struct ifreq {
|
||||
char* ifru_data;
|
||||
struct ifdevmtu ifru_devmtu;
|
||||
struct ifkpi ifru_kpi;
|
||||
unsigned __int32 ifru_wake_flags;
|
||||
uint32_t ifru_wake_flags;
|
||||
} ifr_ifru;
|
||||
#define ifr_addr ifr_ifru.ifru_addr
|
||||
#define ifr_dstaddr ifr_ifru.ifru_dstaddr
|
||||
@ -361,55 +411,13 @@ struct ifreq {
|
||||
#define ifr_wake_flags ifr_ifru.ifru_wake_flags
|
||||
};
|
||||
|
||||
/*#include <packon.h>
|
||||
#pragma pack(push, 1)*/
|
||||
struct ip {
|
||||
u_char ip_hl:4, ip_v:4;
|
||||
u_char ip_tos;
|
||||
u_short ip_len;
|
||||
u_short ip_id;
|
||||
u_short ip_off;
|
||||
#define IP_RP 0x8000
|
||||
#define IP_DF 0x4000
|
||||
#define IP_MF 0x2000
|
||||
#define IP_OFFMASK 0x1fff
|
||||
u_char ip_ttl;
|
||||
u_char ip_p;
|
||||
u_short ip_sum;
|
||||
struct in_addr ip_src, ip_dst;
|
||||
};
|
||||
|
||||
struct ifaddrs {
|
||||
struct ifaddrs *ifa_next;
|
||||
char *ifa_name;
|
||||
unsigned int ifa_flags;
|
||||
struct sockaddr *ifa_addr;
|
||||
struct sockaddr *ifa_netmask;
|
||||
struct sockaddr *ifa_dstaddr;
|
||||
void *ifa_data;
|
||||
};
|
||||
|
||||
struct udphdr {
|
||||
unsigned __int16 uh_sport;
|
||||
unsigned __int16 uh_dport;
|
||||
unsigned __int16 uh_ulen;
|
||||
unsigned __int16 uh_sum;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(__Userspace_os_Windows)
|
||||
int Win_getifaddrs(struct ifaddrs**);
|
||||
#define getifaddrs(interfaces) (int)Win_getifaddrs(interfaces)
|
||||
int win_if_nametoindex(const char *);
|
||||
#define if_nametoindex(x) win_if_nametoindex(x)
|
||||
|
||||
#else /* !defined(Userspace_os_Windows) */
|
||||
#include <sys/cdefs.h> /* needed? added from old __FreeBSD__ */
|
||||
#include <sys/socket.h>
|
||||
#if defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Linux) || defined(__Userspace_os_NetBSD) || defined(__Userspace_os_OpenBSD) || defined(ANDROID)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
typedef pthread_mutex_t userland_mutex_t;
|
||||
typedef pthread_cond_t userland_cond_t;
|
||||
typedef pthread_t userland_thread_t;
|
||||
#endif
|
||||
|
||||
#define mtx_lock(arg1)
|
||||
@ -471,11 +479,13 @@ struct sx {int dummy;};
|
||||
* userspace as well? */
|
||||
/* on FreeBSD, this results in a redefintion of struct route */
|
||||
/* #include <net/route.h> */
|
||||
#if !defined(__Userspace_os_Windows)
|
||||
#if !defined(__Userspace_os_Windows) && !defined(__Userspace_os_NaCl)
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#endif
|
||||
#if defined(HAVE_NETINET_IP_ICMP_H)
|
||||
#include <netinet/ip_icmp.h>
|
||||
#else
|
||||
#include <user_ip_icmp.h>
|
||||
@ -486,7 +496,7 @@ struct sx {int dummy;};
|
||||
/* for getifaddrs */
|
||||
#include <sys/types.h>
|
||||
#if !defined(__Userspace_os_Windows)
|
||||
#if !defined(ANDROID) && (defined(INET) || defined(INET6))
|
||||
#if defined(INET) || defined(INET6)
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
@ -1093,7 +1103,7 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int a
|
||||
/* with the current included files, this is defined in Linux but
|
||||
* in FreeBSD, it is behind a _KERNEL in sys/socket.h ...
|
||||
*/
|
||||
#if defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD)
|
||||
#if defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) || defined(__Userspace_os_NaCl)
|
||||
/* stolen from /usr/include/sys/socket.h */
|
||||
#define CMSG_ALIGN(n) _ALIGN(n)
|
||||
#elif defined(__Userspace_os_NetBSD)
|
||||
@ -1151,4 +1161,12 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int a
|
||||
#define TAILQ_FOREACH_SAFE TAILQ_FOREACH_MUTABLE
|
||||
#define LIST_FOREACH_SAFE LIST_FOREACH_MUTABLE
|
||||
#endif
|
||||
|
||||
#if defined(__Userspace_os_NaCl)
|
||||
#define timercmp(tvp, uvp, cmp) \
|
||||
(((tvp)->tv_sec == (uvp)->tv_sec) ? \
|
||||
((tvp)->tv_usec cmp (uvp)->tv_usec) : \
|
||||
((tvp)->tv_sec cmp (uvp)->tv_sec))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.h 246595 2013-02-09 17:26:14Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.h 272751 2014-10-08 15:30:59Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_OUTPUT_H_
|
||||
@ -208,8 +208,8 @@ sctp_add_stream_reset_result_tsn(struct sctp_tmit_chunk *,
|
||||
uint32_t, uint32_t, uint32_t, uint32_t);
|
||||
|
||||
int
|
||||
sctp_send_str_reset_req(struct sctp_tcb *, int , uint16_t *, uint8_t, uint8_t,
|
||||
uint8_t, uint8_t, uint16_t, uint16_t, uint8_t);
|
||||
sctp_send_str_reset_req(struct sctp_tcb *, uint16_t , uint16_t *, uint8_t,
|
||||
uint8_t, uint8_t, uint8_t, uint16_t, uint16_t, uint8_t);
|
||||
|
||||
void
|
||||
sctp_send_abort(struct mbuf *, int, struct sockaddr *, struct sockaddr *,
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 258765 2013-11-30 12:51:19Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 277031 2015-01-11 21:55:30Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -52,9 +52,11 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 258765 2013-11-30 12:51:19Z tuex
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
|
||||
#include <netinet/sctp_dtrace_define.h>
|
||||
#endif
|
||||
#if defined(INET) || defined(INET6)
|
||||
#if !defined(__Userspace_os_Windows)
|
||||
#include <netinet/udp.h>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef INET6
|
||||
#if defined(__Userspace__)
|
||||
#include "user_ip6_var.h"
|
||||
@ -222,8 +224,8 @@ sctp_allocate_vrf(int vrf_id)
|
||||
}
|
||||
SCTP_MALLOC(vrf, struct sctp_vrf *, sizeof(struct sctp_vrf),
|
||||
SCTP_M_VRF);
|
||||
if (vrf == NULL) {
|
||||
/* No memory */
|
||||
if (vrf == NULL) {
|
||||
/* No memory */
|
||||
#ifdef INVARIANTS
|
||||
panic("No memory for VRF:%d", vrf_id);
|
||||
#endif
|
||||
@ -241,7 +243,7 @@ sctp_allocate_vrf(int vrf_id)
|
||||
vrf->vrf_addr_hash = SCTP_HASH_INIT(SCTP_VRF_ADDR_HASH_SIZE,
|
||||
&vrf->vrf_addr_hashmark);
|
||||
if (vrf->vrf_addr_hash == NULL) {
|
||||
/* No memory */
|
||||
/* No memory */
|
||||
#ifdef INVARIANTS
|
||||
panic("No memory for VRF:%d", vrf_id);
|
||||
#endif
|
||||
@ -654,7 +656,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
|
||||
sctp_remove_ifa_from_ifn(sctp_ifap);
|
||||
/* move the address over to the new ifn */
|
||||
sctp_add_ifa_to_ifn(sctp_ifnp, sctp_ifap);
|
||||
goto exit_stage_left;
|
||||
goto exit_stage_left;
|
||||
} else {
|
||||
/* repair ifnp which was NULL ? */
|
||||
sctp_ifap->localifa_flags = SCTP_ADDR_VALID;
|
||||
@ -711,7 +713,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
|
||||
{
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
sin = (struct sockaddr_in *)&sctp_ifap->address.sin;
|
||||
sin = &sctp_ifap->address.sin;
|
||||
if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
|
||||
(IN4_ISLOOPBACK_ADDRESS(&sin->sin_addr))) {
|
||||
sctp_ifap->src_is_loop = 1;
|
||||
@ -731,7 +733,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
|
||||
/* ok to use deprecated addresses? */
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)&sctp_ifap->address.sin6;
|
||||
sin6 = &sctp_ifap->address.sin6;
|
||||
if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
|
||||
(IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))) {
|
||||
sctp_ifap->src_is_loop = 1;
|
||||
@ -865,7 +867,13 @@ sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr,
|
||||
}
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "Deleting ifa %p\n", (void *)sctp_ifap);
|
||||
sctp_ifap->localifa_flags &= SCTP_ADDR_VALID;
|
||||
sctp_ifap->localifa_flags |= SCTP_BEING_DELETED;
|
||||
/*
|
||||
* We don't set the flag. This means that the structure will
|
||||
* hang around in EP's that have bound specific to it until
|
||||
* they close. This gives us TCP like behavior if someone
|
||||
* removes an address (or for that matter adds it right back).
|
||||
*/
|
||||
/* sctp_ifap->localifa_flags |= SCTP_BEING_DELETED; */
|
||||
vrf->total_ifa_count--;
|
||||
LIST_REMOVE(sctp_ifap, next_bucket);
|
||||
sctp_remove_ifa_from_ifn(sctp_ifap);
|
||||
@ -986,6 +994,12 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
|
||||
IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
|
||||
continue;
|
||||
}
|
||||
#if defined(__FreeBSD__)
|
||||
if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
|
||||
&sin->sin_addr) != 0) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) {
|
||||
SCTP_IPI_ADDR_RUNLOCK();
|
||||
return (1);
|
||||
@ -1002,6 +1016,12 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
|
||||
#endif
|
||||
sin6 = &sctp_ifa->address.sin6;
|
||||
rsin6 = (struct sockaddr_in6 *)to;
|
||||
#if defined(__FreeBSD__)
|
||||
if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
|
||||
&sin6->sin6_addr) != 0) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
|
||||
if (local_scope == 0)
|
||||
continue;
|
||||
@ -1077,7 +1097,7 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
|
||||
{
|
||||
struct sockaddr_in *sin, *rsin;
|
||||
|
||||
sin = (struct sockaddr_in *)&laddr->ifa->address.sin;
|
||||
sin = &laddr->ifa->address.sin;
|
||||
rsin = (struct sockaddr_in *)to;
|
||||
if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) {
|
||||
SCTP_IPI_ADDR_RUNLOCK();
|
||||
@ -1091,7 +1111,7 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
|
||||
{
|
||||
struct sockaddr_in6 *sin6, *rsin6;
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)&laddr->ifa->address.sin6;
|
||||
sin6 = &laddr->ifa->address.sin6;
|
||||
rsin6 = (struct sockaddr_in6 *)to;
|
||||
if (SCTP6_ARE_ADDR_EQUAL(sin6, rsin6)) {
|
||||
SCTP_IPI_ADDR_RUNLOCK();
|
||||
@ -1106,7 +1126,7 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
|
||||
{
|
||||
struct sockaddr_conn *sconn, *rsconn;
|
||||
|
||||
sconn = (struct sockaddr_conn *)&laddr->ifa->address.sconn;
|
||||
sconn = &laddr->ifa->address.sconn;
|
||||
rsconn = (struct sockaddr_conn *)to;
|
||||
if (sconn->sconn_addr == rsconn->sconn_addr) {
|
||||
SCTP_IPI_ADDR_RUNLOCK();
|
||||
@ -1201,6 +1221,41 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
continue;
|
||||
}
|
||||
#if defined(__FreeBSD__)
|
||||
switch (to->sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
{
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
sin = (struct sockaddr_in *)to;
|
||||
if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
|
||||
&sin->sin_addr) != 0) {
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
{
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)to;
|
||||
if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
|
||||
&sin6->sin6_addr) != 0) {
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#ifdef SCTP_MVRF
|
||||
fnd = 0;
|
||||
for (i = 0; i < inp->num_vrfs; i++) {
|
||||
@ -1634,10 +1689,7 @@ sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote,
|
||||
goto null_return;
|
||||
}
|
||||
head = &inp->sctp_tcbhash[SCTP_PCBHASH_ALLADDR(rport,
|
||||
inp->sctp_hashmark)];
|
||||
if (head == NULL) {
|
||||
goto null_return;
|
||||
}
|
||||
inp->sctp_hashmark)];
|
||||
LIST_FOREACH(stcb, head, sctp_tcbhash) {
|
||||
if (stcb->rport != rport) {
|
||||
/* remote port does not match */
|
||||
@ -1901,23 +1953,43 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) &&
|
||||
(inp->sctp_lport == lport)) {
|
||||
/* got it */
|
||||
switch (nam->sa_family) {
|
||||
#ifdef INET
|
||||
if ((nam->sa_family == AF_INET) &&
|
||||
(inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
|
||||
SCTP_IPV6_V6ONLY(inp)) {
|
||||
/* IPv4 on a IPv6 socket with ONLY IPv6 set */
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
continue;
|
||||
}
|
||||
case AF_INET:
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
|
||||
SCTP_IPV6_V6ONLY(inp)) {
|
||||
/* IPv4 on a IPv6 socket with ONLY IPv6 set */
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
continue;
|
||||
}
|
||||
#if defined(__FreeBSD__)
|
||||
if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
|
||||
&sin->sin_addr) != 0) {
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
/* A V6 address and the endpoint is NOT bound V6 */
|
||||
if (nam->sa_family == AF_INET6 &&
|
||||
(inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
continue;
|
||||
}
|
||||
case AF_INET6:
|
||||
/* A V6 address and the endpoint is NOT bound V6 */
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
continue;
|
||||
}
|
||||
#if defined(__FreeBSD__)
|
||||
if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
|
||||
&sin6->sin6_addr) != 0) {
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* does a VRF id match? */
|
||||
fnd = 0;
|
||||
#ifdef SCTP_MVRF
|
||||
@ -2432,12 +2504,7 @@ sctp_findassoc_by_vtag(struct sockaddr *from, struct sockaddr *to, uint32_t vtag
|
||||
|
||||
SCTP_INP_INFO_RLOCK();
|
||||
head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(vtag,
|
||||
SCTP_BASE_INFO(hashasocmark))];
|
||||
if (head == NULL) {
|
||||
/* invalid vtag */
|
||||
SCTP_INP_INFO_RUNLOCK();
|
||||
return (NULL);
|
||||
}
|
||||
SCTP_BASE_INFO(hashasocmark))];
|
||||
LIST_FOREACH(stcb, head, sctp_asocs) {
|
||||
SCTP_INP_RLOCK(stcb->sctp_ep);
|
||||
if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
|
||||
@ -2605,7 +2672,7 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int offset,
|
||||
struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint32_t vrf_id)
|
||||
{
|
||||
struct sctp_tcb *stcb;
|
||||
struct sockaddr_storage remote_store;
|
||||
union sctp_sockstore remote_store;
|
||||
struct sctp_paramhdr parm_buf, *phdr;
|
||||
int ptype;
|
||||
int zero_address = 0;
|
||||
@ -2644,7 +2711,7 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int offset,
|
||||
__FUNCTION__);
|
||||
return (NULL);
|
||||
}
|
||||
sin6 = (struct sockaddr_in6 *)&remote_store;
|
||||
sin6 = &remote_store.sin6;
|
||||
sin6->sin6_family = AF_INET6;
|
||||
#ifdef HAVE_SIN6_LEN
|
||||
sin6->sin6_len = sizeof(*sin6);
|
||||
@ -2673,7 +2740,7 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int offset,
|
||||
__FUNCTION__);
|
||||
return (NULL);
|
||||
}
|
||||
sin = (struct sockaddr_in *)&remote_store;
|
||||
sin = &remote_store.sin;
|
||||
sin->sin_family = AF_INET;
|
||||
#ifdef HAVE_SIN_LEN
|
||||
sin->sin_len = sizeof(*sin);
|
||||
@ -2698,7 +2765,7 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int offset,
|
||||
}
|
||||
} else {
|
||||
stcb = sctp_findassociation_ep_addr(inp_p,
|
||||
(struct sockaddr *)&remote_store, netp,
|
||||
&remote_store.sa, netp,
|
||||
dst, NULL);
|
||||
}
|
||||
return (stcb);
|
||||
@ -2747,6 +2814,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
||||
/* setup socket pointers */
|
||||
inp->sctp_socket = so;
|
||||
inp->ip_inp.inp.inp_socket = so;
|
||||
#if defined(__FreeBSD__)
|
||||
inp->ip_inp.inp.inp_cred = crhold(so->so_cred);
|
||||
#endif
|
||||
#ifdef INET6
|
||||
#if !defined(__Userspace__) && !defined(__Windows__)
|
||||
if (INP_SOCKAF(so) == AF_INET6) {
|
||||
@ -2763,7 +2833,13 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
||||
inp->partial_delivery_point = SCTP_SB_LIMIT_RCV(so) >> SCTP_PARTIAL_DELIVERY_SHIFT;
|
||||
inp->sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT;
|
||||
inp->sctp_cmt_on_off = SCTP_BASE_SYSCTL(sctp_cmt_on_off);
|
||||
inp->sctp_ecn_enable = SCTP_BASE_SYSCTL(sctp_ecn_enable);
|
||||
inp->ecn_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_ecn_enable);
|
||||
inp->prsctp_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_pr_enable);
|
||||
inp->auth_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_auth_enable);
|
||||
inp->asconf_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_asconf_enable);
|
||||
inp->reconfig_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_reconfig_enable);
|
||||
inp->nrsack_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_nrsack_enable);
|
||||
inp->pktdrop_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_pktdrop_enable);
|
||||
#if defined(__Userspace__)
|
||||
inp->ulp_info = NULL;
|
||||
inp->recv_callback = NULL;
|
||||
@ -2773,6 +2849,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
||||
/* init the small hash table we use to track asocid <-> tcb */
|
||||
inp->sctp_asocidhash = SCTP_HASH_INIT(SCTP_STACK_VTAG_HASH_SIZE, &inp->hashasocidmark);
|
||||
if (inp->sctp_asocidhash == NULL) {
|
||||
#if defined(__FreeBSD__)
|
||||
crfree(inp->ip_inp.inp.inp_cred);
|
||||
#endif
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
|
||||
SCTP_INP_INFO_WUNLOCK();
|
||||
return (ENOBUFS);
|
||||
@ -2792,6 +2871,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
||||
error = 0;
|
||||
#endif
|
||||
if (error != 0) {
|
||||
#if defined(__FreeBSD__)
|
||||
crfree(inp->ip_inp.inp.inp_cred);
|
||||
#endif
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
|
||||
SCTP_INP_INFO_WUNLOCK();
|
||||
return error;
|
||||
@ -2837,6 +2919,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
||||
*/
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EOPNOTSUPP);
|
||||
so->so_pcb = NULL;
|
||||
#if defined(__FreeBSD__)
|
||||
crfree(inp->ip_inp.inp.inp_cred);
|
||||
#endif
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
@ -2856,6 +2941,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
||||
SCTP_PRINTF("Out of SCTP-INPCB->hashinit - no resources\n");
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
|
||||
so->so_pcb = NULL;
|
||||
#if defined(__FreeBSD__)
|
||||
crfree(inp->ip_inp.inp.inp_cred);
|
||||
#endif
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
|
||||
return (ENOBUFS);
|
||||
}
|
||||
@ -2867,6 +2955,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
|
||||
so->so_pcb = NULL;
|
||||
SCTP_HASH_FREE(inp->sctp_tcbhash, inp->sctp_hashmark);
|
||||
#if defined(__FreeBSD__)
|
||||
crfree(inp->ip_inp.inp.inp_cred);
|
||||
#endif
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
|
||||
return (ENOBUFS);
|
||||
}
|
||||
@ -2885,6 +2976,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
||||
#endif
|
||||
SCTP_HASH_FREE(inp->sctp_tcbhash, inp->sctp_hashmark);
|
||||
so->so_pcb = NULL;
|
||||
#if defined(__FreeBSD__)
|
||||
crfree(inp->ip_inp.inp.inp_cred);
|
||||
#endif
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
|
||||
SCTP_UNLOCK_EXC(SCTP_BASE_INFO(sctbinfo).ipi_lock);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOMEM);
|
||||
@ -2994,12 +3088,15 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
||||
*/
|
||||
m->local_hmacs = sctp_default_supported_hmaclist();
|
||||
m->local_auth_chunks = sctp_alloc_chunklist();
|
||||
if (inp->asconf_supported) {
|
||||
sctp_auth_add_chunk(SCTP_ASCONF, m->local_auth_chunks);
|
||||
sctp_auth_add_chunk(SCTP_ASCONF_ACK, m->local_auth_chunks);
|
||||
}
|
||||
m->default_dscp = 0;
|
||||
#ifdef INET6
|
||||
m->default_flowlabel = 0;
|
||||
#endif
|
||||
m->port = 0; /* encapsulation disabled by default */
|
||||
sctp_auth_set_default_chunks(m->local_auth_chunks);
|
||||
LIST_INIT(&m->shared_keys);
|
||||
/* add default NULL key as key id 0 */
|
||||
null_key = sctp_alloc_sharedkey();
|
||||
@ -3146,13 +3243,13 @@ extern void in6_sin6_2_sin(struct sockaddr_in *, struct sockaddr_in6 *sin6);
|
||||
int
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
|
||||
sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
struct sctp_ifa *sctp_ifap, struct thread *p)
|
||||
struct sctp_ifa *sctp_ifap, struct thread *p)
|
||||
#elif defined(__Windows__)
|
||||
sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
struct sctp_ifa *sctp_ifap, PKTHREAD p)
|
||||
struct sctp_ifa *sctp_ifap, PKTHREAD p)
|
||||
#else
|
||||
sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
struct sctp_ifa *sctp_ifap, struct proc *p)
|
||||
struct sctp_ifa *sctp_ifap, struct proc *p)
|
||||
#endif
|
||||
{
|
||||
/* bind a ep to a socket address */
|
||||
@ -3217,14 +3314,14 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
sin = (struct sockaddr_in *)addr;
|
||||
lport = sin->sin_port;
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 800000
|
||||
/*
|
||||
* For LOOPBACK the prison_local_ip4() call will transmute the ip address
|
||||
* to the proper value.
|
||||
*/
|
||||
if (p && (error = prison_local_ip4(p->td_ucred, &sin->sin_addr)) != 0) {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
|
||||
return (error);
|
||||
}
|
||||
/*
|
||||
* For LOOPBACK the prison_local_ip4() call will transmute the ip address
|
||||
* to the proper value.
|
||||
*/
|
||||
if (p && (error = prison_local_ip4(p->td_ucred, &sin->sin_addr)) != 0) {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
|
||||
return (error);
|
||||
}
|
||||
#endif
|
||||
if (sin->sin_addr.s_addr != INADDR_ANY) {
|
||||
bindall = 0;
|
||||
@ -3248,15 +3345,15 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
#endif
|
||||
lport = sin6->sin6_port;
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 800000
|
||||
/*
|
||||
* For LOOPBACK the prison_local_ip6() call will transmute the ipv6 address
|
||||
* to the proper value.
|
||||
*/
|
||||
if (p && (error = prison_local_ip6(p->td_ucred, &sin6->sin6_addr,
|
||||
(SCTP_IPV6_V6ONLY(inp) != 0))) != 0) {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
|
||||
return (error);
|
||||
}
|
||||
/*
|
||||
* For LOOPBACK the prison_local_ip6() call will transmute the ipv6 address
|
||||
* to the proper value.
|
||||
*/
|
||||
if (p && (error = prison_local_ip6(p->td_ucred, &sin6->sin6_addr,
|
||||
(SCTP_IPV6_V6ONLY(inp) != 0))) != 0) {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
|
||||
return (error);
|
||||
}
|
||||
#endif
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
||||
bindall = 0;
|
||||
@ -3324,7 +3421,7 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
SCTP_INP_INFO_WLOCK();
|
||||
SCTP_INP_WLOCK(inp);
|
||||
/* Setup a vrf_id to be the default for the non-bind-all case. */
|
||||
vrf_id = inp->def_vrf_id;
|
||||
vrf_id = inp->def_vrf_id;
|
||||
|
||||
/* increase our count due to the unlock we do */
|
||||
SCTP_INP_INCR_REF(inp);
|
||||
@ -3348,7 +3445,7 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
#elif defined(__APPLE__)
|
||||
suser(p->p_ucred, &p->p_acflag)
|
||||
#elif defined(__Userspace__) /* must be true to use raw socket */
|
||||
1
|
||||
1
|
||||
#else
|
||||
suser(p, 0)
|
||||
#endif
|
||||
@ -3368,15 +3465,6 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if !defined(__Panda__) && !defined(__Userspace__)
|
||||
if (p == NULL) {
|
||||
SCTP_INP_DECR_REF(inp);
|
||||
SCTP_INP_WUNLOCK(inp);
|
||||
SCTP_INP_INFO_WUNLOCK();
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
|
||||
return (error);
|
||||
}
|
||||
#endif
|
||||
#endif /* __Windows__ */
|
||||
SCTP_INP_WUNLOCK(inp);
|
||||
if (bindall) {
|
||||
@ -3457,7 +3545,7 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
}
|
||||
} else {
|
||||
uint16_t first, last, candidate;
|
||||
uint16_t count;
|
||||
uint16_t count;
|
||||
int done;
|
||||
|
||||
#if defined(__Windows__)
|
||||
@ -3465,12 +3553,12 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
last = 0xffff;
|
||||
#else
|
||||
#if defined(__Userspace__)
|
||||
/* TODO ensure uid is 0, etc... */
|
||||
/* TODO ensure uid is 0, etc... */
|
||||
#elif defined(__FreeBSD__) || defined(__APPLE__)
|
||||
if (ip_inp->inp_flags & INP_HIGHPORT) {
|
||||
first = MODULE_GLOBAL(ipport_hifirstauto);
|
||||
last = MODULE_GLOBAL(ipport_hilastauto);
|
||||
} else if (ip_inp->inp_flags & INP_LOWPORT) {
|
||||
if (ip_inp->inp_flags & INP_HIGHPORT) {
|
||||
first = MODULE_GLOBAL(ipport_hifirstauto);
|
||||
last = MODULE_GLOBAL(ipport_hilastauto);
|
||||
} else if (ip_inp->inp_flags & INP_LOWPORT) {
|
||||
if (p && (error =
|
||||
#ifdef __FreeBSD__
|
||||
#if __FreeBSD_version > 602000
|
||||
@ -3492,14 +3580,14 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
|
||||
return (error);
|
||||
}
|
||||
first = MODULE_GLOBAL(ipport_lowfirstauto);
|
||||
last = MODULE_GLOBAL(ipport_lowlastauto);
|
||||
} else {
|
||||
first = MODULE_GLOBAL(ipport_lowfirstauto);
|
||||
last = MODULE_GLOBAL(ipport_lowlastauto);
|
||||
} else {
|
||||
#endif
|
||||
first = MODULE_GLOBAL(ipport_firstauto);
|
||||
last = MODULE_GLOBAL(ipport_lastauto);
|
||||
first = MODULE_GLOBAL(ipport_firstauto);
|
||||
last = MODULE_GLOBAL(ipport_lastauto);
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* __Windows__ */
|
||||
if (first > last) {
|
||||
@ -3605,42 +3693,27 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
* too (before adding).
|
||||
*/
|
||||
struct sctp_ifa *ifa;
|
||||
struct sockaddr_storage store_sa;
|
||||
union sctp_sockstore store;
|
||||
|
||||
memset(&store_sa, 0, sizeof(store_sa));
|
||||
memset(&store, 0, sizeof(store));
|
||||
switch (addr->sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
{
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
sin = (struct sockaddr_in *)&store_sa;
|
||||
memcpy(sin, addr, sizeof(struct sockaddr_in));
|
||||
sin->sin_port = 0;
|
||||
memcpy(&store.sin, addr, sizeof(struct sockaddr_in));
|
||||
store.sin.sin_port = 0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
{
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)&store_sa;
|
||||
memcpy(sin6, addr, sizeof(struct sockaddr_in6));
|
||||
sin6->sin6_port = 0;
|
||||
memcpy(&store.sin6, addr, sizeof(struct sockaddr_in6));
|
||||
store.sin6.sin6_port = 0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if defined(__Userspace__)
|
||||
case AF_CONN:
|
||||
{
|
||||
struct sockaddr_conn *sconn;
|
||||
|
||||
sconn = (struct sockaddr_conn *)&store_sa;
|
||||
memcpy(sconn, addr, sizeof(struct sockaddr_conn));
|
||||
sconn->sconn_port = 0;
|
||||
memcpy(&store.sconn, addr, sizeof(struct sockaddr_conn));
|
||||
store.sconn.sconn_port = 0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
@ -3657,7 +3730,7 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
* O/S's will pass things in via the
|
||||
* sctp_ifap argument (Panda).
|
||||
*/
|
||||
ifa = sctp_find_ifa_by_addr((struct sockaddr *)&store_sa,
|
||||
ifa = sctp_find_ifa_by_addr(&store.sa,
|
||||
vrf_id, SCTP_ADDR_NOT_LOCKED);
|
||||
}
|
||||
if (ifa == NULL) {
|
||||
@ -3700,7 +3773,7 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
/* Put it into tcp 1-2-1 hash */
|
||||
head = &SCTP_BASE_INFO(sctp_tcpephash)[SCTP_PCBHASH_ALLADDR(lport, SCTP_BASE_INFO(hashtcpmark))];
|
||||
inp->sctp_flags |= SCTP_PCB_FLAGS_IN_TCPPOOL;
|
||||
} else {
|
||||
} else {
|
||||
head = &SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(lport, SCTP_BASE_INFO(hashmark))];
|
||||
}
|
||||
/* put it in the bucket */
|
||||
@ -3906,17 +3979,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
|
||||
/* Left with Data unread */
|
||||
struct mbuf *op_err;
|
||||
|
||||
op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
|
||||
0, M_NOWAIT, 1, MT_DATA);
|
||||
if (op_err) {
|
||||
/* Fill in the user initiated abort */
|
||||
struct sctp_paramhdr *ph;
|
||||
|
||||
SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
|
||||
ph = mtod(op_err, struct sctp_paramhdr *);
|
||||
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
|
||||
ph->param_length = htons(SCTP_BUF_LEN(op_err));
|
||||
}
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
|
||||
asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB+SCTP_LOC_3;
|
||||
sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED);
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
|
||||
@ -3986,17 +4049,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
|
||||
(asoc->asoc.state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
|
||||
struct mbuf *op_err;
|
||||
abort_anyway:
|
||||
op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
|
||||
0, M_NOWAIT, 1, MT_DATA);
|
||||
if (op_err) {
|
||||
/* Fill in the user initiated abort */
|
||||
struct sctp_paramhdr *ph;
|
||||
|
||||
SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
|
||||
ph = mtod(op_err, struct sctp_paramhdr *);
|
||||
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
|
||||
ph->param_length = htons(SCTP_BUF_LEN(op_err));
|
||||
}
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
|
||||
asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB+SCTP_LOC_5;
|
||||
sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED);
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
|
||||
@ -4063,17 +4116,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
|
||||
((asoc->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0)) {
|
||||
struct mbuf *op_err;
|
||||
|
||||
op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
|
||||
0, M_NOWAIT, 1, MT_DATA);
|
||||
if (op_err) {
|
||||
/* Fill in the user initiated abort */
|
||||
struct sctp_paramhdr *ph;
|
||||
|
||||
SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
|
||||
ph = mtod(op_err, struct sctp_paramhdr *);
|
||||
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
|
||||
ph->param_length = htons(SCTP_BUF_LEN(op_err));
|
||||
}
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
|
||||
asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB+SCTP_LOC_7;
|
||||
sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED);
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
|
||||
@ -4298,6 +4341,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
|
||||
}
|
||||
/* Now we must put the ep memory back into the zone pool */
|
||||
#if defined(__FreeBSD__)
|
||||
crfree(inp->ip_inp.inp.inp_cred);
|
||||
INP_LOCK_DESTROY(&inp->ip_inp.inp);
|
||||
#endif
|
||||
SCTP_INP_LOCK_DESTROY(inp);
|
||||
@ -4557,7 +4601,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
|
||||
* this means its an initial value
|
||||
*/
|
||||
net->rto_needed = 1;
|
||||
net->RTO = 0;
|
||||
net->RTO = 0;
|
||||
net->RTO_measured = 0;
|
||||
stcb->asoc.numnets++;
|
||||
net->ref_count = 1;
|
||||
@ -4610,7 +4654,9 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
|
||||
#endif
|
||||
SCTP_RTALLOC((sctp_route_t *)&net->ro, stcb->asoc.vrf_id);
|
||||
|
||||
#if !defined(__Userspace__)
|
||||
#if defined(__Userspace__)
|
||||
net->src_addr_selected = 0;
|
||||
#else
|
||||
if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro)) {
|
||||
/* Get source address */
|
||||
net->ro._s_addr = sctp_source_address_selection(stcb->sctp_ep,
|
||||
@ -4619,9 +4665,14 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
|
||||
net,
|
||||
0,
|
||||
stcb->asoc.vrf_id);
|
||||
/* Now get the interface MTU */
|
||||
if (net->ro._s_addr && net->ro._s_addr->ifn_p) {
|
||||
net->mtu = SCTP_GATHER_MTU_FROM_INTFC(net->ro._s_addr->ifn_p);
|
||||
if (net->ro._s_addr != NULL) {
|
||||
net->src_addr_selected = 1;
|
||||
/* Now get the interface MTU */
|
||||
if (net->ro._s_addr->ifn_p != NULL) {
|
||||
net->mtu = SCTP_GATHER_MTU_FROM_INTFC(net->ro._s_addr->ifn_p);
|
||||
}
|
||||
} else {
|
||||
net->src_addr_selected = 0;
|
||||
}
|
||||
if (net->mtu > 0) {
|
||||
uint32_t rmtu;
|
||||
@ -4636,9 +4687,11 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
|
||||
* the route may be leading out the loopback, or
|
||||
* a different interface.
|
||||
*/
|
||||
net->mtu = rmtu;
|
||||
net->mtu = rmtu;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
net->src_addr_selected = 0;
|
||||
}
|
||||
#endif
|
||||
if (net->mtu == 0) {
|
||||
@ -4662,9 +4715,11 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if defined(INET) || defined(INET6)
|
||||
if (net->port) {
|
||||
net->mtu -= (uint32_t)sizeof(struct udphdr);
|
||||
}
|
||||
#endif
|
||||
if (from == SCTP_ALLOC_ASOC) {
|
||||
stcb->asoc.smallest_mtu = net->mtu;
|
||||
}
|
||||
@ -4696,15 +4751,12 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
|
||||
*/
|
||||
net->find_pseudo_cumack = 1;
|
||||
net->find_rtx_pseudo_cumack = 1;
|
||||
net->src_addr_selected = 0;
|
||||
#if defined(__FreeBSD__)
|
||||
/* Choose an initial flowid. */
|
||||
net->flowid = stcb->asoc.my_vtag ^
|
||||
ntohs(stcb->rport) ^
|
||||
ntohs(stcb->sctp_ep->sctp_lport);
|
||||
#ifdef INVARIANTS
|
||||
net->flowidset = 1;
|
||||
#endif
|
||||
net->flowtype = M_HASHTYPE_OPAQUE;
|
||||
#endif
|
||||
if (netp) {
|
||||
*netp = net;
|
||||
@ -5131,9 +5183,9 @@ sctp_remove_net(struct sctp_tcb *stcb, struct sctp_nets *net)
|
||||
(by micchie)
|
||||
*/
|
||||
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_BASE) ||
|
||||
SCTP_MOBILITY_BASE) ||
|
||||
sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_FASTHANDOFF)) {
|
||||
SCTP_MOBILITY_FASTHANDOFF)) {
|
||||
SCTPDBG(SCTP_DEBUG_ASCONF1, "remove_net: primary dst is deleting\n");
|
||||
if (asoc->deleted_primary != NULL) {
|
||||
SCTPDBG(SCTP_DEBUG_ASCONF1, "remove_net: deleted primary may be already stored\n");
|
||||
@ -6546,7 +6598,7 @@ sctp_startup_mcore_threads(void)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(__FreeBSD__) && __FreeBSD_cc_version >= 1100000
|
||||
#if defined(__FreeBSD__) && __FreeBSD_cc_version >= 1200000
|
||||
static struct mbuf *
|
||||
sctp_netisr_hdlr(struct mbuf *m, uintptr_t source)
|
||||
{
|
||||
@ -6771,7 +6823,7 @@ sctp_pcb_init()
|
||||
*/
|
||||
sctp_init_vrf_list(SCTP_DEFAULT_VRF);
|
||||
#endif
|
||||
#if defined(__FreeBSD__) && __FreeBSD_cc_version >= 1100000
|
||||
#if defined(__FreeBSD__) && __FreeBSD_cc_version >= 1200000
|
||||
if (ip_register_flow_handler(sctp_netisr_hdlr, IPPROTO_SCTP)) {
|
||||
SCTP_PRINTF("***SCTP- Error can't register netisr handler***\n");
|
||||
}
|
||||
@ -6887,13 +6939,16 @@ sctp_pcb_finish(void)
|
||||
#endif
|
||||
#if !defined(__FreeBSD__)
|
||||
SCTP_IPI_ITERATOR_WQ_DESTROY();
|
||||
SCTP_ITERATOR_LOCK_DESTROY();
|
||||
SCTP_ITERATOR_LOCK_DESTROY();
|
||||
#endif
|
||||
SCTP_OS_TIMER_STOP(&SCTP_BASE_INFO(addr_wq_timer.timer));
|
||||
SCTP_WQ_ADDR_LOCK();
|
||||
LIST_FOREACH_SAFE(wi, &SCTP_BASE_INFO(addr_wq), sctp_nxt_addr, nwi) {
|
||||
LIST_REMOVE(wi, sctp_nxt_addr);
|
||||
SCTP_DECR_LADDR_COUNT();
|
||||
if (wi->action == SCTP_DEL_IP_ADDRESS) {
|
||||
SCTP_FREE(wi->ifa, SCTP_M_IFA);
|
||||
}
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), wi);
|
||||
}
|
||||
SCTP_WQ_ADDR_UNLOCK();
|
||||
@ -7038,7 +7093,14 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
sctp_key_t *new_key;
|
||||
uint32_t keylen;
|
||||
int got_random = 0, got_hmacs = 0, got_chklist = 0;
|
||||
uint8_t ecn_allowed;
|
||||
uint8_t peer_supports_ecn;
|
||||
uint8_t peer_supports_prsctp;
|
||||
uint8_t peer_supports_auth;
|
||||
uint8_t peer_supports_asconf;
|
||||
uint8_t peer_supports_asconf_ack;
|
||||
uint8_t peer_supports_reconfig;
|
||||
uint8_t peer_supports_nrsack;
|
||||
uint8_t peer_supports_pktdrop;
|
||||
#ifdef INET
|
||||
struct sockaddr_in sin;
|
||||
#endif
|
||||
@ -7068,8 +7130,13 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
} else {
|
||||
sa = src;
|
||||
}
|
||||
/* Turn off ECN until we get through all params */
|
||||
ecn_allowed = 0;
|
||||
peer_supports_ecn = 0;
|
||||
peer_supports_prsctp = 0;
|
||||
peer_supports_auth = 0;
|
||||
peer_supports_asconf = 0;
|
||||
peer_supports_reconfig = 0;
|
||||
peer_supports_nrsack = 0;
|
||||
peer_supports_pktdrop = 0;
|
||||
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
|
||||
/* mark all addresses that we have currently on the list */
|
||||
net->dest_state |= SCTP_ADDR_NOT_IN_ASSOC;
|
||||
@ -7128,12 +7195,6 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
/* the assoc was freed? */
|
||||
return (-4);
|
||||
}
|
||||
/*
|
||||
* peer must explicitly turn this on. This may have been initialized
|
||||
* to be "on" in order to allow local addr changes while INIT's are
|
||||
* in flight.
|
||||
*/
|
||||
stcb->asoc.peer_supports_asconf = 0;
|
||||
/* now we must go through each of the params. */
|
||||
phdr = sctp_get_next_param(m, offset, &parm_buf, sizeof(parm_buf));
|
||||
while (phdr) {
|
||||
@ -7319,7 +7380,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
} else
|
||||
#endif
|
||||
if (ptype == SCTP_ECN_CAPABLE) {
|
||||
ecn_allowed = 1;
|
||||
peer_supports_ecn = 1;
|
||||
} else if (ptype == SCTP_ULP_ADAPTATION) {
|
||||
if (stcb->asoc.state != SCTP_STATE_OPEN) {
|
||||
struct sctp_adaptation_layer_indication ai, *aip;
|
||||
@ -7340,7 +7401,9 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
struct sctp_asconf_addrv4_param *fii;
|
||||
#endif
|
||||
|
||||
stcb->asoc.peer_supports_asconf = 1;
|
||||
if (stcb->asoc.asconf_supported == 0) {
|
||||
return (-100);
|
||||
}
|
||||
if (plen > sizeof(lstore)) {
|
||||
return (-23);
|
||||
}
|
||||
@ -7392,7 +7455,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
stcb->asoc.peer_supports_nat = 1;
|
||||
} else if (ptype == SCTP_PRSCTP_SUPPORTED) {
|
||||
/* Peer supports pr-sctp */
|
||||
stcb->asoc.peer_supports_prsctp = 1;
|
||||
peer_supports_prsctp = 1;
|
||||
} else if (ptype == SCTP_SUPPORTED_CHUNK_EXT) {
|
||||
/* A supported extension chunk */
|
||||
struct sctp_supported_chunk_types_param *pr_supported;
|
||||
@ -7404,34 +7467,30 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
if (phdr == NULL) {
|
||||
return (-25);
|
||||
}
|
||||
stcb->asoc.peer_supports_asconf = 0;
|
||||
stcb->asoc.peer_supports_prsctp = 0;
|
||||
stcb->asoc.peer_supports_pktdrop = 0;
|
||||
stcb->asoc.peer_supports_strreset = 0;
|
||||
stcb->asoc.peer_supports_nr_sack = 0;
|
||||
stcb->asoc.peer_supports_auth = 0;
|
||||
pr_supported = (struct sctp_supported_chunk_types_param *)phdr;
|
||||
num_ent = plen - sizeof(struct sctp_paramhdr);
|
||||
for (i = 0; i < num_ent; i++) {
|
||||
switch (pr_supported->chunk_types[i]) {
|
||||
case SCTP_ASCONF:
|
||||
peer_supports_asconf = 1;
|
||||
break;
|
||||
case SCTP_ASCONF_ACK:
|
||||
stcb->asoc.peer_supports_asconf = 1;
|
||||
peer_supports_asconf_ack = 1;
|
||||
break;
|
||||
case SCTP_FORWARD_CUM_TSN:
|
||||
stcb->asoc.peer_supports_prsctp = 1;
|
||||
peer_supports_prsctp = 1;
|
||||
break;
|
||||
case SCTP_PACKET_DROPPED:
|
||||
stcb->asoc.peer_supports_pktdrop = 1;
|
||||
peer_supports_pktdrop = 1;
|
||||
break;
|
||||
case SCTP_NR_SELECTIVE_ACK:
|
||||
stcb->asoc.peer_supports_nr_sack = 1;
|
||||
peer_supports_nrsack = 1;
|
||||
break;
|
||||
case SCTP_STREAM_RESET:
|
||||
stcb->asoc.peer_supports_strreset = 1;
|
||||
peer_supports_reconfig = 1;
|
||||
break;
|
||||
case SCTP_AUTHENTICATION:
|
||||
stcb->asoc.peer_supports_auth = 1;
|
||||
peer_supports_auth = 1;
|
||||
break;
|
||||
default:
|
||||
/* one I have not learned yet */
|
||||
@ -7460,8 +7519,8 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
}
|
||||
got_random = 1;
|
||||
} else if (ptype == SCTP_HMAC_LIST) {
|
||||
int num_hmacs;
|
||||
int i;
|
||||
uint16_t num_hmacs;
|
||||
uint16_t i;
|
||||
|
||||
if (plen > sizeof(hmacs_store))
|
||||
break;
|
||||
@ -7568,24 +7627,47 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ecn_allowed == 0) {
|
||||
stcb->asoc.ecn_allowed = 0;
|
||||
if ((stcb->asoc.ecn_supported == 1) &&
|
||||
(peer_supports_ecn == 0)) {
|
||||
stcb->asoc.ecn_supported = 0;
|
||||
}
|
||||
if ((stcb->asoc.prsctp_supported == 1) &&
|
||||
(peer_supports_prsctp == 0)) {
|
||||
stcb->asoc.prsctp_supported = 0;
|
||||
}
|
||||
if ((stcb->asoc.auth_supported == 1) &&
|
||||
((peer_supports_auth == 0) ||
|
||||
(got_random == 0) || (got_hmacs == 0))) {
|
||||
stcb->asoc.auth_supported = 0;
|
||||
}
|
||||
if ((stcb->asoc.asconf_supported == 1) &&
|
||||
((peer_supports_asconf == 0) || (peer_supports_asconf_ack == 0) ||
|
||||
(stcb->asoc.auth_supported == 0) ||
|
||||
(saw_asconf == 0) || (saw_asconf_ack == 0))) {
|
||||
stcb->asoc.asconf_supported = 0;
|
||||
}
|
||||
if ((stcb->asoc.reconfig_supported == 1) &&
|
||||
(peer_supports_reconfig == 0)) {
|
||||
stcb->asoc.reconfig_supported = 0;
|
||||
}
|
||||
if ((stcb->asoc.nrsack_supported == 1) &&
|
||||
(peer_supports_nrsack == 0)) {
|
||||
stcb->asoc.nrsack_supported = 0;
|
||||
}
|
||||
if ((stcb->asoc.pktdrop_supported == 1) &&
|
||||
(peer_supports_pktdrop == 0)){
|
||||
stcb->asoc.pktdrop_supported = 0;
|
||||
}
|
||||
/* validate authentication required parameters */
|
||||
if (got_random && got_hmacs) {
|
||||
stcb->asoc.peer_supports_auth = 1;
|
||||
} else {
|
||||
stcb->asoc.peer_supports_auth = 0;
|
||||
}
|
||||
if (!stcb->asoc.peer_supports_auth && got_chklist) {
|
||||
if ((peer_supports_auth == 0) && (got_chklist == 1)) {
|
||||
/* peer does not support auth but sent a chunks list? */
|
||||
return (-31);
|
||||
}
|
||||
if (!SCTP_BASE_SYSCTL(sctp_asconf_auth_nochk) && stcb->asoc.peer_supports_asconf &&
|
||||
!stcb->asoc.peer_supports_auth) {
|
||||
if ((peer_supports_asconf == 1) && (peer_supports_auth == 0)) {
|
||||
/* peer supports asconf but not auth? */
|
||||
return (-32);
|
||||
} else if ((stcb->asoc.peer_supports_asconf) && (stcb->asoc.peer_supports_auth) &&
|
||||
} else if ((peer_supports_asconf == 1) &&
|
||||
(peer_supports_auth == 1) &&
|
||||
((saw_asconf == 0) || (saw_asconf_ack == 0))) {
|
||||
return (-33);
|
||||
}
|
||||
@ -7680,10 +7762,6 @@ sctp_is_vtag_good(uint32_t tag, uint16_t lport, uint16_t rport, struct timeval *
|
||||
SCTP_INP_INFO_RLOCK();
|
||||
head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(tag,
|
||||
SCTP_BASE_INFO(hashasocmark))];
|
||||
if (head == NULL) {
|
||||
/* invalid vtag */
|
||||
goto skip_vtag_check;
|
||||
}
|
||||
LIST_FOREACH(stcb, head, sctp_asocs) {
|
||||
/* We choose not to lock anything here. TCB's can't be
|
||||
* removed since we have the read lock, so they can't
|
||||
@ -7707,8 +7785,6 @@ sctp_is_vtag_good(uint32_t tag, uint16_t lport, uint16_t rport, struct timeval *
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
skip_vtag_check:
|
||||
|
||||
chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
|
||||
/* Now what about timed wait ? */
|
||||
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 254248 2013-08-12 13:52:15Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 275427 2014-12-02 20:29:29Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_PCB_H_
|
||||
@ -110,7 +110,7 @@ struct sctp_ifa {
|
||||
*/
|
||||
union sctp_sockstore address;
|
||||
uint32_t refcount; /* number of folks refering to this */
|
||||
uint32_t flags;
|
||||
uint32_t flags;
|
||||
uint32_t localifa_flags;
|
||||
uint32_t vrf_id; /* vrf_id of this addr (for deleting) */
|
||||
uint8_t src_is_loop;
|
||||
@ -480,7 +480,13 @@ struct sctp_inpcb {
|
||||
uint32_t sctp_context;
|
||||
uint8_t local_strreset_support;
|
||||
uint32_t sctp_cmt_on_off;
|
||||
uint32_t sctp_ecn_enable;
|
||||
uint8_t ecn_supported;
|
||||
uint8_t prsctp_supported;
|
||||
uint8_t auth_supported;
|
||||
uint8_t asconf_supported;
|
||||
uint8_t reconfig_supported;
|
||||
uint8_t nrsack_supported;
|
||||
uint8_t pktdrop_supported;
|
||||
struct sctp_nonpad_sndrcvinfo def_send;
|
||||
/*-
|
||||
* These three are here for the sosend_dgram
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_peeloff.c 243565 2012-11-26 16:44:03Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_peeloff.c 269858 2014-08-12 11:30:16Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -125,7 +125,13 @@ sctp_do_peeloff(struct socket *head, struct socket *so, sctp_assoc_t assoc_id)
|
||||
n_inp->sctp_mobility_features = inp->sctp_mobility_features;
|
||||
n_inp->sctp_frag_point = inp->sctp_frag_point;
|
||||
n_inp->sctp_cmt_on_off = inp->sctp_cmt_on_off;
|
||||
n_inp->sctp_ecn_enable = inp->sctp_ecn_enable;
|
||||
n_inp->ecn_supported = inp->ecn_supported;
|
||||
n_inp->prsctp_supported = inp->prsctp_supported;
|
||||
n_inp->auth_supported = inp->auth_supported;
|
||||
n_inp->asconf_supported = inp->asconf_supported;
|
||||
n_inp->reconfig_supported = inp->reconfig_supported;
|
||||
n_inp->nrsack_supported = inp->nrsack_supported;
|
||||
n_inp->pktdrop_supported = inp->pktdrop_supported;
|
||||
n_inp->partial_delivery_point = inp->partial_delivery_point;
|
||||
n_inp->sctp_context = inp->sctp_context;
|
||||
n_inp->local_strreset_support = inp->local_strreset_support;
|
||||
@ -234,7 +240,13 @@ sctp_get_peeloff(struct socket *head, sctp_assoc_t assoc_id, int *error)
|
||||
n_inp->sctp_features = inp->sctp_features;
|
||||
n_inp->sctp_frag_point = inp->sctp_frag_point;
|
||||
n_inp->sctp_cmt_on_off = inp->sctp_cmt_on_off;
|
||||
n_inp->sctp_ecn_enable = inp->sctp_ecn_enable;
|
||||
n_inp->ecn_supported = inp->ecn_supported;
|
||||
n_inp->prsctp_supported = inp->prsctp_supported;
|
||||
n_inp->auth_supported = inp->auth_supported;
|
||||
n_inp->asconf_supported = inp->asconf_supported;
|
||||
n_inp->reconfig_supported = inp->reconfig_supported;
|
||||
n_inp->nrsack_supported = inp->nrsack_supported;
|
||||
n_inp->pktdrop_supported = inp->pktdrop_supported;
|
||||
n_inp->partial_delivery_point = inp->partial_delivery_point;
|
||||
n_inp->sctp_context = inp->sctp_context;
|
||||
n_inp->local_strreset_support = inp->local_strreset_support;
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 255190 2013-09-03 19:31:59Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 275483 2014-12-04 21:17:50Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_STRUCTS_H_
|
||||
@ -428,9 +428,7 @@ struct sctp_nets {
|
||||
uint8_t rto_needed;
|
||||
#if defined(__FreeBSD__)
|
||||
uint32_t flowid;
|
||||
#ifdef INVARIANTS
|
||||
uint8_t flowidset;
|
||||
#endif
|
||||
uint8_t flowtype;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -468,8 +466,8 @@ TAILQ_HEAD(sctpchunk_listhead, sctp_tmit_chunk);
|
||||
#define CHUNK_FLAGS_FRAGMENT_OK 0x0100
|
||||
|
||||
struct chk_id {
|
||||
uint16_t id;
|
||||
uint16_t can_take_data;
|
||||
uint8_t id;
|
||||
uint8_t can_take_data;
|
||||
};
|
||||
|
||||
|
||||
@ -636,6 +634,14 @@ struct sctp_stream_out {
|
||||
struct sctp_streamhead outqueue;
|
||||
union scheduling_parameters ss_params;
|
||||
uint32_t chunks_on_queues;
|
||||
#if defined(SCTP_DETAILED_STR_STATS)
|
||||
uint32_t abandoned_unsent[SCTP_PR_SCTP_MAX + 1];
|
||||
uint32_t abandoned_sent[SCTP_PR_SCTP_MAX + 1];
|
||||
#else
|
||||
/* Only the aggregation */
|
||||
uint32_t abandoned_unsent[1];
|
||||
uint32_t abandoned_sent[1];
|
||||
#endif
|
||||
uint16_t stream_no;
|
||||
uint16_t next_sequence_send; /* next one I expect to send out */
|
||||
uint8_t last_msg_incomplete;
|
||||
@ -714,8 +720,8 @@ struct sctp_nonpad_sndrcvinfo {
|
||||
struct sctp_cc_functions {
|
||||
void (*sctp_set_initial_cc_param)(struct sctp_tcb *stcb, struct sctp_nets *net);
|
||||
void (*sctp_cwnd_update_after_sack)(struct sctp_tcb *stcb,
|
||||
struct sctp_association *asoc,
|
||||
int accum_moved ,int reneged_all, int will_exit);
|
||||
struct sctp_association *asoc,
|
||||
int accum_moved ,int reneged_all, int will_exit);
|
||||
void (*sctp_cwnd_update_exit_pf)(struct sctp_tcb *stcb, struct sctp_nets *net);
|
||||
void (*sctp_cwnd_update_after_fr)(struct sctp_tcb *stcb,
|
||||
struct sctp_association *asoc);
|
||||
@ -1200,30 +1206,21 @@ struct sctp_association {
|
||||
* sum is updated as well.
|
||||
*/
|
||||
|
||||
/* Flag to tell if ECN is allowed */
|
||||
uint8_t ecn_allowed;
|
||||
/* Flags whether an extension is supported or not */
|
||||
uint8_t ecn_supported;
|
||||
uint8_t prsctp_supported;
|
||||
uint8_t auth_supported;
|
||||
uint8_t asconf_supported;
|
||||
uint8_t reconfig_supported;
|
||||
uint8_t nrsack_supported;
|
||||
uint8_t pktdrop_supported;
|
||||
|
||||
/* Did the peer make the stream config (add out) request */
|
||||
uint8_t peer_req_out;
|
||||
|
||||
/* flag to indicate if peer can do asconf */
|
||||
uint8_t peer_supports_asconf;
|
||||
/* EY - flag to indicate if peer can do nr_sack*/
|
||||
uint8_t peer_supports_nr_sack;
|
||||
/* pr-sctp support flag */
|
||||
uint8_t peer_supports_prsctp;
|
||||
/* peer authentication support flag */
|
||||
uint8_t peer_supports_auth;
|
||||
/* stream resets are supported by the peer */
|
||||
uint8_t peer_supports_strreset;
|
||||
uint8_t local_strreset_support;
|
||||
|
||||
uint8_t peer_supports_nat;
|
||||
/*
|
||||
* packet drop's are supported by the peer, we don't really care
|
||||
* about this but we bookkeep it anyway.
|
||||
*/
|
||||
uint8_t peer_supports_pktdrop;
|
||||
uint8_t peer_supports_nat;
|
||||
|
||||
struct sctp_scoping scope;
|
||||
/* flags to handle send alternate net tracking */
|
||||
@ -1248,8 +1245,6 @@ struct sctp_association {
|
||||
uint8_t sctp_cmt_on_off;
|
||||
uint8_t iam_blocking;
|
||||
uint8_t cookie_how[8];
|
||||
/* EY 05/05/08 - NR_SACK variable*/
|
||||
uint8_t sctp_nr_sack_on_off;
|
||||
/* JRS 5/21/07 - CMT PF variable */
|
||||
uint8_t sctp_cmt_pf;
|
||||
uint8_t use_precise_time;
|
||||
@ -1272,6 +1267,8 @@ struct sctp_association {
|
||||
uint32_t timoshutdownack;
|
||||
struct timeval start_time;
|
||||
struct timeval discontinuity_time;
|
||||
uint64_t abandoned_unsent[SCTP_PR_SCTP_MAX + 1];
|
||||
uint64_t abandoned_sent[SCTP_PR_SCTP_MAX + 1];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.h 252779 2013-07-05 10:08:49Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.h 271204 2014-09-06 19:12:14Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_SYSCTL_H_
|
||||
@ -47,6 +47,12 @@ struct sctp_sysctl {
|
||||
uint32_t sctp_auto_asconf;
|
||||
uint32_t sctp_multiple_asconfs;
|
||||
uint32_t sctp_ecn_enable;
|
||||
uint32_t sctp_pr_enable;
|
||||
uint32_t sctp_auth_enable;
|
||||
uint32_t sctp_asconf_enable;
|
||||
uint32_t sctp_reconfig_enable;
|
||||
uint32_t sctp_nrsack_enable;
|
||||
uint32_t sctp_pktdrop_enable;
|
||||
uint32_t sctp_fr_max_burst_default;
|
||||
uint32_t sctp_strict_sacks;
|
||||
#if !(defined(__FreeBSD__) && __FreeBSD_version >= 800000)
|
||||
@ -83,11 +89,7 @@ struct sctp_sysctl {
|
||||
uint32_t sctp_nr_outgoing_streams_default;
|
||||
uint32_t sctp_cmt_on_off;
|
||||
uint32_t sctp_cmt_use_dac;
|
||||
/* EY 5/5/08 - nr_sack flag variable */
|
||||
uint32_t sctp_nr_sack_on_off;
|
||||
uint32_t sctp_use_cwnd_based_maxburst;
|
||||
uint32_t sctp_asconf_auth_nochk;
|
||||
uint32_t sctp_auth_disable;
|
||||
uint32_t sctp_nat_friendly;
|
||||
uint32_t sctp_L2_abc_variable;
|
||||
uint32_t sctp_mbuf_threshold_count;
|
||||
@ -111,6 +113,7 @@ struct sctp_sysctl {
|
||||
uint32_t sctp_rttvar_eqret;
|
||||
uint32_t sctp_steady_step;
|
||||
uint32_t sctp_use_dccc_ecn;
|
||||
uint32_t sctp_diag_info_code;
|
||||
#if defined(SCTP_LOCAL_TRACE_BUF)
|
||||
#if defined(__Windows__)
|
||||
struct sctp_log *sctp_log;
|
||||
@ -157,7 +160,7 @@ struct sctp_sysctl {
|
||||
#define SCTPCTL_AUTOASCONF_DESC "Enable SCTP Auto-ASCONF"
|
||||
#define SCTPCTL_AUTOASCONF_MIN 0
|
||||
#define SCTPCTL_AUTOASCONF_MAX 1
|
||||
#define SCTPCTL_AUTOASCONF_DEFAULT SCTP_DEFAULT_AUTO_ASCONF
|
||||
#define SCTPCTL_AUTOASCONF_DEFAULT 1
|
||||
|
||||
/* autoasconf: Enable SCTP Auto-ASCONF */
|
||||
#define SCTPCTL_MULTIPLEASCONFS_DESC "Enable SCTP Muliple-ASCONFs"
|
||||
@ -171,6 +174,42 @@ struct sctp_sysctl {
|
||||
#define SCTPCTL_ECN_ENABLE_MAX 1
|
||||
#define SCTPCTL_ECN_ENABLE_DEFAULT 1
|
||||
|
||||
/* pr_enable: Enable PR-SCTP */
|
||||
#define SCTPCTL_PR_ENABLE_DESC "Enable PR-SCTP"
|
||||
#define SCTPCTL_PR_ENABLE_MIN 0
|
||||
#define SCTPCTL_PR_ENABLE_MAX 1
|
||||
#define SCTPCTL_PR_ENABLE_DEFAULT 1
|
||||
|
||||
/* auth_enable: Enable SCTP AUTH function */
|
||||
#define SCTPCTL_AUTH_ENABLE_DESC "Enable SCTP AUTH function"
|
||||
#define SCTPCTL_AUTH_ENABLE_MIN 0
|
||||
#define SCTPCTL_AUTH_ENABLE_MAX 1
|
||||
#define SCTPCTL_AUTH_ENABLE_DEFAULT 1
|
||||
|
||||
/* asconf_enable: Enable SCTP ASCONF */
|
||||
#define SCTPCTL_ASCONF_ENABLE_DESC "Enable SCTP ASCONF"
|
||||
#define SCTPCTL_ASCONF_ENABLE_MIN 0
|
||||
#define SCTPCTL_ASCONF_ENABLE_MAX 1
|
||||
#define SCTPCTL_ASCONF_ENABLE_DEFAULT 1
|
||||
|
||||
/* reconfig_enable: Enable SCTP RE-CONFIG */
|
||||
#define SCTPCTL_RECONFIG_ENABLE_DESC "Enable SCTP RE-CONFIG"
|
||||
#define SCTPCTL_RECONFIG_ENABLE_MIN 0
|
||||
#define SCTPCTL_RECONFIG_ENABLE_MAX 1
|
||||
#define SCTPCTL_RECONFIG_ENABLE_DEFAULT 1
|
||||
|
||||
/* nrsack_enable: Enable NR_SACK */
|
||||
#define SCTPCTL_NRSACK_ENABLE_DESC "Enable SCTP NR-SACK"
|
||||
#define SCTPCTL_NRSACK_ENABLE_MIN 0
|
||||
#define SCTPCTL_NRSACK_ENABLE_MAX 1
|
||||
#define SCTPCTL_NRSACK_ENABLE_DEFAULT 0
|
||||
|
||||
/* pktdrop_enable: Enable SCTP Packet Drop Reports */
|
||||
#define SCTPCTL_PKTDROP_ENABLE_DESC "Enable SCTP PKTDROP"
|
||||
#define SCTPCTL_PKTDROP_ENABLE_MIN 0
|
||||
#define SCTPCTL_PKTDROP_ENABLE_MAX 1
|
||||
#define SCTPCTL_PKTDROP_ENABLE_DEFAULT 0
|
||||
|
||||
/* strict_sacks: Enable SCTP Strict SACK checking */
|
||||
#define SCTPCTL_STRICT_SACKS_DESC "Enable SCTP Strict SACK checking"
|
||||
#define SCTPCTL_STRICT_SACKS_MIN 0
|
||||
@ -358,12 +397,6 @@ struct sctp_sysctl {
|
||||
#define SCTPCTL_CMT_ON_OFF_MAX SCTP_CMT_MAX
|
||||
#define SCTPCTL_CMT_ON_OFF_DEFAULT SCTP_CMT_OFF
|
||||
|
||||
/* EY - nr_sack_on_off: NR_SACK on/off flag */
|
||||
#define SCTPCTL_NR_SACK_ON_OFF_DESC "NR_SACK on/off flag"
|
||||
#define SCTPCTL_NR_SACK_ON_OFF_MIN 0
|
||||
#define SCTPCTL_NR_SACK_ON_OFF_MAX 1
|
||||
#define SCTPCTL_NR_SACK_ON_OFF_DEFAULT 0
|
||||
|
||||
/* cmt_use_dac: CMT DAC on/off flag */
|
||||
#define SCTPCTL_CMT_USE_DAC_DESC "CMT DAC on/off flag"
|
||||
#define SCTPCTL_CMT_USE_DAC_MIN 0
|
||||
@ -376,18 +409,6 @@ struct sctp_sysctl {
|
||||
#define SCTPCTL_CWND_MAXBURST_MAX 1
|
||||
#define SCTPCTL_CWND_MAXBURST_DEFAULT 1
|
||||
|
||||
/* asconf_auth_nochk: Disable SCTP ASCONF AUTH requirement */
|
||||
#define SCTPCTL_ASCONF_AUTH_NOCHK_DESC "Disable SCTP ASCONF AUTH requirement"
|
||||
#define SCTPCTL_ASCONF_AUTH_NOCHK_MIN 0
|
||||
#define SCTPCTL_ASCONF_AUTH_NOCHK_MAX 1
|
||||
#define SCTPCTL_ASCONF_AUTH_NOCHK_DEFAULT 0
|
||||
|
||||
/* auth_disable: Disable SCTP AUTH function */
|
||||
#define SCTPCTL_AUTH_DISABLE_DESC "Disable SCTP AUTH function"
|
||||
#define SCTPCTL_AUTH_DISABLE_MIN 0
|
||||
#define SCTPCTL_AUTH_DISABLE_MAX 1
|
||||
#define SCTPCTL_AUTH_DISABLE_DEFAULT 0
|
||||
|
||||
/* nat_friendly: SCTP NAT friendly operation */
|
||||
#define SCTPCTL_NAT_FRIENDLY_DESC "SCTP NAT friendly operation"
|
||||
#define SCTPCTL_NAT_FRIENDLY_MIN 0
|
||||
@ -470,19 +491,23 @@ struct sctp_sysctl {
|
||||
#define SCTPCTL_MOBILITY_BASE_DESC "Enable SCTP base mobility"
|
||||
#define SCTPCTL_MOBILITY_BASE_MIN 0
|
||||
#define SCTPCTL_MOBILITY_BASE_MAX 1
|
||||
#define SCTPCTL_MOBILITY_BASE_DEFAULT SCTP_DEFAULT_MOBILITY_BASE
|
||||
#define SCTPCTL_MOBILITY_BASE_DEFAULT 0
|
||||
|
||||
/* mobility_fasthandoff: Enable SCTP fast handoff support */
|
||||
#define SCTPCTL_MOBILITY_FASTHANDOFF_DESC "Enable SCTP fast handoff"
|
||||
#define SCTPCTL_MOBILITY_FASTHANDOFF_MIN 0
|
||||
#define SCTPCTL_MOBILITY_FASTHANDOFF_MAX 1
|
||||
#define SCTPCTL_MOBILITY_FASTHANDOFF_DEFAULT SCTP_DEFAULT_MOBILITY_FASTHANDOFF
|
||||
#define SCTPCTL_MOBILITY_FASTHANDOFF_DEFAULT 0
|
||||
|
||||
/* Enable SCTP/UDP tunneling port */
|
||||
#define SCTPCTL_UDP_TUNNELING_PORT_DESC "Set the SCTP/UDP tunneling port"
|
||||
#define SCTPCTL_UDP_TUNNELING_PORT_MIN 0
|
||||
#define SCTPCTL_UDP_TUNNELING_PORT_MAX 65535
|
||||
#if defined(__FreeBSD__)
|
||||
#define SCTPCTL_UDP_TUNNELING_PORT_DEFAULT 0
|
||||
#else
|
||||
#define SCTPCTL_UDP_TUNNELING_PORT_DEFAULT SCTP_OVER_UDP_TUNNELING_PORT
|
||||
#endif
|
||||
|
||||
/* Enable sending of the SACK-IMMEDIATELY bit */
|
||||
#define SCTPCTL_SACK_IMMEDIATELY_ENABLE_DESC "Enable sending of the SACK-IMMEDIATELY-bit."
|
||||
@ -546,6 +571,11 @@ struct sctp_sysctl {
|
||||
#define SCTPCTL_BLACKHOLE_MAX 2
|
||||
#define SCTPCTL_BLACKHOLE_DEFAULT SCTPCTL_BLACKHOLE_MIN
|
||||
|
||||
#define SCTPCTL_DIAG_INFO_CODE_DESC "Diagnostic information error cause code"
|
||||
#define SCTPCTL_DIAG_INFO_CODE_MIN 0
|
||||
#define SCTPCTL_DIAG_INFO_CODE_MAX 65535
|
||||
#define SCTPCTL_DIAG_INFO_CODE_DEFAULT 0
|
||||
|
||||
#if defined(SCTP_DEBUG)
|
||||
/* debug: Configure debug output */
|
||||
#define SCTPCTL_DEBUG_DESC "Configure debug output"
|
||||
@ -574,12 +604,14 @@ struct sctp_sysctl {
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#define SCTPCTL_ADDR_WATCHDOG_LIMIT_MIN 0
|
||||
#define SCTPCTL_ADDR_WATCHDOG_LIMIT_MAX 0xFFFFFFFF
|
||||
#define SCTPCTL_ADDR_WATCHDOG_LIMIT_DESC "Address watchdog limit"
|
||||
#define SCTPCTL_ADDR_WATCHDOG_LIMIT_MIN 0
|
||||
#define SCTPCTL_ADDR_WATCHDOG_LIMIT_MAX 0xFFFFFFFF
|
||||
#define SCTPCTL_ADDR_WATCHDOG_LIMIT_DEFAULT SCTPCTL_ADDR_WATCHDOG_LIMIT_MIN
|
||||
|
||||
#define SCTPCTL_VTAG_WATCHDOG_LIMIT_MIN 0
|
||||
#define SCTPCTL_VTAG_WATCHDOG_LIMIT_MAX 0xFFFFFFFF
|
||||
#define SCTPCTL_VTAG_WATCHDOG_LIMIT_DESC "VTag watchdog limit"
|
||||
#define SCTPCTL_VTAG_WATCHDOG_LIMIT_MIN 0
|
||||
#define SCTPCTL_VTAG_WATCHDOG_LIMIT_MAX 0xFFFFFFFF
|
||||
#define SCTPCTL_VTAG_WATCHDOG_LIMIT_DEFAULT SCTPCTL_VTAG_WATCHDOG_LIMIT_MIN
|
||||
#endif
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 257359 2013-10-29 20:04:50Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 277380 2015-01-19 11:52:08Z tuexen $");
|
||||
#endif
|
||||
|
||||
#define _IP_VHL
|
||||
@ -54,9 +54,11 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 257359 2013-10-29 20:04:50Z tu
|
||||
#include <netinet/sctp_input.h>
|
||||
#include <netinet/sctp.h>
|
||||
#include <netinet/sctp_uio.h>
|
||||
#if defined(INET) || defined(INET6)
|
||||
#if !defined(__Userspace_os_Windows)
|
||||
#include <netinet/udp.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#define APPLE_FILE_NO 6
|
||||
@ -157,24 +159,12 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
*/
|
||||
if (stcb->asoc.overall_error_count > threshold) {
|
||||
/* Abort notification sends a ULP notify */
|
||||
struct mbuf *oper;
|
||||
struct mbuf *op_err;
|
||||
|
||||
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
|
||||
0, M_NOWAIT, 1, MT_DATA);
|
||||
if (oper) {
|
||||
struct sctp_paramhdr *ph;
|
||||
uint32_t *ippp;
|
||||
|
||||
SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
|
||||
sizeof(uint32_t);
|
||||
ph = mtod(oper, struct sctp_paramhdr *);
|
||||
ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
|
||||
ph->param_length = htons(SCTP_BUF_LEN(oper));
|
||||
ippp = (uint32_t *) (ph + 1);
|
||||
*ippp = htonl(SCTP_FROM_SCTP_TIMER+SCTP_LOC_1);
|
||||
}
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION,
|
||||
"Association error couter exceeded");
|
||||
inp->last_abort_code = SCTP_FROM_SCTP_TIMER+SCTP_LOC_1;
|
||||
sctp_abort_an_association(inp, stcb, oper, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
@ -228,7 +218,7 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
|
||||
* t3 handler.
|
||||
*/
|
||||
if (mnet == net) {
|
||||
if (min_errors == -1) {
|
||||
if (min_errors == -1) {
|
||||
min_errors = mnet->error_count + 1;
|
||||
min_errors_net = mnet;
|
||||
} else if (mnet->error_count + 1 < min_errors) {
|
||||
@ -241,7 +231,7 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
if (min_errors == -1) {
|
||||
if (min_errors == -1) {
|
||||
min_errors = mnet->error_count;
|
||||
min_errors_net = mnet;
|
||||
} else if (mnet->error_count < min_errors) {
|
||||
@ -342,10 +332,9 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
do {
|
||||
for (;;) {
|
||||
alt = TAILQ_NEXT(mnet, sctp_next);
|
||||
if (alt == NULL)
|
||||
{
|
||||
if (alt == NULL) {
|
||||
once++;
|
||||
if (once > 1) {
|
||||
break;
|
||||
@ -362,7 +351,6 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
|
||||
}
|
||||
alt->src_addr_selected = 0;
|
||||
}
|
||||
/*sa_ignore NO_NULL_CHK*/
|
||||
if (((alt->dest_state & SCTP_ADDR_REACHABLE) == SCTP_ADDR_REACHABLE) &&
|
||||
(alt->ro.ro_rt != NULL) &&
|
||||
(!(alt->dest_state & SCTP_ADDR_UNCONFIRMED))) {
|
||||
@ -370,14 +358,14 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
|
||||
break;
|
||||
}
|
||||
mnet = alt;
|
||||
} while (alt != NULL);
|
||||
}
|
||||
|
||||
if (alt == NULL) {
|
||||
/* Case where NO insv network exists (dormant state) */
|
||||
/* we rotate destinations */
|
||||
once = 0;
|
||||
mnet = net;
|
||||
do {
|
||||
for (;;) {
|
||||
if (mnet == NULL) {
|
||||
return (TAILQ_FIRST(&stcb->asoc.nets));
|
||||
}
|
||||
@ -388,15 +376,17 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
|
||||
break;
|
||||
}
|
||||
alt = TAILQ_FIRST(&stcb->asoc.nets);
|
||||
if (alt == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*sa_ignore NO_NULL_CHK*/
|
||||
if ((!(alt->dest_state & SCTP_ADDR_UNCONFIRMED)) &&
|
||||
(alt != net)) {
|
||||
/* Found an alternate address */
|
||||
break;
|
||||
}
|
||||
mnet = alt;
|
||||
} while (alt != NULL);
|
||||
}
|
||||
}
|
||||
if (alt == NULL) {
|
||||
return (net);
|
||||
@ -451,7 +441,7 @@ sctp_recover_sent_list(struct sctp_tcb *stcb)
|
||||
sctp_free_bufspace(stcb, asoc, chk, 1);
|
||||
sctp_m_freem(chk->data);
|
||||
chk->data = NULL;
|
||||
if (asoc->peer_supports_prsctp && PR_SCTP_BUF_ENABLED(chk->flags)) {
|
||||
if (asoc->prsctp_supported && PR_SCTP_BUF_ENABLED(chk->flags)) {
|
||||
asoc->sent_queue_cnt_removeable--;
|
||||
}
|
||||
}
|
||||
@ -609,7 +599,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (stcb->asoc.peer_supports_prsctp && PR_SCTP_TTL_ENABLED(chk->flags)) {
|
||||
if (stcb->asoc.prsctp_supported && PR_SCTP_TTL_ENABLED(chk->flags)) {
|
||||
/* Is it expired? */
|
||||
#ifndef __FreeBSD__
|
||||
if (timercmp(&now, &chk->rec.data.timetodrop, >)) {
|
||||
@ -627,7 +617,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (stcb->asoc.peer_supports_prsctp && PR_SCTP_RTX_ENABLED(chk->flags)) {
|
||||
if (stcb->asoc.prsctp_supported && PR_SCTP_RTX_ENABLED(chk->flags)) {
|
||||
/* Has it been retransmitted tv_sec times? */
|
||||
if (chk->snd_count > chk->rec.data.timetodrop.tv_sec) {
|
||||
if (chk->data) {
|
||||
@ -936,9 +926,9 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
|
||||
*/
|
||||
if (net->ro._s_addr) {
|
||||
sctp_free_ifa(net->ro._s_addr);
|
||||
net->ro._s_addr = NULL;
|
||||
net->ro._s_addr = NULL;
|
||||
}
|
||||
net->src_addr_selected = 0;
|
||||
net->src_addr_selected = 0;
|
||||
|
||||
/* Force a route allocation too */
|
||||
if (net->ro.ro_rt) {
|
||||
@ -974,7 +964,7 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
|
||||
return (0);
|
||||
}
|
||||
if (stcb->asoc.peer_supports_prsctp) {
|
||||
if (stcb->asoc.prsctp_supported) {
|
||||
struct sctp_tmit_chunk *lchk;
|
||||
|
||||
lchk = sctp_try_advance_peer_ack_point(stcb, &stcb->asoc);
|
||||
@ -1058,24 +1048,12 @@ sctp_cookie_timer(struct sctp_inpcb *inp,
|
||||
if (cookie == NULL) {
|
||||
if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
|
||||
/* FOOBAR! */
|
||||
struct mbuf *oper;
|
||||
struct mbuf *op_err;
|
||||
|
||||
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
|
||||
0, M_NOWAIT, 1, MT_DATA);
|
||||
if (oper) {
|
||||
struct sctp_paramhdr *ph;
|
||||
uint32_t *ippp;
|
||||
|
||||
SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
|
||||
sizeof(uint32_t);
|
||||
ph = mtod(oper, struct sctp_paramhdr *);
|
||||
ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
|
||||
ph->param_length = htons(SCTP_BUF_LEN(oper));
|
||||
ippp = (uint32_t *) (ph + 1);
|
||||
*ippp = htonl(SCTP_FROM_SCTP_TIMER+SCTP_LOC_3);
|
||||
}
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION,
|
||||
"Cookie timer expired, but no cookie");
|
||||
inp->last_abort_code = SCTP_FROM_SCTP_TIMER+SCTP_LOC_4;
|
||||
sctp_abort_an_association(inp, stcb, oper, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
} else {
|
||||
#ifdef INVARIANTS
|
||||
panic("Cookie timer expires in wrong state?");
|
||||
@ -1501,7 +1479,7 @@ sctp_pathmtu_timer(struct sctp_inpcb *inp,
|
||||
#elif defined(SCTP_KAME)
|
||||
(void)sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone));
|
||||
#else
|
||||
(void)in6_embedscope(&sin6->sin6_addr, sin6);
|
||||
(void)in6_embedscope(&sin6->sin6_addr, sin6);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@ -1526,9 +1504,11 @@ sctp_pathmtu_timer(struct sctp_inpcb *inp,
|
||||
}
|
||||
if (net->ro._s_addr) {
|
||||
mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._s_addr.sa, net->ro.ro_rt);
|
||||
#if defined(INET) || defined(INET6)
|
||||
if (net->port) {
|
||||
mtu -= sizeof(struct udphdr);
|
||||
}
|
||||
#endif
|
||||
if (mtu > next_mtu) {
|
||||
net->mtu = next_mtu;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_uio.h 255160 2013-09-02 22:48:41Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_uio.h 269945 2014-08-13 15:50:16Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_UIO_H_
|
||||
@ -279,18 +279,23 @@ struct sctp_snd_all_completes {
|
||||
SCTP_SACK_IMMEDIATELY)) != 0)
|
||||
/* for the endpoint */
|
||||
|
||||
/* The lower byte is an enumeration of PR-SCTP policies */
|
||||
/* The lower four bits is an enumeration of PR-SCTP policies */
|
||||
#define SCTP_PR_SCTP_NONE 0x0000 /* Reliable transfer */
|
||||
#define SCTP_PR_SCTP_TTL 0x0001 /* Time based PR-SCTP */
|
||||
#define SCTP_PR_SCTP_BUF 0x0002 /* Buffer based PR-SCTP */
|
||||
#define SCTP_PR_SCTP_RTX 0x0003 /* Number of retransmissions based PR-SCTP */
|
||||
#define SCTP_PR_SCTP_MAX SCTP_PR_SCTP_RTX
|
||||
#define SCTP_PR_SCTP_ALL 0x000f /* Used for aggregated stats */
|
||||
|
||||
#define PR_SCTP_POLICY(x) ((x) & 0x0f)
|
||||
#define PR_SCTP_ENABLED(x) (PR_SCTP_POLICY(x) != SCTP_PR_SCTP_NONE)
|
||||
#define PR_SCTP_ENABLED(x) ((PR_SCTP_POLICY(x) != SCTP_PR_SCTP_NONE) && \
|
||||
(PR_SCTP_POLICY(x) != SCTP_PR_SCTP_ALL))
|
||||
#define PR_SCTP_TTL_ENABLED(x) (PR_SCTP_POLICY(x) == SCTP_PR_SCTP_TTL)
|
||||
#define PR_SCTP_BUF_ENABLED(x) (PR_SCTP_POLICY(x) == SCTP_PR_SCTP_BUF)
|
||||
#define PR_SCTP_RTX_ENABLED(x) (PR_SCTP_POLICY(x) == SCTP_PR_SCTP_RTX)
|
||||
#define PR_SCTP_INVALID_POLICY(x) (PR_SCTP_POLICY(x) > SCTP_PR_SCTP_RTX)
|
||||
#define PR_SCTP_INVALID_POLICY(x) (PR_SCTP_POLICY(x) > SCTP_PR_SCTP_MAX)
|
||||
#define PR_SCTP_VALID_POLICY(x) (PR_SCTP_POLICY(x) <= SCTP_PR_SCTP_MAX)
|
||||
|
||||
/* Stat's */
|
||||
struct sctp_pcbinfo {
|
||||
uint32_t ep_count;
|
||||
@ -353,7 +358,6 @@ struct sctp_paddr_change {
|
||||
uint32_t spc_state;
|
||||
uint32_t spc_error;
|
||||
sctp_assoc_t spc_assoc_id;
|
||||
uint8_t spc_padding[4];
|
||||
};
|
||||
|
||||
/* paddr state values */
|
||||
@ -376,7 +380,7 @@ struct sctp_remote_error {
|
||||
uint32_t sre_length;
|
||||
uint16_t sre_error;
|
||||
sctp_assoc_t sre_assoc_id;
|
||||
uint8_t sre_data[4];
|
||||
uint8_t sre_data[];
|
||||
};
|
||||
|
||||
/* data send failure event (deprecated) */
|
||||
@ -749,6 +753,14 @@ struct sctp_udpencaps {
|
||||
uint16_t sue_port;
|
||||
};
|
||||
|
||||
struct sctp_prstatus {
|
||||
sctp_assoc_t sprstat_assoc_id;
|
||||
uint16_t sprstat_sid;
|
||||
uint16_t sprstat_policy;
|
||||
uint64_t sprstat_abandoned_unsent;
|
||||
uint64_t sprstat_abandoned_sent;
|
||||
};
|
||||
|
||||
struct sctp_cwnd_args {
|
||||
struct sctp_nets *net; /* network to */ /* FIXME: LP64 issue */
|
||||
uint32_t cwnd_new_value;/* cwnd in k */
|
||||
|
@ -35,7 +35,7 @@
|
||||
#endif
|
||||
#include <netinet/sctp_os_userspace.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#if !defined(_WIN32) && !defined(__Userspace_os_NaCl)
|
||||
int
|
||||
sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
|
||||
{
|
||||
@ -55,6 +55,14 @@ sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__Userspace_os_NaCl)
|
||||
int
|
||||
sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
|
||||
{
|
||||
return 1280;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
int
|
||||
sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af)
|
||||
@ -90,8 +98,8 @@ getwintimeofday(struct timeval *tv)
|
||||
struct timeb tb;
|
||||
|
||||
ftime(&tb);
|
||||
tv->tv_sec = tb.time;
|
||||
tv->tv_usec = tb.millitm * 1000;
|
||||
tv->tv_sec = (long)tb.time;
|
||||
tv->tv_usec = (long)(tb.millitm) * 1000L;
|
||||
}
|
||||
|
||||
int
|
||||
@ -138,10 +146,10 @@ Win_getifaddrs(struct ifaddrs** interfaces)
|
||||
SCTPDBG(SCTP_DEBUG_USR, "Can't allocate memory\n");
|
||||
return (-1);
|
||||
}
|
||||
ifa->ifa_name = strdup(pAdapt->AdapterName);
|
||||
ifa->ifa_name = _strdup(pAdapt->AdapterName);
|
||||
ifa->ifa_flags = pAdapt->Flags;
|
||||
ifa->ifa_addr = (struct sockaddr *)addr;
|
||||
memcpy(&addr, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in));
|
||||
memcpy(addr, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in));
|
||||
interfaces[count] = ifa;
|
||||
}
|
||||
#endif
|
||||
@ -172,10 +180,10 @@ Win_getifaddrs(struct ifaddrs** interfaces)
|
||||
SCTPDBG(SCTP_DEBUG_USR, "Can't allocate memory\n");
|
||||
return (-1);
|
||||
}
|
||||
ifa->ifa_name = strdup(pAdapt->AdapterName);
|
||||
ifa->ifa_name = _strdup(pAdapt->AdapterName);
|
||||
ifa->ifa_flags = pAdapt->Flags;
|
||||
ifa->ifa_addr = (struct sockaddr *)addr6;
|
||||
memcpy(&addr6, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in6));
|
||||
memcpy(addr6, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in6));
|
||||
interfaces[count] = ifa;
|
||||
}
|
||||
}
|
||||
@ -215,11 +223,11 @@ win_if_nametoindex(const char *ifname)
|
||||
}
|
||||
|
||||
#if WINVER < 0x0600
|
||||
/* These functions are written based on the code at
|
||||
/* These functions are written based on the code at
|
||||
* http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
|
||||
* Therefore, for the rest of the file the following applies:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright and Licensing Information for ACE(TM), TAO(TM), CIAO(TM),
|
||||
* DAnCE(TM), and CoSMIC(TM)
|
||||
*
|
||||
@ -326,7 +334,7 @@ win_if_nametoindex(const char *ifname)
|
||||
* 22. http://www.dre.vanderbilt.edu/~schmidt/
|
||||
* 23. http://www.cs.wustl.edu/ACE.html
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
InitializeXPConditionVariable(userland_cond_t *cv)
|
||||
{
|
||||
@ -359,8 +367,7 @@ SleepXPConditionVariable(userland_cond_t *cv, userland_mutex_t *mtx)
|
||||
}
|
||||
EnterCriticalSection(&cv->waiters_count_lock);
|
||||
cv->waiters_count--;
|
||||
last_waiter =
|
||||
result == (C_SIGNAL + C_BROADCAST && (cv->waiters_count == 0));
|
||||
last_waiter = result == (C_SIGNAL + C_BROADCAST && (cv->waiters_count == 0));
|
||||
LeaveCriticalSection(&cv->waiters_count_lock);
|
||||
if (last_waiter)
|
||||
ResetEvent(cv->events_[C_BROADCAST]);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_var.h 242327 2012-10-29 20:47:32Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_var.h 275427 2014-12-02 20:29:29Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_VAR_H_
|
||||
@ -76,7 +76,7 @@ extern struct pr_usrreqs sctp_usrreqs;
|
||||
((stcb->asoc.sctp_features & feature) == 0)) || \
|
||||
((stcb == NULL) && (inp != NULL) && \
|
||||
((inp->sctp_features & feature) == 0)) || \
|
||||
((stcb == NULL) && (inp == NULL)))
|
||||
((stcb == NULL) && (inp == NULL)))
|
||||
|
||||
/* managing mobility_feature in inpcb (by micchie) */
|
||||
#define sctp_mobility_feature_on(inp, feature) (inp->sctp_mobility_features |= feature)
|
||||
@ -110,7 +110,7 @@ extern struct pr_usrreqs sctp_usrreqs;
|
||||
#define sctp_alloc_a_readq(_stcb, _readq) { \
|
||||
(_readq) = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_readq), struct sctp_queued_to_read); \
|
||||
if ((_readq)) { \
|
||||
SCTP_INCR_READQ_COUNT(); \
|
||||
SCTP_INCR_READQ_COUNT(); \
|
||||
} \
|
||||
}
|
||||
|
||||
@ -125,11 +125,11 @@ extern struct pr_usrreqs sctp_usrreqs;
|
||||
|
||||
#define sctp_alloc_a_strmoq(_stcb, _strmoq) { \
|
||||
(_strmoq) = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_strmoq), struct sctp_stream_queue_pending); \
|
||||
if ((_strmoq)) { \
|
||||
if ((_strmoq)) { \
|
||||
memset(_strmoq, 0, sizeof(struct sctp_stream_queue_pending)); \
|
||||
SCTP_INCR_STRMOQ_COUNT(); \
|
||||
(_strmoq)->holds_key_ref = 0; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define sctp_free_a_chunk(_stcb, _chk, _so_locked) { \
|
||||
@ -137,22 +137,22 @@ extern struct pr_usrreqs sctp_usrreqs;
|
||||
sctp_auth_key_release((_stcb), (_chk)->auth_keyid, _so_locked); \
|
||||
(_chk)->holds_key_ref = 0; \
|
||||
} \
|
||||
if (_stcb) { \
|
||||
SCTP_TCB_LOCK_ASSERT((_stcb)); \
|
||||
if ((_chk)->whoTo) { \
|
||||
sctp_free_remote_addr((_chk)->whoTo); \
|
||||
(_chk)->whoTo = NULL; \
|
||||
} \
|
||||
if (((_stcb)->asoc.free_chunk_cnt > SCTP_BASE_SYSCTL(sctp_asoc_free_resc_limit)) || \
|
||||
(SCTP_BASE_INFO(ipi_free_chunks) > SCTP_BASE_SYSCTL(sctp_system_free_resc_limit))) { \
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), (_chk)); \
|
||||
SCTP_DECR_CHK_COUNT(); \
|
||||
} else { \
|
||||
TAILQ_INSERT_TAIL(&(_stcb)->asoc.free_chunks, (_chk), sctp_next); \
|
||||
(_stcb)->asoc.free_chunk_cnt++; \
|
||||
atomic_add_int(&SCTP_BASE_INFO(ipi_free_chunks), 1); \
|
||||
} \
|
||||
} else { \
|
||||
if (_stcb) { \
|
||||
SCTP_TCB_LOCK_ASSERT((_stcb)); \
|
||||
if ((_chk)->whoTo) { \
|
||||
sctp_free_remote_addr((_chk)->whoTo); \
|
||||
(_chk)->whoTo = NULL; \
|
||||
} \
|
||||
if (((_stcb)->asoc.free_chunk_cnt > SCTP_BASE_SYSCTL(sctp_asoc_free_resc_limit)) || \
|
||||
(SCTP_BASE_INFO(ipi_free_chunks) > SCTP_BASE_SYSCTL(sctp_system_free_resc_limit))) { \
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), (_chk)); \
|
||||
SCTP_DECR_CHK_COUNT(); \
|
||||
} else { \
|
||||
TAILQ_INSERT_TAIL(&(_stcb)->asoc.free_chunks, (_chk), sctp_next); \
|
||||
(_stcb)->asoc.free_chunk_cnt++; \
|
||||
atomic_add_int(&SCTP_BASE_INFO(ipi_free_chunks), 1); \
|
||||
} \
|
||||
} else { \
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), (_chk)); \
|
||||
SCTP_DECR_CHK_COUNT(); \
|
||||
} \
|
||||
@ -163,7 +163,7 @@ extern struct pr_usrreqs sctp_usrreqs;
|
||||
(_chk) = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_chunk), struct sctp_tmit_chunk); \
|
||||
if ((_chk)) { \
|
||||
SCTP_INCR_CHK_COUNT(); \
|
||||
(_chk)->whoTo = NULL; \
|
||||
(_chk)->whoTo = NULL; \
|
||||
(_chk)->holds_key_ref = 0; \
|
||||
} \
|
||||
} else { \
|
||||
@ -171,7 +171,7 @@ extern struct pr_usrreqs sctp_usrreqs;
|
||||
TAILQ_REMOVE(&(_stcb)->asoc.free_chunks, (_chk), sctp_next); \
|
||||
atomic_subtract_int(&SCTP_BASE_INFO(ipi_free_chunks), 1); \
|
||||
(_chk)->holds_key_ref = 0; \
|
||||
SCTP_STAT_INCR(sctps_cached_chk); \
|
||||
SCTP_STAT_INCR(sctps_cached_chk); \
|
||||
(_stcb)->asoc.free_chunk_cnt--; \
|
||||
} \
|
||||
}
|
||||
@ -183,15 +183,15 @@ extern struct pr_usrreqs sctp_usrreqs;
|
||||
if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&(__net)->ref_count)) { \
|
||||
(void)SCTP_OS_TIMER_STOP(&(__net)->rxt_timer.timer); \
|
||||
(void)SCTP_OS_TIMER_STOP(&(__net)->pmtu_timer.timer); \
|
||||
if ((__net)->ro.ro_rt) { \
|
||||
if ((__net)->ro.ro_rt) { \
|
||||
RTFREE((__net)->ro.ro_rt); \
|
||||
(__net)->ro.ro_rt = NULL; \
|
||||
} \
|
||||
} \
|
||||
if ((__net)->src_addr_selected) { \
|
||||
sctp_free_ifa((__net)->ro._s_addr); \
|
||||
(__net)->ro._s_addr = NULL; \
|
||||
} \
|
||||
(__net)->src_addr_selected = 0; \
|
||||
(__net)->src_addr_selected = 0; \
|
||||
(__net)->dest_state &= ~SCTP_ADDR_REACHABLE; \
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_net), (__net)); \
|
||||
SCTP_DECR_RADDR_COUNT(); \
|
||||
@ -231,15 +231,15 @@ extern struct pr_usrreqs sctp_usrreqs;
|
||||
(void)SCTP_OS_TIMER_STOP(&(__net)->rxt_timer.timer); \
|
||||
(void)SCTP_OS_TIMER_STOP(&(__net)->pmtu_timer.timer); \
|
||||
(void)SCTP_OS_TIMER_STOP(&(__net)->hb_timer.timer); \
|
||||
if ((__net)->ro.ro_rt) { \
|
||||
if ((__net)->ro.ro_rt) { \
|
||||
RTFREE((__net)->ro.ro_rt); \
|
||||
(__net)->ro.ro_rt = NULL; \
|
||||
} \
|
||||
} \
|
||||
if ((__net)->src_addr_selected) { \
|
||||
sctp_free_ifa((__net)->ro._s_addr); \
|
||||
(__net)->ro._s_addr = NULL; \
|
||||
} \
|
||||
(__net)->src_addr_selected = 0; \
|
||||
(__net)->src_addr_selected = 0; \
|
||||
(__net)->dest_state &=~SCTP_ADDR_REACHABLE; \
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_net), (__net)); \
|
||||
SCTP_DECR_RADDR_COUNT(); \
|
||||
@ -323,12 +323,12 @@ extern struct pr_usrreqs sctp_usrreqs;
|
||||
} while (0)
|
||||
|
||||
#define sctp_flight_size_increase(tp1) do { \
|
||||
(tp1)->whoTo->flight_size += (tp1)->book_size; \
|
||||
(tp1)->whoTo->flight_size += (tp1)->book_size; \
|
||||
} while (0)
|
||||
|
||||
#ifdef SCTP_FS_SPEC_LOG
|
||||
#define sctp_total_flight_decrease(stcb, tp1) do { \
|
||||
if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
|
||||
if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
|
||||
stcb->asoc.fs_index = 0;\
|
||||
stcb->asoc.fslog[stcb->asoc.fs_index].total_flight = stcb->asoc.total_flight; \
|
||||
stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.TSN_seq; \
|
||||
@ -337,7 +337,7 @@ extern struct pr_usrreqs sctp_usrreqs;
|
||||
stcb->asoc.fslog[stcb->asoc.fs_index].incr = 0; \
|
||||
stcb->asoc.fslog[stcb->asoc.fs_index].decr = 1; \
|
||||
stcb->asoc.fs_index++; \
|
||||
tp1->window_probe = 0; \
|
||||
tp1->window_probe = 0; \
|
||||
if (stcb->asoc.total_flight >= tp1->book_size) { \
|
||||
stcb->asoc.total_flight -= tp1->book_size; \
|
||||
if (stcb->asoc.total_flight_count > 0) \
|
||||
@ -349,7 +349,7 @@ extern struct pr_usrreqs sctp_usrreqs;
|
||||
} while (0)
|
||||
|
||||
#define sctp_total_flight_increase(stcb, tp1) do { \
|
||||
if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
|
||||
if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
|
||||
stcb->asoc.fs_index = 0;\
|
||||
stcb->asoc.fslog[stcb->asoc.fs_index].total_flight = stcb->asoc.total_flight; \
|
||||
stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.TSN_seq; \
|
||||
@ -358,14 +358,14 @@ extern struct pr_usrreqs sctp_usrreqs;
|
||||
stcb->asoc.fslog[stcb->asoc.fs_index].incr = 1; \
|
||||
stcb->asoc.fslog[stcb->asoc.fs_index].decr = 0; \
|
||||
stcb->asoc.fs_index++; \
|
||||
(stcb)->asoc.total_flight_count++; \
|
||||
(stcb)->asoc.total_flight += (tp1)->book_size; \
|
||||
(stcb)->asoc.total_flight_count++; \
|
||||
(stcb)->asoc.total_flight += (tp1)->book_size; \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define sctp_total_flight_decrease(stcb, tp1) do { \
|
||||
tp1->window_probe = 0; \
|
||||
tp1->window_probe = 0; \
|
||||
if (stcb->asoc.total_flight >= tp1->book_size) { \
|
||||
stcb->asoc.total_flight -= tp1->book_size; \
|
||||
if (stcb->asoc.total_flight_count > 0) \
|
||||
@ -377,8 +377,8 @@ extern struct pr_usrreqs sctp_usrreqs;
|
||||
} while (0)
|
||||
|
||||
#define sctp_total_flight_increase(stcb, tp1) do { \
|
||||
(stcb)->asoc.total_flight_count++; \
|
||||
(stcb)->asoc.total_flight += (tp1)->book_size; \
|
||||
(stcb)->asoc.total_flight_count++; \
|
||||
(stcb)->asoc.total_flight += (tp1)->book_size; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
@ -412,8 +412,12 @@ void sctp_ctlinput(int, struct sockaddr *, void *);
|
||||
int sctp_ctloutput(struct socket *, struct sockopt *);
|
||||
#ifdef INET
|
||||
void sctp_input_with_port(struct mbuf *, int, uint16_t);
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 1100020
|
||||
int sctp_input(struct mbuf **, int *, int);
|
||||
#else
|
||||
void sctp_input(struct mbuf *, int);
|
||||
#endif
|
||||
#endif
|
||||
void sctp_pathmtu_adjustment(struct sctp_tcb *, uint16_t);
|
||||
#endif
|
||||
#else
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 259943 2013-12-27 13:07:00Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 277049 2015-01-12 07:39:52Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -252,6 +252,7 @@ sctp_log_fr(uint32_t biggest_tsn, uint32_t biggest_new_tsn, uint32_t tsn, int fr
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SCTP_MBUF_LOGGING
|
||||
void
|
||||
sctp_log_mb(struct mbuf *m, int from)
|
||||
{
|
||||
@ -283,6 +284,17 @@ sctp_log_mb(struct mbuf *m, int from)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sctp_log_mbc(struct mbuf *m, int from)
|
||||
{
|
||||
struct mbuf *mat;
|
||||
|
||||
for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) {
|
||||
sctp_log_mb(mat, from);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
sctp_log_strm_del(struct sctp_queued_to_read *control, struct sctp_queued_to_read *poschk, int from)
|
||||
{
|
||||
@ -474,7 +486,8 @@ sctp_log_rwnd_set(uint8_t from, uint32_t peers_rwnd, uint32_t flight_size, uint3
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef SCTP_MBCNT_LOGGING
|
||||
static void
|
||||
sctp_log_mbcnt(uint8_t from, uint32_t total_oq, uint32_t book, uint32_t total_mbcnt_q, uint32_t mbcnt)
|
||||
{
|
||||
#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF)
|
||||
@ -493,6 +506,7 @@ sctp_log_mbcnt(uint8_t from, uint32_t total_oq, uint32_t book, uint32_t total_mb
|
||||
sctp_clog.x.misc.log4);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
sctp_misc_ints(uint8_t from, uint32_t a, uint32_t b, uint32_t c, uint32_t d)
|
||||
@ -963,6 +977,9 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
* caller in the sctp_aloc_assoc() function.
|
||||
*/
|
||||
int i;
|
||||
#if defined(SCTP_DETAILED_STR_STATS)
|
||||
int j;
|
||||
#endif
|
||||
|
||||
asoc = &stcb->asoc;
|
||||
/* init all variables to a known value. */
|
||||
@ -972,8 +989,13 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
asoc->heart_beat_delay = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
|
||||
asoc->cookie_life = inp->sctp_ep.def_cookie_life;
|
||||
asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off;
|
||||
asoc->ecn_allowed = inp->sctp_ecn_enable;
|
||||
asoc->sctp_nr_sack_on_off = (uint8_t)SCTP_BASE_SYSCTL(sctp_nr_sack_on_off);
|
||||
asoc->ecn_supported = inp->ecn_supported;
|
||||
asoc->prsctp_supported = inp->prsctp_supported;
|
||||
asoc->auth_supported = inp->auth_supported;
|
||||
asoc->asconf_supported = inp->asconf_supported;
|
||||
asoc->reconfig_supported = inp->reconfig_supported;
|
||||
asoc->nrsack_supported = inp->nrsack_supported;
|
||||
asoc->pktdrop_supported = inp->pktdrop_supported;
|
||||
asoc->sctp_cmt_pf = (uint8_t)0;
|
||||
asoc->sctp_frag_point = inp->sctp_frag_point;
|
||||
asoc->sctp_features = inp->sctp_features;
|
||||
@ -1004,7 +1026,7 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
|
||||
#ifdef SCTP_ASOCLOG_OF_TSNS
|
||||
asoc->tsn_in_at = 0;
|
||||
asoc->tsn_out_at = 0;
|
||||
asoc->tsn_out_at = 0;
|
||||
asoc->tsn_in_wrapped = 0;
|
||||
asoc->tsn_out_wrapped = 0;
|
||||
asoc->cumack_log_at = 0;
|
||||
@ -1019,7 +1041,6 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
sctp_select_initial_TSN(&inp->sctp_ep);
|
||||
asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
|
||||
/* we are optimisitic here */
|
||||
asoc->peer_supports_pktdrop = 1;
|
||||
asoc->peer_supports_nat = 0;
|
||||
asoc->sent_queue_retran_cnt = 0;
|
||||
|
||||
@ -1133,6 +1154,15 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
asoc->strmout[i].next_sequence_send = 0x0;
|
||||
TAILQ_INIT(&asoc->strmout[i].outqueue);
|
||||
asoc->strmout[i].chunks_on_queues = 0;
|
||||
#if defined(SCTP_DETAILED_STR_STATS)
|
||||
for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) {
|
||||
asoc->strmout[i].abandoned_sent[j] = 0;
|
||||
asoc->strmout[i].abandoned_unsent[j] = 0;
|
||||
}
|
||||
#else
|
||||
asoc->strmout[i].abandoned_sent[0] = 0;
|
||||
asoc->strmout[i].abandoned_unsent[0] = 0;
|
||||
#endif
|
||||
asoc->strmout[i].stream_no = i;
|
||||
asoc->strmout[i].last_msg_incomplete = 0;
|
||||
asoc->ss_functions.sctp_ss_init_stream(&asoc->strmout[i], NULL);
|
||||
@ -1188,6 +1218,10 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
asoc->timoshutdownack = 0;
|
||||
(void)SCTP_GETTIME_TIMEVAL(&asoc->start_time);
|
||||
asoc->discontinuity_time = asoc->start_time;
|
||||
for (i = 0; i < SCTP_PR_SCTP_MAX + 1; i++) {
|
||||
asoc->abandoned_unsent[i] = 0;
|
||||
asoc->abandoned_sent[i] = 0;
|
||||
}
|
||||
/* sa_ignore MEMLEAK {memory is put in the assoc mapping array and freed later when
|
||||
* the association is freed.
|
||||
*/
|
||||
@ -1273,7 +1307,7 @@ sctp_iterator_work(struct sctp_iterator *it)
|
||||
|
||||
SCTP_INP_INFO_RLOCK();
|
||||
SCTP_ITERATOR_LOCK();
|
||||
if (it->inp) {
|
||||
if (it->inp) {
|
||||
SCTP_INP_RLOCK(it->inp);
|
||||
SCTP_INP_DECR_REF(it->inp);
|
||||
}
|
||||
@ -1816,7 +1850,7 @@ sctp_timeout_handler(void *t)
|
||||
goto out_decr;
|
||||
}
|
||||
SCTP_STAT_INCR(sctps_timoshutdownack);
|
||||
stcb->asoc.timoshutdownack++;
|
||||
stcb->asoc.timoshutdownack++;
|
||||
#ifdef SCTP_AUDITING_ENABLED
|
||||
sctp_auditing(4, inp, stcb, net);
|
||||
#endif
|
||||
@ -2047,7 +2081,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
* though we use a different timer. We also add the HB timer
|
||||
* PLUS a random jitter.
|
||||
*/
|
||||
if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
|
||||
if ((stcb == NULL) || (net == NULL)) {
|
||||
return;
|
||||
} else {
|
||||
uint32_t rndval;
|
||||
@ -2102,9 +2136,6 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
* nothing needed but the endpoint here ususually about 60
|
||||
* minutes.
|
||||
*/
|
||||
if (inp == NULL) {
|
||||
return;
|
||||
}
|
||||
tmr = &inp->sctp_ep.signature_change;
|
||||
to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_SIGNATURE];
|
||||
break;
|
||||
@ -2121,9 +2152,6 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
* timer since that has stopped and we are in the GONE
|
||||
* state.
|
||||
*/
|
||||
if (inp == NULL) {
|
||||
return;
|
||||
}
|
||||
tmr = &inp->sctp_ep.signature_change;
|
||||
to_ticks = MSEC_TO_TICKS(SCTP_INP_KILL_TIMEOUT);
|
||||
break;
|
||||
@ -2132,10 +2160,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
* Here we use the value found in the EP for PMTU ususually
|
||||
* about 10 minutes.
|
||||
*/
|
||||
if ((stcb == NULL) || (inp == NULL)) {
|
||||
return;
|
||||
}
|
||||
if (net == NULL) {
|
||||
if ((stcb == NULL) || (net == NULL)) {
|
||||
return;
|
||||
}
|
||||
if (net->dest_state & SCTP_ADDR_NO_PMTUD) {
|
||||
@ -2161,7 +2186,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
* Here we use the endpoints shutdown guard timer usually
|
||||
* about 3 minutes.
|
||||
*/
|
||||
if ((inp == NULL) || (stcb == NULL)) {
|
||||
if (stcb == NULL) {
|
||||
return;
|
||||
}
|
||||
to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN];
|
||||
@ -2504,8 +2529,8 @@ sctp_calculate_rto(struct sctp_tcb *stcb,
|
||||
/* store the current RTT in us */
|
||||
net->rtt = (uint64_t)1000000 * (uint64_t)now.tv_sec +
|
||||
(uint64_t)now.tv_usec;
|
||||
/* computer rtt in ms */
|
||||
rtt = net->rtt / 1000;
|
||||
/* compute rtt in ms */
|
||||
rtt = (int32_t)(net->rtt / 1000);
|
||||
if ((asoc->cc_functions.sctp_rtt_calculated) && (rtt_from_sack == SCTP_RTT_FROM_DATA)) {
|
||||
/* Tell the CC module that a new update has just occurred from a sack */
|
||||
(*asoc->cc_functions.sctp_rtt_calculated)(stcb, net, &now);
|
||||
@ -2566,15 +2591,15 @@ sctp_calculate_rto(struct sctp_tcb *stcb,
|
||||
stcb->asoc.sat_network = 0;
|
||||
stcb->asoc.sat_network_lockout = 1;
|
||||
}
|
||||
/* bound it, per C6/C7 in Section 5.3.1 */
|
||||
if (new_rto < stcb->asoc.minrto) {
|
||||
/* bound it, per C6/C7 in Section 5.3.1 */
|
||||
if (new_rto < stcb->asoc.minrto) {
|
||||
new_rto = stcb->asoc.minrto;
|
||||
}
|
||||
if (new_rto > stcb->asoc.maxrto) {
|
||||
new_rto = stcb->asoc.maxrto;
|
||||
}
|
||||
/* we are now returning the RTO */
|
||||
return (new_rto);
|
||||
return (new_rto);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2637,58 +2662,44 @@ sctp_get_next_param(struct mbuf *m,
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
struct mbuf *
|
||||
sctp_add_pad_tombuf(struct mbuf *m, int padlen)
|
||||
{
|
||||
/*
|
||||
* add padlen bytes of 0 filled padding to the end of the mbuf. If
|
||||
* padlen is > 3 this routine will fail.
|
||||
*/
|
||||
uint8_t *dp;
|
||||
int i;
|
||||
struct mbuf *m_last;
|
||||
caddr_t dp;
|
||||
|
||||
if (padlen > 3) {
|
||||
SCTP_LTRACE_ERR_RET_PKT(m, NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
|
||||
return (ENOBUFS);
|
||||
return (NULL);
|
||||
}
|
||||
if (padlen <= M_TRAILINGSPACE(m)) {
|
||||
/*
|
||||
* The easy way. We hope the majority of the time we hit
|
||||
* here :)
|
||||
*/
|
||||
dp = (uint8_t *) (mtod(m, caddr_t) + SCTP_BUF_LEN(m));
|
||||
SCTP_BUF_LEN(m) += padlen;
|
||||
m_last = m;
|
||||
} else {
|
||||
/* Hard way we must grow the mbuf */
|
||||
struct mbuf *tmp;
|
||||
|
||||
tmp = sctp_get_mbuf_for_msg(padlen, 0, M_NOWAIT, 1, MT_DATA);
|
||||
if (tmp == NULL) {
|
||||
/* Out of space GAK! we are in big trouble. */
|
||||
SCTP_LTRACE_ERR_RET_PKT(m, NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
|
||||
return (ENOBUFS);
|
||||
/* Hard way we must grow the mbuf chain */
|
||||
m_last = sctp_get_mbuf_for_msg(padlen, 0, M_NOWAIT, 1, MT_DATA);
|
||||
if (m_last == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
/* setup and insert in middle */
|
||||
SCTP_BUF_LEN(tmp) = padlen;
|
||||
SCTP_BUF_NEXT(tmp) = NULL;
|
||||
SCTP_BUF_NEXT(m) = tmp;
|
||||
dp = mtod(tmp, uint8_t *);
|
||||
SCTP_BUF_LEN(m_last) = 0;
|
||||
SCTP_BUF_NEXT(m_last) = NULL;
|
||||
SCTP_BUF_NEXT(m) = m_last;
|
||||
}
|
||||
/* zero out the pad */
|
||||
for (i = 0; i < padlen; i++) {
|
||||
*dp = 0;
|
||||
dp++;
|
||||
}
|
||||
return (0);
|
||||
dp = mtod(m_last, caddr_t) + SCTP_BUF_LEN(m_last);
|
||||
SCTP_BUF_LEN(m_last) += padlen;
|
||||
memset(dp, 0, padlen);
|
||||
return (m_last);
|
||||
}
|
||||
|
||||
int
|
||||
struct mbuf *
|
||||
sctp_pad_lastmbuf(struct mbuf *m, int padval, struct mbuf *last_mbuf)
|
||||
{
|
||||
/* find the last mbuf in chain and pad it */
|
||||
struct mbuf *m_at;
|
||||
|
||||
if (last_mbuf) {
|
||||
if (last_mbuf != NULL) {
|
||||
return (sctp_add_pad_tombuf(last_mbuf, padval));
|
||||
} else {
|
||||
for (m_at = m; m_at; m_at = SCTP_BUF_NEXT(m_at)) {
|
||||
@ -2697,8 +2708,7 @@ sctp_pad_lastmbuf(struct mbuf *m, int padval, struct mbuf *last_mbuf)
|
||||
}
|
||||
}
|
||||
}
|
||||
SCTP_LTRACE_ERR_RET_PKT(m, NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EFAULT);
|
||||
return (EFAULT);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2741,6 +2751,7 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
|
||||
}
|
||||
SCTP_BUF_NEXT(m_notify) = NULL;
|
||||
sac = mtod(m_notify, struct sctp_assoc_change *);
|
||||
memset(sac, 0, notif_len);
|
||||
sac->sac_type = SCTP_ASSOC_CHANGE;
|
||||
sac->sac_flags = 0;
|
||||
sac->sac_length = sizeof(struct sctp_assoc_change);
|
||||
@ -2753,17 +2764,17 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
|
||||
if (notif_len > sizeof(struct sctp_assoc_change)) {
|
||||
if ((state == SCTP_COMM_UP) || (state == SCTP_RESTART)) {
|
||||
i = 0;
|
||||
if (stcb->asoc.peer_supports_prsctp) {
|
||||
if (stcb->asoc.prsctp_supported == 1) {
|
||||
sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_PR;
|
||||
}
|
||||
if (stcb->asoc.peer_supports_auth) {
|
||||
if (stcb->asoc.auth_supported == 1) {
|
||||
sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_AUTH;
|
||||
}
|
||||
if (stcb->asoc.peer_supports_asconf) {
|
||||
if (stcb->asoc.asconf_supported == 1) {
|
||||
sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_ASCONF;
|
||||
}
|
||||
sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_MULTIBUF;
|
||||
if (stcb->asoc.peer_supports_strreset) {
|
||||
if (stcb->asoc.reconfig_supported == 1) {
|
||||
sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_RE_CONFIG;
|
||||
}
|
||||
sac->sac_length += i;
|
||||
@ -2868,13 +2879,23 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
|
||||
return;
|
||||
SCTP_BUF_LEN(m_notify) = 0;
|
||||
spc = mtod(m_notify, struct sctp_paddr_change *);
|
||||
memset(spc, 0, sizeof(struct sctp_paddr_change));
|
||||
spc->spc_type = SCTP_PEER_ADDR_CHANGE;
|
||||
spc->spc_flags = 0;
|
||||
spc->spc_length = sizeof(struct sctp_paddr_change);
|
||||
switch (sa->sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
#ifdef INET6
|
||||
if (sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
|
||||
in6_sin_2_v4mapsin6((struct sockaddr_in *)sa,
|
||||
(struct sockaddr_in6 *)&spc->spc_aaddr);
|
||||
} else {
|
||||
memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in));
|
||||
}
|
||||
#else
|
||||
memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in));
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
@ -2891,7 +2912,7 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
|
||||
if (sin6->sin6_scope_id == 0) {
|
||||
/* recover scope_id for user */
|
||||
#ifdef SCTP_KAME
|
||||
(void)sa6_recoverscope(sin6);
|
||||
(void)sa6_recoverscope(sin6);
|
||||
#else
|
||||
(void)in6_recoverscope(sin6, &sin6->sin6_addr,
|
||||
NULL);
|
||||
@ -2972,21 +2993,21 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error,
|
||||
if (m_notify == NULL)
|
||||
/* no space left */
|
||||
return;
|
||||
length += chk->send_size;
|
||||
length -= sizeof(struct sctp_data_chunk);
|
||||
SCTP_BUF_LEN(m_notify) = 0;
|
||||
if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
|
||||
ssfe = mtod(m_notify, struct sctp_send_failed_event *);
|
||||
memset(ssfe, 0, length);
|
||||
ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT;
|
||||
if (sent) {
|
||||
ssfe->ssfe_flags = SCTP_DATA_SENT;
|
||||
} else {
|
||||
ssfe->ssfe_flags = SCTP_DATA_UNSENT;
|
||||
}
|
||||
length += chk->send_size;
|
||||
length -= sizeof(struct sctp_data_chunk);
|
||||
ssfe->ssfe_length = length;
|
||||
ssfe->ssfe_error = error;
|
||||
/* not exactly what the user sent in, but should be close :) */
|
||||
bzero(&ssfe->ssfe_info, sizeof(ssfe->ssfe_info));
|
||||
ssfe->ssfe_info.snd_sid = chk->rec.data.stream_number;
|
||||
ssfe->ssfe_info.snd_flags = chk->rec.data.rcv_flags;
|
||||
ssfe->ssfe_info.snd_ppid = chk->rec.data.payloadtype;
|
||||
@ -2996,12 +3017,15 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error,
|
||||
SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed_event);
|
||||
} else {
|
||||
ssf = mtod(m_notify, struct sctp_send_failed *);
|
||||
memset(ssf, 0, length);
|
||||
ssf->ssf_type = SCTP_SEND_FAILED;
|
||||
if (sent) {
|
||||
ssf->ssf_flags = SCTP_DATA_SENT;
|
||||
} else {
|
||||
ssf->ssf_flags = SCTP_DATA_UNSENT;
|
||||
}
|
||||
length += chk->send_size;
|
||||
length -= sizeof(struct sctp_data_chunk);
|
||||
ssf->ssf_length = length;
|
||||
ssf->ssf_error = error;
|
||||
/* not exactly what the user sent in, but should be close :) */
|
||||
@ -3086,16 +3110,16 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
|
||||
/* no space left */
|
||||
return;
|
||||
}
|
||||
length += sp->length;
|
||||
SCTP_BUF_LEN(m_notify) = 0;
|
||||
if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
|
||||
ssfe = mtod(m_notify, struct sctp_send_failed_event *);
|
||||
memset(ssfe, 0, length);
|
||||
ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT;
|
||||
ssfe->ssfe_flags = SCTP_DATA_UNSENT;
|
||||
length += sp->length;
|
||||
ssfe->ssfe_length = length;
|
||||
ssfe->ssfe_error = error;
|
||||
/* not exactly what the user sent in, but should be close :) */
|
||||
bzero(&ssfe->ssfe_info, sizeof(ssfe->ssfe_info));
|
||||
ssfe->ssfe_info.snd_sid = sp->stream;
|
||||
if (sp->some_taken) {
|
||||
ssfe->ssfe_info.snd_flags = SCTP_DATA_LAST_FRAG;
|
||||
@ -3109,12 +3133,13 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
|
||||
SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed_event);
|
||||
} else {
|
||||
ssf = mtod(m_notify, struct sctp_send_failed *);
|
||||
memset(ssf, 0, length);
|
||||
ssf->ssf_type = SCTP_SEND_FAILED;
|
||||
ssf->ssf_flags = SCTP_DATA_UNSENT;
|
||||
length += sp->length;
|
||||
ssf->ssf_length = length;
|
||||
ssf->ssf_error = error;
|
||||
/* not exactly what the user sent in, but should be close :) */
|
||||
bzero(&ssf->ssf_info, sizeof(ssf->ssf_info));
|
||||
ssf->ssf_info.sinfo_stream = sp->stream;
|
||||
ssf->ssf_info.sinfo_ssn = 0;
|
||||
if (sp->some_taken) {
|
||||
@ -3177,6 +3202,7 @@ sctp_notify_adaptation_layer(struct sctp_tcb *stcb)
|
||||
return;
|
||||
SCTP_BUF_LEN(m_notify) = 0;
|
||||
sai = mtod(m_notify, struct sctp_adaptation_event *);
|
||||
memset(sai, 0, sizeof(struct sctp_adaptation_event));
|
||||
sai->sai_type = SCTP_ADAPTATION_INDICATION;
|
||||
sai->sai_flags = 0;
|
||||
sai->sai_length = sizeof(struct sctp_adaptation_event);
|
||||
@ -3233,6 +3259,7 @@ sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error,
|
||||
return;
|
||||
SCTP_BUF_LEN(m_notify) = 0;
|
||||
pdapi = mtod(m_notify, struct sctp_pdapi_event *);
|
||||
memset(pdapi, 0, sizeof(struct sctp_pdapi_event));
|
||||
pdapi->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT;
|
||||
pdapi->pdapi_flags = 0;
|
||||
pdapi->pdapi_length = sizeof(struct sctp_pdapi_event);
|
||||
@ -3343,6 +3370,7 @@ sctp_notify_shutdown_event(struct sctp_tcb *stcb)
|
||||
/* no space left */
|
||||
return;
|
||||
sse = mtod(m_notify, struct sctp_shutdown_event *);
|
||||
memset(sse, 0, sizeof(struct sctp_shutdown_event));
|
||||
sse->sse_type = SCTP_SHUTDOWN_EVENT;
|
||||
sse->sse_flags = 0;
|
||||
sse->sse_length = sizeof(struct sctp_shutdown_event);
|
||||
@ -3394,6 +3422,7 @@ sctp_notify_sender_dry_event(struct sctp_tcb *stcb,
|
||||
}
|
||||
SCTP_BUF_LEN(m_notify) = 0;
|
||||
event = mtod(m_notify, struct sctp_sender_dry_event *);
|
||||
memset(event, 0, sizeof(struct sctp_sender_dry_event));
|
||||
event->sender_dry_type = SCTP_SENDER_DRY_EVENT;
|
||||
event->sender_dry_flags = 0;
|
||||
event->sender_dry_length = sizeof(struct sctp_sender_dry_event);
|
||||
@ -3426,7 +3455,6 @@ sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, uint16_t
|
||||
struct mbuf *m_notify;
|
||||
struct sctp_queued_to_read *control;
|
||||
struct sctp_stream_change_event *stradd;
|
||||
int len;
|
||||
|
||||
if ((stcb == NULL) ||
|
||||
(sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_CHANGEEVNT))) {
|
||||
@ -3439,25 +3467,20 @@ sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, uint16_t
|
||||
return;
|
||||
}
|
||||
stcb->asoc.peer_req_out = 0;
|
||||
m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
|
||||
m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_stream_change_event), 0, M_NOWAIT, 1, MT_DATA);
|
||||
if (m_notify == NULL)
|
||||
/* no space left */
|
||||
return;
|
||||
SCTP_BUF_LEN(m_notify) = 0;
|
||||
len = sizeof(struct sctp_stream_change_event);
|
||||
if (len > M_TRAILINGSPACE(m_notify)) {
|
||||
/* never enough room */
|
||||
sctp_m_freem(m_notify);
|
||||
return;
|
||||
}
|
||||
stradd = mtod(m_notify, struct sctp_stream_change_event *);
|
||||
memset(stradd, 0, sizeof(struct sctp_stream_change_event));
|
||||
stradd->strchange_type = SCTP_STREAM_CHANGE_EVENT;
|
||||
stradd->strchange_flags = flag;
|
||||
stradd->strchange_length = len;
|
||||
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;
|
||||
SCTP_BUF_LEN(m_notify) = len;
|
||||
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)) {
|
||||
/* no space */
|
||||
@ -3488,32 +3511,26 @@ sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, uint32_t sending_tsn, uint32
|
||||
struct mbuf *m_notify;
|
||||
struct sctp_queued_to_read *control;
|
||||
struct sctp_assoc_reset_event *strasoc;
|
||||
int len;
|
||||
|
||||
if ((stcb == NULL) ||
|
||||
(sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ASSOC_RESETEVNT))) {
|
||||
/* event not enabled */
|
||||
return;
|
||||
}
|
||||
m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
|
||||
m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_assoc_reset_event), 0, M_NOWAIT, 1, MT_DATA);
|
||||
if (m_notify == NULL)
|
||||
/* no space left */
|
||||
return;
|
||||
SCTP_BUF_LEN(m_notify) = 0;
|
||||
len = sizeof(struct sctp_assoc_reset_event);
|
||||
if (len > M_TRAILINGSPACE(m_notify)) {
|
||||
/* never enough room */
|
||||
sctp_m_freem(m_notify);
|
||||
return;
|
||||
}
|
||||
strasoc = mtod(m_notify, struct sctp_assoc_reset_event *);
|
||||
memset(strasoc, 0, sizeof(struct sctp_assoc_reset_event));
|
||||
strasoc->assocreset_type = SCTP_ASSOC_RESET_EVENT;
|
||||
strasoc->assocreset_flags = flag;
|
||||
strasoc->assocreset_length = len;
|
||||
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;
|
||||
SCTP_BUF_LEN(m_notify) = len;
|
||||
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)) {
|
||||
/* no space */
|
||||
@ -3567,6 +3584,7 @@ sctp_notify_stream_reset(struct sctp_tcb *stcb,
|
||||
return;
|
||||
}
|
||||
strreset = mtod(m_notify, struct sctp_stream_reset_event *);
|
||||
memset(strreset, 0, len);
|
||||
strreset->strreset_type = SCTP_STREAM_RESET_EVENT;
|
||||
strreset->strreset_flags = flag;
|
||||
strreset->strreset_length = len;
|
||||
@ -3633,6 +3651,7 @@ sctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error, struct sctp_erro
|
||||
}
|
||||
SCTP_BUF_NEXT(m_notify) = NULL;
|
||||
sre = mtod(m_notify, struct sctp_remote_error *);
|
||||
memset(sre, 0, notif_len);
|
||||
sre->sre_type = SCTP_REMOTE_ERROR;
|
||||
sre->sre_flags = 0;
|
||||
sre->sre_length = sizeof(struct sctp_remote_error);
|
||||
@ -3708,7 +3727,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
|
||||
if (stcb->asoc.adaptation_needed && (stcb->asoc.adaptation_sent == 0)) {
|
||||
sctp_notify_adaptation_layer(stcb);
|
||||
}
|
||||
if (stcb->asoc.peer_supports_auth == 0) {
|
||||
if (stcb->asoc.auth_supported == 0) {
|
||||
sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0,
|
||||
NULL, so_locked);
|
||||
}
|
||||
@ -3797,7 +3816,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
|
||||
break;
|
||||
case SCTP_NOTIFY_ASSOC_RESTART:
|
||||
sctp_notify_assoc_change(SCTP_RESTART, stcb, error, NULL, 0, so_locked);
|
||||
if (stcb->asoc.peer_supports_auth == 0) {
|
||||
if (stcb->asoc.auth_supported == 0) {
|
||||
sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0,
|
||||
NULL, so_locked);
|
||||
}
|
||||
@ -4029,7 +4048,7 @@ sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
struct sockaddr *src, struct sockaddr *dst,
|
||||
struct sctphdr *sh, struct mbuf *op_err,
|
||||
#if defined(__FreeBSD__)
|
||||
uint8_t use_mflowid, uint32_t mflowid,
|
||||
uint8_t mflowtype, uint32_t mflowid,
|
||||
#endif
|
||||
uint32_t vrf_id, uint16_t port)
|
||||
{
|
||||
@ -4049,7 +4068,7 @@ sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
}
|
||||
sctp_send_abort(m, iphlen, src, dst, sh, vtag, op_err,
|
||||
#if defined(__FreeBSD__)
|
||||
use_mflowid, mflowid,
|
||||
mflowtype, mflowid,
|
||||
#endif
|
||||
vrf_id, port);
|
||||
if (stcb != NULL) {
|
||||
@ -4216,8 +4235,9 @@ void
|
||||
sctp_handle_ootb(struct mbuf *m, int iphlen, int offset,
|
||||
struct sockaddr *src, struct sockaddr *dst,
|
||||
struct sctphdr *sh, struct sctp_inpcb *inp,
|
||||
struct mbuf *cause,
|
||||
#if defined(__FreeBSD__)
|
||||
uint8_t use_mflowid, uint32_t mflowid,
|
||||
uint8_t mflowtype, uint32_t mflowid,
|
||||
#endif
|
||||
uint32_t vrf_id, uint16_t port)
|
||||
{
|
||||
@ -4252,9 +4272,6 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset,
|
||||
case SCTP_INIT:
|
||||
contains_init_chunk = 1;
|
||||
break;
|
||||
case SCTP_COOKIE_ECHO:
|
||||
/* We hit here only if the assoc is being freed */
|
||||
return;
|
||||
case SCTP_PACKET_DROPPED:
|
||||
/* we don't respond to pkt-dropped */
|
||||
return;
|
||||
@ -4270,7 +4287,7 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset,
|
||||
case SCTP_SHUTDOWN_ACK:
|
||||
sctp_send_shutdown_complete2(src, dst, sh,
|
||||
#if defined(__FreeBSD__)
|
||||
use_mflowid, mflowid,
|
||||
mflowtype, mflowid,
|
||||
#endif
|
||||
vrf_id, port);
|
||||
return;
|
||||
@ -4284,9 +4301,9 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset,
|
||||
if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
|
||||
((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
|
||||
(contains_init_chunk == 0))) {
|
||||
sctp_send_abort(m, iphlen, src, dst, sh, 0, NULL,
|
||||
sctp_send_abort(m, iphlen, src, dst, sh, 0, cause,
|
||||
#if defined(__FreeBSD__)
|
||||
use_mflowid, mflowid,
|
||||
mflowtype, mflowid,
|
||||
#endif
|
||||
vrf_id, port);
|
||||
}
|
||||
@ -5083,19 +5100,43 @@ sctp_append_to_readq(struct sctp_inpcb *inp,
|
||||
*/
|
||||
|
||||
struct mbuf *
|
||||
sctp_generate_invmanparam(int err)
|
||||
sctp_generate_cause(uint16_t code, char *info)
|
||||
{
|
||||
/* Return a MBUF with a invalid mandatory parameter */
|
||||
struct mbuf *m;
|
||||
struct sctp_gen_error_cause *cause;
|
||||
size_t info_len, len;
|
||||
|
||||
m = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), 0, M_NOWAIT, 1, MT_DATA);
|
||||
if (m) {
|
||||
struct sctp_paramhdr *ph;
|
||||
if ((code == 0) || (info == NULL)) {
|
||||
return (NULL);
|
||||
}
|
||||
info_len = strlen(info);
|
||||
len = sizeof(struct sctp_paramhdr) + info_len;
|
||||
m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA);
|
||||
if (m != NULL) {
|
||||
SCTP_BUF_LEN(m) = len;
|
||||
cause = mtod(m, struct sctp_gen_error_cause *);
|
||||
cause->code = htons(code);
|
||||
cause->length = htons((uint16_t)len);
|
||||
memcpy(cause->info, info, info_len);
|
||||
}
|
||||
return (m);
|
||||
}
|
||||
|
||||
SCTP_BUF_LEN(m) = sizeof(struct sctp_paramhdr);
|
||||
ph = mtod(m, struct sctp_paramhdr *);
|
||||
ph->param_length = htons(sizeof(struct sctp_paramhdr));
|
||||
ph->param_type = htons(err);
|
||||
struct mbuf *
|
||||
sctp_generate_no_user_data_cause(uint32_t tsn)
|
||||
{
|
||||
struct mbuf *m;
|
||||
struct sctp_error_no_user_data *no_user_data_cause;
|
||||
size_t len;
|
||||
|
||||
len = sizeof(struct sctp_error_no_user_data);
|
||||
m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA);
|
||||
if (m != NULL) {
|
||||
SCTP_BUF_LEN(m) = len;
|
||||
no_user_data_cause = mtod(m, struct sctp_error_no_user_data *);
|
||||
no_user_data_cause->cause.code = htons(SCTP_CAUSE_NO_USER_DATA);
|
||||
no_user_data_cause->cause.length = htons((uint16_t)len);
|
||||
no_user_data_cause->tsn = tsn; /* tsn is passed in as NBO */
|
||||
}
|
||||
return (m);
|
||||
}
|
||||
@ -5151,6 +5192,7 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
|
||||
int ret_sz = 0;
|
||||
int notdone;
|
||||
int do_wakeup_routine = 0;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
if (so_locked) {
|
||||
sctp_lock_assert(SCTP_INP_SO(stcb->sctp_ep));
|
||||
@ -5160,6 +5202,21 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
|
||||
#endif
|
||||
stream = tp1->rec.data.stream_number;
|
||||
seq = tp1->rec.data.stream_seq;
|
||||
if (sent || !(tp1->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG)) {
|
||||
stcb->asoc.abandoned_sent[0]++;
|
||||
stcb->asoc.abandoned_sent[PR_SCTP_POLICY(tp1->flags)]++;
|
||||
stcb->asoc.strmout[stream].abandoned_sent[0]++;
|
||||
#if defined(SCTP_DETAILED_STR_STATS)
|
||||
stcb->asoc.strmout[stream].abandoned_sent[PR_SCTP_POLICY(tp1->flags)]++;
|
||||
#endif
|
||||
} else {
|
||||
stcb->asoc.abandoned_unsent[0]++;
|
||||
stcb->asoc.abandoned_unsent[PR_SCTP_POLICY(tp1->flags)]++;
|
||||
stcb->asoc.strmout[stream].abandoned_unsent[0]++;
|
||||
#if defined(SCTP_DETAILED_STR_STATS)
|
||||
stcb->asoc.strmout[stream].abandoned_unsent[PR_SCTP_POLICY(tp1->flags)]++;
|
||||
#endif
|
||||
}
|
||||
do {
|
||||
ret_sz += tp1->book_size;
|
||||
if (tp1->data != NULL) {
|
||||
@ -5210,7 +5267,7 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
|
||||
*/
|
||||
TAILQ_FOREACH_SAFE(tp1, &stcb->asoc.send_queue, sctp_next, tp2) {
|
||||
if ((tp1->rec.data.stream_number != stream) ||
|
||||
(tp1->rec.data.stream_seq != seq)) {
|
||||
(tp1->rec.data.stream_seq != seq)) {
|
||||
break;
|
||||
}
|
||||
/* save to chk in case we have some on stream out
|
||||
@ -5475,7 +5532,6 @@ sctp_find_ifa_by_addr(struct sockaddr *addr, uint32_t vrf_id, int holds_lock)
|
||||
|
||||
vrf = sctp_find_vrf(vrf_id);
|
||||
if (vrf == NULL) {
|
||||
stage_right:
|
||||
if (holds_lock == 0)
|
||||
SCTP_IPI_ADDR_RUNLOCK();
|
||||
return (NULL);
|
||||
@ -5496,15 +5552,6 @@ sctp_find_ifa_by_addr(struct sockaddr *addr, uint32_t vrf_id, int holds_lock)
|
||||
return (NULL);
|
||||
}
|
||||
LIST_FOREACH(sctp_ifap, hash_head, next_bucket) {
|
||||
if (sctp_ifap == NULL) {
|
||||
#ifdef INVARIANTS
|
||||
panic("Huh LIST_FOREACH corrupt");
|
||||
goto stage_right;
|
||||
#else
|
||||
SCTP_PRINTF("LIST corrupt of sctp_ifap's?\n");
|
||||
goto stage_right;
|
||||
#endif
|
||||
}
|
||||
if (addr->sa_family != sctp_ifap->address.sa.sa_family)
|
||||
continue;
|
||||
#ifdef INET
|
||||
@ -5651,7 +5698,7 @@ sctp_sorecvmsg(struct socket *so,
|
||||
*/
|
||||
struct sctp_inpcb *inp = NULL;
|
||||
int my_len = 0;
|
||||
int cp_len = 0, error = 0;
|
||||
int cp_len = 0, error = 0;
|
||||
struct sctp_queued_to_read *control = NULL, *ctl = NULL, *nxt = NULL;
|
||||
struct mbuf *m = NULL;
|
||||
struct sctp_tcb *stcb = NULL;
|
||||
@ -6159,76 +6206,50 @@ sctp_sorecvmsg(struct socket *so,
|
||||
entry->flgs = control->sinfo_flags;
|
||||
}
|
||||
#endif
|
||||
if (fromlen && from) {
|
||||
#ifdef HAVE_SA_LEN
|
||||
cp_len = min((size_t)fromlen, (size_t)control->whoFrom->ro._l_addr.sa.sa_len);
|
||||
#endif
|
||||
if ((fromlen > 0) && (from != NULL)) {
|
||||
union sctp_sockstore store;
|
||||
size_t len;
|
||||
|
||||
switch (control->whoFrom->ro._l_addr.sa.sa_family) {
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
#ifndef HAVE_SA_LEN
|
||||
cp_len = min((size_t)fromlen, sizeof(struct sockaddr_in6));
|
||||
#endif
|
||||
((struct sockaddr_in6 *)from)->sin6_port = control->port_from;
|
||||
len = sizeof(struct sockaddr_in6);
|
||||
store.sin6 = control->whoFrom->ro._l_addr.sin6;
|
||||
store.sin6.sin6_port = control->port_from;
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
#ifndef HAVE_SA_LEN
|
||||
cp_len = min((size_t)fromlen, sizeof(struct sockaddr_in));
|
||||
#ifdef INET6
|
||||
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
|
||||
len = sizeof(struct sockaddr_in6);
|
||||
in6_sin_2_v4mapsin6(&control->whoFrom->ro._l_addr.sin,
|
||||
&store.sin6);
|
||||
store.sin6.sin6_port = control->port_from;
|
||||
} else {
|
||||
len = sizeof(struct sockaddr_in);
|
||||
store.sin = control->whoFrom->ro._l_addr.sin;
|
||||
store.sin.sin_port = control->port_from;
|
||||
}
|
||||
#else
|
||||
len = sizeof(struct sockaddr_in);
|
||||
store.sin = control->whoFrom->ro._l_addr.sin;
|
||||
store.sin.sin_port = control->port_from;
|
||||
#endif
|
||||
((struct sockaddr_in *)from)->sin_port = control->port_from;
|
||||
break;
|
||||
#endif
|
||||
#if defined(__Userspace__)
|
||||
case AF_CONN:
|
||||
#ifndef HAVE_SA_LEN
|
||||
cp_len = min((size_t)fromlen, sizeof(struct sockaddr_conn));
|
||||
#endif
|
||||
((struct sockaddr_conn *)from)->sconn_port = control->port_from;
|
||||
len = sizeof(struct sockaddr_conn);
|
||||
store.sconn = control->whoFrom->ro._l_addr.sconn;
|
||||
store.sconn.sconn_port = control->port_from;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
#ifndef HAVE_SA_LEN
|
||||
cp_len = min((size_t)fromlen, sizeof(struct sockaddr));
|
||||
#endif
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
memcpy(from, &control->whoFrom->ro._l_addr, cp_len);
|
||||
|
||||
#if defined(INET) && defined(INET6)
|
||||
if ((sctp_is_feature_on(inp,SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) &&
|
||||
(from->sa_family == AF_INET) &&
|
||||
((size_t)fromlen >= sizeof(struct sockaddr_in6))) {
|
||||
struct sockaddr_in *sin;
|
||||
struct sockaddr_in6 sin6;
|
||||
|
||||
sin = (struct sockaddr_in *)from;
|
||||
bzero(&sin6, sizeof(sin6));
|
||||
sin6.sin6_family = AF_INET6;
|
||||
#ifdef HAVE_SIN6_LEN
|
||||
sin6.sin6_len = sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
#if defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Darwin) || defined(__Userspace_os_Windows)
|
||||
((uint32_t *)&sin6.sin6_addr)[2] = htonl(0xffff);
|
||||
bcopy(&sin->sin_addr,
|
||||
&(((uint32_t *)&sin6.sin6_addr)[3]),
|
||||
sizeof(uint32_t));
|
||||
#elif defined(__Windows__)
|
||||
((uint32_t *)&sin6.sin6_addr)[2] = htonl(0xffff);
|
||||
bcopy(&sin->sin_addr,
|
||||
&((uint32_t *)&sin6.sin6_addr)[3],
|
||||
sizeof(uint32_t));
|
||||
#else
|
||||
sin6.sin6_addr.s6_addr32[2] = htonl(0xffff);
|
||||
bcopy(&sin->sin_addr,
|
||||
&sin6.sin6_addr.s6_addr32[3],
|
||||
sizeof(sin6.sin6_addr.s6_addr32[3]));
|
||||
#endif
|
||||
sin6.sin6_port = sin->sin_port;
|
||||
memcpy(from, &sin6, sizeof(struct sockaddr_in6));
|
||||
}
|
||||
#endif
|
||||
memcpy(from, &store, min((size_t)fromlen, len));
|
||||
#if defined(SCTP_EMBEDDED_V6_SCOPE)
|
||||
#ifdef INET6
|
||||
{
|
||||
@ -6527,13 +6548,13 @@ sctp_sorecvmsg(struct socket *so,
|
||||
SOCKBUF_LOCK(&so->so_rcv);
|
||||
hold_sblock = 1;
|
||||
}
|
||||
#if defined(__APPLE__)
|
||||
sbunlock(&so->so_rcv, 1);
|
||||
#endif
|
||||
if ((copied_so_far) && (control->length == 0) &&
|
||||
(sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE))) {
|
||||
goto release;
|
||||
}
|
||||
#if defined(__APPLE__)
|
||||
sbunlock(&so->so_rcv, 1);
|
||||
#endif
|
||||
if (so->so_rcv.sb_cc <= control->held_length) {
|
||||
error = sbwait(&so->so_rcv);
|
||||
if (error) {
|
||||
@ -6775,9 +6796,7 @@ struct mbuf *
|
||||
sctp_m_free(struct mbuf *m)
|
||||
{
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
|
||||
if (SCTP_BUF_IS_EXTENDED(m)) {
|
||||
sctp_log_mb(m, SCTP_MBUF_IFREE);
|
||||
}
|
||||
sctp_log_mb(m, SCTP_MBUF_IFREE);
|
||||
}
|
||||
return (m_free(m));
|
||||
}
|
||||
@ -6882,9 +6901,12 @@ sctp_soreceive( struct socket *so,
|
||||
#if defined(__APPLE__)
|
||||
SCTP_SOCKET_LOCK(so, 1);
|
||||
#endif
|
||||
if (filling_sinfo) {
|
||||
memset(&sinfo, 0, sizeof(struct sctp_extrcvinfo));
|
||||
}
|
||||
error = sctp_sorecvmsg(so, uio, mp0, from, fromlen, flagsp,
|
||||
(struct sctp_sndrcvinfo *)&sinfo, filling_sinfo);
|
||||
if ((controlp) && (filling_sinfo)) {
|
||||
if (controlp != NULL) {
|
||||
/* copy back the sinfo in a CMSG format */
|
||||
if (filling_sinfo)
|
||||
*controlp = sctp_build_ctl_nchunk(inp,
|
||||
@ -7233,7 +7255,7 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
|
||||
uint32_t vrf_id, int *error, void *p)
|
||||
{
|
||||
struct sockaddr *addr_touse;
|
||||
#ifdef INET6
|
||||
#if defined(INET) && defined(INET6)
|
||||
struct sockaddr_in sin;
|
||||
#endif
|
||||
#ifdef SCTP_MVRF
|
||||
@ -7263,7 +7285,10 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
|
||||
addr_touse = sa;
|
||||
#ifdef INET6
|
||||
if (sa->sa_family == AF_INET6) {
|
||||
#ifdef INET
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
#endif
|
||||
#ifdef HAVE_SA_LEN
|
||||
if (sa->sa_len != sizeof(struct sockaddr_in6)) {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
|
||||
@ -7277,6 +7302,7 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
|
||||
*error = EINVAL;
|
||||
return;
|
||||
}
|
||||
#ifdef INET
|
||||
sin6 = (struct sockaddr_in6 *)addr_touse;
|
||||
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
|
||||
@ -7289,6 +7315,7 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
|
||||
in6_sin6_2_sin(&sin, sin6);
|
||||
addr_touse = (struct sockaddr *)&sin;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#ifdef INET
|
||||
@ -7383,7 +7410,7 @@ sctp_bindx_delete_address(struct sctp_inpcb *inp,
|
||||
uint32_t vrf_id, int *error)
|
||||
{
|
||||
struct sockaddr *addr_touse;
|
||||
#ifdef INET6
|
||||
#if defined(INET) && defined(INET6)
|
||||
struct sockaddr_in sin;
|
||||
#endif
|
||||
#ifdef SCTP_MVRF
|
||||
@ -7413,7 +7440,10 @@ sctp_bindx_delete_address(struct sctp_inpcb *inp,
|
||||
addr_touse = sa;
|
||||
#ifdef INET6
|
||||
if (sa->sa_family == AF_INET6) {
|
||||
#ifdef INET
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SA_LEN
|
||||
if (sa->sa_len != sizeof(struct sockaddr_in6)) {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
|
||||
@ -7427,6 +7457,7 @@ sctp_bindx_delete_address(struct sctp_inpcb *inp,
|
||||
*error = EINVAL;
|
||||
return;
|
||||
}
|
||||
#ifdef INET
|
||||
sin6 = (struct sockaddr_in6 *)addr_touse;
|
||||
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
|
||||
@ -7439,6 +7470,7 @@ sctp_bindx_delete_address(struct sctp_inpcb *inp,
|
||||
in6_sin6_2_sin(&sin, sin6);
|
||||
addr_touse = (struct sockaddr *)&sin;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#ifdef INET
|
||||
@ -7539,11 +7571,17 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
|
||||
if (ipv4_addr_legal) {
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
|
||||
sin = &sctp_ifa->address.sin;
|
||||
if (sin->sin_addr.s_addr == 0) {
|
||||
/* skip unspecified addrs */
|
||||
continue;
|
||||
}
|
||||
#if defined(__FreeBSD__)
|
||||
if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
|
||||
&sin->sin_addr) != 0) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if ((ipv4_local_scope == 0) &&
|
||||
(IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
|
||||
continue;
|
||||
@ -7563,10 +7601,16 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
|
||||
#if defined(SCTP_EMBEDDED_V6_SCOPE) && !defined(SCTP_KAME)
|
||||
struct sockaddr_in6 lsa6;
|
||||
#endif
|
||||
sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
|
||||
sin6 = &sctp_ifa->address.sin6;
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
||||
continue;
|
||||
}
|
||||
#if defined(__FreeBSD__)
|
||||
if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
|
||||
&sin6->sin6_addr) != 0) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
|
||||
if (local_scope == 0)
|
||||
continue;
|
||||
@ -7693,7 +7737,8 @@ sctp_log_trace(uint32_t subsys, const char *str SCTP_UNUSED, uint32_t a, uint32_
|
||||
#if defined(__FreeBSD__)
|
||||
#if __FreeBSD_version >= 800044
|
||||
static void
|
||||
sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *ignored)
|
||||
sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *ignored,
|
||||
const struct sockaddr *sa SCTP_UNUSED, void *ctx SCTP_UNUSED)
|
||||
{
|
||||
struct ip *iph;
|
||||
#ifdef INET6
|
||||
@ -7828,7 +7873,7 @@ sctp_over_udp_start(void)
|
||||
}
|
||||
/* Call the special UDP hook. */
|
||||
if ((ret = udp_set_kernel_tunneling(SCTP_BASE_INFO(udp4_tun_socket),
|
||||
sctp_recv_udp_tunneled_packet))) {
|
||||
sctp_recv_udp_tunneled_packet, NULL))) {
|
||||
sctp_over_udp_stop();
|
||||
return (ret);
|
||||
}
|
||||
@ -7852,7 +7897,7 @@ sctp_over_udp_start(void)
|
||||
}
|
||||
/* Call the special UDP hook. */
|
||||
if ((ret = udp_set_kernel_tunneling(SCTP_BASE_INFO(udp6_tun_socket),
|
||||
sctp_recv_udp_tunneled_packet))) {
|
||||
sctp_recv_udp_tunneled_packet, NULL))) {
|
||||
sctp_over_udp_stop();
|
||||
return (ret);
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctputil.h 243186 2012-11-17 20:04:04Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctputil.h 276914 2015-01-10 20:49:57Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_UTIL_H_
|
||||
@ -146,9 +146,11 @@ struct sctp_paramhdr *
|
||||
sctp_get_next_param(struct mbuf *, int,
|
||||
struct sctp_paramhdr *, int);
|
||||
|
||||
int sctp_add_pad_tombuf(struct mbuf *, int);
|
||||
struct mbuf *
|
||||
sctp_add_pad_tombuf(struct mbuf *, int);
|
||||
|
||||
int sctp_pad_lastmbuf(struct mbuf *, int, struct mbuf *);
|
||||
struct mbuf *
|
||||
sctp_pad_lastmbuf(struct mbuf *, int, struct mbuf *);
|
||||
|
||||
void sctp_ulp_notify(uint32_t, struct sctp_tcb *, uint32_t, void *, int
|
||||
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
|
||||
@ -202,6 +204,7 @@ sctp_abort_an_association(struct sctp_inpcb *, struct sctp_tcb *,
|
||||
void sctp_handle_ootb(struct mbuf *, int, int,
|
||||
struct sockaddr *, struct sockaddr *,
|
||||
struct sctphdr *, struct sctp_inpcb *,
|
||||
struct mbuf *,
|
||||
#if defined(__FreeBSD__)
|
||||
uint8_t, uint32_t,
|
||||
#endif
|
||||
@ -239,10 +242,10 @@ sctp_recover_scope(struct sockaddr_in6 *, struct sockaddr_in6 *);
|
||||
} while (0)
|
||||
#else
|
||||
#define sctp_recover_scope_mac(addr, store) do { \
|
||||
if ((addr->sin6_family == AF_INET6) && \
|
||||
(IN6_IS_SCOPE_LINKLOCAL(&addr->sin6_addr))) { \
|
||||
if ((addr->sin6_family == AF_INET6) && \
|
||||
(IN6_IS_SCOPE_LINKLOCAL(&addr->sin6_addr))) { \
|
||||
*store = *addr; \
|
||||
if (addr->sin6_scope_id == 0) { \
|
||||
if (addr->sin6_scope_id == 0) { \
|
||||
if (!in6_recoverscope(store, &store->sin6_addr, \
|
||||
NULL)) { \
|
||||
addr = store; \
|
||||
@ -251,7 +254,7 @@ sctp_recover_scope(struct sockaddr_in6 *, struct sockaddr_in6 *);
|
||||
in6_clearscope(&addr->sin6_addr); \
|
||||
addr = store; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
#endif
|
||||
@ -269,7 +272,8 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *, struct sctp_tmit_chunk *,
|
||||
#endif
|
||||
);
|
||||
|
||||
struct mbuf *sctp_generate_invmanparam(int);
|
||||
struct mbuf *sctp_generate_cause(uint16_t, char *);
|
||||
struct mbuf *sctp_generate_no_user_data_cause(uint32_t);
|
||||
|
||||
void sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
|
||||
struct sockaddr *sa, sctp_assoc_t assoc_id,
|
||||
@ -289,42 +293,42 @@ sctp_free_bufspace(struct sctp_tcb *, struct sctp_association *,
|
||||
#define sctp_free_bufspace(stcb, asoc, tp1, chk_cnt) \
|
||||
do { \
|
||||
if (tp1->data != NULL) { \
|
||||
atomic_subtract_int(&((asoc)->chunks_on_out_queue), chk_cnt); \
|
||||
atomic_subtract_int(&((asoc)->chunks_on_out_queue), chk_cnt); \
|
||||
if ((asoc)->total_output_queue_size >= tp1->book_size) { \
|
||||
atomic_subtract_int(&((asoc)->total_output_queue_size), tp1->book_size); \
|
||||
} else { \
|
||||
(asoc)->total_output_queue_size = 0; \
|
||||
} \
|
||||
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 && ((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 >= 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; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#define sctp_free_spbufspace(stcb, asoc, sp) \
|
||||
do { \
|
||||
if (sp->data != NULL) { \
|
||||
if (sp->data != NULL) { \
|
||||
if ((asoc)->total_output_queue_size >= sp->length) { \
|
||||
atomic_subtract_int(&(asoc)->total_output_queue_size, sp->length); \
|
||||
} else { \
|
||||
(asoc)->total_output_queue_size = 0; \
|
||||
} \
|
||||
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 && ((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; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define sctp_snd_sb_alloc(stcb, sz) \
|
||||
@ -365,9 +369,14 @@ void sctp_log_strm_del_alt(struct sctp_tcb *stcb, uint32_t, uint16_t, uint16_t,
|
||||
void sctp_log_nagle_event(struct sctp_tcb *stcb, int action);
|
||||
|
||||
|
||||
#ifdef SCTP_MBUF_LOGGING
|
||||
void
|
||||
sctp_log_mb(struct mbuf *m, int from);
|
||||
|
||||
void
|
||||
sctp_log_mbc(struct mbuf *m, int from);
|
||||
#endif
|
||||
|
||||
void
|
||||
sctp_sblog(struct sockbuf *sb,
|
||||
struct sctp_tcb *stcb, int from, int incr);
|
||||
@ -385,7 +394,6 @@ void sctp_log_lock(struct sctp_inpcb *inp, struct sctp_tcb *stcb, uint8_t from);
|
||||
void sctp_log_maxburst(struct sctp_tcb *stcb, struct sctp_nets *, int, int, uint8_t);
|
||||
void sctp_log_block(uint8_t, struct sctp_association *, int);
|
||||
void sctp_log_rwnd(uint8_t, uint32_t, uint32_t, uint32_t);
|
||||
void sctp_log_mbcnt(uint8_t, uint32_t, uint32_t, uint32_t, uint32_t);
|
||||
void sctp_log_rwnd_set(uint8_t, uint32_t, uint32_t, uint32_t, uint32_t);
|
||||
int sctp_fill_stat_log(void *, size_t *);
|
||||
void sctp_log_fr(uint32_t, uint32_t, uint32_t, int);
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 257555 2013-11-02 20:12:19Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 276914 2015-01-10 20:49:57Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -79,6 +79,7 @@ extern struct protosw inetsw[];
|
||||
int ip6_v6only=0;
|
||||
#endif
|
||||
#if defined(__Userspace__)
|
||||
#ifdef INET
|
||||
void
|
||||
in6_sin6_2_sin(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
|
||||
{
|
||||
@ -96,7 +97,6 @@ in6_sin6_2_sin(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
|
||||
temp = temp << 16;
|
||||
temp = temp | sin6->sin6_addr.s6_addr16[6];
|
||||
sin->sin_addr.s_addr = temp;
|
||||
sctp_print_address((struct sockaddr*)sin);
|
||||
#else
|
||||
sin->sin_addr.s_addr = sin6->sin6_addr.s6_addr32[3];
|
||||
#endif
|
||||
@ -113,6 +113,29 @@ in6_sin6_2_sin_in_sock(struct sockaddr *nam)
|
||||
sin_p = (struct sockaddr_in *)nam;
|
||||
in6_sin6_2_sin(sin_p, &sin6);
|
||||
}
|
||||
|
||||
void
|
||||
in6_sin_2_v4mapsin6(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
|
||||
{
|
||||
bzero(sin6, sizeof(struct sockaddr_in6));
|
||||
sin6->sin6_family = AF_INET6;
|
||||
#ifdef HAVE_SIN6_LEN
|
||||
sin6->sin6_len = sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
sin6->sin6_port = sin->sin_port;
|
||||
#if defined(__Userspace_os_Windows)
|
||||
((uint32_t *)&sin6->sin6_addr)[0] = 0;
|
||||
((uint32_t *)&sin6->sin6_addr)[1] = 0;
|
||||
((uint32_t *)&sin6->sin6_addr)[2] = htonl(0xffff);
|
||||
((uint32_t *)&sin6->sin6_addr)[3] = sin->sin_addr.s_addr;
|
||||
#else
|
||||
sin6->sin6_addr.s6_addr32[0] = 0;
|
||||
sin6->sin6_addr.s6_addr32[1] = 0;
|
||||
sin6->sin6_addr.s6_addr32[2] = htonl(0xffff);
|
||||
sin6->sin6_addr.s6_addr32[3] = sin->sin_addr.s_addr;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(__Userspace__)
|
||||
@ -139,7 +162,7 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
|
||||
#endif
|
||||
#if defined(__FreeBSD__)
|
||||
uint32_t mflowid;
|
||||
uint8_t use_mflowid;
|
||||
uint8_t mflowtype;
|
||||
#endif
|
||||
#if !(defined(__APPLE__) || defined (__FreeBSD__))
|
||||
uint16_t port = 0;
|
||||
@ -163,13 +186,7 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
|
||||
#ifdef SCTP_MBUF_LOGGING
|
||||
/* Log in any input mbufs */
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
|
||||
struct mbuf *mat;
|
||||
|
||||
for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) {
|
||||
if (SCTP_BUF_IS_EXTENDED(mat)) {
|
||||
sctp_log_mb(mat, SCTP_MBUF_INPUT);
|
||||
}
|
||||
}
|
||||
sctp_log_mbc(m, SCTP_MBUF_INPUT);
|
||||
}
|
||||
#endif
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
@ -214,14 +231,9 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
|
||||
m->m_pkthdr.csum_flags);
|
||||
#endif
|
||||
#if defined(__FreeBSD__)
|
||||
if (m->m_flags & M_FLOWID) {
|
||||
mflowid = m->m_pkthdr.flowid;
|
||||
use_mflowid = 1;
|
||||
} else {
|
||||
mflowid = 0;
|
||||
use_mflowid = 0;
|
||||
}
|
||||
#endif
|
||||
mflowid = m->m_pkthdr.flowid;
|
||||
mflowtype = M_HASHTYPE_GET(m);
|
||||
#endif
|
||||
SCTP_STAT_INCR(sctps_recvpackets);
|
||||
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
|
||||
/* Get IP, SCTP, and first chunk header together in the first mbuf. */
|
||||
@ -246,7 +258,7 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
|
||||
#if defined(__APPLE__)
|
||||
/* XXX: This code should also be used on Apple */
|
||||
#endif
|
||||
if (in6_setscope(&src.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) {
|
||||
if (in6_setscope(&src.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) {
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
@ -261,13 +273,7 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
|
||||
#if defined(__APPLE__)
|
||||
/* XXX: This code should also be used on Apple */
|
||||
#endif
|
||||
if (in6_setscope(&dst.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) {
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
if (faithprefix_p != NULL && (*faithprefix_p) (&dst.sin6_addr)) {
|
||||
/* XXX send icmp6 host/port unreach? */
|
||||
if (in6_setscope(&dst.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) {
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
@ -318,7 +324,7 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
|
||||
#endif
|
||||
ecn_bits,
|
||||
#if defined(__FreeBSD__)
|
||||
use_mflowid, mflowid,
|
||||
mflowtype, mflowid,
|
||||
#endif
|
||||
vrf_id, port);
|
||||
out:
|
||||
@ -1184,7 +1190,7 @@ sctp6_connect(struct socket *so, struct mbuf *nam, struct proc *p)
|
||||
#ifdef INET
|
||||
struct in6pcb *inp6;
|
||||
struct sockaddr_in6 *sin6;
|
||||
struct sockaddr_storage ss;
|
||||
union sctp_sockstore store;
|
||||
#endif
|
||||
|
||||
#ifdef INET
|
||||
@ -1273,8 +1279,8 @@ sctp6_connect(struct socket *so, struct mbuf *nam, struct proc *p)
|
||||
}
|
||||
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
|
||||
/* convert v4-mapped into v4 addr */
|
||||
in6_sin6_2_sin((struct sockaddr_in *)&ss, sin6);
|
||||
addr = (struct sockaddr *)&ss;
|
||||
in6_sin6_2_sin(&store.sin, sin6);
|
||||
addr = &store.sa;
|
||||
}
|
||||
#endif /* INET */
|
||||
/* Now do we connect? */
|
||||
@ -1424,7 +1430,7 @@ sctp6_getaddr(struct socket *so, struct mbuf *nam)
|
||||
if (laddr->ifa->address.sa.sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *sin_a;
|
||||
|
||||
sin_a = (struct sockaddr_in6 *)&laddr->ifa->address.sin6;
|
||||
sin_a = &laddr->ifa->address.sin6;
|
||||
sin6->sin6_addr = sin_a->sin6_addr;
|
||||
fnd = 1;
|
||||
break;
|
||||
@ -1544,8 +1550,13 @@ sctp6_peeraddr(struct socket *so, struct mbuf *nam)
|
||||
}
|
||||
#ifdef SCTP_EMBEDDED_V6_SCOPE
|
||||
#ifdef SCTP_KAME
|
||||
if ((error = sa6_recoverscope(sin6)) != 0)
|
||||
if ((error = sa6_recoverscope(sin6)) != 0) {
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__)
|
||||
SCTP_FREE_SONAME(sin6);
|
||||
#endif
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, error);
|
||||
return (error);
|
||||
}
|
||||
#else
|
||||
in6_recoverscope(sin6, &sin6->sin6_addr, NULL);
|
||||
#endif /* SCTP_KAME */
|
||||
@ -1729,7 +1740,7 @@ struct pr_usrreqs sctp6_usrreqs = {
|
||||
.pru_sockaddr = sctp6_in6getaddr,
|
||||
.pru_sosend = sctp_sosend,
|
||||
.pru_soreceive = sctp_soreceive,
|
||||
.pru_sopoll = sopoll
|
||||
.pru_sopoll = sopoll
|
||||
#elif defined(__Windows__)
|
||||
sctp6_abort,
|
||||
sctp_accept,
|
||||
|
@ -39,7 +39,11 @@ __FBSDID("$FreeBSD: head/sys/netinet6/sctp6_var.h 243186 2012-11-17 20:04:04Z tu
|
||||
#define _NETINET6_SCTP6_VAR_H_
|
||||
|
||||
#if defined(__Userspace__)
|
||||
extern void in6_sin6_2_sin(struct sockaddr_in *, struct sockaddr_in6 *sin6);
|
||||
#ifdef INET
|
||||
extern void in6_sin6_2_sin(struct sockaddr_in *, struct sockaddr_in6 *);
|
||||
extern void in6_sin6_2_sin_in_sock(struct sockaddr *);
|
||||
extern void in6_sin_2_v4mapsin6(struct sockaddr_in *, struct sockaddr_in6 *);
|
||||
#endif
|
||||
#endif
|
||||
#if defined(_KERNEL)
|
||||
|
||||
@ -73,10 +77,9 @@ int sctp6_output(struct sctp_inpcb *, struct mbuf *, struct sockaddr *,
|
||||
void sctp6_ctlinput(int, struct sockaddr *, void *);
|
||||
#endif
|
||||
#if !(defined(__FreeBSD__) || defined(__APPLE__))
|
||||
extern void in6_sin_2_v4mapsin6(struct sockaddr_in *sin,
|
||||
struct sockaddr_in6 *sin6);
|
||||
extern void in6_sin6_2_sin(struct sockaddr_in *, struct sockaddr_in6 *sin6);
|
||||
extern void in6_sin6_2_sin_in_sock(struct sockaddr *nam);
|
||||
extern void in6_sin_2_v4mapsin6(struct sockaddr_in *, struct sockaddr_in6 *);
|
||||
extern void in6_sin6_2_sin(struct sockaddr_in *, struct sockaddr_in6 *);
|
||||
extern void in6_sin6_2_sin_in_sock(struct sockaddr *);
|
||||
#endif
|
||||
extern void sctp6_notify(struct sctp_inpcb *, struct icmp6_hdr *,
|
||||
struct sctphdr *, struct sockaddr *,
|
||||
|
@ -107,11 +107,4 @@ extern u_short ip_id;
|
||||
|
||||
/* necessary for sctp_pcb.c */
|
||||
extern int ip_defttl;
|
||||
|
||||
|
||||
/* dummy definitions used (temporarily?) for inpcb userspace port */
|
||||
|
||||
/* called in sctp_usrreq.c */
|
||||
#define in6_sin_2_v4mapsin6(arg1, arg2) /* STUB */
|
||||
|
||||
#endif
|
||||
|
@ -54,6 +54,7 @@ struct icmphdr {
|
||||
};
|
||||
|
||||
#if defined(__Userspace_os_Windows)
|
||||
#pragma pack (push, 1)
|
||||
struct icmp6_hdr {
|
||||
u_int8_t icmp6_type;
|
||||
u_int8_t icmp6_code;
|
||||
@ -63,7 +64,8 @@ struct icmp6_hdr {
|
||||
u_int16_t icmp6_un_data16[2];
|
||||
u_int8_t icmp6_un_data8[4];
|
||||
} icmp6_dataun;
|
||||
} __packed;
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
#define icmp6_data32 icmp6_dataun.icmp6_un_data32
|
||||
#define icmp6_mtu icmp6_data32[0]
|
||||
|
@ -46,8 +46,8 @@
|
||||
#elif defined(SCTP_STDINT_INCLUDE)
|
||||
#include SCTP_STDINT_INCLUDE
|
||||
#else
|
||||
#define uint32_t unsigned __int32
|
||||
#define uint64_t unsigned __int64
|
||||
#define uint32_t unsigned __int32
|
||||
#define uint64_t unsigned __int64
|
||||
#endif
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
@ -54,7 +54,7 @@ struct sctp_route {
|
||||
* retransmission behavior and are included in the routing structure.
|
||||
*/
|
||||
struct sctp_rt_metrics_lite {
|
||||
u_long rmx_mtu; /* MTU for this path */
|
||||
uint32_t rmx_mtu; /* MTU for this path */
|
||||
#if 0
|
||||
u_long rmx_expire; /* lifetime for route, e.g. redirect */
|
||||
u_long rmx_pksent; /* packets sent using this route */
|
||||
|
@ -46,7 +46,9 @@
|
||||
#define __FAVOR_BSD /* (on Ubuntu at least) enables UDP header field names like BSD in RFC 768 */
|
||||
#endif
|
||||
#if !defined (__Userspace_os_Windows)
|
||||
#if defined INET || defined INET6
|
||||
#include <netinet/udp.h>
|
||||
#endif
|
||||
#include <arpa/inet.h>
|
||||
#else
|
||||
#include <user_socketvar.h>
|
||||
@ -708,6 +710,7 @@ userspace_sctp_sendmsg(struct socket *so,
|
||||
struct uio auio;
|
||||
struct iovec iov[1];
|
||||
|
||||
memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo));
|
||||
sinfo->sinfo_ppid = ppid;
|
||||
sinfo->sinfo_flags = flags;
|
||||
sinfo->sinfo_stream = stream_no;
|
||||
@ -1377,7 +1380,7 @@ sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so)
|
||||
{
|
||||
SOCKBUF_LOCK_ASSERT(sb);
|
||||
sb->sb_mbmax = (u_int)min(cc * sb_efficiency, sb_max);
|
||||
sb->sb_hiwat = cc;
|
||||
sb->sb_hiwat = (u_int)cc;
|
||||
if (sb->sb_lowat > (int)sb->sb_hiwat)
|
||||
sb->sb_lowat = (int)sb->sb_hiwat;
|
||||
return (1);
|
||||
@ -1933,7 +1936,7 @@ usrsctp_get_non_blocking(struct socket *so)
|
||||
return (-1);
|
||||
}
|
||||
SOCK_LOCK(so);
|
||||
if (so->so_state | SS_NBIO) {
|
||||
if (so->so_state & SS_NBIO) {
|
||||
result = 1;
|
||||
} else {
|
||||
result = 0;
|
||||
@ -2341,6 +2344,12 @@ userspace_getsockopt(struct socket *so, int level, int option_name,
|
||||
return (usrsctp_getsockopt(so, level, option_name, option_value, option_len));
|
||||
}
|
||||
|
||||
int
|
||||
usrsctp_set_ulpinfo(struct socket *so, void *ulp_info)
|
||||
{
|
||||
return (register_ulp_info(so, ulp_info));
|
||||
}
|
||||
|
||||
int
|
||||
usrsctp_bindx(struct socket *so, struct sockaddr *addrs, int addrcnt, int flags)
|
||||
{
|
||||
@ -2446,7 +2455,7 @@ usrsctp_bindx(struct socket *so, struct sockaddr *addrs, int addrcnt, int flags)
|
||||
for (i = 0; i < addrcnt; i++) {
|
||||
#ifndef HAVE_SA_LEN
|
||||
size_t sa_len;
|
||||
#endif
|
||||
#endif
|
||||
memset(gaddrs, 0, argsz);
|
||||
gaddrs->sget_assoc_id = 0;
|
||||
#ifdef HAVE_SA_LEN
|
||||
@ -2478,6 +2487,7 @@ usrsctp_bindx(struct socket *so, struct sockaddr *addrs, int addrcnt, int flags)
|
||||
* first address has that port to make sure it fails or
|
||||
* succeeds correctly.
|
||||
*/
|
||||
#if defined(INET) || defined(INET6)
|
||||
if ((i == 0) && (sport != 0)) {
|
||||
switch (gaddrs->addr->sa_family) {
|
||||
#ifdef INET
|
||||
@ -2494,6 +2504,7 @@ usrsctp_bindx(struct socket *so, struct sockaddr *addrs, int addrcnt, int flags)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (usrsctp_setsockopt(so, IPPROTO_SCTP, flags, gaddrs, (socklen_t)argsz) != 0) {
|
||||
free(gaddrs);
|
||||
return (-1);
|
||||
@ -2551,6 +2562,7 @@ usrsctp_connectx(struct socket *so,
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
#ifdef INET
|
||||
if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)at)->sin6_addr)) {
|
||||
in6_sin6_2_sin((struct sockaddr_in *)cpto, (struct sockaddr_in6 *)at);
|
||||
cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in));
|
||||
@ -2560,6 +2572,11 @@ usrsctp_connectx(struct socket *so,
|
||||
cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in6));
|
||||
len += sizeof(struct sockaddr_in6);
|
||||
}
|
||||
#else
|
||||
memcpy(cpto, at, sizeof(struct sockaddr_in6));
|
||||
cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in6));
|
||||
len += sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
at = (struct sockaddr *)((caddr_t)at + sizeof(struct sockaddr_in6));
|
||||
break;
|
||||
#endif
|
||||
@ -2982,7 +2999,7 @@ void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak,
|
||||
memset((void *)&dst, 0, sizeof(struct sockaddr_in6));
|
||||
dst.sin6_family = AF_INET6;
|
||||
dst.sin6_addr = ip6->ip6_dst;
|
||||
#ifdef HAVE_SIN6_LEN
|
||||
#ifdef HAVE_SIN6_LEN
|
||||
dst.sin6_len = sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
|
||||
@ -3152,7 +3169,7 @@ usrsctp_dumppacket(void *buf, size_t len, int outbound)
|
||||
strncpy_s(dump_buf + pos, strlen(HEADER) + 1, HEADER, strlen(HEADER));
|
||||
#else
|
||||
strcpy(dump_buf + pos, HEADER);
|
||||
#endif
|
||||
#endif
|
||||
pos += strlen(HEADER);
|
||||
packet = (char *)buf;
|
||||
for (i = 0; i < len; i++) {
|
||||
@ -3243,6 +3260,12 @@ USRSCTP_SYSCTL_SET_DEF(sctp_recvspace)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_auto_asconf)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_multiple_asconfs)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_ecn_enable)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_pr_enable)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_auth_enable)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_asconf_enable)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_reconfig_enable)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_nrsack_enable)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_pktdrop_enable)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_strict_sacks)
|
||||
#if !defined(SCTP_WITH_NO_CSUM)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_no_csum_on_loopback)
|
||||
@ -3274,10 +3297,7 @@ USRSCTP_SYSCTL_SET_DEF(sctp_add_more_threshold)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_nr_outgoing_streams_default)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_cmt_on_off)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_cmt_use_dac)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_nr_sack_on_off)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_use_cwnd_based_maxburst)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_asconf_auth_nochk)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_auth_disable)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_nat_friendly)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_L2_abc_variable)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_mbuf_threshold_count)
|
||||
@ -3297,6 +3317,7 @@ USRSCTP_SYSCTL_SET_DEF(sctp_udp_tunneling_port)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_enable_sack_immediately)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_vtag_time_wait)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_blackhole)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_diag_info_code)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_fr_max_burst_default)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_path_pf_threshold)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_default_ss_module)
|
||||
@ -3321,6 +3342,12 @@ USRSCTP_SYSCTL_GET_DEF(sctp_recvspace)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_auto_asconf)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_multiple_asconfs)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_ecn_enable)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_pr_enable)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_auth_enable)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_asconf_enable)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_reconfig_enable)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_nrsack_enable)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_pktdrop_enable)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_strict_sacks)
|
||||
#if !defined(SCTP_WITH_NO_CSUM)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_no_csum_on_loopback)
|
||||
@ -3352,10 +3379,7 @@ USRSCTP_SYSCTL_GET_DEF(sctp_add_more_threshold)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_nr_outgoing_streams_default)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_cmt_on_off)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_cmt_use_dac)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_nr_sack_on_off)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_use_cwnd_based_maxburst)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_asconf_auth_nochk)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_auth_disable)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_nat_friendly)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_L2_abc_variable)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_mbuf_threshold_count)
|
||||
@ -3375,6 +3399,7 @@ USRSCTP_SYSCTL_GET_DEF(sctp_udp_tunneling_port)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_enable_sack_immediately)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_vtag_time_wait)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_blackhole)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_diag_info_code)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_fr_max_burst_default)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_path_pf_threshold)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_default_ss_module)
|
||||
|
@ -42,7 +42,7 @@
|
||||
/* #include <sys/_lock.h> was 0 byte file */
|
||||
/* #include <sys/_mutex.h> was 0 byte file */
|
||||
/* #include <sys/_sx.h> */ /*__Userspace__ alternative?*/
|
||||
#if !defined(__Userspace_os_DragonFly) && !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_NetBSD) && !defined(__Userspace_os_Windows)
|
||||
#if !defined(__Userspace_os_DragonFly) && !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_NetBSD) && !defined(__Userspace_os_Windows) && !defined(__Userspace_os_NaCl)
|
||||
#include <sys/uio.h>
|
||||
#endif
|
||||
#define SOCK_MAXADDRLEN 255
|
||||
@ -54,7 +54,7 @@
|
||||
#define SS_CANTRCVMORE 0x020
|
||||
#define SS_CANTSENDMORE 0x010
|
||||
|
||||
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) || defined (__Userspace_os_Windows)
|
||||
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) || defined (__Userspace_os_Windows) || defined(__Userspace_os_NaCl)
|
||||
#define UIO_MAXIOV 1024
|
||||
#define ERESTART (-1)
|
||||
#endif
|
||||
|
@ -35,6 +35,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
@ -776,28 +777,6 @@ struct sctp_cc_option {
|
||||
struct sctp_assoc_value aid_value;
|
||||
};
|
||||
|
||||
struct sctp_cwnd_args {
|
||||
struct sctp_nets *net; /* network to */ /* FIXME: LP64 issue */
|
||||
uint32_t cwnd_new_value; /* cwnd in k */
|
||||
uint32_t pseudo_cumack;
|
||||
uint16_t inflight; /* flightsize in k */
|
||||
uint16_t cwnd_augment; /* increment to it */
|
||||
uint8_t meets_pseudo_cumack;
|
||||
uint8_t need_new_pseudo_cumack;
|
||||
uint8_t cnt_in_send;
|
||||
uint8_t cnt_in_str;
|
||||
};
|
||||
|
||||
struct sctp_blk_args {
|
||||
uint32_t onsb; /* in 1k bytes */
|
||||
uint32_t sndlen; /* len of send being attempted */
|
||||
uint32_t peer_rwnd; /* rwnd of peer */
|
||||
uint16_t send_sent_qcnt; /* chnk cnt */
|
||||
uint16_t stream_qcnt; /* chnk cnt */
|
||||
uint16_t chunks_on_oque; /* chunks out */
|
||||
uint16_t flight_size; /* flight size in k */
|
||||
};
|
||||
|
||||
struct sctp_timeouts {
|
||||
sctp_assoc_t stimo_assoc_id;
|
||||
uint32_t stimo_init;
|
||||
@ -848,6 +827,8 @@ struct sctp_timeouts {
|
||||
|
||||
/******************** System calls *************/
|
||||
|
||||
struct socket;
|
||||
|
||||
void
|
||||
usrsctp_init(uint16_t,
|
||||
int (*)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
|
||||
@ -973,6 +954,9 @@ usrsctp_register_address(void *);
|
||||
void
|
||||
usrsctp_deregister_address(void *);
|
||||
|
||||
int
|
||||
usrsctp_set_ulpinfo(struct socket *, void *);
|
||||
|
||||
#define SCTP_DUMP_OUTBOUND 1
|
||||
#define SCTP_DUMP_INBOUND 0
|
||||
|
||||
@ -982,7 +966,7 @@ usrsctp_dumppacket(void *, size_t, int);
|
||||
void
|
||||
usrsctp_freedumpbuffer(char *);
|
||||
|
||||
#define USRSCTP_SYSCTL_DECL(__field) \
|
||||
#define USRSCTP_SYSCTL_DECL(__field) \
|
||||
void usrsctp_sysctl_set_ ## __field(uint32_t value);\
|
||||
uint32_t usrsctp_sysctl_get_ ## __field(void);
|
||||
|
||||
@ -991,6 +975,12 @@ USRSCTP_SYSCTL_DECL(sctp_recvspace)
|
||||
USRSCTP_SYSCTL_DECL(sctp_auto_asconf)
|
||||
USRSCTP_SYSCTL_DECL(sctp_multiple_asconfs)
|
||||
USRSCTP_SYSCTL_DECL(sctp_ecn_enable)
|
||||
USRSCTP_SYSCTL_DECL(sctp_pr_enable)
|
||||
USRSCTP_SYSCTL_DECL(sctp_auth_enable)
|
||||
USRSCTP_SYSCTL_DECL(sctp_asconf_enable)
|
||||
USRSCTP_SYSCTL_DECL(sctp_reconfig_enable)
|
||||
USRSCTP_SYSCTL_DECL(sctp_nrsack_enable)
|
||||
USRSCTP_SYSCTL_DECL(sctp_pktdrop_enable)
|
||||
USRSCTP_SYSCTL_DECL(sctp_strict_sacks)
|
||||
#if !defined(SCTP_WITH_NO_CSUM)
|
||||
USRSCTP_SYSCTL_DECL(sctp_no_csum_on_loopback)
|
||||
@ -1023,10 +1013,7 @@ USRSCTP_SYSCTL_DECL(sctp_nr_incoming_streams_default)
|
||||
USRSCTP_SYSCTL_DECL(sctp_nr_outgoing_streams_default)
|
||||
USRSCTP_SYSCTL_DECL(sctp_cmt_on_off)
|
||||
USRSCTP_SYSCTL_DECL(sctp_cmt_use_dac)
|
||||
USRSCTP_SYSCTL_DECL(sctp_nr_sack_on_off)
|
||||
USRSCTP_SYSCTL_DECL(sctp_use_cwnd_based_maxburst)
|
||||
USRSCTP_SYSCTL_DECL(sctp_asconf_auth_nochk)
|
||||
USRSCTP_SYSCTL_DECL(sctp_auth_disable)
|
||||
USRSCTP_SYSCTL_DECL(sctp_nat_friendly)
|
||||
USRSCTP_SYSCTL_DECL(sctp_L2_abc_variable)
|
||||
USRSCTP_SYSCTL_DECL(sctp_mbuf_threshold_count)
|
||||
@ -1046,6 +1033,7 @@ USRSCTP_SYSCTL_DECL(sctp_udp_tunneling_port)
|
||||
USRSCTP_SYSCTL_DECL(sctp_enable_sack_immediately)
|
||||
USRSCTP_SYSCTL_DECL(sctp_vtag_time_wait)
|
||||
USRSCTP_SYSCTL_DECL(sctp_blackhole)
|
||||
USRSCTP_SYSCTL_DECL(sctp_diag_info_code)
|
||||
USRSCTP_SYSCTL_DECL(sctp_fr_max_burst_default)
|
||||
USRSCTP_SYSCTL_DECL(sctp_path_pf_threshold)
|
||||
USRSCTP_SYSCTL_DECL(sctp_default_ss_module)
|
||||
|
Loading…
Reference in New Issue
Block a user