1 /*
2 * Copyright 2011 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 #include "p2p/base/basic_packet_socket_factory.h"
12
13 #include <stddef.h>
14
15 #include <string>
16
17 #include "absl/memory/memory.h"
18 #include "api/async_dns_resolver.h"
19 #include "api/wrapping_async_dns_resolver.h"
20 #include "p2p/base/async_stun_tcp_socket.h"
21 #include "rtc_base/async_tcp_socket.h"
22 #include "rtc_base/async_udp_socket.h"
23 #include "rtc_base/checks.h"
24 #include "rtc_base/logging.h"
25 #include "rtc_base/socket.h"
26 #include "rtc_base/socket_adapters.h"
27 #include "rtc_base/ssl_adapter.h"
28
29 namespace rtc {
30
BasicPacketSocketFactory(SocketFactory * socket_factory)31 BasicPacketSocketFactory::BasicPacketSocketFactory(
32 SocketFactory* socket_factory)
33 : socket_factory_(socket_factory) {}
34
~BasicPacketSocketFactory()35 BasicPacketSocketFactory::~BasicPacketSocketFactory() {}
36
CreateUdpSocket(const SocketAddress & address,uint16_t min_port,uint16_t max_port)37 AsyncPacketSocket* BasicPacketSocketFactory::CreateUdpSocket(
38 const SocketAddress& address,
39 uint16_t min_port,
40 uint16_t max_port) {
41 // UDP sockets are simple.
42 Socket* socket = socket_factory_->CreateSocket(address.family(), SOCK_DGRAM);
43 if (!socket) {
44 return NULL;
45 }
46 if (BindSocket(socket, address, min_port, max_port) < 0) {
47 RTC_LOG(LS_ERROR) << "UDP bind failed with error " << socket->GetError();
48 delete socket;
49 return NULL;
50 }
51 return new AsyncUDPSocket(socket);
52 }
53
CreateServerTcpSocket(const SocketAddress & local_address,uint16_t min_port,uint16_t max_port,int opts)54 AsyncListenSocket* BasicPacketSocketFactory::CreateServerTcpSocket(
55 const SocketAddress& local_address,
56 uint16_t min_port,
57 uint16_t max_port,
58 int opts) {
59 // Fail if TLS is required.
60 if (opts & PacketSocketFactory::OPT_TLS) {
61 RTC_LOG(LS_ERROR) << "TLS support currently is not available.";
62 return NULL;
63 }
64
65 if (opts & PacketSocketFactory::OPT_TLS_FAKE) {
66 RTC_LOG(LS_ERROR) << "Fake TLS not supported.";
67 return NULL;
68 }
69 Socket* socket =
70 socket_factory_->CreateSocket(local_address.family(), SOCK_STREAM);
71 if (!socket) {
72 return NULL;
73 }
74
75 if (BindSocket(socket, local_address, min_port, max_port) < 0) {
76 RTC_LOG(LS_ERROR) << "TCP bind failed with error " << socket->GetError();
77 delete socket;
78 return NULL;
79 }
80
81 RTC_CHECK(!(opts & PacketSocketFactory::OPT_STUN));
82
83 return new AsyncTcpListenSocket(absl::WrapUnique(socket));
84 }
85
CreateClientTcpSocket(const SocketAddress & local_address,const SocketAddress & remote_address,const ProxyInfo & proxy_info,const std::string & user_agent,const PacketSocketTcpOptions & tcp_options)86 AsyncPacketSocket* BasicPacketSocketFactory::CreateClientTcpSocket(
87 const SocketAddress& local_address,
88 const SocketAddress& remote_address,
89 const ProxyInfo& proxy_info,
90 const std::string& user_agent,
91 const PacketSocketTcpOptions& tcp_options) {
92 Socket* socket =
93 socket_factory_->CreateSocket(local_address.family(), SOCK_STREAM);
94 if (!socket) {
95 return NULL;
96 }
97
98 if (BindSocket(socket, local_address, 0, 0) < 0) {
99 // Allow BindSocket to fail if we're binding to the ANY address, since this
100 // is mostly redundant in the first place. The socket will be bound when we
101 // call Connect() instead.
102 if (local_address.IsAnyIP()) {
103 RTC_LOG(LS_WARNING) << "TCP bind failed with error " << socket->GetError()
104 << "; ignoring since socket is using 'any' address.";
105 } else {
106 RTC_LOG(LS_ERROR) << "TCP bind failed with error " << socket->GetError();
107 delete socket;
108 return NULL;
109 }
110 }
111
112 // Set TCP_NODELAY (via OPT_NODELAY) for improved performance; this causes
113 // small media packets to be sent immediately rather than being buffered up,
114 // reducing latency.
115 //
116 // Must be done before calling Connect, otherwise it may fail.
117 if (socket->SetOption(Socket::OPT_NODELAY, 1) != 0) {
118 RTC_LOG(LS_ERROR) << "Setting TCP_NODELAY option failed with error "
119 << socket->GetError();
120 }
121
122 // If using a proxy, wrap the socket in a proxy socket.
123 if (proxy_info.type == PROXY_SOCKS5) {
124 socket = new AsyncSocksProxySocket(
125 socket, proxy_info.address, proxy_info.username, proxy_info.password);
126 } else if (proxy_info.type == PROXY_HTTPS) {
127 socket =
128 new AsyncHttpsProxySocket(socket, user_agent, proxy_info.address,
129 proxy_info.username, proxy_info.password);
130 }
131
132 // Assert that at most one TLS option is used.
133 int tlsOpts = tcp_options.opts & (PacketSocketFactory::OPT_TLS |
134 PacketSocketFactory::OPT_TLS_FAKE |
135 PacketSocketFactory::OPT_TLS_INSECURE);
136 RTC_DCHECK((tlsOpts & (tlsOpts - 1)) == 0);
137
138 if ((tlsOpts & PacketSocketFactory::OPT_TLS) ||
139 (tlsOpts & PacketSocketFactory::OPT_TLS_INSECURE)) {
140 // Using TLS, wrap the socket in an SSL adapter.
141 SSLAdapter* ssl_adapter = SSLAdapter::Create(socket);
142 if (!ssl_adapter) {
143 return NULL;
144 }
145
146 if (tlsOpts & PacketSocketFactory::OPT_TLS_INSECURE) {
147 ssl_adapter->SetIgnoreBadCert(true);
148 }
149
150 ssl_adapter->SetAlpnProtocols(tcp_options.tls_alpn_protocols);
151 ssl_adapter->SetEllipticCurves(tcp_options.tls_elliptic_curves);
152 ssl_adapter->SetCertVerifier(tcp_options.tls_cert_verifier);
153
154 socket = ssl_adapter;
155
156 if (ssl_adapter->StartSSL(remote_address.hostname().c_str()) != 0) {
157 delete ssl_adapter;
158 return NULL;
159 }
160
161 } else if (tlsOpts & PacketSocketFactory::OPT_TLS_FAKE) {
162 // Using fake TLS, wrap the TCP socket in a pseudo-SSL socket.
163 socket = new AsyncSSLSocket(socket);
164 }
165
166 if (socket->Connect(remote_address) < 0) {
167 RTC_LOG(LS_ERROR) << "TCP connect failed with error " << socket->GetError();
168 delete socket;
169 return NULL;
170 }
171
172 // Finally, wrap that socket in a TCP or STUN TCP packet socket.
173 AsyncPacketSocket* tcp_socket;
174 if (tcp_options.opts & PacketSocketFactory::OPT_STUN) {
175 tcp_socket = new cricket::AsyncStunTCPSocket(socket);
176 } else {
177 tcp_socket = new AsyncTCPSocket(socket);
178 }
179
180 return tcp_socket;
181 }
182
CreateAsyncResolver()183 AsyncResolverInterface* BasicPacketSocketFactory::CreateAsyncResolver() {
184 return new AsyncResolver();
185 }
186
187 std::unique_ptr<webrtc::AsyncDnsResolverInterface>
CreateAsyncDnsResolver()188 BasicPacketSocketFactory::CreateAsyncDnsResolver() {
189 return std::make_unique<webrtc::WrappingAsyncDnsResolver>(
190 new AsyncResolver());
191 }
192
BindSocket(Socket * socket,const SocketAddress & local_address,uint16_t min_port,uint16_t max_port)193 int BasicPacketSocketFactory::BindSocket(Socket* socket,
194 const SocketAddress& local_address,
195 uint16_t min_port,
196 uint16_t max_port) {
197 int ret = -1;
198 if (min_port == 0 && max_port == 0) {
199 // If there's no port range, let the OS pick a port for us.
200 ret = socket->Bind(local_address);
201 } else {
202 // Otherwise, try to find a port in the provided range.
203 for (int port = min_port; ret < 0 && port <= max_port; ++port) {
204 ret = socket->Bind(SocketAddress(local_address.ipaddr(), port));
205 }
206 }
207 return ret;
208 }
209
210 } // namespace rtc
211