1 /* 2 * Copyright (c) 1997, 2019, 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 <dlfcn.h> 26 #include <errno.h> 27 #include <net/if.h> 28 #include <netinet/tcp.h> // defines TCP_NODELAY 29 #include <stdlib.h> 30 #include <string.h> 31 #include <sys/ioctl.h> 32 #include <sys/time.h> 33 34 #if defined(__linux__) 35 #include <arpa/inet.h> 36 #include <net/route.h> 37 #include <sys/utsname.h> 38 #endif 39 40 #if defined(__solaris__) 41 #include <inet/nd.h> 42 #include <limits.h> 43 #include <stropts.h> 44 #include <sys/filio.h> 45 #include <sys/sockio.h> 46 #endif 47 48 #if defined(MACOSX) 49 #include <sys/sysctl.h> 50 #endif 51 52 #include "jvm.h" 53 #include "net_util.h" 54 55 #include "java_net_SocketOptions.h" 56 #include "java_net_InetAddress.h" 57 58 #if defined(__linux__) && !defined(IPV6_FLOWINFO_SEND) 59 #define IPV6_FLOWINFO_SEND 33 60 #endif 61 62 #if defined(__solaris__) && !defined(MAXINT) 63 #define MAXINT INT_MAX 64 #endif 65 66 /* 67 * EXCLBIND socket options only on Solaris 68 */ 69 #if defined(__solaris__) && !defined(TCP_EXCLBIND) 70 #define TCP_EXCLBIND 0x21 71 #endif 72 #if defined(__solaris__) && !defined(UDP_EXCLBIND) 73 #define UDP_EXCLBIND 0x0101 74 #endif 75 76 #define RESTARTABLE(_cmd, _result) do { \ 77 do { \ 78 _result = _cmd; \ 79 } while((_result == -1) && (errno == EINTR)); \ 80 } while(0) 81 82 int NET_SocketAvailable(int s, int *pbytes) { 83 int result; 84 RESTARTABLE(ioctl(s, FIONREAD, pbytes), result); 85 return result; 86 } 87 88 #ifdef __solaris__ 89 static int init_tcp_max_buf, init_udp_max_buf; 90 static int tcp_max_buf; 91 static int udp_max_buf; 92 static int useExclBind = 0; 93 94 /* 95 * Get the specified parameter from the specified driver. The value 96 * of the parameter is assumed to be an 'int'. If the parameter 97 * cannot be obtained return -1 98 */ 99 int net_getParam(char *driver, char *param) 100 { 101 struct strioctl stri; 102 char buf [64]; 103 int s; 104 int value; 105 106 s = open (driver, O_RDWR); 107 if (s < 0) { 108 return -1; 109 } 110 strncpy (buf, param, sizeof(buf)); 111 stri.ic_cmd = ND_GET; 112 stri.ic_timout = 0; 113 stri.ic_dp = buf; 114 stri.ic_len = sizeof(buf); 115 if (ioctl (s, I_STR, &stri) < 0) { 116 value = -1; 117 } else { 118 value = atoi(buf); 119 } 120 close (s); 121 return value; 122 } 123 124 /* 125 * Iterative way to find the max value that SO_SNDBUF or SO_RCVBUF 126 * for Solaris versions that do not support the ioctl() in net_getParam(). 127 * Ugly, but only called once (for each sotype). 128 * 129 * As an optimization, we make a guess using the default values for Solaris 130 * assuming they haven't been modified with ndd. 131 */ 132 133 #define MAX_TCP_GUESS 1024 * 1024 134 #define MAX_UDP_GUESS 2 * 1024 * 1024 135 136 #define FAIL_IF_NOT_ENOBUFS if (errno != ENOBUFS) return -1 137 138 static int findMaxBuf(int fd, int opt, int sotype) { 139 int a = 0; 140 int b = MAXINT; 141 int initial_guess; 142 int limit = -1; 143 144 if (sotype == SOCK_DGRAM) { 145 initial_guess = MAX_UDP_GUESS; 146 } else { 147 initial_guess = MAX_TCP_GUESS; 148 } 149 150 if (setsockopt(fd, SOL_SOCKET, opt, &initial_guess, sizeof(int)) == 0) { 151 initial_guess++; 152 if (setsockopt(fd, SOL_SOCKET, opt, &initial_guess,sizeof(int)) < 0) { 153 FAIL_IF_NOT_ENOBUFS; 154 return initial_guess - 1; 155 } 156 a = initial_guess; 157 } else { 158 FAIL_IF_NOT_ENOBUFS; 159 b = initial_guess - 1; 160 } 161 do { 162 int mid = a + (b-a)/2; 163 if (setsockopt(fd, SOL_SOCKET, opt, &mid, sizeof(int)) == 0) { 164 limit = mid; 165 a = mid + 1; 166 } else { 167 FAIL_IF_NOT_ENOBUFS; 168 b = mid - 1; 169 } 170 } while (b >= a); 171 172 return limit; 173 } 174 #endif 175 176 void 177 NET_ThrowByNameWithLastError(JNIEnv *env, const char *name, 178 const char *defaultDetail) { 179 JNU_ThrowByNameWithMessageAndLastError(env, name, defaultDetail); 180 } 181 182 void 183 NET_ThrowCurrent(JNIEnv *env, char *msg) { 184 NET_ThrowNew(env, errno, msg); 185 } 186 187 void 188 NET_ThrowNew(JNIEnv *env, int errorNumber, char *msg) { 189 char fullMsg[512]; 190 if (!msg) { 191 msg = "no further information"; 192 } 193 switch(errorNumber) { 194 case EBADF: 195 jio_snprintf(fullMsg, sizeof(fullMsg), "socket closed: %s", msg); 196 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", fullMsg); 197 break; 198 case EINTR: 199 JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", msg); 200 break; 201 default: 202 errno = errorNumber; 203 JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", msg); 204 break; 205 } 206 } 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 IPv4_supported() 218 { 219 int fd = socket(AF_INET, SOCK_STREAM, 0) ; 220 if (fd < 0) { 221 return JNI_FALSE; 222 } 223 close(fd); 224 return JNI_TRUE; 225 } 226 227 #if defined(DONT_ENABLE_IPV6) 228 jint IPv6_supported() 229 { 230 return JNI_FALSE; 231 } 232 233 #else /* !DONT_ENABLE_IPV6 */ 234 235 jint IPv6_supported() 236 { 237 int fd; 238 void *ipv6_fn; 239 SOCKETADDRESS sa; 240 socklen_t sa_len = sizeof(SOCKETADDRESS); 241 242 fd = socket(AF_INET6, SOCK_STREAM, 0) ; 243 if (fd < 0) { 244 /* 245 * TODO: We really cant tell since it may be an unrelated error 246 * for now we will assume that AF_INET6 is not available 247 */ 248 return JNI_FALSE; 249 } 250 251 /* 252 * If fd 0 is a socket it means we may have been launched from inetd or 253 * xinetd. If it's a socket then check the family - if it's an 254 * IPv4 socket then we need to disable IPv6. 255 */ 256 if (getsockname(0, &sa.sa, &sa_len) == 0) { 257 if (sa.sa.sa_family == AF_INET) { 258 close(fd); 259 return JNI_FALSE; 260 } 261 } 262 263 /** 264 * Linux - check if any interface has an IPv6 address. 265 * Don't need to parse the line - we just need an indication. 266 */ 267 #ifdef __linux__ 268 { 269 FILE *fP = fopen("/proc/net/if_inet6", "r"); 270 char buf[255]; 271 char *bufP; 272 273 if (fP == NULL) { 274 close(fd); 275 return JNI_FALSE; 276 } 277 bufP = fgets(buf, sizeof(buf), fP); 278 fclose(fP); 279 if (bufP == NULL) { 280 close(fd); 281 return JNI_FALSE; 282 } 283 } 284 #endif 285 286 /** 287 * On Solaris 8 it's possible to create INET6 sockets even 288 * though IPv6 is not enabled on all interfaces. Thus we 289 * query the number of IPv6 addresses to verify that IPv6 290 * has been configured on at least one interface. 291 * 292 * On Linux it doesn't matter - if IPv6 is built-in the 293 * kernel then IPv6 addresses will be bound automatically 294 * to all interfaces. 295 */ 296 #ifdef __solaris__ 297 298 #ifdef SIOCGLIFNUM 299 { 300 struct lifnum numifs; 301 302 numifs.lifn_family = AF_INET6; 303 numifs.lifn_flags = 0; 304 if (ioctl(fd, SIOCGLIFNUM, (char *)&numifs) < 0) { 305 /** 306 * SIOCGLIFNUM failed - assume IPv6 not configured 307 */ 308 close(fd); 309 return JNI_FALSE; 310 } 311 /** 312 * If no IPv6 addresses then return false. If count > 0 313 * it's possible that all IPv6 addresses are "down" but 314 * that's okay as they may be brought "up" while the 315 * VM is running. 316 */ 317 if (numifs.lifn_count == 0) { 318 close(fd); 319 return JNI_FALSE; 320 } 321 } 322 #else 323 /* SIOCGLIFNUM not defined in build environment ??? */ 324 close(fd); 325 return JNI_FALSE; 326 #endif 327 328 #endif /* __solaris */ 329 330 /* 331 * OK we may have the stack available in the kernel, 332 * we should also check if the APIs are available. 333 */ 334 ipv6_fn = JVM_FindLibraryEntry(RTLD_DEFAULT, "inet_pton"); 335 close(fd); 336 if (ipv6_fn == NULL ) { 337 return JNI_FALSE; 338 } else { 339 return JNI_TRUE; 340 } 341 } 342 #endif /* DONT_ENABLE_IPV6 */ 343 344 jint reuseport_supported() 345 { 346 /* Do a simple dummy call, and try to figure out from that */ 347 int one = 1; 348 int rv, s; 349 s = socket(PF_INET, SOCK_STREAM, 0); 350 if (s < 0) { 351 return JNI_FALSE; 352 } 353 rv = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (void *)&one, sizeof(one)); 354 if (rv != 0) { 355 rv = JNI_FALSE; 356 } else { 357 rv = JNI_TRUE; 358 } 359 close(s); 360 return rv; 361 } 362 363 void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, 364 const char* hostname, 365 int gai_error) 366 { 367 int size; 368 char *buf; 369 const char *format = "%s: %s"; 370 const char *error_string = gai_strerror(gai_error); 371 if (error_string == NULL) 372 error_string = "unknown error"; 373 374 size = strlen(format) + strlen(hostname) + strlen(error_string) + 2; 375 buf = (char *) malloc(size); 376 if (buf) { 377 jstring s; 378 sprintf(buf, format, hostname, error_string); 379 s = JNU_NewStringPlatform(env, buf); 380 if (s != NULL) { 381 jobject x = JNU_NewObjectByName(env, 382 "java/net/UnknownHostException", 383 "(Ljava/lang/String;)V", s); 384 if (x != NULL) 385 (*env)->Throw(env, x); 386 } 387 free(buf); 388 } 389 } 390 391 #if defined(_AIX) 392 393 /* Initialize stubs for blocking I/O workarounds (see src/solaris/native/java/net/linux_close.c) */ 394 extern void aix_close_init(); 395 396 void platformInit () { 397 aix_close_init(); 398 } 399 400 #else 401 402 void platformInit () {} 403 404 #endif 405 406 void parseExclusiveBindProperty(JNIEnv *env) { 407 #ifdef __solaris__ 408 jstring s, flagSet; 409 jclass iCls; 410 jmethodID mid; 411 412 s = (*env)->NewStringUTF(env, "sun.net.useExclusiveBind"); 413 CHECK_NULL(s); 414 iCls = (*env)->FindClass(env, "java/lang/System"); 415 CHECK_NULL(iCls); 416 mid = (*env)->GetStaticMethodID(env, iCls, "getProperty", 417 "(Ljava/lang/String;)Ljava/lang/String;"); 418 CHECK_NULL(mid); 419 flagSet = (*env)->CallStaticObjectMethod(env, iCls, mid, s); 420 if (flagSet != NULL) { 421 useExclBind = 1; 422 } 423 #endif 424 } 425 426 JNIEXPORT jint JNICALL 427 NET_EnableFastTcpLoopback(int fd) { 428 return 0; 429 } 430 431 /** 432 * See net_util.h for documentation 433 */ 434 JNIEXPORT int JNICALL 435 NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, 436 SOCKETADDRESS *sa, int *len, 437 jboolean v4MappedAddress) 438 { 439 jint family = getInetAddress_family(env, iaObj); 440 JNU_CHECK_EXCEPTION_RETURN(env, -1); 441 memset((char *)sa, 0, sizeof(SOCKETADDRESS)); 442 443 if (ipv6_available() && 444 !(family == java_net_InetAddress_IPv4 && 445 v4MappedAddress == JNI_FALSE)) 446 { 447 jbyte caddr[16]; 448 jint address; 449 450 if (family == java_net_InetAddress_IPv4) { 451 // convert to IPv4-mapped address 452 memset((char *)caddr, 0, 16); 453 address = getInetAddress_addr(env, iaObj); 454 JNU_CHECK_EXCEPTION_RETURN(env, -1); 455 if (address == INADDR_ANY) { 456 /* we would always prefer IPv6 wildcard address 457 * caddr[10] = 0xff; 458 * caddr[11] = 0xff; */ 459 } else { 460 caddr[10] = 0xff; 461 caddr[11] = 0xff; 462 caddr[12] = ((address >> 24) & 0xff); 463 caddr[13] = ((address >> 16) & 0xff); 464 caddr[14] = ((address >> 8) & 0xff); 465 caddr[15] = (address & 0xff); 466 } 467 } else { 468 getInet6Address_ipaddress(env, iaObj, (char *)caddr); 469 } 470 sa->sa6.sin6_port = htons(port); 471 memcpy((void *)&sa->sa6.sin6_addr, caddr, sizeof(struct in6_addr)); 472 sa->sa6.sin6_family = AF_INET6; 473 if (len != NULL) { 474 *len = sizeof(struct sockaddr_in6); 475 } 476 477 /* handle scope_id */ 478 if (family != java_net_InetAddress_IPv4) { 479 if (ia6_scopeidID) { 480 sa->sa6.sin6_scope_id = getInet6Address_scopeid(env, iaObj); 481 } 482 } 483 } else { 484 jint address; 485 if (family != java_net_InetAddress_IPv4) { 486 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Protocol family unavailable"); 487 return -1; 488 } 489 address = getInetAddress_addr(env, iaObj); 490 JNU_CHECK_EXCEPTION_RETURN(env, -1); 491 sa->sa4.sin_port = htons(port); 492 sa->sa4.sin_addr.s_addr = htonl(address); 493 sa->sa4.sin_family = AF_INET; 494 if (len != NULL) { 495 *len = sizeof(struct sockaddr_in); 496 } 497 } 498 return 0; 499 } 500 501 void 502 NET_SetTrafficClass(SOCKETADDRESS *sa, int trafficClass) { 503 if (sa->sa.sa_family == AF_INET6) { 504 sa->sa6.sin6_flowinfo = htonl((trafficClass & 0xff) << 20); 505 } 506 } 507 508 int 509 NET_IsIPv4Mapped(jbyte* caddr) { 510 int i; 511 for (i = 0; i < 10; i++) { 512 if (caddr[i] != 0x00) { 513 return 0; /* false */ 514 } 515 } 516 517 if (((caddr[10] & 0xff) == 0xff) && ((caddr[11] & 0xff) == 0xff)) { 518 return 1; /* true */ 519 } 520 return 0; /* false */ 521 } 522 523 int 524 NET_IPv4MappedToIPv4(jbyte* caddr) { 525 return ((caddr[12] & 0xff) << 24) | ((caddr[13] & 0xff) << 16) | ((caddr[14] & 0xff) << 8) 526 | (caddr[15] & 0xff); 527 } 528 529 int 530 NET_IsEqual(jbyte* caddr1, jbyte* caddr2) { 531 int i; 532 for (i = 0; i < 16; i++) { 533 if (caddr1[i] != caddr2[i]) { 534 return 0; /* false */ 535 } 536 } 537 return 1; 538 } 539 540 int NET_IsZeroAddr(jbyte* caddr) { 541 int i; 542 for (i = 0; i < 16; i++) { 543 if (caddr[i] != 0) { 544 return 0; 545 } 546 } 547 return 1; 548 } 549 550 /* 551 * Map the Java level socket option to the platform specific 552 * level and option name. 553 */ 554 int 555 NET_MapSocketOption(jint cmd, int *level, int *optname) { 556 static struct { 557 jint cmd; 558 int level; 559 int optname; 560 } const opts[] = { 561 { java_net_SocketOptions_TCP_NODELAY, IPPROTO_TCP, TCP_NODELAY }, 562 { java_net_SocketOptions_SO_OOBINLINE, SOL_SOCKET, SO_OOBINLINE }, 563 { java_net_SocketOptions_SO_LINGER, SOL_SOCKET, SO_LINGER }, 564 { java_net_SocketOptions_SO_SNDBUF, SOL_SOCKET, SO_SNDBUF }, 565 { java_net_SocketOptions_SO_RCVBUF, SOL_SOCKET, SO_RCVBUF }, 566 { java_net_SocketOptions_SO_KEEPALIVE, SOL_SOCKET, SO_KEEPALIVE }, 567 { java_net_SocketOptions_SO_REUSEADDR, SOL_SOCKET, SO_REUSEADDR }, 568 { java_net_SocketOptions_SO_REUSEPORT, SOL_SOCKET, SO_REUSEPORT }, 569 { java_net_SocketOptions_SO_BROADCAST, SOL_SOCKET, SO_BROADCAST }, 570 { java_net_SocketOptions_IP_TOS, IPPROTO_IP, IP_TOS }, 571 { java_net_SocketOptions_IP_MULTICAST_IF, IPPROTO_IP, IP_MULTICAST_IF }, 572 { java_net_SocketOptions_IP_MULTICAST_IF2, IPPROTO_IP, IP_MULTICAST_IF }, 573 { java_net_SocketOptions_IP_MULTICAST_LOOP, IPPROTO_IP, IP_MULTICAST_LOOP }, 574 }; 575 576 int i; 577 578 if (ipv6_available()) { 579 switch (cmd) { 580 // Different multicast options if IPv6 is enabled 581 case java_net_SocketOptions_IP_MULTICAST_IF: 582 case java_net_SocketOptions_IP_MULTICAST_IF2: 583 *level = IPPROTO_IPV6; 584 *optname = IPV6_MULTICAST_IF; 585 return 0; 586 587 case java_net_SocketOptions_IP_MULTICAST_LOOP: 588 *level = IPPROTO_IPV6; 589 *optname = IPV6_MULTICAST_LOOP; 590 return 0; 591 #if (defined(__solaris__) || defined(MACOSX)) 592 // Map IP_TOS request to IPV6_TCLASS 593 case java_net_SocketOptions_IP_TOS: 594 *level = IPPROTO_IPV6; 595 *optname = IPV6_TCLASS; 596 return 0; 597 #endif 598 } 599 } 600 601 /* 602 * Map the Java level option to the native level 603 */ 604 for (i=0; i<(int)(sizeof(opts) / sizeof(opts[0])); i++) { 605 if (cmd == opts[i].cmd) { 606 *level = opts[i].level; 607 *optname = opts[i].optname; 608 return 0; 609 } 610 } 611 612 /* not found */ 613 return -1; 614 } 615 616 /* 617 * Wrapper for getsockopt system routine - does any necessary 618 * pre/post processing to deal with OS specific oddities :- 619 * 620 * On Linux the SO_SNDBUF/SO_RCVBUF values must be post-processed 621 * to compensate for an incorrect value returned by the kernel. 622 */ 623 int 624 NET_GetSockOpt(int fd, int level, int opt, void *result, 625 int *len) 626 { 627 int rv; 628 socklen_t socklen = *len; 629 630 rv = getsockopt(fd, level, opt, result, &socklen); 631 *len = socklen; 632 633 if (rv < 0) { 634 return rv; 635 } 636 637 #ifdef __linux__ 638 /* 639 * On Linux SO_SNDBUF/SO_RCVBUF aren't symmetric. This 640 * stems from additional socket structures in the send 641 * and receive buffers. 642 */ 643 if ((level == SOL_SOCKET) && ((opt == SO_SNDBUF) 644 || (opt == SO_RCVBUF))) { 645 int n = *((int *)result); 646 n /= 2; 647 *((int *)result) = n; 648 } 649 #endif 650 651 /* Workaround for Mac OS treating linger value as 652 * signed integer 653 */ 654 #ifdef MACOSX 655 if (level == SOL_SOCKET && opt == SO_LINGER) { 656 struct linger* to_cast = (struct linger*)result; 657 to_cast->l_linger = (unsigned short)to_cast->l_linger; 658 } 659 #endif 660 return rv; 661 } 662 663 /* 664 * Wrapper for setsockopt system routine - performs any 665 * necessary pre/post processing to deal with OS specific 666 * issue :- 667 * 668 * On Solaris need to limit the suggested value for SO_SNDBUF 669 * and SO_RCVBUF to the kernel configured limit 670 * 671 * For IP_TOS socket option need to mask off bits as this 672 * aren't automatically masked by the kernel and results in 673 * an error. 674 */ 675 int 676 NET_SetSockOpt(int fd, int level, int opt, const void *arg, 677 int len) 678 { 679 680 #ifndef IPTOS_TOS_MASK 681 #define IPTOS_TOS_MASK 0x1e 682 #endif 683 #ifndef IPTOS_PREC_MASK 684 #define IPTOS_PREC_MASK 0xe0 685 #endif 686 687 #if defined(_ALLBSD_SOURCE) 688 #if defined(KIPC_MAXSOCKBUF) 689 int mib[3]; 690 size_t rlen; 691 #endif 692 693 int *bufsize; 694 695 #ifdef __APPLE__ 696 static int maxsockbuf = -1; 697 #else 698 static long maxsockbuf = -1; 699 #endif 700 #endif 701 702 /* 703 * IPPROTO/IP_TOS :- 704 * 1. IPv6 on Solaris/Mac OS: 705 * Set the TOS OR Traffic Class value to cater for 706 * IPv6 and IPv4 scenarios. 707 * 2. IPv6 on Linux: By default Linux ignores flowinfo 708 * field so enable IPV6_FLOWINFO_SEND so that flowinfo 709 * will be examined. We also set the IPv4 TOS option in this case. 710 * 3. IPv4: set socket option based on ToS and Precedence 711 * fields (otherwise get invalid argument) 712 */ 713 if (level == IPPROTO_IP && opt == IP_TOS) { 714 int *iptos; 715 716 #if defined(__linux__) 717 if (ipv6_available()) { 718 int optval = 1; 719 if (setsockopt(fd, IPPROTO_IPV6, IPV6_FLOWINFO_SEND, 720 (void *)&optval, sizeof(optval)) < 0) { 721 return -1; 722 } 723 /* 724 * Let's also set the IPV6_TCLASS flag. 725 * Linux appears to allow both IP_TOS and IPV6_TCLASS to be set 726 * This helps in mixed environments where IPv4 and IPv6 sockets 727 * are connecting. 728 */ 729 if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, 730 arg, len) < 0) { 731 return -1; 732 } 733 } 734 #endif 735 736 iptos = (int *)arg; 737 *iptos &= (IPTOS_TOS_MASK | IPTOS_PREC_MASK); 738 } 739 740 /* 741 * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris we may need to clamp 742 * the value when it exceeds the system limit. 743 */ 744 #ifdef __solaris__ 745 if (level == SOL_SOCKET) { 746 if (opt == SO_SNDBUF || opt == SO_RCVBUF) { 747 int sotype=0; 748 socklen_t arglen; 749 int *bufsize, maxbuf; 750 int ret; 751 752 /* Attempt with the original size */ 753 ret = setsockopt(fd, level, opt, arg, len); 754 if ((ret == 0) || (ret == -1 && errno != ENOBUFS)) 755 return ret; 756 757 /* Exceeded system limit so clamp and retry */ 758 759 arglen = sizeof(sotype); 760 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype, 761 &arglen) < 0) { 762 return -1; 763 } 764 765 /* 766 * We try to get tcp_maxbuf (and udp_max_buf) using 767 * an ioctl() that isn't available on all versions of Solaris. 768 * If that fails, we use the search algorithm in findMaxBuf() 769 */ 770 if (!init_tcp_max_buf && sotype == SOCK_STREAM) { 771 tcp_max_buf = net_getParam("/dev/tcp", "tcp_max_buf"); 772 if (tcp_max_buf == -1) { 773 tcp_max_buf = findMaxBuf(fd, opt, SOCK_STREAM); 774 if (tcp_max_buf == -1) { 775 return -1; 776 } 777 } 778 init_tcp_max_buf = 1; 779 } else if (!init_udp_max_buf && sotype == SOCK_DGRAM) { 780 udp_max_buf = net_getParam("/dev/udp", "udp_max_buf"); 781 if (udp_max_buf == -1) { 782 udp_max_buf = findMaxBuf(fd, opt, SOCK_DGRAM); 783 if (udp_max_buf == -1) { 784 return -1; 785 } 786 } 787 init_udp_max_buf = 1; 788 } 789 790 maxbuf = (sotype == SOCK_STREAM) ? tcp_max_buf : udp_max_buf; 791 bufsize = (int *)arg; 792 if (*bufsize > maxbuf) { 793 *bufsize = maxbuf; 794 } 795 } 796 } 797 #endif 798 799 #ifdef _AIX 800 if (level == SOL_SOCKET) { 801 if (opt == SO_SNDBUF || opt == SO_RCVBUF) { 802 /* 803 * Just try to set the requested size. If it fails we will leave the 804 * socket option as is. Setting the buffer size means only a hint in 805 * the jse2/java software layer, see javadoc. In the previous 806 * solution the buffer has always been truncated to a length of 807 * 0x100000 Byte, even if the technical limit has not been reached. 808 * This kind of absolute truncation was unexpected in the jck tests. 809 */ 810 int ret = setsockopt(fd, level, opt, arg, len); 811 if ((ret == 0) || (ret == -1 && errno == ENOBUFS)) { 812 // Accept failure because of insufficient buffer memory resources. 813 return 0; 814 } else { 815 // Deliver all other kinds of errors. 816 return ret; 817 } 818 } 819 } 820 #endif 821 822 /* 823 * On Linux the receive buffer is used for both socket 824 * structures and the packet payload. The implication 825 * is that if SO_RCVBUF is too small then small packets 826 * must be discarded. 827 */ 828 #ifdef __linux__ 829 if (level == SOL_SOCKET && opt == SO_RCVBUF) { 830 int *bufsize = (int *)arg; 831 if (*bufsize < 1024) { 832 *bufsize = 1024; 833 } 834 } 835 #endif 836 837 #if defined(_ALLBSD_SOURCE) 838 /* 839 * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On FreeBSD need to 840 * ensure that value is <= kern.ipc.maxsockbuf as otherwise we get 841 * an ENOBUFS error. 842 */ 843 if (level == SOL_SOCKET) { 844 if (opt == SO_SNDBUF || opt == SO_RCVBUF) { 845 #ifdef KIPC_MAXSOCKBUF 846 if (maxsockbuf == -1) { 847 mib[0] = CTL_KERN; 848 mib[1] = KERN_IPC; 849 mib[2] = KIPC_MAXSOCKBUF; 850 rlen = sizeof(maxsockbuf); 851 if (sysctl(mib, 3, &maxsockbuf, &rlen, NULL, 0) == -1) 852 maxsockbuf = 1024; 853 854 #if 1 855 /* XXXBSD: This is a hack to workaround mb_max/mb_max_adj 856 problem. It should be removed when kern.ipc.maxsockbuf 857 will be real value. */ 858 maxsockbuf = (maxsockbuf/5)*4; 859 #endif 860 } 861 #elif defined(__OpenBSD__) 862 maxsockbuf = SB_MAX; 863 #else 864 maxsockbuf = 64 * 1024; /* XXX: NetBSD */ 865 #endif 866 867 bufsize = (int *)arg; 868 if (*bufsize > maxsockbuf) { 869 *bufsize = maxsockbuf; 870 } 871 872 if (opt == SO_RCVBUF && *bufsize < 1024) { 873 *bufsize = 1024; 874 } 875 876 } 877 } 878 #endif 879 880 #if defined(_ALLBSD_SOURCE) || defined(_AIX) 881 /* 882 * On Solaris, SO_REUSEADDR will allow multiple datagram 883 * sockets to bind to the same port. The network jck tests check 884 * for this "feature", so we need to emulate it by turning on 885 * SO_REUSEPORT as well for that combination. 886 */ 887 if (level == SOL_SOCKET && opt == SO_REUSEADDR) { 888 int sotype; 889 socklen_t arglen; 890 891 arglen = sizeof(sotype); 892 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype, &arglen) < 0) { 893 return -1; 894 } 895 896 if (sotype == SOCK_DGRAM) { 897 setsockopt(fd, level, SO_REUSEPORT, arg, len); 898 } 899 } 900 #endif 901 902 return setsockopt(fd, level, opt, arg, len); 903 } 904 905 /* 906 * Wrapper for bind system call - performs any necessary pre/post 907 * processing to deal with OS specific issues :- 908 * 909 * Linux allows a socket to bind to 127.0.0.255 which must be 910 * caught. 911 * 912 * On Solaris with IPv6 enabled we must use an exclusive 913 * bind to guarantee a unique port number across the IPv4 and 914 * IPv6 port spaces. 915 * 916 */ 917 int 918 NET_Bind(int fd, SOCKETADDRESS *sa, int len) 919 { 920 #if defined(__solaris__) 921 int level = -1; 922 int exclbind = -1; 923 #endif 924 int rv; 925 int arg, alen; 926 927 #ifdef __linux__ 928 /* 929 * ## get bugId for this issue - goes back to 1.2.2 port ## 930 * ## When IPv6 is enabled this will be an IPv4-mapped 931 * ## with family set to AF_INET6 932 */ 933 if (sa->sa.sa_family == AF_INET) { 934 if ((ntohl(sa->sa4.sin_addr.s_addr) & 0x7f0000ff) == 0x7f0000ff) { 935 errno = EADDRNOTAVAIL; 936 return -1; 937 } 938 } 939 #endif 940 941 #if defined(__solaris__) 942 /* 943 * Solaris has separate IPv4 and IPv6 port spaces so we 944 * use an exclusive bind when SO_REUSEADDR is not used to 945 * give the illusion of a unified port space. 946 * This also avoids problems with IPv6 sockets connecting 947 * to IPv4 mapped addresses whereby the socket conversion 948 * results in a late bind that fails because the 949 * corresponding IPv4 port is in use. 950 */ 951 alen = sizeof(arg); 952 953 if (useExclBind || 954 getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&arg, &alen) == 0) 955 { 956 if (useExclBind || arg == 0) { 957 /* 958 * SO_REUSEADDR is disabled or sun.net.useExclusiveBind 959 * property is true so enable TCP_EXCLBIND or 960 * UDP_EXCLBIND 961 */ 962 alen = sizeof(arg); 963 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&arg, &alen) == 0) 964 { 965 if (arg == SOCK_STREAM) { 966 level = IPPROTO_TCP; 967 exclbind = TCP_EXCLBIND; 968 } else { 969 level = IPPROTO_UDP; 970 exclbind = UDP_EXCLBIND; 971 } 972 } 973 974 arg = 1; 975 setsockopt(fd, level, exclbind, (char *)&arg, sizeof(arg)); 976 } 977 } 978 979 #endif 980 981 rv = bind(fd, &sa->sa, len); 982 983 #if defined(__solaris__) 984 if (rv < 0) { 985 int en = errno; 986 /* Restore *_EXCLBIND if the bind fails */ 987 if (exclbind != -1) { 988 int arg = 0; 989 setsockopt(fd, level, exclbind, (char *)&arg, 990 sizeof(arg)); 991 } 992 errno = en; 993 } 994 #endif 995 996 return rv; 997 } 998 999 /** 1000 * Wrapper for poll with timeout on a single file descriptor. 1001 * 1002 * flags (defined in net_util_md.h can be any combination of 1003 * NET_WAIT_READ, NET_WAIT_WRITE & NET_WAIT_CONNECT. 1004 * 1005 * The function will return when either the socket is ready for one 1006 * of the specified operations or the timeout expired. 1007 * 1008 * It returns the time left from the timeout (possibly 0), or -1 if it expired. 1009 */ 1010 1011 jint 1012 NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout) 1013 { 1014 jlong prevNanoTime = JVM_NanoTime(env, 0); 1015 jlong nanoTimeout = (jlong) timeout * NET_NSEC_PER_MSEC; 1016 jint read_rv; 1017 1018 while (1) { 1019 jlong newNanoTime; 1020 struct pollfd pfd; 1021 pfd.fd = fd; 1022 pfd.events = 0; 1023 if (flags & NET_WAIT_READ) 1024 pfd.events |= POLLIN; 1025 if (flags & NET_WAIT_WRITE) 1026 pfd.events |= POLLOUT; 1027 if (flags & NET_WAIT_CONNECT) 1028 pfd.events |= POLLOUT; 1029 1030 errno = 0; 1031 read_rv = NET_Poll(&pfd, 1, nanoTimeout / NET_NSEC_PER_MSEC); 1032 1033 newNanoTime = JVM_NanoTime(env, 0); 1034 nanoTimeout -= (newNanoTime - prevNanoTime); 1035 if (nanoTimeout < NET_NSEC_PER_MSEC) { 1036 return read_rv > 0 ? 0 : -1; 1037 } 1038 prevNanoTime = newNanoTime; 1039 1040 if (read_rv > 0) { 1041 break; 1042 } 1043 } /* while */ 1044 return (nanoTimeout / NET_NSEC_PER_MSEC); 1045 }