chromium_socket_factory.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "remoting/protocol/chromium_socket_factory.h"
  5. #include <stddef.h>
  6. #include <list>
  7. #include <memory>
  8. #include <string>
  9. #include "base/bind.h"
  10. #include "base/logging.h"
  11. #include "base/rand_util.h"
  12. #include "base/time/time.h"
  13. #include "components/webrtc/net_address_utils.h"
  14. #include "net/base/io_buffer.h"
  15. #include "net/base/ip_endpoint.h"
  16. #include "net/base/net_errors.h"
  17. #include "net/log/net_log_source.h"
  18. #include "net/socket/udp_server_socket.h"
  19. #include "remoting/base/logging.h"
  20. #include "remoting/base/session_options.h"
  21. #include "remoting/protocol/session_options_provider.h"
  22. #include "remoting/protocol/socket_util.h"
  23. #include "remoting/protocol/stream_packet_socket.h"
  24. #include "third_party/webrtc/media/base/rtp_utils.h"
  25. #include "third_party/webrtc/rtc_base/async_packet_socket.h"
  26. #include "third_party/webrtc/rtc_base/async_resolver.h"
  27. #include "third_party/webrtc/rtc_base/net_helpers.h"
  28. #include "third_party/webrtc/rtc_base/socket.h"
  29. namespace remoting {
  30. namespace protocol {
  31. namespace {
  32. // Size of the buffer to allocate for RecvFrom().
  33. const int kReceiveBufferSize = 65536;
  34. // Maximum amount of data in the send buffers. This is necessary to
  35. // prevent out-of-memory crashes if the caller sends data faster than
  36. // Pepper's UDP API can handle it. This maximum should never be
  37. // reached under normal conditions.
  38. const int kMaxSendBufferSize = 256 * 1024;
  39. // Creates a UDP socket and make it listen at |local_address| and |port|.
  40. // Returns nullptr if the socket fails to listen.
  41. std::unique_ptr<net::UDPServerSocket> CreateUdpSocketAndListen(
  42. const net::IPAddress& local_address,
  43. uint16_t port) {
  44. auto socket =
  45. std::make_unique<net::UDPServerSocket>(nullptr, net::NetLogSource());
  46. int result = socket->Listen(net::IPEndPoint(local_address, port));
  47. if (result != net::OK) {
  48. socket.reset();
  49. }
  50. return socket;
  51. }
  52. class UdpPacketSocket : public rtc::AsyncPacketSocket {
  53. public:
  54. UdpPacketSocket();
  55. UdpPacketSocket(const UdpPacketSocket&) = delete;
  56. UdpPacketSocket& operator=(const UdpPacketSocket&) = delete;
  57. ~UdpPacketSocket() override;
  58. bool Init(const rtc::SocketAddress& local_address,
  59. uint16_t min_port,
  60. uint16_t max_port);
  61. // rtc::AsyncPacketSocket interface.
  62. rtc::SocketAddress GetLocalAddress() const override;
  63. rtc::SocketAddress GetRemoteAddress() const override;
  64. int Send(const void* data,
  65. size_t data_size,
  66. const rtc::PacketOptions& options) override;
  67. int SendTo(const void* data,
  68. size_t data_size,
  69. const rtc::SocketAddress& address,
  70. const rtc::PacketOptions& options) override;
  71. int Close() override;
  72. State GetState() const override;
  73. int GetOption(rtc::Socket::Option option, int* value) override;
  74. int SetOption(rtc::Socket::Option option, int value) override;
  75. int GetError() const override;
  76. void SetError(int error) override;
  77. private:
  78. struct PendingPacket {
  79. PendingPacket(const void* buffer,
  80. int buffer_size,
  81. const net::IPEndPoint& address,
  82. const rtc::PacketOptions& options);
  83. scoped_refptr<net::IOBufferWithSize> data;
  84. net::IPEndPoint address;
  85. bool retried;
  86. rtc::PacketOptions options;
  87. };
  88. void OnBindCompleted(int error);
  89. void DoSend();
  90. void OnSendCompleted(int result);
  91. void DoRead();
  92. void OnReadCompleted(int result);
  93. void HandleReadResult(int result);
  94. std::unique_ptr<net::UDPServerSocket> socket_;
  95. State state_;
  96. int error_;
  97. rtc::SocketAddress local_address_;
  98. // Receive buffer and address are populated by asynchronous reads.
  99. scoped_refptr<net::IOBuffer> receive_buffer_;
  100. net::IPEndPoint receive_address_;
  101. bool send_pending_;
  102. std::list<PendingPacket> send_queue_;
  103. int send_queue_size_;
  104. };
  105. UdpPacketSocket::PendingPacket::PendingPacket(const void* buffer,
  106. int buffer_size,
  107. const net::IPEndPoint& address,
  108. const rtc::PacketOptions& options)
  109. : data(base::MakeRefCounted<net::IOBufferWithSize>(buffer_size)),
  110. address(address),
  111. retried(false),
  112. options(options) {
  113. memcpy(data->data(), buffer, buffer_size);
  114. }
  115. UdpPacketSocket::UdpPacketSocket()
  116. : state_(STATE_CLOSED),
  117. error_(0),
  118. send_pending_(false),
  119. send_queue_size_(0) {
  120. }
  121. UdpPacketSocket::~UdpPacketSocket() {
  122. Close();
  123. }
  124. bool UdpPacketSocket::Init(const rtc::SocketAddress& local_address,
  125. uint16_t min_port,
  126. uint16_t max_port) {
  127. DCHECK_LE(min_port, max_port);
  128. net::IPEndPoint local_endpoint;
  129. if (!webrtc::SocketAddressToIPEndPoint(local_address, &local_endpoint)) {
  130. return false;
  131. }
  132. if (min_port == 0 && max_port == 0) {
  133. // Just listen to any port that is available.
  134. socket_ = CreateUdpSocketAndListen(local_endpoint.address(), 0u);
  135. } else {
  136. // Randomly pick a port to start trying with so that we will less likely
  137. // pick the same port for relay. TURN server doesn't allow allocating relay
  138. // session from the same port until the old session is timed out.
  139. uint32_t port_count = max_port - min_port + 1;
  140. uint32_t starting_offset = base::RandGenerator(port_count);
  141. for (uint32_t i = 0; i < port_count; i++) {
  142. uint16_t port = static_cast<uint16_t>(
  143. min_port + ((starting_offset + i) % port_count));
  144. DCHECK_LE(min_port, port);
  145. DCHECK_LE(port, max_port);
  146. socket_ = CreateUdpSocketAndListen(local_endpoint.address(), port);
  147. if (socket_) {
  148. break;
  149. }
  150. }
  151. }
  152. if (!socket_.get()) {
  153. // Failed to bind the socket.
  154. return false;
  155. }
  156. if (socket_->GetLocalAddress(&local_endpoint) != net::OK ||
  157. !webrtc::IPEndPointToSocketAddress(local_endpoint, &local_address_)) {
  158. return false;
  159. }
  160. state_ = STATE_BOUND;
  161. DoRead();
  162. return true;
  163. }
  164. rtc::SocketAddress UdpPacketSocket::GetLocalAddress() const {
  165. DCHECK_EQ(state_, STATE_BOUND);
  166. return local_address_;
  167. }
  168. rtc::SocketAddress UdpPacketSocket::GetRemoteAddress() const {
  169. // UDP sockets are not connected - this method should never be called.
  170. NOTREACHED();
  171. return rtc::SocketAddress();
  172. }
  173. int UdpPacketSocket::Send(const void* data, size_t data_size,
  174. const rtc::PacketOptions& options) {
  175. // UDP sockets are not connected - this method should never be called.
  176. NOTREACHED();
  177. return EWOULDBLOCK;
  178. }
  179. int UdpPacketSocket::SendTo(const void* data, size_t data_size,
  180. const rtc::SocketAddress& address,
  181. const rtc::PacketOptions& options) {
  182. if (state_ != STATE_BOUND) {
  183. NOTREACHED();
  184. return EINVAL;
  185. }
  186. if (error_ != 0) {
  187. return error_;
  188. }
  189. net::IPEndPoint endpoint;
  190. if (!webrtc::SocketAddressToIPEndPoint(address, &endpoint)) {
  191. return EINVAL;
  192. }
  193. if (send_queue_size_ >= kMaxSendBufferSize) {
  194. return EWOULDBLOCK;
  195. }
  196. PendingPacket packet(data, data_size, endpoint, options);
  197. send_queue_.push_back(packet);
  198. send_queue_size_ += data_size;
  199. DoSend();
  200. return data_size;
  201. }
  202. int UdpPacketSocket::Close() {
  203. state_ = STATE_CLOSED;
  204. socket_.reset();
  205. return 0;
  206. }
  207. rtc::AsyncPacketSocket::State UdpPacketSocket::GetState() const {
  208. return state_;
  209. }
  210. int UdpPacketSocket::GetOption(rtc::Socket::Option option, int* value) {
  211. // This method is never called by libjingle.
  212. NOTIMPLEMENTED();
  213. return -1;
  214. }
  215. int UdpPacketSocket::SetOption(rtc::Socket::Option option, int value) {
  216. if (state_ != STATE_BOUND) {
  217. NOTREACHED();
  218. return EINVAL;
  219. }
  220. switch (option) {
  221. case rtc::Socket::OPT_DONTFRAGMENT:
  222. NOTIMPLEMENTED();
  223. return -1;
  224. case rtc::Socket::OPT_RCVBUF: {
  225. int net_error = socket_->SetReceiveBufferSize(value);
  226. return (net_error == net::OK) ? 0 : -1;
  227. }
  228. case rtc::Socket::OPT_SNDBUF: {
  229. int net_error = socket_->SetSendBufferSize(value);
  230. return (net_error == net::OK) ? 0 : -1;
  231. }
  232. case rtc::Socket::OPT_NODELAY:
  233. // OPT_NODELAY is only for TCP sockets.
  234. NOTREACHED();
  235. return -1;
  236. case rtc::Socket::OPT_IPV6_V6ONLY:
  237. NOTIMPLEMENTED();
  238. return -1;
  239. case rtc::Socket::OPT_DSCP:
  240. NOTIMPLEMENTED();
  241. return -1;
  242. case rtc::Socket::OPT_RTP_SENDTIME_EXTN_ID:
  243. NOTIMPLEMENTED();
  244. return -1;
  245. }
  246. NOTREACHED();
  247. return -1;
  248. }
  249. int UdpPacketSocket::GetError() const {
  250. return error_;
  251. }
  252. void UdpPacketSocket::SetError(int error) {
  253. error_ = error;
  254. }
  255. void UdpPacketSocket::DoSend() {
  256. if (send_pending_ || send_queue_.empty())
  257. return;
  258. PendingPacket& packet = send_queue_.front();
  259. cricket::ApplyPacketOptions(
  260. reinterpret_cast<uint8_t*>(packet.data->data()), packet.data->size(),
  261. packet.options.packet_time_params,
  262. (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds());
  263. int result =
  264. socket_->SendTo(packet.data.get(), packet.data->size(), packet.address,
  265. base::BindOnce(&UdpPacketSocket::OnSendCompleted,
  266. base::Unretained(this)));
  267. if (result == net::ERR_IO_PENDING) {
  268. send_pending_ = true;
  269. } else {
  270. OnSendCompleted(result);
  271. }
  272. }
  273. void UdpPacketSocket::OnSendCompleted(int result) {
  274. send_pending_ = false;
  275. if (result < 0) {
  276. SocketErrorAction action = GetSocketErrorAction(result);
  277. switch (action) {
  278. case SOCKET_ERROR_ACTION_FAIL:
  279. LOG(ERROR) << "Send failed on a UDP socket: " << result;
  280. error_ = EINVAL;
  281. return;
  282. case SOCKET_ERROR_ACTION_RETRY:
  283. // Retry resending only once.
  284. if (!send_queue_.front().retried) {
  285. send_queue_.front().retried = true;
  286. DoSend();
  287. return;
  288. }
  289. break;
  290. case SOCKET_ERROR_ACTION_IGNORE:
  291. break;
  292. }
  293. }
  294. // Don't need to worry about partial sends because this is a datagram
  295. // socket.
  296. send_queue_size_ -= send_queue_.front().data->size();
  297. SignalSentPacket(this, rtc::SentPacket(send_queue_.front().options.packet_id,
  298. rtc::TimeMillis()));
  299. send_queue_.pop_front();
  300. DoSend();
  301. }
  302. void UdpPacketSocket::DoRead() {
  303. int result = 0;
  304. while (result >= 0) {
  305. receive_buffer_ = base::MakeRefCounted<net::IOBuffer>(kReceiveBufferSize);
  306. result = socket_->RecvFrom(receive_buffer_.get(), kReceiveBufferSize,
  307. &receive_address_,
  308. base::BindOnce(&UdpPacketSocket::OnReadCompleted,
  309. base::Unretained(this)));
  310. HandleReadResult(result);
  311. }
  312. }
  313. void UdpPacketSocket::OnReadCompleted(int result) {
  314. HandleReadResult(result);
  315. if (result >= 0) {
  316. DoRead();
  317. }
  318. }
  319. void UdpPacketSocket::HandleReadResult(int result) {
  320. if (result == net::ERR_IO_PENDING) {
  321. return;
  322. }
  323. if (result > 0) {
  324. rtc::SocketAddress address;
  325. if (!webrtc::IPEndPointToSocketAddress(receive_address_, &address)) {
  326. NOTREACHED();
  327. LOG(ERROR) << "Failed to convert address received from RecvFrom().";
  328. return;
  329. }
  330. SignalReadPacket(this, receive_buffer_->data(), result, address,
  331. rtc::TimeMicros());
  332. } else {
  333. LOG(ERROR) << "Received error when reading from UDP socket: " << result;
  334. }
  335. }
  336. } // namespace
  337. ChromiumPacketSocketFactory::ChromiumPacketSocketFactory(
  338. base::WeakPtr<SessionOptionsProvider> session_options_provider)
  339. : session_options_provider_(session_options_provider) {}
  340. ChromiumPacketSocketFactory::~ChromiumPacketSocketFactory() = default;
  341. rtc::AsyncPacketSocket* ChromiumPacketSocketFactory::CreateUdpSocket(
  342. const rtc::SocketAddress& local_address,
  343. uint16_t min_port,
  344. uint16_t max_port) {
  345. if (session_options_provider_ &&
  346. session_options_provider_->session_options().GetBoolValue(
  347. "Disable-UDP")) {
  348. HOST_LOG
  349. << "Disable-UDP experiment is enabled. UDP socket won't be created.";
  350. return nullptr;
  351. }
  352. std::unique_ptr<UdpPacketSocket> result(new UdpPacketSocket());
  353. if (!result->Init(local_address, min_port, max_port))
  354. return nullptr;
  355. return result.release();
  356. }
  357. rtc::AsyncListenSocket* ChromiumPacketSocketFactory::CreateServerTcpSocket(
  358. const rtc::SocketAddress& local_address,
  359. uint16_t min_port,
  360. uint16_t max_port,
  361. int opts) {
  362. // TCP sockets are not supported.
  363. // TODO(yuweih): Implement server side TCP support crbug.com/600032 .
  364. NOTIMPLEMENTED();
  365. return nullptr;
  366. }
  367. rtc::AsyncPacketSocket* ChromiumPacketSocketFactory::CreateClientTcpSocket(
  368. const rtc::SocketAddress& local_address,
  369. const rtc::SocketAddress& remote_address,
  370. const rtc::ProxyInfo& proxy_info,
  371. const std::string& user_agent,
  372. const rtc::PacketSocketTcpOptions& opts) {
  373. if (session_options_provider_ &&
  374. session_options_provider_->session_options().GetBoolValue(
  375. "Disable-TCP")) {
  376. HOST_LOG << "Disable-TCP experiment is enabled. Client TCP socket won't be "
  377. << "created.";
  378. return nullptr;
  379. }
  380. auto socket = std::make_unique<StreamPacketSocket>();
  381. if (!socket->InitClientTcp(local_address, remote_address, proxy_info,
  382. user_agent, opts)) {
  383. return nullptr;
  384. }
  385. return socket.release();
  386. }
  387. rtc::AsyncResolverInterface*
  388. ChromiumPacketSocketFactory::CreateAsyncResolver() {
  389. return new rtc::AsyncResolver();
  390. }
  391. } // namespace protocol
  392. } // namespace remoting