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 |