File indexing completed on 2024-06-02 05:05:27
0001 /* 0002 SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #include "authenticatebase.h" 0007 #include <dht/dhtbase.h> 0008 #include <mse/encryptedpacketsocket.h> 0009 #include <peer/peerid.h> 0010 #include <torrent/globals.h> 0011 #include <util/log.h> 0012 #include <util/sha1hash.h> 0013 0014 namespace bt 0015 { 0016 AuthenticateBase::AuthenticateBase() 0017 : finished(false) 0018 , local(false) 0019 { 0020 connect(&timer, &QTimer::timeout, this, &AuthenticateBase::onTimeout); 0021 timer.setSingleShot(true); 0022 timer.start(5000); 0023 memset(handshake, 0x00, 68); 0024 bytes_of_handshake_received = 0; 0025 ext_support = 0; 0026 } 0027 0028 AuthenticateBase::AuthenticateBase(mse::EncryptedPacketSocket::Ptr s) 0029 : sock(s) 0030 , finished(false) 0031 , local(false) 0032 { 0033 connect(&timer, &QTimer::timeout, this, &AuthenticateBase::onTimeout); 0034 timer.setSingleShot(true); 0035 timer.start(5000); 0036 memset(handshake, 0x00, 68); 0037 bytes_of_handshake_received = 0; 0038 ext_support = 0; 0039 } 0040 0041 AuthenticateBase::~AuthenticateBase() 0042 { 0043 } 0044 0045 void AuthenticateBase::sendHandshake(const SHA1Hash &info_hash, const PeerID &our_peer_id) 0046 { 0047 // Out() << "AuthenticateBase::sendHandshake" << endl; 0048 if (!sock) 0049 return; 0050 0051 Uint8 hs[68]; 0052 makeHandshake(hs, info_hash, our_peer_id); 0053 sock->sendData(hs, 68); 0054 } 0055 0056 void AuthenticateBase::makeHandshake(Uint8 *hs, const SHA1Hash &info_hash, const PeerID &our_peer_id) 0057 { 0058 const char *pstr = "BitTorrent protocol"; 0059 hs[0] = 19; 0060 memcpy(hs + 1, pstr, 19); 0061 memset(hs + 20, 0x00, 8); 0062 if (Globals::instance().getDHT().isRunning()) 0063 hs[27] |= 0x01; // DHT support 0064 hs[25] |= 0x10; // extension protocol 0065 hs[27] |= 0x04; // fast extensions 0066 memcpy(hs + 28, info_hash.getData(), 20); 0067 memcpy(hs + 48, our_peer_id.data(), 20); 0068 } 0069 0070 void AuthenticateBase::onReadyRead() 0071 { 0072 Uint32 ba = sock->bytesAvailable(); 0073 // Out() << "AuthenticateBase::onReadyRead " << ba << endl; 0074 if (ba == 0) { 0075 onFinish(false); 0076 return; 0077 } 0078 0079 if (!sock || finished || ba < 48) 0080 return; 0081 0082 // first see if we already have some bytes from the handshake 0083 if (bytes_of_handshake_received == 0) { 0084 if (ba < 68) { 0085 // read partial 0086 sock->readData(handshake, ba); 0087 bytes_of_handshake_received += ba; 0088 if (ba >= 27 && handshake[27] & 0x01) 0089 ext_support |= bt::DHT_SUPPORT; 0090 // tell subclasses of a partial handshake 0091 handshakeReceived(false); 0092 return; 0093 } else { 0094 // read full handshake 0095 sock->readData(handshake, 68); 0096 } 0097 } else { 0098 // read remaining part 0099 Uint32 to_read = 68 - bytes_of_handshake_received; 0100 sock->readData(handshake + bytes_of_handshake_received, to_read); 0101 } 0102 0103 if (handshake[0] != 19) { 0104 onFinish(false); 0105 return; 0106 } 0107 0108 const char *pstr = "BitTorrent protocol"; 0109 if (memcmp(pstr, handshake + 1, 19) != 0) { 0110 onFinish(false); 0111 return; 0112 } 0113 0114 if (Globals::instance().getDHT().isRunning() && (handshake[27] & 0x01)) 0115 ext_support |= bt::DHT_SUPPORT; 0116 0117 if (handshake[27] & 0x04) 0118 ext_support |= bt::FAST_EXT_SUPPORT; 0119 0120 if (handshake[25] & 0x10) 0121 ext_support |= bt::EXT_PROT_SUPPORT; 0122 0123 handshakeReceived(true); 0124 } 0125 0126 void AuthenticateBase::onError(int) 0127 { 0128 if (finished) 0129 return; 0130 onFinish(false); 0131 } 0132 0133 void AuthenticateBase::onTimeout() 0134 { 0135 if (finished) 0136 return; 0137 0138 Out(SYS_CON | LOG_DEBUG) << "Timeout occurred" << endl; 0139 onFinish(false); 0140 } 0141 0142 void AuthenticateBase::onReadyWrite() 0143 { 0144 } 0145 } 0146 0147 #include "moc_authenticatebase.cpp"