Index: c/jnilib.c |
diff --git a/c/jnilib.c b/c/jnilib.c |
index 0110ad00e36d3531ac0ac3f7e6e8c81ad8101401..5074d7e553729c5395eebe78217e07e44f579132 100644 |
--- a/c/jnilib.c |
+++ b/c/jnilib.c |
@@ -1,3 +1,18 @@ |
+/* |
+ * Copyright 2016 The Netty Project |
+ * |
+ * The Netty Project licenses this file to you under the Apache License, |
+ * version 2.0 (the "License"); you may not use this file except in compliance |
+ * with the License. You may obtain a copy of the License at: |
+ * |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
+ * |
+ * Unless required by applicable law or agreed to in writing, software |
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
+ * License for the specific language governing permissions and limitations |
+ * under the License. |
+ */ |
/* Licensed to the Apache Software Foundation (ASF) under one or more |
* contributor license agreements. See the NOTICE file distributed with |
* this work for additional information regarding copyright ownership. |
@@ -14,46 +29,35 @@ |
* limitations under the License. |
*/ |
-/* |
- * |
- * @author Mladen Turk |
- * @version $Id: jnilib.c 1666217 2015-03-12 15:03:31Z rjung $ |
- */ |
- |
#include "tcn.h" |
#include "apr_version.h" |
-#include "apr_file_io.h" |
-#include "apr_mmap.h" |
#include "apr_atomic.h" |
+#include "apr_strings.h" |
-#include "tcn_version.h" |
- |
-#ifdef TCN_DO_STATISTICS |
-extern void sp_poll_dump_statistics(); |
-extern void sp_network_dump_statistics(); |
-extern void ssl_network_dump_statistics(); |
+#ifndef TCN_JNI_VERSION |
+#define TCN_JNI_VERSION JNI_VERSION_1_4 |
#endif |
apr_pool_t *tcn_global_pool = NULL; |
static JavaVM *tcn_global_vm = NULL; |
static jclass jString_class; |
-static jclass jFinfo_class; |
-static jclass jAinfo_class; |
static jmethodID jString_init; |
static jmethodID jString_getBytes; |
- |
-int tcn_parent_pid = 0; |
+static jclass byteArrayClass; |
+static jclass keyMaterialClass; |
+static jfieldID keyMaterialCertificateChainFieldId; |
+static jfieldID keyMaterialPrivateKeyFieldId; |
/* Called by the JVM when APR_JAVA is loaded */ |
-JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) |
+JNIEXPORT jint JNICALL JNI_OnLoad_netty_tcnative(JavaVM *vm, void *reserved) |
{ |
JNIEnv *env; |
apr_version_t apv; |
int apvn; |
UNREFERENCED(reserved); |
- if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_4)) { |
+ if ((*vm)->GetEnv(vm, (void **)&env, TCN_JNI_VERSION)) { |
return JNI_ERR; |
} |
tcn_global_vm = vm; |
@@ -64,7 +68,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) |
apr_version(&apv); |
apvn = apv.major * 1000 + apv.minor * 100 + apv.patch; |
if (apvn < 1201) { |
- tcn_Throw(env, "Unupported APR version (%s)", |
+ tcn_Throw(env, "Unsupported APR version (%s)", |
apr_version_string()); |
return JNI_ERR; |
} |
@@ -72,48 +76,57 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) |
/* Initialize global java.lang.String class */ |
TCN_LOAD_CLASS(env, jString_class, "java/lang/String", JNI_ERR); |
- TCN_LOAD_CLASS(env, jFinfo_class, TCN_FINFO_CLASS, JNI_ERR); |
- TCN_LOAD_CLASS(env, jAinfo_class, TCN_AINFO_CLASS, JNI_ERR); |
TCN_GET_METHOD(env, jString_class, jString_init, |
"<init>", "([B)V", JNI_ERR); |
TCN_GET_METHOD(env, jString_class, jString_getBytes, |
"getBytes", "()[B", JNI_ERR); |
- if(tcn_load_finfo_class(env, jFinfo_class) != APR_SUCCESS) |
- return JNI_ERR; |
- if(tcn_load_ainfo_class(env, jAinfo_class) != APR_SUCCESS) |
+ // Load the class which makes JNI references available in a static scope before loading any other classes. |
+ if ((*env)->FindClass(env, "io/netty/internal/tcnative/NativeStaticallyReferencedJniMethods") == NULL) { |
return JNI_ERR; |
-#ifdef WIN32 |
- { |
- char *ppid = getenv(TCN_PARENT_IDE); |
- if (ppid) |
- tcn_parent_pid = atoi(ppid); |
} |
-#else |
- tcn_parent_pid = getppid(); |
-#endif |
- return JNI_VERSION_1_4; |
+ TCN_LOAD_CLASS(env, byteArrayClass, "[B", JNI_ERR); |
+ TCN_LOAD_CLASS(env, keyMaterialClass, "io/netty/internal/tcnative/CertificateRequestedCallback$KeyMaterial", JNI_ERR); |
+ |
+ TCN_GET_FIELD(env, keyMaterialClass, keyMaterialCertificateChainFieldId, |
+ "certificateChain", "J", JNI_ERR); |
+ TCN_GET_FIELD(env, keyMaterialClass, keyMaterialPrivateKeyFieldId, |
+ "privateKey", "J", JNI_ERR); |
+ |
+ return TCN_JNI_VERSION; |
} |
+/* Called by the JVM when APR_JAVA is loaded */ |
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) |
+{ |
+ return JNI_OnLoad_netty_tcnative(vm, reserved); |
+} |
/* Called by the JVM before the APR_JAVA is unloaded */ |
-JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) |
+JNIEXPORT void JNICALL JNI_OnUnload_netty_tcnative(JavaVM *vm, void *reserved) |
{ |
JNIEnv *env; |
UNREFERENCED(reserved); |
- if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_2)) { |
+ if ((*vm)->GetEnv(vm, (void **)&env, TCN_JNI_VERSION)) { |
return; |
} |
if (tcn_global_pool) { |
TCN_UNLOAD_CLASS(env, jString_class); |
- TCN_UNLOAD_CLASS(env, jFinfo_class); |
- TCN_UNLOAD_CLASS(env, jAinfo_class); |
apr_terminate(); |
} |
+ |
+ TCN_UNLOAD_CLASS(env, byteArrayClass); |
+ TCN_UNLOAD_CLASS(env, keyMaterialClass); |
+} |
+ |
+/* Called by the JVM before the APR_JAVA is unloaded */ |
+JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) |
+{ |
+ JNI_OnUnload_netty_tcnative(vm, reserved); |
} |
jstring tcn_new_stringn(JNIEnv *env, const char *str, size_t l) |
@@ -136,20 +149,6 @@ jstring tcn_new_stringn(JNIEnv *env, const char *str, size_t l) |
return NULL; |
} |
-jbyteArray tcn_new_arrayb(JNIEnv *env, const unsigned char *data, size_t len) |
-{ |
- jbyteArray bytes = (*env)->NewByteArray(env, (jsize)len); |
- if (bytes != NULL) { |
- (*env)->SetByteArrayRegion(env, bytes, 0, (jint)len, (jbyte *)data); |
- } |
- return bytes; |
-} |
- |
-jobjectArray tcn_new_arrays(JNIEnv *env, size_t len) |
-{ |
- return (*env)->NewObjectArray(env, (jsize)len, jString_class, NULL); |
-} |
- |
jstring tcn_new_string(JNIEnv *env, const char *str) |
{ |
if (!str) |
@@ -158,63 +157,7 @@ jstring tcn_new_string(JNIEnv *env, const char *str) |
return (*env)->NewStringUTF(env, str); |
} |
-char *tcn_get_string(JNIEnv *env, jstring jstr) |
-{ |
- jbyteArray bytes = NULL; |
- jthrowable exc; |
- char *result = NULL; |
- |
- if ((*env)->EnsureLocalCapacity(env, 2) < 0) { |
- return NULL; /* out of memory error */ |
- } |
- bytes = (*env)->CallObjectMethod(env, jstr, jString_getBytes); |
- exc = (*env)->ExceptionOccurred(env); |
- if (!exc) { |
- jint len = (*env)->GetArrayLength(env, bytes); |
- result = (char *)malloc(len + 1); |
- if (result == NULL) { |
- TCN_THROW_OS_ERROR(env); |
- (*env)->DeleteLocalRef(env, bytes); |
- return 0; |
- } |
- (*env)->GetByteArrayRegion(env, bytes, 0, len, (jbyte *)result); |
- result[len] = '\0'; /* NULL-terminate */ |
- } |
- else { |
- (*env)->DeleteLocalRef(env, exc); |
- } |
- (*env)->DeleteLocalRef(env, bytes); |
- |
- return result; |
-} |
- |
-char *tcn_strdup(JNIEnv *env, jstring jstr) |
-{ |
- char *result = NULL; |
- const char *cjstr; |
- |
- cjstr = (const char *)((*env)->GetStringUTFChars(env, jstr, 0)); |
- if (cjstr) { |
- result = strdup(cjstr); |
- (*env)->ReleaseStringUTFChars(env, jstr, cjstr); |
- } |
- return result; |
-} |
- |
-char *tcn_pstrdup(JNIEnv *env, jstring jstr, apr_pool_t *pool) |
-{ |
- char *result = NULL; |
- const char *cjstr; |
- |
- cjstr = (const char *)((*env)->GetStringUTFChars(env, jstr, 0)); |
- if (cjstr) { |
- result = apr_pstrdup(pool, cjstr); |
- (*env)->ReleaseStringUTFChars(env, jstr, cjstr); |
- } |
- return result; |
-} |
- |
-TCN_IMPLEMENT_CALL(jboolean, Library, initialize)(TCN_STDARGS) |
+TCN_IMPLEMENT_CALL(jboolean, Library, initialize0)(TCN_STDARGS) |
{ |
UNREFERENCED_STDARGS; |
@@ -228,33 +171,6 @@ TCN_IMPLEMENT_CALL(jboolean, Library, initialize)(TCN_STDARGS) |
return JNI_TRUE; |
} |
-TCN_IMPLEMENT_CALL(void, Library, terminate)(TCN_STDARGS) |
-{ |
- |
- UNREFERENCED_STDARGS; |
- if (tcn_global_pool) { |
- apr_pool_t *p = tcn_global_pool; |
- tcn_global_pool = NULL; |
-#ifdef TCN_DO_STATISTICS |
- fprintf(stderr, "APR Statistical data ....\n"); |
-#endif |
- apr_pool_destroy(p); |
-#ifdef TCN_DO_STATISTICS |
- sp_poll_dump_statistics(); |
- sp_network_dump_statistics(); |
- ssl_network_dump_statistics(); |
- fprintf(stderr, "APR Terminated\n"); |
-#endif |
- apr_terminate(); |
- } |
-} |
- |
-TCN_IMPLEMENT_CALL(jlong, Library, globalPool)(TCN_STDARGS) |
-{ |
- UNREFERENCED_STDARGS; |
- return P2J(tcn_global_pool); |
-} |
- |
TCN_IMPLEMENT_CALL(jint, Library, version)(TCN_STDARGS, jint what) |
{ |
apr_version_t apv; |
@@ -263,18 +179,6 @@ TCN_IMPLEMENT_CALL(jint, Library, version)(TCN_STDARGS, jint what) |
apr_version(&apv); |
switch (what) { |
- case 0x01: |
- return TCN_MAJOR_VERSION; |
- break; |
- case 0x02: |
- return TCN_MINOR_VERSION; |
- break; |
- case 0x03: |
- return TCN_PATCH_VERSION; |
- break; |
- case 0x04: |
- return TCN_IS_DEV_VERSION; |
- break; |
case 0x11: |
return apv.major; |
break; |
@@ -291,12 +195,6 @@ TCN_IMPLEMENT_CALL(jint, Library, version)(TCN_STDARGS, jint what) |
return 0; |
} |
-TCN_IMPLEMENT_CALL(jstring, Library, versionString)(TCN_STDARGS) |
-{ |
- UNREFERENCED(o); |
- return AJP_TO_JSTRING(TCN_VERSION_STRING); |
-} |
- |
TCN_IMPLEMENT_CALL(jstring, Library, aprVersionString)(TCN_STDARGS) |
{ |
UNREFERENCED(o); |
@@ -418,63 +316,30 @@ TCN_IMPLEMENT_CALL(jboolean, Library, has)(TCN_STDARGS, jint what) |
return rv; |
} |
-TCN_IMPLEMENT_CALL(jint, Library, size)(TCN_STDARGS, jint what) |
+jclass tcn_get_string_class() |
{ |
- |
- UNREFERENCED_STDARGS; |
- |
- switch (what) { |
- case 1: |
- return APR_SIZEOF_VOIDP; |
- break; |
- case 2: |
- return APR_PATH_MAX; |
- break; |
- case 3: |
- return APRMAXHOSTLEN; |
- break; |
- case 4: |
- return APR_MAX_IOVEC_SIZE; |
- break; |
- case 5: |
- return APR_MAX_SECS_TO_LINGER; |
- break; |
- case 6: |
- return APR_MMAP_THRESHOLD; |
- break; |
- case 7: |
- return APR_MMAP_LIMIT; |
- break; |
- |
- } |
- return 0; |
+ return jString_class; |
} |
-apr_pool_t *tcn_get_global_pool() |
+jclass tcn_get_byte_array_class() |
{ |
- if (!tcn_global_pool) { |
- if (apr_pool_create(&tcn_global_pool, NULL) != APR_SUCCESS) { |
- return NULL; |
- } |
- apr_atomic_init(tcn_global_pool); |
- } |
- return tcn_global_pool; |
+ return byteArrayClass; |
} |
-jclass tcn_get_string_class() |
+jfieldID tcn_get_key_material_certificate_chain_field() |
{ |
- return jString_class; |
+ return keyMaterialCertificateChainFieldId; |
} |
-JavaVM * tcn_get_java_vm() |
+jfieldID tcn_get_key_material_private_key_field() |
{ |
- return tcn_global_vm; |
+ return keyMaterialPrivateKeyFieldId; |
} |
jint tcn_get_java_env(JNIEnv **env) |
{ |
if ((*tcn_global_vm)->GetEnv(tcn_global_vm, (void **)env, |
- JNI_VERSION_1_4)) { |
+ TCN_JNI_VERSION)) { |
return JNI_ERR; |
} |
return JNI_OK; |