File indexing completed on 2025-01-05 04:37:11

0001 /*
0002     SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #ifndef DHTNODE_H
0007 #define DHTNODE_H
0008 
0009 #include "kbucket.h"
0010 #include "key.h"
0011 #include <qobject.h>
0012 
0013 using bt::Uint8;
0014 
0015 namespace dht
0016 {
0017 class DHT;
0018 class RPCMsg;
0019 class RPCServer;
0020 class KClosestNodesSearch;
0021 
0022 const bt::Uint32 WANT_IPV4 = 1;
0023 const bt::Uint32 WANT_IPV6 = 2;
0024 const bt::Uint32 WANT_BOTH = WANT_IPV4 | WANT_IPV6;
0025 
0026 /**
0027  * @author Joris Guisson
0028  *
0029  * A Node represents us in the kademlia network. It contains
0030  * our id and 160 KBucket's.
0031  * A KBucketEntry is in node i, when the difference between our id and
0032  * the KBucketEntry's id is between 2 to the power i and 2 to the power i+1.
0033  */
0034 class Node : public QObject
0035 {
0036     Q_OBJECT
0037 public:
0038     Node(RPCServer *srv, const QString &key_file);
0039     ~Node() override;
0040 
0041     /**
0042      * An RPC message was received, the node must now update
0043      * the right bucket.
0044      * @param dh_table The DHT
0045      * @param msg The message
0046      * @param srv The RPCServer to send a ping if necessary
0047      */
0048     void received(DHT *dh_table, const RPCMsg &msg);
0049 
0050     /// Get our own ID
0051     const dht::Key &getOurID() const
0052     {
0053         return our_id;
0054     }
0055 
0056     /**
0057      * Find the K closest entries to a key and store them in the KClosestNodesSearch
0058      * object.
0059      * @param kns The object to storre the search results
0060      * @param want Which protocol(s) are wanted
0061      */
0062     void findKClosestNodes(KClosestNodesSearch &kns, bt::Uint32 want);
0063 
0064     /**
0065      * Increase the failed queries count of the bucket entry we sent the message to
0066      */
0067     void onTimeout(RPCMsg::Ptr msg);
0068 
0069     /// Check if a buckets needs to be refreshed, and refresh if necesarry
0070     void refreshBuckets(DHT *dh_table);
0071 
0072     /// Save the routing table to a file
0073     void saveTable(const QString &file);
0074 
0075     /// Load the routing table from a file
0076     void loadTable(const QString &file);
0077 
0078     /// Get the number of entries in the routing table
0079     bt::Uint32 getNumEntriesInRoutingTable() const
0080     {
0081         return num_entries;
0082     }
0083 
0084 private:
0085     class Private;
0086     Private *d;
0087     dht::Key our_id;
0088     bt::Uint32 num_entries;
0089 };
0090 
0091 }
0092 
0093 #endif