doing replay protection before learning remote host
[anytun.git] / src / routingTable.cpp
blobf457505f24f0c2e31e5643c0ded4272a986547b6
1 /*
2 * anytun
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"
35 #include "routingTable.h"
36 #include "routingTree.hpp"
38 RoutingTable* RoutingTable::inst = NULL;
39 Mutex RoutingTable::instMutex;
40 RoutingTable& gRoutingTable = RoutingTable::instance();
43 RoutingTable& RoutingTable::instance()
45 Lock lock(instMutex);
46 static instanceCleaner c;
47 if(!inst)
48 inst = new RoutingTable();
50 return *inst;
53 RoutingTable::RoutingTable()
57 RoutingTable::~RoutingTable()
61 void RoutingTable::updateRouteTreeUnlocked(const NetworkPrefix & pref)
63 //Lock lock(mutex_); //deadlock
65 u_int8_t length=pref.getNetworkPrefixLength();
66 network_address_type_t type=pref.getNetworkAddressType();
67 u_int16_t mux = routes_[pref.getNetworkAddressType()].find(pref)->second;
68 RoutingTreeNode * node = &(root_[type]);
69 if (type==ipv4)
71 ipv4_bytes_type bytes(pref.to_bytes_v4());
72 if (length>32)
73 length=32;
74 RoutingTree::walk(bytes, node, length, mux);
75 } else if (type==ipv6) {
76 ipv6_bytes_type bytes(pref.to_bytes_v6());
77 if (length>128)
78 length=128;
79 RoutingTree::walk(bytes, node, length, mux);
80 } else if (type==ethernet) {
81 ethernet_bytes_type bytes(pref.to_bytes_ethernet());
82 if (length>48)
83 length=48;
84 RoutingTree::walk(bytes, node, length, mux);
85 } else {
86 throw std::runtime_error("illegal protocoll type");
88 //root_[type].print(0);
91 void RoutingTable::addRoute(const NetworkPrefix & pref, u_int16_t mux)
93 Lock lock(mutex_);
95 network_address_type_t type=pref.getNetworkAddressType();
97 if (type==ipv4 || type==ipv6)
99 std::pair<RoutingMap::iterator, bool> ret = routes_[type].insert(RoutingMap::value_type(pref,mux));
100 if(!ret.second)
102 routes_[pref.getNetworkAddressType()].erase(ret.first);
103 routes_[pref.getNetworkAddressType()].insert(RoutingMap::value_type(pref,mux));
105 updateRouteTreeUnlocked(pref);
106 } else if (type==ethernet) {
107 return; // TODO: add support for ethernet
108 } else {
109 throw std::runtime_error("illegal protocoll type");
114 void RoutingTable::delRoute(const NetworkPrefix & pref )
116 Lock lock(mutex_);
118 routes_[pref.getNetworkAddressType()].erase(routes_[pref.getNetworkAddressType()].find(pref));
121 u_int16_t RoutingTable::getRoute(const NetworkAddress & addr)
123 Lock lock(mutex_);
124 network_address_type_t type=addr.getNetworkAddressType();
126 if (routes_[type].empty())
127 throw std::runtime_error("no route");
129 if (type==ipv4)
131 ipv4_bytes_type bytes(addr.to_bytes_v4());
132 return RoutingTree::find(bytes, root_[type]);
133 } else if (type==ipv6) {
134 ipv6_bytes_type bytes(addr.to_bytes_v6());
135 return RoutingTree::find(bytes, root_[type]);
136 } else if (type==ethernet) {
137 //TODO Our model wont fit to ethernet addresses well.
138 // maybe use hashmap or something like that instead
139 ethernet_bytes_type bytes(addr.to_bytes_ethernet());
140 return RoutingTree::find(bytes, root_[type]);
141 } else {
142 throw std::runtime_error("illegal protocoll type");
146 u_int16_t* RoutingTable::getOrNewRoutingTEUnlocked(const NetworkPrefix & addr)
148 RoutingMap::iterator it = routes_[addr.getNetworkAddressType()].find(addr);
149 if(it!=routes_[addr.getNetworkAddressType()].end())
150 return &(it->second);
152 routes_[addr.getNetworkAddressType()].insert(RoutingMap::value_type(addr, 1));
153 it = routes_[addr.getNetworkAddressType()].find(addr);
154 return &(it->second);
157 u_int16_t RoutingTable::getCountUnlocked(network_address_type_t type)
159 RoutingMap::iterator it = routes_[type].begin();
160 u_int16_t routes=0;
161 for (;it!=routes_[type].end();++it)
162 routes++;
163 return routes;
166 RoutingMap::iterator RoutingTable::getBeginUnlocked(network_address_type_t type)
168 return routes_[type].begin();
171 RoutingMap::iterator RoutingTable::getEndUnlocked(network_address_type_t type)
173 return routes_[type].end();
176 void RoutingTable::clear(network_address_type_t type)
178 Lock lock(mutex_);
179 routes_[type].clear();
182 bool RoutingTable::empty(network_address_type_t type)
184 Lock lock(mutex_);
185 return routes_[type].empty();
188 Mutex& RoutingTable::getMutex()
190 return mutex_;