/* */ #include "BtHandshakeMessage.h" #include #include "util.h" #include "BtConstants.h" #include "a2functional.h" namespace aria2 { const char BtHandshakeMessage::NAME[] = "handshake"; const unsigned char* BtHandshakeMessage::BT_PSTR = reinterpret_cast("BitTorrent protocol"); BtHandshakeMessage::BtHandshakeMessage() : SimpleBtMessage(ID, NAME) { init(); } BtHandshakeMessage::BtHandshakeMessage(const unsigned char* infoHash, const unsigned char* peerId) : SimpleBtMessage(ID, NAME) { init(); memcpy(infoHash_, infoHash, INFO_HASH_LENGTH); memcpy(peerId_, peerId, PEER_ID_LENGTH); } void BtHandshakeMessage::init() { pstrlen_ = 19; pstr_ = new unsigned char[PSTR_LENGTH]; reserved_ = new unsigned char[RESERVED_LENGTH]; infoHash_ = new unsigned char[INFO_HASH_LENGTH]; peerId_ = new unsigned char[PEER_ID_LENGTH]; memcpy(pstr_, BT_PSTR, PSTR_LENGTH); memset(reserved_, 0, RESERVED_LENGTH); // fast extension reserved_[7] |= 0x04u; // extended messaging reserved_[5] |= 0x10u; } std::unique_ptr BtHandshakeMessage::create(const unsigned char* data, size_t dataLength) { auto message = make_unique(); message->pstrlen_ = data[0]; memcpy(message->pstr_, &data[1], PSTR_LENGTH); memcpy(message->reserved_, &data[20], RESERVED_LENGTH); memcpy(message->infoHash_, &data[28], INFO_HASH_LENGTH); memcpy(message->peerId_, &data[48], PEER_ID_LENGTH); return message; } unsigned char* BtHandshakeMessage::createMessage() { auto msg = new unsigned char[MESSAGE_LENGTH]; msg[0] = pstrlen_; memcpy(msg + 1, pstr_, PSTR_LENGTH); memcpy(msg + 20, reserved_, RESERVED_LENGTH); memcpy(msg + 28, infoHash_, INFO_HASH_LENGTH); memcpy(msg + 48, peerId_, PEER_ID_LENGTH); return msg; } size_t BtHandshakeMessage::getMessageLength() { return MESSAGE_LENGTH; } std::string BtHandshakeMessage::toString() const { return fmt("%s peerId=%s, reserved=%s", NAME, util::percentEncode(peerId_, PEER_ID_LENGTH).c_str(), util::toHex(reserved_, RESERVED_LENGTH).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) { memcpy(infoHash_, infoHash, INFO_HASH_LENGTH); } void BtHandshakeMessage::setPeerId(const unsigned char* peerId) { memcpy(peerId_, peerId, PEER_ID_LENGTH); } } // namespace aria2