1/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to
5 * deal in the Software without restriction, including without limitation the
6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 * sell copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 * IN THE SOFTWARE.
20 */
21
22#ifndef UV_WIN_WINSOCK_H_
23#define UV_WIN_WINSOCK_H_
24
25#include <winsock2.h>
26#include <iptypes.h>
27#include <mswsock.h>
28#include <ws2tcpip.h>
29#include <windows.h>
30
31#include "winapi.h"
32
33
34/*
35 * MinGW is missing these too
36 */
37#ifndef SO_UPDATE_CONNECT_CONTEXT
38# define SO_UPDATE_CONNECT_CONTEXT 0x7010
39#endif
40
41#ifndef TCP_KEEPALIVE
42# define TCP_KEEPALIVE 3
43#endif
44
45#ifndef IPV6_V6ONLY
46# define IPV6_V6ONLY 27
47#endif
48
49#ifndef IPV6_HOPLIMIT
50# define IPV6_HOPLIMIT 21
51#endif
52
53#ifndef SIO_BASE_HANDLE
54# define SIO_BASE_HANDLE 0x48000022
55#endif
56
57#ifndef MCAST_JOIN_SOURCE_GROUP
58# define MCAST_JOIN_SOURCE_GROUP 45
59#endif
60
61#ifndef MCAST_LEAVE_SOURCE_GROUP
62# define MCAST_LEAVE_SOURCE_GROUP 46
63#endif
64
65/*
66 * TDI defines that are only in the DDK.
67 * We only need receive flags so far.
68 */
69#ifndef TDI_RECEIVE_NORMAL
70  #define TDI_RECEIVE_BROADCAST           0x00000004
71  #define TDI_RECEIVE_MULTICAST           0x00000008
72  #define TDI_RECEIVE_PARTIAL             0x00000010
73  #define TDI_RECEIVE_NORMAL              0x00000020
74  #define TDI_RECEIVE_EXPEDITED           0x00000040
75  #define TDI_RECEIVE_PEEK                0x00000080
76  #define TDI_RECEIVE_NO_RESPONSE_EXP     0x00000100
77  #define TDI_RECEIVE_COPY_LOOKAHEAD      0x00000200
78  #define TDI_RECEIVE_ENTIRE_MESSAGE      0x00000400
79  #define TDI_RECEIVE_AT_DISPATCH_LEVEL   0x00000800
80  #define TDI_RECEIVE_CONTROL_INFO        0x00001000
81  #define TDI_RECEIVE_FORCE_INDICATION    0x00002000
82  #define TDI_RECEIVE_NO_PUSH             0x00004000
83#endif
84
85/*
86 * The "Auxiliary Function Driver" is the windows kernel-mode driver that does
87 * TCP, UDP etc. Winsock is just a layer that dispatches requests to it.
88 * Having these definitions allows us to bypass winsock and make an AFD kernel
89 * call directly, avoiding a bug in winsock's recvfrom implementation.
90 */
91
92#define AFD_NO_FAST_IO   0x00000001
93#define AFD_OVERLAPPED   0x00000002
94#define AFD_IMMEDIATE    0x00000004
95
96#define AFD_POLL_RECEIVE_BIT            0
97#define AFD_POLL_RECEIVE                (1 << AFD_POLL_RECEIVE_BIT)
98#define AFD_POLL_RECEIVE_EXPEDITED_BIT  1
99#define AFD_POLL_RECEIVE_EXPEDITED      (1 << AFD_POLL_RECEIVE_EXPEDITED_BIT)
100#define AFD_POLL_SEND_BIT               2
101#define AFD_POLL_SEND                   (1 << AFD_POLL_SEND_BIT)
102#define AFD_POLL_DISCONNECT_BIT         3
103#define AFD_POLL_DISCONNECT             (1 << AFD_POLL_DISCONNECT_BIT)
104#define AFD_POLL_ABORT_BIT              4
105#define AFD_POLL_ABORT                  (1 << AFD_POLL_ABORT_BIT)
106#define AFD_POLL_LOCAL_CLOSE_BIT        5
107#define AFD_POLL_LOCAL_CLOSE            (1 << AFD_POLL_LOCAL_CLOSE_BIT)
108#define AFD_POLL_CONNECT_BIT            6
109#define AFD_POLL_CONNECT                (1 << AFD_POLL_CONNECT_BIT)
110#define AFD_POLL_ACCEPT_BIT             7
111#define AFD_POLL_ACCEPT                 (1 << AFD_POLL_ACCEPT_BIT)
112#define AFD_POLL_CONNECT_FAIL_BIT       8
113#define AFD_POLL_CONNECT_FAIL           (1 << AFD_POLL_CONNECT_FAIL_BIT)
114#define AFD_POLL_QOS_BIT                9
115#define AFD_POLL_QOS                    (1 << AFD_POLL_QOS_BIT)
116#define AFD_POLL_GROUP_QOS_BIT          10
117#define AFD_POLL_GROUP_QOS              (1 << AFD_POLL_GROUP_QOS_BIT)
118
119#define AFD_NUM_POLL_EVENTS             11
120#define AFD_POLL_ALL                    ((1 << AFD_NUM_POLL_EVENTS) - 1)
121
122typedef struct _AFD_RECV_DATAGRAM_INFO {
123    LPWSABUF BufferArray;
124    ULONG BufferCount;
125    ULONG AfdFlags;
126    ULONG TdiFlags;
127    struct sockaddr* Address;
128    int* AddressLength;
129} AFD_RECV_DATAGRAM_INFO, *PAFD_RECV_DATAGRAM_INFO;
130
131typedef struct _AFD_RECV_INFO {
132    LPWSABUF BufferArray;
133    ULONG BufferCount;
134    ULONG AfdFlags;
135    ULONG TdiFlags;
136} AFD_RECV_INFO, *PAFD_RECV_INFO;
137
138
139#define _AFD_CONTROL_CODE(operation, method) \
140    ((FSCTL_AFD_BASE) << 12 | (operation << 2) | method)
141
142#define FSCTL_AFD_BASE FILE_DEVICE_NETWORK
143
144#define AFD_RECEIVE            5
145#define AFD_RECEIVE_DATAGRAM   6
146#define AFD_POLL               9
147
148#define IOCTL_AFD_RECEIVE \
149    _AFD_CONTROL_CODE(AFD_RECEIVE, METHOD_NEITHER)
150
151#define IOCTL_AFD_RECEIVE_DATAGRAM \
152    _AFD_CONTROL_CODE(AFD_RECEIVE_DATAGRAM, METHOD_NEITHER)
153
154#define IOCTL_AFD_POLL \
155    _AFD_CONTROL_CODE(AFD_POLL, METHOD_BUFFERED)
156
157#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
158typedef struct _IP_ADAPTER_UNICAST_ADDRESS_XP {
159  /* FIXME: __C89_NAMELESS was removed */
160  /* __C89_NAMELESS */ union {
161    ULONGLONG Alignment;
162    /* __C89_NAMELESS */ struct {
163      ULONG Length;
164      DWORD Flags;
165    };
166  };
167  struct _IP_ADAPTER_UNICAST_ADDRESS_XP *Next;
168  SOCKET_ADDRESS Address;
169  IP_PREFIX_ORIGIN PrefixOrigin;
170  IP_SUFFIX_ORIGIN SuffixOrigin;
171  IP_DAD_STATE DadState;
172  ULONG ValidLifetime;
173  ULONG PreferredLifetime;
174  ULONG LeaseLifetime;
175} IP_ADAPTER_UNICAST_ADDRESS_XP,*PIP_ADAPTER_UNICAST_ADDRESS_XP;
176
177typedef struct _IP_ADAPTER_UNICAST_ADDRESS_LH {
178  union {
179    ULONGLONG Alignment;
180    struct {
181      ULONG Length;
182      DWORD Flags;
183    };
184  };
185  struct _IP_ADAPTER_UNICAST_ADDRESS_LH *Next;
186  SOCKET_ADDRESS Address;
187  IP_PREFIX_ORIGIN PrefixOrigin;
188  IP_SUFFIX_ORIGIN SuffixOrigin;
189  IP_DAD_STATE DadState;
190  ULONG ValidLifetime;
191  ULONG PreferredLifetime;
192  ULONG LeaseLifetime;
193  UINT8 OnLinkPrefixLength;
194} IP_ADAPTER_UNICAST_ADDRESS_LH,*PIP_ADAPTER_UNICAST_ADDRESS_LH;
195
196#endif
197
198int uv__convert_to_localhost_if_unspecified(const struct sockaddr* addr,
199                                            struct sockaddr_storage* storage);
200
201#endif /* UV_WIN_WINSOCK_H_ */
202