Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include "net/IPNDAgent.h"
00009 #include "core/BundleCore.h"
00010 #include <ibrdtn/data/Exceptions.h>
00011 #include <sstream>
00012 #include <string.h>
00013 #include <ibrcommon/Logger.h>
00014 #include <ibrcommon/net/MulticastSocket.h>
00015 #include <ibrcommon/net/BroadcastSocket.h>
00016 #include "Configuration.h"
00017 #include <typeinfo>
00018
00019 namespace dtn
00020 {
00021 namespace net
00022 {
00023 IPNDAgent::IPNDAgent(int port, std::string address)
00024 : DiscoveryAgent(dtn::daemon::Configuration::getInstance().getDiscovery()), _version(DiscoveryAnnouncement::DISCO_VERSION_01), _socket(NULL), _destination(address), _port(port)
00025 {
00026 if (ibrcommon::MulticastSocket::isMulticast(_destination))
00027 {
00028 IBRCOMMON_LOGGER(info) << "DiscoveryAgent: multicast mode " << address << ":" << port << IBRCOMMON_LOGGER_ENDL;
00029 _socket = new ibrcommon::MulticastSocket();
00030 }
00031 else
00032 {
00033 IBRCOMMON_LOGGER(info) << "DiscoveryAgent: broadcast mode " << address << ":" << port << IBRCOMMON_LOGGER_ENDL;
00034 _socket = new ibrcommon::BroadcastSocket();
00035 }
00036
00037 switch (_config.version())
00038 {
00039 case 2:
00040 _version = DiscoveryAnnouncement::DISCO_VERSION_01;
00041 break;
00042
00043 case 1:
00044 _version = DiscoveryAnnouncement::DISCO_VERSION_00;
00045 break;
00046
00047 case 0:
00048 IBRCOMMON_LOGGER(info) << "DiscoveryAgent: DTN2 compatibility mode" << IBRCOMMON_LOGGER_ENDL;
00049 _version = DiscoveryAnnouncement::DTND_IPDISCOVERY;
00050 break;
00051 };
00052 }
00053
00054 IPNDAgent::~IPNDAgent()
00055 {
00056 delete _socket;
00057 }
00058
00059 void IPNDAgent::bind(const ibrcommon::NetInterface &net)
00060 {
00061 IBRCOMMON_LOGGER(info) << "DiscoveryAgent: bind to interface " << net.toString() << IBRCOMMON_LOGGER_ENDL;
00062 _interfaces.push_back(net);
00063 }
00064
00065 void IPNDAgent::send(ibrcommon::udpsocket::peer &p, const DiscoveryAnnouncement &announcement)
00066 {
00067 stringstream ss;
00068 ss << announcement;
00069
00070 string data = ss.str();
00071 p.send(data.c_str(), data.length());
00072 }
00073
00074 void IPNDAgent::sendAnnoucement(const u_int16_t &sn, const std::list<DiscoveryService> &services)
00075 {
00076 DiscoveryAnnouncement announcement(_version, dtn::core::BundleCore::local);
00077
00078
00079 announcement.setSequencenumber(sn);
00080
00081 if (_sockets.empty())
00082 {
00083 if (!_config.shortbeacon())
00084 {
00085
00086 for (std::list<DiscoveryService>::const_iterator iter = services.begin(); iter != services.end(); iter++)
00087 {
00088 const DiscoveryService &service = (*iter);
00089 announcement.addService(service);
00090 }
00091 }
00092
00093 ibrcommon::udpsocket::peer p = _socket->getPeer(_destination, _port);
00094
00095
00096 send(p, announcement);
00097
00098 return;
00099 }
00100
00101 for (std::list<ibrcommon::NetInterface>::const_iterator it_iface = _interfaces.begin(); it_iface != _interfaces.end(); it_iface++)
00102 {
00103 const ibrcommon::NetInterface &iface = (*it_iface);
00104
00105
00106 announcement.clearServices();
00107
00108 if (!_config.shortbeacon())
00109 {
00110
00111 for (std::list<DiscoveryService>::const_iterator iter = services.begin(); iter != services.end(); iter++)
00112 {
00113 const DiscoveryService &service = (*iter);
00114 if (service.onInterface(iface))
00115 {
00116 announcement.addService(service);
00117 }
00118 }
00119 }
00120
00121 ibrcommon::udpsocket *sock = _sockets[iface.toString()];
00122
00123 if (sock == NULL)
00124 {
00125 sock = _socket;
00126 }
00127
00128 ibrcommon::udpsocket::peer p = sock->getPeer(_destination, _port);
00129
00130
00131 send(p, announcement);
00132 }
00133 }
00134
00135 void IPNDAgent::componentUp()
00136 {
00137 DiscoveryAgent::componentUp();
00138
00139 try {
00140 ibrcommon::MulticastSocket &sock = dynamic_cast<ibrcommon::MulticastSocket&>(*_socket);
00141 sock.bind(_port);
00142
00143 if (_interfaces.empty())
00144 {
00145 sock.joinGroup(_destination);
00146 }
00147 else
00148 {
00149 for (std::list<ibrcommon::NetInterface>::const_iterator iter = _interfaces.begin(); iter != _interfaces.end(); iter++)
00150 {
00151 const ibrcommon::NetInterface &net = (*iter);
00152
00153 if (_sockets.empty())
00154 {
00155 _sockets[net.toString()] = _socket;
00156 sock.setInterface(net);
00157 }
00158 else
00159 {
00160 ibrcommon::MulticastSocket *newsock = new ibrcommon::MulticastSocket();
00161 newsock->setInterface(net);
00162 _sockets[net.toString()] = newsock;
00163 }
00164
00165 sock.joinGroup(_destination, (*iter));
00166 }
00167 }
00168 } catch (std::bad_cast) {
00169
00170 }
00171
00172 try {
00173 ibrcommon::BroadcastSocket &sock = dynamic_cast<ibrcommon::BroadcastSocket&>(*_socket);
00174 sock.bind(_port);
00175 } catch (std::bad_cast) {
00176
00177 }
00178 }
00179
00180 void IPNDAgent::componentDown()
00181 {
00182 _socket->shutdown();
00183 DiscoveryAgent::componentDown();
00184 }
00185
00186 void IPNDAgent::componentRun()
00187 {
00188 while (true)
00189 {
00190 DiscoveryAnnouncement announce(_version);
00191
00192 char data[1500];
00193
00194 std::string sender;
00195 int len = _socket->receive(data, 1500, sender);
00196
00197 if (announce.isShort())
00198 {
00199
00200 }
00201
00202 if (announce.getServices().empty())
00203 {
00204 announce.addService(dtn::net::DiscoveryService("tcpcl", "ip=" + sender + ";port=4556;"));
00205 }
00206
00207 if (len < 0) return;
00208
00209 stringstream ss;
00210 ss.write(data, len);
00211
00212 try {
00213 ss >> announce;
00214 received(announce);
00215 } catch (dtn::InvalidDataException ex) {
00216 } catch (ibrcommon::IOException ex) {
00217 }
00218
00219 yield();
00220 }
00221 }
00222
00223 bool IPNDAgent::__cancellation()
00224 {
00225
00226 return false;
00227 }
00228
00229 const std::string IPNDAgent::getName() const
00230 {
00231 return "IPNDAgent";
00232 }
00233 }
00234 }