File indexing completed on 2025-01-05 04:37:10
0001 /* 0002 SPDX-FileCopyrightText: 2012 Joris Guisson <joris.guisson@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "getpeersrsp.h" 0008 #include "dht.h" 0009 #include <bcodec/bencoder.h> 0010 #include <bcodec/bnode.h> 0011 #include <util/error.h> 0012 #include <util/functions.h> 0013 #include <util/log.h> 0014 0015 using namespace bt; 0016 0017 namespace dht 0018 { 0019 GetPeersRsp::GetPeersRsp() 0020 : RPCMsg(QByteArray(), dht::GET_PEERS, dht::RSP_MSG, QByteArray()) 0021 { 0022 } 0023 0024 GetPeersRsp::GetPeersRsp(const QByteArray &mtid, const Key &id, const QByteArray &token) 0025 : RPCMsg(mtid, dht::GET_PEERS, dht::RSP_MSG, id) 0026 , token(token) 0027 { 0028 } 0029 0030 GetPeersRsp::GetPeersRsp(const QByteArray &mtid, const Key &id, const DBItemList &values, const QByteArray &token) 0031 : RPCMsg(mtid, dht::GET_PEERS, dht::RSP_MSG, id) 0032 , token(token) 0033 , items(values) 0034 { 0035 } 0036 0037 GetPeersRsp::~GetPeersRsp() 0038 { 0039 } 0040 0041 void GetPeersRsp::apply(dht::DHT *dh_table) 0042 { 0043 dh_table->response(*this); 0044 } 0045 0046 void GetPeersRsp::print() 0047 { 0048 Out(SYS_DHT | LOG_DEBUG) << QString("RSP: %1 %2 : get_peers(%3)").arg(mtid[0]).arg(id.toString()).arg(nodes.size() > 0 ? "nodes" : "values") << endl; 0049 } 0050 0051 void GetPeersRsp::encode(QByteArray &arr) const 0052 { 0053 BEncoder enc(new BEncoderBufferOutput(arr)); 0054 enc.beginDict(); 0055 { 0056 enc.write(RSP); 0057 enc.beginDict(); 0058 { 0059 enc.write(QByteArrayLiteral("id")); 0060 enc.write(id.getData(), 20); 0061 if (nodes.size() > 0) { 0062 enc.write(QByteArrayLiteral("nodes")); 0063 enc.write(nodes); 0064 } 0065 0066 if (nodes6.size() > 0) { 0067 enc.write(QByteArrayLiteral("nodes6")); 0068 enc.write(nodes6); 0069 } 0070 0071 // must cast data() to (const Uint8*) to call right write() overload 0072 enc.write(QByteArrayLiteral("token")); 0073 enc.write((const Uint8 *)token.data(), token.size()); 0074 0075 if (items.size() > 0) { 0076 enc.write(QByteArrayLiteral("values")); 0077 enc.beginList(); 0078 DBItemList::const_iterator i = items.begin(); 0079 while (i != items.end()) { 0080 const DBItem &item = *i; 0081 Uint8 tmp[18]; 0082 Uint32 b = item.pack(tmp); 0083 enc.write(tmp, b); 0084 ++i; 0085 } 0086 enc.end(); 0087 } 0088 } 0089 enc.end(); 0090 enc.write(TID); 0091 enc.write(mtid); 0092 enc.write(TYP); 0093 enc.write(RSP); 0094 } 0095 enc.end(); 0096 } 0097 0098 void GetPeersRsp::parse(BDictNode *dict) 0099 { 0100 dht::RPCMsg::parse(dict); 0101 BDictNode *args = dict->getDict(RSP); 0102 if (!args) 0103 throw bt::Error("Invalid response, arguments missing"); 0104 0105 token = args->getByteArray("token").left(MAX_TOKEN_SIZE); 0106 0107 BListNode *vals = args->getList("values"); 0108 if (vals) { 0109 for (Uint32 i = 0; i < vals->getNumChildren(); i++) { 0110 QByteArray d = vals->getByteArray(i); 0111 if (d.length() == 6) { // IPv4 0112 Uint16 port = bt::ReadUint16((const Uint8 *)d.data(), 4); 0113 Uint32 ip = bt::ReadUint32((const Uint8 *)d.data(), 0); 0114 net::Address addr(QHostAddress(ip), port); 0115 items.append(DBItem(addr)); 0116 } else if (d.length() == 18) { // IPv6 0117 Uint16 port = bt::ReadUint16((const Uint8 *)d.data(), 16); 0118 Q_IPV6ADDR ip; 0119 memcpy(ip.c, d.data(), 16); 0120 net::Address addr(QHostAddress(ip), port); 0121 items.append(DBItem(addr)); 0122 } 0123 } 0124 } 0125 0126 if (args->getValue("nodes") || args->getList("nodes6")) { 0127 BValueNode *v = args->getValue("nodes"); 0128 if (v) 0129 nodes = v->data().toByteArray(); 0130 0131 v = args->getValue("nodes6"); 0132 if (v) 0133 nodes6 = v->data().toByteArray(); 0134 } 0135 } 0136 }