Bug 916427: netwerk/sctp/src updated to version 8815 from SVN on Tue Mar 4 2014 rs=jesup,tuexen

This commit is contained in:
Randell Jesup 2014-03-12 02:09:31 -04:00
parent 677c6954d4
commit 9fb16ab802
44 changed files with 1513 additions and 1790 deletions

View File

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

View File

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

View File

@ -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);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 */
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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);
}
}
}

View File

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

View File

@ -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() \

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 *));

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 *));

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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