summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2007-11-11 18:56:50 +0000
committerIgor Sysoev <igor@sysoev.ru>2007-11-11 18:56:50 +0000
commit479c786e0d5f1f2435f9756695df40e4430130b4 (patch)
tree5f9b6858b58adf88c5a2b4d31922985465745c5f
parent2afdfdcadbbe18cdcbf2e4288bcf1f729310117b (diff)
downloadnginx-479c786e0d5f1f2435f9756695df40e4430130b4.tar.gz
nginx-479c786e0d5f1f2435f9756695df40e4430130b4.tar.bz2
TransmitPackets(), ConnectEx(), and DisconnectEx()
-rw-r--r--src/event/ngx_event_acceptex.c25
-rw-r--r--src/os/win32/ngx_socket.h125
-rw-r--r--src/os/win32/ngx_win32_init.c83
3 files changed, 188 insertions, 45 deletions
diff --git a/src/event/ngx_event_acceptex.c b/src/event/ngx_event_acceptex.c
index c51021a6b..264454454 100644
--- 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 *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,
diff --git a/src/os/win32/ngx_socket.h b/src/os/win32/ngx_socket.h
index 95ecbe8cd..1027a81a0 100644
--- 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_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
+
+
+#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 acceptex;
-extern LPFN_GETACCEPTEXSOCKADDRS getacceptexsockaddrs;
-extern LPFN_TRANSMITFILE transmitfile;
+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
index 9c233c7b3..4437d338d 100644
--- 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;
-
-static GUID ae_guid = WSAID_ACCEPTEX;
+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 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) {