< prev index next >

src/java.base/unix/native/libnet/ExtendedOptionsImpl.c

Print this page




  37 
  38 static jfieldID sf_fd_fdID;             /* FileDescriptor.fd */
  39 
  40 /* References to the literal enum values */
  41 
  42 static jobject sfs_NOSTATUS;
  43 static jobject sfs_OK;
  44 static jobject sfs_NOPERMISSION;
  45 static jobject sfs_NOTCONNECTED;
  46 static jobject sfs_NOTSUPPORTED;
  47 static jobject sfs_ALREADYCREATED;
  48 static jobject sfs_INPROGRESS;
  49 static jobject sfs_OTHER;
  50 
  51 static jobject getEnumField(JNIEnv *env, char *name);
  52 static void setStatus(JNIEnv *env, jobject obj, int errval);
  53 
  54 /* OS specific code is implemented in these three functions */
  55 
  56 static jboolean flowSupported0() ;

  57 
  58 /*
  59  * Class:     sun_net_ExtendedOptionsImpl
  60  * Method:    init
  61  * Signature: ()V
  62  */
  63 JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_init
  64   (JNIEnv *env, jclass UNUSED)
  65 {
  66     static int initialized = 0;
  67     jclass c;
  68 
  69     /* Global class references */
  70 
  71     if (initialized) {
  72         return;
  73     }
  74 
  75     c = (*env)->FindClass(env, "jdk/net/SocketFlow$Status");
  76     CHECK_NULL(c);


 125     sfs_OTHER = getEnumField(env, "OTHER");
 126     CHECK_NULL(sfs_OTHER);
 127     initialized = JNI_TRUE;
 128 }
 129 
 130 static jobject getEnumField(JNIEnv *env, char *name)
 131 {
 132     jobject f;
 133     jfieldID fID = (*env)->GetStaticFieldID(env, sf_status_class, name,
 134         "Ljdk/net/SocketFlow$Status;");
 135     CHECK_NULL_RETURN(fID, NULL);
 136 
 137     f = (*env)->GetStaticObjectField(env, sf_status_class, fID);
 138     CHECK_NULL_RETURN(f, NULL);
 139     f  = (*env)->NewGlobalRef(env, f);
 140     CHECK_NULL_RETURN(f, NULL);
 141     return f;
 142 }
 143 
 144 /*



















 145  * Retrieve the int file-descriptor from a public socket type object.
 146  * Gets impl, then the FileDescriptor from the impl, and then the fd
 147  * from that.
 148  */
 149 static int getFD(JNIEnv *env, jobject fileDesc) {
 150     return (*env)->GetIntField(env, fileDesc, sf_fd_fdID);
 151 }
 152 
 153 /**
 154  * Sets the status field of a SocketFlow to one of the
 155  * canned enum values
 156  */
 157 static void setStatus (JNIEnv *env, jobject obj, int errval)
 158 {
 159     switch (errval) {
 160       case 0: /* OK */
 161         (*env)->SetObjectField(env, obj, sf_status, sfs_OK);
 162         break;
 163       case EPERM:
 164         (*env)->SetObjectField(env, obj, sf_status, sfs_NOPERMISSION);


 320 JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setFlowOption
 321   (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
 322 {
 323     JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
 324         "unsupported socket option");
 325 }
 326 
 327 JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_getFlowOption
 328   (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
 329 {
 330     JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
 331         "unsupported socket option");
 332 }
 333 
 334 static jboolean flowSupported0()  {
 335     return JNI_FALSE;
 336 }
 337 
 338 #endif /* __solaris__ */
 339 





















































































































 340 JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_flowSupported
 341   (JNIEnv *env, jclass UNUSED)
 342 {
 343     return flowSupported0();






 344 }


  37 
  38 static jfieldID sf_fd_fdID;             /* FileDescriptor.fd */
  39 
  40 /* References to the literal enum values */
  41 
  42 static jobject sfs_NOSTATUS;
  43 static jobject sfs_OK;
  44 static jobject sfs_NOPERMISSION;
  45 static jobject sfs_NOTCONNECTED;
  46 static jobject sfs_NOTSUPPORTED;
  47 static jobject sfs_ALREADYCREATED;
  48 static jobject sfs_INPROGRESS;
  49 static jobject sfs_OTHER;
  50 
  51 static jobject getEnumField(JNIEnv *env, char *name);
  52 static void setStatus(JNIEnv *env, jobject obj, int errval);
  53 
  54 /* OS specific code is implemented in these three functions */
  55 
  56 static jboolean flowSupported0() ;
  57 static jboolean reuseportSupported0() ;
  58 
  59 /*
  60  * Class:     sun_net_ExtendedOptionsImpl
  61  * Method:    init
  62  * Signature: ()V
  63  */
  64 JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_init
  65   (JNIEnv *env, jclass UNUSED)
  66 {
  67     static int initialized = 0;
  68     jclass c;
  69 
  70     /* Global class references */
  71 
  72     if (initialized) {
  73         return;
  74     }
  75 
  76     c = (*env)->FindClass(env, "jdk/net/SocketFlow$Status");
  77     CHECK_NULL(c);


 126     sfs_OTHER = getEnumField(env, "OTHER");
 127     CHECK_NULL(sfs_OTHER);
 128     initialized = JNI_TRUE;
 129 }
 130 
 131 static jobject getEnumField(JNIEnv *env, char *name)
 132 {
 133     jobject f;
 134     jfieldID fID = (*env)->GetStaticFieldID(env, sf_status_class, name,
 135         "Ljdk/net/SocketFlow$Status;");
 136     CHECK_NULL_RETURN(fID, NULL);
 137 
 138     f = (*env)->GetStaticObjectField(env, sf_status_class, fID);
 139     CHECK_NULL_RETURN(f, NULL);
 140     f  = (*env)->NewGlobalRef(env, f);
 141     CHECK_NULL_RETURN(f, NULL);
 142     return f;
 143 }
 144 
 145 /*
 146  * Returns a java.lang.Boolean based on 'b'
 147  */
 148 static jobject createBoolean(JNIEnv *env, int b) {
 149     static jclass b_class;
 150     static jmethodID b_ctrID;
 151 
 152     if (b_class == NULL) {
 153         jclass c = (*env)->FindClass(env, "java/lang/Boolean");
 154         CHECK_NULL_RETURN(c, NULL);
 155         b_ctrID = (*env)->GetMethodID(env, c, "<init>", "(Z)V");
 156         CHECK_NULL_RETURN(b_ctrID, NULL);
 157         b_class = (*env)->NewGlobalRef(env, c);
 158         CHECK_NULL_RETURN(b_class, NULL);
 159     }
 160 
 161     return( (*env)->NewObject(env, b_class, b_ctrID, (jboolean)(b!=0)) );
 162 }
 163 
 164 /*
 165  * Retrieve the int file-descriptor from a public socket type object.
 166  * Gets impl, then the FileDescriptor from the impl, and then the fd
 167  * from that.
 168  */
 169 static int getFD(JNIEnv *env, jobject fileDesc) {
 170     return (*env)->GetIntField(env, fileDesc, sf_fd_fdID);
 171 }
 172 
 173 /**
 174  * Sets the status field of a SocketFlow to one of the
 175  * canned enum values
 176  */
 177 static void setStatus (JNIEnv *env, jobject obj, int errval)
 178 {
 179     switch (errval) {
 180       case 0: /* OK */
 181         (*env)->SetObjectField(env, obj, sf_status, sfs_OK);
 182         break;
 183       case EPERM:
 184         (*env)->SetObjectField(env, obj, sf_status, sfs_NOPERMISSION);


 340 JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setFlowOption
 341   (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
 342 {
 343     JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
 344         "unsupported socket option");
 345 }
 346 
 347 JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_getFlowOption
 348   (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
 349 {
 350     JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
 351         "unsupported socket option");
 352 }
 353 
 354 static jboolean flowSupported0()  {
 355     return JNI_FALSE;
 356 }
 357 
 358 #endif /* __solaris__ */
 359 
 360 
 361 #ifdef __linux__
 362 /*
 363  * Class:     sun_net_ExtendedOptionsImpl
 364  * Method:    setReusePortOption
 365  * Signature: (Ljava/io/FileDescriptor;Ljava/lang/Object;)V
 366  */
 367 JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setReusePortOption
 368   (JNIEnv *env, jclass UNUSED, jobject fileDesc, jboolean on)
 369 {
 370     int fd = getFD(env, fileDesc);
 371     int optval;
 372  
 373     if (fd < 0) {
 374         NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed");
 375         return;
 376     } else {
 377         int rv;
 378         optval = (on ? 1 : 0);
 379         rv = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
 380         if (rv < 0) {
 381             if (errno == ENOPROTOOPT) {
 382                 JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
 383                         "unsupported socket option");
 384             } else {
 385                 NET_ERROR(env, JNU_JAVANETPKG "SocketException",
 386                                 "set option SO_REUSEPORT failed");
 387             }
 388             return;
 389         }
 390     }
 391 }
 392 /*
 393  * Class:     sun_net_ExtendedOptionsImpl
 394  * Method:    getReusePortOption
 395  * Signature: (Ljava/io/FileDescriptor;)Ljava/lang/Object;
 396  */
 397 JNIEXPORT jobject JNICALL Java_sun_net_ExtendedOptionsImpl_getReusePortOption
 398   (JNIEnv *env, jclass UNUSED, jobject fileDesc)
 399 {
 400     int fd = getFD(env, fileDesc);
 401 
 402     if (fd < 0) {
 403         NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed");
 404         return JNI_FALSE;
 405     } else {
 406         int on;
 407         socklen_t sz = sizeof(on);
 408 
 409         int rv = getsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, &sz);
 410         if (rv < 0) {
 411             if (errno == ENOPROTOOPT) {
 412                 JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
 413                         "unsupported socket option");
 414             } else {
 415                 NET_ERROR(env, JNU_JAVANETPKG "SocketException",
 416                                 "set option SO_REUSEPORT failed");
 417             }
 418         }
 419         printf("getReusePortOption returns %d\n", on);
 420         return createBoolean(env, on);
 421     }
 422 }
 423 
 424 static jboolean reuseportsupported;
 425 static jboolean reuseportsupported_set = JNI_FALSE;
 426 
 427 static jboolean reuseportSupported0()
 428 {
 429     /* Do a simple dummy call, and try to figure out from that */
 430     int one = 1;
 431     int rv, s;
 432     if (reuseportsupported_set) {
 433         return reuseportsupported;
 434     }
 435     s = socket(PF_INET, SOCK_STREAM, 0);
 436     if (s < 0) {
 437         reuseportsupported = JNI_FALSE;
 438         reuseportsupported_set = JNI_TRUE;
 439         return JNI_FALSE;
 440     }
 441     rv = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (void *)&one, sizeof(one));
 442     if (rv != 0 && errno == ENOPROTOOPT) {
 443         rv = JNI_FALSE;
 444     } else {
 445         rv = JNI_TRUE;
 446     }
 447     close(s);
 448     reuseportsupported = rv;
 449     reuseportsupported_set = JNI_TRUE;
 450     return reuseportsupported;
 451 }
 452 
 453 #else /* __linux__ */
 454 
 455 /* Non Linux. Functionality is not supported. So, throw UnsupportedOpExc */
 456 
 457 JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setReusePortOption
 458   (JNIEnv *env, jclass UNUSED, jobject fileDesc, jboolean on)
 459 {
 460     JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
 461         "unsupported socket option");
 462 }
 463 
 464 JNIEXPORT jobject JNICALL Java_sun_net_ExtendedOptionsImpl_getReusePortOption
 465   (JNIEnv *env, jclass UNUSED, jobject fileDesc)
 466 {
 467     JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
 468         "unsupported socket option");
 469     return JNI_FALSE;
 470 }
 471 
 472 static jboolean reuseportSupported0()  {
 473     return JNI_FALSE;
 474 }
 475 #endif /* __linux__ */
 476 
 477 JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_flowSupported
 478   (JNIEnv *env, jclass UNUSED)
 479 {
 480     return flowSupported0();
 481 }
 482 
 483 JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_reuseportSupported
 484   (JNIEnv *env, jclass UNUSED)
 485 {
 486     return reuseportSupported0();
 487 }
< prev index next >