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 "findnodereq.h" 0008 #include "dht.h" 0009 #include <bcodec/bencoder.h> 0010 #include <bcodec/bnode.h> 0011 #include <util/error.h> 0012 #include <util/log.h> 0013 0014 using namespace bt; 0015 0016 namespace dht 0017 { 0018 FindNodeReq::FindNodeReq() 0019 : RPCMsg(QByteArray(), FIND_NODE, REQ_MSG, Key()) 0020 { 0021 } 0022 0023 FindNodeReq::FindNodeReq(const Key &id, const Key &target) 0024 : RPCMsg(QByteArray(), FIND_NODE, REQ_MSG, id) 0025 , target(target) 0026 { 0027 } 0028 0029 FindNodeReq::~FindNodeReq() 0030 { 0031 } 0032 0033 void FindNodeReq::apply(dht::DHT *dh_table) 0034 { 0035 dh_table->findNode(*this); 0036 } 0037 0038 void FindNodeReq::print() 0039 { 0040 Out(SYS_DHT | LOG_NOTICE) << QString("REQ: %1 %2 : find_node %3").arg(mtid[0]).arg(id.toString()).arg(target.toString()) << endl; 0041 } 0042 0043 void FindNodeReq::encode(QByteArray &arr) const 0044 { 0045 BEncoder enc(new BEncoderBufferOutput(arr)); 0046 enc.beginDict(); 0047 { 0048 enc.write(ARG); 0049 enc.beginDict(); 0050 { 0051 enc.write(QByteArrayLiteral("id")); 0052 enc.write(id.getData(), 20); 0053 enc.write(QByteArrayLiteral("target")); 0054 enc.write(target.getData(), 20); 0055 } 0056 enc.end(); 0057 enc.write(REQ); 0058 enc.write(QByteArrayLiteral("find_node")); 0059 enc.write(TID); 0060 enc.write(mtid); 0061 enc.write(TYP); 0062 enc.write(REQ); 0063 } 0064 enc.end(); 0065 } 0066 0067 void FindNodeReq::parse(BDictNode *dict) 0068 { 0069 dht::RPCMsg::parse(dict); 0070 BDictNode *args = dict->getDict(ARG); 0071 if (!args) 0072 throw bt::Error("Invalid request, arguments missing"); 0073 0074 target = Key(args->getByteArray("target")); 0075 BListNode *ln = args->getList("want"); 0076 if (ln) { 0077 for (bt::Uint32 i = 0; i < ln->getNumChildren(); i++) 0078 want.append(ln->getString(i, nullptr)); 0079 } 0080 } 0081 0082 bool FindNodeReq::wants(int ip_version) const 0083 { 0084 return want.contains(QString("n%1").arg(ip_version)); 0085 } 0086 0087 }