src/solaris/native/java/net/net_util_md.c

Print this page
rev 8975 : 8031581: PPC64: Addons and fixes for AIX to pass the jdk regression tests


 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;


1268     return rv;
1269 }
1270 
1271 /*
1272  * Wrapper for setsockopt system routine - performs any
1273  * necessary pre/post processing to deal with OS specific
1274  * issue :-
1275  *
1276  * On Solaris need to limit the suggested value for SO_SNDBUF
1277  * and SO_RCVBUF to the kernel configured limit
1278  *
1279  * For IP_TOS socket option need to mask off bits as this
1280  * aren't automatically masked by the kernel and results in
1281  * an error. In addition IP_TOS is a NOOP with IPv6 as it
1282  * should be setup as connection time.
1283  */
1284 int
1285 NET_SetSockOpt(int fd, int level, int  opt, const void *arg,
1286                int len)
1287 {

1288 #ifndef IPTOS_TOS_MASK
1289 #define IPTOS_TOS_MASK 0x1e
1290 #endif
1291 #ifndef IPTOS_PREC_MASK
1292 #define IPTOS_PREC_MASK 0xe0
1293 #endif
1294 
1295 #if defined(_ALLBSD_SOURCE)
1296 #if defined(KIPC_MAXSOCKBUF)
1297     int mib[3];
1298     size_t rlen;
1299 #endif
1300 
1301     int *bufsize;
1302 
1303 #ifdef __APPLE__
1304     static int maxsockbuf = -1;
1305 #else
1306     static long maxsockbuf = -1;
1307 #endif
1308 
1309     int addopt;
1310     struct linger *ling;
1311 #endif
1312 
1313     /*
1314      * IPPROTO/IP_TOS :-
1315      * 1. IPv6 on Solaris/Mac OS: NOOP and will be set
1316      *    in flowinfo field when connecting TCP socket,
1317      *    or sending UDP packet.
1318      * 2. IPv6 on Linux: By default Linux ignores flowinfo
1319      *    field so enable IPV6_FLOWINFO_SEND so that flowinfo
1320      *    will be examined.
1321      * 3. IPv4: set socket option based on ToS and Precedence
1322      *    fields (otherwise get invalid argument)
1323      */
1324     if (level == IPPROTO_IP && opt == IP_TOS) {
1325         int *iptos;
1326 
1327 #if defined(AF_INET6) && (defined(__solaris__) || defined(MACOSX))
1328         if (ipv6_available()) {
1329             return 0;
1330         }


1462                maxsockbuf = (maxsockbuf/5)*4;
1463 #endif
1464            }
1465 #elif defined(__OpenBSD__)
1466            maxsockbuf = SB_MAX;
1467 #else
1468            maxsockbuf = 64 * 1024;      /* XXX: NetBSD */
1469 #endif
1470 
1471            bufsize = (int *)arg;
1472            if (*bufsize > maxsockbuf) {
1473                *bufsize = maxsockbuf;
1474            }
1475 
1476            if (opt == SO_RCVBUF && *bufsize < 1024) {
1477                 *bufsize = 1024;
1478            }
1479 
1480         }
1481     }

1482 

1483     /*
1484      * On Solaris, SO_REUSEADDR will allow multiple datagram
1485      * sockets to bind to the same port.  The network jck tests
1486      * for this "feature", so we need to emulate it by turning on
1487      * SO_REUSEPORT as well for that combination.
1488      */
1489     if (level == SOL_SOCKET && opt == SO_REUSEADDR) {
1490         int sotype;
1491         socklen_t arglen;
1492 
1493         arglen = sizeof(sotype);
1494         if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype, &arglen) < 0) {
1495             return -1;
1496         }
1497 
1498         if (sotype == SOCK_DGRAM) {
1499             addopt = SO_REUSEPORT;
1500             setsockopt(fd, level, addopt, arg, len);
1501         }
1502     }
1503 
1504 #endif
1505 
1506     return setsockopt(fd, level, opt, arg, len);
1507 }
1508 
1509 /*
1510  * Wrapper for bind system call - performs any necessary pre/post
1511  * processing to deal with OS specific issues :-
1512  *
1513  * Linux allows a socket to bind to 127.0.0.255 which must be
1514  * caught.
1515  *
1516  * On Solaris with IPv6 enabled we must use an exclusive
1517  * bind to guarantee a unique port number across the IPv4 and
1518  * IPv6 port spaces.
1519  *
1520  */
1521 int
1522 NET_Bind(int fd, struct sockaddr *him, int len)
1523 {


1653             FD_SET(fd, &rd);
1654           }
1655           if (flags & NET_WAIT_WRITE) {
1656             FD_SET(fd, &wr);
1657           }
1658           if (flags & NET_WAIT_CONNECT) {
1659             FD_SET(fd, &wr);
1660             FD_SET(fd, &ex);
1661           }
1662 
1663           errno = 0;
1664           read_rv = NET_Select(fd+1, &rd, &wr, &ex, &t);
1665         }
1666 #endif
1667 
1668         newTime = JVM_CurrentTimeMillis(env, 0);
1669         timeout -= (newTime - prevTime);
1670         if (timeout <= 0) {
1671           return read_rv > 0 ? 0 : -1;
1672         }
1673         newTime = prevTime;
1674 
1675         if (read_rv > 0) {
1676           break;
1677         }
1678 
1679 
1680       } /* while */
1681 
1682     return timeout;
1683 }


 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         { java_net_SocketOptions_SO_REUSEADDR,          SOL_SOCKET,     SO_REUSEADDR },

1000         { java_net_SocketOptions_SO_BROADCAST,          SOL_SOCKET,     SO_BROADCAST },
1001         { java_net_SocketOptions_IP_TOS,                IPPROTO_IP,     IP_TOS },
1002         { java_net_SocketOptions_IP_MULTICAST_IF,       IPPROTO_IP,     IP_MULTICAST_IF },
1003         { java_net_SocketOptions_IP_MULTICAST_IF2,      IPPROTO_IP,     IP_MULTICAST_IF },
1004         { java_net_SocketOptions_IP_MULTICAST_LOOP,     IPPROTO_IP,     IP_MULTICAST_LOOP },
1005     };
1006 
1007     int i;
1008 
1009     /*
1010      * Different multicast options if IPv6 is enabled
1011      */
1012 #ifdef AF_INET6
1013     if (ipv6_available()) {
1014         switch (cmd) {
1015             case java_net_SocketOptions_IP_MULTICAST_IF:
1016             case java_net_SocketOptions_IP_MULTICAST_IF2:
1017                 *level = IPPROTO_IPV6;
1018                 *optname = IPV6_MULTICAST_IF;
1019                 return 0;


1264     return rv;
1265 }
1266 
1267 /*
1268  * Wrapper for setsockopt system routine - performs any
1269  * necessary pre/post processing to deal with OS specific
1270  * issue :-
1271  *
1272  * On Solaris need to limit the suggested value for SO_SNDBUF
1273  * and SO_RCVBUF to the kernel configured limit
1274  *
1275  * For IP_TOS socket option need to mask off bits as this
1276  * aren't automatically masked by the kernel and results in
1277  * an error. In addition IP_TOS is a NOOP with IPv6 as it
1278  * should be setup as connection time.
1279  */
1280 int
1281 NET_SetSockOpt(int fd, int level, int  opt, const void *arg,
1282                int len)
1283 {
1284 
1285 #ifndef IPTOS_TOS_MASK
1286 #define IPTOS_TOS_MASK 0x1e
1287 #endif
1288 #ifndef IPTOS_PREC_MASK
1289 #define IPTOS_PREC_MASK 0xe0
1290 #endif
1291 
1292 #if defined(_ALLBSD_SOURCE)
1293 #if defined(KIPC_MAXSOCKBUF)
1294     int mib[3];
1295     size_t rlen;
1296 #endif
1297 
1298     int *bufsize;
1299 
1300 #ifdef __APPLE__
1301     static int maxsockbuf = -1;
1302 #else
1303     static long maxsockbuf = -1;
1304 #endif



1305 #endif
1306 
1307     /*
1308      * IPPROTO/IP_TOS :-
1309      * 1. IPv6 on Solaris/Mac OS: NOOP and will be set
1310      *    in flowinfo field when connecting TCP socket,
1311      *    or sending UDP packet.
1312      * 2. IPv6 on Linux: By default Linux ignores flowinfo
1313      *    field so enable IPV6_FLOWINFO_SEND so that flowinfo
1314      *    will be examined.
1315      * 3. IPv4: set socket option based on ToS and Precedence
1316      *    fields (otherwise get invalid argument)
1317      */
1318     if (level == IPPROTO_IP && opt == IP_TOS) {
1319         int *iptos;
1320 
1321 #if defined(AF_INET6) && (defined(__solaris__) || defined(MACOSX))
1322         if (ipv6_available()) {
1323             return 0;
1324         }


1456                maxsockbuf = (maxsockbuf/5)*4;
1457 #endif
1458            }
1459 #elif defined(__OpenBSD__)
1460            maxsockbuf = SB_MAX;
1461 #else
1462            maxsockbuf = 64 * 1024;      /* XXX: NetBSD */
1463 #endif
1464 
1465            bufsize = (int *)arg;
1466            if (*bufsize > maxsockbuf) {
1467                *bufsize = maxsockbuf;
1468            }
1469 
1470            if (opt == SO_RCVBUF && *bufsize < 1024) {
1471                 *bufsize = 1024;
1472            }
1473 
1474         }
1475     }
1476 #endif
1477 
1478 #if defined(_ALLBSD_SOURCE) || defined(_AIX)
1479     /*
1480      * On Solaris, SO_REUSEADDR will allow multiple datagram
1481      * sockets to bind to the same port. The network jck tests check
1482      * for this "feature", so we need to emulate it by turning on
1483      * SO_REUSEPORT as well for that combination.
1484      */
1485     if (level == SOL_SOCKET && opt == SO_REUSEADDR) {
1486         int sotype;
1487         socklen_t arglen;
1488 
1489         arglen = sizeof(sotype);
1490         if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype, &arglen) < 0) {
1491             return -1;
1492         }
1493 
1494         if (sotype == SOCK_DGRAM) {
1495             setsockopt(fd, level, SO_REUSEPORT, arg, len);

1496         }
1497     }

1498 #endif
1499 
1500     return setsockopt(fd, level, opt, arg, len);
1501 }
1502 
1503 /*
1504  * Wrapper for bind system call - performs any necessary pre/post
1505  * processing to deal with OS specific issues :-
1506  *
1507  * Linux allows a socket to bind to 127.0.0.255 which must be
1508  * caught.
1509  *
1510  * On Solaris with IPv6 enabled we must use an exclusive
1511  * bind to guarantee a unique port number across the IPv4 and
1512  * IPv6 port spaces.
1513  *
1514  */
1515 int
1516 NET_Bind(int fd, struct sockaddr *him, int len)
1517 {


1647             FD_SET(fd, &rd);
1648           }
1649           if (flags & NET_WAIT_WRITE) {
1650             FD_SET(fd, &wr);
1651           }
1652           if (flags & NET_WAIT_CONNECT) {
1653             FD_SET(fd, &wr);
1654             FD_SET(fd, &ex);
1655           }
1656 
1657           errno = 0;
1658           read_rv = NET_Select(fd+1, &rd, &wr, &ex, &t);
1659         }
1660 #endif
1661 
1662         newTime = JVM_CurrentTimeMillis(env, 0);
1663         timeout -= (newTime - prevTime);
1664         if (timeout <= 0) {
1665           return read_rv > 0 ? 0 : -1;
1666         }
1667         prevTime = newTime;
1668 
1669         if (read_rv > 0) {
1670           break;
1671         }
1672 
1673 
1674       } /* while */
1675 
1676     return timeout;
1677 }