00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef QOLYESTER_DAEMON_MSG_MESSAGE_HXX
00020 # define QOLYESTER_DAEMON_MSG_MESSAGE_HXX 1
00021
00022 # include "utl/vtime.hh"
00023 # include "set/duplicate.hh"
00024 # include "sch/events.hh"
00025 # include "msg/hello.hh"
00026 # include "msg/hna.hh"
00027 # include "msg/mid.hh"
00028 # include "msg/tc.hh"
00029
00030 # include "message.hh"
00031
00032 namespace olsr {
00033
00034 namespace msg {
00035
00036
00037 void
00038 Message::parse(utl::Data d,
00039 const address_t& sender,
00040 const address_t& receiver,
00041 const seqnum_t& pseqnum) {
00042
00043
00044 raw* h = reinterpret_cast<raw*>(d.raw());
00045
00046 if (h->ttl == 0)
00047 return;
00048
00049
00050 address_t orig(h->addr, ADDRESS_SIZE);
00051
00052
00053 if (orig == main_addr)
00054 return;
00055
00056
00057
00058 assert(d.size() == (u_int16_t)(ntohs(h->size)));
00059
00060 utl::Data payload = d + sizeof (raw);
00061 timeval_t validity = utl::Vtime(h->vtime).operator timeval_t();
00062
00063
00064 seqnum_t seqnum(ntohs(h->seqnum));
00065
00066 header mh(sender, receiver, orig, validity,
00067 pseqnum, seqnum, h->hopcount);
00068
00069
00070 if (h->type == HELLO_MESSAGE) {
00071 HELLOMessage::parse(payload, mh);
00072 return;
00073 }
00074
00075
00076 dupset_t::dupset_t::iterator x =
00077 dup_set.dupset().find(set::DuplicateEntry::make_key(orig, seqnum));
00078
00079 if (x == dup_set.dupset().end()) {
00080
00081
00082
00083 switch (h->type) {
00084 case HELLO_MESSAGE:
00085 assert(HELLO_MESSAGE != HELLO_MESSAGE);
00086 break;
00087 case TC_MESSAGE:
00088 TCMessage::parse(payload, mh);
00089 break;
00090 case MID_MESSAGE:
00091 MIDMessage::parse(payload, mh);
00092 break;
00093 case HNA_MESSAGE:
00094 HNAMessage::parse(payload, mh);
00095 break;
00096 default:
00097 break;
00098 }
00099
00100 }
00101
00102
00103 if (x == dup_set.dupset().end() || !x->in_ifaces(receiver)) {
00104
00105
00106 switch (h->type) {
00107 case HELLO_MESSAGE:
00108
00109
00110
00111 assert(HELLO_MESSAGE != HELLO_MESSAGE);
00112 break;
00113 case TC_MESSAGE:
00114 TCMessage::forward(d, mh);
00115 break;
00116 case MID_MESSAGE:
00117 MIDMessage::forward(d, mh);
00118 break;
00119 case HNA_MESSAGE:
00120 HNAMessage::forward(d, mh);
00121 break;
00122 default:
00123
00124 Message::forward(d, mh);
00125 break;
00126 }
00127 }
00128 }
00129
00130
00131 void
00132 Message::forward(utl::Data& d, const header& mh) {
00133 cproxy_t::linkset_t::iterator lx =
00134 cproxy.linkset().find(set::Link::make_key(mh.receiver, mh.sender));
00135
00136
00137
00138 if (lx == cproxy.linkset().end() || !lx->is_sym())
00139 return;
00140
00141
00142 raw* h = reinterpret_cast<raw*>(d.raw());
00143
00144
00145 dupset_t::dupset_t::iterator dx =
00146 dup_set.dupset().find(set::DuplicateEntry::make_key(mh.originator,
00147 ntohs(h->seqnum)));
00148
00149
00150
00151
00152 if (dx != dup_set.dupset().end() &&
00153 (dx->retransmitted() || dx->in_ifaces(mh.receiver)))
00154 return;
00155
00156
00157 const address_t& maddr = alg::main_addr_of(mh.sender);
00158
00159
00160
00161
00162 cproxy_t::sym_neighborset_t::iterator nx =
00163 cproxy.sym_neighborset().find(set::Neighbor::make_key(maddr));
00164
00165 bool retransmit = false;
00166 if (nx != cproxy.sym_neighborset().end() &&
00167 nx->is_mprsel() &&
00168 h->ttl > 1)
00169 retransmit = true;
00170
00171
00172 dup_set.insert(set::DuplicateEntry(mh.originator,
00173 ntohs(h->seqnum),
00174 mh.receiver, retransmit));
00175
00176
00177 if (!retransmit)
00178 return;
00179
00180
00181 --h->ttl;
00182 ++h->hopcount;
00183
00184
00185 typedef UnknownMessage um_t;
00186 typedef sch::MessageForwarder mf_t;
00187
00188 scheduler.insert(new mf_t(timeval_t::in_jitter(cst::maxjitter),
00189 um_t(d)));
00190 }
00191
00192 UnknownMessage::UnknownMessage(utl::Data& d) : _data(d) {}
00193
00194
00195 bool
00196 UnknownMessage::dump(utl::Data& d, const address_t&) const {
00197 if (d.size() < _data.size())
00198 return true;
00199
00200 _data.dump(d);
00201 d += _data.size();
00202 return false;
00203 }
00204
00205 }
00206
00207 }
00208
00209 #endif // ! QOLYESTER_DAEMON_MSG_MESSAGE_HXX