4 * uAnytun is a tiny implementation of SATP. Unlike Anytun which is a full
5 * featured implementation uAnytun has no support for multiple connections
6 * or synchronisation. It is a small single threaded implementation intended
7 * to act as a client on small platforms.
8 * The secure anycast tunneling protocol (satp) defines a protocol used
9 * for communication between any combination of unicast and anycast
10 * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
11 * mode and allows tunneling of every ETHER TYPE protocol (e.g.
12 * ethernet, ip, arp ...). satp directly includes cryptography and
13 * message authentication based on the methods used by SRTP. It is
14 * intended to deliver a generic, scaleable and secure solution for
15 * tunneling and relaying of packets of any protocol.
18 * Copyright (C) 2007-2014 Christian Pointner <equinox@anytun.org>
20 * This file is part of uAnytun.
22 * uAnytun is free software: you can redistribute it and/or modify
23 * it under the terms of the GNU General Public License as published by
24 * the Free Software Foundation, either version 3 of the License, or
27 * uAnytun is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
32 * You should have received a copy of the GNU General Public License
33 * along with uAnytun. If not, see <http://www.gnu.org/licenses/>.
35 * In addition, as a special exception, the copyright holders give
36 * permission to link the code of portions of this program with the
37 * OpenSSL library under certain conditions as described in each
38 * individual source file, and distribute linked combinations
40 * You must obey the GNU General Public License in all respects
41 * for all of the code used other than OpenSSL. If you modify
42 * file(s) with this exception, you may extend this exception to your
43 * version of the file(s), but you are not obligated to do so. If you
44 * do not wish to do so, delete this exception statement from your
45 * version. If you delete this exception statement from all source
46 * files in the program, then also delete it here.
52 #include "datatypes.h"
63 #include <sys/types.h>
64 #include <sys/socket.h>
65 #include <arpa/inet.h>
66 #include <netinet/in.h>
69 #define AI_ADDRCONFIG 0
72 static int udp_resolv_local(udp_t* sock, const char* local_addr, const char* port, resolv_addr_type_t resolv_type, unsigned int* idx)
74 struct addrinfo hints, *res;
77 memset (&hints, 0, sizeof (hints));
78 hints.ai_socktype = SOCK_DGRAM;
79 hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
82 case IPV4_ONLY: hints.ai_family = AF_INET; break;
83 case IPV6_ONLY: hints.ai_family = AF_INET6; break;
84 default: hints.ai_family = AF_UNSPEC; break;
87 int errcode = getaddrinfo(local_addr, port, &hints, &res);
89 log_printf(ERROR, "Error resolving local address (%s:%s): %s", (local_addr) ? local_addr : "*", port, gai_strerror(errcode));
95 log_printf(ERROR, "getaddrinfo returned no address for %s:%s", local_addr, port);
99 struct addrinfo* r = res;
100 udp_socket_t* prev_sock = sock->socks_;
101 while(prev_sock && prev_sock->next_) prev_sock = prev_sock->next_;
103 udp_socket_t* new_sock = malloc(sizeof(udp_socket_t));
105 log_printf(ERROR, "memory error at udp_init");
110 memset(&(new_sock->local_end_.addr_), 0, sizeof(new_sock->local_end_.addr_));
111 new_sock->local_end_.len_ = sizeof(new_sock->local_end_.addr_);
112 memset(&(new_sock->remote_end_.addr_), 0, sizeof(new_sock->remote_end_.addr_));
113 new_sock->remote_end_.len_ = sizeof(new_sock->remote_end_.addr_);
114 new_sock->remote_end_set_ = 0;
115 new_sock->next_ = NULL;
116 new_sock->idx_ = (*idx)++;
119 sock->socks_ = new_sock;
120 prev_sock = new_sock;
123 prev_sock->next_ = new_sock;
124 prev_sock = new_sock;
127 memcpy(&(new_sock->local_end_.addr_), r->ai_addr, r->ai_addrlen);
128 new_sock->local_end_.len_ = r->ai_addrlen;
129 new_sock->fd_ = socket(new_sock->local_end_.addr_.ss_family, SOCK_DGRAM, 0);
130 if(new_sock->fd_ < 0) {
131 log_printf(ERROR, "Error on opening udp socket: %s", strerror(errno));
137 if(r->ai_family == AF_INET6) {
139 if(setsockopt(new_sock->fd_, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)))
140 log_printf(ERROR, "Error on setting IPV6_V6ONLY socket option: %s", strerror(errno));
143 errcode = bind(new_sock->fd_, (struct sockaddr*)&(new_sock->local_end_.addr_), new_sock->local_end_.len_);
145 log_printf(ERROR, "Error on binding udp socket: %s", strerror(errno));
151 char* local_string = udp_endpoint_to_string(&(new_sock->local_end_));
153 log_printf(NOTICE, "socket[%d] listening on: %s", new_sock->idx_, local_string);
164 int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_type_t resolv_type)
170 sock->active_sock_ = NULL;
172 unsigned int idx = 0;
173 int ret = udp_resolv_local(sock, local_addr, port, resolv_type, &idx);
180 int udp_fill_fd_set(udp_t* sock, fd_set* set)
184 udp_socket_t* s = sock->socks_;
187 max_fd = s->fd_ > max_fd ? s->fd_ : max_fd;
194 int udp_has_remote(udp_t* sock)
196 if(!sock->active_sock_ || !sock->active_sock_->remote_end_set_)
199 udp_socket_t* s = sock->socks_;
201 if(s->remote_end_set_)
209 int udp_resolv_remote(udp_t* sock, const char* remote_addr, const char* port, resolv_addr_type_t resolv_type)
211 struct addrinfo hints, *res;
213 if(!sock || !remote_addr || !port)
217 memset (&hints, 0, sizeof (hints));
218 hints.ai_socktype = SOCK_DGRAM;
220 switch(resolv_type) {
221 case IPV4_ONLY: hints.ai_family = PF_INET; break;
222 case IPV6_ONLY: hints.ai_family = PF_INET6; break;
223 default: hints.ai_family = PF_UNSPEC; break;
226 int errcode = getaddrinfo(remote_addr, port, &hints, &res);
228 log_printf(ERROR, "Error resolving remote address (%s:%s): %s", (remote_addr) ? remote_addr : "*", port, gai_strerror(errcode));
232 log_printf(ERROR, "getaddrinfo returned no address for %s:%s", remote_addr, port);
237 struct addrinfo* r = res;
239 udp_socket_t* s = sock->socks_;
241 if(s->local_end_.addr_.ss_family == r->ai_family && !(s->remote_end_set_)) {
242 sock->active_sock_ = s;
249 memcpy(&(s->remote_end_.addr_), r->ai_addr, r->ai_addrlen);
250 s->remote_end_.len_ = r->ai_addrlen;
251 s->remote_end_set_ = 1;
253 char* remote_string = udp_endpoint_to_string(&(s->remote_end_));
255 log_printf(NOTICE, "socket[%d] set remote end to: %s", s->idx_, remote_string);
266 log_printf(WARNING, "no remote address for '%s' found that fits any of the local address families", remote_addr);
271 void udp_update_remote(udp_t* sock, int fd, udp_endpoint_t* remote)
276 if(!(sock->active_sock_) || sock->active_sock_->fd_ != fd) {
277 udp_socket_t* s = sock->socks_;
280 sock->active_sock_ = s;
290 if(sock->active_sock_) {
291 if(remote->len_ != sock->active_sock_->remote_end_.len_ ||
292 memcmp(&(remote->addr_), &(sock->active_sock_->remote_end_.addr_), remote->len_)) {
293 memcpy(&(sock->active_sock_->remote_end_.addr_), &(remote->addr_), remote->len_);
294 sock->active_sock_->remote_end_.len_ = remote->len_;
295 sock->active_sock_->remote_end_set_ = 1;
296 char* addrstring = udp_endpoint_to_string(remote);
297 log_printf(NOTICE, "socket[%d] autodetected remote host changed %s", sock->active_sock_->idx_, addrstring);
303 void udp_close(udp_t* sock)
308 while(sock->socks_) {
309 if(sock->socks_->fd_ > 0)
310 close(sock->socks_->fd_);
312 udp_socket_t*s = sock->socks_;
313 sock->socks_ = sock->socks_->next_;
318 sock->active_sock_ = NULL;
321 char* udp_endpoint_to_string(udp_endpoint_t* e)
324 return strdup("<null>");
326 char addrstr[INET6_ADDRSTRLEN + 1], portstr[6], *ret;
327 char addrport_sep = ':';
329 switch(e->addr_.ss_family)
331 case AF_INET: addrport_sep = ':'; break;
332 case AF_INET6: addrport_sep = '.'; break;
333 case AF_UNSPEC: return NULL;
334 default: return strdup("<unknown address type>");
337 int errcode = getnameinfo((struct sockaddr *)&(e->addr_), e->len_, addrstr, sizeof(addrstr), portstr, sizeof(portstr), NI_NUMERICHOST | NI_NUMERICSERV);
338 if (errcode != 0) return NULL;
339 int len = asprintf(&ret, "%s%c%s", addrstr, addrport_sep ,portstr);
340 if(len == -1) return NULL;
345 int udp_read(udp_t* sock, int fd, u_int8_t* buf, u_int32_t len, udp_endpoint_t* remote_end)
347 if(!sock || !buf || !remote_end)
350 return recvfrom(fd, buf, len, 0, (struct sockaddr *)&(remote_end->addr_), &(remote_end->len_));
354 int udp_write(udp_t* sock, u_int8_t* buf, u_int32_t len)
356 if(!sock || !buf || !sock->active_sock_ || !sock->active_sock_->remote_end_set_)
359 return sendto(sock->active_sock_->fd_, buf, len, 0, (struct sockaddr *)&(sock->active_sock_->remote_end_.addr_), sock->active_sock_->remote_end_.len_);