Annotation of embedaddon/strongswan/src/libcharon/plugins/socket_win/socket_win_socket.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2013 Martin Willi
3: * Copyright (C) 2013 revosec AG
4: *
5: * This program is free software; you can redistribute it and/or modify it
6: * under the terms of the GNU General Public License as published by the
7: * Free Software Foundation; either version 2 of the License, or (at your
8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9: *
10: * This program is distributed in the hope that it will be useful, but
11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13: * for more details.
14: */
15:
16: /* for WSAID_WSASENDMSG, Windows 7 */
17: #define _WIN32_WINNT 0x0601
18:
19: #include "socket_win_socket.h"
20:
21: #include <library.h>
22: #include <threading/thread.h>
23: #include <daemon.h>
24:
25: #include <mswsock.h>
26:
27: /* number of sockets in use */
28: #define SOCKET_COUNT 2
29:
30: /* missing on MinGW */
31: #ifndef IPV6_V6ONLY
32: # define IPV6_V6ONLY 27
33: #endif
34:
35: /* GUIDS to lookup WSASend/RecvMsg */
36: static GUID WSARecvMsgGUID = WSAID_WSARECVMSG;
37: static GUID WSASendMsgGUID = WSAID_WSASENDMSG;
38:
39: typedef struct private_socket_win_socket_t private_socket_win_socket_t;
40:
41: /**
42: * Private data of an socket_t object
43: */
44: struct private_socket_win_socket_t {
45:
46: /**
47: * public functions
48: */
49: socket_win_socket_t public;
50:
51: /**
52: * Port for each socket
53: */
54: uint16_t ports[SOCKET_COUNT];
55:
56: /**
57: * IPv4/IPv6 dual-use sockets
58: */
59: SOCKET socks[SOCKET_COUNT];
60:
61: /**
62: * Events to wait for socket data
63: */
64: HANDLE events[SOCKET_COUNT];
65:
66: /**
67: * Maximum packet size to receive
68: */
69: int max_packet;
70:
71: /**
72: * WSASendMsg function
73: */
74: int WINAPI (*WSASendMsg)(SOCKET, LPWSAMSG, DWORD, LPDWORD,
75: LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE);
76:
77: /**
78: * WSARecvMsg function
79: */
80: int WINAPI (*WSARecvMsg)(SOCKET, LPWSAMSG, LPDWORD,
81: LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE);
82: };
83:
84: METHOD(socket_t, receiver, status_t,
85: private_socket_win_socket_t *this, packet_t **out)
86: {
87: char buf[this->max_packet], cbuf[128];
88: bool old;
89: DWORD i, len, err;
90: WSAMSG msg;
91: WSABUF data;
92: WSACMSGHDR *cmsg;
93: SOCKADDR_IN6 addr;
94: host_t *src = NULL, *dst = NULL;
95: packet_t *pkt;
96:
97: data.buf = buf;
98: data.len = sizeof(buf);
99:
100: memset(&msg, 0, sizeof(msg));
101: msg.name = (struct sockaddr*)&addr;
102: msg.namelen = sizeof(addr);
103: msg.lpBuffers = &data;
104: msg.dwBufferCount = 1;
105: msg.Control.buf = cbuf;
106: msg.Control.len = sizeof(cbuf);
107:
108: /* wait for socket events */
109: old = thread_cancelability(TRUE);
110: i = WSAWaitForMultipleEvents(SOCKET_COUNT, this->events,
111: FALSE, INFINITE, TRUE);
112: thread_cancelability(old);
113: if (i < WSA_WAIT_EVENT_0 || i >= WSA_WAIT_EVENT_0 + SOCKET_COUNT)
114: {
115: DBG1(DBG_NET, "waiting on sockets failed: %d", WSAGetLastError());
116: return FAILED;
117: }
118: i -= WSA_WAIT_EVENT_0;
119:
120: /* WSAEvents must be reset manually */
121: WSAResetEvent(this->events[i]);
122:
123: if (this->WSARecvMsg(this->socks[i], &msg, &len,
124: NULL, NULL) == SOCKET_ERROR)
125: {
126: err = WSAGetLastError();
127: /* ignore WSAECONNRESET; this is returned for any ICMP port unreachable,
128: * for a packet we sent, but is most likely not related to the packet
129: * we try to receive. */
130: if (err != WSAECONNRESET)
131: {
132: DBG1(DBG_NET, "reading from socket failed: %d", WSAGetLastError());
133: }
134: return FAILED;
135: }
136:
137: DBG3(DBG_NET, "received packet %b", buf, (int)len);
138:
139: for (cmsg = WSA_CMSG_FIRSTHDR(&msg); dst == NULL && cmsg != NULL;
140: cmsg = WSA_CMSG_NXTHDR(&msg, cmsg))
141: {
142: if (cmsg->cmsg_level == IPPROTO_IP &&
143: cmsg->cmsg_type == IP_PKTINFO)
144: {
145: struct in_pktinfo *pktinfo;
146: struct sockaddr_in sin = {
147: .sin_family = AF_INET,
148: };
149:
150: pktinfo = (struct in_pktinfo*)WSA_CMSG_DATA(cmsg);
151: sin.sin_addr = pktinfo->ipi_addr;
152: sin.sin_port = htons(this->ports[i]);
153: dst = host_create_from_sockaddr((struct sockaddr*)&sin);
154: }
155: if (cmsg->cmsg_level == IPPROTO_IPV6 &&
156: cmsg->cmsg_type == IPV6_PKTINFO)
157: {
158: struct in6_pktinfo *pktinfo;
159: struct sockaddr_in6 sin = {
160: .sin6_family = AF_INET6,
161: };
162:
163: pktinfo = (struct in6_pktinfo*)WSA_CMSG_DATA(cmsg);
164: sin.sin6_addr = pktinfo->ipi6_addr;
165: sin.sin6_port = htons(this->ports[i]);
166: dst = host_create_from_sockaddr((struct sockaddr*)&sin);
167: }
168: }
169:
170: if (!dst)
171: {
172: DBG1(DBG_NET, "receiving IP destination address failed");
173: return FAILED;
174: }
175:
176: switch (dst->get_family(dst))
177: {
178: case AF_INET6:
179: src = host_create_from_sockaddr((struct sockaddr*)&addr);
180: break;
181: case AF_INET:
182: /* extract v4 address from mapped v6 */
183: src = host_create_from_chunk(AF_INET,
184: chunk_create(addr.sin6_addr.u.Byte + 12, 4),
185: ntohs(addr.sin6_port));
186: break;
187: }
188: if (!src)
189: {
190: DBG1(DBG_NET, "receiving IP source address failed");
191: dst->destroy(dst);
192: return FAILED;
193: }
194:
195: pkt = packet_create();
196: pkt->set_source(pkt, src);
197: pkt->set_destination(pkt, dst);
198: DBG2(DBG_NET, "received packet: from %#H to %#H", src, dst);
199: pkt->set_data(pkt, chunk_clone(chunk_create(buf, len)));
200:
201: *out = pkt;
202: return SUCCESS;
203: }
204:
205: METHOD(socket_t, sender, status_t,
206: private_socket_win_socket_t *this, packet_t *packet)
207: {
208: uint16_t port;
209: int i = -1, j;
210: host_t *src, *dst;
211: WSAMSG msg;
212: DWORD len;
213: WSABUF data;
214: WSACMSGHDR *cmsg;
215: SOCKADDR_IN6 addr = {
216: .sin6_family = AF_INET6,
217: .sin6_addr = {
218: .u = {
219: .Byte = {
220: /* v6-mapped-v4 by default */
221: 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
222: 0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,
223: },
224: },
225: },
226: };
227: char buf[WSA_CMSG_SPACE(max(sizeof(struct in6_pktinfo),
228: sizeof(struct in_pktinfo)))];
229:
230: src = packet->get_source(packet);
231: dst = packet->get_destination(packet);
232: data.len = packet->get_data(packet).len;
233: data.buf = packet->get_data(packet).ptr;
234:
235: DBG2(DBG_NET, "sending packet: from %#H to %#H", src, dst);
236:
237: DBG3(DBG_NET, "sending packet %b", data.buf, (int)data.len);
238:
239: port = src->get_port(src);
240: for (j = 0; j < SOCKET_COUNT; j++)
241: {
242: if (!port || this->ports[j] == port)
243: {
244: i = j;
245: break;
246: }
247: }
248: if (i == -1)
249: {
250: DBG1(DBG_NET, "no socket found to send packet from port %u", port);
251: return FAILED;
252: }
253:
254: /* copy destination IPv6, or last 32 bits of mapped IPv4 address */
255: len = dst->get_address(dst).len;
256: if (len > sizeof(addr.sin6_addr))
257: {
258: return FAILED;
259: }
260: memcpy(addr.sin6_addr.u.Byte + sizeof(addr.sin6_addr) - len,
261: dst->get_address(dst).ptr, len);
262: addr.sin6_port = htons(dst->get_port(dst));
263:
264: memset(&msg, 0, sizeof(msg));
265: msg.name = (struct sockaddr*)&addr;
266: msg.namelen = sizeof(addr);
267: msg.lpBuffers = &data;
268: msg.dwBufferCount = 1;
269:
270: if (!src->is_anyaddr(src))
271: {
272: memset(buf, 0, sizeof(buf));
273: msg.Control.buf = buf;
274:
275: switch (src->get_family(src))
276: {
277: case AF_INET:
278: {
279: struct in_pktinfo *pktinfo;
280: SOCKADDR_IN *sin;
281:
282: msg.Control.len = WSA_CMSG_SPACE(sizeof(*pktinfo));
283: cmsg = WSA_CMSG_FIRSTHDR(&msg);
284: cmsg->cmsg_level = IPPROTO_IP;
285: cmsg->cmsg_type = IP_PKTINFO;
286: cmsg->cmsg_len = WSA_CMSG_LEN(sizeof(*pktinfo));
287: pktinfo = (struct in_pktinfo*)WSA_CMSG_DATA(cmsg);
288: sin = (SOCKADDR_IN*)src->get_sockaddr(src);
289: pktinfo->ipi_addr = sin->sin_addr;
290: break;
291: }
292: case AF_INET6:
293: {
294: struct in6_pktinfo *pktinfo;
295: SOCKADDR_IN6 *sin;
296:
297: msg.Control.len = WSA_CMSG_SPACE(sizeof(*pktinfo));
298: cmsg = WSA_CMSG_FIRSTHDR(&msg);
299: cmsg->cmsg_level = IPPROTO_IPV6;
300: cmsg->cmsg_type = IPV6_PKTINFO;
301: cmsg->cmsg_len = WSA_CMSG_LEN(sizeof(*pktinfo));
302: pktinfo = (struct in6_pktinfo*)WSA_CMSG_DATA(cmsg);
303: sin = (SOCKADDR_IN6*)src->get_sockaddr(src);
304: pktinfo->ipi6_addr = sin->sin6_addr;
305: break;
306: }
307: }
308: }
309:
310: if (this->WSASendMsg(this->socks[i], &msg, 0, &len,
311: NULL, NULL) == SOCKET_ERROR)
312: {
313: DBG1(DBG_NET, "sending packet failed: %d", WSAGetLastError());
314: return FAILED;
315: }
316: return SUCCESS;
317: }
318:
319: METHOD(socket_t, get_port, uint16_t,
320: private_socket_win_socket_t *this, bool nat)
321: {
322: return this->ports[nat != 0];
323: }
324:
325: METHOD(socket_t, supported_families, socket_family_t,
326: private_socket_win_socket_t *this)
327: {
328: return SOCKET_FAMILY_IPV4 | SOCKET_FAMILY_IPV6;
329: }
330:
331: /**
332: * Open an IPv4/IPv6 dual-use socket to send and receive packets
333: */
334: static SOCKET open_socket(private_socket_win_socket_t *this, int i)
335: {
336: SOCKADDR_IN6 addr = {
337: .sin6_family = AF_INET6,
338: .sin6_port = htons(this->ports[i]),
339: };
340: int addrlen = sizeof(addr);
341: BOOL on = TRUE, off = FALSE;
342: DWORD dwon = TRUE;
343: SOCKET s;
344:
345: s = WSASocket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 0);
346: if (s == INVALID_SOCKET)
347: {
348: DBG1(DBG_NET, "creating socket failed: %d", WSAGetLastError());
349: return INVALID_SOCKET;
350: }
351: /* enable IPv4 on IPv6 socket */
352: if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
353: (const char*)&off, sizeof(off)) == SOCKET_ERROR)
354: {
355: DBG1(DBG_NET, "using dual-mode socket failed: %d", WSAGetLastError());
356: closesocket(s);
357: return INVALID_SOCKET;
358: }
359: if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
360: (const char*)&on, sizeof(on)) == SOCKET_ERROR)
361: {
362: DBG1(DBG_NET, "enabling SO_REUSEADDR failed: %d", WSAGetLastError());
363: closesocket(s);
364: return INVALID_SOCKET;
365: }
366: if (bind(s, (const struct sockaddr*)&addr, addrlen) == SOCKET_ERROR)
367: {
368: DBG1(DBG_NET, "unable to bind socket: %d", WSAGetLastError());
369: closesocket(s);
370: return INVALID_SOCKET;
371: }
372: /* retrieve randomly allocated port if needed */
373: if (this->ports[i] == 0)
374: {
375: if (getsockname(s, (struct sockaddr*)&addr,
376: &addrlen) == SOCKET_ERROR)
377: {
378: DBG1(DBG_NET, "unable to determine port: %d", WSAGetLastError());
379: closesocket(s);
380: return INVALID_SOCKET;
381: }
382: this->ports[i] = ntohs(addr.sin6_port);
383: }
384: /* PKTINFO is required for both protocol families */
385: if (setsockopt(s, IPPROTO_IP, IP_PKTINFO,
386: (char*)&dwon, sizeof(dwon)) == SOCKET_ERROR)
387: {
388: DBG1(DBG_NET, "unable to set IP_PKTINFO: %d", WSAGetLastError());
389: closesocket(s);
390: return INVALID_SOCKET;
391: }
392: if (setsockopt(s, IPPROTO_IPV6, IPV6_PKTINFO,
393: (char*)&dwon, sizeof(dwon)) == SOCKET_ERROR)
394: {
395: DBG1(DBG_NET, "unable to set IP6_PKTINFO: %d", WSAGetLastError());
396: closesocket(s);
397: return INVALID_SOCKET;
398: }
399: if (!charon->kernel->bypass_socket(charon->kernel, s, AF_INET))
400: {
401: DBG1(DBG_NET, "installing IPv4 IKE bypass policy failed");
402: }
403: if (!charon->kernel->bypass_socket(charon->kernel, s, AF_INET6))
404: {
405: DBG1(DBG_NET, "installing IPv6 IKE bypass policy failed");
406: }
407: return s;
408: }
409:
410: METHOD(socket_t, destroy, void,
411: private_socket_win_socket_t *this)
412: {
413: int i;
414:
415: for (i = 0; i < SOCKET_COUNT; i++)
416: {
417: if (this->socks[i] != INVALID_SOCKET)
418: {
419: closesocket(this->socks[i]);
420: }
421: if (this->events[i] != WSA_INVALID_EVENT)
422: {
423: WSACloseEvent(this->events[i]);
424: }
425: }
426: free(this);
427: }
428:
429: /*
430: * See header for description
431: */
432: socket_win_socket_t *socket_win_socket_create()
433: {
434: private_socket_win_socket_t *this;
435: DWORD len;
436: int i;
437:
438: INIT(this,
439: .public = {
440: .socket = {
441: .send = _sender,
442: .receive = _receiver,
443: .get_port = _get_port,
444: .supported_families = _supported_families,
445: .destroy = _destroy,
446: },
447: },
448: .ports = {
449: lib->settings->get_int(lib->settings,
450: "%s.port", CHARON_UDP_PORT, lib->ns),
451: lib->settings->get_int(lib->settings,
452: "%s.port_nat_t", CHARON_NATT_PORT, lib->ns),
453: },
454: .max_packet = lib->settings->get_int(lib->settings,
455: "%s.max_packet", PACKET_MAX_DEFAULT, lib->ns),
456: );
457:
458: for (i = 0; i < SOCKET_COUNT; i++)
459: {
460: this->socks[i] = open_socket(this, i);
461: this->events[i] = WSACreateEvent();
462: }
463:
464: for (i = 0; i < SOCKET_COUNT; i++)
465: {
466: if (this->events[i] == WSA_INVALID_EVENT ||
467: this->socks[i] == INVALID_SOCKET)
468: {
469: DBG1(DBG_NET, "creating socket failed: %d", WSAGetLastError());
470: destroy(this);
471: return NULL;
472: }
473: if (WSAEventSelect(this->socks[i], this->events[i],
474: FD_READ) == SOCKET_ERROR)
475: {
476: DBG1(DBG_NET, "WSAEventSelect() failed: %d", WSAGetLastError());
477: destroy(this);
478: return NULL;
479: }
480: }
481:
482: if (WSAIoctl(this->socks[0], SIO_GET_EXTENSION_FUNCTION_POINTER,
483: &WSASendMsgGUID, sizeof(WSASendMsgGUID), &this->WSASendMsg,
484: sizeof(this->WSASendMsg), &len, NULL, NULL) != 0 ||
485: WSAIoctl(this->socks[0], SIO_GET_EXTENSION_FUNCTION_POINTER,
486: &WSARecvMsgGUID, sizeof(WSARecvMsgGUID), &this->WSARecvMsg,
487: sizeof(this->WSARecvMsg), &len, NULL, NULL) != 0)
488: {
489: DBG1(DBG_NET, "send/recvmsg() lookup failed: %d", WSAGetLastError());
490: destroy(this);
491: return NULL;
492: }
493:
494: return &this->public;
495: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>