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