diff options
Diffstat (limited to 'nsprpub/pr/src/io/pripv6.c')
-rw-r--r-- | nsprpub/pr/src/io/pripv6.c | 338 |
1 files changed, 173 insertions, 165 deletions
diff --git a/nsprpub/pr/src/io/pripv6.c b/nsprpub/pr/src/io/pripv6.c index af7de49de..1c299652e 100644 --- a/nsprpub/pr/src/io/pripv6.c +++ b/nsprpub/pr/src/io/pripv6.c @@ -16,117 +16,117 @@ static PRIOMethods ipv6_to_v4_tcpMethods; static PRIOMethods ipv6_to_v4_udpMethods; static PRDescIdentity _pr_ipv6_to_ipv4_id; extern PRBool IsValidNetAddr(const PRNetAddr *addr); -extern PRIPv6Addr _pr_in6addr_any; -extern PRIPv6Addr _pr_in6addr_loopback; +extern const PRIPv6Addr _pr_in6addr_any; +extern const PRIPv6Addr _pr_in6addr_loopback; /* * convert an IPv4-mapped IPv6 addr to an IPv4 addr */ static void _PR_ConvertToIpv4NetAddr(const PRNetAddr *src_v6addr, - PRNetAddr *dst_v4addr) + PRNetAddr *dst_v4addr) { -const PRUint8 *srcp; + const PRUint8 *srcp; - PR_ASSERT(PR_AF_INET6 == src_v6addr->ipv6.family); + PR_ASSERT(PR_AF_INET6 == src_v6addr->ipv6.family); - if (PR_IsNetAddrType(src_v6addr, PR_IpAddrV4Mapped)) { - srcp = src_v6addr->ipv6.ip.pr_s6_addr; - memcpy((char *) &dst_v4addr->inet.ip, srcp + 12, 4); + if (PR_IsNetAddrType(src_v6addr, PR_IpAddrV4Mapped)) { + srcp = src_v6addr->ipv6.ip.pr_s6_addr; + memcpy((char *) &dst_v4addr->inet.ip, srcp + 12, 4); } else if (PR_IsNetAddrType(src_v6addr, PR_IpAddrAny)) { dst_v4addr->inet.ip = htonl(INADDR_ANY); } else if (PR_IsNetAddrType(src_v6addr, PR_IpAddrLoopback)) { dst_v4addr->inet.ip = htonl(INADDR_LOOPBACK); } - dst_v4addr->inet.family = PR_AF_INET; - dst_v4addr->inet.port = src_v6addr->ipv6.port; + dst_v4addr->inet.family = PR_AF_INET; + dst_v4addr->inet.port = src_v6addr->ipv6.port; } /* * convert an IPv4 addr to an IPv4-mapped IPv6 addr */ static void _PR_ConvertToIpv6NetAddr(const PRNetAddr *src_v4addr, - PRNetAddr *dst_v6addr) + PRNetAddr *dst_v6addr) { -PRUint8 *dstp; - - PR_ASSERT(PR_AF_INET == src_v4addr->inet.family); - dst_v6addr->ipv6.family = PR_AF_INET6; - dst_v6addr->ipv6.port = src_v4addr->inet.port; - - if (htonl(INADDR_ANY) == src_v4addr->inet.ip) { - dst_v6addr->ipv6.ip = _pr_in6addr_any; - } else { - dstp = dst_v6addr->ipv6.ip.pr_s6_addr; - memset(dstp, 0, 10); - memset(dstp + 10, 0xff, 2); - memcpy(dstp + 12,(char *) &src_v4addr->inet.ip, 4); - } + PRUint8 *dstp; + + PR_ASSERT(PR_AF_INET == src_v4addr->inet.family); + dst_v6addr->ipv6.family = PR_AF_INET6; + dst_v6addr->ipv6.port = src_v4addr->inet.port; + + if (htonl(INADDR_ANY) == src_v4addr->inet.ip) { + dst_v6addr->ipv6.ip = _pr_in6addr_any; + } else { + dstp = dst_v6addr->ipv6.ip.pr_s6_addr; + memset(dstp, 0, 10); + memset(dstp + 10, 0xff, 2); + memcpy(dstp + 12,(char *) &src_v4addr->inet.ip, 4); + } } static PRStatus PR_CALLBACK Ipv6ToIpv4SocketBind(PRFileDesc *fd, - const PRNetAddr *addr) + const PRNetAddr *addr) { - PRNetAddr tmp_ipv4addr; - const PRNetAddr *tmp_addrp; - PRFileDesc *lo = fd->lower; + PRNetAddr tmp_ipv4addr; + const PRNetAddr *tmp_addrp; + PRFileDesc *lo = fd->lower; - if (PR_AF_INET6 != addr->raw.family) { + if (PR_AF_INET6 != addr->raw.family) { PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0); - return PR_FAILURE; - } - if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) || - PR_IsNetAddrType(addr, PR_IpAddrAny)) { - _PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr); - tmp_addrp = &tmp_ipv4addr; - } else { + return PR_FAILURE; + } + if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) || + PR_IsNetAddrType(addr, PR_IpAddrAny)) { + _PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr); + tmp_addrp = &tmp_ipv4addr; + } else { PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0); - return PR_FAILURE; - } - return((lo->methods->bind)(lo,tmp_addrp)); + return PR_FAILURE; + } + return((lo->methods->bind)(lo,tmp_addrp)); } static PRStatus PR_CALLBACK Ipv6ToIpv4SocketConnect( PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout) { - PRNetAddr tmp_ipv4addr; - const PRNetAddr *tmp_addrp; + PRNetAddr tmp_ipv4addr; + const PRNetAddr *tmp_addrp; - if (PR_AF_INET6 != addr->raw.family) { + if (PR_AF_INET6 != addr->raw.family) { PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0); - return PR_FAILURE; - } - if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) || - PR_IsNetAddrType(addr, PR_IpAddrLoopback)) { - _PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr); - tmp_addrp = &tmp_ipv4addr; - } else { + return PR_FAILURE; + } + if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) || + PR_IsNetAddrType(addr, PR_IpAddrLoopback)) { + _PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr); + tmp_addrp = &tmp_ipv4addr; + } else { PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0); - return PR_FAILURE; - } - return (fd->lower->methods->connect)(fd->lower, tmp_addrp, timeout); + return PR_FAILURE; + } + return (fd->lower->methods->connect)(fd->lower, tmp_addrp, timeout); } static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketSendTo( PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout) { - PRNetAddr tmp_ipv4addr; - const PRNetAddr *tmp_addrp; + PRNetAddr tmp_ipv4addr; + const PRNetAddr *tmp_addrp; - if (PR_AF_INET6 != addr->raw.family) { + if (PR_AF_INET6 != addr->raw.family) { PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0); - return PR_FAILURE; - } - if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) || - PR_IsNetAddrType(addr, PR_IpAddrLoopback)) { - _PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr); - tmp_addrp = &tmp_ipv4addr; - } else { + return PR_FAILURE; + } + if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) || + PR_IsNetAddrType(addr, PR_IpAddrLoopback)) { + _PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr); + tmp_addrp = &tmp_ipv4addr; + } else { PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0); - return PR_FAILURE; - } + return PR_FAILURE; + } return (fd->lower->methods->sendto)( - fd->lower, buf, amount, flags, tmp_addrp, timeout); + fd->lower, buf, amount, flags, tmp_addrp, timeout); } static PRFileDesc* PR_CALLBACK Ipv6ToIpv4SocketAccept ( @@ -135,7 +135,7 @@ static PRFileDesc* PR_CALLBACK Ipv6ToIpv4SocketAccept ( PRStatus rv; PRFileDesc *newfd; PRFileDesc *newstack; - PRNetAddr tmp_ipv4addr; + PRNetAddr tmp_ipv4addr; PRNetAddr *addrlower = NULL; PR_ASSERT(fd != NULL); @@ -149,16 +149,18 @@ static PRFileDesc* PR_CALLBACK Ipv6ToIpv4SocketAccept ( } *newstack = *fd; /* make a copy of the accepting layer */ - if (addr) + if (addr) { addrlower = &tmp_ipv4addr; + } newfd = (fd->lower->methods->accept)(fd->lower, addrlower, timeout); if (NULL == newfd) { PR_DELETE(newstack); return NULL; } - if (addr) + if (addr) { _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, addr); + } rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack); PR_ASSERT(PR_SUCCESS == rv); @@ -166,12 +168,12 @@ static PRFileDesc* PR_CALLBACK Ipv6ToIpv4SocketAccept ( } static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketAcceptRead(PRFileDesc *sd, - PRFileDesc **nd, PRNetAddr **ipv6_raddr, void *buf, PRInt32 amount, - PRIntervalTime timeout) + PRFileDesc **nd, PRNetAddr **ipv6_raddr, void *buf, PRInt32 amount, + PRIntervalTime timeout) { PRInt32 nbytes; PRStatus rv; - PRNetAddr tmp_ipv4addr; + PRNetAddr tmp_ipv4addr; PRFileDesc *newstack; PR_ASSERT(sd != NULL); @@ -186,14 +188,14 @@ static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketAcceptRead(PRFileDesc *sd, *newstack = *sd; /* make a copy of the accepting layer */ nbytes = sd->lower->methods->acceptread( - sd->lower, nd, ipv6_raddr, buf, amount, timeout); + sd->lower, nd, ipv6_raddr, buf, amount, timeout); if (-1 == nbytes) { PR_DELETE(newstack); return nbytes; } - tmp_ipv4addr = **ipv6_raddr; /* copy */ - _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, *ipv6_raddr); + tmp_ipv4addr = **ipv6_raddr; /* copy */ + _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, *ipv6_raddr); /* this PR_PushIOLayer call cannot fail */ rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER, newstack); @@ -202,52 +204,52 @@ static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketAcceptRead(PRFileDesc *sd, } static PRStatus PR_CALLBACK Ipv6ToIpv4SocketGetName(PRFileDesc *fd, - PRNetAddr *ipv6addr) + PRNetAddr *ipv6addr) { - PRStatus result; - PRNetAddr tmp_ipv4addr; - - result = (fd->lower->methods->getsockname)(fd->lower, &tmp_ipv4addr); - if (PR_SUCCESS == result) { - _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr); - PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE); - } - return result; + PRStatus result; + PRNetAddr tmp_ipv4addr; + + result = (fd->lower->methods->getsockname)(fd->lower, &tmp_ipv4addr); + if (PR_SUCCESS == result) { + _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr); + PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE); + } + return result; } static PRStatus PR_CALLBACK Ipv6ToIpv4SocketGetPeerName(PRFileDesc *fd, - PRNetAddr *ipv6addr) + PRNetAddr *ipv6addr) { - PRStatus result; - PRNetAddr tmp_ipv4addr; - - result = (fd->lower->methods->getpeername)(fd->lower, &tmp_ipv4addr); - if (PR_SUCCESS == result) { - _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr); - PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE); - } - return result; + PRStatus result; + PRNetAddr tmp_ipv4addr; + + result = (fd->lower->methods->getpeername)(fd->lower, &tmp_ipv4addr); + if (PR_SUCCESS == result) { + _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr); + PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE); + } + return result; } static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketRecvFrom(PRFileDesc *fd, void *buf, - PRInt32 amount, PRIntn flags, PRNetAddr *ipv6addr, - PRIntervalTime timeout) + PRInt32 amount, PRIntn flags, PRNetAddr *ipv6addr, + PRIntervalTime timeout) { - PRNetAddr tmp_ipv4addr; - PRInt32 result; + PRNetAddr tmp_ipv4addr; + PRInt32 result; result = (fd->lower->methods->recvfrom)( - fd->lower, buf, amount, flags, &tmp_ipv4addr, timeout); - if (-1 != result) { - _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr); - PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE); - } - return result; + fd->lower, buf, amount, flags, &tmp_ipv4addr, timeout); + if (-1 != result) { + _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr); + PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE); + } + return result; } #if defined(_PR_INET6_PROBE) static PRBool ipv6_is_present; -extern PRBool _pr_test_ipv6_socket(void); +PR_EXTERN(PRBool) _pr_test_ipv6_socket(void); #if !defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME) extern PRStatus _pr_find_getipnodebyname(void); @@ -261,13 +263,15 @@ static PRBool _pr_probe_ipv6_presence(void) { #if !defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME) - if (_pr_find_getipnodebyname() != PR_SUCCESS) + if (_pr_find_getipnodebyname() != PR_SUCCESS) { return PR_FALSE; + } #endif #if !defined(_PR_INET6) && defined(_PR_HAVE_GETADDRINFO) - if (_pr_find_getaddrinfo() != PR_SUCCESS) + if (_pr_find_getaddrinfo() != PR_SUCCESS) { return PR_FALSE; + } #endif return _pr_test_ipv6_socket(); @@ -282,83 +286,87 @@ static PRStatus PR_CALLBACK _pr_init_ipv6(void) #if defined(_PR_INET6_PROBE) ipv6_is_present = _pr_probe_ipv6_presence(); - if (ipv6_is_present) + if (ipv6_is_present) { return PR_SUCCESS; + } #endif _pr_ipv6_to_ipv4_id = PR_GetUniqueIdentity("Ipv6_to_Ipv4 layer"); PR_ASSERT(PR_INVALID_IO_LAYER != _pr_ipv6_to_ipv4_id); - stubMethods = PR_GetDefaultIOMethods(); - - ipv6_to_v4_tcpMethods = *stubMethods; /* first get the entire batch */ - /* then override the ones we care about */ - ipv6_to_v4_tcpMethods.connect = Ipv6ToIpv4SocketConnect; - ipv6_to_v4_tcpMethods.bind = Ipv6ToIpv4SocketBind; - ipv6_to_v4_tcpMethods.accept = Ipv6ToIpv4SocketAccept; - ipv6_to_v4_tcpMethods.acceptread = Ipv6ToIpv4SocketAcceptRead; - ipv6_to_v4_tcpMethods.getsockname = Ipv6ToIpv4SocketGetName; - ipv6_to_v4_tcpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName; -/* - ipv6_to_v4_tcpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption; - ipv6_to_v4_tcpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption; -*/ - ipv6_to_v4_udpMethods = *stubMethods; /* first get the entire batch */ - /* then override the ones we care about */ - ipv6_to_v4_udpMethods.connect = Ipv6ToIpv4SocketConnect; - ipv6_to_v4_udpMethods.bind = Ipv6ToIpv4SocketBind; - ipv6_to_v4_udpMethods.sendto = Ipv6ToIpv4SocketSendTo; - ipv6_to_v4_udpMethods.recvfrom = Ipv6ToIpv4SocketRecvFrom; - ipv6_to_v4_udpMethods.getsockname = Ipv6ToIpv4SocketGetName; - ipv6_to_v4_udpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName; -/* - ipv6_to_v4_udpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption; - ipv6_to_v4_udpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption; -*/ - return PR_SUCCESS; + stubMethods = PR_GetDefaultIOMethods(); + + ipv6_to_v4_tcpMethods = *stubMethods; /* first get the entire batch */ + /* then override the ones we care about */ + ipv6_to_v4_tcpMethods.connect = Ipv6ToIpv4SocketConnect; + ipv6_to_v4_tcpMethods.bind = Ipv6ToIpv4SocketBind; + ipv6_to_v4_tcpMethods.accept = Ipv6ToIpv4SocketAccept; + ipv6_to_v4_tcpMethods.acceptread = Ipv6ToIpv4SocketAcceptRead; + ipv6_to_v4_tcpMethods.getsockname = Ipv6ToIpv4SocketGetName; + ipv6_to_v4_tcpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName; + /* + ipv6_to_v4_tcpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption; + ipv6_to_v4_tcpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption; + */ + ipv6_to_v4_udpMethods = *stubMethods; /* first get the entire batch */ + /* then override the ones we care about */ + ipv6_to_v4_udpMethods.connect = Ipv6ToIpv4SocketConnect; + ipv6_to_v4_udpMethods.bind = Ipv6ToIpv4SocketBind; + ipv6_to_v4_udpMethods.sendto = Ipv6ToIpv4SocketSendTo; + ipv6_to_v4_udpMethods.recvfrom = Ipv6ToIpv4SocketRecvFrom; + ipv6_to_v4_udpMethods.getsockname = Ipv6ToIpv4SocketGetName; + ipv6_to_v4_udpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName; + /* + ipv6_to_v4_udpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption; + ipv6_to_v4_udpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption; + */ + return PR_SUCCESS; } #if defined(_PR_INET6_PROBE) PRBool _pr_ipv6_is_present(void) { - if (PR_CallOnce(&_pr_init_ipv6_once, _pr_init_ipv6) != PR_SUCCESS) + if (PR_CallOnce(&_pr_init_ipv6_once, _pr_init_ipv6) != PR_SUCCESS) { return PR_FALSE; + } return ipv6_is_present; } #endif PR_IMPLEMENT(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd) { - PRFileDesc *ipv6_fd = NULL; - - if (PR_CallOnce(&_pr_init_ipv6_once, _pr_init_ipv6) != PR_SUCCESS) - return PR_FAILURE; - - /* - * For platforms with no support for IPv6 - * create layered socket for IPv4-mapped IPv6 addresses - */ - if (fd->methods->file_type == PR_DESC_SOCKET_TCP) - ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id, - &ipv6_to_v4_tcpMethods); - else - ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id, - &ipv6_to_v4_udpMethods); - if (NULL == ipv6_fd) { - goto errorExit; - } - ipv6_fd->secret = NULL; - - if (PR_PushIOLayer(fd, PR_TOP_IO_LAYER, ipv6_fd) == PR_FAILURE) { - goto errorExit; - } - - return PR_SUCCESS; + PRFileDesc *ipv6_fd = NULL; + + if (PR_CallOnce(&_pr_init_ipv6_once, _pr_init_ipv6) != PR_SUCCESS) { + return PR_FAILURE; + } + + /* + * For platforms with no support for IPv6 + * create layered socket for IPv4-mapped IPv6 addresses + */ + if (fd->methods->file_type == PR_DESC_SOCKET_TCP) + ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id, + &ipv6_to_v4_tcpMethods); + else + ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id, + &ipv6_to_v4_udpMethods); + if (NULL == ipv6_fd) { + goto errorExit; + } + ipv6_fd->secret = NULL; + + if (PR_PushIOLayer(fd, PR_TOP_IO_LAYER, ipv6_fd) == PR_FAILURE) { + goto errorExit; + } + + return PR_SUCCESS; errorExit: - if (ipv6_fd) - ipv6_fd->dtor(ipv6_fd); - return PR_FAILURE; + if (ipv6_fd) { + ipv6_fd->dtor(ipv6_fd); + } + return PR_FAILURE; } #endif /* !defined(_PR_INET6) || defined(_PR_INET6_PROBE) */ |