--- a/src/java.base/unix/native/libnet/net_util_md.c Thu Jun 13 12:22:28 2019 +0530
+++ b/src/java.base/unix/native/libnet/net_util_md.c Thu Jun 13 09:10:51 2019 +0100
@@ -452,285 +452,7 @@
}
}
-#if defined(__linux__)
-
-/* following code creates a list of addresses from the kernel
- * routing table that are routed via the loopback address.
- * We check all destination addresses against this table
- * and override the scope_id field to use the relevant value for "lo"
- * in order to work-around the Linux bug that prevents packets destined
- * for certain local addresses from being sent via a physical interface.
- */
-
-struct loopback_route {
- struct in6_addr addr; /* destination address */
- int plen; /* prefix length */
-};
-
-static struct loopback_route *loRoutes = 0;
-static int nRoutes = 0; /* number of routes */
-static int loRoutes_size = 16; /* initial size */
-static int lo_scope_id = 0;
-
-static void initLoopbackRoutes();
-
-void printAddr (struct in6_addr *addr) {
- int i;
- for (i=0; i<16; i++) {
- printf ("%02x", addr->s6_addr[i]);
- }
- printf ("\n");
-}
-
-static jboolean needsLoopbackRoute (struct in6_addr* dest_addr) {
- int byte_count;
- int extra_bits, i;
- struct loopback_route *ptr;
-
- if (loRoutes == 0) {
- initLoopbackRoutes();
- }
-
- for (ptr = loRoutes, i=0; i<nRoutes; i++, ptr++) {
- struct in6_addr *target_addr=&ptr->addr;
- int dest_plen = ptr->plen;
- byte_count = dest_plen >> 3;
- extra_bits = dest_plen & 0x3;
-
- if (byte_count > 0) {
- if (memcmp(target_addr, dest_addr, byte_count)) {
- continue; /* no match */
- }
- }
-
- if (extra_bits > 0) {
- unsigned char c1 = ((unsigned char *)target_addr)[byte_count];
- unsigned char c2 = ((unsigned char *)&dest_addr)[byte_count];
- unsigned char mask = 0xff << (8 - extra_bits);
- if ((c1 & mask) != (c2 & mask)) {
- continue;
- }
- }
- return JNI_TRUE;
- }
- return JNI_FALSE;
-}
-
-
-static void initLoopbackRoutes() {
- FILE *f;
- char srcp[8][5];
- char hopp[8][5];
- int dest_plen, src_plen, use, refcnt, metric;
- unsigned long flags;
- char dest_str[40];
- struct in6_addr dest_addr;
- char device[16];
- struct loopback_route *loRoutesTemp;
-
- if (loRoutes != 0) {
- free (loRoutes);
- }
- loRoutes = calloc (loRoutes_size, sizeof(struct loopback_route));
- if (loRoutes == 0) {
- return;
- }
- /*
- * Scan /proc/net/ipv6_route looking for a matching
- * route.
- */
- if ((f = fopen("/proc/net/ipv6_route", "r")) == NULL) {
- return ;
- }
- while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x "
- "%4s%4s%4s%4s%4s%4s%4s%4s %02x "
- "%4s%4s%4s%4s%4s%4s%4s%4s "
- "%08x %08x %08x %08lx %8s",
- dest_str, &dest_str[5], &dest_str[10], &dest_str[15],
- &dest_str[20], &dest_str[25], &dest_str[30], &dest_str[35],
- &dest_plen,
- srcp[0], srcp[1], srcp[2], srcp[3],
- srcp[4], srcp[5], srcp[6], srcp[7],
- &src_plen,
- hopp[0], hopp[1], hopp[2], hopp[3],
- hopp[4], hopp[5], hopp[6], hopp[7],
- &metric, &use, &refcnt, &flags, device) == 31) {
-
- /*
- * Some routes should be ignored
- */
- if ( (dest_plen < 0 || dest_plen > 128) ||
- (src_plen != 0) ||
- (flags & (RTF_POLICY | RTF_FLOW)) ||
- ((flags & RTF_REJECT) && dest_plen == 0) ) {
- continue;
- }
-
- /*
- * Convert the destination address
- */
- dest_str[4] = ':';
- dest_str[9] = ':';
- dest_str[14] = ':';
- dest_str[19] = ':';
- dest_str[24] = ':';
- dest_str[29] = ':';
- dest_str[34] = ':';
- dest_str[39] = '\0';
-
- if (inet_pton(AF_INET6, dest_str, &dest_addr) < 0) {
- /* not an Ipv6 address */
- continue;
- }
- if (strcmp(device, "lo") != 0) {
- /* Not a loopback route */
- continue;
- } else {
- if (nRoutes == loRoutes_size) {
- loRoutesTemp = realloc (loRoutes, loRoutes_size *
- sizeof (struct loopback_route) * 2);
-
- if (loRoutesTemp == 0) {
- free(loRoutes);
- loRoutes = NULL;
- nRoutes = 0;
- fclose (f);
- return;
- }
- loRoutes=loRoutesTemp;
- loRoutes_size *= 2;
- }
- memcpy (&loRoutes[nRoutes].addr,&dest_addr,sizeof(struct in6_addr));
- loRoutes[nRoutes].plen = dest_plen;
- nRoutes ++;
- }
- }
-
- fclose (f);
- {
- /* now find the scope_id for "lo" */
-
- char devname[21];
- char addr6p[8][5];
- int plen, scope, dad_status, if_idx;
-
- if ((f = fopen("/proc/net/if_inet6", "r")) != NULL) {
- while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n",
- addr6p[0], addr6p[1], addr6p[2], addr6p[3],
- addr6p[4], addr6p[5], addr6p[6], addr6p[7],
- &if_idx, &plen, &scope, &dad_status, devname) == 13) {
-
- if (strcmp(devname, "lo") == 0) {
- /*
- * Found - so just return the index
- */
- fclose(f);
- lo_scope_id = if_idx;
- return;
- }
- }
- fclose(f);
- }
- }
-}
-
-/*
- * Following is used for binding to local addresses. Equivalent
- * to code above, for bind().
- */
-
-struct localinterface {
- int index;
- char localaddr [16];
-};
-
-static struct localinterface *localifs = 0;
-static int localifsSize = 0; /* size of array */
-static int nifs = 0; /* number of entries used in array */
-
-/* not thread safe: make sure called once from one thread */
-
-static void initLocalIfs () {
- FILE *f;
- unsigned char staddr [16];
- char ifname [33];
- struct localinterface *lif=0;
- struct localinterface *localifsTemp;
- int index, x1, x2, x3;
- unsigned int u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,ua,ub,uc,ud,ue,uf;
-
- if ((f = fopen("/proc/net/if_inet6", "r")) == NULL) {
- return ;
- }
- while (fscanf (f, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x "
- "%d %x %x %x %32s",&u0,&u1,&u2,&u3,&u4,&u5,&u6,&u7,
- &u8,&u9,&ua,&ub,&uc,&ud,&ue,&uf,
- &index, &x1, &x2, &x3, ifname) == 21) {
- staddr[0] = (unsigned char)u0;
- staddr[1] = (unsigned char)u1;
- staddr[2] = (unsigned char)u2;
- staddr[3] = (unsigned char)u3;
- staddr[4] = (unsigned char)u4;
- staddr[5] = (unsigned char)u5;
- staddr[6] = (unsigned char)u6;
- staddr[7] = (unsigned char)u7;
- staddr[8] = (unsigned char)u8;
- staddr[9] = (unsigned char)u9;
- staddr[10] = (unsigned char)ua;
- staddr[11] = (unsigned char)ub;
- staddr[12] = (unsigned char)uc;
- staddr[13] = (unsigned char)ud;
- staddr[14] = (unsigned char)ue;
- staddr[15] = (unsigned char)uf;
- nifs ++;
- if (nifs > localifsSize) {
- localifsTemp = (struct localinterface *) realloc(
- localifs, sizeof (struct localinterface)* (localifsSize+5));
- if (localifsTemp == 0) {
- free(localifs);
- localifs = 0;
- localifsSize = 0;
- nifs = 0;
- fclose(f);
- return;
- }
- localifs = localifsTemp;
- lif = localifs + localifsSize;
- localifsSize += 5;
- } else {
- lif ++;
- }
- memcpy (lif->localaddr, staddr, 16);
- lif->index = index;
- }
- fclose (f);
-}
-
-/* return the scope_id (interface index) of the
- * interface corresponding to the given address
- * returns 0 if no match found
- */
-
-static int getLocalScopeID (char *addr) {
- struct localinterface *lif;
- int i;
- if (localifs == 0) {
- initLocalIfs();
- }
- for (i=0, lif=localifs; i<nifs; i++, lif++) {
- if (memcmp (addr, lif->localaddr, 16) == 0) {
- return lif->index;
- }
- }
- return 0;
-}
-
-void platformInit () {
- initLoopbackRoutes();
- initLocalIfs();
-}
-
-#elif defined(_AIX)
+#if defined(_AIX)
/* Initialize stubs for blocking I/O workarounds (see src/solaris/native/java/net/linux_close.c) */
extern void aix_close_init();
@@ -816,71 +538,12 @@
*len = sizeof(struct sockaddr_in6);
}
-#ifdef __linux__
- /*
- * On Linux if we are connecting to a link-local address
- * we need to specify the interface in the scope_id (2.4 kernel only)
- *
- * If the scope was cached then we use the cached value. If not cached but
- * specified in the Inet6Address we use that, but we first check if the
- * address needs to be routed via the loopback interface. In this case,
- * we override the specified value with that of the loopback interface.
- * If no cached value exists and no value was specified by user, then
- * we try to determine a value from the routing table. In all these
- * cases the used value is cached for further use.
- */
- if (IN6_IS_ADDR_LINKLOCAL(&sa->sa6.sin6_addr)) {
- unsigned int cached_scope_id = 0, scope_id = 0;
-
- if (ia6_cachedscopeidID) {
- cached_scope_id = (int)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID);
- /* if cached value exists then use it. Otherwise, check
- * if scope is set in the address.
- */
- if (!cached_scope_id) {
- if (ia6_scopeidID) {
- scope_id = getInet6Address_scopeid(env, iaObj);
- }
- if (scope_id != 0) {
- /* check user-specified value for loopback case
- * that needs to be overridden
- */
- if (kernelIsV24() && needsLoopbackRoute(&sa->sa6.sin6_addr)) {
- cached_scope_id = lo_scope_id;
- (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id);
- }
- } else {
- /*
- * Otherwise consult the IPv6 routing tables to
- * try determine the appropriate interface.
- */
- if (kernelIsV24()) {
- cached_scope_id = getDefaultIPv6Interface(&sa->sa6.sin6_addr);
- } else {
- cached_scope_id = getLocalScopeID((char *)&(sa->sa6.sin6_addr));
- if (cached_scope_id == 0) {
- cached_scope_id = getDefaultIPv6Interface(&sa->sa6.sin6_addr);
- }
- }
- (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id);
- }
- }
- }
-
- /*
- * If we have a scope_id use the extended form
- * of sockaddr_in6.
- */
- sa->sa6.sin6_scope_id = cached_scope_id == 0 ? scope_id : cached_scope_id;
- }
-#else
/* handle scope_id */
if (family != java_net_InetAddress_IPv4) {
if (ia6_scopeidID) {
sa->sa6.sin6_scope_id = getInet6Address_scopeid(env, iaObj);
}
}
-#endif
} else {
jint address;
if (family != java_net_InetAddress_IPv4) {
@@ -1015,158 +678,6 @@
}
/*
- * Determine the default interface for an IPv6 address.
- *
- * 1. Scans /proc/net/ipv6_route for a matching route
- * (eg: fe80::/10 or a route for the specific address).
- * This will tell us the interface to use (eg: "eth0").
- *
- * 2. Lookup /proc/net/if_inet6 to map the interface
- * name to an interface index.
- *
- * Returns :-
- * -1 if error
- * 0 if no matching interface
- * >1 interface index to use for the link-local address.
- */
-#if defined(__linux__)
-int getDefaultIPv6Interface(struct in6_addr *target_addr) {
- FILE *f;
- char srcp[8][5];
- char hopp[8][5];
- int dest_plen, src_plen, use, refcnt, metric;
- unsigned long flags;
- char dest_str[40];
- struct in6_addr dest_addr;
- char device[16];
- jboolean match = JNI_FALSE;
-
- /*
- * Scan /proc/net/ipv6_route looking for a matching
- * route.
- */
- if ((f = fopen("/proc/net/ipv6_route", "r")) == NULL) {
- return -1;
- }
- while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x "
- "%4s%4s%4s%4s%4s%4s%4s%4s %02x "
- "%4s%4s%4s%4s%4s%4s%4s%4s "
- "%08x %08x %08x %08lx %8s",
- dest_str, &dest_str[5], &dest_str[10], &dest_str[15],
- &dest_str[20], &dest_str[25], &dest_str[30], &dest_str[35],
- &dest_plen,
- srcp[0], srcp[1], srcp[2], srcp[3],
- srcp[4], srcp[5], srcp[6], srcp[7],
- &src_plen,
- hopp[0], hopp[1], hopp[2], hopp[3],
- hopp[4], hopp[5], hopp[6], hopp[7],
- &metric, &use, &refcnt, &flags, device) == 31) {
-
- /*
- * Some routes should be ignored
- */
- if ( (dest_plen < 0 || dest_plen > 128) ||
- (src_plen != 0) ||
- (flags & (RTF_POLICY | RTF_FLOW)) ||
- ((flags & RTF_REJECT) && dest_plen == 0) ) {
- continue;
- }
-
- /*
- * Convert the destination address
- */
- dest_str[4] = ':';
- dest_str[9] = ':';
- dest_str[14] = ':';
- dest_str[19] = ':';
- dest_str[24] = ':';
- dest_str[29] = ':';
- dest_str[34] = ':';
- dest_str[39] = '\0';
-
- if (inet_pton(AF_INET6, dest_str, &dest_addr) < 0) {
- /* not an Ipv6 address */
- continue;
- } else {
- /*
- * The prefix len (dest_plen) indicates the number of bits we
- * need to match on.
- *
- * dest_plen / 8 => number of bytes to match
- * dest_plen % 8 => number of additional bits to match
- *
- * eg: fe80::/10 => match 1 byte + 2 additional bits in the
- * next byte.
- */
- int byte_count = dest_plen >> 3;
- int extra_bits = dest_plen & 0x3;
-
- if (byte_count > 0) {
- if (memcmp(target_addr, &dest_addr, byte_count)) {
- continue; /* no match */
- }
- }
-
- if (extra_bits > 0) {
- unsigned char c1 = ((unsigned char *)target_addr)[byte_count];
- unsigned char c2 = ((unsigned char *)&dest_addr)[byte_count];
- unsigned char mask = 0xff << (8 - extra_bits);
- if ((c1 & mask) != (c2 & mask)) {
- continue;
- }
- }
-
- /*
- * We have a match
- */
- match = JNI_TRUE;
- break;
- }
- }
- fclose(f);
-
- /*
- * If there's a match then we lookup the interface
- * index.
- */
- if (match) {
- char devname[21];
- char addr6p[8][5];
- int plen, scope, dad_status, if_idx;
-
- if ((f = fopen("/proc/net/if_inet6", "r")) != NULL) {
- while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n",
- addr6p[0], addr6p[1], addr6p[2], addr6p[3],
- addr6p[4], addr6p[5], addr6p[6], addr6p[7],
- &if_idx, &plen, &scope, &dad_status, devname) == 13) {
-
- if (strcmp(devname, device) == 0) {
- /*
- * Found - so just return the index
- */
- fclose(f);
- return if_idx;
- }
- }
- fclose(f);
- } else {
- /*
- * Couldn't open /proc/net/if_inet6
- */
- return -1;
- }
- }
-
- /*
- * If we get here it means we didn't there wasn't any
- * route or we couldn't get the index of the interface.
- */
- return 0;
-}
-#endif
-
-
-/*
* Wrapper for getsockopt system routine - does any necessary
* pre/post processing to deal with OS specific oddities :-
*