a) macro-ization of all mbuf and random number

access plus timers. This makes the code
   more portable and able to change out the
   mbuf or timer system used more easily ;-)
b) removal of all use of pkt-hdr's until only
   the places we need them (before ip_output routines).
c) remove a bunch of code not needed due to <b> aka
   worrying about pkthdr's :-)
d) There was one last reorder problem it looks where
   if a restart occur's and we release and relock (at
   the point where we setup our alias vtag) we would
   end up possibly getting the wrong TSN in place. The
   code that fixed the TSN's just needed to be shifted
   around BEFORE the release of the lock.. also code that
   set the state (since this also could contribute).
Approved by:	gnn
This commit is contained in:
Randall Stewart 2006-12-29 20:21:42 +00:00
parent c441d123ef
commit 139bc87fda
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=165647
17 changed files with 1222 additions and 1341 deletions

View File

@ -178,7 +178,7 @@ sctp_asconf_success_response(uint32_t id)
aph->correlation_id = id;
aph->ph.param_type = htons(SCTP_SUCCESS_REPORT);
aph->ph.param_length = sizeof(struct sctp_asconf_paramhdr);
m_reply->m_len = aph->ph.param_length;
SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
aph->ph.param_length = htons(aph->ph.param_length);
return m_reply;
@ -229,7 +229,7 @@ sctp_asconf_error_response(uint32_t id, uint16_t cause, uint8_t * error_tlv,
tlv = (uint8_t *) (error + 1);
memcpy(tlv, error_tlv, tlv_length);
}
m_reply->m_len = aph->ph.param_length;
SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
error->length = htons(error->length);
aph->ph.param_length = htons(aph->ph.param_length);
@ -327,7 +327,7 @@ sctp_process_asconf_add_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
} /* end switch */
/* if 0.0.0.0/::0, add the source address instead */
if (zero_address) {
if (zero_address && sctp_nat_friendly) {
sa = (struct sockaddr *)&sa_source;
sctp_asconf_get_source_ip(m, sa);
#ifdef SCTP_DEBUG
@ -500,7 +500,7 @@ sctp_process_asconf_delete_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
return m_reply;
}
/* if deleting 0.0.0.0/::0, delete all addresses except src addr */
if (zero_address) {
if (zero_address && sctp_nat_friendly) {
result = sctp_asconf_del_remote_addrs_except(stcb,
(struct sockaddr *)&sa_source);
@ -637,7 +637,7 @@ sctp_process_asconf_set_primary(struct mbuf *m,
}
/* if 0.0.0.0/::0, use the source address instead */
if (zero_address) {
if (zero_address && sctp_nat_friendly) {
sa = (struct sockaddr *)&sa_source;
sctp_asconf_get_source_ip(m, sa);
#ifdef SCTP_DEBUG
@ -744,7 +744,7 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
sctp_m_freem(asoc->last_asconf_ack_sent);
asoc->last_asconf_ack_sent = NULL;
}
m_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_ack_chunk), 1,
m_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_ack_chunk), 0,
M_DONTWAIT, 1, MT_DATA);
if (m_ack == NULL) {
#ifdef SCTP_DEBUG
@ -762,9 +762,8 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
ack_cp->ch.chunk_flags = 0;
ack_cp->serial_number = htonl(serial_num);
/* set initial lengths (eg. just an ASCONF-ACK), ntohx at the end! */
m_ack->m_len = sizeof(struct sctp_asconf_ack_chunk);
SCTP_BUF_LEN(m_ack) = sizeof(struct sctp_asconf_ack_chunk);
ack_cp->ch.chunk_length = sizeof(struct sctp_asconf_ack_chunk);
m_ack->m_pkthdr.len = sizeof(struct sctp_asconf_ack_chunk);
/* skip the lookup address parameter */
offset += sizeof(struct sctp_asconf_chunk);
@ -881,12 +880,11 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
/* add any (error) result to the reply mbuf chain */
if (m_result != NULL) {
m_tail->m_next = m_result;
SCTP_BUF_NEXT(m_tail) = m_result;
m_tail = m_result;
/* update lengths, make sure it's aligned too */
m_result->m_len = SCTP_SIZE32(m_result->m_len);
m_ack->m_pkthdr.len += m_result->m_len;
ack_cp->ch.chunk_length += m_result->m_len;
SCTP_BUF_LEN(m_result) = SCTP_SIZE32(SCTP_BUF_LEN(m_result));
ack_cp->ch.chunk_length += SCTP_BUF_LEN(m_result);
/* set flag to force success reports */
error = 1;
}
@ -2245,7 +2243,7 @@ sctp_find_valid_localaddr_ep(struct sctp_tcb *stcb)
* mbuf, no ASCONF params queued, etc)
*/
struct mbuf *
sctp_compose_asconf(struct sctp_tcb *stcb)
sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen)
{
struct mbuf *m_asconf, *m_asconf_chk;
struct sctp_asconf_addr *aa;
@ -2266,7 +2264,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb)
* it's simpler to fill in the asconf chunk header lookup address on
* the fly
*/
m_asconf_chk = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_chunk), 1, M_DONTWAIT, 1, MT_DATA);
m_asconf_chk = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_chunk), 0, M_DONTWAIT, 1, MT_DATA);
if (m_asconf_chk == NULL) {
/* no mbuf's */
#ifdef SCTP_DEBUG
@ -2275,7 +2273,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb)
#endif /* SCTP_DEBUG */
return (NULL);
}
m_asconf = sctp_get_mbuf_for_msg(MCLBYTES, 1, M_DONTWAIT, 1, MT_DATA);
m_asconf = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
if (m_asconf == NULL) {
/* no mbuf's */
#ifdef SCTP_DEBUG
@ -2285,8 +2283,8 @@ sctp_compose_asconf(struct sctp_tcb *stcb)
sctp_m_freem(m_asconf_chk);
return (NULL);
}
m_asconf_chk->m_len = sizeof(struct sctp_asconf_chunk);
m_asconf->m_len = 0;
SCTP_BUF_LEN(m_asconf_chk) = sizeof(struct sctp_asconf_chunk);
SCTP_BUF_LEN(m_asconf) = 0;
acp = mtod(m_asconf_chk, struct sctp_asconf_chunk *);
bzero(acp, sizeof(struct sctp_asconf_chunk));
/* save pointers to lookup address and asconf params */
@ -2303,7 +2301,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb)
/* get the parameter length */
p_length = SCTP_SIZE32(aa->ap.aph.ph.param_length);
/* will it fit in current chunk? */
if (m_asconf->m_len + p_length > stcb->asoc.smallest_mtu) {
if (SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu) {
/* won't fit, so we're done with this chunk */
break;
}
@ -2336,7 +2334,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb)
}
lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
memcpy(lookup->addr, &aa->ap.addrp.addr, addr_size);
m_asconf_chk->m_len += SCTP_SIZE32(p_size);
SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size);
lookup_used = 1;
}
/* copy into current space */
@ -2351,7 +2349,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb)
aap->addrp.ph.param_type = htons(aap->addrp.ph.param_type);
aap->addrp.ph.param_length = htons(aap->addrp.ph.param_length);
m_asconf->m_len += SCTP_SIZE32(p_length);
SCTP_BUF_LEN(m_asconf) += SCTP_SIZE32(p_length);
ptr += SCTP_SIZE32(p_length);
/*
@ -2395,7 +2393,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb)
}
lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
memcpy(lookup->addr, addr_ptr, addr_size);
m_asconf_chk->m_len += SCTP_SIZE32(p_size);
SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size);
lookup_used = 1;
} else {
/* uh oh... don't have any address?? */
@ -2407,14 +2405,13 @@ sctp_compose_asconf(struct sctp_tcb *stcb)
lookup->ph.param_type = htons(SCTP_IPV4_ADDRESS);
lookup->ph.param_length = htons(SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param)));
bzero(lookup->addr, sizeof(struct in_addr));
m_asconf_chk->m_len += SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param));
SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param));
lookup_used = 1;
}
}
/* chain it all together */
m_asconf_chk->m_next = m_asconf;
m_asconf_chk->m_pkthdr.len = m_asconf_chk->m_len + m_asconf->m_len;
acp->ch.chunk_length = ntohs(m_asconf_chk->m_pkthdr.len);
SCTP_BUF_NEXT(m_asconf_chk) = m_asconf;
*retlen = acp->ch.chunk_length = ntohs(SCTP_BUF_LEN(m_asconf_chk) + SCTP_BUF_LEN(m_asconf));
/* update "sent" flag */
stcb->asoc.asconf_sent++;

View File

@ -36,16 +36,17 @@ __FBSDID("$FreeBSD$");
#ifndef _NETINET_SCTP_ASCONF_H_
#define _NETINET_SCTP_ASCONF_H_
#include <sys/malloc.h>
#if defined(_KERNEL)
/*
* function prototypes
*/
extern void sctp_asconf_cleanup(struct sctp_tcb *, struct sctp_nets *);
extern struct mbuf *sctp_compose_asconf(struct sctp_tcb *);
extern struct mbuf *sctp_compose_asconf(struct sctp_tcb *, int *);
extern void
sctp_handle_asconf(struct mbuf *, unsigned int, struct sctp_asconf_chunk *,

View File

@ -372,7 +372,7 @@ sctp_generate_random_key(uint32_t keylen)
/* out of memory */
return (NULL);
}
sctp_read_random(new_key->key, keylen);
SCTP_READ_RANDOM(new_key->key, keylen);
new_key->keylen = keylen;
return (new_key);
}
@ -1110,17 +1110,18 @@ sctp_hmac_m(uint16_t hmac_algo, uint8_t * key, uint32_t keylen,
sctp_hmac_update(hmac_algo, &ctx, ipad, blocklen);
/* find the correct starting mbuf and offset (get start of text) */
m_tmp = m;
while ((m_tmp != NULL) && (m_offset >= (uint32_t) m_tmp->m_len)) {
m_offset -= m_tmp->m_len;
m_tmp = m_tmp->m_next;
while ((m_tmp != NULL) && (m_offset >= (uint32_t) SCTP_BUF_LEN(m_tmp))) {
m_offset -= SCTP_BUF_LEN(m_tmp);
m_tmp = SCTP_BUF_NEXT(m_tmp);
}
/* now use the rest of the mbuf chain for the text */
while (m_tmp != NULL) {
sctp_hmac_update(hmac_algo, &ctx, mtod(m_tmp, uint8_t *) + m_offset,
m_tmp->m_len - m_offset);
SCTP_BUF_LEN(m_tmp) - m_offset);
/* clear the offset since it's only for the first mbuf */
m_offset = 0;
m_tmp = m_tmp->m_next;
m_tmp = SCTP_BUF_NEXT(m_tmp);
}
sctp_hmac_final(hmac_algo, &ctx, temp);
@ -1618,23 +1619,23 @@ sctp_bzero_m(struct mbuf *m, uint32_t m_offset, uint32_t size)
/* find the correct starting mbuf and offset (get start position) */
m_tmp = m;
while ((m_tmp != NULL) && (m_offset >= (uint32_t) m_tmp->m_len)) {
m_offset -= m_tmp->m_len;
m_tmp = m_tmp->m_next;
while ((m_tmp != NULL) && (m_offset >= (uint32_t) SCTP_BUF_LEN(m_tmp))) {
m_offset -= SCTP_BUF_LEN(m_tmp);
m_tmp = SCTP_BUF_NEXT(m_tmp);
}
/* now use the rest of the mbuf chain */
while ((m_tmp != NULL) && (size > 0)) {
data = mtod(m_tmp, uint8_t *) + m_offset;
if (size > (uint32_t) m_tmp->m_len) {
bzero(data, m_tmp->m_len);
size -= m_tmp->m_len;
if (size > (uint32_t) SCTP_BUF_LEN(m_tmp)) {
bzero(data, SCTP_BUF_LEN(m_tmp));
size -= SCTP_BUF_LEN(m_tmp);
} else {
bzero(data, size);
size = 0;
}
/* clear the offset since it's only for the first mbuf */
m_offset = 0;
m_tmp = m_tmp->m_next;
m_tmp = SCTP_BUF_NEXT(m_tmp);
}
}
@ -1685,17 +1686,17 @@ sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *auth,
* report this in an Error Chunk: Unsupported HMAC
* Identifier
*/
m_err = sctp_get_mbuf_for_msg(sizeof(*err), 1, M_DONTWAIT, 1, MT_HEADER);
m_err = sctp_get_mbuf_for_msg(sizeof(*err), 0, M_DONTWAIT, 1, MT_HEADER);
if (m_err != NULL) {
/* pre-reserve some space */
m_err->m_data += sizeof(struct sctp_chunkhdr);
SCTP_BUF_RESV_UF(m_err, sizeof(struct sctp_chunkhdr));
/* fill in the error */
err = mtod(m_err, struct sctp_auth_invalid_hmac *);
bzero(err, sizeof(*err));
err->ph.param_type = htons(SCTP_CAUSE_UNSUPPORTED_HMACID);
err->ph.param_length = htons(sizeof(*err));
err->hmac_id = ntohs(hmac_id);
m_err->m_pkthdr.len = m_err->m_len = sizeof(*err);
SCTP_BUF_LEN(m_err) = sizeof(*err);
/* queue it */
sctp_queue_op_err(stcb, m_err);
}
@ -1787,11 +1788,12 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
return;
m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_authkey_event),
1, M_DONTWAIT, 1, MT_HEADER);
0, M_DONTWAIT, 1, MT_HEADER);
if (m_notify == NULL)
/* no space left */
return;
m_notify->m_len = 0;
SCTP_BUF_LEN(m_notify) = 0;
auth = mtod(m_notify, struct sctp_authkey_event *);
auth->auth_type = SCTP_AUTHENTICATION_EVENT;
auth->auth_flags = 0;
@ -1801,11 +1803,8 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
auth->auth_indication = indication;
auth->auth_assoc_id = sctp_get_associd(stcb);
m_notify->m_flags |= M_EOR | M_NOTIFICATION;
m_notify->m_pkthdr.len = sizeof(*auth);
m_notify->m_pkthdr.rcvif = 0;
m_notify->m_len = sizeof(*auth);
m_notify->m_next = NULL;
SCTP_BUF_LEN(m_notify) = sizeof(*auth);
SCTP_BUF_NEXT(m_notify) = NULL;
/* append to socket */
control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
@ -1815,7 +1814,8 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
sctp_m_freem(m_notify);
return;
}
control->length = m_notify->m_len;
control->spec_flags = M_NOTIFICATION;
control->length = SCTP_BUF_LEN(m_notify);
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb, control,
@ -1969,7 +1969,7 @@ sctp_initialize_auth_params(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
new_key = sctp_alloc_key(keylen);
if (new_key != NULL) {
/* generate and copy in the RANDOM */
sctp_read_random(new_key->key, random_len);
SCTP_READ_RANDOM(new_key->key, random_len);
keylen = random_len;
/* append in the AUTH chunks */
if (stcb->asoc.local_auth_chunks) {

View File

@ -1873,23 +1873,22 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct ifaddr *ifa)
/* unknown type */
return (m);
}
if (M_TRAILINGSPACE(m) >= len) {
/* easy side we just drop it on the end */
parmh = (struct sctp_paramhdr *)(m->m_data + m->m_len);
parmh = (struct sctp_paramhdr *)(SCTP_BUF_AT(m, SCTP_BUF_LEN(m)));
mret = m;
} else {
/* Need more space */
mret = m;
while (mret->m_next != NULL) {
mret = mret->m_next;
while (SCTP_BUF_NEXT(mret) != NULL) {
mret = SCTP_BUF_NEXT(mret);
}
mret->m_next = sctp_get_mbuf_for_msg(len, 0, M_DONTWAIT, 1, MT_DATA);
if (mret->m_next == NULL) {
SCTP_BUF_NEXT(mret) = sctp_get_mbuf_for_msg(len, 0, M_DONTWAIT, 1, MT_DATA);
if (SCTP_BUF_NEXT(mret) == NULL) {
/* We are hosed, can't add more addresses */
return (m);
}
mret = mret->m_next;
mret = SCTP_BUF_NEXT(mret);
parmh = mtod(mret, struct sctp_paramhdr *);
}
/* now add the parameter */
@ -1902,7 +1901,7 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct ifaddr *ifa)
parmh->param_type = htons(SCTP_IPV4_ADDRESS);
parmh->param_length = htons(len);
ipv4p->addr = sin->sin_addr.s_addr;
mret->m_len += len;
SCTP_BUF_LEN(mret) += len;
} else if (ifa->ifa_addr->sa_family == AF_INET6) {
struct sctp_ipv6addr_param *ipv6p;
struct sockaddr_in6 *sin6;
@ -1915,7 +1914,7 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct ifaddr *ifa)
sizeof(ipv6p->addr));
/* clear embedded scope in the address */
in6_clearscope((struct in6_addr *)ipv6p->addr);
mret->m_len += len;
SCTP_BUF_LEN(mret) += len;
} else {
return (m);
}

View File

@ -252,6 +252,7 @@ sctp_build_readq_entry(struct sctp_tcb *stcb,
read_queue_e->length = 0;
atomic_add_int(&net->ref_count, 1);
read_queue_e->data = dm;
read_queue_e->spec_flags = 0;
read_queue_e->tail_mbuf = NULL;
read_queue_e->stcb = stcb;
read_queue_e->port_from = stcb->rport;
@ -292,6 +293,7 @@ sctp_build_readq_entry_chk(struct sctp_tcb *stcb,
read_queue_e->tail_mbuf = NULL;
read_queue_e->stcb = stcb;
read_queue_e->port_from = stcb->rport;
read_queue_e->spec_flags = 0;
read_queue_e->do_not_ref_stcb = 0;
read_queue_e->end_added = 0;
read_queue_e->pdapi_aborted = 0;
@ -323,7 +325,7 @@ sctp_build_ctl_nchunk(struct sctp_inpcb *inp,
ret = sctp_get_mbuf_for_msg(len,
1, M_DONTWAIT, 1, MT_DATA);
0, M_DONTWAIT, 1, MT_DATA);
if (ret == NULL) {
/* No space */
@ -342,11 +344,11 @@ sctp_build_ctl_nchunk(struct sctp_inpcb *inp,
cmh->cmsg_len = len;
*outinfo = *sinfo;
}
ret->m_len = cmh->cmsg_len;
ret->m_pkthdr.len = ret->m_len;
SCTP_BUF_LEN(ret) = cmh->cmsg_len;
return (ret);
}
/*
* We are delivering currently from the reassembly queue. We must continue to
* deliver until we either: 1) run out of space. 2) run out of sequential
@ -356,7 +358,6 @@ static void
sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc)
{
struct sctp_tmit_chunk *chk;
struct mbuf *m;
uint16_t nxt_todel;
uint16_t stream_no;
int end = 0;
@ -410,34 +411,6 @@ sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc)
*/
return;
}
if ((chk->data->m_flags & M_PKTHDR) == 0) {
m = sctp_get_mbuf_for_msg(1,
1, M_DONTWAIT, 1, MT_DATA);
if (m == NULL) {
/* no room! */
return;
}
m->m_pkthdr.len = chk->send_size;
m->m_len = 0;
m->m_next = chk->data;
chk->data = m;
}
if (chk->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
if (chk->data->m_next == NULL) {
/* hopefully we hit here most of the time */
chk->data->m_flags |= M_EOR;
} else {
/*
* Add the flag to the LAST mbuf in the
* chain
*/
m = chk->data;
while (m->m_next != NULL) {
m = m->m_next;
}
m->m_flags |= M_EOR;
}
}
if (chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) {
control = sctp_build_readq_entry_chk(stcb, chk);
@ -540,7 +513,7 @@ sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc)
nxt_todel = strm->last_sequence_delivered + 1;
}
}
return;
break;
}
chk = TAILQ_FIRST(&asoc->reasmqueue);
} while (chk);
@ -611,17 +584,17 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb, struct sctp_association *asoc,
* association destruction
*/
TAILQ_INSERT_HEAD(&strm->inqueue, control, next);
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len = sizeof(struct sctp_paramhdr) +
SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
(sizeof(uint32_t) * 3);
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length = htons(oper->m_len);
ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_1);
ippp++;
@ -789,6 +762,7 @@ sctp_deliver_reasm_check(struct sctp_tcb *stcb, struct sctp_association *asoc)
uint16_t nxt_todel;
uint32_t tsize;
doit_again:
chk = TAILQ_FIRST(&asoc->reasmqueue);
if (chk == NULL) {
/* Huh? */
@ -826,7 +800,20 @@ sctp_deliver_reasm_check(struct sctp_tcb *stcb, struct sctp_association *asoc)
}
}
} else {
/*
* Service re-assembly will deliver stream data queued at
* the end of fragmented delivery.. but it wont know to go
* back and call itself again... we do that here with the
* got doit_again
*/
sctp_service_reassembly(stcb, asoc);
if (asoc->fragmented_delivery_inprogress == 0) {
/*
* finished our Fragmented delivery, could be more
* waiting?
*/
goto doit_again;
}
}
}
@ -870,20 +857,20 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
printf("Gak, Evil plot, its not first, no fragmented delivery in progress\n");
}
#endif
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len =
SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(sizeof(uint32_t) * 3);
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length = htons(oper->m_len);
ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_2);
ippp++;
@ -908,19 +895,19 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
printf("Gak, Evil plot, it IS a first and fragmented delivery in progress\n");
}
#endif
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len =
SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length = htons(oper->m_len);
ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_3);
ippp++;
@ -947,13 +934,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
asoc->str_of_pdapi);
}
#endif
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len =
SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(sizeof(uint32_t) * 3);
ph = mtod(oper,
@ -961,7 +948,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
htons(oper->m_len);
htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_4);
ippp++;
@ -985,13 +972,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
asoc->ssn_of_pdapi);
}
#endif
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len =
SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@ -999,7 +986,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
htons(oper->m_len);
htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_5);
ippp++;
@ -1088,13 +1075,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
printf("Gak, Evil plot, it's a FIRST!\n");
}
#endif
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len =
SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@ -1102,7 +1089,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
htons(oper->m_len);
htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_6);
ippp++;
@ -1130,13 +1117,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
prev->rec.data.stream_number);
}
#endif
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len =
SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@ -1144,7 +1131,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
htons(oper->m_len);
htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_7);
ippp++;
@ -1173,13 +1160,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
prev->rec.data.stream_seq);
}
#endif
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len =
SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@ -1187,7 +1174,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
htons(oper->m_len);
htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_8);
ippp++;
@ -1212,13 +1199,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
printf("Prev check - Gak, evil plot, its not FIRST and it must be!\n");
}
#endif
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len =
SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@ -1226,7 +1213,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
htons(oper->m_len);
htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_9);
ippp++;
@ -1262,13 +1249,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
printf("Gak, Evil plot, its not a last!\n");
}
#endif
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len =
SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@ -1276,7 +1263,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
htons(oper->m_len);
htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_10);
ippp++;
@ -1307,13 +1294,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
printf("Gak, Evil plot, new prev chunk is a LAST\n");
}
#endif
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len =
SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@ -1321,7 +1308,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
htons(oper->m_len);
htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_11);
ippp++;
@ -1350,13 +1337,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
next->rec.data.stream_number);
}
#endif
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len =
SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@ -1364,7 +1351,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
htons(oper->m_len);
htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_12);
ippp++;
@ -1394,13 +1381,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
next->rec.data.stream_seq);
}
#endif
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len =
SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@ -1408,7 +1395,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
htons(oper->m_len);
htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_13);
ippp++;
@ -1506,6 +1493,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
uint32_t tsn, gap;
struct mbuf *dmbuf;
int indx, the_len;
int need_reasm_check = 0;
uint16_t strmno, strmseq;
struct mbuf *oper;
struct sctp_queued_to_read *control;
@ -1553,7 +1541,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
asoc->dup_tsns[asoc->numduptsns] = tsn;
asoc->numduptsns++;
}
if (!callout_pending(&asoc->dack_timer.timer)) {
if (!SCTP_OS_TIMER_PENDING(&asoc->dack_timer.timer)) {
/*
* By starting the timer we assure that we WILL sack
* at the end of the packet when sctp_sack_check
@ -1634,18 +1622,17 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
struct mbuf *mb;
mb = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) * 2),
1, M_DONTWAIT, 1, MT_DATA);
0, M_DONTWAIT, 1, MT_DATA);
if (mb != NULL) {
/* add some space up front so prepend will work well */
mb->m_data += sizeof(struct sctp_chunkhdr);
SCTP_BUF_RESV_UF(mb, sizeof(struct sctp_chunkhdr));
phdr = mtod(mb, struct sctp_paramhdr *);
/*
* Error causes are just param's and this one has
* two back to back phdr, one with the error type
* and size, the other with the streamid and a rsvd
*/
mb->m_pkthdr.len = mb->m_len =
(sizeof(struct sctp_paramhdr) * 2);
SCTP_BUF_LEN(mb) = (sizeof(struct sctp_paramhdr) * 2);
phdr->param_type = htons(SCTP_CAUSE_INVALID_STREAM);
phdr->param_length =
htons(sizeof(struct sctp_paramhdr) * 2);
@ -1684,17 +1671,17 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
* throw it in the stream so it gets cleaned up in
* association destruction
*/
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len = sizeof(struct sctp_paramhdr) +
SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length = htons(oper->m_len);
ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_14);
ippp++;
@ -1720,21 +1707,39 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
mat = dmbuf;
while (mat) {
if (mat->m_flags & M_EXT) {
if (SCTP_BUF_IS_EXTENDED(mat)) {
sctp_log_mb(mat, SCTP_MBUF_ICOPY);
}
mat = mat->m_next;
mat = SCTP_BUF_NEXT(mat);
}
}
#endif
} else {
/* We can steal the last chunk */
int l_len;
dmbuf = *m;
/* lop off the top part */
m_adj(dmbuf, (offset + sizeof(struct sctp_data_chunk)));
if (dmbuf->m_pkthdr.len > the_len) {
if (SCTP_BUF_NEXT(dmbuf) == NULL) {
l_len = SCTP_BUF_LEN(dmbuf);
} else {
/*
* need to count up the size hopefully does not hit
* this to often :-0
*/
struct mbuf *lat;
l_len = 0;
lat = dmbuf;
while (lat) {
l_len += SCTP_BUF_LEN(lat);
lat = SCTP_BUF_NEXT(lat);
}
}
if (l_len > the_len) {
/* Trim the end round bytes off too */
m_adj(dmbuf, -(dmbuf->m_pkthdr.len - the_len));
m_adj(dmbuf, -(l_len - the_len));
}
}
if (dmbuf == NULL) {
@ -1821,7 +1826,6 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
asoc->last_flags_delivered = ch->ch.chunk_flags;
asoc->last_strm_seq_delivered = strmseq;
asoc->last_strm_no_delivered = strmno;
if (end) {
/* clean up the flags and such */
asoc->fragmented_delivery_inprogress = 0;
@ -1829,6 +1833,13 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
asoc->strmin[strmno].last_sequence_delivered++;
}
stcb->asoc.control_pdapi = NULL;
if (TAILQ_EMPTY(&asoc->reasmqueue) == 0) {
/*
* There could be another message
* ready
*/
need_reasm_check = 1;
}
}
control = NULL;
goto finish_express_del;
@ -1901,19 +1912,19 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
control->data = NULL;
sctp_free_remote_addr(control->whoFrom);
sctp_free_a_readq(stcb, control);
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len =
SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length = htons(oper->m_len);
ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_15);
ippp++;
@ -1934,13 +1945,13 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
sctp_free_remote_addr(control->whoFrom);
sctp_free_a_readq(stcb, control);
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len =
SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@ -1948,7 +1959,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
htons(oper->m_len);
htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_16);
ippp++;
@ -1978,13 +1989,13 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
control->data = NULL;
sctp_free_remote_addr(control->whoFrom);
sctp_free_a_readq(stcb, control);
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len =
SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@ -1992,7 +2003,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
htons(oper->m_len);
htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_17);
ippp++;
@ -2118,6 +2129,10 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
asoc->highest_tsn_inside_map, SCTP_MAP_PREPARE_SLIDE);
#endif
SCTP_SET_TSN_PRESENT(asoc->mapping_array, gap);
if (need_reasm_check) {
/* Another one waits ? */
sctp_deliver_reasm_check(stcb, asoc);
}
return (1);
}
@ -2367,7 +2382,7 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
* maker sure SACK timer is off and instead send a
* SHUTDOWN and a SACK
*/
if (callout_pending(&stcb->asoc.dack_timer.timer)) {
if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_INDATA + SCTP_LOC_18);
}
@ -2393,15 +2408,15 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
(stcb->asoc.numduptsns) || /* we have dup's */
(is_a_gap) || /* is still a gap */
(stcb->asoc.delayed_ack == 0) ||
(callout_pending(&stcb->asoc.dack_timer.timer)) /* timer was up . second
* packet */
(SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) /* timer was up . second
* packet */
) {
if ((sctp_cmt_on_off) && (sctp_cmt_use_dac) &&
(stcb->asoc.first_ack_sent == 1) &&
(stcb->asoc.numduptsns == 0) &&
(stcb->asoc.delayed_ack) &&
(!callout_pending(&stcb->asoc.dack_timer.timer))) {
(!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer))) {
/*
* CMT DAC algorithm: With CMT,
@ -2456,6 +2471,7 @@ sctp_service_queues(struct sctp_tcb *stcb, struct sctp_association *asoc)
* Now is there some other chunk I can deliver from the reassembly
* queue.
*/
doit_again:
chk = TAILQ_FIRST(&asoc->reasmqueue);
if (chk == NULL) {
asoc->size_on_reasm_queue = 0;
@ -2485,6 +2501,9 @@ sctp_service_queues(struct sctp_tcb *stcb, struct sctp_association *asoc)
asoc->pdapi_ppid = chk->rec.data.payloadtype;
asoc->fragment_flags = chk->rec.data.rcv_flags;
sctp_service_reassembly(stcb, asoc);
if (asoc->fragmented_delivery_inprogress == 0) {
goto doit_again;
}
}
}
}
@ -2542,23 +2561,19 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
* to a smaller mbuf and free up the cluster mbuf. This will help
* with cluster starvation.
*/
if (m->m_len < (long)MHLEN && m->m_next == NULL) {
if (SCTP_BUF_LEN(m) < (long)MHLEN && SCTP_BUF_NEXT(m) == NULL) {
/* we only handle mbufs that are singletons.. not chains */
m = sctp_get_mbuf_for_msg(m->m_len, 1, M_DONTWAIT, 1, MT_DATA);
m = sctp_get_mbuf_for_msg(SCTP_BUF_LEN(m), 0, M_DONTWAIT, 1, MT_DATA);
if (m) {
/* ok lets see if we can copy the data up */
caddr_t *from, *to;
if ((*mm)->m_flags & M_PKTHDR) {
/* got to copy the header first */
M_MOVE_PKTHDR(m, (*mm));
}
/* get the pointers and copy */
to = mtod(m, caddr_t *);
from = mtod((*mm), caddr_t *);
memcpy(to, from, (*mm)->m_len);
memcpy(to, from, SCTP_BUF_LEN((*mm)));
/* copy the length and free up the old */
m->m_len = (*mm)->m_len;
SCTP_BUF_LEN(m) = SCTP_BUF_LEN((*mm));
sctp_m_freem(*mm);
/* sucess, back copy */
*mm = m;
@ -2594,19 +2609,19 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
*/
struct mbuf *op_err;
op_err = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
op_err = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 2 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (op_err) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
op_err->m_len = sizeof(struct sctp_paramhdr) +
SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr) +
(2 * sizeof(uint32_t));
ph = mtod(op_err, struct sctp_paramhdr *);
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length = htons(op_err->m_len);
ph->param_length = htons(SCTP_BUF_LEN(op_err));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_19);
ippp++;
@ -2689,7 +2704,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
struct mbuf *mm;
struct sctp_paramhdr *phd;
mm = sctp_get_mbuf_for_msg(sizeof(*phd), 1, M_DONTWAIT, 1, MT_DATA);
mm = sctp_get_mbuf_for_msg(sizeof(*phd), 0, M_DONTWAIT, 1, MT_DATA);
if (mm) {
phd = mtod(mm, struct sctp_paramhdr *);
/*
@ -2704,14 +2719,11 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
htons(SCTP_CAUSE_UNRECOG_CHUNK);
phd->param_length =
htons(chk_length + sizeof(*phd));
mm->m_len = sizeof(*phd);
mm->m_next = sctp_m_copym(m, *offset,
SCTP_BUF_LEN(mm) = sizeof(*phd);
SCTP_BUF_NEXT(mm) = sctp_m_copym(m, *offset,
SCTP_SIZE32(chk_length),
M_DONTWAIT);
if (mm->m_next) {
mm->m_pkthdr.len =
SCTP_SIZE32(chk_length) +
sizeof(*phd);
if (SCTP_BUF_NEXT(mm)) {
sctp_queue_op_err(stcb, mm);
} else {
sctp_m_freem(mm);
@ -2776,9 +2788,9 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
/* need to do the slide */
sctp_sack_check(stcb, 1, was_a_gap, &abort_flag);
} else {
if (callout_pending(&stcb->asoc.dack_timer.timer)) {
if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
stcb->asoc.first_ack_sent = 1;
callout_stop(&stcb->asoc.dack_timer.timer);
SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
sctp_send_sack(stcb);
} else {
sctp_timer_start(SCTP_TIMER_TYPE_RECV,
@ -2797,7 +2809,8 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
static void
sctp_handle_segments(struct sctp_tcb *stcb, struct sctp_association *asoc,
struct sctp_sack_chunk *ch, uint32_t last_tsn, uint32_t * biggest_tsn_acked,
uint32_t * biggest_newly_acked_tsn, uint32_t * this_sack_lowest_newack, int num_seg, int *ecn_seg_sums)
uint32_t * biggest_newly_acked_tsn, uint32_t * this_sack_lowest_newack,
int num_seg, int *ecn_seg_sums)
{
/************************************************/
/* process fragments and update sendqueue */
@ -3898,7 +3911,7 @@ sctp_cwnd_update(struct sctp_tcb *stcb,
* to illicit a sack with gaps to force out
* the others.
*/
if (callout_pending(&net->fr_timer.timer)) {
if (SCTP_OS_TIMER_PENDING(&net->fr_timer.timer)) {
SCTP_STAT_INCR(sctps_earlyfrstpidsck2);
sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_20);
@ -3907,7 +3920,7 @@ sctp_cwnd_update(struct sctp_tcb *stcb,
sctp_timer_start(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net);
} else {
/* No, stop it if its running */
if (callout_pending(&net->fr_timer.timer)) {
if (SCTP_OS_TIMER_PENDING(&net->fr_timer.timer)) {
SCTP_STAT_INCR(sctps_earlyfrstpidsck3);
sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_21);
@ -4088,6 +4101,44 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
net->net_ack = 0;
net->net_ack2 = 0;
}
if (sctp_strict_sacks) {
uint32_t send_s;
if (TAILQ_EMPTY(&asoc->send_queue)) {
send_s = asoc->sending_seq;
} else {
tp1 = TAILQ_FIRST(&asoc->send_queue);
send_s = tp1->rec.data.TSN_seq;
}
if ((cumack == send_s) ||
compare_with_wrap(cumack, send_s, MAX_TSN)) {
#ifdef INVARIANTS /* for testing only */
panic("Impossible sack 1");
#else
struct mbuf *oper;
*abort_now = 1;
/* XXX */
oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
sizeof(uint32_t);
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_25);
}
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25;
sctp_abort_an_association(stcb->sctp_ep, stcb, SCTP_PEER_FAULTY, oper);
return;
#endif
}
}
asoc->this_sack_highest_gap = cumack;
stcb->asoc.overall_error_count = 0;
/* process the new consecutive TSN first */
@ -4276,16 +4327,16 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
to_ticks = MSEC_TO_TICKS(net->RTO);
}
j++;
callout_reset(&net->rxt_timer.timer, to_ticks,
SCTP_OS_TIMER_START(&net->rxt_timer.timer, to_ticks,
sctp_timeout_handler, &net->rxt_timer);
} else {
if (callout_pending(&net->rxt_timer.timer)) {
if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
stcb, net,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_22);
}
if (sctp_early_fr) {
if (callout_pending(&net->fr_timer.timer)) {
if (SCTP_OS_TIMER_PENDING(&net->fr_timer.timer)) {
SCTP_STAT_INCR(sctps_earlyfrstpidsck4);
sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_23);
@ -4359,11 +4410,11 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len = sizeof(struct sctp_paramhdr) +
SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
sizeof(uint32_t);
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
ph->param_length = htons(oper->m_len);
ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_24);
}
@ -4515,6 +4566,10 @@ sctp_handle_sack(struct sctp_sack_chunk *ch, struct sctp_tcb *stcb,
if (sctp_strict_sacks) {
if (cum_ack == send_s ||
compare_with_wrap(cum_ack, send_s, MAX_TSN)) {
#ifdef INVARIANTS /* for testing only */
hopeless_peer:
panic("Impossible sack 1");
#else
struct mbuf *oper;
/*
@ -4530,17 +4585,18 @@ sctp_handle_sack(struct sctp_sack_chunk *ch, struct sctp_tcb *stcb,
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len = sizeof(struct sctp_paramhdr) +
SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
sizeof(uint32_t);
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length = htons(oper->m_len);
ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_25);
}
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25;
sctp_abort_an_association(stcb->sctp_ep, stcb, SCTP_PEER_FAULTY, oper);
return;
#endif
}
}
/**********************/
@ -4573,7 +4629,7 @@ sctp_handle_sack(struct sctp_sack_chunk *ch, struct sctp_tcb *stcb,
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_26);
if (sctp_early_fr) {
if (callout_pending(&net->fr_timer.timer)) {
if (SCTP_OS_TIMER_PENDING(&net->fr_timer.timer)) {
SCTP_STAT_INCR(sctps_earlyfrstpidsck1);
sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_26);
@ -4927,7 +4983,7 @@ sctp_handle_sack(struct sctp_sack_chunk *ch, struct sctp_tcb *stcb,
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
/* stop all timers */
if (sctp_early_fr) {
if (callout_pending(&net->fr_timer.timer)) {
if (SCTP_OS_TIMER_PENDING(&net->fr_timer.timer)) {
SCTP_STAT_INCR(sctps_earlyfrstpidsck4);
sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_29);
@ -4991,11 +5047,11 @@ sctp_handle_sack(struct sctp_sack_chunk *ch, struct sctp_tcb *stcb,
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len = sizeof(struct sctp_paramhdr) +
SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
sizeof(uint32_t);
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
ph->param_length = htons(oper->m_len);
ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_31);
}
@ -5653,4 +5709,8 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
sctp_kick_prsctp_reorder_queue(stcb, strm);
}
}
if (TAILQ_FIRST(&asoc->reasmqueue)) {
/* now lets kick out and check for more fragmented delivery */
sctp_deliver_reasm_check(stcb, &stcb->asoc);
}
}

View File

@ -455,7 +455,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
*/
struct sctp_inv_mandatory_param *mp;
op_err->m_len =
SCTP_BUF_LEN(op_err) =
sizeof(struct sctp_inv_mandatory_param);
mp = mtod(op_err,
struct sctp_inv_mandatory_param *);
@ -612,9 +612,6 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
SCTP_INP_READ_LOCK(stcb->sctp_ep);
asoc->control_pdapi->end_added = 1;
asoc->control_pdapi->pdapi_aborted = 1;
if (asoc->control_pdapi->tail_mbuf) {
asoc->control_pdapi->tail_mbuf->m_flags |= M_EOR;
}
asoc->control_pdapi = NULL;
SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
@ -704,9 +701,6 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp,
SCTP_INP_READ_LOCK(stcb->sctp_ep);
asoc->control_pdapi->end_added = 1;
asoc->control_pdapi->pdapi_aborted = 1;
if (asoc->control_pdapi->tail_mbuf) {
asoc->control_pdapi->tail_mbuf->m_flags |= M_EOR;
}
asoc->control_pdapi = NULL;
SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
@ -1119,17 +1113,17 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
sctp_send_shutdown_ack(stcb, stcb->asoc.primary_destination);
op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
1, M_DONTWAIT, 1, MT_DATA);
0, M_DONTWAIT, 1, MT_DATA);
if (op_err == NULL) {
/* FOOBAR */
return (NULL);
}
/* pre-reserve some space */
op_err->m_data += sizeof(struct ip6_hdr);
op_err->m_data += sizeof(struct sctphdr);
op_err->m_data += sizeof(struct sctp_chunkhdr);
SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
/* Set the len */
op_err->m_len = op_err->m_pkthdr.len = sizeof(struct sctp_paramhdr);
SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
ph = mtod(op_err, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_COOKIE_IN_SHUTDOWN);
ph->param_length = htons(sizeof(struct sctp_paramhdr));
@ -1371,10 +1365,35 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
/* temp code */
sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_14);
sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_15);
*sac_assoc_id = sctp_get_associd(stcb);
/* notify upper layer */
*notification = SCTP_NOTIFY_ASSOC_RESTART;
atomic_add_int(&stcb->asoc.refcnt, 1);
if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
asoc->state = SCTP_STATE_OPEN |
SCTP_STATE_SHUTDOWN_PENDING;
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
stcb->sctp_ep, stcb, asoc->primary_destination);
} else if (!(asoc->state & SCTP_STATE_SHUTDOWN_SENT)) {
/* move to OPEN state, if not in SHUTDOWN_SENT */
asoc->state = SCTP_STATE_OPEN;
}
asoc->pre_open_streams =
ntohs(initack_cp->init.num_outbound_streams);
asoc->init_seq_number = ntohl(initack_cp->init.initial_tsn);
asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number;
asoc->last_cwr_tsn = asoc->init_seq_number - 1;
asoc->asconf_seq_in = asoc->last_acked_seq = asoc->init_seq_number - 1;
asoc->str_reset_seq_in = asoc->init_seq_number;
asoc->advanced_peer_ack_point = asoc->last_acked_seq;
if (asoc->mapping_array)
memset(asoc->mapping_array, 0,
asoc->mapping_array_size);
SCTP_TCB_UNLOCK(stcb);
SCTP_INP_INFO_WLOCK();
SCTP_INP_WLOCK(stcb->sctp_ep);
@ -1412,20 +1431,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
LIST_INSERT_HEAD(head, stcb, sctp_tcbrestarhash);
stcb->asoc.in_restart_hash = 1;
}
asoc->pre_open_streams =
ntohs(initack_cp->init.num_outbound_streams);
asoc->init_seq_number = ntohl(initack_cp->init.initial_tsn);
asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number;
asoc->last_cwr_tsn = asoc->init_seq_number - 1;
asoc->asconf_seq_in = asoc->last_acked_seq = asoc->init_seq_number - 1;
asoc->str_reset_seq_in = asoc->init_seq_number;
asoc->advanced_peer_ack_point = asoc->last_acked_seq;
if (asoc->mapping_array)
memset(asoc->mapping_array, 0,
asoc->mapping_array_size);
/* process the INIT info (peer's info) */
SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_INP_WUNLOCK(stcb->sctp_ep);
@ -1446,16 +1451,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
initack_offset, sh, init_src)) {
return (NULL);
}
if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
asoc->state = SCTP_STATE_OPEN |
SCTP_STATE_SHUTDOWN_PENDING;
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
stcb->sctp_ep, stcb, asoc->primary_destination);
} else if (!(asoc->state & SCTP_STATE_SHUTDOWN_SENT)) {
/* move to OPEN state, if not in SHUTDOWN_SENT */
asoc->state = SCTP_STATE_OPEN;
}
/* respond with a COOKIE-ACK */
sctp_stop_all_cookie_timers(stcb);
sctp_toss_old_cookies(stcb, asoc);
@ -1799,6 +1794,8 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
sin->sin_len = sizeof(*sin);
sin->sin_port = sh->dest_port;
sin->sin_addr.s_addr = iph->ip_dst.s_addr;
size_of_pkt = SCTP_GET_IPV4_LENGTH(iph);
} else if (iph->ip_v == (IPV6_VERSION >> 4)) {
/* its IPv6 */
struct ip6_hdr *ip6;
@ -1811,6 +1808,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
ip6 = mtod(m, struct ip6_hdr *);
sin6->sin6_port = sh->dest_port;
sin6->sin6_addr = ip6->ip6_dst;
size_of_pkt = SCTP_GET_IPV6_LENGTH(ip6);
} else {
return (NULL);
}
@ -1831,20 +1829,6 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
*/
return (NULL);
}
/* compute size of packet */
if (m->m_flags & M_PKTHDR) {
size_of_pkt = m->m_pkthdr.len;
} else {
/* Should have a pkt hdr really */
struct mbuf *mat;
mat = m;
size_of_pkt = 0;
while (mat != NULL) {
size_of_pkt += mat->m_len;
mat = mat->m_next;
}
}
if (cookie_len > size_of_pkt ||
cookie_len < sizeof(struct sctp_cookie_echo_chunk) +
sizeof(struct sctp_init_chunk) +
@ -1925,35 +1909,10 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
struct mbuf *m_at;
m_at = m;
while (m_at->m_next != NULL) {
m_at = m_at->m_next;
}
m_at->m_next = m_sig;
if (m->m_flags & M_PKTHDR) {
/*
* We should only do this if and only if the front
* mbuf has a m_pkthdr... it should in theory.
*/
if (m_sig->m_flags & M_PKTHDR) {
/* Add back to the pkt hdr of main m chain */
m->m_pkthdr.len += m_sig->m_pkthdr.len;
} else {
/*
* Got a problem, no pkthdr in split chain.
* TSNH but we will handle it just in case
*/
int mmlen = 0;
struct mbuf *lat;
printf("Warning: Hitting m_split join TSNH code - fixed\n");
lat = m_sig;
while (lat) {
mmlen += lat->m_len;
lat = lat->m_next;
}
m->m_pkthdr.len += mmlen;
}
while (SCTP_BUF_NEXT(m_at) != NULL) {
m_at = SCTP_BUF_NEXT(m_at);
}
SCTP_BUF_NEXT(m_at) = m_sig;
}
if (cookie_ok == 0) {
@ -1980,18 +1939,18 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
uint32_t tim;
op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_stale_cookie_msg),
1, M_DONTWAIT, 1, MT_DATA);
0, M_DONTWAIT, 1, MT_DATA);
if (op_err == NULL) {
/* FOOBAR */
return (NULL);
}
/* pre-reserve some space */
op_err->m_data += sizeof(struct ip6_hdr);
op_err->m_data += sizeof(struct sctphdr);
op_err->m_data += sizeof(struct sctp_chunkhdr);
SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
/* Set the len */
op_err->m_len = op_err->m_pkthdr.len = sizeof(struct sctp_stale_cookie_msg);
SCTP_BUF_LEN(op_err) = sizeof(struct sctp_stale_cookie_msg);
scm = mtod(op_err, struct sctp_stale_cookie_msg *);
scm->ph.param_type = htons(SCTP_CAUSE_STALE_COOKIE);
scm->ph.param_length = htons((sizeof(struct sctp_paramhdr) +
@ -3117,7 +3076,7 @@ sctp_handle_stream_reset(struct sctp_tcb *stcb, struct sctp_stream_reset_out_req
chk->asoc = &stcb->asoc;
chk->no_fr_allowed = 0;
chk->book_size = chk->send_size = sizeof(struct sctp_chunkhdr);
chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 1, M_DONTWAIT, 1, MT_DATA);
chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
if (chk->data == NULL) {
strres_nochunk:
if (chk->data) {
@ -3127,7 +3086,7 @@ sctp_handle_stream_reset(struct sctp_tcb *stcb, struct sctp_stream_reset_out_req
sctp_free_a_chunk(stcb, chk);
return (ret_code);
}
chk->data->m_data += SCTP_MIN_OVERHEAD;
SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
/* setup chunk parameters */
chk->sent = SCTP_DATAGRAM_UNSENT;
@ -3139,7 +3098,7 @@ sctp_handle_stream_reset(struct sctp_tcb *stcb, struct sctp_stream_reset_out_req
ch->chunk_type = SCTP_STREAM_RESET;
ch->chunk_flags = 0;
ch->chunk_length = htons(chk->send_size);
chk->data->m_pkthdr.len = chk->data->m_len = SCTP_SIZE32(chk->send_size);
SCTP_BUF_LEN(chk->data) = SCTP_SIZE32(chk->send_size);
ph = (struct sctp_paramhdr *)&sr_req->sr_req;
@ -3706,12 +3665,11 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
oper = NULL;
oper = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
1, M_DONTWAIT, 1, MT_DATA);
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
/* pre-reserve some space */
oper->m_data += sizeof(struct sctp_chunkhdr);
oper->m_len = sizeof(struct sctp_paramhdr);
oper->m_pkthdr.len = oper->m_len;
SCTP_BUF_RESV_UF(oper, sizeof(struct sctp_chunkhdr));
SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr);
phdr = mtod(oper, struct sctp_paramhdr *);
phdr->param_type = htons(SCTP_CAUSE_OUT_OF_RESC);
phdr->param_length = htons(sizeof(struct sctp_paramhdr));
@ -4016,10 +3974,9 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
if (sctp_abort_if_one_2_one_hits_limit) {
oper = NULL;
oper = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
1, M_DONTWAIT, 1, MT_DATA);
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
oper->m_len =
oper->m_pkthdr.len =
SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr);
phdr = mtod(oper,
struct sctp_paramhdr *);
@ -4296,7 +4253,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
struct sctp_paramhdr *phd;
mm = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
1, M_DONTWAIT, 1, MT_DATA);
0, M_DONTWAIT, 1, MT_DATA);
if (mm) {
phd = mtod(mm, struct sctp_paramhdr *);
/*
@ -4308,11 +4265,10 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
*/
phd->param_type = htons(SCTP_CAUSE_UNRECOG_CHUNK);
phd->param_length = htons(chk_length + sizeof(*phd));
mm->m_len = sizeof(*phd);
mm->m_next = sctp_m_copym(m, *offset, SCTP_SIZE32(chk_length),
SCTP_BUF_LEN(mm) = sizeof(*phd);
SCTP_BUF_NEXT(mm) = sctp_m_copym(m, *offset, SCTP_SIZE32(chk_length),
M_DONTWAIT);
if (mm->m_next) {
mm->m_pkthdr.len = SCTP_SIZE32(chk_length) + sizeof(*phd);
if (SCTP_BUF_NEXT(mm)) {
sctp_queue_op_err(stcb, mm);
} else {
sctp_m_freem(mm);
@ -4648,8 +4604,8 @@ uint8_t sctp_list_of_chunks[30000];
void
sctp_input(m, off)
struct mbuf *m;
sctp_input(i_pak, off)
struct mbuf *i_pak;
int off;
{
@ -4657,6 +4613,7 @@ sctp_input(m, off)
struct mbuf *mat;
#endif
struct mbuf *m;
int iphlen;
int s;
uint8_t ecn_bits;
@ -4673,6 +4630,7 @@ sctp_input(m, off)
iphlen = off;
m = SCTP_HEADER_TO_CHAIN(i_pak);
net = NULL;
SCTP_STAT_INCR(sctps_recvpackets);
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
@ -4684,10 +4642,10 @@ sctp_input(m, off)
/* Log in any input mbufs */
mat = m;
while (mat) {
if (mat->m_flags & M_EXT) {
if (SCTP_BUF_IS_EXTENDED(mat)) {
sctp_log_mb(mat, SCTP_MBUF_INPUT);
}
mat = mat->m_next;
mat = SCTP_BUF_NEXT(mat);
}
#endif
if ((size_t)iphlen > sizeof(struct ip)) {
@ -4699,7 +4657,7 @@ sctp_input(m, off)
*/
ip = mtod(m, struct ip *);
offset = iphlen + sizeof(*sh) + sizeof(*ch);
if (m->m_len < offset) {
if (SCTP_BUF_LEN(m) < offset) {
if ((m = m_pullup(m, offset)) == 0) {
SCTP_STAT_INCR(sctps_hdrops);
return;
@ -4716,7 +4674,7 @@ sctp_input(m, off)
if (((ch->chunk_type == SCTP_INITIATION) ||
(ch->chunk_type == SCTP_INITIATION_ACK) ||
(ch->chunk_type == SCTP_COOKIE_ECHO)) &&
(in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif))) {
(SCTP_IS_IT_BROADCAST(ip->ip_dst, i_pak))) {
/*
* We only look at broadcast if its a front state, All
* others we will not have a tcb for anyway.
@ -4730,8 +4688,7 @@ sctp_input(m, off)
}
/* validate SCTP checksum */
if ((sctp_no_csum_on_loopback == 0) ||
(m->m_pkthdr.rcvif == NULL) ||
(m->m_pkthdr.rcvif->if_type != IFT_LOOP)) {
SCTP_IS_IT_LOOPBACK(i_pak)) {
/*
* we do NOT validate things from the loopback if the sysctl
* is set to 1.
@ -4772,7 +4729,7 @@ sctp_input(m, off)
sh->checksum = calc_check;
} else {
sctp_skip_csum_4:
mlen = m->m_pkthdr.len;
mlen = SCTP_HEADER_LEN(i_pak);
}
/* validate mbuf chain length with IP payload length */
if (mlen < (ip->ip_len - iphlen)) {

View File

@ -55,13 +55,9 @@ __FBSDID("$FreeBSD$");
* SCTP_ZONE_DESTROY(zone)
*/
/*
* Functions:
* sctp_read_random(void *buffer, uint32_t bytes)
*/
#include <netinet/sctp_os_bsd.h>
#endif

View File

@ -37,7 +37,6 @@ __FBSDID("$FreeBSD$");
*/
#include <sys/random.h>
/*
*
*/
@ -84,9 +83,75 @@ typedef struct uma_zone *sctp_zone_t;
#define SCTP_ZONE_FREE(zone, element) \
uma_zfree(zone, element);
/*
* timers
*/
#include <sys/callout.h>
typedef struct callout sctp_os_timer_t;
#define SCTP_OS_TIMER_INIT(tmr) callout_init(tmr, 1)
#define SCTP_OS_TIMER_START callout_reset
#define SCTP_OS_TIMER_STOP callout_stop
#define SCTP_OS_TIMER_PENDING callout_pending
#define SCTP_OS_TIMER_ACTIVE callout_active
#define SCTP_OS_TIMER_DEACTIVATE callout_deactivate
/*
* Functions
*/
#define sctp_read_random(buf, len) read_random(buf, len)
#define SCTP_READ_RANDOM(buf, len) read_random(buf, len)
/* Mbuf manipulation and access macros */
#define SCTP_BUF_LEN(m) (m->m_len)
#define SCTP_BUF_NEXT(m) (m->m_next)
#define SCTP_BUF_NEXT_PKT(m) (m->m_nextpkt)
#define SCTP_BUF_RESV_UF(m, size) m->m_data += size
#define SCTP_BUF_AT(m, size) m->m_data + size
#define SCTP_BUF_IS_EXTENDED(m) (m->m_flags & M_EXT)
#define SCTP_BUF_EXTEND_SIZE(m) (m->m_ext.ext_size)
#define SCTP_BUF_TYPE(m) (m->m_type)
#define SCTP_BUF_RECVIF(m) (m->m_pkthdr.rcvif)
#define SCTP_BUF_PREPEND M_PREPEND
/*************************/
/* These are for logging */
/*************************/
/* return the base ext data pointer */
#define SCTP_BUF_EXTEND_BASE(m) (m->m_ext.ext_buf)
/* return the refcnt of the data pointer */
#define SCTP_BUF_EXTEND_REFCNT(m) (*m->m_ext.ref_cnt)
/* return any buffer related flags, this is
* used beyond logging for apple only.
*/
#define SCTP_BUF_GET_FLAGS(m) (m->m_flags)
/* For BSD this just accesses the M_PKTHDR length
* so it operates on an mbuf with hdr flag. Other
* O/S's may have seperate packet header and mbuf
* chain pointers.. thus the macro.
*/
#define SCTP_HEADER_TO_CHAIN(m) (m)
#define SCTP_HEADER_LEN(m) (m->m_pkthdr.len)
#define SCTP_GET_HEADER_FOR_OUTPUT(len) sctp_get_mbuf_for_msg(len, 1, M_DONTWAIT, 1, MT_DATA)
/* Attach the chain of data into the sendable packet. */
#define SCTP_ATTACH_CHAIN(pak, m, packet_length) do { \
pak->m_next = m; \
pak->m_pkthdr.len = packet_length; \
} while(0)
/* Other m_pkthdr type things */
#define SCTP_IS_IT_BROADCAST(dst, m) in_broadcast(dst, m->m_pkthdr.rcvif)
#define SCTP_IS_IT_LOOPBACK(m) ((m->m_pkthdr.rcvif == NULL) ||(m->m_pkthdr.rcvif->if_type == IFT_LOOP))
/* This converts any input packet header
* into the chain of data holders, for BSD
* its a NOP.
*/
#define SCTP_PAK_TO_BUF(i_pak) (i_pak)
/* Macro's for getting length from V6/V4 header */
#define SCTP_GET_IPV4_LENGTH(iph) (iph->ip_len)
#define SCTP_GET_IPV6_LENGTH(ip6) (ntohs(ip6->ip6_plen))
#endif

File diff suppressed because it is too large Load Diff

View File

@ -52,8 +52,6 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <sys/callout.h>
#include <sys/limits.h>
#include <machine/cpu.h>
@ -1461,7 +1459,7 @@ sctp_inpcb_alloc(struct socket *so)
LIST_INIT(&inp->sctp_asoc_free_list);
#endif
/* Init the timer structure for signature change */
callout_init(&inp->sctp_ep.signature_change.timer, 1);
SCTP_OS_TIMER_INIT(&inp->sctp_ep.signature_change.timer);
inp->sctp_ep.signature_change.type = SCTP_TIMER_TYPE_NEWCOOKIE;
/* now init the actual endpoint default data */
@ -1498,7 +1496,7 @@ sctp_inpcb_alloc(struct socket *so)
/* seed random number generator */
m->random_counter = 1;
m->store_at = SCTP_SIGNATURE_SIZE;
sctp_read_random(m->random_numbers, sizeof(m->random_numbers));
SCTP_READ_RANDOM(m->random_numbers, sizeof(m->random_numbers));
sctp_fill_random_store(m);
/* Minimum cookie size */
@ -2162,13 +2160,13 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
struct sctp_paramhdr *ph;
uint32_t *ippp;
op_err->m_len =
SCTP_BUF_LEN(op_err) =
sizeof(struct sctp_paramhdr) + sizeof(uint32_t);
ph = mtod(op_err,
struct sctp_paramhdr *);
ph->param_type = htons(
SCTP_CAUSE_USER_INITIATED_ABT);
ph->param_length = htons(op_err->m_len);
ph->param_length = htons(SCTP_BUF_LEN(op_err));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_PCB + SCTP_LOC_3);
}
@ -2238,14 +2236,14 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
struct sctp_paramhdr *ph;
uint32_t *ippp;
op_err->m_len =
SCTP_BUF_LEN(op_err) =
(sizeof(struct sctp_paramhdr) +
sizeof(uint32_t));
ph = mtod(op_err,
struct sctp_paramhdr *);
ph->param_type = htons(
SCTP_CAUSE_USER_INITIATED_ABT);
ph->param_length = htons(op_err->m_len);
ph->param_length = htons(SCTP_BUF_LEN(op_err));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_PCB + SCTP_LOC_5);
}
@ -2312,12 +2310,12 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
/* Fill in the user initiated abort */
struct sctp_paramhdr *ph;
op_err->m_len = (sizeof(struct sctp_paramhdr) +
SCTP_BUF_LEN(op_err) = (sizeof(struct sctp_paramhdr) +
sizeof(uint32_t));
ph = mtod(op_err, struct sctp_paramhdr *);
ph->param_type = htons(
SCTP_CAUSE_USER_INITIATED_ABT);
ph->param_length = htons(op_err->m_len);
ph->param_length = htons(SCTP_BUF_LEN(op_err));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_PCB + SCTP_LOC_7);
@ -2338,7 +2336,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
}
if (cnt) {
/* Ok we have someone out there that will kill us */
callout_stop(&inp->sctp_ep.signature_change.timer);
SCTP_OS_TIMER_STOP(&inp->sctp_ep.signature_change.timer);
SCTP_INP_WUNLOCK(inp);
SCTP_ASOC_CREATE_UNLOCK(inp);
SCTP_INP_INFO_WUNLOCK();
@ -2349,7 +2347,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
return;
}
if ((inp->refcount) || (inp->sctp_flags & SCTP_PCB_FLAGS_CLOSE_IP)) {
callout_stop(&inp->sctp_ep.signature_change.timer);
SCTP_OS_TIMER_STOP(&inp->sctp_ep.signature_change.timer);
sctp_timer_start(SCTP_TIMER_TYPE_INPKILL, inp, NULL, NULL);
SCTP_INP_WUNLOCK(inp);
SCTP_ASOC_CREATE_UNLOCK(inp);
@ -2360,7 +2358,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
#endif
return;
}
callout_stop(&inp->sctp_ep.signature_change.timer);
SCTP_OS_TIMER_STOP(&inp->sctp_ep.signature_change.timer);
inp->sctp_ep.signature_change.type = 0;
inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_ALLGONE;
@ -2368,7 +2366,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
sctp_log_closing(inp, NULL, 5);
#endif
callout_stop(&inp->sctp_ep.signature_change.timer);
SCTP_OS_TIMER_STOP(&inp->sctp_ep.signature_change.timer);
inp->sctp_ep.signature_change.type = SCTP_TIMER_TYPE_NONE;
/* Clear the read queue */
while ((sq = TAILQ_FIRST(&inp->read_queue)) != NULL) {
@ -2727,9 +2725,9 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
net->tos_flowlabel = stcb->asoc.default_flowlabel;
#endif
/* Init the timer structure */
callout_init(&net->rxt_timer.timer, 1);
callout_init(&net->fr_timer.timer, 1);
callout_init(&net->pmtu_timer.timer, 1);
SCTP_OS_TIMER_INIT(&net->rxt_timer.timer);
SCTP_OS_TIMER_INIT(&net->fr_timer.timer);
SCTP_OS_TIMER_INIT(&net->pmtu_timer.timer);
/* Now generate a route for this guy */
/* KAME hack: embed scopeid */
@ -3019,13 +3017,14 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
return (NULL);
}
/* Init all the timers */
callout_init(&asoc->hb_timer.timer, 1);
callout_init(&asoc->dack_timer.timer, 1);
callout_init(&asoc->asconf_timer.timer, 1);
callout_init(&asoc->strreset_timer.timer, 1);
callout_init(&asoc->shut_guard_timer.timer, 1);
callout_init(&asoc->autoclose_timer.timer, 1);
callout_init(&asoc->delayed_event_timer.timer, 1);
SCTP_OS_TIMER_INIT(&asoc->hb_timer.timer);
SCTP_OS_TIMER_INIT(&asoc->dack_timer.timer);
SCTP_OS_TIMER_INIT(&asoc->strreset_timer.timer);
SCTP_OS_TIMER_INIT(&asoc->asconf_timer.timer);
SCTP_OS_TIMER_INIT(&asoc->shut_guard_timer.timer);
SCTP_OS_TIMER_INIT(&asoc->autoclose_timer.timer);
SCTP_OS_TIMER_INIT(&asoc->delayed_event_timer.timer);
LIST_INSERT_HEAD(&inp->sctp_asoc_list, stcb, sctp_tcblist);
/* now file the port under the hash as well */
if (inp->sctp_tcbhash != NULL) {
@ -3282,18 +3281,18 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
}
}
/* now clean up any other timers */
callout_stop(&asoc->hb_timer.timer);
callout_stop(&asoc->dack_timer.timer);
callout_stop(&asoc->strreset_timer.timer);
callout_stop(&asoc->asconf_timer.timer);
callout_stop(&asoc->autoclose_timer.timer);
callout_stop(&asoc->shut_guard_timer.timer);
callout_stop(&asoc->delayed_event_timer.timer);
SCTP_OS_TIMER_STOP(&asoc->hb_timer.timer);
SCTP_OS_TIMER_STOP(&asoc->dack_timer.timer);
SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
SCTP_OS_TIMER_STOP(&asoc->asconf_timer.timer);
SCTP_OS_TIMER_STOP(&asoc->autoclose_timer.timer);
SCTP_OS_TIMER_STOP(&asoc->shut_guard_timer.timer);
SCTP_OS_TIMER_STOP(&asoc->delayed_event_timer.timer);
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
callout_stop(&net->fr_timer.timer);
callout_stop(&net->rxt_timer.timer);
callout_stop(&net->pmtu_timer.timer);
SCTP_OS_TIMER_STOP(&net->fr_timer.timer);
SCTP_OS_TIMER_STOP(&net->rxt_timer.timer);
SCTP_OS_TIMER_STOP(&net->pmtu_timer.timer);
}
/* Now the read queue needs to be cleaned up (only once) */
cnt = 0;
@ -3421,7 +3420,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
}
}
/* Stop any timer someone may have started */
callout_stop(&asoc->strreset_timer.timer);
SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
/*
* Make it invalid too, that way if its about to run it will abort
* and return.
@ -3433,18 +3432,18 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
atomic_add_int(&stcb->asoc.refcnt, -1);
}
/* now restop the timers to be sure - this is paranoia at is finest! */
callout_stop(&asoc->hb_timer.timer);
callout_stop(&asoc->dack_timer.timer);
callout_stop(&asoc->strreset_timer.timer);
callout_stop(&asoc->asconf_timer.timer);
callout_stop(&asoc->shut_guard_timer.timer);
callout_stop(&asoc->autoclose_timer.timer);
callout_stop(&asoc->delayed_event_timer.timer);
SCTP_OS_TIMER_STOP(&asoc->hb_timer.timer);
SCTP_OS_TIMER_STOP(&asoc->dack_timer.timer);
SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
SCTP_OS_TIMER_STOP(&asoc->asconf_timer.timer);
SCTP_OS_TIMER_STOP(&asoc->shut_guard_timer.timer);
SCTP_OS_TIMER_STOP(&asoc->autoclose_timer.timer);
SCTP_OS_TIMER_STOP(&asoc->delayed_event_timer.timer);
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
callout_stop(&net->fr_timer.timer);
callout_stop(&net->rxt_timer.timer);
callout_stop(&net->pmtu_timer.timer);
SCTP_OS_TIMER_STOP(&net->fr_timer.timer);
SCTP_OS_TIMER_STOP(&net->rxt_timer.timer);
SCTP_OS_TIMER_STOP(&net->pmtu_timer.timer);
}
asoc->state = 0;
if (inp->sctp_tcbhash) {
@ -4198,7 +4197,6 @@ static char sctp_pcb_initialized = 0;
static int sctp_max_number_of_assoc = SCTP_MAX_NUM_OF_ASOC;
static int sctp_scale_up_for_address = SCTP_SCALE_FOR_ADDR;
void
sctp_pcb_init()
{
@ -4308,8 +4306,7 @@ sctp_pcb_init()
sctppcbinfo.ipi_free_strmoq = 0;
sctppcbinfo.ipi_free_chunks = 0;
callout_init(&sctppcbinfo.addr_wq_timer.timer, 1);
SCTP_OS_TIMER_INIT(&sctppcbinfo.addr_wq_timer.timer);
/* port stuff */
sctppcbinfo.lastlow = ipport_firstauto;
@ -5213,7 +5210,7 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
asoc->highest_tsn_inside_map = asoc->cumulative_tsn;
}
asoc->last_revoke_count = cnt;
callout_stop(&stcb->asoc.dack_timer.timer);
SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
sctp_send_sack(stcb);
reneged_asoc_ids[reneged_at] = sctp_get_associd(stcb);
reneged_at++;
@ -5300,7 +5297,7 @@ sctp_initiate_iterator(inp_func inpf, asoc_func af, uint32_t pcb_state,
}
/* Init the timer */
callout_init(&it->tmr.timer, 1);
SCTP_OS_TIMER_INIT(&it->tmr.timer);
/* add to the list of all iterators */
SCTP_INP_INFO_WLOCK();
LIST_INSERT_HEAD(&sctppcbinfo.iteratorhead, it, sctp_nxt_itr);
@ -5311,8 +5308,3 @@ sctp_initiate_iterator(inp_func inpf, asoc_func af, uint32_t pcb_state,
splx(s);
return (0);
}
/*
* Callout/Timer routines for OS that doesn't have them
*/

View File

@ -510,6 +510,5 @@ sctp_initiate_iterator(inp_func inpf, asoc_func af, uint32_t, uint32_t,
uint32_t, void *, uint32_t, end_func ef, struct sctp_inpcb *, uint8_t co_off);
#endif /* _KERNEL */
#endif /* !__sctp_pcb_h__ */

View File

@ -37,8 +37,6 @@ __FBSDID("$FreeBSD$");
#define __sctp_structs_h__
#include <sys/queue.h>
#include <sys/callout.h>
#include <sys/socket.h>
#ifdef IPSEC
@ -46,12 +44,14 @@ __FBSDID("$FreeBSD$");
#include <netkey/key.h>
#endif
#include <netinet/sctp_os.h>
#include <netinet/sctp_header.h>
#include <netinet/sctp_uio.h>
#include <netinet/sctp_auth.h>
struct sctp_timer {
struct callout timer;
sctp_os_timer_t timer;
int type;
/*
* Depending on the timer type these will be setup and cast with the
@ -367,9 +367,11 @@ struct sctp_queued_to_read { /* sinfo structure Pluse more */
struct sctp_tcb *stcb; /* assoc, used for window update */
TAILQ_ENTRY(sctp_queued_to_read) next;
uint16_t port_from;
uint16_t spec_flags; /* Flags to hold the notification field */
uint8_t do_not_ref_stcb;
uint8_t end_added;
uint8_t pdapi_aborted;
uint8_t resv;
};
/* This data structure will be on the outbound

View File

@ -318,11 +318,11 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len = sizeof(struct sctp_paramhdr) +
SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
sizeof(uint32_t);
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length = htons(oper->m_len);
ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_TIMER + SCTP_LOC_1);
}
@ -544,8 +544,8 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
window_probe,
SCTP_FR_T3_MARK_TIME);
sctp_log_fr(net->flight_size,
callout_pending(&net->fr_timer.timer),
callout_active(&net->fr_timer.timer),
SCTP_OS_TIMER_PENDING(&net->fr_timer.timer),
SCTP_OS_TIMER_ACTIVE(&net->fr_timer.timer),
SCTP_FR_CWND_REPORT);
sctp_log_fr(net->flight_size, net->cwnd, stcb->asoc.total_flight, SCTP_FR_CWND_REPORT);
#endif
@ -1091,11 +1091,11 @@ sctp_cookie_timer(struct sctp_inpcb *inp,
struct sctp_paramhdr *ph;
uint32_t *ippp;
oper->m_len = sizeof(struct sctp_paramhdr) +
SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
sizeof(uint32_t);
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length = htons(oper->m_len);
ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_TIMER + SCTP_LOC_2);
}
@ -1472,7 +1472,7 @@ sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
int
sctp_is_hb_timer_running(struct sctp_tcb *stcb)
{
if (callout_pending(&stcb->asoc.hb_timer.timer)) {
if (SCTP_OS_TIMER_PENDING(&stcb->asoc.hb_timer.timer)) {
/* its running */
return (1);
} else {
@ -1484,7 +1484,7 @@ sctp_is_hb_timer_running(struct sctp_tcb *stcb)
int
sctp_is_sack_timer_running(struct sctp_tcb *stcb)
{
if (callout_pending(&stcb->asoc.dack_timer.timer)) {
if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
/* its running */
return (1);
} else {
@ -1493,7 +1493,6 @@ sctp_is_sack_timer_running(struct sctp_tcb *stcb)
}
}
#define SCTP_NUMBER_OF_MTU_SIZES 18
static uint32_t mtu_sizes[] = {
68,
@ -1656,7 +1655,7 @@ sctp_iterator_timer(struct sctp_iterator *it)
LIST_REMOVE(it, sctp_nxt_itr);
/* stopping the callout is not needed, in theory */
SCTP_INP_INFO_WUNLOCK();
callout_stop(&it->tmr.timer);
SCTP_OS_TIMER_STOP(&it->tmr.timer);
if (it->function_atend != NULL) {
(*it->function_atend) (it->pointer, it->val);
}

View File

@ -163,6 +163,7 @@ unsigned int sctp_early_fr_msec = SCTP_MINFR_MSEC_TIMER;
unsigned int sctp_use_rttvar_cc = 0;
int sctp_says_check_for_deadlock = 0;
unsigned int sctp_asconf_auth_nochk = 0;
unsigned int sctp_nat_friendly = 1;
unsigned int sctp_auth_disable = 0;
unsigned int sctp_auth_random_len = SCTP_AUTH_RANDOM_SIZE_DEFAULT;
unsigned int sctp_auth_hmac_id_default = SCTP_AUTH_HMAC_ID_SHA1;
@ -314,7 +315,7 @@ sctp_notify_mbuf(struct sctp_inpcb *inp,
nxtsz = find_next_best_mtu(totsz);
}
/* Stop any PMTU timer */
if (callout_pending(&net->pmtu_timer.timer)) {
if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
tmr_stopped = 1;
sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_1);
@ -923,6 +924,10 @@ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, assoclist, CTLFLAG_RD,
0, 0, sctp_assoclist,
"S,xassoc", "List of active SCTP associations");
SYSCTL_UINT(_net_inet_sctp, OID_AUTO, nat_friendly, CTLFLAG_RW,
&sctp_nat_friendly, 0,
"SCTP NAT friendly operation");
#ifdef SCTP_DEBUG
SYSCTL_INT(_net_inet_sctp, OID_AUTO, debug, CTLFLAG_RW,
&sctp_debug_on, 0, "Configure debug output");
@ -1179,21 +1184,9 @@ sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
}
inp->control = control;
}
/* add it in possibly */
if ((inp->pkt) && (inp->pkt->m_flags & M_PKTHDR)) {
struct mbuf *x;
int c_len;
c_len = 0;
/* How big is it */
for (x = m; x; x = x->m_next) {
c_len += x->m_len;
}
inp->pkt->m_pkthdr.len += c_len;
}
/* Place the data */
if (inp->pkt) {
inp->pkt_last->m_next = m;
SCTP_BUF_NEXT(inp->pkt_last) = m;
inp->pkt_last = m;
} else {
inp->pkt_last = inp->pkt = m;
@ -1275,9 +1268,9 @@ sctp_disconnect(struct socket *so)
struct sctp_paramhdr *ph;
ph = mtod(err, struct sctp_paramhdr *);
err->m_len = sizeof(struct sctp_paramhdr);
SCTP_BUF_LEN(err) = sizeof(struct sctp_paramhdr);
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
ph->param_length = htons(err->m_len);
ph->param_length = htons(SCTP_BUF_LEN(err));
}
sctp_send_abort_tcb(stcb, err);
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
@ -1360,13 +1353,13 @@ sctp_disconnect(struct socket *so)
struct sctp_paramhdr *ph;
uint32_t *ippp;
op_err->m_len =
SCTP_BUF_LEN(op_err) =
(sizeof(struct sctp_paramhdr) + sizeof(uint32_t));
ph = mtod(op_err,
struct sctp_paramhdr *);
ph->param_type = htons(
SCTP_CAUSE_USER_INITIATED_ABT);
ph->param_length = htons(op_err->m_len);
ph->param_length = htons(SCTP_BUF_LEN(op_err));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4);
}
@ -1499,13 +1492,13 @@ sctp_shutdown(struct socket *so)
struct sctp_paramhdr *ph;
uint32_t *ippp;
op_err->m_len =
SCTP_BUF_LEN(op_err) =
sizeof(struct sctp_paramhdr) + sizeof(uint32_t);
ph = mtod(op_err,
struct sctp_paramhdr *);
ph->param_type = htons(
SCTP_CAUSE_USER_INITIATED_ABT);
ph->param_length = htons(op_err->m_len);
ph->param_length = htons(SCTP_BUF_LEN(op_err));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6);
}
@ -1869,7 +1862,7 @@ sctp_do_connect_x(struct socket *so,
error = EALREADY;
goto out_now;
}
if ((at + incr) > m->m_len) {
if ((at + incr) > SCTP_BUF_LEN(m)) {
totaddr = i;
break;
}
@ -2040,57 +2033,57 @@ sctp_optsget(struct socket *so,
/* make it an "on/off" value */
optval = (optval != 0);
}
if ((size_t)m->m_len < sizeof(int)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(int)) {
error = EINVAL;
}
SCTP_INP_RUNLOCK(inp);
if (error == 0) {
/* return the option value */
*mtod(m, int *)= optval;
m->m_len = sizeof(optval);
SCTP_BUF_LEN(m) = sizeof(optval);
}
break;
case SCTP_PARTIAL_DELIVERY_POINT:
{
if ((size_t)m->m_len < sizeof(unsigned int)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(unsigned int)) {
error = EINVAL;
break;
}
*mtod(m, unsigned int *)= inp->partial_delivery_point;
m->m_len = sizeof(unsigned int);
SCTP_BUF_LEN(m) = sizeof(unsigned int);
}
break;
case SCTP_FRAGMENT_INTERLEAVE:
{
if ((size_t)m->m_len < sizeof(unsigned int)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(unsigned int)) {
error = EINVAL;
break;
}
*mtod(m, unsigned int *)= sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
m->m_len = sizeof(unsigned int);
SCTP_BUF_LEN(m) = sizeof(unsigned int);
}
break;
case SCTP_CMT_ON_OFF:
{
if ((size_t)m->m_len < sizeof(unsigned int)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(unsigned int)) {
error = EINVAL;
break;
}
*mtod(m, unsigned int *)= sctp_cmt_sockopt_on_off;
m->m_len = sizeof(unsigned int);
SCTP_BUF_LEN(m) = sizeof(unsigned int);
}
break;
case SCTP_CMT_USE_DAC:
{
*mtod(m, unsigned int *)= sctp_cmt_sockopt_use_dac;
m->m_len = sizeof(unsigned int);
SCTP_BUF_LEN(m) = sizeof(unsigned int);
}
break;
case SCTP_GET_ADDR_LEN:
{
struct sctp_assoc_value *av;
if ((size_t)m->m_len < sizeof(struct sctp_assoc_value)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_value)) {
error = EINVAL;
break;
}
@ -2116,7 +2109,7 @@ sctp_optsget(struct socket *so,
int cnt, at;
uint16_t orig;
if ((size_t)m->m_len < sizeof(struct sctp_assoc_ids)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_ids)) {
error = EINVAL;
break;
}
@ -2164,7 +2157,7 @@ sctp_optsget(struct socket *so,
struct sctp_assoc_value *av;
if ((size_t)m->m_len < sizeof(struct sctp_assoc_value)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_value)) {
error = EINVAL;
break;
}
@ -2186,7 +2179,7 @@ sctp_optsget(struct socket *so,
{
struct sctp_get_nonce_values *gnv;
if ((size_t)m->m_len < sizeof(struct sctp_get_nonce_values)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_get_nonce_values)) {
error = EINVAL;
break;
}
@ -2206,7 +2199,7 @@ sctp_optsget(struct socket *so,
{
struct sctp_assoc_value *tm;
if ((size_t)m->m_len < sizeof(struct sctp_assoc_value)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_value)) {
error = EINVAL;
break;
}
@ -2237,7 +2230,7 @@ sctp_optsget(struct socket *so,
break;
case SCTP_GET_SNDBUF_USE:
if ((size_t)m->m_len < sizeof(struct sctp_sockstat)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_sockstat)) {
error = EINVAL;
} else {
struct sctp_sockstat *ss;
@ -2255,7 +2248,7 @@ sctp_optsget(struct socket *so,
asoc->size_on_all_streams);
SCTP_TCB_UNLOCK(stcb);
error = 0;
m->m_len = sizeof(struct sctp_sockstat);
SCTP_BUF_LEN(m) = sizeof(struct sctp_sockstat);
}
}
break;
@ -2267,7 +2260,7 @@ sctp_optsget(struct socket *so,
SCTP_INP_RLOCK(inp);
*burst = inp->sctp_ep.max_burst;
SCTP_INP_RUNLOCK(inp);
m->m_len = sizeof(uint8_t);
SCTP_BUF_LEN(m) = sizeof(uint8_t);
}
break;
@ -2277,17 +2270,17 @@ sctp_optsget(struct socket *so,
sctp_assoc_t *assoc_id;
int ovh;
if ((size_t)m->m_len < sizeof(uint32_t)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(uint32_t)) {
error = EINVAL;
break;
}
if ((size_t)m->m_len < sizeof(sctp_assoc_t)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(sctp_assoc_t)) {
error = EINVAL;
break;
}
assoc_id = mtod(m, sctp_assoc_t *);
segsize = mtod(m, uint32_t *);
m->m_len = sizeof(uint32_t);
SCTP_BUF_LEN(m) = sizeof(uint32_t);
if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
(inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) ||
@ -2332,14 +2325,14 @@ sctp_optsget(struct socket *so,
{
uint32_t *level;
if ((size_t)m->m_len < sizeof(uint32_t)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(uint32_t)) {
error = EINVAL;
break;
}
level = mtod(m, uint32_t *);
error = 0;
*level = sctp_debug_on;
m->m_len = sizeof(uint32_t);
SCTP_BUF_LEN(m) = sizeof(uint32_t);
printf("Returning DEBUG LEVEL %x is set\n",
(uint32_t) sctp_debug_on);
}
@ -2358,7 +2351,7 @@ sctp_optsget(struct socket *so,
{
struct sctp_event_subscribe *events;
if ((size_t)m->m_len < sizeof(struct sctp_event_subscribe)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_event_subscribe)) {
error = EINVAL;
break;
}
@ -2395,40 +2388,40 @@ sctp_optsget(struct socket *so,
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT))
events->sctp_stream_reset_events = 1;
SCTP_INP_RUNLOCK(inp);
m->m_len = sizeof(struct sctp_event_subscribe);
SCTP_BUF_LEN(m) = sizeof(struct sctp_event_subscribe);
}
break;
case SCTP_ADAPTATION_LAYER:
if ((size_t)m->m_len < sizeof(int)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(int)) {
error = EINVAL;
break;
}
SCTP_INP_RLOCK(inp);
*mtod(m, int *)= inp->sctp_ep.adaptation_layer_indicator;
SCTP_INP_RUNLOCK(inp);
m->m_len = sizeof(int);
SCTP_BUF_LEN(m) = sizeof(int);
break;
case SCTP_SET_INITIAL_DBG_SEQ:
if ((size_t)m->m_len < sizeof(int)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(int)) {
error = EINVAL;
break;
}
SCTP_INP_RLOCK(inp);
*mtod(m, int *)= inp->sctp_ep.initial_sequence_debug;
SCTP_INP_RUNLOCK(inp);
m->m_len = sizeof(int);
SCTP_BUF_LEN(m) = sizeof(int);
break;
case SCTP_GET_LOCAL_ADDR_SIZE:
if ((size_t)m->m_len < sizeof(int)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(int)) {
error = EINVAL;
break;
}
SCTP_INP_RLOCK(inp);
*mtod(m, int *)= sctp_count_max_addresses(inp);
SCTP_INP_RUNLOCK(inp);
m->m_len = sizeof(int);
SCTP_BUF_LEN(m) = sizeof(int);
break;
case SCTP_GET_REMOTE_ADDR_SIZE:
{
@ -2436,7 +2429,7 @@ sctp_optsget(struct socket *so,
uint32_t *val, sz;
struct sctp_nets *net;
if ((size_t)m->m_len < sizeof(sctp_assoc_t)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(sctp_assoc_t)) {
error = EINVAL;
break;
}
@ -2473,7 +2466,7 @@ sctp_optsget(struct socket *so,
}
SCTP_TCB_UNLOCK(stcb);
*val = sz;
m->m_len = sizeof(uint32_t);
SCTP_BUF_LEN(m) = sizeof(uint32_t);
}
break;
case SCTP_GET_PEER_ADDRESSES:
@ -2487,11 +2480,11 @@ sctp_optsget(struct socket *so,
struct sctp_nets *net;
struct sctp_getaddresses *saddr;
if ((size_t)m->m_len < sizeof(struct sctp_getaddresses)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_getaddresses)) {
error = EINVAL;
break;
}
left = m->m_len - sizeof(struct sctp_getaddresses);
left = SCTP_BUF_LEN(m) - sizeof(struct sctp_getaddresses);
saddr = mtod(m, struct sctp_getaddresses *);
if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
SCTP_INP_RLOCK(inp);
@ -2506,7 +2499,7 @@ sctp_optsget(struct socket *so,
error = ENOENT;
break;
}
m->m_len = sizeof(struct sctp_getaddresses);
SCTP_BUF_LEN(m) = sizeof(struct sctp_getaddresses);
sas = (struct sockaddr_storage *)&saddr->addr[0];
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
@ -2535,7 +2528,7 @@ sctp_optsget(struct socket *so,
sas = (struct sockaddr_storage *)((caddr_t)sas + cpsz);
left -= cpsz;
m->m_len += cpsz;
SCTP_BUF_LEN(m) += cpsz;
}
SCTP_TCB_UNLOCK(stcb);
}
@ -2546,7 +2539,7 @@ sctp_optsget(struct socket *so,
struct sockaddr_storage *sas;
struct sctp_getaddresses *saddr;
if ((size_t)m->m_len < sizeof(struct sctp_getaddresses)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_getaddresses)) {
error = EINVAL;
break;
}
@ -2578,11 +2571,11 @@ sctp_optsget(struct socket *so,
SCTP_INP_RUNLOCK(inp);
}
sas = (struct sockaddr_storage *)&saddr->addr[0];
limit = m->m_len - sizeof(sctp_assoc_t);
limit = SCTP_BUF_LEN(m) - sizeof(sctp_assoc_t);
actual = sctp_fill_up_addresses(inp, stcb, limit, sas);
if (stcb)
SCTP_TCB_UNLOCK(stcb);
m->m_len = sizeof(struct sockaddr_storage) + actual;
SCTP_BUF_LEN(m) = sizeof(struct sockaddr_storage) + actual;
}
break;
case SCTP_PEER_ADDR_PARAMS:
@ -2590,7 +2583,7 @@ sctp_optsget(struct socket *so,
struct sctp_paddrparams *paddrp;
struct sctp_nets *net;
if ((size_t)m->m_len < sizeof(struct sctp_paddrparams)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_paddrparams)) {
error = EINVAL;
break;
}
@ -2653,7 +2646,7 @@ sctp_optsget(struct socket *so,
else
paddrp->spp_flags |= SPP_HB_ENABLE;
/* get flags for PMTU */
if (callout_pending(&net->pmtu_timer.timer)) {
if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
paddrp->spp_flags |= SPP_PMTUD_ENABLE;
} else {
paddrp->spp_flags |= SPP_PMTUD_DISABLE;
@ -2725,7 +2718,7 @@ sctp_optsget(struct socket *so,
SCTP_INP_RUNLOCK(inp);
}
m->m_len = sizeof(struct sctp_paddrparams);
SCTP_BUF_LEN(m) = sizeof(struct sctp_paddrparams);
}
break;
case SCTP_GET_PEER_ADDR_INFO:
@ -2733,7 +2726,7 @@ sctp_optsget(struct socket *so,
struct sctp_paddrinfo *paddri;
struct sctp_nets *net;
if ((size_t)m->m_len < sizeof(struct sctp_paddrinfo)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_paddrinfo)) {
error = EINVAL;
break;
}
@ -2771,7 +2764,7 @@ sctp_optsget(struct socket *so,
error = ENOENT;
break;
}
m->m_len = sizeof(struct sctp_paddrinfo);
SCTP_BUF_LEN(m) = sizeof(struct sctp_paddrinfo);
paddri->spinfo_state = net->dest_state & (SCTP_REACHABLE_MASK | SCTP_ADDR_NOHB);
paddri->spinfo_cwnd = net->cwnd;
paddri->spinfo_srtt = ((net->lastsa >> 2) + net->lastsv) >> 1;
@ -2784,13 +2777,13 @@ sctp_optsget(struct socket *so,
{
struct sctp_pcbinfo *spcb;
if ((size_t)m->m_len < sizeof(struct sctp_pcbinfo)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_pcbinfo)) {
error = EINVAL;
break;
}
spcb = mtod(m, struct sctp_pcbinfo *);
sctp_fill_pcbinfo(spcb);
m->m_len = sizeof(struct sctp_pcbinfo);
SCTP_BUF_LEN(m) = sizeof(struct sctp_pcbinfo);
}
break;
case SCTP_STATUS:
@ -2798,7 +2791,7 @@ sctp_optsget(struct socket *so,
struct sctp_nets *net;
struct sctp_status *sstat;
if ((size_t)m->m_len < sizeof(struct sctp_status)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_status)) {
error = EINVAL;
break;
}
@ -2852,14 +2845,14 @@ sctp_optsget(struct socket *so,
sstat->sstat_primary.spinfo_mtu = net->mtu;
sstat->sstat_primary.spinfo_assoc_id = sctp_get_associd(stcb);
SCTP_TCB_UNLOCK(stcb);
m->m_len = sizeof(*sstat);
SCTP_BUF_LEN(m) = sizeof(*sstat);
}
break;
case SCTP_RTOINFO:
{
struct sctp_rtoinfo *srto;
if ((size_t)m->m_len < sizeof(struct sctp_rtoinfo)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_rtoinfo)) {
error = EINVAL;
break;
}
@ -2890,14 +2883,14 @@ sctp_optsget(struct socket *so,
srto->srto_max = stcb->asoc.maxrto;
srto->srto_min = stcb->asoc.minrto;
SCTP_TCB_UNLOCK(stcb);
m->m_len = sizeof(*srto);
SCTP_BUF_LEN(m) = sizeof(*srto);
}
break;
case SCTP_ASSOCINFO:
{
struct sctp_assocparams *sasoc;
if ((size_t)m->m_len < sizeof(struct sctp_assocparams)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assocparams)) {
error = EINVAL;
break;
}
@ -2938,14 +2931,14 @@ sctp_optsget(struct socket *so,
sasoc->sasoc_cookie_life = inp->sctp_ep.def_cookie_life;
SCTP_INP_RUNLOCK(inp);
}
m->m_len = sizeof(*sasoc);
SCTP_BUF_LEN(m) = sizeof(*sasoc);
}
break;
case SCTP_DEFAULT_SEND_PARAM:
{
struct sctp_sndrcvinfo *s_info;
if (m->m_len != sizeof(struct sctp_sndrcvinfo)) {
if (SCTP_BUF_LEN(m) != sizeof(struct sctp_sndrcvinfo)) {
error = EINVAL;
break;
}
@ -2966,14 +2959,14 @@ sctp_optsget(struct socket *so,
/* Copy it out */
*s_info = stcb->asoc.def_send;
SCTP_TCB_UNLOCK(stcb);
m->m_len = sizeof(*s_info);
SCTP_BUF_LEN(m) = sizeof(*s_info);
}
break;
case SCTP_INITMSG:
{
struct sctp_initmsg *sinit;
if ((size_t)m->m_len < sizeof(struct sctp_initmsg)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_initmsg)) {
error = EINVAL;
break;
}
@ -2984,7 +2977,7 @@ sctp_optsget(struct socket *so,
sinit->sinit_max_attempts = inp->sctp_ep.max_init_times;
sinit->sinit_max_init_timeo = inp->sctp_ep.initial_init_rto_max;
SCTP_INP_RUNLOCK(inp);
m->m_len = sizeof(*sinit);
SCTP_BUF_LEN(m) = sizeof(*sinit);
}
break;
case SCTP_PRIMARY_ADDR:
@ -2992,7 +2985,7 @@ sctp_optsget(struct socket *so,
{
struct sctp_setprim *ssp;
if ((size_t)m->m_len < sizeof(struct sctp_setprim)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_setprim)) {
error = EINVAL;
break;
}
@ -3030,7 +3023,7 @@ sctp_optsget(struct socket *so,
&stcb->asoc.primary_destination->ro._l_addr,
((struct sockaddr *)&stcb->asoc.primary_destination->ro._l_addr)->sa_len);
SCTP_TCB_UNLOCK(stcb);
m->m_len = sizeof(*ssp);
SCTP_BUF_LEN(m) = sizeof(*ssp);
}
break;
@ -3041,7 +3034,7 @@ sctp_optsget(struct socket *so,
uint32_t size;
int i;
if ((size_t)(m->m_len) < sizeof(*shmac)) {
if ((size_t)(SCTP_BUF_LEN(m)) < sizeof(*shmac)) {
error = EINVAL;
break;
}
@ -3050,13 +3043,13 @@ sctp_optsget(struct socket *so,
hmaclist = inp->sctp_ep.local_hmacs;
if (hmaclist == NULL) {
/* no HMACs to return */
m->m_len = sizeof(*shmac);
SCTP_BUF_LEN(m) = sizeof(*shmac);
break;
}
/* is there room for all of the hmac ids? */
size = sizeof(*shmac) + (hmaclist->num_algo *
sizeof(shmac->shmac_idents[0]));
if ((size_t)(m->m_len) < size) {
if ((size_t)(SCTP_BUF_LEN(m)) < size) {
error = EINVAL;
SCTP_INP_RUNLOCK(inp);
break;
@ -3065,14 +3058,14 @@ sctp_optsget(struct socket *so,
for (i = 0; i < hmaclist->num_algo; i++)
shmac->shmac_idents[i] = hmaclist->hmac[i];
SCTP_INP_RUNLOCK(inp);
m->m_len = size;
SCTP_BUF_LEN(m) = size;
break;
}
case SCTP_AUTH_ACTIVE_KEY:
{
struct sctp_authkeyid *scact;
if ((size_t)(m->m_len) < sizeof(*scact)) {
if ((size_t)(SCTP_BUF_LEN(m)) < sizeof(*scact)) {
error = EINVAL;
break;
}
@ -3104,7 +3097,7 @@ sctp_optsget(struct socket *so,
scact->scact_keynumber = inp->sctp_ep.default_keyid;
SCTP_INP_RUNLOCK(inp);
}
m->m_len = sizeof(*scact);
SCTP_BUF_LEN(m) = sizeof(*scact);
break;
}
case SCTP_LOCAL_AUTH_CHUNKS:
@ -3113,7 +3106,7 @@ sctp_optsget(struct socket *so,
sctp_auth_chklist_t *chklist = NULL;
int size = 0;
if ((size_t)(m->m_len) < sizeof(*sac)) {
if ((size_t)(SCTP_BUF_LEN(m)) < sizeof(*sac)) {
error = EINVAL;
break;
}
@ -3145,7 +3138,7 @@ sctp_optsget(struct socket *so,
}
/* is there enough space? */
size = sctp_auth_get_chklist_size(chklist);
if ((size_t)m->m_len < (sizeof(struct sctp_authchunks) + size)) {
if ((size_t)SCTP_BUF_LEN(m) < (sizeof(struct sctp_authchunks) + size)) {
error = EINVAL;
SCTP_TCB_UNLOCK(stcb);
break;
@ -3164,7 +3157,7 @@ sctp_optsget(struct socket *so,
}
/* is there enough space? */
size = sctp_auth_get_chklist_size(chklist);
if ((size_t)m->m_len < (sizeof(struct sctp_authchunks) + size)) {
if ((size_t)SCTP_BUF_LEN(m) < (sizeof(struct sctp_authchunks) + size)) {
error = EINVAL;
SCTP_INP_RUNLOCK(inp);
break;
@ -3173,7 +3166,7 @@ sctp_optsget(struct socket *so,
sctp_serialize_auth_chunks(chklist, sac->gauth_chunks);
SCTP_INP_RUNLOCK(inp);
}
m->m_len = sizeof(struct sctp_authchunks) + size;
SCTP_BUF_LEN(m) = sizeof(struct sctp_authchunks) + size;
break;
}
case SCTP_PEER_AUTH_CHUNKS:
@ -3182,7 +3175,7 @@ sctp_optsget(struct socket *so,
sctp_auth_chklist_t *chklist = NULL;
int size = 0;
if ((size_t)(m->m_len) < sizeof(*sac)) {
if ((size_t)(SCTP_BUF_LEN(m)) < sizeof(*sac)) {
error = EINVAL;
break;
}
@ -3213,7 +3206,7 @@ sctp_optsget(struct socket *so,
}
/* is there enough space? */
size = sctp_auth_get_chklist_size(chklist);
if ((size_t)m->m_len < (sizeof(struct sctp_authchunks) + size)) {
if ((size_t)SCTP_BUF_LEN(m) < (sizeof(struct sctp_authchunks) + size)) {
error = EINVAL;
SCTP_TCB_UNLOCK(stcb);
break;
@ -3221,14 +3214,14 @@ sctp_optsget(struct socket *so,
/* copy in the chunks */
sctp_serialize_auth_chunks(chklist, sac->gauth_chunks);
SCTP_TCB_UNLOCK(stcb);
m->m_len = sizeof(struct sctp_authchunks) + size;
SCTP_BUF_LEN(m) = sizeof(struct sctp_authchunks) + size;
break;
}
default:
error = ENOPROTOOPT;
m->m_len = 0;
SCTP_BUF_LEN(m) = 0;
break;
} /* end switch (sopt->sopt_name) */
return (error);
@ -3268,7 +3261,7 @@ sctp_optsset(struct socket *so,
case SCTP_USE_EXT_RCVINFO:
case SCTP_I_WANT_MAPPED_V4_ADDR:
/* copy in the option value */
if ((size_t)m->m_len < sizeof(int)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(int)) {
error = EINVAL;
break;
}
@ -3318,12 +3311,12 @@ sctp_optsset(struct socket *so,
break;
case SCTP_PARTIAL_DELIVERY_POINT:
{
if ((size_t)m->m_len < sizeof(unsigned int)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(unsigned int)) {
error = EINVAL;
break;
}
inp->partial_delivery_point = *mtod(m, unsigned int *);
m->m_len = sizeof(unsigned int);
SCTP_BUF_LEN(m) = sizeof(unsigned int);
}
break;
case SCTP_FRAGMENT_INTERLEAVE:
@ -3331,7 +3324,7 @@ sctp_optsset(struct socket *so,
{
int on_off;
if ((size_t)m->m_len < sizeof(int)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(int)) {
error = EINVAL;
break;
}
@ -3347,7 +3340,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_assoc_value *av;
if ((size_t)m->m_len < sizeof(struct sctp_assoc_value)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_value)) {
error = EINVAL;
break;
}
@ -3371,7 +3364,7 @@ sctp_optsset(struct socket *so,
break;
case SCTP_CMT_USE_DAC:
{
if ((size_t)m->m_len < sizeof(unsigned int)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(unsigned int)) {
error = EINVAL;
break;
}
@ -3392,7 +3385,7 @@ sctp_optsset(struct socket *so,
struct sctp_assoc_value *av;
if ((size_t)m->m_len < sizeof(struct sctp_assoc_value)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_value)) {
error = EINVAL;
break;
}
@ -3414,7 +3407,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_assoc_value *tm;
if ((size_t)m->m_len < sizeof(struct sctp_assoc_value)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_value)) {
error = EINVAL;
break;
}
@ -3453,7 +3446,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_authchunk *sauth;
if ((size_t)m->m_len < sizeof(*sauth)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(*sauth)) {
error = EINVAL;
break;
}
@ -3471,7 +3464,7 @@ sctp_optsset(struct socket *so,
sctp_key_t *key = NULL;
int size;
size = m->m_len - sizeof(*sca);
size = SCTP_BUF_LEN(m) - sizeof(*sca);
if (size < 0) {
error = EINVAL;
break;
@ -3564,7 +3557,7 @@ sctp_optsset(struct socket *so,
uint32_t hmacid;
int size, i;
size = m->m_len - sizeof(*shmac);
size = SCTP_BUF_LEN(m) - sizeof(*shmac);
if (size < 0) {
error = EINVAL;
break;
@ -3598,7 +3591,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_authkeyid *scact;
if ((size_t)m->m_len < sizeof(*scact)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(*scact)) {
error = EINVAL;
break;
}
@ -3639,7 +3632,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_authkeyid *scdel;
if ((size_t)m->m_len < sizeof(*scdel)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(*scdel)) {
error = EINVAL;
break;
}
@ -3681,7 +3674,7 @@ sctp_optsset(struct socket *so,
uint8_t send_in = 0, send_tsn = 0, send_out = 0;
int i;
if ((size_t)m->m_len < sizeof(struct sctp_stream_reset)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_stream_reset)) {
error = EINVAL;
break;
}
@ -3760,7 +3753,7 @@ sctp_optsset(struct socket *so,
}
break;
case SCTP_CONNECT_X:
if ((size_t)m->m_len < (sizeof(int) + sizeof(struct sockaddr_in))) {
if ((size_t)SCTP_BUF_LEN(m) < (sizeof(int) + sizeof(struct sockaddr_in))) {
error = EINVAL;
break;
}
@ -3768,7 +3761,7 @@ sctp_optsset(struct socket *so,
break;
case SCTP_CONNECT_X_DELAYED:
if ((size_t)m->m_len < (sizeof(int) + sizeof(struct sockaddr_in))) {
if ((size_t)SCTP_BUF_LEN(m) < (sizeof(int) + sizeof(struct sockaddr_in))) {
error = EINVAL;
break;
}
@ -3780,7 +3773,7 @@ sctp_optsset(struct socket *so,
struct sockaddr *sa;
struct sctp_nets *net;
if ((size_t)m->m_len < sizeof(struct sockaddr_in)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sockaddr_in)) {
error = EINVAL;
break;
}
@ -3863,7 +3856,7 @@ sctp_optsset(struct socket *so,
{
uint32_t *level;
if ((size_t)m->m_len < sizeof(uint32_t)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(uint32_t)) {
error = EINVAL;
break;
}
@ -3883,7 +3876,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_event_subscribe *events;
if ((size_t)m->m_len < sizeof(struct sctp_event_subscribe)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_event_subscribe)) {
error = EINVAL;
break;
}
@ -3956,7 +3949,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_setadaptation *adap_bits;
if ((size_t)m->m_len < sizeof(struct sctp_setadaptation)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_setadaptation)) {
error = EINVAL;
break;
}
@ -3970,7 +3963,7 @@ sctp_optsset(struct socket *so,
{
uint32_t *vvv;
if ((size_t)m->m_len < sizeof(uint32_t)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(uint32_t)) {
error = EINVAL;
break;
}
@ -3984,7 +3977,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_sndrcvinfo *s_info;
if (m->m_len != sizeof(struct sctp_sndrcvinfo)) {
if (SCTP_BUF_LEN(m) != sizeof(struct sctp_sndrcvinfo)) {
error = EINVAL;
break;
}
@ -4027,7 +4020,7 @@ sctp_optsset(struct socket *so,
struct sctp_paddrparams *paddrp;
struct sctp_nets *net;
if ((size_t)m->m_len < sizeof(struct sctp_paddrparams)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_paddrparams)) {
error = EINVAL;
break;
}
@ -4112,7 +4105,7 @@ sctp_optsset(struct socket *so,
net->dest_state &= ~SCTP_ADDR_NOHB;
}
if (paddrp->spp_flags & SPP_PMTUD_DISABLE) {
if (callout_pending(&net->pmtu_timer.timer)) {
if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10);
}
@ -4123,7 +4116,7 @@ sctp_optsset(struct socket *so,
}
}
if (paddrp->spp_flags & SPP_PMTUD_ENABLE) {
if (callout_pending(&net->pmtu_timer.timer)) {
if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
}
}
@ -4220,7 +4213,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_rtoinfo *srto;
if ((size_t)m->m_len < sizeof(struct sctp_rtoinfo)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_rtoinfo)) {
error = EINVAL;
break;
}
@ -4266,7 +4259,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_assocparams *sasoc;
if ((size_t)m->m_len < sizeof(struct sctp_assocparams)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assocparams)) {
error = EINVAL;
break;
}
@ -4314,7 +4307,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_initmsg *sinit;
if ((size_t)m->m_len < sizeof(struct sctp_initmsg)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_initmsg)) {
error = EINVAL;
break;
}
@ -4343,7 +4336,7 @@ sctp_optsset(struct socket *so,
struct sctp_setprim *spa;
struct sctp_nets *net, *lnet;
if ((size_t)m->m_len < sizeof(struct sctp_setprim)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_setprim)) {
error = EINVAL;
break;
}
@ -4405,7 +4398,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_setpeerprim *sspp;
if ((size_t)m->m_len < sizeof(struct sctp_setpeerprim)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_setpeerprim)) {
error = EINVAL;
break;
}
@ -4441,7 +4434,7 @@ sctp_optsset(struct socket *so,
error = EINVAL;
break;
}
if ((size_t)m->m_len < sizeof(struct sctp_getaddresses)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_getaddresses)) {
error = EINVAL;
break;
}
@ -4517,7 +4510,7 @@ sctp_optsset(struct socket *so,
error = EINVAL;
break;
}
if ((size_t)m->m_len < sizeof(struct sctp_getaddresses)) {
if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_getaddresses)) {
error = EINVAL;
break;
}
@ -4606,7 +4599,7 @@ sctp_ctloutput(struct socket *so, struct sockopt *sopt)
(void)sctp_m_free(m);
goto out;
}
m->m_len = sopt->sopt_valsize;
SCTP_BUF_LEN(m) = sopt->sopt_valsize;
}
if (sopt->sopt_dir == SOPT_SET) {
error = sctp_optsset(so, sopt->sopt_name, &m, sopt->sopt_td);
@ -4616,7 +4609,7 @@ sctp_ctloutput(struct socket *so, struct sockopt *sopt)
error = EINVAL;
}
if ((error == 0) && (m != NULL)) {
error = sooptcopyout(sopt, mtod(m, caddr_t), m->m_len);
error = sooptcopyout(sopt, mtod(m, caddr_t), SCTP_BUF_LEN(m));
sctp_m_freem(m);
} else if (m != NULL) {
sctp_m_freem(m);

View File

@ -96,11 +96,12 @@ __FBSDID("$FreeBSD$");
#define SCTPCTL_ADD_MORE 47
#define SCTPCTL_SYS_RESC 48
#define SCTPCTL_ASOC_RESC 49
#define SCTPCTL_NAT_FRIENDLY 50
#ifdef SCTP_DEBUG
#define SCTPCTL_DEBUG 50
#define SCTPCTL_MAXID 50
#define SCTPCTL_DEBUG 51
#define SCTPCTL_MAXID 51
#else
#define SCTPCTL_MAXID 49
#define SCTPCTL_MAXID 50
#endif
#ifdef SCTP_DEBUG
@ -155,6 +156,7 @@ __FBSDID("$FreeBSD$");
{ "add_more_on_output", CTLTYPE_INT }, \
{ "sys_resource", CTLTYPE_INT }, \
{ "asoc_resource", CTLTYPE_INT }, \
{ "nat_friendly", CTLTYPE_INT }, \
{ "debug", CTLTYPE_INT }, \
}
#else
@ -209,12 +211,12 @@ __FBSDID("$FreeBSD$");
{ "add_more_on_output", CTLTYPE_INT }, \
{ "sys_resource", CTLTYPE_INT }, \
{ "asoc_resource", CTLTYPE_INT }, \
{ "nat_friendly", CTLTYPE_INT }, \
}
#endif
#if defined(_KERNEL)
#ifdef SYSCTL_DECL
@ -317,14 +319,12 @@ extern uint32_t sctp_system_free_resc_limit;
#define sctp_free_remote_addr(__net) { \
if ((__net)) { \
if (atomic_fetchadd_int(&(__net)->ref_count, -1) == 1) { \
callout_stop(&(__net)->rxt_timer.timer); \
callout_stop(&(__net)->pmtu_timer.timer); \
callout_stop(&(__net)->fr_timer.timer); \
SCTP_OS_TIMER_STOP(&(__net)->rxt_timer.timer); \
SCTP_OS_TIMER_STOP(&(__net)->pmtu_timer.timer); \
SCTP_OS_TIMER_STOP(&(__net)->fr_timer.timer); \
(__net)->dest_state = SCTP_ADDR_NOT_REACHABLE; \
SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_net, (__net)); \
SCTP_DECR_RADDR_COUNT(); \
@ -332,59 +332,58 @@ extern uint32_t sctp_system_free_resc_limit;
} \
}
#define sctp_sbfree(ctl, stcb, sb, m) { \
uint32_t val; \
val = atomic_fetchadd_int(&(sb)->sb_cc,-((m)->m_len)); \
if(val < (m)->m_len) { \
val = atomic_fetchadd_int(&(sb)->sb_cc,-(SCTP_BUF_LEN((m)))); \
if(val < SCTP_BUF_LEN((m))) { \
panic("sb_cc goes negative"); \
} \
val = atomic_fetchadd_int(&(sb)->sb_mbcnt,-(MSIZE)); \
if(val < MSIZE) { \
panic("sb_mbcnt goes negative"); \
} \
if ((m)->m_flags & M_EXT) { \
val = atomic_fetchadd_int(&(sb)->sb_mbcnt,-((m)->m_ext.ext_size)); \
if(val < (m)->m_ext.ext_size) { \
if (SCTP_BUF_IS_EXTENDED(m)) { \
val = atomic_fetchadd_int(&(sb)->sb_mbcnt,-(SCTP_BUF_EXTEND_SIZE(m))); \
if(val < SCTP_BUF_EXTEND_SIZE(m)) { \
panic("sb_mbcnt goes negative2"); \
} \
} \
if (((ctl)->do_not_ref_stcb == 0) && stcb) {\
val = atomic_fetchadd_int(&(stcb)->asoc.sb_cc,-((m)->m_len)); \
if(val < (m)->m_len) {\
val = atomic_fetchadd_int(&(stcb)->asoc.sb_cc,-(SCTP_BUF_LEN((m)))); \
if(val < SCTP_BUF_LEN((m))) {\
panic("stcb->sb_cc goes negative"); \
} \
val = atomic_fetchadd_int(&(stcb)->asoc.sb_mbcnt,-(MSIZE)); \
if(val < MSIZE) { \
panic("asoc->mbcnt goes negative"); \
} \
if ((m)->m_flags & M_EXT) { \
val = atomic_fetchadd_int(&(stcb)->asoc.sb_mbcnt,-((m)->m_ext.ext_size)); \
if(val < (m)->m_ext.ext_size) { \
if (SCTP_BUF_IS_EXTENDED(m)) { \
val = atomic_fetchadd_int(&(stcb)->asoc.sb_mbcnt,-(SCTP_BUF_EXTEND_SIZE(m))); \
if(val < SCTP_BUF_EXTEND_SIZE(m)) { \
panic("assoc stcb->mbcnt would go negative"); \
} \
} \
} \
if ((m)->m_type != MT_DATA && (m)->m_type != MT_HEADER && \
(m)->m_type != MT_OOBDATA) \
atomic_subtract_int(&(sb)->sb_ctl,(m)->m_len); \
if (SCTP_BUF_TYPE(m) != MT_DATA && SCTP_BUF_TYPE(m) != MT_HEADER && \
SCTP_BUF_TYPE(m) != MT_OOBDATA) \
atomic_subtract_int(&(sb)->sb_ctl,SCTP_BUF_LEN((m))); \
}
#define sctp_sballoc(stcb, sb, m) { \
atomic_add_int(&(sb)->sb_cc,(m)->m_len); \
atomic_add_int(&(sb)->sb_cc,SCTP_BUF_LEN((m))); \
atomic_add_int(&(sb)->sb_mbcnt, MSIZE); \
if ((m)->m_flags & M_EXT) \
atomic_add_int(&(sb)->sb_mbcnt,(m)->m_ext.ext_size); \
if (SCTP_BUF_IS_EXTENDED(m)) \
atomic_add_int(&(sb)->sb_mbcnt,SCTP_BUF_EXTEND_SIZE(m)); \
if(stcb) { \
atomic_add_int(&(stcb)->asoc.sb_cc,(m)->m_len); \
atomic_add_int(&(stcb)->asoc.sb_cc,SCTP_BUF_LEN((m))); \
atomic_add_int(&(stcb)->asoc.sb_mbcnt, MSIZE); \
if ((m)->m_flags & M_EXT) \
atomic_add_int(&(stcb)->asoc.sb_mbcnt,(m)->m_ext.ext_size); \
if (SCTP_BUF_IS_EXTENDED(m)) \
atomic_add_int(&(stcb)->asoc.sb_mbcnt,SCTP_BUF_EXTEND_SIZE(m)); \
} \
if ((m)->m_type != MT_DATA && (m)->m_type != MT_HEADER && \
(m)->m_type != MT_OOBDATA) \
atomic_add_int(&(sb)->sb_ctl,(m)->m_len); \
if (SCTP_BUF_TYPE(m) != MT_DATA && SCTP_BUF_TYPE(m) != MT_HEADER && \
SCTP_BUF_TYPE(m) != MT_OOBDATA) \
atomic_add_int(&(sb)->sb_ctl,SCTP_BUF_LEN((m))); \
}
@ -403,15 +402,18 @@ extern uint32_t sctp_system_free_resc_limit;
#define sctp_mbuf_crush(data) do { \
struct mbuf *_m; \
_m = (data); \
while(_m && (_m->m_len == 0)) { \
(data) = _m->m_next; \
_m->m_next = NULL; \
while(_m && (SCTP_BUF_LEN(_m) == 0)) { \
(data) = SCTP_BUF_NEXT(_m); \
SCTP_BUF_NEXT(_m) = NULL; \
sctp_m_free(_m); \
_m = (data); \
} \
} while (0)
/*
* some sysctls
*/
extern int sctp_sendspace;
extern int sctp_recvspace;
extern int sctp_ecn_enable;
@ -420,12 +422,13 @@ extern int sctp_use_cwnd_based_maxburst;
extern unsigned int sctp_cmt_on_off;
extern unsigned int sctp_cmt_use_dac;
extern unsigned int sctp_cmt_sockopt_on_off;
extern uint32_t sctp_nat_friendly;
struct sctp_nets;
struct sctp_inpcb;
struct sctp_tcb;
struct sctphdr;
void sctp_ctlinput __P((int, struct sockaddr *, void *));
int sctp_ctloutput __P((struct socket *, struct sockopt *));
void sctp_input __P((struct mbuf *, int));
@ -450,11 +453,9 @@ __P((struct sctp_inpcb *, int, struct sctphdr *,
/* can't use sctp_assoc_t here */
int sctp_peeloff(struct socket *, struct socket *, int, caddr_t, int *);
sctp_assoc_t sctp_getassocid(struct sockaddr *);
int sctp_ingetaddr(struct socket *,
struct sockaddr **
);
@ -465,12 +466,9 @@ __P((struct sctp_inpcb *, int, struct sctphdr *,
int sctp_listen(struct socket *, int, struct thread *);
int sctp_accept(struct socket *, struct sockaddr **);
#endif /* _KERNEL */
#endif /* !_NETINET_SCTP_VAR_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -118,7 +118,7 @@ sctp6_input(mp, offp, proto)
int proto;
{
struct mbuf *m = *mp;
struct mbuf *m;
struct ip6_hdr *ip6;
struct sctphdr *sh;
struct sctp_inpcb *in6p = NULL;
@ -133,6 +133,8 @@ sctp6_input(mp, offp, proto)
int off = *offp;
int s;
m = SCTP_HEADER_TO_CHAIN(*mp);
ip6 = mtod(m, struct ip6_hdr *);
#ifndef PULLDOWN_TEST
/* If PULLDOWN_TEST off, must be in a single mbuf. */
@ -163,7 +165,7 @@ sctp6_input(mp, offp, proto)
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_INPUT1) {
printf("V6 input gets a packet iphlen:%d pktlen:%d\n", iphlen, m->m_pkthdr.len);
printf("V6 input gets a packet iphlen:%d pktlen:%d\n", iphlen, SCTP_HEADER_LEN((*mp)));
}
#endif
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
@ -174,8 +176,7 @@ sctp6_input(mp, offp, proto)
if (sh->dest_port == 0)
goto bad;
if ((sctp_no_csum_on_loopback == 0) ||
(m->m_pkthdr.rcvif == NULL) ||
(m->m_pkthdr.rcvif->if_type != IFT_LOOP)) {
(!SCTP_IS_IT_LOOPBACK(m))) {
/*
* we do NOT validate things from the loopback if the sysctl
* is set to 1.
@ -214,10 +215,8 @@ sctp6_input(mp, offp, proto)
goto bad;
}
sh->checksum = calc_check;
} else {
sctp_skip_csum:
mlen = m->m_pkthdr.len;
}
sctp_skip_csum:
net = NULL;
/*
* Locate pcb and tcb for datagram sctp_findassociation_addr() wants
@ -270,9 +269,12 @@ sctp6_input(mp, offp, proto)
/*
* CONTROL chunk processing
*/
length = ntohs(ip6->ip6_plen) + iphlen;
offset -= sizeof(*ch);
ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff);
/* Length now holds the total packet length payload + iphlen */
length = ntohs(ip6->ip6_plen) + iphlen;
s = splnet();
(void)sctp_common_input_processing(&m, iphlen, offset, length, sh, ch,
in6p, stcb, net, ecn_bits);
@ -420,8 +422,7 @@ sctp6_ctlinput(cmd, pktdst, d)
struct sctp_nets *net = NULL;
struct sockaddr_in6 final;
if (ip6cp->ip6c_m == NULL ||
(size_t)ip6cp->ip6c_m->m_pkthdr.len < (ip6cp->ip6c_off + sizeof(sh)))
if (ip6cp->ip6c_m == NULL)
return;
bzero(&sh, sizeof(sh));
@ -818,9 +819,9 @@ sctp6_disconnect(struct socket *so)
struct sctp_paramhdr *ph;
ph = mtod(err, struct sctp_paramhdr *);
err->m_len = sizeof(struct sctp_paramhdr);
SCTP_BUF_LEN(err) = sizeof(struct sctp_paramhdr);
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
ph->param_length = htons(err->m_len);
ph->param_length = htons(SCTP_BUF_LEN(err));
}
sctp_send_abort_tcb(stcb, err);
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
@ -982,22 +983,9 @@ sctp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
}
inp->control = control;
}
/* add it in possibly */
if ((inp->pkt) &&
(inp->pkt->m_flags & M_PKTHDR)) {
struct mbuf *x;
int c_len;
c_len = 0;
/* How big is it */
for (x = m; x; x = x->m_next) {
c_len += x->m_len;
}
inp->pkt->m_pkthdr.len += c_len;
}
/* Place the data */
if (inp->pkt) {
inp->pkt_last->m_next = m;
SCTP_BUF_NEXT(inp->pkt_last) = m;
inp->pkt_last = m;
} else {
inp->pkt_last = inp->pkt = m;