1 /*
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_RELAYPORT_H_
12 #define WEBRTC_P2P_BASE_RELAYPORT_H_
13 
14 #include <deque>
15 #include <string>
16 #include <utility>
17 #include <vector>
18 
19 #include "webrtc/p2p/base/port.h"
20 #include "webrtc/p2p/base/stunrequest.h"
21 
22 namespace cricket {
23 
24 class RelayEntry;
25 class RelayConnection;
26 
27 // Communicates using an allocated port on the relay server. For each
28 // remote candidate that we try to send data to a RelayEntry instance
29 // is created. The RelayEntry will try to reach the remote destination
30 // by connecting to all available server addresses in a pre defined
31 // order with a small delay in between. When a connection is
32 // successful all other connection attempts are aborted.
33 class RelayPort : public Port {
34  public:
35   typedef std::pair<rtc::Socket::Option, int> OptionValue;
36 
37   // RelayPort doesn't yet do anything fancy in the ctor.
Create(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,const rtc::IPAddress & ip,uint16_t min_port,uint16_t max_port,const std::string & username,const std::string & password)38   static RelayPort* Create(rtc::Thread* thread,
39                            rtc::PacketSocketFactory* factory,
40                            rtc::Network* network,
41                            const rtc::IPAddress& ip,
42                            uint16_t min_port,
43                            uint16_t max_port,
44                            const std::string& username,
45                            const std::string& password) {
46     return new RelayPort(thread, factory, network, ip, min_port, max_port,
47                          username, password);
48   }
49   ~RelayPort() override;
50 
51   void AddServerAddress(const ProtocolAddress& addr);
52   void AddExternalAddress(const ProtocolAddress& addr);
53 
options()54   const std::vector<OptionValue>& options() const { return options_; }
55   bool HasMagicCookie(const char* data, size_t size);
56 
57   void PrepareAddress() override;
58   Connection* CreateConnection(const Candidate& address,
59                                CandidateOrigin origin) override;
60   int SetOption(rtc::Socket::Option opt, int value) override;
61   int GetOption(rtc::Socket::Option opt, int* value) override;
62   int GetError() override;
SupportsProtocol(const std::string & protocol)63   bool SupportsProtocol(const std::string& protocol) const override {
64     // Relay port may create both TCP and UDP connections.
65     return true;
66   }
67 
68   const ProtocolAddress * ServerAddress(size_t index) const;
IsReady()69   bool IsReady() { return ready_; }
70 
GetProtocol()71   ProtocolType GetProtocol() const override {
72     // We shouldn't be using RelayPort, but we need to provide an
73     // implementation here.
74     return PROTO_UDP;
75   }
76 
77   // Used for testing.
78   sigslot::signal1<const ProtocolAddress*> SignalConnectFailure;
79   sigslot::signal1<const ProtocolAddress*> SignalSoftTimeout;
80 
81  protected:
82   RelayPort(rtc::Thread* thread,
83             rtc::PacketSocketFactory* factory,
84             rtc::Network*,
85             const rtc::IPAddress& ip,
86             uint16_t min_port,
87             uint16_t max_port,
88             const std::string& username,
89             const std::string& password);
90   bool Init();
91 
92   void SetReady();
93 
94   int SendTo(const void* data,
95              size_t size,
96              const rtc::SocketAddress& addr,
97              const rtc::PacketOptions& options,
98              bool payload) override;
99 
100   // Dispatches the given packet to the port or connection as appropriate.
101   void OnReadPacket(const char* data, size_t size,
102                     const rtc::SocketAddress& remote_addr,
103                     ProtocolType proto,
104                     const rtc::PacketTime& packet_time);
105 
106   // The OnSentPacket callback is left empty here since they are handled by
107   // RelayEntry.
OnSentPacket(rtc::AsyncPacketSocket * socket,const rtc::SentPacket & sent_packet)108   void OnSentPacket(rtc::AsyncPacketSocket* socket,
109                     const rtc::SentPacket& sent_packet) override {}
110 
111  private:
112   friend class RelayEntry;
113 
114   std::deque<ProtocolAddress> server_addr_;
115   std::vector<ProtocolAddress> external_addr_;
116   bool ready_;
117   std::vector<RelayEntry*> entries_;
118   std::vector<OptionValue> options_;
119   int error_;
120 };
121 
122 }  // namespace cricket
123 
124 #endif  // WEBRTC_P2P_BASE_RELAYPORT_H_
125