4 * The secure anycast tunneling protocol (satp) defines a protocol used
5 * for communication between any combination of unicast and anycast
6 * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
7 * mode and allows tunneling of every ETHER TYPE protocol (e.g.
8 * ethernet, ip, arp ...). satp directly includes cryptography and
9 * message authentication based on the methods used by SRTP. It is
10 * intended to deliver a generic, scaleable and secure solution for
11 * tunneling and relaying of packets of any protocol.
14 * Copyright (C) 2007-2014 Markus Grüneis, Othmar Gsenger, Erwin Nindl,
15 * Christian Pointner <satp@wirdorange.org>
17 * This file is part of Anytun.
19 * Anytun is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation, either version 3 of the License, or
24 * Anytun is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with Anytun. If not, see <http://www.gnu.org/licenses/>.
32 * In addition, as a special exception, the copyright holders give
33 * permission to link the code of portions of this program with the
34 * OpenSSL library under certain conditions as described in each
35 * individual source file, and distribute linked combinations
37 * You must obey the GNU General Public License in all respects
38 * for all of the code used other than OpenSSL. If you modify
39 * file(s) with this exception, you may extend this exception to your
40 * version of the file(s), but you are not obligated to do so. If you
41 * do not wish to do so, delete this exception statement from your
42 * version. If you delete this exception statement from all source
43 * files in the program, then also delete it here.
46 #include <boost/bind.hpp>
47 #include <boost/system/error_code.hpp>
52 using ::boost::asio::ip::udp;
53 using ::boost::asio::ip::tcp;
56 void waitAndEnqueue(uint32_t s, const std::string& addr, const std::string& port, boost::function<void(boost::asio::ip::basic_resolver_iterator<Proto>)> const& onResolve, ErrorCallback const& onError, ResolvAddrType r)
58 cLog.msg(Log::PRIO_ERROR) << "the resolver only supports udp and tcp";
62 void waitAndEnqueue(uint32_t s, const std::string& addr, const std::string& port, boost::function<void(boost::asio::ip::basic_resolver_iterator<udp>)> const& onResolve, ErrorCallback const& onError, ResolvAddrType r)
64 boost::this_thread::sleep(boost::posix_time::milliseconds(s * 1000));
65 gResolver.resolveUdp(addr, port, onResolve, onError, r);
69 void waitAndEnqueue(uint32_t s, const std::string& addr, const std::string& port, boost::function<void(boost::asio::ip::basic_resolver_iterator<tcp>)> const& onResolve, ErrorCallback const& onError, ResolvAddrType r)
71 boost::this_thread::sleep(boost::posix_time::milliseconds(s * 1000));
72 gResolver.resolveTcp(addr, port, onResolve, onError, r);
77 ResolveHandler<Proto>::ResolveHandler(const std::string& addr, const std::string& port, boost::function<void(boost::asio::ip::basic_resolver_iterator<Proto>)> const& onResolve, ErrorCallback const& onError, ResolvAddrType r) : addr_(addr), port_(port), onResolve_(onResolve), onError_(onError), resolv_addr_type_(r)
82 void ResolveHandler<Proto>::operator()(const boost::system::error_code& e, boost::asio::ip::basic_resolver_iterator<Proto> endpointIt)
84 if(boost::system::posix_error::success == e) {
86 onResolve_(endpointIt);
87 } catch(const std::runtime_error& e) {
91 cLog.msg(Log::PRIO_ERROR) << "Error while resolving '" << addr_ << "' '" << port_ << "', retrying in 10 sec.";
92 boost::thread(boost::bind(waitAndEnqueue<Proto>, 10, addr_, port_, onResolve_, onError_, resolv_addr_type_));
96 Resolver& gResolver = Resolver::instance();
98 Resolver& Resolver::instance()
100 static Resolver instance;
104 Resolver::Resolver() : udp_resolver_(io_service_), tcp_resolver_(io_service_), thread_(NULL)
108 Resolver::~Resolver()
115 void Resolver::init()
118 thread_ = new boost::thread(boost::bind(&Resolver::run, this));
124 cLog.msg(Log::PRIO_DEBUG) << "Resolver Thread started";
130 boost::this_thread::sleep(boost::posix_time::milliseconds(250));
131 } catch(const std::runtime_error& e) {
132 cLog.msg(Log::PRIO_ERROR) << "resolver caught runtime error, restarting: " << e.what();
133 } catch(const std::exception& e) {
134 cLog.msg(Log::PRIO_ERROR) << "resolver caught exception, restarting: " << e.what();
140 void Resolver::resolveUdp(const std::string& addr, const std::string& port, UdpResolveCallback const& onResolve, ErrorCallback const& onError, ResolvAddrType r)
142 cLog.msg(Log::PRIO_DEBUG) << "trying to resolv UDP: '" << addr << "' '" << port << "'";
144 boost::shared_ptr<udp::resolver::query> query;
148 query = boost::shared_ptr<udp::resolver::query>(new udp::resolver::query(udp::v4(), addr, port));
151 query = boost::shared_ptr<udp::resolver::query>(new udp::resolver::query(udp::v6(), addr, port));
154 query = boost::shared_ptr<udp::resolver::query>(new udp::resolver::query(addr, port));
160 query = boost::shared_ptr<udp::resolver::query>(new udp::resolver::query(udp::v4(), port));
163 query = boost::shared_ptr<udp::resolver::query>(new udp::resolver::query(udp::v6(), port));
166 query = boost::shared_ptr<udp::resolver::query>(new udp::resolver::query(port));
170 UdpResolveHandler handler(addr, port, onResolve, onError, r);
171 udp_resolver_.async_resolve(*query, handler);
174 void Resolver::resolveTcp(const std::string& addr, const std::string& port, TcpResolveCallback const& onResolve, ErrorCallback const& onError, ResolvAddrType r)
176 cLog.msg(Log::PRIO_DEBUG) << "trying to resolv TCP: '" << addr << "' '" << port << "'";
178 boost::shared_ptr<tcp::resolver::query> query;
182 query = boost::shared_ptr<tcp::resolver::query>(new tcp::resolver::query(tcp::v4(), addr, port));
185 query = boost::shared_ptr<tcp::resolver::query>(new tcp::resolver::query(tcp::v6(), addr, port));
188 query = boost::shared_ptr<tcp::resolver::query>(new tcp::resolver::query(addr, port));
194 query = boost::shared_ptr<tcp::resolver::query>(new tcp::resolver::query(tcp::v4(), port));
197 query = boost::shared_ptr<tcp::resolver::query>(new tcp::resolver::query(tcp::v6(), port));
200 query = boost::shared_ptr<tcp::resolver::query>(new tcp::resolver::query(port));
204 TcpResolveHandler handler(addr, port, onResolve, onError, r);
205 tcp_resolver_.async_resolve(*query, handler);