< prev index next >

src/java.base/windows/native/libnet/Inet6AddressImpl.c

Print this page

  1 /*
  2  * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 #include <malloc.h>
 26 
 27 #include "net_util.h"
 28 
 29 #include "java_net_InetAddress.h"
 30 #include "java_net_Inet4AddressImpl.h"
 31 #include "java_net_Inet6AddressImpl.h"

 32 
 33 /*
 34  * Inet6AddressImpl
 35  */
 36 
 37 /*
 38  * Class:     java_net_Inet6AddressImpl
 39  * Method:    getLocalHostName
 40  * Signature: ()Ljava/lang/String;
 41  */
 42 JNIEXPORT jstring JNICALL
 43 Java_java_net_Inet6AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
 44     char hostname[256];
 45 
 46     if (gethostname(hostname, sizeof(hostname)) == -1) {
 47         strcpy(hostname, "localhost");
 48     }
 49     return JNU_NewStringPlatform(env, hostname);
 50 }
 51 
 52 /*
 53  * Class:     java_net_Inet6AddressImpl
 54  * Method:    lookupAllHostAddr
 55  * Signature: (Ljava/lang/String;)[[B
 56  */
 57 JNIEXPORT jobjectArray JNICALL
 58 Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
 59                                                  jstring host) {
 60     jobjectArray ret = NULL;
 61     const char *hostname;
 62     int error = 0;
 63     struct addrinfo hints, *res = NULL, *resNew = NULL, *last = NULL,
 64         *iterator;
 65 
 66     initInetAddressIDs(env);
 67     JNU_CHECK_EXCEPTION_RETURN(env, NULL);
 68 
 69     if (IS_NULL(host)) {
 70         JNU_ThrowNullPointerException(env, "host argument is null");
 71         return NULL;
 72     }
 73     hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE);
 74     CHECK_NULL_RETURN(hostname, NULL);
 75 
 76     // try once, with our static buffer
 77     memset(&hints, 0, sizeof(hints));
 78     hints.ai_flags = AI_CANONNAME;
 79     hints.ai_family = AF_UNSPEC;
 80 
 81     error = getaddrinfo(hostname, NULL, &hints, &res);
 82 
 83     if (error) {
 84         // report error
 85         NET_ThrowByNameWithLastError(env, "java/net/UnknownHostException",
 86                                      hostname);
 87         goto cleanupAndReturn;
 88     } else {
 89         int i = 0, inetCount = 0, inet6Count = 0, inetIndex = 0,
 90             inet6Index = 0, originalIndex = 0;
 91         int addressPreference =
 92             (*env)->GetStaticIntField(env, ia_class, ia_preferIPv6AddressID);
 93         iterator = res;
 94         while (iterator != NULL) {
 95             // skip duplicates
 96             int skip = 0;
 97             struct addrinfo *iteratorNew = resNew;
 98             while (iteratorNew != NULL) {
 99                 if (iterator->ai_family == iteratorNew->ai_family &&
100                     iterator->ai_addrlen == iteratorNew->ai_addrlen) {
101                     if (iteratorNew->ai_family == AF_INET) { /* AF_INET */
102                         struct sockaddr_in *addr1, *addr2;
103                         addr1 = (struct sockaddr_in *)iterator->ai_addr;
104                         addr2 = (struct sockaddr_in *)iteratorNew->ai_addr;
105                         if (addr1->sin_addr.s_addr == addr2->sin_addr.s_addr) {
106                             skip = 1;
107                             break;
108                         }
109                     } else {
110                         int t;
111                         struct sockaddr_in6 *addr1, *addr2;
112                         addr1 = (struct sockaddr_in6 *)iterator->ai_addr;

151                     last->ai_next = next;
152                 }
153                 last = next;
154                 i++;
155                 if (iterator->ai_family == AF_INET) {
156                     inetCount++;
157                 } else if (iterator->ai_family == AF_INET6) {
158                     inet6Count++;
159                 }
160             }
161             iterator = iterator->ai_next;
162         }
163 
164         // allocate array - at this point i contains the number of addresses
165         ret = (*env)->NewObjectArray(env, i, ia_class, NULL);
166         if (IS_NULL(ret)) {
167             /* we may have memory to free at the end of this */
168             goto cleanupAndReturn;
169         }
170 
171         if (addressPreference == java_net_InetAddress_PREFER_IPV6_VALUE) {
172             inetIndex = inet6Count;
173             inet6Index = 0;
174         } else if (addressPreference == java_net_InetAddress_PREFER_IPV4_VALUE) {
175             inetIndex = 0;
176             inet6Index = inetCount;
177         } else if (addressPreference == java_net_InetAddress_PREFER_SYSTEM_VALUE) {
178             inetIndex = inet6Index = originalIndex = 0;
179         }
180 
181         iterator = resNew;
182         while (iterator != NULL) {
183             if (iterator->ai_family == AF_INET) {
184                 jobject iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
185                 if (IS_NULL(iaObj)) {
186                     ret = NULL;
187                     goto cleanupAndReturn;
188                 }
189                 setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
190                 if ((*env)->ExceptionCheck(env))
191                     goto cleanupAndReturn;
192                 setInetAddress_hostName(env, iaObj, host);
193                 if ((*env)->ExceptionCheck(env))
194                     goto cleanupAndReturn;
195                 (*env)->SetObjectArrayElement(env, ret, (inetIndex | originalIndex), iaObj);
196                 inetIndex++;
197             } else if (iterator->ai_family == AF_INET6) {

200                 jobject iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
201                 if (IS_NULL(iaObj)) {
202                     ret = NULL;
203                     goto cleanupAndReturn;
204                 }
205                 ret1 = setInet6Address_ipaddress(env, iaObj, (char *)&(((struct sockaddr_in6*)iterator->ai_addr)->sin6_addr));
206                 if (ret1 == JNI_FALSE) {
207                     ret = NULL;
208                     goto cleanupAndReturn;
209                 }
210                 scope = ((struct sockaddr_in6 *)iterator->ai_addr)->sin6_scope_id;
211                 if (scope != 0) { // zero is default value, no need to set
212                     setInet6Address_scopeid(env, iaObj, scope);
213                 }
214                 setInetAddress_hostName(env, iaObj, host);
215                 if ((*env)->ExceptionCheck(env))
216                     goto cleanupAndReturn;
217                 (*env)->SetObjectArrayElement(env, ret, (inet6Index | originalIndex), iaObj);
218                 inet6Index++;
219             }
220             if (addressPreference == java_net_InetAddress_PREFER_SYSTEM_VALUE) {

221                 originalIndex++;
222                 inetIndex = inet6Index = 0;
223             }
224             iterator = iterator->ai_next;
225         }
226     }
227 cleanupAndReturn:
228     JNU_ReleaseStringPlatformChars(env, host, hostname);
229     while (resNew != NULL) {
230         last = resNew;
231         resNew = resNew->ai_next;
232         free(last);
233     }
234     if (res != NULL) {
235         freeaddrinfo(res);
236     }
237     return ret;
238 }
239 
240 /*

  1 /*
  2  * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 #include <malloc.h>
 26 
 27 #include "net_util.h"
 28 
 29 #include "java_net_InetAddress.h"
 30 #include "java_net_Inet4AddressImpl.h"
 31 #include "java_net_Inet6AddressImpl.h"
 32 #include "java_net_spi_InetAddressResolver_LookupPolicy.h"
 33 
 34 /*
 35  * Inet6AddressImpl
 36  */
 37 
 38 /*
 39  * Class:     java_net_Inet6AddressImpl
 40  * Method:    getLocalHostName
 41  * Signature: ()Ljava/lang/String;
 42  */
 43 JNIEXPORT jstring JNICALL
 44 Java_java_net_Inet6AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
 45     char hostname[256];
 46 
 47     if (gethostname(hostname, sizeof(hostname)) == -1) {
 48         strcpy(hostname, "localhost");
 49     }
 50     return JNU_NewStringPlatform(env, hostname);
 51 }
 52 
 53 /*
 54  * Class:     java_net_Inet6AddressImpl
 55  * Method:    lookupAllHostAddr
 56  * Signature: (Ljava/lang/String;)[[B
 57  */
 58 JNIEXPORT jobjectArray JNICALL
 59 Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
 60                                                  jstring host, jint characteristics) {
 61     jobjectArray ret = NULL;
 62     const char *hostname;
 63     int error = 0;
 64     struct addrinfo hints, *res = NULL, *resNew = NULL, *last = NULL,
 65         *iterator;
 66 
 67     initInetAddressIDs(env);
 68     JNU_CHECK_EXCEPTION_RETURN(env, NULL);
 69 
 70     if (IS_NULL(host)) {
 71         JNU_ThrowNullPointerException(env, "host argument is null");
 72         return NULL;
 73     }
 74     hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE);
 75     CHECK_NULL_RETURN(hostname, NULL);
 76 
 77     // try once, with our static buffer
 78     memset(&hints, 0, sizeof(hints));
 79     hints.ai_flags = AI_CANONNAME;
 80     hints.ai_family = lookupCharacteristicsToAddressFamily(characteristics);
 81 
 82     error = getaddrinfo(hostname, NULL, &hints, &res);
 83 
 84     if (error) {
 85         // report error
 86         NET_ThrowByNameWithLastError(env, "java/net/UnknownHostException",
 87                                      hostname);
 88         goto cleanupAndReturn;
 89     } else {
 90         int i = 0, inetCount = 0, inet6Count = 0, inetIndex = 0,
 91             inet6Index = 0, originalIndex = 0;


 92         iterator = res;
 93         while (iterator != NULL) {
 94             // skip duplicates
 95             int skip = 0;
 96             struct addrinfo *iteratorNew = resNew;
 97             while (iteratorNew != NULL) {
 98                 if (iterator->ai_family == iteratorNew->ai_family &&
 99                     iterator->ai_addrlen == iteratorNew->ai_addrlen) {
100                     if (iteratorNew->ai_family == AF_INET) { /* AF_INET */
101                         struct sockaddr_in *addr1, *addr2;
102                         addr1 = (struct sockaddr_in *)iterator->ai_addr;
103                         addr2 = (struct sockaddr_in *)iteratorNew->ai_addr;
104                         if (addr1->sin_addr.s_addr == addr2->sin_addr.s_addr) {
105                             skip = 1;
106                             break;
107                         }
108                     } else {
109                         int t;
110                         struct sockaddr_in6 *addr1, *addr2;
111                         addr1 = (struct sockaddr_in6 *)iterator->ai_addr;

150                     last->ai_next = next;
151                 }
152                 last = next;
153                 i++;
154                 if (iterator->ai_family == AF_INET) {
155                     inetCount++;
156                 } else if (iterator->ai_family == AF_INET6) {
157                     inet6Count++;
158                 }
159             }
160             iterator = iterator->ai_next;
161         }
162 
163         // allocate array - at this point i contains the number of addresses
164         ret = (*env)->NewObjectArray(env, i, ia_class, NULL);
165         if (IS_NULL(ret)) {
166             /* we may have memory to free at the end of this */
167             goto cleanupAndReturn;
168         }
169 
170         if ((characteristics & java_net_spi_InetAddressResolver_LookupPolicy_IPV6_FIRST) != 0) {
171             inetIndex = inet6Count;
172             inet6Index = 0;
173         } else if ((characteristics & java_net_spi_InetAddressResolver_LookupPolicy_IPV4_FIRST) != 0) {
174             inetIndex = 0;
175             inet6Index = inetCount;
176         } else {
177             inetIndex = inet6Index = originalIndex = 0;
178         }
179 
180         iterator = resNew;
181         while (iterator != NULL) {
182             if (iterator->ai_family == AF_INET) {
183                 jobject iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
184                 if (IS_NULL(iaObj)) {
185                     ret = NULL;
186                     goto cleanupAndReturn;
187                 }
188                 setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
189                 if ((*env)->ExceptionCheck(env))
190                     goto cleanupAndReturn;
191                 setInetAddress_hostName(env, iaObj, host);
192                 if ((*env)->ExceptionCheck(env))
193                     goto cleanupAndReturn;
194                 (*env)->SetObjectArrayElement(env, ret, (inetIndex | originalIndex), iaObj);
195                 inetIndex++;
196             } else if (iterator->ai_family == AF_INET6) {

199                 jobject iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
200                 if (IS_NULL(iaObj)) {
201                     ret = NULL;
202                     goto cleanupAndReturn;
203                 }
204                 ret1 = setInet6Address_ipaddress(env, iaObj, (char *)&(((struct sockaddr_in6*)iterator->ai_addr)->sin6_addr));
205                 if (ret1 == JNI_FALSE) {
206                     ret = NULL;
207                     goto cleanupAndReturn;
208                 }
209                 scope = ((struct sockaddr_in6 *)iterator->ai_addr)->sin6_scope_id;
210                 if (scope != 0) { // zero is default value, no need to set
211                     setInet6Address_scopeid(env, iaObj, scope);
212                 }
213                 setInetAddress_hostName(env, iaObj, host);
214                 if ((*env)->ExceptionCheck(env))
215                     goto cleanupAndReturn;
216                 (*env)->SetObjectArrayElement(env, ret, (inet6Index | originalIndex), iaObj);
217                 inet6Index++;
218             }
219             // Check if addresses are requested to be returned in SYSTEM order
220             if (addressesInSystemOrder(characteristics)) {
221                 originalIndex++;
222                 inetIndex = inet6Index = 0;
223             }
224             iterator = iterator->ai_next;
225         }
226     }
227 cleanupAndReturn:
228     JNU_ReleaseStringPlatformChars(env, host, hostname);
229     while (resNew != NULL) {
230         last = resNew;
231         resNew = resNew->ai_next;
232         free(last);
233     }
234     if (res != NULL) {
235         freeaddrinfo(res);
236     }
237     return ret;
238 }
239 
240 /*
< prev index next >