5107N/A * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 0N/A/* needed from libsocket on Solaris 8 */ 5107N/A * EXCLBIND socket options only on Solaris 0N/A * Get the specified parameter from the specified driver. The value 0N/A * of the parameter is assumed to be an 'int'. If the parameter 3123N/A * cannot be obtained return -1 3123N/A * Iterative way to find the max value that SO_SNDBUF or SO_RCVBUF 3123N/A * for Solaris versions that do not support the ioctl() in getParam(). 3123N/A * Ugly, but only called once (for each sotype). 3123N/A * As an optimisation, we make a guess using the default values for Solaris 3123N/A * assuming they haven't been modified with ndd. 0N/A return 1;
/* scope is ignored for comparison in 2.2 kernel */ 0N/A msg =
"no further information";
4632N/A#
else /* !DONT_ENABLE_IPV6 */ 0N/A * TODO: We really cant tell since it may be an unrelated error 0N/A * for now we will assume that AF_INET6 is not available 0N/A * If fd 0 is a socket it means we've been launched from inetd or 0N/A * xinetd. If it's a socket then check the family - if it's an 0N/A * IPv4 socket then we need to disable IPv6. 0N/A * Linux - check if any interface has an IPv6 address. 0N/A * Don't need to parse the line - we just need an indication. 0N/A * On Solaris 8 it's possible to create INET6 sockets even 0N/A * though IPv6 is not enabled on all interfaces. Thus we 0N/A * query the number of IPv6 addresses to verify that IPv6 0N/A * has been configured on at least one interface. 0N/A * On Linux it doesn't matter - if IPv6 is built-in the 0N/A * kernel then IPv6 addresses will be bound automatically 0N/A * to all interfaces. 0N/A * SIOCGLIFNUM failed - assume IPv6 not configured 0N/A * If no IPv6 addresses then return false. If count > 0 0N/A * it's possible that all IPv6 addresses are "down" but 0N/A * that's okay as they may be brought "up" while the 0N/A /* SIOCGLIFNUM not defined in build environment ??? */ 0N/A#
endif /* __solaris */ 0N/A * OK we may have the stack available in the kernel, 0N/A * we should also check if the APIs are available. 0N/A * We've got the library, let's get the pointers to some 0N/A * IPV6 specific functions. We have to do that because, at least 0N/A * on Solaris we may build on a system without IPV6 networking 0N/A * libraries, therefore we can't have a hard link to these 2801N/A /* We need all 3 of them */ 4632N/A#
endif /* DONT_ENABLE_IPV6 */ 0N/A#
endif /* AF_INET6 */ 0N/A/* following code creates a list of addresses from the kernel 0N/A * routing table that are routed via the loopback address. 0N/A * We check all destination addresses against this table 0N/A * and override the scope_id field to use the relevant value for "lo" 0N/A * in order to work-around the Linux bug that prevents packets destined 0N/A * for certain local addresses from being sent via a physical interface. 0N/A for (i=0; i<
16; i++) {
0N/A continue;
/* no match */ 0N/A while (
fscanf(f,
"%4s%4s%4s%4s%4s%4s%4s%4s %02x " 0N/A "%4s%4s%4s%4s%4s%4s%4s%4s %02x " 0N/A "%4s%4s%4s%4s%4s%4s%4s%4s " 0N/A "%08x %08x %08x %08lx %8s",
0N/A * Some routes should be ignored 0N/A * Convert the destination address 0N/A /* not an Ipv6 address */ 0N/A /* Not a loopback route */ 0N/A /* now find the scope_id for "lo" */ 0N/A while (
fscanf(f,
"%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
0N/A * Found - so just return the index 0N/A * Following is used for binding to local addresses. Equivalent 0N/A * to code above, for bind(). 0N/Astatic int nifs = 0;
/* number of entries used in array */ 0N/A/* not thread safe: make sure called once from one thread */ 0N/A unsigned int u0,
u1,
u2,
u3,
u4,
u5,
u6,
u7,
u8,
u9,
ua,
ub,
uc,
ud,
ue,
uf;
0N/A while (
fscanf (f,
"%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x " 0N/A/* return the scope_id (interface index) of the 0N/A * interface corresponding to the given address 0N/A * returns 0 if no match found 0N/A/* In the case of an IPv4 Inetaddress this method will return an 0N/A * IPv4 mapped address where IPv6 is available and v4MappedAddress is TRUE. 0N/A * Otherwise it will return a sockaddr_in structure for an IPv4 InetAddress. 0N/A /* needs work. 1. family 2. clean up him6 etc deallocate memory */ 0N/A /* we would always prefer IPv6 wildcard address 0N/A caddr[11] = 0xff; */ 4632N/A// XXXBSD: should we do something with scope id here ? see below linux comment 4632N/A/* MMM: Come back to this! */ 0N/A * On Linux if we are connecting to a link-local address 0N/A * we need to specify the interface in the scope_id (2.4 kernel only) 0N/A * If the scope was cached the we use the cached value. If not cached but 0N/A * specified in the Inet6Address we use that, but we first check if the 0N/A * address needs to be routed via the loopback interface. In this case, 0N/A * we override the specified value with that of the loopback interface. 0N/A * If no cached value exists and no value was specified by user, then 0N/A * we try to determine a value ffrom the routing table. In all these 0N/A * cases the used value is cached for further use. 0N/A /* if cached value exists then use it. Otherwise, check 0N/A * if scope is set in the address. 0N/A /* check user-specified value for loopback case 0N/A * that needs to be overridden 0N/A * Otherwise consult the IPv6 routing tables to 0N/A * try determine the appropriate interface. 0N/A * If we have a scope_id use the extended form 0N/A /* handle scope_id for solaris */ 0N/A#
endif /* AF_INET6 */ 0N/A#
endif /* AF_INET6 */ 0N/A#
endif /* AF_INET6 */ 0N/A for (i = 0; i <
10; i++) {
0N/A return 0;
/* false */ 0N/A if (((
caddr[
10] &
0xff) ==
0xff) && ((
caddr[
11] &
0xff) ==
0xff)) {
0N/A return 1;
/* true */ 0N/A return 0;
/* false */ 0N/A return ((
caddr[
12] &
0xff) <<
24) | ((
caddr[
13] &
0xff) <<
16) | ((
caddr[
14] &
0xff) <<
8)
0N/A for (i = 0; i <
16; i++) {
0N/A return 0;
/* false */ 0N/A * Map the Java level socket option to the platform specific 0N/A * level and option name. 0N/A * Different multicast options if IPv6 is enabled 0N/A * Map the Java level option to the native level 0N/A for (i=0; i<(
int)(
sizeof(
opts) /
sizeof(
opts[0])); i++) {
0N/A * Determine the default interface for an IPv6 address. 0N/A * (eg: fe80::/10 or a route for the specific address). 0N/A * This will tell us the interface to use (eg: "eth0"). 0N/A * name to an interface index. 0N/A * 0 if no matching interface 0N/A * >1 interface index to use for the link-local address. 0N/A while (
fscanf(f,
"%4s%4s%4s%4s%4s%4s%4s%4s %02x " 0N/A "%4s%4s%4s%4s%4s%4s%4s%4s %02x " 0N/A "%4s%4s%4s%4s%4s%4s%4s%4s " 0N/A "%08x %08x %08x %08lx %8s",
0N/A * Some routes should be ignored 0N/A * Convert the destination address 0N/A /* not an Ipv6 address */ 0N/A * The prefix len (dest_plen) indicates the number of bits we 0N/A * dest_plen / 8 => number of bytes to match 0N/A * dest_plen % 8 => number of additional bits to match 0N/A * eg: fe80::/10 => match 1 byte + 2 additional bits in the 0N/A continue;
/* no match */ 0N/A * If there's a match then we lookup the interface 0N/A while (
fscanf(f,
"%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
0N/A * Found - so just return the index 0N/A * If we get here it means we didn't there wasn't any 0N/A * route or we couldn't get the index of the interface. 0N/A * Wrapper for getsockopt system routine - does any necessary 0N/A * pre/post processing to deal with OS specific oddies :- 0N/A * IP_TOS is a no-op with IPv6 sockets as it's setup when 0N/A * the connection is established. 0N/A * to compensate for an incorrect value returned by the kernel. 0N/A * For IPv6 socket option implemented at Java-level 0N/A * stems from additional socket structures in the send 0N/A * and receive buffers. 4638N/A/* Workaround for Mac OS treating linger value as 0N/A * Wrapper for setsockopt system routine - performs any 0N/A * necessary pre/post processing to deal with OS specific 0N/A * On Solaris need to limit the suggested value for SO_SNDBUF 0N/A * and SO_RCVBUF to the kernel configured limit 0N/A * For IP_TOS socket option need to mask off bits as this 0N/A * aren't automatically masked by the kernel and results in 0N/A * an error. In addition IP_TOS is a noop with IPv6 as it 0N/A * should be setup as connection time. 4669N/A * in flowinfo field when connecting TCP socket, 0N/A * 2. IPv6 on Linux: By default Linux ignores flowinfo 0N/A * field so enable IPV6_FLOWINFO_SEND so that flowinfo 0N/A * 3. IPv4: set socket option based on ToS and Precedence 0N/A * fields (otherwise get invalid argument) 2827N/A * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris we may need to clamp 2827N/A * the value when it exceeds the system limit. 2827N/A /* Attempt with the original size */ 2827N/A /* Exceeded system limit so clamp and retry */ 3123N/A * We try to get tcp_maxbuf (and udp_max_buf) using 3123N/A * an ioctl() that isn't available on all versions of Solaris. 3123N/A * If that fails, we use the search algorithm in findMaxBuf() 0N/A * On Linux the receive buffer is used for both socket 0N/A * structures and the the packet payload. The implication 0N/A * is that if SO_RCVBUF is too small then small packets 4632N/A * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On FreeBSD need to 4632N/A * ensure that value is <= kern.ipc.maxsockbuf as otherwise we get 4632N/A problem. It should be removed when kern.ipc.maxsockbuf 4632N/A * On Solaris, SO_REUSEADDR will allow multiple datagram 4632N/A * sockets to bind to the same port. The network jck tests 4632N/A * for this "feature", so we need to emulate it by turning on 4632N/A * SO_REUSEPORT as well for that combination. 0N/A * Wrapper for bind system call - performs any necessary pre/post 0N/A * processing to deal with OS specific issues :- 0N/A * Linux allows a socket to bind to 127.0.0.255 which must be 5107N/A * On Solaris with IPv6 enabled we must use an exclusive 0N/A * bind to guaranteed a unique port number across the IPv4 and 0N/A * ## get bugId for this issue - goes back to 1.2.2 port ## 0N/A * ## When IPv6 is enabled this will be an IPv4-mapped 0N/A * ## with family set to AF_INET6 5107N/A * Solaris has seperate IPv4 and IPv6 port spaces so we 0N/A * use an exclusive bind when SO_REUSEADDR is not used to 0N/A * give the illusion of a unified port space. 5107N/A * This also avoids problems with IPv6 sockets connecting 0N/A * to IPv4 mapped addresses whereby the socket conversion 0N/A * results in a late bind that fails because the 0N/A * corresponding IPv4 port is in use. 5107N/A * SO_REUSEADDR is disabled or sun.net.useExclusiveBind 5107N/A * property is true so enable TCP_EXCLBIND or 0N/A /* Restore *_EXCLBIND if the bind fails */ 0N/A * Wrapper for select/poll with timeout on a single file descriptor. 0N/A * NET_WAIT_READ, NET_WAIT_WRITE & NET_WAIT_CONNECT. 0N/A * The function will return when either the socket is ready for one 0N/A * of the specified operation or the timeout expired. 0N/A * It returns the time left from the timeout (possibly 0), or -1 if it expired.