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