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