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/>.
32 #include "networkPrefix.h"
33 #include "threadUtils.hpp"
34 #include "datatypes.h"
35 #include "anytunError.h"
37 #include "routingTable.h"
38 #include "routingTree.hpp"
40 RoutingTable* RoutingTable::inst = NULL;
41 Mutex RoutingTable::instMutex;
42 RoutingTable& gRoutingTable = RoutingTable::instance();
45 RoutingTable& RoutingTable::instance()
48 static instanceCleaner c;
50 inst = new RoutingTable();
56 RoutingTable::RoutingTable()
60 RoutingTable::~RoutingTable()
64 void RoutingTable::updateRouteTreeUnlocked(const NetworkPrefix& pref)
66 //Lock lock(mutex_); //deadlock
68 uint8_t length=pref.getNetworkPrefixLength();
69 network_address_type_t type=pref.getNetworkAddressType();
70 uint16_t mux = routes_[pref.getNetworkAddressType()].find(pref)->second;
71 RoutingTreeNode* node = &(root_[type]);
73 ipv4_bytes_type bytes(pref.to_bytes_v4());
77 RoutingTree::walk(bytes, node, length, mux);
78 } else if(type==ipv6) {
79 ipv6_bytes_type bytes(pref.to_bytes_v6());
83 RoutingTree::walk(bytes, node, length, mux);
84 } else if(type==ethernet) {
85 ethernet_bytes_type bytes(pref.to_bytes_ethernet());
89 RoutingTree::walk(bytes, node, length, mux);
91 AnytunError::throwErr() << "illegal protocol type";
93 //root_[type].print(0);
96 void RoutingTable::addRoute(const NetworkPrefix& pref, uint16_t mux)
100 network_address_type_t type=pref.getNetworkAddressType();
102 if(type==ipv4 || type==ipv6) {
103 std::pair<RoutingMap::iterator, bool> ret = routes_[type].insert(RoutingMap::value_type(pref,mux));
105 routes_[pref.getNetworkAddressType()].erase(ret.first);
106 routes_[pref.getNetworkAddressType()].insert(RoutingMap::value_type(pref,mux));
108 root_[pref.getNetworkAddressType()]=RoutingTreeNode();
109 RoutingMap::iterator it = routes_[type].begin();
110 for(; it!=routes_[pref.getNetworkAddressType()].end(); ++it) {
111 updateRouteTreeUnlocked(it->first);
113 } else if(type==ethernet) {
114 return; // TODO: add support for ethernet
116 AnytunError::throwErr() << "illegal protocol type";
121 void RoutingTable::delRoute(const NetworkPrefix& pref)
125 routes_[pref.getNetworkAddressType()].erase(routes_[pref.getNetworkAddressType()].find(pref));
128 uint16_t RoutingTable::getRoute(const NetworkAddress& addr)
131 network_address_type_t type=addr.getNetworkAddressType();
133 if(routes_[type].empty()) {
134 AnytunError::throwErr() << "no route";
138 ipv4_bytes_type bytes(addr.to_bytes_v4());
139 return RoutingTree::find(bytes, root_[type]);
140 } else if(type==ipv6) {
141 ipv6_bytes_type bytes(addr.to_bytes_v6());
142 return RoutingTree::find(bytes, root_[type]);
143 } else if(type==ethernet) {
144 //TODO Our model wont fit to ethernet addresses well.
145 // maybe use hashmap or something like that instead
146 ethernet_bytes_type bytes(addr.to_bytes_ethernet());
147 return RoutingTree::find(bytes, root_[type]);
149 AnytunError::throwErr() << "illegal protocol type";
154 uint16_t* RoutingTable::getOrNewRoutingTEUnlocked(const NetworkPrefix& addr)
156 RoutingMap::iterator it = routes_[addr.getNetworkAddressType()].find(addr);
157 if(it!=routes_[addr.getNetworkAddressType()].end()) {
158 return &(it->second);
161 routes_[addr.getNetworkAddressType()].insert(RoutingMap::value_type(addr, 1));
162 it = routes_[addr.getNetworkAddressType()].find(addr);
163 return &(it->second);
166 uint16_t RoutingTable::getCountUnlocked(network_address_type_t type)
168 RoutingMap::iterator it = routes_[type].begin();
170 for(; it!=routes_[type].end(); ++it) {
176 RoutingMap::iterator RoutingTable::getBeginUnlocked(network_address_type_t type)
178 return routes_[type].begin();
181 RoutingMap::iterator RoutingTable::getEndUnlocked(network_address_type_t type)
183 return routes_[type].end();
186 void RoutingTable::clear(network_address_type_t type)
189 routes_[type].clear();
192 bool RoutingTable::empty(network_address_type_t type)
195 return routes_[type].empty();
198 Mutex& RoutingTable::getMutex()