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-2008 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 version 3 as
21 * published by the Free Software Foundation.
23 * Anytun is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with anytun. If not, see <http://www.gnu.org/licenses/>.
31 #include "networkPrefix.h"
32 #include "threadUtils.hpp"
33 #include "datatypes.h"
34 #include "anytunError.h"
36 #include "routingTable.h"
37 #include "routingTree.hpp"
39 RoutingTable* RoutingTable::inst = NULL;
40 Mutex RoutingTable::instMutex;
41 RoutingTable& gRoutingTable = RoutingTable::instance();
44 RoutingTable& RoutingTable::instance()
47 static instanceCleaner c;
49 inst = new RoutingTable();
54 RoutingTable::RoutingTable()
58 RoutingTable::~RoutingTable()
62 void RoutingTable::updateRouteTreeUnlocked(const NetworkPrefix & pref)
64 //Lock lock(mutex_); //deadlock
66 u_int8_t length=pref.getNetworkPrefixLength();
67 network_address_type_t type=pref.getNetworkAddressType();
68 u_int16_t mux = routes_[pref.getNetworkAddressType()].find(pref)->second;
69 RoutingTreeNode * node = &(root_[type]);
72 ipv4_bytes_type bytes(pref.to_bytes_v4());
75 RoutingTree::walk(bytes, node, length, mux);
76 } else if (type==ipv6) {
77 ipv6_bytes_type bytes(pref.to_bytes_v6());
80 RoutingTree::walk(bytes, node, length, mux);
81 } else if (type==ethernet) {
82 ethernet_bytes_type bytes(pref.to_bytes_ethernet());
85 RoutingTree::walk(bytes, node, length, mux);
87 AnytunError::throwErr() << "illegal protocol type";
89 //root_[type].print(0);
92 void RoutingTable::addRoute(const NetworkPrefix & pref, u_int16_t mux)
96 network_address_type_t type=pref.getNetworkAddressType();
98 if (type==ipv4 || type==ipv6)
100 std::pair<RoutingMap::iterator, bool> ret = routes_[type].insert(RoutingMap::value_type(pref,mux));
103 routes_[pref.getNetworkAddressType()].erase(ret.first);
104 routes_[pref.getNetworkAddressType()].insert(RoutingMap::value_type(pref,mux));
106 root_[pref.getNetworkAddressType()]=RoutingTreeNode();
107 RoutingMap::iterator it = routes_[type].begin();
108 for (;it!=routes_[pref.getNetworkAddressType()].end();++it)
109 updateRouteTreeUnlocked(it->first);
110 } else if (type==ethernet) {
111 return; // TODO: add support for ethernet
113 AnytunError::throwErr() << "illegal protocol type";
118 void RoutingTable::delRoute(const NetworkPrefix & pref )
122 routes_[pref.getNetworkAddressType()].erase(routes_[pref.getNetworkAddressType()].find(pref));
125 u_int16_t RoutingTable::getRoute(const NetworkAddress & addr)
128 network_address_type_t type=addr.getNetworkAddressType();
130 if (routes_[type].empty())
131 AnytunError::throwErr() << "no route";
135 ipv4_bytes_type bytes(addr.to_bytes_v4());
136 return RoutingTree::find(bytes, root_[type]);
137 } else if (type==ipv6) {
138 ipv6_bytes_type bytes(addr.to_bytes_v6());
139 return RoutingTree::find(bytes, root_[type]);
140 } else if (type==ethernet) {
141 //TODO Our model wont fit to ethernet addresses well.
142 // maybe use hashmap or something like that instead
143 ethernet_bytes_type bytes(addr.to_bytes_ethernet());
144 return RoutingTree::find(bytes, root_[type]);
146 AnytunError::throwErr() << "illegal protocol type";
151 u_int16_t* RoutingTable::getOrNewRoutingTEUnlocked(const NetworkPrefix & addr)
153 RoutingMap::iterator it = routes_[addr.getNetworkAddressType()].find(addr);
154 if(it!=routes_[addr.getNetworkAddressType()].end())
155 return &(it->second);
157 routes_[addr.getNetworkAddressType()].insert(RoutingMap::value_type(addr, 1));
158 it = routes_[addr.getNetworkAddressType()].find(addr);
159 return &(it->second);
162 u_int16_t RoutingTable::getCountUnlocked(network_address_type_t type)
164 RoutingMap::iterator it = routes_[type].begin();
166 for (;it!=routes_[type].end();++it)
171 RoutingMap::iterator RoutingTable::getBeginUnlocked(network_address_type_t type)
173 return routes_[type].begin();
176 RoutingMap::iterator RoutingTable::getEndUnlocked(network_address_type_t type)
178 return routes_[type].end();
181 void RoutingTable::clear(network_address_type_t type)
184 routes_[type].clear();
187 bool RoutingTable::empty(network_address_type_t type)
190 return routes_[type].empty();
193 Mutex& RoutingTable::getMutex()