| OLD | NEW |
| 1 /* |
| 2 * Copyright 2016 The Netty Project |
| 3 * |
| 4 * The Netty Project licenses this file to you under the Apache License, |
| 5 * version 2.0 (the "License"); you may not use this file except in compliance |
| 6 * with the License. You may obtain a copy of the License at: |
| 7 * |
| 8 * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 * |
| 10 * Unless required by applicable law or agreed to in writing, software |
| 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 13 * License for the specific language governing permissions and limitations |
| 14 * under the License. |
| 15 */ |
| 1 /* Licensed to the Apache Software Foundation (ASF) under one or more | 16 /* Licensed to the Apache Software Foundation (ASF) under one or more |
| 2 * contributor license agreements. See the NOTICE file distributed with | 17 * contributor license agreements. See the NOTICE file distributed with |
| 3 * this work for additional information regarding copyright ownership. | 18 * this work for additional information regarding copyright ownership. |
| 4 * The ASF licenses this file to You under the Apache License, Version 2.0 | 19 * The ASF licenses this file to You under the Apache License, Version 2.0 |
| 5 * (the "License"); you may not use this file except in compliance with | 20 * (the "License"); you may not use this file except in compliance with |
| 6 * the License. You may obtain a copy of the License at | 21 * the License. You may obtain a copy of the License at |
| 7 * | 22 * |
| 8 * http://www.apache.org/licenses/LICENSE-2.0 | 23 * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 * | 24 * |
| 10 * Unless required by applicable law or agreed to in writing, software | 25 * Unless required by applicable law or agreed to in writing, software |
| 11 * distributed under the License is distributed on an "AS IS" BASIS, | 26 * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 27 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 * See the License for the specific language governing permissions and | 28 * See the License for the specific language governing permissions and |
| 14 * limitations under the License. | 29 * limitations under the License. |
| 15 */ | 30 */ |
| 16 | 31 |
| 17 /* | |
| 18 * | |
| 19 * @author Mladen Turk | |
| 20 * @version $Id: tcn.h 1446443 2013-02-15 04:18:04Z rjung $ | |
| 21 */ | |
| 22 | |
| 23 #ifndef TCN_H | 32 #ifndef TCN_H |
| 24 #define TCN_H | 33 #define TCN_H |
| 25 | 34 |
| 35 // Start includes |
| 36 #include <jni.h> |
| 37 |
| 26 #include "apr.h" | 38 #include "apr.h" |
| 27 #include "apr_general.h" | |
| 28 #include "apr_lib.h" | |
| 29 #include "apr_pools.h" | 39 #include "apr_pools.h" |
| 30 #include "apr_portable.h" | |
| 31 #include "apr_network_io.h" | |
| 32 #include "apr_poll.h" | |
| 33 #include "apr_ring.h" | |
| 34 #include "apr_strings.h" | |
| 35 | 40 |
| 36 #ifndef APR_HAS_THREADS | 41 #ifndef APR_HAS_THREADS |
| 37 #error "Missing APR_HAS_THREADS support from APR." | 42 #error "Missing APR_HAS_THREADS support from APR." |
| 38 #endif | 43 #endif |
| 39 | 44 |
| 40 #if defined(DEBUG) || defined(_DEBUG) | |
| 41 /* On -DDEBUG use the statistics */ | |
| 42 #ifndef TCN_DO_STATISTICS | |
| 43 #define TCN_DO_STATISTICS | |
| 44 #endif | |
| 45 #endif | |
| 46 #include <stdio.h> | 45 #include <stdio.h> |
| 47 #include <stdlib.h> | 46 #include <stdlib.h> |
| 48 #if defined(_WIN32) && !defined(__CYGWIN__) | 47 #if defined(_WIN32) && !defined(__CYGWIN__) |
| 49 #include <process.h> | 48 #include <process.h> |
| 50 #else | 49 #else |
| 51 #include <unistd.h> | 50 #include <unistd.h> |
| 52 #endif | 51 #endif |
| 53 | 52 |
| 54 #if !defined(APR_POLLSET_NOCOPY) | |
| 55 /* Add missing API */ | |
| 56 #define APR_RING_FOREACH(ep, head, elem, link) \ | |
| 57 for (ep = APR_RING_FIRST(head); \ | |
| 58 ep != APR_RING_SENTINEL(head, elem, link); \ | |
| 59 ep = APR_RING_NEXT(ep, link)) | |
| 60 | |
| 61 #define APR_RING_FOREACH_SAFE(ep1, ep2, head, elem, link) \ | |
| 62 for (ep1 = APR_RING_FIRST(head), ep2 = APR_RING_NEXT(ep1, link); \ | |
| 63 ep1 != APR_RING_SENTINEL(head, elem, link); \ | |
| 64 ep1 = ep2, ep2 = APR_RING_NEXT(ep1, link)) | |
| 65 | |
| 66 #define APR_POLLSET_NOCOPY 0 | |
| 67 #endif | |
| 68 | |
| 69 #include "tcn_api.h" | |
| 70 | |
| 71 | |
| 72 #if defined(_DEBUG) || defined(DEBUG) | 53 #if defined(_DEBUG) || defined(DEBUG) |
| 73 #include <assert.h> | 54 #include <assert.h> |
| 74 #define TCN_ASSERT(x) assert((x)) | 55 #define TCN_ASSERT(x) assert((x)) |
| 75 #else | 56 #else |
| 76 #define TCN_ASSERT(x) (void)0 | 57 #define TCN_ASSERT(x) (void)0 |
| 77 #endif | 58 #endif |
| 78 | 59 // End includes |
| 79 #ifndef APR_MAX_IOVEC_SIZE | |
| 80 #define APR_MAX_IOVEC_SIZE 1024 | |
| 81 #endif | |
| 82 | |
| 83 #define TCN_TIMEUP APR_OS_START_USERERR + 1 | |
| 84 #define TCN_EAGAIN APR_OS_START_USERERR + 2 | |
| 85 #define TCN_EINTR APR_OS_START_USERERR + 3 | |
| 86 #define TCN_EINPROGRESS APR_OS_START_USERERR + 4 | |
| 87 #define TCN_ETIMEDOUT APR_OS_START_USERERR + 5 | |
| 88 | |
| 89 #define TCN_LOG_EMERG 1 | |
| 90 #define TCN_LOG_ERROR 2 | |
| 91 #define TCN_LOG_NOTICE 3 | |
| 92 #define TCN_LOG_WARN 4 | |
| 93 #define TCN_LOG_INFO 5 | |
| 94 #define TCN_LOG_DEBUG 6 | |
| 95 | |
| 96 #define TCN_ERROR_WRAP(E) \ | |
| 97 if (APR_STATUS_IS_TIMEUP(E)) \ | |
| 98 (E) = TCN_TIMEUP; \ | |
| 99 else if (APR_STATUS_IS_EAGAIN(E)) \ | |
| 100 (E) = TCN_EAGAIN; \ | |
| 101 else if (APR_STATUS_IS_EINTR(E)) \ | |
| 102 (E) = TCN_EINTR; \ | |
| 103 else if (APR_STATUS_IS_EINPROGRESS(E)) \ | |
| 104 (E) = TCN_EINPROGRESS; \ | |
| 105 else if (APR_STATUS_IS_ETIMEDOUT(E)) \ | |
| 106 (E) = TCN_ETIMEDOUT; \ | |
| 107 else \ | |
| 108 (E) = (E) | |
| 109 | |
| 110 #define TCN_CLASS_PATH "org/apache/tomcat/jni/" | |
| 111 #define TCN_FINFO_CLASS TCN_CLASS_PATH "FileInfo" | |
| 112 #define TCN_AINFO_CLASS TCN_CLASS_PATH "Sockaddr" | |
| 113 #define TCN_ERROR_CLASS TCN_CLASS_PATH "Error" | |
| 114 #define TCN_PARENT_IDE "TCN_PARENT_ID" | |
| 115 | 60 |
| 116 #define UNREFERENCED(P) (P) = (P) | 61 #define UNREFERENCED(P) (P) = (P) |
| 117 #define UNREFERENCED_STDARGS e = e; o = o | 62 #define UNREFERENCED_STDARGS e = e; o = o |
| 118 #ifdef WIN32 | 63 #ifdef WIN32 |
| 119 #define LLT(X) (X) | 64 #define LLT(X) (X) |
| 120 #else | 65 #else |
| 121 #define LLT(X) ((long)(X)) | 66 #define LLT(X) ((long)(X)) |
| 122 #endif | 67 #endif |
| 123 #define P2J(P) ((jlong)LLT(P)) | 68 #define P2J(P) ((jlong)LLT(P)) |
| 124 #define J2P(P, T) ((T)LLT((jlong)P)) | 69 #define J2P(P, T) ((T)LLT((jlong)P)) |
| 125 /* On stack buffer size */ | 70 /* On stack buffer size */ |
| 126 #define TCN_BUFFER_SZ 8192 | 71 #define TCN_BUFFER_SZ 8192 |
| 127 #define TCN_STDARGS JNIEnv *e, jobject o | 72 #define TCN_STDARGS JNIEnv *e, jobject o |
| 128 #define TCN_IMPARGS JNIEnv *e, jobject o, void *sock | |
| 129 #define TCN_IMPCALL(X) e, o, X->opaque | |
| 130 | 73 |
| 131 #define TCN_IMPLEMENT_CALL(RT, CL, FN) \ | 74 #define TCN_IMPLEMENT_CALL(RT, CL, FN) \ |
| 132 JNIEXPORT RT JNICALL Java_org_apache_tomcat_jni_##CL##_##FN | 75 JNIEXPORT RT JNICALL Java_io_netty_internal_tcnative_##CL##_##FN |
| 133 | |
| 134 #define TCN_IMPLEMENT_METHOD(RT, FN) \ | |
| 135 static RT method_##FN | |
| 136 | |
| 137 #define TCN_GETNET_METHOD(FN) method_##FN | |
| 138 | |
| 139 #define TCN_SOCKET_UNKNOWN 0 | |
| 140 #define TCN_SOCKET_APR 1 | |
| 141 #define TCN_SOCKET_SSL 2 | |
| 142 #define TCN_SOCKET_UNIX 3 | |
| 143 #define TCN_SOCKET_NTPIPE 4 | |
| 144 | |
| 145 #define TCN_SOCKET_GET_POOL 0 | |
| 146 #define TCN_SOCKET_GET_IMPL 1 | |
| 147 #define TCN_SOCKET_GET_APRS 2 | |
| 148 #define TCN_SOCKET_GET_TYPE 3 | |
| 149 | |
| 150 typedef struct { | |
| 151 int type; | |
| 152 apr_status_t (*cleanup)(void *); | |
| 153 apr_status_t (APR_THREAD_FUNC *close) (apr_socket_t *); | |
| 154 apr_status_t (APR_THREAD_FUNC *shutdown) (apr_socket_t *, apr_shutdown_how_e
); | |
| 155 apr_status_t (APR_THREAD_FUNC *opt_get)(apr_socket_t *, apr_int32_t, apr_int
32_t *); | |
| 156 apr_status_t (APR_THREAD_FUNC *opt_set)(apr_socket_t *, apr_int32_t, apr_int
32_t); | |
| 157 apr_status_t (APR_THREAD_FUNC *timeout_get)(apr_socket_t *, apr_interval_tim
e_t *); | |
| 158 apr_status_t (APR_THREAD_FUNC *timeout_set)(apr_socket_t *, apr_interval_tim
e_t); | |
| 159 apr_status_t (APR_THREAD_FUNC *send) (apr_socket_t *, const char *, apr_size
_t *); | |
| 160 apr_status_t (APR_THREAD_FUNC *sendv)(apr_socket_t *, const struct iovec *,
apr_int32_t, apr_size_t *); | |
| 161 apr_status_t (APR_THREAD_FUNC *recv) (apr_socket_t *, char *, apr_size_t *); | |
| 162 } tcn_nlayer_t; | |
| 163 | |
| 164 typedef struct tcn_socket_t tcn_socket_t; | |
| 165 typedef struct tcn_pfde_t tcn_pfde_t; | |
| 166 | |
| 167 struct tcn_pfde_t { | |
| 168 APR_RING_ENTRY(tcn_pfde_t) link; | |
| 169 apr_pollfd_t fd; | |
| 170 }; | |
| 171 | |
| 172 struct tcn_socket_t { | |
| 173 apr_pool_t *pool; | |
| 174 apr_pool_t *child; | |
| 175 apr_socket_t *sock; | |
| 176 void *opaque; | |
| 177 char *jsbbuff; | |
| 178 char *jrbbuff; | |
| 179 tcn_nlayer_t *net; | |
| 180 tcn_pfde_t *pe; | |
| 181 apr_time_t last_active; | |
| 182 apr_interval_time_t timeout; | |
| 183 }; | |
| 184 | 76 |
| 185 /* Private helper functions */ | 77 /* Private helper functions */ |
| 186 void tcn_Throw(JNIEnv *, const char *, ...); | 78 void tcn_Throw(JNIEnv *, const char *, ...); |
| 187 void tcn_ThrowException(JNIEnv *, const char *); | 79 void tcn_ThrowException(JNIEnv *, const char *); |
| 188 void tcn_ThrowMemoryException(JNIEnv *, const char *, int, const char
*); | |
| 189 void tcn_ThrowAPRException(JNIEnv *, apr_status_t); | 80 void tcn_ThrowAPRException(JNIEnv *, apr_status_t); |
| 190 jstring tcn_new_string(JNIEnv *, const char *); | 81 jstring tcn_new_string(JNIEnv *, const char *); |
| 191 jstring tcn_new_stringn(JNIEnv *, const char *, size_t); | 82 jstring tcn_new_stringn(JNIEnv *, const char *, size_t); |
| 192 jbyteArray tcn_new_arrayb(JNIEnv *, const unsigned char *, size_t); | |
| 193 jobjectArray tcn_new_arrays(JNIEnv *env, size_t len); | |
| 194 char *tcn_get_string(JNIEnv *, jstring); | |
| 195 char *tcn_strdup(JNIEnv *, jstring); | |
| 196 char *tcn_pstrdup(JNIEnv *, jstring, apr_pool_t *); | |
| 197 apr_status_t tcn_load_finfo_class(JNIEnv *, jclass); | |
| 198 apr_status_t tcn_load_ainfo_class(JNIEnv *, jclass); | |
| 199 | 83 |
| 200 #define J2S(V) c##V | 84 #define J2S(V) c##V |
| 201 #define J2L(V) p##V | 85 #define J2L(V) p##V |
| 202 | 86 |
| 203 #define J2T(T) (apr_time_t)((T)) | |
| 204 | |
| 205 #define TCN_BEGIN_MACRO if (1) { | 87 #define TCN_BEGIN_MACRO if (1) { |
| 206 #define TCN_END_MACRO } else (void)(0) | 88 #define TCN_END_MACRO } else (void)(0) |
| 207 | 89 |
| 208 #define TCN_ALLOC_CSTRING(V) \ | 90 #define TCN_ALLOC_CSTRING(V) \ |
| 209 const char *c##V = V ? (const char *)((*e)->GetStringUTFChars(e, V, 0)) : NU
LL | 91 const char *c##V = V ? (const char *)((*e)->GetStringUTFChars(e, V, 0)) : NU
LL |
| 210 | 92 |
| 211 #define TCN_FREE_CSTRING(V) \ | 93 #define TCN_FREE_CSTRING(V) \ |
| 212 if (c##V) (*e)->ReleaseStringUTFChars(e, V, c##V) | 94 if (c##V) (*e)->ReleaseStringUTFChars(e, V, c##V) |
| 213 | 95 |
| 214 #define TCN_ALLOC_JSTRING(V) \ | |
| 215 char *c##V = tcn_get_string(e, (V)) | |
| 216 | |
| 217 #define AJP_TO_JSTRING(V) (*e)->NewStringUTF((e), (V)) | 96 #define AJP_TO_JSTRING(V) (*e)->NewStringUTF((e), (V)) |
| 218 | 97 |
| 219 #define TCN_FREE_JSTRING(V) \ | 98 #define TCN_FREE_JSTRING(V) \ |
| 220 TCN_BEGIN_MACRO \ | 99 TCN_BEGIN_MACRO \ |
| 221 if (c##V) \ | 100 if (c##V) \ |
| 222 free(c##V); \ | 101 free(c##V); \ |
| 223 TCN_END_MACRO | 102 TCN_END_MACRO |
| 224 | 103 |
| 225 #define TCN_CHECK_ALLOCATED(x) \ | |
| 226 if (x == NULL) { \ | |
| 227 tcn_ThrowMemoryException(e, __FILE__, __LINE__, \ | |
| 228 "APR memory allocation failed"); \ | |
| 229 goto cleanup; \ | |
| 230 } else (void)(0) | |
| 231 | |
| 232 #define TCN_THROW_IF_ERR(x, r) \ | 104 #define TCN_THROW_IF_ERR(x, r) \ |
| 233 TCN_BEGIN_MACRO \ | 105 TCN_BEGIN_MACRO \ |
| 234 apr_status_t R = (x); \ | 106 apr_status_t R = (x); \ |
| 235 if (R != APR_SUCCESS) { \ | 107 if (R != APR_SUCCESS) { \ |
| 236 tcn_ThrowAPRException(e, R); \ | 108 tcn_ThrowAPRException(e, R); \ |
| 237 (r) = 0; \ | 109 (r) = 0; \ |
| 238 goto cleanup; \ | 110 goto cleanup; \ |
| 239 } \ | 111 } \ |
| 240 TCN_END_MACRO | 112 TCN_END_MACRO |
| 241 | 113 |
| 242 #define TCN_THROW_OS_ERROR(E) \ | |
| 243 tcn_ThrowAPRException((E), apr_get_os_error()) | |
| 244 | |
| 245 #define TCN_LOAD_CLASS(E, C, N, R) \ | 114 #define TCN_LOAD_CLASS(E, C, N, R) \ |
| 246 TCN_BEGIN_MACRO \ | 115 TCN_BEGIN_MACRO \ |
| 247 jclass _##C = (*(E))->FindClass((E), N); \ | 116 jclass _##C = (*(E))->FindClass((E), N); \ |
| 248 if (_##C == NULL) { \ | 117 if (_##C == NULL) { \ |
| 249 (*(E))->ExceptionClear((E)); \ | 118 (*(E))->ExceptionClear((E)); \ |
| 250 return R; \ | 119 return R; \ |
| 251 } \ | 120 } \ |
| 252 C = (*(E))->NewGlobalRef((E), _##C); \ | 121 C = (*(E))->NewGlobalRef((E), _##C); \ |
| 253 (*(E))->DeleteLocalRef((E), _##C); \ | 122 (*(E))->DeleteLocalRef((E), _##C); \ |
| 254 TCN_END_MACRO | 123 TCN_END_MACRO |
| 255 | 124 |
| 256 #define TCN_UNLOAD_CLASS(E, C) \ | 125 #define TCN_UNLOAD_CLASS(E, C) \ |
| 257 (*(E))->DeleteGlobalRef((E), (C)) | 126 (*(E))->DeleteGlobalRef((E), (C)) |
| 258 | 127 |
| 259 #define TCN_IS_NULL(E, O) \ | |
| 260 ((*(E))->IsSameObject((E), (O), NULL) == JNI_TRUE) | |
| 261 | |
| 262 #define TCN_GET_METHOD(E, C, M, N, S, R) \ | 128 #define TCN_GET_METHOD(E, C, M, N, S, R) \ |
| 263 TCN_BEGIN_MACRO \ | 129 TCN_BEGIN_MACRO \ |
| 264 M = (*(E))->GetMethodID((E), C, N, S); \ | 130 M = (*(E))->GetMethodID((E), C, N, S); \ |
| 265 if (M == NULL) { \ | 131 if (M == NULL) { \ |
| 266 return R; \ | 132 return R; \ |
| 267 } \ | 133 } \ |
| 268 TCN_END_MACRO | 134 TCN_END_MACRO |
| 269 | 135 |
| 270 #define TCN_MAX_METHODS 8 | 136 #define TCN_GET_FIELD(E, C, F, N, S, R) \ |
| 271 | 137 TCN_BEGIN_MACRO \ |
| 272 typedef struct { | 138 F = (*(E))->GetFieldID((E), C, N, S); \ |
| 273 jobject obj; | 139 if (F == NULL) { \ |
| 274 jmethodID mid[TCN_MAX_METHODS]; | 140 return R; \ |
| 275 void *opaque; | 141 } \ |
| 276 } tcn_callback_t; | 142 TCN_END_MACRO |
| 277 | 143 |
| 278 #define TCN_MIN(a, b) ((a) < (b) ? (a) : (b)) | 144 #define TCN_MIN(a, b) ((a) < (b) ? (a) : (b)) |
| 279 #define TCN_MAX(a, b) ((a) > (b) ? (a) : (b)) | |
| 280 | 145 |
| 281 #ifdef WIN32 | 146 /* Return global String class |
| 282 #define TCN_ALLOC_WSTRING(V) \ | 147 */ |
| 283 jsize wl##V = (*e)->GetStringLength(e, V); \ | 148 jclass tcn_get_string_class(void); |
| 284 const jchar *ws##V = V ? (const jchar *)((*e)->GetStringChars(e, V, 0)) : NU
LL; \ | |
| 285 jchar *w##V = NULL | |
| 286 | 149 |
| 287 #define TCN_INIT_WSTRING(V) \ | 150 jclass tcn_get_byte_array_class(); |
| 288 w##V = (jchar *)malloc((wl##V + 1) * sizeof(jchar)); \ | 151 jfieldID tcn_get_key_material_certificate_chain_field(); |
| 289 wcsncpy(w##V, ws##V, wl##V); \ | 152 jfieldID tcn_get_key_material_private_key_field(); |
| 290 w##V[wl##V] = 0 | |
| 291 | 153 |
| 292 #define TCN_FREE_WSTRING(V) \ | 154 /* Get current thread JNIEnv |
| 293 if (ws##V) (*e)->ReleaseStringChars(e, V, ws##V); \ | 155 */ |
| 294 if (ws##V) free (w##V) | 156 jint tcn_get_java_env(JNIEnv **); |
| 295 | |
| 296 #define J2W(V) w##V | |
| 297 | |
| 298 #endif | |
| 299 | |
| 300 #if !APR_HAVE_IPV6 | |
| 301 #define APR_INET6 APR_INET | |
| 302 #endif | |
| 303 | |
| 304 #define GET_S_FAMILY(T, F) \ | |
| 305 if (F == 0) T = APR_UNSPEC; \ | |
| 306 else if (F == 1) T = APR_INET; \ | |
| 307 else if (F == 2) T = APR_INET6; \ | |
| 308 else T = F | |
| 309 | |
| 310 #define GET_S_TYPE(T, F) \ | |
| 311 if (F == 0) T = SOCK_STREAM; \ | |
| 312 else if (F == 1) T = SOCK_DGRAM; \ | |
| 313 else T = F | |
| 314 | |
| 315 #define TCN_NO_SOCKET_TIMEOUT -2 | |
| 316 | 157 |
| 317 #endif /* TCN_H */ | 158 #endif /* TCN_H */ |
| OLD | NEW |