/
openjdk_x86-1.7.u80_b32-source9.patchset
364 lines (350 loc) · 12.6 KB
/
openjdk_x86-1.7.u80_b32-source9.patchset
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
From 21be8c5d2379b6dbf75a09a751bc4401dbec205c Mon Sep 17 00:00:00 2001
From: Sergei Reznikov <diver@gelios.net>
Date: Wed, 7 Oct 2015 15:22:29 +0300
Subject: Inet4AddressImpl: replace gethostbyname_r with getaddrinfo
Backport OpenJDK 8 implementation, not completely working yet, e.g.
muCommander can't connect to smb shares for some reason.
diff --git a/src/solaris/native/java/net/Inet4AddressImpl.c b/src/solaris/native/java/net/Inet4AddressImpl.c
index 2c2a6b1..bfd2755 100644
--- a/src/solaris/native/java/net/Inet4AddressImpl.c
+++ b/src/solaris/native/java/net/Inet4AddressImpl.c
@@ -351,60 +351,36 @@ Java_java_net_Inet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
*/
JNIEXPORT jstring JNICALL
Java_java_net_Inet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
- char hostname[MAXHOSTNAMELEN+1];
+ char hostname[NI_MAXHOST+1];
hostname[0] = '\0';
if (JVM_GetHostName(hostname, sizeof(hostname))) {
/* Something went wrong, maybe networking is not setup? */
strcpy(hostname, "localhost");
} else {
-#if defined(__linux__) || (__HAIKU__)
- /* On Linux gethostname() says "host.domain.sun.com". On
- * Solaris gethostname() says "host", so extra work is needed.
- */
-#else
- /* Solaris doesn't want to give us a fully qualified domain name.
- * We do a reverse lookup to try and get one. This works
- * if DNS occurs before NIS in /etc/resolv.conf, but fails
- * if NIS comes first (it still gets only a partial name).
- * We use thread-safe system calls.
- */
-#endif /* __linux__ */
- struct hostent res, res2, *hp;
- // these buffers must be pointer-aligned so they are declared
- // with pointer type
- char *buf[HENT_BUF_SIZE/(sizeof (char *))];
- char *buf2[HENT_BUF_SIZE/(sizeof (char *))];
- int h_error=0;
-
- // ensure null-terminated
- hostname[MAXHOSTNAMELEN] = '\0';
-
-#ifdef HAS_GLIBC_GETHOSTBY_R
- gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &hp, &h_error);
-#else
- hp = gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &h_error);
-#endif
- if (hp) {
-#ifdef HAS_GLIBC_GETHOSTBY_R
- gethostbyaddr_r(hp->h_addr, hp->h_length, AF_INET,
- &res2, (char*)buf2, sizeof(buf2), &hp, &h_error);
-#else
- hp = gethostbyaddr_r(hp->h_addr, hp->h_length, AF_INET,
- &res2, (char*)buf2, sizeof(buf2), &h_error);
-#endif
- if (hp) {
- /*
- * If gethostbyaddr_r() found a fully qualified host name,
- * returns that name. Otherwise, returns the hostname
- * found by gethostname().
- */
- char *p = hp->h_name;
- if ((strlen(hp->h_name) > strlen(hostname))
- && (strncmp(hostname, hp->h_name, strlen(hostname)) == 0)
- && (*(p + strlen(hostname)) == '.'))
- strcpy(hostname, hp->h_name);
- }
+ struct addrinfo hints, *res;
+ int error;
+
+ hostname[NI_MAXHOST] = '\0';
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_family = AF_INET;
+
+ error = getaddrinfo(hostname, NULL, &hints, &res);
+
+ if (error == 0) {/* host is known to name service */
+ getnameinfo(res->ai_addr,
+ res->ai_addrlen,
+ hostname,
+ NI_MAXHOST,
+ NULL,
+ 0,
+ NI_NAMEREQD);
+
+ /* if getnameinfo fails hostname is still the value
+ from gethostname */
+
+ freeaddrinfo(res);
}
}
return (*env)->NewStringUTF(env, hostname);
@@ -426,14 +402,9 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
jstring host) {
const char *hostname;
jobjectArray ret = 0;
- struct hostent res, *hp = 0;
- // this buffer must be pointer-aligned so is declared
- // with pointer type
- char *buf[HENT_BUF_SIZE/(sizeof (char *))];
-
- /* temporary buffer, on the off chance we need to expand */
- char *tmp = NULL;
- int h_error=0;
+ int retLen = 0;
+ int error = 0;
+ struct addrinfo hints, *res, *resNew = NULL;
if (!initializeInetClasses(env))
return NULL;
@@ -445,6 +416,11 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE);
CHECK_NULL_RETURN(hostname, NULL);
+ /* Try once, with our static buffer. */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_family = AF_INET;
+
#ifdef __solaris__
/*
* Workaround for Solaris bug 4160367 - if a hostname contains a
@@ -458,71 +434,96 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
}
#endif
- /* Try once, with our static buffer. */
-#ifdef HAS_GLIBC_GETHOSTBY_R
- gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &hp, &h_error);
-#else
- hp = gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &h_error);
-#endif
+ error = getaddrinfo(hostname, NULL, &hints, &res);
- /* With the re-entrant system calls, it's possible that the buffer
- * we pass to it is not large enough to hold an exceptionally
- * large DNS entry. This is signaled by errno->ERANGE. We try once
- * more, with a very big size.
- */
- if (hp == NULL && errno == ERANGE) {
- if ((tmp = (char*)malloc(BIG_HENT_BUF_SIZE))) {
-#ifdef HAS_GLIBC_GETHOSTBY_R
- gethostbyname_r(hostname, &res, tmp, BIG_HENT_BUF_SIZE,
- &hp, &h_error);
-#else
- hp = gethostbyname_r(hostname, &res, tmp, BIG_HENT_BUF_SIZE,
- &h_error);
-#endif
- }
- }
- if (hp != NULL) {
- struct in_addr **addrp = (struct in_addr **) hp->h_addr_list;
+ if (error) {
+ /* report error */
+ ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
+ JNU_ReleaseStringPlatformChars(env, host, hostname);
+ return NULL;
+ } else {
int i = 0;
+ struct addrinfo *itr, *last = NULL, *iterator = res;
- while (*addrp != (struct in_addr *) 0) {
- i++;
- addrp++;
+ while (iterator != NULL) {
+ // remove the duplicate one
+ int skip = 0;
+ itr = resNew;
+ while (itr != NULL) {
+ struct sockaddr_in *addr1, *addr2;
+ addr1 = (struct sockaddr_in *)iterator->ai_addr;
+ addr2 = (struct sockaddr_in *)itr->ai_addr;
+ if (addr1->sin_addr.s_addr ==
+ addr2->sin_addr.s_addr) {
+ skip = 1;
+ break;
+ }
+ itr = itr->ai_next;
+ }
+
+ if (!skip) {
+ struct addrinfo *next
+ = (struct addrinfo*) malloc(sizeof(struct addrinfo));
+ if (!next) {
+ JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
+ ret = NULL;
+ goto cleanupAndReturn;
+ }
+ memcpy(next, iterator, sizeof(struct addrinfo));
+ next->ai_next = NULL;
+ if (resNew == NULL) {
+ resNew = next;
+ } else {
+ last->ai_next = next;
+ }
+ last = next;
+ i++;
+ }
+ iterator = iterator->ai_next;
}
- ret = (*env)->NewObjectArray(env, i, ni_iacls, NULL);
+ retLen = i;
+ iterator = resNew;
+
+ ret = (*env)->NewObjectArray(env, retLen, ni_iacls, NULL);
+
if (IS_NULL(ret)) {
/* we may have memory to free at the end of this */
goto cleanupAndReturn;
}
- addrp = (struct in_addr **) hp->h_addr_list;
+
i = 0;
- while (*addrp) {
- jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
- if (IS_NULL(iaObj)) {
- ret = NULL;
- goto cleanupAndReturn;
- }
- setInetAddress_addr(env, iaObj, ntohl((*addrp)->s_addr));
- setInetAddress_hostName(env, iaObj, host);
- (*env)->SetObjectArrayElement(env, ret, i, iaObj);
- addrp++;
- i++;
+ while (iterator != NULL) {
+ jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
+ if (IS_NULL(iaObj)) {
+ ret = NULL;
+ goto cleanupAndReturn;
+ }
+ setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
+ setInetAddress_hostName(env, iaObj, host);
+ (*env)->SetObjectArrayElement(env, ret, i++, iaObj);
+ iterator = iterator->ai_next;
}
- } else {
- JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
- (char *)hostname);
- ret = NULL;
}
-cleanupAndReturn:
- JNU_ReleaseStringPlatformChars(env, host, hostname);
- if (tmp != NULL) {
- free(tmp);
+ cleanupAndReturn:
+ {
+ struct addrinfo *iterator, *tmp;
+ iterator = resNew;
+ while (iterator != NULL) {
+ tmp = iterator;
+ iterator = iterator->ai_next;
+ free(tmp);
+ }
+ JNU_ReleaseStringPlatformChars(env, host, hostname);
}
+
+ freeaddrinfo(res);
+
return ret;
}
+
/*
* Class: java_net_Inet4AddressImpl
* Method: getHostByAddr
@@ -532,66 +533,40 @@ JNIEXPORT jstring JNICALL
Java_java_net_Inet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
jbyteArray addrArray) {
jstring ret = NULL;
- jint addr;
- struct hostent hent, *hp = 0;
- // this buffer must be pointer-aligned so is declared
- // with pointer type
- char *buf[HENT_BUF_SIZE/(sizeof (char *))];
- int h_error = 0;
- char *tmp = NULL;
- /*
- * We are careful here to use the reentrant version of
- * gethostbyname because at the Java level this routine is not
- * protected by any synchronization.
- *
- * Still keeping the reentrant platform dependent calls temporarily
- * We should probably conform to one interface later.
- *
- */
+ char host[NI_MAXHOST+1];
+ int error = 0;
+ int len = 0;
jbyte caddr[4];
+
+ struct sockaddr_in him4;
+ struct sockaddr *sa;
+
+ jint addr;
(*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
addr = ((caddr[0]<<24) & 0xff000000);
addr |= ((caddr[1] <<16) & 0xff0000);
addr |= ((caddr[2] <<8) & 0xff00);
addr |= (caddr[3] & 0xff);
- addr = htonl(addr);
-#ifdef HAS_GLIBC_GETHOSTBY_R
- gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET, &hent,
- (char*)buf, sizeof(buf), &hp, &h_error);
-#else
- hp = gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET, &hent,
- (char*)buf, sizeof(buf), &h_error);
-#endif
- /* With the re-entrant system calls, it's possible that the buffer
- * we pass to it is not large enough to hold an exceptionally
- * large DNS entry. This is signaled by errno->ERANGE. We try once
- * more, with a very big size.
- */
- if (hp == NULL && errno == ERANGE) {
- if ((tmp = (char*)malloc(BIG_HENT_BUF_SIZE))) {
-#ifdef HAS_GLIBC_GETHOSTBY_R
- gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET,
- &hent, tmp, BIG_HENT_BUF_SIZE, &hp, &h_error);
-#else
- hp = gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET,
- &hent, tmp, BIG_HENT_BUF_SIZE, &h_error);
-#endif
- } else {
- JNU_ThrowOutOfMemoryError(env, "getHostByAddr");
- }
+ memset((void *) &him4, 0, sizeof(him4));
+ him4.sin_addr.s_addr = (uint32_t) htonl(addr);
+ him4.sin_family = AF_INET;
+ sa = (struct sockaddr *) &him4;
+ len = sizeof(him4);
+
+ error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0,
+ NI_NAMEREQD);
+
+ if (!error) {
+ ret = (*env)->NewStringUTF(env, host);
}
- if (hp == NULL) {
+
+ if (ret == NULL) {
JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException", NULL);
- } else {
- ret = (*env)->NewStringUTF(env, hp->h_name);
- }
- if (tmp) {
- free(tmp);
}
+
return ret;
}
-
#endif /* _ALLBSD_SOURCE */
#define SET_NONBLOCKING(fd) { \
--
2.2.2