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 onn Windows */ 231 return JNI_FALSE; 232 } 233 /* 234 * Return the default TOS value 235 */ 236 int NET_GetDefaultTOS() { 237 static int default_tos = -1; 238 OSVERSIONINFO ver; 239 HKEY hKey; 240 LONG ret; 241 242 /* 243 * If default ToS already determined then return it 244 */ 245 if (default_tos >= 0) { 246 return default_tos; 247 } 248 249 /* 250 * Assume default is "normal service" 251 */ 252 default_tos = 0; 253 254 /* 255 * Which OS is this? 256 */ 257 ver.dwOSVersionInfoSize = sizeof(ver); 258 GetVersionEx(&ver); 259 260 /* 261 * If 2000 or greater then no default ToS in registry 262 */ 263 if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) { 264 if (ver.dwMajorVersion >= 5) { 265 return default_tos; 266 } 267 } 268 269 /* 270 * Query the registry to see if a Default ToS has been set. 271 * Different registry entry for NT vs 95/98/ME. 272 */ 273 if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) { 274 ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, 275 "SYSTEM\\CurrentControlSet\\Services\\Tcp\\Parameters", 276 0, KEY_READ, (PHKEY)&hKey); 277 } else { 278 ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, 279 "SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP\\Parameters", 280 0, KEY_READ, (PHKEY)&hKey); 281 } 282 if (ret == ERROR_SUCCESS) { 283 DWORD dwLen; 284 DWORD dwDefaultTOS; 285 ULONG ulType; 286 dwLen = sizeof(dwDefaultTOS); 287 288 ret = RegQueryValueEx(hKey, "DefaultTOS", NULL, &ulType, 289 (LPBYTE)&dwDefaultTOS, &dwLen); 290 RegCloseKey(hKey); 291 if (ret == ERROR_SUCCESS) { 292 default_tos = (int)dwDefaultTOS; 293 } 294 } 295 return default_tos; 296 } 297 298 /* call NET_MapSocketOptionV6 for the IPv6 fd only 299 * and NET_MapSocketOption for the IPv4 fd 300 */ 301 JNIEXPORT int JNICALL 302 NET_MapSocketOptionV6(jint cmd, int *level, int *optname) { 303 304 switch (cmd) { 305 case java_net_SocketOptions_IP_MULTICAST_IF: 306 case java_net_SocketOptions_IP_MULTICAST_IF2: 307 *level = IPPROTO_IPV6; 308 *optname = IPV6_MULTICAST_IF; 309 return 0; 310 311 case java_net_SocketOptions_IP_MULTICAST_LOOP: 312 *level = IPPROTO_IPV6; 313 *optname = IPV6_MULTICAST_LOOP; 314 return 0; 315 } 316 return NET_MapSocketOption (cmd, level, optname); 317 } 318 319 /* 320 * Map the Java level socket option to the platform specific 321 * level and option name. 322 */ 323 324 JNIEXPORT int JNICALL 325 NET_MapSocketOption(jint cmd, int *level, int *optname) { 326 327 typedef struct { 328 jint cmd; 329 int level; 330 int optname; 331 } sockopts; 332 333 static sockopts opts[] = { 334 { java_net_SocketOptions_TCP_NODELAY, IPPROTO_TCP, TCP_NODELAY }, 335 { java_net_SocketOptions_SO_OOBINLINE, SOL_SOCKET, SO_OOBINLINE }, 336 { java_net_SocketOptions_SO_LINGER, SOL_SOCKET, SO_LINGER }, 337 { java_net_SocketOptions_SO_SNDBUF, SOL_SOCKET, SO_SNDBUF }, 338 { java_net_SocketOptions_SO_RCVBUF, SOL_SOCKET, SO_RCVBUF }, 339 { java_net_SocketOptions_SO_KEEPALIVE, SOL_SOCKET, SO_KEEPALIVE }, 340 { java_net_SocketOptions_SO_REUSEADDR, SOL_SOCKET, SO_REUSEADDR }, 341 { java_net_SocketOptions_SO_BROADCAST, SOL_SOCKET, SO_BROADCAST }, 342 { java_net_SocketOptions_IP_MULTICAST_IF, IPPROTO_IP, IP_MULTICAST_IF }, 343 { java_net_SocketOptions_IP_MULTICAST_LOOP, IPPROTO_IP, IP_MULTICAST_LOOP }, 344 { java_net_SocketOptions_IP_TOS, IPPROTO_IP, IP_TOS }, 345 346 }; 347 348 349 int i; 350 351 /* 352 * Map the Java level option to the native level 353 */ 354 for (i=0; i<(int)(sizeof(opts) / sizeof(opts[0])); i++) { 355 if (cmd == opts[i].cmd) { 356 *level = opts[i].level; 357 *optname = opts[i].optname; 358 return 0; 359 } 360 } 361 362 /* not found */ 363 return -1; 364 } 365 366 367 /* 368 * Wrapper for setsockopt dealing with Windows specific issues :- 369 * 370 * IP_TOS and IP_MULTICAST_LOOP can't be set on some Windows 371 * editions. 372 * 373 * The value for the type-of-service (TOS) needs to be masked 374 * to get consistent behaviour with other operating systems. 375 */ 376 JNIEXPORT int JNICALL 377 NET_SetSockOpt(int s, int level, int optname, const void *optval, 378 int optlen) 379 { 380 int rv = 0; 381 int parg = 0; 382 int plen = sizeof(parg); 383 384 if (level == IPPROTO_IP && optname == IP_TOS) { 385 int *tos = (int *)optval; 386 *tos &= (IPTOS_TOS_MASK | IPTOS_PREC_MASK); 387 } 388 389 if (optname == SO_REUSEADDR) { 390 /* 391 * Do not set SO_REUSEADDE if SO_EXCLUSIVEADDUSE is already set 392 */ 393 rv = NET_GetSockOpt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *)&parg, &plen); 394 if (rv == 0 && parg == 1) { 395 return rv; 396 } 397 } 398 399 rv = setsockopt(s, level, optname, optval, optlen); 400 401 if (rv == SOCKET_ERROR) { 402 /* 403 * IP_TOS & IP_MULTICAST_LOOP can't be set on some versions 404 * of Windows. 405 */ 406 if ((WSAGetLastError() == WSAENOPROTOOPT) && 407 (level == IPPROTO_IP) && 408 (optname == IP_TOS || optname == IP_MULTICAST_LOOP)) { 409 rv = 0; 410 } 411 412 /* 413 * IP_TOS can't be set on unbound UDP sockets. 414 */ 415 if ((WSAGetLastError() == WSAEINVAL) && 416 (level == IPPROTO_IP) && 417 (optname == IP_TOS)) { 418 rv = 0; 419 } 420 } 421 422 return rv; 423 } 424 425 /* 426 * Wrapper for setsockopt dealing with Windows specific issues :- 427 * 428 * IP_TOS is not supported on some versions of Windows so 429 * instead return the default value for the OS. 430 */ 431 JNIEXPORT int JNICALL 432 NET_GetSockOpt(int s, int level, int optname, void *optval, 433 int *optlen) 434 { 435 int rv; 436 437 if (level == IPPROTO_IPV6 && optname == IPV6_TCLASS) { 438 int *intopt = (int *)optval; 439 *intopt = 0; 440 *optlen = sizeof(*intopt); 441 return 0; 442 } 443 444 rv = getsockopt(s, level, optname, optval, optlen); 445 446 447 /* 448 * IPPROTO_IP/IP_TOS is not supported on some Windows 449 * editions so return the default type-of-service 450 * value. 451 */ 452 if (rv == SOCKET_ERROR) { 453 454 if (WSAGetLastError() == WSAENOPROTOOPT && 455 level == IPPROTO_IP && optname == IP_TOS) { 456 457 int *tos; 458 tos = (int *)optval; 459 *tos = NET_GetDefaultTOS(); 460 461 rv = 0; 462 } 463 } 464 465 return rv; 466 } 467 468 /* 469 * Sets SO_ECLUSIVEADDRUSE if SO_REUSEADDR is not already set. 470 */ 471 void setExclusiveBind(int fd) { 472 int parg = 0; 473 int plen = sizeof(parg); 474 int rv = 0; 475 rv = NET_GetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&parg, &plen); 476 if (rv == 0 && parg == 0) { 477 parg = 1; 478 rv = NET_SetSockOpt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char*)&parg, plen); 479 } 480 } 481 482 /* 483 * Wrapper for bind winsock call - transparent converts an 484 * error related to binding to a port that has exclusive access 485 * into an error indicating the port is in use (facilitates 486 * better error reporting). 487 * 488 * Should be only called by the wrapper method NET_WinBind 489 */ 490 JNIEXPORT int JNICALL 491 NET_Bind(int s, SOCKETADDRESS *sa, int len) 492 { 493 int rv = 0; 494 rv = bind(s, &sa->sa, len); 495 496 if (rv == SOCKET_ERROR) { 497 /* 498 * If bind fails with WSAEACCES it means that a privileged 499 * process has done an exclusive bind (NT SP4/2000/XP only). 500 */ 501 if (WSAGetLastError() == WSAEACCES) { 502 WSASetLastError(WSAEADDRINUSE); 503 } 504 } 505 506 return rv; 507 } 508 509 /* 510 * Wrapper for NET_Bind call. Sets SO_EXCLUSIVEADDRUSE 511 * if required, and then calls NET_BIND 512 */ 513 JNIEXPORT int JNICALL 514 NET_WinBind(int s, SOCKETADDRESS *sa, int len, jboolean exclBind) 515 { 516 if (exclBind == JNI_TRUE) 517 setExclusiveBind(s); 518 return NET_Bind(s, sa, len); 519 } 520 521 JNIEXPORT int JNICALL 522 NET_SocketClose(int fd) { 523 struct linger l = {0, 0}; 524 int ret = 0; 525 int len = sizeof (l); 526 if (getsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&l, &len) == 0) { 527 if (l.l_onoff == 0) { 528 shutdown(fd, SD_SEND); 529 } 530 } 531 ret = closesocket (fd); 532 return ret; 533 } 534 535 JNIEXPORT int JNICALL 536 NET_Timeout(int fd, long timeout) { 537 int ret; 538 fd_set tbl; 539 struct timeval t; 540 t.tv_sec = timeout / 1000; 541 t.tv_usec = (timeout % 1000) * 1000; 542 FD_ZERO(&tbl); 543 FD_SET(fd, &tbl); 544 ret = select (fd + 1, &tbl, 0, 0, &t); 545 return ret; 546 } 547 548 549 /* 550 * differs from NET_Timeout() as follows: 551 * 552 * If timeout = -1, it blocks forever. 553 * 554 * returns 1 or 2 depending if only one or both sockets 555 * fire at same time. 556 * 557 * *fdret is (one of) the active fds. If both sockets 558 * fire at same time, *fdret = fd always. 559 */ 560 JNIEXPORT int JNICALL 561 NET_Timeout2(int fd, int fd1, long timeout, int *fdret) { 562 int ret; 563 fd_set tbl; 564 struct timeval t, *tP = &t; 565 if (timeout == -1) { 566 tP = 0; 567 } else { 568 t.tv_sec = timeout / 1000; 569 t.tv_usec = (timeout % 1000) * 1000; 570 } 571 FD_ZERO(&tbl); 572 FD_SET(fd, &tbl); 573 FD_SET(fd1, &tbl); 574 ret = select (0, &tbl, 0, 0, tP); 575 switch (ret) { 576 case 0: 577 return 0; /* timeout */ 578 case 1: 579 if (FD_ISSET (fd, &tbl)) { 580 *fdret= fd; 581 } else { 582 *fdret= fd1; 583 } 584 return 1; 585 case 2: 586 *fdret= fd; 587 return 2; 588 } 589 return -1; 590 } 591 592 593 void dumpAddr (char *str, void *addr) { 594 struct sockaddr_in6 *a = (struct sockaddr_in6 *)addr; 595 int family = a->sin6_family; 596 printf ("%s\n", str); 597 if (family == AF_INET) { 598 struct sockaddr_in *him = (struct sockaddr_in *)addr; 599 printf ("AF_INET: port %d: %x\n", ntohs(him->sin_port), 600 ntohl(him->sin_addr.s_addr)); 601 } else { 602 int i; 603 struct in6_addr *in = &a->sin6_addr; 604 printf ("AF_INET6 "); 605 printf ("port %d ", ntohs (a->sin6_port)); 606 printf ("flow %d ", a->sin6_flowinfo); 607 printf ("addr "); 608 for (i=0; i<7; i++) { 609 printf ("%04x:", ntohs(in->s6_words[i])); 610 } 611 printf ("%04x", ntohs(in->s6_words[7])); 612 printf (" scope %d\n", a->sin6_scope_id); 613 } 614 } 615 616 /* Macro, which cleans-up the iv6bind structure, 617 * closes the two sockets (if open), 618 * and returns SOCKET_ERROR. Used in NET_BindV6 only. 619 */ 620 621 #define CLOSE_SOCKETS_AND_RETURN do { \ 622 if (fd != -1) { \ 623 closesocket (fd); \ 624 fd = -1; \ 625 } \ 626 if (ofd != -1) { \ 627 closesocket (ofd); \ 628 ofd = -1; \ 629 } \ 630 if (close_fd != -1) { \ 631 closesocket (close_fd); \ 632 close_fd = -1; \ 633 } \ 634 if (close_ofd != -1) { \ 635 closesocket (close_ofd); \ 636 close_ofd = -1; \ 637 } \ 638 b->ipv4_fd = b->ipv6_fd = -1; \ 639 return SOCKET_ERROR; \ 640 } while(0) 641 642 /* 643 * if ipv6 is available, call NET_BindV6 to bind to the required address/port. 644 * Because the same port number may need to be reserved in both v4 and v6 space, 645 * this may require socket(s) to be re-opened. Therefore, all of this information 646 * is passed in and returned through the ipv6bind structure. 647 * 648 * If the request is to bind to a specific address, then this (by definition) means 649 * only bind in either v4 or v6, and this is just the same as normal. ie. a single 650 * call to bind() will suffice. The other socket is closed in this case. 651 * 652 * The more complicated case is when the requested address is ::0 or 0.0.0.0. 653 * 654 * Two further cases: 655 * 2. If the reqeusted port is 0 (ie. any port) then we try to bind in v4 space 656 * first with a wild-card port argument. We then try to bind in v6 space 657 * using the returned port number. If this fails, we repeat the process 658 * until a free port common to both spaces becomes available. 659 * 660 * 3. If the requested port is a specific port, then we just try to get that 661 * port in both spaces, and if it is not free in both, then the bind fails. 662 * 663 * On failure, sockets are closed and an error returned with CLOSE_SOCKETS_AND_RETURN 664 */ 665 666 JNIEXPORT int JNICALL 667 NET_BindV6(struct ipv6bind *b, jboolean exclBind) { 668 int fd=-1, ofd=-1, rv, len; 669 /* need to defer close until new sockets created */ 670 int close_fd=-1, close_ofd=-1; 671 SOCKETADDRESS oaddr; /* other address to bind */ 672 int family = b->addr->sa.sa_family; 673 int ofamily; 674 u_short port; /* requested port parameter */ 675 u_short bound_port; 676 677 if (family == AF_INET && (b->addr->sa4.sin_addr.s_addr != INADDR_ANY)) { 678 /* bind to v4 only */ 679 int ret; 680 ret = NET_WinBind((int)b->ipv4_fd, b->addr, 681 sizeof(SOCKETADDRESS), exclBind); 682 if (ret == SOCKET_ERROR) { 683 CLOSE_SOCKETS_AND_RETURN; 684 } 685 closesocket (b->ipv6_fd); 686 b->ipv6_fd = -1; 687 return 0; 688 } 689 if (family == AF_INET6 && (!IN6_IS_ADDR_ANY(&b->addr->sa6.sin6_addr))) { 690 /* bind to v6 only */ 691 int ret; 692 ret = NET_WinBind((int)b->ipv6_fd, b->addr, 693 sizeof(SOCKETADDRESS), exclBind); 694 if (ret == SOCKET_ERROR) { 695 CLOSE_SOCKETS_AND_RETURN; 696 } 697 closesocket (b->ipv4_fd); 698 b->ipv4_fd = -1; 699 return 0; 700 } 701 702 /* We need to bind on both stacks, with the same port number */ 703 704 memset (&oaddr, 0, sizeof(oaddr)); 705 if (family == AF_INET) { 706 ofamily = AF_INET6; 707 fd = (int)b->ipv4_fd; 708 ofd = (int)b->ipv6_fd; 709 port = (u_short)GET_PORT (b->addr); 710 IN6ADDR_SETANY(&oaddr.sa6); 711 oaddr.sa6.sin6_port = port; 712 } else { 713 ofamily = AF_INET; 714 ofd = (int)b->ipv4_fd; 715 fd = (int)b->ipv6_fd; 716 port = (u_short)GET_PORT (b->addr); 717 oaddr.sa4.sin_family = AF_INET; 718 oaddr.sa4.sin_port = port; 719 oaddr.sa4.sin_addr.s_addr = INADDR_ANY; 720 } 721 722 rv = NET_WinBind(fd, b->addr, sizeof(SOCKETADDRESS), exclBind); 723 if (rv == SOCKET_ERROR) { 724 CLOSE_SOCKETS_AND_RETURN; 725 } 726 727 /* get the port and set it in the other address */ 728 len = sizeof(SOCKETADDRESS); 729 if (getsockname(fd, (struct sockaddr *)b->addr, &len) == -1) { 730 CLOSE_SOCKETS_AND_RETURN; 731 } 732 bound_port = GET_PORT (b->addr); 733 SET_PORT (&oaddr, bound_port); 734 if ((rv = NET_WinBind(ofd, &oaddr, 735 sizeof(SOCKETADDRESS), exclBind)) == SOCKET_ERROR) { 736 int retries; 737 int sotype, arglen=sizeof(sotype); 738 739 /* no retries unless, the request was for any free port */ 740 741 if (port != 0) { 742 CLOSE_SOCKETS_AND_RETURN; 743 } 744 745 getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype, &arglen); 746 747 #define SOCK_RETRIES 50 748 /* 50 is an arbitrary limit, just to ensure that this 749 * cannot be an endless loop. Would expect socket creation to 750 * succeed sooner. 751 */ 752 for (retries = 0; retries < SOCK_RETRIES; retries ++) { 753 int len; 754 close_fd = fd; fd = -1; 755 close_ofd = ofd; ofd = -1; 756 b->ipv4_fd = SOCKET_ERROR; 757 b->ipv6_fd = SOCKET_ERROR; 758 759 /* create two new sockets */ 760 fd = (int)socket (family, sotype, 0); 761 if (fd == SOCKET_ERROR) { 762 CLOSE_SOCKETS_AND_RETURN; 763 } 764 ofd = (int)socket (ofamily, sotype, 0); 765 if (ofd == SOCKET_ERROR) { 766 CLOSE_SOCKETS_AND_RETURN; 767 } 768 769 /* bind random port on first socket */ 770 SET_PORT (&oaddr, 0); 771 rv = NET_WinBind(ofd, &oaddr, sizeof(SOCKETADDRESS), exclBind); 772 if (rv == SOCKET_ERROR) { 773 CLOSE_SOCKETS_AND_RETURN; 774 } 775 /* close the original pair of sockets before continuing */ 776 closesocket (close_fd); 777 closesocket (close_ofd); 778 close_fd = close_ofd = -1; 779 780 /* bind new port on second socket */ 781 len = sizeof(SOCKETADDRESS); 782 if (getsockname(ofd, &oaddr.sa, &len) == -1) { 783 CLOSE_SOCKETS_AND_RETURN; 784 } 785 bound_port = GET_PORT (&oaddr); 786 SET_PORT (b->addr, bound_port); 787 rv = NET_WinBind(fd, b->addr, sizeof(SOCKETADDRESS), exclBind); 788 789 if (rv != SOCKET_ERROR) { 790 if (family == AF_INET) { 791 b->ipv4_fd = fd; 792 b->ipv6_fd = ofd; 793 } else { 794 b->ipv4_fd = ofd; 795 b->ipv6_fd = fd; 796 } 797 return 0; 798 } 799 } 800 CLOSE_SOCKETS_AND_RETURN; 801 } 802 return 0; 803 } 804 805 /* 806 * Determine the default interface for an IPv6 address. 807 * 808 * Returns :- 809 * 0 if error 810 * > 0 interface index to use 811 */ 812 jint getDefaultIPv6Interface(JNIEnv *env, struct sockaddr_in6 *target_addr) 813 { 814 int ret; 815 DWORD b; 816 struct sockaddr_in6 route; 817 SOCKET fd = socket(AF_INET6, SOCK_STREAM, 0); 818 if (fd == INVALID_SOCKET) { 819 return 0; 820 } 821 822 ret = WSAIoctl(fd, SIO_ROUTING_INTERFACE_QUERY, 823 (void *)target_addr, sizeof(struct sockaddr_in6), 824 (void *)&route, sizeof(struct sockaddr_in6), 825 &b, 0, 0); 826 if (ret == SOCKET_ERROR) { 827 // error 828 closesocket(fd); 829 return 0; 830 } else { 831 closesocket(fd); 832 return route.sin6_scope_id; 833 } 834 } 835 836 /** 837 * Enables SIO_LOOPBACK_FAST_PATH 838 */ 839 JNIEXPORT jint JNICALL 840 NET_EnableFastTcpLoopback(int fd) { 841 int enabled = 1; 842 DWORD result_byte_count = -1; 843 int result = WSAIoctl(fd, 844 SIO_LOOPBACK_FAST_PATH, 845 &enabled, 846 sizeof(enabled), 847 NULL, 848 0, 849 &result_byte_count, 850 NULL, 851 NULL); 852 return result == SOCKET_ERROR ? WSAGetLastError() : 0; 853 } 854 855 /** 856 * See net_util.h for documentation 857 */ 858 JNIEXPORT int JNICALL 859 NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, 860 SOCKETADDRESS *sa, int *len, 861 jboolean v4MappedAddress) 862 { 863 jint family = getInetAddress_family(env, iaObj); 864 memset((char *)sa, 0, sizeof(SOCKETADDRESS)); 865 866 if (ipv6_available() && 867 !(family == java_net_InetAddress_IPv4 && 868 v4MappedAddress == JNI_FALSE)) 869 { 870 jbyte caddr[16]; 871 jint address; 872 unsigned int scopeid = 0, cached_scope_id = 0; 873 874 if (family == java_net_InetAddress_IPv4) { 875 // convert to IPv4-mapped address 876 memset((char *)caddr, 0, 16); 877 address = getInetAddress_addr(env, iaObj); 878 if (address == INADDR_ANY) { 879 /* we would always prefer IPv6 wildcard address 880 * caddr[10] = 0xff; 881 * caddr[11] = 0xff; */ 882 } else { 883 caddr[10] = 0xff; 884 caddr[11] = 0xff; 885 caddr[12] = ((address >> 24) & 0xff); 886 caddr[13] = ((address >> 16) & 0xff); 887 caddr[14] = ((address >> 8) & 0xff); 888 caddr[15] = (address & 0xff); 889 } 890 } else { 891 getInet6Address_ipaddress(env, iaObj, (char *)caddr); 892 scopeid = getInet6Address_scopeid(env, iaObj); 893 cached_scope_id = (unsigned int)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID); 894 } 895 sa->sa6.sin6_port = (u_short)htons((u_short)port); 896 memcpy((void *)&sa->sa6.sin6_addr, caddr, sizeof(struct in6_addr)); 897 sa->sa6.sin6_family = AF_INET6; 898 if ((family == java_net_InetAddress_IPv6) && 899 IN6_IS_ADDR_LINKLOCAL(&sa->sa6.sin6_addr) && 900 (!scopeid && !cached_scope_id)) 901 { 902 cached_scope_id = getDefaultIPv6Interface(env, &sa->sa6); 903 (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id); 904 } 905 sa->sa6.sin6_scope_id = scopeid == 0 ? cached_scope_id : scopeid; 906 if (len != NULL) { 907 *len = sizeof(struct sockaddr_in6); 908 } 909 } else { 910 jint address; 911 if (family != java_net_InetAddress_IPv4) { 912 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Protocol family unavailable"); 913 return -1; 914 } 915 address = getInetAddress_addr(env, iaObj); 916 sa->sa4.sin_port = htons((short)port); 917 sa->sa4.sin_addr.s_addr = (u_long)htonl(address); 918 sa->sa4.sin_family = AF_INET; 919 if (len != NULL) { 920 *len = sizeof(struct sockaddr_in); 921 } 922 } 923 return 0; 924 } 925 926 int 927 NET_IsIPv4Mapped(jbyte* caddr) { 928 int i; 929 for (i = 0; i < 10; i++) { 930 if (caddr[i] != 0x00) { 931 return 0; /* false */ 932 } 933 } 934 935 if (((caddr[10] & 0xff) == 0xff) && ((caddr[11] & 0xff) == 0xff)) { 936 return 1; /* true */ 937 } 938 return 0; /* false */ 939 } 940 941 int 942 NET_IPv4MappedToIPv4(jbyte* caddr) { 943 return ((caddr[12] & 0xff) << 24) | ((caddr[13] & 0xff) << 16) | ((caddr[14] & 0xff) << 8) 944 | (caddr[15] & 0xff); 945 } 946 947 int 948 NET_IsEqual(jbyte* caddr1, jbyte* caddr2) { 949 int i; 950 for (i = 0; i < 16; i++) { 951 if (caddr1[i] != caddr2[i]) { 952 return 0; /* false */ 953 } 954 } 955 return 1; 956 } 957 958 /** 959 * Wrapper for select/poll with timeout on a single file descriptor. 960 * 961 * flags (defined in net_util_md.h can be any combination of 962 * NET_WAIT_READ, NET_WAIT_WRITE & NET_WAIT_CONNECT. 963 * 964 * The function will return when either the socket is ready for one 965 * of the specified operation or the timeout expired. 966 * 967 * It returns the time left from the timeout, or -1 if it expired. 968 */ 969 970 JNIEXPORT jint JNICALL 971 NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout) 972 { 973 jlong prevTime = JVM_CurrentTimeMillis(env, 0); 974 jint read_rv; 975 976 while (1) { 977 jlong newTime; 978 fd_set rd, wr, ex; 979 struct timeval t; 980 981 t.tv_sec = timeout / 1000; 982 t.tv_usec = (timeout % 1000) * 1000; 983 984 FD_ZERO(&rd); 985 FD_ZERO(&wr); 986 FD_ZERO(&ex); 987 if (flags & NET_WAIT_READ) { 988 FD_SET(fd, &rd); 989 } 990 if (flags & NET_WAIT_WRITE) { 991 FD_SET(fd, &wr); 992 } 993 if (flags & NET_WAIT_CONNECT) { 994 FD_SET(fd, &wr); 995 FD_SET(fd, &ex); 996 } 997 998 errno = 0; 999 read_rv = select(fd+1, &rd, &wr, &ex, &t); 1000 1001 newTime = JVM_CurrentTimeMillis(env, 0); 1002 timeout -= (jint)(newTime - prevTime); 1003 if (timeout <= 0) { 1004 return read_rv > 0 ? 0 : -1; 1005 } 1006 newTime = prevTime; 1007 1008 if (read_rv > 0) { 1009 break; 1010 } 1011 1012 1013 } /* while */ 1014 1015 return timeout; 1016 } 1017 1018 int NET_Socket (int domain, int type, int protocol) { 1019 SOCKET sock; 1020 sock = socket (domain, type, protocol); 1021 if (sock != INVALID_SOCKET) { 1022 SetHandleInformation((HANDLE)(uintptr_t)sock, HANDLE_FLAG_INHERIT, FALSE); 1023 } 1024 return (int)sock; 1025 }