udp_socket_client.cc 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // Copyright 2018 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 "components/mirroring/service/udp_socket_client.h"
  5. #include "base/bind.h"
  6. #include "base/callback.h"
  7. #include "net/base/address_family.h"
  8. #include "net/traffic_annotation/network_traffic_annotation.h"
  9. #include "services/network/public/mojom/network_context.mojom.h"
  10. namespace mirroring {
  11. namespace {
  12. // The minimal number of packets asking for receiving.
  13. constexpr int kNumPacketsAsking = 1024;
  14. net::NetworkTrafficAnnotationTag GetNetworkTrafficAnnotationTag() {
  15. return net::DefineNetworkTrafficAnnotation("cast_udp_socket", R"(
  16. semantics {
  17. sender: "Cast Streaming"
  18. description:
  19. "Media streaming protocol for LAN transport of screen mirroring "
  20. "audio/video. This is also used by browser features that wish to "
  21. "send browser content for remote display, and such features are "
  22. "generally started/stopped from the Media Router dialog."
  23. trigger:
  24. "User invokes feature from the Media Router dialog (right click on "
  25. "page, 'Cast...')."
  26. data:
  27. "Media and related protocol-level control and performance messages."
  28. destination: OTHER
  29. destination_other:
  30. "A playback receiver, such as a Chromecast device."
  31. }
  32. policy {
  33. cookies_allowed: NO
  34. setting: "This feature cannot be disabled in settings."
  35. chrome_policy {
  36. EnableMediaRouter {
  37. EnableMediaRouter: false
  38. }
  39. }
  40. })");
  41. }
  42. } // namespace
  43. UdpSocketClient::UdpSocketClient(const net::IPEndPoint& remote_endpoint,
  44. network::mojom::NetworkContext* context,
  45. base::OnceClosure error_callback)
  46. : remote_endpoint_(remote_endpoint),
  47. network_context_(context),
  48. error_callback_(std::move(error_callback)),
  49. bytes_sent_(0),
  50. allow_sending_(false),
  51. num_packets_pending_receive_(0) {
  52. DCHECK(network_context_);
  53. }
  54. UdpSocketClient::~UdpSocketClient() {}
  55. bool UdpSocketClient::SendPacket(media::cast::PacketRef packet,
  56. base::OnceClosure cb) {
  57. DVLOG(3) << __func__;
  58. DCHECK(resume_send_callback_.is_null());
  59. bytes_sent_ += packet->data.size();
  60. if (!allow_sending_) {
  61. resume_send_callback_ = std::move(cb);
  62. return false;
  63. }
  64. DCHECK(udp_socket_);
  65. udp_socket_->Send(
  66. packet->data,
  67. net::MutableNetworkTrafficAnnotationTag(GetNetworkTrafficAnnotationTag()),
  68. base::BindOnce(&UdpSocketClient::OnPacketSent,
  69. weak_factory_.GetWeakPtr()));
  70. return true;
  71. }
  72. void UdpSocketClient::OnPacketSent(int result) {
  73. if (result != net::OK)
  74. VLOG(2) << __func__ << ": error=" << result;
  75. // Block the further sending if too many send requests are pending.
  76. if (result == net::ERR_INSUFFICIENT_RESOURCES) {
  77. allow_sending_ = false;
  78. return;
  79. }
  80. allow_sending_ = true;
  81. if (!resume_send_callback_.is_null())
  82. std::move(resume_send_callback_).Run();
  83. }
  84. int64_t UdpSocketClient::GetBytesSent() {
  85. return bytes_sent_;
  86. }
  87. void UdpSocketClient::StartReceiving(
  88. media::cast::PacketReceiverCallbackWithStatus packet_receiver) {
  89. DVLOG(1) << __func__;
  90. packet_receiver_callback_ = std::move(packet_receiver);
  91. network_context_->CreateUDPSocket(udp_socket_.BindNewPipeAndPassReceiver(),
  92. receiver_.BindNewPipeAndPassRemote());
  93. network::mojom::UDPSocketOptionsPtr options;
  94. udp_socket_->Connect(remote_endpoint_, std::move(options),
  95. base::BindOnce(&UdpSocketClient::OnSocketConnected,
  96. weak_factory_.GetWeakPtr()));
  97. }
  98. void UdpSocketClient::OnSocketConnected(
  99. int result,
  100. const absl::optional<net::IPEndPoint>& addr) {
  101. DVLOG(2) << __func__ << ": result=" << result;
  102. if (result == net::OK) {
  103. allow_sending_ = true;
  104. if (!resume_send_callback_.is_null())
  105. std::move(resume_send_callback_).Run();
  106. } else {
  107. allow_sending_ = false;
  108. VLOG(1) << "Socket connect error=" << result;
  109. if (!error_callback_.is_null())
  110. std::move(error_callback_).Run();
  111. return;
  112. }
  113. if (!packet_receiver_callback_.is_null()) {
  114. udp_socket_->ReceiveMore(kNumPacketsAsking);
  115. num_packets_pending_receive_ = kNumPacketsAsking;
  116. }
  117. }
  118. void UdpSocketClient::StopReceiving() {
  119. packet_receiver_callback_.Reset();
  120. if (receiver_.is_bound())
  121. receiver_.reset();
  122. if (udp_socket_.is_bound())
  123. udp_socket_.reset();
  124. num_packets_pending_receive_ = 0;
  125. }
  126. void UdpSocketClient::OnReceived(
  127. int32_t result,
  128. const absl::optional<net::IPEndPoint>& src_addr,
  129. absl::optional<base::span<const uint8_t>> data) {
  130. DVLOG(3) << __func__ << ": result=" << result;
  131. DCHECK_GT(num_packets_pending_receive_, 0);
  132. DCHECK(!packet_receiver_callback_.is_null());
  133. --num_packets_pending_receive_;
  134. if (num_packets_pending_receive_ < kNumPacketsAsking) {
  135. udp_socket_->ReceiveMore(kNumPacketsAsking);
  136. num_packets_pending_receive_ += kNumPacketsAsking;
  137. }
  138. if (result != net::OK)
  139. return;
  140. std::unique_ptr<media::cast::Packet> packet(
  141. new media::cast::Packet(data->begin(), data->end()));
  142. packet_receiver_callback_.Run(std::move(packet));
  143. }
  144. } // namespace mirroring