#ifndef CLICK_LINKTABLE_HH
#define CLICK_LINKTABLE_HH
#include <click/ipaddress.hh>
#include <click/glue.hh>
#include <click/timer.hh>
#include <click/element.hh>
#include <click/bighashmap.hh>
#include <click/hashmap.hh>
#include "path.hh"
CLICK_DECLS
/*
* =c
* LinkTable(IP Address, [STALE timeout])
* =s Wifi
* Keeps a Link state database and calculates Weighted Shortest Path
* for other elements
* =d
* Runs dijkstra's algorithm occasionally.
* =a ARPTable
*
*/
class IPPair {
public:
IPAddress _to;
IPAddress _from;
IPPair() : _to(), _from() { }
IPPair(IPAddress from, IPAddress to) {
_to = to;
_from = from;
}
bool contains(IPAddress foo) {
return ((foo == _to) || (foo == _from));
}
bool other(IPAddress foo) { return ((_to == foo) ? _from : _to); }
inline bool
operator==(IPPair other)
{
return (other._to == _to && other._from == _from);
}
};
inline unsigned
hashcode(IPPair p)
{
return hashcode(p._to) + hashcode(p._from);
}
class LinkTable: public Element{
public:
/* generic click-mandated stuff*/
LinkTable();
~LinkTable();
void add_handlers();
const char* class_name() const { return "LinkTable"; }
int initialize(ErrorHandler *);
void run_timer(Timer *);
int configure(Vector<String> &conf, ErrorHandler *errh);
void take_state(Element *, ErrorHandler *);
void *cast(const char *n);
/* read/write handlers */
String print_routes(bool, bool);
String print_links();
String print_hosts();
static int static_update_link(const String &arg, Element *e,
void *, ErrorHandler *errh);
void clear();
/* other public functions */
String route_to_string(Path p);
bool update_link(IPAddress from, IPAddress to,
uint32_t seq, uint32_t age, uint32_t metric);
bool update_both_links(IPAddress a, IPAddress b,
uint32_t seq, uint32_t age, uint32_t metric) {
if (update_link(a,b,seq,age, metric)) {
return update_link(b,a,seq,age, metric);
}
return false;
}
uint32_t get_link_metric(IPAddress from, IPAddress to);
uint32_t get_link_seq(IPAddress from, IPAddress to);
uint32_t get_link_age(IPAddress from, IPAddress to);
bool valid_route(Vector<IPAddress> route);
unsigned get_route_metric(Vector<IPAddress> route);
Vector<IPAddress> get_neighbors(IPAddress ip);
void dijkstra(bool);
void clear_stale();
Vector<IPAddress> best_route(IPAddress dst, bool from_me);
Vector< Vector<IPAddress> > top_n_routes(IPAddress dst, int n);
uint32_t get_host_metric_to_me(IPAddress s);
uint32_t get_host_metric_from_me(IPAddress s);
Vector<IPAddress> get_hosts();
class Link {
public:
IPAddress _from;
IPAddress _to;
uint32_t _seq;
uint32_t _metric;
Link() : _from(), _to(), _seq(0), _metric(0) { }
Link(IPAddress from, IPAddress to, uint32_t seq, uint32_t metric) {
_from = from;
_to = to;
_seq = seq;
_metric = metric;
}
};
Link random_link();
typedef HashMap<IPAddress, IPAddress> IPTable;
typedef IPTable::const_iterator IPIter;
IPTable _blacklist;
struct timeval dijkstra_time;
private:
class LinkInfo {
public:
IPAddress _from;
IPAddress _to;
unsigned _metric;
uint32_t _seq;
uint32_t _age;
struct timeval _last_updated;
LinkInfo() {
_from = IPAddress();
_to = IPAddress();
_metric = 0;
_seq = 0;
_age = 0;
_last_updated.tv_sec = 0;
}
LinkInfo(IPAddress from, IPAddress to,
uint32_t seq, uint32_t age, unsigned metric) {
_from = from;
_to = to;
_metric = metric;
_seq = seq;
_age = age;
click_gettimeofday(&_last_updated);
}
LinkInfo(const LinkInfo &p) :
_from(p._from), _to(p._to),
_metric(p._metric), _seq(p._seq),
_age(p._age),
_last_updated(p._last_updated)
{ }
uint32_t age() {
struct timeval now;
click_gettimeofday(&now);
return _age + (now.tv_sec - _last_updated.tv_sec);
}
void update(uint32_t seq, uint32_t age, unsigned metric) {
if (seq <= _seq) {
return;
}
_metric = metric;
_seq = seq;
_age = age;
click_gettimeofday(&_last_updated);
}
};
class HostInfo {
public:
IPAddress _ip;
uint32_t _metric_from_me;
uint32_t _metric_to_me;
IPAddress _prev_from_me;
IPAddress _prev_to_me;
bool _marked_from_me;
bool _marked_to_me;
HostInfo(IPAddress p) {
_ip = p;
_metric_from_me = 0;
_metric_to_me = 0;
_prev_from_me = IPAddress();
_prev_to_me = IPAddress();
_marked_from_me = false;
_marked_to_me = false;
}
HostInfo() {
HostInfo(IPAddress());
}
HostInfo(const HostInfo &p) :
_ip(p._ip),
_metric_from_me(p._metric_from_me),
_metric_to_me(p._metric_to_me),
_prev_from_me(p._prev_from_me),
_prev_to_me(p._prev_to_me),
_marked_from_me(p._marked_from_me),
_marked_to_me(p._marked_to_me)
{ }
void clear(bool from_me) {
if (from_me ) {
_prev_from_me = IPAddress();
_metric_from_me = 0;
_marked_from_me = false;
} else {
_prev_to_me = IPAddress();
_metric_to_me = 0;
_marked_to_me = false;
}
}
};
typedef HashMap<IPAddress, HostInfo> HTable;
typedef HTable::const_iterator HTIter;
typedef HashMap<IPPair, LinkInfo> LTable;
typedef LTable::const_iterator LTIter;
HTable _hosts;
LTable _links;
IPAddress _ip;
struct timeval _stale_timeout;
Timer _timer;
};
CLICK_ENDDECLS
#endif /* CLICK_LINKTABLE_HH */
syntax highlighted by Code2HTML, v. 0.9.1