changeset 1633:74b2a52bc3c9

TransmitPackets(), ConnectEx(), and DisconnectEx()
author Igor Sysoev <igor@sysoev.ru>
date Sun, 11 Nov 2007 18:56:50 +0000
parents 2142e5cf62da
children d3cbb96818f1
files src/event/ngx_event_acceptex.c src/os/win32/ngx_socket.h src/os/win32/ngx_win32_init.c
diffstat 3 files changed, 187 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/src/event/ngx_event_acceptex.c
+++ b/src/event/ngx_event_acceptex.c
@@ -32,7 +32,8 @@ ngx_event_acceptex(ngx_event_t *rev)
     /* SO_UPDATE_ACCEPT_CONTEXT is required for shutdown() to work */
 
     if (setsockopt(c->fd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
-                   (char *) &c->listening->fd, sizeof(ngx_socket_t)) == -1)
+                   (char *) &c->listening->fd, sizeof(ngx_socket_t))
+        == -1)
     {
         ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
                       "setsockopt(SO_UPDATE_ACCEPT_CONTEXT) failed for %V",
@@ -41,17 +42,17 @@ ngx_event_acceptex(ngx_event_t *rev)
         c->accept_context_updated = 1;
     }
 
-    getacceptexsockaddrs(c->buffer->pos, c->listening->post_accept_buffer_size,
-                         c->listening->socklen + 16,
-                         c->listening->socklen + 16,
-                         &c->local_sockaddr, &c->local_socklen,
-                         &c->sockaddr, &c->socklen);
+    ngx_getacceptexsockaddrs(c->buffer->pos,
+                             c->listening->post_accept_buffer_size,
+                             c->listening->socklen + 16,
+                             c->listening->socklen + 16,
+                             &c->local_sockaddr, &c->local_socklen,
+                             &c->sockaddr, &c->socklen);
 
     if (c->listening->post_accept_buffer_size) {
         c->buffer->last += rev->available;
         c->buffer->end = c->buffer->start
-                                       + c->listening->post_accept_buffer_size;
-
+                         + c->listening->post_accept_buffer_size;
     } else {
         c->buffer = NULL;
     }
@@ -178,11 +179,11 @@ ngx_event_post_acceptex(ngx_listening_t 
             return NGX_ERROR;
         }
 
-        if (acceptex(ls->fd, s, c->buffer->pos, ls->post_accept_buffer_size,
-                     ls->socklen + 16, ls->socklen + 16,
-                     &rcvd, (LPOVERLAPPED) &rev->ovlp) == 0)
+        if (ngx_acceptex(ls->fd, s, c->buffer->pos, ls->post_accept_buffer_size,
+                         ls->socklen + 16, ls->socklen + 16,
+                         &rcvd, (LPOVERLAPPED) &rev->ovlp)
+            == 0)
         {
-
             err = ngx_socket_errno;
             if (err != WSA_IO_PENDING) {
                 ngx_log_error(NGX_LOG_ALERT, &ls->log, err,
--- a/src/os/win32/ngx_socket.h
+++ b/src/os/win32/ngx_socket.h
@@ -19,8 +19,8 @@ typedef SOCKET  ngx_socket_t;
 typedef int     socklen_t;
 
 
-#define ngx_socket(af, type, proto)                                         \
-                   WSASocket(af, type, proto, NULL, 0, WSA_FLAG_OVERLAPPED)
+#define ngx_socket(af, type, proto)                                          \
+    WSASocket(af, type, proto, NULL, 0, WSA_FLAG_OVERLAPPED)
 
 #define ngx_socket_n        "WSASocket()"
 
@@ -50,8 +50,8 @@ typedef BOOL (PASCAL FAR * LPFN_ACCEPTEX
     IN LPOVERLAPPED lpOverlapped
     );
 
-#define WSAID_ACCEPTEX \
-        {0xb5367df1,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
+#define WSAID_ACCEPTEX                                                       \
+    {0xb5367df1,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
 
 #endif
 
@@ -69,13 +69,31 @@ typedef VOID (PASCAL FAR * LPFN_GETACCEP
     OUT LPINT RemoteSockaddrLength
     );
 
-#define WSAID_GETACCEPTEXSOCKADDRS \
+#define WSAID_GETACCEPTEXSOCKADDRS                                           \
         {0xb5367df2,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
 
 #endif
 
 
-#ifndef LPFN_TRANSMITFILE
+#ifndef WSAID_TRANSMITFILE
+
+#ifndef TF_DISCONNECT
+
+#define TF_DISCONNECT           1
+#define TF_REUSE_SOCKET         2
+#define TF_WRITE_BEHIND         4
+#define TF_USE_DEFAULT_WORKER   0
+#define TF_USE_SYSTEM_THREAD    16
+#define TF_USE_KERNEL_APC       32
+
+typedef struct _TRANSMIT_FILE_BUFFERS {
+    LPVOID Head;
+    DWORD HeadLength;
+    LPVOID Tail;
+    DWORD TailLength;
+} TRANSMIT_FILE_BUFFERS, *PTRANSMIT_FILE_BUFFERS, FAR *LPTRANSMIT_FILE_BUFFERS;
+
+#endif
 
 typedef BOOL (PASCAL FAR * LPFN_TRANSMITFILE)(
     IN SOCKET hSocket,
@@ -87,19 +105,102 @@ typedef BOOL (PASCAL FAR * LPFN_TRANSMIT
     IN DWORD dwReserved
     );
 
-#define WSAID_TRANSMITFILE \
-        {0xb5367df0,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
+#define WSAID_TRANSMITFILE                                                   \
+    {0xb5367df0,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
 
 #endif
 
 
-extern LPFN_ACCEPTEX              acceptex;
-extern LPFN_GETACCEPTEXSOCKADDRS  getacceptexsockaddrs;
-extern LPFN_TRANSMITFILE          transmitfile;
+#ifndef WSAID_TRANSMITPACKETS
+
+/* OpenWatcom has a swapped TP_ELEMENT_FILE and TP_ELEMENT_MEMORY definition */
+
+#ifndef TP_ELEMENT_FILE
+
+#ifdef _MSC_VER
+#pragma warning(disable:4201) /* Nonstandard extension, nameless struct/union */
+#endif
+
+typedef struct _TRANSMIT_PACKETS_ELEMENT { 
+    ULONG dwElFlags; 
+#define TP_ELEMENT_MEMORY   1
+#define TP_ELEMENT_FILE     2
+#define TP_ELEMENT_EOP      4
+    ULONG cLength; 
+    union {
+        struct {
+            LARGE_INTEGER nFileOffset;
+            HANDLE        hFile;
+        };
+        PVOID             pBuffer;
+    };
+} TRANSMIT_PACKETS_ELEMENT, *PTRANSMIT_PACKETS_ELEMENT,
+    FAR *LPTRANSMIT_PACKETS_ELEMENT;
+
+#ifdef _MSC_VER
+#pragma warning(default:4201)
+#endif
+
+#endif
+
+typedef BOOL (PASCAL FAR * LPFN_TRANSMITPACKETS) (
+    SOCKET hSocket,                             
+    TRANSMIT_PACKETS_ELEMENT *lpPacketArray,                               
+    DWORD nElementCount,                
+    DWORD nSendSize,                
+    LPOVERLAPPED lpOverlapped,                  
+    DWORD dwFlags                               
+    );
+
+#define WSAID_TRANSMITPACKETS                                                \
+    {0xd9689da0,0x1f90,0x11d3,{0x99,0x71,0x00,0xc0,0x4f,0x68,0xc8,0x76}}
+
+#endif
+
+
+#ifndef WSAID_CONNECTEX
+
+typedef BOOL (PASCAL FAR * LPFN_CONNECTEX) (
+    IN SOCKET s,
+    IN const struct sockaddr FAR *name,
+    IN int namelen,
+    IN PVOID lpSendBuffer OPTIONAL,
+    IN DWORD dwSendDataLength,
+    OUT LPDWORD lpdwBytesSent,
+    IN LPOVERLAPPED lpOverlapped
+    );
+
+#define WSAID_CONNECTEX \
+    {0x25a207b9,0xddf3,0x4660,{0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e}}
+
+#endif
+
+
+#ifndef WSAID_DISCONNECTEX
+
+typedef BOOL (PASCAL FAR * LPFN_DISCONNECTEX) (
+    IN SOCKET s,
+    IN LPOVERLAPPED lpOverlapped,
+    IN DWORD  dwFlags,
+    IN DWORD  dwReserved
+    );
+
+#define WSAID_DISCONNECTEX                                                   \
+    {0x7fda2e11,0x8630,0x436f,{0xa0,0x31,0xf5,0x36,0xa6,0xee,0xc1,0x57}}
+
+#endif
+
+
+extern LPFN_ACCEPTEX              ngx_acceptex;
+extern LPFN_GETACCEPTEXSOCKADDRS  ngx_getacceptexsockaddrs;
+extern LPFN_TRANSMITFILE          ngx_transmitfile;
+extern LPFN_TRANSMITPACKETS       ngx_transmitpackets;
+extern LPFN_CONNECTEX             ngx_connectex;
+extern LPFN_DISCONNECTEX          ngx_disconnectex;
 
 
 int ngx_tcp_push(ngx_socket_t s);
-#define ngx_tcp_push_n        "tcp_push()"
+#define ngx_tcp_push_n            "tcp_push()"
 
 
 #endif /* _NGX_SOCKET_H_INCLUDED_ */
--- a/src/os/win32/ngx_win32_init.c
+++ b/src/os/win32/ngx_win32_init.c
@@ -39,13 +39,19 @@ static u_int               osviex;
 static OSVERSIONINFOEX     osvi;
 
 /* Should these pointers be per protocol ? */
-LPFN_ACCEPTEX              acceptex;
-LPFN_GETACCEPTEXSOCKADDRS  getacceptexsockaddrs;
-LPFN_TRANSMITFILE          transmitfile;
+LPFN_ACCEPTEX              ngx_acceptex;
+LPFN_GETACCEPTEXSOCKADDRS  ngx_getacceptexsockaddrs;
+LPFN_TRANSMITFILE          ngx_transmitfile;
+LPFN_TRANSMITPACKETS       ngx_transmitpackets;
+LPFN_CONNECTEX             ngx_connectex;
+LPFN_DISCONNECTEX          ngx_disconnectex;
 
-static GUID ae_guid = WSAID_ACCEPTEX;
+static GUID ax_guid = WSAID_ACCEPTEX;
 static GUID as_guid = WSAID_GETACCEPTEXSOCKADDRS;
 static GUID tf_guid = WSAID_TRANSMITFILE;
+static GUID tp_guid = WSAID_TRANSMITPACKETS;
+static GUID cx_guid = WSAID_CONNECTEX;
+static GUID dx_guid = WSAID_DISCONNECTEX;
 
 
 ngx_int_t ngx_os_init(ngx_log_t *log)
@@ -84,6 +90,7 @@ ngx_int_t ngx_os_init(ngx_log_t *log)
      *  Windows 2000         250000
      *  Windows XP           250100
      *  Windows 2003         250200
+     *  Windows Vista/2008   260000
      *
      *  Windows CE x.x       3xxxxx
      */
@@ -121,7 +128,10 @@ ngx_int_t ngx_os_init(ngx_log_t *log)
     /* STUB: ngx_uint_t max */
     ngx_max_wsabufs = 1024 * 1024;
 
-    /* get AcceptEx(), GetAcceptExSockAddrs() and TransmitFile() addresses */
+    /*
+     * get AcceptEx(), GetAcceptExSockAddrs(), TransmitFile(),
+     * TransmitPackets(), ConnectEx(), and DisconnectEx() addresses
+     */
 
     s = ngx_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
     if (s == -1) {
@@ -130,32 +140,63 @@ ngx_int_t ngx_os_init(ngx_log_t *log)
         return NGX_ERROR;
     }
 
-    if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &ae_guid, sizeof(GUID),
-                 &acceptex, sizeof(LPFN_ACCEPTEX), &bytes, NULL, NULL) == -1) {
-
-        ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
+    if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &ax_guid, sizeof(GUID),
+                 &ngx_acceptex, sizeof(LPFN_ACCEPTEX), &bytes, NULL, NULL)
+        == -1)
+    {
+        ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
                       "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
                                "WSAID_ACCEPTEX) failed");
-        return NGX_ERROR;
     }
 
     if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &as_guid, sizeof(GUID),
-                 &getacceptexsockaddrs, sizeof(LPFN_GETACCEPTEXSOCKADDRS),
-                 &bytes, NULL, NULL) == -1) {
-
-        ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
+                 &ngx_getacceptexsockaddrs, sizeof(LPFN_GETACCEPTEXSOCKADDRS),
+                 &bytes, NULL, NULL)
+        == -1)
+    {
+        ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
                       "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
-                               "WSAID_ACCEPTEX) failed");
-        return NGX_ERROR;
+                               "WSAID_GETACCEPTEXSOCKADDRS) failed");
     }
 
     if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &tf_guid, sizeof(GUID),
-                 &transmitfile, sizeof(LPFN_TRANSMITFILE), &bytes,
-                                                           NULL, NULL) == -1) {
-        ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
+                 &ngx_transmitfile, sizeof(LPFN_TRANSMITFILE), &bytes,
+                 NULL, NULL)
+        == -1)
+    {
+        ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
                       "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
                                "WSAID_TRANSMITFILE) failed");
-        return NGX_ERROR;
+    }
+
+    if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &tp_guid, sizeof(GUID),
+                 &ngx_transmitpackets, sizeof(LPFN_TRANSMITPACKETS), &bytes,
+                 NULL, NULL)
+        == -1)
+    {
+        ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
+                      "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
+                               "WSAID_TRANSMITPACKETS) failed");
+    }
+
+    if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &cx_guid, sizeof(GUID),
+                 &ngx_connectex, sizeof(LPFN_CONNECTEX), &bytes,
+                 NULL, NULL)
+        == -1)
+    {
+        ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
+                      "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
+                               "WSAID_CONNECTEX) failed");
+    }
+
+    if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &dx_guid, sizeof(GUID),
+                 &ngx_disconnectex, sizeof(LPFN_DISCONNECTEX), &bytes,
+                 NULL, NULL)
+        == -1)
+    {
+        ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
+                      "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
+                               "WSAID_DISCONNECTEX) failed");
     }
 
     if (ngx_close_socket(s) == -1) {