TransmitPackets(), ConnectEx(), and DisconnectEx()

This commit is contained in:
Igor Sysoev 2007-11-11 18:56:50 +00:00
parent 2afdfdcadb
commit 479c786e0d
3 changed files with 187 additions and 44 deletions

View File

@ -32,7 +32,8 @@ ngx_event_acceptex(ngx_event_t *rev)
/* SO_UPDATE_ACCEPT_CONTEXT is required for shutdown() to work */ /* SO_UPDATE_ACCEPT_CONTEXT is required for shutdown() to work */
if (setsockopt(c->fd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, 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, ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
"setsockopt(SO_UPDATE_ACCEPT_CONTEXT) failed for %V", "setsockopt(SO_UPDATE_ACCEPT_CONTEXT) failed for %V",
@ -41,7 +42,8 @@ ngx_event_acceptex(ngx_event_t *rev)
c->accept_context_updated = 1; c->accept_context_updated = 1;
} }
getacceptexsockaddrs(c->buffer->pos, c->listening->post_accept_buffer_size, ngx_getacceptexsockaddrs(c->buffer->pos,
c->listening->post_accept_buffer_size,
c->listening->socklen + 16, c->listening->socklen + 16,
c->listening->socklen + 16, c->listening->socklen + 16,
&c->local_sockaddr, &c->local_socklen, &c->local_sockaddr, &c->local_socklen,
@ -51,7 +53,6 @@ ngx_event_acceptex(ngx_event_t *rev)
c->buffer->last += rev->available; c->buffer->last += rev->available;
c->buffer->end = c->buffer->start c->buffer->end = c->buffer->start
+ c->listening->post_accept_buffer_size; + c->listening->post_accept_buffer_size;
} else { } else {
c->buffer = NULL; c->buffer = NULL;
} }
@ -178,11 +179,11 @@ ngx_event_post_acceptex(ngx_listening_t *ls, ngx_uint_t n)
return NGX_ERROR; return NGX_ERROR;
} }
if (acceptex(ls->fd, s, c->buffer->pos, ls->post_accept_buffer_size, if (ngx_acceptex(ls->fd, s, c->buffer->pos, ls->post_accept_buffer_size,
ls->socklen + 16, ls->socklen + 16, ls->socklen + 16, ls->socklen + 16,
&rcvd, (LPOVERLAPPED) &rev->ovlp) == 0) &rcvd, (LPOVERLAPPED) &rev->ovlp)
== 0)
{ {
err = ngx_socket_errno; err = ngx_socket_errno;
if (err != WSA_IO_PENDING) { if (err != WSA_IO_PENDING) {
ngx_log_error(NGX_LOG_ALERT, &ls->log, err, ngx_log_error(NGX_LOG_ALERT, &ls->log, err,

View File

@ -75,7 +75,25 @@ typedef VOID (PASCAL FAR * LPFN_GETACCEPTEXSOCKADDRS)(
#endif #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)( typedef BOOL (PASCAL FAR * LPFN_TRANSMITFILE)(
IN SOCKET hSocket, IN SOCKET hSocket,
@ -93,9 +111,92 @@ typedef BOOL (PASCAL FAR * LPFN_TRANSMITFILE)(
#endif #endif
extern LPFN_ACCEPTEX acceptex; #ifndef WSAID_TRANSMITPACKETS
extern LPFN_GETACCEPTEXSOCKADDRS getacceptexsockaddrs;
extern LPFN_TRANSMITFILE transmitfile; /* 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); int ngx_tcp_push(ngx_socket_t s);

View File

@ -39,13 +39,19 @@ static u_int osviex;
static OSVERSIONINFOEX osvi; static OSVERSIONINFOEX osvi;
/* Should these pointers be per protocol ? */ /* Should these pointers be per protocol ? */
LPFN_ACCEPTEX acceptex; LPFN_ACCEPTEX ngx_acceptex;
LPFN_GETACCEPTEXSOCKADDRS getacceptexsockaddrs; LPFN_GETACCEPTEXSOCKADDRS ngx_getacceptexsockaddrs;
LPFN_TRANSMITFILE transmitfile; 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 as_guid = WSAID_GETACCEPTEXSOCKADDRS;
static GUID tf_guid = WSAID_TRANSMITFILE; 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) 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 2000 250000
* Windows XP 250100 * Windows XP 250100
* Windows 2003 250200 * Windows 2003 250200
* Windows Vista/2008 260000
* *
* Windows CE x.x 3xxxxx * Windows CE x.x 3xxxxx
*/ */
@ -121,7 +128,10 @@ ngx_int_t ngx_os_init(ngx_log_t *log)
/* STUB: ngx_uint_t max */ /* STUB: ngx_uint_t max */
ngx_max_wsabufs = 1024 * 1024; 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); s = ngx_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (s == -1) { if (s == -1) {
@ -130,32 +140,63 @@ ngx_int_t ngx_os_init(ngx_log_t *log)
return NGX_ERROR; return NGX_ERROR;
} }
if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &ae_guid, sizeof(GUID), if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &ax_guid, sizeof(GUID),
&acceptex, sizeof(LPFN_ACCEPTEX), &bytes, NULL, NULL) == -1) { &ngx_acceptex, sizeof(LPFN_ACCEPTEX), &bytes, NULL, NULL)
== -1)
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, {
ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
"WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, " "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
"WSAID_ACCEPTEX) failed"); "WSAID_ACCEPTEX) failed");
return NGX_ERROR;
} }
if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &as_guid, sizeof(GUID), if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &as_guid, sizeof(GUID),
&getacceptexsockaddrs, sizeof(LPFN_GETACCEPTEXSOCKADDRS), &ngx_getacceptexsockaddrs, sizeof(LPFN_GETACCEPTEXSOCKADDRS),
&bytes, NULL, NULL) == -1) { &bytes, NULL, NULL)
== -1)
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, {
ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
"WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, " "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
"WSAID_ACCEPTEX) failed"); "WSAID_GETACCEPTEXSOCKADDRS) failed");
return NGX_ERROR;
} }
if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &tf_guid, sizeof(GUID), if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &tf_guid, sizeof(GUID),
&transmitfile, sizeof(LPFN_TRANSMITFILE), &bytes, &ngx_transmitfile, sizeof(LPFN_TRANSMITFILE), &bytes,
NULL, NULL) == -1) { NULL, NULL)
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, == -1)
{
ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
"WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, " "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
"WSAID_TRANSMITFILE) failed"); "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) { if (ngx_close_socket(s) == -1) {