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();
55 RoutingTable::RoutingTable()
59 RoutingTable::~RoutingTable()
63 void RoutingTable::updateRouteTreeUnlocked(const NetworkPrefix & pref)
65 //Lock lock(mutex_); //deadlock
67 u_int8_t length=pref.getNetworkPrefixLength();
68 network_address_type_t type=pref.getNetworkAddressType();
69 u_int16_t mux = routes_[pref.getNetworkAddressType()].find(pref)->second;
70 RoutingTreeNode * node = &(root_[type]);
73 ipv4_bytes_type bytes(pref.to_bytes_v4());
76 RoutingTree::walk(bytes, node, length, mux);
77 } else if (type==ipv6) {
78 ipv6_bytes_type bytes(pref.to_bytes_v6());
81 RoutingTree::walk(bytes, node, length, mux);
82 } else if (type==ethernet) {
83 ethernet_bytes_type bytes(pref.to_bytes_ethernet());
86 RoutingTree::walk(bytes, node, length, mux);
88 AnytunError::throwErr() << "illegal protocol type";
90 //root_[type].print(0);
93 void RoutingTable::addRoute(const NetworkPrefix & pref, u_int16_t mux)
97 network_address_type_t type=pref.getNetworkAddressType();
99 if (type==ipv4 || type==ipv6)
101 std::pair<RoutingMap::iterator, bool> ret = routes_[type].insert(RoutingMap::value_type(pref,mux));
104 routes_[pref.getNetworkAddressType()].erase(ret.first);
105 routes_[pref.getNetworkAddressType()].insert(RoutingMap::value_type(pref,mux));
107 root_[pref.getNetworkAddressType()]=RoutingTreeNode();
108 RoutingMap::iterator it = routes_[type].begin();
109 for (;it!=routes_[pref.getNetworkAddressType()].end();++it)
110 updateRouteTreeUnlocked(it->first);
111 } else if (type==ethernet) {
112 return; // TODO: add support for ethernet
114 AnytunError::throwErr() << "illegal protocol type";
119 void RoutingTable::delRoute(const NetworkPrefix & pref )
123 routes_[pref.getNetworkAddressType()].erase(routes_[pref.getNetworkAddressType()].find(pref));
126 u_int16_t RoutingTable::getRoute(const NetworkAddress & addr)
129 network_address_type_t type=addr.getNetworkAddressType();
131 if (routes_[type].empty())
132 AnytunError::throwErr() << "no route";
136 ipv4_bytes_type bytes(addr.to_bytes_v4());
137 return RoutingTree::find(bytes, root_[type]);
138 } else if (type==ipv6) {
139 ipv6_bytes_type bytes(addr.to_bytes_v6());
140 return RoutingTree::find(bytes, root_[type]);
141 } else if (type==ethernet) {
142 //TODO Our model wont fit to ethernet addresses well.
143 // maybe use hashmap or something like that instead
144 ethernet_bytes_type bytes(addr.to_bytes_ethernet());
145 return RoutingTree::find(bytes, root_[type]);
147 AnytunError::throwErr() << "illegal protocol type";
152 u_int16_t* RoutingTable::getOrNewRoutingTEUnlocked(const NetworkPrefix & addr)
154 RoutingMap::iterator it = routes_[addr.getNetworkAddressType()].find(addr);
155 if(it!=routes_[addr.getNetworkAddressType()].end())
156 return &(it->second);
158 routes_[addr.getNetworkAddressType()].insert(RoutingMap::value_type(addr, 1));
159 it = routes_[addr.getNetworkAddressType()].find(addr);
160 return &(it->second);
163 u_int16_t RoutingTable::getCountUnlocked(network_address_type_t type)
165 RoutingMap::iterator it = routes_[type].begin();
167 for (;it!=routes_[type].end();++it)
172 RoutingMap::iterator RoutingTable::getBeginUnlocked(network_address_type_t type)
174 return routes_[type].begin();
177 RoutingMap::iterator RoutingTable::getEndUnlocked(network_address_type_t type)
179 return routes_[type].end();
182 void RoutingTable::clear(network_address_type_t type)
185 routes_[type].clear();
188 bool RoutingTable::empty(network_address_type_t type)
191 return routes_[type].empty();
194 Mutex& RoutingTable::getMutex()