Print this page


Split Close
Expand all
Collapse all
          --- old/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c
          +++ new/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c
↓ open down ↓ 57 lines elided ↑ open up ↑
  58   58  static jfieldID pdsi_trafficClassID;
  59   59  jfieldID pdsi_fdID;
  60   60  jfieldID pdsi_fd1ID;
  61   61  jfieldID pdsi_fduseID;
  62   62  jfieldID pdsi_lastfdID;
  63   63  jfieldID pdsi_timeoutID;
  64   64  
  65   65  jfieldID pdsi_localPortID;
  66   66  jfieldID pdsi_connected;
  67   67  
  68      -static jclass ia4_clazz;
  69      -static jmethodID ia4_ctor;
  70      -
  71   68  static CRITICAL_SECTION sizeCheckLock;
  72   69  
  73   70  /* Windows OS version is XP or better */
  74   71  static int xp_or_later = 0;
  75   72  /* Windows OS version is Windows 2000 or better */
  76   73  static int w2k_or_later = 0;
  77   74  
  78   75  /*
  79   76   * Notes about UDP/IPV6 on Windows (XP and 2003 server):
  80   77   *
  81   78   * fd always points to the IPv4 fd, and fd1 points to the IPv6 fd.
  82   79   * Both fds are used when we bind to a wild-card address. When a specific
  83   80   * address is used, only one of them is used.
  84   81   */
  85   82  
  86      -/*
  87      - * Returns a java.lang.Integer based on 'i'
  88      - */
  89      -jobject createInteger(JNIEnv *env, int i) {
  90      -    static jclass i_class;
  91      -    static jmethodID i_ctrID;
  92      -    static jfieldID i_valueID;
       83 +static jclass i_class;
       84 +static jmethodID i_ctrID;
       85 +static jfieldID i_valueID;
  93   86  
       87 +int initIntegerIDs(JNIEnv* env) {
  94   88      if (i_class == NULL) {
  95   89          jclass c = (*env)->FindClass(env, "java/lang/Integer");
  96   90          CHECK_NULL_RETURN(c, NULL);
  97   91          i_ctrID = (*env)->GetMethodID(env, c, "<init>", "(I)V");
  98   92          CHECK_NULL_RETURN(i_ctrID, NULL);
       93 +        i_valueID = (*env)->GetFieldID(env, c, "value", "I");
       94 +        CHECK_NULL_RETURN(i_valueID, NULL);
  99   95          i_class = (*env)->NewGlobalRef(env, c);
 100   96          CHECK_NULL_RETURN(i_class, NULL);
 101   97      }
       98 +    return 1;
       99 +}
 102  100  
      101 +/* Returns a java.lang.Integer based on 'i' */
      102 +static jobject createInteger(JNIEnv *env, int i) {
      103 +    CHECK_NULL_RETURN(initIntegerIDs(env), NULL);
 103  104      return ( (*env)->NewObject(env, i_class, i_ctrID, i) );
 104  105  }
 105  106  
 106      -/*
 107      - * Returns a java.lang.Boolean based on 'b'
 108      - */
 109      -jobject createBoolean(JNIEnv *env, int b) {
 110      -    static jclass b_class;
 111      -    static jmethodID b_ctrID;
 112      -    static jfieldID b_valueID;
      107 +/* Returns a jint based on the given java.lang.Integer */
      108 +static jint retrieveInteger(JNIEnv *env, jobject i) {
      109 +    CHECK_NULL_RETURN(initIntegerIDs(env), NULL);
      110 +    return (*env)->GetIntField(env, i, i_valueID);
      111 +}
 113  112  
      113 +static jclass b_class;
      114 +static jmethodID b_ctrID;
      115 +static jfieldID b_valueID;
      116 +
      117 +int initBooleanIDs(JNIEnv* env) {
 114  118      if (b_class == NULL) {
 115  119          jclass c = (*env)->FindClass(env, "java/lang/Boolean");
 116  120          CHECK_NULL_RETURN(c, NULL);
 117  121          b_ctrID = (*env)->GetMethodID(env, c, "<init>", "(Z)V");
 118  122          CHECK_NULL_RETURN(b_ctrID, NULL);
      123 +        b_valueID = (*env)->GetFieldID(env, c, "value", "Z");
      124 +        CHECK_NULL_RETURN(b_valueID, NULL);
 119  125          b_class = (*env)->NewGlobalRef(env, c);
 120  126          CHECK_NULL_RETURN(b_class, NULL);
 121  127      }
      128 +    return 1;
      129 +}
 122  130  
      131 +/* Returns a java.lang.Boolean based on 'b' */
      132 +static jobject createBoolean(JNIEnv *env, int b) {
      133 +    CHECK_NULL_RETURN(initBooleanIDs(env), NULL);
 123  134      return( (*env)->NewObject(env, b_class, b_ctrID, (jboolean)(b!=0)) );
 124  135  }
 125  136  
      137 +/* Returns a jboolean based on the given java.lang.Boolean */
      138 +static jboolean retrieveBoolean(JNIEnv *env, jobject b) {
      139 +    CHECK_NULL_RETURN(initBooleanIDs(env), NULL);
      140 +    return (*env)->GetBooleanField(env, b, b_valueID);
      141 +}
 126  142  
 127  143  static int getFD(JNIEnv *env, jobject this) {
 128  144      jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
 129  145  
 130  146      if (fdObj == NULL) {
 131  147          return -1;
 132  148      }
 133  149      return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
 134  150  }
 135  151  
↓ open down ↓ 265 lines elided ↑ open up ↑
 401  417      pdsi_localPortID = (*env)->GetFieldID(env, cls, "localPort", "I");
 402  418      CHECK_NULL(pdsi_localPortID);
 403  419      pdsi_connected = (*env)->GetFieldID(env, cls, "connected", "Z");
 404  420      CHECK_NULL(pdsi_connected);
 405  421  
 406  422      cls = (*env)->FindClass(env, "java/io/FileDescriptor");
 407  423      CHECK_NULL(cls);
 408  424      IO_fd_fdID = NET_GetFileDescriptorID(env);
 409  425      CHECK_NULL(IO_fd_fdID);
 410  426  
 411      -    ia4_clazz = (*env)->FindClass(env, "java/net/Inet4Address");
 412      -    CHECK_NULL(ia4_clazz);
 413      -    ia4_clazz = (*env)->NewGlobalRef(env, ia4_clazz);
 414      -    CHECK_NULL(ia4_clazz);
 415      -    ia4_ctor = (*env)->GetMethodID(env, ia4_clazz, "<init>", "()V");
 416      -    CHECK_NULL(ia4_ctor);
      427 +    // Load static data (jclass, methodIDs, fieldID ) from InetAddress,
      428 +    // Inet4Address, Inet6Address and NetorkInterface.
      429 +    init(env);
      430 +    (*env)->FindClass(env, "java/net/NetworkInterface");
 417  431  
 418      -
 419      -    InitializeCriticalSection(&sizeCheckLock);
      432 +   InitializeCriticalSection(&sizeCheckLock);
 420  433  }
 421  434  
 422  435  JNIEXPORT void JNICALL
 423  436  Java_java_net_TwoStacksPlainDatagramSocketImpl_bind0(JNIEnv *env, jobject this,
 424  437                                             jint port, jobject addressObj) {
 425  438      jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
 426  439      jobject fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
 427  440  
 428  441      int fd, fd1, family;
 429  442      int ipv6_supported = ipv6_available();
↓ open down ↓ 30 lines elided ↑ open up ↑
 460  473      }
 461  474  
 462  475      if (ipv6_supported) {
 463  476          struct ipv6bind v6bind;
 464  477          v6bind.addr = &lcladdr;
 465  478          v6bind.ipv4_fd = fd;
 466  479          v6bind.ipv6_fd = fd1;
 467  480          if (NET_BindV6(&v6bind) != -1) {
 468  481              /* check if the fds have changed */
 469  482              if (v6bind.ipv4_fd != fd) {
 470      -                fd = v6bind.ipv4_fd;
      483 +                fd = (int)v6bind.ipv4_fd;
 471  484                  if (fd == -1) {
 472  485                      /* socket is closed. */
 473  486                      (*env)->SetObjectField(env, this, pdsi_fdID, NULL);
 474  487                  } else {
 475  488                      /* socket was re-created */
 476  489                      (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
 477  490                  }
 478  491              }
 479  492              if (v6bind.ipv6_fd != fd1) {
 480      -                fd1 = v6bind.ipv6_fd;
      493 +                fd1 = (int)v6bind.ipv6_fd;
 481  494                  if (fd1 == -1) {
 482  495                      /* socket is closed. */
 483  496                      (*env)->SetObjectField(env, this, pdsi_fd1ID, NULL);
 484  497                  } else {
 485  498                      /* socket was re-created */
 486  499                      (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, fd1);
 487  500                  }
 488  501              }
 489  502          } else {
 490  503              NET_ThrowCurrent (env, "Cannot bind");
↓ open down ↓ 1012 lines elided ↑ open up ↑
1503 1516  
1504 1517      if (ipv6_supported) {
1505 1518          /* SIO_UDP_CONNRESET fixes a bug introduced in Windows 2000, which
1506 1519           * returns connection reset errors un connected UDP sockets (as well
1507 1520           * as connected sockets. The solution is to only enable this feature
1508 1521           * when the socket is connected
1509 1522           */
1510 1523          t = FALSE;
1511 1524          WSAIoctl(fd,SIO_UDP_CONNRESET,&t,sizeof(t),&x1,sizeof(x1),&x2,0,0);
1512 1525          t = TRUE;
1513      -        fd1 = socket (AF_INET6, SOCK_DGRAM, 0);
     1526 +        fd1 = (int)socket (AF_INET6, SOCK_DGRAM, 0);
1514 1527          if (fd1 == JVM_IO_ERR) {
1515 1528              NET_ThrowCurrent(env, "Socket creation failed");
1516 1529              return;
1517 1530          }
1518 1531          NET_SetSockOpt(fd1, SOL_SOCKET, SO_BROADCAST, (char*)&t, sizeof(BOOL));
1519 1532          t = FALSE;
1520 1533          WSAIoctl(fd1,SIO_UDP_CONNRESET,&t,sizeof(t),&x1,sizeof(x1),&x2,0,0);
1521 1534          (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, fd1);
1522 1535          SetHandleInformation((HANDLE)(UINT_PTR)fd1, HANDLE_FLAG_INHERIT, FALSE);
1523 1536      } else {
↓ open down ↓ 42 lines elided ↑ open up ↑
1566 1579  
1567 1580  /*
1568 1581   * check the addresses attached to the NetworkInterface object
1569 1582   * and return the first one (of the requested family Ipv4 or Ipv6)
1570 1583   * in *iaddr
1571 1584   */
1572 1585  
1573 1586  static int getInetAddrFromIf (JNIEnv *env, int family, jobject nif, jobject *iaddr)
1574 1587  {
1575 1588      jobjectArray addrArray;
1576      -    static jfieldID ni_addrsID=0;
1577      -    static jfieldID ia_familyID=0;
1578 1589      jsize len;
1579 1590      jobject addr;
1580 1591      int i;
1581 1592  
1582      -    if (ni_addrsID == NULL) {
1583      -        jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
1584      -        CHECK_NULL_RETURN (c, -1);
1585      -        ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
1586      -                                        "[Ljava/net/InetAddress;");
1587      -        CHECK_NULL_RETURN (ni_addrsID, -1);
1588      -        c = (*env)->FindClass(env,"java/net/InetAddress");
1589      -        CHECK_NULL_RETURN (c, -1);
1590      -        ia_familyID = (*env)->GetFieldID(env, c, "family", "I");
1591      -        CHECK_NULL_RETURN (ia_familyID, -1);
1592      -    }
1593      -
1594 1593      addrArray = (*env)->GetObjectField(env, nif, ni_addrsID);
1595 1594      len = (*env)->GetArrayLength(env, addrArray);
1596 1595  
1597 1596      /*
1598 1597       * Check that there is at least one address bound to this
1599 1598       * interface.
1600 1599       */
1601 1600      if (len < 1) {
1602 1601          JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1603 1602              "bad argument for IP_MULTICAST_IF2: No IP addresses bound to interface");
↓ open down ↓ 7 lines elided ↑ open up ↑
1611 1610              *iaddr = addr;
1612 1611              return 0;
1613 1612          }
1614 1613      }
1615 1614      return -1;
1616 1615  }
1617 1616  
1618 1617  static int getInet4AddrFromIf (JNIEnv *env, jobject nif, struct in_addr *iaddr)
1619 1618  {
1620 1619      jobject addr;
1621      -    static jfieldID ia_addressID;
1622 1620  
1623 1621      int ret = getInetAddrFromIf (env, IPv4, nif, &addr);
1624 1622      if (ret == -1) {
1625 1623          return -1;
1626 1624      }
1627 1625  
1628      -    if (ia_addressID == 0) {
1629      -        jclass c = (*env)->FindClass(env,"java/net/InetAddress");
1630      -        CHECK_NULL_RETURN (c, -1);
1631      -        ia_addressID = (*env)->GetFieldID(env, c, "address", "I");
1632      -        CHECK_NULL_RETURN (ia_addressID, -1);
1633      -    }
1634 1626      iaddr->s_addr = htonl((*env)->GetIntField(env, addr, ia_addressID));
1635 1627      return 0;
1636 1628  }
1637 1629  
1638 1630  /* Get the multicasting index from the interface */
1639 1631  
1640 1632  static int getIndexFromIf (JNIEnv *env, jobject nif) {
1641      -    static jfieldID ni_indexID;
1642      -
1643      -    if (ni_indexID == NULL) {
1644      -        jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
1645      -        CHECK_NULL_RETURN(c, -1);
1646      -        ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
1647      -        CHECK_NULL_RETURN(ni_indexID, -1);
1648      -    }
1649      -
1650 1633      return (*env)->GetIntField(env, nif, ni_indexID);
1651 1634  }
1652 1635  
1653 1636  /*
1654 1637   * Sets the multicast interface.
1655 1638   *
1656 1639   * SocketOptions.IP_MULTICAST_IF (argument is an InetAddress) :-
1657 1640   *      IPv4:   set outgoing multicast interface using
1658 1641   *              IPPROTO_IP/IP_MULTICAST_IF
1659 1642   *
↓ open down ↓ 20 lines elided ↑ open up ↑
1680 1663  
1681 1664      if (opt == java_net_SocketOptions_IP_MULTICAST_IF) {
1682 1665          /*
1683 1666           * value is an InetAddress.
1684 1667           * On IPv4 system use IP_MULTICAST_IF socket option
1685 1668           * On IPv6 system get the NetworkInterface that this IP
1686 1669           * address is bound to and use the IPV6_MULTICAST_IF
1687 1670           * option instead of IP_MULTICAST_IF
1688 1671           */
1689 1672          if (ipv6_supported) {
1690      -            static jclass ni_class;
1691      -            if (ni_class == NULL) {
1692      -                jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
1693      -                CHECK_NULL(c);
1694      -                ni_class = (*env)->NewGlobalRef(env, c);
1695      -                CHECK_NULL(ni_class);
1696      -            }
1697      -
1698 1673              value = Java_java_net_NetworkInterface_getByInetAddress0(env, ni_class, value);
1699 1674              if (value == NULL) {
1700 1675                  if (!(*env)->ExceptionOccurred(env)) {
1701 1676                      JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1702 1677                           "bad argument for IP_MULTICAST_IF"
1703 1678                           ": address not bound to any interface");
1704 1679                  }
1705 1680                  return;
1706 1681              }
1707 1682              opt = java_net_SocketOptions_IP_MULTICAST_IF2;
1708 1683          } else {
1709      -            static jfieldID ia_addressID;
1710 1684              struct in_addr in;
1711 1685  
1712      -            if (ia_addressID == NULL) {
1713      -                        jclass c = (*env)->FindClass(env,"java/net/InetAddress");
1714      -                CHECK_NULL(c);
1715      -                ia_addressID = (*env)->GetFieldID(env, c, "address", "I");
1716      -                CHECK_NULL(ia_addressID);
1717      -            }
1718      -
1719 1686              in.s_addr = htonl((*env)->GetIntField(env, value, ia_addressID));
1720 1687  
1721 1688              if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
1722 1689                                 (const char*)&in, sizeof(in)) < 0) {
1723 1690                  NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1724 1691                                   "Error setting socket option");
1725 1692              }
1726 1693              return;
1727 1694          }
1728 1695      }
1729 1696  
1730 1697      if (opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
1731 1698          /*
1732 1699           * value is a NetworkInterface.
1733 1700           * On IPv6 system get the index of the interface and use the
1734 1701           * IPV6_MULTICAST_IF socket option
1735 1702           * On IPv4 system extract addr[0] and use the IP_MULTICAST_IF
1736 1703           * option. For IPv6 both must be done.
1737 1704           */
1738 1705          if (ipv6_supported) {
1739      -            static jfieldID ni_indexID;
1740 1706              struct in_addr in;
1741 1707              int index;
1742 1708  
1743      -            if (ni_indexID == NULL) {
1744      -                jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
1745      -                CHECK_NULL(c);
1746      -                ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
1747      -                CHECK_NULL(ni_indexID);
1748      -            }
1749 1709              index = (*env)->GetIntField(env, value, ni_indexID);
1750 1710  
1751 1711              if (setsockopt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_IF,
1752 1712                                 (const char*)&index, sizeof(index)) < 0) {
1753 1713                  if (errno == EINVAL && index > 0) {
1754 1714                      JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1755 1715                          "IPV6_MULTICAST_IF failed (interface has IPv4 "
1756 1716                          "address only?)");
1757 1717                  } else {
1758 1718                      NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
↓ open down ↓ 85 lines elided ↑ open up ↑
1844 1804              JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Invalid option");
1845 1805              return;
1846 1806          }
1847 1807      }
1848 1808  
1849 1809      switch (opt) {
1850 1810          case java_net_SocketOptions_SO_SNDBUF :
1851 1811          case java_net_SocketOptions_SO_RCVBUF :
1852 1812          case java_net_SocketOptions_IP_TOS :
1853 1813              {
1854      -                jclass cls;
1855      -                jfieldID fid;
1856      -
1857      -                cls = (*env)->FindClass(env, "java/lang/Integer");
1858      -                CHECK_NULL(cls);
1859      -                fid =  (*env)->GetFieldID(env, cls, "value", "I");
1860      -                CHECK_NULL(fid);
1861      -
1862      -                optval.i = (*env)->GetIntField(env, value, fid);
     1814 +                optval.i = retrieveInteger(env, value);
1863 1815                  optlen = sizeof(optval.i);
1864 1816              }
1865 1817              break;
1866 1818  
1867 1819          case java_net_SocketOptions_SO_REUSEADDR:
1868 1820          case java_net_SocketOptions_SO_BROADCAST:
1869 1821          case java_net_SocketOptions_IP_MULTICAST_LOOP:
1870 1822              {
1871      -                jclass cls;
1872      -                jfieldID fid;
1873      -                jboolean on;
1874      -
1875      -                cls = (*env)->FindClass(env, "java/lang/Boolean");
1876      -                CHECK_NULL(cls);
1877      -                fid =  (*env)->GetFieldID(env, cls, "value", "Z");
1878      -                CHECK_NULL(fid);
1879      -
1880      -                on = (*env)->GetBooleanField(env, value, fid);
     1823 +                jboolean on = retrieveBoolean(env, value);
1881 1824                  optval.i = (on ? 1 : 0);
1882 1825                  /*
1883 1826                   * setLoopbackMode (true) disables IP_MULTICAST_LOOP rather
1884 1827                   * than enabling it.
1885 1828                   */
1886 1829                  if (opt == java_net_SocketOptions_IP_MULTICAST_LOOP) {
1887 1830                      optval.i = !optval.i;
1888 1831                  }
1889 1832                  optlen = sizeof(optval.i);
1890 1833              }
↓ open down ↓ 45 lines elided ↑ open up ↑
1936 1879   *              Query NetworkInterface by index and
1937 1880   *              return NetworkInterface.
1938 1881   */
1939 1882  jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, jint opt) {
1940 1883      jboolean isIPV4 = !ipv6_available() || fd1 == -1;
1941 1884  
1942 1885      /*
1943 1886       * IPv4 implementation
1944 1887       */
1945 1888      if (isIPV4) {
1946      -        static jclass inet4_class;
1947      -        static jmethodID inet4_ctrID;
1948      -        static jfieldID inet4_addrID;
1949      -
1950      -        static jclass ni_class;
1951      -        static jmethodID ni_ctrID;
1952      -        static jfieldID ni_indexID;
1953      -        static jfieldID ni_addrsID;
1954      -
1955 1889          jobjectArray addrArray;
1956 1890          jobject addr;
1957 1891          jobject ni;
1958 1892  
1959 1893          struct in_addr in;
1960 1894          struct in_addr *inP = &in;
1961 1895          int len = sizeof(struct in_addr);
1962 1896  
1963 1897          if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
1964 1898                             (char *)inP, &len) < 0) {
1965 1899              NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
1966 1900                               "Error getting socket option");
1967 1901              return NULL;
1968 1902          }
1969 1903  
1970 1904          /*
1971 1905           * Construct and populate an Inet4Address
1972 1906           */
1973      -        if (inet4_class == NULL) {
1974      -            jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
1975      -            CHECK_NULL_RETURN(c, NULL);
1976      -            inet4_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
1977      -            CHECK_NULL_RETURN(inet4_ctrID, NULL);
1978      -            inet4_addrID = (*env)->GetFieldID(env, c, "address", "I");
1979      -            CHECK_NULL_RETURN(inet4_addrID, NULL);
1980      -            inet4_class = (*env)->NewGlobalRef(env, c);
1981      -            CHECK_NULL_RETURN(inet4_class, NULL);
1982      -        }
1983      -        addr = (*env)->NewObject(env, inet4_class, inet4_ctrID, 0);
     1907 +        addr = (*env)->NewObject(env, ia4_class, ia4_ctrID, 0);
1984 1908          CHECK_NULL_RETURN(addr, NULL);
1985 1909  
1986      -        (*env)->SetIntField(env, addr, inet4_addrID, ntohl(in.s_addr));
     1910 +        (*env)->SetIntField(env, addr, ia_addressID, ntohl(in.s_addr));
1987 1911  
1988 1912          /*
1989 1913           * For IP_MULTICAST_IF return InetAddress
1990 1914           */
1991 1915          if (opt == java_net_SocketOptions_IP_MULTICAST_IF) {
1992 1916              return addr;
1993 1917          }
1994 1918  
1995 1919          /*
1996 1920           * For IP_MULTICAST_IF2 we get the NetworkInterface for
1997 1921           * this address and return it
1998 1922           */
1999      -        if (ni_class == NULL) {
2000      -            jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
2001      -            CHECK_NULL_RETURN(c, NULL);
2002      -            ni_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
2003      -            CHECK_NULL_RETURN(ni_ctrID, NULL);
2004      -            ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
2005      -            CHECK_NULL_RETURN(ni_indexID, NULL);
2006      -            ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
2007      -                                            "[Ljava/net/InetAddress;");
2008      -            CHECK_NULL_RETURN(ni_addrsID, NULL);
2009      -            ni_class = (*env)->NewGlobalRef(env, c);
2010      -            CHECK_NULL_RETURN(ni_class, NULL);
2011      -        }
2012 1923          ni = Java_java_net_NetworkInterface_getByInetAddress0(env, ni_class, addr);
2013 1924          if (ni) {
2014 1925              return ni;
2015 1926          }
2016 1927  
2017 1928          /*
2018 1929           * The address doesn't appear to be bound at any known
2019 1930           * NetworkInterface. Therefore we construct a NetworkInterface
2020 1931           * with this address.
2021 1932           */
2022 1933          ni = (*env)->NewObject(env, ni_class, ni_ctrID, 0);
2023 1934          CHECK_NULL_RETURN(ni, NULL);
2024 1935  
2025 1936          (*env)->SetIntField(env, ni, ni_indexID, -1);
2026      -        addrArray = (*env)->NewObjectArray(env, 1, inet4_class, NULL);
     1937 +        addrArray = (*env)->NewObjectArray(env, 1, ia4_class, NULL);
2027 1938          CHECK_NULL_RETURN(addrArray, NULL);
2028 1939          (*env)->SetObjectArrayElement(env, addrArray, 0, addr);
2029 1940          (*env)->SetObjectField(env, ni, ni_addrsID, addrArray);
2030 1941          return ni;
2031 1942      }
2032 1943  
2033 1944  
2034 1945      /*
2035 1946       * IPv6 implementation
2036 1947       */
2037 1948      if ((opt == java_net_SocketOptions_IP_MULTICAST_IF) ||
2038 1949          (opt == java_net_SocketOptions_IP_MULTICAST_IF2)) {
2039 1950  
2040      -        static jclass ni_class;
2041      -        static jmethodID ni_ctrID;
2042      -        static jfieldID ni_indexID;
2043      -        static jfieldID ni_addrsID;
2044      -        static jclass ia_class;
2045 1951          static jmethodID ia_anyLocalAddressID;
2046 1952  
2047 1953          int index;
2048 1954          int len = sizeof(index);
2049 1955  
2050 1956          jobjectArray addrArray;
2051 1957          jobject addr;
2052 1958          jobject ni;
2053 1959  
2054 1960          {
2055 1961              if (getsockopt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_IF,
2056 1962                                 (char*)&index, &len) < 0) {
2057 1963                  NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
2058 1964                                 "Error getting socket option");
2059 1965                  return NULL;
2060 1966              }
2061 1967          }
2062 1968  
2063      -        if (ni_class == NULL) {
2064      -            jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
2065      -            CHECK_NULL_RETURN(c, NULL);
2066      -            ni_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
2067      -            CHECK_NULL_RETURN(ni_ctrID, NULL);
2068      -            ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
2069      -            CHECK_NULL_RETURN(ni_indexID, NULL);
2070      -            ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
2071      -                                            "[Ljava/net/InetAddress;");
2072      -            CHECK_NULL_RETURN(ni_addrsID, NULL);
2073      -
2074      -            ia_class = (*env)->FindClass(env, "java/net/InetAddress");
2075      -            CHECK_NULL_RETURN(ia_class, NULL);
2076      -            ia_class = (*env)->NewGlobalRef(env, ia_class);
2077      -            CHECK_NULL_RETURN(ia_class, NULL);
     1969 +        if (ia_anyLocalAddressID == NULL) {
2078 1970              ia_anyLocalAddressID = (*env)->GetStaticMethodID(env,
2079 1971                                                               ia_class,
2080 1972                                                               "anyLocalAddress",
2081 1973                                                               "()Ljava/net/InetAddress;");
2082 1974              CHECK_NULL_RETURN(ia_anyLocalAddressID, NULL);
2083      -            ni_class = (*env)->NewGlobalRef(env, c);
2084      -            CHECK_NULL_RETURN(ni_class, NULL);
2085 1975          }
2086 1976  
2087 1977          /*
2088 1978           * If multicast to a specific interface then return the
2089 1979           * interface (for IF2) or the any address on that interface
2090 1980           * (for IF).
2091 1981           */
2092 1982          if (index > 0) {
2093 1983              ni = Java_java_net_NetworkInterface_getByIndex0(env, ni_class,
2094 1984                                                                     index);
↓ open down ↓ 426 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX