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>