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_STUNPORT_H_
12 #define WEBRTC_P2P_BASE_STUNPORT_H_
13 
14 #include <string>
15 
16 #include "webrtc/p2p/base/port.h"
17 #include "webrtc/p2p/base/stunrequest.h"
18 #include "webrtc/base/asyncpacketsocket.h"
19 
20 // TODO(mallinath) - Rename stunport.cc|h to udpport.cc|h.
21 namespace rtc {
22 class AsyncResolver;
23 class SignalThread;
24 }
25 
26 namespace cricket {
27 
28 // Communicates using the address on the outside of a NAT.
29 class UDPPort : public Port {
30  public:
Create(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,rtc::AsyncPacketSocket * socket,const std::string & username,const std::string & password,const std::string & origin)31   static UDPPort* Create(rtc::Thread* thread,
32                          rtc::PacketSocketFactory* factory,
33                          rtc::Network* network,
34                          rtc::AsyncPacketSocket* socket,
35                          const std::string& username,
36                          const std::string& password,
37                          const std::string& origin) {
38     UDPPort* port = new UDPPort(thread, factory, network, socket,
39                                 username, password, origin);
40     if (!port->Init()) {
41       delete port;
42       port = NULL;
43     }
44     return port;
45   }
46 
Create(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,const rtc::IPAddress & ip,uint16 min_port,uint16 max_port,const std::string & username,const std::string & password,const std::string & origin)47   static UDPPort* Create(rtc::Thread* thread,
48                          rtc::PacketSocketFactory* factory,
49                          rtc::Network* network,
50                          const rtc::IPAddress& ip,
51                          uint16 min_port,
52                          uint16 max_port,
53                          const std::string& username,
54                          const std::string& password,
55                          const std::string& origin) {
56     UDPPort* port = new UDPPort(thread, factory, network,
57                                 ip, min_port, max_port,
58                                 username, password, origin);
59     if (!port->Init()) {
60       delete port;
61       port = NULL;
62     }
63     return port;
64   }
65 
66   virtual ~UDPPort();
67 
GetLocalAddress()68   rtc::SocketAddress GetLocalAddress() const {
69     return socket_->GetLocalAddress();
70   }
71 
server_addresses()72   const ServerAddresses& server_addresses() const {
73     return server_addresses_;
74   }
75   void
set_server_addresses(const ServerAddresses & addresses)76   set_server_addresses(const ServerAddresses& addresses) {
77     server_addresses_ = addresses;
78   }
79 
80   virtual void PrepareAddress();
81 
82   virtual Connection* CreateConnection(const Candidate& address,
83                                        CandidateOrigin origin);
84   virtual int SetOption(rtc::Socket::Option opt, int value);
85   virtual int GetOption(rtc::Socket::Option opt, int* value);
86   virtual int GetError();
87 
HandleIncomingPacket(rtc::AsyncPacketSocket * socket,const char * data,size_t size,const rtc::SocketAddress & remote_addr,const rtc::PacketTime & packet_time)88   virtual bool HandleIncomingPacket(
89       rtc::AsyncPacketSocket* socket, const char* data, size_t size,
90       const rtc::SocketAddress& remote_addr,
91       const rtc::PacketTime& packet_time) {
92     // All packets given to UDP port will be consumed.
93     OnReadPacket(socket, data, size, remote_addr, packet_time);
94     return true;
95   }
96 
set_stun_keepalive_delay(int delay)97   void set_stun_keepalive_delay(int delay) {
98     stun_keepalive_delay_ = delay;
99   }
stun_keepalive_delay()100   int stun_keepalive_delay() const {
101     return stun_keepalive_delay_;
102   }
103 
104  protected:
105   UDPPort(rtc::Thread* thread,
106           rtc::PacketSocketFactory* factory,
107           rtc::Network* network,
108           const rtc::IPAddress& ip,
109           uint16 min_port,
110           uint16 max_port,
111           const std::string& username,
112           const std::string& password,
113           const std::string& origin);
114 
115   UDPPort(rtc::Thread* thread,
116           rtc::PacketSocketFactory* factory,
117           rtc::Network* network,
118           rtc::AsyncPacketSocket* socket,
119           const std::string& username,
120           const std::string& password,
121           const std::string& origin);
122 
123   bool Init();
124 
125   virtual int SendTo(const void* data, size_t size,
126                      const rtc::SocketAddress& addr,
127                      const rtc::PacketOptions& options,
128                      bool payload);
129 
130   void OnLocalAddressReady(rtc::AsyncPacketSocket* socket,
131                            const rtc::SocketAddress& address);
132   void OnReadPacket(rtc::AsyncPacketSocket* socket,
133                     const char* data, size_t size,
134                     const rtc::SocketAddress& remote_addr,
135                     const rtc::PacketTime& packet_time);
136 
137   void OnReadyToSend(rtc::AsyncPacketSocket* socket);
138 
139   // This method will send STUN binding request if STUN server address is set.
140   void MaybePrepareStunCandidate();
141 
142   void SendStunBindingRequests();
143 
144  private:
145   // A helper class which can be called repeatedly to resolve multiple
146   // addresses, as opposed to rtc::AsyncResolverInterface, which can only
147   // resolve one address per instance.
148   class AddressResolver : public sigslot::has_slots<> {
149    public:
150     explicit AddressResolver(rtc::PacketSocketFactory* factory);
151     ~AddressResolver();
152 
153     void Resolve(const rtc::SocketAddress& address);
154     bool GetResolvedAddress(const rtc::SocketAddress& input,
155                             int family,
156                             rtc::SocketAddress* output) const;
157 
158     // The signal is sent when resolving the specified address is finished. The
159     // first argument is the input address, the second argument is the error
160     // or 0 if it succeeded.
161     sigslot::signal2<const rtc::SocketAddress&, int> SignalDone;
162 
163    private:
164     typedef std::map<rtc::SocketAddress,
165                      rtc::AsyncResolverInterface*> ResolverMap;
166 
167     void OnResolveResult(rtc::AsyncResolverInterface* resolver);
168 
169     rtc::PacketSocketFactory* socket_factory_;
170     ResolverMap resolvers_;
171   };
172 
173   // DNS resolution of the STUN server.
174   void ResolveStunAddress(const rtc::SocketAddress& stun_addr);
175   void OnResolveResult(const rtc::SocketAddress& input, int error);
176 
177   void SendStunBindingRequest(const rtc::SocketAddress& stun_addr);
178 
179   // Below methods handles binding request responses.
180   void OnStunBindingRequestSucceeded(
181       const rtc::SocketAddress& stun_server_addr,
182       const rtc::SocketAddress& stun_reflected_addr);
183   void OnStunBindingOrResolveRequestFailed(
184       const rtc::SocketAddress& stun_server_addr);
185 
186   // Sends STUN requests to the server.
187   void OnSendPacket(const void* data, size_t size, StunRequest* req);
188 
189   // TODO(mallinaht) - Move this up to cricket::Port when SignalAddressReady is
190   // changed to SignalPortReady.
191   void MaybeSetPortCompleteOrError();
192 
193   bool HasCandidateWithAddress(const rtc::SocketAddress& addr) const;
194 
195   ServerAddresses server_addresses_;
196   ServerAddresses bind_request_succeeded_servers_;
197   ServerAddresses bind_request_failed_servers_;
198   StunRequestManager requests_;
199   rtc::AsyncPacketSocket* socket_;
200   int error_;
201   rtc::scoped_ptr<AddressResolver> resolver_;
202   bool ready_;
203   int stun_keepalive_delay_;
204 
205   friend class StunBindingRequest;
206 };
207 
208 class StunPort : public UDPPort {
209  public:
Create(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,const rtc::IPAddress & ip,uint16 min_port,uint16 max_port,const std::string & username,const std::string & password,const ServerAddresses & servers,const std::string & origin)210   static StunPort* Create(rtc::Thread* thread,
211                           rtc::PacketSocketFactory* factory,
212                           rtc::Network* network,
213                           const rtc::IPAddress& ip,
214                           uint16 min_port, uint16 max_port,
215                           const std::string& username,
216                           const std::string& password,
217                           const ServerAddresses& servers,
218                           const std::string& origin) {
219     StunPort* port = new StunPort(thread, factory, network,
220                                   ip, min_port, max_port,
221                                   username, password, servers,
222                                   origin);
223     if (!port->Init()) {
224       delete port;
225       port = NULL;
226     }
227     return port;
228   }
229 
~StunPort()230   virtual ~StunPort() {}
231 
PrepareAddress()232   virtual void PrepareAddress() {
233     SendStunBindingRequests();
234   }
235 
236  protected:
StunPort(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,const rtc::IPAddress & ip,uint16 min_port,uint16 max_port,const std::string & username,const std::string & password,const ServerAddresses & servers,const std::string & origin)237   StunPort(rtc::Thread* thread,
238            rtc::PacketSocketFactory* factory,
239            rtc::Network* network,
240            const rtc::IPAddress& ip,
241            uint16 min_port,
242            uint16 max_port,
243            const std::string& username,
244            const std::string& password,
245            const ServerAddresses& servers,
246            const std::string& origin)
247      : UDPPort(thread, factory, network, ip, min_port, max_port, username,
248                password, origin) {
249     // UDPPort will set these to local udp, updating these to STUN.
250     set_type(STUN_PORT_TYPE);
251     set_server_addresses(servers);
252   }
253 };
254 
255 }  // namespace cricket
256 
257 #endif  // WEBRTC_P2P_BASE_STUNPORT_H_
258