# HG changeset patch # User Igor Sysoev # Date 1194807410 0 # Node ID 74b2a52bc3c99b63c60784223d396352abfeec38 # Parent 2142e5cf62da1bf0fc234e6156a4fba6f2b93a90 TransmitPackets(), ConnectEx(), and DisconnectEx() diff --git a/src/event/ngx_event_acceptex.c b/src/event/ngx_event_acceptex.c --- 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, diff --git a/src/os/win32/ngx_socket.h b/src/os/win32/ngx_socket.h --- 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_ */ diff --git a/src/os/win32/ngx_win32_init.c b/src/os/win32/ngx_win32_init.c --- 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) {