/* */ #include "BtHandshakeMessage.h" #include #include "util.h" #include "a2functional.h" namespace aria2 { const unsigned char BtHandshakeMessage::BT_PSTR[] = "BitTorrent protocol"; const char BtHandshakeMessage::NAME[] = "handshake"; BtHandshakeMessage::BtHandshakeMessage() : SimpleBtMessage(ID, NAME) { init(); } BtHandshakeMessage::BtHandshakeMessage(const unsigned char* infoHash, const unsigned char* peerId) : SimpleBtMessage(ID, NAME) { init(); std::copy_n(infoHash, infoHash_.size(), std::begin(infoHash_)); std::copy_n(peerId, peerId_.size(), std::begin(peerId_)); } BtHandshakeMessage::~BtHandshakeMessage() {} void BtHandshakeMessage::init() { pstrlen_ = 19; std::copy_n(BT_PSTR, pstr_.size(), std::begin(pstr_)); std::fill(std::begin(reserved_), std::end(reserved_), 0); // fast extension reserved_[7] |= 0x04u; // extended messaging reserved_[5] |= 0x10u; } std::unique_ptr BtHandshakeMessage::create(const unsigned char* data, size_t dataLength) { auto msg = make_unique(); msg->pstrlen_ = data[0]; std::copy_n(&data[1], msg->pstr_.size(), std::begin(msg->pstr_)); std::copy_n(&data[20], msg->reserved_.size(), std::begin(msg->reserved_)); std::copy_n(&data[28], msg->infoHash_.size(), std::begin(msg->infoHash_)); std::copy_n(&data[48], msg->peerId_.size(), std::begin(msg->peerId_)); return msg; } std::vector BtHandshakeMessage::createMessage() { auto msg = std::vector(MESSAGE_LENGTH); auto dst = msg.data(); *dst++ = pstrlen_; dst = std::copy(std::begin(pstr_), std::end(pstr_), dst); dst = std::copy(std::begin(reserved_), std::end(reserved_), dst); dst = std::copy(std::begin(infoHash_), std::end(infoHash_), dst); std::copy(std::begin(peerId_), std::end(peerId_), dst); return msg; } std::string BtHandshakeMessage::toString() const { return fmt("%s peerId=%s, reserved=%s", NAME, util::percentEncode(peerId_.data(), peerId_.size()).c_str(), util::toHex(reserved_.data(), reserved_.size()).c_str()); } bool BtHandshakeMessage::isFastExtensionSupported() const { return reserved_[7] & 0x04u; } bool BtHandshakeMessage::isExtendedMessagingEnabled() const { return reserved_[5] & 0x10u; } bool BtHandshakeMessage::isDHTEnabled() const { return reserved_[7] & 0x01u; } void BtHandshakeMessage::setInfoHash(const unsigned char* infoHash) { std::copy_n(infoHash, infoHash_.size(), std::begin(infoHash_)); } void BtHandshakeMessage::setPeerId(const unsigned char* peerId) { std::copy_n(peerId, peerId_.size(), std::begin(peerId_)); } } // namespace aria2