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 methodes 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-2009 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/>.
33 #include <boost/bind.hpp>
34 #include <boost/system/error_code.hpp>
39 using ::boost::asio::ip::udp;
40 using ::boost::asio::ip::tcp;
43 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)
45 cLog.msg(Log::PRIO_ERROR) << "the resolver only supports udp and tcp";
49 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)
51 boost::this_thread::sleep(boost::posix_time::milliseconds(s * 1000));
52 gResolver.resolveUdp(addr, port, onResolve, onError, r);
56 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)
58 boost::this_thread::sleep(boost::posix_time::milliseconds(s * 1000));
59 gResolver.resolveTcp(addr, port, onResolve, onError, r);
64 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)
69 void ResolveHandler<Proto>::operator()(const boost::system::error_code& e, boost::asio::ip::basic_resolver_iterator<Proto> endpointIt)
71 if(boost::system::posix_error::success == e) {
73 onResolve_(endpointIt);
74 } catch(const std::runtime_error& e) {
78 cLog.msg(Log::PRIO_ERROR) << "Error while resolving '" << addr_ << "' '" << port_ << "', retrying in 10 sec.";
79 boost::thread(boost::bind(waitAndEnqueue<Proto>, 10, addr_, port_, onResolve_, onError_, resolv_addr_type_));
83 Resolver* Resolver::inst = NULL;
84 Mutex Resolver::instMutex;
85 Resolver& gResolver = Resolver::instance();
87 Resolver& Resolver::instance()
90 static instanceCleaner c;
92 inst = new Resolver();
98 Resolver::Resolver() : udp_resolver_(io_service_), tcp_resolver_(io_service_), thread_(NULL)
102 Resolver::~Resolver()
109 void Resolver::init()
112 thread_ = new boost::thread(boost::bind(&Resolver::run, this));
118 cLog.msg(Log::PRIO_DEBUG) << "Resolver Thread started";
124 boost::this_thread::sleep(boost::posix_time::milliseconds(250));
125 } catch(const std::runtime_error& e) {
126 cLog.msg(Log::PRIO_ERROR) << "resolver caught runtime error, restarting: " << e.what();
127 } catch(const std::exception& e) {
128 cLog.msg(Log::PRIO_ERROR) << "resolver caught exception, restarting: " << e.what();
134 void Resolver::resolveUdp(const std::string& addr, const std::string& port, UdpResolveCallback const& onResolve, ErrorCallback const& onError, ResolvAddrType r)
136 cLog.msg(Log::PRIO_DEBUG) << "trying to resolv UDP: '" << addr << "' '" << port << "'";
138 std::auto_ptr<udp::resolver::query> query;
142 query = std::auto_ptr<udp::resolver::query>(new udp::resolver::query(udp::v4(), addr, port));
145 query = std::auto_ptr<udp::resolver::query>(new udp::resolver::query(udp::v6(), addr, port));
148 query = std::auto_ptr<udp::resolver::query>(new udp::resolver::query(addr, port));
154 query = std::auto_ptr<udp::resolver::query>(new udp::resolver::query(udp::v4(), port));
157 query = std::auto_ptr<udp::resolver::query>(new udp::resolver::query(udp::v6(), port));
160 query = std::auto_ptr<udp::resolver::query>(new udp::resolver::query(port));
164 UdpResolveHandler handler(addr, port, onResolve, onError, r);
165 udp_resolver_.async_resolve(*query, handler);
168 void Resolver::resolveTcp(const std::string& addr, const std::string& port, TcpResolveCallback const& onResolve, ErrorCallback const& onError, ResolvAddrType r)
170 cLog.msg(Log::PRIO_DEBUG) << "trying to resolv TCP: '" << addr << "' '" << port << "'";
172 std::auto_ptr<tcp::resolver::query> query;
176 query = std::auto_ptr<tcp::resolver::query>(new tcp::resolver::query(tcp::v4(), addr, port));
179 query = std::auto_ptr<tcp::resolver::query>(new tcp::resolver::query(tcp::v6(), addr, port));
182 query = std::auto_ptr<tcp::resolver::query>(new tcp::resolver::query(addr, port));
188 query = std::auto_ptr<tcp::resolver::query>(new tcp::resolver::query(tcp::v4(), port));
191 query = std::auto_ptr<tcp::resolver::query>(new tcp::resolver::query(tcp::v6(), port));
194 query = std::auto_ptr<tcp::resolver::query>(new tcp::resolver::query(port));
198 TcpResolveHandler handler(addr, port, onResolve, onError, r);
199 tcp_resolver_.async_resolve(*query, handler);