blob: c21e5b8769ee6dc66f5a3b724b37f8304e11026d [file] [log] [blame]
deadbeefd1c09982017-01-18 15:16:37 -08001/*
2 * Copyright 2016 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "p2p/base/udptransport.h"
deadbeefd1c09982017-01-18 15:16:37 -080012
13#include <string>
14#include <utility> // For std::move.
15
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "rtc_base/asyncpacketsocket.h"
17#include "rtc_base/asyncudpsocket.h"
18#include "rtc_base/logging.h"
Zhi Huang942bc2e2017-11-13 13:26:07 -080019#include "rtc_base/nethelper.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "rtc_base/socketaddress.h"
21#include "rtc_base/thread.h"
22#include "rtc_base/thread_checker.h"
deadbeefd1c09982017-01-18 15:16:37 -080023
24namespace cricket {
25
26UdpTransport::UdpTransport(const std::string& transport_name,
27 std::unique_ptr<rtc::AsyncPacketSocket> socket)
28 : transport_name_(transport_name), socket_(std::move(socket)) {
29 RTC_DCHECK(socket_);
30 socket_->SignalReadPacket.connect(this, &UdpTransport::OnSocketReadPacket);
31 socket_->SignalSentPacket.connect(this, &UdpTransport::OnSocketSentPacket);
32}
33
34UdpTransport::~UdpTransport() {
35 RTC_DCHECK_RUN_ON(&network_thread_checker_);
36}
37
38rtc::SocketAddress UdpTransport::GetLocalAddress() const {
39 RTC_DCHECK_RUN_ON(&network_thread_checker_);
40 return socket_->GetLocalAddress();
41}
42
43bool UdpTransport::SetRemoteAddress(const rtc::SocketAddress& addr) {
44 RTC_DCHECK_RUN_ON(&network_thread_checker_);
45 if (!addr.IsComplete()) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010046 RTC_LOG(LS_WARNING) << "Remote address not complete.";
deadbeefd1c09982017-01-18 15:16:37 -080047 return false;
48 }
49 // TODO(johan): check for ipv4, other settings.
50 bool prev_destination_nil = remote_address_.IsNil();
51 remote_address_ = addr;
52 // Going from "didn't have destination" to "have destination" or vice versa.
53 if (prev_destination_nil != remote_address_.IsNil()) {
54 SignalWritableState(this);
55 if (prev_destination_nil) {
56 SignalReadyToSend(this);
57 }
58 }
59 return true;
60}
61
62rtc::SocketAddress UdpTransport::GetRemoteAddress() const {
63 RTC_DCHECK_RUN_ON(&network_thread_checker_);
64 return remote_address_;
65}
66
Zhi Huang942bc2e2017-11-13 13:26:07 -080067const std::string& UdpTransport::transport_name() const {
Steve Anton33f69db2017-10-30 10:01:15 -070068 return transport_name_;
69}
70
71bool UdpTransport::receiving() const {
72 // TODO(johan): Implement method and signal.
73 return true;
74}
75
deadbeefd1c09982017-01-18 15:16:37 -080076bool UdpTransport::writable() const {
77 RTC_DCHECK_RUN_ON(&network_thread_checker_);
78 return !remote_address_.IsNil();
79}
80
81int UdpTransport::SendPacket(const char* data,
82 size_t len,
83 const rtc::PacketOptions& options,
84 int flags) {
85 // No thread_checker in high frequency network function.
86 if (remote_address_.IsNil()) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010087 RTC_LOG(LS_WARNING) << "Remote address not set.";
deadbeefd1c09982017-01-18 15:16:37 -080088 send_error_ = ENOTCONN;
89 return -1;
90 }
91 int result =
92 socket_->SendTo((const void*)data, len, remote_address_, options);
93 if (result <= 0) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010094 RTC_LOG(LS_VERBOSE) << "SendPacket() " << result;
deadbeefd1c09982017-01-18 15:16:37 -080095 }
96 return result;
97}
98
Danil Chapovalov00c71832018-06-15 15:58:38 +020099absl::optional<rtc::NetworkRoute> UdpTransport::network_route() const {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800100 rtc::NetworkRoute network_route;
101 network_route.packet_overhead =
102 /*kUdpOverhead=*/8 + GetIpOverhead(GetLocalAddress().family());
Danil Chapovalov00c71832018-06-15 15:58:38 +0200103 return absl::optional<rtc::NetworkRoute>(network_route);
Zhi Huang942bc2e2017-11-13 13:26:07 -0800104}
105
Steve Anton33f69db2017-10-30 10:01:15 -0700106int UdpTransport::SetOption(rtc::Socket::Option opt, int value) {
107 return 0;
108}
109
110int UdpTransport::GetError() {
111 return send_error_;
112}
113
114rtc::PacketTransportInternal* UdpTransport::GetInternal() {
115 return this;
116}
117
deadbeefd1c09982017-01-18 15:16:37 -0800118void UdpTransport::OnSocketReadPacket(rtc::AsyncPacketSocket* socket,
119 const char* data,
120 size_t len,
121 const rtc::SocketAddress& remote_addr,
122 const rtc::PacketTime& packet_time) {
123 // No thread_checker in high frequency network function.
124 SignalReadPacket(this, data, len, packet_time, 0);
125}
126
127void UdpTransport::OnSocketSentPacket(rtc::AsyncPacketSocket* socket,
128 const rtc::SentPacket& packet) {
129 RTC_DCHECK_EQ(socket_.get(), socket);
130 SignalSentPacket(this, packet);
131}
132
133} // namespace cricket