/* */ #include "HandshakeExtensionMessage.h" #include "Peer.h" #include "BtContext.h" #include "Util.h" #include "DlAbortEx.h" #include "LogFactory.h" #include "Logger.h" #include "message.h" #include "StringFormat.h" #include "bencode.h" namespace aria2 { const std::string HandshakeExtensionMessage::EXTENSION_NAME = "handshake"; HandshakeExtensionMessage::HandshakeExtensionMessage(): _tcpPort(0), _logger(LogFactory::getInstance()) {} HandshakeExtensionMessage::~HandshakeExtensionMessage() {} std::string HandshakeExtensionMessage::getBencodedData() { BDE dict = BDE::dict(); if(!_clientVersion.empty()) { dict["v"] = _clientVersion; } if(_tcpPort > 0) { dict["p"] = _tcpPort; } BDE extDict = BDE::dict(); for(std::map::const_iterator itr = _extensions.begin(); itr != _extensions.end(); ++itr) { const std::map::value_type& vt = *itr; extDict[vt.first] = vt.second; } dict["m"] = extDict; return bencode::encode(dict); } std::string HandshakeExtensionMessage::toString() const { std::string s = getExtensionName(); if(!_clientVersion.empty()) { s += " client="+Util::urlencode(_clientVersion); } if(_tcpPort > 0) { s += ", tcpPort="+Util::uitos(_tcpPort); } for(std::map::const_iterator itr = _extensions.begin(); itr != _extensions.end(); ++itr) { const std::map::value_type& vt = *itr; s += ", "+vt.first+"="+Util::uitos(vt.second); } return s; } void HandshakeExtensionMessage::doReceivedAction() { if(_tcpPort > 0) { _peer->port = _tcpPort; _peer->setIncomingPeer(false); } for(std::map::const_iterator itr = _extensions.begin(); itr != _extensions.end(); ++itr) { const std::map::value_type& vt = *itr; _peer->setExtension(vt.first, vt.second); } } void HandshakeExtensionMessage::setPeer(const PeerHandle& peer) { _peer = peer; } void HandshakeExtensionMessage::setBtContext(const BtContextHandle& btContext) { _btContext = btContext; } uint8_t HandshakeExtensionMessage::getExtensionMessageID(const std::string& name) const { std::map::const_iterator i = _extensions.find(name); if(i == _extensions.end()) { return 0; } else { return (*i).second; } } HandshakeExtensionMessageHandle HandshakeExtensionMessage::create(const unsigned char* data, size_t length) { if(length < 1) { throw DlAbortEx (StringFormat(MSG_TOO_SMALL_PAYLOAD_SIZE, EXTENSION_NAME.c_str(), length).str()); } HandshakeExtensionMessageHandle msg(new HandshakeExtensionMessage()); msg->_logger->debug("Creating HandshakeExtensionMessage from %s", Util::urlencode(data, length).c_str()); const BDE dict = bencode::decode(data+1, length-1); if(!dict.isDict()) { throw DlAbortEx("Unexpected payload format for extended message handshake"); } const BDE& port = dict["p"]; if(port.isInteger() && 0 < port.i() && port.i() < 65536) { msg->_tcpPort = port.i(); } const BDE& version = dict["v"]; if(version.isString()) { msg->_clientVersion = version.s(); } const BDE& extDict = dict["m"]; if(extDict.isDict()) { for(BDE::Dict::const_iterator i = extDict.dictBegin(); i != extDict.dictEnd(); ++i) { if((*i).second.isInteger()) { msg->_extensions[(*i).first] = (*i).second.i(); } } } return msg; } } // namespace aria2