diff options
author | truckman <truckman@FreeBSD.org> | 2002-08-21 11:57:12 +0000 |
---|---|---|
committer | truckman <truckman@FreeBSD.org> | 2002-08-21 11:57:12 +0000 |
commit | 7199888e8f06576febc8146d51d09b781470e8ce (patch) | |
tree | 20c70efb8a65a6f9c615daec57afaba3656fe3cc /sys/netinet/in_pcb.c | |
parent | 2d2341a634a0d5c812cce6d8552614bd05f799c4 (diff) | |
download | FreeBSD-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.c | 53 |
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; } |