void IPNDAgent::componentRun() throw () { struct timeval tv; // every second we want to transmit a discovery message, timeout of 1 seconds tv.tv_sec = 1; tv.tv_usec = 0; // get the reference to the discovery agent dtn::net::DiscoveryAgent &agent = dtn::core::BundleCore::getInstance().getDiscoveryAgent(); try { while (true) { ibrcommon::socketset fds; try { // select on all bound sockets _socket.select(&fds, NULL, NULL, &tv); // receive from all sockets for (ibrcommon::socketset::const_iterator iter = fds.begin(); iter != fds.end(); ++iter) { ibrcommon::multicastsocket &sock = dynamic_cast<ibrcommon::multicastsocket&>(**iter); char data[1500]; ibrcommon::vaddress sender; DiscoveryBeacon beacon = agent.obtainBeacon(); ssize_t len = sock.recvfrom(data, 1500, 0, sender); if (len < 0) return; stringstream ss; ss.write(data, len); try { ss >> beacon; if (beacon.isShort()) { // generate name with the sender address beacon.setEID( dtn::data::EID("udp://[" + sender.address() + "]:4556") ); // add generated tcpcl service if the services list is empty beacon.addService(dtn::net::DiscoveryService(dtn::core::Node::CONN_TCPIP, "ip=" + sender.address() + ";port=4556;")); } DiscoveryBeacon::service_list &services = beacon.getServices(); // add source address if not set for (dtn::net::DiscoveryBeacon::service_list::iterator iter = services.begin(); iter != services.end(); ++iter) { DiscoveryService &service = (*iter); if ( (service.getParameters().find("port=") != std::string::npos) && (service.getParameters().find("ip=") == std::string::npos) ) { // update service entry service.update("ip=" + sender.address() + ";" + service.getParameters()); } } // announce the received beacon agent.onBeaconReceived(beacon); } catch (const dtn::InvalidDataException&) { } catch (const ibrcommon::IOException&) { } } // trigger an artificial timeout if the remaining timeout value is zero or below if ( tv.tv_sec <= 0 && tv.tv_usec <= 0 ) throw ibrcommon::vsocket_timeout("timeout"); } catch (const ibrcommon::vsocket_timeout&) { // reset timeout to 1 second tv.tv_sec = 1; tv.tv_usec = 0; } yield(); } } catch (const ibrcommon::vsocket_interrupt&) { // vsocket has been interrupted - exit now } catch (const ibrcommon::socket_exception &ex) { // unexpected error - exit now IBRCOMMON_LOGGER_TAG(IPNDAgent::TAG, error) << "unexpected error: " << ex.what() << IBRCOMMON_LOGGER_ENDL; } }