src/java.base/unix/native/libnet/net_util_md.c
changeset 55375 96c7427456f9
parent 54627 22323f20401b
child 59243 fb1d9bf1be2b
equal deleted inserted replaced
55374:5c4f1b7c753b 55375:96c7427456f9
   450         }
   450         }
   451         free(buf);
   451         free(buf);
   452     }
   452     }
   453 }
   453 }
   454 
   454 
   455 #if defined(__linux__)
   455 #if defined(_AIX)
   456 
       
   457 /* following code creates a list of addresses from the kernel
       
   458  * routing table that are routed via the loopback address.
       
   459  * We check all destination addresses against this table
       
   460  * and override the scope_id field to use the relevant value for "lo"
       
   461  * in order to work-around the Linux bug that prevents packets destined
       
   462  * for certain local addresses from being sent via a physical interface.
       
   463  */
       
   464 
       
   465 struct loopback_route {
       
   466     struct in6_addr addr; /* destination address */
       
   467     int plen; /* prefix length */
       
   468 };
       
   469 
       
   470 static struct loopback_route *loRoutes = 0;
       
   471 static int nRoutes = 0; /* number of routes */
       
   472 static int loRoutes_size = 16; /* initial size */
       
   473 static int lo_scope_id = 0;
       
   474 
       
   475 static void initLoopbackRoutes();
       
   476 
       
   477 void printAddr (struct in6_addr *addr) {
       
   478     int i;
       
   479     for (i=0; i<16; i++) {
       
   480         printf ("%02x", addr->s6_addr[i]);
       
   481     }
       
   482     printf ("\n");
       
   483 }
       
   484 
       
   485 static jboolean needsLoopbackRoute (struct in6_addr* dest_addr) {
       
   486     int byte_count;
       
   487     int extra_bits, i;
       
   488     struct loopback_route *ptr;
       
   489 
       
   490     if (loRoutes == 0) {
       
   491         initLoopbackRoutes();
       
   492     }
       
   493 
       
   494     for (ptr = loRoutes, i=0; i<nRoutes; i++, ptr++) {
       
   495         struct in6_addr *target_addr=&ptr->addr;
       
   496         int dest_plen = ptr->plen;
       
   497         byte_count = dest_plen >> 3;
       
   498         extra_bits = dest_plen & 0x3;
       
   499 
       
   500         if (byte_count > 0) {
       
   501             if (memcmp(target_addr, dest_addr, byte_count)) {
       
   502                 continue;  /* no match */
       
   503             }
       
   504         }
       
   505 
       
   506         if (extra_bits > 0) {
       
   507             unsigned char c1 = ((unsigned char *)target_addr)[byte_count];
       
   508             unsigned char c2 = ((unsigned char *)&dest_addr)[byte_count];
       
   509             unsigned char mask = 0xff << (8 - extra_bits);
       
   510             if ((c1 & mask) != (c2 & mask)) {
       
   511                 continue;
       
   512             }
       
   513         }
       
   514         return JNI_TRUE;
       
   515     }
       
   516     return JNI_FALSE;
       
   517 }
       
   518 
       
   519 
       
   520 static void initLoopbackRoutes() {
       
   521     FILE *f;
       
   522     char srcp[8][5];
       
   523     char hopp[8][5];
       
   524     int dest_plen, src_plen, use, refcnt, metric;
       
   525     unsigned long flags;
       
   526     char dest_str[40];
       
   527     struct in6_addr dest_addr;
       
   528     char device[16];
       
   529     struct loopback_route *loRoutesTemp;
       
   530 
       
   531     if (loRoutes != 0) {
       
   532         free (loRoutes);
       
   533     }
       
   534     loRoutes = calloc (loRoutes_size, sizeof(struct loopback_route));
       
   535     if (loRoutes == 0) {
       
   536         return;
       
   537     }
       
   538     /*
       
   539      * Scan /proc/net/ipv6_route looking for a matching
       
   540      * route.
       
   541      */
       
   542     if ((f = fopen("/proc/net/ipv6_route", "r")) == NULL) {
       
   543         return ;
       
   544     }
       
   545     while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x "
       
   546                      "%4s%4s%4s%4s%4s%4s%4s%4s %02x "
       
   547                      "%4s%4s%4s%4s%4s%4s%4s%4s "
       
   548                      "%08x %08x %08x %08lx %8s",
       
   549                      dest_str, &dest_str[5], &dest_str[10], &dest_str[15],
       
   550                      &dest_str[20], &dest_str[25], &dest_str[30], &dest_str[35],
       
   551                      &dest_plen,
       
   552                      srcp[0], srcp[1], srcp[2], srcp[3],
       
   553                      srcp[4], srcp[5], srcp[6], srcp[7],
       
   554                      &src_plen,
       
   555                      hopp[0], hopp[1], hopp[2], hopp[3],
       
   556                      hopp[4], hopp[5], hopp[6], hopp[7],
       
   557                      &metric, &use, &refcnt, &flags, device) == 31) {
       
   558 
       
   559         /*
       
   560          * Some routes should be ignored
       
   561          */
       
   562         if ( (dest_plen < 0 || dest_plen > 128)  ||
       
   563              (src_plen != 0) ||
       
   564              (flags & (RTF_POLICY | RTF_FLOW)) ||
       
   565              ((flags & RTF_REJECT) && dest_plen == 0) ) {
       
   566             continue;
       
   567         }
       
   568 
       
   569         /*
       
   570          * Convert the destination address
       
   571          */
       
   572         dest_str[4] = ':';
       
   573         dest_str[9] = ':';
       
   574         dest_str[14] = ':';
       
   575         dest_str[19] = ':';
       
   576         dest_str[24] = ':';
       
   577         dest_str[29] = ':';
       
   578         dest_str[34] = ':';
       
   579         dest_str[39] = '\0';
       
   580 
       
   581         if (inet_pton(AF_INET6, dest_str, &dest_addr) < 0) {
       
   582             /* not an Ipv6 address */
       
   583             continue;
       
   584         }
       
   585         if (strcmp(device, "lo") != 0) {
       
   586             /* Not a loopback route */
       
   587             continue;
       
   588         } else {
       
   589             if (nRoutes == loRoutes_size) {
       
   590                 loRoutesTemp = realloc (loRoutes, loRoutes_size *
       
   591                                         sizeof (struct loopback_route) * 2);
       
   592 
       
   593                 if (loRoutesTemp == 0) {
       
   594                     free(loRoutes);
       
   595                     loRoutes = NULL;
       
   596                     nRoutes = 0;
       
   597                     fclose (f);
       
   598                     return;
       
   599                 }
       
   600                 loRoutes=loRoutesTemp;
       
   601                 loRoutes_size *= 2;
       
   602             }
       
   603             memcpy (&loRoutes[nRoutes].addr,&dest_addr,sizeof(struct in6_addr));
       
   604             loRoutes[nRoutes].plen = dest_plen;
       
   605             nRoutes ++;
       
   606         }
       
   607     }
       
   608 
       
   609     fclose (f);
       
   610     {
       
   611         /* now find the scope_id for "lo" */
       
   612 
       
   613         char devname[21];
       
   614         char addr6p[8][5];
       
   615         int plen, scope, dad_status, if_idx;
       
   616 
       
   617         if ((f = fopen("/proc/net/if_inet6", "r")) != NULL) {
       
   618             while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n",
       
   619                       addr6p[0], addr6p[1], addr6p[2], addr6p[3],
       
   620                       addr6p[4], addr6p[5], addr6p[6], addr6p[7],
       
   621                   &if_idx, &plen, &scope, &dad_status, devname) == 13) {
       
   622 
       
   623                 if (strcmp(devname, "lo") == 0) {
       
   624                     /*
       
   625                      * Found - so just return the index
       
   626                      */
       
   627                     fclose(f);
       
   628                     lo_scope_id = if_idx;
       
   629                     return;
       
   630                 }
       
   631             }
       
   632             fclose(f);
       
   633         }
       
   634     }
       
   635 }
       
   636 
       
   637 /*
       
   638  * Following is used for binding to local addresses. Equivalent
       
   639  * to code above, for bind().
       
   640  */
       
   641 
       
   642 struct localinterface {
       
   643     int index;
       
   644     char localaddr [16];
       
   645 };
       
   646 
       
   647 static struct localinterface *localifs = 0;
       
   648 static int localifsSize = 0;    /* size of array */
       
   649 static int nifs = 0;            /* number of entries used in array */
       
   650 
       
   651 /* not thread safe: make sure called once from one thread */
       
   652 
       
   653 static void initLocalIfs () {
       
   654     FILE *f;
       
   655     unsigned char staddr [16];
       
   656     char ifname [33];
       
   657     struct localinterface *lif=0;
       
   658     struct localinterface *localifsTemp;
       
   659     int index, x1, x2, x3;
       
   660     unsigned int u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,ua,ub,uc,ud,ue,uf;
       
   661 
       
   662     if ((f = fopen("/proc/net/if_inet6", "r")) == NULL) {
       
   663         return ;
       
   664     }
       
   665     while (fscanf (f, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x "
       
   666                 "%d %x %x %x %32s",&u0,&u1,&u2,&u3,&u4,&u5,&u6,&u7,
       
   667                 &u8,&u9,&ua,&ub,&uc,&ud,&ue,&uf,
       
   668                 &index, &x1, &x2, &x3, ifname) == 21) {
       
   669         staddr[0] = (unsigned char)u0;
       
   670         staddr[1] = (unsigned char)u1;
       
   671         staddr[2] = (unsigned char)u2;
       
   672         staddr[3] = (unsigned char)u3;
       
   673         staddr[4] = (unsigned char)u4;
       
   674         staddr[5] = (unsigned char)u5;
       
   675         staddr[6] = (unsigned char)u6;
       
   676         staddr[7] = (unsigned char)u7;
       
   677         staddr[8] = (unsigned char)u8;
       
   678         staddr[9] = (unsigned char)u9;
       
   679         staddr[10] = (unsigned char)ua;
       
   680         staddr[11] = (unsigned char)ub;
       
   681         staddr[12] = (unsigned char)uc;
       
   682         staddr[13] = (unsigned char)ud;
       
   683         staddr[14] = (unsigned char)ue;
       
   684         staddr[15] = (unsigned char)uf;
       
   685         nifs ++;
       
   686         if (nifs > localifsSize) {
       
   687             localifsTemp = (struct localinterface *) realloc(
       
   688                         localifs, sizeof (struct localinterface)* (localifsSize+5));
       
   689             if (localifsTemp == 0) {
       
   690                 free(localifs);
       
   691                 localifs = 0;
       
   692                 localifsSize = 0;
       
   693                 nifs = 0;
       
   694                 fclose(f);
       
   695                 return;
       
   696             }
       
   697             localifs = localifsTemp;
       
   698             lif = localifs + localifsSize;
       
   699             localifsSize += 5;
       
   700         } else {
       
   701             lif ++;
       
   702         }
       
   703         memcpy (lif->localaddr, staddr, 16);
       
   704         lif->index = index;
       
   705     }
       
   706     fclose (f);
       
   707 }
       
   708 
       
   709 /* return the scope_id (interface index) of the
       
   710  * interface corresponding to the given address
       
   711  * returns 0 if no match found
       
   712  */
       
   713 
       
   714 static int getLocalScopeID (char *addr) {
       
   715     struct localinterface *lif;
       
   716     int i;
       
   717     if (localifs == 0) {
       
   718         initLocalIfs();
       
   719     }
       
   720     for (i=0, lif=localifs; i<nifs; i++, lif++) {
       
   721         if (memcmp (addr, lif->localaddr, 16) == 0) {
       
   722             return lif->index;
       
   723         }
       
   724     }
       
   725     return 0;
       
   726 }
       
   727 
       
   728 void platformInit () {
       
   729     initLoopbackRoutes();
       
   730     initLocalIfs();
       
   731 }
       
   732 
       
   733 #elif defined(_AIX)
       
   734 
   456 
   735 /* Initialize stubs for blocking I/O workarounds (see src/solaris/native/java/net/linux_close.c) */
   457 /* Initialize stubs for blocking I/O workarounds (see src/solaris/native/java/net/linux_close.c) */
   736 extern void aix_close_init();
   458 extern void aix_close_init();
   737 
   459 
   738 void platformInit () {
   460 void platformInit () {
   814         sa->sa6.sin6_family = AF_INET6;
   536         sa->sa6.sin6_family = AF_INET6;
   815         if (len != NULL) {
   537         if (len != NULL) {
   816             *len = sizeof(struct sockaddr_in6);
   538             *len = sizeof(struct sockaddr_in6);
   817         }
   539         }
   818 
   540 
   819 #ifdef __linux__
       
   820         /*
       
   821          * On Linux if we are connecting to a link-local address
       
   822          * we need to specify the interface in the scope_id (2.4 kernel only)
       
   823          *
       
   824          * If the scope was cached then we use the cached value. If not cached but
       
   825          * specified in the Inet6Address we use that, but we first check if the
       
   826          * address needs to be routed via the loopback interface. In this case,
       
   827          * we override the specified value with that of the loopback interface.
       
   828          * If no cached value exists and no value was specified by user, then
       
   829          * we try to determine a value from the routing table. In all these
       
   830          * cases the used value is cached for further use.
       
   831          */
       
   832         if (IN6_IS_ADDR_LINKLOCAL(&sa->sa6.sin6_addr)) {
       
   833             unsigned int cached_scope_id = 0, scope_id = 0;
       
   834 
       
   835             if (ia6_cachedscopeidID) {
       
   836                 cached_scope_id = (int)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID);
       
   837                 /* if cached value exists then use it. Otherwise, check
       
   838                  * if scope is set in the address.
       
   839                  */
       
   840                 if (!cached_scope_id) {
       
   841                     if (ia6_scopeidID) {
       
   842                         scope_id = getInet6Address_scopeid(env, iaObj);
       
   843                     }
       
   844                     if (scope_id != 0) {
       
   845                         /* check user-specified value for loopback case
       
   846                          * that needs to be overridden
       
   847                          */
       
   848                         if (kernelIsV24() && needsLoopbackRoute(&sa->sa6.sin6_addr)) {
       
   849                             cached_scope_id = lo_scope_id;
       
   850                             (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id);
       
   851                         }
       
   852                     } else {
       
   853                         /*
       
   854                          * Otherwise consult the IPv6 routing tables to
       
   855                          * try determine the appropriate interface.
       
   856                          */
       
   857                         if (kernelIsV24()) {
       
   858                             cached_scope_id = getDefaultIPv6Interface(&sa->sa6.sin6_addr);
       
   859                         } else {
       
   860                             cached_scope_id = getLocalScopeID((char *)&(sa->sa6.sin6_addr));
       
   861                             if (cached_scope_id == 0) {
       
   862                                 cached_scope_id = getDefaultIPv6Interface(&sa->sa6.sin6_addr);
       
   863                             }
       
   864                         }
       
   865                         (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id);
       
   866                     }
       
   867                 }
       
   868             }
       
   869 
       
   870             /*
       
   871              * If we have a scope_id use the extended form
       
   872              * of sockaddr_in6.
       
   873              */
       
   874             sa->sa6.sin6_scope_id = cached_scope_id == 0 ? scope_id : cached_scope_id;
       
   875         }
       
   876 #else
       
   877         /* handle scope_id */
   541         /* handle scope_id */
   878         if (family != java_net_InetAddress_IPv4) {
   542         if (family != java_net_InetAddress_IPv4) {
   879             if (ia6_scopeidID) {
   543             if (ia6_scopeidID) {
   880                 sa->sa6.sin6_scope_id = getInet6Address_scopeid(env, iaObj);
   544                 sa->sa6.sin6_scope_id = getInet6Address_scopeid(env, iaObj);
   881             }
   545             }
   882         }
   546         }
   883 #endif
       
   884     } else {
   547     } else {
   885         jint address;
   548         jint address;
   886         if (family != java_net_InetAddress_IPv4) {
   549         if (family != java_net_InetAddress_IPv4) {
   887             JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Protocol family unavailable");
   550             JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Protocol family unavailable");
   888             return -1;
   551             return -1;
  1013     /* not found */
   676     /* not found */
  1014     return -1;
   677     return -1;
  1015 }
   678 }
  1016 
   679 
  1017 /*
   680 /*
  1018  * Determine the default interface for an IPv6 address.
       
  1019  *
       
  1020  * 1. Scans /proc/net/ipv6_route for a matching route
       
  1021  *    (eg: fe80::/10 or a route for the specific address).
       
  1022  *    This will tell us the interface to use (eg: "eth0").
       
  1023  *
       
  1024  * 2. Lookup /proc/net/if_inet6 to map the interface
       
  1025  *    name to an interface index.
       
  1026  *
       
  1027  * Returns :-
       
  1028  *      -1 if error
       
  1029  *       0 if no matching interface
       
  1030  *      >1 interface index to use for the link-local address.
       
  1031  */
       
  1032 #if defined(__linux__)
       
  1033 int getDefaultIPv6Interface(struct in6_addr *target_addr) {
       
  1034     FILE *f;
       
  1035     char srcp[8][5];
       
  1036     char hopp[8][5];
       
  1037     int dest_plen, src_plen, use, refcnt, metric;
       
  1038     unsigned long flags;
       
  1039     char dest_str[40];
       
  1040     struct in6_addr dest_addr;
       
  1041     char device[16];
       
  1042     jboolean match = JNI_FALSE;
       
  1043 
       
  1044     /*
       
  1045      * Scan /proc/net/ipv6_route looking for a matching
       
  1046      * route.
       
  1047      */
       
  1048     if ((f = fopen("/proc/net/ipv6_route", "r")) == NULL) {
       
  1049         return -1;
       
  1050     }
       
  1051     while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x "
       
  1052                      "%4s%4s%4s%4s%4s%4s%4s%4s %02x "
       
  1053                      "%4s%4s%4s%4s%4s%4s%4s%4s "
       
  1054                      "%08x %08x %08x %08lx %8s",
       
  1055                      dest_str, &dest_str[5], &dest_str[10], &dest_str[15],
       
  1056                      &dest_str[20], &dest_str[25], &dest_str[30], &dest_str[35],
       
  1057                      &dest_plen,
       
  1058                      srcp[0], srcp[1], srcp[2], srcp[3],
       
  1059                      srcp[4], srcp[5], srcp[6], srcp[7],
       
  1060                      &src_plen,
       
  1061                      hopp[0], hopp[1], hopp[2], hopp[3],
       
  1062                      hopp[4], hopp[5], hopp[6], hopp[7],
       
  1063                      &metric, &use, &refcnt, &flags, device) == 31) {
       
  1064 
       
  1065         /*
       
  1066          * Some routes should be ignored
       
  1067          */
       
  1068         if ( (dest_plen < 0 || dest_plen > 128)  ||
       
  1069              (src_plen != 0) ||
       
  1070              (flags & (RTF_POLICY | RTF_FLOW)) ||
       
  1071              ((flags & RTF_REJECT) && dest_plen == 0) ) {
       
  1072             continue;
       
  1073         }
       
  1074 
       
  1075         /*
       
  1076          * Convert the destination address
       
  1077          */
       
  1078         dest_str[4] = ':';
       
  1079         dest_str[9] = ':';
       
  1080         dest_str[14] = ':';
       
  1081         dest_str[19] = ':';
       
  1082         dest_str[24] = ':';
       
  1083         dest_str[29] = ':';
       
  1084         dest_str[34] = ':';
       
  1085         dest_str[39] = '\0';
       
  1086 
       
  1087         if (inet_pton(AF_INET6, dest_str, &dest_addr) < 0) {
       
  1088             /* not an Ipv6 address */
       
  1089             continue;
       
  1090         } else {
       
  1091             /*
       
  1092              * The prefix len (dest_plen) indicates the number of bits we
       
  1093              * need to match on.
       
  1094              *
       
  1095              * dest_plen / 8    => number of bytes to match
       
  1096              * dest_plen % 8    => number of additional bits to match
       
  1097              *
       
  1098              * eg: fe80::/10 => match 1 byte + 2 additional bits in the
       
  1099              *                  next byte.
       
  1100              */
       
  1101             int byte_count = dest_plen >> 3;
       
  1102             int extra_bits = dest_plen & 0x3;
       
  1103 
       
  1104             if (byte_count > 0) {
       
  1105                 if (memcmp(target_addr, &dest_addr, byte_count)) {
       
  1106                     continue;  /* no match */
       
  1107                 }
       
  1108             }
       
  1109 
       
  1110             if (extra_bits > 0) {
       
  1111                 unsigned char c1 = ((unsigned char *)target_addr)[byte_count];
       
  1112                 unsigned char c2 = ((unsigned char *)&dest_addr)[byte_count];
       
  1113                 unsigned char mask = 0xff << (8 - extra_bits);
       
  1114                 if ((c1 & mask) != (c2 & mask)) {
       
  1115                     continue;
       
  1116                 }
       
  1117             }
       
  1118 
       
  1119             /*
       
  1120              * We have a match
       
  1121              */
       
  1122             match = JNI_TRUE;
       
  1123             break;
       
  1124         }
       
  1125     }
       
  1126     fclose(f);
       
  1127 
       
  1128     /*
       
  1129      * If there's a match then we lookup the interface
       
  1130      * index.
       
  1131      */
       
  1132     if (match) {
       
  1133         char devname[21];
       
  1134         char addr6p[8][5];
       
  1135         int plen, scope, dad_status, if_idx;
       
  1136 
       
  1137         if ((f = fopen("/proc/net/if_inet6", "r")) != NULL) {
       
  1138             while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n",
       
  1139                       addr6p[0], addr6p[1], addr6p[2], addr6p[3],
       
  1140                       addr6p[4], addr6p[5], addr6p[6], addr6p[7],
       
  1141                   &if_idx, &plen, &scope, &dad_status, devname) == 13) {
       
  1142 
       
  1143                 if (strcmp(devname, device) == 0) {
       
  1144                     /*
       
  1145                      * Found - so just return the index
       
  1146                      */
       
  1147                     fclose(f);
       
  1148                     return if_idx;
       
  1149                 }
       
  1150             }
       
  1151             fclose(f);
       
  1152         } else {
       
  1153             /*
       
  1154              * Couldn't open /proc/net/if_inet6
       
  1155              */
       
  1156             return -1;
       
  1157         }
       
  1158     }
       
  1159 
       
  1160     /*
       
  1161      * If we get here it means we didn't there wasn't any
       
  1162      * route or we couldn't get the index of the interface.
       
  1163      */
       
  1164     return 0;
       
  1165 }
       
  1166 #endif
       
  1167 
       
  1168 
       
  1169 /*
       
  1170  * Wrapper for getsockopt system routine - does any necessary
   681  * Wrapper for getsockopt system routine - does any necessary
  1171  * pre/post processing to deal with OS specific oddities :-
   682  * pre/post processing to deal with OS specific oddities :-
  1172  *
   683  *
  1173  * On Linux the SO_SNDBUF/SO_RCVBUF values must be post-processed
   684  * On Linux the SO_SNDBUF/SO_RCVBUF values must be post-processed
  1174  * to compensate for an incorrect value returned by the kernel.
   685  * to compensate for an incorrect value returned by the kernel.