summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netinet/sctp_output.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-09 14:02:09 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:38 +0200
commitbb80d9df8bac71eedee1a6787ca63aef972a7e48 (patch)
tree1b5cb9443c5ead5706c35afb618abbbd1592315e /freebsd/sys/netinet/sctp_output.c
parentUpdate to FreeBSD head 2017-10-01 (diff)
downloadrtems-libbsd-bb80d9df8bac71eedee1a6787ca63aef972a7e48.tar.bz2
Update to FreeBSD head 2017-12-01
Git mirror commit e724f51f811a4b2bd29447f8b85ab5c2f9b88266. Update #3472.
Diffstat (limited to 'freebsd/sys/netinet/sctp_output.c')
-rw-r--r--freebsd/sys/netinet/sctp_output.c58
1 files changed, 32 insertions, 26 deletions
diff --git a/freebsd/sys/netinet/sctp_output.c b/freebsd/sys/netinet/sctp_output.c
index 2540b5b9..bc54ee96 100644
--- a/freebsd/sys/netinet/sctp_output.c
+++ b/freebsd/sys/netinet/sctp_output.c
@@ -1,6 +1,8 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
* Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
@@ -3467,32 +3469,35 @@ static int
sctp_find_cmsg(int c_type, void *data, struct mbuf *control, size_t cpsize)
{
struct cmsghdr cmh;
- int tlen, at, found;
struct sctp_sndinfo sndinfo;
struct sctp_prinfo prinfo;
struct sctp_authinfo authinfo;
+ int tot_len, rem_len, cmsg_data_len, cmsg_data_off, off;
+ int found;
- tlen = SCTP_BUF_LEN(control);
- at = 0;
- found = 0;
/*
* Independent of how many mbufs, find the c_type inside the control
* structure and copy out the data.
*/
- while (at < tlen) {
- if ((tlen - at) < (int)CMSG_ALIGN(sizeof(cmh))) {
+ found = 0;
+ tot_len = SCTP_BUF_LEN(control);
+ for (off = 0; off < tot_len; off += CMSG_ALIGN(cmh.cmsg_len)) {
+ rem_len = tot_len - off;
+ if (rem_len < (int)CMSG_ALIGN(sizeof(cmh))) {
/* There is not enough room for one more. */
return (found);
}
- m_copydata(control, at, sizeof(cmh), (caddr_t)&cmh);
+ m_copydata(control, off, sizeof(cmh), (caddr_t)&cmh);
if (cmh.cmsg_len < CMSG_ALIGN(sizeof(cmh))) {
/* We dont't have a complete CMSG header. */
return (found);
}
- if (((int)cmh.cmsg_len + at) > tlen) {
+ if ((cmh.cmsg_len > INT_MAX) || ((int)cmh.cmsg_len > rem_len)) {
/* We don't have the complete CMSG. */
return (found);
}
+ cmsg_data_len = (int)cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh));
+ cmsg_data_off = off + CMSG_ALIGN(sizeof(cmh));
if ((cmh.cmsg_level == IPPROTO_SCTP) &&
((c_type == cmh.cmsg_type) ||
((c_type == SCTP_SNDRCV) &&
@@ -3500,11 +3505,14 @@ sctp_find_cmsg(int c_type, void *data, struct mbuf *control, size_t cpsize)
(cmh.cmsg_type == SCTP_PRINFO) ||
(cmh.cmsg_type == SCTP_AUTHINFO))))) {
if (c_type == cmh.cmsg_type) {
- if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < cpsize) {
+ if (cpsize > INT_MAX) {
+ return (found);
+ }
+ if (cmsg_data_len < (int)cpsize) {
return (found);
}
/* It is exactly what we want. Copy it out. */
- m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), (int)cpsize, (caddr_t)data);
+ m_copydata(control, cmsg_data_off, (int)cpsize, (caddr_t)data);
return (1);
} else {
struct sctp_sndrcvinfo *sndrcvinfo;
@@ -3518,10 +3526,10 @@ sctp_find_cmsg(int c_type, void *data, struct mbuf *control, size_t cpsize)
}
switch (cmh.cmsg_type) {
case SCTP_SNDINFO:
- if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct sctp_sndinfo)) {
+ if (cmsg_data_len < (int)sizeof(struct sctp_sndinfo)) {
return (found);
}
- m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct sctp_sndinfo), (caddr_t)&sndinfo);
+ m_copydata(control, cmsg_data_off, sizeof(struct sctp_sndinfo), (caddr_t)&sndinfo);
sndrcvinfo->sinfo_stream = sndinfo.snd_sid;
sndrcvinfo->sinfo_flags = sndinfo.snd_flags;
sndrcvinfo->sinfo_ppid = sndinfo.snd_ppid;
@@ -3529,10 +3537,10 @@ sctp_find_cmsg(int c_type, void *data, struct mbuf *control, size_t cpsize)
sndrcvinfo->sinfo_assoc_id = sndinfo.snd_assoc_id;
break;
case SCTP_PRINFO:
- if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct sctp_prinfo)) {
+ if (cmsg_data_len < (int)sizeof(struct sctp_prinfo)) {
return (found);
}
- m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct sctp_prinfo), (caddr_t)&prinfo);
+ m_copydata(control, cmsg_data_off, sizeof(struct sctp_prinfo), (caddr_t)&prinfo);
if (prinfo.pr_policy != SCTP_PR_SCTP_NONE) {
sndrcvinfo->sinfo_timetolive = prinfo.pr_value;
} else {
@@ -3541,10 +3549,10 @@ sctp_find_cmsg(int c_type, void *data, struct mbuf *control, size_t cpsize)
sndrcvinfo->sinfo_flags |= prinfo.pr_policy;
break;
case SCTP_AUTHINFO:
- if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct sctp_authinfo)) {
+ if (cmsg_data_len < (int)sizeof(struct sctp_authinfo)) {
return (found);
}
- m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct sctp_authinfo), (caddr_t)&authinfo);
+ m_copydata(control, cmsg_data_off, sizeof(struct sctp_authinfo), (caddr_t)&authinfo);
sndrcvinfo->sinfo_keynumber_valid = 1;
sndrcvinfo->sinfo_keynumber = authinfo.auth_keynumber;
break;
@@ -3554,7 +3562,6 @@ sctp_find_cmsg(int c_type, void *data, struct mbuf *control, size_t cpsize)
found = 1;
}
}
- at += CMSG_ALIGN(cmh.cmsg_len);
}
return (found);
}
@@ -4270,12 +4277,8 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
/* free tempy routes */
RO_RTFREE(ro);
} else {
- /*
- * PMTU check versus smallest asoc MTU goes
- * here
- */
- if ((ro->ro_rt != NULL) &&
- (net->ro._s_addr)) {
+ if ((ro->ro_rt != NULL) && (net->ro._s_addr) &&
+ ((net->dest_state & SCTP_ADDR_NO_PMTUD) == 0)) {
uint32_t mtu;
mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, ro->ro_rt);
@@ -4632,8 +4635,8 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
}
net->src_addr_selected = 0;
}
- if ((ro->ro_rt != NULL) &&
- (net->ro._s_addr)) {
+ if ((ro->ro_rt != NULL) && (net->ro._s_addr) &&
+ ((net->dest_state & SCTP_ADDR_NO_PMTUD) == 0)) {
uint32_t mtu;
mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, ro->ro_rt);
@@ -5503,6 +5506,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct sctp_paramhdr *ph;
union sctp_sockstore *over_addr;
struct sctp_scoping scp;
+ struct timeval now;
#ifdef INET
struct sockaddr_in *dst4 = (struct sockaddr_in *)dst;
struct sockaddr_in *src4 = (struct sockaddr_in *)src;
@@ -5603,7 +5607,9 @@ do_a_abort:
memset(&stc, 0, sizeof(struct sctp_state_cookie));
/* the time I built cookie */
- (void)SCTP_GETTIME_TIMEVAL(&stc.time_entered);
+ (void)SCTP_GETTIME_TIMEVAL(&now);
+ stc.time_entered.tv_sec = now.tv_sec;
+ stc.time_entered.tv_usec = now.tv_usec;
/* populate any tie tags */
if (asoc != NULL) {