jdk/src/windows/native/java/net/net_util_md.c
changeset 18192 fa6bd0992104
parent 16870 f35b2bd19761
child 20821 e0d0a585aa49
equal deleted inserted replaced
18191:be617b8c4427 18192:fa6bd0992104
   385 JNIEXPORT int JNICALL
   385 JNIEXPORT int JNICALL
   386 NET_SetSockOpt(int s, int level, int optname, const void *optval,
   386 NET_SetSockOpt(int s, int level, int optname, const void *optval,
   387                int optlen)
   387                int optlen)
   388 {
   388 {
   389     int rv;
   389     int rv;
       
   390     int parg;
       
   391     int plen = sizeof(parg);
   390 
   392 
   391     if (level == IPPROTO_IP && optname == IP_TOS) {
   393     if (level == IPPROTO_IP && optname == IP_TOS) {
   392         int *tos = (int *)optval;
   394         int *tos = (int *)optval;
   393         *tos &= (IPTOS_TOS_MASK | IPTOS_PREC_MASK);
   395         *tos &= (IPTOS_TOS_MASK | IPTOS_PREC_MASK);
       
   396     }
       
   397 
       
   398     if (optname == SO_REUSEADDR) {
       
   399         /*
       
   400          * Do not set SO_REUSEADDE if SO_EXCLUSIVEADDUSE is already set
       
   401          */
       
   402         rv = NET_GetSockOpt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *)&parg, &plen);
       
   403         if (rv == 0 && parg == 1) {
       
   404             return rv;
       
   405         }
   394     }
   406     }
   395 
   407 
   396     rv = setsockopt(s, level, optname, optval, optlen);
   408     rv = setsockopt(s, level, optname, optval, optlen);
   397 
   409 
   398     if (rv == SOCKET_ERROR) {
   410     if (rv == SOCKET_ERROR) {
   454 
   466 
   455     return rv;
   467     return rv;
   456 }
   468 }
   457 
   469 
   458 /*
   470 /*
       
   471  * Sets SO_ECLUSIVEADDRUSE if SO_REUSEADDR is not already set.
       
   472  */
       
   473 void setExclusiveBind(int fd) {
       
   474     int parg;
       
   475     int plen = sizeof(parg);
       
   476     int rv = 0;
       
   477     rv = NET_GetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&parg, &plen);
       
   478     if (rv == 0 && parg == 0) {
       
   479         parg = 1;
       
   480         rv = NET_SetSockOpt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char*)&parg, plen);
       
   481     }
       
   482 }
       
   483 
       
   484 /*
   459  * Wrapper for bind winsock call - transparent converts an
   485  * Wrapper for bind winsock call - transparent converts an
   460  * error related to binding to a port that has exclusive access
   486  * error related to binding to a port that has exclusive access
   461  * into an error indicating the port is in use (facilitates
   487  * into an error indicating the port is in use (facilitates
   462  * better error reporting).
   488  * better error reporting).
       
   489  *
       
   490  * Should be only called by the wrapper method NET_WinBind
   463  */
   491  */
   464 JNIEXPORT int JNICALL
   492 JNIEXPORT int JNICALL
   465 NET_Bind(int s, struct sockaddr *him, int len)
   493 NET_Bind(int s, struct sockaddr *him, int len)
   466 {
   494 {
   467     int rv = bind(s, him, len);
   495     int rv;
       
   496     rv = bind(s, him, len);
   468 
   497 
   469     if (rv == SOCKET_ERROR) {
   498     if (rv == SOCKET_ERROR) {
   470         /*
   499         /*
   471          * If bind fails with WSAEACCES it means that a privileged
   500          * If bind fails with WSAEACCES it means that a privileged
   472          * process has done an exclusive bind (NT SP4/2000/XP only).
   501          * process has done an exclusive bind (NT SP4/2000/XP only).
   475             WSASetLastError(WSAEADDRINUSE);
   504             WSASetLastError(WSAEADDRINUSE);
   476         }
   505         }
   477     }
   506     }
   478 
   507 
   479     return rv;
   508     return rv;
       
   509 }
       
   510 
       
   511 /*
       
   512  * Wrapper for NET_Bind call. Sets SO_EXCLUSIVEADDRUSE
       
   513  * if required, and then calls NET_BIND
       
   514  */
       
   515 JNIEXPORT int JNICALL
       
   516 NET_WinBind(int s, struct sockaddr *him, int len, jboolean exclBind)
       
   517 {
       
   518     if (exclBind == JNI_TRUE)
       
   519         setExclusiveBind(s);
       
   520     return NET_Bind(s, him, len);
   480 }
   521 }
   481 
   522 
   482 JNIEXPORT int JNICALL
   523 JNIEXPORT int JNICALL
   483 NET_SocketClose(int fd) {
   524 NET_SocketClose(int fd) {
   484     struct linger l;
   525     struct linger l;
   623  *
   664  *
   624  * On failure, sockets are closed and an error returned with CLOSE_SOCKETS_AND_RETURN
   665  * On failure, sockets are closed and an error returned with CLOSE_SOCKETS_AND_RETURN
   625  */
   666  */
   626 
   667 
   627 JNIEXPORT int JNICALL
   668 JNIEXPORT int JNICALL
   628 NET_BindV6(struct ipv6bind* b) {
   669 NET_BindV6(struct ipv6bind* b, jboolean exclBind) {
   629     int fd=-1, ofd=-1, rv, len;
   670     int fd=-1, ofd=-1, rv, len;
   630     /* need to defer close until new sockets created */
   671     /* need to defer close until new sockets created */
   631     int close_fd=-1, close_ofd=-1;
   672     int close_fd=-1, close_ofd=-1;
   632     SOCKETADDRESS oaddr; /* other address to bind */
   673     SOCKETADDRESS oaddr; /* other address to bind */
   633     int family = b->addr->him.sa_family;
   674     int family = b->addr->him.sa_family;
   636     u_short bound_port;
   677     u_short bound_port;
   637 
   678 
   638     if (family == AF_INET && (b->addr->him4.sin_addr.s_addr != INADDR_ANY)) {
   679     if (family == AF_INET && (b->addr->him4.sin_addr.s_addr != INADDR_ANY)) {
   639         /* bind to v4 only */
   680         /* bind to v4 only */
   640         int ret;
   681         int ret;
   641         ret = NET_Bind ((int)b->ipv4_fd, (struct sockaddr *)b->addr,
   682         ret = NET_WinBind ((int)b->ipv4_fd, (struct sockaddr *)b->addr,
   642                                 sizeof (struct sockaddr_in));
   683                                 sizeof (struct sockaddr_in), exclBind);
   643         if (ret == SOCKET_ERROR) {
   684         if (ret == SOCKET_ERROR) {
   644             CLOSE_SOCKETS_AND_RETURN;
   685             CLOSE_SOCKETS_AND_RETURN;
   645         }
   686         }
   646         closesocket (b->ipv6_fd);
   687         closesocket (b->ipv6_fd);
   647         b->ipv6_fd = -1;
   688         b->ipv6_fd = -1;
   648         return 0;
   689         return 0;
   649     }
   690     }
   650     if (family == AF_INET6 && (!IN6_IS_ADDR_ANY(&b->addr->him6.sin6_addr))) {
   691     if (family == AF_INET6 && (!IN6_IS_ADDR_ANY(&b->addr->him6.sin6_addr))) {
   651         /* bind to v6 only */
   692         /* bind to v6 only */
   652         int ret;
   693         int ret;
   653         ret = NET_Bind ((int)b->ipv6_fd, (struct sockaddr *)b->addr,
   694         ret = NET_WinBind ((int)b->ipv6_fd, (struct sockaddr *)b->addr,
   654                                 sizeof (struct SOCKADDR_IN6));
   695                                 sizeof (struct SOCKADDR_IN6), exclBind);
   655         if (ret == SOCKET_ERROR) {
   696         if (ret == SOCKET_ERROR) {
   656             CLOSE_SOCKETS_AND_RETURN;
   697             CLOSE_SOCKETS_AND_RETURN;
   657         }
   698         }
   658         closesocket (b->ipv4_fd);
   699         closesocket (b->ipv4_fd);
   659         b->ipv4_fd = -1;
   700         b->ipv4_fd = -1;
   678         oaddr.him4.sin_family = AF_INET;
   719         oaddr.him4.sin_family = AF_INET;
   679         oaddr.him4.sin_port = port;
   720         oaddr.him4.sin_port = port;
   680         oaddr.him4.sin_addr.s_addr = INADDR_ANY;
   721         oaddr.him4.sin_addr.s_addr = INADDR_ANY;
   681     }
   722     }
   682 
   723 
   683     rv = NET_Bind (fd, (struct sockaddr *)b->addr, SOCKETADDRESS_LEN(b->addr));
   724     rv = NET_WinBind(fd, (struct sockaddr *)b->addr, SOCKETADDRESS_LEN(b->addr), exclBind);
   684     if (rv == SOCKET_ERROR) {
   725     if (rv == SOCKET_ERROR) {
   685         CLOSE_SOCKETS_AND_RETURN;
   726         CLOSE_SOCKETS_AND_RETURN;
   686     }
   727     }
   687 
   728 
   688     /* get the port and set it in the other address */
   729     /* get the port and set it in the other address */
   690     if (getsockname(fd, (struct sockaddr *)b->addr, &len) == -1) {
   731     if (getsockname(fd, (struct sockaddr *)b->addr, &len) == -1) {
   691         CLOSE_SOCKETS_AND_RETURN;
   732         CLOSE_SOCKETS_AND_RETURN;
   692     }
   733     }
   693     bound_port = GET_PORT (b->addr);
   734     bound_port = GET_PORT (b->addr);
   694     SET_PORT (&oaddr, bound_port);
   735     SET_PORT (&oaddr, bound_port);
   695     if ((rv=NET_Bind (ofd, (struct sockaddr *) &oaddr,
   736     if ((rv=NET_WinBind (ofd, (struct sockaddr *) &oaddr,
   696                                 SOCKETADDRESS_LEN (&oaddr))) == SOCKET_ERROR) {
   737                          SOCKETADDRESS_LEN (&oaddr), exclBind)) == SOCKET_ERROR) {
   697         int retries;
   738         int retries;
   698         int sotype, arglen=sizeof(sotype);
   739         int sotype, arglen=sizeof(sotype);
   699 
   740 
   700         /* no retries unless, the request was for any free port */
   741         /* no retries unless, the request was for any free port */
   701 
   742 
   727                 CLOSE_SOCKETS_AND_RETURN;
   768                 CLOSE_SOCKETS_AND_RETURN;
   728             }
   769             }
   729 
   770 
   730             /* bind random port on first socket */
   771             /* bind random port on first socket */
   731             SET_PORT (&oaddr, 0);
   772             SET_PORT (&oaddr, 0);
   732             rv = NET_Bind (ofd, (struct sockaddr *)&oaddr, SOCKETADDRESS_LEN(&oaddr));
   773             rv = NET_WinBind (ofd, (struct sockaddr *)&oaddr, SOCKETADDRESS_LEN(&oaddr),
       
   774                               exclBind);
   733             if (rv == SOCKET_ERROR) {
   775             if (rv == SOCKET_ERROR) {
   734                 CLOSE_SOCKETS_AND_RETURN;
   776                 CLOSE_SOCKETS_AND_RETURN;
   735             }
   777             }
   736             /* close the original pair of sockets before continuing */
   778             /* close the original pair of sockets before continuing */
   737             closesocket (close_fd);
   779             closesocket (close_fd);
   743             if (getsockname(ofd, (struct sockaddr *)&oaddr, &len) == -1) {
   785             if (getsockname(ofd, (struct sockaddr *)&oaddr, &len) == -1) {
   744                 CLOSE_SOCKETS_AND_RETURN;
   786                 CLOSE_SOCKETS_AND_RETURN;
   745             }
   787             }
   746             bound_port = GET_PORT (&oaddr);
   788             bound_port = GET_PORT (&oaddr);
   747             SET_PORT (b->addr, bound_port);
   789             SET_PORT (b->addr, bound_port);
   748             rv = NET_Bind (fd, (struct sockaddr *)b->addr, SOCKETADDRESS_LEN(b->addr));
   790             rv = NET_WinBind (fd, (struct sockaddr *)b->addr, SOCKETADDRESS_LEN(b->addr),
       
   791                               exclBind);
   749 
   792 
   750             if (rv != SOCKET_ERROR) {
   793             if (rv != SOCKET_ERROR) {
   751                 if (family == AF_INET) {
   794                 if (family == AF_INET) {
   752                     b->ipv4_fd = fd;
   795                     b->ipv4_fd = fd;
   753                     b->ipv6_fd = ofd;
   796                     b->ipv6_fd = ofd;