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(u_int32_t s, const std::string& addr, const std::string& port, boost::function<void(boost::asio::ip::basic_endpoint<Proto>)> const& onResolve, ErrorCallback const& onError, ResolvAddrType r)
45 cLog.msg(Log::PRIO_ERROR) << "the resolver only supports udp and tcp";
49 void waitAndEnqueue(u_int32_t s, const std::string& addr, const std::string& port, boost::function<void(boost::asio::ip::basic_endpoint<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(u_int32_t s, const std::string& addr, const std::string& port, boost::function<void(boost::asio::ip::basic_endpoint<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_endpoint<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, const boost::asio::ip::basic_resolver_iterator<Proto> endpointIt)
71 if(boost::system::posix_error::success == e) {
73 onResolve_(*endpointIt);
75 catch(const std::runtime_error& e)
80 cLog.msg(Log::PRIO_ERROR) << "Error while resolving '" << addr_ << "' '" << port_ << "', retrying in 10 sec.";
81 boost::thread(boost::bind(waitAndEnqueue<Proto>, 10, addr_, port_, onResolve_, onError_, resolv_addr_type_));
85 Resolver* Resolver::inst = NULL;
86 Mutex Resolver::instMutex;
87 Resolver& gResolver = Resolver::instance();
89 Resolver& Resolver::instance()
92 static instanceCleaner c;
94 inst = new Resolver();
99 Resolver::Resolver() : udp_resolver_(io_service_), tcp_resolver_(io_service_), thread_(NULL)
103 Resolver::~Resolver()
109 void Resolver::init()
112 thread_ = new boost::thread(boost::bind(&Resolver::run, this));
117 cLog.msg(Log::PRIO_DEBUG) << "Resolver Thread started";
123 boost::this_thread::sleep(boost::posix_time::milliseconds(250));
125 catch(const std::runtime_error& e)
127 cLog.msg(Log::PRIO_ERROR) << "resolver caught runtime error, restarting: " << e.what();
129 catch(const std::exception& e)
131 cLog.msg(Log::PRIO_ERROR) << "resolver caught exception, restarting: " << e.what();
137 void Resolver::resolveUdp(const std::string& addr, const std::string& port, UdpResolveCallback const& onResolve, ErrorCallback const& onError, ResolvAddrType r)
139 cLog.msg(Log::PRIO_DEBUG) << "trying to resolv UDP: '" << addr << "' '" << port << "'";
141 std::auto_ptr<udp::resolver::query> query;
144 case IPV4_ONLY: query = std::auto_ptr<udp::resolver::query>(new udp::resolver::query(udp::v4(), addr, port)); break;
145 case IPV6_ONLY: query = std::auto_ptr<udp::resolver::query>(new udp::resolver::query(udp::v6(), addr, port)); break;
146 default: query = std::auto_ptr<udp::resolver::query>(new udp::resolver::query(addr, port)); break;
151 case IPV4_ONLY: query = std::auto_ptr<udp::resolver::query>(new udp::resolver::query(udp::v4(), port)); break;
152 case IPV6_ONLY: query = std::auto_ptr<udp::resolver::query>(new udp::resolver::query(udp::v6(), port)); break;
153 default: query = std::auto_ptr<udp::resolver::query>(new udp::resolver::query(port)); break;
156 UdpResolveHandler handler(addr, port, onResolve, onError, r);
157 udp_resolver_.async_resolve(*query, handler);
160 void Resolver::resolveTcp(const std::string& addr, const std::string& port, TcpResolveCallback const& onResolve, ErrorCallback const& onError, ResolvAddrType r)
162 cLog.msg(Log::PRIO_DEBUG) << "trying to resolv TCP: '" << addr << "' '" << port << "'";
164 std::auto_ptr<tcp::resolver::query> query;
167 case IPV4_ONLY: query = std::auto_ptr<tcp::resolver::query>(new tcp::resolver::query(tcp::v4(), addr, port)); break;
168 case IPV6_ONLY: query = std::auto_ptr<tcp::resolver::query>(new tcp::resolver::query(tcp::v6(), addr, port)); break;
169 default: query = std::auto_ptr<tcp::resolver::query>(new tcp::resolver::query(addr, port)); break;
174 case IPV4_ONLY: query = std::auto_ptr<tcp::resolver::query>(new tcp::resolver::query(tcp::v4(), port)); break;
175 case IPV6_ONLY: query = std::auto_ptr<tcp::resolver::query>(new tcp::resolver::query(tcp::v6(), port)); break;
176 default: query = std::auto_ptr<tcp::resolver::query>(new tcp::resolver::query(port)); break;
179 TcpResolveHandler handler(addr, port, onResolve, onError, r);
180 tcp_resolver_.async_resolve(*query, handler);