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 "getpeersreq.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 GetPeersReq::GetPeersReq()
0019     : RPCMsg(QByteArray(), GET_PEERS, REQ_MSG, Key())
0020 {
0021 }
0022 
0023 GetPeersReq::GetPeersReq(const Key &id, const Key &info_hash)
0024     : RPCMsg(QByteArray(), GET_PEERS, REQ_MSG, id)
0025     , info_hash(info_hash)
0026 {
0027 }
0028 
0029 GetPeersReq::~GetPeersReq()
0030 {
0031 }
0032 
0033 void GetPeersReq::apply(dht::DHT *dh_table)
0034 {
0035     dh_table->getPeers(*this);
0036 }
0037 
0038 void GetPeersReq::print()
0039 {
0040     Out(SYS_DHT | LOG_DEBUG) << QString("REQ: %1 %2 : get_peers %3").arg(mtid[0]).arg(id.toString()).arg(info_hash.toString()) << endl;
0041 }
0042 
0043 void GetPeersReq::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("info_hash"));
0054             enc.write(info_hash.getData(), 20);
0055         }
0056         enc.end();
0057         enc.write(REQ);
0058         enc.write(QByteArrayLiteral("get_peers"));
0059         enc.write(TID);
0060         enc.write(mtid);
0061         enc.write(TYP);
0062         enc.write(REQ);
0063     }
0064     enc.end();
0065 }
0066 
0067 void GetPeersReq::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     info_hash = Key(args->getByteArray("info_hash"));
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 GetPeersReq::wants(int ip_version) const
0083 {
0084     return want.contains(QString("n%1").arg(ip_version));
0085 }
0086 
0087 }