< prev index next >

src/java.base/unix/native/libnio/ch/Net.c

Print this page
rev 55750 : UDS support, temporary commit


 131         strcpy(uts.sysname, "?");
 132         const int utsRes = uname(&uts);
 133         int major = -1;
 134         int minor = -1;
 135         major = atoi(uts.version);
 136         minor = atoi(uts.release);
 137         if (strcmp(uts.sysname, "AIX") == 0) {
 138             if (major < 6 || (major == 6 && minor < 1)) {// unsupported on aix < 6.1
 139                 result = JNI_FALSE;
 140             }
 141         }
 142         alreadyChecked = JNI_TRUE;
 143     }
 144     return result;
 145 }
 146 
 147 #endif  /* _AIX */
 148 
 149 static jclass isa_class;        /* java.net.InetSocketAddress */
 150 static jmethodID isa_ctorID;    /* InetSocketAddress(InetAddress, int) */



 151 
 152 JNIEXPORT void JNICALL
 153 Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz)
 154 {
 155      jclass cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
 156      CHECK_NULL(cls);
 157      isa_class = (*env)->NewGlobalRef(env, cls);
 158      if (isa_class == NULL) {
 159          JNU_ThrowOutOfMemoryError(env, NULL);
 160          return;
 161      }
 162      isa_ctorID = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/net/InetAddress;I)V");
 163      CHECK_NULL(isa_ctorID);
 164 












 165      initInetAddressIDs(env);
 166 }
 167 
 168 JNIEXPORT jboolean JNICALL
 169 Java_sun_nio_ch_Net_isIPv6Available0(JNIEnv* env, jclass cl)
 170 {
 171     return (ipv6_available()) ? JNI_TRUE : JNI_FALSE;
 172 }
 173 
 174 JNIEXPORT jboolean JNICALL
 175 Java_sun_nio_ch_Net_isReusePortAvailable0(JNIEnv* env, jclass c1)
 176 {
 177     return (reuseport_available()) ? JNI_TRUE : JNI_FALSE;
 178 }
 179 
 180 JNIEXPORT jint JNICALL
 181 Java_sun_nio_ch_Net_isExclusiveBindAvailable(JNIEnv *env, jclass clazz) {
 182     return -1;
 183 }
 184 


 256             return -1;
 257         }
 258     }
 259 
 260     /* By default, Linux uses the route default */
 261     if (domain == AF_INET6 && type == SOCK_DGRAM) {
 262         int arg = 1;
 263         if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &arg,
 264                        sizeof(arg)) < 0) {
 265             JNU_ThrowByNameWithLastError(env,
 266                                          JNU_JAVANETPKG "SocketException",
 267                                          "Unable to set IPV6_MULTICAST_HOPS");
 268             close(fd);
 269             return -1;
 270         }
 271     }
 272 #endif
 273     return fd;
 274 }
 275 











 276 JNIEXPORT void JNICALL
 277 Java_sun_nio_ch_Net_bind0(JNIEnv *env, jclass clazz, jobject fdo, jboolean preferIPv6,
 278                           jboolean useExclBind, jobject iao, int port)
 279 {
 280     SOCKETADDRESS sa;
 281     int sa_len = 0;
 282     int rv = 0;
 283 
 284     if (NET_InetAddressToSockaddr(env, iao, port, &sa, &sa_len,
 285                                   preferIPv6) != 0) {
 286         return;
 287     }
 288 
 289     rv = NET_Bind(fdval(env, fdo), &sa, sa_len);
 290     if (rv != 0) {
 291         handleSocketError(env, errno);
 292     }
 293 }
 294 
 295 JNIEXPORT void JNICALL



















 296 Java_sun_nio_ch_Net_listen(JNIEnv *env, jclass cl, jobject fdo, jint backlog)
 297 {
 298     if (listen(fdval(env, fdo), backlog) < 0)
 299         handleSocketError(env, errno);
 300 }
 301 
 302 JNIEXPORT jint JNICALL
 303 Java_sun_nio_ch_Net_connect0(JNIEnv *env, jclass clazz, jboolean preferIPv6,
 304                              jobject fdo, jobject iao, jint port)
 305 {
 306     SOCKETADDRESS sa;
 307     int sa_len = 0;
 308     int rv;
 309 
 310     if (NET_InetAddressToSockaddr(env, iao, port, &sa, &sa_len, preferIPv6) != 0) {
 311         return IOS_THROWN;
 312     }
 313 
 314     rv = connect(fdval(env, fdo), &sa.sa, sa_len);
 315     if (rv != 0) {
 316         if (errno == EINPROGRESS) {
 317             return IOS_UNAVAILABLE;
 318         } else if (errno == EINTR) {
 319             return IOS_INTERRUPTED;
 320         }
 321         return handleSocketError(env, errno);
 322     }
 323     return 1;
 324 }
 325 
 326 JNIEXPORT jint JNICALL



























 327 Java_sun_nio_ch_Net_accept(JNIEnv *env, jclass clazz, jobject fdo, jobject newfdo,
 328                            jobjectArray isaa)
 329 {
 330     jint fd = fdval(env, fdo);
 331     jint newfd;
 332     SOCKETADDRESS sa;
 333     socklen_t sa_len = sizeof(SOCKETADDRESS);
 334     jobject remote_ia;
 335     jint remote_port = 0;
 336     jobject isa;
 337 
 338     /* accept connection but ignore ECONNABORTED */
 339     for (;;) {
 340         newfd = accept(fd, &sa.sa, &sa_len);
 341         if (newfd >= 0) {
 342             break;
 343         }
 344         if (errno != ECONNABORTED) {
 345             break;
 346         }
 347         /* ECONNABORTED => restart accept */
 348     }
 349 
 350     if (newfd < 0) {
 351         if (errno == EAGAIN || errno == EWOULDBLOCK)
 352             return IOS_UNAVAILABLE;
 353         if (errno == EINTR)
 354             return IOS_INTERRUPTED;
 355         JNU_ThrowIOExceptionWithLastError(env, "Accept failed");
 356         return IOS_THROWN;
 357     }
 358 
 359     setfdval(env, newfdo, newfd);
 360 

 361     remote_ia = NET_SockaddrToInetAddress(env, &sa, (int *)&remote_port);
 362     CHECK_NULL_RETURN(remote_ia, IOS_THROWN);
 363 
 364     isa = (*env)->NewObject(env, isa_class, isa_ctorID, remote_ia, remote_port);
 365     CHECK_NULL_RETURN(isa, IOS_THROWN);
 366     (*env)->SetObjectArrayElement(env, isaa, 0, isa);
 367 
 368     return 1;








 369 }
 370 
 371 JNIEXPORT jint JNICALL
 372 Java_sun_nio_ch_Net_localPort(JNIEnv *env, jclass clazz, jobject fdo)
 373 {
 374     SOCKETADDRESS sa;
 375     socklen_t sa_len = sizeof(SOCKETADDRESS);
 376     if (getsockname(fdval(env, fdo), &sa.sa, &sa_len) < 0) {
 377 #ifdef _ALLBSD_SOURCE
 378         /*
 379          * XXXBSD:
 380          * ECONNRESET is specific to the BSDs. We can not return an error,
 381          * as the calling Java code with raise a java.lang.Error given the expectation
 382          * that getsockname() will never fail. According to the Single UNIX Specification,
 383          * it shouldn't fail. As such, we just fill in generic Linux-compatible values.
 384          */
 385         if (errno == ECONNRESET) {
 386             bzero(&sa.sa4, sizeof(sa));
 387             sa.sa4.sin_len = sizeof(struct sockaddr_in);
 388             sa.sa4.sin_family = AF_INET;


 414          * as the calling Java code with raise a java.lang.Error with the expectation
 415          * that getsockname() will never fail. According to the Single UNIX Specification,
 416          * it shouldn't fail. As such, we just fill in generic Linux-compatible values.
 417          */
 418         if (errno == ECONNRESET) {
 419             bzero(&sa.sa4, sizeof(sa));
 420             sa.sa4.sin_len  = sizeof(struct sockaddr_in);
 421             sa.sa4.sin_family = AF_INET;
 422             sa.sa4.sin_port = htonl(0);
 423             sa.sa4.sin_addr.s_addr = INADDR_ANY;
 424         } else {
 425             handleSocketError(env, errno);
 426             return NULL;
 427         }
 428 #else /* _ALLBSD_SOURCE */
 429         handleSocketError(env, errno);
 430         return NULL;
 431 #endif /* _ALLBSD_SOURCE */
 432     }
 433     return NET_SockaddrToInetAddress(env, &sa, &port);























 434 }
 435 
 436 JNIEXPORT jint JNICALL
 437 Java_sun_nio_ch_Net_remotePort(JNIEnv *env, jclass clazz, jobject fdo)
 438 {
 439     SOCKETADDRESS sa;
 440     socklen_t sa_len = sizeof(sa);
 441 
 442     if (getpeername(fdval(env, fdo), &sa.sa, &sa_len) < 0) {
 443         handleSocketError(env, errno);
 444         return IOS_THROWN;
 445     }
 446     return NET_GetPortFromSockaddr(&sa);
 447 }
 448 
 449 JNIEXPORT jobject JNICALL
 450 Java_sun_nio_ch_Net_remoteInetAddress(JNIEnv *env, jclass clazz, jobject fdo)
 451 {
 452     SOCKETADDRESS sa;
 453     socklen_t sa_len = sizeof(sa);




 131         strcpy(uts.sysname, "?");
 132         const int utsRes = uname(&uts);
 133         int major = -1;
 134         int minor = -1;
 135         major = atoi(uts.version);
 136         minor = atoi(uts.release);
 137         if (strcmp(uts.sysname, "AIX") == 0) {
 138             if (major < 6 || (major == 6 && minor < 1)) {// unsupported on aix < 6.1
 139                 result = JNI_FALSE;
 140             }
 141         }
 142         alreadyChecked = JNI_TRUE;
 143     }
 144     return result;
 145 }
 146 
 147 #endif  /* _AIX */
 148 
 149 static jclass isa_class;        /* java.net.InetSocketAddress */
 150 static jmethodID isa_ctorID;    /* InetSocketAddress(InetAddress, int) */
 151 static jclass usa_class;        /* java.net.UnixSocketAddress */
 152 static jmethodID usa_ctor;      /* UnixSocketAddress() */
 153 static jmethodID usa_ctorBytes; /* UnixSocketAddress(byte[]) */
 154 
 155 JNIEXPORT void JNICALL
 156 Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz)
 157 {
 158      jclass cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
 159      CHECK_NULL(cls);
 160      isa_class = (*env)->NewGlobalRef(env, cls);
 161      if (isa_class == NULL) {
 162          JNU_ThrowOutOfMemoryError(env, NULL);
 163          return;
 164      }
 165      isa_ctorID = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/net/InetAddress;I)V");
 166      CHECK_NULL(isa_ctorID);
 167      
 168      cls = (*env)->FindClass(env, "java/net/UnixSocketAddress");
 169      CHECK_NULL(cls);
 170      usa_class = (*env)->NewGlobalRef(env, cls);
 171      if (usa_class == NULL) {
 172          JNU_ThrowOutOfMemoryError(env, NULL);
 173          return;
 174      }
 175      usa_ctor = (*env)->GetMethodID(env, cls, "<init>", "()V");
 176      CHECK_NULL(usa_ctor);
 177      usa_ctorBytes = (*env)->GetMethodID(env, cls, "<init>", "([B)V");
 178      CHECK_NULL(usa_ctorBytes);
 179 
 180      initInetAddressIDs(env);
 181 }
 182 
 183 JNIEXPORT jboolean JNICALL
 184 Java_sun_nio_ch_Net_isIPv6Available0(JNIEnv* env, jclass cl)
 185 {
 186     return (ipv6_available()) ? JNI_TRUE : JNI_FALSE;
 187 }
 188 
 189 JNIEXPORT jboolean JNICALL
 190 Java_sun_nio_ch_Net_isReusePortAvailable0(JNIEnv* env, jclass c1)
 191 {
 192     return (reuseport_available()) ? JNI_TRUE : JNI_FALSE;
 193 }
 194 
 195 JNIEXPORT jint JNICALL
 196 Java_sun_nio_ch_Net_isExclusiveBindAvailable(JNIEnv *env, jclass clazz) {
 197     return -1;
 198 }
 199 


 271             return -1;
 272         }
 273     }
 274 
 275     /* By default, Linux uses the route default */
 276     if (domain == AF_INET6 && type == SOCK_DGRAM) {
 277         int arg = 1;
 278         if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &arg,
 279                        sizeof(arg)) < 0) {
 280             JNU_ThrowByNameWithLastError(env,
 281                                          JNU_JAVANETPKG "SocketException",
 282                                          "Unable to set IPV6_MULTICAST_HOPS");
 283             close(fd);
 284             return -1;
 285         }
 286     }
 287 #endif
 288     return fd;
 289 }
 290 
 291 JNIEXPORT jint JNICALL 
 292 Java_sun_nio_ch_Net_socket1 (JNIEnv *env, jclass clazz, jboolean stream) 
 293 {
 294     int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
 295     int fd = socket(AF_UNIX, type, 0);
 296     if (fd < 0) {
 297         return handleSocketError(env, errno);
 298     }
 299     return fd;
 300 }
 301 
 302 JNIEXPORT void JNICALL
 303 Java_sun_nio_ch_Net_bind0(JNIEnv *env, jclass clazz, jobject fdo, jboolean preferIPv6,
 304                           jboolean useExclBind, jobject iao, int port)
 305 {
 306     SOCKETADDRESS sa;
 307     int sa_len = 0;
 308     int rv = 0;
 309 
 310     if (NET_InetAddressToSockaddr(env, iao, port, &sa, &sa_len,
 311                                   preferIPv6) != 0) {
 312         return;
 313     }
 314 
 315     rv = NET_Bind(fdval(env, fdo), &sa, sa_len);
 316     if (rv != 0) {
 317         handleSocketError(env, errno);
 318     }
 319 }
 320 
 321 JNIEXPORT void JNICALL
 322 Java_sun_nio_ch_Net_bind1(JNIEnv *env, jclass clazz, jobject fdo, jbyteArray uao)
 323 {
 324     SOCKETADDRESS sa;
 325     memset(&sa, 0x00, sizeof (sa));
 326     sa.sau.sun_family = AF_UNIX;
 327     size_t uao_len = (* env) -> GetArrayLength(env, uao);
 328     size_t sa_len = sizeof (sa.sau.sun_path);
 329     if (uao_len > sa_len) {
 330         // TODO: throw propper exception
 331         return;
 332     }
 333     (* env) -> GetByteArrayRegion(env, uao, 0, uao_len, (jbyte *) sa.sau.sun_path);
 334     int rv = bind(fdval(env, fdo), &sa.sa, sa_len);
 335     if (rv != 0) {
 336         handleSocketError(env, errno);
 337     }
 338 }
 339 
 340 JNIEXPORT void JNICALL
 341 Java_sun_nio_ch_Net_listen(JNIEnv *env, jclass cl, jobject fdo, jint backlog)
 342 {
 343     if (listen(fdval(env, fdo), backlog) < 0)
 344         handleSocketError(env, errno);
 345 }
 346 
 347 JNIEXPORT jint JNICALL
 348 Java_sun_nio_ch_Net_connect0(JNIEnv *env, jclass clazz, jboolean preferIPv6,
 349                              jobject fdo, jobject iao, jint port)
 350 {
 351     SOCKETADDRESS sa;
 352     int sa_len = 0;
 353     int rv;
 354 
 355     if (NET_InetAddressToSockaddr(env, iao, port, &sa, &sa_len, preferIPv6) != 0) {
 356         return IOS_THROWN;
 357     }
 358 
 359     rv = connect(fdval(env, fdo), &sa.sa, sa_len);
 360     if (rv != 0) {
 361         if (errno == EINPROGRESS) {
 362             return IOS_UNAVAILABLE;
 363         } else if (errno == EINTR) {
 364             return IOS_INTERRUPTED;
 365         }
 366         return handleSocketError(env, errno);
 367     }
 368     return 1;
 369 }
 370 
 371 JNIEXPORT jint JNICALL
 372 Java_sun_nio_ch_Net_connect1(JNIEnv *env, jclass clazz, jobject fdo, jbyteArray uao)
 373 {
 374     SOCKETADDRESS sa;
 375     memset(&sa, 0x00, sizeof (sa));
 376     sa.sau.sun_family = AF_UNIX;
 377     size_t uao_len = (* env) -> GetArrayLength(env, uao);
 378     size_t sa_len = sizeof (sa.sau.sun_path);
 379     if (uao_len > sa_len) {
 380         // TODO: throw propper exception
 381         return IOS_UNAVAILABLE;
 382     }
 383     (* env) -> GetByteArrayRegion(env, uao, 0, uao_len, (jbyte *) sa.sau.sun_path);
 384     
 385     // TODO: refactoring, common method
 386     int rv = connect(fdval(env, fdo), &sa.sa, sa_len);
 387     if (rv != 0) {
 388         if (errno == EINPROGRESS) {
 389             return IOS_UNAVAILABLE;
 390         } else if (errno == EINTR) {
 391             return IOS_INTERRUPTED;
 392         }
 393         return handleSocketError(env, errno);
 394     }
 395     return 1;
 396 }
 397 
 398 JNIEXPORT jint JNICALL
 399 Java_sun_nio_ch_Net_accept(JNIEnv *env, jclass clazz, jobject fdo, jobject newfdo,
 400                            jobjectArray isaa)
 401 {
 402     jint fd = fdval(env, fdo);
 403     jint newfd;
 404     SOCKETADDRESS sa;
 405     socklen_t sa_len = sizeof(SOCKETADDRESS);
 406     jobject remote_ia;
 407     jint remote_port = 0;
 408     jobject isa;
 409 
 410     /* accept connection but ignore ECONNABORTED */
 411     for (;;) {
 412         newfd = accept(fd, &sa.sa, &sa_len);
 413         if (newfd >= 0) {
 414             break;
 415         }
 416         if (errno != ECONNABORTED) {
 417             break;
 418         }
 419         /* ECONNABORTED => restart accept */
 420     }
 421 
 422     if (newfd < 0) {
 423         if (errno == EAGAIN || errno == EWOULDBLOCK)
 424             return IOS_UNAVAILABLE;
 425         if (errno == EINTR)
 426             return IOS_INTERRUPTED;
 427         JNU_ThrowIOExceptionWithLastError(env, "Accept failed");
 428         return IOS_THROWN;
 429     }
 430 
 431     setfdval(env, newfdo, newfd);
 432     
 433     if (sa.sa.sa_family == AF_INET || sa.sa.sa_family == AF_INET6) {
 434         remote_ia = NET_SockaddrToInetAddress(env, &sa, (int *)&remote_port);
 435         CHECK_NULL_RETURN(remote_ia, IOS_THROWN);
 436 
 437         isa = (*env)->NewObject(env, isa_class, isa_ctorID, remote_ia, remote_port);
 438         CHECK_NULL_RETURN(isa, IOS_THROWN);
 439         (*env)->SetObjectArrayElement(env, isaa, 0, isa);
 440 
 441         return 1;
 442     } else if (sa.sa.sa_family == AF_UNIX) {
 443         isa = (*env)->NewObject(env, usa_class, usa_ctor);
 444         CHECK_NULL_RETURN(isa, IOS_THROWN);
 445         (*env)->SetObjectArrayElement(env, isaa, 0, isa);
 446         return 1;
 447     } else {
 448         return -6; // UNSUPPORTED_CASE
 449     }
 450 }
 451 
 452 JNIEXPORT jint JNICALL
 453 Java_sun_nio_ch_Net_localPort(JNIEnv *env, jclass clazz, jobject fdo)
 454 {
 455     SOCKETADDRESS sa;
 456     socklen_t sa_len = sizeof(SOCKETADDRESS);
 457     if (getsockname(fdval(env, fdo), &sa.sa, &sa_len) < 0) {
 458 #ifdef _ALLBSD_SOURCE
 459         /*
 460          * XXXBSD:
 461          * ECONNRESET is specific to the BSDs. We can not return an error,
 462          * as the calling Java code with raise a java.lang.Error given the expectation
 463          * that getsockname() will never fail. According to the Single UNIX Specification,
 464          * it shouldn't fail. As such, we just fill in generic Linux-compatible values.
 465          */
 466         if (errno == ECONNRESET) {
 467             bzero(&sa.sa4, sizeof(sa));
 468             sa.sa4.sin_len = sizeof(struct sockaddr_in);
 469             sa.sa4.sin_family = AF_INET;


 495          * as the calling Java code with raise a java.lang.Error with the expectation
 496          * that getsockname() will never fail. According to the Single UNIX Specification,
 497          * it shouldn't fail. As such, we just fill in generic Linux-compatible values.
 498          */
 499         if (errno == ECONNRESET) {
 500             bzero(&sa.sa4, sizeof(sa));
 501             sa.sa4.sin_len  = sizeof(struct sockaddr_in);
 502             sa.sa4.sin_family = AF_INET;
 503             sa.sa4.sin_port = htonl(0);
 504             sa.sa4.sin_addr.s_addr = INADDR_ANY;
 505         } else {
 506             handleSocketError(env, errno);
 507             return NULL;
 508         }
 509 #else /* _ALLBSD_SOURCE */
 510         handleSocketError(env, errno);
 511         return NULL;
 512 #endif /* _ALLBSD_SOURCE */
 513     }
 514     return NET_SockaddrToInetAddress(env, &sa, &port);
 515 }
 516 
 517 JNIEXPORT jobject JNICALL
 518 Java_sun_nio_ch_Net_localSocketAddress(JNIEnv *env, jclass clazz, jobject fdo) 
 519 {
 520     SOCKETADDRESS sa;
 521     socklen_t sa_len = sizeof (SOCKETADDRESS);
 522     memset(&sa, 0x00, sa_len);
 523     if (getsockname(fdval(env, fdo), &sa.sa, &sa_len) != 0) {
 524         return NULL; // TODO: exception?
 525     }
 526 
 527     if (sa.sa.sa_family == AF_UNIX) {
 528         jbyteArray addr = (*env)->NewByteArray(env, sizeof(sa.sau.sun_path));
 529         (*env)->SetByteArrayRegion(env, addr, 0, sizeof(sa.sau.sun_path), (jbyte *) sa.sau.sun_path);
 530         return (*env)->NewObject(env, usa_class, usa_ctorBytes, addr);
 531     } else if (sa.sa.sa_family == AF_INET || sa.sa.sa_family == AF_INET6) {
 532         jobject address = Java_sun_nio_ch_Net_localInetAddress(env, clazz, fdo);
 533         jint port = Java_sun_nio_ch_Net_localPort(env, clazz, fdo);
 534         return (*env)->NewObject(env, isa_class, isa_ctorID, address, port);
 535     } else {
 536         return NULL; // TODO: exception?
 537     }
 538 }
 539 
 540 JNIEXPORT jint JNICALL
 541 Java_sun_nio_ch_Net_remotePort(JNIEnv *env, jclass clazz, jobject fdo)
 542 {
 543     SOCKETADDRESS sa;
 544     socklen_t sa_len = sizeof(sa);
 545 
 546     if (getpeername(fdval(env, fdo), &sa.sa, &sa_len) < 0) {
 547         handleSocketError(env, errno);
 548         return IOS_THROWN;
 549     }
 550     return NET_GetPortFromSockaddr(&sa);
 551 }
 552 
 553 JNIEXPORT jobject JNICALL
 554 Java_sun_nio_ch_Net_remoteInetAddress(JNIEnv *env, jclass clazz, jobject fdo)
 555 {
 556     SOCKETADDRESS sa;
 557     socklen_t sa_len = sizeof(sa);


< prev index next >