Return to socket_dynamic_socket.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / plugins / socket_dynamic |
1.1 misho 1: /* 2: * Copyright (C) 2006-2013 Tobias Brunner 3: * Copyright (C) 2006 Daniel Roethlisberger 4: * Copyright (C) 2005-2010 Martin Willi 5: * Copyright (C) 2005 Jan Hutter 6: * HSR Hochschule fuer Technik Rapperswil 7: * Copyright (C) 2010 revosec AG 8: * 9: * This program is free software; you can redistribute it and/or modify it 10: * under the terms of the GNU General Public License as published by the 11: * Free Software Foundation; either version 2 of the License, or (at your 12: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 13: * 14: * This program is distributed in the hope that it will be useful, but 15: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17: * for more details. 18: */ 19: 20: /* for struct in6_pktinfo */ 21: #define _GNU_SOURCE 22: 23: #include "socket_dynamic_socket.h" 24: 25: #include <sys/types.h> 26: #include <sys/socket.h> 27: #include <string.h> 28: #include <errno.h> 29: #include <unistd.h> 30: #include <stdlib.h> 31: #include <fcntl.h> 32: #include <sys/ioctl.h> 33: #include <netinet/in_systm.h> 34: #include <netinet/in.h> 35: #include <netinet/ip.h> 36: #include <netinet/udp.h> 37: #include <net/if.h> 38: 39: #include <daemon.h> 40: #include <threading/thread.h> 41: #include <threading/rwlock.h> 42: #include <collections/hashtable.h> 43: 44: /* these are not defined on some platforms */ 45: #ifndef SOL_IP 46: #define SOL_IP IPPROTO_IP 47: #endif 48: #ifndef SOL_IPV6 49: #define SOL_IPV6 IPPROTO_IPV6 50: #endif 51: 52: /* IPV6_RECVPKTINFO is defined in RFC 3542 which obsoletes RFC 2292 that 53: * previously defined IPV6_PKTINFO */ 54: #ifndef IPV6_RECVPKTINFO 55: #define IPV6_RECVPKTINFO IPV6_PKTINFO 56: #endif 57: 58: typedef struct private_socket_dynamic_socket_t private_socket_dynamic_socket_t; 59: typedef struct dynsock_t dynsock_t; 60: 61: /** 62: * Private data of an socket_t object 63: */ 64: struct private_socket_dynamic_socket_t { 65: 66: /** 67: * public functions 68: */ 69: socket_dynamic_socket_t public; 70: 71: /** 72: * Hashtable of bound sockets 73: */ 74: hashtable_t *sockets; 75: 76: /** 77: * Lock for sockets hashtable 78: */ 79: rwlock_t *lock; 80: 81: /** 82: * Notification pipe to signal receiver 83: */ 84: int notify[2]; 85: 86: /** 87: * Maximum packet size to receive 88: */ 89: int max_packet; 90: }; 91: 92: /** 93: * Struct for a dynamically allocated socket 94: */ 95: struct dynsock_t { 96: 97: /** 98: * File descriptor of socket 99: */ 100: int fd; 101: 102: /** 103: * Address family 104: */ 105: int family; 106: 107: /** 108: * Bound source port 109: */ 110: uint16_t port; 111: }; 112: 113: /** 114: * Hash function for hashtable 115: */ 116: static u_int hash(dynsock_t *key) 117: { 118: return (key->family << 16) | key->port; 119: } 120: 121: /** 122: * Equals function for hashtable 123: */ 124: static bool equals(dynsock_t *a, dynsock_t *b) 125: { 126: return a->family == b->family && a->port == b->port; 127: } 128: 129: /** 130: * Create a fd_set from all bound sockets 131: */ 132: static int build_fds(private_socket_dynamic_socket_t *this, fd_set *fds) 133: { 134: enumerator_t *enumerator; 135: dynsock_t *key, *value; 136: int maxfd; 137: 138: FD_ZERO(fds); 139: FD_SET(this->notify[0], fds); 140: maxfd = this->notify[0]; 141: 142: this->lock->read_lock(this->lock); 143: enumerator = this->sockets->create_enumerator(this->sockets); 144: while (enumerator->enumerate(enumerator, &key, &value)) 145: { 146: FD_SET(value->fd, fds); 147: maxfd = max(maxfd, value->fd); 148: } 149: enumerator->destroy(enumerator); 150: this->lock->unlock(this->lock); 151: 152: return maxfd + 1; 153: } 154: 155: /** 156: * Find the socket select()ed 157: */ 158: static dynsock_t* scan_fds(private_socket_dynamic_socket_t *this, fd_set *fds) 159: { 160: enumerator_t *enumerator; 161: dynsock_t *key, *value, *selected = NULL; 162: 163: this->lock->read_lock(this->lock); 164: enumerator = this->sockets->create_enumerator(this->sockets); 165: while (enumerator->enumerate(enumerator, &key, &value)) 166: { 167: if (FD_ISSET(value->fd, fds)) 168: { 169: selected = value; 170: break; 171: } 172: } 173: enumerator->destroy(enumerator); 174: this->lock->unlock(this->lock); 175: 176: return selected; 177: } 178: 179: /** 180: * Receive a packet from a given socket fd 181: */ 182: static packet_t *receive_packet(private_socket_dynamic_socket_t *this, 183: dynsock_t *skt) 184: { 185: host_t *source = NULL, *dest = NULL; 186: ssize_t len; 187: char buffer[this->max_packet]; 188: chunk_t data; 189: packet_t *packet; 190: struct msghdr msg; 191: struct cmsghdr *cmsgptr; 192: struct iovec iov; 193: char ancillary[64]; 194: union { 195: struct sockaddr_in in4; 196: struct sockaddr_in6 in6; 197: } src; 198: 199: msg.msg_name = &src; 200: msg.msg_namelen = sizeof(src); 201: iov.iov_base = buffer; 202: iov.iov_len = this->max_packet; 203: msg.msg_iov = &iov; 204: msg.msg_iovlen = 1; 205: msg.msg_control = ancillary; 206: msg.msg_controllen = sizeof(ancillary); 207: msg.msg_flags = 0; 208: len = recvmsg(skt->fd, &msg, 0); 209: if (len < 0) 210: { 211: DBG1(DBG_NET, "error reading socket: %s", strerror(errno)); 212: return NULL; 213: } 214: if (msg.msg_flags & MSG_TRUNC) 215: { 216: DBG1(DBG_NET, "receive buffer too small, packet discarded"); 217: return NULL; 218: } 219: DBG3(DBG_NET, "received packet %b", buffer, (u_int)len); 220: 221: /* read ancillary data to get destination address */ 222: for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; 223: cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) 224: { 225: if (cmsgptr->cmsg_len == 0) 226: { 227: DBG1(DBG_NET, "error reading ancillary data"); 228: return NULL; 229: } 230: 231: if (cmsgptr->cmsg_level == SOL_IPV6 && 232: cmsgptr->cmsg_type == IPV6_PKTINFO) 233: { 234: struct in6_pktinfo *pktinfo; 235: struct sockaddr_in6 dst; 236: 237: pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsgptr); 238: memset(&dst, 0, sizeof(dst)); 239: memcpy(&dst.sin6_addr, &pktinfo->ipi6_addr, sizeof(dst.sin6_addr)); 240: dst.sin6_family = AF_INET6; 241: dst.sin6_port = htons(skt->port); 242: dest = host_create_from_sockaddr((sockaddr_t*)&dst); 243: } 244: if (cmsgptr->cmsg_level == SOL_IP && 245: cmsgptr->cmsg_type == IP_PKTINFO) 246: { 247: struct in_pktinfo *pktinfo; 248: struct sockaddr_in dst; 249: 250: pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsgptr); 251: memset(&dst, 0, sizeof(dst)); 252: memcpy(&dst.sin_addr, &pktinfo->ipi_addr, sizeof(dst.sin_addr)); 253: 254: dst.sin_family = AF_INET; 255: dst.sin_port = htons(skt->port); 256: dest = host_create_from_sockaddr((sockaddr_t*)&dst); 257: } 258: if (dest) 259: { 260: break; 261: } 262: } 263: if (dest == NULL) 264: { 265: DBG1(DBG_NET, "error reading IP header"); 266: return NULL; 267: } 268: source = host_create_from_sockaddr((sockaddr_t*)&src); 269: DBG2(DBG_NET, "received packet: from %#H to %#H", source, dest); 270: data = chunk_create(buffer, len); 271: 272: packet = packet_create(); 273: packet->set_source(packet, source); 274: packet->set_destination(packet, dest); 275: packet->set_data(packet, chunk_clone(data)); 276: return packet; 277: } 278: 279: METHOD(socket_t, receiver, status_t, 280: private_socket_dynamic_socket_t *this, packet_t **packet) 281: { 282: dynsock_t *selected; 283: packet_t *pkt; 284: bool oldstate; 285: fd_set fds; 286: int maxfd; 287: 288: while (TRUE) 289: { 290: maxfd = build_fds(this, &fds); 291: 292: DBG2(DBG_NET, "waiting for data on sockets"); 293: oldstate = thread_cancelability(TRUE); 294: if (select(maxfd, &fds, NULL, NULL, NULL) <= 0) 295: { 296: thread_cancelability(oldstate); 297: return FAILED; 298: } 299: thread_cancelability(oldstate); 300: 301: if (FD_ISSET(this->notify[0], &fds)) 302: { /* got notified, read garbage, rebuild fdset */ 303: char buf[1]; 304: 305: ignore_result(read(this->notify[0], buf, sizeof(buf))); 306: DBG2(DBG_NET, "rebuilding fdset due to newly bound ports"); 307: continue; 308: } 309: selected = scan_fds(this, &fds); 310: if (selected) 311: { 312: break; 313: } 314: } 315: pkt = receive_packet(this, selected); 316: if (pkt) 317: { 318: *packet = pkt; 319: return SUCCESS; 320: } 321: return FAILED; 322: } 323: 324: /** 325: * Get the port allocated dynamically using bind() 326: */ 327: static bool get_dynamic_port(int fd, int family, uint16_t *port) 328: { 329: union { 330: struct sockaddr_storage ss; 331: struct sockaddr s; 332: struct sockaddr_in sin; 333: struct sockaddr_in6 sin6; 334: } addr; 335: socklen_t addrlen; 336: 337: addrlen = sizeof(addr); 338: if (getsockname(fd, &addr.s, &addrlen) != 0) 339: { 340: DBG1(DBG_NET, "unable to getsockname: %s", strerror(errno)); 341: return FALSE; 342: } 343: switch (family) 344: { 345: case AF_INET: 346: if (addrlen != sizeof(addr.sin) || addr.sin.sin_family != family) 347: { 348: break; 349: } 350: *port = ntohs(addr.sin.sin_port); 351: return TRUE; 352: case AF_INET6: 353: if (addrlen != sizeof(addr.sin6) || addr.sin6.sin6_family != family) 354: { 355: break; 356: } 357: *port = ntohs(addr.sin6.sin6_port); 358: return TRUE; 359: default: 360: return FALSE; 361: } 362: DBG1(DBG_NET, "received invalid getsockname() result"); 363: return FALSE; 364: } 365: 366: /** 367: * open a socket to send and receive packets 368: */ 369: static int open_socket(private_socket_dynamic_socket_t *this, 370: int family, uint16_t *port) 371: { 372: union { 373: struct sockaddr_storage ss; 374: struct sockaddr s; 375: struct sockaddr_in sin; 376: struct sockaddr_in6 sin6; 377: } addr; 378: int on = TRUE; 379: socklen_t addrlen; 380: u_int sol, pktinfo = 0; 381: int fd; 382: 383: memset(&addr, 0, sizeof(addr)); 384: /* precalculate constants depending on address family */ 385: switch (family) 386: { 387: case AF_INET: 388: addr.sin.sin_family = AF_INET; 389: addr.sin.sin_addr.s_addr = INADDR_ANY; 390: addr.sin.sin_port = htons(*port); 391: addrlen = sizeof(addr.sin); 392: sol = SOL_IP; 393: pktinfo = IP_PKTINFO; 394: break; 395: case AF_INET6: 396: addr.sin6.sin6_family = AF_INET6; 397: memset(&addr.sin6.sin6_addr, 0, sizeof(addr.sin6.sin6_addr)); 398: addr.sin6.sin6_port = htons(*port); 399: addrlen = sizeof(addr.sin6); 400: sol = SOL_IPV6; 401: pktinfo = IPV6_RECVPKTINFO; 402: break; 403: default: 404: return 0; 405: } 406: 407: fd = socket(family, SOCK_DGRAM, IPPROTO_UDP); 408: if (fd < 0) 409: { 410: DBG1(DBG_NET, "could not open socket: %s", strerror(errno)); 411: return 0; 412: } 413: if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0) 414: { 415: DBG1(DBG_NET, "unable to set SO_REUSEADDR on socket: %s", strerror(errno)); 416: close(fd); 417: return 0; 418: } 419: 420: if (bind(fd, &addr.s, addrlen) < 0) 421: { 422: DBG1(DBG_NET, "unable to bind socket: %s", strerror(errno)); 423: close(fd); 424: return 0; 425: } 426: if (*port == 0 && !get_dynamic_port(fd, family, port)) 427: { 428: close(fd); 429: return 0; 430: } 431: 432: /* get additional packet info on receive */ 433: if (setsockopt(fd, sol, pktinfo, &on, sizeof(on)) < 0) 434: { 435: DBG1(DBG_NET, "unable to set IP_PKTINFO on socket: %s", strerror(errno)); 436: close(fd); 437: return 0; 438: } 439: 440: if (!charon->kernel->bypass_socket(charon->kernel, fd, family)) 441: { 442: DBG1(DBG_NET, "installing IKE bypass policy failed"); 443: } 444: 445: /* enable UDP decapsulation on each socket */ 446: if (!charon->kernel->enable_udp_decap(charon->kernel, fd, family, *port)) 447: { 448: DBG1(DBG_NET, "enabling UDP decapsulation for %s on port %d failed", 449: family == AF_INET ? "IPv4" : "IPv6", *port); 450: } 451: 452: return fd; 453: } 454: 455: /** 456: * Get the first usable socket for an address family 457: */ 458: static dynsock_t *get_any_socket(private_socket_dynamic_socket_t *this, 459: int family) 460: { 461: dynsock_t *key, *value, *found = NULL; 462: enumerator_t *enumerator; 463: 464: this->lock->read_lock(this->lock); 465: enumerator = this->sockets->create_enumerator(this->sockets); 466: while (enumerator->enumerate(enumerator, &key, &value)) 467: { 468: if (value->family == family) 469: { 470: found = value; 471: break; 472: } 473: } 474: enumerator->destroy(enumerator); 475: this->lock->unlock(this->lock); 476: 477: return found; 478: } 479: 480: /** 481: * Find/Create a socket to send from host 482: */ 483: static dynsock_t *find_socket(private_socket_dynamic_socket_t *this, 484: int family, uint16_t port) 485: { 486: dynsock_t *skt, lookup = { 487: .family = family, 488: .port = port, 489: }; 490: char buf[] = {0x01}; 491: int fd; 492: 493: this->lock->read_lock(this->lock); 494: skt = this->sockets->get(this->sockets, &lookup); 495: this->lock->unlock(this->lock); 496: if (skt) 497: { 498: return skt; 499: } 500: if (!port) 501: { 502: skt = get_any_socket(this, family); 503: if (skt) 504: { 505: return skt; 506: } 507: } 508: fd = open_socket(this, family, &port); 509: if (!fd) 510: { 511: return NULL; 512: } 513: INIT(skt, 514: .family = family, 515: .port = port, 516: .fd = fd, 517: ); 518: this->lock->write_lock(this->lock); 519: this->sockets->put(this->sockets, skt, skt); 520: this->lock->unlock(this->lock); 521: /* notify receiver thread to reread socket list */ 522: ignore_result(write(this->notify[1], buf, sizeof(buf))); 523: 524: return skt; 525: } 526: 527: /** 528: * Generic function to send a message. 529: */ 530: static ssize_t send_msg_generic(int skt, struct msghdr *msg) 531: { 532: return sendmsg(skt, msg, 0); 533: } 534: 535: /** 536: * Send a message with the IPv4 source address set. 537: */ 538: static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src) 539: { 540: char buf[CMSG_SPACE(sizeof(struct in_pktinfo))] = {}; 541: struct cmsghdr *cmsg; 542: struct in_addr *addr; 543: struct in_pktinfo *pktinfo; 544: struct sockaddr_in *sin; 545: 546: msg->msg_control = buf; 547: msg->msg_controllen = sizeof(buf); 548: cmsg = CMSG_FIRSTHDR(msg); 549: cmsg->cmsg_level = SOL_IP; 550: cmsg->cmsg_type = IP_PKTINFO; 551: cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); 552: 553: pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg); 554: addr = &pktinfo->ipi_spec_dst; 555: 556: sin = (struct sockaddr_in*)src->get_sockaddr(src); 557: memcpy(addr, &sin->sin_addr, sizeof(struct in_addr)); 558: return send_msg_generic(skt, msg); 559: } 560: 561: /** 562: * Send a message with the IPv6 source address set. 563: */ 564: static ssize_t send_msg_v6(int skt, struct msghdr *msg, host_t *src) 565: { 566: char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))] = {}; 567: struct cmsghdr *cmsg; 568: struct in6_pktinfo *pktinfo; 569: struct sockaddr_in6 *sin; 570: 571: msg->msg_control = buf; 572: msg->msg_controllen = sizeof(buf); 573: cmsg = CMSG_FIRSTHDR(msg); 574: cmsg->cmsg_level = SOL_IPV6; 575: cmsg->cmsg_type = IPV6_PKTINFO; 576: cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); 577: pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg); 578: sin = (struct sockaddr_in6*)src->get_sockaddr(src); 579: memcpy(&pktinfo->ipi6_addr, &sin->sin6_addr, sizeof(struct in6_addr)); 580: return send_msg_generic(skt, msg); 581: } 582: 583: METHOD(socket_t, sender, status_t, 584: private_socket_dynamic_socket_t *this, packet_t *packet) 585: { 586: dynsock_t *skt; 587: host_t *src, *dst; 588: int family; 589: ssize_t len; 590: chunk_t data; 591: struct msghdr msg; 592: struct iovec iov; 593: 594: src = packet->get_source(packet); 595: dst = packet->get_destination(packet); 596: family = src->get_family(src); 597: skt = find_socket(this, family, src->get_port(src)); 598: if (!skt) 599: { 600: return FAILED; 601: } 602: 603: data = packet->get_data(packet); 604: DBG2(DBG_NET, "sending packet: from %#H to %#H", src, dst); 605: 606: memset(&msg, 0, sizeof(struct msghdr)); 607: msg.msg_name = dst->get_sockaddr(dst);; 608: msg.msg_namelen = *dst->get_sockaddr_len(dst); 609: iov.iov_base = data.ptr; 610: iov.iov_len = data.len; 611: msg.msg_iov = &iov; 612: msg.msg_iovlen = 1; 613: msg.msg_flags = 0; 614: 615: if (!src->is_anyaddr(src)) 616: { 617: if (family == AF_INET) 618: { 619: len = send_msg_v4(skt->fd, &msg, src); 620: } 621: else 622: { 623: len = send_msg_v6(skt->fd, &msg, src); 624: } 625: } 626: else 627: { 628: len = send_msg_generic(skt->fd, &msg); 629: } 630: 631: if (len != data.len) 632: { 633: DBG1(DBG_NET, "error writing to socket: %s", strerror(errno)); 634: return FAILED; 635: } 636: return SUCCESS; 637: } 638: 639: METHOD(socket_t, get_port, uint16_t, 640: private_socket_dynamic_socket_t *this, bool nat_t) 641: { 642: /* we return 0 here for users that have no explicit port configured, the 643: * sender will default to the default port in this case */ 644: return 0; 645: } 646: 647: METHOD(socket_t, supported_families, socket_family_t, 648: private_socket_dynamic_socket_t *this) 649: { 650: /* we could return only the families of the opened sockets, but it could 651: * be that both families are supported even if no socket is yet open */ 652: return SOCKET_FAMILY_BOTH; 653: } 654: 655: METHOD(socket_t, destroy, void, 656: private_socket_dynamic_socket_t *this) 657: { 658: enumerator_t *enumerator; 659: dynsock_t *key, *value; 660: 661: enumerator = this->sockets->create_enumerator(this->sockets); 662: while (enumerator->enumerate(enumerator, &key, &value)) 663: { 664: close(value->fd); 665: free(value); 666: } 667: enumerator->destroy(enumerator); 668: this->sockets->destroy(this->sockets); 669: this->lock->destroy(this->lock); 670: 671: close(this->notify[0]); 672: close(this->notify[1]); 673: free(this); 674: } 675: 676: /* 677: * See header for description 678: */ 679: socket_dynamic_socket_t *socket_dynamic_socket_create() 680: { 681: private_socket_dynamic_socket_t *this; 682: 683: INIT(this, 684: .public = { 685: .socket = { 686: .send = _sender, 687: .receive = _receiver, 688: .get_port = _get_port, 689: .supported_families = _supported_families, 690: .destroy = _destroy, 691: }, 692: }, 693: .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), 694: .max_packet = lib->settings->get_int(lib->settings, 695: "%s.max_packet", PACKET_MAX_DEFAULT, lib->ns), 696: ); 697: 698: if (pipe(this->notify) != 0) 699: { 700: DBG1(DBG_NET, "creating notify pipe for dynamic socket failed"); 701: free(this); 702: return NULL; 703: } 704: 705: this->sockets = hashtable_create((void*)hash, (void*)equals, 8); 706: 707: return &this->public; 708: }