mirror of
https://github.com/nginx/nginx.git
synced 2025-06-07 01:12:40 +08:00
TransmitPackets(), ConnectEx(), and DisconnectEx()
This commit is contained in:
parent
2afdfdcadb
commit
479c786e0d
@ -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 *ls, ngx_uint_t n)
|
||||
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,
|
||||
|
@ -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_GETACCEPTEXSOCKADDRS)(
|
||||
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_TRANSMITFILE)(
|
||||
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_ */
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user