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

Print this page




  53 
  54 
  55 #if defined(_ALLBSD_SOURCE) && !defined(HAS_GLIBC_GETHOSTBY_R)
  56 extern jobjectArray lookupIfLocalhost(JNIEnv *env, const char *hostname, jboolean includeV6);
  57 
  58 /* Use getaddrinfo(3), which is thread safe */
  59 /************************************************************************
  60  * Inet4AddressImpl
  61  */
  62 
  63 /*
  64  * Class:     java_net_Inet4AddressImpl
  65  * Method:    getLocalHostName
  66  * Signature: ()Ljava/lang/String;
  67  */
  68 JNIEXPORT jstring JNICALL
  69 Java_java_net_Inet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
  70     char hostname[NI_MAXHOST+1];
  71 
  72     hostname[0] = '\0';
  73     if (JVM_GetHostName(hostname, NI_MAXHOST)) {
  74         /* Something went wrong, maybe networking is not setup? */
  75         strcpy(hostname, "localhost");
  76     } else {
  77          struct addrinfo  hints, *res;
  78          int error;
  79 
  80          memset(&hints, 0, sizeof(hints));
  81          hints.ai_flags = AI_CANONNAME;
  82          hints.ai_family = AF_UNSPEC;
  83 
  84          error = getaddrinfo(hostname, NULL, &hints, &res);
  85 
  86          if (error == 0) {
  87              /* host is known to name service */
  88              error = getnameinfo(res->ai_addr,
  89                                  res->ai_addrlen,
  90                                  hostname,
  91                                  NI_MAXHOST,
  92                                  NULL,
  93                                  0,


 315 
 316 /* the initial size of our hostent buffers */
 317 #ifndef NI_MAXHOST
 318 #define NI_MAXHOST 1025
 319 #endif
 320 
 321 /************************************************************************
 322  * Inet4AddressImpl
 323  */
 324 
 325 /*
 326  * Class:     java_net_Inet4AddressImpl
 327  * Method:    getLocalHostName
 328  * Signature: ()Ljava/lang/String;
 329  */
 330 JNIEXPORT jstring JNICALL
 331 Java_java_net_Inet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
 332     char hostname[NI_MAXHOST+1];
 333 
 334     hostname[0] = '\0';
 335     if (JVM_GetHostName(hostname, sizeof(hostname))) {
 336         /* Something went wrong, maybe networking is not setup? */
 337         strcpy(hostname, "localhost");
 338     } else {
 339         struct addrinfo hints, *res;
 340         int error;
 341 
 342         hostname[NI_MAXHOST] = '\0';
 343         memset(&hints, 0, sizeof(hints));
 344         hints.ai_flags = AI_CANONNAME;
 345         hints.ai_family = AF_INET;
 346 
 347         error = getaddrinfo(hostname, NULL, &hints, &res);
 348 
 349         if (error == 0) {/* host is known to name service */
 350             getnameinfo(res->ai_addr,
 351                         res->ai_addrlen,
 352                         hostname,
 353                         NI_MAXHOST,
 354                         NULL,
 355                         0,


 712      * for it.
 713      */
 714     if (!(IS_NULL(ifArray))) {
 715       memset((char *) caddr, 0, sizeof(caddr));
 716       (*env)->GetByteArrayRegion(env, ifArray, 0, 4, caddr);
 717       addr = ((caddr[0]<<24) & 0xff000000);
 718       addr |= ((caddr[1] <<16) & 0xff0000);
 719       addr |= ((caddr[2] <<8) & 0xff00);
 720       addr |= (caddr[3] & 0xff);
 721       addr = htonl(addr);
 722       inf.sin_addr.s_addr = addr;
 723       inf.sin_family = AF_INET;
 724       inf.sin_port = 0;
 725       netif = &inf;
 726     }
 727 
 728     /*
 729      * Let's try to create a RAW socket to send ICMP packets
 730      * This usually requires "root" privileges, so it's likely to fail.
 731      */
 732     fd = JVM_Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
 733     if (fd != -1) {
 734       /*
 735        * It didn't fail, so we can use ICMP_ECHO requests.
 736        */
 737       return ping4(env, fd, &him, timeout, netif, ttl);
 738     }
 739 
 740     /*
 741      * Can't create a raw socket, so let's try a TCP socket
 742      */
 743     fd = JVM_Socket(AF_INET, SOCK_STREAM, 0);
 744     if (fd == JVM_IO_ERR) {
 745         /* note: if you run out of fds, you may not be able to load
 746          * the exception class, and get a NoClassDefFoundError
 747          * instead.
 748          */
 749         NET_ThrowNew(env, errno, "Can't create socket");
 750         return JNI_FALSE;
 751     }
 752     if (ttl > 0) {
 753       setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
 754     }
 755 
 756     /*
 757      * A network interface was specified, so let's bind to it.
 758      */
 759     if (netif != NULL) {
 760       if (bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in)) < 0) {
 761         NET_ThrowNew(env, errno, "Can't bind socket");
 762         close(fd);
 763         return JNI_FALSE;
 764       }
 765     }
 766 
 767     /*
 768      * Make the socket non blocking so we can use select/poll.
 769      */
 770     SET_NONBLOCKING(fd);
 771 
 772     /* no need to use NET_Connect as non-blocking */
 773     him.sin_port = htons(7);    /* Echo */
 774     connect_rv = JVM_Connect(fd, (struct sockaddr *)&him, len);
 775 
 776     /**
 777      * connection established or refused immediately, either way it means
 778      * we were able to reach the host!
 779      */
 780     if (connect_rv == 0 || errno == ECONNREFUSED) {
 781         close(fd);
 782         return JNI_TRUE;
 783     } else {
 784         int optlen;
 785 
 786         switch (errno) {
 787         case ENETUNREACH: /* Network Unreachable */
 788         case EAFNOSUPPORT: /* Address Family not supported */
 789         case EADDRNOTAVAIL: /* address is not available on  the  remote machine */
 790 #ifdef __linux__
 791         case EINVAL:
 792         case EHOSTUNREACH:
 793           /*
 794            * On some Linux versions, when a socket is bound to the loopback
 795            * interface, connect will fail and errno will be set to EINVAL
 796            * or EHOSTUNREACH.  When that happens, don't throw an exception,
 797            * just return false.
 798            */
 799 #endif /* __linux__ */
 800           close(fd);
 801           return JNI_FALSE;
 802         }
 803 
 804         if (errno != EINPROGRESS) {
 805           NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
 806                                        "connect failed");
 807           close(fd);
 808           return JNI_FALSE;
 809         }
 810 
 811         timeout = NET_Wait(env, fd, NET_WAIT_CONNECT, timeout);
 812         if (timeout >= 0) {
 813           /* has connection been established? */
 814           optlen = sizeof(connect_rv);
 815           if (JVM_GetSockOpt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
 816                              &optlen) <0) {
 817             connect_rv = errno;
 818           }
 819           if (connect_rv == 0 || connect_rv == ECONNREFUSED) {
 820             close(fd);
 821             return JNI_TRUE;
 822           }
 823         }
 824         close(fd);
 825         return JNI_FALSE;
 826     }
 827 }


  53 
  54 
  55 #if defined(_ALLBSD_SOURCE) && !defined(HAS_GLIBC_GETHOSTBY_R)
  56 extern jobjectArray lookupIfLocalhost(JNIEnv *env, const char *hostname, jboolean includeV6);
  57 
  58 /* Use getaddrinfo(3), which is thread safe */
  59 /************************************************************************
  60  * Inet4AddressImpl
  61  */
  62 
  63 /*
  64  * Class:     java_net_Inet4AddressImpl
  65  * Method:    getLocalHostName
  66  * Signature: ()Ljava/lang/String;
  67  */
  68 JNIEXPORT jstring JNICALL
  69 Java_java_net_Inet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
  70     char hostname[NI_MAXHOST+1];
  71 
  72     hostname[0] = '\0';
  73     if (gethostname(hostname, NI_MAXHOST)) {
  74         /* Something went wrong, maybe networking is not setup? */
  75         strcpy(hostname, "localhost");
  76     } else {
  77          struct addrinfo  hints, *res;
  78          int error;
  79 
  80          memset(&hints, 0, sizeof(hints));
  81          hints.ai_flags = AI_CANONNAME;
  82          hints.ai_family = AF_UNSPEC;
  83 
  84          error = getaddrinfo(hostname, NULL, &hints, &res);
  85 
  86          if (error == 0) {
  87              /* host is known to name service */
  88              error = getnameinfo(res->ai_addr,
  89                                  res->ai_addrlen,
  90                                  hostname,
  91                                  NI_MAXHOST,
  92                                  NULL,
  93                                  0,


 315 
 316 /* the initial size of our hostent buffers */
 317 #ifndef NI_MAXHOST
 318 #define NI_MAXHOST 1025
 319 #endif
 320 
 321 /************************************************************************
 322  * Inet4AddressImpl
 323  */
 324 
 325 /*
 326  * Class:     java_net_Inet4AddressImpl
 327  * Method:    getLocalHostName
 328  * Signature: ()Ljava/lang/String;
 329  */
 330 JNIEXPORT jstring JNICALL
 331 Java_java_net_Inet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
 332     char hostname[NI_MAXHOST+1];
 333 
 334     hostname[0] = '\0';
 335     if (gethostname(hostname, NI_MAXHOST)) {
 336         /* Something went wrong, maybe networking is not setup? */
 337         strcpy(hostname, "localhost");
 338     } else {
 339         struct addrinfo hints, *res;
 340         int error;
 341 
 342         hostname[NI_MAXHOST] = '\0';
 343         memset(&hints, 0, sizeof(hints));
 344         hints.ai_flags = AI_CANONNAME;
 345         hints.ai_family = AF_INET;
 346 
 347         error = getaddrinfo(hostname, NULL, &hints, &res);
 348 
 349         if (error == 0) {/* host is known to name service */
 350             getnameinfo(res->ai_addr,
 351                         res->ai_addrlen,
 352                         hostname,
 353                         NI_MAXHOST,
 354                         NULL,
 355                         0,


 712      * for it.
 713      */
 714     if (!(IS_NULL(ifArray))) {
 715       memset((char *) caddr, 0, sizeof(caddr));
 716       (*env)->GetByteArrayRegion(env, ifArray, 0, 4, caddr);
 717       addr = ((caddr[0]<<24) & 0xff000000);
 718       addr |= ((caddr[1] <<16) & 0xff0000);
 719       addr |= ((caddr[2] <<8) & 0xff00);
 720       addr |= (caddr[3] & 0xff);
 721       addr = htonl(addr);
 722       inf.sin_addr.s_addr = addr;
 723       inf.sin_family = AF_INET;
 724       inf.sin_port = 0;
 725       netif = &inf;
 726     }
 727 
 728     /*
 729      * Let's try to create a RAW socket to send ICMP packets
 730      * This usually requires "root" privileges, so it's likely to fail.
 731      */
 732     fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
 733     if (fd != -1) {
 734       /*
 735        * It didn't fail, so we can use ICMP_ECHO requests.
 736        */
 737       return ping4(env, fd, &him, timeout, netif, ttl);
 738     }
 739 
 740     /*
 741      * Can't create a raw socket, so let's try a TCP socket
 742      */
 743     fd = socket(AF_INET, SOCK_STREAM, 0);
 744     if (fd == -1) {
 745         /* note: if you run out of fds, you may not be able to load
 746          * the exception class, and get a NoClassDefFoundError
 747          * instead.
 748          */
 749         NET_ThrowNew(env, errno, "Can't create socket");
 750         return JNI_FALSE;
 751     }
 752     if (ttl > 0) {
 753       setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
 754     }
 755 
 756     /*
 757      * A network interface was specified, so let's bind to it.
 758      */
 759     if (netif != NULL) {
 760       if (bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in)) < 0) {
 761         NET_ThrowNew(env, errno, "Can't bind socket");
 762         close(fd);
 763         return JNI_FALSE;
 764       }
 765     }
 766 
 767     /*
 768      * Make the socket non blocking so we can use select/poll.
 769      */
 770     SET_NONBLOCKING(fd);
 771 

 772     him.sin_port = htons(7);    /* Echo */
 773     connect_rv = NET_Connect(fd, (struct sockaddr *)&him, len);
 774 
 775     /**
 776      * connection established or refused immediately, either way it means
 777      * we were able to reach the host!
 778      */
 779     if (connect_rv == 0 || errno == ECONNREFUSED) {
 780         close(fd);
 781         return JNI_TRUE;
 782     } else {
 783         socklen_t optlen = (socklen_t)sizeof(connect_rv);
 784 
 785         switch (errno) {
 786         case ENETUNREACH: /* Network Unreachable */
 787         case EAFNOSUPPORT: /* Address Family not supported */
 788         case EADDRNOTAVAIL: /* address is not available on  the  remote machine */
 789 #ifdef __linux__
 790         case EINVAL:
 791         case EHOSTUNREACH:
 792           /*
 793            * On some Linux versions, when a socket is bound to the loopback
 794            * interface, connect will fail and errno will be set to EINVAL
 795            * or EHOSTUNREACH.  When that happens, don't throw an exception,
 796            * just return false.
 797            */
 798 #endif /* __linux__ */
 799           close(fd);
 800           return JNI_FALSE;
 801         }
 802 
 803         if (errno != EINPROGRESS) {
 804           NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
 805                                        "connect failed");
 806           close(fd);
 807           return JNI_FALSE;
 808         }
 809 
 810         timeout = NET_Wait(env, fd, NET_WAIT_CONNECT, timeout);
 811         if (timeout >= 0) {
 812           /* has connection been established? */
 813           if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,

 814                          &optlen) <0) {
 815             connect_rv = errno;
 816           }
 817           if (connect_rv == 0 || connect_rv == ECONNREFUSED) {
 818             close(fd);
 819             return JNI_TRUE;
 820           }
 821         }
 822         close(fd);
 823         return JNI_FALSE;
 824     }
 825 }