Changeset View
Changeset View
Standalone View
Standalone View
src/dht/announcereq.cpp
Show All 29 Lines | |||||
30 | 30 | | |||
31 | namespace dht | 31 | namespace dht | ||
32 | { | 32 | { | ||
33 | AnnounceReq::AnnounceReq() | 33 | AnnounceReq::AnnounceReq() | ||
34 | { | 34 | { | ||
35 | method = dht::ANNOUNCE_PEER; | 35 | method = dht::ANNOUNCE_PEER; | ||
36 | } | 36 | } | ||
37 | 37 | | |||
38 | AnnounceReq::AnnounceReq(const Key & id, const Key & info_hash, Uint16 port, const Key & token) | 38 | AnnounceReq::AnnounceReq(const Key & id, const Key & info_hash, Uint16 port, const QByteArray & token) | ||
39 | : GetPeersReq(id, info_hash), port(port), token(token) | 39 | : GetPeersReq(id, info_hash), port(port), token(token) | ||
40 | { | 40 | { | ||
41 | method = dht::ANNOUNCE_PEER; | 41 | method = dht::ANNOUNCE_PEER; | ||
42 | } | 42 | } | ||
43 | 43 | | |||
44 | AnnounceReq::~AnnounceReq() {} | 44 | AnnounceReq::~AnnounceReq() {} | ||
45 | 45 | | |||
46 | void AnnounceReq::apply(dht::DHT* dh_table) | 46 | void AnnounceReq::apply(dht::DHT* dh_table) | ||
47 | { | 47 | { | ||
48 | dh_table->announce(*this); | 48 | dh_table->announce(*this); | ||
49 | } | 49 | } | ||
50 | 50 | | |||
51 | QString tokenToHex(const QByteArray &token) | ||||
52 | { | ||||
53 | // slightly modified implementation of QByteArray::ToHex() (since Qt 5.9) | ||||
54 | // copied here to keep minimal Qt ver. requirement eq. to 5.7 | ||||
55 | QByteArray hex(token.size() * 2, Qt::Uninitialized); | ||||
56 | char *hexData = hex.data(); | ||||
57 | const uchar *data = (const uchar *)token.data(); | ||||
58 | for (int i = 0; i < token.size(); ++i) { | ||||
59 | int j = (data[i] >> 4) & 0xf; | ||||
60 | if (j <= 9) | ||||
61 | hexData[i*2] = (j + '0'); | ||||
62 | else | ||||
63 | hexData[i*2] = (j + 'A' - 10); // <- use upper case | ||||
64 | j = data[i] & 0xf; | ||||
65 | if (j <= 9) | ||||
66 | hexData[i*2+1] = (j + '0'); | ||||
67 | else | ||||
68 | hexData[i*2+1] = (j + 'A' - 10); | ||||
69 | } | ||||
70 | return QString(hex); | ||||
71 | } | ||||
72 | | ||||
51 | void AnnounceReq::print() | 73 | void AnnounceReq::print() | ||
52 | { | 74 | { | ||
53 | Out(SYS_DHT | LOG_DEBUG) << QString("REQ: %1 %2 : announce_peer %3 %4 %5") | 75 | Out(SYS_DHT | LOG_DEBUG) << QString("REQ: %1 %2 : announce_peer %3 %4 %5") | ||
54 | .arg(mtid[0]).arg(id.toString()).arg(info_hash.toString()) | 76 | .arg(mtid[0]).arg(id.toString()).arg(info_hash.toString()) | ||
55 | .arg(port).arg(token.toString()) << endl; | 77 | .arg(port).arg(tokenToHex(token)) << endl; | ||
56 | } | 78 | } | ||
57 | 79 | | |||
58 | void AnnounceReq::encode(QByteArray & arr) const | 80 | void AnnounceReq::encode(QByteArray & arr) const | ||
59 | { | 81 | { | ||
60 | BEncoder enc(new BEncoderBufferOutput(arr)); | 82 | BEncoder enc(new BEncoderBufferOutput(arr)); | ||
61 | enc.beginDict(); | 83 | enc.beginDict(); | ||
62 | { | 84 | { | ||
63 | enc.write(ARG); enc.beginDict(); | 85 | enc.write(ARG); enc.beginDict(); | ||
64 | { | 86 | { | ||
65 | enc.write(QByteArrayLiteral("id")); enc.write(id.getData(), 20); | 87 | enc.write(QByteArrayLiteral("id")); enc.write(id.getData(), 20); | ||
66 | enc.write(QByteArrayLiteral("info_hash")); enc.write(info_hash.getData(), 20); | 88 | enc.write(QByteArrayLiteral("info_hash")); enc.write(info_hash.getData(), 20); | ||
67 | enc.write(QByteArrayLiteral("port")); enc.write((Uint32)port); | 89 | enc.write(QByteArrayLiteral("port")); enc.write((Uint32)port); | ||
68 | enc.write(QByteArrayLiteral("token")); enc.write(token.getData(), 20); | 90 | // must cast data() to (const Uint8*) to call right write() overload | ||
91 | enc.write(QByteArrayLiteral("token")); enc.write((const Uint8*)token.data(), token.size()); | ||||
69 | } | 92 | } | ||
70 | enc.end(); | 93 | enc.end(); | ||
71 | enc.write(REQ); enc.write(QByteArrayLiteral("announce_peer")); | 94 | enc.write(REQ); enc.write(QByteArrayLiteral("announce_peer")); | ||
72 | enc.write(TID); enc.write(mtid); | 95 | enc.write(TID); enc.write(mtid); | ||
73 | enc.write(TYP); enc.write(REQ); | 96 | enc.write(TYP); enc.write(REQ); | ||
74 | } | 97 | } | ||
75 | enc.end(); | 98 | enc.end(); | ||
76 | } | 99 | } | ||
77 | 100 | | |||
78 | void AnnounceReq::parse(BDictNode* dict) | 101 | void AnnounceReq::parse(BDictNode* dict) | ||
79 | { | 102 | { | ||
80 | dht::GetPeersReq::parse(dict); | 103 | dht::GetPeersReq::parse(dict); | ||
81 | BDictNode* args = dict->getDict(ARG); | 104 | BDictNode* args = dict->getDict(ARG); | ||
82 | if (!args) | 105 | if (!args) | ||
83 | throw bt::Error("Invalid request, arguments missing"); | 106 | throw bt::Error("Invalid request, arguments missing"); | ||
84 | 107 | | |||
85 | info_hash = Key(args->getByteArray("info_hash")); | 108 | info_hash = Key(args->getByteArray("info_hash")); | ||
86 | port = args->getInt("port"); | 109 | port = args->getInt("port"); | ||
87 | token = Key(args->getByteArray("token")); | 110 | token = args->getByteArray("token").left(MAX_TOKEN_SIZE); | ||
88 | } | 111 | } | ||
89 | } | 112 | } | ||
90 | 113 | |