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 <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 void setDefaultScopeID(JNIEnv *env, struct sockaddr *him) 77 { 78 #ifdef MACOSX 79 static jclass ni_class = NULL; 80 static jfieldID ni_defaultIndexID; 81 if (ni_class == NULL) { 82 jclass c = (*env)->FindClass(env, "java/net/NetworkInterface"); 83 CHECK_NULL(c); 84 c = (*env)->NewGlobalRef(env, c); 85 CHECK_NULL(c); 86 ni_defaultIndexID = (*env)->GetStaticFieldID(env, c, "defaultIndex", "I"); 87 CHECK_NULL(ni_defaultIndexID); 88 ni_class = c; 89 } 90 int defaultIndex; 91 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)him; 92 if (sin6->sin6_family == AF_INET6 && (sin6->sin6_scope_id == 0) && 93 (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || 94 IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) { 95 defaultIndex = (*env)->GetStaticIntField(env, ni_class, 96 ni_defaultIndexID); 97 sin6->sin6_scope_id = defaultIndex; 98 } 99 #endif 100 } 101 102 int getDefaultScopeID(JNIEnv *env) { 103 int defaultIndex = 0; 104 static jclass ni_class = NULL; 105 static jfieldID ni_defaultIndexID; 106 if (ni_class == NULL) { 107 jclass c = (*env)->FindClass(env, "java/net/NetworkInterface"); 108 CHECK_NULL_RETURN(c, 0); 109 c = (*env)->NewGlobalRef(env, c); 110 CHECK_NULL_RETURN(c, 0); 111 ni_defaultIndexID = (*env)->GetStaticFieldID(env, c, "defaultIndex", "I"); 112 CHECK_NULL_RETURN(ni_defaultIndexID, 0); 113 ni_class = c; 114 } 115 defaultIndex = (*env)->GetStaticIntField(env, ni_class, 116 ni_defaultIndexID); 117 return defaultIndex; 118 } 119 120 #define RESTARTABLE(_cmd, _result) do { \ 121 do { \ 122 _result = _cmd; \ 123 } while((_result == -1) && (errno == EINTR)); \ 124 } while(0) 125 126 int NET_SocketAvailable(int s, jint *pbytes) { 127 int result; 128 RESTARTABLE(ioctl(s, FIONREAD, pbytes), result); 129 // note: ioctl can return 0 when successful, NET_SocketAvailable 130 // is expected to return 0 on failure and 1 on success. 131 return (result == -1) ? 0 : 1; 132 } 133 134 #ifdef __solaris__ 135 static int init_tcp_max_buf, init_udp_max_buf; 136 static int tcp_max_buf; 137 static int udp_max_buf; 138 static int useExclBind = 0; 139 140 /* 141 * Get the specified parameter from the specified driver. The value 142 * of the parameter is assumed to be an 'int'. If the parameter 143 * cannot be obtained return -1 144 */ 145 int net_getParam(char *driver, char *param) 146 { 147 struct strioctl stri; 148 char buf [64]; 149 int s; 150 int value; 151 152 s = open (driver, O_RDWR); 153 if (s < 0) { 154 return -1; 155 } 156 strncpy (buf, param, sizeof(buf)); 157 stri.ic_cmd = ND_GET; 158 stri.ic_timout = 0; 159 stri.ic_dp = buf; 160 stri.ic_len = sizeof(buf); 161 if (ioctl (s, I_STR, &stri) < 0) { 162 value = -1; 163 } else { 164 value = atoi(buf); 165 } 166 close (s); 167 return value; 168 } 169 170 /* 171 * Iterative way to find the max value that SO_SNDBUF or SO_RCVBUF 172 * for Solaris versions that do not support the ioctl() in net_getParam(). 173 * Ugly, but only called once (for each sotype). 174 * 175 * As an optimization, we make a guess using the default values for Solaris 176 * assuming they haven't been modified with ndd. 177 */ 178 179 #define MAX_TCP_GUESS 1024 * 1024 180 #define MAX_UDP_GUESS 2 * 1024 * 1024 181 182 #define FAIL_IF_NOT_ENOBUFS if (errno != ENOBUFS) return -1 183 184 static int findMaxBuf(int fd, int opt, int sotype) { 185 int a = 0; 186 int b = MAXINT; 187 int initial_guess; 188 int limit = -1; 189 190 if (sotype == SOCK_DGRAM) { 191 initial_guess = MAX_UDP_GUESS; 192 } else { 193 initial_guess = MAX_TCP_GUESS; 194 } 195 196 if (setsockopt(fd, SOL_SOCKET, opt, &initial_guess, sizeof(int)) == 0) { 197 initial_guess++; 198 if (setsockopt(fd, SOL_SOCKET, opt, &initial_guess,sizeof(int)) < 0) { 199 FAIL_IF_NOT_ENOBUFS; 200 return initial_guess - 1; 201 } 202 a = initial_guess; 203 } else { 204 FAIL_IF_NOT_ENOBUFS; 205 b = initial_guess - 1; 206 } 207 do { 208 int mid = a + (b-a)/2; 209 if (setsockopt(fd, SOL_SOCKET, opt, &mid, sizeof(int)) == 0) { 210 limit = mid; 211 a = mid + 1; 212 } else { 213 FAIL_IF_NOT_ENOBUFS; 214 b = mid - 1; 215 } 216 } while (b >= a); 217 218 return limit; 219 } 220 #endif 221 222 #ifdef __linux__ 223 static int vinit = 0; 224 static int kernelV24 = 0; 225 static int vinit24 = 0; 226 227 int kernelIsV24 () { 228 if (!vinit24) { 229 struct utsname sysinfo; 230 if (uname(&sysinfo) == 0) { 231 sysinfo.release[3] = '\0'; 232 if (strcmp(sysinfo.release, "2.4") == 0) { 233 kernelV24 = JNI_TRUE; 234 } 235 } 236 vinit24 = 1; 237 } 238 return kernelV24; 239 } 240 #endif 241 242 void 243 NET_ThrowByNameWithLastError(JNIEnv *env, const char *name, 244 const char *defaultDetail) { 245 JNU_ThrowByNameWithMessageAndLastError(env, name, defaultDetail); 246 } 247 248 void 249 NET_ThrowCurrent(JNIEnv *env, char *msg) { 250 NET_ThrowNew(env, errno, msg); 251 } 252 253 void 254 NET_ThrowNew(JNIEnv *env, int errorNumber, char *msg) { 255 char fullMsg[512]; 256 if (!msg) { 257 msg = "no further information"; 258 } 259 switch(errorNumber) { 260 case EBADF: 261 jio_snprintf(fullMsg, sizeof(fullMsg), "socket closed: %s", msg); 262 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", fullMsg); 263 break; 264 case EINTR: 265 JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", msg); 266 break; 267 default: 268 errno = errorNumber; 269 JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", msg); 270 break; 271 } 272 } 273 274 275 jfieldID 276 NET_GetFileDescriptorID(JNIEnv *env) 277 { 278 jclass cls = (*env)->FindClass(env, "java/io/FileDescriptor"); 279 CHECK_NULL_RETURN(cls, NULL); 280 return (*env)->GetFieldID(env, cls, "fd", "I"); 281 } 282 283 #if defined(DONT_ENABLE_IPV6) 284 jint IPv6_supported() 285 { 286 return JNI_FALSE; 287 } 288 289 #else /* !DONT_ENABLE_IPV6 */ 290 291 jint IPv6_supported() 292 { 293 int fd; 294 void *ipv6_fn; 295 SOCKETADDRESS sa; 296 socklen_t sa_len = sizeof(SOCKETADDRESS); 297 298 fd = socket(AF_INET6, SOCK_STREAM, 0) ; 299 if (fd < 0) { 300 /* 301 * TODO: We really cant tell since it may be an unrelated error 302 * for now we will assume that AF_INET6 is not available 303 */ 304 return JNI_FALSE; 305 } 306 307 /* 308 * If fd 0 is a socket it means we've been launched from inetd or 309 * xinetd. If it's a socket then check the family - if it's an 310 * IPv4 socket then we need to disable IPv6. 311 */ 312 if (getsockname(0, &sa.sa, &sa_len) == 0) { 313 if (sa.sa.sa_family != AF_INET6) { 314 close(fd); 315 return JNI_FALSE; 316 } 317 } 318 319 /** 320 * Linux - check if any interface has an IPv6 address. 321 * Don't need to parse the line - we just need an indication. 322 */ 323 #ifdef __linux__ 324 { 325 FILE *fP = fopen("/proc/net/if_inet6", "r"); 326 char buf[255]; 327 char *bufP; 328 329 if (fP == NULL) { 330 close(fd); 331 return JNI_FALSE; 332 } 333 bufP = fgets(buf, sizeof(buf), fP); 334 fclose(fP); 335 if (bufP == NULL) { 336 close(fd); 337 return JNI_FALSE; 338 } 339 } 340 #endif 341 342 /** 343 * On Solaris 8 it's possible to create INET6 sockets even 344 * though IPv6 is not enabled on all interfaces. Thus we 345 * query the number of IPv6 addresses to verify that IPv6 346 * has been configured on at least one interface. 347 * 348 * On Linux it doesn't matter - if IPv6 is built-in the 349 * kernel then IPv6 addresses will be bound automatically 350 * to all interfaces. 351 */ 352 #ifdef __solaris__ 353 354 #ifdef SIOCGLIFNUM 355 { 356 struct lifnum numifs; 357 358 numifs.lifn_family = AF_INET6; 359 numifs.lifn_flags = 0; 360 if (ioctl(fd, SIOCGLIFNUM, (char *)&numifs) < 0) { 361 /** 362 * SIOCGLIFNUM failed - assume IPv6 not configured 363 */ 364 close(fd); 365 return JNI_FALSE; 366 } 367 /** 368 * If no IPv6 addresses then return false. If count > 0 369 * it's possible that all IPv6 addresses are "down" but 370 * that's okay as they may be brought "up" while the 371 * VM is running. 372 */ 373 if (numifs.lifn_count == 0) { 374 close(fd); 375 return JNI_FALSE; 376 } 377 } 378 #else 379 /* SIOCGLIFNUM not defined in build environment ??? */ 380 close(fd); 381 return JNI_FALSE; 382 #endif 383 384 #endif /* __solaris */ 385 386 /* 387 * OK we may have the stack available in the kernel, 388 * we should also check if the APIs are available. 389 */ 390 ipv6_fn = JVM_FindLibraryEntry(RTLD_DEFAULT, "inet_pton"); 391 close(fd); 392 if (ipv6_fn == NULL ) { 393 return JNI_FALSE; 394 } else { 395 return JNI_TRUE; 396 } 397 } 398 #endif /* DONT_ENABLE_IPV6 */ 399 400 jint reuseport_supported() 401 { 402 /* Do a simple dummy call, and try to figure out from that */ 403 int one = 1; 404 int rv, s; 405 s = socket(PF_INET, SOCK_STREAM, 0); 406 if (s < 0) { 407 return JNI_FALSE; 408 } 409 rv = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (void *)&one, sizeof(one)); 410 if (rv != 0) { 411 rv = JNI_FALSE; 412 } else { 413 rv = JNI_TRUE; 414 } 415 close(s); 416 return rv; 417 } 418 419 void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, 420 const char* hostname, 421 int gai_error) 422 { 423 int size; 424 char *buf; 425 const char *format = "%s: %s"; 426 const char *error_string = gai_strerror(gai_error); 427 if (error_string == NULL) 428 error_string = "unknown error"; 429 430 size = strlen(format) + strlen(hostname) + strlen(error_string) + 2; 431 buf = (char *) malloc(size); 432 if (buf) { 433 jstring s; 434 sprintf(buf, format, hostname, error_string); 435 s = JNU_NewStringPlatform(env, buf); 436 if (s != NULL) { 437 jobject x = JNU_NewObjectByName(env, 438 "java/net/UnknownHostException", 439 "(Ljava/lang/String;)V", s); 440 if (x != NULL) 441 (*env)->Throw(env, x); 442 } 443 free(buf); 444 } 445 } 446 447 #if defined(__linux__) 448 449 /* following code creates a list of addresses from the kernel 450 * routing table that are routed via the loopback address. 451 * We check all destination addresses against this table 452 * and override the scope_id field to use the relevant value for "lo" 453 * in order to work-around the Linux bug that prevents packets destined 454 * for certain local addresses from being sent via a physical interface. 455 */ 456 457 struct loopback_route { 458 struct in6_addr addr; /* destination address */ 459 int plen; /* prefix length */ 460 }; 461 462 static struct loopback_route *loRoutes = 0; 463 static int nRoutes = 0; /* number of routes */ 464 static int loRoutes_size = 16; /* initial size */ 465 static int lo_scope_id = 0; 466 467 static void initLoopbackRoutes(); 468 469 void printAddr (struct in6_addr *addr) { 470 int i; 471 for (i=0; i<16; i++) { 472 printf ("%02x", addr->s6_addr[i]); 473 } 474 printf ("\n"); 475 } 476 477 static jboolean needsLoopbackRoute (struct in6_addr* dest_addr) { 478 int byte_count; 479 int extra_bits, i; 480 struct loopback_route *ptr; 481 482 if (loRoutes == 0) { 483 initLoopbackRoutes(); 484 } 485 486 for (ptr = loRoutes, i=0; i<nRoutes; i++, ptr++) { 487 struct in6_addr *target_addr=&ptr->addr; 488 int dest_plen = ptr->plen; 489 byte_count = dest_plen >> 3; 490 extra_bits = dest_plen & 0x3; 491 492 if (byte_count > 0) { 493 if (memcmp(target_addr, dest_addr, byte_count)) { 494 continue; /* no match */ 495 } 496 } 497 498 if (extra_bits > 0) { 499 unsigned char c1 = ((unsigned char *)target_addr)[byte_count]; 500 unsigned char c2 = ((unsigned char *)&dest_addr)[byte_count]; 501 unsigned char mask = 0xff << (8 - extra_bits); 502 if ((c1 & mask) != (c2 & mask)) { 503 continue; 504 } 505 } 506 return JNI_TRUE; 507 } 508 return JNI_FALSE; 509 } 510 511 512 static void initLoopbackRoutes() { 513 FILE *f; 514 char srcp[8][5]; 515 char hopp[8][5]; 516 int dest_plen, src_plen, use, refcnt, metric; 517 unsigned long flags; 518 char dest_str[40]; 519 struct in6_addr dest_addr; 520 char device[16]; 521 struct loopback_route *loRoutesTemp; 522 523 if (loRoutes != 0) { 524 free (loRoutes); 525 } 526 loRoutes = calloc (loRoutes_size, sizeof(struct loopback_route)); 527 if (loRoutes == 0) { 528 return; 529 } 530 /* 531 * Scan /proc/net/ipv6_route looking for a matching 532 * route. 533 */ 534 if ((f = fopen("/proc/net/ipv6_route", "r")) == NULL) { 535 return ; 536 } 537 while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x " 538 "%4s%4s%4s%4s%4s%4s%4s%4s %02x " 539 "%4s%4s%4s%4s%4s%4s%4s%4s " 540 "%08x %08x %08x %08lx %8s", 541 dest_str, &dest_str[5], &dest_str[10], &dest_str[15], 542 &dest_str[20], &dest_str[25], &dest_str[30], &dest_str[35], 543 &dest_plen, 544 srcp[0], srcp[1], srcp[2], srcp[3], 545 srcp[4], srcp[5], srcp[6], srcp[7], 546 &src_plen, 547 hopp[0], hopp[1], hopp[2], hopp[3], 548 hopp[4], hopp[5], hopp[6], hopp[7], 549 &metric, &use, &refcnt, &flags, device) == 31) { 550 551 /* 552 * Some routes should be ignored 553 */ 554 if ( (dest_plen < 0 || dest_plen > 128) || 555 (src_plen != 0) || 556 (flags & (RTF_POLICY | RTF_FLOW)) || 557 ((flags & RTF_REJECT) && dest_plen == 0) ) { 558 continue; 559 } 560 561 /* 562 * Convert the destination address 563 */ 564 dest_str[4] = ':'; 565 dest_str[9] = ':'; 566 dest_str[14] = ':'; 567 dest_str[19] = ':'; 568 dest_str[24] = ':'; 569 dest_str[29] = ':'; 570 dest_str[34] = ':'; 571 dest_str[39] = '\0'; 572 573 if (inet_pton(AF_INET6, dest_str, &dest_addr) < 0) { 574 /* not an Ipv6 address */ 575 continue; 576 } 577 if (strcmp(device, "lo") != 0) { 578 /* Not a loopback route */ 579 continue; 580 } else { 581 if (nRoutes == loRoutes_size) { 582 loRoutesTemp = realloc (loRoutes, loRoutes_size * 583 sizeof (struct loopback_route) * 2); 584 585 if (loRoutesTemp == 0) { 586 free(loRoutes); 587 fclose (f); 588 return; 589 } 590 loRoutes=loRoutesTemp; 591 loRoutes_size *= 2; 592 } 593 memcpy (&loRoutes[nRoutes].addr,&dest_addr,sizeof(struct in6_addr)); 594 loRoutes[nRoutes].plen = dest_plen; 595 nRoutes ++; 596 } 597 } 598 599 fclose (f); 600 { 601 /* now find the scope_id for "lo" */ 602 603 char devname[21]; 604 char addr6p[8][5]; 605 int plen, scope, dad_status, if_idx; 606 607 if ((f = fopen("/proc/net/if_inet6", "r")) != NULL) { 608 while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n", 609 addr6p[0], addr6p[1], addr6p[2], addr6p[3], 610 addr6p[4], addr6p[5], addr6p[6], addr6p[7], 611 &if_idx, &plen, &scope, &dad_status, devname) == 13) { 612 613 if (strcmp(devname, "lo") == 0) { 614 /* 615 * Found - so just return the index 616 */ 617 fclose(f); 618 lo_scope_id = if_idx; 619 return; 620 } 621 } 622 fclose(f); 623 } 624 } 625 } 626 627 /* 628 * Following is used for binding to local addresses. Equivalent 629 * to code above, for bind(). 630 */ 631 632 struct localinterface { 633 int index; 634 char localaddr [16]; 635 }; 636 637 static struct localinterface *localifs = 0; 638 static int localifsSize = 0; /* size of array */ 639 static int nifs = 0; /* number of entries used in array */ 640 641 /* not thread safe: make sure called once from one thread */ 642 643 static void initLocalIfs () { 644 FILE *f; 645 unsigned char staddr [16]; 646 char ifname [33]; 647 struct localinterface *lif=0; 648 int index, x1, x2, x3; 649 unsigned int u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,ua,ub,uc,ud,ue,uf; 650 651 if ((f = fopen("/proc/net/if_inet6", "r")) == NULL) { 652 return ; 653 } 654 while (fscanf (f, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x " 655 "%d %x %x %x %32s",&u0,&u1,&u2,&u3,&u4,&u5,&u6,&u7, 656 &u8,&u9,&ua,&ub,&uc,&ud,&ue,&uf, 657 &index, &x1, &x2, &x3, ifname) == 21) { 658 staddr[0] = (unsigned char)u0; 659 staddr[1] = (unsigned char)u1; 660 staddr[2] = (unsigned char)u2; 661 staddr[3] = (unsigned char)u3; 662 staddr[4] = (unsigned char)u4; 663 staddr[5] = (unsigned char)u5; 664 staddr[6] = (unsigned char)u6; 665 staddr[7] = (unsigned char)u7; 666 staddr[8] = (unsigned char)u8; 667 staddr[9] = (unsigned char)u9; 668 staddr[10] = (unsigned char)ua; 669 staddr[11] = (unsigned char)ub; 670 staddr[12] = (unsigned char)uc; 671 staddr[13] = (unsigned char)ud; 672 staddr[14] = (unsigned char)ue; 673 staddr[15] = (unsigned char)uf; 674 nifs ++; 675 if (nifs > localifsSize) { 676 localifs = (struct localinterface *) realloc ( 677 localifs, sizeof (struct localinterface)* (localifsSize+5)); 678 if (localifs == 0) { 679 nifs = 0; 680 fclose (f); 681 return; 682 } 683 lif = localifs + localifsSize; 684 localifsSize += 5; 685 } else { 686 lif ++; 687 } 688 memcpy (lif->localaddr, staddr, 16); 689 lif->index = index; 690 } 691 fclose (f); 692 } 693 694 /* return the scope_id (interface index) of the 695 * interface corresponding to the given address 696 * returns 0 if no match found 697 */ 698 699 static int getLocalScopeID (char *addr) { 700 struct localinterface *lif; 701 int i; 702 if (localifs == 0) { 703 initLocalIfs(); 704 } 705 for (i=0, lif=localifs; i<nifs; i++, lif++) { 706 if (memcmp (addr, lif->localaddr, 16) == 0) { 707 return lif->index; 708 } 709 } 710 return 0; 711 } 712 713 void platformInit () { 714 initLoopbackRoutes(); 715 initLocalIfs(); 716 } 717 718 #elif defined(_AIX) 719 720 /* Initialize stubs for blocking I/O workarounds (see src/solaris/native/java/net/linux_close.c) */ 721 extern void aix_close_init(); 722 723 void platformInit () { 724 aix_close_init(); 725 } 726 727 #else 728 729 void platformInit () {} 730 731 #endif 732 733 void parseExclusiveBindProperty(JNIEnv *env) { 734 #ifdef __solaris__ 735 jstring s, flagSet; 736 jclass iCls; 737 jmethodID mid; 738 739 s = (*env)->NewStringUTF(env, "sun.net.useExclusiveBind"); 740 CHECK_NULL(s); 741 iCls = (*env)->FindClass(env, "java/lang/System"); 742 CHECK_NULL(iCls); 743 mid = (*env)->GetStaticMethodID(env, iCls, "getProperty", 744 "(Ljava/lang/String;)Ljava/lang/String;"); 745 CHECK_NULL(mid); 746 flagSet = (*env)->CallStaticObjectMethod(env, iCls, mid, s); 747 if (flagSet != NULL) { 748 useExclBind = 1; 749 } 750 #endif 751 } 752 753 JNIEXPORT jint JNICALL 754 NET_EnableFastTcpLoopback(int fd) { 755 return 0; 756 } 757 758 /** 759 * See net_util.h for documentation 760 */ 761 JNIEXPORT int JNICALL 762 NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, 763 SOCKETADDRESS *sa, int *len, 764 jboolean v4MappedAddress) 765 { 766 jint family = getInetAddress_family(env, iaObj); 767 JNU_CHECK_EXCEPTION_RETURN(env, -1); 768 memset((char *)sa, 0, sizeof(SOCKETADDRESS)); 769 770 if (ipv6_available() && 771 !(family == java_net_InetAddress_IPv4 && 772 v4MappedAddress == JNI_FALSE)) 773 { 774 jbyte caddr[16]; 775 jint address; 776 777 if (family == java_net_InetAddress_IPv4) { 778 // convert to IPv4-mapped address 779 memset((char *)caddr, 0, 16); 780 address = getInetAddress_addr(env, iaObj); 781 JNU_CHECK_EXCEPTION_RETURN(env, -1); 782 if (address == INADDR_ANY) { 783 /* we would always prefer IPv6 wildcard address 784 * caddr[10] = 0xff; 785 * caddr[11] = 0xff; */ 786 } else { 787 caddr[10] = 0xff; 788 caddr[11] = 0xff; 789 caddr[12] = ((address >> 24) & 0xff); 790 caddr[13] = ((address >> 16) & 0xff); 791 caddr[14] = ((address >> 8) & 0xff); 792 caddr[15] = (address & 0xff); 793 } 794 } else { 795 getInet6Address_ipaddress(env, iaObj, (char *)caddr); 796 } 797 sa->sa6.sin6_port = htons(port); 798 memcpy((void *)&sa->sa6.sin6_addr, caddr, sizeof(struct in6_addr)); 799 sa->sa6.sin6_family = AF_INET6; 800 if (len != NULL) { 801 *len = sizeof(struct sockaddr_in6); 802 } 803 804 #ifdef __linux__ 805 /* 806 * On Linux if we are connecting to a link-local address 807 * we need to specify the interface in the scope_id (2.4 kernel only) 808 * 809 * If the scope was cached then we use the cached value. If not cached but 810 * specified in the Inet6Address we use that, but we first check if the 811 * address needs to be routed via the loopback interface. In this case, 812 * we override the specified value with that of the loopback interface. 813 * If no cached value exists and no value was specified by user, then 814 * we try to determine a value from the routing table. In all these 815 * cases the used value is cached for further use. 816 */ 817 if (IN6_IS_ADDR_LINKLOCAL(&sa->sa6.sin6_addr)) { 818 unsigned int cached_scope_id = 0, scope_id = 0; 819 820 if (ia6_cachedscopeidID) { 821 cached_scope_id = (int)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID); 822 /* if cached value exists then use it. Otherwise, check 823 * if scope is set in the address. 824 */ 825 if (!cached_scope_id) { 826 if (ia6_scopeidID) { 827 scope_id = getInet6Address_scopeid(env, iaObj); 828 } 829 if (scope_id != 0) { 830 /* check user-specified value for loopback case 831 * that needs to be overridden 832 */ 833 if (kernelIsV24() && needsLoopbackRoute(&sa->sa6.sin6_addr)) { 834 cached_scope_id = lo_scope_id; 835 (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id); 836 } 837 } else { 838 /* 839 * Otherwise consult the IPv6 routing tables to 840 * try determine the appropriate interface. 841 */ 842 if (kernelIsV24()) { 843 cached_scope_id = getDefaultIPv6Interface(&sa->sa6.sin6_addr); 844 } else { 845 cached_scope_id = getLocalScopeID((char *)&(sa->sa6.sin6_addr)); 846 if (cached_scope_id == 0) { 847 cached_scope_id = getDefaultIPv6Interface(&sa->sa6.sin6_addr); 848 } 849 } 850 (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id); 851 } 852 } 853 } 854 855 /* 856 * If we have a scope_id use the extended form 857 * of sockaddr_in6. 858 */ 859 sa->sa6.sin6_scope_id = cached_scope_id == 0 ? scope_id : cached_scope_id; 860 } 861 #else 862 /* handle scope_id */ 863 if (family != java_net_InetAddress_IPv4) { 864 if (ia6_scopeidID) { 865 sa->sa6.sin6_scope_id = getInet6Address_scopeid(env, iaObj); 866 } 867 } 868 #endif 869 } else { 870 jint address; 871 if (family != java_net_InetAddress_IPv4) { 872 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Protocol family unavailable"); 873 return -1; 874 } 875 address = getInetAddress_addr(env, iaObj); 876 JNU_CHECK_EXCEPTION_RETURN(env, -1); 877 sa->sa4.sin_port = htons(port); 878 sa->sa4.sin_addr.s_addr = htonl(address); 879 sa->sa4.sin_family = AF_INET; 880 if (len != NULL) { 881 *len = sizeof(struct sockaddr_in); 882 } 883 } 884 return 0; 885 } 886 887 void 888 NET_SetTrafficClass(SOCKETADDRESS *sa, int trafficClass) { 889 if (sa->sa.sa_family == AF_INET6) { 890 sa->sa6.sin6_flowinfo = htonl((trafficClass & 0xff) << 20); 891 } 892 } 893 894 int 895 NET_IsIPv4Mapped(jbyte* caddr) { 896 int i; 897 for (i = 0; i < 10; i++) { 898 if (caddr[i] != 0x00) { 899 return 0; /* false */ 900 } 901 } 902 903 if (((caddr[10] & 0xff) == 0xff) && ((caddr[11] & 0xff) == 0xff)) { 904 return 1; /* true */ 905 } 906 return 0; /* false */ 907 } 908 909 int 910 NET_IPv4MappedToIPv4(jbyte* caddr) { 911 return ((caddr[12] & 0xff) << 24) | ((caddr[13] & 0xff) << 16) | ((caddr[14] & 0xff) << 8) 912 | (caddr[15] & 0xff); 913 } 914 915 int 916 NET_IsEqual(jbyte* caddr1, jbyte* caddr2) { 917 int i; 918 for (i = 0; i < 16; i++) { 919 if (caddr1[i] != caddr2[i]) { 920 return 0; /* false */ 921 } 922 } 923 return 1; 924 } 925 926 int NET_IsZeroAddr(jbyte* caddr) { 927 int i; 928 for (i = 0; i < 16; i++) { 929 if (caddr[i] != 0) { 930 return 0; 931 } 932 } 933 return 1; 934 } 935 936 /* 937 * Map the Java level socket option to the platform specific 938 * level and option name. 939 */ 940 int 941 NET_MapSocketOption(jint cmd, int *level, int *optname) { 942 static struct { 943 jint cmd; 944 int level; 945 int optname; 946 } const opts[] = { 947 { java_net_SocketOptions_TCP_NODELAY, IPPROTO_TCP, TCP_NODELAY }, 948 { java_net_SocketOptions_SO_OOBINLINE, SOL_SOCKET, SO_OOBINLINE }, 949 { java_net_SocketOptions_SO_LINGER, SOL_SOCKET, SO_LINGER }, 950 { java_net_SocketOptions_SO_SNDBUF, SOL_SOCKET, SO_SNDBUF }, 951 { java_net_SocketOptions_SO_RCVBUF, SOL_SOCKET, SO_RCVBUF }, 952 { java_net_SocketOptions_SO_KEEPALIVE, SOL_SOCKET, SO_KEEPALIVE }, 953 { java_net_SocketOptions_SO_REUSEADDR, SOL_SOCKET, SO_REUSEADDR }, 954 { java_net_SocketOptions_SO_REUSEPORT, SOL_SOCKET, SO_REUSEPORT }, 955 { java_net_SocketOptions_SO_BROADCAST, SOL_SOCKET, SO_BROADCAST }, 956 { java_net_SocketOptions_IP_TOS, IPPROTO_IP, IP_TOS }, 957 { java_net_SocketOptions_IP_MULTICAST_IF, IPPROTO_IP, IP_MULTICAST_IF }, 958 { java_net_SocketOptions_IP_MULTICAST_IF2, IPPROTO_IP, IP_MULTICAST_IF }, 959 { java_net_SocketOptions_IP_MULTICAST_LOOP, IPPROTO_IP, IP_MULTICAST_LOOP }, 960 }; 961 962 int i; 963 964 if (ipv6_available()) { 965 switch (cmd) { 966 // Different multicast options if IPv6 is enabled 967 case java_net_SocketOptions_IP_MULTICAST_IF: 968 case java_net_SocketOptions_IP_MULTICAST_IF2: 969 *level = IPPROTO_IPV6; 970 *optname = IPV6_MULTICAST_IF; 971 return 0; 972 973 case java_net_SocketOptions_IP_MULTICAST_LOOP: 974 *level = IPPROTO_IPV6; 975 *optname = IPV6_MULTICAST_LOOP; 976 return 0; 977 #if (defined(__solaris__) || defined(MACOSX)) 978 // Map IP_TOS request to IPV6_TCLASS 979 case java_net_SocketOptions_IP_TOS: 980 *level = IPPROTO_IPV6; 981 *optname = IPV6_TCLASS; 982 return 0; 983 #endif 984 } 985 } 986 987 /* 988 * Map the Java level option to the native level 989 */ 990 for (i=0; i<(int)(sizeof(opts) / sizeof(opts[0])); i++) { 991 if (cmd == opts[i].cmd) { 992 *level = opts[i].level; 993 *optname = opts[i].optname; 994 return 0; 995 } 996 } 997 998 /* not found */ 999 return -1; 1000 } 1001 1002 /* 1003 * Determine the default interface for an IPv6 address. 1004 * 1005 * 1. Scans /proc/net/ipv6_route for a matching route 1006 * (eg: fe80::/10 or a route for the specific address). 1007 * This will tell us the interface to use (eg: "eth0"). 1008 * 1009 * 2. Lookup /proc/net/if_inet6 to map the interface 1010 * name to an interface index. 1011 * 1012 * Returns :- 1013 * -1 if error 1014 * 0 if no matching interface 1015 * >1 interface index to use for the link-local address. 1016 */ 1017 #if defined(__linux__) 1018 int getDefaultIPv6Interface(struct in6_addr *target_addr) { 1019 FILE *f; 1020 char srcp[8][5]; 1021 char hopp[8][5]; 1022 int dest_plen, src_plen, use, refcnt, metric; 1023 unsigned long flags; 1024 char dest_str[40]; 1025 struct in6_addr dest_addr; 1026 char device[16]; 1027 jboolean match = JNI_FALSE; 1028 1029 /* 1030 * Scan /proc/net/ipv6_route looking for a matching 1031 * route. 1032 */ 1033 if ((f = fopen("/proc/net/ipv6_route", "r")) == NULL) { 1034 return -1; 1035 } 1036 while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x " 1037 "%4s%4s%4s%4s%4s%4s%4s%4s %02x " 1038 "%4s%4s%4s%4s%4s%4s%4s%4s " 1039 "%08x %08x %08x %08lx %8s", 1040 dest_str, &dest_str[5], &dest_str[10], &dest_str[15], 1041 &dest_str[20], &dest_str[25], &dest_str[30], &dest_str[35], 1042 &dest_plen, 1043 srcp[0], srcp[1], srcp[2], srcp[3], 1044 srcp[4], srcp[5], srcp[6], srcp[7], 1045 &src_plen, 1046 hopp[0], hopp[1], hopp[2], hopp[3], 1047 hopp[4], hopp[5], hopp[6], hopp[7], 1048 &metric, &use, &refcnt, &flags, device) == 31) { 1049 1050 /* 1051 * Some routes should be ignored 1052 */ 1053 if ( (dest_plen < 0 || dest_plen > 128) || 1054 (src_plen != 0) || 1055 (flags & (RTF_POLICY | RTF_FLOW)) || 1056 ((flags & RTF_REJECT) && dest_plen == 0) ) { 1057 continue; 1058 } 1059 1060 /* 1061 * Convert the destination address 1062 */ 1063 dest_str[4] = ':'; 1064 dest_str[9] = ':'; 1065 dest_str[14] = ':'; 1066 dest_str[19] = ':'; 1067 dest_str[24] = ':'; 1068 dest_str[29] = ':'; 1069 dest_str[34] = ':'; 1070 dest_str[39] = '\0'; 1071 1072 if (inet_pton(AF_INET6, dest_str, &dest_addr) < 0) { 1073 /* not an Ipv6 address */ 1074 continue; 1075 } else { 1076 /* 1077 * The prefix len (dest_plen) indicates the number of bits we 1078 * need to match on. 1079 * 1080 * dest_plen / 8 => number of bytes to match 1081 * dest_plen % 8 => number of additional bits to match 1082 * 1083 * eg: fe80::/10 => match 1 byte + 2 additional bits in the 1084 * the next byte. 1085 */ 1086 int byte_count = dest_plen >> 3; 1087 int extra_bits = dest_plen & 0x3; 1088 1089 if (byte_count > 0) { 1090 if (memcmp(target_addr, &dest_addr, byte_count)) { 1091 continue; /* no match */ 1092 } 1093 } 1094 1095 if (extra_bits > 0) { 1096 unsigned char c1 = ((unsigned char *)target_addr)[byte_count]; 1097 unsigned char c2 = ((unsigned char *)&dest_addr)[byte_count]; 1098 unsigned char mask = 0xff << (8 - extra_bits); 1099 if ((c1 & mask) != (c2 & mask)) { 1100 continue; 1101 } 1102 } 1103 1104 /* 1105 * We have a match 1106 */ 1107 match = JNI_TRUE; 1108 break; 1109 } 1110 } 1111 fclose(f); 1112 1113 /* 1114 * If there's a match then we lookup the interface 1115 * index. 1116 */ 1117 if (match) { 1118 char devname[21]; 1119 char addr6p[8][5]; 1120 int plen, scope, dad_status, if_idx; 1121 1122 if ((f = fopen("/proc/net/if_inet6", "r")) != NULL) { 1123 while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n", 1124 addr6p[0], addr6p[1], addr6p[2], addr6p[3], 1125 addr6p[4], addr6p[5], addr6p[6], addr6p[7], 1126 &if_idx, &plen, &scope, &dad_status, devname) == 13) { 1127 1128 if (strcmp(devname, device) == 0) { 1129 /* 1130 * Found - so just return the index 1131 */ 1132 fclose(f); 1133 return if_idx; 1134 } 1135 } 1136 fclose(f); 1137 } else { 1138 /* 1139 * Couldn't open /proc/net/if_inet6 1140 */ 1141 return -1; 1142 } 1143 } 1144 1145 /* 1146 * If we get here it means we didn't there wasn't any 1147 * route or we couldn't get the index of the interface. 1148 */ 1149 return 0; 1150 } 1151 #endif 1152 1153 1154 /* 1155 * Wrapper for getsockopt system routine - does any necessary 1156 * pre/post processing to deal with OS specific oddities :- 1157 * 1158 * On Linux the SO_SNDBUF/SO_RCVBUF values must be post-processed 1159 * to compensate for an incorrect value returned by the kernel. 1160 */ 1161 int 1162 NET_GetSockOpt(int fd, int level, int opt, void *result, 1163 int *len) 1164 { 1165 int rv; 1166 socklen_t socklen = *len; 1167 1168 rv = getsockopt(fd, level, opt, result, &socklen); 1169 *len = socklen; 1170 1171 if (rv < 0) { 1172 return rv; 1173 } 1174 1175 #ifdef __linux__ 1176 /* 1177 * On Linux SO_SNDBUF/SO_RCVBUF aren't symmetric. This 1178 * stems from additional socket structures in the send 1179 * and receive buffers. 1180 */ 1181 if ((level == SOL_SOCKET) && ((opt == SO_SNDBUF) 1182 || (opt == SO_RCVBUF))) { 1183 int n = *((int *)result); 1184 n /= 2; 1185 *((int *)result) = n; 1186 } 1187 #endif 1188 1189 /* Workaround for Mac OS treating linger value as 1190 * signed integer 1191 */ 1192 #ifdef MACOSX 1193 if (level == SOL_SOCKET && opt == SO_LINGER) { 1194 struct linger* to_cast = (struct linger*)result; 1195 to_cast->l_linger = (unsigned short)to_cast->l_linger; 1196 } 1197 #endif 1198 return rv; 1199 } 1200 1201 /* 1202 * Wrapper for setsockopt system routine - performs any 1203 * necessary pre/post processing to deal with OS specific 1204 * issue :- 1205 * 1206 * On Solaris need to limit the suggested value for SO_SNDBUF 1207 * and SO_RCVBUF to the kernel configured limit 1208 * 1209 * For IP_TOS socket option need to mask off bits as this 1210 * aren't automatically masked by the kernel and results in 1211 * an error. 1212 */ 1213 int 1214 NET_SetSockOpt(int fd, int level, int opt, const void *arg, 1215 int len) 1216 { 1217 1218 #ifndef IPTOS_TOS_MASK 1219 #define IPTOS_TOS_MASK 0x1e 1220 #endif 1221 #ifndef IPTOS_PREC_MASK 1222 #define IPTOS_PREC_MASK 0xe0 1223 #endif 1224 1225 #if defined(_ALLBSD_SOURCE) 1226 #if defined(KIPC_MAXSOCKBUF) 1227 int mib[3]; 1228 size_t rlen; 1229 #endif 1230 1231 int *bufsize; 1232 1233 #ifdef __APPLE__ 1234 static int maxsockbuf = -1; 1235 #else 1236 static long maxsockbuf = -1; 1237 #endif 1238 #endif 1239 1240 /* 1241 * IPPROTO/IP_TOS :- 1242 * 1. IPv6 on Solaris/Mac OS: 1243 * Set the TOS OR Traffic Class value to cater for 1244 * IPv6 and IPv4 scenarios. 1245 * 2. IPv6 on Linux: By default Linux ignores flowinfo 1246 * field so enable IPV6_FLOWINFO_SEND so that flowinfo 1247 * will be examined. We also set the IPv4 TOS option in this case. 1248 * 3. IPv4: set socket option based on ToS and Precedence 1249 * fields (otherwise get invalid argument) 1250 */ 1251 if (level == IPPROTO_IP && opt == IP_TOS) { 1252 int *iptos; 1253 1254 #if defined(__linux__) 1255 if (ipv6_available()) { 1256 int optval = 1; 1257 if (setsockopt(fd, IPPROTO_IPV6, IPV6_FLOWINFO_SEND, 1258 (void *)&optval, sizeof(optval)) < 0) { 1259 return -1; 1260 } 1261 /* 1262 * Let's also set the IPV6_TCLASS flag. 1263 * Linux appears to allow both IP_TOS and IPV6_TCLASS to be set 1264 * This helps in mixed environments where IPv4 and IPv6 sockets 1265 * are connecting. 1266 */ 1267 if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, 1268 arg, len) < 0) { 1269 return -1; 1270 } 1271 } 1272 #endif 1273 1274 iptos = (int *)arg; 1275 *iptos &= (IPTOS_TOS_MASK | IPTOS_PREC_MASK); 1276 } 1277 1278 /* 1279 * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris we may need to clamp 1280 * the value when it exceeds the system limit. 1281 */ 1282 #ifdef __solaris__ 1283 if (level == SOL_SOCKET) { 1284 if (opt == SO_SNDBUF || opt == SO_RCVBUF) { 1285 int sotype=0; 1286 socklen_t arglen; 1287 int *bufsize, maxbuf; 1288 int ret; 1289 1290 /* Attempt with the original size */ 1291 ret = setsockopt(fd, level, opt, arg, len); 1292 if ((ret == 0) || (ret == -1 && errno != ENOBUFS)) 1293 return ret; 1294 1295 /* Exceeded system limit so clamp and retry */ 1296 1297 arglen = sizeof(sotype); 1298 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype, 1299 &arglen) < 0) { 1300 return -1; 1301 } 1302 1303 /* 1304 * We try to get tcp_maxbuf (and udp_max_buf) using 1305 * an ioctl() that isn't available on all versions of Solaris. 1306 * If that fails, we use the search algorithm in findMaxBuf() 1307 */ 1308 if (!init_tcp_max_buf && sotype == SOCK_STREAM) { 1309 tcp_max_buf = net_getParam("/dev/tcp", "tcp_max_buf"); 1310 if (tcp_max_buf == -1) { 1311 tcp_max_buf = findMaxBuf(fd, opt, SOCK_STREAM); 1312 if (tcp_max_buf == -1) { 1313 return -1; 1314 } 1315 } 1316 init_tcp_max_buf = 1; 1317 } else if (!init_udp_max_buf && sotype == SOCK_DGRAM) { 1318 udp_max_buf = net_getParam("/dev/udp", "udp_max_buf"); 1319 if (udp_max_buf == -1) { 1320 udp_max_buf = findMaxBuf(fd, opt, SOCK_DGRAM); 1321 if (udp_max_buf == -1) { 1322 return -1; 1323 } 1324 } 1325 init_udp_max_buf = 1; 1326 } 1327 1328 maxbuf = (sotype == SOCK_STREAM) ? tcp_max_buf : udp_max_buf; 1329 bufsize = (int *)arg; 1330 if (*bufsize > maxbuf) { 1331 *bufsize = maxbuf; 1332 } 1333 } 1334 } 1335 #endif 1336 1337 #ifdef _AIX 1338 if (level == SOL_SOCKET) { 1339 if (opt == SO_SNDBUF || opt == SO_RCVBUF) { 1340 /* 1341 * Just try to set the requested size. If it fails we will leave the 1342 * socket option as is. Setting the buffer size means only a hint in 1343 * the jse2/java software layer, see javadoc. In the previous 1344 * solution the buffer has always been truncated to a length of 1345 * 0x100000 Byte, even if the technical limit has not been reached. 1346 * This kind of absolute truncation was unexpected in the jck tests. 1347 */ 1348 int ret = setsockopt(fd, level, opt, arg, len); 1349 if ((ret == 0) || (ret == -1 && errno == ENOBUFS)) { 1350 // Accept failure because of insufficient buffer memory resources. 1351 return 0; 1352 } else { 1353 // Deliver all other kinds of errors. 1354 return ret; 1355 } 1356 } 1357 } 1358 #endif 1359 1360 /* 1361 * On Linux the receive buffer is used for both socket 1362 * structures and the packet payload. The implication 1363 * is that if SO_RCVBUF is too small then small packets 1364 * must be discarded. 1365 */ 1366 #ifdef __linux__ 1367 if (level == SOL_SOCKET && opt == SO_RCVBUF) { 1368 int *bufsize = (int *)arg; 1369 if (*bufsize < 1024) { 1370 *bufsize = 1024; 1371 } 1372 } 1373 #endif 1374 1375 #if defined(_ALLBSD_SOURCE) 1376 /* 1377 * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On FreeBSD need to 1378 * ensure that value is <= kern.ipc.maxsockbuf as otherwise we get 1379 * an ENOBUFS error. 1380 */ 1381 if (level == SOL_SOCKET) { 1382 if (opt == SO_SNDBUF || opt == SO_RCVBUF) { 1383 #ifdef KIPC_MAXSOCKBUF 1384 if (maxsockbuf == -1) { 1385 mib[0] = CTL_KERN; 1386 mib[1] = KERN_IPC; 1387 mib[2] = KIPC_MAXSOCKBUF; 1388 rlen = sizeof(maxsockbuf); 1389 if (sysctl(mib, 3, &maxsockbuf, &rlen, NULL, 0) == -1) 1390 maxsockbuf = 1024; 1391 1392 #if 1 1393 /* XXXBSD: This is a hack to workaround mb_max/mb_max_adj 1394 problem. It should be removed when kern.ipc.maxsockbuf 1395 will be real value. */ 1396 maxsockbuf = (maxsockbuf/5)*4; 1397 #endif 1398 } 1399 #elif defined(__OpenBSD__) 1400 maxsockbuf = SB_MAX; 1401 #else 1402 maxsockbuf = 64 * 1024; /* XXX: NetBSD */ 1403 #endif 1404 1405 bufsize = (int *)arg; 1406 if (*bufsize > maxsockbuf) { 1407 *bufsize = maxsockbuf; 1408 } 1409 1410 if (opt == SO_RCVBUF && *bufsize < 1024) { 1411 *bufsize = 1024; 1412 } 1413 1414 } 1415 } 1416 #endif 1417 1418 #if defined(_ALLBSD_SOURCE) || defined(_AIX) 1419 /* 1420 * On Solaris, SO_REUSEADDR will allow multiple datagram 1421 * sockets to bind to the same port. The network jck tests check 1422 * for this "feature", so we need to emulate it by turning on 1423 * SO_REUSEPORT as well for that combination. 1424 */ 1425 if (level == SOL_SOCKET && opt == SO_REUSEADDR) { 1426 int sotype; 1427 socklen_t arglen; 1428 1429 arglen = sizeof(sotype); 1430 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype, &arglen) < 0) { 1431 return -1; 1432 } 1433 1434 if (sotype == SOCK_DGRAM) { 1435 setsockopt(fd, level, SO_REUSEPORT, arg, len); 1436 } 1437 } 1438 #endif 1439 1440 return setsockopt(fd, level, opt, arg, len); 1441 } 1442 1443 /* 1444 * Wrapper for bind system call - performs any necessary pre/post 1445 * processing to deal with OS specific issues :- 1446 * 1447 * Linux allows a socket to bind to 127.0.0.255 which must be 1448 * caught. 1449 * 1450 * On Solaris with IPv6 enabled we must use an exclusive 1451 * bind to guarantee a unique port number across the IPv4 and 1452 * IPv6 port spaces. 1453 * 1454 */ 1455 int 1456 NET_Bind(int fd, SOCKETADDRESS *sa, int len) 1457 { 1458 #if defined(__solaris__) 1459 int level = -1; 1460 int exclbind = -1; 1461 #endif 1462 int rv; 1463 int arg, alen; 1464 1465 #ifdef __linux__ 1466 /* 1467 * ## get bugId for this issue - goes back to 1.2.2 port ## 1468 * ## When IPv6 is enabled this will be an IPv4-mapped 1469 * ## with family set to AF_INET6 1470 */ 1471 if (sa->sa.sa_family == AF_INET) { 1472 if ((ntohl(sa->sa4.sin_addr.s_addr) & 0x7f0000ff) == 0x7f0000ff) { 1473 errno = EADDRNOTAVAIL; 1474 return -1; 1475 } 1476 } 1477 #endif 1478 1479 #if defined(__solaris__) 1480 /* 1481 * Solaris has separate IPv4 and IPv6 port spaces so we 1482 * use an exclusive bind when SO_REUSEADDR is not used to 1483 * give the illusion of a unified port space. 1484 * This also avoids problems with IPv6 sockets connecting 1485 * to IPv4 mapped addresses whereby the socket conversion 1486 * results in a late bind that fails because the 1487 * corresponding IPv4 port is in use. 1488 */ 1489 alen = sizeof(arg); 1490 1491 if (useExclBind || 1492 getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&arg, &alen) == 0) 1493 { 1494 if (useExclBind || arg == 0) { 1495 /* 1496 * SO_REUSEADDR is disabled or sun.net.useExclusiveBind 1497 * property is true so enable TCP_EXCLBIND or 1498 * UDP_EXCLBIND 1499 */ 1500 alen = sizeof(arg); 1501 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&arg, &alen) == 0) 1502 { 1503 if (arg == SOCK_STREAM) { 1504 level = IPPROTO_TCP; 1505 exclbind = TCP_EXCLBIND; 1506 } else { 1507 level = IPPROTO_UDP; 1508 exclbind = UDP_EXCLBIND; 1509 } 1510 } 1511 1512 arg = 1; 1513 setsockopt(fd, level, exclbind, (char *)&arg, sizeof(arg)); 1514 } 1515 } 1516 1517 #endif 1518 1519 rv = bind(fd, &sa->sa, len); 1520 1521 #if defined(__solaris__) 1522 if (rv < 0) { 1523 int en = errno; 1524 /* Restore *_EXCLBIND if the bind fails */ 1525 if (exclbind != -1) { 1526 int arg = 0; 1527 setsockopt(fd, level, exclbind, (char *)&arg, 1528 sizeof(arg)); 1529 } 1530 errno = en; 1531 } 1532 #endif 1533 1534 return rv; 1535 } 1536 1537 /** 1538 * Wrapper for poll with timeout on a single file descriptor. 1539 * 1540 * flags (defined in net_util_md.h can be any combination of 1541 * NET_WAIT_READ, NET_WAIT_WRITE & NET_WAIT_CONNECT. 1542 * 1543 * The function will return when either the socket is ready for one 1544 * of the specified operations or the timeout expired. 1545 * 1546 * It returns the time left from the timeout (possibly 0), or -1 if it expired. 1547 */ 1548 1549 jint 1550 NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout) 1551 { 1552 jlong prevNanoTime = JVM_NanoTime(env, 0); 1553 jlong nanoTimeout = (jlong) timeout * NET_NSEC_PER_MSEC; 1554 jint read_rv; 1555 1556 while (1) { 1557 jlong newNanoTime; 1558 struct pollfd pfd; 1559 pfd.fd = fd; 1560 pfd.events = 0; 1561 if (flags & NET_WAIT_READ) 1562 pfd.events |= POLLIN; 1563 if (flags & NET_WAIT_WRITE) 1564 pfd.events |= POLLOUT; 1565 if (flags & NET_WAIT_CONNECT) 1566 pfd.events |= POLLOUT; 1567 1568 errno = 0; 1569 read_rv = NET_Poll(&pfd, 1, nanoTimeout / NET_NSEC_PER_MSEC); 1570 1571 newNanoTime = JVM_NanoTime(env, 0); 1572 nanoTimeout -= (newNanoTime - prevNanoTime); 1573 if (nanoTimeout < NET_NSEC_PER_MSEC) { 1574 return read_rv > 0 ? 0 : -1; 1575 } 1576 prevNanoTime = newNanoTime; 1577 1578 if (read_rv > 0) { 1579 break; 1580 } 1581 } /* while */ 1582 return (nanoTimeout / NET_NSEC_PER_MSEC); 1583 }