00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "config.hh"
00021
00022 #ifdef QOLYESTER_ENABLE_VIRTUAL
00023
00024 # ifndef QOLYESTER_DAEMON_NET_VIRTUALINTERFACE_HXX
00025 # define QOLYESTER_DAEMON_NET_VIRTUALINTERFACE_HXX 1
00026
00027 # include "sch/events.hh"
00028 # include "virtualinterface.hh"
00029
00030 namespace olsr {
00031
00032 namespace net {
00033
00034 VirtualInterface::VirtualInterface()
00035 : info_(),
00036 addr_(info_.addr()),
00037 prefix_(0),
00038 events_(),
00039 sender_(0),
00040 queue_size_(cst::queue_size)
00041 {}
00042
00043 VirtualInterface::VirtualInterface(const sys::VirtualInterfaceInfo& info)
00044 : info_(info),
00045 addr_(info_.addr()),
00046 prefix_(info_.prefix()),
00047 events_(),
00048 sender_(0),
00049 queue_size_(cst::queue_size)
00050 {}
00051
00052 VirtualInterface::VirtualInterface(const This& other)
00053 : Super(other),
00054 info_(other.info_),
00055 addr_(info_.addr()),
00056 prefix_(info_.prefix()),
00057 events_(),
00058 sender_(0),
00059 queue_size_(other.queue_size_)
00060 {}
00061
00062 VirtualInterface::~VirtualInterface() {
00063 debug << "Destroying interface instance {\n";
00064 for (events_t::iterator i = events_.begin(); i != events_.end();
00065 ) {
00066 debug << " Destroying " << (*i)->name() << '\n';
00067 events_t::iterator tmp = i++;
00068 scheduler.destroy(*tmp);
00069 }
00070 debug << '}' << std::endl;
00071 }
00072
00073 unsigned
00074 VirtualInterface::mtu() const {
00075 return info_.mtu();
00076 }
00077
00078 sch::IOEvent::p_t
00079 VirtualInterface::recv_p() const {
00080 return info_.socket().read_p();
00081 }
00082
00083 sch::IOEvent::p_t
00084 VirtualInterface::send_p() const {
00085 return info_.socket().write_p();
00086 }
00087
00088 void
00089 VirtualInterface::insert_event(sch::IOEvent* e) {
00090 debug << "Inserting " << e->name() << " into interface" << std::endl;
00091 events_.insert(e);
00092 }
00093
00094 void
00095 VirtualInterface::erase_event(sch::IOEvent* e) {
00096 debug << "Erasing " << e->name() << " from interface" << std::endl;
00097 if (e == sender_)
00098 sender_ = 0;
00099 events_.erase(e);
00100 }
00101
00102 void
00103 VirtualInterface::destroy_all_events() {
00104 while (!events_.empty()) {
00105 sch::IOEvent* e = *events_.begin();
00106 events_.erase(events_.begin());
00107 scheduler.destroy(e);
00108 }
00109 }
00110
00111 pkt::Packet
00112 VirtualInterface::receive() const {
00113
00114
00115 try {
00116 utl::Data d = info_.socket().receive();
00117 address_t froma(d.raw(), address_t::address_size);
00118 d += address_t::address_size;
00119 return pkt::Packet(froma, d);
00120 } catch (sys::UnixClosedConnection&) {
00121 terminate_now.set_mark();
00122 throw std::runtime_error("VirtualInterface::receive(): "
00123 "closed connection");
00124 }
00125 }
00126
00127 void
00128 VirtualInterface::send(const pkt::Packet& p) const {
00129 try {
00130 info_.socket().send(p.data());
00131 } catch (sys::UnixClosedConnection&) {
00132 terminate_now.set_mark();
00133 throw std::runtime_error("VirtualInterface::send(): "
00134 "closed connection");
00135 }
00136 }
00137
00138 void
00139 VirtualInterface::shipout(const pkt::Packet& p) {
00140 debug << up << "Shipping out packet of " << p.size()
00141 << " bytes through " << info_.name() << std::endl << down;
00142 if (sender_ == 0) {
00143 sender_ = new sch::PacketSender(this, p);
00144 scheduler.insert(sender_);
00145 } else {
00146 sender_->push_packet(p);
00147 }
00148 }
00149
00150 bool
00151 VirtualInterface::operator<(const This& rhs) const {
00152 return addr_ < rhs.addr_;
00153 }
00154
00155 VirtualInterface&
00156 VirtualInterface::make_key(const address_t& a) {
00157 const_cast<address_t&>(dummy_for_find_.addr_) = a;
00158 return dummy_for_find_;
00159 }
00160
00161 }
00162
00163 }
00164
00165 # endif // ! QOLYESTER_DAEMON_NET_VIRTUALINTERFACE_HXX
00166
00167 #endif // QOLYESTER_ENABLE_VIRTUAL