File indexing completed on 2025-01-05 04:37:20
0001 /* 0002 SPDX-FileCopyrightText: 2011 Joris Guisson <joris.guisson@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "trafficshapedsocket.h" 0008 0009 #include "socket.h" 0010 #include "speed.h" 0011 #include <QStringList> 0012 #include <util/functions.h> 0013 0014 const bt::Uint32 OUTPUT_BUFFER_SIZE = 16393; 0015 0016 using namespace bt; 0017 0018 namespace net 0019 { 0020 TrafficShapedSocket::TrafficShapedSocket(SocketDevice *sock) 0021 : rdr(nullptr) 0022 , up_gid(0) 0023 , down_gid(0) 0024 , sock(sock) 0025 , mutex() 0026 { 0027 down_speed = new Speed(); 0028 up_speed = new Speed(); 0029 } 0030 0031 TrafficShapedSocket::TrafficShapedSocket(int fd, int ip_version) 0032 : rdr(nullptr) 0033 , up_gid(0) 0034 , down_gid(0) 0035 , mutex() 0036 { 0037 sock = new Socket(fd, ip_version); 0038 down_speed = new Speed(); 0039 up_speed = new Speed(); 0040 } 0041 0042 TrafficShapedSocket::TrafficShapedSocket(bool tcp, int ip_version) 0043 : rdr(nullptr) 0044 , up_gid(0) 0045 , down_gid(0) 0046 , mutex() 0047 { 0048 Socket *socket = new Socket(tcp, ip_version); 0049 0050 QString iface = NetworkInterface(); 0051 QStringList ips = NetworkInterfaceIPAddresses(iface); 0052 if (ips.size() > 0) 0053 socket->bind(ips.front(), 0, false); 0054 0055 sock = socket; 0056 down_speed = new Speed(); 0057 up_speed = new Speed(); 0058 } 0059 0060 TrafficShapedSocket::~TrafficShapedSocket() 0061 { 0062 delete up_speed; 0063 delete down_speed; 0064 delete sock; 0065 } 0066 0067 void TrafficShapedSocket::setGroupID(Uint32 gid, bool upload) 0068 { 0069 if (upload) 0070 up_gid = gid; 0071 else 0072 down_gid = gid; 0073 } 0074 0075 int TrafficShapedSocket::getDownloadRate() const 0076 { 0077 // getRate is atomic 0078 return down_speed->getRate(); 0079 } 0080 0081 int TrafficShapedSocket::getUploadRate() const 0082 { 0083 // getRate is atomic 0084 return up_speed->getRate(); 0085 } 0086 0087 void TrafficShapedSocket::updateSpeeds(bt::TimeStamp now) 0088 { 0089 mutex.lock(); 0090 up_speed->update(now); 0091 down_speed->update(now); 0092 mutex.unlock(); 0093 } 0094 0095 static bt::Uint8 input_buffer[OUTPUT_BUFFER_SIZE]; 0096 0097 Uint32 TrafficShapedSocket::read(bt::Uint32 max_bytes_to_read, bt::TimeStamp now) 0098 { 0099 Uint32 br = 0; 0100 bool no_limit = (max_bytes_to_read == 0); 0101 Uint32 ba = sock->bytesAvailable(); 0102 if (ba == 0) { 0103 // For some strange reason, sometimes bytesAvailable returns 0, while there are 0104 // bytes to read, so give ba the maximum value it can be 0105 ba = max_bytes_to_read > 0 ? max_bytes_to_read : OUTPUT_BUFFER_SIZE; 0106 } 0107 0108 while ((br < max_bytes_to_read || no_limit) && ba > 0) { 0109 Uint32 tr = ba; 0110 if (tr > OUTPUT_BUFFER_SIZE) 0111 tr = OUTPUT_BUFFER_SIZE; 0112 if (!no_limit && tr + br > max_bytes_to_read) 0113 tr = max_bytes_to_read - br; 0114 0115 int ret = sock->recv(input_buffer, tr); 0116 if (ret > 0) { 0117 mutex.lock(); 0118 down_speed->onData(ret, now); 0119 mutex.unlock(); 0120 if (rdr) { 0121 postProcess(input_buffer, ret); 0122 rdr->onDataReady(input_buffer, ret); 0123 } 0124 br += ret; 0125 ba -= ret; 0126 } else if (ret < 0) { 0127 return br; 0128 } else { 0129 sock->close(); 0130 return br; 0131 } 0132 } 0133 return br; 0134 } 0135 0136 void TrafficShapedSocket::postProcess(Uint8 *data, Uint32 size) 0137 { 0138 Q_UNUSED(data); 0139 Q_UNUSED(size); 0140 } 0141 }