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 /* these are not defined on some platforms */
47 #define SOL_IP IPPROTO_IP
50 #define SOL_IPV6 IPPROTO_IPV6
53 /* IPV6_RECVPKTINFO is defined in RFC 3542 which obsoletes RFC 2292 that
54 * previously defined IPV6_PKTINFO */
55 #ifndef IPV6_RECVPKTINFO
56 #define IPV6_RECVPKTINFO IPV6_PKTINFO
59 typedef struct private_socket_dynamic_socket_t private_socket_dynamic_socket_t
;
60 typedef struct dynsock_t dynsock_t
;
63 * Private data of an socket_t object
65 struct private_socket_dynamic_socket_t
{
70 socket_dynamic_socket_t
public;
73 * Hashtable of bound sockets
78 * Lock for sockets hashtable
83 * Notification pipe to signal receiver
88 * Maximum packet size to receive
94 * Struct for a dynamically allocated socket
99 * File descriptor of socket
115 * Hash function for hashtable
117 static u_int
hash(dynsock_t
*key
)
119 return (key
->family
<< 16) | key
->port
;
123 * Equals function for hashtable
125 static bool equals(dynsock_t
*a
, dynsock_t
*b
)
127 return a
->family
== b
->family
&& a
->port
== b
->port
;
131 * Create a fd_set from all bound sockets
133 static int build_fds(private_socket_dynamic_socket_t
*this, fd_set
*fds
)
135 enumerator_t
*enumerator
;
136 dynsock_t
*key
, *value
;
140 FD_SET(this->notify
[0], fds
);
141 maxfd
= this->notify
[0];
143 this->lock
->read_lock(this->lock
);
144 enumerator
= this->sockets
->create_enumerator(this->sockets
);
145 while (enumerator
->enumerate(enumerator
, &key
, &value
))
147 FD_SET(value
->fd
, fds
);
148 maxfd
= max(maxfd
, value
->fd
);
150 enumerator
->destroy(enumerator
);
151 this->lock
->unlock(this->lock
);
157 * Find the socket select()ed
159 static dynsock_t
* scan_fds(private_socket_dynamic_socket_t
*this, fd_set
*fds
)
161 enumerator_t
*enumerator
;
162 dynsock_t
*key
, *value
, *selected
= NULL
;
164 this->lock
->read_lock(this->lock
);
165 enumerator
= this->sockets
->create_enumerator(this->sockets
);
166 while (enumerator
->enumerate(enumerator
, &key
, &value
))
168 if (FD_ISSET(value
->fd
, fds
))
174 enumerator
->destroy(enumerator
);
175 this->lock
->unlock(this->lock
);
181 * Receive a packet from a given socket fd
183 static packet_t
*receive_packet(private_socket_dynamic_socket_t
*this,
186 host_t
*source
= NULL
, *dest
= NULL
;
188 char buffer
[this->max_packet
];
192 struct cmsghdr
*cmsgptr
;
196 struct sockaddr_in in4
;
197 struct sockaddr_in6 in6
;
201 msg
.msg_namelen
= sizeof(src
);
202 iov
.iov_base
= buffer
;
203 iov
.iov_len
= this->max_packet
;
206 msg
.msg_control
= ancillary
;
207 msg
.msg_controllen
= sizeof(ancillary
);
209 len
= recvmsg(skt
->fd
, &msg
, 0);
212 DBG1(DBG_NET
, "error reading socket: %s", strerror(errno
));
215 if (msg
.msg_flags
& MSG_TRUNC
)
217 DBG1(DBG_NET
, "receive buffer too small, packet discarded");
220 DBG3(DBG_NET
, "received packet %b", buffer
, (u_int
)len
);
222 /* read ancillary data to get destination address */
223 for (cmsgptr
= CMSG_FIRSTHDR(&msg
); cmsgptr
!= NULL
;
224 cmsgptr
= CMSG_NXTHDR(&msg
, cmsgptr
))
226 if (cmsgptr
->cmsg_len
== 0)
228 DBG1(DBG_NET
, "error reading ancillary data");
232 if (cmsgptr
->cmsg_level
== SOL_IPV6
&&
233 cmsgptr
->cmsg_type
== IPV6_PKTINFO
)
235 struct in6_pktinfo
*pktinfo
;
236 struct sockaddr_in6 dst
;
238 pktinfo
= (struct in6_pktinfo
*)CMSG_DATA(cmsgptr
);
239 memset(&dst
, 0, sizeof(dst
));
240 memcpy(&dst
.sin6_addr
, &pktinfo
->ipi6_addr
, sizeof(dst
.sin6_addr
));
241 dst
.sin6_family
= AF_INET6
;
242 dst
.sin6_port
= htons(skt
->port
);
243 dest
= host_create_from_sockaddr((sockaddr_t
*)&dst
);
245 if (cmsgptr
->cmsg_level
== SOL_IP
&&
246 cmsgptr
->cmsg_type
== IP_PKTINFO
)
248 struct in_pktinfo
*pktinfo
;
249 struct sockaddr_in dst
;
251 pktinfo
= (struct in_pktinfo
*)CMSG_DATA(cmsgptr
);
252 memset(&dst
, 0, sizeof(dst
));
253 memcpy(&dst
.sin_addr
, &pktinfo
->ipi_addr
, sizeof(dst
.sin_addr
));
255 dst
.sin_family
= AF_INET
;
256 dst
.sin_port
= htons(skt
->port
);
257 dest
= host_create_from_sockaddr((sockaddr_t
*)&dst
);
266 DBG1(DBG_NET
, "error reading IP header");
269 source
= host_create_from_sockaddr((sockaddr_t
*)&src
);
270 DBG2(DBG_NET
, "received packet: from %#H to %#H", source
, dest
);
271 data
= chunk_create(buffer
, len
);
273 packet
= packet_create();
274 packet
->set_source(packet
, source
);
275 packet
->set_destination(packet
, dest
);
276 packet
->set_data(packet
, chunk_clone(data
));
280 METHOD(socket_t
, receiver
, status_t
,
281 private_socket_dynamic_socket_t
*this, packet_t
**packet
)
291 maxfd
= build_fds(this, &fds
);
293 DBG2(DBG_NET
, "waiting for data on sockets");
294 oldstate
= thread_cancelability(TRUE
);
295 if (select(maxfd
, &fds
, NULL
, NULL
, NULL
) <= 0)
297 thread_cancelability(oldstate
);
300 thread_cancelability(oldstate
);
302 if (FD_ISSET(this->notify
[0], &fds
))
303 { /* got notified, read garbage, rebuild fdset */
306 ignore_result(read(this->notify
[0], buf
, sizeof(buf
)));
307 DBG2(DBG_NET
, "rebuilding fdset due to newly bound ports");
310 selected
= scan_fds(this, &fds
);
316 pkt
= receive_packet(this, selected
);
326 * Get the port allocated dynamically using bind()
328 static bool get_dynamic_port(int fd
, int family
, u_int16_t
*port
)
331 struct sockaddr_storage ss
;
333 struct sockaddr_in sin
;
334 struct sockaddr_in6 sin6
;
338 addrlen
= sizeof(addr
);
339 if (getsockname(fd
, &addr
.s
, &addrlen
) != 0)
341 DBG1(DBG_NET
, "unable to getsockname: %s", strerror(errno
));
347 if (addrlen
!= sizeof(addr
.sin
) || addr
.sin
.sin_family
!= family
)
351 *port
= ntohs(addr
.sin
.sin_port
);
354 if (addrlen
!= sizeof(addr
.sin6
) || addr
.sin6
.sin6_family
!= family
)
358 *port
= ntohs(addr
.sin6
.sin6_port
);
363 DBG1(DBG_NET
, "received invalid getsockname() result");
368 * open a socket to send and receive packets
370 static int open_socket(private_socket_dynamic_socket_t
*this,
371 int family
, u_int16_t
*port
)
374 struct sockaddr_storage ss
;
376 struct sockaddr_in sin
;
377 struct sockaddr_in6 sin6
;
381 u_int sol
, pktinfo
= 0;
384 memset(&addr
, 0, sizeof(addr
));
385 /* precalculate constants depending on address family */
389 addr
.sin
.sin_family
= AF_INET
;
390 addr
.sin
.sin_addr
.s_addr
= INADDR_ANY
;
391 addr
.sin
.sin_port
= htons(*port
);
392 addrlen
= sizeof(addr
.sin
);
394 pktinfo
= IP_PKTINFO
;
397 addr
.sin6
.sin6_family
= AF_INET6
;
398 memset(&addr
.sin6
.sin6_addr
, 0, sizeof(addr
.sin6
.sin6_addr
));
399 addr
.sin6
.sin6_port
= htons(*port
);
400 addrlen
= sizeof(addr
.sin6
);
402 pktinfo
= IPV6_RECVPKTINFO
;
408 fd
= socket(family
, SOCK_DGRAM
, IPPROTO_UDP
);
411 DBG1(DBG_NET
, "could not open socket: %s", strerror(errno
));
414 if (setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&on
, sizeof(on
)) < 0)
416 DBG1(DBG_NET
, "unable to set SO_REUSEADDR on socket: %s", strerror(errno
));
421 if (bind(fd
, &addr
.s
, addrlen
) < 0)
423 DBG1(DBG_NET
, "unable to bind socket: %s", strerror(errno
));
427 if (*port
== 0 && !get_dynamic_port(fd
, family
, port
))
433 /* get additional packet info on receive */
434 if (setsockopt(fd
, sol
, pktinfo
, &on
, sizeof(on
)) < 0)
436 DBG1(DBG_NET
, "unable to set IP_PKTINFO on socket: %s", strerror(errno
));
441 if (!hydra
->kernel_interface
->bypass_socket(hydra
->kernel_interface
,
444 DBG1(DBG_NET
, "installing IKE bypass policy failed");
447 /* enable UDP decapsulation on each socket */
448 if (!hydra
->kernel_interface
->enable_udp_decap(hydra
->kernel_interface
,
451 DBG1(DBG_NET
, "enabling UDP decapsulation for %s on port %d failed",
452 family
== AF_INET ?
"IPv4" : "IPv6", *port
);
459 * Get the first usable socket for an address family
461 static dynsock_t
*get_any_socket(private_socket_dynamic_socket_t
*this,
464 dynsock_t
*key
, *value
, *found
= NULL
;
465 enumerator_t
*enumerator
;
467 this->lock
->read_lock(this->lock
);
468 enumerator
= this->sockets
->create_enumerator(this->sockets
);
469 while (enumerator
->enumerate(enumerator
, &key
, &value
))
471 if (value
->family
== family
)
477 enumerator
->destroy(enumerator
);
478 this->lock
->unlock(this->lock
);
484 * Find/Create a socket to send from host
486 static dynsock_t
*find_socket(private_socket_dynamic_socket_t
*this,
487 int family
, u_int16_t port
)
489 dynsock_t
*skt
, lookup
= {
496 this->lock
->read_lock(this->lock
);
497 skt
= this->sockets
->get(this->sockets
, &lookup
);
498 this->lock
->unlock(this->lock
);
505 skt
= get_any_socket(this, family
);
511 fd
= open_socket(this, family
, &port
);
521 this->lock
->write_lock(this->lock
);
522 this->sockets
->put(this->sockets
, skt
, skt
);
523 this->lock
->unlock(this->lock
);
524 /* notify receiver thread to reread socket list */
525 ignore_result(write(this->notify
[1], buf
, sizeof(buf
)));
530 METHOD(socket_t
, sender
, status_t
,
531 private_socket_dynamic_socket_t
*this, packet_t
*packet
)
539 struct cmsghdr
*cmsg
;
542 src
= packet
->get_source(packet
);
543 dst
= packet
->get_destination(packet
);
544 family
= src
->get_family(src
);
545 skt
= find_socket(this, family
, src
->get_port(src
));
551 data
= packet
->get_data(packet
);
552 DBG2(DBG_NET
, "sending packet: from %#H to %#H", src
, dst
);
554 memset(&msg
, 0, sizeof(struct msghdr
));
555 msg
.msg_name
= dst
->get_sockaddr(dst
);;
556 msg
.msg_namelen
= *dst
->get_sockaddr_len(dst
);
557 iov
.iov_base
= data
.ptr
;
558 iov
.iov_len
= data
.len
;
563 if (!src
->is_anyaddr(src
))
565 if (family
== AF_INET
)
567 struct in_addr
*addr
;
568 struct sockaddr_in
*sin
;
569 char buf
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
570 struct in_pktinfo
*pktinfo
;
572 memset(buf
, 0, sizeof(buf
));
573 msg
.msg_control
= buf
;
574 msg
.msg_controllen
= sizeof(buf
);
575 cmsg
= CMSG_FIRSTHDR(&msg
);
576 cmsg
->cmsg_level
= SOL_IP
;
577 cmsg
->cmsg_type
= IP_PKTINFO
;
578 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct in_pktinfo
));
579 pktinfo
= (struct in_pktinfo
*)CMSG_DATA(cmsg
);
580 addr
= &pktinfo
->ipi_spec_dst
;
581 sin
= (struct sockaddr_in
*)src
->get_sockaddr(src
);
582 memcpy(addr
, &sin
->sin_addr
, sizeof(struct in_addr
));
586 char buf
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
587 struct in6_pktinfo
*pktinfo
;
588 struct sockaddr_in6
*sin
;
590 memset(buf
, 0, sizeof(buf
));
591 msg
.msg_control
= buf
;
592 msg
.msg_controllen
= sizeof(buf
);
593 cmsg
= CMSG_FIRSTHDR(&msg
);
594 cmsg
->cmsg_level
= SOL_IPV6
;
595 cmsg
->cmsg_type
= IPV6_PKTINFO
;
596 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct in6_pktinfo
));
597 pktinfo
= (struct in6_pktinfo
*)CMSG_DATA(cmsg
);
598 sin
= (struct sockaddr_in6
*)src
->get_sockaddr(src
);
599 memcpy(&pktinfo
->ipi6_addr
, &sin
->sin6_addr
, sizeof(struct in6_addr
));
603 len
= sendmsg(skt
->fd
, &msg
, 0);
606 DBG1(DBG_NET
, "error writing to socket: %s", strerror(errno
));
612 METHOD(socket_t
, get_port
, u_int16_t
,
613 private_socket_dynamic_socket_t
*this, bool nat_t
)
615 /* we return 0 here for users that have no explicit port configured, the
616 * sender will default to the default port in this case */
620 METHOD(socket_t
, supported_families
, socket_family_t
,
621 private_socket_dynamic_socket_t
*this)
623 /* we could return only the families of the opened sockets, but it could
624 * be that both families are supported even if no socket is yet open */
625 return SOCKET_FAMILY_BOTH
;
628 METHOD(socket_t
, destroy
, void,
629 private_socket_dynamic_socket_t
*this)
631 enumerator_t
*enumerator
;
632 dynsock_t
*key
, *value
;
634 enumerator
= this->sockets
->create_enumerator(this->sockets
);
635 while (enumerator
->enumerate(enumerator
, &key
, &value
))
640 enumerator
->destroy(enumerator
);
641 this->sockets
->destroy(this->sockets
);
642 this->lock
->destroy(this->lock
);
644 close(this->notify
[0]);
645 close(this->notify
[1]);
650 * See header for description
652 socket_dynamic_socket_t
*socket_dynamic_socket_create()
654 private_socket_dynamic_socket_t
*this;
660 .receive
= _receiver
,
661 .get_port
= _get_port
,
662 .supported_families
= _supported_families
,
666 .lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
),
667 .max_packet
= lib
->settings
->get_int(lib
->settings
,
668 "%s.max_packet", PACKET_MAX_DEFAULT
, lib
->ns
),
671 if (pipe(this->notify
) != 0)
673 DBG1(DBG_NET
, "creating notify pipe for dynamic socket failed");
678 this->sockets
= hashtable_create((void*)hash
, (void*)equals
, 8);
680 return &this->public;