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 * Copyright (C) 2010 revosec AG
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>.
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
20 /* for struct in6_pktinfo */
23 #include "socket_dynamic_socket.h"
25 #include <sys/types.h>
26 #include <sys/socket.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>
41 #include <threading/thread.h>
42 #include <threading/rwlock.h>
43 #include <collections/hashtable.h>
45 /* Maximum size of a packet */
46 #define MAX_PACKET 10000
48 /* these are not defined on some platforms */
50 #define SOL_IP IPPROTO_IP
53 #define SOL_IPV6 IPPROTO_IPV6
56 /* IPV6_RECVPKTINFO is defined in RFC 3542 which obsoletes RFC 2292 that
57 * previously defined IPV6_PKTINFO */
58 #ifndef IPV6_RECVPKTINFO
59 #define IPV6_RECVPKTINFO IPV6_PKTINFO
62 typedef struct private_socket_dynamic_socket_t private_socket_dynamic_socket_t
;
63 typedef struct dynsock_t dynsock_t
;
66 * Private data of an socket_t object
68 struct private_socket_dynamic_socket_t
{
73 socket_dynamic_socket_t
public;
76 * Hashtable of bound sockets
81 * Lock for sockets hashtable
86 * Notification pipe to signal receiver
91 * Maximum packet size to receive
97 * Struct for a dynamically allocated socket
102 * File descriptor of socket
118 * Hash function for hashtable
120 static u_int
hash(dynsock_t
*key
)
122 return (key
->family
<< 16) | key
->port
;
126 * Equals function for hashtable
128 static bool equals(dynsock_t
*a
, dynsock_t
*b
)
130 return a
->family
== b
->family
&& a
->port
== b
->port
;
134 * Create a fd_set from all bound sockets
136 static int build_fds(private_socket_dynamic_socket_t
*this, fd_set
*fds
)
138 enumerator_t
*enumerator
;
139 dynsock_t
*key
, *value
;
143 FD_SET(this->notify
[0], fds
);
144 maxfd
= this->notify
[0];
146 this->lock
->read_lock(this->lock
);
147 enumerator
= this->sockets
->create_enumerator(this->sockets
);
148 while (enumerator
->enumerate(enumerator
, &key
, &value
))
150 FD_SET(value
->fd
, fds
);
151 maxfd
= max(maxfd
, value
->fd
);
153 enumerator
->destroy(enumerator
);
154 this->lock
->unlock(this->lock
);
160 * Find the socket select()ed
162 static dynsock_t
* scan_fds(private_socket_dynamic_socket_t
*this, fd_set
*fds
)
164 enumerator_t
*enumerator
;
165 dynsock_t
*key
, *value
, *selected
= NULL
;
167 this->lock
->read_lock(this->lock
);
168 enumerator
= this->sockets
->create_enumerator(this->sockets
);
169 while (enumerator
->enumerate(enumerator
, &key
, &value
))
171 if (FD_ISSET(value
->fd
, fds
))
177 enumerator
->destroy(enumerator
);
178 this->lock
->unlock(this->lock
);
184 * Receive a packet from a given socket fd
186 static packet_t
*receive_packet(private_socket_dynamic_socket_t
*this,
189 host_t
*source
= NULL
, *dest
= NULL
;
191 char buffer
[this->max_packet
];
195 struct cmsghdr
*cmsgptr
;
199 struct sockaddr_in in4
;
200 struct sockaddr_in6 in6
;
204 msg
.msg_namelen
= sizeof(src
);
205 iov
.iov_base
= buffer
;
206 iov
.iov_len
= this->max_packet
;
209 msg
.msg_control
= ancillary
;
210 msg
.msg_controllen
= sizeof(ancillary
);
212 len
= recvmsg(skt
->fd
, &msg
, 0);
215 DBG1(DBG_NET
, "error reading socket: %s", strerror(errno
));
218 if (msg
.msg_flags
& MSG_TRUNC
)
220 DBG1(DBG_NET
, "receive buffer too small, packet discarded");
223 DBG3(DBG_NET
, "received packet %b", buffer
, (u_int
)len
);
225 /* read ancillary data to get destination address */
226 for (cmsgptr
= CMSG_FIRSTHDR(&msg
); cmsgptr
!= NULL
;
227 cmsgptr
= CMSG_NXTHDR(&msg
, cmsgptr
))
229 if (cmsgptr
->cmsg_len
== 0)
231 DBG1(DBG_NET
, "error reading ancillary data");
235 if (cmsgptr
->cmsg_level
== SOL_IPV6
&&
236 cmsgptr
->cmsg_type
== IPV6_PKTINFO
)
238 struct in6_pktinfo
*pktinfo
;
239 struct sockaddr_in6 dst
;
241 pktinfo
= (struct in6_pktinfo
*)CMSG_DATA(cmsgptr
);
242 memset(&dst
, 0, sizeof(dst
));
243 memcpy(&dst
.sin6_addr
, &pktinfo
->ipi6_addr
, sizeof(dst
.sin6_addr
));
244 dst
.sin6_family
= AF_INET6
;
245 dst
.sin6_port
= htons(skt
->port
);
246 dest
= host_create_from_sockaddr((sockaddr_t
*)&dst
);
248 if (cmsgptr
->cmsg_level
== SOL_IP
&&
249 cmsgptr
->cmsg_type
== IP_PKTINFO
)
251 struct in_pktinfo
*pktinfo
;
252 struct sockaddr_in dst
;
254 pktinfo
= (struct in_pktinfo
*)CMSG_DATA(cmsgptr
);
255 memset(&dst
, 0, sizeof(dst
));
256 memcpy(&dst
.sin_addr
, &pktinfo
->ipi_addr
, sizeof(dst
.sin_addr
));
258 dst
.sin_family
= AF_INET
;
259 dst
.sin_port
= htons(skt
->port
);
260 dest
= host_create_from_sockaddr((sockaddr_t
*)&dst
);
269 DBG1(DBG_NET
, "error reading IP header");
272 source
= host_create_from_sockaddr((sockaddr_t
*)&src
);
273 DBG2(DBG_NET
, "received packet: from %#H to %#H", source
, dest
);
274 data
= chunk_create(buffer
, len
);
276 packet
= packet_create();
277 packet
->set_source(packet
, source
);
278 packet
->set_destination(packet
, dest
);
279 packet
->set_data(packet
, chunk_clone(data
));
283 METHOD(socket_t
, receiver
, status_t
,
284 private_socket_dynamic_socket_t
*this, packet_t
**packet
)
294 maxfd
= build_fds(this, &fds
);
296 DBG2(DBG_NET
, "waiting for data on sockets");
297 oldstate
= thread_cancelability(TRUE
);
298 if (select(maxfd
, &fds
, NULL
, NULL
, NULL
) <= 0)
300 thread_cancelability(oldstate
);
303 thread_cancelability(oldstate
);
305 if (FD_ISSET(this->notify
[0], &fds
))
306 { /* got notified, read garbage, rebuild fdset */
309 ignore_result(read(this->notify
[0], buf
, sizeof(buf
)));
310 DBG2(DBG_NET
, "rebuilding fdset due to newly bound ports");
313 selected
= scan_fds(this, &fds
);
319 pkt
= receive_packet(this, selected
);
329 * Get the port allocated dynamically using bind()
331 static bool get_dynamic_port(int fd
, int family
, u_int16_t
*port
)
334 struct sockaddr_storage ss
;
336 struct sockaddr_in sin
;
337 struct sockaddr_in6 sin6
;
341 addrlen
= sizeof(addr
);
342 if (getsockname(fd
, &addr
.s
, &addrlen
) != 0)
344 DBG1(DBG_NET
, "unable to getsockname: %s", strerror(errno
));
350 if (addrlen
!= sizeof(addr
.sin
) || addr
.sin
.sin_family
!= family
)
354 *port
= ntohs(addr
.sin
.sin_port
);
357 if (addrlen
!= sizeof(addr
.sin6
) || addr
.sin6
.sin6_family
!= family
)
361 *port
= ntohs(addr
.sin6
.sin6_port
);
366 DBG1(DBG_NET
, "received invalid getsockname() result");
371 * open a socket to send and receive packets
373 static int open_socket(private_socket_dynamic_socket_t
*this,
374 int family
, u_int16_t
*port
)
377 struct sockaddr_storage ss
;
379 struct sockaddr_in sin
;
380 struct sockaddr_in6 sin6
;
384 u_int sol
, pktinfo
= 0;
387 memset(&addr
, 0, sizeof(addr
));
388 /* precalculate constants depending on address family */
392 addr
.sin
.sin_family
= AF_INET
;
393 addr
.sin
.sin_addr
.s_addr
= INADDR_ANY
;
394 addr
.sin
.sin_port
= htons(*port
);
395 addrlen
= sizeof(addr
.sin
);
397 pktinfo
= IP_PKTINFO
;
400 addr
.sin6
.sin6_family
= AF_INET6
;
401 memset(&addr
.sin6
.sin6_addr
, 0, sizeof(addr
.sin6
));
402 addr
.sin6
.sin6_port
= htons(*port
);
403 addrlen
= sizeof(addr
.sin6
);
405 pktinfo
= IPV6_RECVPKTINFO
;
411 fd
= socket(family
, SOCK_DGRAM
, IPPROTO_UDP
);
414 DBG1(DBG_NET
, "could not open socket: %s", strerror(errno
));
417 if (setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&on
, sizeof(on
)) < 0)
419 DBG1(DBG_NET
, "unable to set SO_REUSEADDR on socket: %s", strerror(errno
));
424 if (bind(fd
, &addr
.s
, addrlen
) < 0)
426 DBG1(DBG_NET
, "unable to bind socket: %s", strerror(errno
));
430 if (*port
== 0 && !get_dynamic_port(fd
, family
, port
))
436 /* get additional packet info on receive */
437 if (setsockopt(fd
, sol
, pktinfo
, &on
, sizeof(on
)) < 0)
439 DBG1(DBG_NET
, "unable to set IP_PKTINFO on socket: %s", strerror(errno
));
444 if (!hydra
->kernel_interface
->bypass_socket(hydra
->kernel_interface
,
447 DBG1(DBG_NET
, "installing IKE bypass policy failed");
450 /* enable UDP decapsulation on each socket */
451 if (!hydra
->kernel_interface
->enable_udp_decap(hydra
->kernel_interface
,
454 DBG1(DBG_NET
, "enabling UDP decapsulation for %s on port %d failed",
455 family
== AF_INET ?
"IPv4" : "IPv6", *port
);
462 * Get the first usable socket for an address family
464 static dynsock_t
*get_any_socket(private_socket_dynamic_socket_t
*this,
467 dynsock_t
*key
, *value
, *found
= NULL
;
468 enumerator_t
*enumerator
;
470 this->lock
->read_lock(this->lock
);
471 enumerator
= this->sockets
->create_enumerator(this->sockets
);
472 while (enumerator
->enumerate(enumerator
, &key
, &value
))
474 if (value
->family
== family
)
480 enumerator
->destroy(enumerator
);
481 this->lock
->unlock(this->lock
);
487 * Find/Create a socket to send from host
489 static dynsock_t
*find_socket(private_socket_dynamic_socket_t
*this,
490 int family
, u_int16_t port
)
492 dynsock_t
*skt
, lookup
= {
499 this->lock
->read_lock(this->lock
);
500 skt
= this->sockets
->get(this->sockets
, &lookup
);
501 this->lock
->unlock(this->lock
);
508 skt
= get_any_socket(this, family
);
514 fd
= open_socket(this, family
, &port
);
524 this->lock
->write_lock(this->lock
);
525 this->sockets
->put(this->sockets
, skt
, skt
);
526 this->lock
->unlock(this->lock
);
527 /* notify receiver thread to reread socket list */
528 ignore_result(write(this->notify
[1], buf
, sizeof(buf
)));
533 METHOD(socket_t
, sender
, status_t
,
534 private_socket_dynamic_socket_t
*this, packet_t
*packet
)
542 struct cmsghdr
*cmsg
;
545 src
= packet
->get_source(packet
);
546 dst
= packet
->get_destination(packet
);
547 family
= src
->get_family(src
);
548 skt
= find_socket(this, family
, src
->get_port(src
));
554 data
= packet
->get_data(packet
);
555 DBG2(DBG_NET
, "sending packet: from %#H to %#H", src
, dst
);
557 memset(&msg
, 0, sizeof(struct msghdr
));
558 msg
.msg_name
= dst
->get_sockaddr(dst
);;
559 msg
.msg_namelen
= *dst
->get_sockaddr_len(dst
);
560 iov
.iov_base
= data
.ptr
;
561 iov
.iov_len
= data
.len
;
566 if (!src
->is_anyaddr(src
))
568 if (family
== AF_INET
)
570 struct in_addr
*addr
;
571 struct sockaddr_in
*sin
;
572 char buf
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
573 struct in_pktinfo
*pktinfo
;
575 msg
.msg_control
= buf
;
576 msg
.msg_controllen
= sizeof(buf
);
577 cmsg
= CMSG_FIRSTHDR(&msg
);
578 cmsg
->cmsg_level
= SOL_IP
;
579 cmsg
->cmsg_type
= IP_PKTINFO
;
580 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct in_pktinfo
));
581 pktinfo
= (struct in_pktinfo
*)CMSG_DATA(cmsg
);
582 memset(pktinfo
, 0, sizeof(struct in_pktinfo
));
583 addr
= &pktinfo
->ipi_spec_dst
;
584 sin
= (struct sockaddr_in
*)src
->get_sockaddr(src
);
585 memcpy(addr
, &sin
->sin_addr
, sizeof(struct in_addr
));
589 char buf
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
590 struct in6_pktinfo
*pktinfo
;
591 struct sockaddr_in6
*sin
;
593 msg
.msg_control
= buf
;
594 msg
.msg_controllen
= sizeof(buf
);
595 cmsg
= CMSG_FIRSTHDR(&msg
);
596 cmsg
->cmsg_level
= SOL_IPV6
;
597 cmsg
->cmsg_type
= IPV6_PKTINFO
;
598 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct in6_pktinfo
));
599 pktinfo
= (struct in6_pktinfo
*)CMSG_DATA(cmsg
);
600 memset(pktinfo
, 0, sizeof(struct in6_pktinfo
));
601 sin
= (struct sockaddr_in6
*)src
->get_sockaddr(src
);
602 memcpy(&pktinfo
->ipi6_addr
, &sin
->sin6_addr
, sizeof(struct in6_addr
));
606 len
= sendmsg(skt
->fd
, &msg
, 0);
609 DBG1(DBG_NET
, "error writing to socket: %s", strerror(errno
));
615 METHOD(socket_t
, get_port
, u_int16_t
,
616 private_socket_dynamic_socket_t
*this, bool nat_t
)
618 /* we return 0 here for users that have no explicit port configured, the
619 * sender will default to the default port in this case */
623 METHOD(socket_t
, supported_families
, socket_family_t
,
624 private_socket_dynamic_socket_t
*this)
626 /* we could return only the families of the opened sockets, but it could
627 * be that both families are supported even if no socket is yet open */
628 return SOCKET_FAMILY_BOTH
;
631 METHOD(socket_t
, destroy
, void,
632 private_socket_dynamic_socket_t
*this)
634 enumerator_t
*enumerator
;
635 dynsock_t
*key
, *value
;
637 enumerator
= this->sockets
->create_enumerator(this->sockets
);
638 while (enumerator
->enumerate(enumerator
, &key
, &value
))
643 enumerator
->destroy(enumerator
);
644 this->sockets
->destroy(this->sockets
);
645 this->lock
->destroy(this->lock
);
647 close(this->notify
[0]);
648 close(this->notify
[1]);
653 * See header for description
655 socket_dynamic_socket_t
*socket_dynamic_socket_create()
657 private_socket_dynamic_socket_t
*this;
663 .receive
= _receiver
,
664 .get_port
= _get_port
,
665 .supported_families
= _supported_families
,
669 .lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
),
670 .max_packet
= lib
->settings
->get_int(lib
->settings
,
671 "%s.max_packet", MAX_PACKET
, charon
->name
),
674 if (pipe(this->notify
) != 0)
676 DBG1(DBG_NET
, "creating notify pipe for dynamic socket failed");
681 this->sockets
= hashtable_create((void*)hash
, (void*)equals
, 8);
683 return &this->public;