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 #include "node.h" 0007 0008 #include "dht.h" 0009 #include "kbuckettable.h" 0010 #include "kclosestnodessearch.h" 0011 #include "key.h" 0012 #include "nodelookup.h" 0013 #include "rpccall.h" 0014 #include "rpcmsg.h" 0015 #include "rpcserver.h" 0016 #include <torrent/globals.h> 0017 #include <util/error.h> 0018 #include <util/file.h> 0019 #include <util/fileops.h> 0020 #include <util/functions.h> 0021 #include <util/log.h> 0022 0023 using namespace bt; 0024 0025 namespace dht 0026 { 0027 class Node::Private 0028 { 0029 public: 0030 Private(RPCServer *srv) 0031 : srv(srv) 0032 { 0033 num_receives = 0; 0034 new_key = false; 0035 } 0036 0037 ~Private() 0038 { 0039 } 0040 0041 void saveKey(const dht::Key &key, const QString &key_file) 0042 { 0043 bt::File fptr; 0044 if (!fptr.open(key_file, "wb")) { 0045 Out(SYS_DHT | LOG_IMPORTANT) << "DHT: Cannot open file " << key_file << " : " << fptr.errorString() << endl; 0046 return; 0047 } 0048 0049 fptr.write(key.getData(), 20); 0050 fptr.close(); 0051 } 0052 0053 dht::Key loadKey(const QString &key_file) 0054 { 0055 bt::File fptr; 0056 if (!fptr.open(key_file, "rb")) { 0057 Out(SYS_DHT | LOG_IMPORTANT) << "DHT: Cannot open file " << key_file << " : " << fptr.errorString() << endl; 0058 dht::Key r = dht::Key::random(); 0059 saveKey(r, key_file); 0060 new_key = true; 0061 return r; 0062 } 0063 0064 Uint8 data[20]; 0065 if (fptr.read(data, 20) != 20) { 0066 dht::Key r = dht::Key::random(); 0067 saveKey(r, key_file); 0068 new_key = true; 0069 return r; 0070 } 0071 0072 new_key = false; 0073 return dht::Key(data); 0074 } 0075 0076 QScopedPointer<KBucketTable> ipv4_table; 0077 QScopedPointer<KBucketTable> ipv6_table; 0078 RPCServer *srv; 0079 Uint32 num_receives; 0080 bool new_key; 0081 }; 0082 0083 Node::Node(RPCServer *srv, const QString &key_file) 0084 : d(new Private(srv)) 0085 { 0086 num_entries = 0; 0087 our_id = d->loadKey(key_file); 0088 d->ipv4_table.reset(new KBucketTable(our_id)); 0089 d->ipv6_table.reset(new KBucketTable(our_id)); 0090 } 0091 0092 Node::~Node() 0093 { 0094 delete d; 0095 } 0096 0097 void Node::received(dht::DHT *dh_table, const dht::RPCMsg &msg) 0098 { 0099 if (msg.getOrigin().ipVersion() == 4) 0100 d->ipv4_table->insert(KBucketEntry(msg.getOrigin(), msg.getID()), d->srv); 0101 else 0102 d->ipv6_table->insert(KBucketEntry(msg.getOrigin(), msg.getID()), d->srv); 0103 0104 d->num_receives++; 0105 if (d->num_receives == 3) { 0106 // do a node lookup upon our own id 0107 // when we insert the first entry in the table 0108 dh_table->findOwnNode(); 0109 } 0110 0111 num_entries = d->ipv4_table->numEntries() + d->ipv6_table->numEntries(); 0112 } 0113 0114 void Node::findKClosestNodes(KClosestNodesSearch &kns, bt::Uint32 want) 0115 { 0116 if (want & WANT_IPV4) 0117 d->ipv4_table->findKClosestNodes(kns); 0118 if (want & WANT_IPV6) 0119 d->ipv6_table->findKClosestNodes(kns); 0120 } 0121 0122 void Node::onTimeout(RPCMsg::Ptr msg) 0123 { 0124 if (msg->getOrigin().ipVersion() == 4) 0125 d->ipv4_table->onTimeout(msg->getOrigin()); 0126 else 0127 d->ipv6_table->onTimeout(msg->getOrigin()); 0128 } 0129 0130 void Node::refreshBuckets(DHT *dh_table) 0131 { 0132 d->ipv4_table->refreshBuckets(dh_table); 0133 d->ipv6_table->refreshBuckets(dh_table); 0134 } 0135 0136 void Node::saveTable(const QString &file) 0137 { 0138 d->ipv4_table->saveTable(file + ".ipv4"); 0139 d->ipv6_table->saveTable(file + ".ipv6"); 0140 } 0141 0142 void Node::loadTable(const QString &file) 0143 { 0144 if (d->new_key) { 0145 d->new_key = false; 0146 bt::Delete(file + ".ipv4", true); 0147 bt::Delete(file + ".ipv6", true); 0148 Out(SYS_DHT | LOG_IMPORTANT) << "DHT: new key, so removing tables" << endl; 0149 } else { 0150 d->ipv4_table->loadTable(file + ".ipv4", d->srv); 0151 d->ipv6_table->loadTable(file + ".ipv6", d->srv); 0152 num_entries = d->ipv4_table->numEntries() + d->ipv6_table->numEntries(); 0153 } 0154 } 0155 } 0156 0157 #include "moc_node.cpp"