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 debug << "Unknown message type, not parsing" << std::endl;
00098 break;
00099 }
00100
00101 }
00102
00103
00104 if (x == dup_set.dupset().end() || !x->in_ifaces(receiver)) {
00105
00106
00107 switch (h->type) {
00108 case HELLO_MESSAGE:
00109
00110
00111
00112 assert(HELLO_MESSAGE != HELLO_MESSAGE);
00113 break;
00114 case TC_MESSAGE:
00115 TCMessage::forward(d, mh);
00116 break;
00117 case MID_MESSAGE:
00118 MIDMessage::forward(d, mh);
00119 break;
00120 case HNA_MESSAGE:
00121 HNAMessage::forward(d, mh);
00122 break;
00123 default:
00124
00125 Message::forward(d, mh);
00126 break;
00127 }
00128 }
00129 }
00130
00131
00132 void
00133 Message::forward(utl::Data& d, const header& mh) {
00134 cproxy_t::linkset_t::iterator lx =
00135 cproxy.linkset().find(set::Link::make_key(mh.receiver, mh.sender));
00136
00137
00138
00139 if (lx == cproxy.linkset().end() || !lx->is_sym())
00140 return;
00141
00142
00143 raw* h = reinterpret_cast<raw*>(d.raw());
00144
00145
00146 dupset_t::dupset_t::iterator dx =
00147 dup_set.dupset().find(set::DuplicateEntry::make_key(mh.originator,
00148 ntohs(h->seqnum)));
00149
00150
00151
00152
00153 if (dx != dup_set.dupset().end() &&
00154 (dx->retransmitted() || dx->in_ifaces(mh.receiver)))
00155 return;
00156
00157
00158 const address_t& maddr = alg::main_addr_of(mh.sender);
00159
00160
00161
00162
00163 cproxy_t::sym_neighborset_t::iterator nx =
00164 cproxy.sym_neighborset().find(set::Neighbor::make_key(maddr));
00165
00166 bool retransmit = false;
00167 if (nx != cproxy.sym_neighborset().end() &&
00168 nx->is_mprsel() &&
00169 h->ttl > 1)
00170 retransmit = true;
00171
00172
00173 dup_set.insert(set::DuplicateEntry(mh.originator,
00174 ntohs(h->seqnum),
00175 mh.receiver, retransmit));
00176
00177
00178 if (!retransmit)
00179 return;
00180
00181
00182 --h->ttl;
00183 ++h->hopcount;
00184
00185
00186 typedef UnknownMessage um_t;
00187 typedef sch::MessageForwarder mf_t;
00188
00189 scheduler.insert(new mf_t(timeval_t::in_jitter(cst::maxjitter),
00190 um_t(d)));
00191 }
00192
00193 UnknownMessage::UnknownMessage(utl::Data& d) : _data(d) {}
00194
00195
00196 bool
00197 UnknownMessage::dump(utl::Data& d, const address_t&) const {
00198 if (d.size() < _data.size())
00199 return true;
00200
00201 _data.dump(d);
00202 d += _data.size();
00203 return false;
00204 }
00205
00206 }
00207
00208 }
00209
00210 #endif // ! QOLYESTER_DAEMON_MSG_MESSAGE_HXX