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()
46 static instanceCleaner c
;
48 inst
= new RoutingTable();
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
]);
71 ipv4_bytes_type
bytes(pref
.to_bytes_v4());
74 RoutingTree::walk(bytes
, node
, length
, mux
);
75 } else if (type
==ipv6
) {
76 ipv6_bytes_type
bytes(pref
.to_bytes_v6());
79 RoutingTree::walk(bytes
, node
, length
, mux
);
80 } else if (type
==ethernet
) {
81 ethernet_bytes_type
bytes(pref
.to_bytes_ethernet());
84 RoutingTree::walk(bytes
, node
, length
, mux
);
86 throw std::runtime_error("illegal protocoll type");
88 //root_[type].print(0);
91 void RoutingTable::addRoute(const NetworkPrefix
& pref
, u_int16_t mux
)
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
));
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
109 throw std::runtime_error("illegal protocoll type");
114 void RoutingTable::delRoute(const NetworkPrefix
& pref
)
118 routes_
[pref
.getNetworkAddressType()].erase(routes_
[pref
.getNetworkAddressType()].find(pref
));
121 u_int16_t
RoutingTable::getRoute(const NetworkAddress
& addr
)
124 network_address_type_t type
=addr
.getNetworkAddressType();
126 if (routes_
[type
].empty())
127 throw std::runtime_error("no route");
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
]);
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();
161 for (;it
!=routes_
[type
].end();++it
)
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
)
179 routes_
[type
].clear();
182 bool RoutingTable::empty(network_address_type_t type
)
185 return routes_
[type
].empty();
188 Mutex
& RoutingTable::getMutex()