Mercurial > hg > nginx-quic
view src/os/win32/ngx_socket.h @ 8039:09fb2135a589
SSL: fixed shutdown handling.
Previously, bidirectional shutdown never worked, due to two issues
in the code:
1. The code only tested SSL_ERROR_WANT_READ and SSL_ERROR_WANT_WRITE
when there was an error in the error queue, which cannot happen.
The bug was introduced in an attempt to fix unexpected error logging
as reported with OpenSSL 0.9.8g
(http://mailman.nginx.org/pipermail/nginx/2008-January/003084.html).
2. The code never called SSL_shutdown() for the second time to wait for
the peer's close_notify alert.
This change fixes both issues.
Note that after this change bidirectional shutdown is expected to work for
the first time, so c->ssl->no_wait_shutdown now makes a difference. This
is not a problem for HTTP code which always uses c->ssl->no_wait_shutdown,
but might be a problem for stream and mail code, as well as 3rd party
modules.
To minimize the effect of the change, the timeout, which was used to be 30
seconds and not configurable, though never actually used, is now set to
3 seconds. It is also expanded to apply to both SSL_ERROR_WANT_READ and
SSL_ERROR_WANT_WRITE, so timeout is properly set if writing to the socket
buffer is not possible.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 10 Aug 2020 18:52:09 +0300 |
parents | efd71d49bde0 |
children | 96bdda15413a |
line wrap: on
line source
/* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */ #ifndef _NGX_SOCKET_H_INCLUDED_ #define _NGX_SOCKET_H_INCLUDED_ #include <ngx_config.h> #include <ngx_core.h> #define NGX_WRITE_SHUTDOWN SD_SEND typedef SOCKET ngx_socket_t; typedef int socklen_t; #define ngx_socket(af, type, proto) \ WSASocketW(af, type, proto, NULL, 0, WSA_FLAG_OVERLAPPED) #define ngx_socket_n "WSASocketW()" int ngx_nonblocking(ngx_socket_t s); int ngx_blocking(ngx_socket_t s); #define ngx_nonblocking_n "ioctlsocket(FIONBIO)" #define ngx_blocking_n "ioctlsocket(!FIONBIO)" int ngx_socket_nread(ngx_socket_t s, int *n); #define ngx_socket_nread_n "ioctlsocket(FIONREAD)" #define ngx_shutdown_socket shutdown #define ngx_shutdown_socket_n "shutdown()" #define ngx_close_socket closesocket #define ngx_close_socket_n "closesocket()" #ifndef WSAID_ACCEPTEX typedef BOOL (PASCAL FAR * LPFN_ACCEPTEX)( IN SOCKET sListenSocket, IN SOCKET sAcceptSocket, IN PVOID lpOutputBuffer, IN DWORD dwReceiveDataLength, IN DWORD dwLocalAddressLength, IN DWORD dwRemoteAddressLength, OUT LPDWORD lpdwBytesReceived, IN LPOVERLAPPED lpOverlapped ); #define WSAID_ACCEPTEX \ {0xb5367df1,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}} #endif #ifndef WSAID_GETACCEPTEXSOCKADDRS typedef VOID (PASCAL FAR * LPFN_GETACCEPTEXSOCKADDRS)( IN PVOID lpOutputBuffer, IN DWORD dwReceiveDataLength, IN DWORD dwLocalAddressLength, IN DWORD dwRemoteAddressLength, OUT struct sockaddr **LocalSockaddr, OUT LPINT LocalSockaddrLength, OUT struct sockaddr **RemoteSockaddr, OUT LPINT RemoteSockaddrLength ); #define WSAID_GETACCEPTEXSOCKADDRS \ {0xb5367df2,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}} #endif #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, IN HANDLE hFile, IN DWORD nNumberOfBytesToWrite, IN DWORD nNumberOfBytesPerSend, IN LPOVERLAPPED lpOverlapped, IN LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers, IN DWORD dwReserved ); #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 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; #if (NGX_HAVE_POLL && !defined POLLIN) /* * WSAPoll() is only available if _WIN32_WINNT >= 0x0600. * If it is not available during compilation, we try to * load it dynamically at runtime. */ #define NGX_LOAD_WSAPOLL 1 #define POLLRDNORM 0x0100 #define POLLRDBAND 0x0200 #define POLLIN (POLLRDNORM | POLLRDBAND) #define POLLPRI 0x0400 #define POLLWRNORM 0x0010 #define POLLOUT (POLLWRNORM) #define POLLWRBAND 0x0020 #define POLLERR 0x0001 #define POLLHUP 0x0002 #define POLLNVAL 0x0004 typedef struct pollfd { SOCKET fd; SHORT events; SHORT revents; } WSAPOLLFD, *PWSAPOLLFD, FAR *LPWSAPOLLFD; typedef int (WSAAPI *ngx_wsapoll_pt)( LPWSAPOLLFD fdArray, ULONG fds, INT timeout ); extern ngx_wsapoll_pt WSAPoll; extern ngx_uint_t ngx_have_wsapoll; #endif int ngx_tcp_push(ngx_socket_t s); #define ngx_tcp_push_n "tcp_push()" #endif /* _NGX_SOCKET_H_INCLUDED_ */