00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "config.hh"
00020
00021 #ifdef QOLYESTER_ENABLE_VIRTUAL
00022
00023 # ifndef QOLYESTER_DAEMON_SYS_VIRTUALINTERFACEINFO_HXX
00024 # define QOLYESTER_DAEMON_SYS_VIRTUALINTERFACEINFO_HXX 1
00025
00026 # include <cassert>
00027 # include <stdexcept>
00028 # include "utl/data.hh"
00029 # include "utl/exception.hh"
00030 # include "virtualinterfaceinfo.hh"
00031
00032 namespace olsr {
00033
00034 namespace sys {
00035
00036 VirtualInterfaceInfo::VirtualInterfaceInfo()
00037 : _name(),
00038 _addr(),
00039 _prefix(0),
00040 _index(0),
00041 _usecount(0),
00042 _sock(0)
00043 {}
00044
00045 VirtualInterfaceInfo::VirtualInterfaceInfo(const std::string& name,
00046 const address_t& addr,
00047 const std::string& dname)
00048 : _name(name),
00049 _addr(addr),
00050 _prefix(ADDRESS_SIZE * 8),
00051 _index(_index_map[name]),
00052 _usecount(new unsigned(1)),
00053 _sock(new UnixSocket) {
00054
00055
00056
00057
00058 try {
00059 _sock->connect(dname);
00060
00061 std::string sender;
00062
00063 utl::Data sd(ADDRESS_SIZE);
00064 addr.dump(sd.raw());
00065 _sock->send(sd);
00066
00067 utl::Data rd = _sock->receive();
00068
00069 assert(rd.size() == ADDRESS_SIZE);
00070
00071 address_t raddr(rd.raw(), rd.size());
00072
00073 if (raddr == address_t())
00074 if (addr == address_t())
00075 throw std::runtime_error(name + " has no usable address");
00076 else
00077 throw std::runtime_error(name + " has no address " +
00078 addr.to_string());
00079
00080 debug << "Received IP: " << raddr << std::endl;
00081 const_cast<address_t&>(_addr) = raddr;
00082 } catch (errnoexcept_t& e) {
00083 _sock->close();
00084 throw;
00085 }
00086
00087 if (_index == 0) {
00088 if (_name_map.empty())
00089 const_cast<unsigned&>(_index) = _index_map[name] = 1;
00090 else
00091 const_cast<unsigned&>(_index) =
00092 (_index_map[name] = _name_map.rbegin()->first + 1);
00093 _name_map[_index] = name;
00094 }
00095 }
00096
00097 VirtualInterfaceInfo::VirtualInterfaceInfo(const This& other)
00098 : _name(other._name),
00099 _addr(other._addr),
00100 _prefix(other._prefix),
00101 _index(other._index),
00102 _usecount(other._usecount),
00103 _sock(other._sock) {
00104 use();
00105 }
00106
00107 VirtualInterfaceInfo::~VirtualInterfaceInfo() {
00108 if (_usecount != 0) {
00109 unuse();
00110 if (*_usecount == 0) {
00111 delete _usecount;
00112 _sock->close();
00113 delete _sock;
00114 }
00115 }
00116 }
00117
00118 VirtualInterfaceInfo&
00119 VirtualInterfaceInfo::operator=(const This& other) {
00120 if (_usecount != 0) {
00121 unuse();
00122 if (*_usecount == 0) {
00123 delete _usecount;
00124 _sock->close();
00125 delete _sock;
00126 }
00127 }
00128 const_cast<std::string&>(_name) = other._name;
00129 const_cast<address_t&>(_addr) = other._addr;
00130 const_cast<unsigned&>(_prefix) = other._prefix;
00131 const_cast<unsigned&>(_index) = other._index;
00132 _usecount = other._usecount;
00133 _sock = other._sock;
00134 use();
00135
00136 return *this;
00137 }
00138
00139 }
00140
00141 }
00142
00143 # endif // ! QOLYESTER_DAEMON_SYS_VIRTUALINTERFACEINFO_HXX
00144
00145 #endif // QOLYESTER_ENABLE_VIRTUAL