1 /*
   2  * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 #include "net_util.h"
  26 
  27 #include "java_net_InetAddress.h"
  28 #include "java_net_SocketOptions.h"
  29 
  30 // Taken from mstcpip.h in Windows SDK 8.0 or newer.
  31 #define SIO_LOOPBACK_FAST_PATH              _WSAIOW(IOC_VENDOR,16)
  32 
  33 #ifndef IPTOS_TOS_MASK
  34 #define IPTOS_TOS_MASK 0x1e
  35 #endif
  36 #ifndef IPTOS_PREC_MASK
  37 #define IPTOS_PREC_MASK 0xe0
  38 #endif
  39 
  40 /* true if SO_RCVTIMEO is supported */
  41 jboolean isRcvTimeoutSupported = JNI_TRUE;
  42 
  43 /*
  44  * Table of Windows Sockets errors, the specific exception we
  45  * throw for the error, and the error text.
  46  *
  47  * Note that this table excludes OS dependent errors.
  48  *
  49  * Latest list of Windows Sockets errors can be found at :-
  50  * http://msdn.microsoft.com/library/psdk/winsock/errors_3wc2.htm
  51  */
  52 static struct {
  53     int errCode;
  54     const char *exc;
  55     const char *errString;
  56 } const winsock_errors[] = {
  57     { WSAEACCES,                0,      "Permission denied" },
  58     { WSAEADDRINUSE,            "BindException",        "Address already in use" },
  59     { WSAEADDRNOTAVAIL,         "BindException",        "Cannot assign requested address" },
  60     { WSAEAFNOSUPPORT,          0,      "Address family not supported by protocol family" },
  61     { WSAEALREADY,              0,      "Operation already in progress" },
  62     { WSAECONNABORTED,          0,      "Software caused connection abort" },
  63     { WSAECONNREFUSED,          "ConnectException",     "Connection refused" },
  64     { WSAECONNRESET,            0,      "Connection reset by peer" },
  65     { WSAEDESTADDRREQ,          0,      "Destination address required" },
  66     { WSAEFAULT,                0,      "Bad address" },
  67     { WSAEHOSTDOWN,             0,      "Host is down" },
  68     { WSAEHOSTUNREACH,          "NoRouteToHostException",       "No route to host" },
  69     { WSAEINPROGRESS,           0,      "Operation now in progress" },
  70     { WSAEINTR,                 0,      "Interrupted function call" },
  71     { WSAEINVAL,                0,      "Invalid argument" },
  72     { WSAEISCONN,               0,      "Socket is already connected" },
  73     { WSAEMFILE,                0,      "Too many open files" },
  74     { WSAEMSGSIZE,              0,      "The message is larger than the maximum supported by the underlying transport" },
  75     { WSAENETDOWN,              0,      "Network is down" },
  76     { WSAENETRESET,             0,      "Network dropped connection on reset" },
  77     { WSAENETUNREACH,           0,      "Network is unreachable" },
  78     { WSAENOBUFS,               0,      "No buffer space available (maximum connections reached?)" },
  79     { WSAENOPROTOOPT,           0,      "Bad protocol option" },
  80     { WSAENOTCONN,              0,      "Socket is not connected" },
  81     { WSAENOTSOCK,              0,      "Socket operation on nonsocket" },
  82     { WSAEOPNOTSUPP,            0,      "Operation not supported" },
  83     { WSAEPFNOSUPPORT,          0,      "Protocol family not supported" },
  84     { WSAEPROCLIM,              0,      "Too many processes" },
  85     { WSAEPROTONOSUPPORT,       0,      "Protocol not supported" },
  86     { WSAEPROTOTYPE,            0,      "Protocol wrong type for socket" },
  87     { WSAESHUTDOWN,             0,      "Cannot send after socket shutdown" },
  88     { WSAESOCKTNOSUPPORT,       0,      "Socket type not supported" },
  89     { WSAETIMEDOUT,             "ConnectException",     "Connection timed out" },
  90     { WSATYPE_NOT_FOUND,        0,      "Class type not found" },
  91     { WSAEWOULDBLOCK,           0,      "Resource temporarily unavailable" },
  92     { WSAHOST_NOT_FOUND,        0,      "Host not found" },
  93     { WSA_NOT_ENOUGH_MEMORY,    0,      "Insufficient memory available" },
  94     { WSANOTINITIALISED,        0,      "Successful WSAStartup not yet performed" },
  95     { WSANO_DATA,               0,      "Valid name, no data record of requested type" },
  96     { WSANO_RECOVERY,           0,      "This is a nonrecoverable error" },
  97     { WSASYSNOTREADY,           0,      "Network subsystem is unavailable" },
  98     { WSATRY_AGAIN,             0,      "Nonauthoritative host not found" },
  99     { WSAVERNOTSUPPORTED,       0,      "Winsock.dll version out of range" },
 100     { WSAEDISCON,               0,      "Graceful shutdown in progress" },
 101     { WSA_OPERATION_ABORTED,    0,      "Overlapped operation aborted" },
 102 };
 103 
 104 /*
 105  * Initialize Windows Sockets API support
 106  */
 107 BOOL WINAPI
 108 DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
 109 {
 110     WSADATA wsadata;
 111 
 112     switch (reason) {
 113         case DLL_PROCESS_ATTACH:
 114             if (WSAStartup(MAKEWORD(2,2), &wsadata) != 0) {
 115                 return FALSE;
 116             }
 117             break;
 118 
 119         case DLL_PROCESS_DETACH:
 120             WSACleanup();
 121             break;
 122 
 123         default:
 124             break;
 125     }
 126     return TRUE;
 127 }
 128 
 129 void platformInit() {}
 130 void parseExclusiveBindProperty(JNIEnv *env) {}
 131 
 132 /*
 133  * Since winsock doesn't have the equivalent of strerror(errno)
 134  * use table to lookup error text for the error.
 135  */
 136 JNIEXPORT void JNICALL
 137 NET_ThrowNew(JNIEnv *env, int errorNum, char *msg)
 138 {
 139     int i;
 140     int table_size = sizeof(winsock_errors) /
 141                      sizeof(winsock_errors[0]);
 142     char exc[256];
 143     char fullMsg[256];
 144     char *excP = NULL;
 145 
 146     /*
 147      * If exception already throw then don't overwrite it.
 148      */
 149     if ((*env)->ExceptionOccurred(env)) {
 150         return;
 151     }
 152 
 153     /*
 154      * Default message text if not provided
 155      */
 156     if (!msg) {
 157         msg = "no further information";
 158     }
 159 
 160     /*
 161      * Check table for known winsock errors
 162      */
 163     i=0;
 164     while (i < table_size) {
 165         if (errorNum == winsock_errors[i].errCode) {
 166             break;
 167         }
 168         i++;
 169     }
 170 
 171     /*
 172      * If found get pick the specific exception and error
 173      * message corresponding to this error.
 174      */
 175     if (i < table_size) {
 176         excP = (char *)winsock_errors[i].exc;
 177         jio_snprintf(fullMsg, sizeof(fullMsg), "%s: %s",
 178                      (char *)winsock_errors[i].errString, msg);
 179     } else {
 180         jio_snprintf(fullMsg, sizeof(fullMsg),
 181                      "Unrecognized Windows Sockets error: %d: %s",
 182                      errorNum, msg);
 183 
 184     }
 185 
 186     /*
 187      * Throw SocketException if no specific exception for this
 188      * error.
 189      */
 190     if (excP == NULL) {
 191         excP = "SocketException";
 192     }
 193     sprintf(exc, "%s%s", JNU_JAVANETPKG, excP);
 194     JNU_ThrowByName(env, exc, fullMsg);
 195 }
 196 
 197 void
 198 NET_ThrowCurrent(JNIEnv *env, char *msg)
 199 {
 200     NET_ThrowNew(env, WSAGetLastError(), msg);
 201 }
 202 
 203 void
 204 NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
 205                    const char *defaultDetail) {
 206     JNU_ThrowByNameWithMessageAndLastError(env, name, defaultDetail);
 207 }
 208 
 209 jfieldID
 210 NET_GetFileDescriptorID(JNIEnv *env)
 211 {
 212     jclass cls = (*env)->FindClass(env, "java/io/FileDescriptor");
 213     CHECK_NULL_RETURN(cls, NULL);
 214     return (*env)->GetFieldID(env, cls, "fd", "I");
 215 }
 216 
 217 jint  IPv6_supported()
 218 {
 219     SOCKET s = socket(AF_INET6, SOCK_STREAM, 0) ;
 220     if (s == INVALID_SOCKET) {
 221         return JNI_FALSE;
 222     }
 223     closesocket(s);
 224 
 225     return JNI_TRUE;
 226 }
 227 
 228 jint reuseport_supported()
 229 {
 230     /* SO_REUSEPORT is not supported on Windows */
 231     return JNI_FALSE;
 232 }
 233 
 234 /* call NET_MapSocketOptionV6 for the IPv6 fd only
 235  * and NET_MapSocketOption for the IPv4 fd
 236  */
 237 JNIEXPORT int JNICALL
 238 NET_MapSocketOptionV6(jint cmd, int *level, int *optname) {
 239 
 240     switch (cmd) {
 241         case java_net_SocketOptions_IP_MULTICAST_IF:
 242         case java_net_SocketOptions_IP_MULTICAST_IF2:
 243             *level = IPPROTO_IPV6;
 244             *optname = IPV6_MULTICAST_IF;
 245             return 0;
 246 
 247         case java_net_SocketOptions_IP_MULTICAST_LOOP:
 248             *level = IPPROTO_IPV6;
 249             *optname = IPV6_MULTICAST_LOOP;
 250             return 0;
 251     }
 252     return NET_MapSocketOption (cmd, level, optname);
 253 }
 254 
 255 /*
 256  * Map the Java level socket option to the platform specific
 257  * level and option name.
 258  */
 259 
 260 JNIEXPORT int JNICALL
 261 NET_MapSocketOption(jint cmd, int *level, int *optname) {
 262 
 263     typedef struct {
 264         jint cmd;
 265         int level;
 266         int optname;
 267     } sockopts;
 268 
 269     static sockopts opts[] = {
 270         { java_net_SocketOptions_TCP_NODELAY,   IPPROTO_TCP,    TCP_NODELAY },
 271         { java_net_SocketOptions_SO_OOBINLINE,  SOL_SOCKET,     SO_OOBINLINE },
 272         { java_net_SocketOptions_SO_LINGER,     SOL_SOCKET,     SO_LINGER },
 273         { java_net_SocketOptions_SO_SNDBUF,     SOL_SOCKET,     SO_SNDBUF },
 274         { java_net_SocketOptions_SO_RCVBUF,     SOL_SOCKET,     SO_RCVBUF },
 275         { java_net_SocketOptions_SO_KEEPALIVE,  SOL_SOCKET,     SO_KEEPALIVE },
 276         { java_net_SocketOptions_SO_REUSEADDR,  SOL_SOCKET,     SO_REUSEADDR },
 277         { java_net_SocketOptions_SO_BROADCAST,  SOL_SOCKET,     SO_BROADCAST },
 278         { java_net_SocketOptions_IP_MULTICAST_IF,   IPPROTO_IP, IP_MULTICAST_IF },
 279         { java_net_SocketOptions_IP_MULTICAST_LOOP, IPPROTO_IP, IP_MULTICAST_LOOP },
 280         { java_net_SocketOptions_IP_TOS,            IPPROTO_IP, IP_TOS },
 281 
 282     };
 283 
 284 
 285     int i;
 286 
 287     /*
 288      * Map the Java level option to the native level
 289      */
 290     for (i=0; i<(int)(sizeof(opts) / sizeof(opts[0])); i++) {
 291         if (cmd == opts[i].cmd) {
 292             *level = opts[i].level;
 293             *optname = opts[i].optname;
 294             return 0;
 295         }
 296     }
 297 
 298     /* not found */
 299     return -1;
 300 }
 301 
 302 
 303 /*
 304  * Wrapper for setsockopt dealing with Windows specific issues :-
 305  *
 306  * IP_TOS and IP_MULTICAST_LOOP can't be set on some Windows
 307  * editions.
 308  *
 309  * The value for the type-of-service (TOS) needs to be masked
 310  * to get consistent behaviour with other operating systems.
 311  */
 312 JNIEXPORT int JNICALL
 313 NET_SetSockOpt(int s, int level, int optname, const void *optval,
 314                int optlen)
 315 {
 316     int rv = 0;
 317     int parg = 0;
 318     int plen = sizeof(parg);
 319 
 320     if (level == IPPROTO_IP && optname == IP_TOS) {
 321         int *tos = (int *)optval;
 322         *tos &= (IPTOS_TOS_MASK | IPTOS_PREC_MASK);
 323     }
 324 
 325     if (optname == SO_REUSEADDR) {
 326         /*
 327          * Do not set SO_REUSEADDE if SO_EXCLUSIVEADDUSE is already set
 328          */
 329         rv = NET_GetSockOpt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *)&parg, &plen);
 330         if (rv == 0 && parg == 1) {
 331             return rv;
 332         }
 333     }
 334 
 335     rv = setsockopt(s, level, optname, optval, optlen);
 336 
 337     if (rv == SOCKET_ERROR) {
 338         /*
 339          * IP_TOS & IP_MULTICAST_LOOP can't be set on some versions
 340          * of Windows.
 341          */
 342         if ((WSAGetLastError() == WSAENOPROTOOPT) &&
 343             (level == IPPROTO_IP) &&
 344             (optname == IP_TOS || optname == IP_MULTICAST_LOOP)) {
 345             rv = 0;
 346         }
 347 
 348         /*
 349          * IP_TOS can't be set on unbound UDP sockets.
 350          */
 351         if ((WSAGetLastError() == WSAEINVAL) &&
 352             (level == IPPROTO_IP) &&
 353             (optname == IP_TOS)) {
 354             rv = 0;
 355         }
 356     }
 357 
 358     return rv;
 359 }
 360 
 361 /*
 362  * Wrapper for setsockopt dealing with Windows specific issues :-
 363  *
 364  * IP_TOS is not supported on some versions of Windows so
 365  * instead return the default value for the OS.
 366  */
 367 JNIEXPORT int JNICALL
 368 NET_GetSockOpt(int s, int level, int optname, void *optval,
 369                int *optlen)
 370 {
 371     int rv;
 372 
 373     if (level == IPPROTO_IPV6 && optname == IPV6_TCLASS) {
 374         int *intopt = (int *)optval;
 375         *intopt = 0;
 376         *optlen = sizeof(*intopt);
 377         return 0;
 378     }
 379 
 380     rv = getsockopt(s, level, optname, optval, optlen);
 381 
 382 
 383     /*
 384      * IPPROTO_IP/IP_TOS is not supported on some Windows
 385      * editions so return the default type-of-service
 386      * value.
 387      */
 388     if (rv == SOCKET_ERROR) {
 389 
 390         if (WSAGetLastError() == WSAENOPROTOOPT &&
 391             level == IPPROTO_IP && optname == IP_TOS) {
 392 
 393             *((int *)optval) = 0;
 394             rv = 0;
 395         }
 396     }
 397 
 398     return rv;
 399 }
 400 
 401 /*
 402  * Sets SO_ECLUSIVEADDRUSE if SO_REUSEADDR is not already set.
 403  */
 404 void setExclusiveBind(int fd) {
 405     int parg = 0;
 406     int plen = sizeof(parg);
 407     int rv = 0;
 408     rv = NET_GetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&parg, &plen);
 409     if (rv == 0 && parg == 0) {
 410         parg = 1;
 411         rv = NET_SetSockOpt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char*)&parg, plen);
 412     }
 413 }
 414 
 415 /*
 416  * Wrapper for bind winsock call - transparent converts an
 417  * error related to binding to a port that has exclusive access
 418  * into an error indicating the port is in use (facilitates
 419  * better error reporting).
 420  *
 421  * Should be only called by the wrapper method NET_WinBind
 422  */
 423 JNIEXPORT int JNICALL
 424 NET_Bind(int s, SOCKETADDRESS *sa, int len)
 425 {
 426     int rv = 0;
 427     rv = bind(s, &sa->sa, len);
 428 
 429     if (rv == SOCKET_ERROR) {
 430         /*
 431          * If bind fails with WSAEACCES it means that a privileged
 432          * process has done an exclusive bind (NT SP4/2000/XP only).
 433          */
 434         if (WSAGetLastError() == WSAEACCES) {
 435             WSASetLastError(WSAEADDRINUSE);
 436         }
 437     }
 438 
 439     return rv;
 440 }
 441 
 442 /*
 443  * Wrapper for NET_Bind call. Sets SO_EXCLUSIVEADDRUSE
 444  * if required, and then calls NET_BIND
 445  */
 446 JNIEXPORT int JNICALL
 447 NET_WinBind(int s, SOCKETADDRESS *sa, int len, jboolean exclBind)
 448 {
 449     if (exclBind == JNI_TRUE)
 450         setExclusiveBind(s);
 451     return NET_Bind(s, sa, len);
 452 }
 453 
 454 JNIEXPORT int JNICALL
 455 NET_SocketClose(int fd) {
 456     struct linger l = {0, 0};
 457     int ret = 0;
 458     int len = sizeof (l);
 459     if (getsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&l, &len) == 0) {
 460         if (l.l_onoff == 0) {
 461             shutdown(fd, SD_SEND);
 462         }
 463     }
 464     ret = closesocket (fd);
 465     return ret;
 466 }
 467 
 468 JNIEXPORT int JNICALL
 469 NET_Timeout(int fd, long timeout) {
 470     int ret;
 471     fd_set tbl;
 472     struct timeval t;
 473     t.tv_sec = timeout / 1000;
 474     t.tv_usec = (timeout % 1000) * 1000;
 475     FD_ZERO(&tbl);
 476     FD_SET(fd, &tbl);
 477     ret = select (fd + 1, &tbl, 0, 0, &t);
 478     return ret;
 479 }
 480 
 481 
 482 /*
 483  * differs from NET_Timeout() as follows:
 484  *
 485  * If timeout = -1, it blocks forever.
 486  *
 487  * returns 1 or 2 depending if only one or both sockets
 488  * fire at same time.
 489  *
 490  * *fdret is (one of) the active fds. If both sockets
 491  * fire at same time, *fdret = fd always.
 492  */
 493 JNIEXPORT int JNICALL
 494 NET_Timeout2(int fd, int fd1, long timeout, int *fdret) {
 495     int ret;
 496     fd_set tbl;
 497     struct timeval t, *tP = &t;
 498     if (timeout == -1) {
 499         tP = 0;
 500     } else {
 501         t.tv_sec = timeout / 1000;
 502         t.tv_usec = (timeout % 1000) * 1000;
 503     }
 504     FD_ZERO(&tbl);
 505     FD_SET(fd, &tbl);
 506     FD_SET(fd1, &tbl);
 507     ret = select (0, &tbl, 0, 0, tP);
 508     switch (ret) {
 509     case 0:
 510         return 0; /* timeout */
 511     case 1:
 512         if (FD_ISSET (fd, &tbl)) {
 513             *fdret= fd;
 514         } else {
 515             *fdret= fd1;
 516         }
 517         return 1;
 518     case 2:
 519         *fdret= fd;
 520         return 2;
 521     }
 522     return -1;
 523 }
 524 
 525 
 526 void dumpAddr (char *str, void *addr) {
 527     struct sockaddr_in6 *a = (struct sockaddr_in6 *)addr;
 528     int family = a->sin6_family;
 529     printf ("%s\n", str);
 530     if (family == AF_INET) {
 531         struct sockaddr_in *him = (struct sockaddr_in *)addr;
 532         printf ("AF_INET: port %d: %x\n", ntohs(him->sin_port),
 533                                           ntohl(him->sin_addr.s_addr));
 534     } else {
 535         int i;
 536         struct in6_addr *in = &a->sin6_addr;
 537         printf ("AF_INET6 ");
 538         printf ("port %d ", ntohs (a->sin6_port));
 539         printf ("flow %d ", a->sin6_flowinfo);
 540         printf ("addr ");
 541         for (i=0; i<7; i++) {
 542             printf ("%04x:", ntohs(in->s6_words[i]));
 543         }
 544         printf ("%04x", ntohs(in->s6_words[7]));
 545         printf (" scope %d\n", a->sin6_scope_id);
 546     }
 547 }
 548 
 549 /* Macro, which cleans-up the iv6bind structure,
 550  * closes the two sockets (if open),
 551  * and returns SOCKET_ERROR. Used in NET_BindV6 only.
 552  */
 553 
 554 #define CLOSE_SOCKETS_AND_RETURN do {   \
 555     if (fd != -1) {                     \
 556         closesocket (fd);               \
 557         fd = -1;                        \
 558     }                                   \
 559     if (ofd != -1) {                    \
 560         closesocket (ofd);              \
 561         ofd = -1;                       \
 562     }                                   \
 563     if (close_fd != -1) {               \
 564         closesocket (close_fd);         \
 565         close_fd = -1;                  \
 566     }                                   \
 567     if (close_ofd != -1) {              \
 568         closesocket (close_ofd);        \
 569         close_ofd = -1;                 \
 570     }                                   \
 571     b->ipv4_fd = b->ipv6_fd = -1;       \
 572     return SOCKET_ERROR;                \
 573 } while(0)
 574 
 575 /*
 576  * if ipv6 is available, call NET_BindV6 to bind to the required address/port.
 577  * Because the same port number may need to be reserved in both v4 and v6 space,
 578  * this may require socket(s) to be re-opened. Therefore, all of this information
 579  * is passed in and returned through the ipv6bind structure.
 580  *
 581  * If the request is to bind to a specific address, then this (by definition) means
 582  * only bind in either v4 or v6, and this is just the same as normal. ie. a single
 583  * call to bind() will suffice. The other socket is closed in this case.
 584  *
 585  * The more complicated case is when the requested address is ::0 or 0.0.0.0.
 586  *
 587  * Two further cases:
 588  * 2. If the requested port is 0 (ie. any port) then we try to bind in v4 space
 589  *    first with a wild-card port argument. We then try to bind in v6 space
 590  *    using the returned port number. If this fails, we repeat the process
 591  *    until a free port common to both spaces becomes available.
 592  *
 593  * 3. If the requested port is a specific port, then we just try to get that
 594  *    port in both spaces, and if it is not free in both, then the bind fails.
 595  *
 596  * On failure, sockets are closed and an error returned with CLOSE_SOCKETS_AND_RETURN
 597  */
 598 
 599 JNIEXPORT int JNICALL
 600 NET_BindV6(struct ipv6bind *b, jboolean exclBind) {
 601     int fd=-1, ofd=-1, rv, len;
 602     /* need to defer close until new sockets created */
 603     int close_fd=-1, close_ofd=-1;
 604     SOCKETADDRESS oaddr; /* other address to bind */
 605     int family = b->addr->sa.sa_family;
 606     int ofamily;
 607     u_short port; /* requested port parameter */
 608     u_short bound_port;
 609 
 610     if (family == AF_INET && (b->addr->sa4.sin_addr.s_addr != INADDR_ANY)) {
 611         /* bind to v4 only */
 612         int ret;
 613         ret = NET_WinBind((int)b->ipv4_fd, b->addr,
 614                           sizeof(SOCKETADDRESS), exclBind);
 615         if (ret == SOCKET_ERROR) {
 616             CLOSE_SOCKETS_AND_RETURN;
 617         }
 618         closesocket (b->ipv6_fd);
 619         b->ipv6_fd = -1;
 620         return 0;
 621     }
 622     if (family == AF_INET6 && (!IN6_IS_ADDR_ANY(&b->addr->sa6.sin6_addr))) {
 623         /* bind to v6 only */
 624         int ret;
 625         ret = NET_WinBind((int)b->ipv6_fd, b->addr,
 626                           sizeof(SOCKETADDRESS), exclBind);
 627         if (ret == SOCKET_ERROR) {
 628             CLOSE_SOCKETS_AND_RETURN;
 629         }
 630         closesocket (b->ipv4_fd);
 631         b->ipv4_fd = -1;
 632         return 0;
 633     }
 634 
 635     /* We need to bind on both stacks, with the same port number */
 636 
 637     memset (&oaddr, 0, sizeof(oaddr));
 638     if (family == AF_INET) {
 639         ofamily = AF_INET6;
 640         fd = (int)b->ipv4_fd;
 641         ofd = (int)b->ipv6_fd;
 642         port = (u_short)GET_PORT (b->addr);
 643         IN6ADDR_SETANY(&oaddr.sa6);
 644         oaddr.sa6.sin6_port = port;
 645     } else {
 646         ofamily = AF_INET;
 647         ofd = (int)b->ipv4_fd;
 648         fd = (int)b->ipv6_fd;
 649         port = (u_short)GET_PORT (b->addr);
 650         oaddr.sa4.sin_family = AF_INET;
 651         oaddr.sa4.sin_port = port;
 652         oaddr.sa4.sin_addr.s_addr = INADDR_ANY;
 653     }
 654 
 655     rv = NET_WinBind(fd, b->addr, sizeof(SOCKETADDRESS), exclBind);
 656     if (rv == SOCKET_ERROR) {
 657         CLOSE_SOCKETS_AND_RETURN;
 658     }
 659 
 660     /* get the port and set it in the other address */
 661     len = sizeof(SOCKETADDRESS);
 662     if (getsockname(fd, (struct sockaddr *)b->addr, &len) == -1) {
 663         CLOSE_SOCKETS_AND_RETURN;
 664     }
 665     bound_port = GET_PORT (b->addr);
 666     SET_PORT (&oaddr, bound_port);
 667     if ((rv = NET_WinBind(ofd, &oaddr,
 668                           sizeof(SOCKETADDRESS), exclBind)) == SOCKET_ERROR) {
 669         int retries;
 670         int sotype, arglen=sizeof(sotype);
 671 
 672         /* no retries unless, the request was for any free port */
 673 
 674         if (port != 0) {
 675             CLOSE_SOCKETS_AND_RETURN;
 676         }
 677 
 678         getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype, &arglen);
 679 
 680 #define SOCK_RETRIES 50
 681         /* 50 is an arbitrary limit, just to ensure that this
 682          * cannot be an endless loop. Would expect socket creation to
 683          * succeed sooner.
 684          */
 685         for (retries = 0; retries < SOCK_RETRIES; retries ++) {
 686             int len;
 687             close_fd = fd; fd = -1;
 688             close_ofd = ofd; ofd = -1;
 689             b->ipv4_fd = SOCKET_ERROR;
 690             b->ipv6_fd = SOCKET_ERROR;
 691 
 692             /* create two new sockets */
 693             fd = (int)socket (family, sotype, 0);
 694             if (fd == SOCKET_ERROR) {
 695                 CLOSE_SOCKETS_AND_RETURN;
 696             }
 697             ofd = (int)socket (ofamily, sotype, 0);
 698             if (ofd == SOCKET_ERROR) {
 699                 CLOSE_SOCKETS_AND_RETURN;
 700             }
 701 
 702             /* bind random port on first socket */
 703             SET_PORT (&oaddr, 0);
 704             rv = NET_WinBind(ofd, &oaddr, sizeof(SOCKETADDRESS), exclBind);
 705             if (rv == SOCKET_ERROR) {
 706                 CLOSE_SOCKETS_AND_RETURN;
 707             }
 708             /* close the original pair of sockets before continuing */
 709             closesocket (close_fd);
 710             closesocket (close_ofd);
 711             close_fd = close_ofd = -1;
 712 
 713             /* bind new port on second socket */
 714             len = sizeof(SOCKETADDRESS);
 715             if (getsockname(ofd, &oaddr.sa, &len) == -1) {
 716                 CLOSE_SOCKETS_AND_RETURN;
 717             }
 718             bound_port = GET_PORT (&oaddr);
 719             SET_PORT (b->addr, bound_port);
 720             rv = NET_WinBind(fd, b->addr, sizeof(SOCKETADDRESS), exclBind);
 721 
 722             if (rv != SOCKET_ERROR) {
 723                 if (family == AF_INET) {
 724                     b->ipv4_fd = fd;
 725                     b->ipv6_fd = ofd;
 726                 } else {
 727                     b->ipv4_fd = ofd;
 728                     b->ipv6_fd = fd;
 729                 }
 730                 return 0;
 731             }
 732         }
 733         CLOSE_SOCKETS_AND_RETURN;
 734     }
 735     return 0;
 736 }
 737 
 738 /*
 739  * Determine the default interface for an IPv6 address.
 740  *
 741  * Returns :-
 742  *      0 if error
 743  *      > 0 interface index to use
 744  */
 745 jint getDefaultIPv6Interface(JNIEnv *env, struct sockaddr_in6 *target_addr)
 746 {
 747     int ret;
 748     DWORD b;
 749     struct sockaddr_in6 route;
 750     SOCKET fd = socket(AF_INET6, SOCK_STREAM, 0);
 751     if (fd == INVALID_SOCKET) {
 752         return 0;
 753     }
 754 
 755     ret = WSAIoctl(fd, SIO_ROUTING_INTERFACE_QUERY,
 756                    (void *)target_addr, sizeof(struct sockaddr_in6),
 757                    (void *)&route, sizeof(struct sockaddr_in6),
 758                    &b, 0, 0);
 759     if (ret == SOCKET_ERROR) {
 760         // error
 761         closesocket(fd);
 762         return 0;
 763     } else {
 764         closesocket(fd);
 765         return route.sin6_scope_id;
 766     }
 767 }
 768 
 769 /**
 770  * Enables SIO_LOOPBACK_FAST_PATH
 771  */
 772 JNIEXPORT jint JNICALL
 773 NET_EnableFastTcpLoopback(int fd) {
 774     int enabled = 1;
 775     DWORD result_byte_count = -1;
 776     int result = WSAIoctl(fd,
 777                           SIO_LOOPBACK_FAST_PATH,
 778                           &enabled,
 779                           sizeof(enabled),
 780                           NULL,
 781                           0,
 782                           &result_byte_count,
 783                           NULL,
 784                           NULL);
 785     return result == SOCKET_ERROR ? WSAGetLastError() : 0;
 786 }
 787 
 788 /**
 789  * See net_util.h for documentation
 790  */
 791 JNIEXPORT int JNICALL
 792 NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
 793                           SOCKETADDRESS *sa, int *len,
 794                           jboolean v4MappedAddress)
 795 {
 796     jint family = getInetAddress_family(env, iaObj);
 797     JNU_CHECK_EXCEPTION_RETURN(env, -1);
 798     memset((char *)sa, 0, sizeof(SOCKETADDRESS));
 799 
 800     if (ipv6_available() &&
 801         !(family == java_net_InetAddress_IPv4 &&
 802           v4MappedAddress == JNI_FALSE))
 803     {
 804         jbyte caddr[16];
 805         jint address;
 806         unsigned int scopeid = 0, cached_scope_id = 0;
 807 
 808         if (family == java_net_InetAddress_IPv4) {
 809             // convert to IPv4-mapped address
 810             memset((char *)caddr, 0, 16);
 811             address = getInetAddress_addr(env, iaObj);
 812             JNU_CHECK_EXCEPTION_RETURN(env, -1);
 813             if (address == INADDR_ANY) {
 814                 /* we would always prefer IPv6 wildcard address
 815                  * caddr[10] = 0xff;
 816                  * caddr[11] = 0xff; */
 817             } else {
 818                 caddr[10] = 0xff;
 819                 caddr[11] = 0xff;
 820                 caddr[12] = ((address >> 24) & 0xff);
 821                 caddr[13] = ((address >> 16) & 0xff);
 822                 caddr[14] = ((address >> 8) & 0xff);
 823                 caddr[15] = (address & 0xff);
 824             }
 825         } else {
 826             getInet6Address_ipaddress(env, iaObj, (char *)caddr);
 827             scopeid = getInet6Address_scopeid(env, iaObj);
 828             cached_scope_id = (unsigned int)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID);
 829         }
 830         sa->sa6.sin6_port = (u_short)htons((u_short)port);
 831         memcpy((void *)&sa->sa6.sin6_addr, caddr, sizeof(struct in6_addr));
 832         sa->sa6.sin6_family = AF_INET6;
 833         if ((family == java_net_InetAddress_IPv6) &&
 834             IN6_IS_ADDR_LINKLOCAL(&sa->sa6.sin6_addr) &&
 835             (!scopeid && !cached_scope_id))
 836         {
 837             cached_scope_id = getDefaultIPv6Interface(env, &sa->sa6);
 838             (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id);
 839         }
 840         sa->sa6.sin6_scope_id = scopeid == 0 ? cached_scope_id : scopeid;
 841         if (len != NULL) {
 842             *len = sizeof(struct sockaddr_in6);
 843         }
 844     } else {
 845         jint address;
 846         if (family != java_net_InetAddress_IPv4) {
 847             JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Protocol family unavailable");
 848             return -1;
 849         }
 850         address = getInetAddress_addr(env, iaObj);
 851         JNU_CHECK_EXCEPTION_RETURN(env, -1);
 852         sa->sa4.sin_port = htons((short)port);
 853         sa->sa4.sin_addr.s_addr = (u_long)htonl(address);
 854         sa->sa4.sin_family = AF_INET;
 855         if (len != NULL) {
 856             *len = sizeof(struct sockaddr_in);
 857         }
 858     }
 859     return 0;
 860 }
 861 
 862 int
 863 NET_IsIPv4Mapped(jbyte* caddr) {
 864     int i;
 865     for (i = 0; i < 10; i++) {
 866         if (caddr[i] != 0x00) {
 867             return 0; /* false */
 868         }
 869     }
 870 
 871     if (((caddr[10] & 0xff) == 0xff) && ((caddr[11] & 0xff) == 0xff)) {
 872         return 1; /* true */
 873     }
 874     return 0; /* false */
 875 }
 876 
 877 int
 878 NET_IPv4MappedToIPv4(jbyte* caddr) {
 879     return ((caddr[12] & 0xff) << 24) | ((caddr[13] & 0xff) << 16) | ((caddr[14] & 0xff) << 8)
 880         | (caddr[15] & 0xff);
 881 }
 882 
 883 int
 884 NET_IsEqual(jbyte* caddr1, jbyte* caddr2) {
 885     int i;
 886     for (i = 0; i < 16; i++) {
 887         if (caddr1[i] != caddr2[i]) {
 888             return 0; /* false */
 889         }
 890     }
 891     return 1;
 892 }
 893 
 894 /**
 895  * Wrapper for select/poll with timeout on a single file descriptor.
 896  *
 897  * flags (defined in net_util_md.h can be any combination of
 898  * NET_WAIT_READ, NET_WAIT_WRITE & NET_WAIT_CONNECT.
 899  *
 900  * The function will return when either the socket is ready for one
 901  * of the specified operation or the timeout expired.
 902  *
 903  * It returns the time left from the timeout, or -1 if it expired.
 904  */
 905 
 906 jint
 907 NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout)
 908 {
 909     jlong prevTime = JVM_CurrentTimeMillis(env, 0);
 910     jint read_rv;
 911 
 912     while (1) {
 913         jlong newTime;
 914         fd_set rd, wr, ex;
 915         struct timeval t;
 916 
 917         t.tv_sec = timeout / 1000;
 918         t.tv_usec = (timeout % 1000) * 1000;
 919 
 920         FD_ZERO(&rd);
 921         FD_ZERO(&wr);
 922         FD_ZERO(&ex);
 923         if (flags & NET_WAIT_READ) {
 924           FD_SET(fd, &rd);
 925         }
 926         if (flags & NET_WAIT_WRITE) {
 927           FD_SET(fd, &wr);
 928         }
 929         if (flags & NET_WAIT_CONNECT) {
 930           FD_SET(fd, &wr);
 931           FD_SET(fd, &ex);
 932         }
 933 
 934         errno = 0;
 935         read_rv = select(fd+1, &rd, &wr, &ex, &t);
 936 
 937         newTime = JVM_CurrentTimeMillis(env, 0);
 938         timeout -= (jint)(newTime - prevTime);
 939         if (timeout <= 0) {
 940           return read_rv > 0 ? 0 : -1;
 941         }
 942         newTime = prevTime;
 943 
 944         if (read_rv > 0) {
 945           break;
 946         }
 947 
 948 
 949       } /* while */
 950 
 951     return timeout;
 952 }
 953 
 954 int NET_Socket (int domain, int type, int protocol) {
 955     SOCKET sock;
 956     sock = socket (domain, type, protocol);
 957     if (sock != INVALID_SOCKET) {
 958         SetHandleInformation((HANDLE)(uintptr_t)sock, HANDLE_FLAG_INHERIT, FALSE);
 959     }
 960     return (int)sock;
 961 }