Index: c/os_win32_ntpipe.c |
diff --git a/c/os_win32_ntpipe.c b/c/os_win32_ntpipe.c |
deleted file mode 100644 |
index 4ef80c7d990a8a2f9803bfec1a39b3bd26fe522d..0000000000000000000000000000000000000000 |
--- a/c/os_win32_ntpipe.c |
+++ /dev/null |
@@ -1,511 +0,0 @@ |
-#ifdef _WINDOWS |
- |
-/* 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. |
- * The ASF 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. |
- */ |
- |
-/** NT Pipes network wrapper |
- * |
- * @author Mladen Turk |
- * @version $Id: ntpipe.c 1442587 2013-02-05 13:49:48Z rjung $ |
- */ |
- |
- |
-#ifndef _WIN32_WINNT |
-#define _WIN32_WINNT 0x0500 |
-#endif |
-#define STRICT |
-#include <winsock2.h> |
-#include <mswsock.h> |
-#include <ws2tcpip.h> |
-#include <sddl.h> |
- |
-#include "tcn.h" |
-#include "apr_thread_mutex.h" |
-#include "apr_poll.h" |
- |
-#ifdef TCN_DO_STATISTICS |
-#include "apr_atomic.h" |
- |
-static volatile apr_uint32_t ntp_created = 0; |
-static volatile apr_uint32_t ntp_closed = 0; |
-static volatile apr_uint32_t ntp_cleared = 0; |
-static volatile apr_uint32_t ntp_accepted = 0; |
- |
-void ntp_network_dump_statistics() |
-{ |
- fprintf(stderr, "NT Network Statistics ..\n"); |
- fprintf(stderr, "Sockets created : %d\n", ntp_created); |
- fprintf(stderr, "Sockets accepted : %d\n", ntp_accepted); |
- fprintf(stderr, "Sockets closed : %d\n", ntp_closed); |
- fprintf(stderr, "Sockets cleared : %d\n", ntp_cleared); |
-} |
- |
-#endif |
- |
-#define DEFNAME "\\\\.\\PIPE\\TOMCATNATIVEPIPE" |
-#define DEFNAME_FMT "\\\\.\\PIPE\\TOMCATNATIVEPIPE%08X%08X" |
-#define DEFSIZE 8192 |
-#define DEFTIMEOUT 60000 |
- |
-#define TCN_NTP_UNKNOWN 0 |
-#define TCN_NTP_CLIENT 1 |
-#define TCN_NTP_SERVER 2 |
- |
-typedef struct { |
- apr_pool_t *pool; |
- apr_socket_t *sock; /* Dummy socket */ |
- OVERLAPPED rd_o; |
- OVERLAPPED wr_o; |
- HANDLE h_pipe; |
- HANDLE rd_event; |
- HANDLE wr_event; |
- DWORD timeout; |
- int mode; /* Client or server mode */ |
- int nmax; |
- DWORD sndbuf; |
- DWORD rcvbuf; |
- char name[MAX_PATH+1]; |
- SECURITY_ATTRIBUTES sa; |
-} tcn_ntp_conn_t; |
- |
-static const char *NTSD_STRING = "D:" /* Discretionary ACL */ |
- "(D;OICI;GA;;;BG)" /* Deny access to Built-in Guests */ |
- "(D;OICI;GA;;;AN)" /* Deny access to Anonymous Logon */ |
- "(A;OICI;GRGWGX;;;AU)" /* Allow read/write/execute to Authenticated Users */ |
- "(A;OICI;GA;;;BA)" /* Allow full control to Administrators */ |
- "(A;OICI;GA;;;LS)" /* Allow full control to Local service account */ |
- "(A;OICI;GA;;;SY)"; /* Allow full control to Local system */ |
- |
- |
- |
-static apr_status_t APR_THREAD_FUNC |
-ntp_socket_timeout_set(apr_socket_t *sock, apr_interval_time_t t) |
-{ |
- tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)sock; |
- if (t < 0) |
- con->timeout = INFINITE; |
- else |
- con->timeout = (DWORD)(apr_time_as_msec(t)); |
- return APR_SUCCESS; |
-} |
- |
-static apr_status_t APR_THREAD_FUNC |
-ntp_socket_timeout_get(apr_socket_t *sock, apr_interval_time_t *t) |
-{ |
- tcn_ntp_conn_t *con = (tcn_ntp_conn_t*)sock; |
- if (con->timeout == INFINITE) |
- *t = -1; |
- else |
- *t = con->timeout * 1000; |
- return APR_SUCCESS; |
-} |
- |
-static APR_INLINE apr_status_t APR_THREAD_FUNC |
-ntp_socket_opt_set(apr_socket_t *sock, apr_int32_t opt, apr_int32_t on) |
-{ |
- tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)sock; |
- apr_status_t rv = APR_SUCCESS; |
- switch (opt) { |
- case APR_SO_SNDBUF: |
- con->sndbuf = (DWORD)on; |
- break; |
- case APR_SO_RCVBUF: |
- con->rcvbuf = (DWORD)on; |
- break; |
- default: |
- rv = APR_EINVAL; |
- break; |
- } |
- return rv; |
-} |
- |
-static APR_INLINE apr_status_t APR_THREAD_FUNC |
-ntp_socket_opt_get(apr_socket_t *sock, apr_int32_t opt, apr_int32_t *on) |
-{ |
- tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)sock; |
- apr_status_t rv = APR_SUCCESS; |
- switch (opt) { |
- case APR_SO_SNDBUF: |
- *on = con->sndbuf; |
- break; |
- case APR_SO_RCVBUF: |
- *on = con->rcvbuf; |
- break; |
- default: |
- rv = APR_EINVAL; |
- break; |
- } |
- return rv; |
-} |
- |
-static apr_status_t ntp_cleanup(void *data) |
-{ |
- tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)data; |
- |
- if (con) { |
- if (con->h_pipe) { |
- FlushFileBuffers(con->h_pipe); |
- CloseHandle(con->h_pipe); |
- con->h_pipe = NULL; |
- } |
- if (con->rd_event) { |
- CloseHandle(con->rd_event); |
- con->rd_event = NULL; |
- } |
- if (con->wr_event) { |
- CloseHandle(con->wr_event); |
- con->wr_event= NULL; |
- } |
- } |
- |
-#ifdef TCN_DO_STATISTICS |
- apr_atomic_inc32(&ntp_cleared); |
-#endif |
- return APR_SUCCESS; |
-} |
- |
-static apr_status_t APR_THREAD_FUNC |
-ntp_socket_shutdown(apr_socket_t *sock, apr_shutdown_how_e how) |
-{ |
- UNREFERENCED(how); |
- return ntp_cleanup(sock);; |
-} |
- |
-static apr_status_t APR_THREAD_FUNC |
-ntp_socket_close(apr_socket_t *sock) |
-{ |
-#ifdef TCN_DO_STATISTICS |
- apr_atomic_inc32(&ntp_closed); |
-#endif |
- return ntp_cleanup(sock);; |
-} |
- |
-static apr_status_t APR_THREAD_FUNC |
-ntp_socket_recv(apr_socket_t *sock, char *buf, apr_size_t *len) |
-{ |
- tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)sock; |
- DWORD readed; |
- |
- if (!ReadFile(con->h_pipe, buf, (DWORD)*len, &readed, &con->rd_o)) { |
- DWORD err = GetLastError(); |
- if (err == ERROR_IO_PENDING) { |
- DWORD r = WaitForSingleObject(con->rd_event, con->timeout); |
- if (r == WAIT_TIMEOUT) |
- return APR_TIMEUP; |
- else if (r != WAIT_OBJECT_0) |
- return APR_EOF; |
- } |
- else if (err == ERROR_BROKEN_PIPE || err == ERROR_NO_DATA) { |
- /* Server closed the pipe */ |
- return APR_EOF; |
- } |
- GetOverlappedResult(con->h_pipe, &con->rd_o, &readed, FALSE); |
- } |
- *len = readed; |
- return APR_SUCCESS; |
-} |
- |
-static apr_status_t APR_THREAD_FUNC |
-ntp_socket_send(apr_socket_t *sock, const char *buf, |
- apr_size_t *len) |
-{ |
- tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)sock; |
- DWORD written; |
- |
- if (!WriteFile(con->h_pipe, buf, (DWORD)*len, &written, &con->wr_o)) { |
- DWORD err = GetLastError(); |
- if (err == ERROR_IO_PENDING) { |
- DWORD r = WaitForSingleObject(con->wr_event, con->timeout); |
- if (r == WAIT_TIMEOUT) |
- return APR_TIMEUP; |
- else if (r != WAIT_OBJECT_0) |
- return APR_EOF; |
- } |
- else if (err == ERROR_BROKEN_PIPE || err == ERROR_NO_DATA) { |
- /* Server closed the pipe */ |
- return APR_EOF; |
- } |
- GetOverlappedResult(con->h_pipe, &con->wr_o, &written, FALSE); |
- } |
- *len = written; |
- return APR_SUCCESS; |
-} |
- |
-static apr_status_t APR_THREAD_FUNC |
-ntp_socket_sendv(apr_socket_t *sock, |
- const struct iovec *vec, |
- apr_int32_t nvec, apr_size_t *len) |
-{ |
- tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)sock; |
- apr_status_t rv; |
- apr_size_t written = 0; |
- apr_int32_t i; |
- |
- for (i = 0; i < nvec; i++) { |
- apr_size_t rd = vec[i].iov_len; |
- if ((rv = ntp_socket_send((apr_socket_t *)con, |
- vec[i].iov_base, &rd)) != APR_SUCCESS) { |
- *len = written; |
- return rv; |
- } |
- written += rd; |
- } |
- *len = written; |
- return APR_SUCCESS; |
-} |
- |
-static apr_status_t ntp_socket_cleanup(void *data) |
-{ |
- tcn_socket_t *s = (tcn_socket_t *)data; |
- |
- if (s->net->cleanup) { |
- (*s->net->cleanup)(s->opaque); |
- s->net->cleanup = NULL; |
- } |
-#ifdef TCN_DO_STATISTICS |
- apr_atomic_inc32(&ntp_cleared); |
-#endif |
- return APR_SUCCESS; |
-} |
- |
-static tcn_nlayer_t ntp_socket_layer = { |
- TCN_SOCKET_NTPIPE, |
- ntp_cleanup, |
- ntp_socket_close, |
- ntp_socket_shutdown, |
- ntp_socket_opt_get, |
- ntp_socket_opt_set, |
- ntp_socket_timeout_get, |
- ntp_socket_timeout_set, |
- ntp_socket_send, |
- ntp_socket_sendv, |
- ntp_socket_recv |
-}; |
- |
-static BOOL create_DACL(LPSECURITY_ATTRIBUTES psa) |
-{ |
- |
- return ConvertStringSecurityDescriptorToSecurityDescriptor( |
- NTSD_STRING, |
- SDDL_REVISION_1, |
- &(psa->lpSecurityDescriptor), |
- NULL); |
-} |
- |
-TCN_IMPLEMENT_CALL(jlong, Local, create)(TCN_STDARGS, jstring name, |
- jlong pool) |
-{ |
- apr_pool_t *p = J2P(pool, apr_pool_t *); |
- tcn_socket_t *s = NULL; |
- tcn_ntp_conn_t *con = NULL; |
- TCN_ALLOC_CSTRING(name); |
- |
- UNREFERENCED(o); |
- TCN_ASSERT(pool != 0); |
- |
-#ifdef TCN_DO_STATISTICS |
- ntp_created++; |
-#endif |
- con = (tcn_ntp_conn_t *)apr_pcalloc(p, sizeof(tcn_ntp_conn_t)); |
- con->pool = p; |
- con->mode = TCN_NTP_UNKNOWN; |
- con->nmax = PIPE_UNLIMITED_INSTANCES; |
- con->timeout = DEFTIMEOUT; |
- con->sndbuf = DEFSIZE; |
- con->rcvbuf = DEFSIZE; |
- if (J2S(name)) { |
- strncpy(con->name, J2S(name), MAX_PATH); |
- con->name[MAX_PATH] = '\0'; |
- TCN_FREE_CSTRING(name); |
- } |
- else |
- strcpy(con->name, DEFNAME); |
- con->sa.nLength = sizeof(con->sa); |
- con->sa.bInheritHandle = TRUE; |
- if (!create_DACL(&con->sa)) { |
- tcn_ThrowAPRException(e, apr_get_os_error()); |
- return 0; |
- } |
- |
- s = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t)); |
- s->pool = p; |
- s->net = &ntp_socket_layer; |
- s->opaque = con; |
- apr_pool_cleanup_register(p, (const void *)s, |
- ntp_socket_cleanup, |
- apr_pool_cleanup_null); |
- |
- fflush(stderr); |
- return P2J(s); |
- |
-} |
- |
-TCN_IMPLEMENT_CALL(jint, Local, bind)(TCN_STDARGS, jlong sock, |
- jlong sa) |
-{ |
- tcn_socket_t *s = J2P(sock, tcn_socket_t *); |
- UNREFERENCED_STDARGS; |
- UNREFERENCED(sa); |
- TCN_ASSERT(sock != 0); |
- if (s->net->type == TCN_SOCKET_NTPIPE) { |
- tcn_ntp_conn_t *c = (tcn_ntp_conn_t *)s->opaque; |
- c->mode = TCN_NTP_SERVER; |
- return APR_SUCCESS; |
- } |
- else |
- return APR_EINVAL; |
-} |
- |
-TCN_IMPLEMENT_CALL(jint, Local, listen)(TCN_STDARGS, jlong sock, |
- jint backlog) |
-{ |
- tcn_socket_t *s = J2P(sock, tcn_socket_t *); |
- UNREFERENCED_STDARGS; |
- |
- TCN_ASSERT(sock != 0); |
- if (s->net->type == TCN_SOCKET_NTPIPE) { |
- tcn_ntp_conn_t *c = (tcn_ntp_conn_t *)s->opaque; |
- c->mode = TCN_NTP_SERVER; |
- if (backlog > 0) |
- c->nmax = backlog; |
- else |
- c->nmax = PIPE_UNLIMITED_INSTANCES; |
- return APR_SUCCESS; |
- } |
- else |
- return APR_EINVAL; |
-} |
- |
-TCN_IMPLEMENT_CALL(jlong, Local, accept)(TCN_STDARGS, jlong sock) |
-{ |
- tcn_socket_t *s = J2P(sock, tcn_socket_t *); |
- apr_pool_t *p = NULL; |
- tcn_socket_t *a = NULL; |
- tcn_ntp_conn_t *con = NULL; |
- |
- UNREFERENCED(o); |
- TCN_ASSERT(sock != 0); |
- |
- TCN_THROW_IF_ERR(apr_pool_create(&p, s->pool), p); |
- if (s->net->type == TCN_SOCKET_NTPIPE) { |
- tcn_ntp_conn_t *c = (tcn_ntp_conn_t *)s->opaque; |
- con = (tcn_ntp_conn_t *)apr_pcalloc(p, sizeof(tcn_ntp_conn_t)); |
- con->pool = p; |
- con->mode = TCN_NTP_SERVER; |
- con->nmax = c->nmax; |
- con->timeout = c->timeout; |
- strcpy(con->name, c->name); |
- con->h_pipe = CreateNamedPipe(con->name, |
- PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, |
- PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, |
- con->nmax, |
- con->sndbuf, |
- con->rcvbuf, |
- con->timeout, |
- &c->sa); |
- if (con->h_pipe == INVALID_HANDLE_VALUE) { |
- tcn_ThrowAPRException(e, apr_get_os_error()); |
- goto cleanup; |
- } |
- /* Block until a client connects */ |
- if (!ConnectNamedPipe(con->h_pipe, NULL)) { |
- DWORD err = GetLastError(); |
- if (err != ERROR_PIPE_CONNECTED) { |
- CloseHandle(con->h_pipe); |
- tcn_ThrowAPRException(e, APR_FROM_OS_ERROR(err)); |
- goto cleanup; |
- } |
- } |
- /* Create overlapped events */ |
- con->rd_event = CreateEvent(NULL, TRUE, FALSE, NULL); |
- con->rd_o.hEvent = con->rd_event; |
- con->wr_event = CreateEvent(NULL, TRUE, FALSE, NULL); |
- con->wr_o.hEvent = con->wr_event; |
- } |
- else { |
- tcn_ThrowAPRException(e, APR_ENOTIMPL); |
- goto cleanup; |
- } |
- if (con) { |
-#ifdef TCN_DO_STATISTICS |
- apr_atomic_inc32(&ntp_accepted); |
-#endif |
- a = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t)); |
- a->pool = p; |
- a->net = &ntp_socket_layer; |
- a->opaque = con; |
- apr_pool_cleanup_register(p, (const void *)a, |
- ntp_socket_cleanup, |
- apr_pool_cleanup_null); |
- } |
- return P2J(a); |
-cleanup: |
- if (p) |
- apr_pool_destroy(p); |
- return 0; |
-} |
- |
-TCN_IMPLEMENT_CALL(jint, Local, connect)(TCN_STDARGS, jlong sock, |
- jlong sa) |
-{ |
- tcn_socket_t *s = J2P(sock, tcn_socket_t *); |
- apr_pool_t *p = NULL; |
- tcn_socket_t *a = NULL; |
- tcn_ntp_conn_t *con = NULL; |
- |
- UNREFERENCED(o); |
- UNREFERENCED(sa); |
- TCN_ASSERT(sock != 0); |
- if (s->net->type != TCN_SOCKET_NTPIPE) |
- return APR_ENOTSOCK; |
- con = (tcn_ntp_conn_t *)s->opaque; |
- if (con->mode == TCN_NTP_SERVER) |
- return APR_EINVAL; |
- con->mode = TCN_NTP_CLIENT; |
- |
- while (TRUE) { |
- con->h_pipe = CreateFile(con->name, |
- GENERIC_WRITE | GENERIC_READ, |
- FILE_SHARE_READ | FILE_SHARE_WRITE , |
- NULL, |
- OPEN_EXISTING, |
- FILE_FLAG_OVERLAPPED, |
- NULL); |
- if (con->h_pipe != INVALID_HANDLE_VALUE) |
- break; |
- if (GetLastError() == ERROR_PIPE_BUSY) { |
- /* All pipe instances are busy, so wait for |
- * timeout value specified by the server process in |
- * the CreateNamedPipe function. |
- */ |
- if (!WaitNamedPipe(con->name, NMPWAIT_USE_DEFAULT_WAIT)) |
- return apr_get_os_error(); |
- } |
- else |
- return apr_get_os_error(); |
- } |
- |
- /* Create overlapped events */ |
- con->rd_event = CreateEvent(NULL, TRUE, FALSE, NULL); |
- con->rd_o.hEvent = con->rd_event; |
- con->wr_event = CreateEvent(NULL, TRUE, FALSE, NULL); |
- con->wr_o.hEvent = con->wr_event; |
- |
- return APR_SUCCESS; |
-} |
- |
-#endif |
- |