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; |