socket-default: Add an option to force the sending interface via IP_PKTINFO
[strongswan.git] / src / libcharon / plugins / socket_default / socket_default_socket.c
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 * Hochschule fuer Technik Rapperswil
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 */
18
19 /* for struct in6_pktinfo */
20 #define _GNU_SOURCE
21 #ifdef __sun
22 #define _XPG4_2
23 #define __EXTENSIONS__
24 #endif
25 /* make sure to use the proper defs on Mac OS X */
26 #define __APPLE_USE_RFC_3542
27
28 #include "socket_default_socket.h"
29
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #include <fcntl.h>
37 #include <sys/ioctl.h>
38 #include <netinet/in_systm.h>
39 #include <netinet/in.h>
40 #include <netinet/ip.h>
41 #include <netinet/udp.h>
42 #include <net/if.h>
43
44 #include <daemon.h>
45 #include <threading/thread.h>
46
47 /* these are not defined on some platforms */
48 #ifndef SOL_IP
49 #define SOL_IP IPPROTO_IP
50 #endif
51 #ifndef SOL_IPV6
52 #define SOL_IPV6 IPPROTO_IPV6
53 #endif
54 #ifndef IPV6_TCLASS
55 #define IPV6_TCLASS 67
56 #endif
57
58 /* IPV6_RECVPKTINFO is defined in RFC 3542 which obsoletes RFC 2292 that
59 * previously defined IPV6_PKTINFO */
60 #ifndef IPV6_RECVPKTINFO
61 #define IPV6_RECVPKTINFO IPV6_PKTINFO
62 #endif
63
64 #ifndef IN6ADDR_ANY_INIT
65 #define IN6ADDR_ANY_INIT {{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}
66 #endif
67
68 #ifndef HAVE_IN6ADDR_ANY
69 static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
70 #endif
71
72 typedef struct private_socket_default_socket_t private_socket_default_socket_t;
73
74 /**
75 * Private data of an socket_t object
76 */
77 struct private_socket_default_socket_t {
78
79 /**
80 * public functions
81 */
82 socket_default_socket_t public;
83
84 /**
85 * Configured port (or random, if initially 0)
86 */
87 uint16_t port;
88
89 /**
90 * Configured port for NAT-T (or random, if initially 0)
91 */
92 uint16_t natt;
93
94 /**
95 * IPv4 socket (500 or port)
96 */
97 int ipv4;
98
99 /**
100 * IPv4 socket for NAT-T (4500 or natt)
101 */
102 int ipv4_natt;
103
104 /**
105 * IPv6 socket (500 or port)
106 */
107 int ipv6;
108
109 /**
110 * IPv6 socket for NAT-T (4500 or natt)
111 */
112 int ipv6_natt;
113
114 /**
115 * DSCP value set on IPv4 socket
116 */
117 uint8_t dscp4;
118
119 /**
120 * DSCP value set on IPv4 socket for NAT-T (4500 or natt)
121 */
122 uint8_t dscp4_natt;
123
124 /**
125 * DSCP value set on IPv6 socket (500 or port)
126 */
127 uint8_t dscp6;
128
129 /**
130 * DSCP value set on IPv6 socket for NAT-T (4500 or natt)
131 */
132 uint8_t dscp6_natt;
133
134 /**
135 * Maximum packet size to receive
136 */
137 int max_packet;
138
139 /**
140 * TRUE if the source address should be set on outbound packets
141 */
142 bool set_source;
143
144 /**
145 * TRUE to force sending source interface on outbound packetrs
146 */
147 bool set_sourceif;
148
149 /**
150 * A counter to implement round-robin selection of read sockets
151 */
152 u_int rr_counter;
153 };
154
155 /**
156 * Get the destination IPv4 address of a received packet, depending on the
157 * available mechanism.
158 */
159 #ifdef IP_PKTINFO
160
161 static host_t *get_dst_v4(struct cmsghdr *cmsgptr, uint16_t port)
162 {
163 struct sockaddr_in dst = {
164 .sin_family = AF_INET,
165 .sin_port = htons(port),
166 };
167 struct in_pktinfo *pktinfo;
168 struct in_addr *addr;
169
170 if (cmsgptr->cmsg_type == IP_PKTINFO)
171 {
172 pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsgptr);
173 addr = &pktinfo->ipi_addr;
174 memcpy(&dst.sin_addr, addr, sizeof(dst.sin_addr));
175 return host_create_from_sockaddr((sockaddr_t*)&dst);
176 }
177 return NULL;
178 }
179
180 #elif defined(IP_RECVDSTADDR)
181
182 static host_t *get_dst_v4(struct cmsghdr *cmsgptr, uint16_t port)
183 {
184 struct sockaddr_in dst = {
185 .sin_family = AF_INET,
186 .sin_port = htons(port),
187 };
188 struct in_addr *addr;
189
190 if (cmsgptr->cmsg_type == IP_RECVDSTADDR)
191 {
192 addr = (struct in_addr*)CMSG_DATA(cmsgptr);
193 memcpy(&dst.sin_addr, addr, sizeof(dst.sin_addr));
194 return host_create_from_sockaddr((sockaddr_t*)&dst);
195 }
196 return NULL;
197 }
198
199 #else /* IP_PKTINFO || IP_RECVDSTADDR */
200
201 static host_t *get_dst_v4(struct cmsghdr *cmsgptr, uint16_t port)
202 {
203 return NULL;
204 }
205
206 #endif /* IP_PKTINFO || IP_RECVDSTADDR */
207
208 /**
209 * Get the destination IPv6 address of a received packet, depending on the
210 * available mechanism.
211 */
212 #ifdef HAVE_IN6_PKTINFO
213
214 static host_t *get_dst_v6(struct cmsghdr *cmsgptr, uint16_t port)
215 {
216 struct in6_pktinfo *pktinfo;
217 struct sockaddr_in6 dst = {
218 .sin6_family = AF_INET6,
219 .sin6_port = htons(port),
220 };
221
222 if (cmsgptr->cmsg_type == IPV6_PKTINFO)
223 {
224 pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsgptr);
225 memcpy(&dst.sin6_addr, &pktinfo->ipi6_addr, sizeof(dst.sin6_addr));
226 return host_create_from_sockaddr((sockaddr_t*)&dst);
227 }
228 return NULL;
229 }
230
231 #else /* HAVE_IN6_PKTINFO */
232
233 static host_t *get_dst_v6(struct cmsghdr *cmsgptr, uint16_t port)
234 {
235 return NULL;
236 }
237
238 #endif /* HAVE_IN6_PKTINFO */
239
240 METHOD(socket_t, receiver, status_t,
241 private_socket_default_socket_t *this, packet_t **packet)
242 {
243 char buffer[this->max_packet];
244 chunk_t data;
245 packet_t *pkt;
246 host_t *source = NULL, *dest = NULL;
247 int i, rr, index, bytes_read = 0, selected = -1;
248 bool oldstate;
249 uint16_t port = 0;
250 struct pollfd pfd[] = {
251 { .fd = this->ipv4, .events = POLLIN },
252 { .fd = this->ipv4_natt, .events = POLLIN },
253 { .fd = this->ipv6, .events = POLLIN },
254 { .fd = this->ipv6_natt, .events = POLLIN },
255 };
256 int ports[] = {
257 /* port numbers associated to pollfds */
258 this->port, this->natt, this->port, this->natt,
259 };
260
261 DBG2(DBG_NET, "waiting for data on sockets");
262 oldstate = thread_cancelability(TRUE);
263 if (poll(pfd, countof(pfd), -1) <= 0)
264 {
265 thread_cancelability(oldstate);
266 return FAILED;
267 }
268 thread_cancelability(oldstate);
269
270 rr = this->rr_counter++;
271 for (i = 0; i < countof(pfd); i++)
272 {
273 /* To serve all ports with equal priority, we use a round-robin
274 * scheme to choose the one to process in this invocation */
275 index = (rr + i) % countof(pfd);
276 if (pfd[index].revents & POLLIN)
277 {
278 selected = pfd[index].fd;
279 port = ports[index];
280 break;
281 }
282 }
283 if (selected != -1)
284 {
285 struct msghdr msg;
286 struct cmsghdr *cmsgptr;
287 struct iovec iov;
288 char ancillary[64];
289 union {
290 struct sockaddr_in in4;
291 struct sockaddr_in6 in6;
292 } src;
293
294 msg.msg_name = &src;
295 msg.msg_namelen = sizeof(src);
296 iov.iov_base = buffer;
297 iov.iov_len = this->max_packet;
298 msg.msg_iov = &iov;
299 msg.msg_iovlen = 1;
300 msg.msg_control = ancillary;
301 msg.msg_controllen = sizeof(ancillary);
302 msg.msg_flags = 0;
303 bytes_read = recvmsg(selected, &msg, 0);
304 if (bytes_read < 0)
305 {
306 DBG1(DBG_NET, "error reading socket: %s", strerror(errno));
307 return FAILED;
308 }
309 if (msg.msg_flags & MSG_TRUNC)
310 {
311 DBG1(DBG_NET, "receive buffer too small, packet discarded");
312 return FAILED;
313 }
314 DBG3(DBG_NET, "received packet %b", buffer, bytes_read);
315
316 /* read ancillary data to get destination address */
317 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
318 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
319 {
320 if (cmsgptr->cmsg_len == 0)
321 {
322 DBG1(DBG_NET, "error reading ancillary data");
323 return FAILED;
324 }
325 if (cmsgptr->cmsg_level == SOL_IP)
326 {
327 dest = get_dst_v4(cmsgptr, port);
328 }
329 else if (cmsgptr->cmsg_level == SOL_IPV6)
330 {
331 dest = get_dst_v6(cmsgptr, port);
332 }
333 if (dest)
334 {
335 break;
336 }
337 }
338 if (dest == NULL)
339 {
340 DBG1(DBG_NET, "error reading IP header");
341 return FAILED;
342 }
343 source = host_create_from_sockaddr((sockaddr_t*)&src);
344
345 pkt = packet_create();
346 pkt->set_source(pkt, source);
347 pkt->set_destination(pkt, dest);
348 DBG2(DBG_NET, "received packet: from %#H to %#H", source, dest);
349 data = chunk_create(buffer, bytes_read);
350 pkt->set_data(pkt, chunk_clone(data));
351 }
352 else
353 {
354 /* oops, shouldn't happen */
355 return FAILED;
356 }
357 /* return packet */
358 *packet = pkt;
359 return SUCCESS;
360 }
361
362 /**
363 * Generic function to send a message.
364 */
365 static ssize_t send_msg_generic(int skt, struct msghdr *msg)
366 {
367 return sendmsg(skt, msg, 0);
368 }
369
370 #if defined(IP_PKTINFO) || defined(HAVE_IN6_PKTINFO)
371
372 /**
373 * Find the interface index a source address is installed on
374 */
375 static int find_srcif(host_t *src)
376 {
377 char *ifname;
378 int idx = 0;
379
380 if (charon->kernel->get_interface(charon->kernel, src, &ifname))
381 {
382 idx = if_nametoindex(ifname);
383 free(ifname);
384 }
385 return idx;
386 }
387
388 #endif /* IP_PKTINFO || HAVE_IN6_PKTINFO */
389
390 /**
391 * Send a message with the IPv4 source address set, if possible.
392 */
393 #ifdef IP_PKTINFO
394
395 static ssize_t send_msg_v4(private_socket_default_socket_t *this, int skt,
396 struct msghdr *msg, host_t *src)
397 {
398 char buf[CMSG_SPACE(sizeof(struct in_pktinfo))] = {};
399 struct cmsghdr *cmsg;
400 struct in_addr *addr;
401 struct in_pktinfo *pktinfo;
402 struct sockaddr_in *sin;
403
404 msg->msg_control = buf;
405 msg->msg_controllen = sizeof(buf);
406 cmsg = CMSG_FIRSTHDR(msg);
407 cmsg->cmsg_level = SOL_IP;
408 cmsg->cmsg_type = IP_PKTINFO;
409 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
410
411 pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg);
412 if (this->set_sourceif)
413 {
414 pktinfo->ipi_ifindex = find_srcif(src);
415 }
416 addr = &pktinfo->ipi_spec_dst;
417
418 sin = (struct sockaddr_in*)src->get_sockaddr(src);
419 memcpy(addr, &sin->sin_addr, sizeof(struct in_addr));
420 return send_msg_generic(skt, msg);
421 }
422
423 #elif defined(IP_SENDSRCADDR)
424
425 static ssize_t send_msg_v4(private_socket_default_socket_t *this, int skt,
426 struct msghdr *msg, host_t *src)
427 {
428 char buf[CMSG_SPACE(sizeof(struct in_addr))] = {};
429 struct cmsghdr *cmsg;
430 struct in_addr *addr;
431 struct sockaddr_in *sin;
432
433 msg->msg_control = buf;
434 msg->msg_controllen = sizeof(buf);
435 cmsg = CMSG_FIRSTHDR(msg);
436 cmsg->cmsg_level = SOL_IP;
437 cmsg->cmsg_type = IP_SENDSRCADDR;
438 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
439
440 addr = (struct in_addr*)CMSG_DATA(cmsg);
441
442 sin = (struct sockaddr_in*)src->get_sockaddr(src);
443 memcpy(addr, &sin->sin_addr, sizeof(struct in_addr));
444 return send_msg_generic(skt, msg);
445 }
446
447 #else /* IP_PKTINFO || IP_RECVDSTADDR */
448
449 static ssize_t send_msg_v4(private_socket_default_socket_t *this,
450 int skt, struct msghdr *msg, host_t *src)
451 {
452 return send_msg_generic(skt, msg);
453 }
454
455 #endif /* IP_PKTINFO || IP_RECVDSTADDR */
456
457 /**
458 * Send a message with the IPv6 source address set, if possible.
459 */
460 #ifdef HAVE_IN6_PKTINFO
461
462 static ssize_t send_msg_v6(private_socket_default_socket_t *this, int skt,
463 struct msghdr *msg, host_t *src)
464 {
465 char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))] = {};
466 struct cmsghdr *cmsg;
467 struct in6_pktinfo *pktinfo;
468 struct sockaddr_in6 *sin;
469
470 msg->msg_control = buf;
471 msg->msg_controllen = sizeof(buf);
472 cmsg = CMSG_FIRSTHDR(msg);
473 cmsg->cmsg_level = SOL_IPV6;
474 cmsg->cmsg_type = IPV6_PKTINFO;
475 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
476 pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg);
477 if (this->set_sourceif)
478 {
479 pktinfo->ipi6_ifindex = find_srcif(src);
480 }
481 sin = (struct sockaddr_in6*)src->get_sockaddr(src);
482 memcpy(&pktinfo->ipi6_addr, &sin->sin6_addr, sizeof(struct in6_addr));
483 return send_msg_generic(skt, msg);
484 }
485
486 #else /* HAVE_IN6_PKTINFO */
487
488 static ssize_t send_msg_v6(private_socket_default_socket_t *this,
489 int skt, struct msghdr *msg, host_t *src)
490 {
491 return send_msg_generic(skt, msg);
492 }
493
494 #endif /* HAVE_IN6_PKTINFO */
495
496 METHOD(socket_t, sender, status_t,
497 private_socket_default_socket_t *this, packet_t *packet)
498 {
499 int sport, skt = -1, family;
500 ssize_t bytes_sent;
501 chunk_t data;
502 host_t *src, *dst;
503 struct msghdr msg;
504 struct iovec iov;
505 uint8_t *dscp;
506
507 src = packet->get_source(packet);
508 dst = packet->get_destination(packet);
509 data = packet->get_data(packet);
510
511 DBG2(DBG_NET, "sending packet: from %#H to %#H", src, dst);
512
513 /* send data */
514 sport = src->get_port(src);
515 family = dst->get_family(dst);
516 if (sport == 0 || sport == this->port)
517 {
518 switch (family)
519 {
520 case AF_INET:
521 skt = this->ipv4;
522 dscp = &this->dscp4;
523 break;
524 case AF_INET6:
525 skt = this->ipv6;
526 dscp = &this->dscp6;
527 break;
528 default:
529 return FAILED;
530 }
531 }
532 else if (sport == this->natt)
533 {
534 switch (family)
535 {
536 case AF_INET:
537 skt = this->ipv4_natt;
538 dscp = &this->dscp4_natt;
539 break;
540 case AF_INET6:
541 skt = this->ipv6_natt;
542 dscp = &this->dscp6_natt;
543 break;
544 default:
545 return FAILED;
546 }
547 }
548 if (skt == -1)
549 {
550 DBG1(DBG_NET, "no socket found to send IPv%d packet from port %d",
551 family == AF_INET ? 4 : 6, sport);
552 return FAILED;
553 }
554
555 /* setting DSCP values per-packet in a cmsg seems not to be supported
556 * on Linux. We instead setsockopt() before sending it, this should be
557 * safe as only a single thread calls send(). */
558 if (*dscp != packet->get_dscp(packet))
559 {
560 if (family == AF_INET)
561 {
562 uint8_t ds4;
563
564 ds4 = packet->get_dscp(packet) << 2;
565 if (setsockopt(skt, SOL_IP, IP_TOS, &ds4, sizeof(ds4)) == 0)
566 {
567 *dscp = packet->get_dscp(packet);
568 }
569 else
570 {
571 DBG1(DBG_NET, "unable to set IP_TOS on socket: %s",
572 strerror(errno));
573 }
574 }
575 else
576 {
577 u_int ds6;
578
579 ds6 = packet->get_dscp(packet) << 2;
580 if (setsockopt(skt, SOL_IPV6, IPV6_TCLASS, &ds6, sizeof(ds6)) == 0)
581 {
582 *dscp = packet->get_dscp(packet);
583 }
584 else
585 {
586 DBG1(DBG_NET, "unable to set IPV6_TCLASS on socket: %s",
587 strerror(errno));
588 }
589 }
590 }
591
592 memset(&msg, 0, sizeof(struct msghdr));
593 msg.msg_name = dst->get_sockaddr(dst);;
594 msg.msg_namelen = *dst->get_sockaddr_len(dst);
595 iov.iov_base = data.ptr;
596 iov.iov_len = data.len;
597 msg.msg_iov = &iov;
598 msg.msg_iovlen = 1;
599 msg.msg_flags = 0;
600
601 if (this->set_source && !src->is_anyaddr(src))
602 {
603 if (family == AF_INET)
604 {
605 bytes_sent = send_msg_v4(this, skt, &msg, src);
606 }
607 else
608 {
609 bytes_sent = send_msg_v6(this, skt, &msg, src);
610 }
611 }
612 else
613 {
614 bytes_sent = send_msg_generic(skt, &msg);
615 }
616
617 if (bytes_sent != data.len)
618 {
619 DBG1(DBG_NET, "error writing to socket: %s", strerror(errno));
620 return FAILED;
621 }
622 return SUCCESS;
623 }
624
625 METHOD(socket_t, get_port, uint16_t,
626 private_socket_default_socket_t *this, bool nat_t)
627 {
628 return nat_t ? this->natt : this->port;
629 }
630
631 METHOD(socket_t, supported_families, socket_family_t,
632 private_socket_default_socket_t *this)
633 {
634 socket_family_t families = SOCKET_FAMILY_NONE;
635
636 if (this->ipv4 != -1 || this->ipv4_natt != -1)
637 {
638 families |= SOCKET_FAMILY_IPV4;
639 }
640 if (this->ipv6 != -1 || this->ipv6_natt != -1)
641 {
642 families |= SOCKET_FAMILY_IPV6;
643 }
644 return families;
645 }
646
647 /**
648 * open a socket to send and receive packets
649 */
650 static int open_socket(private_socket_default_socket_t *this,
651 int family, uint16_t *port)
652 {
653 int on = TRUE;
654 union {
655 struct sockaddr sockaddr;
656 struct sockaddr_in sin;
657 struct sockaddr_in6 sin6;
658 } addr;
659 socklen_t addrlen;
660 u_int sol, pktinfo = 0;
661 int skt;
662
663 memset(&addr, 0, sizeof(addr));
664 addr.sockaddr.sa_family = family;
665 /* precalculate constants depending on address family */
666 switch (family)
667 {
668 case AF_INET:
669 addr.sin.sin_addr.s_addr = htonl(INADDR_ANY);
670 addr.sin.sin_port = htons(*port);
671 addrlen = sizeof(addr.sin);
672 sol = SOL_IP;
673 #ifdef IP_PKTINFO
674 pktinfo = IP_PKTINFO;
675 #elif defined(IP_RECVDSTADDR)
676 pktinfo = IP_RECVDSTADDR;
677 #endif
678 break;
679 case AF_INET6:
680 memcpy(&addr.sin6.sin6_addr, &in6addr_any, sizeof(in6addr_any));
681 addr.sin6.sin6_port = htons(*port);
682 addrlen = sizeof(addr.sin6);
683 sol = SOL_IPV6;
684 pktinfo = IPV6_RECVPKTINFO;
685 break;
686 default:
687 return -1;
688 }
689
690 skt = socket(family, SOCK_DGRAM, IPPROTO_UDP);
691 if (skt < 0)
692 {
693 DBG1(DBG_NET, "could not open socket: %s", strerror(errno));
694 return -1;
695 }
696 if (setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0)
697 {
698 DBG1(DBG_NET, "unable to set SO_REUSEADDR on socket: %s", strerror(errno));
699 close(skt);
700 return -1;
701 }
702
703 /* bind the socket */
704 if (bind(skt, &addr.sockaddr, addrlen) < 0)
705 {
706 DBG1(DBG_NET, "unable to bind socket: %s", strerror(errno));
707 close(skt);
708 return -1;
709 }
710
711 /* retrieve randomly allocated port if needed */
712 if (*port == 0)
713 {
714 if (getsockname(skt, &addr.sockaddr, &addrlen) < 0)
715 {
716 DBG1(DBG_NET, "unable to determine port: %s", strerror(errno));
717 close(skt);
718 return -1;
719 }
720 switch (family)
721 {
722 case AF_INET:
723 *port = ntohs(addr.sin.sin_port);
724 break;
725 case AF_INET6:
726 *port = ntohs(addr.sin6.sin6_port);
727 break;
728 }
729 }
730
731 /* get additional packet info on receive */
732 if (pktinfo > 0)
733 {
734 if (setsockopt(skt, sol, pktinfo, &on, sizeof(on)) < 0)
735 {
736 DBG1(DBG_NET, "unable to set IP_PKTINFO on socket: %s", strerror(errno));
737 close(skt);
738 return -1;
739 }
740 }
741 #ifdef SO_MARK
742 { /* set optional MARK on socket (requires CAP_NET_ADMIN) */
743 char *fwmark;
744 mark_t mark;
745
746 fwmark = lib->settings->get_str(lib->settings,
747 "%s.plugins.socket-default.fwmark", NULL, lib->ns);
748 if (fwmark && mark_from_string(fwmark, &mark))
749 {
750 if (setsockopt(skt, SOL_SOCKET, SO_MARK, &mark.value,
751 sizeof(mark.value)) < 0)
752 {
753 DBG1(DBG_NET, "unable to set SO_MARK on socket: %s",
754 strerror(errno));
755 }
756 }
757 }
758 #endif
759
760 if (!charon->kernel->bypass_socket(charon->kernel, skt, family))
761 {
762 DBG1(DBG_NET, "installing IKE bypass policy failed");
763 }
764
765 /* enable UDP decapsulation for NAT-T sockets */
766 if (port == &this->natt &&
767 !charon->kernel->enable_udp_decap(charon->kernel, skt, family,
768 this->natt))
769 {
770 DBG1(DBG_NET, "enabling UDP decapsulation for %s on port %d failed",
771 family == AF_INET ? "IPv4" : "IPv6", this->natt);
772 }
773
774 return skt;
775 }
776
777 /**
778 * Check if we should use the given family
779 */
780 static bool use_family(int family)
781 {
782 switch (family)
783 {
784 case AF_INET:
785 return lib->settings->get_bool(lib->settings,
786 "%s.plugins.socket-default.use_ipv4", TRUE, lib->ns);
787 case AF_INET6:
788 return lib->settings->get_bool(lib->settings,
789 "%s.plugins.socket-default.use_ipv6", TRUE, lib->ns);
790 default:
791 return FALSE;
792 }
793 }
794
795 /**
796 * Open a socket pair (normal and NAT traversal) for a given address family
797 */
798 static void open_socketpair(private_socket_default_socket_t *this, int family,
799 int *skt, int *skt_natt, char *label)
800 {
801 if (!use_family(family))
802 {
803 *skt = -1;
804 *skt_natt = -1;
805 return;
806 }
807
808 *skt = open_socket(this, family, &this->port);
809 if (*skt == -1)
810 {
811 *skt_natt = -1;
812 DBG1(DBG_NET, "could not open %s socket, %s disabled", label, label);
813 }
814 else
815 {
816 *skt_natt = open_socket(this, family, &this->natt);
817 if (*skt_natt == -1)
818 {
819 DBG1(DBG_NET, "could not open %s NAT-T socket", label);
820 }
821 }
822 }
823
824 METHOD(socket_t, destroy, void,
825 private_socket_default_socket_t *this)
826 {
827 if (this->ipv4 != -1)
828 {
829 close(this->ipv4);
830 }
831 if (this->ipv4_natt != -1)
832 {
833 close(this->ipv4_natt);
834 }
835 if (this->ipv6 != -1)
836 {
837 close(this->ipv6);
838 }
839 if (this->ipv6_natt != -1)
840 {
841 close(this->ipv6_natt);
842 }
843 free(this);
844 }
845
846 /*
847 * See header for description
848 */
849 socket_default_socket_t *socket_default_socket_create()
850 {
851 private_socket_default_socket_t *this;
852
853 INIT(this,
854 .public = {
855 .socket = {
856 .send = _sender,
857 .receive = _receiver,
858 .get_port = _get_port,
859 .supported_families = _supported_families,
860 .destroy = _destroy,
861 },
862 },
863 .port = lib->settings->get_int(lib->settings,
864 "%s.port", CHARON_UDP_PORT, lib->ns),
865 .natt = lib->settings->get_int(lib->settings,
866 "%s.port_nat_t", CHARON_NATT_PORT, lib->ns),
867 .max_packet = lib->settings->get_int(lib->settings,
868 "%s.max_packet", PACKET_MAX_DEFAULT, lib->ns),
869 .set_source = lib->settings->get_bool(lib->settings,
870 "%s.plugins.socket-default.set_source", TRUE,
871 lib->ns),
872 .set_sourceif = lib->settings->get_bool(lib->settings,
873 "%s.plugins.socket-default.set_sourceif", FALSE,
874 lib->ns),
875 );
876
877 if (this->port && this->port == this->natt)
878 {
879 DBG1(DBG_NET, "IKE ports can't be equal, will allocate NAT-T "
880 "port randomly");
881 this->natt = 0;
882 }
883
884 if ((this->port && this->port < 1024) || (this->natt && this->natt < 1024))
885 {
886 if (!lib->caps->check(lib->caps, CAP_NET_BIND_SERVICE))
887 {
888 /* required to bind ports < 1024 */
889 DBG1(DBG_NET, "socket-default plugin requires CAP_NET_BIND_SERVICE "
890 "capability");
891 destroy(this);
892 return NULL;
893 }
894 }
895
896 /* we allocate IPv6 sockets first as that will reserve randomly allocated
897 * ports also for IPv4. On OS X, we have to do it the other way round
898 * for the same effect. */
899 #ifdef __APPLE__
900 open_socketpair(this, AF_INET, &this->ipv4, &this->ipv4_natt, "IPv4");
901 open_socketpair(this, AF_INET6, &this->ipv6, &this->ipv6_natt, "IPv6");
902 #else /* !__APPLE__ */
903 open_socketpair(this, AF_INET6, &this->ipv6, &this->ipv6_natt, "IPv6");
904 open_socketpair(this, AF_INET, &this->ipv4, &this->ipv4_natt, "IPv4");
905 #endif /* __APPLE__ */
906
907 if (this->ipv4 == -1 && this->ipv6 == -1)
908 {
909 DBG1(DBG_NET, "could not create any sockets");
910 destroy(this);
911 return NULL;
912 }
913
914 return &this->public;
915 }