00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.hh"
00022
00023 #ifndef QOLYESTER_ENABLE_VIRTUAL
00024
00025 # ifndef QOLYESTER_DAEMON_NET_REALINTERFACE_HXX
00026 # define QOLYESTER_DAEMON_NET_REALINTERFACE_HXX 1
00027
00028 # include "cst/constants.hh"
00029 # include "sys/realinterfaceinfo.hh"
00030 # include "sys/socket.hh"
00031 # include "sch/events.hh"
00032
00033 # include "realinterface.hh"
00034
00035 namespace olsr {
00036
00037 extern sch::Scheduler scheduler;
00038
00039 namespace net {
00040
00041 void
00042 RealInterface::configure() {
00043 assert(config_ != 0);
00044 config_->setup();
00045 }
00046
00047 void
00048 RealInterface::unconfigure() {
00049 assert(config_ != 0);
00050 config_->revert();
00051 }
00052
00053 RealInterface::RealInterface()
00054 : info_(),
00055 addr_(),
00056 prefix_(0),
00057 # ifdef QOLYESTER_TWO_SOCKETS
00058 insock_(sys::Socket::dummy()),
00059 outsock_(sys::Socket::dummy()),
00060 # else // !QOLYESTER_TWO_SOCKETS
00061 sock_(sys::Socket::dummy()),
00062 # endif
00063 events_(),
00064 sender_(0),
00065 usecount_(new unsigned(1)),
00066 config_(0),
00067 queue_size_(cst::queue_size)
00068 {}
00069
00070 RealInterface::RealInterface(const sys::RealInterfaceInfo& info)
00071 : info_(info),
00072 addr_(info_.get_addr()),
00073 prefix_(info_.get_prefix(addr_)),
00074 # ifdef QOLYESTER_TWO_SOCKETS
00075 insock_(),
00076 outsock_(),
00077 events_(),
00078 sender_(0),
00079 usecount_(new unsigned(1)),
00080 config_(new sys::RealInterfaceInfo::config_t(info_.name())),
00081 queue_size_(cst::queue_size) {
00082 insock_.set_mtu(info_.mtu() - address_t::header_length);
00083 outsock_.set_mtu(info_.mtu() - address_t::header_length);
00084
00085 address_t bcast = info_.get_bcast(addr_);
00086
00087 # if QOLYESTER_FAMILY_INET == 6
00088 insock_.bind_multicast(info_, bcast, OLSR_PORT_NUMBER);
00089 outsock_.set_multicast(info_);
00090 if (addr_.is_linklocal())
00091 outsock_.bind(addr_, OLSR_PORT_NUMBER, info_.index());
00092 else
00093 outsock_.bind(addr_, OLSR_PORT_NUMBER);
00094 # else // QOLYESTER_FAMILY_INET != 6
00095
00096 insock_.bind(bcast, OLSR_PORT_NUMBER);
00097 outsock_.bind_multicast(info_, addr_, OLSR_PORT_NUMBER);
00098 # endif
00099
00100 outsock_.set_baddr(bcast);
00101
00102 outsock_.set_priority();
00103 # else // !QOLYESTER_TWO_SOCKETS
00104 sock_(),
00105 events_(),
00106 sender_(0),
00107 usecount_(new unsigned(1)),
00108 config_(new sys::RealInterfaceInfo::config_t(info_.name())),
00109 queue_size_(cst::queue_size) {
00110 address_t bcast = info_.get_bcast(addr_);
00111 sock_.set_mtu(info_.mtu() - address_t::header_length);
00112 sock_.bind_multicast(info_, bcast, OLSR_PORT_NUMBER);
00113 sock_.set_baddr(bcast);
00114 # endif
00115 }
00116
00117 RealInterface::RealInterface(const sys::RealInterfaceInfo& info,
00118 const address_t& addr)
00119 : info_(info),
00120 addr_(info_.get_addr(addr)),
00121 prefix_(info_.get_prefix(addr)),
00122 # ifdef QOLYESTER_TWO_SOCKETS
00123 insock_(),
00124 outsock_(),
00125 events_(),
00126 sender_(0),
00127 usecount_(new unsigned(1)),
00128 config_(new sys::RealInterfaceInfo::config_t(info_.name())),
00129 queue_size_(cst::queue_size) {
00130 insock_.set_mtu(info_.mtu() - address_t::header_length);
00131 outsock_.set_mtu(info_.mtu() - address_t::header_length);
00132
00133 address_t bcast = info_.get_bcast(addr_);
00134
00135 # if QOLYESTER_FAMILY_INET == 6
00136 insock_.bind_multicast(info_, bcast, OLSR_PORT_NUMBER);
00137 outsock_.set_multicast(info_);
00138 if (addr_.is_linklocal())
00139 outsock_.bind(addr_, OLSR_PORT_NUMBER, info_.index());
00140 else
00141 outsock_.bind(addr_, OLSR_PORT_NUMBER);
00142 # else // QOLYESTER_FAMILY_INET != 6
00143 insock_.bind(bcast, OLSR_PORT_NUMBER);
00144 outsock_.bind_multicast(info_, addr_, OLSR_PORT_NUMBER);
00145 # endif
00146
00147 outsock_.set_baddr(bcast);
00148 outsock_.set_priority();
00149 # else // !QOLYSTER_TWO_SOCKETS
00150 sock_(),
00151 events_(),
00152 sender_(0),
00153 usecount_(new unsigned(1)),
00154 config_(new sys::RealInterfaceInfo::config_t(info_.name())),
00155 queue_size_(cst::queue_size) {
00156 address_t bcast = info_.get_bcast(addr_);
00157 sock_.set_mtu(info_.mtu() - address_t::header_length);
00158 sock_.bind_multicast(info_, bcast, OLSR_PORT_NUMBER);
00159 sock_.set_baddr(bcast);
00160 # endif
00161 }
00162
00163 RealInterface::RealInterface(const This& other)
00164 : Super(other),
00165 info_(other.info_),
00166 addr_(other.addr_),
00167 prefix_(other.prefix_),
00168 # ifdef QOLYESTER_TWO_SOCKETS
00169 insock_(other.insock_),
00170 outsock_(other.outsock_),
00171 # else // !QOLYESTER_TWO_SOCKETS
00172 sock_(other.sock_),
00173 # endif
00174 events_(),
00175 sender_(0),
00176 usecount_(other.usecount_),
00177 config_(other.config_),
00178 queue_size_(other.queue_size_) {
00179 ++(*usecount_);
00180 }
00181
00182 RealInterface::~RealInterface() {
00183 debug << "Destroying interface instance {\n";
00184 for (events_t::iterator i = events_.begin(); i != events_.end();
00185 ) {
00186 debug << " Destroying " << (*i)->name() << '\n';
00187 events_t::iterator tmp = i++;
00188 scheduler.destroy(*tmp);
00189 }
00190 debug << '}' << std::endl;
00191 --(*usecount_);
00192 if (*usecount_ == 0) {
00193 delete usecount_;
00194 # ifdef QOLYESTER_TWO_SOCKETS
00195 insock_.close();
00196 outsock_.close();
00197 # else // !QOLYESTER_TWO_SOCKETS
00198 sock_.close();
00199 # endif
00200 if (config_ != 0) {
00201 unconfigure();
00202 delete config_;
00203 }
00204 }
00205 }
00206
00207 unsigned
00208 RealInterface::mtu() const {
00209 return info_.mtu() - address_t::header_length;
00210 }
00211
00212 sch::IOEvent::p_t
00213 RealInterface::recv_p() const {
00214 # ifdef QOLYESTER_TWO_SOCKETS
00215 return insock_.read_p();
00216 # else
00217 return sock_.read_p();
00218 # endif
00219 }
00220
00221 sch::IOEvent::p_t
00222 RealInterface::send_p() const {
00223 # ifdef QOLYESTER_TWO_SOCKETS
00224 return outsock_.write_p();
00225 # else
00226 return sock_.write_p();
00227 # endif
00228 }
00229
00230 void
00231 RealInterface::insert_event(sch::IOEvent* e) {
00232 debug << "Inserting " << e->name() << " into interface" << std::endl;
00233 events_.insert(e);
00234 }
00235
00236 void
00237 RealInterface::erase_event(sch::IOEvent* e) {
00238 debug << "Erasing " << e->name() << " from interface" << std::endl;
00239 if (e == sender_)
00240 sender_ = 0;
00241 events_.erase(e);
00242 }
00243
00244 void
00245 RealInterface::destroy_all_events() {
00246 while (!events_.empty()) {
00247 sch::IOEvent* e = *events_.begin();
00248 events_.erase(events_.begin());
00249 if (sender_ == e)
00250 sender_ = 0;
00251 scheduler.destroy(e);
00252 }
00253 }
00254
00255
00256
00257
00258
00259
00260 pkt::Packet
00261 RealInterface::receive() const {
00262 address_t from;
00263 # ifdef QOLYESTER_TWO_SOCKETS
00264 utl::Data data = insock_.receive(from);
00265 # else // !QOLYESTER_TWO_SOCKETS
00266 utl::Data data = sock_.receive(from);
00267 # endif
00268 return pkt::Packet(from, data);
00269 }
00270
00271 void
00272 RealInterface::send(const pkt::Packet& p) const {
00273 # ifdef QOLYESTER_TWO_SOCKETS
00274 outsock_.sendto_bcast(p.data());
00275 # else // !QOLYESTER_TWO_SOCKETS
00276 sock_.sendto_bcast(p.data());
00277 # endif
00278 }
00279
00280 void
00281 RealInterface::shipout(const pkt::Packet& p) {
00282 debug << up << "Shipping out packet of " << p.size()
00283 << " bytes through " << info_.name() << std::endl << down;
00284 if (sender_ == 0) {
00285 sender_ = new sch::PacketSender(this, p);
00286 scheduler.insert(sender_);
00287 } else {
00288 sender_->push_packet(p);
00289 }
00290 }
00291
00292 bool
00293 RealInterface::operator<(const This& rhs) const {
00294 return addr_ < rhs.addr_;
00295 }
00296
00297 RealInterface&
00298 RealInterface::make_key(const address_t& a) {
00299 const_cast<address_t&>(dummy_for_find_.addr_) = a;
00300 return dummy_for_find_;
00301 }
00302
00303 }
00304
00305 }
00306
00307 # endif // ! QOLYESTER_DAEMON_NET_REALINTERFACE_HXX
00308
00309 #endif // ! QOLYESTER_ENABLE_VIRTUAL