blob: 3b9e9be1cb9ed63801b7d6d02b70a8d9c6249de7 [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001/*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Steve Anton10542f22019-01-11 09:11:00 -080011#ifndef P2P_BASE_RELAY_SERVER_H_
12#define P2P_BASE_RELAY_SERVER_H_
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000013
14#include <map>
15#include <string>
16#include <vector>
17
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "p2p/base/port.h"
19#include "p2p/base/stun.h"
Steve Anton10542f22019-01-11 09:11:00 -080020#include "rtc_base/async_udp_socket.h"
Steve Anton6c38cc72017-11-29 10:25:58 -080021#include "rtc_base/random.h"
Steve Anton10542f22019-01-11 09:11:00 -080022#include "rtc_base/socket_address_pair.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080024#include "rtc_base/time_utils.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000025
26namespace cricket {
27
28class RelayServerBinding;
29class RelayServerConnection;
30
31// Relays traffic between connections to the server that are "bound" together.
32// All connections created with the same username/password are bound together.
Yves Gerey665174f2018-06-19 15:03:05 +020033class RelayServer : public rtc::MessageHandler, public sigslot::has_slots<> {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000034 public:
35 // Creates a server, which will use this thread to post messages to itself.
36 explicit RelayServer(rtc::Thread* thread);
Steve Antonf2737d22017-10-31 16:27:34 -070037 ~RelayServer() override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000038
39 rtc::Thread* thread() { return thread_; }
40
41 // Indicates whether we will print updates of the number of bindings.
42 bool log_bindings() const { return log_bindings_; }
43 void set_log_bindings(bool log_bindings) { log_bindings_ = log_bindings; }
44
45 // Updates the set of sockets that the server uses to talk to "internal"
46 // clients. These are clients that do the "port allocations".
47 void AddInternalSocket(rtc::AsyncPacketSocket* socket);
48 void RemoveInternalSocket(rtc::AsyncPacketSocket* socket);
49
50 // Updates the set of sockets that the server uses to talk to "external"
51 // clients. These are the clients that do not do allocations. They do not
52 // know that these addresses represent a relay server.
53 void AddExternalSocket(rtc::AsyncPacketSocket* socket);
54 void RemoveExternalSocket(rtc::AsyncPacketSocket* socket);
55
56 // Starts listening for connections on this sockets. When someone
57 // tries to connect, the connection will be accepted and a new
58 // internal socket will be added.
59 void AddInternalServerSocket(rtc::AsyncSocket* socket,
60 cricket::ProtocolType proto);
61
62 // Removes this server socket from the list.
63 void RemoveInternalServerSocket(rtc::AsyncSocket* socket);
64
65 // Methods for testing and debuging.
66 int GetConnectionCount() const;
67 rtc::SocketAddressPair GetConnection(int connection) const;
68 bool HasConnection(const rtc::SocketAddress& address) const;
69
70 private:
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000071 rtc::Thread* thread_;
Steve Anton6c38cc72017-11-29 10:25:58 -080072 webrtc::Random random_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000073 bool log_bindings_;
Steve Antonaabf2042018-10-09 16:37:43 -070074 std::vector<rtc::AsyncPacketSocket*> internal_sockets_;
75 std::vector<rtc::AsyncPacketSocket*> external_sockets_;
76 std::vector<rtc::AsyncPacketSocket*> removed_sockets_;
77 std::map<rtc::AsyncSocket*, cricket::ProtocolType> server_sockets_;
78 std::map<std::string, RelayServerBinding*> bindings_;
79 std::map<rtc::SocketAddressPair, RelayServerConnection*> connections_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000080
81 // Called when a packet is received by the server on one of its sockets.
82 void OnInternalPacket(rtc::AsyncPacketSocket* socket,
Yves Gerey665174f2018-06-19 15:03:05 +020083 const char* bytes,
84 size_t size,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000085 const rtc::SocketAddress& remote_addr,
Niels Möllere6933812018-11-05 13:01:41 +010086 const int64_t& packet_time_us);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000087 void OnExternalPacket(rtc::AsyncPacketSocket* socket,
Yves Gerey665174f2018-06-19 15:03:05 +020088 const char* bytes,
89 size_t size,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000090 const rtc::SocketAddress& remote_addr,
Niels Möllere6933812018-11-05 13:01:41 +010091 const int64_t& packet_time_us);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000092
93 void OnReadEvent(rtc::AsyncSocket* socket);
94
95 // Processes the relevant STUN request types from the client.
Yves Gerey665174f2018-06-19 15:03:05 +020096 bool HandleStun(const char* bytes,
97 size_t size,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000098 const rtc::SocketAddress& remote_addr,
99 rtc::AsyncPacketSocket* socket,
Yves Gerey665174f2018-06-19 15:03:05 +0200100 std::string* username,
101 StunMessage* msg);
102 void HandleStunAllocate(const char* bytes,
103 size_t size,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000104 const rtc::SocketAddressPair& ap,
105 rtc::AsyncPacketSocket* socket);
Yves Gerey665174f2018-06-19 15:03:05 +0200106 void HandleStun(RelayServerConnection* int_conn,
107 const char* bytes,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000108 size_t size);
109 void HandleStunAllocate(RelayServerConnection* int_conn,
110 const StunMessage& msg);
111 void HandleStunSend(RelayServerConnection* int_conn, const StunMessage& msg);
112
113 // Adds/Removes the a connection or binding.
114 void AddConnection(RelayServerConnection* conn);
115 void RemoveConnection(RelayServerConnection* conn);
116 void RemoveBinding(RelayServerBinding* binding);
117
johan27c3d5b2016-10-17 00:54:57 -0700118 // Handle messages in our thread.
Steve Antonf2737d22017-10-31 16:27:34 -0700119 void OnMessage(rtc::Message* pmsg) override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000120
121 // Called when the timer for checking lifetime times out.
122 void OnTimeout(RelayServerBinding* binding);
123
124 // Accept connections on this server socket.
125 void AcceptConnection(rtc::AsyncSocket* server_socket);
126
127 friend class RelayServerConnection;
128 friend class RelayServerBinding;
129};
130
131// Maintains information about a connection to the server. Each connection is
132// part of one and only one binding.
133class RelayServerConnection {
134 public:
135 RelayServerConnection(RelayServerBinding* binding,
136 const rtc::SocketAddressPair& addrs,
137 rtc::AsyncPacketSocket* socket);
138 ~RelayServerConnection();
139
140 RelayServerBinding* binding() { return binding_; }
141 rtc::AsyncPacketSocket* socket() { return socket_; }
142
143 // Returns a pair where the source is the remote address and the destination
144 // is the local address.
145 const rtc::SocketAddressPair& addr_pair() { return addr_pair_; }
146
147 // Sends a packet to the connected client. If an address is provided, then
148 // we make sure the internal client receives it, wrapping if necessary.
149 void Send(const char* data, size_t size);
Yves Gerey665174f2018-06-19 15:03:05 +0200150 void Send(const char* data, size_t size, const rtc::SocketAddress& ext_addr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000151
152 // Sends a STUN message to the connected client with no wrapping.
153 void SendStun(const StunMessage& msg);
154 void SendStunError(const StunMessage& request, int code, const char* desc);
155
156 // A locked connection is one for which we know the intended destination of
157 // any raw packet received.
158 bool locked() const { return locked_; }
159 void Lock();
160 void Unlock();
161
162 // Records the address that raw packets should be forwarded to (for internal
163 // packets only; for external, we already know where they go).
164 const rtc::SocketAddress& default_destination() const {
165 return default_dest_;
166 }
167 void set_default_destination(const rtc::SocketAddress& addr) {
168 default_dest_ = addr;
169 }
170
171 private:
172 RelayServerBinding* binding_;
173 rtc::SocketAddressPair addr_pair_;
174 rtc::AsyncPacketSocket* socket_;
175 bool locked_;
176 rtc::SocketAddress default_dest_;
177};
178
179// Records a set of internal and external connections that we relay between,
180// or in other words, that are "bound" together.
181class RelayServerBinding : public rtc::MessageHandler {
182 public:
Peter Boström0c4e06b2015-10-07 12:23:21 +0200183 RelayServerBinding(RelayServer* server,
184 const std::string& username,
185 const std::string& password,
honghaiz34b11eb2016-03-16 08:55:44 -0700186 int lifetime);
Steve Antonf2737d22017-10-31 16:27:34 -0700187 ~RelayServerBinding() override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000188
189 RelayServer* server() { return server_; }
honghaiz34b11eb2016-03-16 08:55:44 -0700190 int lifetime() { return lifetime_; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000191 const std::string& username() { return username_; }
192 const std::string& password() { return password_; }
193 const std::string& magic_cookie() { return magic_cookie_; }
194
195 // Adds/Removes a connection into the binding.
196 void AddInternalConnection(RelayServerConnection* conn);
197 void AddExternalConnection(RelayServerConnection* conn);
198
199 // We keep track of the use of each binding. If we detect that it was not
200 // used for longer than the lifetime, then we send a signal.
201 void NoteUsed();
202 sigslot::signal1<RelayServerBinding*> SignalTimeout;
203
204 // Determines whether the given packet has the magic cookie present (in the
205 // right place).
206 bool HasMagicCookie(const char* bytes, size_t size) const;
207
208 // Determines the connection to use to send packets to or from the given
209 // external address.
210 RelayServerConnection* GetInternalConnection(
211 const rtc::SocketAddress& ext_addr);
212 RelayServerConnection* GetExternalConnection(
213 const rtc::SocketAddress& ext_addr);
214
215 // MessageHandler:
Steve Antonf2737d22017-10-31 16:27:34 -0700216 void OnMessage(rtc::Message* pmsg) override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000217
218 private:
219 RelayServer* server_;
220
221 std::string username_;
222 std::string password_;
223 std::string magic_cookie_;
224
225 std::vector<RelayServerConnection*> internal_connections_;
226 std::vector<RelayServerConnection*> external_connections_;
227
honghaiz34b11eb2016-03-16 08:55:44 -0700228 int lifetime_;
229 int64_t last_used_;
Steve Anton6c38cc72017-11-29 10:25:58 -0800230 // TODO(?): bandwidth
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000231};
232
233} // namespace cricket
234
Steve Anton10542f22019-01-11 09:11:00 -0800235#endif // P2P_BASE_RELAY_SERVER_H_