Page MenuHomeFreeBSD

D31734.diff
No OneTemporary

D31734.diff

diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -2818,6 +2818,7 @@
KASSERT(td != NULL, ("%s: null thread", __func__));
+ error = 0;
lport = 0;
bindall = 1;
inp = (struct sctp_inpcb *)so->so_pcb;
@@ -2830,10 +2831,13 @@
SCTPDBG_ADDR(SCTP_DEBUG_PCB1, addr);
}
#endif
+ SCTP_INP_INFO_WLOCK();
+ SCTP_INP_WLOCK(inp);
if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) {
+ error = EINVAL;
/* already did a bind, subsequent binds NOT allowed ! */
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
- return (EINVAL);
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
+ goto out;
}
if (addr != NULL) {
switch (addr->sa_family) {
@@ -2844,12 +2848,14 @@
/* IPV6_V6ONLY socket? */
if (SCTP_IPV6_V6ONLY(inp)) {
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
- return (EINVAL);
+ error = EINVAL;
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
+ goto out;
}
if (addr->sa_len != sizeof(*sin)) {
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
- return (EINVAL);
+ error = EINVAL;
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
+ goto out;
}
sin = (struct sockaddr_in *)addr;
@@ -2861,7 +2867,7 @@
*/
if ((error = prison_local_ip4(td->td_ucred, &sin->sin_addr)) != 0) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
- return (error);
+ goto out;
}
if (sin->sin_addr.s_addr != INADDR_ANY) {
bindall = 0;
@@ -2879,10 +2885,10 @@
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)addr;
-
if (addr->sa_len != sizeof(*sin6)) {
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
- return (EINVAL);
+ error = EINVAL;
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
+ goto out;
}
lport = sin6->sin6_port;
/*
@@ -2893,14 +2899,15 @@
if ((error = prison_local_ip6(td->td_ucred, &sin6->sin6_addr,
(SCTP_IPV6_V6ONLY(inp) != 0))) != 0) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
- return (error);
+ goto out;
}
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
bindall = 0;
/* KAME hack: embed scopeid */
if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
- return (EINVAL);
+ error = EINVAL;
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
+ goto out;
}
}
/* this must be cleared for ifa_ifwithaddr() */
@@ -2909,12 +2916,11 @@
}
#endif
default:
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EAFNOSUPPORT);
- return (EAFNOSUPPORT);
+ error = EAFNOSUPPORT;
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
+ goto out;
}
}
- SCTP_INP_INFO_WLOCK();
- SCTP_INP_WLOCK(inp);
/* Setup a vrf_id to be the default for the non-bind-all case. */
vrf_id = inp->def_vrf_id;
@@ -2930,9 +2936,7 @@
if (ntohs(lport) < IPPORT_RESERVED) {
if ((error = priv_check(td, PRIV_NETINET_RESERVEDPORT)) != 0) {
SCTP_INP_DECR_REF(inp);
- SCTP_INP_WUNLOCK(inp);
- SCTP_INP_INFO_WUNLOCK();
- return (error);
+ goto out;
}
}
SCTP_INP_WUNLOCK(inp);
@@ -2959,9 +2963,9 @@
goto continue_anyway;
}
SCTP_INP_DECR_REF(inp);
- SCTP_INP_INFO_WUNLOCK();
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EADDRINUSE);
- return (EADDRINUSE);
+ error = EADDRINUSE;
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
+ goto out_inp_unlocked;
}
} else {
inp_tmp = sctp_pcb_findep(addr, 0, 1, vrf_id);
@@ -2985,9 +2989,9 @@
goto continue_anyway;
}
SCTP_INP_DECR_REF(inp);
- SCTP_INP_INFO_WUNLOCK();
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EADDRINUSE);
- return (EADDRINUSE);
+ error = EADDRINUSE;
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
+ goto out_inp_unlocked;
}
}
continue_anyway:
@@ -3002,10 +3006,9 @@
(sctp_is_feature_on(inp_tmp, SCTP_PCB_FLAGS_PORTREUSE))) {
port_reuse_active = 1;
} else {
- SCTP_INP_WUNLOCK(inp);
- SCTP_INP_INFO_WUNLOCK();
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EADDRINUSE);
- return (EADDRINUSE);
+ error = EADDRINUSE;
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
+ goto out;
}
}
}
@@ -3018,10 +3021,8 @@
last = MODULE_GLOBAL(ipport_hilastauto);
} else if (ip_inp->inp_flags & INP_LOWPORT) {
if ((error = priv_check(td, PRIV_NETINET_RESERVEDPORT)) != 0) {
- SCTP_INP_WUNLOCK(inp);
- SCTP_INP_INFO_WUNLOCK();
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
- return (error);
+ goto out;
}
first = MODULE_GLOBAL(ipport_lowfirstauto);
last = MODULE_GLOBAL(ipport_lowlastauto);
@@ -3045,10 +3046,9 @@
break;
}
if (--count == 0) {
- SCTP_INP_WUNLOCK(inp);
- SCTP_INP_INFO_WUNLOCK();
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EADDRINUSE);
- return (EADDRINUSE);
+ error = EADDRINUSE;
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
+ goto out;
}
if (candidate == last)
candidate = first;
@@ -3062,10 +3062,9 @@
* this really should not happen. The guy did a non-blocking
* bind and then did a close at the same time.
*/
- SCTP_INP_WUNLOCK(inp);
- SCTP_INP_INFO_WUNLOCK();
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
- return (EINVAL);
+ error = EINVAL;
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
+ goto out;
}
/* ok we look clear to give out this port, so lets setup the binding */
if (bindall) {
@@ -3153,21 +3152,19 @@
vrf_id, SCTP_ADDR_NOT_LOCKED);
}
if (ifa == NULL) {
+ error = EADDRNOTAVAIL;
/* Can't find an interface with that address */
- SCTP_INP_WUNLOCK(inp);
- SCTP_INP_INFO_WUNLOCK();
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EADDRNOTAVAIL);
- return (EADDRNOTAVAIL);
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
+ goto out;
}
#ifdef INET6
if (addr->sa_family == AF_INET6) {
/* GAK, more FIXME IFA lock? */
if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
/* Can't bind a non-existent addr. */
- SCTP_INP_WUNLOCK(inp);
- SCTP_INP_INFO_WUNLOCK();
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
- return (EINVAL);
+ error = EINVAL;
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
+ goto out;
}
}
#endif
@@ -3180,11 +3177,8 @@
/* add this address to the endpoint list */
error = sctp_insert_laddr(&inp->sctp_addr_list, ifa, 0);
- if (error != 0) {
- SCTP_INP_WUNLOCK(inp);
- SCTP_INP_INFO_WUNLOCK();
- return (error);
- }
+ if (error != 0)
+ goto out;
inp->laddr_count++;
}
/* find the bucket */
@@ -3203,10 +3197,14 @@
inp->sctp_lport = lport;
/* turn off just the unbound flag */
+ KASSERT((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) != 0,
+ ("%s: inp %p is already bound", __func__, inp));
inp->sctp_flags &= ~SCTP_PCB_FLAGS_UNBOUND;
+out:
SCTP_INP_WUNLOCK(inp);
+out_inp_unlocked:
SCTP_INP_INFO_WUNLOCK();
- return (0);
+ return (error);
}
static void

File Metadata

Mime Type
text/plain
Expires
Tue, Mar 11, 1:30 AM (18 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17092489
Default Alt Text
D31734.diff (7 KB)

Event Timeline