Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/native/java/net/net_util.c
38829 views
1
/*
2
* Copyright (c) 1998, 2018, 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
26
#include "jni.h"
27
#include "jvm.h"
28
#include "jni_util.h"
29
#include "net_util.h"
30
31
int IPv6_supported() ;
32
33
static int IPv6_available;
34
35
JNIEXPORT jint JNICALL ipv6_available()
36
{
37
return IPv6_available ;
38
}
39
40
JNIEXPORT jint JNICALL
41
JNI_OnLoad(JavaVM *vm, void *reserved)
42
{
43
JNIEnv *env;
44
jclass iCls;
45
jmethodID mid;
46
jstring s;
47
jint preferIPv4Stack;
48
49
if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_2) == JNI_OK) {
50
if (JVM_InitializeSocketLibrary() < 0) {
51
JNU_ThrowByName(env, "java/lang/UnsatisfiedLinkError",
52
"failed to initialize net library.");
53
return JNI_VERSION_1_2;
54
}
55
}
56
iCls = (*env)->FindClass(env, "java/lang/Boolean");
57
CHECK_NULL_RETURN(iCls, JNI_VERSION_1_2);
58
mid = (*env)->GetStaticMethodID(env, iCls, "getBoolean", "(Ljava/lang/String;)Z");
59
CHECK_NULL_RETURN(mid, JNI_VERSION_1_2);
60
s = (*env)->NewStringUTF(env, "java.net.preferIPv4Stack");
61
CHECK_NULL_RETURN(s, JNI_VERSION_1_2);
62
preferIPv4Stack = (*env)->CallStaticBooleanMethod(env, iCls, mid, s);
63
64
/*
65
Since we have initialized and loaded the Socket library we will
66
check now to whether we have IPv6 on this platform and if the
67
supporting socket APIs are available
68
*/
69
IPv6_available = IPv6_supported() & (!preferIPv4Stack);
70
platformInit();
71
parseExclusiveBindProperty(env);
72
73
return JNI_VERSION_1_2;
74
}
75
76
static int initialized = 0;
77
78
JNIEXPORT void JNICALL initInetAddressIDs(JNIEnv *env) {
79
if (!initialized) {
80
Java_java_net_InetAddress_init(env, 0);
81
JNU_CHECK_EXCEPTION(env);
82
Java_java_net_Inet4Address_init(env, 0);
83
JNU_CHECK_EXCEPTION(env);
84
Java_java_net_Inet6Address_init(env, 0);
85
JNU_CHECK_EXCEPTION(env);
86
initialized = 1;
87
}
88
}
89
90
/* The address, and family fields used to be in InetAddress
91
* but are now in an implementation object. So, there is an extra
92
* level of indirection to access them now.
93
*/
94
95
extern jclass iac_class;
96
extern jfieldID ia_holderID;
97
extern jfieldID iac_addressID;
98
extern jfieldID iac_familyID;
99
100
/**
101
* set_ methods return JNI_TRUE on success JNI_FALSE on error
102
* get_ methods that return +ve int return -1 on error
103
* get_ methods that return objects return NULL on error.
104
*/
105
jobject getInet6Address_scopeifname(JNIEnv *env, jobject iaObj) {
106
jobject holder = (*env)->GetObjectField(env, iaObj, ia6_holder6ID);
107
CHECK_NULL_RETURN(holder, NULL);
108
return (*env)->GetObjectField(env, holder, ia6_scopeifnameID);
109
}
110
111
int setInet6Address_scopeifname(JNIEnv *env, jobject iaObj, jobject scopeifname) {
112
jobject holder = (*env)->GetObjectField(env, iaObj, ia6_holder6ID);
113
CHECK_NULL_RETURN(holder, JNI_FALSE);
114
(*env)->SetObjectField(env, holder, ia6_scopeifnameID, scopeifname);
115
return JNI_TRUE;
116
}
117
118
int getInet6Address_scopeid_set(JNIEnv *env, jobject iaObj) {
119
jobject holder = (*env)->GetObjectField(env, iaObj, ia6_holder6ID);
120
CHECK_NULL_RETURN(holder, -1);
121
return (*env)->GetBooleanField(env, holder, ia6_scopeidsetID);
122
}
123
124
int getInet6Address_scopeid(JNIEnv *env, jobject iaObj) {
125
jobject holder = (*env)->GetObjectField(env, iaObj, ia6_holder6ID);
126
CHECK_NULL_RETURN(holder, -1);
127
return (*env)->GetIntField(env, holder, ia6_scopeidID);
128
}
129
130
int setInet6Address_scopeid(JNIEnv *env, jobject iaObj, int scopeid) {
131
jobject holder = (*env)->GetObjectField(env, iaObj, ia6_holder6ID);
132
CHECK_NULL_RETURN(holder, JNI_FALSE);
133
(*env)->SetIntField(env, holder, ia6_scopeidID, scopeid);
134
if (scopeid > 0) {
135
(*env)->SetBooleanField(env, holder, ia6_scopeidsetID, JNI_TRUE);
136
}
137
return JNI_TRUE;
138
}
139
140
141
int getInet6Address_ipaddress(JNIEnv *env, jobject iaObj, char *dest) {
142
jobject holder, addr;
143
jbyteArray barr;
144
145
holder = (*env)->GetObjectField(env, iaObj, ia6_holder6ID);
146
CHECK_NULL_RETURN(holder, JNI_FALSE);
147
addr = (*env)->GetObjectField(env, holder, ia6_ipaddressID);
148
CHECK_NULL_RETURN(addr, JNI_FALSE);
149
(*env)->GetByteArrayRegion(env, addr, 0, 16, (jbyte *)dest);
150
return JNI_TRUE;
151
}
152
153
int setInet6Address_ipaddress(JNIEnv *env, jobject iaObj, char *address) {
154
jobject holder;
155
jbyteArray addr;
156
157
holder = (*env)->GetObjectField(env, iaObj, ia6_holder6ID);
158
CHECK_NULL_RETURN(holder, JNI_FALSE);
159
addr = (jbyteArray)(*env)->GetObjectField(env, holder, ia6_ipaddressID);
160
if (addr == NULL) {
161
addr = (*env)->NewByteArray(env, 16);
162
CHECK_NULL_RETURN(addr, JNI_FALSE);
163
(*env)->SetObjectField(env, holder, ia6_ipaddressID, addr);
164
}
165
(*env)->SetByteArrayRegion(env, addr, 0, 16, (jbyte *)address);
166
return JNI_TRUE;
167
}
168
169
void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address) {
170
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
171
CHECK_NULL_THROW_NPE(env, holder, "InetAddress holder is null");
172
(*env)->SetIntField(env, holder, iac_addressID, address);
173
}
174
175
void setInetAddress_family(JNIEnv *env, jobject iaObj, int family) {
176
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
177
CHECK_NULL_THROW_NPE(env, holder, "InetAddress holder is null");
178
(*env)->SetIntField(env, holder, iac_familyID, family);
179
}
180
181
void setInetAddress_hostName(JNIEnv *env, jobject iaObj, jobject host) {
182
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
183
CHECK_NULL_THROW_NPE(env, holder, "InetAddress holder is null");
184
(*env)->SetObjectField(env, holder, iac_hostNameID, host);
185
(*env)->SetObjectField(env, holder, iac_origHostNameID, host);
186
}
187
188
int getInetAddress_addr(JNIEnv *env, jobject iaObj) {
189
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
190
CHECK_NULL_THROW_NPE_RETURN(env, holder, "InetAddress holder is null", -1);
191
return (*env)->GetIntField(env, holder, iac_addressID);
192
}
193
194
int getInetAddress_family(JNIEnv *env, jobject iaObj) {
195
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
196
CHECK_NULL_THROW_NPE_RETURN(env, holder, "InetAddress holder is null", -1);
197
return (*env)->GetIntField(env, holder, iac_familyID);
198
}
199
200
jobject getInetAddress_hostName(JNIEnv *env, jobject iaObj) {
201
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
202
CHECK_NULL_THROW_NPE_RETURN(env, holder, "InetAddress holder is null", NULL);
203
return (*env)->GetObjectField(env, holder, iac_hostNameID);
204
}
205
206
JNIEXPORT jobject JNICALL
207
NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port) {
208
jobject iaObj;
209
#ifdef AF_INET6
210
if (him->sa_family == AF_INET6) {
211
jbyteArray ipaddress;
212
#ifdef WIN32
213
struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him;
214
#else
215
struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
216
#endif
217
jbyte *caddr = (jbyte *)&(him6->sin6_addr);
218
if (NET_IsIPv4Mapped(caddr)) {
219
int address;
220
iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
221
CHECK_NULL_RETURN(iaObj, NULL);
222
address = NET_IPv4MappedToIPv4(caddr);
223
setInetAddress_addr(env, iaObj, address);
224
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
225
setInetAddress_family(env, iaObj, IPv4);
226
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
227
} else {
228
jint scope;
229
int ret;
230
iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
231
CHECK_NULL_RETURN(iaObj, NULL);
232
ret = setInet6Address_ipaddress(env, iaObj, (char *)&(him6->sin6_addr));
233
CHECK_NULL_RETURN(ret, NULL);
234
setInetAddress_family(env, iaObj, IPv6);
235
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
236
scope = getScopeID(him);
237
setInet6Address_scopeid(env, iaObj, scope);
238
}
239
*port = ntohs(him6->sin6_port);
240
} else
241
#endif /* AF_INET6 */
242
{
243
struct sockaddr_in *him4 = (struct sockaddr_in *)him;
244
iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
245
CHECK_NULL_RETURN(iaObj, NULL);
246
setInetAddress_family(env, iaObj, IPv4);
247
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
248
setInetAddress_addr(env, iaObj, ntohl(him4->sin_addr.s_addr));
249
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
250
*port = ntohs(him4->sin_port);
251
}
252
return iaObj;
253
}
254
255
JNIEXPORT jint JNICALL
256
NET_SockaddrEqualsInetAddress(JNIEnv *env, struct sockaddr *him, jobject iaObj)
257
{
258
jint family = AF_INET;
259
260
#ifdef AF_INET6
261
family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6;
262
JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
263
if (him->sa_family == AF_INET6) {
264
#ifdef WIN32
265
struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him;
266
#else
267
struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
268
#endif
269
jbyte *caddrNew = (jbyte *)&(him6->sin6_addr);
270
if (NET_IsIPv4Mapped(caddrNew)) {
271
int addrNew;
272
int addrCur;
273
if (family == AF_INET6) {
274
return JNI_FALSE;
275
}
276
addrNew = NET_IPv4MappedToIPv4(caddrNew);
277
addrCur = getInetAddress_addr(env, iaObj);
278
JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
279
if (addrNew == addrCur) {
280
return JNI_TRUE;
281
} else {
282
return JNI_FALSE;
283
}
284
} else {
285
jbyteArray ipaddress;
286
jbyte caddrCur[16];
287
int scope;
288
289
if (family == AF_INET) {
290
return JNI_FALSE;
291
}
292
scope = getInet6Address_scopeid(env, iaObj);
293
getInet6Address_ipaddress(env, iaObj, (char *)caddrCur);
294
if (NET_IsEqual(caddrNew, caddrCur) && cmpScopeID(scope, him)) {
295
return JNI_TRUE;
296
} else {
297
return JNI_FALSE;
298
}
299
}
300
} else
301
#endif /* AF_INET6 */
302
{
303
struct sockaddr_in *him4 = (struct sockaddr_in *)him;
304
int addrNew, addrCur;
305
if (family != AF_INET) {
306
return JNI_FALSE;
307
}
308
addrNew = ntohl(him4->sin_addr.s_addr);
309
addrCur = getInetAddress_addr(env, iaObj);
310
JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
311
if (addrNew == addrCur) {
312
return JNI_TRUE;
313
} else {
314
return JNI_FALSE;
315
}
316
}
317
}
318
319
unsigned short
320
in_cksum(unsigned short *addr, int len) {
321
int nleft = len;
322
int sum = 0;
323
unsigned short *w = addr;
324
unsigned short answer = 0;
325
while(nleft > 1) {
326
sum += *w++;
327
nleft -= 2;
328
}
329
330
if (nleft == 1) {
331
*(unsigned char *) (&answer) = *(unsigned char *)w;
332
sum += answer;
333
}
334
335
sum = (sum >> 16) + (sum & 0xffff);
336
sum += (sum >> 16);
337
answer = ~sum;
338
return (answer);
339
}
340
341