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 }