mturk       2005/06/24 01:21:29

  Modified:    jni/native libtcnative.dsp tcnative.dsp
               jni/native/src network.c sslnetwork.c
  Added:       jni/native/os/win32 ntpipe.c
  Log:
  Added NT Pipe network layer.
  The same will be done for AF_UNIX/AF_LOCAL.
  
  Revision  Changes    Path
  1.13      +4 -0      jakarta-tomcat-connectors/jni/native/libtcnative.dsp
  
  Index: libtcnative.dsp
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jni/native/libtcnative.dsp,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- libtcnative.dsp   14 Jun 2005 11:55:54 -0000      1.12
  +++ libtcnative.dsp   24 Jun 2005 08:21:29 -0000      1.13
  @@ -196,6 +196,10 @@
   # PROP Default_Filter ""
   # Begin Source File
   
  +SOURCE=.\os\win32\ntpipe.c
  +# End Source File
  +# Begin Source File
  +
   SOURCE=.\os\win32\system.c
   # End Source File
   # End Group
  
  
  
  1.13      +4 -0      jakarta-tomcat-connectors/jni/native/tcnative.dsp
  
  Index: tcnative.dsp
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jni/native/tcnative.dsp,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- tcnative.dsp      14 Jun 2005 11:55:54 -0000      1.12
  +++ tcnative.dsp      24 Jun 2005 08:21:29 -0000      1.13
  @@ -196,6 +196,10 @@
   # PROP Default_Filter ""
   # Begin Source File
   
  +SOURCE=.\os\win32\ntpipe.c
  +# End Source File
  +# Begin Source File
  +
   SOURCE=.\os\win32\system.c
   # End Source File
   # End Group
  
  
  
  1.1                  jakarta-tomcat-connectors/jni/native/os/win32/ntpipe.c
  
  Index: ntpipe.c
  ===================================================================
  /* Copyright 2000-2004 The Apache Software Foundation
   *
   * Licensed 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 $Revision: 1.1 $, $Date: 2005/06/24 08:21:29 $
   */
  
  
  #define _WIN32_WINNT 0x0500
  #define STRICT
  #include <windows.h>
  #include <winsock.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;
      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_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, *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, *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->cleanup) {
          (*s->cleanup)(s->opaque);
          s->cleanup = NULL;
      }
  #ifdef TCN_DO_STATISTICS
      apr_atomic_inc32(&ntp_cleared);
  #endif
      return APR_SUCCESS;
  }
  
  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;
      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->type     = TCN_SOCKET_NTPIPE;
      s->cleanup  = ntp_cleanup;
      s->recv     = ntp_socket_recv;
      s->send     = ntp_socket_send;
      s->sendv    = ntp_socket_sendv;
      s->shutdown = ntp_socket_shutdown;
      s->tmget    = ntp_socket_timeout_get;
      s->tmset    = ntp_socket_timeout_set;
      s->close    = ntp_socket_close;
      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->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->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->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,
                                        DEFSIZE,
                                        DEFSIZE,
                                        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->type     = TCN_SOCKET_NTPIPE;
          a->cleanup  = ntp_cleanup;
          a->recv     = ntp_socket_recv;
          a->send     = ntp_socket_send;
          a->sendv    = ntp_socket_sendv;
          a->shutdown = ntp_socket_shutdown;
          a->tmget    = ntp_socket_timeout_get;
          a->tmset    = ntp_socket_timeout_set;
          a->close    = ntp_socket_close;
          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->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;
  }
  
  
  
  1.40      +7 -3      jakarta-tomcat-connectors/jni/native/src/network.c
  
  Index: network.c
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jni/native/src/network.c,v
  retrieving revision 1.39
  retrieving revision 1.40
  diff -u -r1.39 -r1.40
  --- network.c 23 Jun 2005 14:10:08 -0000      1.39
  +++ network.c 24 Jun 2005 08:21:29 -0000      1.40
  @@ -480,7 +480,7 @@
   
       UNREFERENCED(o);
       TCN_ASSERT(sock != 0);
  -    TCN_ASSERT(s->sock != NULL);
  +    TCN_ASSERT(s->opaque != NULL);
   #ifdef TCN_DO_STATISTICS
       sp_max_send = TCN_MAX(sp_max_send, nbytes);
       sp_min_send = TCN_MIN(sp_min_send, nbytes);
  @@ -525,6 +525,7 @@
   
       UNREFERENCED(o);
       TCN_ASSERT(sock != 0);
  +    TCN_ASSERT(s->opaque != NULL);
       TCN_ASSERT(buf != NULL);
   #ifdef TCN_DO_STATISTICS
       sp_max_send = TCN_MAX(sp_max_send, nbytes);
  @@ -557,6 +558,7 @@
   
       UNREFERENCED(o);
       TCN_ASSERT(sock != 0);
  +    TCN_ASSERT(s->opaque != NULL);
   
       nvec = (*e)->GetArrayLength(e, bufs);
       if (nvec >= APR_MAX_IOVEC_SIZE)
  @@ -626,6 +628,7 @@
   
       UNREFERENCED(o);
       TCN_ASSERT(sock != 0);
  +    TCN_ASSERT(s->opaque != NULL);
   
       if (toread <= TCN_BUFFER_SZ) {
           char sb[TCN_BUFFER_SZ];
  @@ -739,6 +742,7 @@
   
       UNREFERENCED(o);
       TCN_ASSERT(sock != 0);
  +    TCN_ASSERT(s->opaque != NULL);
       TCN_ASSERT(buf != NULL);
   
       bytes  = (char *)(*e)->GetDirectBufferAddress(e, buf);
  @@ -786,7 +790,7 @@
       UNREFERENCED(o);
       TCN_ASSERT(sock != 0);
       TCN_ASSERT(buf != NULL);
  -    TCN_ASSERT(s->sock != NULL);
  +    TCN_ASSERT(s->opaque != NULL);
   
       bytes  = (char *)(*e)->GetDirectBufferAddress(e, buf);
       TCN_ASSERT(bytes != NULL);
  
  
  
  1.19      +5 -5      jakarta-tomcat-connectors/jni/native/src/sslnetwork.c
  
  Index: sslnetwork.c
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jni/native/src/sslnetwork.c,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- sslnetwork.c      23 Jun 2005 08:58:05 -0000      1.18
  +++ sslnetwork.c      24 Jun 2005 08:21:29 -0000      1.19
  @@ -419,19 +419,19 @@
   {
       tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)sock;
       apr_status_t rv;
  -    apr_size_t readed = 0;
  +    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 = ssl_socket_send((apr_socket_t *)con,
                                     vec[i].iov_base, &rd)) != APR_SUCCESS) {
  -            *len = readed;
  +            *len = written;
               return rv;
           }
  -        readed += rd;
  +        written += rd;
       }
  -    *len = readed;
  +    *len = written;
       return APR_SUCCESS;
   }
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to