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