Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / p2p / base / stunport.h
1 /*
2  * libjingle
3  * Copyright 2004--2005, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #ifndef TALK_P2P_BASE_STUNPORT_H_
29 #define TALK_P2P_BASE_STUNPORT_H_
30
31 #include <string>
32
33 #include "talk/p2p/base/port.h"
34 #include "talk/p2p/base/stunrequest.h"
35 #include "webrtc/base/asyncpacketsocket.h"
36
37 // TODO(mallinath) - Rename stunport.cc|h to udpport.cc|h.
38 namespace rtc {
39 class AsyncResolver;
40 class SignalThread;
41 }
42
43 namespace cricket {
44
45 // Communicates using the address on the outside of a NAT.
46 class UDPPort : public Port {
47  public:
48   static UDPPort* Create(rtc::Thread* thread,
49                          rtc::PacketSocketFactory* factory,
50                          rtc::Network* network,
51                          rtc::AsyncPacketSocket* socket,
52                          const std::string& username,
53                          const std::string& password) {
54     UDPPort* port = new UDPPort(thread, factory, network, socket,
55                                 username, password);
56     if (!port->Init()) {
57       delete port;
58       port = NULL;
59     }
60     return port;
61   }
62
63   static UDPPort* Create(rtc::Thread* thread,
64                          rtc::PacketSocketFactory* factory,
65                          rtc::Network* network,
66                          const rtc::IPAddress& ip,
67                          int min_port, int max_port,
68                          const std::string& username,
69                          const std::string& password) {
70     UDPPort* port = new UDPPort(thread, factory, network,
71                                 ip, min_port, max_port,
72                                 username, password);
73     if (!port->Init()) {
74       delete port;
75       port = NULL;
76     }
77     return port;
78   }
79   virtual ~UDPPort();
80
81   rtc::SocketAddress GetLocalAddress() const {
82     return socket_->GetLocalAddress();
83   }
84
85   const ServerAddresses& server_addresses() const {
86     return server_addresses_;
87   }
88   void
89   set_server_addresses(const ServerAddresses& addresses) {
90     server_addresses_ = addresses;
91   }
92
93   virtual void PrepareAddress();
94
95   virtual Connection* CreateConnection(const Candidate& address,
96                                        CandidateOrigin origin);
97   virtual int SetOption(rtc::Socket::Option opt, int value);
98   virtual int GetOption(rtc::Socket::Option opt, int* value);
99   virtual int GetError();
100
101   virtual bool HandleIncomingPacket(
102       rtc::AsyncPacketSocket* socket, const char* data, size_t size,
103       const rtc::SocketAddress& remote_addr,
104       const rtc::PacketTime& packet_time) {
105     // All packets given to UDP port will be consumed.
106     OnReadPacket(socket, data, size, remote_addr, packet_time);
107     return true;
108   }
109
110   void set_stun_keepalive_delay(int delay) {
111     stun_keepalive_delay_ = delay;
112   }
113   int stun_keepalive_delay() const {
114     return stun_keepalive_delay_;
115   }
116
117  protected:
118   UDPPort(rtc::Thread* thread, rtc::PacketSocketFactory* factory,
119           rtc::Network* network, const rtc::IPAddress& ip,
120           int min_port, int max_port,
121           const std::string& username, const std::string& password);
122
123   UDPPort(rtc::Thread* thread, rtc::PacketSocketFactory* factory,
124           rtc::Network* network, rtc::AsyncPacketSocket* socket,
125           const std::string& username, const std::string& password);
126
127   bool Init();
128
129   virtual int SendTo(const void* data, size_t size,
130                      const rtc::SocketAddress& addr,
131                      const rtc::PacketOptions& options,
132                      bool payload);
133
134   void OnLocalAddressReady(rtc::AsyncPacketSocket* socket,
135                            const rtc::SocketAddress& address);
136   void OnReadPacket(rtc::AsyncPacketSocket* socket,
137                     const char* data, size_t size,
138                     const rtc::SocketAddress& remote_addr,
139                     const rtc::PacketTime& packet_time);
140
141   void OnReadyToSend(rtc::AsyncPacketSocket* socket);
142
143   // This method will send STUN binding request if STUN server address is set.
144   void MaybePrepareStunCandidate();
145
146   void SendStunBindingRequests();
147
148  private:
149   // A helper class which can be called repeatedly to resolve multiple
150   // addresses, as opposed to rtc::AsyncResolverInterface, which can only
151   // resolve one address per instance.
152   class AddressResolver : public sigslot::has_slots<> {
153    public:
154     explicit AddressResolver(rtc::PacketSocketFactory* factory);
155     ~AddressResolver();
156
157     void Resolve(const rtc::SocketAddress& address);
158     bool GetResolvedAddress(const rtc::SocketAddress& input,
159                             int family,
160                             rtc::SocketAddress* output) const;
161
162     // The signal is sent when resolving the specified address is finished. The
163     // first argument is the input address, the second argument is the error
164     // or 0 if it succeeded.
165     sigslot::signal2<const rtc::SocketAddress&, int> SignalDone;
166
167    private:
168     typedef std::map<rtc::SocketAddress,
169                      rtc::AsyncResolverInterface*> ResolverMap;
170
171     void OnResolveResult(rtc::AsyncResolverInterface* resolver);
172
173     rtc::PacketSocketFactory* socket_factory_;
174     ResolverMap resolvers_;
175   };
176
177   // DNS resolution of the STUN server.
178   void ResolveStunAddress(const rtc::SocketAddress& stun_addr);
179   void OnResolveResult(const rtc::SocketAddress& input, int error);
180
181   void SendStunBindingRequest(const rtc::SocketAddress& stun_addr);
182
183   // Below methods handles binding request responses.
184   void OnStunBindingRequestSucceeded(
185       const rtc::SocketAddress& stun_server_addr,
186       const rtc::SocketAddress& stun_reflected_addr);
187   void OnStunBindingOrResolveRequestFailed(
188       const rtc::SocketAddress& stun_server_addr);
189
190   // Sends STUN requests to the server.
191   void OnSendPacket(const void* data, size_t size, StunRequest* req);
192
193   // TODO(mallinaht) - Move this up to cricket::Port when SignalAddressReady is
194   // changed to SignalPortReady.
195   void MaybeSetPortCompleteOrError();
196
197   ServerAddresses server_addresses_;
198   ServerAddresses bind_request_succeeded_servers_;
199   ServerAddresses bind_request_failed_servers_;
200   StunRequestManager requests_;
201   rtc::AsyncPacketSocket* socket_;
202   int error_;
203   rtc::scoped_ptr<AddressResolver> resolver_;
204   bool ready_;
205   int stun_keepalive_delay_;
206
207   friend class StunBindingRequest;
208 };
209
210 class StunPort : public UDPPort {
211  public:
212   static StunPort* Create(
213       rtc::Thread* thread,
214       rtc::PacketSocketFactory* factory,
215       rtc::Network* network,
216       const rtc::IPAddress& ip,
217       int min_port, int max_port,
218       const std::string& username,
219       const std::string& password,
220       const ServerAddresses& servers) {
221     StunPort* port = new StunPort(thread, factory, network,
222                                   ip, min_port, max_port,
223                                   username, password, servers);
224     if (!port->Init()) {
225       delete port;
226       port = NULL;
227     }
228     return port;
229   }
230
231   virtual ~StunPort() {}
232
233   virtual void PrepareAddress() {
234     SendStunBindingRequests();
235   }
236
237  protected:
238   StunPort(rtc::Thread* thread, rtc::PacketSocketFactory* factory,
239            rtc::Network* network, const rtc::IPAddress& ip,
240            int min_port, int max_port,
241            const std::string& username, const std::string& password,
242            const ServerAddresses& servers)
243      : UDPPort(thread, factory, network, ip, min_port, max_port, username,
244                password) {
245     // UDPPort will set these to local udp, updating these to STUN.
246     set_type(STUN_PORT_TYPE);
247     set_server_addresses(servers);
248   }
249 };
250
251 }  // namespace cricket
252
253 #endif  // TALK_P2P_BASE_STUNPORT_H_