3 * Copyright 2004--2005, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
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.
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.
28 #ifndef TALK_P2P_BASE_STUNPORT_H_
29 #define TALK_P2P_BASE_STUNPORT_H_
33 #include "talk/p2p/base/port.h"
34 #include "talk/p2p/base/stunrequest.h"
35 #include "webrtc/base/asyncpacketsocket.h"
37 // TODO(mallinath) - Rename stunport.cc|h to udpport.cc|h.
45 // Communicates using the address on the outside of a NAT.
46 class UDPPort : public Port {
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,
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,
81 rtc::SocketAddress GetLocalAddress() const {
82 return socket_->GetLocalAddress();
85 const ServerAddresses& server_addresses() const {
86 return server_addresses_;
89 set_server_addresses(const ServerAddresses& addresses) {
90 server_addresses_ = addresses;
93 virtual void PrepareAddress();
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();
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);
110 void set_stun_keepalive_delay(int delay) {
111 stun_keepalive_delay_ = delay;
113 int stun_keepalive_delay() const {
114 return stun_keepalive_delay_;
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);
123 UDPPort(rtc::Thread* thread, rtc::PacketSocketFactory* factory,
124 rtc::Network* network, rtc::AsyncPacketSocket* socket,
125 const std::string& username, const std::string& password);
129 virtual int SendTo(const void* data, size_t size,
130 const rtc::SocketAddress& addr,
131 const rtc::PacketOptions& options,
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);
141 void OnReadyToSend(rtc::AsyncPacketSocket* socket);
143 // This method will send STUN binding request if STUN server address is set.
144 void MaybePrepareStunCandidate();
146 void SendStunBindingRequests();
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<> {
154 explicit AddressResolver(rtc::PacketSocketFactory* factory);
157 void Resolve(const rtc::SocketAddress& address);
158 bool GetResolvedAddress(const rtc::SocketAddress& input,
160 rtc::SocketAddress* output) const;
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;
168 typedef std::map<rtc::SocketAddress,
169 rtc::AsyncResolverInterface*> ResolverMap;
171 void OnResolveResult(rtc::AsyncResolverInterface* resolver);
173 rtc::PacketSocketFactory* socket_factory_;
174 ResolverMap resolvers_;
177 // DNS resolution of the STUN server.
178 void ResolveStunAddress(const rtc::SocketAddress& stun_addr);
179 void OnResolveResult(const rtc::SocketAddress& input, int error);
181 void SendStunBindingRequest(const rtc::SocketAddress& stun_addr);
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);
190 // Sends STUN requests to the server.
191 void OnSendPacket(const void* data, size_t size, StunRequest* req);
193 // TODO(mallinaht) - Move this up to cricket::Port when SignalAddressReady is
194 // changed to SignalPortReady.
195 void MaybeSetPortCompleteOrError();
197 ServerAddresses server_addresses_;
198 ServerAddresses bind_request_succeeded_servers_;
199 ServerAddresses bind_request_failed_servers_;
200 StunRequestManager requests_;
201 rtc::AsyncPacketSocket* socket_;
203 rtc::scoped_ptr<AddressResolver> resolver_;
205 int stun_keepalive_delay_;
207 friend class StunBindingRequest;
210 class StunPort : public UDPPort {
212 static StunPort* Create(
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);
231 virtual ~StunPort() {}
233 virtual void PrepareAddress() {
234 SendStunBindingRequests();
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,
245 // UDPPort will set these to local udp, updating these to STUN.
246 set_type(STUN_PORT_TYPE);
247 set_server_addresses(servers);
251 } // namespace cricket
253 #endif // TALK_P2P_BASE_STUNPORT_H_