Print this page
Split |
Close |
Expand all |
Collapse all |
--- old/src/solaris/native/java/net/Inet4AddressImpl.c
+++ new/src/solaris/native/java/net/Inet4AddressImpl.c
1 1 /*
2 2 * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 4 *
5 5 * This code is free software; you can redistribute it and/or modify it
6 6 * under the terms of the GNU General Public License version 2 only, as
7 7 * published by the Free Software Foundation. Sun designates this
8 8 * particular file as subject to the "Classpath" exception as provided
9 9 * by Sun in the LICENSE file that accompanied this code.
10 10 *
11 11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 14 * version 2 for more details (a copy is included in the LICENSE file that
15 15 * accompanied this code).
16 16 *
17 17 * You should have received a copy of the GNU General Public License version
18 18 * 2 along with this work; if not, write to the Free Software Foundation,
19 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 20 *
21 21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 23 * have any questions.
24 24 */
25 25
26 26 #include <errno.h>
27 27 #include <sys/time.h>
28 28 #include <sys/types.h>
29 29 #include <sys/socket.h>
30 30 #include <netinet/in_systm.h>
31 31 #include <netinet/in.h>
32 32 #include <netinet/ip.h>
33 33 #include <netinet/ip_icmp.h>
34 34 #include <netdb.h>
35 35 #include <string.h>
36 36 #include <stdlib.h>
37 37 #include <ctype.h>
38 38
39 39 #include "jvm.h"
40 40 #include "jni_util.h"
41 41 #include "net_util.h"
42 42
43 43 #include "java_net_Inet4AddressImpl.h"
44 44
45 45 /* the initial size of our hostent buffers */
46 46 #define HENT_BUF_SIZE 1024
47 47 #define BIG_HENT_BUF_SIZE 10240 /* a jumbo-sized one */
48 48
49 49 /************************************************************************
50 50 * Inet4AddressImpl
51 51 */
52 52
53 53 /*
54 54 * Class: java_net_Inet4AddressImpl
55 55 * Method: getLocalHostName
56 56 * Signature: ()Ljava/lang/String;
57 57 */
58 58 JNIEXPORT jstring JNICALL
59 59 Java_java_net_Inet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
60 60 char hostname[MAXHOSTNAMELEN+1];
61 61
62 62 hostname[0] = '\0';
63 63 if (JVM_GetHostName(hostname, MAXHOSTNAMELEN)) {
64 64 /* Something went wrong, maybe networking is not setup? */
65 65 strcpy(hostname, "localhost");
66 66 } else {
67 67 #ifdef __linux__
68 68 /* On Linux gethostname() says "host.domain.sun.com". On
69 69 * Solaris gethostname() says "host", so extra work is needed.
70 70 */
71 71 #else
72 72 /* Solaris doesn't want to give us a fully qualified domain name.
73 73 * We do a reverse lookup to try and get one. This works
74 74 * if DNS occurs before NIS in /etc/resolv.conf, but fails
75 75 * if NIS comes first (it still gets only a partial name).
76 76 * We use thread-safe system calls.
77 77 */
78 78 #endif /* __linux__ */
79 79 struct hostent res, res2, *hp;
80 80 char buf[HENT_BUF_SIZE];
81 81 char buf2[HENT_BUF_SIZE];
82 82 int h_error=0;
83 83
84 84 #ifdef __GLIBC__
85 85 gethostbyname_r(hostname, &res, buf, sizeof(buf), &hp, &h_error);
86 86 #else
87 87 hp = gethostbyname_r(hostname, &res, buf, sizeof(buf), &h_error);
88 88 #endif
89 89 if (hp) {
90 90 #ifdef __GLIBC__
91 91 gethostbyaddr_r(hp->h_addr, hp->h_length, AF_INET,
92 92 &res2, buf2, sizeof(buf2), &hp, &h_error);
93 93 #else
94 94 hp = gethostbyaddr_r(hp->h_addr, hp->h_length, AF_INET,
95 95 &res2, buf2, sizeof(buf2), &h_error);
96 96 #endif
97 97 if (hp) {
98 98 /*
99 99 * If gethostbyaddr_r() found a fully qualified host name,
100 100 * returns that name. Otherwise, returns the hostname
101 101 * found by gethostname().
102 102 */
103 103 char *p = hp->h_name;
↓ open down ↓ |
103 lines elided |
↑ open up ↑ |
104 104 if ((strlen(hp->h_name) > strlen(hostname))
105 105 && (strncmp(hostname, hp->h_name, strlen(hostname)) == 0)
106 106 && (*(p + strlen(hostname)) == '.'))
107 107 strcpy(hostname, hp->h_name);
108 108 }
109 109 }
110 110 }
111 111 return (*env)->NewStringUTF(env, hostname);
112 112 }
113 113
114 -static jclass ni_iacls;
115 -static jclass ni_ia4cls;
116 -static jmethodID ni_ia4ctrID;
117 -static jfieldID ni_iaaddressID;
118 -static jfieldID ni_iahostID;
119 -static jfieldID ni_iafamilyID;
120 -static int initialized = 0;
121 -
122 114 /*
123 115 * Find an internet address for a given hostname. Note that this
124 116 * code only works for addresses of type INET. The translation
125 117 * of %d.%d.%d.%d to an address (int) occurs in java now, so the
126 118 * String "host" shouldn't *ever* be a %d.%d.%d.%d string
127 119 *
128 120 * Class: java_net_Inet4AddressImpl
129 121 * Method: lookupAllHostAddr
130 122 * Signature: (Ljava/lang/String;)[[B
131 123 */
132 124
133 125 JNIEXPORT jobjectArray JNICALL
134 126 Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
135 127 jstring host) {
136 128 const char *hostname;
137 129 jobjectArray ret = 0;
138 130 struct hostent res, *hp = 0;
139 131 char buf[HENT_BUF_SIZE];
140 132
141 133 /* temporary buffer, on the off chance we need to expand */
142 134 char *tmp = NULL;
143 135 int h_error=0;
144 136
145 - if (!initialized) {
146 - ni_iacls = (*env)->FindClass(env, "java/net/InetAddress");
147 - ni_iacls = (*env)->NewGlobalRef(env, ni_iacls);
148 - ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address");
149 - ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls);
150 - ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V");
151 - ni_iaaddressID = (*env)->GetFieldID(env, ni_iacls, "address", "I");
152 - ni_iafamilyID = (*env)->GetFieldID(env, ni_iacls, "family", "I");
153 - ni_iahostID = (*env)->GetFieldID(env, ni_iacls, "hostName", "Ljava/lang/String;");
154 - initialized = 1;
155 - }
137 + init(env);
156 138
157 139 if (IS_NULL(host)) {
158 140 JNU_ThrowNullPointerException(env, "host is null");
159 141 return 0;
160 142 }
161 143 hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE);
162 144 CHECK_NULL_RETURN(hostname, NULL);
163 145
164 146 #ifdef __solaris__
165 147 /*
166 148 * Workaround for Solaris bug 4160367 - if a hostname contains a
167 149 * white space then 0.0.0.0 is returned
168 150 */
169 151 if (isspace((unsigned char)hostname[0])) {
170 152 JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
171 153 (char *)hostname);
172 154 JNU_ReleaseStringPlatformChars(env, host, hostname);
173 155 return NULL;
174 156 }
175 157 #endif
176 158
177 159 /* Try once, with our static buffer. */
178 160 #ifdef __GLIBC__
179 161 gethostbyname_r(hostname, &res, buf, sizeof(buf), &hp, &h_error);
180 162 #else
181 163 hp = gethostbyname_r(hostname, &res, buf, sizeof(buf), &h_error);
182 164 #endif
183 165
184 166 /* With the re-entrant system calls, it's possible that the buffer
185 167 * we pass to it is not large enough to hold an exceptionally
186 168 * large DNS entry. This is signaled by errno->ERANGE. We try once
187 169 * more, with a very big size.
188 170 */
189 171 if (hp == NULL && errno == ERANGE) {
190 172 if ((tmp = (char*)malloc(BIG_HENT_BUF_SIZE))) {
191 173 #ifdef __GLIBC__
192 174 gethostbyname_r(hostname, &res, tmp, BIG_HENT_BUF_SIZE,
193 175 &hp, &h_error);
194 176 #else
195 177 hp = gethostbyname_r(hostname, &res, tmp, BIG_HENT_BUF_SIZE,
196 178 &h_error);
197 179 #endif
198 180 }
↓ open down ↓ |
33 lines elided |
↑ open up ↑ |
199 181 }
200 182 if (hp != NULL) {
201 183 struct in_addr **addrp = (struct in_addr **) hp->h_addr_list;
202 184 int i = 0;
203 185
204 186 while (*addrp != (struct in_addr *) 0) {
205 187 i++;
206 188 addrp++;
207 189 }
208 190
209 - ret = (*env)->NewObjectArray(env, i, ni_iacls, NULL);
191 + ret = (*env)->NewObjectArray(env, i, ia_class, NULL);
210 192 if (IS_NULL(ret)) {
211 193 /* we may have memory to free at the end of this */
212 194 goto cleanupAndReturn;
213 195 }
214 196 addrp = (struct in_addr **) hp->h_addr_list;
215 197 i = 0;
216 198 while (*addrp) {
217 - jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
199 + jobject iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
218 200 if (IS_NULL(iaObj)) {
219 201 ret = NULL;
220 202 goto cleanupAndReturn;
221 203 }
222 - (*env)->SetIntField(env, iaObj, ni_iaaddressID,
204 + (*env)->SetIntField(env, iaObj, ia_addressID,
223 205 ntohl((*addrp)->s_addr));
224 - (*env)->SetObjectField(env, iaObj, ni_iahostID, host);
206 + (*env)->SetObjectField(env, iaObj, ia_hostNameID, host);
225 207 (*env)->SetObjectArrayElement(env, ret, i, iaObj);
226 208 addrp++;
227 209 i++;
228 210 }
229 211 } else {
230 212 JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
231 213 (char *)hostname);
232 214 ret = NULL;
233 215 }
234 216
235 217 cleanupAndReturn:
236 218 JNU_ReleaseStringPlatformChars(env, host, hostname);
237 219 if (tmp != NULL) {
238 220 free(tmp);
239 221 }
240 222 return ret;
241 223 }
242 224
243 225 /*
244 226 * Class: java_net_Inet4AddressImpl
245 227 * Method: getHostByAddr
246 228 * Signature: (I)Ljava/lang/String;
247 229 */
248 230 JNIEXPORT jstring JNICALL
249 231 Java_java_net_Inet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
250 232 jbyteArray addrArray) {
251 233 jstring ret = NULL;
252 234 jint addr;
253 235 struct hostent hent, *hp = 0;
254 236 char buf[HENT_BUF_SIZE];
255 237 int h_error = 0;
256 238 char *tmp = NULL;
257 239
258 240 /*
259 241 * We are careful here to use the reentrant version of
260 242 * gethostbyname because at the Java level this routine is not
261 243 * protected by any synchronization.
262 244 *
263 245 * Still keeping the reentrant platform dependent calls temporarily
264 246 * We should probably conform to one interface later.
265 247 *
266 248 */
267 249 jbyte caddr[4];
268 250 (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
269 251 addr = ((caddr[0]<<24) & 0xff000000);
270 252 addr |= ((caddr[1] <<16) & 0xff0000);
271 253 addr |= ((caddr[2] <<8) & 0xff00);
272 254 addr |= (caddr[3] & 0xff);
273 255 addr = htonl(addr);
274 256 #ifdef __GLIBC__
275 257 gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET, &hent,
276 258 buf, sizeof(buf), &hp, &h_error);
277 259 #else
278 260 hp = gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET, &hent,
279 261 buf, sizeof(buf), &h_error);
280 262 #endif
281 263 /* With the re-entrant system calls, it's possible that the buffer
282 264 * we pass to it is not large enough to hold an exceptionally
283 265 * large DNS entry. This is signaled by errno->ERANGE. We try once
284 266 * more, with a very big size.
285 267 */
286 268 if (hp == NULL && errno == ERANGE) {
287 269 if ((tmp = (char*)malloc(BIG_HENT_BUF_SIZE))) {
288 270 #ifdef __GLIBC__
289 271 gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET,
290 272 &hent, tmp, BIG_HENT_BUF_SIZE, &hp, &h_error);
291 273 #else
292 274 hp = gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET,
293 275 &hent, tmp, BIG_HENT_BUF_SIZE, &h_error);
294 276 #endif
295 277 } else {
296 278 JNU_ThrowOutOfMemoryError(env, "getHostByAddr");
297 279 }
298 280 }
299 281 if (hp == NULL) {
300 282 JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException", NULL);
301 283 } else {
302 284 ret = (*env)->NewStringUTF(env, hp->h_name);
303 285 }
304 286 if (tmp) {
305 287 free(tmp);
306 288 }
307 289 return ret;
308 290 }
309 291
310 292 #define SET_NONBLOCKING(fd) { \
311 293 int flags = fcntl(fd, F_GETFL); \
312 294 flags |= O_NONBLOCK; \
313 295 fcntl(fd, F_SETFL, flags); \
314 296 }
315 297
316 298 /**
317 299 * ping implementation.
318 300 * Send a ICMP_ECHO_REQUEST packet every second until either the timeout
319 301 * expires or a answer is received.
320 302 * Returns true is an ECHO_REPLY is received, otherwise, false.
321 303 */
322 304 static jboolean
323 305 ping4(JNIEnv *env, jint fd, struct sockaddr_in* him, jint timeout,
324 306 struct sockaddr_in* netif, jint ttl) {
325 307 jint size;
326 308 jint n, hlen1, icmplen;
327 309 socklen_t len;
328 310 char sendbuf[1500];
329 311 char recvbuf[1500];
330 312 struct icmp *icmp;
331 313 struct ip *ip;
332 314 struct sockaddr_in sa_recv;
333 315 jchar pid;
334 316 jint tmout2, seq = 1;
335 317 struct timeval tv;
336 318 size_t plen;
337 319
338 320 /* icmp_id is a 16 bit data type, therefore down cast the pid */
339 321 pid = (jchar)getpid();
340 322 size = 60*1024;
341 323 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
342 324 /*
343 325 * sets the ttl (max number of hops)
344 326 */
345 327 if (ttl > 0) {
346 328 setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
347 329 }
348 330 /*
349 331 * a specific interface was specified, so let's bind the socket
350 332 * to that interface to ensure the requests are sent only through it.
351 333 */
352 334 if (netif != NULL) {
353 335 if (bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in)) < 0) {
354 336 NET_ThrowNew(env, errno, "Can't bind socket");
355 337 close(fd);
356 338 return JNI_FALSE;
357 339 }
358 340 }
359 341 /*
360 342 * Make the socket non blocking so we can use select
361 343 */
362 344 SET_NONBLOCKING(fd);
363 345 do {
364 346 /*
365 347 * create the ICMP request
366 348 */
367 349 icmp = (struct icmp *) sendbuf;
368 350 icmp->icmp_type = ICMP_ECHO;
369 351 icmp->icmp_code = 0;
370 352 icmp->icmp_id = htons(pid);
371 353 icmp->icmp_seq = htons(seq);
372 354 seq++;
373 355 gettimeofday(&tv, NULL);
374 356 memcpy(icmp->icmp_data, &tv, sizeof(tv));
375 357 plen = ICMP_ADVLENMIN + sizeof(tv);
376 358 icmp->icmp_cksum = 0;
377 359 icmp->icmp_cksum = in_cksum((u_short *)icmp, plen);
378 360 /*
379 361 * send it
380 362 */
381 363 n = sendto(fd, sendbuf, plen, 0, (struct sockaddr *)him,
382 364 sizeof(struct sockaddr));
383 365 if (n < 0 && errno != EINPROGRESS ) {
384 366 NET_ThrowNew(env, errno, "Can't send ICMP packet");
385 367 close(fd);
386 368 return JNI_FALSE;
387 369 }
388 370
389 371 tmout2 = timeout > 1000 ? 1000 : timeout;
390 372 do {
391 373 tmout2 = NET_Wait(env, fd, NET_WAIT_READ, tmout2);
392 374 if (tmout2 >= 0) {
393 375 len = sizeof(sa_recv);
394 376 n = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&sa_recv, &len);
395 377 ip = (struct ip*) recvbuf;
396 378 hlen1 = (ip->ip_hl) << 2;
397 379 icmp = (struct icmp *) (recvbuf + hlen1);
398 380 icmplen = n - hlen1;
399 381 /*
400 382 * We did receive something, but is it what we were expecting?
401 383 * I.E.: A ICMP_ECHOREPLY packet with the proper PID.
402 384 */
403 385 if (icmplen >= 8 && icmp->icmp_type == ICMP_ECHOREPLY &&
404 386 (ntohs(icmp->icmp_id) == pid) &&
405 387 (him->sin_addr.s_addr == sa_recv.sin_addr.s_addr)) {
406 388 close(fd);
407 389 return JNI_TRUE;
408 390 }
409 391 }
410 392 } while (tmout2 > 0);
411 393 timeout -= 1000;
412 394 } while (timeout >0);
413 395 close(fd);
414 396 return JNI_FALSE;
415 397 }
416 398
417 399 /*
418 400 * Class: java_net_Inet4AddressImpl
419 401 * Method: isReachable0
420 402 * Signature: ([bI[bI)Z
421 403 */
422 404 JNIEXPORT jboolean JNICALL
423 405 Java_java_net_Inet4AddressImpl_isReachable0(JNIEnv *env, jobject this,
424 406 jbyteArray addrArray,
425 407 jint timeout,
426 408 jbyteArray ifArray,
427 409 jint ttl) {
428 410 jint addr;
429 411 jbyte caddr[4];
430 412 jint fd;
431 413 struct sockaddr_in him;
432 414 struct sockaddr_in* netif = NULL;
433 415 struct sockaddr_in inf;
434 416 int len = 0;
435 417 int connect_rv = -1;
436 418 int sz;
437 419
438 420 memset((char *) caddr, 0, sizeof(caddr));
439 421 memset((char *) &him, 0, sizeof(him));
440 422 sz = (*env)->GetArrayLength(env, addrArray);
441 423 if (sz != 4) {
442 424 return JNI_FALSE;
443 425 }
444 426 (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
445 427 addr = ((caddr[0]<<24) & 0xff000000);
446 428 addr |= ((caddr[1] <<16) & 0xff0000);
447 429 addr |= ((caddr[2] <<8) & 0xff00);
448 430 addr |= (caddr[3] & 0xff);
449 431 addr = htonl(addr);
450 432 him.sin_addr.s_addr = addr;
451 433 him.sin_family = AF_INET;
452 434 len = sizeof(him);
453 435 /*
454 436 * If a network interface was specified, let's create the address
455 437 * for it.
456 438 */
457 439 if (!(IS_NULL(ifArray))) {
458 440 memset((char *) caddr, 0, sizeof(caddr));
459 441 (*env)->GetByteArrayRegion(env, ifArray, 0, 4, caddr);
460 442 addr = ((caddr[0]<<24) & 0xff000000);
461 443 addr |= ((caddr[1] <<16) & 0xff0000);
462 444 addr |= ((caddr[2] <<8) & 0xff00);
463 445 addr |= (caddr[3] & 0xff);
464 446 addr = htonl(addr);
465 447 inf.sin_addr.s_addr = addr;
466 448 inf.sin_family = AF_INET;
467 449 inf.sin_port = 0;
468 450 netif = &inf;
469 451 }
470 452
471 453 /*
472 454 * Let's try to create a RAW socket to send ICMP packets
473 455 * This usually requires "root" privileges, so it's likely to fail.
474 456 */
475 457 fd = JVM_Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
476 458 if (fd != -1) {
477 459 /*
478 460 * It didn't fail, so we can use ICMP_ECHO requests.
479 461 */
480 462 return ping4(env, fd, &him, timeout, netif, ttl);
481 463 }
482 464
483 465 /*
484 466 * Can't create a raw socket, so let's try a TCP socket
485 467 */
486 468 fd = JVM_Socket(AF_INET, SOCK_STREAM, 0);
487 469 if (fd == JVM_IO_ERR) {
488 470 /* note: if you run out of fds, you may not be able to load
489 471 * the exception class, and get a NoClassDefFoundError
490 472 * instead.
491 473 */
492 474 NET_ThrowNew(env, errno, "Can't create socket");
493 475 return JNI_FALSE;
494 476 }
495 477 if (ttl > 0) {
496 478 setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
497 479 }
498 480
499 481 /*
500 482 * A network interface was specified, so let's bind to it.
501 483 */
502 484 if (netif != NULL) {
503 485 if (bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in)) < 0) {
504 486 NET_ThrowNew(env, errno, "Can't bind socket");
505 487 close(fd);
506 488 return JNI_FALSE;
507 489 }
508 490 }
509 491
510 492 /*
511 493 * Make the socket non blocking so we can use select/poll.
512 494 */
513 495 SET_NONBLOCKING(fd);
514 496
515 497 /* no need to use NET_Connect as non-blocking */
516 498 him.sin_port = htons(7); /* Echo */
517 499 connect_rv = JVM_Connect(fd, (struct sockaddr *)&him, len);
518 500
519 501 /**
520 502 * connection established or refused immediately, either way it means
521 503 * we were able to reach the host!
522 504 */
523 505 if (connect_rv == 0 || errno == ECONNREFUSED) {
524 506 close(fd);
525 507 return JNI_TRUE;
526 508 } else {
527 509 int optlen;
528 510
529 511 switch (errno) {
530 512 case ENETUNREACH: /* Network Unreachable */
531 513 case EAFNOSUPPORT: /* Address Family not supported */
532 514 case EADDRNOTAVAIL: /* address is not available on the remote machine */
533 515 #ifdef __linux__
534 516 case EINVAL:
535 517 /*
536 518 * On some Linuxes, when bound to the loopback interface, connect
537 519 * will fail and errno will be set to EINVAL. When that happens,
538 520 * don't throw an exception, just return false.
539 521 */
540 522 #endif /* __linux__ */
541 523 close(fd);
542 524 return JNI_FALSE;
543 525 }
544 526
545 527 if (errno != EINPROGRESS) {
546 528 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
547 529 "connect failed");
548 530 close(fd);
549 531 return JNI_FALSE;
550 532 }
551 533
552 534 timeout = NET_Wait(env, fd, NET_WAIT_CONNECT, timeout);
553 535 if (timeout >= 0) {
554 536 /* has connection been established? */
555 537 optlen = sizeof(connect_rv);
556 538 if (JVM_GetSockOpt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
557 539 &optlen) <0) {
558 540 connect_rv = errno;
559 541 }
560 542 if (connect_rv == 0 || connect_rv == ECONNREFUSED) {
561 543 close(fd);
562 544 return JNI_TRUE;
563 545 }
564 546 }
565 547 close(fd);
566 548 return JNI_FALSE;
567 549 }
568 550 }
↓ open down ↓ |
334 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX