Overte C++ Documentation
Socket.h
1 //
2 // Socket.h
3 // libraries/networking/src/udt
4 //
5 // Created by Stephen Birarda on 2015-07-20.
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 #pragma once
14 
15 #ifndef hifi_Socket_h
16 #define hifi_Socket_h
17 
18 #include <functional>
19 #include <unordered_map>
20 #include <mutex>
21 #include <list>
22 
23 #include <QtCore/QObject>
24 #include <QtCore/QTimer>
25 
26 #include "../SockAddr.h"
27 #include "TCPVegasCC.h"
28 #include "Connection.h"
29 #include "NetworkSocket.h"
30 
31 //#define UDT_CONNECTION_DEBUG
32 
33 class UDTTest;
34 
35 namespace udt {
36 
37 class BasePacket;
38 class Packet;
39 class PacketList;
40 class SequenceNumber;
41 
42 using PacketFilterOperator = std::function<bool(const Packet&)>;
43 using ConnectionCreationFilterOperator = std::function<bool(const SockAddr&)>;
44 
45 using BasePacketHandler = std::function<void(std::unique_ptr<BasePacket>)>;
46 using PacketHandler = std::function<void(std::unique_ptr<Packet>)>;
47 using MessageHandler = std::function<void(std::unique_ptr<Packet>)>;
48 using MessageFailureHandler = std::function<void(SockAddr, udt::Packet::MessageNumber)>;
49 
50 class Socket : public QObject {
51  Q_OBJECT
52 
53  using Mutex = std::mutex;
54  using Lock = std::unique_lock<Mutex>;
55 
56 public:
57  using StatsVector = std::vector<std::pair<SockAddr, ConnectionStats::Stats>>;
58 
59  Socket(QObject* object = 0, bool shouldChangeSocketOptions = true);
60 
61  quint16 localPort(SocketType socketType) const { return _networkSocket.localPort(socketType); }
62 
63  // Simple functions writing to the socket with no processing
64  qint64 writeBasePacket(const BasePacket& packet, const SockAddr& sockAddr);
65  qint64 writePacket(const Packet& packet, const SockAddr& sockAddr);
66  qint64 writePacket(std::unique_ptr<Packet> packet, const SockAddr& sockAddr);
67  qint64 writePacketList(std::unique_ptr<PacketList> packetList, const SockAddr& sockAddr);
68  qint64 writeDatagram(const char* data, qint64 size, const SockAddr& sockAddr);
69  qint64 writeDatagram(const QByteArray& datagram, const SockAddr& sockAddr);
70 
71  void bind(SocketType socketType, const QHostAddress& address, quint16 port = 0);
72  void rebind(SocketType socketType, quint16 port);
73  void rebind(SocketType socketType);
74 
75  void setPacketFilterOperator(PacketFilterOperator filterOperator) { _packetFilterOperator = filterOperator; }
76  void setPacketHandler(PacketHandler handler) { _packetHandler = handler; }
77  void setMessageHandler(MessageHandler handler) { _messageHandler = handler; }
78  void setMessageFailureHandler(MessageFailureHandler handler) { _messageFailureHandler = handler; }
79  void setConnectionCreationFilterOperator(ConnectionCreationFilterOperator filterOperator)
80  { _connectionCreationFilterOperator = filterOperator; }
81 
82  void addUnfilteredHandler(const SockAddr& senderSockAddr, BasePacketHandler handler)
83  { _unfilteredHandlers[senderSockAddr] = handler; }
84 
85  void setCongestionControlFactory(std::unique_ptr<CongestionControlVirtualFactory> ccFactory);
86  void setConnectionMaxBandwidth(int maxBandwidth);
87 
88  void messageReceived(std::unique_ptr<Packet> packet);
89  void messageFailed(Connection* connection, Packet::MessageNumber messageNumber);
90 
91  StatsVector sampleStatsForAllConnections();
92 
93 #if defined(WEBRTC_DATA_CHANNELS)
94  const WebRTCSocket* getWebRTCSocket();
95 #endif
96 
97 #if (PR_BUILD || DEV_BUILD)
98  void sendFakedHandshakeRequest(const SockAddr& sockAddr);
99 #endif
100 
101 signals:
102  void clientHandshakeRequestComplete(const SockAddr& sockAddr);
103 
104 public slots:
105  void cleanupConnection(SockAddr sockAddr);
106  void clearConnections();
107  void handleRemoteAddressChange(SockAddr previousAddress, SockAddr currentAddress);
108 
109 private slots:
110  void readPendingDatagrams();
111  void checkForReadyReadBackup();
112 
113  void handleSocketError(SocketType socketType, QAbstractSocket::SocketError socketError);
114  void handleStateChanged(SocketType socketType, QAbstractSocket::SocketState socketState);
115 
116 private:
117  void setSystemBufferSizes(SocketType socketType);
118  Connection* findOrCreateConnection(const SockAddr& sockAddr, bool filterCreation = false);
119 
120  // privatized methods used by UDTTest - they are private since they must be called on the Socket thread
121  ConnectionStats::Stats sampleStatsForConnection(const SockAddr& destination);
122 
123  std::vector<SockAddr> getConnectionSockAddrs();
124  void connectToSendSignal(const SockAddr& destinationAddr, QObject* receiver, const char* slot);
125 
126  Q_INVOKABLE void writeReliablePacket(Packet* packet, const SockAddr& sockAddr);
127  Q_INVOKABLE void writeReliablePacketList(PacketList* packetList, const SockAddr& sockAddr);
128 
129  NetworkSocket _networkSocket;
130  PacketFilterOperator _packetFilterOperator;
131  PacketHandler _packetHandler;
132  MessageHandler _messageHandler;
133  MessageFailureHandler _messageFailureHandler;
134  ConnectionCreationFilterOperator _connectionCreationFilterOperator;
135 
136  Mutex _unreliableSequenceNumbersMutex;
137  Mutex _connectionsHashMutex;
138 
139  std::unordered_map<SockAddr, BasePacketHandler> _unfilteredHandlers;
140  std::unordered_map<SockAddr, SequenceNumber> _unreliableSequenceNumbers;
141  std::unordered_map<SockAddr, std::unique_ptr<Connection>> _connectionsHash;
142 
143  QTimer* _readyReadBackupTimer { nullptr };
144 
145  int _maxBandwidth { -1 };
146 
147  std::unique_ptr<CongestionControlVirtualFactory> _ccFactory { new CongestionControlFactory<TCPVegasCC>() };
148 
149  bool _shouldChangeSocketOptions { true };
150 
151  int _lastPacketSizeRead { 0 };
152  SequenceNumber _lastReceivedSequenceNumber;
153  SockAddr _lastPacketSockAddr;
154 
155  friend UDTTest;
156 };
157 
158 } // namespace udt
159 
160 #endif // hifi_Socket_h
Multiplexes a QUdpSocket and a WebRTCSocket so that they appear as a single QUdpSocket-style socket.
Definition: NetworkSocket.h:29
Provides a QUdpSocket-style interface for using WebRTCDataChannels.
Definition: WebRTCSocket.h:31
SocketType
The types of network socket.
Definition: SocketType.h:22