| 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;
|
|
|