summaryrefslogtreecommitdiffstats
path: root/sys/netinet/in_pcb.c
diff options
context:
space:
mode:
authortruckman <truckman@FreeBSD.org>2002-08-21 11:57:12 +0000
committertruckman <truckman@FreeBSD.org>2002-08-21 11:57:12 +0000
commit7199888e8f06576febc8146d51d09b781470e8ce (patch)
tree20c70efb8a65a6f9c615daec57afaba3656fe3cc /sys/netinet/in_pcb.c
parent2d2341a634a0d5c812cce6d8552614bd05f799c4 (diff)
downloadFreeBSD-src-7199888e8f06576febc8146d51d09b781470e8ce.zip
FreeBSD-src-7199888e8f06576febc8146d51d09b781470e8ce.tar.gz
Create new functions in_sockaddr(), in6_sockaddr(), and
in6_v4mapsin6_sockaddr() which allocate the appropriate sockaddr_in* structure and initialize it with the address and port information passed as arguments. Use calls to these new functions to replace code that is replicated multiple times in in_setsockaddr(), in_setpeeraddr(), in6_setsockaddr(), in6_setpeeraddr(), in6_mapped_sockaddr(), and in6_mapped_peeraddr(). Inline COMMON_END in tcp_usr_accept() so that we can call in_sockaddr() with temporary copies of the address and port after the PCB is unlocked. Fix the lock violation in tcp6_usr_accept() (caused by calling MALLOC() inside in6_mapped_peeraddr() while the PCB is locked) by changing the implementation of tcp6_usr_accept() to match tcp_usr_accept(). Reviewed by: suz
Diffstat (limited to 'sys/netinet/in_pcb.c')
-rw-r--r--sys/netinet/in_pcb.c53
1 files changed, 27 insertions, 26 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 8284031..9ad3607 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -577,6 +577,23 @@ in_pcbdetach(inp)
uma_zfree(ipi->ipi_zone, inp);
}
+struct sockaddr *
+in_sockaddr(port, addr_p)
+ in_port_t port;
+ struct in_addr *addr_p;
+{
+ struct sockaddr_in *sin;
+
+ MALLOC(sin, struct sockaddr_in *, sizeof *sin, M_SONAME,
+ M_WAITOK | M_ZERO);
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(*sin);
+ sin->sin_addr = *addr_p;
+ sin->sin_port = port;
+
+ return (struct sockaddr *)sin;
+}
+
/*
* The wrapper function will pass down the pcbinfo for this function to lock.
* The socket must have a valid
@@ -593,15 +610,8 @@ in_setsockaddr(so, nam, pcbinfo)
{
int s;
register struct inpcb *inp;
- register struct sockaddr_in *sin;
-
- /*
- * Do the malloc first in case it blocks.
- */
- MALLOC(sin, struct sockaddr_in *, sizeof *sin, M_SONAME,
- M_WAITOK | M_ZERO);
- sin->sin_family = AF_INET;
- sin->sin_len = sizeof(*sin);
+ struct in_addr addr;
+ in_port_t port;
s = splnet();
INP_INFO_RLOCK(pcbinfo);
@@ -609,17 +619,16 @@ in_setsockaddr(so, nam, pcbinfo)
if (!inp) {
INP_INFO_RUNLOCK(pcbinfo);
splx(s);
- free(sin, M_SONAME);
return ECONNRESET;
}
INP_LOCK(inp);
- sin->sin_port = inp->inp_lport;
- sin->sin_addr = inp->inp_laddr;
+ port = inp->inp_lport;
+ addr = inp->inp_laddr;
INP_UNLOCK(inp);
INP_INFO_RUNLOCK(pcbinfo);
splx(s);
- *nam = (struct sockaddr *)sin;
+ *nam = in_sockaddr(port, &addr);
return 0;
}
@@ -634,15 +643,8 @@ in_setpeeraddr(so, nam, pcbinfo)
{
int s;
register struct inpcb *inp;
- register struct sockaddr_in *sin;
-
- /*
- * Do the malloc first in case it blocks.
- */
- MALLOC(sin, struct sockaddr_in *, sizeof *sin, M_SONAME,
- M_WAITOK | M_ZERO);
- sin->sin_family = AF_INET;
- sin->sin_len = sizeof(*sin);
+ struct in_addr addr;
+ in_port_t port;
s = splnet();
INP_INFO_RLOCK(pcbinfo);
@@ -650,17 +652,16 @@ in_setpeeraddr(so, nam, pcbinfo)
if (!inp) {
INP_INFO_RUNLOCK(pcbinfo);
splx(s);
- free(sin, M_SONAME);
return ECONNRESET;
}
INP_LOCK(inp);
- sin->sin_port = inp->inp_fport;
- sin->sin_addr = inp->inp_faddr;
+ port = inp->inp_fport;
+ addr = inp->inp_faddr;
INP_UNLOCK(inp);
INP_INFO_RUNLOCK(pcbinfo);
splx(s);
- *nam = (struct sockaddr *)sin;
+ *nam = in_sockaddr(port, &addr);
return 0;
}
OpenPOWER on IntegriCloud