mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 916427: netwerk/sctp/src updated to version 8815 from SVN on Tue Mar 4 2014 rs=jesup,tuexen
This commit is contained in:
parent
677c6954d4
commit
9fb16ab802
@ -13,3 +13,4 @@ sctp updated to version 8263 from SVN on Sun Sep 16 00:48:48 EDT 2012
|
||||
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
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 246595 2013-02-09 17:26:14Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 254248 2013-08-12 13:52:15Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_H_
|
||||
@ -439,7 +439,7 @@ struct sctp_error_unrecognized_chunk {
|
||||
/* RFC4895 */
|
||||
#define SCTP_AUTHENTICATION 0x0f
|
||||
/* EY nr_sack chunk id*/
|
||||
#define SCTP_NR_SELECTIVE_ACK 0x10
|
||||
#define SCTP_NR_SELECTIVE_ACK 0x10
|
||||
/************0x40 series ***********/
|
||||
/************0x80 series ***********/
|
||||
/* RFC5061 */
|
||||
@ -533,38 +533,38 @@ struct sctp_error_unrecognized_chunk {
|
||||
/*
|
||||
* PCB Features (in sctp_features bitmask)
|
||||
*/
|
||||
#define SCTP_PCB_FLAGS_DO_NOT_PMTUD 0x00000001
|
||||
#define SCTP_PCB_FLAGS_EXT_RCVINFO 0x00000002 /* deprecated */
|
||||
#define SCTP_PCB_FLAGS_DONOT_HEARTBEAT 0x00000004
|
||||
#define SCTP_PCB_FLAGS_FRAG_INTERLEAVE 0x00000008
|
||||
#define SCTP_PCB_FLAGS_INTERLEAVE_STRMS 0x00000010
|
||||
#define SCTP_PCB_FLAGS_DO_ASCONF 0x00000020
|
||||
#define SCTP_PCB_FLAGS_AUTO_ASCONF 0x00000040
|
||||
#define SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE 0x00000080
|
||||
#define SCTP_PCB_FLAGS_DO_NOT_PMTUD 0x0000000000000001
|
||||
#define SCTP_PCB_FLAGS_EXT_RCVINFO 0x0000000000000002 /* deprecated */
|
||||
#define SCTP_PCB_FLAGS_DONOT_HEARTBEAT 0x0000000000000004
|
||||
#define SCTP_PCB_FLAGS_FRAG_INTERLEAVE 0x0000000000000008
|
||||
#define SCTP_PCB_FLAGS_INTERLEAVE_STRMS 0x0000000000000010
|
||||
#define SCTP_PCB_FLAGS_DO_ASCONF 0x0000000000000020
|
||||
#define SCTP_PCB_FLAGS_AUTO_ASCONF 0x0000000000000040
|
||||
#define SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE 0x0000000000000080
|
||||
/* socket options */
|
||||
#define SCTP_PCB_FLAGS_NODELAY 0x00000100
|
||||
#define SCTP_PCB_FLAGS_AUTOCLOSE 0x00000200
|
||||
#define SCTP_PCB_FLAGS_RECVDATAIOEVNT 0x00000400 /* deprecated */
|
||||
#define SCTP_PCB_FLAGS_RECVASSOCEVNT 0x00000800
|
||||
#define SCTP_PCB_FLAGS_RECVPADDREVNT 0x00001000
|
||||
#define SCTP_PCB_FLAGS_RECVPEERERR 0x00002000
|
||||
#define SCTP_PCB_FLAGS_RECVSENDFAILEVNT 0x00004000 /* deprecated */
|
||||
#define SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT 0x00008000
|
||||
#define SCTP_PCB_FLAGS_ADAPTATIONEVNT 0x00010000
|
||||
#define SCTP_PCB_FLAGS_PDAPIEVNT 0x00020000
|
||||
#define SCTP_PCB_FLAGS_AUTHEVNT 0x00040000
|
||||
#define SCTP_PCB_FLAGS_STREAM_RESETEVNT 0x00080000
|
||||
#define SCTP_PCB_FLAGS_NO_FRAGMENT 0x00100000
|
||||
#define SCTP_PCB_FLAGS_EXPLICIT_EOR 0x00400000
|
||||
#define SCTP_PCB_FLAGS_NEEDS_MAPPED_V4 0x00800000
|
||||
#define SCTP_PCB_FLAGS_MULTIPLE_ASCONFS 0x01000000
|
||||
#define SCTP_PCB_FLAGS_PORTREUSE 0x02000000
|
||||
#define SCTP_PCB_FLAGS_DRYEVNT 0x04000000
|
||||
#define SCTP_PCB_FLAGS_RECVRCVINFO 0x08000000
|
||||
#define SCTP_PCB_FLAGS_RECVNXTINFO 0x10000000
|
||||
#define SCTP_PCB_FLAGS_ASSOC_RESETEVNT 0x20000000
|
||||
#define SCTP_PCB_FLAGS_STREAM_CHANGEEVNT 0x40000000
|
||||
#define SCTP_PCB_FLAGS_RECVNSENDFAILEVNT 0x80000000
|
||||
#define SCTP_PCB_FLAGS_NODELAY 0x0000000000000100
|
||||
#define SCTP_PCB_FLAGS_AUTOCLOSE 0x0000000000000200
|
||||
#define SCTP_PCB_FLAGS_RECVDATAIOEVNT 0x0000000000000400 /* deprecated */
|
||||
#define SCTP_PCB_FLAGS_RECVASSOCEVNT 0x0000000000000800
|
||||
#define SCTP_PCB_FLAGS_RECVPADDREVNT 0x0000000000001000
|
||||
#define SCTP_PCB_FLAGS_RECVPEERERR 0x0000000000002000
|
||||
#define SCTP_PCB_FLAGS_RECVSENDFAILEVNT 0x0000000000004000 /* deprecated */
|
||||
#define SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT 0x0000000000008000
|
||||
#define SCTP_PCB_FLAGS_ADAPTATIONEVNT 0x0000000000010000
|
||||
#define SCTP_PCB_FLAGS_PDAPIEVNT 0x0000000000020000
|
||||
#define SCTP_PCB_FLAGS_AUTHEVNT 0x0000000000040000
|
||||
#define SCTP_PCB_FLAGS_STREAM_RESETEVNT 0x0000000000080000
|
||||
#define SCTP_PCB_FLAGS_NO_FRAGMENT 0x0000000000100000
|
||||
#define SCTP_PCB_FLAGS_EXPLICIT_EOR 0x0000000000400000
|
||||
#define SCTP_PCB_FLAGS_NEEDS_MAPPED_V4 0x0000000000800000
|
||||
#define SCTP_PCB_FLAGS_MULTIPLE_ASCONFS 0x0000000001000000
|
||||
#define SCTP_PCB_FLAGS_PORTREUSE 0x0000000002000000
|
||||
#define SCTP_PCB_FLAGS_DRYEVNT 0x0000000004000000
|
||||
#define SCTP_PCB_FLAGS_RECVRCVINFO 0x0000000008000000
|
||||
#define SCTP_PCB_FLAGS_RECVNXTINFO 0x0000000010000000
|
||||
#define SCTP_PCB_FLAGS_ASSOC_RESETEVNT 0x0000000020000000
|
||||
#define SCTP_PCB_FLAGS_STREAM_CHANGEEVNT 0x0000000040000000
|
||||
#define SCTP_PCB_FLAGS_RECVNSENDFAILEVNT 0x0000000080000000
|
||||
|
||||
/*-
|
||||
* mobility_features parameters (by micchie).Note
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 246595 2013-02-09 17:26:14Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 257803 2013-11-07 17:08:09Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -155,7 +155,10 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
|
||||
struct mbuf *m_reply = NULL;
|
||||
struct sockaddr_storage sa_store;
|
||||
struct sctp_paramhdr *ph;
|
||||
uint16_t param_type, param_length, aparam_length;
|
||||
uint16_t param_type, aparam_length;
|
||||
#if defined(INET) || defined(INET6)
|
||||
uint16_t param_length;
|
||||
#endif
|
||||
struct sockaddr *sa;
|
||||
int zero_address = 0;
|
||||
int bad_address = 0;
|
||||
@ -171,8 +174,9 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
|
||||
aparam_length = ntohs(aph->ph.param_length);
|
||||
ph = (struct sctp_paramhdr *)(aph + 1);
|
||||
param_type = ntohs(ph->param_type);
|
||||
#if defined(INET) || defined(INET6)
|
||||
param_length = ntohs(ph->param_length);
|
||||
|
||||
#endif
|
||||
sa = (struct sockaddr *)&sa_store;
|
||||
switch (param_type) {
|
||||
#ifdef INET
|
||||
@ -305,7 +309,10 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
|
||||
struct mbuf *m_reply = NULL;
|
||||
struct sockaddr_storage sa_store;
|
||||
struct sctp_paramhdr *ph;
|
||||
uint16_t param_type, param_length, aparam_length;
|
||||
uint16_t param_type, aparam_length;
|
||||
#if defined(INET) || defined(INET6)
|
||||
uint16_t param_length;
|
||||
#endif
|
||||
struct sockaddr *sa;
|
||||
int zero_address = 0;
|
||||
int result;
|
||||
@ -321,8 +328,9 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
|
||||
aparam_length = ntohs(aph->ph.param_length);
|
||||
ph = (struct sctp_paramhdr *)(aph + 1);
|
||||
param_type = ntohs(ph->param_type);
|
||||
#if defined(INET) || defined(INET6)
|
||||
param_length = ntohs(ph->param_length);
|
||||
|
||||
#endif
|
||||
sa = (struct sockaddr *)&sa_store;
|
||||
switch (param_type) {
|
||||
#ifdef INET
|
||||
@ -437,7 +445,10 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
|
||||
struct mbuf *m_reply = NULL;
|
||||
struct sockaddr_storage sa_store;
|
||||
struct sctp_paramhdr *ph;
|
||||
uint16_t param_type, param_length, aparam_length;
|
||||
uint16_t param_type, aparam_length;
|
||||
#if defined(INET) || defined(INET6)
|
||||
uint16_t param_length;
|
||||
#endif
|
||||
struct sockaddr *sa;
|
||||
int zero_address = 0;
|
||||
#ifdef INET
|
||||
@ -452,8 +463,9 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
|
||||
aparam_length = ntohs(aph->ph.param_length);
|
||||
ph = (struct sctp_paramhdr *)(aph + 1);
|
||||
param_type = ntohs(ph->param_type);
|
||||
#if defined(INET) || defined(INET6)
|
||||
param_length = ntohs(ph->param_length);
|
||||
|
||||
#endif
|
||||
sa = (struct sockaddr *)&sa_store;
|
||||
switch (param_type) {
|
||||
#ifdef INET
|
||||
@ -873,10 +885,12 @@ sctp_asconf_addr_match(struct sctp_asconf_addr *aa, struct sockaddr *sa)
|
||||
static uint32_t
|
||||
sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
|
||||
{
|
||||
#if defined(INET) || defined(INET6)
|
||||
uint16_t param_type, param_length;
|
||||
|
||||
param_type = ntohs(ph->param_type);
|
||||
param_length = ntohs(ph->param_length);
|
||||
#endif
|
||||
switch (sa->sa_family) {
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
@ -887,7 +901,7 @@ sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
|
||||
|
||||
v6addr = (struct sctp_ipv6addr_param *)ph;
|
||||
if ((param_type == SCTP_IPV6_ADDRESS) &&
|
||||
param_length == sizeof(struct sctp_ipv6addr_param) &&
|
||||
(param_length == sizeof(struct sctp_ipv6addr_param)) &&
|
||||
(memcmp(&v6addr->addr, &sin6->sin6_addr,
|
||||
sizeof(struct in6_addr)) == 0)) {
|
||||
return (1);
|
||||
@ -903,7 +917,7 @@ sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
|
||||
|
||||
v4addr = (struct sctp_ipv4addr_param *)ph;
|
||||
if ((param_type == SCTP_IPV4_ADDRESS) &&
|
||||
param_length == sizeof(struct sctp_ipv4addr_param) &&
|
||||
(param_length == sizeof(struct sctp_ipv4addr_param)) &&
|
||||
(memcmp(&v4addr->addr, &sin->sin_addr,
|
||||
sizeof(struct in_addr)) == 0)) {
|
||||
return (1);
|
||||
@ -1206,7 +1220,6 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
|
||||
uint16_t type)
|
||||
{
|
||||
struct sctp_asconf_addr *aa, *aa_next;
|
||||
struct sockaddr *sa;
|
||||
|
||||
/* make sure the request isn't already in the queue */
|
||||
TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
|
||||
@ -1269,7 +1282,6 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)&ifa->address.sa;
|
||||
sa = (struct sockaddr *)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) +
|
||||
@ -1285,7 +1297,6 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
sin= (struct sockaddr_in *)&ifa->address.sa;
|
||||
sa = (struct sockaddr *)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) +
|
||||
@ -1308,13 +1319,13 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
|
||||
if (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_ASCONF2) {
|
||||
if (type == SCTP_ADD_IP_ADDRESS) {
|
||||
SCTP_PRINTF("asconf_queue_mgmt: inserted asconf ADD_IP_ADDRESS: ");
|
||||
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
|
||||
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
|
||||
} else if (type == SCTP_DEL_IP_ADDRESS) {
|
||||
SCTP_PRINTF("asconf_queue_mgmt: appended asconf DEL_IP_ADDRESS: ");
|
||||
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
|
||||
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
|
||||
} else {
|
||||
SCTP_PRINTF("asconf_queue_mgmt: appended asconf SET_PRIM_ADDR: ");
|
||||
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
|
||||
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -2609,7 +2620,8 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
|
||||
/* get the parameter length */
|
||||
p_length = SCTP_SIZE32(aa->ap.aph.ph.param_length);
|
||||
/* will it fit in current chunk? */
|
||||
if (SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu) {
|
||||
if ((SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu) ||
|
||||
(SCTP_BUF_LEN(m_asconf) + p_length > MCLBYTES)) {
|
||||
/* won't fit, so we're done with this chunk */
|
||||
break;
|
||||
}
|
||||
@ -2730,7 +2742,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
|
||||
/* chain it all together */
|
||||
SCTP_BUF_NEXT(m_asconf_chk) = m_asconf;
|
||||
*retlen = SCTP_BUF_LEN(m_asconf_chk) + SCTP_BUF_LEN(m_asconf);
|
||||
acp->ch.chunk_length = ntohs(*retlen);
|
||||
acp->ch.chunk_length = htons(*retlen);
|
||||
|
||||
return (m_asconf_chk);
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.c 243882 2012-12-05 08:04:20Z glebius $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.c 257804 2013-11-07 18:50:11Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -335,10 +335,6 @@ sctp_generate_random_key(uint32_t keylen)
|
||||
{
|
||||
sctp_key_t *new_key;
|
||||
|
||||
/* validate keylen */
|
||||
if (keylen > SCTP_AUTH_RANDOM_SIZE_MAX)
|
||||
keylen = SCTP_AUTH_RANDOM_SIZE_MAX;
|
||||
|
||||
new_key = sctp_alloc_key(keylen);
|
||||
if (new_key == NULL) {
|
||||
/* out of memory */
|
||||
@ -376,7 +372,7 @@ sctp_compare_key(sctp_key_t *key1, sctp_key_t *key2)
|
||||
uint32_t i;
|
||||
uint32_t key1len, key2len;
|
||||
uint8_t *key_1, *key_2;
|
||||
uint8_t temp[SCTP_AUTH_RANDOM_SIZE_MAX];
|
||||
uint8_t val1, val2;
|
||||
|
||||
/* sanity/length check */
|
||||
key1len = sctp_get_keylen(key1);
|
||||
@ -388,38 +384,24 @@ sctp_compare_key(sctp_key_t *key1, sctp_key_t *key2)
|
||||
else if (key2len == 0)
|
||||
return (1);
|
||||
|
||||
if (key1len != key2len) {
|
||||
if (key1len >= key2len)
|
||||
maxlen = key1len;
|
||||
else
|
||||
maxlen = key2len;
|
||||
bzero(temp, maxlen);
|
||||
if (key1len < maxlen) {
|
||||
/* prepend zeroes to key1 */
|
||||
bcopy(key1->key, temp + (maxlen - key1len), key1len);
|
||||
key_1 = temp;
|
||||
key_2 = key2->key;
|
||||
} else {
|
||||
/* prepend zeroes to key2 */
|
||||
bcopy(key2->key, temp + (maxlen - key2len), key2len);
|
||||
key_1 = key1->key;
|
||||
key_2 = temp;
|
||||
}
|
||||
if (key1len < key2len) {
|
||||
maxlen = key2len;
|
||||
} else {
|
||||
maxlen = key1len;
|
||||
key_1 = key1->key;
|
||||
key_2 = key2->key;
|
||||
}
|
||||
|
||||
key_1 = key1->key;
|
||||
key_2 = key2->key;
|
||||
/* check for numeric equality */
|
||||
for (i = 0; i < maxlen; i++) {
|
||||
if (*key_1 > *key_2)
|
||||
return (1);
|
||||
else if (*key_1 < *key_2)
|
||||
return (-1);
|
||||
key_1++;
|
||||
key_2++;
|
||||
/* left-pad with zeros */
|
||||
val1 = (i < (maxlen - key1len)) ? 0 : *(key_1++);
|
||||
val2 = (i < (maxlen - key2len)) ? 0 : *(key_2++);
|
||||
if (val1 > val2) {
|
||||
return (1);
|
||||
} else if (val1 < val2) {
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* keys are equal value, so check lengths */
|
||||
if (key1len == key2len)
|
||||
return (0);
|
||||
@ -703,16 +685,12 @@ sctp_auth_add_hmacid(sctp_hmaclist_t *list, uint16_t hmac_id)
|
||||
"SCTP: HMAC id list full, ignoring add %u\n", hmac_id);
|
||||
return (-1);
|
||||
}
|
||||
#if defined(SCTP_SUPPORT_HMAC_SHA256)
|
||||
if ((hmac_id != SCTP_AUTH_HMAC_ID_SHA1) &&
|
||||
#ifdef HAVE_SHA224
|
||||
(hmac_id != SCTP_AUTH_HMAC_ID_SHA224) &&
|
||||
(hmac_id != SCTP_AUTH_HMAC_ID_SHA256)) {
|
||||
#else
|
||||
if (hmac_id != SCTP_AUTH_HMAC_ID_SHA1) {
|
||||
#endif
|
||||
#ifdef HAVE_SHA2
|
||||
(hmac_id != SCTP_AUTH_HMAC_ID_SHA256) &&
|
||||
(hmac_id != SCTP_AUTH_HMAC_ID_SHA384) &&
|
||||
(hmac_id != SCTP_AUTH_HMAC_ID_SHA512) &&
|
||||
#endif
|
||||
1) {
|
||||
return (-1);
|
||||
}
|
||||
/* Now is it already in the list */
|
||||
@ -752,11 +730,18 @@ sctp_default_supported_hmaclist(void)
|
||||
{
|
||||
sctp_hmaclist_t *new_list;
|
||||
|
||||
#if defined(SCTP_SUPPORT_HMAC_SHA256)
|
||||
new_list = sctp_alloc_hmaclist(2);
|
||||
#else
|
||||
new_list = sctp_alloc_hmaclist(1);
|
||||
#endif
|
||||
if (new_list == NULL)
|
||||
return (NULL);
|
||||
(void)sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA1);
|
||||
#if defined(SCTP_SUPPORT_HMAC_SHA256)
|
||||
/* We prefer SHA256, so list it first */
|
||||
(void)sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA256);
|
||||
#endif
|
||||
(void)sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA1);
|
||||
return (new_list);
|
||||
}
|
||||
|
||||
@ -812,19 +797,13 @@ int
|
||||
sctp_verify_hmac_param (struct sctp_auth_hmac_algo *hmacs, uint32_t num_hmacs)
|
||||
{
|
||||
uint32_t i;
|
||||
uint16_t hmac_id;
|
||||
uint32_t sha1_supported = 0;
|
||||
|
||||
for (i = 0; i < num_hmacs; i++) {
|
||||
hmac_id = ntohs(hmacs->hmac_ids[i]);
|
||||
if (hmac_id == SCTP_AUTH_HMAC_ID_SHA1)
|
||||
sha1_supported = 1;
|
||||
if (ntohs(hmacs->hmac_ids[i]) == SCTP_AUTH_HMAC_ID_SHA1) {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
/* all HMAC id's are supported */
|
||||
if (sha1_supported == 0)
|
||||
return (-1);
|
||||
else
|
||||
return (0);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
sctp_authinfo_t *
|
||||
@ -878,17 +857,9 @@ sctp_get_hmac_digest_len(uint16_t hmac_algo)
|
||||
switch (hmac_algo) {
|
||||
case SCTP_AUTH_HMAC_ID_SHA1:
|
||||
return (SCTP_AUTH_DIGEST_LEN_SHA1);
|
||||
#ifdef HAVE_SHA224
|
||||
case SCTP_AUTH_HMAC_ID_SHA224:
|
||||
return (SCTP_AUTH_DIGEST_LEN_SHA224);
|
||||
#endif
|
||||
#ifdef HAVE_SHA2
|
||||
#if defined(SCTP_SUPPORT_HMAC_SHA256)
|
||||
case SCTP_AUTH_HMAC_ID_SHA256:
|
||||
return (SCTP_AUTH_DIGEST_LEN_SHA256);
|
||||
case SCTP_AUTH_HMAC_ID_SHA384:
|
||||
return (SCTP_AUTH_DIGEST_LEN_SHA384);
|
||||
case SCTP_AUTH_HMAC_ID_SHA512:
|
||||
return (SCTP_AUTH_DIGEST_LEN_SHA512);
|
||||
#endif
|
||||
default:
|
||||
/* unknown HMAC algorithm: can't do anything */
|
||||
@ -901,16 +872,10 @@ sctp_get_hmac_block_len(uint16_t hmac_algo)
|
||||
{
|
||||
switch (hmac_algo) {
|
||||
case SCTP_AUTH_HMAC_ID_SHA1:
|
||||
#ifdef HAVE_SHA224
|
||||
case SCTP_AUTH_HMAC_ID_SHA224:
|
||||
#endif
|
||||
return (64);
|
||||
#ifdef HAVE_SHA2
|
||||
#if defined(SCTP_SUPPORT_HMAC_SHA256)
|
||||
case SCTP_AUTH_HMAC_ID_SHA256:
|
||||
return (64);
|
||||
case SCTP_AUTH_HMAC_ID_SHA384:
|
||||
case SCTP_AUTH_HMAC_ID_SHA512:
|
||||
return (128);
|
||||
#endif
|
||||
case SCTP_AUTH_HMAC_ID_RSVD:
|
||||
default:
|
||||
@ -927,21 +892,11 @@ sctp_hmac_init(uint16_t hmac_algo, sctp_hash_context_t *ctx)
|
||||
{
|
||||
switch (hmac_algo) {
|
||||
case SCTP_AUTH_HMAC_ID_SHA1:
|
||||
SHA1_Init(&ctx->sha1);
|
||||
SCTP_SHA1_INIT(&ctx->sha1);
|
||||
break;
|
||||
#ifdef HAVE_SHA224
|
||||
case SCTP_AUTH_HMAC_ID_SHA224:
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_SHA2
|
||||
#if defined(SCTP_SUPPORT_HMAC_SHA256)
|
||||
case SCTP_AUTH_HMAC_ID_SHA256:
|
||||
SHA256_Init(&ctx->sha256);
|
||||
break;
|
||||
case SCTP_AUTH_HMAC_ID_SHA384:
|
||||
SHA384_Init(&ctx->sha384);
|
||||
break;
|
||||
case SCTP_AUTH_HMAC_ID_SHA512:
|
||||
SHA512_Init(&ctx->sha512);
|
||||
SCTP_SHA256_INIT(&ctx->sha256);
|
||||
break;
|
||||
#endif
|
||||
case SCTP_AUTH_HMAC_ID_RSVD:
|
||||
@ -957,21 +912,11 @@ sctp_hmac_update(uint16_t hmac_algo, sctp_hash_context_t *ctx,
|
||||
{
|
||||
switch (hmac_algo) {
|
||||
case SCTP_AUTH_HMAC_ID_SHA1:
|
||||
SHA1_Update(&ctx->sha1, text, textlen);
|
||||
SCTP_SHA1_UPDATE(&ctx->sha1, text, textlen);
|
||||
break;
|
||||
#ifdef HAVE_SHA224
|
||||
case SCTP_AUTH_HMAC_ID_SHA224:
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_SHA2
|
||||
#if defined(SCTP_SUPPORT_HMAC_SHA256)
|
||||
case SCTP_AUTH_HMAC_ID_SHA256:
|
||||
SHA256_Update(&ctx->sha256, text, textlen);
|
||||
break;
|
||||
case SCTP_AUTH_HMAC_ID_SHA384:
|
||||
SHA384_Update(&ctx->sha384, text, textlen);
|
||||
break;
|
||||
case SCTP_AUTH_HMAC_ID_SHA512:
|
||||
SHA512_Update(&ctx->sha512, text, textlen);
|
||||
SCTP_SHA256_UPDATE(&ctx->sha256, text, textlen);
|
||||
break;
|
||||
#endif
|
||||
case SCTP_AUTH_HMAC_ID_RSVD:
|
||||
@ -987,22 +932,11 @@ sctp_hmac_final(uint16_t hmac_algo, sctp_hash_context_t *ctx,
|
||||
{
|
||||
switch (hmac_algo) {
|
||||
case SCTP_AUTH_HMAC_ID_SHA1:
|
||||
SHA1_Final(digest, &ctx->sha1);
|
||||
SCTP_SHA1_FINAL(digest, &ctx->sha1);
|
||||
break;
|
||||
#ifdef HAVE_SHA224
|
||||
case SCTP_AUTH_HMAC_ID_SHA224:
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_SHA2
|
||||
#if defined(SCTP_SUPPORT_HMAC_SHA256)
|
||||
case SCTP_AUTH_HMAC_ID_SHA256:
|
||||
SHA256_Final(digest, &ctx->sha256);
|
||||
break;
|
||||
case SCTP_AUTH_HMAC_ID_SHA384:
|
||||
/* SHA384 is truncated SHA512 */
|
||||
SHA384_Final(digest, &ctx->sha384);
|
||||
break;
|
||||
case SCTP_AUTH_HMAC_ID_SHA512:
|
||||
SHA512_Final(digest, &ctx->sha512);
|
||||
SCTP_SHA256_FINAL(digest, &ctx->sha256);
|
||||
break;
|
||||
#endif
|
||||
case SCTP_AUTH_HMAC_ID_RSVD:
|
||||
|
@ -32,33 +32,28 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.h 235828 2012-05-23 11:26:28Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.h 257804 2013-11-07 18:50:11Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_AUTH_H_
|
||||
#define _NETINET_SCTP_AUTH_H_
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
|
||||
/* digest lengths */
|
||||
#define SCTP_AUTH_DIGEST_LEN_SHA1 20
|
||||
#define SCTP_AUTH_DIGEST_LEN_SHA224 28
|
||||
#define SCTP_AUTH_DIGEST_LEN_SHA256 32
|
||||
#define SCTP_AUTH_DIGEST_LEN_SHA384 48
|
||||
#define SCTP_AUTH_DIGEST_LEN_SHA512 64
|
||||
#define SCTP_AUTH_DIGEST_LEN_MAX 64
|
||||
#define SCTP_AUTH_DIGEST_LEN_MAX SCTP_AUTH_DIGEST_LEN_SHA256
|
||||
|
||||
/* random sizes */
|
||||
#define SCTP_AUTH_RANDOM_SIZE_DEFAULT 32
|
||||
#define SCTP_AUTH_RANDOM_SIZE_REQUIRED 32
|
||||
#define SCTP_AUTH_RANDOM_SIZE_MAX 256
|
||||
|
||||
/* union of all supported HMAC algorithm contexts */
|
||||
typedef union sctp_hash_context {
|
||||
SHA1_CTX sha1;
|
||||
#ifdef HAVE_SHA2
|
||||
SHA256_CTX sha256;
|
||||
SHA384_CTX sha384;
|
||||
SHA512_CTX sha512;
|
||||
SCTP_SHA1_CTX sha1;
|
||||
#if defined(SCTP_SUPPORT_HMAC_SHA256)
|
||||
SCTP_SHA256_CTX sha256;
|
||||
#endif
|
||||
} sctp_hash_context_t;
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 239035 2012-08-04 08:03:30Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 258765 2013-11-30 12:51:19Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -48,14 +48,9 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 239035 2012-08-04 08:03:30Z
|
||||
#include <netinet/sctp_asconf.h>
|
||||
#include <netinet/sctp_sysctl.h>
|
||||
#include <netinet/sctp_indata.h>
|
||||
#if !defined(__Userspace_os_Windows)
|
||||
#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__
|
||||
@ -165,20 +160,13 @@ sctp_iterator_thread(void *v SCTP_UNUSED)
|
||||
SCTP_IPI_ITERATOR_WQ_UNLOCK();
|
||||
#if defined(__Userspace__)
|
||||
sctp_wakeup_iterator();
|
||||
#if !defined(__Userspace_os_Windows)
|
||||
pthread_exit(NULL);
|
||||
#else
|
||||
ExitThread(0);
|
||||
#endif
|
||||
return (NULL);
|
||||
#else
|
||||
wakeup(&sctp_it_ctl.iterator_flags);
|
||||
thread_terminate(current_thread());
|
||||
#endif
|
||||
#ifdef INVARIANTS
|
||||
panic("Hmm. thread_terminate() continues...");
|
||||
#endif
|
||||
#if defined(__Userspace__)
|
||||
return (NULL);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@ -186,46 +174,35 @@ sctp_iterator_thread(void *v SCTP_UNUSED)
|
||||
void
|
||||
sctp_startup_iterator(void)
|
||||
{
|
||||
static int called = 0;
|
||||
#if defined(__FreeBSD__) || (defined(__Userspace__) && !defined(__Userspace_os_Windows))
|
||||
int ret;
|
||||
#endif
|
||||
|
||||
if (called) {
|
||||
if (sctp_it_ctl.thread_proc) {
|
||||
/* You only get one */
|
||||
return;
|
||||
}
|
||||
/* init the iterator head */
|
||||
called = 1;
|
||||
sctp_it_ctl.iterator_running = 0;
|
||||
sctp_it_ctl.iterator_flags = 0;
|
||||
sctp_it_ctl.cur_it = NULL;
|
||||
/* Initialize global locks here, thus only once. */
|
||||
SCTP_ITERATOR_LOCK_INIT();
|
||||
SCTP_IPI_ITERATOR_WQ_INIT();
|
||||
TAILQ_INIT(&sctp_it_ctl.iteratorhead);
|
||||
#if defined(__FreeBSD__)
|
||||
#if __FreeBSD_version <= 701000
|
||||
ret = kthread_create(sctp_iterator_thread,
|
||||
kthread_create(sctp_iterator_thread,
|
||||
#else
|
||||
ret = kproc_create(sctp_iterator_thread,
|
||||
kproc_create(sctp_iterator_thread,
|
||||
#endif
|
||||
(void *)NULL,
|
||||
&sctp_it_ctl.thread_proc,
|
||||
RFPROC,
|
||||
SCTP_KTHREAD_PAGES,
|
||||
SCTP_KTRHEAD_NAME);
|
||||
(void *)NULL,
|
||||
&sctp_it_ctl.thread_proc,
|
||||
RFPROC,
|
||||
SCTP_KTHREAD_PAGES,
|
||||
SCTP_KTRHEAD_NAME);
|
||||
#elif defined(__APPLE__)
|
||||
(void)kernel_thread_start((thread_continue_t)sctp_iterator_thread, NULL, &sctp_it_ctl.thread_proc);
|
||||
kernel_thread_start((thread_continue_t)sctp_iterator_thread, NULL, &sctp_it_ctl.thread_proc);
|
||||
#elif defined(__Userspace__)
|
||||
#if defined(__Userspace_os_Windows)
|
||||
if ((sctp_it_ctl.thread_proc = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&sctp_iterator_thread, NULL, 0, NULL)) == NULL) {
|
||||
SCTP_PRINTF("ERROR; Creating sctp_iterator_thread failed\n");
|
||||
}
|
||||
#else
|
||||
if ((ret = pthread_create(&sctp_it_ctl.thread_proc, NULL, &sctp_iterator_thread, NULL))) {
|
||||
SCTP_PRINTF("ERROR; return code from sctp_iterator_thread pthread_create() is %d\n", ret);
|
||||
}
|
||||
if (pthread_create(&sctp_it_ctl.thread_proc, NULL, &sctp_iterator_thread, NULL)) {
|
||||
#endif
|
||||
SCTP_PRINTF("ERROR: Creating sctp_iterator_thread failed.\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -341,11 +318,13 @@ sctp_is_vmware_interface(struct ifnet *ifn)
|
||||
static void
|
||||
sctp_init_ifns_for_vrf(int vrfid)
|
||||
{
|
||||
#if defined(INET) || defined(INET6)
|
||||
struct ifaddrs *ifa;
|
||||
struct sctp_ifa *sctp_ifa;
|
||||
DWORD Err, AdapterAddrsSize;
|
||||
PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapterAddrs6, pAdapt;
|
||||
PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt;
|
||||
PIP_ADAPTER_UNICAST_ADDRESS pUnicast;
|
||||
#endif
|
||||
|
||||
#ifdef INET
|
||||
AdapterAddrsSize = 0;
|
||||
@ -372,6 +351,9 @@ sctp_init_ifns_for_vrf(int vrfid)
|
||||
for (pAdapt = pAdapterAddrs; pAdapt; pAdapt = pAdapt->Next) {
|
||||
if (pAdapt->IfType == IF_TYPE_IEEE80211 || pAdapt->IfType == IF_TYPE_ETHERNET_CSMACD) {
|
||||
for (pUnicast = pAdapt->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
|
||||
if (IN4_ISLINKLOCAL_ADDRESS(&(((struct sockaddr_in *)(pUnicast->Address.lpSockaddr))->sin_addr))) {
|
||||
continue;
|
||||
}
|
||||
ifa = (struct ifaddrs*)malloc(sizeof(struct ifaddrs));
|
||||
ifa->ifa_name = strdup(pAdapt->AdapterName);
|
||||
ifa->ifa_flags = pAdapt->Flags;
|
||||
@ -407,17 +389,17 @@ sctp_init_ifns_for_vrf(int vrfid)
|
||||
}
|
||||
}
|
||||
/* Allocate memory from sizing information */
|
||||
if ((pAdapterAddrs6 = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) {
|
||||
if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) {
|
||||
SCTP_PRINTF("Memory allocation error!\n");
|
||||
return;
|
||||
}
|
||||
/* Get actual adapter information */
|
||||
if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, pAdapterAddrs6, &AdapterAddrsSize)) != ERROR_SUCCESS) {
|
||||
if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) {
|
||||
SCTP_PRINTF("GetAdaptersV6Addresses() failed with error code %d\n", Err);
|
||||
return;
|
||||
}
|
||||
/* Enumerate through each returned adapter and save its information */
|
||||
for (pAdapt = pAdapterAddrs6; pAdapt; pAdapt = pAdapt->Next) {
|
||||
for (pAdapt = pAdapterAddrs; pAdapt; pAdapt = pAdapt->Next) {
|
||||
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));
|
||||
@ -440,18 +422,15 @@ sctp_init_ifns_for_vrf(int vrfid)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pAdapterAddrs6)
|
||||
FREE(pAdapterAddrs6);
|
||||
if (pAdapterAddrs)
|
||||
FREE(pAdapterAddrs);
|
||||
#endif
|
||||
}
|
||||
#elif defined(__Userspace__)
|
||||
static void
|
||||
sctp_init_ifns_for_vrf(int vrfid)
|
||||
{
|
||||
/* __Userspace__ TODO struct ifaddr is defined in net/if_var.h
|
||||
* This struct contains struct ifnet, which is also defined in
|
||||
* net/if_var.h. Currently a zero byte if_var.h file is present for Linux boxes
|
||||
*/
|
||||
#if defined(INET) || defined(INET6)
|
||||
int rc;
|
||||
struct ifaddrs *ifa = NULL;
|
||||
struct sctp_ifa *sctp_ifa;
|
||||
@ -461,24 +440,39 @@ sctp_init_ifns_for_vrf(int vrfid)
|
||||
if (rc != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (ifa = g_interfaces; ifa; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr == NULL) {
|
||||
continue;
|
||||
}
|
||||
#if !defined(INET)
|
||||
if (ifa->ifa_addr->sa_family != AF_INET6) {
|
||||
/* non inet6 skip */
|
||||
continue;
|
||||
}
|
||||
#elif !defined(INET6)
|
||||
if (ifa->ifa_addr->sa_family != AF_INET) {
|
||||
/* non inet skip */
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
if ((ifa->ifa_addr->sa_family != AF_INET) && (ifa->ifa_addr->sa_family != AF_INET6)) {
|
||||
/* non inet/inet6 skip */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#if defined(INET6)
|
||||
if ((ifa->ifa_addr->sa_family == AF_INET6) &&
|
||||
IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
|
||||
/* skip unspecifed addresses */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#if defined(INET)
|
||||
if (ifa->ifa_addr->sa_family == AF_INET &&
|
||||
((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
ifa_flags = 0;
|
||||
sctp_ifa = sctp_add_addr_to_vrf(vrfid,
|
||||
ifa,
|
||||
@ -493,6 +487,7 @@ sctp_init_ifns_for_vrf(int vrfid)
|
||||
sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -830,12 +825,12 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
|
||||
return (NULL);
|
||||
}
|
||||
if (allonebuf == 0)
|
||||
mbuf_threshold = SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count);
|
||||
mbuf_threshold = SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count);
|
||||
else
|
||||
mbuf_threshold = 1;
|
||||
|
||||
|
||||
if (space_needed > (((mbuf_threshold - 1) * MLEN) + MHLEN)) {
|
||||
if ((int)space_needed > (((mbuf_threshold - 1) * MLEN) + MHLEN)) {
|
||||
MCLGET(m, how);
|
||||
if (m == NULL) {
|
||||
return (NULL);
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_constants.h 243157 2012-11-16 19:39:10Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_constants.h 256556 2013-10-15 20:21:27Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_CONSTANTS_H_
|
||||
@ -557,9 +557,6 @@ extern void getwintimeofday(struct timeval *tv);
|
||||
/* How long a cookie lives in milli-seconds */
|
||||
#define SCTP_DEFAULT_COOKIE_LIFE 60000
|
||||
|
||||
/* resource limit of streams */
|
||||
#define MAX_SCTP_STREAMS 2048
|
||||
|
||||
/* Maximum the mapping array will grow to (TSN mapping array) */
|
||||
#define SCTP_MAPPING_ARRAY 512
|
||||
|
||||
@ -702,6 +699,7 @@ extern void getwintimeofday(struct timeval *tv);
|
||||
|
||||
/* How many streams I request initally by default */
|
||||
#define SCTP_OSTREAM_INITIAL 10
|
||||
#define SCTP_ISTREAM_INITIAL 2048
|
||||
|
||||
/*
|
||||
* How many smallest_mtu's need to increase before a window update sack is
|
||||
@ -776,7 +774,6 @@ extern void getwintimeofday(struct timeval *tv);
|
||||
/* small chunk store for looking at chunk_list in auth */
|
||||
#define SCTP_SMALL_CHUNK_STORE 260
|
||||
|
||||
#define SCTP_DEFAULT_MINSEGMENT 512 /* MTU size ... if no mtu disc */
|
||||
#define SCTP_HOW_MANY_SECRETS 2 /* how many secrets I keep */
|
||||
|
||||
#define SCTP_NUMBER_OF_SECRETS 8 /* or 8 * 4 = 32 octets */
|
||||
@ -1050,6 +1047,10 @@ extern void getwintimeofday(struct timeval *tv);
|
||||
(((uint8_t *)&(a)->s_addr)[2] == 0) && \
|
||||
(((uint8_t *)&(a)->s_addr)[3] == 1))
|
||||
|
||||
#define IN4_ISLINKLOCAL_ADDRESS(a) \
|
||||
((((uint8_t *)&(a)->s_addr)[0] == 169) && \
|
||||
(((uint8_t *)&(a)->s_addr)[1] == 254))
|
||||
|
||||
#if defined(__Userspace__)
|
||||
#if defined(__Userspace_os_Windows)
|
||||
#define SCTP_GETTIME_TIMEVAL(x) getwintimeofday(x)
|
||||
|
@ -40,6 +40,8 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_crc32.c 235828 2012-05-23 11:26:28Z tu
|
||||
#include <netinet/sctp_crc32.h>
|
||||
#include <netinet/sctp_pcb.h>
|
||||
|
||||
|
||||
#if !defined(SCTP_WITH_NO_CSUM)
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 800000
|
||||
#else
|
||||
/**
|
||||
@ -708,8 +710,6 @@ calculate_crc32c(uint32_t crc32c,
|
||||
}
|
||||
#endif /* FreeBSD < 80000 || other OS */
|
||||
|
||||
#if !defined(SCTP_WITH_NO_CSUM)
|
||||
|
||||
static uint32_t
|
||||
sctp_finalize_crc32c(uint32_t crc32c)
|
||||
{
|
||||
@ -785,6 +785,7 @@ sctp_calculate_cksum(struct mbuf *m, uint32_t offset)
|
||||
#endif /* !defined(SCTP_WITH_NO_CSUM) */
|
||||
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
void
|
||||
sctp_delayed_cksum(struct mbuf *m, uint32_t offset)
|
||||
{
|
||||
@ -813,4 +814,5 @@ sctp_delayed_cksum(struct mbuf *m, uint32_t offset)
|
||||
*(uint32_t *) (m->m_data + offset) = checksum;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -42,7 +42,9 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_crc32.h 235828 2012-05-23 11:26:28Z tu
|
||||
#if !defined(SCTP_WITH_NO_CSUM)
|
||||
uint32_t sctp_calculate_cksum(struct mbuf *, uint32_t);
|
||||
#endif
|
||||
#if defined(__FreeBSD__)
|
||||
void sctp_delayed_cksum(struct mbuf *, uint32_t offset);
|
||||
#endif
|
||||
#endif /* _KERNEL */
|
||||
#if defined(__Userspace__)
|
||||
#if !defined(SCTP_WITH_NO_CSUM)
|
||||
|
@ -1,89 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
|
||||
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* a) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* b) Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* c) Neither the name of Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_dtrace_declare.h 235828 2012-05-23 11:26:28Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_DTRACE_DECLARE_H_
|
||||
#define _NETINET_SCTP_DTRACE_DECLARE_H_
|
||||
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
|
||||
#include "opt_kdtrace.h"
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/sdt.h>
|
||||
|
||||
/* Declare the SCTP provider */
|
||||
SDT_PROVIDER_DECLARE(sctp);
|
||||
|
||||
/* The probes we have so far: */
|
||||
|
||||
/* One to track a net's cwnd */
|
||||
/* initial */
|
||||
SDT_PROBE_DECLARE(sctp, cwnd, net, init);
|
||||
/* update at a ack -- increase */
|
||||
SDT_PROBE_DECLARE(sctp, cwnd, net, ack);
|
||||
/* update at a fast retransmit -- decrease */
|
||||
SDT_PROBE_DECLARE(sctp, cwnd, net, fr);
|
||||
/* update at a time-out -- decrease */
|
||||
SDT_PROBE_DECLARE(sctp, cwnd, net, to);
|
||||
/* update at a burst-limit -- decrease */
|
||||
SDT_PROBE_DECLARE(sctp, cwnd, net, bl);
|
||||
/* update at a ECN -- decrease */
|
||||
SDT_PROBE_DECLARE(sctp, cwnd, net, ecn);
|
||||
/* update at a Packet-Drop -- decrease */
|
||||
SDT_PROBE_DECLARE(sctp, cwnd, net, pd);
|
||||
/* Rttvar probe declaration */
|
||||
SDT_PROBE_DECLARE(sctp, cwnd, net, rttvar);
|
||||
SDT_PROBE_DECLARE(sctp, cwnd, net, rttstep);
|
||||
|
||||
/* One to track an associations rwnd */
|
||||
SDT_PROBE_DECLARE(sctp, rwnd, assoc, val);
|
||||
|
||||
/* One to track a net's flight size */
|
||||
SDT_PROBE_DECLARE(sctp, flightsize, net, val);
|
||||
|
||||
/* One to track an associations flight size */
|
||||
SDT_PROBE_DECLARE(sctp, flightsize, assoc, val);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#else
|
||||
/* All other platforms not defining dtrace probes */
|
||||
#ifndef SDT_PROBE
|
||||
#define SDT_PROBE(a, b, c, d, e, f, g, h, i)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
@ -1,243 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
|
||||
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* a) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* b) Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* c) Neither the name of Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_dtrace_define.h 235828 2012-05-23 11:26:28Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_DTRACE_DEFINE_H_
|
||||
#define _NETINET_SCTP_DTRACE_DEFINE_H_
|
||||
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
|
||||
#include "opt_kdtrace.h"
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/sdt.h>
|
||||
|
||||
SDT_PROVIDER_DEFINE(sctp);
|
||||
|
||||
/********************************************************/
|
||||
/* Cwnd probe - tracks changes in the congestion window on a netp */
|
||||
/********************************************************/
|
||||
/* Initial */
|
||||
SDT_PROBE_DEFINE(sctp, cwnd, net, init, init);
|
||||
/* The Vtag for this end */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 0, "uint32_t");
|
||||
/* The port number of the local side << 16 | port number of remote
|
||||
* in network byte order.
|
||||
*/
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 1, "uint32_t");
|
||||
/* The pointer to the struct sctp_nets * changing */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 2, "uintptr_t");
|
||||
/* The old value of the cwnd */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 3, "int");
|
||||
/* The new value of the cwnd */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 4, "int");
|
||||
|
||||
|
||||
/* ACK-INCREASE */
|
||||
SDT_PROBE_DEFINE(sctp, cwnd, net, ack, ack);
|
||||
/* The Vtag for this end */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 0, "uint32_t");
|
||||
/* The port number of the local side << 16 | port number of remote
|
||||
* in network byte order.
|
||||
*/
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 1, "uint32_t");
|
||||
/* The pointer to the struct sctp_nets * changing */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 2, "uintptr_t");
|
||||
/* The old value of the cwnd */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 3, "int");
|
||||
/* The new value of the cwnd */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 4, "int");
|
||||
|
||||
|
||||
/* ACK-INCREASE */
|
||||
SDT_PROBE_DEFINE(sctp, cwnd, net, rttvar, rttvar);
|
||||
/* The Vtag << 32 | localport << 16 | remoteport */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 0, "uint64_t");
|
||||
/* obw | nbw */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 1, "uint64_t");
|
||||
/* bwrtt | newrtt */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 2, "uint64_t");
|
||||
/* flight */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 3, "uint64_t");
|
||||
/* (cwnd << 32) | point << 16 | retval(0/1) */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 4, "uint64_t");
|
||||
|
||||
|
||||
SDT_PROBE_DEFINE(sctp, cwnd, net, rttstep, rttstep);
|
||||
/* The Vtag << 32 | localport << 16 | remoteport */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 0, "uint64_t");
|
||||
/* obw | nbw */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 1, "uint64_t");
|
||||
/* bwrtt | nrtt */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 2, "uint64_t");
|
||||
/* cwnd_saved | stepcnt << 16 | oldstep */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 3, "uint64_t");
|
||||
/* (cwnd << 32) | point << 16 | retval(0/1) */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 4, "uint64_t");
|
||||
|
||||
|
||||
/* FastRetransmit-DECREASE */
|
||||
SDT_PROBE_DEFINE(sctp, cwnd, net, fr, fr);
|
||||
/* The Vtag for this end */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 0, "uint32_t");
|
||||
/* The port number of the local side << 16 | port number of remote
|
||||
* in network byte order.
|
||||
*/
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 1, "uint32_t");
|
||||
/* The pointer to the struct sctp_nets * changing */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 2, "uintptr_t");
|
||||
/* The old value of the cwnd */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 3, "int");
|
||||
/* The new value of the cwnd */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 4, "int");
|
||||
|
||||
|
||||
/* TimeOut-DECREASE */
|
||||
SDT_PROBE_DEFINE(sctp, cwnd, net, to, to);
|
||||
/* The Vtag for this end */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 0, "uint32_t");
|
||||
/* The port number of the local side << 16 | port number of remote
|
||||
* in network byte order.
|
||||
*/
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 1, "uint32_t");
|
||||
/* The pointer to the struct sctp_nets * changing */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 2, "uintptr_t");
|
||||
/* The old value of the cwnd */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 3, "int");
|
||||
/* The new value of the cwnd */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 4, "int");
|
||||
|
||||
|
||||
/* BurstLimit-DECREASE */
|
||||
SDT_PROBE_DEFINE(sctp, cwnd, net, bl, bl);
|
||||
/* The Vtag for this end */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 0, "uint32_t");
|
||||
/* The port number of the local side << 16 | port number of remote
|
||||
* in network byte order.
|
||||
*/
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 1, "uint32_t");
|
||||
/* The pointer to the struct sctp_nets * changing */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 2, "uintptr_t");
|
||||
/* The old value of the cwnd */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 3, "int");
|
||||
/* The new value of the cwnd */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 4, "int");
|
||||
|
||||
|
||||
/* ECN-DECREASE */
|
||||
SDT_PROBE_DEFINE(sctp, cwnd, net, ecn, ecn);
|
||||
/* The Vtag for this end */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 0, "uint32_t");
|
||||
/* The port number of the local side << 16 | port number of remote
|
||||
* in network byte order.
|
||||
*/
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 1, "uint32_t");
|
||||
/* The pointer to the struct sctp_nets * changing */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 2, "uintptr_t");
|
||||
/* The old value of the cwnd */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 3, "int");
|
||||
/* The new value of the cwnd */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 4, "int");
|
||||
|
||||
|
||||
/* PacketDrop-DECREASE */
|
||||
SDT_PROBE_DEFINE(sctp, cwnd, net, pd, pd);
|
||||
/* The Vtag for this end */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 0, "uint32_t");
|
||||
/* The port number of the local side << 16 | port number of remote
|
||||
* in network byte order.
|
||||
*/
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 1, "uint32_t");
|
||||
/* The pointer to the struct sctp_nets * changing */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 2, "uintptr_t");
|
||||
/* The old value of the cwnd */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 3, "int");
|
||||
/* The new value of the cwnd */
|
||||
SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 4, "int");
|
||||
|
||||
|
||||
|
||||
/********************************************************/
|
||||
/* Rwnd probe - tracks changes in the receiver window for an assoc */
|
||||
/********************************************************/
|
||||
SDT_PROBE_DEFINE(sctp, rwnd, assoc, val, val);
|
||||
/* The Vtag for this end */
|
||||
SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 0, "uint32_t");
|
||||
/* The port number of the local side << 16 | port number of remote
|
||||
* in network byte order.
|
||||
*/
|
||||
SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 1, "uint32_t");
|
||||
/* The up/down amount */
|
||||
SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 2, "int");
|
||||
/* The new value of the cwnd */
|
||||
SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 3, "int");
|
||||
|
||||
/********************************************************/
|
||||
/* flight probe - tracks changes in the flight size on a net or assoc */
|
||||
/********************************************************/
|
||||
SDT_PROBE_DEFINE(sctp, flightsize, net, val, val);
|
||||
/* The Vtag for this end */
|
||||
SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 0, "uint32_t");
|
||||
/* The port number of the local side << 16 | port number of remote
|
||||
* in network byte order.
|
||||
*/
|
||||
SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 1, "uint32_t");
|
||||
/* The pointer to the struct sctp_nets * changing */
|
||||
SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 2, "uintptr_t");
|
||||
/* The up/down amount */
|
||||
SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 3, "int");
|
||||
/* The new value of the cwnd */
|
||||
SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 4, "int");
|
||||
/********************************************************/
|
||||
/* The total flight version */
|
||||
/********************************************************/
|
||||
SDT_PROBE_DEFINE(sctp, flightsize, assoc, val, val);
|
||||
/* The Vtag for this end */
|
||||
SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 0, "uint32_t");
|
||||
/* The port number of the local side << 16 | port number of remote
|
||||
* in network byte order.
|
||||
*/
|
||||
SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 1, "uint32_t");
|
||||
/* The up/down amount */
|
||||
SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 2, "int");
|
||||
/* The new value of the cwnd */
|
||||
SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 3, "int");
|
||||
#else /* to #if Freebsd */
|
||||
/* All other platforms not defining dtrace probes */
|
||||
#ifndef SDT_PROBE
|
||||
#define SDT_PROBE(a, b, c, d, e, f, g, h, i)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,284 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
|
||||
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* a) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* b) Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* c) Neither the name of Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
|
||||
#include <netinet/sctp_constants.h>
|
||||
#ifdef USE_MD5
|
||||
#include <crypto/md5.h>
|
||||
#else
|
||||
#if !defined(__APPLE__) && !defined(__Userspace__)
|
||||
#include <netinet/sctp_sha1.h>
|
||||
#endif
|
||||
#endif /* USE_MD5 */
|
||||
#include <netinet/sctp_hashdriver.h>
|
||||
|
||||
/*
|
||||
* Main driver for SCTP's hashing. passing a two pointers and two lengths,
|
||||
* returning a digest pointer filled. The md5 code was taken directly from
|
||||
* the RFC (2104) so to understand it you may want to go look at the RFC
|
||||
* referenced in the SCTP spec. We did modify this code to either user OURs
|
||||
* implementation of SLA1 or the MD5 that comes from its RFC. SLA1 may have
|
||||
* IPR issues so you need to check in to this if you wish to use it... Or at
|
||||
* least that is what the FIP-180.1 web page says.
|
||||
*/
|
||||
|
||||
void
|
||||
sctp_hash_digest(char *key, int key_len, char *text, int text_len,
|
||||
unsigned char *digest)
|
||||
{
|
||||
#ifdef USE_MD5
|
||||
md5_ctxt context;
|
||||
|
||||
#else
|
||||
#if defined(__APPLE__) || defined(__Userspace__)
|
||||
SHA1_CTX context;
|
||||
#else
|
||||
struct sha1_context context;
|
||||
#endif
|
||||
|
||||
#endif /* USE_MD5 */
|
||||
/* inner padding - key XORd with ipad */
|
||||
unsigned char k_ipad[65];
|
||||
|
||||
/* outer padding - key XORd with opad */
|
||||
unsigned char k_opad[65];
|
||||
unsigned char tk[20];
|
||||
int i;
|
||||
|
||||
if (key_len > 64) {
|
||||
#ifdef USE_MD5
|
||||
md5_ctxt tctx;
|
||||
|
||||
MD5Init(&tctx);
|
||||
MD5Update(&tctx, key, key_len);
|
||||
MD5Final(tk, &tctx);
|
||||
key = tk;
|
||||
key_len = 16;
|
||||
#else
|
||||
#if defined(__APPLE__) || defined(__Userspace__)
|
||||
SHA1_CTX tctx;
|
||||
#else
|
||||
struct sha1_context tctx;
|
||||
#endif
|
||||
|
||||
SHA1_Init(&tctx);
|
||||
SHA1_Update(&tctx, (unsigned char *)key, key_len);
|
||||
SHA1_Final(tk, &tctx);
|
||||
key = (char *)tk;
|
||||
key_len = 20;
|
||||
#endif /* USE_MD5 */
|
||||
}
|
||||
/*
|
||||
* the HMAC_MD5 transform looks like:
|
||||
*
|
||||
* MD5(K XOR opad, MD5(K XOR ipad, text))
|
||||
*
|
||||
* where K is an n byte key ipad is the byte 0x36 repeated 64 times
|
||||
* opad is the byte 0x5c repeated 64 times and text is the data
|
||||
* being protected
|
||||
*/
|
||||
|
||||
/* start out by storing key in pads */
|
||||
bzero(k_ipad, sizeof k_ipad);
|
||||
bzero(k_opad, sizeof k_opad);
|
||||
bcopy(key, k_ipad, key_len);
|
||||
bcopy(key, k_opad, key_len);
|
||||
|
||||
/* XOR key with ipad and opad values */
|
||||
for (i = 0; i < 64; i++) {
|
||||
k_ipad[i] ^= 0x36;
|
||||
k_opad[i] ^= 0x5c;
|
||||
}
|
||||
/*
|
||||
* perform inner MD5
|
||||
*/
|
||||
#ifdef USE_MD5
|
||||
MD5Init(&context); /* init context for 1st pass */
|
||||
MD5Update(&context, k_ipad, 64); /* start with inner pad */
|
||||
MD5Update(&context, text, text_len); /* then text of datagram */
|
||||
MD5Final(digest, &context); /* finish up 1st pass */
|
||||
#else
|
||||
SHA1_Init(&context); /* init context for 1st pass */
|
||||
SHA1_Update(&context, k_ipad, 64); /* start with inner pad */
|
||||
SHA1_Update(&context,
|
||||
(unsigned char *)text,
|
||||
text_len); /* then text of datagram */
|
||||
SHA1_Final(digest, &context); /* finish up 1st pass */
|
||||
#endif /* USE_MD5 */
|
||||
|
||||
/*
|
||||
* perform outer MD5
|
||||
*/
|
||||
#ifdef USE_MD5
|
||||
MD5Init(&context); /* init context for 2nd pass */
|
||||
MD5Update(&context, k_opad, 64); /* start with outer pad */
|
||||
MD5Update(&context, digest, 16); /* then results of 1st hash */
|
||||
MD5Final(digest, &context); /* finish up 2nd pass */
|
||||
#else
|
||||
SHA1_Init(&context); /* init context for 2nd pass */
|
||||
SHA1_Update(&context, k_opad, 64); /* start with outer pad */
|
||||
SHA1_Update(&context,
|
||||
(unsigned char *)digest, 20); /* then results of 1st hash */
|
||||
SHA1_Final(digest, &context); /* finish up 2nd pass */
|
||||
#endif /* USE_MD5 */
|
||||
}
|
||||
|
||||
void
|
||||
sctp_hash_digest_m(char *key, int key_len, struct mbuf *m, int offset,
|
||||
unsigned char *digest)
|
||||
{
|
||||
struct mbuf *m_at;
|
||||
|
||||
#ifdef USE_MD5
|
||||
md5_ctxt context;
|
||||
|
||||
#else
|
||||
#if defined(__APPLE__) || defined(__Userspace__)
|
||||
SHA1_CTX context;
|
||||
#else
|
||||
struct sha1_context context;
|
||||
#endif
|
||||
|
||||
#endif /* USE_MD5 */
|
||||
/* inner padding - key XORd with ipad */
|
||||
unsigned char k_ipad[65];
|
||||
|
||||
/* outer padding - key XORd with opad */
|
||||
unsigned char k_opad[65];
|
||||
unsigned char tk[20];
|
||||
int i;
|
||||
|
||||
if (key_len > 64) {
|
||||
#ifdef USE_MD5
|
||||
md5_ctxt tctx;
|
||||
|
||||
MD5Init(&tctx);
|
||||
MD5Update(&tctx, key, key_len);
|
||||
MD5Final(tk, &tctx);
|
||||
key = tk;
|
||||
key_len = 16;
|
||||
#else
|
||||
#if defined(__APPLE__) || defined(__Userspace__)
|
||||
SHA1_CTX tctx;
|
||||
#else
|
||||
struct sha1_context tctx;
|
||||
#endif
|
||||
|
||||
SHA1_Init(&tctx);
|
||||
SHA1_Update(&tctx, (unsigned char *)key, key_len);
|
||||
SHA1_Final(tk, &tctx);
|
||||
key = (char *)tk;
|
||||
key_len = 20;
|
||||
#endif /* USE_MD5 */
|
||||
}
|
||||
/*
|
||||
* the HMAC_MD5 transform looks like:
|
||||
*
|
||||
* MD5(K XOR opad, MD5(K XOR ipad, text))
|
||||
*
|
||||
* where K is an n byte key ipad is the byte 0x36 repeated 64 times
|
||||
* opad is the byte 0x5c repeated 64 times and text is the data
|
||||
* being protected
|
||||
*/
|
||||
|
||||
/* start out by storing key in pads */
|
||||
bzero(k_ipad, sizeof k_ipad);
|
||||
bzero(k_opad, sizeof k_opad);
|
||||
bcopy(key, k_ipad, key_len);
|
||||
bcopy(key, k_opad, key_len);
|
||||
|
||||
/* XOR key with ipad and opad values */
|
||||
for (i = 0; i < 64; i++) {
|
||||
k_ipad[i] ^= 0x36;
|
||||
k_opad[i] ^= 0x5c;
|
||||
}
|
||||
|
||||
/* find the correct mbuf and offset into mbuf */
|
||||
m_at = m;
|
||||
while ((m_at != NULL) && (offset > SCTP_BUF_LEN(m_at))) {
|
||||
offset -= SCTP_BUF_LEN(m_at); /* update remaining offset left */
|
||||
m_at = SCTP_BUF_NEXT(m_at);
|
||||
}
|
||||
/*
|
||||
* perform inner MD5
|
||||
*/
|
||||
#ifdef USE_MD5
|
||||
MD5Init(&context); /* init context for 1st pass */
|
||||
MD5Update(&context, k_ipad, 64); /* start with inner pad */
|
||||
/******/
|
||||
while (m_at != NULL) {
|
||||
/* then text of datagram... */
|
||||
MD5Update(&context, mtod(m_at, char *)+offset,
|
||||
SCTP_BUF_LEN(m_at) - offset);
|
||||
/* only offset on the first mbuf */
|
||||
offset = 0;
|
||||
m_at = SCTP_BUF_NEXT(m_at);
|
||||
}
|
||||
/******/
|
||||
MD5Final(digest, &context); /* finish up 1st pass */
|
||||
#else
|
||||
SHA1_Init(&context); /* init context for 1st pass */
|
||||
SHA1_Update(&context, k_ipad, 64); /* start with inner pad */
|
||||
/******/
|
||||
while (m_at != NULL) {
|
||||
/* then text of datagram */
|
||||
SHA1_Update(&context, mtod(m_at, unsigned char *)+offset,
|
||||
SCTP_BUF_LEN(m_at) - offset);
|
||||
/* only offset on the first mbuf */
|
||||
offset = 0;
|
||||
m_at = SCTP_BUF_NEXT(m_at);
|
||||
}
|
||||
/******/
|
||||
SHA1_Final(digest, &context); /* finish up 1st pass */
|
||||
#endif /* USE_MD5 */
|
||||
|
||||
/*
|
||||
* perform outer MD5
|
||||
*/
|
||||
#ifdef USE_MD5
|
||||
MD5Init(&context); /* init context for 2nd pass */
|
||||
MD5Update(&context, k_opad, 64); /* start with outer pad */
|
||||
MD5Update(&context, digest, 16); /* then results of 1st hash */
|
||||
MD5Final(digest, &context); /* finish up 2nd pass */
|
||||
#else
|
||||
SHA1_Init(&context); /* init context for 2nd pass */
|
||||
SHA1_Update(&context, k_opad, 64); /* start with outer pad */
|
||||
SHA1_Update(&context, digest, 20); /* then results of 1st hash */
|
||||
SHA1_Final(digest, &context); /* finish up 2nd pass */
|
||||
#endif /* USE_MD5 */
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
|
||||
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* a) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* b) Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* c) Neither the name of Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_HASHDRIVER_H_
|
||||
#define _NETINET_SCTP_HASHDRIVER_H_
|
||||
|
||||
|
||||
void sctp_hash_digest(char *, int, char *, int, unsigned char *);
|
||||
|
||||
void sctp_hash_digest_m(char *, int, struct mbuf *, int, unsigned char *);
|
||||
|
||||
#endif
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 246674 2013-02-11 13:57:03Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 258228 2013-11-16 16:09:09Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -806,13 +806,12 @@ sctp_deliver_reasm_check(struct sctp_tcb *stcb, struct sctp_association *asoc)
|
||||
* but should we?
|
||||
*/
|
||||
if (stcb->sctp_socket) {
|
||||
pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket),
|
||||
pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT,
|
||||
stcb->sctp_ep->partial_delivery_point);
|
||||
} else {
|
||||
pd_point = stcb->sctp_ep->partial_delivery_point;
|
||||
}
|
||||
if (sctp_is_all_msg_on_reasm(asoc, &tsize) || (tsize >= pd_point)) {
|
||||
|
||||
/*
|
||||
* Yes, we setup to start reception, by
|
||||
* backing down the TSN just in case we
|
||||
@ -1432,7 +1431,6 @@ sctp_does_tsn_belong_to_reasm(struct sctp_association *asoc,
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
struct mbuf **m, int offset, struct sctp_data_chunk *ch, int chk_length,
|
||||
@ -1742,7 +1740,6 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
sctp_alloc_a_readq(stcb, control);
|
||||
sctp_build_readq_entry_mac(control, stcb, asoc->context, net, tsn,
|
||||
protocol_id,
|
||||
stcb->asoc.context,
|
||||
strmno, strmseq,
|
||||
chunk_flags,
|
||||
dmbuf);
|
||||
@ -1804,7 +1801,6 @@ failed_express_del:
|
||||
asoc->highest_tsn_inside_nr_map = tsn;
|
||||
}
|
||||
SCTP_STAT_INCR(sctps_recvexpressm);
|
||||
control->sinfo_tsn = tsn;
|
||||
asoc->tsn_last_delivered = tsn;
|
||||
asoc->fragment_flags = chunk_flags;
|
||||
asoc->tsn_of_pdapi_last_delivered = tsn;
|
||||
@ -1868,7 +1864,6 @@ failed_express_del:
|
||||
sctp_alloc_a_readq(stcb, control);
|
||||
sctp_build_readq_entry_mac(control, stcb, asoc->context, net, tsn,
|
||||
protocol_id,
|
||||
stcb->asoc.context,
|
||||
strmno, strmseq,
|
||||
chunk_flags,
|
||||
dmbuf);
|
||||
@ -2506,7 +2501,7 @@ sctp_service_queues(struct sctp_tcb *stcb, struct sctp_association *asoc)
|
||||
* delivery queue and something can be delivered.
|
||||
*/
|
||||
if (stcb->sctp_socket) {
|
||||
pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket),
|
||||
pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT,
|
||||
stcb->sctp_ep->partial_delivery_point);
|
||||
} else {
|
||||
pd_point = stcb->sctp_ep->partial_delivery_point;
|
||||
@ -3695,6 +3690,7 @@ sctp_fs_audit(struct sctp_association *asoc)
|
||||
struct sctp_tmit_chunk *chk;
|
||||
int inflight = 0, resend = 0, inbetween = 0, acked = 0, above = 0;
|
||||
int entry_flight, entry_cnt, ret;
|
||||
|
||||
entry_flight = asoc->total_flight;
|
||||
entry_cnt = asoc->total_flight_count;
|
||||
ret = 0;
|
||||
@ -4743,7 +4739,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
|
||||
}
|
||||
}
|
||||
TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next);
|
||||
if (tp1->pr_sctp_on) {
|
||||
if (PR_SCTP_ENABLED(tp1->flags)) {
|
||||
if (asoc->pr_sctp_cnt != 0)
|
||||
asoc->pr_sctp_cnt--;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.h 237715 2012-06-28 16:01:08Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.h 252585 2013-07-03 18:48:43Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_INDATA_H_
|
||||
@ -49,14 +49,14 @@ sctp_build_readq_entry(struct sctp_tcb *stcb,
|
||||
struct mbuf *dm);
|
||||
|
||||
|
||||
#define sctp_build_readq_entry_mac(_ctl, in_it, a, net, tsn, ppid, context, stream_no, stream_seq, flags, dm) do { \
|
||||
#define sctp_build_readq_entry_mac(_ctl, in_it, context, net, tsn, ppid, stream_no, stream_seq, flags, dm) do { \
|
||||
if (_ctl) { \
|
||||
atomic_add_int(&((net)->ref_count), 1); \
|
||||
(_ctl)->sinfo_stream = stream_no; \
|
||||
(_ctl)->sinfo_ssn = stream_seq; \
|
||||
(_ctl)->sinfo_flags = (flags << 8); \
|
||||
(_ctl)->sinfo_ppid = ppid; \
|
||||
(_ctl)->sinfo_context = a; \
|
||||
(_ctl)->sinfo_context = context; \
|
||||
(_ctl)->sinfo_timetolive = 0; \
|
||||
(_ctl)->sinfo_tsn = tsn; \
|
||||
(_ctl)->sinfo_cumtsn = tsn; \
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 246595 2013-02-09 17:26:14Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 262252 2014-02-20 20:14:43Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -412,9 +412,10 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
|
||||
}
|
||||
SCTP_FREE(asoc->strmin, SCTP_M_STRMI);
|
||||
}
|
||||
asoc->streamincnt = ntohs(init->num_outbound_streams);
|
||||
if (asoc->streamincnt > MAX_SCTP_STREAMS) {
|
||||
asoc->streamincnt = MAX_SCTP_STREAMS;
|
||||
if (asoc->max_inbound_streams > ntohs(init->num_outbound_streams)) {
|
||||
asoc->streamincnt = ntohs(init->num_outbound_streams);
|
||||
} else {
|
||||
asoc->streamincnt = asoc->max_inbound_streams;
|
||||
}
|
||||
SCTP_MALLOC(asoc->strmin, struct sctp_stream_in *, asoc->streamincnt *
|
||||
sizeof(struct sctp_stream_in), SCTP_M_STRMI);
|
||||
@ -426,11 +427,6 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
|
||||
for (i = 0; i < asoc->streamincnt; i++) {
|
||||
asoc->strmin[i].stream_no = i;
|
||||
asoc->strmin[i].last_sequence_delivered = 0xffff;
|
||||
/*
|
||||
* U-stream ranges will be set when the cookie is unpacked.
|
||||
* Or for the INIT sender they are un set (if pr-sctp not
|
||||
* supported) when the INIT-ACK arrives.
|
||||
*/
|
||||
TAILQ_INIT(&asoc->strmin[i].inqueue);
|
||||
asoc->strmin[i].delivery_started = 0;
|
||||
}
|
||||
@ -468,7 +464,6 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
|
||||
|
||||
/* First verify that we have no illegal param's */
|
||||
abort_flag = 0;
|
||||
op_err = NULL;
|
||||
|
||||
op_err = sctp_arethere_unrecognized_parameters(m,
|
||||
(offset + sizeof(struct sctp_init_chunk)),
|
||||
@ -1068,12 +1063,13 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp SCTP_UNUSED,
|
||||
SCTP_SOCKET_UNLOCK(so, 1);
|
||||
#endif
|
||||
}
|
||||
/* are the queues empty? */
|
||||
#ifdef INVARIANTS
|
||||
if (!TAILQ_EMPTY(&asoc->send_queue) ||
|
||||
!TAILQ_EMPTY(&asoc->sent_queue) ||
|
||||
!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
|
||||
sctp_report_all_outbound(stcb, 0, 0, SCTP_SO_NOT_LOCKED);
|
||||
panic("Queues are not empty when handling SHUTDOWN-ACK");
|
||||
}
|
||||
#endif
|
||||
/* stop the timer */
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_9);
|
||||
/* send SHUTDOWN-COMPLETE */
|
||||
@ -1614,7 +1610,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
return (NULL);
|
||||
|
||||
}
|
||||
switch SCTP_GET_STATE(asoc) {
|
||||
switch (SCTP_GET_STATE(asoc)) {
|
||||
case SCTP_STATE_COOKIE_WAIT:
|
||||
case SCTP_STATE_COOKIE_ECHOED:
|
||||
/*
|
||||
@ -1926,20 +1922,24 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
cookie->tie_tag_peer_vtag == asoc->peer_vtag_nonce &&
|
||||
cookie->tie_tag_peer_vtag != 0) {
|
||||
struct sctpasochead *head;
|
||||
if (asoc->peer_supports_nat) {
|
||||
/* This is a gross gross hack.
|
||||
* just call the cookie_new code since we
|
||||
* are allowing a duplicate association. I hope
|
||||
* this works...
|
||||
*/
|
||||
return (sctp_process_cookie_new(m, iphlen, offset, src, dst,
|
||||
sh, cookie, cookie_len,
|
||||
inp, netp, init_src,notification,
|
||||
auth_skipped, auth_offset, auth_len,
|
||||
#if defined(__FreeBSD__)
|
||||
use_mflowid, mflowid,
|
||||
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
|
||||
struct socket *so;
|
||||
#endif
|
||||
vrf_id, port));
|
||||
|
||||
if (asoc->peer_supports_nat) {
|
||||
/* This is a gross gross hack.
|
||||
* Just call the cookie_new code since we
|
||||
* are allowing a duplicate association.
|
||||
* I hope this works...
|
||||
*/
|
||||
return (sctp_process_cookie_new(m, iphlen, offset, src, dst,
|
||||
sh, cookie, cookie_len,
|
||||
inp, netp, init_src,notification,
|
||||
auth_skipped, auth_offset, auth_len,
|
||||
#if defined(__FreeBSD__)
|
||||
use_mflowid, mflowid,
|
||||
#endif
|
||||
vrf_id, port));
|
||||
}
|
||||
/*
|
||||
* case A in Section 5.2.4 Table 2: XXMM (peer restarted)
|
||||
@ -1992,6 +1992,10 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
asoc->mapping_array_size);
|
||||
}
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
|
||||
so = SCTP_INP_SO(stcb->sctp_ep);
|
||||
SCTP_SOCKET_LOCK(so, 1);
|
||||
#endif
|
||||
SCTP_INP_INFO_WLOCK();
|
||||
SCTP_INP_WLOCK(stcb->sctp_ep);
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
@ -1999,7 +2003,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
/* send up all the data */
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
|
||||
sctp_report_all_outbound(stcb, 0, 1, SCTP_SO_NOT_LOCKED);
|
||||
sctp_report_all_outbound(stcb, 0, 1, SCTP_SO_LOCKED);
|
||||
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
|
||||
stcb->asoc.strmout[i].chunks_on_queues = 0;
|
||||
stcb->asoc.strmout[i].stream_no = i;
|
||||
@ -2021,11 +2025,15 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
*/
|
||||
LIST_INSERT_HEAD(head, stcb, sctp_asocs);
|
||||
|
||||
/* process the INIT info (peer's info) */
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
SCTP_INP_WUNLOCK(stcb->sctp_ep);
|
||||
SCTP_INP_INFO_WUNLOCK();
|
||||
|
||||
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
|
||||
SCTP_SOCKET_UNLOCK(so, 1);
|
||||
#endif
|
||||
asoc->total_flight = 0;
|
||||
asoc->total_flight_count = 0;
|
||||
/* process the INIT info (peer's info) */
|
||||
retval = sctp_process_init(init_cp, stcb);
|
||||
if (retval < 0) {
|
||||
if (how_indx < sizeof(asoc->cookie_how))
|
||||
@ -3335,13 +3343,14 @@ sctp_handle_shutdown_complete(struct sctp_shutdown_complete_chunk *cp SCTP_UNUSE
|
||||
/* notify upper layer protocol */
|
||||
if (stcb->sctp_socket) {
|
||||
sctp_ulp_notify(SCTP_NOTIFY_ASSOC_DOWN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
|
||||
/* are the queues empty? they should be */
|
||||
if (!TAILQ_EMPTY(&asoc->send_queue) ||
|
||||
!TAILQ_EMPTY(&asoc->sent_queue) ||
|
||||
!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
|
||||
sctp_report_all_outbound(stcb, 0, 0, SCTP_SO_NOT_LOCKED);
|
||||
}
|
||||
}
|
||||
#ifdef INVARIANTS
|
||||
if (!TAILQ_EMPTY(&asoc->send_queue) ||
|
||||
!TAILQ_EMPTY(&asoc->sent_queue) ||
|
||||
!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
|
||||
panic("Queues are not empty when handling SHUTDOWN-COMPLETE");
|
||||
}
|
||||
#endif
|
||||
/* stop the timer */
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWNACK, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_22);
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_shutdown);
|
||||
@ -3599,7 +3608,7 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc,
|
||||
}
|
||||
|
||||
void
|
||||
sctp_reset_in_stream(struct sctp_tcb *stcb, uint32_t number_entries, uint16_t * list)
|
||||
sctp_reset_in_stream(struct sctp_tcb *stcb, uint32_t number_entries, uint16_t *list)
|
||||
{
|
||||
uint32_t i;
|
||||
uint16_t temp;
|
||||
@ -3627,18 +3636,13 @@ sctp_reset_in_stream(struct sctp_tcb *stcb, uint32_t number_entries, uint16_t *
|
||||
}
|
||||
|
||||
static void
|
||||
sctp_reset_out_streams(struct sctp_tcb *stcb, int number_entries, uint16_t * list)
|
||||
sctp_reset_out_streams(struct sctp_tcb *stcb, uint32_t number_entries, uint16_t *list)
|
||||
{
|
||||
int i;
|
||||
uint32_t i;
|
||||
uint16_t temp;
|
||||
|
||||
if (number_entries == 0) {
|
||||
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
|
||||
stcb->asoc.strmout[i].next_sequence_send = 0;
|
||||
}
|
||||
} else if (number_entries) {
|
||||
if (number_entries > 0) {
|
||||
for (i = 0; i < number_entries; i++) {
|
||||
uint16_t temp;
|
||||
|
||||
temp = ntohs(list[i]);
|
||||
if (temp >= stcb->asoc.streamoutcnt) {
|
||||
/* no such stream */
|
||||
@ -3646,6 +3650,10 @@ sctp_reset_out_streams(struct sctp_tcb *stcb, int number_entries, uint16_t * lis
|
||||
}
|
||||
stcb->asoc.strmout[temp].next_sequence_send = 0;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
|
||||
stcb->asoc.strmout[i].next_sequence_send = 0;
|
||||
}
|
||||
}
|
||||
sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_SEND, stcb, number_entries, (void *)list, SCTP_SO_NOT_LOCKED);
|
||||
}
|
||||
@ -3732,7 +3740,7 @@ sctp_handle_stream_reset_response(struct sctp_tcb *stcb,
|
||||
struct sctp_association *asoc = &stcb->asoc;
|
||||
struct sctp_tmit_chunk *chk;
|
||||
struct sctp_stream_reset_out_request *srparam;
|
||||
int number_entries;
|
||||
uint32_t number_entries;
|
||||
|
||||
if (asoc->stream_reset_outstanding == 0) {
|
||||
/* duplicate */
|
||||
@ -4079,7 +4087,7 @@ sctp_handle_str_reset_add_strm(struct sctp_tcb *stcb, struct sctp_tmit_chunk *ch
|
||||
if (!(asoc->local_strreset_support & SCTP_ENABLE_CHANGE_ASSOC_REQ)) {
|
||||
asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
|
||||
} else if ((num_stream > stcb->asoc.max_inbound_streams) ||
|
||||
(num_stream > 0xffff)) {
|
||||
(num_stream > 0xffff)) {
|
||||
/* We must reject it they ask for to many */
|
||||
denied:
|
||||
stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
|
||||
@ -4691,8 +4699,10 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
if ((ch->chunk_type == SCTP_ABORT_ASSOCIATION) ||
|
||||
(ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) ||
|
||||
(ch->chunk_type == SCTP_PACKET_DROPPED)) {
|
||||
if ((vtag_in == asoc->my_vtag) ||
|
||||
((ch->chunk_flags & SCTP_HAD_NO_TCB) &&
|
||||
/* Take the T-bit always into account. */
|
||||
if ((((ch->chunk_flags & SCTP_HAD_NO_TCB) == 0) &&
|
||||
(vtag_in == asoc->my_vtag)) ||
|
||||
(((ch->chunk_flags & SCTP_HAD_NO_TCB) == SCTP_HAD_NO_TCB) &&
|
||||
(vtag_in == asoc->peer_vtag))) {
|
||||
/* this is valid */
|
||||
} else {
|
||||
@ -5704,6 +5714,7 @@ sctp_validate_no_locks(struct sctp_inpcb *inp)
|
||||
{
|
||||
#ifndef __APPLE__
|
||||
struct sctp_tcb *lstcb;
|
||||
|
||||
LIST_FOREACH(lstcb, &inp->sctp_asoc_list, sctp_tcblist) {
|
||||
if (mtx_owned(&lstcb->tcb_mtx)) {
|
||||
panic("Own lock on stcb at return from input");
|
||||
@ -5853,7 +5864,11 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
if (ipsec4_in_reject(m, &inp->ip_inp.inp)) {
|
||||
#if defined(__FreeBSD__) && (__FreeBSD_version > 1000036)
|
||||
IPSECSTAT_INC(ips_in_polvio);
|
||||
#else
|
||||
MODULE_GLOBAL(ipsec4stat).in_polvio++;
|
||||
#endif
|
||||
SCTP_STAT_INCR(sctps_hdrops);
|
||||
goto out;
|
||||
}
|
||||
@ -5862,7 +5877,11 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (ipsec6_in_reject(m, &inp->ip_inp.inp)) {
|
||||
#if defined(__FreeBSD__) && (__FreeBSD_version > 1000036)
|
||||
IPSEC6STAT_INC(ips_in_polvio);
|
||||
#else
|
||||
MODULE_GLOBAL(ipsec6stat).in_polvio++;
|
||||
#endif
|
||||
SCTP_STAT_INCR(sctps_hdrops);
|
||||
goto out;
|
||||
}
|
||||
@ -6209,7 +6228,13 @@ sctp_input(i_pak, va_alist)
|
||||
}
|
||||
#endif
|
||||
#if defined(__FreeBSD__)
|
||||
#if __FreeBSD_version >= 800000
|
||||
#if __FreeBSD_version > 1000049
|
||||
SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
|
||||
"sctp_input(): Packet of length %d received on %s with csum_flags 0x%b.\n",
|
||||
m->m_pkthdr.len,
|
||||
if_name(m->m_pkthdr.rcvif),
|
||||
(int)m->m_pkthdr.csum_flags, CSUM_BITS);
|
||||
#elif __FreeBSD_version >= 800000
|
||||
SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
|
||||
"sctp_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
|
||||
m->m_pkthdr.len,
|
||||
|
@ -44,8 +44,6 @@
|
||||
#if defined(__Userspace_os_Windows)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <ws2ipdef.h>
|
||||
#include <ws2def.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <Mswsock.h>
|
||||
#include <Windows.h>
|
||||
@ -63,6 +61,10 @@ typedef struct
|
||||
CRITICAL_SECTION waiters_count_lock;
|
||||
HANDLE events_[C_MAX_EVENTS];
|
||||
} userland_cond_t;
|
||||
void InitializeXPConditionVariable(userland_cond_t *);
|
||||
void DeleteXPConditionVariable(userland_cond_t *);
|
||||
int SleepXPConditionVariable(userland_cond_t *, userland_mutex_t *);
|
||||
void WakeAllXPConditionVariable(userland_cond_t *);
|
||||
#define InitializeConditionVariable(cond) InitializeXPConditionVariable(cond)
|
||||
#define DeleteConditionVariable(cond) DeleteXPConditionVariable(cond)
|
||||
#define SleepConditionVariableCS(cond, mtx, time) SleepXPConditionVariable(cond, mtx)
|
||||
@ -75,27 +77,32 @@ typedef HANDLE userland_thread_t;
|
||||
#define ADDRESS_FAMILY unsigned __int8
|
||||
#define IPVERSION 4
|
||||
#define MAXTTL 255
|
||||
/* VS2010 comes with stdint.h */
|
||||
#if _MSC_VER >= 1600
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#define uint64_t unsigned __int64
|
||||
#define uint32_t unsigned __int32
|
||||
#define int32_t __int32
|
||||
#define uint16_t unsigned __int16
|
||||
#define int16_t __int16
|
||||
#define uint8_t unsigned __int8
|
||||
#define int8_t __int8
|
||||
#endif
|
||||
#ifndef _SIZE_T_DEFINED
|
||||
#define size_t __int32
|
||||
#endif
|
||||
#define u_long unsigned __int64
|
||||
#define u_int unsigned __int32
|
||||
#define uint32_t unsigned __int32
|
||||
#define u_int32_t unsigned __int32
|
||||
#define int32_t __int32
|
||||
#define int16_t __int16
|
||||
#define uint16_t unsigned __int16
|
||||
#define u_int16_t unsigned __int16
|
||||
#define uint8_t unsigned __int8
|
||||
#define u_int8_t unsigned __int8
|
||||
#define int8_t __int8
|
||||
#define u_char unsigned char
|
||||
#define n_short unsigned __int16
|
||||
#define u_short unsigned __int16
|
||||
#define ssize_t __int64
|
||||
#define size_t __int32
|
||||
#define in_addr_t unsigned __int32
|
||||
#define in_port_t unsigned __int16
|
||||
#define n_time unsigned __int32
|
||||
#define sa_family_t unsigned __int8
|
||||
#define ssize_t __int64
|
||||
#define IFNAMSIZ 64
|
||||
#define __func__ __FUNCTION__
|
||||
|
||||
@ -210,8 +217,10 @@ typedef HANDLE userland_thread_t;
|
||||
|
||||
typedef char* caddr_t;
|
||||
|
||||
int Win_getifaddrs(struct ifaddrs**);
|
||||
#define getifaddrs(interfaces) (int)Win_getifaddrs(interfaces)
|
||||
#define if_nametoindex(x) (int)win_if_nametoindex(x)
|
||||
int win_if_nametoindex(const char *);
|
||||
#define if_nametoindex(x) win_if_nametoindex(x)
|
||||
|
||||
#define bzero(buf, len) memset(buf, 0, len)
|
||||
#define bcopy(srcKey, dstKey, len) memcpy(dstKey, srcKey, len)
|
||||
@ -226,12 +235,22 @@ typedef char* caddr_t;
|
||||
#ifdef CMSG_DATA
|
||||
#undef CMSG_DATA
|
||||
#endif
|
||||
/*
|
||||
* The following definitions should apply iff WINVER < 0x0600
|
||||
* but that check doesn't work in all cases. So be more pedantic...
|
||||
*/
|
||||
#define CMSG_DATA(x) WSA_CMSG_DATA(x)
|
||||
#define CMSG_ALIGN(x) WSA_CMSGDATA_ALIGN(x)
|
||||
#if WINVER < 0x0600
|
||||
#ifndef CMSG_FIRSTHDR
|
||||
#define CMSG_FIRSTHDR(x) WSA_CMSG_FIRSTHDR(x)
|
||||
#endif
|
||||
#ifndef CMSG_NXTHDR
|
||||
#define CMSG_NXTHDR(x, y) WSA_CMSG_NXTHDR(x, y)
|
||||
#endif
|
||||
#ifndef CMSG_SPACE
|
||||
#define CMSG_SPACE(x) WSA_CMSG_SPACE(x)
|
||||
#endif
|
||||
#ifndef CMSG_LEN
|
||||
#define CMSG_LEN(x) WSA_CMSG_LEN(x)
|
||||
#endif
|
||||
|
||||
@ -383,7 +402,7 @@ struct udphdr {
|
||||
#else /* !defined(Userspace_os_Windows) */
|
||||
#include <sys/cdefs.h> /* needed? added from old __FreeBSD__ */
|
||||
#include <sys/socket.h>
|
||||
#if defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) || defined(ANDROID)
|
||||
#if defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Linux) || defined(__Userspace_os_NetBSD) || defined(__Userspace_os_OpenBSD)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
typedef pthread_mutex_t userland_mutex_t;
|
||||
@ -397,7 +416,9 @@ typedef pthread_t userland_thread_t;
|
||||
#define MA_OWNED 7 /* sys/mutex.h typically on FreeBSD */
|
||||
#if !defined(__Userspace_os_FreeBSD)
|
||||
struct mtx {int dummy;};
|
||||
#if !defined(__Userspace_os_NetBSD)
|
||||
struct selinfo {int dummy;};
|
||||
#endif
|
||||
struct sx {int dummy;};
|
||||
#endif
|
||||
|
||||
@ -463,7 +484,7 @@ struct sx {int dummy;};
|
||||
/* for getifaddrs */
|
||||
#include <sys/types.h>
|
||||
#if !defined(__Userspace_os_Windows)
|
||||
#if !defined(ANDROID)
|
||||
#if defined(INET) || defined(INET6)
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
@ -500,7 +521,7 @@ struct sx {int dummy;};
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/icmp6.h>
|
||||
#endif
|
||||
#if defined(__Userspace_os_Linux) || defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) ||defined(__Userspace_os_Windows)
|
||||
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Linux) || defined(__Userspace_os_NetBSD) || defined(__Userspace_os_OpenBSD) || defined(__Userspace_os_Windows)
|
||||
#include "user_ip6_var.h"
|
||||
#else
|
||||
#include <netinet6/ip6_var.h>
|
||||
@ -518,6 +539,8 @@ struct sx {int dummy;};
|
||||
#include <sys/filedesc.h>
|
||||
#endif
|
||||
|
||||
#include "netinet/sctp_sha1.h"
|
||||
|
||||
#if __FreeBSD_version >= 700000
|
||||
#include <netinet/ip_options.h>
|
||||
#endif
|
||||
@ -582,21 +605,21 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT);
|
||||
|
||||
#if defined(SCTP_DEBUG)
|
||||
#include <netinet/sctp_constants.h>
|
||||
#define SCTPDBG(level, ...) \
|
||||
{ \
|
||||
do { \
|
||||
if (SCTP_BASE_SYSCTL(sctp_debug_on) & level) { \
|
||||
SCTP_PRINTF(__VA_ARGS__); \
|
||||
} \
|
||||
} while (0); \
|
||||
#define SCTPDBG(level, ...) \
|
||||
{ \
|
||||
do { \
|
||||
if (SCTP_BASE_SYSCTL(sctp_debug_on) & level) { \
|
||||
SCTP_PRINTF(__VA_ARGS__); \
|
||||
} \
|
||||
} while (0); \
|
||||
}
|
||||
#define SCTPDBG_ADDR(level, addr) \
|
||||
{ \
|
||||
do { \
|
||||
if (SCTP_BASE_SYSCTL(sctp_debug_on) & level ) { \
|
||||
sctp_print_address(addr); \
|
||||
} \
|
||||
} while (0); \
|
||||
#define SCTPDBG_ADDR(level, addr) \
|
||||
{ \
|
||||
do { \
|
||||
if (SCTP_BASE_SYSCTL(sctp_debug_on) & level ) { \
|
||||
sctp_print_address(addr); \
|
||||
} \
|
||||
} while (0); \
|
||||
}
|
||||
#else
|
||||
#define SCTPDBG(level, ...)
|
||||
@ -654,17 +677,17 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT);
|
||||
/*
|
||||
* general memory allocation
|
||||
*/
|
||||
#define SCTP_MALLOC(var, type, size, name) \
|
||||
do { \
|
||||
MALLOC(var, type, size, name, M_NOWAIT); \
|
||||
} while (0)
|
||||
#define SCTP_MALLOC(var, type, size, name) \
|
||||
do { \
|
||||
MALLOC(var, type, size, name, M_NOWAIT); \
|
||||
} while (0)
|
||||
|
||||
#define SCTP_FREE(var, type) FREE(var, type)
|
||||
|
||||
#define SCTP_MALLOC_SONAME(var, type, size) \
|
||||
do { \
|
||||
MALLOC(var, type, size, M_SONAME, (M_WAITOK | M_ZERO)); \
|
||||
} while (0)
|
||||
#define SCTP_MALLOC_SONAME(var, type, size) \
|
||||
do { \
|
||||
MALLOC(var, type, size, M_SONAME, (M_WAITOK | M_ZERO)); \
|
||||
} while (0)
|
||||
|
||||
#define SCTP_FREE_SONAME(var) FREE(var, M_SONAME)
|
||||
|
||||
@ -978,72 +1001,18 @@ int sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af);
|
||||
/* This is re-pulse ourselves for sendbuf */
|
||||
#define SCTP_ZERO_COPY_SENDQ_EVENT(inp, so)
|
||||
|
||||
|
||||
/*
|
||||
* SCTP AUTH
|
||||
*/
|
||||
/* USE_SCTP_SHA1 is defined if you need sctp_sha1.[ch]. SHA1_* functions are defined
|
||||
* there. On Linux, they are also defined in libcrypto.a once you install
|
||||
* the libssl-dev package (on Ubuntu, at least).
|
||||
*/
|
||||
/* #define USE_SCTP_SHA1 */
|
||||
|
||||
/* #define HAVE_SHA2 sha2.h exists on Linux? */
|
||||
|
||||
|
||||
#define SCTP_READ_RANDOM(buf, len) read_random(buf, len)
|
||||
|
||||
|
||||
#ifdef USE_SCTP_SHA1
|
||||
#include <netinet/sctp_sha1.h>
|
||||
#else
|
||||
#if 0 /*this was old _KERNEL code... */
|
||||
#include <crypto/sha1.h>
|
||||
/* map standard crypto API names */
|
||||
#define SHA1_Init SHA1Init
|
||||
#define SHA1_Update SHA1Update
|
||||
#define SHA1_Final(x,y) SHA1Final((caddr_t)x, y)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SHA2)
|
||||
#include <crypto/sha2/sha2.h>
|
||||
#endif
|
||||
#if 0
|
||||
/* going to have to port so generic across OS's... */
|
||||
#if 1 /* openssl header files on FreeBSD 6.3 on Emulab and libssl-dev for Ubuntu */
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/sha.h>
|
||||
/* libssl-dev calls this SHA_CTX, but it's refered to as SHA1_CTX within the
|
||||
* SCTP stack code so here we typedef (or macro?) to equate the two.
|
||||
*/
|
||||
typedef SHA_CTX SHA1_CTX;
|
||||
|
||||
#else /* only _KERNEL? */
|
||||
|
||||
#include <sys/md5.h>
|
||||
/* map standard crypto API names */
|
||||
#define MD5_Init MD5Init
|
||||
#define MD5_Update MD5Update
|
||||
#define MD5_Final MD5Final
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define SCTP_SHA1_CTX struct sctp_sha1_context
|
||||
#define SCTP_SHA1_INIT sctp_sha1_init
|
||||
#define SCTP_SHA1_UPDATE sctp_sha1_update
|
||||
#define SCTP_SHA1_FINAL(x,y) sctp_sha1_final((unsigned char *)x, y)
|
||||
|
||||
/* start OOTB only stuff */
|
||||
|
||||
|
||||
/* TODO IFT_LOOP is in net/if_types.h on Linux */
|
||||
#define IFT_LOOP 0x18
|
||||
|
||||
/* sctp_pcb.h */
|
||||
/* typedef int SHA1_CTX; */
|
||||
/* typedef int MD5_CTX; */
|
||||
#ifdef HAVE_SHA2
|
||||
typedef int SHA256_CTX;
|
||||
typedef int SHA384_CTX;
|
||||
typedef int SHA512_CTX;
|
||||
#endif
|
||||
|
||||
#if defined(__Userspace_os_Windows)
|
||||
#define SHUT_RD 1
|
||||
@ -1070,6 +1039,11 @@ struct sockaddr_conn {
|
||||
void *sconn_addr;
|
||||
};
|
||||
|
||||
/*
|
||||
* SCTP protocol specific mbuf flags.
|
||||
*/
|
||||
#define M_NOTIFICATION M_PROTO5 /* SCTP notification */
|
||||
|
||||
/*
|
||||
* IP output routines
|
||||
*/
|
||||
@ -1117,9 +1091,11 @@ 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_FreeBSD) || defined(__Userspace_os_OpenBSD)
|
||||
#if defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD)
|
||||
/* stolen from /usr/include/sys/socket.h */
|
||||
#define CMSG_ALIGN(n) _ALIGN(n)
|
||||
#elif defined(__Userspace_os_NetBSD)
|
||||
#define CMSG_ALIGN(n) (((n) + __ALIGNBYTES) & ~__ALIGNBYTES)
|
||||
#elif defined(__Userspace_os_Darwin)
|
||||
#if !defined(__DARWIN_ALIGNBYTES)
|
||||
#define __DARWIN_ALIGNBYTES (sizeof(__darwin_size_t) - 1)
|
||||
@ -1156,14 +1132,21 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int a
|
||||
#endif
|
||||
|
||||
#if defined(__Userspace_os_Linux)
|
||||
#if !defined(TAILQ_FOREACH_SAFE)
|
||||
#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
|
||||
for ((var) = ((head)->tqh_first); \
|
||||
(var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
|
||||
(var) = (tvar))
|
||||
|
||||
#endif
|
||||
#if !defined(LIST_FOREACH_SAFE)
|
||||
#define LIST_FOREACH_SAFE(var, head, field, tvar) \
|
||||
for ((var) = ((head)->lh_first); \
|
||||
(var) && ((tvar) = LIST_NEXT((var), field), 1); \
|
||||
(var) = (tvar))
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__Userspace_os_DragonFly)
|
||||
#define TAILQ_FOREACH_SAFE TAILQ_FOREACH_MUTABLE
|
||||
#define LIST_FOREACH_SAFE LIST_FOREACH_MUTABLE
|
||||
#endif
|
||||
#endif
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 246687 2013-02-11 21:02:49Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 262252 2014-02-20 20:14:43Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -1972,9 +1972,11 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa,
|
||||
static struct mbuf *
|
||||
sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t *len)
|
||||
{
|
||||
#if defined(INET) || defined(INET6)
|
||||
struct sctp_paramhdr *parmh;
|
||||
struct mbuf *mret;
|
||||
uint16_t plen;
|
||||
#endif
|
||||
|
||||
switch (ifa->address.sa.sa_family) {
|
||||
#ifdef INET
|
||||
@ -1990,6 +1992,7 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t *len)
|
||||
default:
|
||||
return (m);
|
||||
}
|
||||
#if defined(INET) || defined(INET6)
|
||||
if (M_TRAILINGSPACE(m) >= plen) {
|
||||
/* easy side we just drop it on the end */
|
||||
parmh = (struct sctp_paramhdr *)(SCTP_BUF_AT(m, SCTP_BUF_LEN(m)));
|
||||
@ -2052,6 +2055,7 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t *len)
|
||||
*len += plen;
|
||||
}
|
||||
return (mret);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -3446,7 +3450,11 @@ sctp_find_cmsg(int c_type, void *data, struct mbuf *control, size_t cpsize)
|
||||
return (found);
|
||||
}
|
||||
m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct sctp_prinfo), (caddr_t)&prinfo);
|
||||
sndrcvinfo->sinfo_timetolive = prinfo.pr_value;
|
||||
if (prinfo.pr_policy != SCTP_PR_SCTP_NONE) {
|
||||
sndrcvinfo->sinfo_timetolive = prinfo.pr_value;
|
||||
} else {
|
||||
sndrcvinfo->sinfo_timetolive = 0;
|
||||
}
|
||||
sndrcvinfo->sinfo_flags |= prinfo.pr_policy;
|
||||
break;
|
||||
case SCTP_AUTHINFO:
|
||||
@ -3628,7 +3636,7 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
|
||||
|
||||
static struct sctp_tcb *
|
||||
sctp_findassociation_cmsgs(struct sctp_inpcb **inp_p,
|
||||
in_port_t port,
|
||||
uint16_t port,
|
||||
struct mbuf *control,
|
||||
struct sctp_nets **net_p,
|
||||
int *error)
|
||||
@ -3734,7 +3742,6 @@ sctp_add_cookie(struct mbuf *init, int init_offset,
|
||||
int sig_offset;
|
||||
uint16_t cookie_sz;
|
||||
|
||||
mret = NULL;
|
||||
mret = sctp_get_mbuf_for_msg((sizeof(struct sctp_state_cookie) +
|
||||
sizeof(struct sctp_paramhdr)), 0,
|
||||
M_NOWAIT, 1, MT_DATA);
|
||||
@ -3931,7 +3938,9 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
||||
struct sctphdr *sctphdr;
|
||||
int packet_length;
|
||||
int ret;
|
||||
#if defined(INET) || defined(INET6)
|
||||
uint32_t vrf_id;
|
||||
#endif
|
||||
#if defined(INET) || defined(INET6)
|
||||
#if !defined(__Panda__)
|
||||
struct mbuf *o_pak;
|
||||
@ -3957,12 +3966,13 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
||||
sctp_m_freem(m);
|
||||
return (EFAULT);
|
||||
}
|
||||
#if defined(INET) || defined(INET6)
|
||||
if (stcb) {
|
||||
vrf_id = stcb->asoc.vrf_id;
|
||||
} else {
|
||||
vrf_id = inp->def_vrf_id;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* fill in the HMAC digest for any AUTH chunk in the packet */
|
||||
if ((auth != NULL) && (stcb != NULL)) {
|
||||
sctp_fill_hmac_digest_m(m, auth_offset, auth, stcb, auth_keyid);
|
||||
@ -4338,7 +4348,11 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
||||
* This means especially, that it is not set at the
|
||||
* SCTP layer. So use the value from the IP layer.
|
||||
*/
|
||||
#if defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
|
||||
flowlabel = ntohl(inp->ip_inp.inp.inp_flow);
|
||||
#else
|
||||
flowlabel = ntohl(((struct in6pcb *)inp)->in6p_flowinfo);
|
||||
#endif
|
||||
}
|
||||
flowlabel &= 0x000fffff;
|
||||
len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr);
|
||||
@ -4418,7 +4432,11 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
||||
* SCTP layer. So use the value from the IP layer.
|
||||
*/
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Panda__) || defined(__Windows__) || defined(__Userspace__)
|
||||
#if defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
|
||||
tos_value = (ntohl(inp->ip_inp.inp.inp_flow) >> 20) & 0xff;
|
||||
#else
|
||||
tos_value = (ntohl(((struct in6pcb *)inp)->in6p_flowinfo) >> 20) & 0xff;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
tos_value &= 0xfc;
|
||||
@ -4736,6 +4754,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
||||
#else
|
||||
if (ro->ro_rt) {
|
||||
RTFREE(ro->ro_rt);
|
||||
ro->ro_rt = NULL;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
@ -4805,8 +4824,12 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
||||
sctphdr->dest_port = dest_port;
|
||||
sctphdr->v_tag = v_tag;
|
||||
sctphdr->checksum = 0;
|
||||
#if defined(SCTP_WITH_NO_CSUM)
|
||||
SCTP_STAT_INCR(sctps_sendnocrc);
|
||||
#else
|
||||
sctphdr->checksum = sctp_calculate_cksum(m, 0);
|
||||
SCTP_STAT_INCR(sctps_sendswcrc);
|
||||
#endif
|
||||
if (tos_value == 0) {
|
||||
tos_value = inp->ip_inp.inp.inp_ip_tos;
|
||||
}
|
||||
@ -4846,9 +4869,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
|
||||
struct mbuf *m;
|
||||
struct sctp_nets *net;
|
||||
struct sctp_init_chunk *init;
|
||||
#if defined(INET) || defined(INET6)
|
||||
struct sctp_supported_addr_param *sup_addr;
|
||||
#endif
|
||||
struct sctp_adaptation_layer_indication *ali;
|
||||
struct sctp_supported_chunk_types_param *pr_supported;
|
||||
struct sctp_paramhdr *ph;
|
||||
@ -5730,6 +5751,14 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
}
|
||||
SCTP_BUF_LEN(m) = sizeof(struct sctp_init_chunk);
|
||||
|
||||
/*
|
||||
* We might not overwrite the identification[] completely and on
|
||||
* some platforms time_entered will contain some padding.
|
||||
* Therefore zero out the cookie to avoid putting
|
||||
* uninitialized memory on the wire.
|
||||
*/
|
||||
memset(&stc, 0, sizeof(struct sctp_state_cookie));
|
||||
|
||||
/* the time I built cookie */
|
||||
(void)SCTP_GETTIME_TIMEVAL(&stc.time_entered);
|
||||
|
||||
@ -5892,6 +5921,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
memcpy(&stc.laddress, &dstconn->sconn_addr, sizeof(void *));
|
||||
stc.laddr_type = SCTP_CONN_ADDRESS;
|
||||
/* scope_id is only for v6 */
|
||||
stc.scope_id = 0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -5987,11 +6017,19 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
#if defined(__Userspace__)
|
||||
case AF_CONN:
|
||||
sconn = (struct sockaddr_conn *)to;
|
||||
stc.address[0] = 0;
|
||||
stc.address[1] = 0;
|
||||
stc.address[2] = 0;
|
||||
stc.address[3] = 0;
|
||||
memcpy(&stc.address, &sconn->sconn_addr, sizeof(void *));
|
||||
stc.addr_type = SCTP_CONN_ADDRESS;
|
||||
stc.laddress[0] = 0;
|
||||
stc.laddress[1] = 0;
|
||||
stc.laddress[2] = 0;
|
||||
stc.laddress[3] = 0;
|
||||
memcpy(&stc.laddress, &sconn->sconn_addr, sizeof(void *));
|
||||
stc.scope_id = 0;
|
||||
stc.laddr_type = SCTP_CONN_ADDRESS;
|
||||
stc.scope_id = 0;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
@ -6427,17 +6465,16 @@ sctp_get_frag_point(struct sctp_tcb *stcb,
|
||||
static void
|
||||
sctp_set_prsctp_policy(struct sctp_stream_queue_pending *sp)
|
||||
{
|
||||
sp->pr_sctp_on = 0;
|
||||
/*
|
||||
* We assume that the user wants PR_SCTP_TTL if the user
|
||||
* provides a positive lifetime but does not specify any
|
||||
* PR_SCTP policy. This is a BAD assumption and causes
|
||||
* problems at least with the U-Vancovers MPI folks. I will
|
||||
* change this to be no policy means NO PR-SCTP.
|
||||
* PR_SCTP policy.
|
||||
*/
|
||||
if (PR_SCTP_ENABLED(sp->sinfo_flags)) {
|
||||
sp->act_flags |= PR_SCTP_POLICY(sp->sinfo_flags);
|
||||
sp->pr_sctp_on = 1;
|
||||
} else if (sp->timetolive > 0) {
|
||||
sp->sinfo_flags |= SCTP_PR_SCTP_TTL;
|
||||
sp->act_flags |= PR_SCTP_POLICY(sp->sinfo_flags);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@ -6774,7 +6811,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
|
||||
/* TSNH */
|
||||
return;
|
||||
}
|
||||
if ((ca->m) && ca->sndlen) {
|
||||
if (ca->sndlen > 0) {
|
||||
m = SCTP_M_COPYM(ca->m, 0, M_COPYALL, M_NOWAIT);
|
||||
if (m == NULL) {
|
||||
/* can't copy so we are done */
|
||||
@ -6803,35 +6840,39 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
|
||||
}
|
||||
if (ca->sndrcv.sinfo_flags & SCTP_ABORT) {
|
||||
/* Abort this assoc with m as the user defined reason */
|
||||
if (m) {
|
||||
if (m != NULL) {
|
||||
SCTP_BUF_PREPEND(m, sizeof(struct sctp_paramhdr), M_NOWAIT);
|
||||
} else {
|
||||
m = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
|
||||
0, M_NOWAIT, 1, MT_DATA);
|
||||
SCTP_BUF_LEN(m) = sizeof(struct sctp_paramhdr);
|
||||
}
|
||||
if (m != NULL) {
|
||||
struct sctp_paramhdr *ph;
|
||||
|
||||
SCTP_BUF_PREPEND(m, sizeof(struct sctp_paramhdr), M_NOWAIT);
|
||||
if (m) {
|
||||
ph = mtod(m, struct sctp_paramhdr *);
|
||||
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
|
||||
ph->param_length = htons(sizeof(struct sctp_paramhdr) + ca->sndlen);
|
||||
}
|
||||
/* We add one here to keep the assoc from
|
||||
* dis-appearing on us.
|
||||
*/
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
sctp_abort_an_association(inp, stcb, m, SCTP_SO_NOT_LOCKED);
|
||||
/* sctp_abort_an_association calls sctp_free_asoc()
|
||||
* free association will NOT free it since we
|
||||
* incremented the refcnt .. we do this to prevent
|
||||
* it being freed and things getting tricky since
|
||||
* we could end up (from free_asoc) calling inpcb_free
|
||||
* which would get a recursive lock call to the
|
||||
* iterator lock.. But as a consequence of that the
|
||||
* stcb will return to us un-locked.. since free_asoc
|
||||
* returns with either no TCB or the TCB unlocked, we
|
||||
* must relock.. to unlock in the iterator timer :-0
|
||||
*/
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
atomic_add_int(&stcb->asoc.refcnt, -1);
|
||||
goto no_chunk_output;
|
||||
ph = mtod(m, struct sctp_paramhdr *);
|
||||
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
|
||||
ph->param_length = htons(sizeof(struct sctp_paramhdr) + ca->sndlen);
|
||||
}
|
||||
/* We add one here to keep the assoc from
|
||||
* dis-appearing on us.
|
||||
*/
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
sctp_abort_an_association(inp, stcb, m, SCTP_SO_NOT_LOCKED);
|
||||
/* sctp_abort_an_association calls sctp_free_asoc()
|
||||
* free association will NOT free it since we
|
||||
* incremented the refcnt .. we do this to prevent
|
||||
* it being freed and things getting tricky since
|
||||
* we could end up (from free_asoc) calling inpcb_free
|
||||
* which would get a recursive lock call to the
|
||||
* iterator lock.. But as a consequence of that the
|
||||
* stcb will return to us un-locked.. since free_asoc
|
||||
* returns with either no TCB or the TCB unlocked, we
|
||||
* must relock.. to unlock in the iterator timer :-0
|
||||
*/
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
atomic_add_int(&stcb->asoc.refcnt, -1);
|
||||
goto no_chunk_output;
|
||||
} else {
|
||||
if (m) {
|
||||
ret = sctp_msg_append(stcb, net, m,
|
||||
@ -6914,8 +6955,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
|
||||
|
||||
if ((sctp_is_feature_off(inp, SCTP_PCB_FLAGS_NODELAY)) &&
|
||||
(stcb->asoc.total_flight > 0) &&
|
||||
(un_sent < (int)(stcb->asoc.smallest_mtu - SCTP_MIN_OVERHEAD))
|
||||
) {
|
||||
(un_sent < (int)(stcb->asoc.smallest_mtu - SCTP_MIN_OVERHEAD))) {
|
||||
do_chunk_output = 0;
|
||||
}
|
||||
if (do_chunk_output)
|
||||
@ -7057,13 +7097,10 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m,
|
||||
/* Gather the length of the send */
|
||||
struct mbuf *mat;
|
||||
|
||||
mat = m;
|
||||
ca->sndlen = 0;
|
||||
while (m) {
|
||||
ca->sndlen += SCTP_BUF_LEN(m);
|
||||
m = SCTP_BUF_NEXT(m);
|
||||
for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) {
|
||||
ca->sndlen += SCTP_BUF_LEN(mat);
|
||||
}
|
||||
ca->m = mat;
|
||||
}
|
||||
ret = sctp_initiate_iterator(NULL, sctp_sendall_iterator, NULL,
|
||||
SCTP_PCB_ANY_FLAGS, SCTP_PCB_ANY_FEATURES,
|
||||
@ -7265,8 +7302,8 @@ sctp_clean_up_ctl(struct sctp_tcb *stcb, struct sctp_association *asoc, int so_l
|
||||
|
||||
static int
|
||||
sctp_can_we_split_this(struct sctp_tcb *stcb,
|
||||
uint32_t length,
|
||||
uint32_t goal_mtu, uint32_t frag_point, int eeor_on)
|
||||
uint32_t length,
|
||||
uint32_t goal_mtu, uint32_t frag_point, int eeor_on)
|
||||
{
|
||||
/* Make a decision on if I should split a
|
||||
* msg into multiple parts. This is only asked of
|
||||
@ -7325,18 +7362,18 @@ sctp_can_we_split_this(struct sctp_tcb *stcb,
|
||||
|
||||
static uint32_t
|
||||
sctp_move_to_outqueue(struct sctp_tcb *stcb,
|
||||
struct sctp_stream_out *strq,
|
||||
uint32_t goal_mtu,
|
||||
uint32_t frag_point,
|
||||
int *locked,
|
||||
int *giveup,
|
||||
int eeor_mode,
|
||||
int *bail,
|
||||
int so_locked
|
||||
struct sctp_stream_out *strq,
|
||||
uint32_t goal_mtu,
|
||||
uint32_t frag_point,
|
||||
int *locked,
|
||||
int *giveup,
|
||||
int eeor_mode,
|
||||
int *bail,
|
||||
int so_locked
|
||||
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
|
||||
SCTP_UNUSED
|
||||
SCTP_UNUSED
|
||||
#endif
|
||||
)
|
||||
)
|
||||
{
|
||||
/* Move from the stream to the send_queue keeping track of the total */
|
||||
struct sctp_association *asoc;
|
||||
@ -7350,7 +7387,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
|
||||
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
asoc = &stcb->asoc;
|
||||
one_more_time:
|
||||
one_more_time:
|
||||
/*sa_ignore FREED_MEMORY*/
|
||||
sp = TAILQ_FIRST(&strq->outqueue);
|
||||
if (sp == NULL) {
|
||||
@ -7385,11 +7422,11 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
|
||||
if ((sp->put_last_out == 0) && (sp->discard_rest == 0)) {
|
||||
SCTP_PRINTF("Gak, put out entire msg with NO end!-1\n");
|
||||
SCTP_PRINTF("sender_done:%d len:%d msg_comp:%d put_last_out:%d send_lock:%d\n",
|
||||
sp->sender_all_done,
|
||||
sp->length,
|
||||
sp->msg_is_complete,
|
||||
sp->put_last_out,
|
||||
send_lock_up);
|
||||
sp->sender_all_done,
|
||||
sp->length,
|
||||
sp->msg_is_complete,
|
||||
sp->put_last_out,
|
||||
send_lock_up);
|
||||
}
|
||||
if ((TAILQ_NEXT(sp, next) == NULL) && (send_lock_up == 0)) {
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
@ -7462,7 +7499,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
|
||||
if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
|
||||
sp->msg_is_complete = 1;
|
||||
}
|
||||
re_look:
|
||||
re_look:
|
||||
length = sp->length;
|
||||
if (sp->msg_is_complete) {
|
||||
/* The message is complete */
|
||||
@ -7561,7 +7598,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
|
||||
sp->data = sp->tail_mbuf = NULL;
|
||||
} else {
|
||||
struct mbuf *m;
|
||||
dont_do_it:
|
||||
dont_do_it:
|
||||
chk->data = SCTP_M_COPYM(sp->data, 0, to_move, M_NOWAIT);
|
||||
chk->last_mbuf = NULL;
|
||||
if (chk->data == NULL) {
|
||||
@ -7779,13 +7816,8 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
|
||||
}
|
||||
chk->send_size += pads;
|
||||
}
|
||||
/* We only re-set the policy if it is on */
|
||||
if (sp->pr_sctp_on) {
|
||||
sctp_set_prsctp_policy(sp);
|
||||
if (PR_SCTP_ENABLED(chk->flags)) {
|
||||
asoc->pr_sctp_cnt++;
|
||||
chk->pr_sctp_on = 1;
|
||||
} else {
|
||||
chk->pr_sctp_on = 0;
|
||||
}
|
||||
if (sp->msg_is_complete && (sp->length == 0) && (sp->sender_all_done)) {
|
||||
/* All done pull and kill the message */
|
||||
@ -7826,7 +7858,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
|
||||
strq->chunks_on_queues++;
|
||||
TAILQ_INSERT_TAIL(&asoc->send_queue, chk, sctp_next);
|
||||
asoc->send_queue_cnt++;
|
||||
out_of:
|
||||
out_of:
|
||||
if (send_lock_up) {
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
}
|
||||
@ -7980,7 +8012,7 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
|
||||
#endif
|
||||
)
|
||||
{
|
||||
/*
|
||||
/**
|
||||
* Ok this is the generic chunk service queue. we must do the
|
||||
* following: - Service the stream queue that is next, moving any
|
||||
* message (note I must get a complete message i.e. FIRST/MIDDLE and
|
||||
@ -9331,7 +9363,6 @@ sctp_send_cookie_ack(struct sctp_tcb *stcb)
|
||||
struct sctp_chunkhdr *hdr;
|
||||
struct sctp_tmit_chunk *chk;
|
||||
|
||||
cookie_ack = NULL;
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
cookie_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_chunkhdr), 0, M_NOWAIT, 1, MT_HEADER);
|
||||
@ -11083,6 +11114,7 @@ sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr, int so_locked
|
||||
struct sctp_abort_chunk *abort;
|
||||
struct sctp_auth_chunk *auth = NULL;
|
||||
struct sctp_nets *net;
|
||||
uint32_t vtag;
|
||||
uint32_t auth_offset = 0;
|
||||
uint16_t cause_len, chunk_len, padding_len;
|
||||
|
||||
@ -11145,7 +11177,14 @@ sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr, int so_locked
|
||||
/* Fill in the ABORT chunk header. */
|
||||
abort = mtod(m_abort, struct sctp_abort_chunk *);
|
||||
abort->ch.chunk_type = SCTP_ABORT_ASSOCIATION;
|
||||
abort->ch.chunk_flags = 0;
|
||||
if (stcb->asoc.peer_vtag == 0) {
|
||||
/* This happens iff the assoc is in COOKIE-WAIT state. */
|
||||
vtag = stcb->asoc.my_vtag;
|
||||
abort->ch.chunk_flags = SCTP_HAD_NO_TCB;
|
||||
} else {
|
||||
vtag = stcb->asoc.peer_vtag;
|
||||
abort->ch.chunk_flags = 0;
|
||||
}
|
||||
abort->ch.chunk_length = htons(chunk_len);
|
||||
/* Add padding, if necessary. */
|
||||
if (padding_len > 0) {
|
||||
@ -11157,7 +11196,7 @@ sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr, int so_locked
|
||||
(void)sctp_lowlevel_chunk_output(stcb->sctp_ep, stcb, net,
|
||||
(struct sockaddr *)&net->ro._l_addr,
|
||||
m_out, auth_offset, auth, stcb->asoc.authinfo.active_keyid, 1, 0, 0,
|
||||
stcb->sctp_ep->sctp_lport, stcb->rport, htonl(stcb->asoc.peer_vtag),
|
||||
stcb->sctp_ep->sctp_lport, stcb->rport, htonl(vtag),
|
||||
stcb->asoc.primary_destination->port, NULL,
|
||||
#if defined(__FreeBSD__)
|
||||
0, 0,
|
||||
@ -11232,7 +11271,10 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
|
||||
struct sctphdr *shout;
|
||||
struct sctp_chunkhdr *ch;
|
||||
struct udphdr *udp;
|
||||
int len, cause_len, padding_len, ret;
|
||||
int len, cause_len, padding_len;
|
||||
#if defined(INET) || defined(INET6)
|
||||
int ret;
|
||||
#endif
|
||||
#ifdef INET
|
||||
#if defined(__APPLE__) || defined(__Panda__)
|
||||
sctp_route_t ro;
|
||||
@ -11508,6 +11550,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
|
||||
/* Free the route if we got one back */
|
||||
if (ro.ro_rt) {
|
||||
RTFREE(ro.ro_rt);
|
||||
ro.ro_rt = NULL;
|
||||
}
|
||||
#else
|
||||
SCTP_IP_OUTPUT(ret, o_pak, NULL, NULL, vrf_id);
|
||||
@ -11564,8 +11607,12 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
|
||||
struct sockaddr_conn *sconn;
|
||||
|
||||
sconn = (struct sockaddr_conn *)src;
|
||||
#if defined(SCTP_WITH_NO_CSUM)
|
||||
SCTP_STAT_INCR(sctps_sendnocrc);
|
||||
#else
|
||||
shout->checksum = sctp_calculate_cksum(mout, 0);
|
||||
SCTP_STAT_INCR(sctps_sendswcrc);
|
||||
#endif
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) {
|
||||
sctp_packet_log(mout);
|
||||
@ -11574,7 +11621,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
|
||||
/* Don't alloc/free for each packet */
|
||||
if ((buffer = malloc(len)) != NULL) {
|
||||
m_copydata(mout, 0, len, buffer);
|
||||
ret = SCTP_BASE_VAR(conn_output)(sconn->sconn_addr, buffer, len, 0, 0);
|
||||
SCTP_BASE_VAR(conn_output)(sconn->sconn_addr, buffer, len, 0, 0);
|
||||
free(buffer);
|
||||
}
|
||||
sctp_m_freem(mout);
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 246687 2013-02-11 21:02:49Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 258765 2013-11-30 12:51:19Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -68,14 +68,6 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 246687 2013-02-11 21:02:49Z tuex
|
||||
#include <sys/unistd.h>
|
||||
#endif
|
||||
#if defined(__Userspace__)
|
||||
#if !defined(__Userspace_os_Windows)
|
||||
#if defined(ANDROID)
|
||||
#include <unistd.h>
|
||||
#include <ifaddrs-android-ext.h>
|
||||
#else
|
||||
#include <sys/unistd.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <user_socketvar.h>
|
||||
#endif
|
||||
|
||||
@ -90,8 +82,10 @@ struct sctp_base_info system_base_info;
|
||||
#endif
|
||||
|
||||
#if defined(__Userspace__)
|
||||
#if defined(INET) || defined(INET6)
|
||||
struct ifaddrs *g_interfaces;
|
||||
#endif
|
||||
#endif
|
||||
/* FIX: we don't handle multiple link local scopes */
|
||||
/* "scopeless" replacement IN6_ARE_ADDR_EQUAL */
|
||||
#ifdef INET6
|
||||
@ -926,8 +920,13 @@ sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr,
|
||||
static int
|
||||
sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
|
||||
{
|
||||
int loopback_scope, ipv4_local_scope, local_scope, site_scope;
|
||||
int ipv4_addr_legal, ipv6_addr_legal;
|
||||
int loopback_scope;
|
||||
#if defined(INET)
|
||||
int ipv4_local_scope, ipv4_addr_legal;
|
||||
#endif
|
||||
#if defined(INET6)
|
||||
int local_scope, site_scope, ipv6_addr_legal;
|
||||
#endif
|
||||
#if defined(__Userspace__)
|
||||
int conn_addr_legal;
|
||||
#endif
|
||||
@ -936,11 +935,15 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
|
||||
struct sctp_ifa *sctp_ifa;
|
||||
|
||||
loopback_scope = stcb->asoc.scope.loopback_scope;
|
||||
#if defined(INET)
|
||||
ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
|
||||
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
|
||||
#endif
|
||||
#if defined(INET6)
|
||||
local_scope = stcb->asoc.scope.local_scope;
|
||||
site_scope = stcb->asoc.scope.site_scope;
|
||||
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
|
||||
ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
|
||||
#endif
|
||||
#if defined(__Userspace__)
|
||||
conn_addr_legal = stcb->asoc.scope.conn_addr_legal;
|
||||
#endif
|
||||
@ -968,7 +971,9 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sctp_ifa->address.sa.sa_family != to->sa_family) {
|
||||
continue;
|
||||
}
|
||||
switch (sctp_ifa->address.sa.sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
@ -2318,8 +2323,11 @@ sctp_findassociation_special_addr(struct mbuf *m, int offset,
|
||||
struct sockaddr *dst)
|
||||
{
|
||||
struct sctp_paramhdr *phdr, parm_buf;
|
||||
#if defined(INET) || defined(INET6)
|
||||
struct sctp_tcb *stcb;
|
||||
uint32_t ptype, plen;
|
||||
uint16_t ptype;
|
||||
#endif
|
||||
uint16_t plen;
|
||||
#ifdef INET
|
||||
struct sockaddr_in sin4;
|
||||
#endif
|
||||
@ -2344,13 +2352,14 @@ sctp_findassociation_special_addr(struct mbuf *m, int offset,
|
||||
sin6.sin6_port = sh->src_port;
|
||||
#endif
|
||||
|
||||
stcb = NULL;
|
||||
offset += sizeof(struct sctp_init_chunk);
|
||||
|
||||
phdr = sctp_get_next_param(m, offset, &parm_buf, sizeof(parm_buf));
|
||||
while (phdr != NULL) {
|
||||
/* now we must see if we want the parameter */
|
||||
#if defined(INET) || defined(INET6)
|
||||
ptype = ntohs(phdr->param_type);
|
||||
#endif
|
||||
plen = ntohs(phdr->param_length);
|
||||
if (plen == 0) {
|
||||
break;
|
||||
@ -2534,7 +2543,7 @@ sctp_findassociation_addr(struct mbuf *m, int offset,
|
||||
if (sh->v_tag) {
|
||||
/* we only go down this path if vtag is non-zero */
|
||||
stcb = sctp_findassoc_by_vtag(src, dst, ntohl(sh->v_tag),
|
||||
inp_p, netp, sh->src_port, sh->dest_port, 0, vrf_id, 0);
|
||||
inp_p, netp, sh->src_port, sh->dest_port, 0, vrf_id, 0);
|
||||
if (stcb) {
|
||||
return (stcb);
|
||||
}
|
||||
@ -2550,11 +2559,11 @@ sctp_findassociation_addr(struct mbuf *m, int offset,
|
||||
}
|
||||
if (inp_p) {
|
||||
stcb = sctp_findassociation_addr_sa(src, dst, inp_p, netp,
|
||||
find_tcp_pool, vrf_id);
|
||||
find_tcp_pool, vrf_id);
|
||||
inp = *inp_p;
|
||||
} else {
|
||||
stcb = sctp_findassociation_addr_sa(src, dst, &inp, netp,
|
||||
find_tcp_pool, vrf_id);
|
||||
find_tcp_pool, vrf_id);
|
||||
}
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "stcb:%p inp:%p\n", (void *)stcb, (void *)inp);
|
||||
if (stcb == NULL && inp) {
|
||||
@ -2740,8 +2749,13 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
||||
inp->ip_inp.inp.inp_socket = so;
|
||||
#ifdef INET6
|
||||
#if !defined(__Userspace__) && !defined(__Windows__)
|
||||
if (MODULE_GLOBAL(ip6_auto_flowlabel)) {
|
||||
inp->ip_inp.inp.inp_flags |= IN6P_AUTOFLOWLABEL;
|
||||
if (INP_SOCKAF(so) == AF_INET6) {
|
||||
if (MODULE_GLOBAL(ip6_auto_flowlabel)) {
|
||||
inp->ip_inp.inp.inp_flags |= IN6P_AUTOFLOWLABEL;
|
||||
}
|
||||
if (MODULE_GLOBAL(ip6_v6only)) {
|
||||
inp->ip_inp.inp.inp_flags |= IN6P_IPV6_V6ONLY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@ -2863,7 +2877,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
|
||||
inp->ip_inp.inp.inpcb_mtx = lck_mtx_alloc_init(SCTP_BASE_INFO(mtx_grp), SCTP_BASE_INFO(mtx_attr));
|
||||
inp->ip_inp.inp.inpcb_mtx = lck_mtx_alloc_init(SCTP_BASE_INFO(sctbinfo).mtx_grp, SCTP_BASE_INFO(sctbinfo).mtx_attr);
|
||||
if (inp->ip_inp.inp.inpcb_mtx == NULL) {
|
||||
SCTP_PRINTF("in_pcballoc: can't alloc mutex! so=%p\n", (void *)so);
|
||||
#ifdef SCTP_MVRF
|
||||
@ -2872,12 +2886,14 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
||||
SCTP_HASH_FREE(inp->sctp_tcbhash, inp->sctp_hashmark);
|
||||
so->so_pcb = NULL;
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
|
||||
SCTP_UNLOCK_EXC(SCTP_BASE_INFO(ipi_ep_mtx));
|
||||
SCTP_UNLOCK_EXC(SCTP_BASE_INFO(sctbinfo).ipi_lock);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOMEM);
|
||||
return (ENOMEM);
|
||||
}
|
||||
#elif defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
|
||||
lck_mtx_init(&inp->ip_inp.inp.inpcb_mtx, SCTP_BASE_INFO(sctbinfo).mtx_grp, SCTP_BASE_INFO(sctbinfo).mtx_attr);
|
||||
#else
|
||||
lck_mtx_init(&inp->ip_inp.inp.inpcb_mtx, SCTP_BASE_INFO(mtx_grp), SCTP_BASE_INFO(mtx_attr));
|
||||
lck_mtx_init(&inp->ip_inp.inp.inpcb_mtx, SCTP_BASE_INFO(sctbinfo).ipi_lock_grp, SCTP_BASE_INFO(sctbinfo).ipi_lock_attr);
|
||||
#endif
|
||||
#endif
|
||||
SCTP_INP_INFO_WLOCK();
|
||||
@ -2893,7 +2909,12 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
||||
/* add it to the info area */
|
||||
LIST_INSERT_HEAD(&SCTP_BASE_INFO(listhead), inp, sctp_list);
|
||||
#if defined(__APPLE__)
|
||||
LIST_INSERT_HEAD(&SCTP_BASE_INFO(inplisthead), &inp->ip_inp.inp, inp_list);
|
||||
inp->ip_inp.inp.inp_pcbinfo = &SCTP_BASE_INFO(sctbinfo);
|
||||
#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
|
||||
LIST_INSERT_HEAD(SCTP_BASE_INFO(sctbinfo).listhead, &inp->ip_inp.inp, inp_list);
|
||||
#else
|
||||
LIST_INSERT_HEAD(SCTP_BASE_INFO(sctbinfo).ipi_listhead, &inp->ip_inp.inp, inp_list);
|
||||
#endif
|
||||
#endif
|
||||
SCTP_INP_INFO_WUNLOCK();
|
||||
|
||||
@ -2927,9 +2948,6 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
||||
m->initial_rto = SCTP_BASE_SYSCTL(sctp_rto_initial_default);
|
||||
m->initial_init_rto_max = SCTP_BASE_SYSCTL(sctp_init_rto_max_default);
|
||||
m->sctp_sack_freq = SCTP_BASE_SYSCTL(sctp_sack_freq_default);
|
||||
|
||||
m->max_open_streams_intome = MAX_SCTP_STREAMS;
|
||||
|
||||
m->max_init_times = SCTP_BASE_SYSCTL(sctp_init_rtx_max_default);
|
||||
m->max_send_times = SCTP_BASE_SYSCTL(sctp_assoc_rtx_max_default);
|
||||
m->def_net_failure = SCTP_BASE_SYSCTL(sctp_path_rtx_max_default);
|
||||
@ -2941,6 +2959,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
||||
|
||||
m->sctp_default_cc_module = SCTP_BASE_SYSCTL(sctp_default_cc_module);
|
||||
m->sctp_default_ss_module = SCTP_BASE_SYSCTL(sctp_default_ss_module);
|
||||
m->max_open_streams_intome = SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default);
|
||||
/* number of streams to pre-open on a association */
|
||||
m->pre_open_stream_count = SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default);
|
||||
|
||||
@ -3139,7 +3158,9 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
/* bind a ep to a socket address */
|
||||
struct sctppcbhead *head;
|
||||
struct sctp_inpcb *inp, *inp_tmp;
|
||||
#if defined(INET) || (defined(INET6) && defined(__APPLE__)) || defined(__FreeBSD__) || defined(__APPLE__)
|
||||
struct inpcb *ip_inp;
|
||||
#endif
|
||||
int port_reuse_active = 0;
|
||||
int bindall;
|
||||
#ifdef SCTP_MVRF
|
||||
@ -3153,7 +3174,9 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
error = 0;
|
||||
bindall = 1;
|
||||
inp = (struct sctp_inpcb *)so->so_pcb;
|
||||
#if defined(INET) || (defined(INET6) && defined(__APPLE__)) || defined(__FreeBSD__) || defined(__APPLE__)
|
||||
ip_inp = (struct inpcb *)so->so_pcb;
|
||||
#endif
|
||||
#ifdef SCTP_DEBUG
|
||||
if (addr) {
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "Bind called port: %d\n",
|
||||
@ -4382,7 +4405,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
|
||||
#endif
|
||||
if (set_scope) {
|
||||
#ifdef SCTP_DONT_DO_PRIVADDR_SCOPE
|
||||
stcb->ipv4_local_scope = 1;
|
||||
stcb->asoc.scope.ipv4_local_scope = 1;
|
||||
#else
|
||||
if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
|
||||
stcb->asoc.scope.ipv4_local_scope = 1;
|
||||
@ -4588,6 +4611,7 @@ 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 (SCTP_ROUTE_HAS_VALID_IFN(&net->ro)) {
|
||||
/* Get source address */
|
||||
net->ro._s_addr = sctp_source_address_selection(stcb->sctp_ep,
|
||||
@ -4617,6 +4641,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (net->mtu == 0) {
|
||||
switch (newaddr->sa_family) {
|
||||
#ifdef INET
|
||||
@ -5056,6 +5081,7 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
|
||||
asoc->nr_mapping_array = NULL;
|
||||
}
|
||||
SCTP_DECR_ASOC_COUNT();
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
SCTP_TCB_LOCK_DESTROY(stcb);
|
||||
SCTP_TCB_SEND_LOCK_DESTROY(stcb);
|
||||
LIST_REMOVE(stcb, sctp_tcbasocidhash);
|
||||
@ -5191,23 +5217,21 @@ sctp_delete_from_timewait(uint32_t tag, uint16_t lport, uint16_t rport)
|
||||
int i;
|
||||
|
||||
chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
|
||||
if (!LIST_EMPTY(chain)) {
|
||||
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
|
||||
for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
|
||||
if ((twait_block->vtag_block[i].v_tag == tag) &&
|
||||
(twait_block->vtag_block[i].lport == lport) &&
|
||||
(twait_block->vtag_block[i].rport == rport)) {
|
||||
twait_block->vtag_block[i].tv_sec_at_expire = 0;
|
||||
twait_block->vtag_block[i].v_tag = 0;
|
||||
twait_block->vtag_block[i].lport = 0;
|
||||
twait_block->vtag_block[i].rport = 0;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
|
||||
for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
|
||||
if ((twait_block->vtag_block[i].v_tag == tag) &&
|
||||
(twait_block->vtag_block[i].lport == lport) &&
|
||||
(twait_block->vtag_block[i].rport == rport)) {
|
||||
twait_block->vtag_block[i].tv_sec_at_expire = 0;
|
||||
twait_block->vtag_block[i].v_tag = 0;
|
||||
twait_block->vtag_block[i].lport = 0;
|
||||
twait_block->vtag_block[i].rport = 0;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5221,19 +5245,17 @@ sctp_is_in_timewait(uint32_t tag, uint16_t lport, uint16_t rport)
|
||||
|
||||
SCTP_INP_INFO_WLOCK();
|
||||
chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
|
||||
if (!LIST_EMPTY(chain)) {
|
||||
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
|
||||
for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
|
||||
if ((twait_block->vtag_block[i].v_tag == tag) &&
|
||||
(twait_block->vtag_block[i].lport == lport) &&
|
||||
(twait_block->vtag_block[i].rport == rport)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
|
||||
for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
|
||||
if ((twait_block->vtag_block[i].v_tag == tag) &&
|
||||
(twait_block->vtag_block[i].lport == lport) &&
|
||||
(twait_block->vtag_block[i].rport == rport)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
SCTP_INP_INFO_WUNLOCK();
|
||||
return (found);
|
||||
@ -5255,42 +5277,40 @@ sctp_add_vtag_to_timewait(uint32_t tag, uint32_t time, uint16_t lport, uint16_t
|
||||
(void)SCTP_GETTIME_TIMEVAL(&now);
|
||||
chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
|
||||
set = 0;
|
||||
if (!LIST_EMPTY(chain)) {
|
||||
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
|
||||
/* Block(s) present, lets find space, and expire on the fly */
|
||||
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
|
||||
for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
|
||||
if ((twait_block->vtag_block[i].v_tag == 0) &&
|
||||
!set) {
|
||||
twait_block->vtag_block[i].tv_sec_at_expire =
|
||||
now.tv_sec + time;
|
||||
for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
|
||||
if ((twait_block->vtag_block[i].v_tag == 0) &&
|
||||
!set) {
|
||||
twait_block->vtag_block[i].tv_sec_at_expire =
|
||||
now.tv_sec + time;
|
||||
twait_block->vtag_block[i].v_tag = tag;
|
||||
twait_block->vtag_block[i].lport = lport;
|
||||
twait_block->vtag_block[i].rport = rport;
|
||||
set = 1;
|
||||
} else if ((twait_block->vtag_block[i].v_tag) &&
|
||||
((long)twait_block->vtag_block[i].tv_sec_at_expire < now.tv_sec)) {
|
||||
/* Audit expires this guy */
|
||||
twait_block->vtag_block[i].tv_sec_at_expire = 0;
|
||||
twait_block->vtag_block[i].v_tag = 0;
|
||||
twait_block->vtag_block[i].lport = 0;
|
||||
twait_block->vtag_block[i].rport = 0;
|
||||
if (set == 0) {
|
||||
/* Reuse it for my new tag */
|
||||
twait_block->vtag_block[i].tv_sec_at_expire = now.tv_sec + time;
|
||||
twait_block->vtag_block[i].v_tag = tag;
|
||||
twait_block->vtag_block[i].lport = lport;
|
||||
twait_block->vtag_block[i].rport = rport;
|
||||
set = 1;
|
||||
} else if ((twait_block->vtag_block[i].v_tag) &&
|
||||
((long)twait_block->vtag_block[i].tv_sec_at_expire < now.tv_sec)) {
|
||||
/* Audit expires this guy */
|
||||
twait_block->vtag_block[i].tv_sec_at_expire = 0;
|
||||
twait_block->vtag_block[i].v_tag = 0;
|
||||
twait_block->vtag_block[i].lport = 0;
|
||||
twait_block->vtag_block[i].rport = 0;
|
||||
if (set == 0) {
|
||||
/* Reuse it for my new tag */
|
||||
twait_block->vtag_block[i].tv_sec_at_expire = now.tv_sec + time;
|
||||
twait_block->vtag_block[i].v_tag = tag;
|
||||
twait_block->vtag_block[i].lport = lport;
|
||||
twait_block->vtag_block[i].rport = rport;
|
||||
set = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (set) {
|
||||
/*
|
||||
* We only do up to the block where we can
|
||||
* place our tag for audits
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (set) {
|
||||
/*
|
||||
* We only do up to the block where we can
|
||||
* place our tag for audits
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Need to add a new block to chain */
|
||||
@ -5876,6 +5896,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
/* Insert new items here :> */
|
||||
|
||||
/* Get rid of LOCK */
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
SCTP_TCB_LOCK_DESTROY(stcb);
|
||||
SCTP_TCB_SEND_LOCK_DESTROY(stcb);
|
||||
if (from_inpcbfree == SCTP_NORMAL_PROC) {
|
||||
@ -6601,6 +6622,25 @@ sctp_pcb_init()
|
||||
LIST_INIT(&SCTP_BASE_INFO(listhead));
|
||||
#if defined(__APPLE__)
|
||||
LIST_INIT(&SCTP_BASE_INFO(inplisthead));
|
||||
#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
|
||||
SCTP_BASE_INFO(sctbinfo).listhead = &SCTP_BASE_INFO(inplisthead);
|
||||
SCTP_BASE_INFO(sctbinfo).mtx_grp_attr = lck_grp_attr_alloc_init();
|
||||
lck_grp_attr_setdefault(SCTP_BASE_INFO(sctbinfo).mtx_grp_attr);
|
||||
SCTP_BASE_INFO(sctbinfo).mtx_grp = lck_grp_alloc_init("sctppcb", SCTP_BASE_INFO(sctbinfo).mtx_grp_attr);
|
||||
SCTP_BASE_INFO(sctbinfo).mtx_attr = lck_attr_alloc_init();
|
||||
lck_attr_setdefault(SCTP_BASE_INFO(sctbinfo).mtx_attr);
|
||||
#else
|
||||
SCTP_BASE_INFO(sctbinfo).ipi_listhead = &SCTP_BASE_INFO(inplisthead);
|
||||
SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr = lck_grp_attr_alloc_init();
|
||||
lck_grp_attr_setdefault(SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr);
|
||||
SCTP_BASE_INFO(sctbinfo).ipi_lock_grp = lck_grp_alloc_init("sctppcb", SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr);
|
||||
SCTP_BASE_INFO(sctbinfo).ipi_lock_attr = lck_attr_alloc_init();
|
||||
lck_attr_setdefault(SCTP_BASE_INFO(sctbinfo).ipi_lock_attr);
|
||||
#endif
|
||||
#if !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION)
|
||||
SCTP_BASE_INFO(sctbinfo).ipi_gc = sctp_gc;
|
||||
in_pcbinfo_attach(&SCTP_BASE_INFO(sctbinfo));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@ -6674,17 +6714,6 @@ sctp_pcb_init()
|
||||
|
||||
|
||||
/* Master Lock INIT for info structure */
|
||||
#if defined(__APPLE__)
|
||||
/* allocate the lock group attribute for SCTP PCB mutexes */
|
||||
SCTP_BASE_INFO(mtx_grp_attr) = lck_grp_attr_alloc_init();
|
||||
lck_grp_attr_setdefault(SCTP_BASE_INFO(mtx_grp_attr));
|
||||
/* allocate the lock group for SCTP PCB mutexes */
|
||||
SCTP_BASE_INFO(mtx_grp) = lck_grp_alloc_init("sctppcb",
|
||||
SCTP_BASE_INFO(mtx_grp_attr));
|
||||
/* allocate the lock attribute for SCTP PCB mutexes */
|
||||
SCTP_BASE_INFO(mtx_attr) = lck_attr_alloc_init();
|
||||
lck_attr_setdefault(SCTP_BASE_INFO(mtx_attr));
|
||||
#endif /* __APPLE__ */
|
||||
SCTP_INP_INFO_LOCK_INIT();
|
||||
SCTP_STATLOG_INIT_LOCK();
|
||||
|
||||
@ -6722,7 +6751,6 @@ sctp_pcb_init()
|
||||
for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
|
||||
LIST_INIT(&SCTP_BASE_INFO(vtag_timewait)[i]);
|
||||
}
|
||||
|
||||
#if defined(SCTP_PROCESS_LEVEL_LOCKS)
|
||||
#if defined(__Userspace_os_Windows)
|
||||
InitializeConditionVariable(&sctp_it_ctl.iterator_wakeup);
|
||||
@ -6777,37 +6805,9 @@ sctp_pcb_finish(void)
|
||||
struct sctp_tagblock *twait_block, *prev_twait_block;
|
||||
struct sctp_laddr *wi, *nwi;
|
||||
int i;
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
/* Free BSD the it thread never exits
|
||||
* but we do clean up. The only way
|
||||
* freebsd reaches here if we have VRF's
|
||||
* but we still add the ifdef to make it
|
||||
* compile on old versions.
|
||||
*/
|
||||
{
|
||||
struct sctp_iterator *it, *nit;
|
||||
|
||||
SCTP_IPI_ITERATOR_WQ_LOCK();
|
||||
TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) {
|
||||
if (it->vn != curvnet) {
|
||||
continue;
|
||||
}
|
||||
TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
|
||||
if (it->function_atend != NULL) {
|
||||
(*it->function_atend) (it->pointer, it->val);
|
||||
}
|
||||
SCTP_FREE(it,SCTP_M_ITER);
|
||||
}
|
||||
SCTP_IPI_ITERATOR_WQ_UNLOCK();
|
||||
SCTP_ITERATOR_LOCK();
|
||||
if ((sctp_it_ctl.cur_it) &&
|
||||
(sctp_it_ctl.cur_it->vn == curvnet)) {
|
||||
sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT;
|
||||
}
|
||||
SCTP_ITERATOR_UNLOCK();
|
||||
}
|
||||
#else
|
||||
struct sctp_iterator *it, *nit;
|
||||
|
||||
#if !defined(__FreeBSD__)
|
||||
/* Notify the iterator to exit. */
|
||||
SCTP_IPI_ITERATOR_WQ_LOCK();
|
||||
sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_MUST_EXIT;
|
||||
@ -6815,6 +6815,9 @@ sctp_pcb_finish(void)
|
||||
SCTP_IPI_ITERATOR_WQ_UNLOCK();
|
||||
#endif
|
||||
#if defined(__APPLE__)
|
||||
#if !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION)
|
||||
in_pcbinfo_detach(&SCTP_BASE_INFO(sctbinfo));
|
||||
#endif
|
||||
SCTP_IPI_ITERATOR_WQ_LOCK();
|
||||
do {
|
||||
msleep(&sctp_it_ctl.iterator_flags,
|
||||
@ -6823,8 +6826,6 @@ sctp_pcb_finish(void)
|
||||
} while ((sctp_it_ctl.iterator_flags & SCTP_ITERATOR_EXITED) == 0);
|
||||
thread_deallocate(sctp_it_ctl.thread_proc);
|
||||
SCTP_IPI_ITERATOR_WQ_UNLOCK();
|
||||
SCTP_IPI_ITERATOR_WQ_DESTROY();
|
||||
SCTP_ITERATOR_LOCK_DESTROY();
|
||||
#endif
|
||||
#if defined(__Windows__)
|
||||
if (sctp_it_ctl.iterator_thread_obj != NULL) {
|
||||
@ -6839,7 +6840,56 @@ sctp_pcb_finish(void)
|
||||
ObDereferenceObject(sctp_it_ctl.iterator_thread_obj);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__Userspace__)
|
||||
if (sctp_it_ctl.thread_proc) {
|
||||
#if defined(__Userspace_os_Windows)
|
||||
WaitForSingleObject(sctp_it_ctl.thread_proc, INFINITE);
|
||||
CloseHandle(sctp_it_ctl.thread_proc);
|
||||
sctp_it_ctl.thread_proc = NULL;
|
||||
#else
|
||||
pthread_join(sctp_it_ctl.thread_proc, NULL);
|
||||
sctp_it_ctl.thread_proc = 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if defined(SCTP_PROCESS_LEVEL_LOCKS)
|
||||
#if defined(__Userspace_os_Windows)
|
||||
DeleteConditionVariable(&sctp_it_ctl.iterator_wakeup);
|
||||
#else
|
||||
pthread_cond_destroy(&sctp_it_ctl.iterator_wakeup);
|
||||
#endif
|
||||
#endif
|
||||
/* In FreeBSD the iterator thread never exits
|
||||
* but we do clean up.
|
||||
* The only way FreeBSD reaches here is if we have VRF's
|
||||
* but we still add the ifdef to make it compile on old versions.
|
||||
*/
|
||||
SCTP_IPI_ITERATOR_WQ_LOCK();
|
||||
TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) {
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
|
||||
if (it->vn != curvnet) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
|
||||
if (it->function_atend != NULL) {
|
||||
(*it->function_atend) (it->pointer, it->val);
|
||||
}
|
||||
SCTP_FREE(it,SCTP_M_ITER);
|
||||
}
|
||||
SCTP_IPI_ITERATOR_WQ_UNLOCK();
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
|
||||
SCTP_ITERATOR_LOCK();
|
||||
if ((sctp_it_ctl.cur_it) &&
|
||||
(sctp_it_ctl.cur_it->vn == curvnet)) {
|
||||
sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT;
|
||||
}
|
||||
SCTP_ITERATOR_UNLOCK();
|
||||
#endif
|
||||
#if !defined(__FreeBSD__)
|
||||
SCTP_IPI_ITERATOR_WQ_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) {
|
||||
@ -6877,7 +6927,9 @@ sctp_pcb_finish(void)
|
||||
SCTP_HASH_FREE(SCTP_BASE_INFO(vrf_ifn_hash), SCTP_BASE_INFO(vrf_ifn_hashmark));
|
||||
#if defined(__Userspace__) && !defined(__Userspace_os_Windows)
|
||||
/* free memory allocated by getifaddrs call */
|
||||
#if defined(INET) || defined(INET6)
|
||||
freeifaddrs(g_interfaces);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* free the TIMEWAIT list elements malloc'd in the function
|
||||
@ -6909,16 +6961,20 @@ sctp_pcb_finish(void)
|
||||
SCTP_IPI_COUNT_DESTROY();
|
||||
#endif
|
||||
SCTP_STATLOG_DESTROY();
|
||||
#if !defined(__Userspace__)
|
||||
SCTP_INP_INFO_LOCK_DESTROY();
|
||||
#endif
|
||||
|
||||
SCTP_WQ_ADDR_DESTROY();
|
||||
|
||||
#if defined(__APPLE__)
|
||||
lck_grp_attr_free(SCTP_BASE_INFO(mtx_grp_attr));
|
||||
lck_grp_free(SCTP_BASE_INFO(mtx_grp));
|
||||
lck_attr_free(SCTP_BASE_INFO(mtx_attr));
|
||||
#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
|
||||
lck_grp_attr_free(SCTP_BASE_INFO(sctbinfo).mtx_grp_attr);
|
||||
lck_grp_free(SCTP_BASE_INFO(sctbinfo).mtx_grp);
|
||||
lck_attr_free(SCTP_BASE_INFO(sctbinfo).mtx_attr);
|
||||
#else
|
||||
lck_grp_attr_free(SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr);
|
||||
lck_grp_free(SCTP_BASE_INFO(sctbinfo).ipi_lock_grp);
|
||||
lck_attr_free(SCTP_BASE_INFO(sctbinfo).ipi_lock_attr);
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__Userspace__)
|
||||
SCTP_TIMERQ_LOCK_DESTROY();
|
||||
@ -7656,30 +7712,28 @@ skip_vtag_check:
|
||||
|
||||
chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
|
||||
/* Now what about timed wait ? */
|
||||
if (!LIST_EMPTY(chain)) {
|
||||
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
|
||||
/*
|
||||
* Block(s) are present, lets see if we have this tag in the
|
||||
* list
|
||||
*/
|
||||
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
|
||||
for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
|
||||
if (twait_block->vtag_block[i].v_tag == 0) {
|
||||
/* not used */
|
||||
continue;
|
||||
} else if ((long)twait_block->vtag_block[i].tv_sec_at_expire <
|
||||
now->tv_sec) {
|
||||
/* Audit expires this guy */
|
||||
twait_block->vtag_block[i].tv_sec_at_expire = 0;
|
||||
twait_block->vtag_block[i].v_tag = 0;
|
||||
twait_block->vtag_block[i].lport = 0;
|
||||
twait_block->vtag_block[i].rport = 0;
|
||||
} else if ((twait_block->vtag_block[i].v_tag == tag) &&
|
||||
(twait_block->vtag_block[i].lport == lport) &&
|
||||
(twait_block->vtag_block[i].rport == rport)) {
|
||||
/* Bad tag, sorry :< */
|
||||
SCTP_INP_INFO_RUNLOCK();
|
||||
return (0);
|
||||
}
|
||||
for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
|
||||
if (twait_block->vtag_block[i].v_tag == 0) {
|
||||
/* not used */
|
||||
continue;
|
||||
} else if ((long)twait_block->vtag_block[i].tv_sec_at_expire <
|
||||
now->tv_sec) {
|
||||
/* Audit expires this guy */
|
||||
twait_block->vtag_block[i].tv_sec_at_expire = 0;
|
||||
twait_block->vtag_block[i].v_tag = 0;
|
||||
twait_block->vtag_block[i].lport = 0;
|
||||
twait_block->vtag_block[i].rport = 0;
|
||||
} else if ((twait_block->vtag_block[i].v_tag == tag) &&
|
||||
(twait_block->vtag_block[i].lport == lport) &&
|
||||
(twait_block->vtag_block[i].rport == rport)) {
|
||||
/* Bad tag, sorry :< */
|
||||
SCTP_INP_INFO_RUNLOCK();
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 246687 2013-02-11 21:02:49Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 254248 2013-08-12 13:52:15Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_PCB_H_
|
||||
@ -189,6 +189,7 @@ struct sctp_epinfo {
|
||||
|
||||
#if defined(__APPLE__)
|
||||
struct inpcbhead inplisthead;
|
||||
struct inpcbinfo sctbinfo;
|
||||
#endif
|
||||
/* ep zone info */
|
||||
sctp_zone_t ipi_zone_ep;
|
||||
@ -223,20 +224,12 @@ struct sctp_epinfo {
|
||||
userland_mutex_t wq_addr_mtx;
|
||||
#elif defined(__APPLE__)
|
||||
#ifdef _KERN_LOCKS_H_
|
||||
lck_grp_attr_t *mtx_grp_attr;
|
||||
lck_grp_t *mtx_grp;
|
||||
lck_attr_t *mtx_attr;
|
||||
lck_rw_t *ipi_ep_mtx;
|
||||
lck_mtx_t *ipi_addr_mtx;
|
||||
lck_mtx_t *ipi_count_mtx;
|
||||
lck_mtx_t *ipi_pktlog_mtx;
|
||||
lck_mtx_t *logging_mtx;
|
||||
lck_mtx_t *wq_addr_mtx;
|
||||
#else
|
||||
void *mtx_grp_attr;
|
||||
void *mtx_grp;
|
||||
void *mtx_attr;
|
||||
void *ipi_ep_mtx;
|
||||
void *ipi_count_mtx;
|
||||
void *logging_mtx;
|
||||
#endif /* _KERN_LOCKS_H_ */
|
||||
@ -469,8 +462,8 @@ struct sctp_inpcb {
|
||||
|
||||
/* back pointer to our socket */
|
||||
struct socket *sctp_socket;
|
||||
uint64_t sctp_features; /* Feature flags */
|
||||
uint32_t sctp_flags; /* INP state flag set */
|
||||
uint32_t sctp_features; /* Feature flags */
|
||||
uint32_t sctp_mobility_features; /* Mobility Feature flags */
|
||||
struct sctp_pcb sctp_ep;/* SCTP ep data */
|
||||
/* head of the hash of all associations */
|
||||
|
@ -126,6 +126,8 @@
|
||||
|
||||
#define SCTP_INP_INFO_LOCK_INIT() \
|
||||
InitializeCriticalSection(&SCTP_BASE_INFO(ipi_ep_mtx))
|
||||
#define SCTP_INP_INFO_LOCK_DESTROY() \
|
||||
DeleteCriticalSection(&SCTP_BASE_INFO(ipi_ep_mtx))
|
||||
#define SCTP_INP_INFO_RLOCK() \
|
||||
EnterCriticalSection(&SCTP_BASE_INFO(ipi_ep_mtx))
|
||||
#define SCTP_INP_INFO_TRYLOCK() \
|
||||
@ -275,6 +277,8 @@
|
||||
|
||||
#define SCTP_INP_INFO_LOCK_INIT() \
|
||||
(void)pthread_mutex_init(&SCTP_BASE_INFO(ipi_ep_mtx), NULL)
|
||||
#define SCTP_INP_INFO_LOCK_DESTROY() \
|
||||
(void)pthread_mutex_destroy(&SCTP_BASE_INFO(ipi_ep_mtx))
|
||||
#define SCTP_INP_INFO_RLOCK() \
|
||||
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_ep_mtx))
|
||||
#define SCTP_INP_INFO_TRYLOCK() \
|
||||
|
@ -1,7 +1,8 @@
|
||||
/*-
|
||||
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
|
||||
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
|
||||
* Copyright (c) 2008-2013, by Michael Tuexen. All rights reserved.
|
||||
* Copyright (c) 2013, by Lally Singh. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@ -30,26 +31,84 @@
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_sha1.h>
|
||||
#if !defined(__Userspace_os_Windows)
|
||||
#include <sys/param.h>
|
||||
#if !defined(__Windows__)
|
||||
|
||||
#if defined(SCTP_USE_NSS_SHA1)
|
||||
/* A SHA-1 Digest is 160 bits, or 20 bytes */
|
||||
#define SHA_DIGEST_LENGTH (20)
|
||||
|
||||
void
|
||||
sctp_sha1_init(struct sctp_sha1_context *ctx)
|
||||
{
|
||||
ctx->pk11_ctx = PK11_CreateDigestContext(SEC_OID_SHA1);
|
||||
PK11_DigestBegin(ctx->pk11_ctx);
|
||||
}
|
||||
|
||||
void
|
||||
sctp_sha1_update(struct sctp_sha1_context *ctx, const unsigned char *ptr, unsigned int siz)
|
||||
{
|
||||
PK11_DigestOp(ctx->pk11_ctx, ptr, siz);
|
||||
}
|
||||
|
||||
void
|
||||
sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx)
|
||||
{
|
||||
unsigned int output_len = 0;
|
||||
|
||||
PK11_DigestFinal(ctx->pk11_ctx, digest, &output_len, SHA_DIGEST_LENGTH);
|
||||
PK11_DestroyContext(ctx->pk11_ctx, PR_TRUE);
|
||||
}
|
||||
|
||||
#elif defined(SCTP_USE_OPENSSL_SHA1)
|
||||
|
||||
void
|
||||
sctp_sha1_init(struct sctp_sha1_context *ctx)
|
||||
{
|
||||
SHA1_Init(&ctx->sha_ctx);
|
||||
}
|
||||
|
||||
void
|
||||
sctp_sha1_update(struct sctp_sha1_context *ctx, const unsigned char *ptr, unsigned int siz)
|
||||
{
|
||||
SHA1_Update(&ctx->sha_ctx, ptr, (unsigned long)siz);
|
||||
}
|
||||
|
||||
void
|
||||
sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx)
|
||||
{
|
||||
SHA1_Final(digest, &ctx->sha_ctx);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <string.h>
|
||||
#if defined(__Userspace_os_Windows)
|
||||
#include <winsock2.h>
|
||||
#elif !defined(__Windows__)
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
#if !defined(__Userspace__)
|
||||
#include <sys/systm.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#define F1(B,C,D) (((B & C) | ((~B) & D))) /* 0 <= t <= 19 */
|
||||
#define F2(B,C,D) (B ^ C ^ D) /* 20 <= t <= 39 */
|
||||
#define F3(B,C,D) ((B & C) | (B & D) | (C & D)) /* 40 <= t <= 59 */
|
||||
#define F4(B,C,D) (B ^ C ^ D) /* 600 <= t <= 79 */
|
||||
|
||||
/* circular shift */
|
||||
#define CSHIFT(A,B) ((B << A) | (B >> (32-A)))
|
||||
|
||||
#define K1 0x5a827999 /* 0 <= t <= 19 */
|
||||
#define K2 0x6ed9eba1 /* 20 <= t <= 39 */
|
||||
#define K3 0x8f1bbcdc /* 40 <= t <= 59 */
|
||||
#define K4 0xca62c1d6 /* 60 <= t <= 79 */
|
||||
|
||||
#define H0INIT 0x67452301
|
||||
#define H1INIT 0xefcdab89
|
||||
#define H2INIT 0x98badcfe
|
||||
#define H3INIT 0x10325476
|
||||
#define H4INIT 0xc3d2e1f0
|
||||
|
||||
void
|
||||
SHA1_Init(struct sha1_context *ctx)
|
||||
sctp_sha1_init(struct sctp_sha1_context *ctx)
|
||||
{
|
||||
/* Init the SHA-1 context structure */
|
||||
ctx->A = 0;
|
||||
@ -69,7 +128,7 @@ SHA1_Init(struct sha1_context *ctx)
|
||||
}
|
||||
|
||||
static void
|
||||
sha1_process_a_block(struct sha1_context *ctx, unsigned int *block)
|
||||
sctp_sha1_process_a_block(struct sctp_sha1_context *ctx, unsigned int *block)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -133,11 +192,10 @@ sha1_process_a_block(struct sha1_context *ctx, unsigned int *block)
|
||||
ctx->H4 = (ctx->H4) + (ctx->E);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SHA1_Update(struct sha1_context *ctx, const unsigned char *ptr, int siz)
|
||||
sctp_sha1_update(struct sctp_sha1_context *ctx, const unsigned char *ptr, unsigned int siz)
|
||||
{
|
||||
int number_left, left_to_fill;
|
||||
unsigned int number_left, left_to_fill;
|
||||
|
||||
number_left = siz;
|
||||
while (number_left > 0) {
|
||||
@ -154,7 +212,7 @@ SHA1_Update(struct sha1_context *ctx, const unsigned char *ptr, int siz)
|
||||
/* block is now full, process it */
|
||||
memcpy(&ctx->sha_block[ctx->how_many_in_block],
|
||||
ptr, left_to_fill);
|
||||
sha1_process_a_block(ctx,
|
||||
sctp_sha1_process_a_block(ctx,
|
||||
(unsigned int *)ctx->sha_block);
|
||||
number_left -= left_to_fill;
|
||||
ctx->running_total += left_to_fill;
|
||||
@ -165,7 +223,7 @@ SHA1_Update(struct sha1_context *ctx, const unsigned char *ptr, int siz)
|
||||
}
|
||||
|
||||
void
|
||||
SHA1_Final(unsigned char *digest, struct sha1_context *ctx)
|
||||
sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx)
|
||||
{
|
||||
/*
|
||||
* if any left in block fill with padding and process. Then transfer
|
||||
@ -191,7 +249,7 @@ SHA1_Final(unsigned char *digest, struct sha1_context *ctx)
|
||||
left_to_fill = sizeof(ctx->sha_block) - ctx->how_many_in_block;
|
||||
if (left_to_fill == 0) {
|
||||
/* Should not really happen but I am paranoid */
|
||||
sha1_process_a_block(ctx,
|
||||
sctp_sha1_process_a_block(ctx,
|
||||
(unsigned int *)ctx->sha_block);
|
||||
/* init last block, a bit different than the rest */
|
||||
ctx->sha_block[0] = '\x80';
|
||||
@ -200,7 +258,7 @@ SHA1_Final(unsigned char *digest, struct sha1_context *ctx)
|
||||
}
|
||||
} else if (left_to_fill == 1) {
|
||||
ctx->sha_block[ctx->how_many_in_block] = '\x80';
|
||||
sha1_process_a_block(ctx,
|
||||
sctp_sha1_process_a_block(ctx,
|
||||
(unsigned int *)ctx->sha_block);
|
||||
/* init last block */
|
||||
memset(ctx->sha_block, 0, sizeof(ctx->sha_block));
|
||||
@ -211,7 +269,7 @@ SHA1_Final(unsigned char *digest, struct sha1_context *ctx)
|
||||
i++) {
|
||||
ctx->sha_block[i] = 0x0;
|
||||
}
|
||||
sha1_process_a_block(ctx,
|
||||
sctp_sha1_process_a_block(ctx,
|
||||
(unsigned int *)ctx->sha_block);
|
||||
/* init last block */
|
||||
memset(ctx->sha_block, 0, sizeof(ctx->sha_block));
|
||||
@ -220,7 +278,7 @@ SHA1_Final(unsigned char *digest, struct sha1_context *ctx)
|
||||
ctx->running_total *= 8;
|
||||
ptr = (unsigned int *)&ctx->sha_block[60];
|
||||
*ptr = htonl(ctx->running_total);
|
||||
sha1_process_a_block(ctx, (unsigned int *)ctx->sha_block);
|
||||
sctp_sha1_process_a_block(ctx, (unsigned int *)ctx->sha_block);
|
||||
} else {
|
||||
/*
|
||||
* easy case, we just pad this message to size - end with 0
|
||||
@ -238,7 +296,7 @@ SHA1_Final(unsigned char *digest, struct sha1_context *ctx)
|
||||
ctx->running_total *= 8;
|
||||
ptr = (unsigned int *)&ctx->sha_block[60];
|
||||
*ptr = htonl(ctx->running_total);
|
||||
sha1_process_a_block(ctx, (unsigned int *)ctx->sha_block);
|
||||
sctp_sha1_process_a_block(ctx, (unsigned int *)ctx->sha_block);
|
||||
}
|
||||
/* transfer the digest back to the user */
|
||||
digest[3] = (ctx->H0 & 0xff);
|
||||
@ -266,3 +324,5 @@ SHA1_Final(unsigned char *digest, struct sha1_context *ctx)
|
||||
digest[17] = ((ctx->H4 >> 16) & 0xff);
|
||||
digest[16] = ((ctx->H4 >> 24) & 0xff);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -36,12 +36,31 @@ __FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __SCTP_SLA1_h__
|
||||
#define __SCTP_SLA1_h__
|
||||
#ifndef __NETINET_SCTP_SHA1_H__
|
||||
#define __NETINET_SCTP_SHA1_H__
|
||||
|
||||
#include <sys/types.h>
|
||||
#if defined(SCTP_USE_NSS_SHA1)
|
||||
#if defined(__Userspace_os_Darwin)
|
||||
/* The NSS sources require __APPLE__ to be defined.
|
||||
* XXX: Remove this ugly hack once the platform defines have been cleaned up.
|
||||
*/
|
||||
#define __APPLE__
|
||||
#endif
|
||||
#include <pk11pub.h>
|
||||
#if defined(__Userspace_os_Darwin)
|
||||
#undef __APPLE__
|
||||
#endif
|
||||
#elif defined(SCTP_USE_OPENSSL_SHA1)
|
||||
#include <openssl/sha.h>
|
||||
#endif
|
||||
|
||||
struct sha1_context {
|
||||
struct sctp_sha1_context {
|
||||
#if defined(SCTP_USE_NSS_SHA1)
|
||||
struct PK11Context *pk11_ctx;
|
||||
#elif defined(SCTP_USE_OPENSSL_SHA1)
|
||||
SHA_CTX sha_ctx;
|
||||
#else
|
||||
unsigned int A;
|
||||
unsigned int B;
|
||||
unsigned int C;
|
||||
@ -59,28 +78,8 @@ struct sha1_context {
|
||||
/* collected so far */
|
||||
int how_many_in_block;
|
||||
unsigned int running_total;
|
||||
#endif
|
||||
};
|
||||
typedef struct sha1_context SHA1_CTX;
|
||||
|
||||
#define F1(B,C,D) (((B & C) | ((~B) & D))) /* 0 <= t <= 19 */
|
||||
#define F2(B,C,D) (B ^ C ^ D) /* 20 <= t <= 39 */
|
||||
#define F3(B,C,D) ((B & C) | (B & D) | (C & D)) /* 40 <= t <= 59 */
|
||||
#define F4(B,C,D) (B ^ C ^ D) /* 600 <= t <= 79 */
|
||||
|
||||
/* circular shift */
|
||||
#define CSHIFT(A,B) ((B << A) | (B >> (32-A)))
|
||||
|
||||
#define K1 0x5a827999 /* 0 <= t <= 19 */
|
||||
#define K2 0x6ed9eba1 /* 20 <= t <= 39 */
|
||||
#define K3 0x8f1bbcdc /* 40 <= t <= 59 */
|
||||
#define K4 0xca62c1d6 /* 60 <= t <= 79 */
|
||||
|
||||
#define H0INIT 0x67452301
|
||||
#define H1INIT 0xefcdab89
|
||||
#define H2INIT 0x98badcfe
|
||||
#define H3INIT 0x10325476
|
||||
#define H4INIT 0xc3d2e1f0
|
||||
|
||||
|
||||
#if (defined(__APPLE__) && defined(KERNEL))
|
||||
#ifndef _KERNEL
|
||||
@ -90,9 +89,9 @@ typedef struct sha1_context SHA1_CTX;
|
||||
|
||||
#if defined(_KERNEL) || defined(__Userspace__)
|
||||
|
||||
void SHA1_Init(struct sha1_context *);
|
||||
void SHA1_Update(struct sha1_context *, const unsigned char *, int);
|
||||
void SHA1_Final(unsigned char *, struct sha1_context *);
|
||||
void sctp_sha1_init(struct sctp_sha1_context *);
|
||||
void sctp_sha1_update(struct sctp_sha1_context *, const unsigned char *, unsigned int);
|
||||
void sctp_sha1_final(unsigned char *, struct sctp_sha1_context *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
#endif
|
||||
#endif
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 246595 2013-02-09 17:26:14Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 255190 2013-09-03 19:31:59Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_STRUCTS_H_
|
||||
@ -236,6 +236,9 @@ struct sctp_net_route {
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__APPLE__)
|
||||
#if !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION)
|
||||
struct ifaddr *ro_srcia;
|
||||
#endif
|
||||
#if !defined(APPLE_LEOPARD)
|
||||
uint32_t ro_flags;
|
||||
#endif
|
||||
@ -493,7 +496,6 @@ struct sctp_tmit_chunk {
|
||||
uint8_t do_rtt;
|
||||
uint8_t book_size_scale;
|
||||
uint8_t no_fr_allowed;
|
||||
uint8_t pr_sctp_on;
|
||||
uint8_t copy_by_ref;
|
||||
uint8_t window_probe;
|
||||
};
|
||||
@ -568,7 +570,6 @@ struct sctp_stream_queue_pending {
|
||||
uint8_t holds_key_ref;
|
||||
uint8_t msg_is_complete;
|
||||
uint8_t some_taken;
|
||||
uint8_t pr_sctp_on;
|
||||
uint8_t sender_all_done;
|
||||
uint8_t put_last_out;
|
||||
uint8_t discard_rest;
|
||||
@ -1252,7 +1253,7 @@ struct sctp_association {
|
||||
/* JRS 5/21/07 - CMT PF variable */
|
||||
uint8_t sctp_cmt_pf;
|
||||
uint8_t use_precise_time;
|
||||
uint32_t sctp_features;
|
||||
uint64_t sctp_features;
|
||||
uint16_t port; /* remote UDP encapsulation port */
|
||||
/*
|
||||
* The mapping array is used to track out of order sequences above
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 246595 2013-02-09 17:26:14Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 254672 2013-08-22 20:29:57Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -93,6 +93,7 @@ sctp_init_sysctls()
|
||||
SCTP_BASE_SYSCTL(sctp_path_rtx_max_default) = SCTPCTL_PATH_RTX_MAX_DEFAULT;
|
||||
SCTP_BASE_SYSCTL(sctp_path_pf_threshold) = SCTPCTL_PATH_PF_THRESHOLD_DEFAULT;
|
||||
SCTP_BASE_SYSCTL(sctp_add_more_threshold) = SCTPCTL_ADD_MORE_ON_OUTPUT_DEFAULT;
|
||||
SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default) = SCTPCTL_INCOMING_STREAMS_DEFAULT;
|
||||
SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default) = SCTPCTL_OUTGOING_STREAMS_DEFAULT;
|
||||
SCTP_BASE_SYSCTL(sctp_cmt_on_off) = SCTPCTL_CMT_ON_OFF_DEFAULT;
|
||||
/* EY */
|
||||
@ -491,7 +492,11 @@ sctp_assoclist(SYSCTL_HANDLER_ARGS)
|
||||
xinpcb.last = 0;
|
||||
xinpcb.local_port = ntohs(inp->sctp_lport);
|
||||
xinpcb.flags = inp->sctp_flags;
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version < 1000048
|
||||
xinpcb.features = (uint32_t)inp->sctp_features;
|
||||
#else
|
||||
xinpcb.features = inp->sctp_features;
|
||||
#endif
|
||||
xinpcb.total_sends = inp->total_sends;
|
||||
xinpcb.total_recvs = inp->total_recvs;
|
||||
xinpcb.total_nospaces = inp->total_nospaces;
|
||||
@ -788,6 +793,7 @@ sysctl_sctp_check(SYSCTL_HANDLER_ARGS)
|
||||
RANGECHK(SCTP_BASE_SYSCTL(sctp_path_rtx_max_default), SCTPCTL_PATH_RTX_MAX_MIN, SCTPCTL_PATH_RTX_MAX_MAX);
|
||||
RANGECHK(SCTP_BASE_SYSCTL(sctp_path_pf_threshold), SCTPCTL_PATH_PF_THRESHOLD_MIN, SCTPCTL_PATH_PF_THRESHOLD_MAX);
|
||||
RANGECHK(SCTP_BASE_SYSCTL(sctp_add_more_threshold), SCTPCTL_ADD_MORE_ON_OUTPUT_MIN, SCTPCTL_ADD_MORE_ON_OUTPUT_MAX);
|
||||
RANGECHK(SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default), SCTPCTL_INCOMING_STREAMS_MIN, SCTPCTL_INCOMING_STREAMS_MAX);
|
||||
RANGECHK(SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default), SCTPCTL_OUTGOING_STREAMS_MIN, SCTPCTL_OUTGOING_STREAMS_MAX);
|
||||
RANGECHK(SCTP_BASE_SYSCTL(sctp_cmt_on_off), SCTPCTL_CMT_ON_OFF_MIN, SCTPCTL_CMT_ON_OFF_MAX);
|
||||
/* EY */
|
||||
@ -1180,6 +1186,10 @@ SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, add_more_on_output, CTLTYPE_UINT|CTLF
|
||||
&SCTP_BASE_SYSCTL(sctp_add_more_threshold), 0, sysctl_sctp_check, "IU",
|
||||
SCTPCTL_ADD_MORE_ON_OUTPUT_DESC);
|
||||
|
||||
SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, incoming_streams, CTLTYPE_UINT|CTLFLAG_RW,
|
||||
&SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default), 0, sysctl_sctp_check, "IU",
|
||||
SCTPCTL_INCOMING_STREAMS_DESC);
|
||||
|
||||
SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, outgoing_streams, CTLTYPE_UINT|CTLFLAG_RW,
|
||||
&SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default), 0, sysctl_sctp_check, "IU",
|
||||
SCTPCTL_OUTGOING_STREAMS_DESC);
|
||||
@ -1515,6 +1525,10 @@ void sysctl_setup_sctp(void)
|
||||
&SCTP_BASE_SYSCTL(sctp_add_more_threshold), 0, sysctl_sctp_check,
|
||||
SCTPCTL_ADD_MORE_ON_OUTPUT_DESC);
|
||||
|
||||
sysctl_add_oid(&sysctl_oid_top, "incoming_streams", CTLTYPE_INT|CTLFLAG_RW,
|
||||
&SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default), 0, sysctl_sctp_check,
|
||||
SCTPCTL_INCOMING_STREAMS_DESC);
|
||||
|
||||
sysctl_add_oid(&sysctl_oid_top, "outgoing_streams", CTLTYPE_INT|CTLFLAG_RW,
|
||||
&SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default), 0, sysctl_sctp_check,
|
||||
SCTPCTL_OUTGOING_STREAMS_DESC);
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.h 237565 2012-06-25 17:15:09Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.h 252779 2013-07-05 10:08:49Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_SYSCTL_H_
|
||||
@ -79,6 +79,7 @@ struct sctp_sysctl {
|
||||
uint32_t sctp_path_rtx_max_default;
|
||||
uint32_t sctp_path_pf_threshold;
|
||||
uint32_t sctp_add_more_threshold;
|
||||
uint32_t sctp_nr_incoming_streams_default;
|
||||
uint32_t sctp_nr_outgoing_streams_default;
|
||||
uint32_t sctp_cmt_on_off;
|
||||
uint32_t sctp_cmt_use_dac;
|
||||
@ -339,6 +340,12 @@ struct sctp_sysctl {
|
||||
#define SCTPCTL_ADD_MORE_ON_OUTPUT_MAX 0xFFFFFFFF
|
||||
#define SCTPCTL_ADD_MORE_ON_OUTPUT_DEFAULT SCTP_DEFAULT_ADD_MORE
|
||||
|
||||
/* incoming_streams: Default number of incoming streams */
|
||||
#define SCTPCTL_INCOMING_STREAMS_DESC "Default number of incoming streams"
|
||||
#define SCTPCTL_INCOMING_STREAMS_MIN 1
|
||||
#define SCTPCTL_INCOMING_STREAMS_MAX 65535
|
||||
#define SCTPCTL_INCOMING_STREAMS_DEFAULT SCTP_ISTREAM_INITIAL
|
||||
|
||||
/* outgoing_streams: Default number of outgoing streams */
|
||||
#define SCTPCTL_OUTGOING_STREAMS_DESC "Default number of outgoing streams"
|
||||
#define SCTPCTL_OUTGOING_STREAMS_MIN 1
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 246588 2013-02-09 08:27:08Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 257359 2013-10-29 20:04:50Z tuexen $");
|
||||
#endif
|
||||
|
||||
#define _IP_VHL
|
||||
@ -442,7 +442,7 @@ sctp_recover_sent_list(struct sctp_tcb *stcb)
|
||||
}
|
||||
}
|
||||
TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
|
||||
if (chk->pr_sctp_on) {
|
||||
if (PR_SCTP_ENABLED(chk->flags)) {
|
||||
if (asoc->pr_sctp_cnt != 0)
|
||||
asoc->pr_sctp_cnt--;
|
||||
}
|
||||
@ -551,7 +551,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
|
||||
TAILQ_FOREACH_SAFE(chk, &stcb->asoc.sent_queue, sctp_next, nchk) {
|
||||
if (SCTP_TSN_GE(stcb->asoc.last_acked_seq, chk->rec.data.TSN_seq)) {
|
||||
/* Strange case our list got out of order? */
|
||||
SCTP_PRINTF("Our list is out of order? last_acked:%x chk:%x",
|
||||
SCTP_PRINTF("Our list is out of order? last_acked:%x chk:%x\n",
|
||||
(unsigned int)stcb->asoc.last_acked_seq, (unsigned int)chk->rec.data.TSN_seq);
|
||||
recovery_cnt++;
|
||||
#ifdef INVARIANTS
|
||||
|
@ -96,8 +96,11 @@ void sctp_audit_retranmission_queue(struct sctp_association *);
|
||||
void sctp_iterator_timer(struct sctp_iterator *it);
|
||||
|
||||
#if defined(__APPLE__)
|
||||
void sctp_slowtimo();
|
||||
|
||||
#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
|
||||
void sctp_slowtimo(void);
|
||||
#else
|
||||
void sctp_gc(struct inpcbinfo *);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_uio.h 242327 2012-10-29 20:47:32Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_uio.h 255160 2013-09-02 22:48:41Z tuexen $");
|
||||
#endif
|
||||
|
||||
#ifndef _NETINET_SCTP_UIO_H_
|
||||
@ -691,10 +691,6 @@ struct sctp_hmacalgo {
|
||||
#define SCTP_AUTH_HMAC_ID_RSVD 0x0000
|
||||
#define SCTP_AUTH_HMAC_ID_SHA1 0x0001 /* default, mandatory */
|
||||
#define SCTP_AUTH_HMAC_ID_SHA256 0x0003
|
||||
#define SCTP_AUTH_HMAC_ID_SHA224 0x0004
|
||||
#define SCTP_AUTH_HMAC_ID_SHA384 0x0005
|
||||
#define SCTP_AUTH_HMAC_ID_SHA512 0x0006
|
||||
|
||||
|
||||
/* SCTP_AUTH_ACTIVE_KEY / SCTP_AUTH_DELETE_KEY */
|
||||
struct sctp_authkeyid {
|
||||
@ -1174,7 +1170,11 @@ union sctp_sockstore {
|
||||
struct xsctp_inpcb {
|
||||
uint32_t last;
|
||||
uint32_t flags;
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version < 1000048
|
||||
uint32_t features;
|
||||
#else
|
||||
uint64_t features;
|
||||
#endif
|
||||
uint32_t total_sends;
|
||||
uint32_t total_recvs;
|
||||
uint32_t total_nospaces;
|
||||
@ -1185,7 +1185,11 @@ struct xsctp_inpcb {
|
||||
#if defined(__Windows__)
|
||||
uint16_t padding;
|
||||
#endif
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version < 1000048
|
||||
uint32_t extra_padding[32]; /* future */
|
||||
#else
|
||||
uint32_t extra_padding[31]; /* future */
|
||||
#endif
|
||||
};
|
||||
|
||||
struct xsctp_tcb {
|
||||
@ -1328,7 +1332,7 @@ sctp_sorecvmsg(struct socket *so,
|
||||
#if !(defined(_KERNEL)) && !(defined(__Userspace__))
|
||||
|
||||
__BEGIN_DECLS
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version < 1000000
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version < 902000
|
||||
int sctp_peeloff __P((int, sctp_assoc_t));
|
||||
int sctp_bindx __P((int, struct sockaddr *, int, int));
|
||||
int sctp_connectx __P((int, const struct sockaddr *, int, sctp_assoc_t *));
|
||||
|
@ -97,17 +97,21 @@ getwintimeofday(struct timeval *tv)
|
||||
int
|
||||
Win_getifaddrs(struct ifaddrs** interfaces)
|
||||
{
|
||||
#if defined(INET) || defined(INET6)
|
||||
DWORD Err, AdapterAddrsSize;
|
||||
int count;
|
||||
PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt;
|
||||
struct ifaddrs *ifa;
|
||||
#endif
|
||||
#if defined(INET)
|
||||
struct sockaddr_in *addr;
|
||||
#endif
|
||||
#if defined(INET6)
|
||||
struct sockaddr_in6 *addr6;
|
||||
#endif
|
||||
#if defined(INET) || defined(INET6)
|
||||
count = 0;
|
||||
#endif
|
||||
#if defined(INET)
|
||||
AdapterAddrsSize = 0;
|
||||
if ((Err = GetAdaptersAddresses(AF_INET, 0, NULL, NULL, &AdapterAddrsSize)) != 0) {
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 246687 2013-02-11 21:02:49Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 259943 2013-12-27 13:07:00Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -76,6 +76,8 @@ void
|
||||
sctp_init(uint16_t port,
|
||||
int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
|
||||
void (*debug_printf)(const char *format, ...))
|
||||
#elif defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) &&!defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
|
||||
sctp_init(struct protosw *pp SCTP_UNUSED, struct domain *dp SCTP_UNUSED)
|
||||
#else
|
||||
sctp_init(void)
|
||||
#endif
|
||||
@ -84,16 +86,22 @@ sctp_init(void)
|
||||
u_long sb_max_adj;
|
||||
|
||||
#endif
|
||||
#if defined(__Userspace__)
|
||||
#if defined(__Userspace_os_Windows)
|
||||
#if defined(INET) || defined(INET6)
|
||||
WSADATA wsaData;
|
||||
int Ret;
|
||||
|
||||
if ((Ret = WSAStartup(MAKEWORD(2,2), &wsaData))!=0) {
|
||||
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
|
||||
SCTP_PRINTF("WSAStartup failed\n");
|
||||
exit (-1);
|
||||
}
|
||||
#endif
|
||||
InitializeConditionVariable(&accept_cond);
|
||||
InitializeCriticalSection(&accept_mtx);
|
||||
#else
|
||||
pthread_cond_init(&accept_cond, NULL);
|
||||
pthread_mutex_init(&accept_mtx, NULL);
|
||||
#endif
|
||||
#endif
|
||||
/* Initialize and modify the sysctled variables */
|
||||
sctp_init_sysctls();
|
||||
@ -171,8 +179,7 @@ sctp_init(void)
|
||||
#if defined(__APPLE__)
|
||||
SCTP_BASE_VAR(sctp_main_timer_ticks) = 0;
|
||||
sctp_start_main_timer();
|
||||
sctp_address_monitor_start();
|
||||
sctp_over_udp_start();
|
||||
timeout(sctp_delayed_startup, NULL, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -180,6 +187,7 @@ void
|
||||
sctp_finish(void)
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
untimeout(sctp_delayed_startup, NULL);
|
||||
sctp_over_udp_stop();
|
||||
sctp_address_monitor_stop();
|
||||
sctp_stop_main_timer();
|
||||
@ -199,6 +207,7 @@ sctp_finish(void)
|
||||
if (SCTP_BASE_VAR(userspace_rawsctp) != -1) {
|
||||
#if defined(__Userspace_os_Windows)
|
||||
WaitForSingleObject(SCTP_BASE_VAR(recvthreadraw), INFINITE);
|
||||
CloseHandle(SCTP_BASE_VAR(recvthreadraw));
|
||||
#else
|
||||
pthread_join(SCTP_BASE_VAR(recvthreadraw), NULL);
|
||||
#endif
|
||||
@ -206,6 +215,7 @@ sctp_finish(void)
|
||||
if (SCTP_BASE_VAR(userspace_udpsctp) != -1) {
|
||||
#if defined(__Userspace_os_Windows)
|
||||
WaitForSingleObject(SCTP_BASE_VAR(recvthreadudp), INFINITE);
|
||||
CloseHandle(SCTP_BASE_VAR(recvthreadudp));
|
||||
#else
|
||||
pthread_join(SCTP_BASE_VAR(recvthreadudp), NULL);
|
||||
#endif
|
||||
@ -215,6 +225,7 @@ sctp_finish(void)
|
||||
if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) {
|
||||
#if defined(__Userspace_os_Windows)
|
||||
WaitForSingleObject(SCTP_BASE_VAR(recvthreadraw6), INFINITE);
|
||||
CloseHandle(SCTP_BASE_VAR(recvthreadraw6));
|
||||
#else
|
||||
pthread_join(SCTP_BASE_VAR(recvthreadraw6), NULL);
|
||||
#endif
|
||||
@ -222,6 +233,7 @@ sctp_finish(void)
|
||||
if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) {
|
||||
#if defined(__Userspace_os_Windows)
|
||||
WaitForSingleObject(SCTP_BASE_VAR(recvthreadudp6), INFINITE);
|
||||
CloseHandle(SCTP_BASE_VAR(recvthreadudp6));
|
||||
#else
|
||||
pthread_join(SCTP_BASE_VAR(recvthreadudp6), NULL);
|
||||
#endif
|
||||
@ -230,13 +242,26 @@ sctp_finish(void)
|
||||
SCTP_BASE_VAR(timer_thread_should_exit) = 1;
|
||||
#if defined(__Userspace_os_Windows)
|
||||
WaitForSingleObject(SCTP_BASE_VAR(timer_thread), INFINITE);
|
||||
CloseHandle(SCTP_BASE_VAR(timer_thread));
|
||||
#else
|
||||
pthread_join(SCTP_BASE_VAR(timer_thread), NULL);
|
||||
#endif
|
||||
#endif
|
||||
sctp_pcb_finish();
|
||||
#if defined(__Userspace__)
|
||||
#if defined(__Userspace_os_Windows)
|
||||
DeleteConditionVariable(&accept_cond);
|
||||
DeleteCriticalSection(&accept_mtx);
|
||||
#else
|
||||
pthread_cond_destroy(&accept_cond);
|
||||
pthread_mutex_destroy(&accept_mtx);
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__Windows__)
|
||||
sctp_finish_sysctls();
|
||||
#if defined(INET) || defined(INET6)
|
||||
WSACleanup();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -412,8 +437,10 @@ sctp_notify(struct sctp_inpcb *inp,
|
||||
(icmph->icmp_code == ICMP_UNREACH_ISOLATED) ||
|
||||
(icmph->icmp_code == ICMP_UNREACH_NET_PROHIB) ||
|
||||
(icmph->icmp_code == ICMP_UNREACH_HOST_PROHIB) ||
|
||||
#ifdef __Panda__
|
||||
#if defined(__Panda__)
|
||||
(icmph->icmp_code == ICMP_UNREACH_ADMIN)) {
|
||||
#elif defined(__Userspace_os_NetBSD)
|
||||
(icmph->icmp_code == ICMP_UNREACH_ADMIN_PROHIBIT)) {
|
||||
#else
|
||||
(icmph->icmp_code == ICMP_UNREACH_FILTER_PROHIB)) {
|
||||
#endif
|
||||
@ -1162,11 +1189,11 @@ sctp_disconnect(struct socket *so)
|
||||
}
|
||||
#if defined(__Userspace__)
|
||||
if (((so->so_options & SCTP_SO_LINGER) &&
|
||||
(so->so_linger == 0)) ||
|
||||
(so->so_linger == 0)) ||
|
||||
(so->so_rcv.sb_cc > 0)) {
|
||||
#else
|
||||
if (((so->so_options & SO_LINGER) &&
|
||||
(so->so_linger == 0)) ||
|
||||
(so->so_linger == 0)) ||
|
||||
(so->so_rcv.sb_cc > 0)) {
|
||||
#endif
|
||||
if (SCTP_GET_STATE(asoc) !=
|
||||
@ -1558,9 +1585,14 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
|
||||
{
|
||||
struct sctp_ifn *sctp_ifn;
|
||||
struct sctp_ifa *sctp_ifa;
|
||||
int loopback_scope, ipv4_local_scope, local_scope, site_scope;
|
||||
size_t actual;
|
||||
int ipv4_addr_legal, ipv6_addr_legal;
|
||||
int loopback_scope;
|
||||
#if defined(INET)
|
||||
int ipv4_local_scope, ipv4_addr_legal;
|
||||
#endif
|
||||
#if defined(INET6)
|
||||
int local_scope, site_scope, ipv6_addr_legal;
|
||||
#endif
|
||||
#if defined(__Userspace__)
|
||||
int conn_addr_legal;
|
||||
#endif
|
||||
@ -1573,42 +1605,62 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
|
||||
if (stcb) {
|
||||
/* Turn on all the appropriate scope */
|
||||
loopback_scope = stcb->asoc.scope.loopback_scope;
|
||||
#if defined(INET)
|
||||
ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
|
||||
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
|
||||
#endif
|
||||
#if defined(INET6)
|
||||
local_scope = stcb->asoc.scope.local_scope;
|
||||
site_scope = stcb->asoc.scope.site_scope;
|
||||
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
|
||||
ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
|
||||
#endif
|
||||
#if defined(__Userspace__)
|
||||
conn_addr_legal = stcb->asoc.scope.conn_addr_legal;
|
||||
#endif
|
||||
} else {
|
||||
/* Use generic values for endpoints. */
|
||||
loopback_scope = 1;
|
||||
#if defined(INET)
|
||||
ipv4_local_scope = 1;
|
||||
#endif
|
||||
#if defined(INET6)
|
||||
local_scope = 1;
|
||||
site_scope = 1;
|
||||
#endif
|
||||
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
|
||||
#if defined(INET6)
|
||||
ipv6_addr_legal = 1;
|
||||
#endif
|
||||
#if defined(INET)
|
||||
if (SCTP_IPV6_V6ONLY(inp)) {
|
||||
ipv4_addr_legal = 0;
|
||||
} else {
|
||||
ipv4_addr_legal = 1;
|
||||
}
|
||||
#endif
|
||||
#if defined(__Userspace__)
|
||||
conn_addr_legal = 0;
|
||||
#endif
|
||||
} else {
|
||||
#if defined(INET6)
|
||||
ipv6_addr_legal = 0;
|
||||
#endif
|
||||
#if defined(__Userspace__)
|
||||
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) {
|
||||
conn_addr_legal = 1;
|
||||
#if defined(INET)
|
||||
ipv4_addr_legal = 0;
|
||||
#endif
|
||||
} else {
|
||||
conn_addr_legal = 0;
|
||||
#if defined(INET)
|
||||
ipv4_addr_legal = 1;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
#if defined(INET)
|
||||
ipv4_addr_legal = 1;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -3391,7 +3443,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
||||
|
||||
if (stcb) {
|
||||
/* simply copy out the sockaddr_storage... */
|
||||
int len;
|
||||
size_t len;
|
||||
|
||||
len = *optsize;
|
||||
#ifdef HAVE_SA_LEN
|
||||
@ -3954,7 +4006,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
||||
}
|
||||
}
|
||||
if (error == 0) {
|
||||
*optsize = sizeof(struct sctp_paddrparams);
|
||||
*optsize = sizeof(struct sctp_udpencaps);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -4726,7 +4778,6 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
||||
sctp_hmaclist_t *hmaclist;
|
||||
uint16_t hmacid;
|
||||
uint32_t i;
|
||||
size_t found;
|
||||
|
||||
SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, optsize);
|
||||
if (optsize < sizeof(struct sctp_hmacalgo) + shmac->shmac_number_of_idents * sizeof(uint16_t)) {
|
||||
@ -4751,14 +4802,14 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
||||
goto sctp_set_hmac_done;
|
||||
}
|
||||
}
|
||||
found = 0;
|
||||
for (i = 0; i < hmaclist->num_algo; i++) {
|
||||
if (hmaclist->hmac[i] == SCTP_AUTH_HMAC_ID_SHA1) {
|
||||
/* already in list */
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (i == hmaclist->num_algo) {
|
||||
/* not found in list */
|
||||
sctp_free_hmaclist(hmaclist);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
||||
error = EINVAL;
|
||||
@ -5592,11 +5643,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
||||
SCTP_FROM_SCTP_USRREQ+SCTP_LOC_10);
|
||||
}
|
||||
net->dest_state |= SCTP_ADDR_NO_PMTUD;
|
||||
if (paddrp->spp_pathmtu > SCTP_DEFAULT_MINSEGMENT) {
|
||||
net->mtu = paddrp->spp_pathmtu + ovh;
|
||||
if (net->mtu < stcb->asoc.smallest_mtu) {
|
||||
sctp_pathmtu_adjustment(stcb, net->mtu);
|
||||
}
|
||||
net->mtu = paddrp->spp_pathmtu + ovh;
|
||||
if (net->mtu < stcb->asoc.smallest_mtu) {
|
||||
sctp_pathmtu_adjustment(stcb, net->mtu);
|
||||
}
|
||||
}
|
||||
if (paddrp->spp_flags & SPP_PMTUD_ENABLE) {
|
||||
@ -5717,11 +5766,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
||||
SCTP_FROM_SCTP_USRREQ+SCTP_LOC_10);
|
||||
}
|
||||
net->dest_state |= SCTP_ADDR_NO_PMTUD;
|
||||
if (paddrp->spp_pathmtu > SCTP_DEFAULT_MINSEGMENT) {
|
||||
net->mtu = paddrp->spp_pathmtu + ovh;
|
||||
if (net->mtu < stcb->asoc.smallest_mtu) {
|
||||
sctp_pathmtu_adjustment(stcb, net->mtu);
|
||||
}
|
||||
net->mtu = paddrp->spp_pathmtu + ovh;
|
||||
if (net->mtu < stcb->asoc.smallest_mtu) {
|
||||
sctp_pathmtu_adjustment(stcb, net->mtu);
|
||||
}
|
||||
}
|
||||
sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD);
|
||||
@ -7754,7 +7801,7 @@ sctp_peeraddr(struct socket *so, struct mbuf *nam)
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__)
|
||||
struct pr_usrreqs sctp_usrreqs = {
|
||||
#if __FreeBSD_version >= 600000
|
||||
#if defined(__FreeBSD__)
|
||||
.pru_abort = sctp_abort,
|
||||
.pru_accept = sctp_accept,
|
||||
.pru_attach = sctp_attach,
|
||||
@ -7778,45 +7825,51 @@ struct pr_usrreqs sctp_usrreqs = {
|
||||
.pru_sockaddr = sctp_ingetaddr,
|
||||
.pru_sosend = sctp_sosend,
|
||||
.pru_soreceive = sctp_soreceive
|
||||
#else
|
||||
#elif defined(__APPLE__)
|
||||
.pru_abort = sctp_abort,
|
||||
.pru_accept = sctp_accept,
|
||||
.pru_attach = sctp_attach,
|
||||
.pru_bind = sctp_bind,
|
||||
.pru_connect = sctp_connect,
|
||||
.pru_connect2 = pru_connect2_notsupp,
|
||||
.pru_control = in_control,
|
||||
.pru_detach = sctp_detach,
|
||||
.pru_disconnect = sctp_disconnect,
|
||||
.pru_listen = sctp_listen,
|
||||
.pru_peeraddr = sctp_peeraddr,
|
||||
.pru_rcvd = NULL,
|
||||
.pru_rcvoob = pru_rcvoob_notsupp,
|
||||
.pru_send = sctp_sendm,
|
||||
.pru_sense = pru_sense_null,
|
||||
.pru_shutdown = sctp_shutdown,
|
||||
.pru_sockaddr = sctp_ingetaddr,
|
||||
.pru_sosend = sctp_sosend,
|
||||
.pru_soreceive = sctp_soreceive,
|
||||
.pru_sopoll = sopoll
|
||||
#elif defined(__Windows__)
|
||||
sctp_abort,
|
||||
sctp_accept,
|
||||
sctp_attach,
|
||||
sctp_bind,
|
||||
sctp_connect,
|
||||
pru_connect2_notsupp,
|
||||
#if defined(__Windows__)
|
||||
NULL,
|
||||
NULL,
|
||||
#else
|
||||
in_control,
|
||||
sctp_detach,
|
||||
#endif
|
||||
sctp_disconnect,
|
||||
sctp_listen,
|
||||
sctp_peeraddr,
|
||||
NULL,
|
||||
pru_rcvoob_notsupp,
|
||||
#if defined(__Windows__)
|
||||
NULL,
|
||||
#else
|
||||
sctp_sendm,
|
||||
#endif
|
||||
pru_sense_null,
|
||||
sctp_shutdown,
|
||||
#if defined(__Windows__)
|
||||
sctp_flush,
|
||||
#endif
|
||||
sctp_ingetaddr,
|
||||
sctp_sosend,
|
||||
sctp_soreceive,
|
||||
#if defined(__Windows__)
|
||||
sopoll_generic,
|
||||
NULL,
|
||||
sctp_close
|
||||
#else
|
||||
sopoll
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
#elif !defined(__Panda__) && !defined(__Userspace__)
|
||||
|
@ -399,7 +399,7 @@ int sctp_detach(struct socket *so);
|
||||
#endif
|
||||
int sctp_disconnect(struct socket *so);
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__)
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version < 1000000
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version < 902000
|
||||
void sctp_ctlinput __P((int, struct sockaddr *, void *));
|
||||
int sctp_ctloutput __P((struct socket *, struct sockopt *));
|
||||
#ifdef INET
|
||||
@ -427,7 +427,7 @@ void sctp_input(struct mbuf *,...);
|
||||
void *sctp_ctlinput(int, struct sockaddr *, void *);
|
||||
int sctp_ctloutput(int, struct socket *, int, int, struct mbuf **);
|
||||
#endif
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version < 1000000
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version < 902000
|
||||
void sctp_drain __P((void));
|
||||
#else
|
||||
void sctp_drain(void);
|
||||
@ -436,18 +436,18 @@ void sctp_drain(void);
|
||||
void sctp_init(uint16_t,
|
||||
int (*)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
|
||||
void (*)(const char *, ...));
|
||||
#else
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version < 1000000
|
||||
#elif defined(__FreeBSD__) && __FreeBSD_version < 902000
|
||||
void sctp_init __P((void));
|
||||
#elif defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) &&!defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
|
||||
void sctp_init(struct protosw *pp, struct domain *dp);
|
||||
#else
|
||||
void sctp_init(void);
|
||||
#endif
|
||||
#endif
|
||||
void sctp_finish(void);
|
||||
#if defined(__FreeBSD__) || defined(__Windows__) || defined(__Userspace__)
|
||||
int sctp_flush(struct socket *, int);
|
||||
#endif
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version < 1000000
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version < 902000
|
||||
int sctp_shutdown __P((struct socket *));
|
||||
void sctp_notify __P((struct sctp_inpcb *, struct ip *ip, struct sctphdr *,
|
||||
struct sockaddr *, struct sctp_tcb *,
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 247412 2013-02-27 19:51:47Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 259943 2013-12-27 13:07:00Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -2721,7 +2721,7 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
|
||||
if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT)) {
|
||||
notif_len = sizeof(struct sctp_assoc_change);
|
||||
if (abort != NULL) {
|
||||
abort_len = htons(abort->ch.chunk_length);
|
||||
abort_len = ntohs(abort->ch.chunk_length);
|
||||
} else {
|
||||
abort_len = 0;
|
||||
}
|
||||
@ -2756,7 +2756,7 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
|
||||
if (stcb->asoc.peer_supports_prsctp) {
|
||||
sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_PR;
|
||||
}
|
||||
if (stcb->asoc.peer_supports_auth) {
|
||||
if (stcb->asoc.peer_supports_auth) {
|
||||
sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_AUTH;
|
||||
}
|
||||
if (stcb->asoc.peer_supports_asconf) {
|
||||
@ -2774,17 +2774,17 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
|
||||
}
|
||||
SCTP_BUF_LEN(m_notify) = sac->sac_length;
|
||||
control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
|
||||
0, 0, stcb->asoc.context, 0, 0, 0,
|
||||
m_notify);
|
||||
0, 0, stcb->asoc.context, 0, 0, 0,
|
||||
m_notify);
|
||||
if (control != NULL) {
|
||||
control->length = SCTP_BUF_LEN(m_notify);
|
||||
/* not that we need this */
|
||||
control->tail_mbuf = m_notify;
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
sctp_add_to_readq(stcb->sctp_ep, stcb,
|
||||
control,
|
||||
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD,
|
||||
so_locked);
|
||||
control,
|
||||
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD,
|
||||
so_locked);
|
||||
} else {
|
||||
sctp_m_freem(m_notify);
|
||||
}
|
||||
@ -2807,8 +2807,14 @@ set_error:
|
||||
stcb->sctp_socket->so_error = ECONNRESET;
|
||||
}
|
||||
} else {
|
||||
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNABORTED);
|
||||
stcb->sctp_socket->so_error = ECONNABORTED;
|
||||
if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) ||
|
||||
(SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED)) {
|
||||
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ETIMEDOUT);
|
||||
stcb->sctp_socket->so_error = ETIMEDOUT;
|
||||
} else {
|
||||
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNABORTED);
|
||||
stcb->sctp_socket->so_error = ECONNABORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Wake ANY sleepers */
|
||||
@ -2929,10 +2935,10 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
|
||||
/* not that we need this */
|
||||
control->tail_mbuf = m_notify;
|
||||
sctp_add_to_readq(stcb->sctp_ep, stcb,
|
||||
control,
|
||||
&stcb->sctp_socket->so_rcv, 1,
|
||||
SCTP_READ_LOCK_NOT_HELD,
|
||||
SCTP_SO_NOT_LOCKED);
|
||||
control,
|
||||
&stcb->sctp_socket->so_rcv, 1,
|
||||
SCTP_READ_LOCK_NOT_HELD,
|
||||
SCTP_SO_NOT_LOCKED);
|
||||
}
|
||||
|
||||
|
||||
@ -3611,7 +3617,7 @@ sctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error, struct sctp_erro
|
||||
return;
|
||||
}
|
||||
if (chunk != NULL) {
|
||||
chunk_len = htons(chunk->ch.chunk_length);
|
||||
chunk_len = ntohs(chunk->ch.chunk_length);
|
||||
} else {
|
||||
chunk_len = 0;
|
||||
}
|
||||
@ -3684,8 +3690,8 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
|
||||
sctp_unlock_assert(SCTP_INP_SO(stcb->sctp_ep));
|
||||
}
|
||||
#endif
|
||||
if (stcb && ((stcb->asoc.state & SCTP_STATE_COOKIE_WAIT) ||
|
||||
(stcb->asoc.state & SCTP_STATE_COOKIE_ECHOED))) {
|
||||
if ((stcb->asoc.state & SCTP_STATE_COOKIE_WAIT) ||
|
||||
(stcb->asoc.state & SCTP_STATE_COOKIE_ECHOED)) {
|
||||
if ((notification == SCTP_NOTIFY_INTERFACE_DOWN) ||
|
||||
(notification == SCTP_NOTIFY_INTERFACE_UP) ||
|
||||
(notification == SCTP_NOTIFY_INTERFACE_CONFIRMED)) {
|
||||
@ -3704,7 +3710,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
|
||||
}
|
||||
if (stcb->asoc.peer_supports_auth == 0) {
|
||||
sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0,
|
||||
NULL, so_locked);
|
||||
NULL, so_locked);
|
||||
}
|
||||
break;
|
||||
case SCTP_NOTIFY_ASSOC_DOWN:
|
||||
@ -3755,7 +3761,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
|
||||
}
|
||||
case SCTP_NOTIFY_SPECIAL_SP_FAIL:
|
||||
sctp_notify_send_failed2(stcb, error,
|
||||
(struct sctp_stream_queue_pending *)data, so_locked);
|
||||
(struct sctp_stream_queue_pending *)data, so_locked);
|
||||
break;
|
||||
case SCTP_NOTIFY_SENT_DG_FAIL:
|
||||
sctp_notify_send_failed(stcb, 1, error,
|
||||
@ -3763,7 +3769,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
|
||||
break;
|
||||
case SCTP_NOTIFY_UNSENT_DG_FAIL:
|
||||
sctp_notify_send_failed(stcb, 0, error,
|
||||
(struct sctp_tmit_chunk *)data, so_locked);
|
||||
(struct sctp_tmit_chunk *)data, so_locked);
|
||||
break;
|
||||
case SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION:
|
||||
{
|
||||
@ -3774,16 +3780,16 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
|
||||
break;
|
||||
}
|
||||
case SCTP_NOTIFY_ASSOC_LOC_ABORTED:
|
||||
if ((stcb) && (((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_WAIT) ||
|
||||
((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_ECHOED))) {
|
||||
if (((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_WAIT) ||
|
||||
((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_ECHOED)) {
|
||||
sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, 0, so_locked);
|
||||
} else {
|
||||
sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, 0, so_locked);
|
||||
}
|
||||
break;
|
||||
case SCTP_NOTIFY_ASSOC_REM_ABORTED:
|
||||
if ((stcb) && (((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_WAIT) ||
|
||||
((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_ECHOED))) {
|
||||
if (((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_WAIT) ||
|
||||
((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_ECHOED)) {
|
||||
sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, 1, so_locked);
|
||||
} else {
|
||||
sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, 1, so_locked);
|
||||
@ -3793,7 +3799,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
|
||||
sctp_notify_assoc_change(SCTP_RESTART, stcb, error, NULL, 0, so_locked);
|
||||
if (stcb->asoc.peer_supports_auth == 0) {
|
||||
sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0,
|
||||
NULL, so_locked);
|
||||
NULL, so_locked);
|
||||
}
|
||||
break;
|
||||
case SCTP_NOTIFY_STR_RESET_SEND:
|
||||
@ -3804,7 +3810,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
|
||||
break;
|
||||
case SCTP_NOTIFY_STR_RESET_FAILED_OUT:
|
||||
sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
|
||||
(SCTP_STREAM_RESET_OUTGOING_SSN|SCTP_STREAM_RESET_FAILED));
|
||||
(SCTP_STREAM_RESET_OUTGOING_SSN|SCTP_STREAM_RESET_FAILED));
|
||||
break;
|
||||
case SCTP_NOTIFY_STR_RESET_DENIED_OUT:
|
||||
sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
|
||||
@ -3812,7 +3818,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
|
||||
break;
|
||||
case SCTP_NOTIFY_STR_RESET_FAILED_IN:
|
||||
sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
|
||||
(SCTP_STREAM_RESET_INCOMING|SCTP_STREAM_RESET_FAILED));
|
||||
(SCTP_STREAM_RESET_INCOMING|SCTP_STREAM_RESET_FAILED));
|
||||
break;
|
||||
case SCTP_NOTIFY_STR_RESET_DENIED_IN:
|
||||
sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
|
||||
@ -3824,29 +3830,29 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
|
||||
break;
|
||||
case SCTP_NOTIFY_ASCONF_DELETE_IP:
|
||||
sctp_notify_peer_addr_change(stcb, SCTP_ADDR_REMOVED, data,
|
||||
error);
|
||||
error);
|
||||
break;
|
||||
case SCTP_NOTIFY_ASCONF_SET_PRIMARY:
|
||||
sctp_notify_peer_addr_change(stcb, SCTP_ADDR_MADE_PRIM, data,
|
||||
error);
|
||||
error);
|
||||
break;
|
||||
case SCTP_NOTIFY_PEER_SHUTDOWN:
|
||||
sctp_notify_shutdown_event(stcb);
|
||||
break;
|
||||
case SCTP_NOTIFY_AUTH_NEW_KEY:
|
||||
sctp_notify_authentication(stcb, SCTP_AUTH_NEW_KEY, error,
|
||||
(uint16_t)(uintptr_t)data,
|
||||
so_locked);
|
||||
(uint16_t)(uintptr_t)data,
|
||||
so_locked);
|
||||
break;
|
||||
case SCTP_NOTIFY_AUTH_FREE_KEY:
|
||||
sctp_notify_authentication(stcb, SCTP_AUTH_FREE_KEY, error,
|
||||
(uint16_t)(uintptr_t)data,
|
||||
so_locked);
|
||||
(uint16_t)(uintptr_t)data,
|
||||
so_locked);
|
||||
break;
|
||||
case SCTP_NOTIFY_NO_PEER_AUTH:
|
||||
sctp_notify_authentication(stcb, SCTP_AUTH_NO_AUTH, error,
|
||||
(uint16_t)(uintptr_t)data,
|
||||
so_locked);
|
||||
(uint16_t)(uintptr_t)data,
|
||||
so_locked);
|
||||
break;
|
||||
case SCTP_NOTIFY_SENDER_DRY:
|
||||
sctp_notify_sender_dry_event(stcb, so_locked);
|
||||
@ -4155,7 +4161,7 @@ sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
if (stcb == NULL) {
|
||||
/* Got to have a TCB */
|
||||
if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
|
||||
if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
|
||||
if (LIST_EMPTY(&inp->sctp_asoc_list)) {
|
||||
#if defined(__APPLE__)
|
||||
if (!so_locked) {
|
||||
SCTP_SOCKET_LOCK(so, 1);
|
||||
@ -4222,7 +4228,7 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset,
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_outoftheblue);
|
||||
/* Generate a TO address for future reference */
|
||||
if (inp && (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
|
||||
if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
|
||||
if (LIST_EMPTY(&inp->sctp_asoc_list)) {
|
||||
#if defined(__APPLE__)
|
||||
SCTP_SOCKET_LOCK(SCTP_INP_SO(inp), 1);
|
||||
#endif
|
||||
@ -4737,7 +4743,7 @@ sctp_add_to_readq(struct sctp_inpcb *inp,
|
||||
char *buffer;
|
||||
struct sctp_rcvinfo rcv;
|
||||
union sctp_sockstore addr;
|
||||
int flags = 0;
|
||||
int flags;
|
||||
|
||||
if ((buffer = malloc(control->length)) == NULL) {
|
||||
return;
|
||||
@ -4770,24 +4776,22 @@ sctp_add_to_readq(struct sctp_inpcb *inp,
|
||||
addr.sin6 = control->whoFrom->ro._l_addr.sin6;
|
||||
break;
|
||||
#endif
|
||||
#if defined(__Userspace__)
|
||||
case AF_CONN:
|
||||
addr.sconn = control->whoFrom->ro._l_addr.sconn;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
addr.sa = control->whoFrom->ro._l_addr.sa;
|
||||
break;
|
||||
}
|
||||
flags = MSG_EOR;
|
||||
if (control->spec_flags & M_NOTIFICATION) {
|
||||
flags |= MSG_NOTIFICATION;
|
||||
}
|
||||
if (control->spec_flags & M_EOR) {
|
||||
flags |= MSG_EOR;
|
||||
}
|
||||
inp->recv_callback(so, addr, buffer, control->length, rcv, flags, inp->ulp_info);
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
atomic_subtract_int(&stcb->asoc.refcnt, 1);
|
||||
sctp_free_remote_addr(control->whoFrom);
|
||||
control->whoFrom = NULL;
|
||||
sctp_m_freem(control->data);
|
||||
control->data = NULL;
|
||||
control->length = 0;
|
||||
@ -4950,24 +4954,32 @@ sctp_append_to_readq(struct sctp_inpcb *inp,
|
||||
* is populated in the outbound sinfo structure from the true cumack
|
||||
* if the association exists...
|
||||
*/
|
||||
control->sinfo_tsn = control->sinfo_cumtsn = ctls_cumack;
|
||||
#if defined(__Userspace__)
|
||||
if (inp->recv_callback) {
|
||||
if (control->end_added == 1) {
|
||||
uint32_t pd_point, length;
|
||||
|
||||
length = control->length;
|
||||
if (stcb != NULL && stcb->sctp_socket != NULL) {
|
||||
pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT,
|
||||
stcb->sctp_ep->partial_delivery_point);
|
||||
} else {
|
||||
pd_point = inp->partial_delivery_point;
|
||||
}
|
||||
if ((control->end_added == 1) || (length >= pd_point)) {
|
||||
struct socket *so;
|
||||
char *buffer;
|
||||
struct sctp_rcvinfo rcv;
|
||||
union sctp_sockstore addr;
|
||||
int flags = 0;
|
||||
int flags;
|
||||
|
||||
if ((buffer = malloc(control->length)) == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
so = inp->sctp_socket;
|
||||
so = stcb->sctp_socket;
|
||||
for (m = control->data; m; m = SCTP_BUF_NEXT(m)) {
|
||||
sctp_sbfree(control, control->stcb, &so->so_rcv, m);
|
||||
}
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
m_copydata(control->data, 0, control->length, buffer);
|
||||
memset(&rcv, 0, sizeof(struct sctp_rcvinfo));
|
||||
rcv.rcv_sid = control->sinfo_stream;
|
||||
@ -4990,35 +5002,42 @@ sctp_append_to_readq(struct sctp_inpcb *inp,
|
||||
addr.sin6 = control->whoFrom->ro._l_addr.sin6;
|
||||
break;
|
||||
#endif
|
||||
#if defined(__Userspace__)
|
||||
case AF_CONN:
|
||||
addr.sconn = control->whoFrom->ro._l_addr.sconn;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
addr.sa = control->whoFrom->ro._l_addr.sa;
|
||||
break;
|
||||
}
|
||||
flags = 0;
|
||||
if (control->end_added == 1) {
|
||||
flags |= MSG_EOR;
|
||||
}
|
||||
if (control->spec_flags & M_NOTIFICATION) {
|
||||
flags |= MSG_NOTIFICATION;
|
||||
}
|
||||
if (control->spec_flags & M_EOR) {
|
||||
flags |= MSG_EOR;
|
||||
}
|
||||
inp->recv_callback(so, addr, buffer, control->length, rcv, flags, inp->ulp_info);
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
atomic_subtract_int(&stcb->asoc.refcnt, 1);
|
||||
sctp_m_freem(control->data);
|
||||
control->data = NULL;
|
||||
control->tail_mbuf = NULL;
|
||||
control->length = 0;
|
||||
sctp_free_a_readq(stcb, control);
|
||||
if (control->end_added) {
|
||||
sctp_free_remote_addr(control->whoFrom);
|
||||
control->whoFrom = NULL;
|
||||
sctp_free_a_readq(stcb, control);
|
||||
} else {
|
||||
control->some_taken = 1;
|
||||
}
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
inp->recv_callback(so, addr, buffer, length, rcv, flags, inp->ulp_info);
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
atomic_subtract_int(&stcb->asoc.refcnt, 1);
|
||||
}
|
||||
if (inp)
|
||||
SCTP_INP_READ_UNLOCK(inp);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
control->sinfo_tsn = control->sinfo_cumtsn = ctls_cumack;
|
||||
if (inp) {
|
||||
SCTP_INP_READ_UNLOCK(inp);
|
||||
}
|
||||
@ -5272,7 +5291,6 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
|
||||
chk->rec.data.TSN_seq = stcb->asoc.sending_seq++;
|
||||
#endif
|
||||
stcb->asoc.pr_sctp_cnt++;
|
||||
chk->pr_sctp_on = 1;
|
||||
TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, chk, sctp_next);
|
||||
stcb->asoc.sent_queue_cnt++;
|
||||
stcb->asoc.pr_sctp_cnt++;
|
||||
@ -5431,10 +5449,10 @@ sctp_get_ifa_hash_val(struct sockaddr *addr)
|
||||
case AF_CONN:
|
||||
{
|
||||
struct sockaddr_conn *sconn;
|
||||
uint64_t temp;
|
||||
uintptr_t temp;
|
||||
|
||||
sconn = (struct sockaddr_conn *)addr;
|
||||
temp = (uint64_t)sconn->sconn_addr;
|
||||
temp = (uintptr_t)sconn->sconn_addr;
|
||||
return ((uint32_t)(temp ^ (temp >> 16)));
|
||||
}
|
||||
#endif
|
||||
@ -5704,7 +5722,7 @@ sctp_sorecvmsg(struct socket *so,
|
||||
if (rwnd_req < SCTP_MIN_RWND)
|
||||
rwnd_req = SCTP_MIN_RWND;
|
||||
in_eeor_mode = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR);
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) &SCTP_RECV_RWND_LOGGING_ENABLE) {
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RECV_RWND_LOGGING_ENABLE) {
|
||||
#if defined(__APPLE__)
|
||||
#if defined(APPLE_LEOPARD)
|
||||
sctp_misc_ints(SCTP_SORECV_ENTER,
|
||||
@ -6459,8 +6477,8 @@ sctp_sorecvmsg(struct socket *so,
|
||||
#else
|
||||
if ((uio->uio_resid == 0) ||
|
||||
#endif
|
||||
((in_eeor_mode) && (copied_so_far >= max(so->so_rcv.sb_lowat, 1)))
|
||||
) {
|
||||
((in_eeor_mode) &&
|
||||
(copied_so_far >= (uint32_t)max(so->so_rcv.sb_lowat, 1)))) {
|
||||
goto release;
|
||||
}
|
||||
/*
|
||||
@ -6980,7 +6998,7 @@ sctp_hashinit_flags(int elements, struct malloc_type *type,
|
||||
hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl));
|
||||
else {
|
||||
#ifdef INVARIANTS
|
||||
SCTP_PRINTF("flag incorrect in hashinit_flags");
|
||||
SCTP_PRINTF("flag incorrect in hashinit_flags.\n");
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
@ -7004,7 +7022,7 @@ sctp_hashdestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask)
|
||||
hashtbl = vhashtbl;
|
||||
for (hp = hashtbl; hp <= &hashtbl[hashmask]; hp++)
|
||||
if (!LIST_EMPTY(hp)) {
|
||||
SCTP_PRINTF("hashdestroy: hash not empty");
|
||||
SCTP_PRINTF("hashdestroy: hash not empty.\n");
|
||||
return;
|
||||
}
|
||||
FREE(hashtbl, type);
|
||||
@ -7466,8 +7484,13 @@ sctp_bindx_delete_address(struct sctp_inpcb *inp,
|
||||
int
|
||||
sctp_local_addr_count(struct sctp_tcb *stcb)
|
||||
{
|
||||
int loopback_scope, ipv4_local_scope, local_scope, site_scope;
|
||||
int ipv4_addr_legal, ipv6_addr_legal;
|
||||
int loopback_scope;
|
||||
#if defined(INET)
|
||||
int ipv4_local_scope, ipv4_addr_legal;
|
||||
#endif
|
||||
#if defined (INET6)
|
||||
int local_scope, site_scope, ipv6_addr_legal;
|
||||
#endif
|
||||
#if defined(__Userspace__)
|
||||
int conn_addr_legal;
|
||||
#endif
|
||||
@ -7478,11 +7501,15 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
|
||||
|
||||
/* Turn on all the appropriate scopes */
|
||||
loopback_scope = stcb->asoc.scope.loopback_scope;
|
||||
#if defined(INET)
|
||||
ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
|
||||
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
|
||||
#endif
|
||||
#if defined(INET6)
|
||||
local_scope = stcb->asoc.scope.local_scope;
|
||||
site_scope = stcb->asoc.scope.site_scope;
|
||||
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
|
||||
ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
|
||||
#endif
|
||||
#if defined(__Userspace__)
|
||||
conn_addr_legal = stcb->asoc.scope.conn_addr_legal;
|
||||
#endif
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 243186 2012-11-17 20:04:04Z tuexen $");
|
||||
__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 257555 2013-11-02 20:12:19Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@ -178,7 +178,13 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
|
||||
}
|
||||
#endif
|
||||
#if defined(__FreeBSD__)
|
||||
#if __FreeBSD_version >= 800000
|
||||
#if __FreeBSD_version > 1000049
|
||||
SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
|
||||
"sctp6_input(): Packet of length %d received on %s with csum_flags 0x%b.\n",
|
||||
m->m_pkthdr.len,
|
||||
if_name(m->m_pkthdr.rcvif),
|
||||
(int)m->m_pkthdr.csum_flags, CSUM_BITS);
|
||||
#elif __FreeBSD_version >= 800000
|
||||
SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
|
||||
"sctp6_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
|
||||
m->m_pkthdr.len,
|
||||
@ -457,8 +463,10 @@ sctp6_notify(struct sctp_inpcb *inp,
|
||||
(icmph->icmp6_code == ICMP_UNREACH_ISOLATED) ||
|
||||
(icmph->icmp6_code == ICMP_UNREACH_NET_PROHIB) ||
|
||||
(icmph->icmp6_code == ICMP_UNREACH_HOST_PROHIB) ||
|
||||
#ifdef __Panda__
|
||||
#if defined(__Panda__)
|
||||
(icmph->icmp6_code == ICMP_UNREACH_ADMIN)) {
|
||||
#elif defined(__Userspace_os_NetBSD)
|
||||
(icmph->icmp6_code == ICMP_UNREACH_ADMIN_PROHIBIT)) {
|
||||
#else
|
||||
(icmph->icmp6_code == ICMP_UNREACH_FILTER_PROHIB)) {
|
||||
#endif
|
||||
@ -1090,18 +1098,11 @@ sctp6_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *nam,
|
||||
}
|
||||
}
|
||||
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
|
||||
if (!MODULE_GLOBAL(ip6_v6only)) {
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
/* convert v4-mapped into v4 addr and send */
|
||||
in6_sin6_2_sin(&sin, sin6);
|
||||
return (sctp_sendm(so, flags, m, (struct sockaddr *)&sin,
|
||||
control, p));
|
||||
} else {
|
||||
/* mapped addresses aren't enabled */
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
/* convert v4-mapped into v4 addr and send */
|
||||
in6_sin6_2_sin(&sin, sin6);
|
||||
return (sctp_sendm(so, flags, m, (struct sockaddr *)&sin, control, p));
|
||||
}
|
||||
#endif /* INET */
|
||||
connected_type:
|
||||
@ -1179,14 +1180,16 @@ sctp6_connect(struct socket *so, struct mbuf *nam, struct proc *p)
|
||||
uint32_t vrf_id;
|
||||
int error = 0;
|
||||
struct sctp_inpcb *inp;
|
||||
struct in6pcb *inp6;
|
||||
struct sctp_tcb *stcb;
|
||||
#ifdef INET
|
||||
struct in6pcb *inp6;
|
||||
struct sockaddr_in6 *sin6;
|
||||
struct sockaddr_storage ss;
|
||||
#endif
|
||||
|
||||
#ifdef INET
|
||||
inp6 = (struct in6pcb *)so->so_pcb;
|
||||
#endif
|
||||
inp = (struct sctp_inpcb *)so->so_pcb;
|
||||
if (inp == NULL) {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET);
|
||||
@ -1269,17 +1272,9 @@ sctp6_connect(struct socket *so, struct mbuf *nam, struct proc *p)
|
||||
}
|
||||
}
|
||||
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
|
||||
if (!MODULE_GLOBAL(ip6_v6only)) {
|
||||
/* convert v4-mapped into v4 addr */
|
||||
in6_sin6_2_sin((struct sockaddr_in *)&ss, sin6);
|
||||
addr = (struct sockaddr *)&ss;
|
||||
} else {
|
||||
/* mapped addresses aren't enabled */
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
SCTP_ASOC_CREATE_UNLOCK(inp);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
/* convert v4-mapped into v4 addr */
|
||||
in6_sin6_2_sin((struct sockaddr_in *)&ss, sin6);
|
||||
addr = (struct sockaddr *)&ss;
|
||||
}
|
||||
#endif /* INET */
|
||||
/* Now do we connect? */
|
||||
@ -1690,7 +1685,7 @@ sctp6_getpeeraddr(struct socket *so, struct mbuf *nam)
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__)
|
||||
struct pr_usrreqs sctp6_usrreqs = {
|
||||
#if __FreeBSD_version >= 600000
|
||||
#if defined(__FreeBSD__)
|
||||
.pru_abort = sctp6_abort,
|
||||
.pru_accept = sctp_accept,
|
||||
.pru_attach = sctp6_attach,
|
||||
@ -1714,46 +1709,52 @@ struct pr_usrreqs sctp6_usrreqs = {
|
||||
.pru_sockaddr = sctp6_in6getaddr,
|
||||
.pru_sosend = sctp_sosend,
|
||||
.pru_soreceive = sctp_soreceive
|
||||
#else
|
||||
#elif defined(__APPLE__)
|
||||
.pru_abort = sctp6_abort,
|
||||
.pru_accept = sctp_accept,
|
||||
.pru_attach = sctp6_attach,
|
||||
.pru_bind = sctp6_bind,
|
||||
.pru_connect = sctp6_connect,
|
||||
.pru_connect2 = pru_connect2_notsupp,
|
||||
.pru_control = in6_control,
|
||||
.pru_detach = sctp6_detach,
|
||||
.pru_disconnect = sctp6_disconnect,
|
||||
.pru_listen = sctp_listen,
|
||||
.pru_peeraddr = sctp6_getpeeraddr,
|
||||
.pru_rcvd = NULL,
|
||||
.pru_rcvoob = pru_rcvoob_notsupp,
|
||||
.pru_send = sctp6_send,
|
||||
.pru_sense = pru_sense_null,
|
||||
.pru_shutdown = sctp_shutdown,
|
||||
.pru_sockaddr = sctp6_in6getaddr,
|
||||
.pru_sosend = sctp_sosend,
|
||||
.pru_soreceive = sctp_soreceive,
|
||||
.pru_sopoll = sopoll
|
||||
#elif defined(__Windows__)
|
||||
sctp6_abort,
|
||||
sctp_accept,
|
||||
sctp6_attach,
|
||||
sctp6_bind,
|
||||
sctp6_connect,
|
||||
pru_connect2_notsupp,
|
||||
#if defined(__Windows__)
|
||||
NULL,
|
||||
NULL,
|
||||
#else
|
||||
in6_control,
|
||||
sctp6_detach,
|
||||
#endif
|
||||
sctp6_disconnect,
|
||||
sctp_listen,
|
||||
sctp6_getpeeraddr,
|
||||
NULL,
|
||||
pru_rcvoob_notsupp,
|
||||
#if defined(__Windows__)
|
||||
NULL,
|
||||
#else
|
||||
sctp6_send,
|
||||
#endif
|
||||
pru_sense_null,
|
||||
sctp_shutdown,
|
||||
#if defined(__Windows__)
|
||||
sctp_flush,
|
||||
#endif
|
||||
sctp6_in6getaddr,
|
||||
sctp_sosend,
|
||||
sctp_soreceive,
|
||||
#if !defined(__Windows__)
|
||||
sopoll
|
||||
#else
|
||||
sopoll_generic,
|
||||
NULL,
|
||||
sctp6_close
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
#elif !defined(__Panda__) && !defined(__Userspace__)
|
||||
|
@ -55,14 +55,14 @@ int sctp6_input(struct mbuf **, int *);
|
||||
int sctp6_input_with_port(struct mbuf **, int *, uint16_t);
|
||||
#elif defined(__Panda__)
|
||||
int sctp6_input (pakhandle_type *);
|
||||
#elif defined(__FreeBSD__) && __FreeBSD_version < 1000000
|
||||
#elif defined(__FreeBSD__) && __FreeBSD_version < 902000
|
||||
int sctp6_input __P((struct mbuf **, int *, int));
|
||||
int sctp6_input_with_port __P((struct mbuf **, int *, uint16_t));
|
||||
#else
|
||||
int sctp6_input(struct mbuf **, int *, int);
|
||||
int sctp6_input_with_port(struct mbuf **, int *, uint16_t);
|
||||
#endif
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version < 1000000
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version < 902000
|
||||
int sctp6_output
|
||||
__P((struct sctp_inpcb *, struct mbuf *, struct sockaddr *,
|
||||
struct mbuf *, struct proc *));
|
||||
|
@ -33,11 +33,6 @@
|
||||
#include <stdlib.h>
|
||||
#if !defined (__Userspace_os_Windows)
|
||||
#include <stdint.h>
|
||||
#if !defined(__Userspace_os_FreeBSD)
|
||||
#if !defined(ANDROID)
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <netinet/sctp_os_userspace.h>
|
||||
#endif
|
||||
#include <user_environment.h>
|
||||
|
@ -35,13 +35,6 @@
|
||||
|
||||
#include <user_route.h> /* was <net/route.h> */
|
||||
|
||||
#if defined(ANDROID)
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
/* missing defines in Android bionic libc/NDK */
|
||||
typedef uint16_t in_port_t;
|
||||
#endif
|
||||
|
||||
#define in6pcb inpcb /* for KAME src sync over BSD*'s */
|
||||
#define in6p_sp inp_sp /* for KAME src sync over BSD*'s */
|
||||
struct inpcbpolicy;
|
||||
@ -56,7 +49,6 @@ struct inpcbpolicy;
|
||||
*/
|
||||
LIST_HEAD(inpcbhead, inpcb);
|
||||
LIST_HEAD(inpcbporthead, inpcbport);
|
||||
typedef u_quad_t inp_gen_t;
|
||||
|
||||
/*
|
||||
* PCB with AF_INET6 null bind'ed laddr can receive AF_INET input packet.
|
||||
@ -176,7 +168,6 @@ struct inpcb {
|
||||
LIST_ENTRY(inpcb) inp_portlist;
|
||||
struct inpcbport *inp_phd; /* head of this list */
|
||||
#define inp_zero_size offsetof(struct inpcb, inp_gencnt)
|
||||
inp_gen_t inp_gencnt; /* generation count of this instance */
|
||||
struct mtx inp_mtx;
|
||||
|
||||
#define in6p_faddr inp_inc.inc6_faddr
|
||||
@ -205,26 +196,6 @@ struct inpcb {
|
||||
* don't concern ourselves with that possibility.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Interface exported to userland by various protocols which use inpcbs. Hack
|
||||
* alert -- only define if struct xsocket is in scope.
|
||||
*/
|
||||
#ifdef _SYS_SOCKETVAR_H_
|
||||
struct xinpcb {
|
||||
size_t xi_len; /* length of this structure */
|
||||
struct inpcb xi_inp;
|
||||
struct xsocket xi_socket;
|
||||
u_quad_t xi_alignment_hack;
|
||||
};
|
||||
|
||||
struct xinpgen {
|
||||
size_t xig_len; /* length of this structure */
|
||||
u_int xig_count; /* number of PCBs at this time */
|
||||
inp_gen_t xig_gen; /* generation count at this time */
|
||||
so_gen_t xig_sogen; /* socket generation count at this time */
|
||||
};
|
||||
#endif /* _SYS_SOCKETVAR_H_ */
|
||||
|
||||
struct inpcbport {
|
||||
LIST_ENTRY(inpcbport) phd_hash;
|
||||
struct inpcbhead phd_pcblist;
|
||||
@ -271,7 +242,6 @@ struct inpcbinfo {
|
||||
* Generation count--incremented each time a connection is allocated
|
||||
* or freed.
|
||||
*/
|
||||
u_quad_t ipi_gencnt;
|
||||
struct mtx ipi_mtx;
|
||||
|
||||
/*
|
||||
@ -376,12 +346,7 @@ extern struct callout ipport_tick_callout;
|
||||
void in_pcbpurgeif0(struct inpcbinfo *, struct ifnet *);
|
||||
int in_pcballoc(struct socket *, struct inpcbinfo *);
|
||||
int in_pcbbind(struct inpcb *, struct sockaddr *, struct ucred *);
|
||||
int in_pcbbind_setup(struct inpcb *, struct sockaddr *, in_addr_t *,
|
||||
u_short *, struct ucred *);
|
||||
int in_pcbconnect(struct inpcb *, struct sockaddr *, struct ucred *);
|
||||
int in_pcbconnect_setup(struct inpcb *, struct sockaddr *, in_addr_t *,
|
||||
u_short *, in_addr_t *, u_short *, struct inpcb **,
|
||||
struct ucred *);
|
||||
void in_pcbdetach(struct inpcb *);
|
||||
void in_pcbdisconnect(struct inpcb *);
|
||||
void in_pcbdrop(struct inpcb *);
|
||||
@ -399,8 +364,6 @@ void in_pcbrehash(struct inpcb *);
|
||||
void in_pcbsetsolabel(struct socket *so);
|
||||
int in_getpeeraddr(struct socket *so, struct sockaddr **nam);
|
||||
int in_getsockaddr(struct socket *so, struct sockaddr **nam);
|
||||
struct sockaddr *
|
||||
in_sockaddr(in_port_t port, struct in_addr *addr);
|
||||
void in_pcbsosetlabel(struct socket *so);
|
||||
void in_pcbremlists(struct inpcb *inp);
|
||||
void ipport_tick(void *xtp);
|
||||
|
@ -95,7 +95,7 @@ struct ip6_hdr {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_OpenBSD)
|
||||
#if !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_OpenBSD) && !defined(__Userspace_os_DragonFly)
|
||||
struct route_in6 {
|
||||
struct rtentry *ro_rt;
|
||||
struct llentry *ro_lle;
|
||||
|
@ -163,9 +163,9 @@ struct mbstat {
|
||||
* externally and attach it to the mbuf in a way similar to that of mbuf
|
||||
* clusters.
|
||||
*/
|
||||
#define MLEN (MSIZE - sizeof(struct m_hdr)) /* normal data len */
|
||||
#define MHLEN (MLEN - sizeof(struct pkthdr)) /* data len w/pkthdr */
|
||||
#define MINCLSIZE (MHLEN + 1) /* smallest amount to put in cluster */
|
||||
#define MLEN ((int)(MSIZE - sizeof(struct m_hdr))) /* normal data len */
|
||||
#define MHLEN ((int)(MLEN - sizeof(struct pkthdr))) /* data len w/pkthdr */
|
||||
#define MINCLSIZE ((int)(MHLEN + 1)) /* smallest amount to put in cluster */
|
||||
#define M_MAXCOMPRESS (MHLEN / 2) /* max amount to copy for compression */
|
||||
|
||||
|
||||
@ -267,7 +267,6 @@ struct mbuf {
|
||||
#define M_PROTO3 0x0040 /* protocol-specific */
|
||||
#define M_PROTO4 0x0080 /* protocol-specific */
|
||||
#define M_PROTO5 0x0100 /* protocol-specific */
|
||||
#define M_NOTIFICATION M_PROTO5/* SCTP notification */
|
||||
#define M_SKIP_FIREWALL 0x4000 /* skip firewall processing */
|
||||
#define M_FREELIST 0x8000 /* mbuf is on the free list */
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#if !defined(__Userspace_os_FreeBSD)
|
||||
#if !defined(__Userspace_os_DragonFly) && !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_NetBSD)
|
||||
#include <sys/uio.h>
|
||||
#else
|
||||
#include <user_ip6_var.h>
|
||||
@ -56,7 +56,7 @@
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Darwin)
|
||||
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
|
||||
#include <net/route.h>
|
||||
#endif
|
||||
/* local macros and datatypes used to get IP addresses system independently */
|
||||
@ -67,12 +67,12 @@
|
||||
void recv_thread_destroy(void);
|
||||
#define MAXLEN_MBUF_CHAIN 32 /* What should this value be? */
|
||||
#define ROUNDUP(a, size) (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))
|
||||
#if defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Darwin)
|
||||
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
|
||||
#define NEXT_SA(ap) ap = (struct sockaddr *) \
|
||||
((caddr_t) ap + (ap->sa_len ? ROUNDUP(ap->sa_len, sizeof (uint32_t)) : sizeof(uint32_t)))
|
||||
#endif
|
||||
|
||||
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD)
|
||||
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
|
||||
static void
|
||||
sctp_get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
|
||||
{
|
||||
@ -183,7 +183,7 @@ recv_function_route(void *arg)
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
return (NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -266,7 +266,7 @@ recv_function_route(void *arg)
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
return (NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -360,6 +360,8 @@ recv_function_raw(void *arg)
|
||||
}
|
||||
#endif
|
||||
SCTP_HEADER_LEN(recvmbuf[0]) = n; /* length of total packet */
|
||||
SCTP_STAT_INCR(sctps_recvpackets);
|
||||
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
|
||||
|
||||
if (n <= iovlen) {
|
||||
SCTP_BUF_LEN(recvmbuf[0]) = n;
|
||||
@ -404,44 +406,44 @@ recv_function_raw(void *arg)
|
||||
|
||||
/* SCTP does not allow broadcasts or multicasts */
|
||||
if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) {
|
||||
return NULL;
|
||||
return (NULL);
|
||||
}
|
||||
if (SCTP_IS_IT_BROADCAST(dst.sin_addr, recvmbuf[0])) {
|
||||
return NULL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
port = 0;
|
||||
|
||||
#if !defined(SCTP_WITH_NO_CSUM)
|
||||
#if defined(SCTP_WITH_NO_CSUM)
|
||||
SCTP_STAT_INCR(sctps_recvnocrc);
|
||||
#else
|
||||
if (src.sin_addr.s_addr == dst.sin_addr.s_addr) {
|
||||
compute_crc = 0;
|
||||
SCTP_STAT_INCR(sctps_recvnocrc);
|
||||
} else {
|
||||
SCTP_STAT_INCR(sctps_recvswcrc);
|
||||
}
|
||||
#endif
|
||||
SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n);
|
||||
SCTPDBG(SCTP_DEBUG_USR, " - calling sctp_common_input_processing with off=%d\n", offset);
|
||||
|
||||
sctp_common_input_processing(&recvmbuf[0], sizeof(struct ip), offset, n,
|
||||
(struct sockaddr *)&src,
|
||||
(struct sockaddr *)&dst,
|
||||
sh, ch,
|
||||
#if !defined(SCTP_WITH_NO_CSUM)
|
||||
compute_crc,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
ecn,
|
||||
SCTP_DEFAULT_VRFID, port);
|
||||
if (recvmbuf[0]) {
|
||||
m_freem(recvmbuf[0]);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
|
||||
m_free(recvmbuf[i]);
|
||||
}
|
||||
/* free the array itself */
|
||||
free(recvmbuf);
|
||||
#if defined (__Userspace_os_Windows)
|
||||
ExitThread(0);
|
||||
#else
|
||||
pthread_exit(NULL);
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
#endif
|
||||
@ -553,6 +555,8 @@ recv_function_raw6(void *arg)
|
||||
}
|
||||
#endif
|
||||
SCTP_HEADER_LEN(recvmbuf6[0]) = n; /* length of total packet */
|
||||
SCTP_STAT_INCR(sctps_recvpackets);
|
||||
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
|
||||
|
||||
if (n <= iovlen) {
|
||||
SCTP_BUF_LEN(recvmbuf6[0]) = n;
|
||||
@ -597,9 +601,14 @@ recv_function_raw6(void *arg)
|
||||
src.sin6_len = sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
src.sin6_port = sh->src_port;
|
||||
#if !defined(SCTP_WITH_NO_CSUM)
|
||||
#if defined(SCTP_WITH_NO_CSUM)
|
||||
SCTP_STAT_INCR(sctps_recvnocrc);
|
||||
#else
|
||||
if (memcmp(&src.sin6_addr, &dst.sin6_addr, sizeof(struct in6_addr)) == 0) {
|
||||
compute_crc = 0;
|
||||
SCTP_STAT_INCR(sctps_recvnocrc);
|
||||
} else {
|
||||
SCTP_STAT_INCR(sctps_recvswcrc);
|
||||
}
|
||||
#endif
|
||||
SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n);
|
||||
@ -610,22 +619,18 @@ recv_function_raw6(void *arg)
|
||||
sh, ch,
|
||||
#if !defined(SCTP_WITH_NO_CSUM)
|
||||
compute_crc,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
0,
|
||||
SCTP_DEFAULT_VRFID, 0);
|
||||
if (recvmbuf6[0]) {
|
||||
m_freem(recvmbuf6[0]);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
|
||||
m_free(recvmbuf6[i]);
|
||||
}
|
||||
/* free the array itself */
|
||||
free(recvmbuf6);
|
||||
#if defined (__Userspace_os_Windows)
|
||||
ExitThread(0);
|
||||
#else
|
||||
pthread_exit(NULL);
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
#endif
|
||||
@ -740,6 +745,8 @@ recv_function_udp(void *arg)
|
||||
n = ncounter;
|
||||
#endif
|
||||
SCTP_HEADER_LEN(udprecvmbuf[0]) = n; /* length of total packet */
|
||||
SCTP_STAT_INCR(sctps_recvpackets);
|
||||
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
|
||||
|
||||
if (n <= iovlen) {
|
||||
SCTP_BUF_LEN(udprecvmbuf[0]) = n;
|
||||
@ -789,10 +796,10 @@ recv_function_udp(void *arg)
|
||||
|
||||
/* SCTP does not allow broadcasts or multicasts */
|
||||
if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) {
|
||||
return NULL;
|
||||
return (NULL);
|
||||
}
|
||||
if (SCTP_IS_IT_BROADCAST(dst.sin_addr, udprecvmbuf[0])) {
|
||||
return NULL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*offset = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);*/
|
||||
@ -802,9 +809,14 @@ recv_function_udp(void *arg)
|
||||
port = src.sin_port;
|
||||
src.sin_port = sh->src_port;
|
||||
dst.sin_port = sh->dest_port;
|
||||
#if !defined(SCTP_WITH_NO_CSUM)
|
||||
#if defined(SCTP_WITH_NO_CSUM)
|
||||
SCTP_STAT_INCR(sctps_recvnocrc);
|
||||
#else
|
||||
if (src.sin_addr.s_addr == dst.sin_addr.s_addr) {
|
||||
compute_crc = 0;
|
||||
SCTP_STAT_INCR(sctps_recvnocrc);
|
||||
} else {
|
||||
SCTP_STAT_INCR(sctps_recvswcrc);
|
||||
}
|
||||
#endif
|
||||
SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n);
|
||||
@ -815,22 +827,18 @@ recv_function_udp(void *arg)
|
||||
sh, ch,
|
||||
#if !defined(SCTP_WITH_NO_CSUM)
|
||||
compute_crc,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
0,
|
||||
SCTP_DEFAULT_VRFID, port);
|
||||
if (udprecvmbuf[0]) {
|
||||
m_freem(udprecvmbuf[0]);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
|
||||
m_free(udprecvmbuf[i]);
|
||||
}
|
||||
/* free the array itself */
|
||||
free(udprecvmbuf);
|
||||
#if defined (__Userspace_os_Windows)
|
||||
ExitThread(0);
|
||||
#else
|
||||
pthread_exit(NULL);
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
#endif
|
||||
@ -945,6 +953,8 @@ recv_function_udp6(void *arg)
|
||||
n = ncounter;
|
||||
#endif
|
||||
SCTP_HEADER_LEN(udprecvmbuf6[0]) = n; /* length of total packet */
|
||||
SCTP_STAT_INCR(sctps_recvpackets);
|
||||
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
|
||||
|
||||
if (n <= iovlen) {
|
||||
SCTP_BUF_LEN(udprecvmbuf6[0]) = n;
|
||||
@ -980,7 +990,7 @@ recv_function_udp6(void *arg)
|
||||
|
||||
/* SCTP does not allow broadcasts or multicasts */
|
||||
if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) {
|
||||
return NULL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
sh = mtod(udprecvmbuf6[0], struct sctphdr *);
|
||||
@ -990,9 +1000,14 @@ recv_function_udp6(void *arg)
|
||||
port = src.sin6_port;
|
||||
src.sin6_port = sh->src_port;
|
||||
dst.sin6_port = sh->dest_port;
|
||||
#if !defined(SCTP_WITH_NO_CSUM)
|
||||
#if defined(SCTP_WITH_NO_CSUM)
|
||||
SCTP_STAT_INCR(sctps_recvnocrc);
|
||||
#else
|
||||
if ((memcmp(&src.sin6_addr, &dst.sin6_addr, sizeof(struct in6_addr)) == 0)) {
|
||||
compute_crc = 0;
|
||||
SCTP_STAT_INCR(sctps_recvnocrc);
|
||||
} else {
|
||||
SCTP_STAT_INCR(sctps_recvswcrc);
|
||||
}
|
||||
#endif
|
||||
SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n);
|
||||
@ -1006,18 +1021,15 @@ recv_function_udp6(void *arg)
|
||||
#endif
|
||||
0,
|
||||
SCTP_DEFAULT_VRFID, port);
|
||||
|
||||
if (udprecvmbuf6[0]) {
|
||||
m_freem(udprecvmbuf6[0]);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
|
||||
m_free(udprecvmbuf6[i]);
|
||||
}
|
||||
/* free the array itself */
|
||||
free(udprecvmbuf6);
|
||||
#if defined (__Userspace_os_Windows)
|
||||
ExitThread(0);
|
||||
#else
|
||||
pthread_exit(NULL);
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
#endif
|
||||
@ -1074,7 +1086,7 @@ recv_thread_init(void)
|
||||
#else
|
||||
unsigned int timeout = SOCKET_TIMEOUT; /* Timeout in milliseconds */
|
||||
#endif
|
||||
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD)
|
||||
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
|
||||
if (SCTP_BASE_VAR(userspace_route) == -1) {
|
||||
if ((SCTP_BASE_VAR(userspace_route) = socket(AF_ROUTE, SOCK_RAW, 0)) < 0) {
|
||||
SCTPDBG(SCTP_DEBUG_USR, "Can't create routing socket (errno = %d).\n", errno);
|
||||
@ -1375,7 +1387,7 @@ recv_thread_init(void)
|
||||
}
|
||||
#endif
|
||||
#if !defined(__Userspace_os_Windows)
|
||||
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD)
|
||||
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
|
||||
#if defined(INET) || defined(INET6)
|
||||
if (SCTP_BASE_VAR(userspace_route) != -1) {
|
||||
int rc;
|
||||
@ -1467,7 +1479,7 @@ recv_thread_init(void)
|
||||
void
|
||||
recv_thread_destroy(void)
|
||||
{
|
||||
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD)
|
||||
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
|
||||
#if defined(INET) || defined(INET6)
|
||||
if (SCTP_BASE_VAR(userspace_route) != -1) {
|
||||
close(SCTP_BASE_VAR(userspace_route));
|
||||
@ -1507,4 +1519,6 @@ recv_thread_destroy(void)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
int foo;
|
||||
#endif
|
||||
|
@ -94,12 +94,7 @@ user_sctp_timer_iterate(void *arg)
|
||||
}
|
||||
SCTP_TIMERQ_UNLOCK();
|
||||
}
|
||||
#if defined (__Userspace_os_Windows)
|
||||
ExitThread(0);
|
||||
#else
|
||||
pthread_exit(NULL);
|
||||
#endif
|
||||
return NULL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -48,14 +48,11 @@
|
||||
#if !defined (__Userspace_os_Windows)
|
||||
#include <netinet/udp.h>
|
||||
#include <arpa/inet.h>
|
||||
/* Statically initializing accept_mtx and accept_cond since there is no call for ACCEPT_LOCK_INIT() */
|
||||
userland_mutex_t accept_mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
userland_cond_t accept_cond = PTHREAD_COND_INITIALIZER;
|
||||
#else
|
||||
#include <user_socketvar.h>
|
||||
#endif
|
||||
userland_mutex_t accept_mtx;
|
||||
userland_cond_t accept_cond;
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
@ -161,7 +158,6 @@ sbwait(struct sockbuf *sb)
|
||||
static struct socket *
|
||||
soalloc(void)
|
||||
{
|
||||
#if defined(__Userspace__)
|
||||
struct socket *so;
|
||||
|
||||
/*
|
||||
@ -176,9 +172,10 @@ soalloc(void)
|
||||
|
||||
so = (struct socket *)malloc(sizeof(struct socket));
|
||||
|
||||
if (so == NULL)
|
||||
if (so == NULL) {
|
||||
return (NULL);
|
||||
bzero(so, sizeof(struct socket));
|
||||
}
|
||||
memset(so, 0, sizeof(struct socket));
|
||||
|
||||
/* __Userspace__ Initializing the socket locks here */
|
||||
SOCKBUF_LOCK_INIT(&so->so_snd, "so_snd");
|
||||
@ -191,39 +188,8 @@ soalloc(void)
|
||||
What about gencnt and numopensockets?*/
|
||||
TAILQ_INIT(&so->so_aiojobq);
|
||||
return (so);
|
||||
#else
|
||||
/* Putting the kernel version for reference. The #else
|
||||
should be removed once the __Userspace__
|
||||
version is tested.
|
||||
*/
|
||||
struct socket *so;
|
||||
|
||||
so = uma_zalloc(socket_zone, M_NOWAIT | M_ZERO);
|
||||
if (so == NULL)
|
||||
return (NULL);
|
||||
#ifdef MAC
|
||||
if (mac_init_socket(so, M_NOWAIT) != 0) {
|
||||
uma_zfree(socket_zone, so);
|
||||
return (NULL);
|
||||
}
|
||||
#endif
|
||||
SOCKBUF_LOCK_INIT(&so->so_snd, "so_snd");
|
||||
SOCKBUF_LOCK_INIT(&so->so_rcv, "so_rcv");
|
||||
sx_init(&so->so_snd.sb_sx, "so_snd_sx");
|
||||
sx_init(&so->so_rcv.sb_sx, "so_rcv_sx");
|
||||
TAILQ_INIT(&so->so_aiojobq);
|
||||
mtx_lock(&so_global_mtx);
|
||||
so->so_gencnt = ++so_gencnt;
|
||||
++numopensockets;
|
||||
mtx_unlock(&so_global_mtx);
|
||||
return (so);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__Userspace__)
|
||||
/*
|
||||
* Free the storage associated with a socket at the socket layer.
|
||||
*/
|
||||
static void
|
||||
sodealloc(struct socket *so)
|
||||
{
|
||||
@ -231,57 +197,17 @@ sodealloc(struct socket *so)
|
||||
KASSERT(so->so_count == 0, ("sodealloc(): so_count %d", so->so_count));
|
||||
KASSERT(so->so_pcb == NULL, ("sodealloc(): so_pcb != NULL"));
|
||||
|
||||
SOCKBUF_LOCK_DESTROY(&so->so_snd);
|
||||
SOCKBUF_LOCK_DESTROY(&so->so_rcv);
|
||||
|
||||
SOCKBUF_COND_DESTROY(&so->so_snd);
|
||||
SOCKBUF_COND_DESTROY(&so->so_rcv);
|
||||
|
||||
SOCK_COND_DESTROY(so);
|
||||
SOCK_COND_DESTROY(so);
|
||||
|
||||
SOCKBUF_LOCK_DESTROY(&so->so_snd);
|
||||
SOCKBUF_LOCK_DESTROY(&so->so_rcv);
|
||||
|
||||
free(so);
|
||||
}
|
||||
|
||||
#else /* kernel version for reference. */
|
||||
/*
|
||||
* Free the storage associated with a socket at the socket layer, tear down
|
||||
* locks, labels, etc. All protocol state is assumed already to have been
|
||||
* torn down (and possibly never set up) by the caller.
|
||||
*/
|
||||
static void
|
||||
sodealloc(struct socket *so)
|
||||
{
|
||||
|
||||
KASSERT(so->so_count == 0, ("sodealloc(): so_count %d", so->so_count));
|
||||
KASSERT(so->so_pcb == NULL, ("sodealloc(): so_pcb != NULL"));
|
||||
|
||||
mtx_lock(&so_global_mtx);
|
||||
so->so_gencnt = ++so_gencnt;
|
||||
--numopensockets; /* Could be below, but faster here. */
|
||||
mtx_unlock(&so_global_mtx);
|
||||
if (so->so_rcv.sb_hiwat)
|
||||
(void)chgsbsize(so->so_cred->cr_uidinfo,
|
||||
&so->so_rcv.sb_hiwat, 0, RLIM_INFINITY);
|
||||
if (so->so_snd.sb_hiwat)
|
||||
(void)chgsbsize(so->so_cred->cr_uidinfo,
|
||||
&so->so_snd.sb_hiwat, 0, RLIM_INFINITY);
|
||||
#ifdef INET
|
||||
/* remove acccept filter if one is present. */
|
||||
if (so->so_accf != NULL)
|
||||
do_setopt_accept_filter(so, NULL);
|
||||
#endif
|
||||
#ifdef MAC
|
||||
mac_destroy_socket(so);
|
||||
#endif
|
||||
crfree(so->so_cred);
|
||||
sx_destroy(&so->so_snd.sb_sx);
|
||||
sx_destroy(&so->so_rcv.sb_sx);
|
||||
SOCKBUF_LOCK_DESTROY(&so->so_snd);
|
||||
SOCKBUF_LOCK_DESTROY(&so->so_rcv);
|
||||
uma_zfree(socket_zone, so);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Taken from /src/sys/kern/uipc_socket.c
|
||||
* and modified for __Userspace__
|
||||
*/
|
||||
@ -351,17 +277,21 @@ soabort(so)
|
||||
struct socket *so;
|
||||
{
|
||||
int error;
|
||||
#if defined(INET6)
|
||||
struct sctp_inpcb *inp;
|
||||
|
||||
inp = (struct sctp_inpcb *)so->so_pcb;
|
||||
#endif
|
||||
|
||||
#if defined(INET6)
|
||||
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6)
|
||||
inp = (struct sctp_inpcb *)so->so_pcb;
|
||||
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
|
||||
error = sctp6_abort(so);
|
||||
} else {
|
||||
#if defined(INET)
|
||||
else
|
||||
error = sctp_abort(so);
|
||||
#else
|
||||
error = EAFNOSUPPORT;
|
||||
#endif
|
||||
}
|
||||
#elif defined(INET)
|
||||
error = sctp_abort(so);
|
||||
#else
|
||||
@ -792,7 +722,7 @@ userspace_sctp_sendmsg(struct socket *so,
|
||||
return (-1);
|
||||
}
|
||||
if ((tolen > 0) &&
|
||||
((to == NULL) || (tolen < sizeof(struct sockaddr)))) {
|
||||
((to == NULL) || (tolen < (socklen_t)sizeof(struct sockaddr)))) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
@ -962,7 +892,7 @@ userspace_sctp_sendmbuf(struct socket *so,
|
||||
error = (ENAMETOOLONG);
|
||||
goto sendmsg_return;
|
||||
}
|
||||
if (tolen < offsetof(struct sockaddr, sa_data)){
|
||||
if (tolen < (socklen_t)offsetof(struct sockaddr, sa_data)){
|
||||
error = (EINVAL);
|
||||
goto sendmsg_return;
|
||||
}
|
||||
@ -1044,10 +974,15 @@ userspace_sctp_recvmsg(struct socket *so,
|
||||
(struct sctp_sndrcvinfo *)sinfo, 1);
|
||||
|
||||
if (error) {
|
||||
if (auio.uio_resid != (int)ulen && (error == ERESTART ||
|
||||
error == EINTR || error == EWOULDBLOCK))
|
||||
if (auio.uio_resid != (int)ulen &&
|
||||
(error == EINTR ||
|
||||
#if !defined(__Userspace_os_NetBSD)
|
||||
error == ERESTART ||
|
||||
#endif
|
||||
error == EWOULDBLOCK)) {
|
||||
error = 0;
|
||||
}
|
||||
}
|
||||
if ((fromlenp != NULL) && (fromlen > 0) && (from != NULL)) {
|
||||
switch (from->sa_family) {
|
||||
#if defined(INET)
|
||||
@ -1133,7 +1068,11 @@ usrsctp_recvv(struct socket *so,
|
||||
(struct sctp_sndrcvinfo *)&seinfo, 1);
|
||||
if (errno) {
|
||||
if (auio.uio_resid != (int)ulen &&
|
||||
(errno == ERESTART || errno == EINTR || errno == EWOULDBLOCK)) {
|
||||
(errno == EINTR ||
|
||||
#if !defined(__Userspace_os_NetBSD)
|
||||
errno == ERESTART ||
|
||||
#endif
|
||||
errno == EWOULDBLOCK)) {
|
||||
errno = 0;
|
||||
}
|
||||
}
|
||||
@ -1143,7 +1082,7 @@ usrsctp_recvv(struct socket *so,
|
||||
inp = (struct sctp_inpcb *)so->so_pcb;
|
||||
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO) &&
|
||||
sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO) &&
|
||||
*infolen >= sizeof(struct sctp_recvv_rn) &&
|
||||
*infolen >= (socklen_t)sizeof(struct sctp_recvv_rn) &&
|
||||
seinfo.sreinfo_next_flags & SCTP_NEXT_MSG_AVAIL) {
|
||||
rn = (struct sctp_recvv_rn *)info;
|
||||
rn->recvv_rcvinfo.rcv_sid = seinfo.sinfo_stream;
|
||||
@ -1171,7 +1110,7 @@ usrsctp_recvv(struct socket *so,
|
||||
*infolen = (socklen_t)sizeof(struct sctp_recvv_rn);
|
||||
*infotype = SCTP_RECVV_RN;
|
||||
} else if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO) &&
|
||||
*infolen >= sizeof(struct sctp_rcvinfo)) {
|
||||
*infolen >= (socklen_t)sizeof(struct sctp_rcvinfo)) {
|
||||
rcv = (struct sctp_rcvinfo *)info;
|
||||
rcv->rcv_sid = seinfo.sinfo_stream;
|
||||
rcv->rcv_ssn = seinfo.sinfo_ssn;
|
||||
@ -1429,7 +1368,6 @@ u_long sb_max_adj =
|
||||
|
||||
static u_long sb_efficiency = 8; /* parameter for sbreserve() */
|
||||
|
||||
#if defined (__Userspace__)
|
||||
/*
|
||||
* Allot mbufs to a sockbuf. Attempt to scale mbmax so that mbcnt doesn't
|
||||
* become limiting if buffering efficiency is near the normal case.
|
||||
@ -1439,48 +1377,22 @@ 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;
|
||||
if (sb->sb_lowat > (int)sb->sb_hiwat)
|
||||
sb->sb_lowat = (int)sb->sb_hiwat;
|
||||
return (1);
|
||||
}
|
||||
#else /* kernel version for reference */
|
||||
/*
|
||||
* Allot mbufs to a sockbuf. Attempt to scale mbmax so that mbcnt doesn't
|
||||
* become limiting if buffering efficiency is near the normal case.
|
||||
*/
|
||||
int
|
||||
sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so,
|
||||
struct thread *td)
|
||||
|
||||
static int
|
||||
sbreserve(struct sockbuf *sb, u_long cc, struct socket *so)
|
||||
{
|
||||
rlim_t sbsize_limit;
|
||||
int error;
|
||||
|
||||
SOCKBUF_LOCK_ASSERT(sb);
|
||||
|
||||
/*
|
||||
* td will only be NULL when we're in an interrupt (e.g. in
|
||||
* tcp_input()).
|
||||
*
|
||||
* XXXRW: This comment needs updating, as might the code.
|
||||
*/
|
||||
if (cc > sb_max_adj)
|
||||
return (0);
|
||||
if (td != NULL) {
|
||||
PROC_LOCK(td->td_proc);
|
||||
sbsize_limit = lim_cur(td->td_proc, RLIMIT_SBSIZE);
|
||||
PROC_UNLOCK(td->td_proc);
|
||||
} else
|
||||
sbsize_limit = RLIM_INFINITY;
|
||||
if (!chgsbsize(so->so_cred->cr_uidinfo, &sb->sb_hiwat, cc,
|
||||
sbsize_limit))
|
||||
return (0);
|
||||
sb->sb_mbmax = min(cc * sb_efficiency, sb_max);
|
||||
if (sb->sb_lowat > sb->sb_hiwat)
|
||||
sb->sb_lowat = sb->sb_hiwat;
|
||||
return (1);
|
||||
SOCKBUF_LOCK(sb);
|
||||
error = sbreserve_locked(sb, cc, so);
|
||||
SOCKBUF_UNLOCK(sb);
|
||||
return (error);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if defined(__Userspace__)
|
||||
int
|
||||
@ -1841,8 +1753,33 @@ user_accept(struct socket *head, struct sockaddr **name, socklen_t *namelen, st
|
||||
if (name) {
|
||||
#ifdef HAVE_SA_LEN
|
||||
/* check sa_len before it is destroyed */
|
||||
if (*namelen > sa->sa_len)
|
||||
if (*namelen > sa->sa_len) {
|
||||
*namelen = sa->sa_len;
|
||||
}
|
||||
#else
|
||||
socklen_t sa_len;
|
||||
|
||||
switch (sa->sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
sa_len = sizeof(struct sockaddr_in);
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
sa_len = sizeof(struct sockaddr_in6);
|
||||
break;
|
||||
#endif
|
||||
case AF_CONN:
|
||||
sa_len = sizeof(struct sockaddr_conn);
|
||||
break;
|
||||
default:
|
||||
sa_len = 0;
|
||||
break;
|
||||
}
|
||||
if (*namelen > sa_len) {
|
||||
*namelen = sa_len;
|
||||
}
|
||||
#endif
|
||||
*name = sa;
|
||||
sa = NULL;
|
||||
@ -2083,8 +2020,13 @@ int user_connect(struct socket *so, struct sockaddr *sa)
|
||||
error = pthread_cond_wait(SOCK_COND(so), SOCK_MTX(so));
|
||||
#endif
|
||||
if (error) {
|
||||
if (error == EINTR || error == ERESTART)
|
||||
#if defined(__Userspace_os_NetBSD)
|
||||
if (error == EINTR) {
|
||||
#else
|
||||
if (error == EINTR || error == ERESTART) {
|
||||
#endif
|
||||
interrupted = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2095,10 +2037,14 @@ int user_connect(struct socket *so, struct sockaddr *sa)
|
||||
SOCK_UNLOCK(so);
|
||||
|
||||
bad:
|
||||
if (!interrupted)
|
||||
if (!interrupted) {
|
||||
so->so_state &= ~SS_ISCONNECTING;
|
||||
if (error == ERESTART)
|
||||
}
|
||||
#if !defined(__Userspace_os_NetBSD)
|
||||
if (error == ERESTART) {
|
||||
error = EINTR;
|
||||
}
|
||||
#endif
|
||||
done1:
|
||||
return (error);
|
||||
}
|
||||
@ -2199,6 +2145,7 @@ usrsctp_finish(void)
|
||||
SCTP_INP_INFO_RUNLOCK();
|
||||
return (-1);
|
||||
}
|
||||
SCTP_INP_INFO_RUNLOCK();
|
||||
} else {
|
||||
return (-1);
|
||||
}
|
||||
@ -2228,6 +2175,38 @@ usrsctp_setsockopt(struct socket *so, int level, int option_name,
|
||||
case SOL_SOCKET:
|
||||
{
|
||||
switch (option_name) {
|
||||
case SO_RCVBUF:
|
||||
if (option_len < (socklen_t)sizeof(int)) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
} else {
|
||||
int *buf_size;
|
||||
|
||||
buf_size = (int *)option_value;
|
||||
if (*buf_size < 1) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
sbreserve(&so->so_rcv, (u_long)*buf_size, so);
|
||||
return (0);
|
||||
}
|
||||
break;
|
||||
case SO_SNDBUF:
|
||||
if (option_len < (socklen_t)sizeof(int)) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
} else {
|
||||
int *buf_size;
|
||||
|
||||
buf_size = (int *)option_value;
|
||||
if (*buf_size < 1) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
sbreserve(&so->so_snd, (u_long)*buf_size, so);
|
||||
return (0);
|
||||
}
|
||||
break;
|
||||
case SO_LINGER:
|
||||
if (option_len < (socklen_t)sizeof(struct linger)) {
|
||||
errno = EINVAL;
|
||||
@ -2289,6 +2268,32 @@ usrsctp_getsockopt(struct socket *so, int level, int option_name,
|
||||
switch (level) {
|
||||
case SOL_SOCKET:
|
||||
switch (option_name) {
|
||||
case SO_RCVBUF:
|
||||
if (*option_len < (socklen_t)sizeof(int)) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
} else {
|
||||
int *buf_size;
|
||||
|
||||
buf_size = (int *)option_value;
|
||||
*buf_size = so->so_rcv.sb_hiwat;;
|
||||
*option_len = (socklen_t)sizeof(int);
|
||||
return (0);
|
||||
}
|
||||
break;
|
||||
case SO_SNDBUF:
|
||||
if (*option_len < (socklen_t)sizeof(int)) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
} else {
|
||||
int *buf_size;
|
||||
|
||||
buf_size = (int *)option_value;
|
||||
*buf_size = so->so_snd.sb_hiwat;
|
||||
*option_len = (socklen_t)sizeof(int);
|
||||
return (0);
|
||||
}
|
||||
break;
|
||||
case SO_LINGER:
|
||||
if (*option_len < (socklen_t)sizeof(struct linger)) {
|
||||
errno = EINVAL;
|
||||
@ -2341,13 +2346,17 @@ usrsctp_bindx(struct socket *so, struct sockaddr *addrs, int addrcnt, int flags)
|
||||
{
|
||||
struct sctp_getaddresses *gaddrs;
|
||||
struct sockaddr *sa;
|
||||
#ifdef INET
|
||||
struct sockaddr_in *sin;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
int i;
|
||||
size_t argsz;
|
||||
#if defined(INET) || defined(INET6)
|
||||
uint16_t sport = 0;
|
||||
#endif
|
||||
|
||||
/* validate the flags */
|
||||
if ((flags != SCTP_BINDX_ADD_ADDR) &&
|
||||
@ -2387,7 +2396,7 @@ usrsctp_bindx(struct socket *so, struct sockaddr *addrs, int addrcnt, int flags)
|
||||
}
|
||||
}
|
||||
#ifndef HAVE_SA_LEN
|
||||
sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in));
|
||||
sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in));
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
@ -2414,27 +2423,19 @@ usrsctp_bindx(struct socket *so, struct sockaddr *addrs, int addrcnt, int flags)
|
||||
}
|
||||
}
|
||||
#ifndef HAVE_SA_LEN
|
||||
sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6));
|
||||
sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6));
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* Invalid address family specified. */
|
||||
errno = EINVAL;
|
||||
errno = EAFNOSUPPORT;
|
||||
return (-1);
|
||||
}
|
||||
#ifdef HAVE_SA_LEN
|
||||
sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len);
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* Now if there was a port mentioned, assure that the first address
|
||||
* has that port to make sure it fails or succeeds correctly.
|
||||
*/
|
||||
if (sport) {
|
||||
sin = (struct sockaddr_in *)sa;
|
||||
sin->sin_port = sport;
|
||||
}
|
||||
argsz = sizeof(struct sctp_getaddresses) +
|
||||
sizeof(struct sockaddr_storage);
|
||||
if ((gaddrs = (struct sctp_getaddresses *)malloc(argsz)) == NULL) {
|
||||
@ -2472,6 +2473,27 @@ usrsctp_bindx(struct socket *so, struct sockaddr *addrs, int addrcnt, int flags)
|
||||
break;
|
||||
}
|
||||
memcpy(gaddrs->addr, sa, sa_len);
|
||||
/*
|
||||
* Now, if there was a port mentioned, assure that the
|
||||
* first address has that port to make sure it fails or
|
||||
* succeeds correctly.
|
||||
*/
|
||||
if ((i == 0) && (sport != 0)) {
|
||||
switch (gaddrs->addr->sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
sin = (struct sockaddr_in *)gaddrs->addr;
|
||||
sin->sin_port = sport;
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *)gaddrs->addr;
|
||||
sin6->sin6_port = sport;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (usrsctp_setsockopt(so, IPPROTO_SCTP, flags, gaddrs, (socklen_t)argsz) != 0) {
|
||||
free(gaddrs);
|
||||
return (-1);
|
||||
@ -2488,6 +2510,7 @@ usrsctp_connectx(struct socket *so,
|
||||
const struct sockaddr *addrs, int addrcnt,
|
||||
sctp_assoc_t *id)
|
||||
{
|
||||
#if defined(INET) || defined(INET6)
|
||||
char buf[SCTP_STACK_BUF_SIZE];
|
||||
int i, ret, cnt, *aa;
|
||||
char *cpto;
|
||||
@ -2564,6 +2587,10 @@ usrsctp_connectx(struct socket *so,
|
||||
*id = *p_id;
|
||||
}
|
||||
return (ret);
|
||||
#else
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
@ -2780,6 +2807,8 @@ sctp_userspace_ip_output(int *result, struct mbuf *o_pak,
|
||||
ip = mtod(m, struct ip *);
|
||||
}
|
||||
udp = (struct udphdr *)(ip + 1);
|
||||
} else {
|
||||
udp = NULL;
|
||||
}
|
||||
|
||||
if (!use_udp_tunneling) {
|
||||
@ -2936,6 +2965,8 @@ void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak,
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
}
|
||||
udp = (struct udphdr *)(ip6 + 1);
|
||||
} else {
|
||||
udp = NULL;
|
||||
}
|
||||
|
||||
if (!use_udp_tunneling) {
|
||||
@ -3160,6 +3191,8 @@ usrsctp_conninput(void *addr, const void *buffer, size_t length, uint8_t ecn_bit
|
||||
struct sctphdr *sh;
|
||||
struct sctp_chunkhdr *ch;
|
||||
|
||||
SCTP_STAT_INCR(sctps_recvpackets);
|
||||
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
|
||||
memset(&src, 0, sizeof(struct sockaddr_conn));
|
||||
src.sconn_family = AF_CONN;
|
||||
#ifdef HAVE_SCONN_LEN
|
||||
@ -3195,6 +3228,9 @@ usrsctp_conninput(void *addr, const void *buffer, size_t length, uint8_t ecn_bit
|
||||
#endif
|
||||
ecn_bits,
|
||||
SCTP_DEFAULT_VRFID, 0);
|
||||
if (m) {
|
||||
sctp_m_freem(m);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3210,7 +3246,9 @@ 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_strict_sacks)
|
||||
#if !defined(SCTP_WITH_NO_CSUM)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_no_csum_on_loopback)
|
||||
#endif
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_peer_chunk_oh)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_max_burst_default)
|
||||
USRSCTP_SYSCTL_SET_DEF(sctp_max_chunks_on_queue)
|
||||
@ -3286,7 +3324,9 @@ 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_strict_sacks)
|
||||
#if !defined(SCTP_WITH_NO_CSUM)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_no_csum_on_loopback)
|
||||
#endif
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_peer_chunk_oh)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_max_burst_default)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_max_chunks_on_queue)
|
||||
@ -3351,3 +3391,7 @@ USRSCTP_SYSCTL_GET_DEF(sctp_initial_cwnd)
|
||||
USRSCTP_SYSCTL_GET_DEF(sctp_debug_on)
|
||||
#endif
|
||||
|
||||
void usrsctp_get_stat(struct sctpstat *stat)
|
||||
{
|
||||
*stat = SCTP_BASE_STATS;
|
||||
}
|
||||
|
@ -37,17 +37,12 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if defined(ANDROID)
|
||||
/* Android bionic libc is missing some defines in sys/types.h. Pick them
|
||||
* up elsewhere */
|
||||
#include <linux/coda.h>
|
||||
#endif
|
||||
|
||||
/* #include <sys/selinfo.h> */ /*__Userspace__ alternative?*/ /* for struct selinfo */
|
||||
/* #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_Windows) && !defined(__Userspace_os_FreeBSD)
|
||||
#if !defined(__Userspace_os_DragonFly) && !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_NetBSD) && !defined(__Userspace_os_Windows)
|
||||
#include <sys/uio.h>
|
||||
#endif
|
||||
#define SOCK_MAXADDRLEN 255
|
||||
@ -59,16 +54,16 @@
|
||||
#define SS_CANTRCVMORE 0x020
|
||||
#define SS_CANTSENDMORE 0x010
|
||||
|
||||
#if defined (__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) || defined(__Userspace_os_Darwin) || 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)
|
||||
#define UIO_MAXIOV 1024
|
||||
#define ERESTART (-1)
|
||||
#endif
|
||||
|
||||
#if !defined(__Userspace_os_Darwin) && !defined(__Userspace_os_OpenBSD)
|
||||
#if !defined(__Userspace_os_Darwin) && !defined(__Userspace_os_NetBSD) && !defined(__Userspace_os_OpenBSD)
|
||||
enum uio_rw { UIO_READ, UIO_WRITE };
|
||||
#endif
|
||||
|
||||
#if !defined(__Userspace_os_OpenBSD)
|
||||
#if !defined(__Userspace_os_NetBSD) && !defined(__Userspace_os_OpenBSD)
|
||||
/* Segment flag values. */
|
||||
enum uio_seg {
|
||||
UIO_USERSPACE, /* from user data space */
|
||||
@ -107,7 +102,6 @@ struct uio {
|
||||
*/
|
||||
#if defined (__Userspace_os_Windows)
|
||||
#define AF_ROUTE 17
|
||||
typedef __int32 u_quad_t;
|
||||
typedef __int32 pid_t;
|
||||
typedef unsigned __int32 uid_t;
|
||||
enum sigType {
|
||||
@ -116,7 +110,6 @@ enum sigType {
|
||||
MAX_EVENTS = 2
|
||||
};
|
||||
#endif
|
||||
typedef u_quad_t so_gen_t;
|
||||
|
||||
/*-
|
||||
* Locking key to struct socket:
|
||||
@ -220,7 +213,7 @@ struct socket {
|
||||
struct label *so_label; /* (b) MAC label for socket */
|
||||
struct label *so_peerlabel; /* (b) cached MAC label for peer */
|
||||
/* NB: generation count must not be first. */
|
||||
so_gen_t so_gencnt; /* (h) generation count */
|
||||
uint32_t so_gencnt; /* (h) generation count */
|
||||
void *so_emuldata; /* (b) private data for emulators */
|
||||
struct so_accf {
|
||||
struct accept_filter *so_accept_filter;
|
||||
@ -255,6 +248,7 @@ extern userland_cond_t accept_cond;
|
||||
#define ACCEPT_UNLOCK_ASSERT()
|
||||
#else
|
||||
extern userland_mutex_t accept_mtx;
|
||||
extern userland_cond_t accept_cond;
|
||||
#define ACCEPT_LOCK_ASSERT() KASSERT(pthread_mutex_trylock(&accept_mtx) == EBUSY, ("%s: accept_mtx not locked", __func__))
|
||||
#define ACCEPT_LOCK() (void)pthread_mutex_lock(&accept_mtx)
|
||||
#define ACCEPT_UNLOCK() (void)pthread_mutex_unlock(&accept_mtx)
|
||||
@ -743,7 +737,7 @@ void socantsendmore(struct socket *so);
|
||||
|
||||
/* can we read something from so? */
|
||||
#define soreadable(so) \
|
||||
((so)->so_rcv.sb_cc >= (so)->so_rcv.sb_lowat || \
|
||||
((int)((so)->so_rcv.sb_cc) >= (so)->so_rcv.sb_lowat || \
|
||||
((so)->so_rcv.sb_state & SBS_CANTRCVMORE) || \
|
||||
!TAILQ_EMPTY(&(so)->so_comp) || (so)->so_error)
|
||||
|
||||
|
@ -37,10 +37,11 @@ extern "C" {
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4200)
|
||||
#endif
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <ws2ipdef.h>
|
||||
#include <ws2def.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
@ -991,7 +992,9 @@ USRSCTP_SYSCTL_DECL(sctp_auto_asconf)
|
||||
USRSCTP_SYSCTL_DECL(sctp_multiple_asconfs)
|
||||
USRSCTP_SYSCTL_DECL(sctp_ecn_enable)
|
||||
USRSCTP_SYSCTL_DECL(sctp_strict_sacks)
|
||||
#if !defined(SCTP_WITH_NO_CSUM)
|
||||
USRSCTP_SYSCTL_DECL(sctp_no_csum_on_loopback)
|
||||
#endif
|
||||
USRSCTP_SYSCTL_DECL(sctp_peer_chunk_oh)
|
||||
USRSCTP_SYSCTL_DECL(sctp_max_burst_default)
|
||||
USRSCTP_SYSCTL_DECL(sctp_max_chunks_on_queue)
|
||||
@ -1016,6 +1019,7 @@ USRSCTP_SYSCTL_DECL(sctp_init_rtx_max_default)
|
||||
USRSCTP_SYSCTL_DECL(sctp_assoc_rtx_max_default)
|
||||
USRSCTP_SYSCTL_DECL(sctp_path_rtx_max_default)
|
||||
USRSCTP_SYSCTL_DECL(sctp_add_more_threshold)
|
||||
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)
|
||||
@ -1061,6 +1065,166 @@ USRSCTP_SYSCTL_DECL(sctp_debug_on)
|
||||
#define SCTP_DEBUG_ALL 0xffffffff
|
||||
#endif
|
||||
#undef USRSCTP_SYSCTL_DECL
|
||||
struct sctp_timeval {
|
||||
uint32_t tv_sec;
|
||||
uint32_t tv_usec;
|
||||
};
|
||||
|
||||
struct sctpstat {
|
||||
struct sctp_timeval sctps_discontinuitytime; /* sctpStats 18 (TimeStamp) */
|
||||
/* MIB according to RFC 3873 */
|
||||
uint32_t sctps_currestab; /* sctpStats 1 (Gauge32) */
|
||||
uint32_t sctps_activeestab; /* sctpStats 2 (Counter32) */
|
||||
uint32_t sctps_restartestab;
|
||||
uint32_t sctps_collisionestab;
|
||||
uint32_t sctps_passiveestab; /* sctpStats 3 (Counter32) */
|
||||
uint32_t sctps_aborted; /* sctpStats 4 (Counter32) */
|
||||
uint32_t sctps_shutdown; /* sctpStats 5 (Counter32) */
|
||||
uint32_t sctps_outoftheblue; /* sctpStats 6 (Counter32) */
|
||||
uint32_t sctps_checksumerrors; /* sctpStats 7 (Counter32) */
|
||||
uint32_t sctps_outcontrolchunks; /* sctpStats 8 (Counter64) */
|
||||
uint32_t sctps_outorderchunks; /* sctpStats 9 (Counter64) */
|
||||
uint32_t sctps_outunorderchunks; /* sctpStats 10 (Counter64) */
|
||||
uint32_t sctps_incontrolchunks; /* sctpStats 11 (Counter64) */
|
||||
uint32_t sctps_inorderchunks; /* sctpStats 12 (Counter64) */
|
||||
uint32_t sctps_inunorderchunks; /* sctpStats 13 (Counter64) */
|
||||
uint32_t sctps_fragusrmsgs; /* sctpStats 14 (Counter64) */
|
||||
uint32_t sctps_reasmusrmsgs; /* sctpStats 15 (Counter64) */
|
||||
uint32_t sctps_outpackets; /* sctpStats 16 (Counter64) */
|
||||
uint32_t sctps_inpackets; /* sctpStats 17 (Counter64) */
|
||||
|
||||
/* input statistics: */
|
||||
uint32_t sctps_recvpackets; /* total input packets */
|
||||
uint32_t sctps_recvdatagrams; /* total input datagrams */
|
||||
uint32_t sctps_recvpktwithdata; /* total packets that had data */
|
||||
uint32_t sctps_recvsacks; /* total input SACK chunks */
|
||||
uint32_t sctps_recvdata; /* total input DATA chunks */
|
||||
uint32_t sctps_recvdupdata; /* total input duplicate DATA chunks */
|
||||
uint32_t sctps_recvheartbeat; /* total input HB chunks */
|
||||
uint32_t sctps_recvheartbeatack; /* total input HB-ACK chunks */
|
||||
uint32_t sctps_recvecne; /* total input ECNE chunks */
|
||||
uint32_t sctps_recvauth; /* total input AUTH chunks */
|
||||
uint32_t sctps_recvauthmissing; /* total input chunks missing AUTH */
|
||||
uint32_t sctps_recvivalhmacid; /* total number of invalid HMAC ids received */
|
||||
uint32_t sctps_recvivalkeyid; /* total number of invalid secret ids received */
|
||||
uint32_t sctps_recvauthfailed; /* total number of auth failed */
|
||||
uint32_t sctps_recvexpress; /* total fast path receives all one chunk */
|
||||
uint32_t sctps_recvexpressm; /* total fast path multi-part data */
|
||||
uint32_t sctps_recvnocrc;
|
||||
uint32_t sctps_recvswcrc;
|
||||
uint32_t sctps_recvhwcrc;
|
||||
|
||||
/* output statistics: */
|
||||
uint32_t sctps_sendpackets; /* total output packets */
|
||||
uint32_t sctps_sendsacks; /* total output SACKs */
|
||||
uint32_t sctps_senddata; /* total output DATA chunks */
|
||||
uint32_t sctps_sendretransdata; /* total output retransmitted DATA chunks */
|
||||
uint32_t sctps_sendfastretrans; /* total output fast retransmitted DATA chunks */
|
||||
uint32_t sctps_sendmultfastretrans; /* total FR's that happened more than once
|
||||
* to same chunk (u-del multi-fr algo).
|
||||
*/
|
||||
uint32_t sctps_sendheartbeat; /* total output HB chunks */
|
||||
uint32_t sctps_sendecne; /* total output ECNE chunks */
|
||||
uint32_t sctps_sendauth; /* total output AUTH chunks FIXME */
|
||||
uint32_t sctps_senderrors; /* ip_output error counter */
|
||||
uint32_t sctps_sendnocrc;
|
||||
uint32_t sctps_sendswcrc;
|
||||
uint32_t sctps_sendhwcrc;
|
||||
/* PCKDROPREP statistics: */
|
||||
uint32_t sctps_pdrpfmbox; /* Packet drop from middle box */
|
||||
uint32_t sctps_pdrpfehos; /* P-drop from end host */
|
||||
uint32_t sctps_pdrpmbda; /* P-drops with data */
|
||||
uint32_t sctps_pdrpmbct; /* P-drops, non-data, non-endhost */
|
||||
uint32_t sctps_pdrpbwrpt; /* P-drop, non-endhost, bandwidth rep only */
|
||||
uint32_t sctps_pdrpcrupt; /* P-drop, not enough for chunk header */
|
||||
uint32_t sctps_pdrpnedat; /* P-drop, not enough data to confirm */
|
||||
uint32_t sctps_pdrppdbrk; /* P-drop, where process_chunk_drop said break */
|
||||
uint32_t sctps_pdrptsnnf; /* P-drop, could not find TSN */
|
||||
uint32_t sctps_pdrpdnfnd; /* P-drop, attempt reverse TSN lookup */
|
||||
uint32_t sctps_pdrpdiwnp; /* P-drop, e-host confirms zero-rwnd */
|
||||
uint32_t sctps_pdrpdizrw; /* P-drop, midbox confirms no space */
|
||||
uint32_t sctps_pdrpbadd; /* P-drop, data did not match TSN */
|
||||
uint32_t sctps_pdrpmark; /* P-drop, TSN's marked for Fast Retran */
|
||||
/* timeouts */
|
||||
uint32_t sctps_timoiterator; /* Number of iterator timers that fired */
|
||||
uint32_t sctps_timodata; /* Number of T3 data time outs */
|
||||
uint32_t sctps_timowindowprobe; /* Number of window probe (T3) timers that fired */
|
||||
uint32_t sctps_timoinit; /* Number of INIT timers that fired */
|
||||
uint32_t sctps_timosack; /* Number of sack timers that fired */
|
||||
uint32_t sctps_timoshutdown; /* Number of shutdown timers that fired */
|
||||
uint32_t sctps_timoheartbeat; /* Number of heartbeat timers that fired */
|
||||
uint32_t sctps_timocookie; /* Number of times a cookie timeout fired */
|
||||
uint32_t sctps_timosecret; /* Number of times an endpoint changed its cookie secret*/
|
||||
uint32_t sctps_timopathmtu; /* Number of PMTU timers that fired */
|
||||
uint32_t sctps_timoshutdownack; /* Number of shutdown ack timers that fired */
|
||||
uint32_t sctps_timoshutdownguard; /* Number of shutdown guard timers that fired */
|
||||
uint32_t sctps_timostrmrst; /* Number of stream reset timers that fired */
|
||||
uint32_t sctps_timoearlyfr; /* Number of early FR timers that fired */
|
||||
uint32_t sctps_timoasconf; /* Number of times an asconf timer fired */
|
||||
uint32_t sctps_timodelprim; /* Number of times a prim_deleted timer fired */
|
||||
uint32_t sctps_timoautoclose; /* Number of times auto close timer fired */
|
||||
uint32_t sctps_timoassockill; /* Number of asoc free timers expired */
|
||||
uint32_t sctps_timoinpkill; /* Number of inp free timers expired */
|
||||
/* former early FR counters */
|
||||
uint32_t sctps_spare[11];
|
||||
/* others */
|
||||
uint32_t sctps_hdrops; /* packet shorter than header */
|
||||
uint32_t sctps_badsum; /* checksum error */
|
||||
uint32_t sctps_noport; /* no endpoint for port */
|
||||
uint32_t sctps_badvtag; /* bad v-tag */
|
||||
uint32_t sctps_badsid; /* bad SID */
|
||||
uint32_t sctps_nomem; /* no memory */
|
||||
uint32_t sctps_fastretransinrtt; /* number of multiple FR in a RTT window */
|
||||
uint32_t sctps_markedretrans;
|
||||
uint32_t sctps_naglesent; /* nagle allowed sending */
|
||||
uint32_t sctps_naglequeued; /* nagle doesn't allow sending */
|
||||
uint32_t sctps_maxburstqueued; /* max burst doesn't allow sending */
|
||||
uint32_t sctps_ifnomemqueued; /* look ahead tells us no memory in
|
||||
* interface ring buffer OR we had a
|
||||
* send error and are queuing one send.
|
||||
*/
|
||||
uint32_t sctps_windowprobed; /* total number of window probes sent */
|
||||
uint32_t sctps_lowlevelerr; /* total times an output error causes us
|
||||
* to clamp down on next user send.
|
||||
*/
|
||||
uint32_t sctps_lowlevelerrusr; /* total times sctp_senderrors were caused from
|
||||
* a user send from a user invoked send not
|
||||
* a sack response
|
||||
*/
|
||||
uint32_t sctps_datadropchklmt; /* Number of in data drops due to chunk limit reached */
|
||||
uint32_t sctps_datadroprwnd; /* Number of in data drops due to rwnd limit reached */
|
||||
uint32_t sctps_ecnereducedcwnd; /* Number of times a ECN reduced the cwnd */
|
||||
uint32_t sctps_vtagexpress; /* Used express lookup via vtag */
|
||||
uint32_t sctps_vtagbogus; /* Collision in express lookup. */
|
||||
uint32_t sctps_primary_randry; /* Number of times the sender ran dry of user data on primary */
|
||||
uint32_t sctps_cmt_randry; /* Same for above */
|
||||
uint32_t sctps_slowpath_sack; /* Sacks the slow way */
|
||||
uint32_t sctps_wu_sacks_sent; /* Window Update only sacks sent */
|
||||
uint32_t sctps_sends_with_flags; /* number of sends with sinfo_flags !=0 */
|
||||
uint32_t sctps_sends_with_unord; /* number of unordered sends */
|
||||
uint32_t sctps_sends_with_eof; /* number of sends with EOF flag set */
|
||||
uint32_t sctps_sends_with_abort; /* number of sends with ABORT flag set */
|
||||
uint32_t sctps_protocol_drain_calls;/* number of times protocol drain called */
|
||||
uint32_t sctps_protocol_drains_done;/* number of times we did a protocol drain */
|
||||
uint32_t sctps_read_peeks; /* Number of times recv was called with peek */
|
||||
uint32_t sctps_cached_chk; /* Number of cached chunks used */
|
||||
uint32_t sctps_cached_strmoq; /* Number of cached stream oq's used */
|
||||
uint32_t sctps_left_abandon; /* Number of unread messages abandoned by close */
|
||||
uint32_t sctps_send_burst_avoid; /* Unused */
|
||||
uint32_t sctps_send_cwnd_avoid; /* Send cwnd full avoidance, already max burst inflight to net */
|
||||
uint32_t sctps_fwdtsn_map_over; /* number of map array over-runs via fwd-tsn's */
|
||||
uint32_t sctps_queue_upd_ecne; /* Number of times we queued or updated an ECN chunk on send queue */
|
||||
uint32_t sctps_reserved[31]; /* Future ABI compat - remove int's from here when adding new */
|
||||
};
|
||||
|
||||
void
|
||||
usrsctp_get_stat(struct sctpstat *);
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(default: 4200)
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user