Klaus Demo nginx / 479c786
TransmitPackets(), ConnectEx(), and DisconnectEx() Igor Sysoev 14 years ago
3 changed file(s) with 193 addition(s) and 50 deletion(s). Raw diff Collapse all Expand all
3131 /* SO_UPDATE_ACCEPT_CONTEXT is required for shutdown() to work */
3232
3333 if (setsockopt(c->fd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
34 (char *) &c->listening->fd, sizeof(ngx_socket_t)) == -1)
34 (char *) &c->listening->fd, sizeof(ngx_socket_t))
35 == -1)
3536 {
3637 ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
3738 "setsockopt(SO_UPDATE_ACCEPT_CONTEXT) failed for %V",
4041 c->accept_context_updated = 1;
4142 }
4243
43 getacceptexsockaddrs(c->buffer->pos, c->listening->post_accept_buffer_size,
44 c->listening->socklen + 16,
45 c->listening->socklen + 16,
46 &c->local_sockaddr, &c->local_socklen,
47 &c->sockaddr, &c->socklen);
44 ngx_getacceptexsockaddrs(c->buffer->pos,
45 c->listening->post_accept_buffer_size,
46 c->listening->socklen + 16,
47 c->listening->socklen + 16,
48 &c->local_sockaddr, &c->local_socklen,
49 &c->sockaddr, &c->socklen);
4850
4951 if (c->listening->post_accept_buffer_size) {
5052 c->buffer->last += rev->available;
5153 c->buffer->end = c->buffer->start
52 + c->listening->post_accept_buffer_size;
53
54 + c->listening->post_accept_buffer_size;
5455 } else {
5556 c->buffer = NULL;
5657 }
177178 return NGX_ERROR;
178179 }
179180
180 if (acceptex(ls->fd, s, c->buffer->pos, ls->post_accept_buffer_size,
181 ls->socklen + 16, ls->socklen + 16,
182 &rcvd, (LPOVERLAPPED) &rev->ovlp) == 0)
181 if (ngx_acceptex(ls->fd, s, c->buffer->pos, ls->post_accept_buffer_size,
182 ls->socklen + 16, ls->socklen + 16,
183 &rcvd, (LPOVERLAPPED) &rev->ovlp)
184 == 0)
183185 {
184
185186 err = ngx_socket_errno;
186187 if (err != WSA_IO_PENDING) {
187188 ngx_log_error(NGX_LOG_ALERT, &ls->log, err,
1818 typedef int socklen_t;
1919
2020
21 #define ngx_socket(af, type, proto) \
22 WSASocket(af, type, proto, NULL, 0, WSA_FLAG_OVERLAPPED)
21 #define ngx_socket(af, type, proto) \
22 WSASocket(af, type, proto, NULL, 0, WSA_FLAG_OVERLAPPED)
2323
2424 #define ngx_socket_n "WSASocket()"
2525
4949 IN LPOVERLAPPED lpOverlapped
5050 );
5151
52 #define WSAID_ACCEPTEX \
53 {0xb5367df1,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
52 #define WSAID_ACCEPTEX \
53 {0xb5367df1,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
5454
5555 #endif
5656
6868 OUT LPINT RemoteSockaddrLength
6969 );
7070
71 #define WSAID_GETACCEPTEXSOCKADDRS \
71 #define WSAID_GETACCEPTEXSOCKADDRS \
7272 {0xb5367df2,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
7373
7474 #endif
7575
7676
77 #ifndef LPFN_TRANSMITFILE
77 #ifndef WSAID_TRANSMITFILE
78
79 #ifndef TF_DISCONNECT
80
81 #define TF_DISCONNECT 1
82 #define TF_REUSE_SOCKET 2
83 #define TF_WRITE_BEHIND 4
84 #define TF_USE_DEFAULT_WORKER 0
85 #define TF_USE_SYSTEM_THREAD 16
86 #define TF_USE_KERNEL_APC 32
87
88 typedef struct _TRANSMIT_FILE_BUFFERS {
89 LPVOID Head;
90 DWORD HeadLength;
91 LPVOID Tail;
92 DWORD TailLength;
93 } TRANSMIT_FILE_BUFFERS, *PTRANSMIT_FILE_BUFFERS, FAR *LPTRANSMIT_FILE_BUFFERS;
94
95 #endif
7896
7997 typedef BOOL (PASCAL FAR * LPFN_TRANSMITFILE)(
8098 IN SOCKET hSocket,
86104 IN DWORD dwReserved
87105 );
88106
89 #define WSAID_TRANSMITFILE \
90 {0xb5367df0,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
91
92 #endif
93
94
95 extern LPFN_ACCEPTEX acceptex;
96 extern LPFN_GETACCEPTEXSOCKADDRS getacceptexsockaddrs;
97 extern LPFN_TRANSMITFILE transmitfile;
107 #define WSAID_TRANSMITFILE \
108 {0xb5367df0,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
109
110 #endif
111
112
113 #ifndef WSAID_TRANSMITPACKETS
114
115 /* OpenWatcom has a swapped TP_ELEMENT_FILE and TP_ELEMENT_MEMORY definition */
116
117 #ifndef TP_ELEMENT_FILE
118
119 #ifdef _MSC_VER
120 #pragma warning(disable:4201) /* Nonstandard extension, nameless struct/union */
121 #endif
122
123 typedef struct _TRANSMIT_PACKETS_ELEMENT {
124 ULONG dwElFlags;
125 #define TP_ELEMENT_MEMORY 1
126 #define TP_ELEMENT_FILE 2
127 #define TP_ELEMENT_EOP 4
128 ULONG cLength;
129 union {
130 struct {
131 LARGE_INTEGER nFileOffset;
132 HANDLE hFile;
133 };
134 PVOID pBuffer;
135 };
136 } TRANSMIT_PACKETS_ELEMENT, *PTRANSMIT_PACKETS_ELEMENT,
137 FAR *LPTRANSMIT_PACKETS_ELEMENT;
138
139 #ifdef _MSC_VER
140 #pragma warning(default:4201)
141 #endif
142
143 #endif
144
145 typedef BOOL (PASCAL FAR * LPFN_TRANSMITPACKETS) (
146 SOCKET hSocket,
147 TRANSMIT_PACKETS_ELEMENT *lpPacketArray,
148 DWORD nElementCount,
149 DWORD nSendSize,
150 LPOVERLAPPED lpOverlapped,
151 DWORD dwFlags
152 );
153
154 #define WSAID_TRANSMITPACKETS \
155 {0xd9689da0,0x1f90,0x11d3,{0x99,0x71,0x00,0xc0,0x4f,0x68,0xc8,0x76}}
156
157 #endif
158
159
160 #ifndef WSAID_CONNECTEX
161
162 typedef BOOL (PASCAL FAR * LPFN_CONNECTEX) (
163 IN SOCKET s,
164 IN const struct sockaddr FAR *name,
165 IN int namelen,
166 IN PVOID lpSendBuffer OPTIONAL,
167 IN DWORD dwSendDataLength,
168 OUT LPDWORD lpdwBytesSent,
169 IN LPOVERLAPPED lpOverlapped
170 );
171
172 #define WSAID_CONNECTEX \
173 {0x25a207b9,0xddf3,0x4660,{0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e}}
174
175 #endif
176
177
178 #ifndef WSAID_DISCONNECTEX
179
180 typedef BOOL (PASCAL FAR * LPFN_DISCONNECTEX) (
181 IN SOCKET s,
182 IN LPOVERLAPPED lpOverlapped,
183 IN DWORD dwFlags,
184 IN DWORD dwReserved
185 );
186
187 #define WSAID_DISCONNECTEX \
188 {0x7fda2e11,0x8630,0x436f,{0xa0,0x31,0xf5,0x36,0xa6,0xee,0xc1,0x57}}
189
190 #endif
191
192
193 extern LPFN_ACCEPTEX ngx_acceptex;
194 extern LPFN_GETACCEPTEXSOCKADDRS ngx_getacceptexsockaddrs;
195 extern LPFN_TRANSMITFILE ngx_transmitfile;
196 extern LPFN_TRANSMITPACKETS ngx_transmitpackets;
197 extern LPFN_CONNECTEX ngx_connectex;
198 extern LPFN_DISCONNECTEX ngx_disconnectex;
98199
99200
100201 int ngx_tcp_push(ngx_socket_t s);
101 #define ngx_tcp_push_n "tcp_push()"
202 #define ngx_tcp_push_n "tcp_push()"
102203
103204
104205 #endif /* _NGX_SOCKET_H_INCLUDED_ */
3838 static OSVERSIONINFOEX osvi;
3939
4040 /* Should these pointers be per protocol ? */
41 LPFN_ACCEPTEX acceptex;
42 LPFN_GETACCEPTEXSOCKADDRS getacceptexsockaddrs;
43 LPFN_TRANSMITFILE transmitfile;
44
45 static GUID ae_guid = WSAID_ACCEPTEX;
41 LPFN_ACCEPTEX ngx_acceptex;
42 LPFN_GETACCEPTEXSOCKADDRS ngx_getacceptexsockaddrs;
43 LPFN_TRANSMITFILE ngx_transmitfile;
44 LPFN_TRANSMITPACKETS ngx_transmitpackets;
45 LPFN_CONNECTEX ngx_connectex;
46 LPFN_DISCONNECTEX ngx_disconnectex;
47
48 static GUID ax_guid = WSAID_ACCEPTEX;
4649 static GUID as_guid = WSAID_GETACCEPTEXSOCKADDRS;
4750 static GUID tf_guid = WSAID_TRANSMITFILE;
51 static GUID tp_guid = WSAID_TRANSMITPACKETS;
52 static GUID cx_guid = WSAID_CONNECTEX;
53 static GUID dx_guid = WSAID_DISCONNECTEX;
4854
4955
5056 ngx_int_t ngx_os_init(ngx_log_t *log)
8389 * Windows 2000 250000
8490 * Windows XP 250100
8591 * Windows 2003 250200
92 * Windows Vista/2008 260000
8693 *
8794 * Windows CE x.x 3xxxxx
8895 */
120127 /* STUB: ngx_uint_t max */
121128 ngx_max_wsabufs = 1024 * 1024;
122129
123 /* get AcceptEx(), GetAcceptExSockAddrs() and TransmitFile() addresses */
130 /*
131 * get AcceptEx(), GetAcceptExSockAddrs(), TransmitFile(),
132 * TransmitPackets(), ConnectEx(), and DisconnectEx() addresses
133 */
124134
125135 s = ngx_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
126136 if (s == -1) {
129139 return NGX_ERROR;
130140 }
131141
132 if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &ae_guid, sizeof(GUID),
133 &acceptex, sizeof(LPFN_ACCEPTEX), &bytes, NULL, NULL) == -1) {
134
135 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
142 if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &ax_guid, sizeof(GUID),
143 &ngx_acceptex, sizeof(LPFN_ACCEPTEX), &bytes, NULL, NULL)
144 == -1)
145 {
146 ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
136147 "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
137148 "WSAID_ACCEPTEX) failed");
138 return NGX_ERROR;
139149 }
140150
141151 if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &as_guid, sizeof(GUID),
142 &getacceptexsockaddrs, sizeof(LPFN_GETACCEPTEXSOCKADDRS),
143 &bytes, NULL, NULL) == -1) {
144
145 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
146 "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
147 "WSAID_ACCEPTEX) failed");
148 return NGX_ERROR;
152 &ngx_getacceptexsockaddrs, sizeof(LPFN_GETACCEPTEXSOCKADDRS),
153 &bytes, NULL, NULL)
154 == -1)
155 {
156 ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
157 "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
158 "WSAID_GETACCEPTEXSOCKADDRS) failed");
149159 }
150160
151161 if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &tf_guid, sizeof(GUID),
152 &transmitfile, sizeof(LPFN_TRANSMITFILE), &bytes,
153 NULL, NULL) == -1) {
154 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
162 &ngx_transmitfile, sizeof(LPFN_TRANSMITFILE), &bytes,
163 NULL, NULL)
164 == -1)
165 {
166 ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
155167 "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
156168 "WSAID_TRANSMITFILE) failed");
157 return NGX_ERROR;
169 }
170
171 if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &tp_guid, sizeof(GUID),
172 &ngx_transmitpackets, sizeof(LPFN_TRANSMITPACKETS), &bytes,
173 NULL, NULL)
174 == -1)
175 {
176 ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
177 "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
178 "WSAID_TRANSMITPACKETS) failed");
179 }
180
181 if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &cx_guid, sizeof(GUID),
182 &ngx_connectex, sizeof(LPFN_CONNECTEX), &bytes,
183 NULL, NULL)
184 == -1)
185 {
186 ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
187 "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
188 "WSAID_CONNECTEX) failed");
189 }
190
191 if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &dx_guid, sizeof(GUID),
192 &ngx_disconnectex, sizeof(LPFN_DISCONNECTEX), &bytes,
193 NULL, NULL)
194 == -1)
195 {
196 ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
197 "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
198 "WSAID_DISCONNECTEX) failed");
158199 }
159200
160201 if (ngx_close_socket(s) == -1) {