File indexing completed on 2025-01-05 04:37:21
0001 /* 0002 SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #include "packetreader.h" 0007 #include "peer.h" 0008 #include <QtAlgorithms> 0009 #include <util/file.h> 0010 #include <util/functions.h> 0011 #include <util/log.h> 0012 0013 namespace bt 0014 { 0015 IncomingPacket::IncomingPacket(Uint32 size) 0016 : data(new Uint8[size]) 0017 , size(size) 0018 , read(0) 0019 { 0020 } 0021 0022 PacketReader::PacketReader(Uint32 max_packet_size) 0023 : error(false) 0024 , len_received(-1) 0025 , max_packet_size(max_packet_size) 0026 { 0027 } 0028 0029 PacketReader::~PacketReader() 0030 { 0031 } 0032 0033 IncomingPacket::Ptr PacketReader::dequeuePacket() 0034 { 0035 QMutexLocker lock(&mutex); 0036 if (packet_queue.size() == 0) 0037 return IncomingPacket::Ptr(); 0038 0039 IncomingPacket::Ptr pck = packet_queue.front(); 0040 if (pck->read != pck->size) 0041 return IncomingPacket::Ptr(); 0042 0043 packet_queue.pop_front(); 0044 return pck; 0045 } 0046 0047 void PacketReader::update(PeerInterface &peer) 0048 { 0049 if (error) 0050 return; 0051 0052 IncomingPacket::Ptr pck = dequeuePacket(); 0053 while (pck) { 0054 peer.handlePacket(pck->data.data(), pck->size); 0055 pck = dequeuePacket(); 0056 } 0057 } 0058 0059 Uint32 PacketReader::newPacket(Uint8 *buf, Uint32 size) 0060 { 0061 Uint32 packet_length = 0; 0062 Uint32 am_of_len_read = 0; 0063 if (len_received > 0) { 0064 if ((int)size < 4 - len_received) { 0065 memcpy(len + len_received, buf, size); 0066 len_received += size; 0067 return size; 0068 } else { 0069 memcpy(len + len_received, buf, 4 - len_received); 0070 am_of_len_read = 4 - len_received; 0071 len_received = 0; 0072 packet_length = ReadUint32(len, 0); 0073 } 0074 } else if (size < 4) { 0075 memcpy(len, buf, size); 0076 len_received = size; 0077 return size; 0078 } else { 0079 packet_length = ReadUint32(buf, 0); 0080 am_of_len_read = 4; 0081 } 0082 0083 if (packet_length == 0) 0084 return am_of_len_read; 0085 0086 if (packet_length > max_packet_size) { 0087 Out(SYS_CON | LOG_DEBUG) << " packet_length too large " << packet_length << endl; 0088 error = true; 0089 return size; 0090 } 0091 0092 IncomingPacket::Ptr pck(new IncomingPacket(packet_length)); 0093 packet_queue.push_back(pck); 0094 return am_of_len_read + readPacket(buf + am_of_len_read, size - am_of_len_read); 0095 } 0096 0097 Uint32 PacketReader::readPacket(Uint8 *buf, Uint32 size) 0098 { 0099 if (!size) 0100 return 0; 0101 0102 IncomingPacket::Ptr pck = packet_queue.back(); 0103 if (pck->read + size >= pck->size) { 0104 // we can read the full packet 0105 Uint32 tr = pck->size - pck->read; 0106 memcpy(pck->data.data() + pck->read, buf, tr); 0107 pck->read += tr; 0108 return tr; 0109 } else { 0110 // we can do a partial read 0111 Uint32 tr = size; 0112 memcpy(pck->data.data() + pck->read, buf, tr); 0113 pck->read += tr; 0114 return tr; 0115 } 0116 } 0117 0118 void PacketReader::onDataReady(Uint8 *buf, Uint32 size) 0119 { 0120 if (error) 0121 return; 0122 0123 mutex.lock(); 0124 if (packet_queue.size() == 0) { 0125 Uint32 ret = 0; 0126 while (ret < size && !error) { 0127 ret += newPacket(buf + ret, size - ret); 0128 } 0129 } else { 0130 Uint32 ret = 0; 0131 IncomingPacket::Ptr pck = packet_queue.back(); 0132 if (pck->read == pck->size) // last packet in queue is fully read 0133 ret = newPacket(buf, size); 0134 else 0135 ret = readPacket(buf, size); 0136 0137 while (ret < size && !error) { 0138 ret += newPacket(buf + ret, size - ret); 0139 } 0140 } 0141 mutex.unlock(); 0142 } 0143 }