Return to socket_win_socket.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / plugins / socket_win |
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: }