721
722 /* return the scope_id (interface index) of the
723 * interface corresponding to the given address
724 * returns 0 if no match found
725 */
726
727 static int getLocalScopeID (char *addr) {
728 struct localinterface *lif;
729 int i;
730 if (localifs == 0) {
731 initLocalIfs();
732 }
733 for (i=0, lif=localifs; i<nifs; i++, lif++) {
734 if (memcmp (addr, lif->localaddr, 16) == 0) {
735 return lif->index;
736 }
737 }
738 return 0;
739 }
740
741 void initLocalAddrTable () {
742 initLoopbackRoutes();
743 initLocalIfs();
744 }
745
746 #else
747
748 void initLocalAddrTable () {}
749
750 #endif
751
752 void parseExclusiveBindProperty(JNIEnv *env) {
753 #ifdef __solaris__
754 jstring s, flagSet;
755 jclass iCls;
756 jmethodID mid;
757
758 s = (*env)->NewStringUTF(env, "sun.net.useExclusiveBind");
759 CHECK_NULL(s);
760 iCls = (*env)->FindClass(env, "java/lang/System");
761 CHECK_NULL(iCls);
762 mid = (*env)->GetStaticMethodID(env, iCls, "getProperty",
763 "(Ljava/lang/String;)Ljava/lang/String;");
764 CHECK_NULL(mid);
765 flagSet = (*env)->CallStaticObjectMethod(env, iCls, mid, s);
766 if (flagSet != NULL) {
767 useExclBind = 1;
768 }
970 return 1;
971 }
972
973 /*
974 * Map the Java level socket option to the platform specific
975 * level and option name.
976 */
977 int
978 NET_MapSocketOption(jint cmd, int *level, int *optname) {
979 static struct {
980 jint cmd;
981 int level;
982 int optname;
983 } const opts[] = {
984 { java_net_SocketOptions_TCP_NODELAY, IPPROTO_TCP, TCP_NODELAY },
985 { java_net_SocketOptions_SO_OOBINLINE, SOL_SOCKET, SO_OOBINLINE },
986 { java_net_SocketOptions_SO_LINGER, SOL_SOCKET, SO_LINGER },
987 { java_net_SocketOptions_SO_SNDBUF, SOL_SOCKET, SO_SNDBUF },
988 { java_net_SocketOptions_SO_RCVBUF, SOL_SOCKET, SO_RCVBUF },
989 { java_net_SocketOptions_SO_KEEPALIVE, SOL_SOCKET, SO_KEEPALIVE },
990 { java_net_SocketOptions_SO_REUSEADDR, SOL_SOCKET, SO_REUSEADDR },
991 { java_net_SocketOptions_SO_BROADCAST, SOL_SOCKET, SO_BROADCAST },
992 { java_net_SocketOptions_IP_TOS, IPPROTO_IP, IP_TOS },
993 { java_net_SocketOptions_IP_MULTICAST_IF, IPPROTO_IP, IP_MULTICAST_IF },
994 { java_net_SocketOptions_IP_MULTICAST_IF2, IPPROTO_IP, IP_MULTICAST_IF },
995 { java_net_SocketOptions_IP_MULTICAST_LOOP, IPPROTO_IP, IP_MULTICAST_LOOP },
996 };
997
998 int i;
999
1000 /*
1001 * Different multicast options if IPv6 is enabled
1002 */
1003 #ifdef AF_INET6
1004 if (ipv6_available()) {
1005 switch (cmd) {
1006 case java_net_SocketOptions_IP_MULTICAST_IF:
1007 case java_net_SocketOptions_IP_MULTICAST_IF2:
1008 *level = IPPROTO_IPV6;
1009 *optname = IPV6_MULTICAST_IF;
1010 return 0;
1365 if (tcp_max_buf == -1) {
1366 return -1;
1367 }
1368 }
1369 init_tcp_max_buf = 1;
1370 } else if (!init_udp_max_buf && sotype == SOCK_DGRAM) {
1371 udp_max_buf = getParam("/dev/udp", "udp_max_buf");
1372 if (udp_max_buf == -1) {
1373 udp_max_buf = findMaxBuf(fd, opt, SOCK_DGRAM);
1374 if (udp_max_buf == -1) {
1375 return -1;
1376 }
1377 }
1378 init_udp_max_buf = 1;
1379 }
1380
1381 maxbuf = (sotype == SOCK_STREAM) ? tcp_max_buf : udp_max_buf;
1382 bufsize = (int *)arg;
1383 if (*bufsize > maxbuf) {
1384 *bufsize = maxbuf;
1385 }
1386 }
1387 }
1388 #endif
1389
1390 /*
1391 * On Linux the receive buffer is used for both socket
1392 * structures and the the packet payload. The implication
1393 * is that if SO_RCVBUF is too small then small packets
1394 * must be discard.
1395 */
1396 #ifdef __linux__
1397 if (level == SOL_SOCKET && opt == SO_RCVBUF) {
1398 int *bufsize = (int *)arg;
1399 if (*bufsize < 1024) {
1400 *bufsize = 1024;
1401 }
1402 }
1403 #endif
1404
|
721
722 /* return the scope_id (interface index) of the
723 * interface corresponding to the given address
724 * returns 0 if no match found
725 */
726
727 static int getLocalScopeID (char *addr) {
728 struct localinterface *lif;
729 int i;
730 if (localifs == 0) {
731 initLocalIfs();
732 }
733 for (i=0, lif=localifs; i<nifs; i++, lif++) {
734 if (memcmp (addr, lif->localaddr, 16) == 0) {
735 return lif->index;
736 }
737 }
738 return 0;
739 }
740
741 void platformInit () {
742 initLoopbackRoutes();
743 initLocalIfs();
744 }
745
746 #elif defined(_AIX)
747
748 /* Initialize stubs for blocking I/O workarounds (see src/solaris/native/java/net/linux_close.c) */
749 extern void aix_close_init();
750
751 void platformInit () {
752 aix_close_init();
753 }
754
755 #else
756
757 void platformInit () {}
758
759 #endif
760
761 void parseExclusiveBindProperty(JNIEnv *env) {
762 #ifdef __solaris__
763 jstring s, flagSet;
764 jclass iCls;
765 jmethodID mid;
766
767 s = (*env)->NewStringUTF(env, "sun.net.useExclusiveBind");
768 CHECK_NULL(s);
769 iCls = (*env)->FindClass(env, "java/lang/System");
770 CHECK_NULL(iCls);
771 mid = (*env)->GetStaticMethodID(env, iCls, "getProperty",
772 "(Ljava/lang/String;)Ljava/lang/String;");
773 CHECK_NULL(mid);
774 flagSet = (*env)->CallStaticObjectMethod(env, iCls, mid, s);
775 if (flagSet != NULL) {
776 useExclBind = 1;
777 }
979 return 1;
980 }
981
982 /*
983 * Map the Java level socket option to the platform specific
984 * level and option name.
985 */
986 int
987 NET_MapSocketOption(jint cmd, int *level, int *optname) {
988 static struct {
989 jint cmd;
990 int level;
991 int optname;
992 } const opts[] = {
993 { java_net_SocketOptions_TCP_NODELAY, IPPROTO_TCP, TCP_NODELAY },
994 { java_net_SocketOptions_SO_OOBINLINE, SOL_SOCKET, SO_OOBINLINE },
995 { java_net_SocketOptions_SO_LINGER, SOL_SOCKET, SO_LINGER },
996 { java_net_SocketOptions_SO_SNDBUF, SOL_SOCKET, SO_SNDBUF },
997 { java_net_SocketOptions_SO_RCVBUF, SOL_SOCKET, SO_RCVBUF },
998 { java_net_SocketOptions_SO_KEEPALIVE, SOL_SOCKET, SO_KEEPALIVE },
999 #if defined(_AIX)
1000 { java_net_SocketOptions_SO_REUSEADDR, SOL_SOCKET, SO_REUSEPORT },
1001 #else
1002 { java_net_SocketOptions_SO_REUSEADDR, SOL_SOCKET, SO_REUSEADDR },
1003 #endif
1004 { java_net_SocketOptions_SO_BROADCAST, SOL_SOCKET, SO_BROADCAST },
1005 { java_net_SocketOptions_IP_TOS, IPPROTO_IP, IP_TOS },
1006 { java_net_SocketOptions_IP_MULTICAST_IF, IPPROTO_IP, IP_MULTICAST_IF },
1007 { java_net_SocketOptions_IP_MULTICAST_IF2, IPPROTO_IP, IP_MULTICAST_IF },
1008 { java_net_SocketOptions_IP_MULTICAST_LOOP, IPPROTO_IP, IP_MULTICAST_LOOP },
1009 };
1010
1011 int i;
1012
1013 /*
1014 * Different multicast options if IPv6 is enabled
1015 */
1016 #ifdef AF_INET6
1017 if (ipv6_available()) {
1018 switch (cmd) {
1019 case java_net_SocketOptions_IP_MULTICAST_IF:
1020 case java_net_SocketOptions_IP_MULTICAST_IF2:
1021 *level = IPPROTO_IPV6;
1022 *optname = IPV6_MULTICAST_IF;
1023 return 0;
1378 if (tcp_max_buf == -1) {
1379 return -1;
1380 }
1381 }
1382 init_tcp_max_buf = 1;
1383 } else if (!init_udp_max_buf && sotype == SOCK_DGRAM) {
1384 udp_max_buf = getParam("/dev/udp", "udp_max_buf");
1385 if (udp_max_buf == -1) {
1386 udp_max_buf = findMaxBuf(fd, opt, SOCK_DGRAM);
1387 if (udp_max_buf == -1) {
1388 return -1;
1389 }
1390 }
1391 init_udp_max_buf = 1;
1392 }
1393
1394 maxbuf = (sotype == SOCK_STREAM) ? tcp_max_buf : udp_max_buf;
1395 bufsize = (int *)arg;
1396 if (*bufsize > maxbuf) {
1397 *bufsize = maxbuf;
1398 }
1399 }
1400 }
1401 #endif
1402
1403 #ifdef _AIX
1404 if (level == SOL_SOCKET) {
1405 if (opt == SO_SNDBUF || opt == SO_RCVBUF) {
1406 /*
1407 * Just try to set the requested size. If it fails we will leave the
1408 * socket option as is. Setting the buffer size means only a hint in
1409 * the jse2/java software layer, see javadoc. In the previous
1410 * solution the buffer has always been truncated to a length of
1411 * 0x100000 Byte, even if the technical limit has not been reached.
1412 * This kind of absolute truncation was unexpected in the jck tests.
1413 */
1414 int ret = setsockopt(fd, level, opt, arg, len);
1415 if ((ret == 0) || (ret == -1 && errno == ENOBUFS)) {
1416 // Accept failure because of insufficient buffer memory resources.
1417 return 0;
1418 } else {
1419 // Deliver all other kinds of errors.
1420 return ret;
1421 }
1422 }
1423 }
1424 #endif
1425
1426 /*
1427 * On Linux the receive buffer is used for both socket
1428 * structures and the the packet payload. The implication
1429 * is that if SO_RCVBUF is too small then small packets
1430 * must be discard.
1431 */
1432 #ifdef __linux__
1433 if (level == SOL_SOCKET && opt == SO_RCVBUF) {
1434 int *bufsize = (int *)arg;
1435 if (*bufsize < 1024) {
1436 *bufsize = 1024;
1437 }
1438 }
1439 #endif
1440
|