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