summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2014-07-20 18:31:19 -0700
committerBen Murdoch <benm@google.com>2014-07-20 18:31:19 -0700
commited9a6fb519aa7606cab965b2c4218756e849ddb6 (patch)
treee44213c06aa2801acffafafef538021815559979
parent46100e9a86ac58447f99ee8ed55a9d7eb01d101a (diff)
parent20d3b9ce7744465ea350696de9160a349cd52a05 (diff)
downloadusrsctplib-ed9a6fb519aa7606cab965b2c4218756e849ddb6.tar.gz
Merge from Chromium at DEPS revision 284076android-wear-5.1.1_r1android-wear-5.1.0_r1
This commit was generated by merge_to_master.py. Change-Id: Id9832ab1559c6be7b68890be21e02a23214c7e5f
-rwxr-xr-xnetinet/sctp_asconf.c68
-rwxr-xr-xnetinet/sctp_input.c8
-rwxr-xr-xnetinet/sctp_os_userspace.h18
-rwxr-xr-xnetinet/sctp_output.c244
-rwxr-xr-xnetinet/sctp_pcb.c121
-rwxr-xr-xnetinet/sctp_sysctl.c14
-rwxr-xr-xnetinet/sctp_timer.c4
-rwxr-xr-xnetinet/sctp_userspace.c4
-rwxr-xr-xnetinet/sctp_usrreq.c131
-rwxr-xr-xnetinet/sctputil.c14
-rwxr-xr-xuser_malloc.h10
-rwxr-xr-xuser_socket.c2
-rw-r--r--usrsctp.h1
13 files changed, 543 insertions, 96 deletions
diff --git a/netinet/sctp_asconf.c b/netinet/sctp_asconf.c
index 3f8b5f2..0f35ae1 100755
--- a/netinet/sctp_asconf.c
+++ b/netinet/sctp_asconf.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 257803 2013-11-07 17:08:09Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 267674 2014-06-20 13:26:49Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -1296,7 +1296,7 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
{
struct sockaddr_in *sin;
- sin= (struct sockaddr_in *)&ifa->address.sa;
+ sin = (struct sockaddr_in *)&ifa->address.sa;
aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
@@ -1900,14 +1900,26 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
* this is boundall or subset bound w/ASCONF allowed
*/
- /* first, make sure it's a good address family */
+ /* first, make sure that the address is IPv4 or IPv6 and not jailed */
switch (ifa->address.sa.sa_family) {
#ifdef INET6
case AF_INET6:
+#if defined(__FreeBSD__)
+ if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+ &ifa->address.sin6.sin6_addr) != 0) {
+ return;
+ }
+#endif
break;
#endif
#ifdef INET
case AF_INET:
+#if defined(__FreeBSD__)
+ if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+ &ifa->address.sin.sin_addr) != 0) {
+ return;
+ }
+#endif
break;
#endif
default:
@@ -2134,6 +2146,12 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/* we skip unspecifed addresses */
continue;
}
+#if defined(__FreeBSD__)
+ if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+ &sin6->sin6_addr) != 0) {
+ continue;
+ }
+#endif
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
if (stcb->asoc.scope.local_scope == 0) {
continue;
@@ -2164,6 +2182,12 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/* we skip unspecifed addresses */
continue;
}
+#if defined(__FreeBSD__)
+ if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+ &sin->sin_addr) != 0) {
+ continue;
+ }
+#endif
if (stcb->asoc.scope.ipv4_local_scope == 0 &&
IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
continue;
@@ -2221,7 +2245,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
} else if (type == SCTP_SET_PRIM_ADDR) {
if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
/* must validate the ifa is in the ep */
- if (sctp_is_addr_in_ep(stcb->sctp_ep,ifa) == 0) {
+ if (sctp_is_addr_in_ep(stcb->sctp_ep, ifa) == 0) {
continue;
}
} else {
@@ -2477,6 +2501,12 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
/* skip unspecifed addresses */
continue;
}
+#if defined(__FreeBSD__)
+ if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
+ &sin->sin_addr) != 0) {
+ continue;
+ }
+#endif
if (stcb->asoc.scope.ipv4_local_scope == 0 &&
IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))
continue;
@@ -2505,6 +2535,12 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
/* we skip unspecifed addresses */
continue;
}
+#if defined(__FreeBSD__)
+ if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
+ &sin6->sin6_addr) != 0) {
+ continue;
+ }
+#endif
if (stcb->asoc.scope.local_scope == 0 &&
IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
continue;
@@ -3116,6 +3152,12 @@ sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
#ifdef INET
case AF_INET:
sin = (struct sockaddr_in *)&sctp_ifa->address.sin;
+#if defined(__FreeBSD__)
+ if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
+ &sin->sin_addr) != 0) {
+ continue;
+ }
+#endif
if ((ipv4_scope == 0) &&
(IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
/* private address not in scope */
@@ -3126,6 +3168,12 @@ sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
#ifdef INET6
case AF_INET6:
sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sin6;
+#if defined(__FreeBSD__)
+ if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
+ &sin6->sin6_addr) != 0) {
+ continue;
+ }
+#endif
if ((local_scope == 0) &&
(IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
continue;
@@ -3413,6 +3461,12 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
#ifdef INET
case AF_INET:
to = &sctp_ifap->address.sin;
+#if defined(__FreeBSD__)
+ if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
+ &to->sin_addr) != 0) {
+ continue;
+ }
+#endif
if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
continue;
}
@@ -3424,6 +3478,12 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
#ifdef INET6
case AF_INET6:
to6 = &sctp_ifap->address.sin6;
+#if defined(__FreeBSD__)
+ if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
+ &to6->sin6_addr) != 0) {
+ continue;
+ }
+#endif
if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
continue;
}
diff --git a/netinet/sctp_input.c b/netinet/sctp_input.c
index 889f9bb..df244e8 100755
--- a/netinet/sctp_input.c
+++ b/netinet/sctp_input.c
@@ -49,9 +49,11 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 263237 2014-03-16 12:32:16Z tu
#include <netinet/sctp_bsd_addr.h>
#include <netinet/sctp_timer.h>
#include <netinet/sctp_crc32.h>
+#if defined INET || defined INET6
#if !defined(__Userspace_os_Windows)
#include <netinet/udp.h>
#endif
+#endif
#if defined(__FreeBSD__)
#include <sys/smp.h>
#endif
@@ -5754,12 +5756,14 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
calc_check, check, (void *)m, length, iphlen);
stcb = sctp_findassociation_addr(m, offset, src, dst,
sh, ch, &inp, &net, vrf_id);
+#if defined INET || defined INET6
if ((net != NULL) && (port != 0)) {
if (net->port == 0) {
sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr));
}
net->port = port;
}
+#endif
#if defined(__FreeBSD__)
if ((net != NULL) && (use_mflowid != 0)) {
net->flowid = mflowid;
@@ -5787,12 +5791,14 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
}
stcb = sctp_findassociation_addr(m, offset, src, dst,
sh, ch, &inp, &net, vrf_id);
+#if defined INET || defined INET6
if ((net != NULL) && (port != 0)) {
if (net->port == 0) {
sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr));
}
net->port = port;
}
+#endif
#if defined(__FreeBSD__)
if ((net != NULL) && (use_mflowid != 0)) {
net->flowid = mflowid;
@@ -5921,12 +5927,14 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
* and it changes our INP.
*/
inp = stcb->sctp_ep;
+#if defined INET || defined INET6
if ((net) && (port)) {
if (net->port == 0) {
sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr));
}
net->port = port;
}
+#endif
}
} else {
/*
diff --git a/netinet/sctp_os_userspace.h b/netinet/sctp_os_userspace.h
index f863295..eca3e18 100755
--- a/netinet/sctp_os_userspace.h
+++ b/netinet/sctp_os_userspace.h
@@ -217,11 +217,6 @@ typedef HANDLE userland_thread_t;
typedef char* caddr_t;
-int Win_getifaddrs(struct ifaddrs**);
-#define getifaddrs(interfaces) (int)Win_getifaddrs(interfaces)
-int win_if_nametoindex(const char *);
-#define if_nametoindex(x) win_if_nametoindex(x)
-
#define bzero(buf, len) memset(buf, 0, len)
#define bcopy(srcKey, dstKey, len) memcpy(dstKey, srcKey, len)
#define snprintf(data, size, format, ...) _snprintf_s(data, size, _TRUNCATE, format, __VA_ARGS__)
@@ -399,6 +394,11 @@ struct udphdr {
unsigned __int16 uh_sum;
};
+int Win_getifaddrs(struct ifaddrs**);
+#define getifaddrs(interfaces) (int)Win_getifaddrs(interfaces)
+int win_if_nametoindex(const char *);
+#define if_nametoindex(x) win_if_nametoindex(x)
+
#else /* !defined(Userspace_os_Windows) */
#include <sys/cdefs.h> /* needed? added from old __FreeBSD__ */
#include <sys/socket.h>
@@ -474,9 +474,13 @@ struct sx {int dummy;};
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-#else
+#endif
+#if defined INET
+#if defined(__Userspace_os_Windows)
#include <user_ip_icmp.h>
+#else
+#include <netinet/ip_icmp.h>
+#endif
#endif
/* #include <netinet/in_pcb.h> ported to userspace */
#include <user_inpcb.h>
diff --git a/netinet/sctp_output.c b/netinet/sctp_output.c
index 72f6bc3..14f2cc0 100755
--- a/netinet/sctp_output.c
+++ b/netinet/sctp_output.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 264017 2014-04-01 18:38:04Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 267674 2014-06-20 13:26:49Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -57,9 +57,11 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 264017 2014-04-01 18:38:04Z t
#if defined(__Userspace_os_Linux)
#define __FAVOR_BSD /* (on Ubuntu at least) enables UDP header field names like BSD in RFC 768 */
#endif
+#if defined INET || defined INET6
#if !defined(__Userspace_os_Windows)
#include <netinet/udp.h>
#endif
+#endif
#if defined(__APPLE__)
#include <netinet/in.h>
#endif
@@ -2096,6 +2098,22 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
continue;
}
LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) {
+#if defined(__FreeBSD__)
+#ifdef INET
+ if ((sctp_ifap->address.sa.sa_family == AF_INET) &&
+ (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+ &sctp_ifap->address.sin.sin_addr) != 0)) {
+ continue;
+ }
+#endif
+#ifdef INET6
+ if ((sctp_ifap->address.sa.sa_family == AF_INET6) &&
+ (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+ &sctp_ifap->address.sin6.sin6_addr) != 0)) {
+ continue;
+ }
+#endif
+#endif
if (sctp_is_addr_restricted(stcb, sctp_ifap)) {
continue;
}
@@ -2130,6 +2148,22 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
continue;
}
LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) {
+#if defined(__FreeBSD__)
+#ifdef INET
+ if ((sctp_ifap->address.sa.sa_family == AF_INET) &&
+ (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+ &sctp_ifap->address.sin.sin_addr) != 0)) {
+ continue;
+ }
+#endif
+#ifdef INET6
+ if ((sctp_ifap->address.sa.sa_family == AF_INET6) &&
+ (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+ &sctp_ifap->address.sin6.sin6_addr) != 0)) {
+ continue;
+ }
+#endif
+#endif
if (sctp_is_addr_restricted(stcb, sctp_ifap)) {
continue;
}
@@ -2502,6 +2536,22 @@ sctp_choose_boundspecific_inp(struct sctp_inpcb *inp,
if (sctp_ifn) {
/* is a preferred one on the interface we route out? */
LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
+#if defined(__FreeBSD__)
+#ifdef INET
+ if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
+ (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+ &sctp_ifa->address.sin.sin_addr) != 0)) {
+ continue;
+ }
+#endif
+#ifdef INET6
+ if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
+ (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+ &sctp_ifa->address.sin6.sin6_addr) != 0)) {
+ continue;
+ }
+#endif
+#endif
if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) &&
(non_asoc_addr_ok == 0))
continue;
@@ -2628,6 +2678,22 @@ sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp,
if (sctp_ifn) {
/* first try for a preferred address on the ep */
LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
+#if defined(__FreeBSD__)
+#ifdef INET
+ if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
+ (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+ &sctp_ifa->address.sin.sin_addr) != 0)) {
+ continue;
+ }
+#endif
+#ifdef INET6
+ if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
+ (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+ &sctp_ifa->address.sin6.sin6_addr) != 0)) {
+ continue;
+ }
+#endif
+#endif
if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0))
continue;
if (sctp_is_addr_in_ep(inp, sctp_ifa)) {
@@ -2648,6 +2714,22 @@ sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp,
}
/* next try for an acceptable address on the ep */
LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
+#if defined(__FreeBSD__)
+#ifdef INET
+ if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
+ (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+ &sctp_ifa->address.sin.sin_addr) != 0)) {
+ continue;
+ }
+#endif
+#ifdef INET6
+ if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
+ (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+ &sctp_ifa->address.sin6.sin6_addr) != 0)) {
+ continue;
+ }
+#endif
+#endif
if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0))
continue;
if (sctp_is_addr_in_ep(inp, sctp_ifa)) {
@@ -2753,6 +2835,11 @@ sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp,
static struct sctp_ifa *
sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn,
+#if defined(__FreeBSD__)
+ struct sctp_inpcb *inp,
+#else
+ struct sctp_inpcb *inp SCTP_UNUSED,
+#endif
struct sctp_tcb *stcb,
int non_asoc_addr_ok,
uint8_t dest_is_loop,
@@ -2779,6 +2866,22 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn,
#endif /* SCTP_EMBEDDED_V6_SCOPE */
#endif /* INET6 */
LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) {
+#if defined(__FreeBSD__)
+#ifdef INET
+ if ((ifa->address.sa.sa_family == AF_INET) &&
+ (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+ &ifa->address.sin.sin_addr) != 0)) {
+ continue;
+ }
+#endif
+#ifdef INET6
+ if ((ifa->address.sa.sa_family == AF_INET6) &&
+ (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+ &ifa->address.sin6.sin6_addr) != 0)) {
+ continue;
+ }
+#endif
+#endif
if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) &&
(non_asoc_addr_ok == 0))
continue;
@@ -2866,6 +2969,11 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn,
static int
sctp_count_num_preferred_boundall(struct sctp_ifn *ifn,
+#if defined(__FreeBSD__)
+ struct sctp_inpcb *inp,
+#else
+ struct sctp_inpcb *inp SCTP_UNUSED,
+#endif
struct sctp_tcb *stcb,
int non_asoc_addr_ok,
uint8_t dest_is_loop,
@@ -2876,6 +2984,23 @@ sctp_count_num_preferred_boundall(struct sctp_ifn *ifn,
int num_eligible_addr = 0;
LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) {
+#if defined(__FreeBSD__)
+#ifdef INET
+ if ((ifa->address.sa.sa_family == AF_INET) &&
+ (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+ &ifa->address.sin.sin_addr) != 0)) {
+ continue;
+ }
+#endif
+#ifdef INET6
+ if ((ifa->address.sa.sa_family == AF_INET6) &&
+ (stcb != NULL) &&
+ (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+ &ifa->address.sin6.sin6_addr) != 0)) {
+ continue;
+ }
+#endif
+#endif
if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) &&
(non_asoc_addr_ok == 0)) {
continue;
@@ -2907,7 +3032,8 @@ sctp_count_num_preferred_boundall(struct sctp_ifn *ifn,
}
static struct sctp_ifa *
-sctp_choose_boundall(struct sctp_tcb *stcb,
+sctp_choose_boundall(struct sctp_inpcb *inp,
+ struct sctp_tcb *stcb,
struct sctp_nets *net,
sctp_route_t *ro,
uint32_t vrf_id,
@@ -2960,7 +3086,7 @@ sctp_choose_boundall(struct sctp_tcb *stcb,
cur_addr_num = net->indx_of_eligible_next_to_use;
}
num_preferred = sctp_count_num_preferred_boundall(sctp_ifn,
- stcb,
+ inp, stcb,
non_asoc_addr_ok,
dest_is_loop,
dest_is_priv, fam);
@@ -2987,7 +3113,7 @@ sctp_choose_boundall(struct sctp_tcb *stcb,
*/
SCTPDBG(SCTP_DEBUG_OUTPUT2, "cur_addr_num:%d\n", cur_addr_num);
- sctp_ifa = sctp_select_nth_preferred_addr_from_ifn_boundall(sctp_ifn, stcb, non_asoc_addr_ok, dest_is_loop,
+ sctp_ifa = sctp_select_nth_preferred_addr_from_ifn_boundall(sctp_ifn, inp, stcb, non_asoc_addr_ok, dest_is_loop,
dest_is_priv, cur_addr_num, fam, ro);
/* if sctp_ifa is NULL something changed??, fall to plan b. */
@@ -3018,7 +3144,7 @@ sctp_choose_boundall(struct sctp_tcb *stcb,
SCTPDBG(SCTP_DEBUG_OUTPUT2, "already seen\n");
continue;
}
- num_preferred = sctp_count_num_preferred_boundall(sctp_ifn, stcb, non_asoc_addr_ok,
+ num_preferred = sctp_count_num_preferred_boundall(sctp_ifn, inp, stcb, non_asoc_addr_ok,
dest_is_loop, dest_is_priv, fam);
SCTPDBG(SCTP_DEBUG_OUTPUT2,
"Found ifn:%p %d preferred source addresses\n",
@@ -3040,7 +3166,7 @@ sctp_choose_boundall(struct sctp_tcb *stcb,
if (cur_addr_num >= num_preferred) {
cur_addr_num = 0;
}
- sifa = sctp_select_nth_preferred_addr_from_ifn_boundall(sctp_ifn, stcb, non_asoc_addr_ok, dest_is_loop,
+ sifa = sctp_select_nth_preferred_addr_from_ifn_boundall(sctp_ifn, inp, stcb, non_asoc_addr_ok, dest_is_loop,
dest_is_priv, cur_addr_num, fam, ro);
if (sifa == NULL)
continue;
@@ -3068,6 +3194,24 @@ again_with_private_addresses_allowed:
}
LIST_FOREACH(sctp_ifa, &emit_ifn->ifalist, next_ifa) {
SCTPDBG(SCTP_DEBUG_OUTPUT2, "ifa:%p\n", (void *)sctp_ifa);
+#if defined(__FreeBSD__)
+#ifdef INET
+ if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
+ (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+ &sctp_ifa->address.sin.sin_addr) != 0)) {
+ SCTPDBG(SCTP_DEBUG_OUTPUT2,"Jailed\n");
+ continue;
+ }
+#endif
+#ifdef INET6
+ if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
+ (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+ &sctp_ifa->address.sin6.sin6_addr) != 0)) {
+ SCTPDBG(SCTP_DEBUG_OUTPUT2,"Jailed\n");
+ continue;
+ }
+#endif
+#endif
if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) &&
(non_asoc_addr_ok == 0)) {
SCTPDBG(SCTP_DEBUG_OUTPUT2,"Defer\n");
@@ -3118,6 +3262,22 @@ again_with_private_addresses_allowed:
continue;
}
LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
+#if defined(__FreeBSD__)
+#ifdef INET
+ if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
+ (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+ &sctp_ifa->address.sin.sin_addr) != 0)) {
+ continue;
+ }
+#endif
+#ifdef INET6
+ if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
+ (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+ &sctp_ifa->address.sin6.sin6_addr) != 0)) {
+ continue;
+ }
+#endif
+#endif
if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) &&
(non_asoc_addr_ok == 0))
continue;
@@ -3168,6 +3328,22 @@ out:
LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
struct sctp_ifa *tmp_sifa;
+#if defined(__FreeBSD__)
+#ifdef INET
+ if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
+ (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+ &sctp_ifa->address.sin.sin_addr) != 0)) {
+ continue;
+ }
+#endif
+#ifdef INET6
+ if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
+ (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+ &sctp_ifa->address.sin6.sin6_addr) != 0)) {
+ continue;
+ }
+#endif
+#endif
if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) &&
(non_asoc_addr_ok == 0))
continue;
@@ -3352,7 +3528,7 @@ sctp_source_address_selection(struct sctp_inpcb *inp,
/*
* Bound all case
*/
- answer = sctp_choose_boundall(stcb, net, ro, vrf_id,
+ answer = sctp_choose_boundall(inp, stcb, net, ro, vrf_id,
dest_is_priv, dest_is_loop,
non_asoc_addr_ok, fam);
SCTP_IPI_ADDR_RUNLOCK();
@@ -11280,11 +11456,11 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
struct mbuf *mout;
struct sctphdr *shout;
struct sctp_chunkhdr *ch;
- struct udphdr *udp;
- int len, cause_len, padding_len;
#if defined(INET) || defined(INET6)
+ struct udphdr *udp;
int ret;
#endif
+ int len, cause_len, padding_len;
#ifdef INET
#if defined(__APPLE__) || defined(__Panda__)
sctp_route_t ro;
@@ -11336,9 +11512,11 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
default:
break;
}
+#if defined INET || defined INET6
if (port) {
len += sizeof(struct udphdr);
}
+#endif
#if defined(__APPLE__)
#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
mout = sctp_get_mbuf_for_msg(len + max_linkhdr, 1, M_NOWAIT, 1, MT_DATA);
@@ -11443,6 +11621,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
shout = mtod(mout, struct sctphdr *);
break;
}
+#if defined INET || defined INET6
if (port) {
if (htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)) == 0) {
sctp_m_freem(mout);
@@ -11461,6 +11640,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
} else {
udp = NULL;
}
+#endif
shout->src_port = sh->dest_port;
shout->dest_port = sh->src_port;
shout->checksum = 0;
@@ -12532,8 +12712,8 @@ sctp_copy_resume(struct uio *uio,
m = m_uiotombuf(uio, M_WAITOK, max_send_len, 0,
(user_marks_eor ? M_EOR : 0));
if (m == NULL) {
- SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
- *error = ENOMEM;
+ SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
+ *error = ENOBUFS;
} else {
*sndout = m_length(m, NULL);
*new_tail = m_last(m);
@@ -12545,8 +12725,8 @@ sctp_copy_resume(struct uio *uio,
m = m_uiotombuf(uio, M_WAITOK, max_send_len, 0,
(M_PKTHDR | (user_marks_eor ? M_EOR : 0)));
if (m == NULL) {
- SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
- *error = ENOMEM;
+ SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
+ *error = ENOBUFS;
} else {
*sndout = m_length(m, NULL);
*new_tail = m_last(m);
@@ -12558,18 +12738,18 @@ sctp_copy_resume(struct uio *uio,
#if defined(__APPLE__)
#if defined(APPLE_LEOPARD)
- left = min(uio->uio_resid, max_send_len);
+ left = min(uio->uio_resid, max_send_len);
#else
- left = min(uio_resid(uio), max_send_len);
+ left = min(uio_resid(uio), max_send_len);
#endif
#else
- left = min(uio->uio_resid, max_send_len);
+ left = min(uio->uio_resid, max_send_len);
#endif
/* Always get a header just in case */
head = sctp_get_mbuf_for_msg(left, 0, M_WAITOK, 0, MT_DATA);
if (head == NULL) {
- SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
- *error = ENOMEM;
+ SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
+ *error = ENOBUFS;
return (NULL);
}
cancpy = M_TRAILINGSPACE(head);
@@ -12590,8 +12770,8 @@ sctp_copy_resume(struct uio *uio,
if (SCTP_BUF_NEXT(m) == NULL) {
sctp_m_freem(head);
*new_tail = NULL;
- SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
- *error = ENOMEM;
+ SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
+ *error = ENOBUFS;
return (NULL);
}
m = SCTP_BUF_NEXT(m);
@@ -12619,17 +12799,17 @@ sctp_copy_resume(struct uio *uio,
static int
sctp_copy_one(struct sctp_stream_queue_pending *sp,
- struct uio *uio,
- int resv_upfront)
+ struct uio *uio,
+ int resv_upfront)
{
int left;
#if defined(__Panda__)
left = sp->length;
sp->data = m_uiotombuf(uio, M_WAITOK, sp->length,
- resv_upfront, 0);
+ resv_upfront, 0);
if (sp->data == NULL) {
- SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
- return (ENOMEM);
+ SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
+ return (ENOBUFS);
}
sp->tail_mbuf = m_last(sp->data);
@@ -12638,10 +12818,10 @@ sctp_copy_one(struct sctp_stream_queue_pending *sp,
#elif defined(__FreeBSD__) && __FreeBSD_version > 602000
left = sp->length;
sp->data = m_uiotombuf(uio, M_WAITOK, sp->length,
- resv_upfront, 0);
+ resv_upfront, 0);
if (sp->data == NULL) {
- SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
- return (ENOMEM);
+ SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
+ return (ENOBUFS);
}
sp->tail_mbuf = m_last(sp->data);
@@ -12655,8 +12835,8 @@ sctp_copy_one(struct sctp_stream_queue_pending *sp,
left = sp->length;
head = m = sctp_get_mbuf_for_msg((left + resv_upfront), 0, M_WAITOK, 0, MT_DATA);
if (m == NULL) {
- SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
- return (ENOMEM);
+ SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
+ return (ENOBUFS);
}
/*-
* Add this one for m in now, that way if the alloc fails we won't
@@ -12683,8 +12863,8 @@ sctp_copy_one(struct sctp_stream_queue_pending *sp,
* the rest
*/
sctp_m_freem(head);
- SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
- return (ENOMEM);
+ SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
+ return (ENOBUFS);
}
m = SCTP_BUF_NEXT(m);
cancpy = M_TRAILINGSPACE(m);
diff --git a/netinet/sctp_pcb.c b/netinet/sctp_pcb.c
index fcacdac..a7f8b85 100755
--- a/netinet/sctp_pcb.c
+++ b/netinet/sctp_pcb.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 265455 2014-05-06 16:51:07Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 267674 2014-06-20 13:26:49Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -52,9 +52,11 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 265455 2014-05-06 16:51:07Z tuex
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
#include <netinet/sctp_dtrace_define.h>
#endif
+#if defined INET || defined INET6
#if !defined(__Userspace_os_Windows)
#include <netinet/udp.h>
#endif
+#endif
#ifdef INET6
#if defined(__Userspace__)
#include "user_ip6_var.h"
@@ -992,6 +994,12 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
continue;
}
+#if defined(__FreeBSD__)
+ if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
+ &sin->sin_addr) != 0) {
+ continue;
+ }
+#endif
if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) {
SCTP_IPI_ADDR_RUNLOCK();
return (1);
@@ -1008,6 +1016,12 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
#endif
sin6 = &sctp_ifa->address.sin6;
rsin6 = (struct sockaddr_in6 *)to;
+#if defined(__FreeBSD__)
+ if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
+ &sin6->sin6_addr) != 0) {
+ continue;
+ }
+#endif
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
if (local_scope == 0)
continue;
@@ -1207,6 +1221,41 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
SCTP_INP_RUNLOCK(inp);
continue;
}
+#if defined(__FreeBSD__)
+ switch (to->sa_family) {
+#ifdef INET
+ case AF_INET:
+ {
+ struct sockaddr_in *sin;
+
+ sin = (struct sockaddr_in *)to;
+ if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+ &sin->sin_addr) != 0) {
+ SCTP_INP_RUNLOCK(inp);
+ continue;
+ }
+ break;
+ }
+#endif
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6;
+
+ sin6 = (struct sockaddr_in6 *)to;
+ if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+ &sin6->sin6_addr) != 0) {
+ SCTP_INP_RUNLOCK(inp);
+ continue;
+ }
+ break;
+ }
+#endif
+ default:
+ SCTP_INP_RUNLOCK(inp);
+ continue;
+ }
+#endif
#ifdef SCTP_MVRF
fnd = 0;
for (i = 0; i < inp->num_vrfs; i++) {
@@ -1907,23 +1956,43 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) &&
(inp->sctp_lport == lport)) {
/* got it */
+ switch (nam->sa_family) {
#ifdef INET
- if ((nam->sa_family == AF_INET) &&
- (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
- SCTP_IPV6_V6ONLY(inp)) {
- /* IPv4 on a IPv6 socket with ONLY IPv6 set */
- SCTP_INP_RUNLOCK(inp);
- continue;
- }
+ case AF_INET:
+ if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
+ SCTP_IPV6_V6ONLY(inp)) {
+ /* IPv4 on a IPv6 socket with ONLY IPv6 set */
+ SCTP_INP_RUNLOCK(inp);
+ continue;
+ }
+#if defined(__FreeBSD__)
+ if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+ &sin->sin_addr) != 0) {
+ SCTP_INP_RUNLOCK(inp);
+ continue;
+ }
+#endif
+ break;
#endif
#ifdef INET6
- /* A V6 address and the endpoint is NOT bound V6 */
- if (nam->sa_family == AF_INET6 &&
- (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
- SCTP_INP_RUNLOCK(inp);
- continue;
- }
+ case AF_INET6:
+ /* A V6 address and the endpoint is NOT bound V6 */
+ if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
+ SCTP_INP_RUNLOCK(inp);
+ continue;
+ }
+#if defined(__FreeBSD__)
+ if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+ &sin6->sin6_addr) != 0) {
+ SCTP_INP_RUNLOCK(inp);
+ continue;
+ }
#endif
+ break;
+#endif
+ default:
+ break;
+ }
/* does a VRF id match? */
fnd = 0;
#ifdef SCTP_MVRF
@@ -2753,6 +2822,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
/* setup socket pointers */
inp->sctp_socket = so;
inp->ip_inp.inp.inp_socket = so;
+#if defined(__FreeBSD__)
+ inp->ip_inp.inp.inp_cred = crhold(so->so_cred);
+#endif
#ifdef INET6
#if !defined(__Userspace__) && !defined(__Windows__)
if (INP_SOCKAF(so) == AF_INET6) {
@@ -2779,6 +2851,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
/* init the small hash table we use to track asocid <-> tcb */
inp->sctp_asocidhash = SCTP_HASH_INIT(SCTP_STACK_VTAG_HASH_SIZE, &inp->hashasocidmark);
if (inp->sctp_asocidhash == NULL) {
+#if defined(__FreeBSD__)
+ crfree(inp->ip_inp.inp.inp_cred);
+#endif
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
SCTP_INP_INFO_WUNLOCK();
return (ENOBUFS);
@@ -2798,6 +2873,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
error = 0;
#endif
if (error != 0) {
+#if defined(__FreeBSD__)
+ crfree(inp->ip_inp.inp.inp_cred);
+#endif
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
SCTP_INP_INFO_WUNLOCK();
return error;
@@ -2843,6 +2921,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
*/
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EOPNOTSUPP);
so->so_pcb = NULL;
+#if defined(__FreeBSD__)
+ crfree(inp->ip_inp.inp.inp_cred);
+#endif
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
return (EOPNOTSUPP);
}
@@ -2862,6 +2943,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
SCTP_PRINTF("Out of SCTP-INPCB->hashinit - no resources\n");
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
so->so_pcb = NULL;
+#if defined(__FreeBSD__)
+ crfree(inp->ip_inp.inp.inp_cred);
+#endif
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
return (ENOBUFS);
}
@@ -2873,6 +2957,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
so->so_pcb = NULL;
SCTP_HASH_FREE(inp->sctp_tcbhash, inp->sctp_hashmark);
+#if defined(__FreeBSD__)
+ crfree(inp->ip_inp.inp.inp_cred);
+#endif
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
return (ENOBUFS);
}
@@ -2891,6 +2978,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
#endif
SCTP_HASH_FREE(inp->sctp_tcbhash, inp->sctp_hashmark);
so->so_pcb = NULL;
+#if defined(__FreeBSD__)
+ crfree(inp->ip_inp.inp.inp_cred);
+#endif
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
SCTP_UNLOCK_EXC(SCTP_BASE_INFO(sctbinfo).ipi_lock);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOMEM);
@@ -4265,6 +4355,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
}
/* Now we must put the ep memory back into the zone pool */
#if defined(__FreeBSD__)
+ crfree(inp->ip_inp.inp.inp_cred);
INP_LOCK_DESTROY(&inp->ip_inp.inp);
#endif
SCTP_INP_LOCK_DESTROY(inp);
@@ -4629,9 +4720,11 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
break;
}
}
+#if defined INET || defined INET6
if (net->port) {
net->mtu -= (uint32_t)sizeof(struct udphdr);
}
+#endif
if (from == SCTP_ALLOC_ASOC) {
stcb->asoc.smallest_mtu = net->mtu;
}
diff --git a/netinet/sctp_sysctl.c b/netinet/sctp_sysctl.c
index 1374dba..21329f0 100755
--- a/netinet/sctp_sysctl.c
+++ b/netinet/sctp_sysctl.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 263237 2014-03-16 12:32:16Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 267674 2014-06-20 13:26:49Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -307,6 +307,12 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s
sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
if (sin->sin_addr.s_addr == 0)
continue;
+#if defined(__FreeBSD__)
+ if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+ &sin->sin_addr) != 0) {
+ continue;
+ }
+#endif
if ((ipv4_local_scope == 0) && (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)))
continue;
} else {
@@ -325,6 +331,12 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s
sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
continue;
+#if defined(__FreeBSD__)
+ if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+ &sin6->sin6_addr) != 0) {
+ continue;
+ }
+#endif
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
if (local_scope == 0)
continue;
diff --git a/netinet/sctp_timer.c b/netinet/sctp_timer.c
index 0ad6de0..9627dc5 100755
--- a/netinet/sctp_timer.c
+++ b/netinet/sctp_timer.c
@@ -54,9 +54,11 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 263237 2014-03-16 12:32:16Z tu
#include <netinet/sctp_input.h>
#include <netinet/sctp.h>
#include <netinet/sctp_uio.h>
+#if defined INET || defined INET6
#if !defined(__Userspace_os_Windows)
#include <netinet/udp.h>
#endif
+#endif
#if defined(__APPLE__)
#define APPLE_FILE_NO 6
@@ -1502,9 +1504,11 @@ sctp_pathmtu_timer(struct sctp_inpcb *inp,
}
if (net->ro._s_addr) {
mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._s_addr.sa, net->ro.ro_rt);
+#if defined INET || defined INET6
if (net->port) {
mtu -= sizeof(struct udphdr);
}
+#endif
if (mtu > next_mtu) {
net->mtu = next_mtu;
}
diff --git a/netinet/sctp_userspace.c b/netinet/sctp_userspace.c
index e0cbac4..7763f30 100755
--- a/netinet/sctp_userspace.c
+++ b/netinet/sctp_userspace.c
@@ -141,7 +141,7 @@ Win_getifaddrs(struct ifaddrs** interfaces)
ifa->ifa_name = strdup(pAdapt->AdapterName);
ifa->ifa_flags = pAdapt->Flags;
ifa->ifa_addr = (struct sockaddr *)addr;
- memcpy(&addr, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in));
+ memcpy(addr, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in));
interfaces[count] = ifa;
}
#endif
@@ -175,7 +175,7 @@ Win_getifaddrs(struct ifaddrs** interfaces)
ifa->ifa_name = strdup(pAdapt->AdapterName);
ifa->ifa_flags = pAdapt->Flags;
ifa->ifa_addr = (struct sockaddr *)addr6;
- memcpy(&addr6, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in6));
+ memcpy(addr6, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in6));
interfaces[count] = ifa;
}
}
diff --git a/netinet/sctp_usrreq.c b/netinet/sctp_usrreq.c
index a3b9641..796fd16 100755
--- a/netinet/sctp_usrreq.c
+++ b/netinet/sctp_usrreq.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 263237 2014-03-16 12:32:16Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 267688 2014-06-20 20:17:39Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -56,7 +56,7 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 263237 2014-03-16 12:32:16Z t
#include <netinet/sctp_timer.h>
#include <netinet/sctp_auth.h>
#include <netinet/sctp_bsd_addr.h>
-#if !defined(__Userspace_os_Windows)
+#if !defined(__Userspace__)
#include <netinet/udp.h>
#endif
@@ -393,8 +393,6 @@ sctp_notify_mbuf(struct sctp_inpcb *inp,
SCTP_TCB_UNLOCK(stcb);
}
-#endif
-#endif
void
sctp_notify(struct sctp_inpcb *inp,
@@ -489,6 +487,8 @@ sctp_notify(struct sctp_inpcb *inp,
SCTP_TCB_UNLOCK(stcb);
}
}
+#endif
+#endif
#ifdef INET
#if !defined(__Panda__) && !defined(__Userspace__)
@@ -1684,6 +1684,12 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
*/
continue;
}
+#if defined(__FreeBSD__)
+ if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+ &sin->sin_addr) != 0) {
+ continue;
+ }
+#endif
if ((ipv4_local_scope == 0) &&
(IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
continue;
@@ -1727,6 +1733,12 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
*/
continue;
}
+#if defined(__FreeBSD__)
+ if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+ &sin6->sin6_addr) != 0) {
+ continue;
+ }
+#endif
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
if (local_scope == 0)
continue;
@@ -6096,6 +6108,45 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
error = EINVAL;
goto out_of_it;
}
+#if defined(__FreeBSD__)
+ } else {
+ switch (sspp->sspp_addr.ss_family) {
+#ifdef INET
+ case AF_INET:
+ {
+ struct sockaddr_in *sin;
+
+ sin = (struct sockaddr_in *)&sspp->sspp_addr;
+ if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+ &sin->sin_addr) != 0) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
+ goto out_of_it;
+ }
+ break;
+ }
+#endif
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6;
+
+ sin6 = (struct sockaddr_in6 *)&sspp->sspp_addr;
+ if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+ &sin6->sin6_addr) != 0) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
+ goto out_of_it;
+ }
+ break;
+ }
+#endif
+ default:
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
+ goto out_of_it;
+ }
+#endif
}
if (sctp_set_primary_ip_address_sa(stcb,
(struct sockaddr *)&sspp->sspp_addr) != 0) {
@@ -6477,7 +6528,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id);
net = NULL;
if (stcb) {
- net = sctp_findnet(stcb, (struct sockaddr *)&thlds->spt_assoc_id);
+ net = sctp_findnet(stcb, (struct sockaddr *)&thlds->spt_address);
} else {
/* We increment here since sctp_findassociation_ep_addr() wil
* do a decrement if it finds the stcb as long as the locked
@@ -6485,7 +6536,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
*/
SCTP_INP_INCR_REF(inp);
stcb = sctp_findassociation_ep_addr(&inp,
- (struct sockaddr *)&thlds->spt_assoc_id,
+ (struct sockaddr *)&thlds->spt_address,
&net, NULL, NULL);
if (stcb == NULL) {
SCTP_INP_DECR_REF(inp);
@@ -6494,7 +6545,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
if (stcb && (net == NULL)) {
struct sockaddr *sa;
- sa = (struct sockaddr *)&thlds->spt_assoc_id;
+ sa = (struct sockaddr *)&thlds->spt_address;
#ifdef INET
if (sa->sa_family == AF_INET) {
@@ -7197,35 +7248,34 @@ sctp_listen(struct socket *so, struct proc *p)
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) {
/* See if we have a listener */
struct sctp_inpcb *tinp;
- union sctp_sockstore store, *sp;
+ union sctp_sockstore store;
- sp = &store;
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
/* not bound all */
struct sctp_laddr *laddr;
LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
memcpy(&store, &laddr->ifa->address, sizeof(store));
- switch (sp->sa.sa_family) {
+ switch (store.sa.sa_family) {
#ifdef INET
case AF_INET:
- sp->sin.sin_port = inp->sctp_lport;
+ store.sin.sin_port = inp->sctp_lport;
break;
#endif
#ifdef INET6
case AF_INET6:
- sp->sin6.sin6_port = inp->sctp_lport;
+ store.sin6.sin6_port = inp->sctp_lport;
break;
#endif
#if defined(__Userspace__)
case AF_CONN:
- sp->sconn.sconn_port = inp->sctp_lport;
+ store.sconn.sconn_port = inp->sctp_lport;
break;
#endif
default:
break;
}
- tinp = sctp_pcb_findep(&sp->sa, 0, 0, inp->def_vrf_id);
+ tinp = sctp_pcb_findep(&store.sa, 0, 0, inp->def_vrf_id);
if (tinp && (tinp != inp) &&
((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) &&
((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
@@ -7240,25 +7290,6 @@ sctp_listen(struct socket *so, struct proc *p)
} else {
/* Setup a local addr bound all */
memset(&store, 0, sizeof(store));
- switch (sp->sa.sa_family) {
-#ifdef INET
- case AF_INET:
- store.sin.sin_port = inp->sctp_lport;
- break;
-#endif
-#ifdef INET6
- case AF_INET6:
- sp->sin6.sin6_port = inp->sctp_lport;
- break;
-#endif
-#if defined(__Userspace__)
- case AF_CONN:
- sp->sconn.sconn_port = inp->sctp_lport;
- break;
-#endif
- default:
- break;
- }
#ifdef INET6
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
store.sa.sa_family = AF_INET6;
@@ -7267,15 +7298,47 @@ sctp_listen(struct socket *so, struct proc *p)
#endif
}
#endif
+#if defined(__Userspace__)
+ if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) {
+ store.sa.sa_family = AF_CONN;
+#ifdef HAVE_SA_LEN
+ store.sa.sa_len = sizeof(struct sockaddr_conn);
+#endif
+ }
+#endif
#ifdef INET
+#if defined(__Userspace__)
+ if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) &&
+ ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) == 0)) {
+#else
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
+#endif
store.sa.sa_family = AF_INET;
#ifdef HAVE_SA_LEN
store.sa.sa_len = sizeof(struct sockaddr_in);
#endif
}
#endif
- tinp = sctp_pcb_findep(&sp->sa, 0, 0, inp->def_vrf_id);
+ switch (store.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+ store.sin.sin_port = inp->sctp_lport;
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ store.sin6.sin6_port = inp->sctp_lport;
+ break;
+#endif
+#if defined(__Userspace__)
+ case AF_CONN:
+ store.sconn.sconn_port = inp->sctp_lport;
+ break;
+#endif
+ default:
+ break;
+ }
+ tinp = sctp_pcb_findep(&store.sa, 0, 0, inp->def_vrf_id);
if (tinp && (tinp != inp) &&
((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) &&
((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
diff --git a/netinet/sctputil.c b/netinet/sctputil.c
index 38cbcf7..73cf3ab 100755
--- a/netinet/sctputil.c
+++ b/netinet/sctputil.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 264701 2014-04-20 18:15:23Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 267674 2014-06-20 13:26:49Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -7566,6 +7566,12 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
/* skip unspecified addrs */
continue;
}
+#if defined(__FreeBSD__)
+ if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
+ &sin->sin_addr) != 0) {
+ continue;
+ }
+#endif
if ((ipv4_local_scope == 0) &&
(IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
continue;
@@ -7589,6 +7595,12 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
continue;
}
+#if defined(__FreeBSD__)
+ if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
+ &sin6->sin6_addr) != 0) {
+ continue;
+ }
+#endif
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
if (local_scope == 0)
continue;
diff --git a/user_malloc.h b/user_malloc.h
index 07187ee..4ea9548 100755
--- a/user_malloc.h
+++ b/user_malloc.h
@@ -41,7 +41,15 @@
#include <strings.h>
#include <stdint.h>
#else
-#include "netinet/sctp_os_userspace.h"
+#if defined(_MSC_VER) && _MSC_VER >= 1600
+#include <stdint.h>
+#elif defined(SCTP_STDINT_INCLUDE)
+#include SCTP_STDINT_INCLUDE
+#else
+#define uint32_t unsigned __int32
+#define uint64_t unsigned __int64
+#endif
+#include <winsock2.h>
#endif
#define MINALLOCSIZE UMA_SMALLEST_UNIT
diff --git a/user_socket.c b/user_socket.c
index adb798c..1b44f11 100755
--- a/user_socket.c
+++ b/user_socket.c
@@ -46,7 +46,9 @@
#define __FAVOR_BSD /* (on Ubuntu at least) enables UDP header field names like BSD in RFC 768 */
#endif
#if !defined (__Userspace_os_Windows)
+#if defined INET || defined INET6
#include <netinet/udp.h>
+#endif
#include <arpa/inet.h>
#else
#include <user_socketvar.h>
diff --git a/usrsctp.h b/usrsctp.h
index 052c076..b72eeb6 100644
--- a/usrsctp.h
+++ b/usrsctp.h
@@ -35,6 +35,7 @@
extern "C" {
#endif
+#include <errno.h>
#include <sys/types.h>
#ifdef _WIN32
#ifdef _MSC_VER