00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00026
00027 # include "msg/message.hh"
00028
00029 #ifndef QOLYESTER_DAEMON_SET_NEIGHBORS_HH
00030 # define QOLYESTER_DAEMON_SET_NEIGHBORS_HH 1
00031
00032 # include "config.hh"
00033
00034 # include "cst/constants.hh"
00035 # include "net/ipaddress.hh"
00036 # include "sch/scheduler.hh"
00037 # include "utl/set.hh"
00038 # include "utl/seqnum.hh"
00039 # include "utl/stampable.hh"
00040 # include "utl/timeval.hh"
00041
00042 namespace olsr {
00043
00044 namespace sch {
00045
00046 class StatePrinter;
00047
00048 }
00049
00050 namespace set {
00051
00052
00053
00054
00055
00056 class Link : public utl::MultiStampable<1, address_t> {
00057 typedef Link This;
00058 typedef utl::MultiStampable<1, address_t> Super;
00059
00060 explicit Link();
00061
00062 # ifdef QOLYESTER_ENABLE_LINKHYS
00063 class LinkQuality {
00064 typedef LinkQuality This;
00065 public:
00066 LinkQuality(Link& i, float v = HYST_SCALING);
00067 virtual ~LinkQuality() {}
00068 operator float() const {
00069 return value_;
00070 }
00071 This& operator++();
00072 This operator++(int) {
00073 This tmp(*this);
00074 ++*this;
00075 return tmp;
00076 }
00077 This& operator--();
00078 This operator--(int) {
00079 This tmp(*this);
00080 --*this;
00081 return tmp;
00082 }
00083 void expire() {
00084 ++expired_;
00085 }
00086 void lost(unsigned n) {
00087 if (n > expired_ || n == 0)
00088 blocked_ = false;
00089 else
00090 blocked_ = true;
00091 expired_ = 0;
00092 }
00093 private:
00094 void update();
00095
00096 float value_;
00097 Link& instance_;
00098 unsigned expired_;
00099 bool blocked_;
00100 };
00101 public:
00102 Link(const address_t& l, const address_t& r, const address_t& m,
00103 const timeval_t& v, const seqnum_t& s, const timeval_t& ht);
00104 # else
00105 public:
00106 Link(const address_t& l, const address_t& r, const address_t& m,
00107 const timeval_t& v);
00108 # endif
00109
00110 Link(const This& other);
00111
00112 virtual ~Link() {}
00113
00114 void set_asymtime(const timeval_t& t) { asymtime_ = t; }
00115 void set_symtime (const timeval_t& t) { symtime_ = t; }
00116 void set_time (const timeval_t& t) { time_ = t; }
00117 # ifdef QOLYESTER_ENABLE_LINKHYS
00118 void set_losttime(const timeval_t& t) { losttime_ = t; }
00119 void set_nexttime(const timeval_t& t) { nexttime_ = t; }
00120 void set_htime (const timeval_t& t) { htime_ = t; }
00121 void set_pending (const bool p) { pending_ = p; }
00122
00123 void set_last_seqnum(const seqnum_t& s);
00124 # endif // !QOLYESTER_ENABLE_LINKHYS
00125
00126
00127 const address_t& local_addr() const { return l_addr_; }
00128 const address_t& remote_addr() const { return r_addr_; }
00129 const address_t& main_addr() const { return m_addr_; }
00130 const timeval_t& asymtime() const { return asymtime_; }
00131 const timeval_t& symtime() const { return symtime_; }
00132 const timeval_t& time() const { return time_; }
00133 # ifdef QOLYESTER_ENABLE_LINKHYS
00134 const timeval_t& losttime() const { return losttime_; }
00135 const timeval_t& nexttime() const { return nexttime_; }
00136 const timeval_t& htime() const { return htime_; }
00137 const bool pending() const { return pending_; }
00138
00139 const LinkQuality& quality() const { return quality_; }
00140 LinkQuality& quality() { return quality_; }
00141 # endif // !QOLYESTER_ENABLE_LINKHYS
00142
00143
00144 bool is_valid() const;
00145 bool is_sym() const;
00146
00147
00148 bool operator<(const This& rhs) const;
00149
00150
00151 static const This& make_key(const address_t& local,
00152 const address_t& remote);
00153 static const This& make_key_local(const address_t& local);
00154 private:
00155 const address_t l_addr_;
00156 const address_t r_addr_;
00157 const address_t m_addr_;
00158 timeval_t asymtime_;
00159 timeval_t symtime_;
00160 timeval_t time_;
00161 # ifdef QOLYESTER_ENABLE_LINKHYS
00162 timeval_t losttime_;
00163 timeval_t nexttime_;
00164 timeval_t htime_;
00165 bool pending_;
00166 LinkQuality quality_;
00167 seqnum_t last_seqnum_;
00168 # endif // !QOLYESTER_ENABLE_LINKHYS
00169
00170
00171 static This dummy_for_find_;
00172
00173 friend class sch::StatePrinter;
00174 };
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 class CoherenceProxy;
00187
00188 namespace upd {
00189
00190 class LinkUpdater {
00191 typedef LinkUpdater This;
00192 typedef CoherenceProxy Set;
00193 typedef sch::Updatable<Link> elem_t;
00194 typedef std::set<elem_t>::iterator Iter;
00195 typedef sch::UpdateEvent<This> updater_t;
00196 public:
00197 LinkUpdater(Set& s, const Iter& i)
00198 : set_(s),
00199 iter_(i)
00200 {}
00201 void operator()();
00202 static timeval_t min_time(const Link& l) {
00203 timeval_t min_time(0);
00204 if (!l.time().is_past())
00205 min_time = l.time();
00206 if (!l.asymtime().is_past() &&
00207 (min_time == 0 ||
00208 l.asymtime() < min_time))
00209 min_time = l.asymtime();
00210 if (!l.symtime().is_past() &&
00211 (min_time == 0 ||
00212 l.symtime() < min_time))
00213 min_time = l.symtime();
00214 # ifdef QOLYESTER_ENABLE_LINKHYS
00215 if (!l.losttime().is_past() &&
00216 (min_time == 0 ||
00217 l.losttime() < min_time))
00218 min_time = l.losttime();
00219 if (!l.nexttime().is_past() &&
00220 (min_time == 0 ||
00221 l.nexttime() < min_time))
00222 min_time = l.nexttime();
00223 # endif // !QOLYESTER_ENABLE_LINKHYS
00224 return min_time;
00225 }
00226 private:
00227 Set& set_;
00228 Iter iter_;
00229 };
00230
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 class Neighbor : public utl::MultiStampable<1, address_t> {
00301 typedef Neighbor This;
00302 typedef utl::MultiStampable<1, address_t> Super;
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 typedef sch::Updatable<Link> ulink_t;
00317
00318 struct ilinkless {
00319 typedef std::set<ulink_t>::iterator iter_t;
00320 bool operator()(const iter_t& a, const iter_t& b) const {
00321 return a->local_addr() < b->local_addr();
00322 }
00323 };
00324
00325 typedef utl::Index<std::multiset,
00326 std::set<ulink_t>,
00327 ilinkless> lset_t;
00328
00329 struct lset_valid {
00330 bool operator()(This&, const lset_t::iterator& pos) const {
00331 return pos->is_valid();
00332 }
00333 };
00334
00335 typedef utl::Subset<utl::MultiAdapt<lset_t>,
00336 utl::NoAction<This, lset_t::iterator>,
00337 lset_valid,
00338 This> val_lset_t;
00339
00340 explicit Neighbor();
00341 public:
00342 typedef val_lset_t linkset_t;
00343
00344 Neighbor(const address_t& maddr, const std::set<ulink_t>::iterator& i,
00345 unsigned w);
00346
00347 Neighbor(const This&);
00348
00349 virtual ~Neighbor() {}
00350
00351 const address_t& main_addr() const { return m_addr_; }
00352 unsigned willingness() const { return willingness_; }
00353 const timeval_t& mprsel_time() const { return mprsel_time_; }
00354
00355 void set_willingness(unsigned w);
00356
00357 bool is_sym() const { return sym_; }
00358 bool is_mpr() const { return mpr_; }
00359 bool is_mprsel() const;
00360 bool was_mprsel();
00361
00362 void set_sym(bool state) { sym_ = state; }
00363
00364 void set_mpr(bool state) { mpr_ = state; }
00365
00366 void set_mprsel(const timeval_t& validity);
00367
00368 void unset_mprsel();
00369
00370 std::pair<linkset_t::const_iterator, linkset_t::const_iterator>
00371 find_lifaces(const address_t& laddr) const;
00372
00373
00374
00375 linkset_t& linkset() { return val_lset_; }
00376
00377 void insert(const std::set<ulink_t>::iterator& pos);
00378
00379 void erase(const lset_t::iterator& pos);
00380 void erase(const std::set<ulink_t>::iterator& pos);
00381
00382 bool operator<(const This& rhs) const;
00383
00384 static const This& make_key(const address_t& m);
00385
00386 private:
00387 const address_t m_addr_;
00388 lset_t lset_;
00389 val_lset_t val_lset_;
00390 bool sym_;
00391 bool mpr_;
00392 timeval_t mprsel_time_;
00393 bool was_mprsel_;
00394 unsigned willingness_;
00395
00396 static Neighbor dummy_for_find_;
00397
00398 friend class sch::StatePrinter;
00399 };
00400
00401 namespace upd {
00402
00403 class NeighborUpdater {
00404 typedef NeighborUpdater This;
00405 typedef CoherenceProxy Set;
00406 typedef sch::Updatable<Neighbor> elem_t;
00407 typedef std::set<elem_t>::iterator Iter;
00408 typedef sch::UpdateEvent<This> updater_t;
00409 public:
00410 NeighborUpdater(Set& s, const Iter& i)
00411 : set_(s),
00412 iter_(i)
00413 {}
00414 void operator()();
00415 private:
00416 Set& set_;
00417 Iter iter_;
00418 };
00419
00420 }
00421
00423
00424
00425
00426 class CoherenceProxy {
00427 typedef CoherenceProxy This;
00428
00429
00430
00431 typedef sch::Updatable<Link> ulink_t;
00432 typedef sch::UpdateEvent<upd::LinkUpdater> link_updater_t;
00433 typedef std::set<ulink_t> lset_t;
00434
00435 typedef sch::Updatable<Neighbor> uneighbor_t;
00436 typedef sch::UpdateEvent<upd::NeighborUpdater> neighbor_updater_t;
00437
00438 struct stampable_nset_ : public std::set<uneighbor_t>,
00439 public utl::Stampable {};
00440
00441 typedef stampable_nset_ nset_t;
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493 template <class Set, class Iter>
00494 struct nset_valid {
00495 bool operator()(Set& explicit_this, const Iter& pos) const {
00496 return explicit_this.is_valid(pos);
00497 }
00498 };
00499
00500
00501 typedef utl::Subset<lset_t> val_lset_t;
00502
00503
00504 typedef utl::Subset<nset_t,
00505 utl::NoAction<This, nset_t::iterator>,
00506 nset_valid<This, nset_t::iterator>,
00507 This> val_nset_t;
00508
00509 template <class Set>
00510 struct nset_sym {
00511 bool operator()(Set&, const typename Set::iterator& pos) const {
00512 return pos->is_sym();
00513 }
00514 };
00515
00516
00517 typedef utl::Subset<val_nset_t,
00518 utl::NoAction<val_nset_t>,
00519 nset_sym<val_nset_t> > sym_val_nset_t;
00520
00521 typedef utl::MSIndex<lset_t, 0, address_t> idx_lset_t;
00522
00523
00524 typedef utl::MSIndex<nset_t, 0, address_t> idx_nset_t;
00525
00526
00527
00528
00529 typedef utl::Subset<utl::MSAdapt<idx_lset_t>,
00530 utl::NoAction<idx_lset_t>,
00531 utl::DefaultPredicate<idx_lset_t>,
00532 idx_lset_t> val_idx_lset_t;
00533
00534
00535 typedef utl::Subset<utl::MSAdapt<idx_nset_t>,
00536 utl::NoAction<This, idx_nset_t::iterator>,
00537 nset_valid<This, idx_nset_t::iterator>,
00538 This> val_idx_nset_t;
00539
00540
00541
00542
00543
00544
00545
00546 struct val_idx_nset_stamper {
00547 void operator()(val_idx_nset_t& set_ref,
00548 val_idx_nset_t::iterator pos) const {
00549 set_ref.set_stamp(pos);
00550 }
00551 };
00552
00553 typedef utl::Subset<utl::MSAdapt<val_idx_nset_t>,
00554 val_idx_nset_stamper,
00555 nset_sym<val_idx_nset_t>,
00556 val_idx_nset_t> sym_val_idx_nset_t;
00557 public:
00558 CoherenceProxy();
00559
00560 virtual ~CoherenceProxy();
00561
00562 typedef val_lset_t linkset_t;
00563 typedef val_idx_lset_t hello_linkset_t;
00564
00565 typedef val_nset_t neighborset_t;
00566 typedef sym_val_nset_t sym_neighborset_t;
00567 typedef sym_val_idx_nset_t tc_neighborset_t;
00568
00584 # ifdef QOLYESTER_ENABLE_LINKHYS
00585 std::pair<neighborset_t::iterator, bool>
00586 insert_link(const msg::Message::header& mh,
00587 const int linktype,
00588 const int will,
00589 const timeval_t& htime);
00590 # else // !QOLYESTER_ENABLE_LINKHYS
00591 std::pair<neighborset_t::iterator, bool>
00592 insert_link(const msg::Message::header& mh,
00593 const int linktype,
00594 const int will);
00595 # endif
00608 void set_willingness(const nset_t::iterator& pos, unsigned w);
00609
00614 void update_graph(const nset_t::iterator& pos);
00615
00621 bool update_state(const nset_t::iterator& pos);
00622
00623 void update_state(const address_t& maddr);
00624
00629 void set_sym(const nset_t::iterator& pos);
00630
00635 void unset_sym(const nset_t::iterator& pos);
00636
00637 void set_mpr(const nset_t::iterator& pos);
00638 void set_mpr(const sym_neighborset_t::iterator& pos);
00639
00640 void unset_mpr(const nset_t::iterator& pos);
00641 void unset_mpr(const sym_neighborset_t::iterator& pos);
00642
00643 void set_mprsel(const nset_t::iterator& pos,
00644 const timeval_t& v);
00645
00646 void unset_mprsel(const nset_t::iterator& pos);
00647
00648 bool is_advset_empty();
00649
00650 bool is_hold_expired() const {
00651 return nset_.expired(cst::top_hold_time);
00652 }
00653
00654 void stamp_hold() {
00655 nset_.set_stamp();
00656 }
00657
00658 bool is_valid(const nset_t::iterator& pos);
00659 bool is_valid(const idx_nset_t::iterator& pos);
00660
00661
00662 void erase(lset_t::iterator pos);
00663 private:
00664 void erase_from_all(nset_t::iterator pos);
00665 public:
00666
00667
00668 linkset_t& linkset() {
00669 return linkset_;
00670 }
00671
00672 hello_linkset_t& hello_linkset() {
00673 return hello_linkset_;
00674 }
00675
00676 neighborset_t& neighborset() {
00677 return neighborset_;
00678 }
00679
00680 sym_neighborset_t& sym_neighborset() {
00681 return sym_neighborset_;
00682 }
00683
00684 tc_neighborset_t& tc_neighborset() {
00685 return tc_neighborset_;
00686 }
00687
00688 const utl::Seqnum<u_int16_t>& advset_seqnum() {
00689 if (advset_changed_) {
00690 ++advset_seqnum_;
00691 advset_changed_ = false;
00692 }
00693 return advset_seqnum_;
00694 }
00695
00696
00697 void add_interface(const address_t& a);
00698
00699 void remove_interface(const address_t& a);
00700
00701 private:
00702 lset_t lset_;
00703 nset_t nset_;
00704
00705 linkset_t linkset_;
00706
00707 idx_lset_t idx_lset_;
00708 hello_linkset_t hello_linkset_;
00709
00710 neighborset_t neighborset_;
00711
00712 sym_neighborset_t sym_neighborset_;
00713
00714 idx_nset_t idx_nset_;
00715 val_idx_nset_t val_idx_nset_;
00716 tc_neighborset_t tc_neighborset_;
00717
00718 utl::Seqnum<u_int16_t> advset_seqnum_;
00719 bool advset_changed_;
00720
00721 unsigned sym_count_;
00722 unsigned mpr_count_;
00723 bool mprsel_empty_;
00724
00725 friend class sch::StatePrinter;
00726
00727 };
00728
00729 class TwoHopNeighbor {
00730 typedef TwoHopNeighbor This;
00731
00732 TwoHopNeighbor();
00733 public:
00734 TwoHopNeighbor(const address_t& a,
00735 const address_t& tha,
00736 const timeval_t& validity);
00737
00738 virtual ~TwoHopNeighbor() {}
00739
00740
00741 const address_t& main_addr() const { return mainaddr_; }
00742 const address_t& twohop_addr() const { return twohopaddr_; }
00743 const timeval_t& time() const { return time_; }
00744
00745
00746 void set_time(const timeval_t& t) { time_ = t; }
00747
00748 bool is_valid() const { return !time_.is_past(); }
00749
00750 bool operator<(const This& rhs) const;
00751
00752 This& operator=(const This& other);
00753
00754 static const This& make_key(const address_t& ma,
00755 const address_t& tha);
00756 private:
00757 const address_t mainaddr_;
00758 const address_t twohopaddr_;
00759 timeval_t time_;
00760
00761 static This dummy_for_find_;
00762
00763 friend class sch::StatePrinter;
00764 };
00765
00766 class TwoHopNeighborSet {
00767 typedef TwoHopNeighborSet This;
00768 typedef sch::Updatable<TwoHopNeighbor> elem_t;
00769 typedef std::set<elem_t> tset_t;
00770 typedef sch::upd::SetEraser<This, tset_t::iterator> eraser_t;
00771 typedef sch::UpdateEvent<eraser_t> updater_t;
00772
00773 typedef utl::Subset<tset_t,
00774 utl::NoAction<This, tset_t::iterator>,
00775 utl::DefaultPredicate<This, tset_t::iterator>,
00776 This> val_tset_t;
00777 public:
00778 typedef val_tset_t thnset_t;
00779
00780 thnset_t& thnset() { return thnset_; }
00781
00782 TwoHopNeighborSet();
00783 virtual ~TwoHopNeighborSet() {}
00784
00785 void insert(const TwoHopNeighbor& x);
00786 void erase(const tset_t::iterator& pos);
00787 void erase(const tset_t::value_type& x);
00788
00789 private:
00790 tset_t tset_;
00791 thnset_t thnset_;
00792
00793 friend class sch::StatePrinter;
00794 };
00795
00796 }
00797
00798 typedef set::CoherenceProxy cproxy_t;
00799 typedef set::TwoHopNeighborSet thnset_t;
00800
00801 }
00802
00803 # ifndef QOLYESTER_DONTINCLUDE_HXX
00804 # include "neighbors.hxx"
00805 # endif
00806
00807 #endif // ! QOLYESTER_DAEMON_SET_NEIGHBORS_HH