00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef QOLYESTER_DAEMON_MSG_MID_HXX
00020 # define QOLYESTER_DAEMON_MSG_MID_HXX 1
00021
00022 # include "set/interfaces.hh"
00023 # include "set/mid.hh"
00024 # include "set/neighbors.hh"
00025 # include "utl/args.hh"
00026
00027 # include "mid.hh"
00028
00029 namespace olsr {
00030
00031 extern ifaceset_t iface_set;
00032 extern midset_t mid_set;
00033 extern cproxy_t cproxy;
00034 extern std::ostream dump_mid;
00035
00036 namespace msg {
00037
00038 MIDMessage::MIDMessage() : _data() {}
00039
00040 MIDMessage::MIDMessage(const utl::Data& d, const address_t&) : _data(d) {}
00041
00042 bool
00043 MIDMessage::dump(utl::Data& d, const address_t& interface) const {
00044 bool ret = false;
00045
00046 if (_data.empty()) {
00047
00048
00049
00050 if (d.size() < Message::min_length + min_length)
00051 return true;
00052
00053 if (do_dump_mid)
00054 dump_mid << "MID preparation (" << interface << ") "
00055 << Message::seqnum << " {\n";
00056
00057 Message::raw* mraw = reinterpret_cast<Message::raw*>(d.raw());
00058
00059 d += sizeof *mraw;
00060
00061 mraw->type = MID_MESSAGE;
00062 mraw->vtime = utl::Vtime(cst::mid_hold_time);
00063 mraw->size = 0;
00064 main_addr.dump(mraw->addr);
00065 mraw->ttl = 255;
00066 mraw->hopcount = 0;
00067 mraw->seqnum = htons(Message::seqnum);
00068
00069 typedef std::list<ifaceset_t::mid_iset_t::iterator> ipset_t;
00070 ipset_t ip_set;
00071
00072 for (ifaceset_t::mid_iset_t::iterator i =
00073 iface_set.mid_iset().begin(interface);
00074 i != iface_set.mid_iset().end(interface); ++i) {
00075
00076 if (iface_set.mid_iset().stamp(i) == timeval_t::now())
00077 break;
00078
00079 if (i->addr() == main_addr)
00080 continue;
00081
00082 if (d.size() < ADDRESS_SIZE) {
00083 if (iface_set.mid_iset().expired(i,
00084 cst::mid_interval,
00085 timeval_t::in(cst::mid_interval)))
00086 ret = true;
00087 break;
00088 }
00089
00090 if (do_dump_mid)
00091 dump_mid << " " << i->addr() << "\n";
00092
00093 i->addr().dump(d.raw());
00094 ip_set.push_back(i);
00095 d += ADDRESS_SIZE;
00096 }
00097
00098 mraw->size = htons(d.raw() - reinterpret_cast<u_int8_t*>(mraw));
00099
00100 if (do_dump_mid)
00101 dump_mid << "}" << std::endl;
00102
00103 for (ipset_t::const_iterator i = ip_set.begin();
00104 i != ip_set.end(); ++i)
00105 iface_set.mid_iset().set_stamp(*i);
00106
00107 } else {
00108 if (d.size() < _data.size())
00109 return true;
00110
00111 _data.dump(d);
00112 d += _data.size();
00113 }
00114
00115 return ret;
00116 }
00117
00118 void
00119 MIDMessage::parse(const utl::ConstData& d, const Message::header& mh) {
00120 if (do_dump_mid)
00121 dump_mid << "MID from " << mh.originator
00122 << " (" << mh.sender << " -> " << mh.receiver << ") M("
00123 << mh.mseqnum << ") P(" << mh.pseqnum << ") {\n";
00124
00125
00126
00127
00128
00129 cproxy_t::linkset_t::iterator l =
00130 cproxy.linkset().find(set::Link::make_key(mh.receiver, mh.sender));
00131
00132 if (l == cproxy.linkset().end() || !l->is_sym()) {
00133
00134 if (do_dump_mid)
00135 dump_mid << " (ignored since not from symmetric neighbor)\n}"
00136 << std::endl;
00137 return;
00138 }
00139
00140 const u_int8_t (*addrs)[ADDRESS_SIZE] =
00141 reinterpret_cast<const u_int8_t (*)[ADDRESS_SIZE]>(d.raw());
00142 unsigned len = d.size() / ADDRESS_SIZE;
00143
00144 for (unsigned i = 0; i < len; ++i) {
00145 address_t addr(addrs[i], ADDRESS_SIZE);
00146
00147 if (do_dump_mid)
00148 dump_mid << " " << addr << "\n";
00149
00150 mid_set.insert(set::MIDEntry(addr, mh.originator, mh.validity));
00151 }
00152
00153 if (do_dump_mid)
00154 dump_mid << "}" << std::endl;
00155 }
00156
00157 }
00158
00159 }
00160
00161 #endif // ! QOLYESTER_DAEMON_MSG_MID_HXX