/* */ #include "BtPortMessage.h" #include "bittorrent_helper.h" #include "DlAbortEx.h" #include "util.h" #include "message.h" #include "Logger.h" #include "LogFactory.h" #include "Peer.h" #include "DHTNode.h" #include "DHTRoutingTable.h" #include "DHTTaskQueue.h" #include "DHTTaskFactory.h" #include "DHTTask.h" #include "fmt.h" #include "a2functional.h" namespace aria2 { const char BtPortMessage::NAME[] = "port"; BtPortMessage::BtPortMessage(uint16_t port) : SimpleBtMessage(ID, NAME), port_(port), localNode_(nullptr), routingTable_(nullptr), taskQueue_(nullptr), taskFactory_(nullptr) { } std::unique_ptr BtPortMessage::create(const unsigned char* data, size_t dataLength) { bittorrent::assertPayloadLengthEqual(3, dataLength, NAME); bittorrent::assertID(ID, data, NAME); uint16_t port = bittorrent::getShortIntParam(data, 1); return make_unique(port); } void BtPortMessage::doReceivedAction() { if (taskFactory_ && taskQueue_) { if (port_ == 0) { A2_LOG_DEBUG("Ignored port 0."); return; } // node id is random at this point. When ping reply received, new DHTNode // instance created with proper node ID and is added to a routing table. auto node = std::make_shared(); node->setIPAddress(getPeer()->getIPAddress()); node->setPort(port_); { std::shared_ptr task = taskFactory_->createPingTask(node); taskQueue_->addImmediateTask(task); } if (routingTable_->getNumBucket() == 1) { // initiate bootstrap A2_LOG_INFO("Dispatch node_lookup since too few buckets."); taskQueue_->addImmediateTask( taskFactory_->createNodeLookupTask(localNode_->getID())); } } else { A2_LOG_INFO( "DHT port message received while localhost didn't declare support it."); } } std::vector BtPortMessage::createMessage() { /** * len --- 5, 4bytes * id --- 4, 1byte * port --- port number, 2bytes * total: 7bytes */ auto msg = std::vector(MESSAGE_LENGTH); bittorrent::createPeerMessageString(msg.data(), MESSAGE_LENGTH, 3, ID); bittorrent::setShortIntParam(&msg[5], port_); return msg; } std::string BtPortMessage::toString() const { return fmt("%s port=%u", NAME, port_); } void BtPortMessage::setLocalNode(DHTNode* localNode) { localNode_ = localNode; } void BtPortMessage::setRoutingTable(DHTRoutingTable* routingTable) { routingTable_ = routingTable; } void BtPortMessage::setTaskQueue(DHTTaskQueue* taskQueue) { taskQueue_ = taskQueue; } void BtPortMessage::setTaskFactory(DHTTaskFactory* taskFactory) { taskFactory_ = taskFactory; } } // namespace aria2