Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102661974
D39591.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D39591.diff
View Options
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -136,9 +136,7 @@
{
struct tcp_log_buffer *lgb;
- if (tp == NULL) {
- return;
- }
+ KASSERT(tp != NULL, ("tcp_bblog_pru: tp == NULL"));
INP_WLOCK_ASSERT(tptoinpcb(tp));
if (tcp_bblogging_on(tp)) {
lgb = tcp_log_event(tp, NULL, NULL, NULL, TCP_LOG_PRU, error,
@@ -232,9 +230,18 @@
{
int error = 0;
struct inpcb *inp;
- struct tcpcb *tp = NULL;
+ struct tcpcb *tp;
struct sockaddr_in *sinp;
+ inp = sotoinpcb(so);
+ KASSERT(inp != NULL, ("tcp_usr_bind: inp == NULL"));
+ INP_WLOCK(inp);
+ if (inp->inp_flags & INP_DROPPED) {
+ INP_WUNLOCK(inp);
+ return (EINVAL);
+ }
+ tp = intotcpcb(inp);
+
sinp = (struct sockaddr_in *)nam;
if (nam->sa_family != AF_INET) {
/*
@@ -242,28 +249,24 @@
*/
if (nam->sa_family != AF_UNSPEC ||
nam->sa_len < offsetof(struct sockaddr_in, sin_zero) ||
- sinp->sin_addr.s_addr != INADDR_ANY)
- return (EAFNOSUPPORT);
+ sinp->sin_addr.s_addr != INADDR_ANY) {
+ error = EAFNOSUPPORT;
+ goto out;
+ }
nam->sa_family = AF_INET;
}
- if (nam->sa_len != sizeof(*sinp))
- return (EINVAL);
-
+ if (nam->sa_len != sizeof(*sinp)) {
+ error = EINVAL;
+ goto out;
+ }
/*
* Must check for multicast addresses and disallow binding
* to them.
*/
- if (IN_MULTICAST(ntohl(sinp->sin_addr.s_addr)))
- return (EAFNOSUPPORT);
-
- inp = sotoinpcb(so);
- KASSERT(inp != NULL, ("tcp_usr_bind: inp == NULL"));
- INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
- error = EINVAL;
+ if (IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
+ error = EAFNOSUPPORT;
goto out;
}
- tp = intotcpcb(inp);
INP_HASH_WLOCK(&V_tcbinfo);
error = in_pcbbind(inp, sinp, td->td_ucred);
INP_HASH_WUNLOCK(&V_tcbinfo);
@@ -282,32 +285,39 @@
{
int error = 0;
struct inpcb *inp;
- struct tcpcb *tp = NULL;
+ struct tcpcb *tp;
struct sockaddr_in6 *sin6;
u_char vflagsav;
- sin6 = (struct sockaddr_in6 *)nam;
- if (nam->sa_family != AF_INET6)
- return (EAFNOSUPPORT);
- if (nam->sa_len != sizeof(*sin6))
+ inp = sotoinpcb(so);
+ KASSERT(inp != NULL, ("tcp6_usr_bind: inp == NULL"));
+ INP_WLOCK(inp);
+ if (inp->inp_flags & INP_DROPPED) {
+ INP_WUNLOCK(inp);
return (EINVAL);
+ }
+ tp = intotcpcb(inp);
+
+ vflagsav = inp->inp_vflag;
+ sin6 = (struct sockaddr_in6 *)nam;
+ if (nam->sa_family != AF_INET6) {
+ error = EAFNOSUPPORT;
+ goto out;
+ }
+ if (nam->sa_len != sizeof(*sin6)) {
+ error = EINVAL;
+ goto out;
+ }
/*
* Must check for multicast addresses and disallow binding
* to them.
*/
- if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
- return (EAFNOSUPPORT);
-
- inp = sotoinpcb(so);
- KASSERT(inp != NULL, ("tcp6_usr_bind: inp == NULL"));
- INP_WLOCK(inp);
- vflagsav = inp->inp_vflag;
- if (inp->inp_flags & INP_DROPPED) {
- error = EINVAL;
+ if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
+ error = EAFNOSUPPORT;
goto out;
}
- tp = intotcpcb(inp);
+
INP_HASH_WLOCK(&V_tcbinfo);
inp->inp_vflag &= ~INP_IPV4;
inp->inp_vflag |= INP_IPV6;
@@ -353,16 +363,17 @@
{
int error = 0;
struct inpcb *inp;
- struct tcpcb *tp = NULL;
+ struct tcpcb *tp;
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("tcp_usr_listen: inp == NULL"));
INP_WLOCK(inp);
if (inp->inp_flags & INP_DROPPED) {
- error = EINVAL;
- goto out;
+ INP_WUNLOCK(inp);
+ return (EINVAL);
}
tp = intotcpcb(inp);
+
SOCK_LOCK(so);
error = solisten_proto_check(so);
if (error != 0) {
@@ -403,18 +414,20 @@
{
int error = 0;
struct inpcb *inp;
- struct tcpcb *tp = NULL;
+ struct tcpcb *tp;
u_char vflagsav;
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("tcp6_usr_listen: inp == NULL"));
INP_WLOCK(inp);
if (inp->inp_flags & INP_DROPPED) {
- error = EINVAL;
- goto out;
+ INP_WUNLOCK(inp);
+ return (EINVAL);
}
- vflagsav = inp->inp_vflag;
tp = intotcpcb(inp);
+
+ vflagsav = inp->inp_vflag;
+
SOCK_LOCK(so);
error = solisten_proto_check(so);
if (error != 0) {
@@ -469,37 +482,44 @@
struct epoch_tracker et;
int error = 0;
struct inpcb *inp;
- struct tcpcb *tp = NULL;
+ struct tcpcb *tp;
struct sockaddr_in *sinp;
- sinp = (struct sockaddr_in *)nam;
- if (nam->sa_family != AF_INET)
- return (EAFNOSUPPORT);
- if (nam->sa_len != sizeof (*sinp))
- return (EINVAL);
-
- /*
- * Must disallow TCP ``connections'' to multicast addresses.
- */
- if (IN_MULTICAST(ntohl(sinp->sin_addr.s_addr)))
- return (EAFNOSUPPORT);
- if (ntohl(sinp->sin_addr.s_addr) == INADDR_BROADCAST)
- return (EACCES);
- if ((error = prison_remote_ip4(td->td_ucred, &sinp->sin_addr)) != 0)
- return (error);
-
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("tcp_usr_connect: inp == NULL"));
INP_WLOCK(inp);
if (inp->inp_flags & INP_DROPPED) {
- error = ECONNREFUSED;
+ INP_WUNLOCK(inp);
+ return (ECONNREFUSED);
+ }
+ tp = intotcpcb(inp);
+
+ sinp = (struct sockaddr_in *)nam;
+ if (nam->sa_family != AF_INET) {
+ error = EAFNOSUPPORT;
+ goto out;
+ }
+ if (nam->sa_len != sizeof (*sinp)) {
+ error = EINVAL;
+ goto out;
+ }
+ /*
+ * Must disallow TCP ``connections'' to multicast addresses.
+ */
+ if (IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
+ error = EAFNOSUPPORT;
goto out;
}
+ if (ntohl(sinp->sin_addr.s_addr) == INADDR_BROADCAST) {
+ error = EACCES;
+ goto out;
+ }
+ if ((error = prison_remote_ip4(td->td_ucred, &sinp->sin_addr)) != 0)
+ goto out;
if (SOLISTENING(so)) {
error = EOPNOTSUPP;
goto out;
}
- tp = intotcpcb(inp);
NET_EPOCH_ENTER(et);
if ((error = tcp_connect(tp, sinp, td)) != 0)
goto out_in_epoch;
@@ -530,37 +550,43 @@
struct epoch_tracker et;
int error = 0;
struct inpcb *inp;
- struct tcpcb *tp = NULL;
+ struct tcpcb *tp;
struct sockaddr_in6 *sin6;
u_int8_t incflagsav;
u_char vflagsav;
- sin6 = (struct sockaddr_in6 *)nam;
- if (nam->sa_family != AF_INET6)
- return (EAFNOSUPPORT);
- if (nam->sa_len != sizeof (*sin6))
- return (EINVAL);
-
- /*
- * Must disallow TCP ``connections'' to multicast addresses.
- */
- if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
- return (EAFNOSUPPORT);
-
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("tcp6_usr_connect: inp == NULL"));
INP_WLOCK(inp);
+ if (inp->inp_flags & INP_DROPPED) {
+ INP_WUNLOCK(inp);
+ return (ECONNREFUSED);
+ }
+ tp = intotcpcb(inp);
+
vflagsav = inp->inp_vflag;
incflagsav = inp->inp_inc.inc_flags;
- if (inp->inp_flags & INP_DROPPED) {
- error = ECONNREFUSED;
+
+ sin6 = (struct sockaddr_in6 *)nam;
+ if (nam->sa_family != AF_INET6) {
+ error = EAFNOSUPPORT;
+ goto out;
+ }
+ if (nam->sa_len != sizeof (*sin6)) {
+ error = EINVAL;
+ goto out;
+ }
+ /*
+ * Must disallow TCP ``connections'' to multicast addresses.
+ */
+ if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
+ error = EAFNOSUPPORT;
goto out;
}
if (SOLISTENING(so)) {
error = EINVAL;
goto out;
}
- tp = intotcpcb(inp);
#ifdef INET
/*
* XXXRW: Some confusion: V4/V6 flags relate to binding, and
@@ -672,10 +698,12 @@
KASSERT(inp != NULL, ("tcp_usr_disconnect: inp == NULL"));
INP_WLOCK(inp);
if (inp->inp_flags & INP_DROPPED) {
- error = ECONNRESET;
- goto out;
+ INP_WUNLOCK(inp);
+ NET_EPOCH_EXIT(et);
+ return (ECONNRESET);
}
tp = intotcpcb(inp);
+
if (tp->t_state == TCPS_TIME_WAIT)
goto out;
tcp_disconnect(tp);
@@ -696,23 +724,24 @@
tcp_usr_accept(struct socket *so, struct sockaddr **nam)
{
int error = 0;
- struct inpcb *inp = NULL;
- struct tcpcb *tp = NULL;
+ struct inpcb *inp;
+ struct tcpcb *tp;
struct in_addr addr;
in_port_t port = 0;
- if (so->so_state & SS_ISDISCONNECTED)
- return (ECONNABORTED);
-
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("tcp_usr_accept: inp == NULL"));
INP_WLOCK(inp);
if (inp->inp_flags & INP_DROPPED) {
- error = ECONNABORTED;
- goto out;
+ INP_WUNLOCK(inp);
+ return (ECONNABORTED);
}
tp = intotcpcb(inp);
+ if (so->so_state & SS_ISDISCONNECTED) {
+ error = ECONNABORTED;
+ goto out;
+ }
/*
* We inline in_getpeeraddr and COMMON_END here, so that we can
* copy the data of interest and defer the malloc until after we
@@ -735,28 +764,30 @@
static int
tcp6_usr_accept(struct socket *so, struct sockaddr **nam)
{
- struct inpcb *inp = NULL;
+ struct inpcb *inp;
int error = 0;
- struct tcpcb *tp = NULL;
+ struct tcpcb *tp;
struct in_addr addr;
struct in6_addr addr6;
struct epoch_tracker et;
in_port_t port = 0;
int v4 = 0;
- if (so->so_state & SS_ISDISCONNECTED)
- return (ECONNABORTED);
-
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("tcp6_usr_accept: inp == NULL"));
- NET_EPOCH_ENTER(et);
+ NET_EPOCH_ENTER(et); /* XXXMT Why is this needed? */
INP_WLOCK(inp);
if (inp->inp_flags & INP_DROPPED) {
- error = ECONNABORTED;
- goto out;
+ INP_WUNLOCK(inp);
+ NET_EPOCH_EXIT(et);
+ return (ECONNABORTED);
}
tp = intotcpcb(inp);
+ if (so->so_state & SS_ISDISCONNECTED) {
+ error = ECONNABORTED;
+ goto out;
+ }
/*
* We inline in6_mapped_peeraddr and COMMON_END here, so that we can
* copy the data of interest and defer the malloc until after we
@@ -794,7 +825,7 @@
{
int error = 0;
struct inpcb *inp;
- struct tcpcb *tp = NULL;
+ struct tcpcb *tp;
struct epoch_tracker et;
inp = sotoinpcb(so);
@@ -805,6 +836,7 @@
return (ECONNRESET);
}
tp = intotcpcb(inp);
+
NET_EPOCH_ENTER(et);
socantsendmore(so);
tcp_usrclosed(tp);
@@ -826,7 +858,7 @@
{
struct epoch_tracker et;
struct inpcb *inp;
- struct tcpcb *tp = NULL;
+ struct tcpcb *tp;
int outrv = 0, error = 0;
inp = sotoinpcb(so);
@@ -837,6 +869,7 @@
return (ECONNRESET);
}
tp = intotcpcb(inp);
+
NET_EPOCH_ENTER(et);
/*
* For passively-created TFO connections, don't attempt a window
@@ -876,7 +909,7 @@
struct epoch_tracker et;
int error = 0;
struct inpcb *inp;
- struct tcpcb *tp = NULL;
+ struct tcpcb *tp;
#ifdef INET
#ifdef INET6
struct sockaddr_in sin;
@@ -891,15 +924,6 @@
u_char vflagsav;
bool restoreflags;
- if (control != NULL) {
- /* TCP doesn't do control messages (rights, creds, etc) */
- if (control->m_len) {
- m_freem(control);
- return (EINVAL);
- }
- m_freem(control); /* empty control, just free it */
- }
-
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("tcp_usr_send: inp == NULL"));
INP_WLOCK(inp);
@@ -909,13 +933,23 @@
INP_WUNLOCK(inp);
return (ECONNRESET);
}
+ tp = intotcpcb(inp);
vflagsav = inp->inp_vflag;
incflagsav = inp->inp_inc.inc_flags;
restoreflags = false;
- tp = intotcpcb(inp);
NET_EPOCH_ENTER(et);
+ if (control != NULL) {
+ /* TCP doesn't do control messages (rights, creds, etc) */
+ if (control->m_len > 0) {
+ m_freem(control);
+ error = EINVAL;
+ goto out;
+ }
+ m_freem(control); /* empty control, just free it */
+ }
+
if ((flags & PRUS_OOB) != 0 &&
(error = tcp_pru_options_support(tp, PRUS_OOB)) != 0)
goto out;
@@ -1222,7 +1256,7 @@
tcp_usr_abort(struct socket *so)
{
struct inpcb *inp;
- struct tcpcb *tp = NULL;
+ struct tcpcb *tp;
struct epoch_tracker et;
inp = sotoinpcb(so);
@@ -1260,7 +1294,7 @@
tcp_usr_close(struct socket *so)
{
struct inpcb *inp;
- struct tcpcb *tp = NULL;
+ struct tcpcb *tp;
struct epoch_tracker et;
inp = sotoinpcb(so);
@@ -1318,16 +1352,17 @@
{
int error = 0;
struct inpcb *inp;
- struct tcpcb *tp = NULL;
+ struct tcpcb *tp;
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("tcp_usr_rcvoob: inp == NULL"));
INP_WLOCK(inp);
if (inp->inp_flags & INP_DROPPED) {
- error = ECONNRESET;
- goto out;
+ INP_WUNLOCK(inp);
+ return (ECONNRESET);
}
tp = intotcpcb(inp);
+
error = tcp_pru_options_support(tp, PRUS_OOB);
if (error) {
goto out;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 16, 12:35 PM (21 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14658792
Default Alt Text
D39591.diff (11 KB)
Attached To
Mode
D39591: tcp: improve logging for PRUs
Attached
Detach File
Event Timeline
Log In to Comment