diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-08-07 14:56:50 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-09-21 10:29:37 +0200 |
commit | c37f9fba70085fedc8eede7559489d2321393005 (patch) | |
tree | 042455ebf1fa89a277a825f72e1ed805d0b4d296 /freebsd/sys/netinet/sctp_output.c | |
parent | Update to FreeBSD head 2017-06-01 (diff) | |
download | rtems-libbsd-c37f9fba70085fedc8eede7559489d2321393005.tar.bz2 |
Update to FreeBSD head 2017-08-01
Git mirror commit f5002f5e5f78cae9f0269d812dc0aedb0339312c.
Update #3472.
Diffstat (limited to 'freebsd/sys/netinet/sctp_output.c')
-rw-r--r-- | freebsd/sys/netinet/sctp_output.c | 136 |
1 files changed, 60 insertions, 76 deletions
diff --git a/freebsd/sys/netinet/sctp_output.c b/freebsd/sys/netinet/sctp_output.c index 221d0570..5e2fbbc2 100644 --- a/freebsd/sys/netinet/sctp_output.c +++ b/freebsd/sys/netinet/sctp_output.c @@ -1942,7 +1942,7 @@ static struct mbuf * sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t *len) { #if defined(INET) || defined(INET6) - struct sctp_paramhdr *parmh; + struct sctp_paramhdr *paramh; struct mbuf *mret; uint16_t plen; #endif @@ -1964,7 +1964,7 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t *len) #if defined(INET) || defined(INET6) if (M_TRAILINGSPACE(m) >= plen) { /* easy side we just drop it on the end */ - parmh = (struct sctp_paramhdr *)(SCTP_BUF_AT(m, SCTP_BUF_LEN(m))); + paramh = (struct sctp_paramhdr *)(SCTP_BUF_AT(m, SCTP_BUF_LEN(m))); mret = m; } else { /* Need more space */ @@ -1978,7 +1978,7 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t *len) return (m); } mret = SCTP_BUF_NEXT(mret); - parmh = mtod(mret, struct sctp_paramhdr *); + paramh = mtod(mret, struct sctp_paramhdr *); } /* now add the parameter */ switch (ifa->address.sa.sa_family) { @@ -1989,9 +1989,9 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t *len) struct sockaddr_in *sin; sin = &ifa->address.sin; - ipv4p = (struct sctp_ipv4addr_param *)parmh; - parmh->param_type = htons(SCTP_IPV4_ADDRESS); - parmh->param_length = htons(plen); + ipv4p = (struct sctp_ipv4addr_param *)paramh; + paramh->param_type = htons(SCTP_IPV4_ADDRESS); + paramh->param_length = htons(plen); ipv4p->addr = sin->sin_addr.s_addr; SCTP_BUF_LEN(mret) += plen; break; @@ -2004,9 +2004,9 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t *len) struct sockaddr_in6 *sin6; sin6 = &ifa->address.sin6; - ipv6p = (struct sctp_ipv6addr_param *)parmh; - parmh->param_type = htons(SCTP_IPV6_ADDRESS); - parmh->param_length = htons(plen); + ipv6p = (struct sctp_ipv6addr_param *)paramh; + paramh->param_type = htons(SCTP_IPV6_ADDRESS); + paramh->param_length = htons(plen); memcpy(ipv6p->addr, &sin6->sin6_addr, sizeof(ipv6p->addr)); /* clear embedded scope in the address */ @@ -4406,7 +4406,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, * we can try their selection but it may not be * bound. */ - bzero(&lsa6_tmp, sizeof(lsa6_tmp)); + memset(&lsa6_tmp, 0, sizeof(lsa6_tmp)); lsa6_tmp.sin6_family = AF_INET6; lsa6_tmp.sin6_len = sizeof(lsa6_tmp); lsa6 = &lsa6_tmp; @@ -4491,7 +4491,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, * XXX: sa6 may not have a valid sin6_scope_id in * the non-SCOPEDROUTING case. */ - bzero(&lsa6_storage, sizeof(lsa6_storage)); + memset(&lsa6_storage, 0, sizeof(lsa6_storage)); lsa6_storage.sin6_family = AF_INET6; lsa6_storage.sin6_len = sizeof(lsa6_storage); lsa6_storage.sin6_addr = lsa6->sin6_addr; @@ -5143,7 +5143,10 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt, s.param_length = htons(sizeof(s) + plen); m_copyback(op_err, err_at, sizeof(s), (caddr_t)&s); err_at += sizeof(s); - phdr = sctp_get_next_param(mat, at, (struct sctp_paramhdr *)tempbuf, min(sizeof(tempbuf), plen)); + if (plen > sizeof(tempbuf)) { + plen = sizeof(tempbuf); + } + phdr = sctp_get_next_param(mat, at, (struct sctp_paramhdr *)tempbuf, plen); if (phdr == NULL) { sctp_m_freem(op_err); /* @@ -5211,7 +5214,7 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt, if (plen > sizeof(tempbuf)) { plen = sizeof(tempbuf); } - phdr = sctp_get_next_param(mat, at, (struct sctp_paramhdr *)tempbuf, min(sizeof(tempbuf), plen)); + phdr = sctp_get_next_param(mat, at, (struct sctp_paramhdr *)tempbuf, plen); if (phdr == NULL) { sctp_m_freem(op_err); /* @@ -5392,10 +5395,12 @@ sctp_are_there_new_addresses(struct sctp_association *asoc, { struct sctp_ipv4addr_param *p4, p4_buf; + if (plen != sizeof(struct sctp_ipv4addr_param)) { + return (1); + } phdr = sctp_get_next_param(in_initpkt, offset, (struct sctp_paramhdr *)&p4_buf, sizeof(p4_buf)); - if (plen != sizeof(struct sctp_ipv4addr_param) || - phdr == NULL) { + if (phdr == NULL) { return (1); } if (asoc->scope.ipv4_addr_legal) { @@ -5411,10 +5416,12 @@ sctp_are_there_new_addresses(struct sctp_association *asoc, { struct sctp_ipv6addr_param *p6, p6_buf; + if (plen != sizeof(struct sctp_ipv6addr_param)) { + return (1); + } phdr = sctp_get_next_param(in_initpkt, offset, (struct sctp_paramhdr *)&p6_buf, sizeof(p6_buf)); - if (plen != sizeof(struct sctp_ipv6addr_param) || - phdr == NULL) { + if (phdr == NULL) { return (1); } if (asoc->scope.ipv6_addr_legal) { @@ -6245,11 +6252,7 @@ sctp_get_frag_point(struct sctp_tcb *stcb, } else { ovh = SCTP_MIN_V4_OVERHEAD; } - if (stcb->asoc.idata_supported) { - ovh += sizeof(struct sctp_idata_chunk); - } else { - ovh += sizeof(struct sctp_data_chunk); - } + ovh += SCTP_DATA_CHUNK_OVERHEAD(stcb); if (stcb->asoc.sctp_frag_point > asoc->smallest_mtu) siz = asoc->smallest_mtu - ovh; else @@ -6754,7 +6757,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr, } } un_sent = ((stcb->asoc.total_output_queue_size - stcb->asoc.total_flight) + - (stcb->asoc.stream_queue_cnt * sizeof(struct sctp_data_chunk))); + (stcb->asoc.stream_queue_cnt * SCTP_DATA_CHUNK_OVERHEAD(stcb))); if ((sctp_is_feature_off(inp, SCTP_PCB_FLAGS_NODELAY)) && (stcb->asoc.total_flight > 0) && @@ -7454,11 +7457,7 @@ dont_do_it: } else { atomic_subtract_int(&sp->length, to_move); } - if (stcb->asoc.idata_supported == 0) { - leading = sizeof(struct sctp_data_chunk); - } else { - leading = sizeof(struct sctp_idata_chunk); - } + leading = SCTP_DATA_CHUNK_OVERHEAD(stcb); if (M_LEADINGSPACE(chk->data) < leading) { /* Not enough room for a chunk header, get some */ struct mbuf *m; @@ -7500,11 +7499,7 @@ dont_do_it: M_ALIGN(chk->data, 4); } } - if (stcb->asoc.idata_supported == 0) { - SCTP_BUF_PREPEND(chk->data, sizeof(struct sctp_data_chunk), M_NOWAIT); - } else { - SCTP_BUF_PREPEND(chk->data, sizeof(struct sctp_idata_chunk), M_NOWAIT); - } + SCTP_BUF_PREPEND(chk->data, SCTP_DATA_CHUNK_OVERHEAD(stcb), M_NOWAIT); if (chk->data == NULL) { /* HELP, TSNH since we assured it would not above? */ #ifdef INVARIANTS @@ -7517,13 +7512,8 @@ dont_do_it: to_move = 0; goto out_of; } - if (stcb->asoc.idata_supported == 0) { - sctp_snd_sb_alloc(stcb, sizeof(struct sctp_data_chunk)); - chk->book_size = chk->send_size = (uint16_t)(to_move + sizeof(struct sctp_data_chunk)); - } else { - sctp_snd_sb_alloc(stcb, sizeof(struct sctp_idata_chunk)); - chk->book_size = chk->send_size = (uint16_t)(to_move + sizeof(struct sctp_idata_chunk)); - } + sctp_snd_sb_alloc(stcb, SCTP_DATA_CHUNK_OVERHEAD(stcb)); + chk->book_size = chk->send_size = (uint16_t)(to_move + SCTP_DATA_CHUNK_OVERHEAD(stcb)); chk->book_size_scale = 0; chk->sent = SCTP_DATAGRAM_UNSENT; @@ -7723,11 +7713,7 @@ sctp_fill_outqueue(struct sctp_tcb *stcb, break; } /* Need an allowance for the data chunk header too */ - if (stcb->asoc.idata_supported == 0) { - space_left -= sizeof(struct sctp_data_chunk); - } else { - space_left -= sizeof(struct sctp_idata_chunk); - } + space_left -= SCTP_DATA_CHUNK_OVERHEAD(stcb); /* must make even word boundary */ space_left &= 0xfffffffc; @@ -7744,18 +7730,10 @@ sctp_fill_outqueue(struct sctp_tcb *stcb, strq = stcb->asoc.ss_functions.sctp_ss_select_stream(stcb, net, asoc); total_moved += moved; space_left -= moved; - if (stcb->asoc.idata_supported == 0) { - if (space_left >= sizeof(struct sctp_data_chunk)) { - space_left -= sizeof(struct sctp_data_chunk); - } else { - space_left = 0; - } + if (space_left >= SCTP_DATA_CHUNK_OVERHEAD(stcb)) { + space_left -= SCTP_DATA_CHUNK_OVERHEAD(stcb); } else { - if (space_left >= sizeof(struct sctp_idata_chunk)) { - space_left -= sizeof(struct sctp_idata_chunk); - } else { - space_left = 0; - } + space_left = 0; } space_left &= 0xfffffffc; } @@ -9002,7 +8980,7 @@ sctp_send_cookie_echo(struct mbuf *m, */ int at; struct mbuf *cookie; - struct sctp_paramhdr parm, *phdr; + struct sctp_paramhdr param, *phdr; struct sctp_chunkhdr *hdr; struct sctp_tmit_chunk *chk; uint16_t ptype, plen; @@ -9012,7 +8990,7 @@ sctp_send_cookie_echo(struct mbuf *m, cookie = NULL; at = offset + sizeof(struct sctp_init_chunk); for (;;) { - phdr = sctp_get_next_param(m, at, &parm, sizeof(parm)); + phdr = sctp_get_next_param(m, at, ¶m, sizeof(param)); if (phdr == NULL) { return (-3); } @@ -10204,8 +10182,7 @@ do_it_again: * and we have data in flight we stop, except if we * are handling a fragmented user message. */ - un_sent = ((stcb->asoc.total_output_queue_size - stcb->asoc.total_flight) + - (stcb->asoc.stream_queue_cnt * sizeof(struct sctp_data_chunk))); + un_sent = stcb->asoc.total_output_queue_size - stcb->asoc.total_flight; if ((un_sent < (int)(stcb->asoc.smallest_mtu - SCTP_MIN_OVERHEAD)) && (stcb->asoc.total_flight > 0)) { /* && sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR))) {*/ @@ -12443,7 +12420,7 @@ sctp_copy_it_in(struct sctp_tcb *stcb, sp->sender_all_done = 0; sp->some_taken = 0; sp->put_last_out = 0; - resv_in_first = sizeof(struct sctp_data_chunk); + resv_in_first = SCTP_DATA_CHUNK_OVERHEAD(stcb); sp->data = sp->tail_mbuf = NULL; if (sp->length == 0) { *error = 0; @@ -12860,12 +12837,19 @@ sctp_lower_sosend(struct socket *so, } /* would we block? */ if (non_blocking) { + uint32_t amount; + if (hold_tcblock == 0) { SCTP_TCB_LOCK(stcb); hold_tcblock = 1; } - inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * sizeof(struct sctp_data_chunk)); - if ((SCTP_SB_LIMIT_SND(so) < (sndlen + inqueue_bytes + stcb->asoc.sb_send_resv)) || + inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * SCTP_DATA_CHUNK_OVERHEAD(stcb)); + if (user_marks_eor == 0) { + amount = sndlen; + } else { + amount = 1; + } + if ((SCTP_SB_LIMIT_SND(so) < (amount + inqueue_bytes + stcb->asoc.sb_send_resv)) || (stcb->asoc.chunks_on_out_queue >= SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue))) { SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EWOULDBLOCK); if (sndlen > SCTP_SB_LIMIT_SND(so)) @@ -13033,7 +13017,7 @@ sctp_lower_sosend(struct socket *so, goto out_unlocked; } /* Calculate the maximum we can send */ - inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * sizeof(struct sctp_data_chunk)); + inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * SCTP_DATA_CHUNK_OVERHEAD(stcb)); if (SCTP_SB_LIMIT_SND(so) > inqueue_bytes) { if (non_blocking) { /* we already checked for non-blocking above. */ @@ -13090,7 +13074,7 @@ sctp_lower_sosend(struct socket *so, ((stcb->asoc.chunks_on_out_queue + stcb->asoc.stream_queue_cnt) >= SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue))) { /* No room right now ! */ SOCKBUF_LOCK(&so->so_snd); - inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * sizeof(struct sctp_data_chunk)); + inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * SCTP_DATA_CHUNK_OVERHEAD(stcb)); while ((SCTP_SB_LIMIT_SND(so) < (inqueue_bytes + local_add_more)) || ((stcb->asoc.stream_queue_cnt + stcb->asoc.chunks_on_out_queue) >= SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue))) { SCTPDBG(SCTP_DEBUG_OUTPUT1, "pre_block limit:%u <(inq:%d + %d) || (%d+%d > %d)\n", @@ -13126,7 +13110,7 @@ sctp_lower_sosend(struct socket *so, SOCKBUF_UNLOCK(&so->so_snd); goto out_unlocked; } - inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * sizeof(struct sctp_data_chunk)); + inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * SCTP_DATA_CHUNK_OVERHEAD(stcb)); } if (SCTP_SB_LIMIT_SND(so) > inqueue_bytes) { max_len = SCTP_SB_LIMIT_SND(so) - inqueue_bytes; @@ -13219,8 +13203,9 @@ skip_preblock: /* How much room do we have? */ struct mbuf *new_tail, *mm; - if (SCTP_SB_LIMIT_SND(so) > stcb->asoc.total_output_queue_size) - max_len = SCTP_SB_LIMIT_SND(so) - stcb->asoc.total_output_queue_size; + inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * SCTP_DATA_CHUNK_OVERHEAD(stcb)); + if (SCTP_SB_LIMIT_SND(so) > inqueue_bytes) + max_len = SCTP_SB_LIMIT_SND(so) - inqueue_bytes; else max_len = 0; @@ -13296,8 +13281,8 @@ skip_preblock: hold_tcblock = 1; } sctp_prune_prsctp(stcb, asoc, srcv, sndlen); - inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * sizeof(struct sctp_data_chunk)); - if (SCTP_SB_LIMIT_SND(so) > stcb->asoc.total_output_queue_size) + inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * SCTP_DATA_CHUNK_OVERHEAD(stcb)); + if (SCTP_SB_LIMIT_SND(so) > inqueue_bytes) max_len = SCTP_SB_LIMIT_SND(so) - inqueue_bytes; else max_len = 0; @@ -13338,8 +13323,7 @@ skip_preblock: } asoc->ifp_had_enobuf = 0; } - un_sent = ((stcb->asoc.total_output_queue_size - stcb->asoc.total_flight) + - (stcb->asoc.stream_queue_cnt * sizeof(struct sctp_data_chunk))); + un_sent = stcb->asoc.total_output_queue_size - stcb->asoc.total_flight; if ((sctp_is_feature_off(inp, SCTP_PCB_FLAGS_NODELAY)) && (stcb->asoc.total_flight > 0) && (stcb->asoc.stream_queue_cnt < SCTP_MAX_DATA_BUNDLING) && @@ -13413,7 +13397,8 @@ skip_preblock: * size we KNOW we will get to sleep safely with the * wakeup flag in place. */ - if (SCTP_SB_LIMIT_SND(so) <= (stcb->asoc.total_output_queue_size + + inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * SCTP_DATA_CHUNK_OVERHEAD(stcb)); + if (SCTP_SB_LIMIT_SND(so) <= (inqueue_bytes + min(SCTP_BASE_SYSCTL(sctp_add_more_threshold), SCTP_SB_LIMIT_SND(so)))) { if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_BLK_LOGGING_ENABLE) { sctp_log_block(SCTP_BLOCK_LOG_INTO_BLK, @@ -13610,8 +13595,7 @@ skip_out_eof: } asoc->ifp_had_enobuf = 0; } - un_sent = ((stcb->asoc.total_output_queue_size - stcb->asoc.total_flight) + - (stcb->asoc.stream_queue_cnt * sizeof(struct sctp_data_chunk))); + un_sent = stcb->asoc.total_output_queue_size - stcb->asoc.total_flight; if ((sctp_is_feature_off(inp, SCTP_PCB_FLAGS_NODELAY)) && (stcb->asoc.total_flight > 0) && (stcb->asoc.stream_queue_cnt < SCTP_MAX_DATA_BUNDLING) && @@ -13750,7 +13734,7 @@ sctp_add_auth_chunk(struct mbuf *m, struct mbuf **m_end, SCTP_BUF_RESV_UF(m_auth, SCTP_MIN_OVERHEAD); /* fill in the AUTH chunk details */ auth = mtod(m_auth, struct sctp_auth_chunk *); - bzero(auth, sizeof(*auth)); + memset(auth, 0, sizeof(*auth)); auth->ch.chunk_type = SCTP_AUTHENTICATION; auth->ch.chunk_flags = 0; chunk_len = sizeof(*auth) + |