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>
68 static int udp_resolv_local(udp_t* sock, const char* local_addr, const char* port, resolv_addr_type_t resolv_type, unsigned int* idx)
70 struct addrinfo hints, *res;
73 memset (&hints, 0, sizeof (hints));
74 hints.ai_socktype = SOCK_DGRAM;
75 hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
78 case IPV4_ONLY: hints.ai_family = AF_INET; break;
79 case IPV6_ONLY: hints.ai_family = AF_INET6; break;
80 default: hints.ai_family = AF_UNSPEC; break;
83 int errcode = getaddrinfo(local_addr, port, &hints, &res);
85 log_printf(ERROR, "Error resolving local address (%s:%s): %s", (local_addr) ? local_addr : "*", port, gai_strerror(errcode));
91 log_printf(ERROR, "getaddrinfo returned no address for %s:%s", local_addr, port);
95 struct addrinfo* r = res;
96 udp_socket_t* prev_sock = sock->socks_;
97 while(prev_sock && prev_sock->next_) prev_sock = prev_sock->next_;
99 udp_socket_t* new_sock = malloc(sizeof(udp_socket_t));
101 log_printf(ERROR, "memory error at udp_init");
106 memset(&(new_sock->local_end_.addr_), 0, sizeof(new_sock->local_end_.addr_));
107 new_sock->local_end_.len_ = sizeof(new_sock->local_end_.addr_);
108 memset(&(new_sock->remote_end_.addr_), 0, sizeof(new_sock->remote_end_.addr_));
109 new_sock->remote_end_.len_ = sizeof(new_sock->remote_end_.addr_);
110 new_sock->remote_end_set_ = 0;
111 new_sock->next_ = NULL;
112 new_sock->idx_ = (*idx)++;
115 sock->socks_ = new_sock;
116 prev_sock = new_sock;
119 prev_sock->next_ = new_sock;
120 prev_sock = new_sock;
123 memcpy(&(new_sock->local_end_.addr_), r->ai_addr, r->ai_addrlen);
124 new_sock->local_end_.len_ = r->ai_addrlen;
125 new_sock->fd_ = socket(new_sock->local_end_.addr_.ss_family, SOCK_DGRAM, 0);
126 if(new_sock->fd_ < 0) {
127 log_printf(ERROR, "Error on opening udp socket: %s", strerror(errno));
133 if(r->ai_family == AF_INET6) {
135 if(setsockopt(new_sock->fd_, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)))
136 log_printf(ERROR, "Error on setting IPV6_V6ONLY socket option: %s", strerror(errno));
139 errcode = bind(new_sock->fd_, (struct sockaddr*)&(new_sock->local_end_.addr_), new_sock->local_end_.len_);
141 log_printf(ERROR, "Error on binding udp socket: %s", strerror(errno));
147 char* local_string = udp_endpoint_to_string(&(new_sock->local_end_));
149 log_printf(NOTICE, "socket[%d] listening on: %s", new_sock->idx_, local_string);
160 int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_type_t resolv_type)
166 sock->active_sock_ = NULL;
168 unsigned int idx = 0;
169 int ret = udp_resolv_local(sock, local_addr, port, resolv_type, &idx);
176 int udp_fill_fd_set(udp_t* sock, fd_set* set)
180 udp_socket_t* s = sock->socks_;
183 max_fd = s->fd_ > max_fd ? s->fd_ : max_fd;
190 int udp_has_remote(udp_t* sock)
192 if(!sock->active_sock_ || !sock->active_sock_->remote_end_set_)
195 udp_socket_t* s = sock->socks_;
197 if(s->remote_end_set_)
205 int udp_resolv_remote(udp_t* sock, const char* remote_addr, const char* port, resolv_addr_type_t resolv_type)
207 struct addrinfo hints, *res;
209 if(!sock || !remote_addr || !port)
213 memset (&hints, 0, sizeof (hints));
214 hints.ai_socktype = SOCK_DGRAM;
216 switch(resolv_type) {
217 case IPV4_ONLY: hints.ai_family = PF_INET; break;
218 case IPV6_ONLY: hints.ai_family = PF_INET6; break;
219 default: hints.ai_family = PF_UNSPEC; break;
222 int errcode = getaddrinfo(remote_addr, port, &hints, &res);
224 log_printf(ERROR, "Error resolving remote address (%s:%s): %s", (remote_addr) ? remote_addr : "*", port, gai_strerror(errcode));
228 log_printf(ERROR, "getaddrinfo returned no address for %s:%s", remote_addr, port);
233 struct addrinfo* r = res;
235 udp_socket_t* s = sock->socks_;
237 if(s->local_end_.addr_.ss_family == r->ai_family && !(s->remote_end_set_)) {
238 sock->active_sock_ = s;
245 memcpy(&(s->remote_end_.addr_), r->ai_addr, r->ai_addrlen);
246 s->remote_end_.len_ = r->ai_addrlen;
247 s->remote_end_set_ = 1;
249 char* remote_string = udp_endpoint_to_string(&(s->remote_end_));
251 log_printf(NOTICE, "socket[%d] set remote end to: %s", s->idx_, remote_string);
262 log_printf(WARNING, "no remote address for '%s' found that fits any of the local address families", remote_addr);
267 void udp_update_remote(udp_t* sock, int fd, udp_endpoint_t* remote)
272 if(!(sock->active_sock_) || sock->active_sock_->fd_ != fd) {
273 udp_socket_t* s = sock->socks_;
276 sock->active_sock_ = s;
286 if(sock->active_sock_) {
287 if(remote->len_ != sock->active_sock_->remote_end_.len_ ||
288 memcmp(&(remote->addr_), &(sock->active_sock_->remote_end_.addr_), remote->len_)) {
289 memcpy(&(sock->active_sock_->remote_end_.addr_), &(remote->addr_), remote->len_);
290 sock->active_sock_->remote_end_.len_ = remote->len_;
291 sock->active_sock_->remote_end_set_ = 1;
292 char* addrstring = udp_endpoint_to_string(remote);
293 log_printf(NOTICE, "socket[%d] autodetected remote host changed %s", sock->active_sock_->idx_, addrstring);
299 void udp_close(udp_t* sock)
304 while(sock->socks_) {
305 if(sock->socks_->fd_ > 0)
306 close(sock->socks_->fd_);
308 udp_socket_t*s = sock->socks_;
309 sock->socks_ = sock->socks_->next_;
314 sock->active_sock_ = NULL;
317 char* udp_endpoint_to_string(udp_endpoint_t* e)
320 return strdup("<null>");
322 char addrstr[INET6_ADDRSTRLEN + 1], portstr[6], *ret;
323 char addrport_sep = ':';
325 switch(e->addr_.ss_family)
327 case AF_INET: addrport_sep = ':'; break;
328 case AF_INET6: addrport_sep = '.'; break;
329 case AF_UNSPEC: return NULL;
330 default: return strdup("<unknown address type>");
333 int errcode = getnameinfo((struct sockaddr *)&(e->addr_), e->len_, addrstr, sizeof(addrstr), portstr, sizeof(portstr), NI_NUMERICHOST | NI_NUMERICSERV);
334 if (errcode != 0) return NULL;
335 int len = asprintf(&ret, "%s%c%s", addrstr, addrport_sep ,portstr);
336 if(len == -1) return NULL;
341 int udp_read(udp_t* sock, int fd, u_int8_t* buf, u_int32_t len, udp_endpoint_t* remote_end)
343 if(!sock || !buf || !remote_end)
346 return recvfrom(fd, buf, len, 0, (struct sockaddr *)&(remote_end->addr_), &(remote_end->len_));
350 int udp_write(udp_t* sock, u_int8_t* buf, u_int32_t len)
352 if(!sock || !buf || !sock->active_sock_ || !sock->active_sock_->remote_end_set_)
355 return sendto(sock->active_sock_->fd_, buf, len, 0, (struct sockaddr *)&(sock->active_sock_->remote_end_.addr_), sock->active_sock_->remote_end_.len_);