File indexing completed on 2025-01-05 04:37:33
0001 /* 0002 SPDX-FileCopyrightText: 2009 Joris Guisson <joris.guisson@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef UTP_CONNECTION_H 0008 #define UTP_CONNECTION_H 0009 0010 #include <QBasicTimer> 0011 #include <QMutex> 0012 #include <QPair> 0013 #include <QSharedPointer> 0014 #include <QWaitCondition> 0015 #include <boost/concept_check.hpp> 0016 #include <ktorrent_export.h> 0017 #include <net/address.h> 0018 #include <util/circularbuffer.h> 0019 #include <util/timer.h> 0020 #include <utp/remotewindow.h> 0021 #include <utp/utpprotocol.h> 0022 0023 namespace utp 0024 { 0025 class DelayWindow; 0026 class LocalWindow; 0027 class Transmitter; 0028 0029 /** 0030 Keeps track of a single UTP connection 0031 */ 0032 class KTORRENT_EXPORT Connection : public QObject, public Retransmitter 0033 { 0034 Q_OBJECT 0035 public: 0036 enum Type { 0037 INCOMING, 0038 OUTGOING, 0039 }; 0040 0041 /// Thrown when a transmission error occurs, server should kill the connection if it happens 0042 class TransmissionError 0043 { 0044 public: 0045 TransmissionError(const char *file, int line); 0046 0047 QString location; 0048 }; 0049 0050 struct Stats { 0051 Type type; 0052 net::Address remote; 0053 ConnectionState state; 0054 bt::Uint16 send_connection_id; 0055 bt::Uint32 reply_micro; 0056 bt::Uint16 recv_connection_id; 0057 bt::Uint16 seq_nr; 0058 int eof_seq_nr; 0059 bt::Uint32 timeout; 0060 TimeValue absolute_timeout; 0061 int rtt; 0062 int rtt_var; 0063 bt::Uint32 packet_size; 0064 bt::Uint32 last_window_size_transmitted; 0065 0066 bt::Uint64 bytes_received; 0067 bt::Uint64 bytes_sent; 0068 bt::Uint32 packets_received; 0069 bt::Uint32 packets_sent; 0070 bt::Uint64 bytes_lost; 0071 bt::Uint32 packets_lost; 0072 0073 bool readable; 0074 bool writeable; 0075 }; 0076 0077 Connection(bt::Uint16 recv_connection_id, Type type, const net::Address &remote, Transmitter *transmitter); 0078 ~Connection() override; 0079 0080 /// Turn on or off blocking mode 0081 void setBlocking(bool on) 0082 { 0083 blocking = on; 0084 } 0085 0086 /// Dump connection stats 0087 void dumpStats(); 0088 0089 /// Start connecting (OUTGOING only) 0090 void startConnecting(); 0091 0092 /// Get the connection stats 0093 const Stats &connectionStats() const 0094 { 0095 return stats; 0096 } 0097 0098 /// Handle a single packet 0099 ConnectionState handlePacket(const PacketParser &parser, bt::Buffer::Ptr packet); 0100 0101 /// Get the remote address 0102 const net::Address &remoteAddress() const 0103 { 0104 return stats.remote; 0105 } 0106 0107 /// Get the receive connection id 0108 bt::Uint16 receiveConnectionID() const 0109 { 0110 return stats.recv_connection_id; 0111 } 0112 0113 /// Send some data, returns the amount of bytes sent (or -1 on error) 0114 int send(const bt::Uint8 *data, bt::Uint32 len); 0115 0116 /// Read available data from local window, returns the amount of bytes read 0117 int recv(bt::Uint8 *buf, bt::Uint32 max_len); 0118 0119 /// Get the connection state 0120 ConnectionState connectionState() const 0121 { 0122 return stats.state; 0123 } 0124 0125 /// Get the type of connection 0126 Type connectionType() const 0127 { 0128 return stats.type; 0129 } 0130 0131 /// Get the number of bytes available 0132 bt::Uint32 bytesAvailable() const; 0133 0134 /// Can we write to this socket 0135 bool isWriteable() const; 0136 0137 /// Wait until the connectTo call fails or succeeds 0138 bool waitUntilConnected(); 0139 0140 /// Wait until there is data ready or the socket is closed or a timeout occurs 0141 bool waitForData(bt::Uint32 timeout = 0); 0142 0143 /// Close the socket 0144 void close(); 0145 0146 /// Reset the connection 0147 void reset(); 0148 0149 /// Update the RTT time 0150 void updateRTT(const Header *hdr, bt::Uint32 packet_rtt, bt::Uint32 packet_size) override; 0151 0152 /// Retransmit a packet 0153 void retransmit(PacketBuffer &packet, bt::Uint16 p_seq_nr) override; 0154 0155 /// Is all data sent 0156 bool allDataSent() const; 0157 0158 /// Get the current timeout 0159 bt::Uint32 currentTimeout() const override 0160 { 0161 return stats.timeout; 0162 } 0163 0164 typedef QSharedPointer<Connection> Ptr; 0165 typedef QWeakPointer<Connection> WPtr; 0166 0167 /// Set a weak pointer to self 0168 void setWeakPointer(WPtr ptr) 0169 { 0170 self = ptr; 0171 } 0172 0173 /// Check if we haven't hit a timeout yet 0174 void checkTimeout(const TimeValue &now); 0175 0176 private: 0177 void sendSYN(); 0178 void sendState(); 0179 void sendFIN(); 0180 void sendReset(); 0181 void updateDelayMeasurement(const Header *hdr); 0182 void sendStateOrData(); 0183 void sendPackets(); 0184 void sendPacket(bt::Uint32 type, bt::Uint16 p_ack_nr); 0185 void checkIfClosed(); 0186 void sendDataPacket(PacketBuffer &packet, bt::Uint16 seq_nr, const TimeValue &now); 0187 void startTimer(); 0188 void checkState(); 0189 bt::Uint32 extensionLength() const; 0190 void handleTimeout(); 0191 0192 private: 0193 Transmitter *transmitter; 0194 LocalWindow *local_wnd; 0195 RemoteWindow *remote_wnd; 0196 bt::CircularBuffer output_buffer; 0197 // bt::Timer timer; 0198 mutable QMutex mutex; 0199 QWaitCondition connected; 0200 QWaitCondition data_ready; 0201 Stats stats; 0202 bool fin_sent; 0203 TimeValue last_packet_sent; 0204 DelayWindow *delay_window; 0205 Connection::WPtr self; 0206 bool blocking; 0207 0208 friend class UTPServer; 0209 }; 0210 0211 /** 0212 Interface class for transmitting packets and notifying if a connection becomes readable or writeable 0213 */ 0214 class KTORRENT_EXPORT Transmitter 0215 { 0216 public: 0217 virtual ~Transmitter(); 0218 0219 /// Send a packet of a connection 0220 virtual bool sendTo(Connection::Ptr conn, const PacketBuffer &packet) = 0; 0221 0222 /// Connection has become readable, writeable or both 0223 virtual void stateChanged(Connection::Ptr conn, bool readable, bool writeable) = 0; 0224 0225 /// Called when the connection is closed 0226 virtual void closed(Connection::Ptr conn) = 0; 0227 }; 0228 0229 } 0230 0231 #endif // UTP_CONNECTION_H