Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(560)

Side by Side Diff: c/os_win32_ntpipe.c

Issue 2842333002: Updated netty-tcnative to version 2.0.0.Final (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « c/os_win32_logmessages.mc ('k') | c/os_win32_registry.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #ifdef _WINDOWS
2
3 /* Licensed to the Apache Software Foundation (ASF) under one or more
4 * contributor license agreements. See the NOTICE file distributed with
5 * this work for additional information regarding copyright ownership.
6 * The ASF licenses this file to You under the Apache License, Version 2.0
7 * (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 /** NT Pipes network wrapper
20 *
21 * @author Mladen Turk
22 * @version $Id: ntpipe.c 1442587 2013-02-05 13:49:48Z rjung $
23 */
24
25
26 #ifndef _WIN32_WINNT
27 #define _WIN32_WINNT 0x0500
28 #endif
29 #define STRICT
30 #include <winsock2.h>
31 #include <mswsock.h>
32 #include <ws2tcpip.h>
33 #include <sddl.h>
34
35 #include "tcn.h"
36 #include "apr_thread_mutex.h"
37 #include "apr_poll.h"
38
39 #ifdef TCN_DO_STATISTICS
40 #include "apr_atomic.h"
41
42 static volatile apr_uint32_t ntp_created = 0;
43 static volatile apr_uint32_t ntp_closed = 0;
44 static volatile apr_uint32_t ntp_cleared = 0;
45 static volatile apr_uint32_t ntp_accepted = 0;
46
47 void ntp_network_dump_statistics()
48 {
49 fprintf(stderr, "NT Network Statistics ..\n");
50 fprintf(stderr, "Sockets created : %d\n", ntp_created);
51 fprintf(stderr, "Sockets accepted : %d\n", ntp_accepted);
52 fprintf(stderr, "Sockets closed : %d\n", ntp_closed);
53 fprintf(stderr, "Sockets cleared : %d\n", ntp_cleared);
54 }
55
56 #endif
57
58 #define DEFNAME "\\\\.\\PIPE\\TOMCATNATIVEPIPE"
59 #define DEFNAME_FMT "\\\\.\\PIPE\\TOMCATNATIVEPIPE%08X%08X"
60 #define DEFSIZE 8192
61 #define DEFTIMEOUT 60000
62
63 #define TCN_NTP_UNKNOWN 0
64 #define TCN_NTP_CLIENT 1
65 #define TCN_NTP_SERVER 2
66
67 typedef struct {
68 apr_pool_t *pool;
69 apr_socket_t *sock; /* Dummy socket */
70 OVERLAPPED rd_o;
71 OVERLAPPED wr_o;
72 HANDLE h_pipe;
73 HANDLE rd_event;
74 HANDLE wr_event;
75 DWORD timeout;
76 int mode; /* Client or server mode */
77 int nmax;
78 DWORD sndbuf;
79 DWORD rcvbuf;
80 char name[MAX_PATH+1];
81 SECURITY_ATTRIBUTES sa;
82 } tcn_ntp_conn_t;
83
84 static const char *NTSD_STRING = "D:" /* Discretionary ACL */
85 "(D;OICI;GA;;;BG)" /* Deny access to Built-in Guests */
86 "(D;OICI;GA;;;AN)" /* Deny access to Anonymous Logon */
87 "(A;OICI;GRGWGX;;;AU)" /* Allow read/write/execute to Authent icated Users */
88 "(A;OICI;GA;;;BA)" /* Allow full control to Administrator s */
89 "(A;OICI;GA;;;LS)" /* Allow full control to Local service account */
90 "(A;OICI;GA;;;SY)"; /* Allow full control to Local system */
91
92
93
94 static apr_status_t APR_THREAD_FUNC
95 ntp_socket_timeout_set(apr_socket_t *sock, apr_interval_time_t t)
96 {
97 tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)sock;
98 if (t < 0)
99 con->timeout = INFINITE;
100 else
101 con->timeout = (DWORD)(apr_time_as_msec(t));
102 return APR_SUCCESS;
103 }
104
105 static apr_status_t APR_THREAD_FUNC
106 ntp_socket_timeout_get(apr_socket_t *sock, apr_interval_time_t *t)
107 {
108 tcn_ntp_conn_t *con = (tcn_ntp_conn_t*)sock;
109 if (con->timeout == INFINITE)
110 *t = -1;
111 else
112 *t = con->timeout * 1000;
113 return APR_SUCCESS;
114 }
115
116 static APR_INLINE apr_status_t APR_THREAD_FUNC
117 ntp_socket_opt_set(apr_socket_t *sock, apr_int32_t opt, apr_int32_t on)
118 {
119 tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)sock;
120 apr_status_t rv = APR_SUCCESS;
121 switch (opt) {
122 case APR_SO_SNDBUF:
123 con->sndbuf = (DWORD)on;
124 break;
125 case APR_SO_RCVBUF:
126 con->rcvbuf = (DWORD)on;
127 break;
128 default:
129 rv = APR_EINVAL;
130 break;
131 }
132 return rv;
133 }
134
135 static APR_INLINE apr_status_t APR_THREAD_FUNC
136 ntp_socket_opt_get(apr_socket_t *sock, apr_int32_t opt, apr_int32_t *on)
137 {
138 tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)sock;
139 apr_status_t rv = APR_SUCCESS;
140 switch (opt) {
141 case APR_SO_SNDBUF:
142 *on = con->sndbuf;
143 break;
144 case APR_SO_RCVBUF:
145 *on = con->rcvbuf;
146 break;
147 default:
148 rv = APR_EINVAL;
149 break;
150 }
151 return rv;
152 }
153
154 static apr_status_t ntp_cleanup(void *data)
155 {
156 tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)data;
157
158 if (con) {
159 if (con->h_pipe) {
160 FlushFileBuffers(con->h_pipe);
161 CloseHandle(con->h_pipe);
162 con->h_pipe = NULL;
163 }
164 if (con->rd_event) {
165 CloseHandle(con->rd_event);
166 con->rd_event = NULL;
167 }
168 if (con->wr_event) {
169 CloseHandle(con->wr_event);
170 con->wr_event= NULL;
171 }
172 }
173
174 #ifdef TCN_DO_STATISTICS
175 apr_atomic_inc32(&ntp_cleared);
176 #endif
177 return APR_SUCCESS;
178 }
179
180 static apr_status_t APR_THREAD_FUNC
181 ntp_socket_shutdown(apr_socket_t *sock, apr_shutdown_how_e how)
182 {
183 UNREFERENCED(how);
184 return ntp_cleanup(sock);;
185 }
186
187 static apr_status_t APR_THREAD_FUNC
188 ntp_socket_close(apr_socket_t *sock)
189 {
190 #ifdef TCN_DO_STATISTICS
191 apr_atomic_inc32(&ntp_closed);
192 #endif
193 return ntp_cleanup(sock);;
194 }
195
196 static apr_status_t APR_THREAD_FUNC
197 ntp_socket_recv(apr_socket_t *sock, char *buf, apr_size_t *len)
198 {
199 tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)sock;
200 DWORD readed;
201
202 if (!ReadFile(con->h_pipe, buf, (DWORD)*len, &readed, &con->rd_o)) {
203 DWORD err = GetLastError();
204 if (err == ERROR_IO_PENDING) {
205 DWORD r = WaitForSingleObject(con->rd_event, con->timeout);
206 if (r == WAIT_TIMEOUT)
207 return APR_TIMEUP;
208 else if (r != WAIT_OBJECT_0)
209 return APR_EOF;
210 }
211 else if (err == ERROR_BROKEN_PIPE || err == ERROR_NO_DATA) {
212 /* Server closed the pipe */
213 return APR_EOF;
214 }
215 GetOverlappedResult(con->h_pipe, &con->rd_o, &readed, FALSE);
216 }
217 *len = readed;
218 return APR_SUCCESS;
219 }
220
221 static apr_status_t APR_THREAD_FUNC
222 ntp_socket_send(apr_socket_t *sock, const char *buf,
223 apr_size_t *len)
224 {
225 tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)sock;
226 DWORD written;
227
228 if (!WriteFile(con->h_pipe, buf, (DWORD)*len, &written, &con->wr_o)) {
229 DWORD err = GetLastError();
230 if (err == ERROR_IO_PENDING) {
231 DWORD r = WaitForSingleObject(con->wr_event, con->timeout);
232 if (r == WAIT_TIMEOUT)
233 return APR_TIMEUP;
234 else if (r != WAIT_OBJECT_0)
235 return APR_EOF;
236 }
237 else if (err == ERROR_BROKEN_PIPE || err == ERROR_NO_DATA) {
238 /* Server closed the pipe */
239 return APR_EOF;
240 }
241 GetOverlappedResult(con->h_pipe, &con->wr_o, &written, FALSE);
242 }
243 *len = written;
244 return APR_SUCCESS;
245 }
246
247 static apr_status_t APR_THREAD_FUNC
248 ntp_socket_sendv(apr_socket_t *sock,
249 const struct iovec *vec,
250 apr_int32_t nvec, apr_size_t *len)
251 {
252 tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)sock;
253 apr_status_t rv;
254 apr_size_t written = 0;
255 apr_int32_t i;
256
257 for (i = 0; i < nvec; i++) {
258 apr_size_t rd = vec[i].iov_len;
259 if ((rv = ntp_socket_send((apr_socket_t *)con,
260 vec[i].iov_base, &rd)) != APR_SUCCESS) {
261 *len = written;
262 return rv;
263 }
264 written += rd;
265 }
266 *len = written;
267 return APR_SUCCESS;
268 }
269
270 static apr_status_t ntp_socket_cleanup(void *data)
271 {
272 tcn_socket_t *s = (tcn_socket_t *)data;
273
274 if (s->net->cleanup) {
275 (*s->net->cleanup)(s->opaque);
276 s->net->cleanup = NULL;
277 }
278 #ifdef TCN_DO_STATISTICS
279 apr_atomic_inc32(&ntp_cleared);
280 #endif
281 return APR_SUCCESS;
282 }
283
284 static tcn_nlayer_t ntp_socket_layer = {
285 TCN_SOCKET_NTPIPE,
286 ntp_cleanup,
287 ntp_socket_close,
288 ntp_socket_shutdown,
289 ntp_socket_opt_get,
290 ntp_socket_opt_set,
291 ntp_socket_timeout_get,
292 ntp_socket_timeout_set,
293 ntp_socket_send,
294 ntp_socket_sendv,
295 ntp_socket_recv
296 };
297
298 static BOOL create_DACL(LPSECURITY_ATTRIBUTES psa)
299 {
300
301 return ConvertStringSecurityDescriptorToSecurityDescriptor(
302 NTSD_STRING,
303 SDDL_REVISION_1,
304 &(psa->lpSecurityDescriptor),
305 NULL);
306 }
307
308 TCN_IMPLEMENT_CALL(jlong, Local, create)(TCN_STDARGS, jstring name,
309 jlong pool)
310 {
311 apr_pool_t *p = J2P(pool, apr_pool_t *);
312 tcn_socket_t *s = NULL;
313 tcn_ntp_conn_t *con = NULL;
314 TCN_ALLOC_CSTRING(name);
315
316 UNREFERENCED(o);
317 TCN_ASSERT(pool != 0);
318
319 #ifdef TCN_DO_STATISTICS
320 ntp_created++;
321 #endif
322 con = (tcn_ntp_conn_t *)apr_pcalloc(p, sizeof(tcn_ntp_conn_t));
323 con->pool = p;
324 con->mode = TCN_NTP_UNKNOWN;
325 con->nmax = PIPE_UNLIMITED_INSTANCES;
326 con->timeout = DEFTIMEOUT;
327 con->sndbuf = DEFSIZE;
328 con->rcvbuf = DEFSIZE;
329 if (J2S(name)) {
330 strncpy(con->name, J2S(name), MAX_PATH);
331 con->name[MAX_PATH] = '\0';
332 TCN_FREE_CSTRING(name);
333 }
334 else
335 strcpy(con->name, DEFNAME);
336 con->sa.nLength = sizeof(con->sa);
337 con->sa.bInheritHandle = TRUE;
338 if (!create_DACL(&con->sa)) {
339 tcn_ThrowAPRException(e, apr_get_os_error());
340 return 0;
341 }
342
343 s = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t));
344 s->pool = p;
345 s->net = &ntp_socket_layer;
346 s->opaque = con;
347 apr_pool_cleanup_register(p, (const void *)s,
348 ntp_socket_cleanup,
349 apr_pool_cleanup_null);
350
351 fflush(stderr);
352 return P2J(s);
353
354 }
355
356 TCN_IMPLEMENT_CALL(jint, Local, bind)(TCN_STDARGS, jlong sock,
357 jlong sa)
358 {
359 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
360 UNREFERENCED_STDARGS;
361 UNREFERENCED(sa);
362 TCN_ASSERT(sock != 0);
363 if (s->net->type == TCN_SOCKET_NTPIPE) {
364 tcn_ntp_conn_t *c = (tcn_ntp_conn_t *)s->opaque;
365 c->mode = TCN_NTP_SERVER;
366 return APR_SUCCESS;
367 }
368 else
369 return APR_EINVAL;
370 }
371
372 TCN_IMPLEMENT_CALL(jint, Local, listen)(TCN_STDARGS, jlong sock,
373 jint backlog)
374 {
375 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
376 UNREFERENCED_STDARGS;
377
378 TCN_ASSERT(sock != 0);
379 if (s->net->type == TCN_SOCKET_NTPIPE) {
380 tcn_ntp_conn_t *c = (tcn_ntp_conn_t *)s->opaque;
381 c->mode = TCN_NTP_SERVER;
382 if (backlog > 0)
383 c->nmax = backlog;
384 else
385 c->nmax = PIPE_UNLIMITED_INSTANCES;
386 return APR_SUCCESS;
387 }
388 else
389 return APR_EINVAL;
390 }
391
392 TCN_IMPLEMENT_CALL(jlong, Local, accept)(TCN_STDARGS, jlong sock)
393 {
394 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
395 apr_pool_t *p = NULL;
396 tcn_socket_t *a = NULL;
397 tcn_ntp_conn_t *con = NULL;
398
399 UNREFERENCED(o);
400 TCN_ASSERT(sock != 0);
401
402 TCN_THROW_IF_ERR(apr_pool_create(&p, s->pool), p);
403 if (s->net->type == TCN_SOCKET_NTPIPE) {
404 tcn_ntp_conn_t *c = (tcn_ntp_conn_t *)s->opaque;
405 con = (tcn_ntp_conn_t *)apr_pcalloc(p, sizeof(tcn_ntp_conn_t));
406 con->pool = p;
407 con->mode = TCN_NTP_SERVER;
408 con->nmax = c->nmax;
409 con->timeout = c->timeout;
410 strcpy(con->name, c->name);
411 con->h_pipe = CreateNamedPipe(con->name,
412 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
413 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE _WAIT,
414 con->nmax,
415 con->sndbuf,
416 con->rcvbuf,
417 con->timeout,
418 &c->sa);
419 if (con->h_pipe == INVALID_HANDLE_VALUE) {
420 tcn_ThrowAPRException(e, apr_get_os_error());
421 goto cleanup;
422 }
423 /* Block until a client connects */
424 if (!ConnectNamedPipe(con->h_pipe, NULL)) {
425 DWORD err = GetLastError();
426 if (err != ERROR_PIPE_CONNECTED) {
427 CloseHandle(con->h_pipe);
428 tcn_ThrowAPRException(e, APR_FROM_OS_ERROR(err));
429 goto cleanup;
430 }
431 }
432 /* Create overlapped events */
433 con->rd_event = CreateEvent(NULL, TRUE, FALSE, NULL);
434 con->rd_o.hEvent = con->rd_event;
435 con->wr_event = CreateEvent(NULL, TRUE, FALSE, NULL);
436 con->wr_o.hEvent = con->wr_event;
437 }
438 else {
439 tcn_ThrowAPRException(e, APR_ENOTIMPL);
440 goto cleanup;
441 }
442 if (con) {
443 #ifdef TCN_DO_STATISTICS
444 apr_atomic_inc32(&ntp_accepted);
445 #endif
446 a = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t));
447 a->pool = p;
448 a->net = &ntp_socket_layer;
449 a->opaque = con;
450 apr_pool_cleanup_register(p, (const void *)a,
451 ntp_socket_cleanup,
452 apr_pool_cleanup_null);
453 }
454 return P2J(a);
455 cleanup:
456 if (p)
457 apr_pool_destroy(p);
458 return 0;
459 }
460
461 TCN_IMPLEMENT_CALL(jint, Local, connect)(TCN_STDARGS, jlong sock,
462 jlong sa)
463 {
464 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
465 apr_pool_t *p = NULL;
466 tcn_socket_t *a = NULL;
467 tcn_ntp_conn_t *con = NULL;
468
469 UNREFERENCED(o);
470 UNREFERENCED(sa);
471 TCN_ASSERT(sock != 0);
472 if (s->net->type != TCN_SOCKET_NTPIPE)
473 return APR_ENOTSOCK;
474 con = (tcn_ntp_conn_t *)s->opaque;
475 if (con->mode == TCN_NTP_SERVER)
476 return APR_EINVAL;
477 con->mode = TCN_NTP_CLIENT;
478
479 while (TRUE) {
480 con->h_pipe = CreateFile(con->name,
481 GENERIC_WRITE | GENERIC_READ,
482 FILE_SHARE_READ | FILE_SHARE_WRITE ,
483 NULL,
484 OPEN_EXISTING,
485 FILE_FLAG_OVERLAPPED,
486 NULL);
487 if (con->h_pipe != INVALID_HANDLE_VALUE)
488 break;
489 if (GetLastError() == ERROR_PIPE_BUSY) {
490 /* All pipe instances are busy, so wait for
491 * timeout value specified by the server process in
492 * the CreateNamedPipe function.
493 */
494 if (!WaitNamedPipe(con->name, NMPWAIT_USE_DEFAULT_WAIT))
495 return apr_get_os_error();
496 }
497 else
498 return apr_get_os_error();
499 }
500
501 /* Create overlapped events */
502 con->rd_event = CreateEvent(NULL, TRUE, FALSE, NULL);
503 con->rd_o.hEvent = con->rd_event;
504 con->wr_event = CreateEvent(NULL, TRUE, FALSE, NULL);
505 con->wr_o.hEvent = con->wr_event;
506
507 return APR_SUCCESS;
508 }
509
510 #endif
511
OLDNEW
« no previous file with comments | « c/os_win32_logmessages.mc ('k') | c/os_win32_registry.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698