blob: 7ee71d9f21693b0365644f2f6dc11034573e47d8 [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
11#ifndef WEBRTC_P2P_BASE_RELAYSERVER_H_
12#define WEBRTC_P2P_BASE_RELAYSERVER_H_
13
14#include <map>
15#include <string>
16#include <vector>
17
18#include "webrtc/p2p/base/port.h"
19#include "webrtc/p2p/base/stun.h"
20#include "webrtc/base/asyncudpsocket.h"
21#include "webrtc/base/socketaddresspair.h"
22#include "webrtc/base/thread.h"
23#include "webrtc/base/timeutils.h"
24
25namespace cricket {
26
27class RelayServerBinding;
28class RelayServerConnection;
29
30// Relays traffic between connections to the server that are "bound" together.
31// All connections created with the same username/password are bound together.
32class RelayServer : public rtc::MessageHandler,
33 public sigslot::has_slots<> {
34 public:
35 // Creates a server, which will use this thread to post messages to itself.
36 explicit RelayServer(rtc::Thread* thread);
37 ~RelayServer();
38
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:
71 typedef std::vector<rtc::AsyncPacketSocket*> SocketList;
72 typedef std::map<rtc::AsyncSocket*,
73 cricket::ProtocolType> ServerSocketMap;
74 typedef std::map<std::string, RelayServerBinding*> BindingMap;
75 typedef std::map<rtc::SocketAddressPair,
76 RelayServerConnection*> ConnectionMap;
77
78 rtc::Thread* thread_;
79 bool log_bindings_;
80 SocketList internal_sockets_;
81 SocketList external_sockets_;
82 SocketList removed_sockets_;
83 ServerSocketMap server_sockets_;
84 BindingMap bindings_;
85 ConnectionMap connections_;
86
87 // Called when a packet is received by the server on one of its sockets.
88 void OnInternalPacket(rtc::AsyncPacketSocket* socket,
89 const char* bytes, size_t size,
90 const rtc::SocketAddress& remote_addr,
91 const rtc::PacketTime& packet_time);
92 void OnExternalPacket(rtc::AsyncPacketSocket* socket,
93 const char* bytes, size_t size,
94 const rtc::SocketAddress& remote_addr,
95 const rtc::PacketTime& packet_time);
96
97 void OnReadEvent(rtc::AsyncSocket* socket);
98
99 // Processes the relevant STUN request types from the client.
100 bool HandleStun(const char* bytes, size_t size,
101 const rtc::SocketAddress& remote_addr,
102 rtc::AsyncPacketSocket* socket,
103 std::string* username, StunMessage* msg);
104 void HandleStunAllocate(const char* bytes, size_t size,
105 const rtc::SocketAddressPair& ap,
106 rtc::AsyncPacketSocket* socket);
107 void HandleStun(RelayServerConnection* int_conn, const char* bytes,
108 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
118 // Handle messages in our worker thread.
119 void OnMessage(rtc::Message *pmsg);
120
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);
150 void Send(const char* data, size_t size,
151 const rtc::SocketAddress& ext_addr);
152
153 // Sends a STUN message to the connected client with no wrapping.
154 void SendStun(const StunMessage& msg);
155 void SendStunError(const StunMessage& request, int code, const char* desc);
156
157 // A locked connection is one for which we know the intended destination of
158 // any raw packet received.
159 bool locked() const { return locked_; }
160 void Lock();
161 void Unlock();
162
163 // Records the address that raw packets should be forwarded to (for internal
164 // packets only; for external, we already know where they go).
165 const rtc::SocketAddress& default_destination() const {
166 return default_dest_;
167 }
168 void set_default_destination(const rtc::SocketAddress& addr) {
169 default_dest_ = addr;
170 }
171
172 private:
173 RelayServerBinding* binding_;
174 rtc::SocketAddressPair addr_pair_;
175 rtc::AsyncPacketSocket* socket_;
176 bool locked_;
177 rtc::SocketAddress default_dest_;
178};
179
180// Records a set of internal and external connections that we relay between,
181// or in other words, that are "bound" together.
182class RelayServerBinding : public rtc::MessageHandler {
183 public:
Peter Boström0c4e06b2015-10-07 12:23:21 +0200184 RelayServerBinding(RelayServer* server,
185 const std::string& username,
186 const std::string& password,
honghaiz34b11eb2016-03-16 08:55:44 -0700187 int lifetime);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000188 virtual ~RelayServerBinding();
189
190 RelayServer* server() { return server_; }
honghaiz34b11eb2016-03-16 08:55:44 -0700191 int lifetime() { return lifetime_; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000192 const std::string& username() { return username_; }
193 const std::string& password() { return password_; }
194 const std::string& magic_cookie() { return magic_cookie_; }
195
196 // Adds/Removes a connection into the binding.
197 void AddInternalConnection(RelayServerConnection* conn);
198 void AddExternalConnection(RelayServerConnection* conn);
199
200 // We keep track of the use of each binding. If we detect that it was not
201 // used for longer than the lifetime, then we send a signal.
202 void NoteUsed();
203 sigslot::signal1<RelayServerBinding*> SignalTimeout;
204
205 // Determines whether the given packet has the magic cookie present (in the
206 // right place).
207 bool HasMagicCookie(const char* bytes, size_t size) const;
208
209 // Determines the connection to use to send packets to or from the given
210 // external address.
211 RelayServerConnection* GetInternalConnection(
212 const rtc::SocketAddress& ext_addr);
213 RelayServerConnection* GetExternalConnection(
214 const rtc::SocketAddress& ext_addr);
215
216 // MessageHandler:
217 void OnMessage(rtc::Message *pmsg);
218
219 private:
220 RelayServer* server_;
221
222 std::string username_;
223 std::string password_;
224 std::string magic_cookie_;
225
226 std::vector<RelayServerConnection*> internal_connections_;
227 std::vector<RelayServerConnection*> external_connections_;
228
honghaiz34b11eb2016-03-16 08:55:44 -0700229 int lifetime_;
230 int64_t last_used_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000231 // TODO: bandwidth
232};
233
234} // namespace cricket
235
236#endif // WEBRTC_P2P_BASE_RELAYSERVER_H_