• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,bool emit_local_for_anyaddress)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                          bool emit_local_for_anyaddress) {
39     UDPPort* port = new UDPPort(thread, factory, network, socket, username,
40                                 password, origin, emit_local_for_anyaddress);
41     if (!port->Init()) {
42       delete port;
43       port = NULL;
44     }
45     return port;
46   }
47 
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,const std::string & origin,bool emit_local_for_anyaddress)48   static UDPPort* Create(rtc::Thread* thread,
49                          rtc::PacketSocketFactory* factory,
50                          rtc::Network* network,
51                          const rtc::IPAddress& ip,
52                          uint16_t min_port,
53                          uint16_t max_port,
54                          const std::string& username,
55                          const std::string& password,
56                          const std::string& origin,
57                          bool emit_local_for_anyaddress) {
58     UDPPort* port =
59         new UDPPort(thread, factory, network, ip, min_port, max_port, username,
60                     password, origin, emit_local_for_anyaddress);
61     if (!port->Init()) {
62       delete port;
63       port = NULL;
64     }
65     return port;
66   }
67 
68   virtual ~UDPPort();
69 
GetLocalAddress()70   rtc::SocketAddress GetLocalAddress() const {
71     return socket_->GetLocalAddress();
72   }
73 
server_addresses()74   const ServerAddresses& server_addresses() const {
75     return server_addresses_;
76   }
77   void
set_server_addresses(const ServerAddresses & addresses)78   set_server_addresses(const ServerAddresses& addresses) {
79     server_addresses_ = addresses;
80   }
81 
82   virtual void PrepareAddress();
83 
84   virtual Connection* CreateConnection(const Candidate& address,
85                                        CandidateOrigin origin);
86   virtual int SetOption(rtc::Socket::Option opt, int value);
87   virtual int GetOption(rtc::Socket::Option opt, int* value);
88   virtual int GetError();
89 
HandleIncomingPacket(rtc::AsyncPacketSocket * socket,const char * data,size_t size,const rtc::SocketAddress & remote_addr,const rtc::PacketTime & packet_time)90   virtual bool HandleIncomingPacket(
91       rtc::AsyncPacketSocket* socket, const char* data, size_t size,
92       const rtc::SocketAddress& remote_addr,
93       const rtc::PacketTime& packet_time) {
94     // All packets given to UDP port will be consumed.
95     OnReadPacket(socket, data, size, remote_addr, packet_time);
96     return true;
97   }
SupportsProtocol(const std::string & protocol)98   virtual bool SupportsProtocol(const std::string& protocol) const {
99     return protocol == UDP_PROTOCOL_NAME;
100   }
101 
set_stun_keepalive_delay(int delay)102   void set_stun_keepalive_delay(int delay) {
103     stun_keepalive_delay_ = delay;
104   }
stun_keepalive_delay()105   int stun_keepalive_delay() const {
106     return stun_keepalive_delay_;
107   }
108 
109  protected:
110   UDPPort(rtc::Thread* thread,
111           rtc::PacketSocketFactory* factory,
112           rtc::Network* network,
113           const rtc::IPAddress& ip,
114           uint16_t min_port,
115           uint16_t max_port,
116           const std::string& username,
117           const std::string& password,
118           const std::string& origin,
119           bool emit_local_for_anyaddress);
120 
121   UDPPort(rtc::Thread* thread,
122           rtc::PacketSocketFactory* factory,
123           rtc::Network* network,
124           rtc::AsyncPacketSocket* socket,
125           const std::string& username,
126           const std::string& password,
127           const std::string& origin,
128           bool emit_local_for_anyaddress);
129 
130   bool Init();
131 
132   virtual int SendTo(const void* data, size_t size,
133                      const rtc::SocketAddress& addr,
134                      const rtc::PacketOptions& options,
135                      bool payload);
136 
137   void OnLocalAddressReady(rtc::AsyncPacketSocket* socket,
138                            const rtc::SocketAddress& address);
139   void OnReadPacket(rtc::AsyncPacketSocket* socket,
140                     const char* data, size_t size,
141                     const rtc::SocketAddress& remote_addr,
142                     const rtc::PacketTime& packet_time);
143 
144   void OnSentPacket(rtc::AsyncPacketSocket* socket,
145                     const rtc::SentPacket& sent_packet);
146 
147   void OnReadyToSend(rtc::AsyncPacketSocket* socket);
148 
149   // This method will send STUN binding request if STUN server address is set.
150   void MaybePrepareStunCandidate();
151 
152   void SendStunBindingRequests();
153 
154   // Helper function which will set |addr|'s IP to the default local address if
155   // |addr| is the "any" address and |emit_local_for_anyaddress_| is true. When
156   // returning false, it indicates that the operation has failed and the
157   // address shouldn't be used by any candidate.
158   bool MaybeSetDefaultLocalAddress(rtc::SocketAddress* addr) const;
159 
160  private:
161   // A helper class which can be called repeatedly to resolve multiple
162   // addresses, as opposed to rtc::AsyncResolverInterface, which can only
163   // resolve one address per instance.
164   class AddressResolver : public sigslot::has_slots<> {
165    public:
166     explicit AddressResolver(rtc::PacketSocketFactory* factory);
167     ~AddressResolver();
168 
169     void Resolve(const rtc::SocketAddress& address);
170     bool GetResolvedAddress(const rtc::SocketAddress& input,
171                             int family,
172                             rtc::SocketAddress* output) const;
173 
174     // The signal is sent when resolving the specified address is finished. The
175     // first argument is the input address, the second argument is the error
176     // or 0 if it succeeded.
177     sigslot::signal2<const rtc::SocketAddress&, int> SignalDone;
178 
179    private:
180     typedef std::map<rtc::SocketAddress,
181                      rtc::AsyncResolverInterface*> ResolverMap;
182 
183     void OnResolveResult(rtc::AsyncResolverInterface* resolver);
184 
185     rtc::PacketSocketFactory* socket_factory_;
186     ResolverMap resolvers_;
187   };
188 
189   // DNS resolution of the STUN server.
190   void ResolveStunAddress(const rtc::SocketAddress& stun_addr);
191   void OnResolveResult(const rtc::SocketAddress& input, int error);
192 
193   void SendStunBindingRequest(const rtc::SocketAddress& stun_addr);
194 
195   // Below methods handles binding request responses.
196   void OnStunBindingRequestSucceeded(
197       const rtc::SocketAddress& stun_server_addr,
198       const rtc::SocketAddress& stun_reflected_addr);
199   void OnStunBindingOrResolveRequestFailed(
200       const rtc::SocketAddress& stun_server_addr);
201 
202   // Sends STUN requests to the server.
203   void OnSendPacket(const void* data, size_t size, StunRequest* req);
204 
205   // TODO(mallinaht) - Move this up to cricket::Port when SignalAddressReady is
206   // changed to SignalPortReady.
207   void MaybeSetPortCompleteOrError();
208 
209   bool HasCandidateWithAddress(const rtc::SocketAddress& addr) const;
210 
211   ServerAddresses server_addresses_;
212   ServerAddresses bind_request_succeeded_servers_;
213   ServerAddresses bind_request_failed_servers_;
214   StunRequestManager requests_;
215   rtc::AsyncPacketSocket* socket_;
216   int error_;
217   rtc::scoped_ptr<AddressResolver> resolver_;
218   bool ready_;
219   int stun_keepalive_delay_;
220 
221   // This is true by default and false when
222   // PORTALLOCATOR_DISABLE_DEFAULT_LOCAL_CANDIDATE is specified.
223   bool emit_local_for_anyaddress_;
224 
225   friend class StunBindingRequest;
226 };
227 
228 class StunPort : public UDPPort {
229  public:
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,const ServerAddresses & servers,const std::string & origin)230   static StunPort* Create(rtc::Thread* thread,
231                           rtc::PacketSocketFactory* factory,
232                           rtc::Network* network,
233                           const rtc::IPAddress& ip,
234                           uint16_t min_port,
235                           uint16_t max_port,
236                           const std::string& username,
237                           const std::string& password,
238                           const ServerAddresses& servers,
239                           const std::string& origin) {
240     StunPort* port = new StunPort(thread, factory, network,
241                                   ip, min_port, max_port,
242                                   username, password, servers,
243                                   origin);
244     if (!port->Init()) {
245       delete port;
246       port = NULL;
247     }
248     return port;
249   }
250 
~StunPort()251   virtual ~StunPort() {}
252 
PrepareAddress()253   virtual void PrepareAddress() {
254     SendStunBindingRequests();
255   }
256 
257  protected:
StunPort(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,const ServerAddresses & servers,const std::string & origin)258   StunPort(rtc::Thread* thread,
259            rtc::PacketSocketFactory* factory,
260            rtc::Network* network,
261            const rtc::IPAddress& ip,
262            uint16_t min_port,
263            uint16_t max_port,
264            const std::string& username,
265            const std::string& password,
266            const ServerAddresses& servers,
267            const std::string& origin)
268       : UDPPort(thread,
269                 factory,
270                 network,
271                 ip,
272                 min_port,
273                 max_port,
274                 username,
275                 password,
276                 origin,
277                 false) {
278     // UDPPort will set these to local udp, updating these to STUN.
279     set_type(STUN_PORT_TYPE);
280     set_server_addresses(servers);
281   }
282 };
283 
284 }  // namespace cricket
285 
286 #endif  // WEBRTC_P2P_BASE_STUNPORT_H_
287