void NodeHandshakeExtension::processHandshake(const dtn::data::Bundle &bundle) { // read the ecm const dtn::data::PayloadBlock &p = bundle.find<dtn::data::PayloadBlock>(); ibrcommon::BLOB::Reference ref = p.getBLOB(); NodeHandshake handshake; // locked within this region { ibrcommon::BLOB::iostream s = ref.iostream(); (*s) >> handshake; } IBRCOMMON_LOGGER_DEBUG_TAG(NodeHandshakeExtension::TAG, 15) << "handshake received from " << bundle.source.getString() << ": " << handshake.toString() << IBRCOMMON_LOGGER_ENDL; // if this is a request answer with an summary vector if (handshake.getType() == NodeHandshake::HANDSHAKE_REQUEST) { // create a new request for the summary vector of the neighbor NodeHandshake response(NodeHandshake::HANDSHAKE_RESPONSE); // lock the extension list during the processing (**this).responseHandshake(bundle.source, handshake, response); IBRCOMMON_LOGGER_DEBUG_TAG(NodeHandshakeExtension::TAG, 15) << "handshake reply to " << bundle.source.getString() << ": " << response.toString() << IBRCOMMON_LOGGER_ENDL; // create a new bundle with a zero timestamp (+age block) dtn::data::Bundle answer(true); // set the source of the bundle answer.source = _endpoint.getWorkerURI(); // set the destination of the bundle answer.set(dtn::data::PrimaryBlock::DESTINATION_IS_SINGLETON, true); answer.destination = bundle.source; // limit the lifetime to 60 seconds answer.lifetime = 60; // set high priority answer.set(dtn::data::PrimaryBlock::PRIORITY_BIT1, false); answer.set(dtn::data::PrimaryBlock::PRIORITY_BIT2, true); dtn::data::PayloadBlock &p = answer.push_back<PayloadBlock>(); ibrcommon::BLOB::Reference ref = p.getBLOB(); // serialize the request into the payload { ibrcommon::BLOB::iostream ios = ref.iostream(); (*ios) << response; } // add a schl block dtn::data::ScopeControlHopLimitBlock &schl = answer.push_front<dtn::data::ScopeControlHopLimitBlock>(); schl.setLimit(1); // request compression answer.set(dtn::data::PrimaryBlock::IBRDTN_REQUEST_COMPRESSION, true); // transfer the bundle to the neighbor _endpoint.send(answer); // call handshake completed event NodeHandshakeEvent::raiseEvent( NodeHandshakeEvent::HANDSHAKE_REPLIED, bundle.source.getNode() ); } else if (handshake.getType() == NodeHandshake::HANDSHAKE_RESPONSE) { // walk through all extensions to process the contents of the response (**this).processHandshake(bundle.source, handshake); // call handshake completed event NodeHandshakeEvent::raiseEvent( NodeHandshakeEvent::HANDSHAKE_COMPLETED, bundle.source.getNode() ); } else if (handshake.getType() == NodeHandshake::HANDSHAKE_NOTIFICATION) { // create a new request NodeHandshake request(NodeHandshake::HANDSHAKE_REQUEST); // walk through all extensions to find out which requests are of interest (**this).requestHandshake(BROADCAST_ENDPOINT, request); const NodeHandshake::request_set &rs = handshake.getRequests(); for (NodeHandshake::request_set::const_iterator it = rs.begin(); it != rs.end(); ++it) { if (request.hasRequest(*it)) { // get node endpoint const dtn::data::EID node = bundle.source.getNode(); // clear 60 second blockage _endpoint.removeFromBlacklist(node); // execute handshake _endpoint.query(node); return; } } } }
void NodeHandshakeExtension::processHandshake(const dtn::data::Bundle &bundle) { // read the ecm const dtn::data::PayloadBlock &p = bundle.find<dtn::data::PayloadBlock>(); ibrcommon::BLOB::Reference ref = p.getBLOB(); NodeHandshake handshake; // locked within this region { ibrcommon::BLOB::iostream s = ref.iostream(); (*s) >> handshake; } IBRCOMMON_LOGGER_DEBUG_TAG(NodeHandshakeExtension::TAG, 15) << "handshake received from " << bundle.source.getString() << ": " << handshake.toString() << IBRCOMMON_LOGGER_ENDL; // if this is a request answer with an summary vector if (handshake.getType() == NodeHandshake::HANDSHAKE_REQUEST) { // create a new request for the summary vector of the neighbor NodeHandshake response(NodeHandshake::HANDSHAKE_RESPONSE); // lock the extension list during the processing (**this).responseHandshake(bundle.source, handshake, response); IBRCOMMON_LOGGER_DEBUG_TAG(NodeHandshakeExtension::TAG, 15) << "handshake reply to " << bundle.source.getString() << ": " << response.toString() << IBRCOMMON_LOGGER_ENDL; // create a new bundle dtn::data::Bundle answer; // set the source of the bundle answer.source = _endpoint.getWorkerURI(); // set the destination of the bundle answer.set(dtn::data::PrimaryBlock::DESTINATION_IS_SINGLETON, true); answer.destination = bundle.source; // limit the lifetime to 60 seconds answer.lifetime = 60; // set high priority answer.set(dtn::data::PrimaryBlock::PRIORITY_BIT1, false); answer.set(dtn::data::PrimaryBlock::PRIORITY_BIT2, true); dtn::data::PayloadBlock &p = answer.push_back<PayloadBlock>(); ibrcommon::BLOB::Reference ref = p.getBLOB(); // serialize the request into the payload { ibrcommon::BLOB::iostream ios = ref.iostream(); (*ios) << response; } // add a schl block dtn::data::ScopeControlHopLimitBlock &schl = answer.push_front<dtn::data::ScopeControlHopLimitBlock>(); schl.setLimit(1); // add an age block (to prevent expiring due to wrong clocks) answer.push_front<dtn::data::AgeBlock>(); // transfer the bundle to the neighbor _endpoint.send(answer); // call handshake completed event NodeHandshakeEvent::raiseEvent( NodeHandshakeEvent::HANDSHAKE_REPLIED, bundle.source.getNode() ); } else if (handshake.getType() == NodeHandshake::HANDSHAKE_RESPONSE) { // walk through all extensions to process the contents of the response (**this).processHandshake(bundle.source, handshake); // call handshake completed event NodeHandshakeEvent::raiseEvent( NodeHandshakeEvent::HANDSHAKE_COMPLETED, bundle.source.getNode() ); } }
void NodeHandshakeExtension::processHandshake(const dtn::data::Bundle &bundle) { // read the ecm const dtn::data::PayloadBlock &p = bundle.find<dtn::data::PayloadBlock>(); ibrcommon::BLOB::Reference ref = p.getBLOB(); NodeHandshake handshake; // locked within this region { ibrcommon::BLOB::iostream s = ref.iostream(); (*s) >> handshake; } IBRCOMMON_LOGGER_DEBUG_TAG(NodeHandshakeExtension::TAG, 15) << "handshake received from " << bundle.source.getString() << ": " << handshake.toString() << IBRCOMMON_LOGGER_ENDL; // if this is a request answer with an summary vector if (handshake.getType() == NodeHandshake::HANDSHAKE_REQUEST) { // create a new request for the summary vector of the neighbor NodeHandshake response(NodeHandshake::HANDSHAKE_RESPONSE); // lock the extension list during the processing (**this).responseHandshake(bundle.source, handshake, response); IBRCOMMON_LOGGER_DEBUG_TAG(NodeHandshakeExtension::TAG, 15) << "handshake reply to " << bundle.source.getString() << ": " << response.toString() << IBRCOMMON_LOGGER_ENDL; // create a new bundle with a zero timestamp (+age block) dtn::data::Bundle answer(true); // set the source of the bundle answer.source = _endpoint.getWorkerURI(); // set the destination of the bundle answer.set(dtn::data::PrimaryBlock::DESTINATION_IS_SINGLETON, true); answer.destination = bundle.source; // limit the lifetime to 60 seconds answer.lifetime = 60; // set high priority answer.set(dtn::data::PrimaryBlock::PRIORITY_BIT1, false); answer.set(dtn::data::PrimaryBlock::PRIORITY_BIT2, true); dtn::data::PayloadBlock &p = answer.push_back<PayloadBlock>(); ibrcommon::BLOB::Reference ref = p.getBLOB(); // serialize the request into the payload { ibrcommon::BLOB::iostream ios = ref.iostream(); (*ios) << response; } // add a schl block dtn::data::ScopeControlHopLimitBlock &schl = answer.push_front<dtn::data::ScopeControlHopLimitBlock>(); schl.setLimit(1); #ifdef IBRDTN_SUPPORT_COMPRESSION // compress bundle if requested if (handshake.hasRequest(NodeHandshakeItem::REQUEST_COMPRESSED_ANSWER)) { try { dtn::data::CompressedPayloadBlock::compress(answer, dtn::data::CompressedPayloadBlock::COMPRESSION_ZLIB); } catch (const ibrcommon::Exception &ex) { IBRCOMMON_LOGGER_TAG(TAG, warning) << "compression of bundle failed: " << ex.what() << IBRCOMMON_LOGGER_ENDL; }; } #endif // transfer the bundle to the neighbor _endpoint.send(answer); // call handshake completed event NodeHandshakeEvent::raiseEvent( NodeHandshakeEvent::HANDSHAKE_REPLIED, bundle.source.getNode() ); } else if (handshake.getType() == NodeHandshake::HANDSHAKE_RESPONSE) { // walk through all extensions to process the contents of the response (**this).processHandshake(bundle.source, handshake); // call handshake completed event NodeHandshakeEvent::raiseEvent( NodeHandshakeEvent::HANDSHAKE_COMPLETED, bundle.source.getNode() ); } }