Overte C++ Documentation
Connection.h
1 //
2 // Connection.h
3 // libraries/networking/src/udt
4 //
5 // Created by Clement on 7/27/15.
6 // Copyright 2015 High Fidelity, Inc.
7 // Copyright 2021 Vircadia contributors.
8 //
9 // Distributed under the Apache License, Version 2.0.
10 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
11 //
12 
13 #ifndef hifi_Connection_h
14 #define hifi_Connection_h
15 
16 #include <list>
17 #include <memory>
18 
19 #include <QtCore/QObject>
20 
21 #include <PortableHighResolutionClock.h>
22 
23 #include "ConnectionStats.h"
24 #include "Constants.h"
25 #include "LossList.h"
26 #include "SendQueue.h"
27 #include "../SockAddr.h"
28 
29 namespace udt {
30 
31 class CongestionControl;
32 class ControlPacket;
33 class Packet;
34 class PacketList;
35 class Socket;
36 
37 class PendingReceivedMessage {
38 public:
39  void enqueuePacket(std::unique_ptr<Packet> packet);
40  bool hasAvailablePackets() const;
41  std::unique_ptr<Packet> removeNextPacket();
42 
43  std::list<std::unique_ptr<Packet>> _packets;
44 
45 private:
46  Packet::MessagePartNumber _nextPartNumber = 0;
47 };
48 
49 class Connection : public QObject {
50  Q_OBJECT
51 public:
52  using ControlPacketPointer = std::unique_ptr<ControlPacket>;
53 
54  Connection(Socket* parentSocket, SockAddr destination, std::unique_ptr<CongestionControl> congestionControl);
55  virtual ~Connection();
56 
57  void sendReliablePacket(std::unique_ptr<Packet> packet);
58  void sendReliablePacketList(std::unique_ptr<PacketList> packet);
59 
60  void sync(); // rate control method, fired by Socket for all connections on SYN interval
61 
62  // return indicates if this packet should be processed
63  bool processReceivedSequenceNumber(SequenceNumber sequenceNumber, int packetSize, int payloadSize);
64  void processControl(ControlPacketPointer controlPacket);
65 
66  void queueReceivedMessagePacket(std::unique_ptr<Packet> packet);
67 
68  ConnectionStats::Stats sampleStats() { return _stats.sample(); }
69 
70  SockAddr getDestination() const { return _destination; }
71 
72  void setMaxBandwidth(int maxBandwidth);
73 
74  void sendHandshakeRequest();
75  bool hasReceivedHandshake() const { return _hasReceivedHandshake; }
76 
77  void recordSentUnreliablePackets(int wireSize, int payloadSize);
78  void recordReceivedUnreliablePackets(int wireSize, int payloadSize);
79  void setDestinationAddress(const SockAddr& destination);
80 
81 signals:
82  void packetSent();
83  void receiverHandshakeRequestComplete(const SockAddr& sockAddr);
84  void destinationAddressChange(SockAddr currentAddress);
85 
86 private slots:
87  void recordSentPackets(int wireSize, int payloadSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint);
88  void recordRetransmission(int wireSize, int payloadSize, SequenceNumber sequenceNumber, p_high_resolution_clock::time_point timePoint);
89 
90  void queueInactive();
91  void queueTimeout();
92 
93 private:
94  void sendACK();
95 
96  void processACK(ControlPacketPointer controlPacket);
97  void processHandshake(ControlPacketPointer controlPacket);
98  void processHandshakeACK(ControlPacketPointer controlPacket);
99 
100  void resetReceiveState();
101 
102  SendQueue& getSendQueue();
103  SequenceNumber nextACK() const;
104 
105  void updateCongestionControlAndSendQueue(std::function<void()> congestionCallback);
106 
107  void stopSendQueue();
108 
109  bool _hasReceivedHandshake { false }; // flag for receipt of handshake from server
110  bool _hasReceivedHandshakeACK { false }; // flag for receipt of handshake ACK from client
111  bool _didRequestHandshake { false }; // flag for request of handshake from server
112 
113  SequenceNumber _initialSequenceNumber; // Randomized on Connection creation, identifies connection during re-connect requests
114  SequenceNumber _initialReceiveSequenceNumber; // Randomized by peer Connection on creation, identifies connection during re-connect requests
115 
116  MessageNumber _lastMessageNumber { 0 };
117 
118  LossList _lossList; // List of all missing packets
119  SequenceNumber _lastReceivedSequenceNumber; // The largest sequence number received from the peer
120  SequenceNumber _lastReceivedACK; // The last ACK received
121 
122  Socket* _parentSocket { nullptr };
123  SockAddr _destination;
124 
125  std::unique_ptr<CongestionControl> _congestionControl;
126 
127  std::unique_ptr<SendQueue> _sendQueue;
128 
129  std::map<MessageNumber, PendingReceivedMessage> _pendingReceivedMessages;
130 
131  // Re-used control packets
132  ControlPacketPointer _ackPacket;
133  ControlPacketPointer _handshakeACK;
134 
135  ConnectionStats _stats;
136 };
137 
138 }
139 
140 #endif // hifi_Connection_h