Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F81970178
D5017.id12550.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D5017.id12550.diff
View Options
Index: sys/netinet/in_pcb.h
===================================================================
--- sys/netinet/in_pcb.h
+++ sys/netinet/in_pcb.h
@@ -687,8 +687,8 @@
void in_pcbpurgeif0(struct inpcbinfo *, struct ifnet *);
int in_pcballoc(struct socket *, struct inpcbinfo *);
int in_pcbbind(struct inpcb *, struct sockaddr *, struct ucred *);
-int in_pcb_lport(struct inpcb *, struct in_addr *, u_short *,
- struct ucred *, int);
+int in_pcb_lport(struct inpcb *, struct sockaddr *, struct in_addr *,
+ u_short *, struct ucred *, int);
int in_pcbbind_setup(struct inpcb *, struct sockaddr *, in_addr_t *,
u_short *, struct ucred *);
int in_pcbconnect(struct inpcb *, struct sockaddr *, struct ucred *);
Index: sys/netinet/in_pcb.c
===================================================================
--- sys/netinet/in_pcb.c
+++ sys/netinet/in_pcb.c
@@ -372,8 +372,8 @@
*/
#if defined(INET) || defined(INET6)
int
-in_pcb_lport(struct inpcb *inp, struct in_addr *laddrp, u_short *lportp,
- struct ucred *cred, int lookupflags)
+in_pcb_lport(struct inpcb *inp, struct sockaddr *nam, struct in_addr *laddrp,
+ u_short *lportp, struct ucred *cred, int lookupflags)
{
struct inpcbinfo *pcbinfo;
struct inpcb *tmpinp;
@@ -382,6 +382,7 @@
u_short aux, first, last, lport;
#ifdef INET
struct in_addr laddr;
+ struct sockaddr_in *sin = NULL;
#endif
pcbinfo = inp->inp_pcbinfo;
@@ -448,6 +449,7 @@
KASSERT(laddrp != NULL, ("%s: laddrp NULL for v4 inp %p",
__func__, inp));
laddr = *laddrp;
+ sin = (struct sockaddr_in *)nam;
}
#endif
tmpinp = NULL; /* Make compiler happy. */
@@ -467,16 +469,29 @@
lport = htons(*lastport);
#ifdef INET6
- if ((inp->inp_vflag & INP_IPV6) != 0)
- tmpinp = in6_pcblookup_local(pcbinfo,
- &inp->in6p_laddr, lport, lookupflags, cred);
+ if ((inp->inp_vflag & INP_IPV6) != 0) {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
+ if (sin6 != NULL && (inp->inp_flags & INP_ANONPORT)) {
+ tmpinp = in6_pcblookup_hash_locked(pcbinfo,
+ &sin6->sin6_addr, sin6->sin6_port,
+ &inp->in6p_laddr, lport,
+ lookupflags & (~INPLOOKUP_WILDCARD),
+ NULL);
+ } else
+ tmpinp = in6_pcblookup_local(pcbinfo,
+ &inp->in6p_laddr, lport, lookupflags, cred);
+ }
#endif
#if defined(INET) && defined(INET6)
else
#endif
#ifdef INET
- tmpinp = in_pcblookup_local(pcbinfo, laddr,
- lport, lookupflags, cred);
+ if (sin != NULL && (inp->inp_flags & INP_ANONPORT))
+ tmpinp = in_pcblookup_hash_locked(pcbinfo, sin->sin_addr, sin->sin_port, laddr,
+ lport, lookupflags & (~INPLOOKUP_WILDCARD), NULL);
+ else
+ tmpinp = in_pcblookup_local(pcbinfo, laddr,
+ lport, lookupflags, cred);
#endif
} while (tmpinp != NULL);
@@ -572,7 +587,7 @@
return (EINVAL);
if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
lookupflags = INPLOOKUP_WILDCARD;
- if (nam == NULL) {
+ if (nam == NULL || ((*lportp) == 0 && (inp->inp_flags & INP_ANONPORT))) {
if ((error = prison_local_ip4(cred, &laddr)) != 0)
return (error);
} else {
@@ -693,7 +708,7 @@
if (*lportp != 0)
lport = *lportp;
if (lport == 0) {
- error = in_pcb_lport(inp, &laddr, &lport, cred, lookupflags);
+ error = in_pcb_lport(inp, nam, &laddr, &lport, cred, lookupflags);
if (error != 0)
return (error);
Index: sys/netinet/tcp_usrreq.c
===================================================================
--- sys/netinet/tcp_usrreq.c
+++ sys/netinet/tcp_usrreq.c
@@ -1217,9 +1217,12 @@
INP_HASH_WLOCK(&V_tcbinfo);
if (inp->inp_lport == 0) {
- error = in_pcbbind(inp, (struct sockaddr *)0, td->td_ucred);
- if (error)
+ inp->inp_flags |= INP_ANONPORT;
+ error = in_pcbbind(inp, nam, td->td_ucred);
+ if (error) {
+ inp->inp_flags &= ~INP_ANONPORT;
goto out;
+ }
}
/*
@@ -1275,9 +1278,12 @@
INP_HASH_WLOCK(&V_tcbinfo);
if (inp->inp_lport == 0) {
- error = in6_pcbbind(inp, (struct sockaddr *)0, td->td_ucred);
- if (error)
+ inp->inp_flags |= INP_ANONPORT;
+ error = in6_pcbbind(inp, nam, td->td_ucred);
+ if (error) {
+ inp->inp_flags &= ~INP_ANONPORT;
goto out;
+ }
}
error = in6_pcbconnect(inp, nam, td->td_ucred);
if (error != 0)
Index: sys/netinet6/in6_pcb.h
===================================================================
--- sys/netinet6/in6_pcb.h
+++ sys/netinet6/in6_pcb.h
@@ -112,7 +112,8 @@
int in6_mapped_sockaddr(struct socket *so, struct sockaddr **nam);
int in6_mapped_peeraddr(struct socket *so, struct sockaddr **nam);
int in6_selecthlim(struct in6pcb *, struct ifnet *);
-int in6_pcbsetport(struct in6_addr *, struct inpcb *, struct ucred *);
+int in6_pcbsetport(struct sockaddr *, struct in6_addr *, struct inpcb *,
+ struct ucred *);
void init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m);
#endif /* _KERNEL */
Index: sys/netinet6/in6_pcb.c
===================================================================
--- sys/netinet6/in6_pcb.c
+++ sys/netinet6/in6_pcb.c
@@ -131,7 +131,7 @@
return (EINVAL);
if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
lookupflags = INPLOOKUP_WILDCARD;
- if (nam == NULL) {
+ if (nam == NULL || (inp->inp_flags & INP_ANONPORT)) {
if ((error = prison_local_ip6(cred, &inp->in6p_laddr,
((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0)
return (error);
@@ -295,7 +295,7 @@
inp->in6p_laddr = sin6->sin6_addr;
}
if (lport == 0) {
- if ((error = in6_pcbsetport(&inp->in6p_laddr, inp, cred)) != 0) {
+ if ((error = in6_pcbsetport(nam, &inp->in6p_laddr, inp, cred)) != 0) {
/* Undo an address bind that may have occurred. */
inp->in6p_laddr = in6addr_any;
return (error);
@@ -415,9 +415,12 @@
}
if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) {
if (inp->inp_lport == 0) {
- error = in6_pcbbind(inp, (struct sockaddr *)0, cred);
- if (error)
+ inp->inp_flags |= INP_ANONPORT;
+ error = in6_pcbbind(inp, nam, cred);
+ if (error) {
+ inp->inp_flags &= ~INP_ANONPORT;
return (error);
+ }
}
inp->in6p_laddr = addr6;
}
Index: sys/netinet6/in6_src.c
===================================================================
--- sys/netinet6/in6_src.c
+++ sys/netinet6/in6_src.c
@@ -956,7 +956,8 @@
* share this function by all *bsd*...
*/
int
-in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct ucred *cred)
+in6_pcbsetport(struct sockaddr *nam6, struct in6_addr *laddr, struct inpcb *inp,
+ struct ucred *cred)
{
struct socket *so = inp->inp_socket;
u_int16_t lport = 0;
@@ -979,7 +980,7 @@
inp->inp_flags |= INP_ANONPORT;
- error = in_pcb_lport(inp, NULL, &lport, cred, lookupflags);
+ error = in_pcb_lport(inp, nam6, NULL, &lport, cred, lookupflags);
if (error != 0)
return (error);
Index: sys/netinet6/udp6_usrreq.c
===================================================================
--- sys/netinet6/udp6_usrreq.c
+++ sys/netinet6/udp6_usrreq.c
@@ -742,11 +742,16 @@
error = EADDRNOTAVAIL;
goto release;
}
- if (inp->inp_lport == 0 &&
- (error = in6_pcbsetport(laddr, inp, td->td_ucred)) != 0) {
- /* Undo an address bind that may have occurred. */
- inp->in6p_laddr = in6addr_any;
- goto release;
+ if (inp->inp_lport == 0) {
+ inp->inp_flags |= INP_ANONPORT;
+ error = in6_pcbsetport((struct sockaddr *)addr6, laddr,
+ inp, td->td_ucred);
+ if (error) {
+ inp->inp_flags &= ~INP_ANONPORT;
+ /* Undo an address bind that may have occurred. */
+ inp->in6p_laddr = in6addr_any;
+ goto release;
+ }
}
} else {
if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Dec 15, 3:00 PM (12 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
9091716
Default Alt Text
D5017.id12550.diff (7 KB)
Attached To
Mode
D5017: More than 65K connection from single application
Attached
Detach File
Event Timeline
Log In to Comment