Index: webrtc/p2p/rawudp/rawudptransportchannel.cc |
diff --git a/webrtc/p2p/rawudp/rawudptransportchannel.cc b/webrtc/p2p/rawudp/rawudptransportchannel.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..681762aff729954024da249007d5b58988e2f755 |
--- /dev/null |
+++ b/webrtc/p2p/rawudp/rawudptransportchannel.cc |
@@ -0,0 +1,204 @@ |
+/* |
+ * Copyright 2016 The WebRTC project authors. All Rights Reserved. |
+ * |
+ * Use of this source code is governed by a BSD-style license |
+ * that can be found in the LICENSE file in the root of the source |
+ * tree. An additional intellectual property rights grant can be found |
+ * in the file PATENTS. All contributing project authors may |
+ * be found in the AUTHORS file in the root of the source tree. |
+ */ |
+ |
+#include "webrtc/p2p/rawudp/rawudptransportchannel.h" |
+ |
+#include <string> |
+ |
+#include "webrtc/base/asyncudpsocket.h" |
+#include "webrtc/base/logging.h" |
+#include "webrtc/base/physicalsocketserver.h" |
+#include "webrtc/base/socketaddress.h" |
+#include "webrtc/base/thread.h" |
+#include "webrtc/base/thread_checker.h" |
+ |
+namespace cricket { |
+ |
+RawUdpTransportChannel::RawUdpTransportChannel( |
+ const std::string& transport_name, |
+ int component) |
+ : RawUdpTransportChannel(transport_name, |
+ component, |
+ rtc::Thread::Current()->socketserver()) { |
+ RTC_DCHECK_RUN_ON(&network_thread_checker_); |
Taylor Brandstetter
2016/10/07 18:24:03
The constructor is where the thread checker is ini
johan
2016/10/11 13:36:09
You have a point here.
|
+} |
+ |
+RawUdpTransportChannel::RawUdpTransportChannel( |
+ const std::string& transport_name, |
+ int component, |
+ rtc::SocketServer* socket_server) |
+ : TransportChannelImpl(transport_name, component), |
+ tch_state_(STATE_INIT), |
+ gathering_state_(kIceGatheringNew) { |
Taylor Brandstetter
2016/10/07 18:24:03
Can initialize these to default values in the head
johan
2016/10/11 13:36:09
Done.
|
+ socket_server_ = socket_server; |
Taylor Brandstetter
2016/10/07 18:24:03
Can set socket_server_ in initializer list.
johan
2016/10/11 13:36:09
Acknowledged.
|
+ RTC_DCHECK_RUN_ON(&network_thread_checker_); |
+} |
+ |
+RawUdpTransportChannel::~RawUdpTransportChannel() { |
+ RTC_DCHECK_RUN_ON(&network_thread_checker_); |
+} |
+ |
+void RawUdpTransportChannel::OnSocketReadPacket( |
+ rtc::AsyncPacketSocket* socket, |
+ const char* data, |
+ size_t len, |
+ const rtc::SocketAddress& remote_addr, |
+ const rtc::PacketTime& packet_time, |
+ bool is_rtcp) { |
+ // No thread_checker in high frequency network function. |
+ // Serialisation of processing RTP and RTCP socket is implicit done by event |
+ // loop. |
pthatcher1
2016/10/07 17:36:36
I don't think this is comment is needed, nor is an
Taylor Brandstetter
2016/10/07 18:24:03
I see the value of these checks. But since they're
johan
2016/10/11 13:36:09
FYI: similar checks are present in some methods of
|
+ SignalReadPacket(this, data, len, packet_time, 0); |
+} |
+ |
+void RawUdpTransportChannel::OnRtpSocketReadPacket( |
+ rtc::AsyncPacketSocket* socket, |
+ const char* data, |
+ size_t len, |
+ const rtc::SocketAddress& remote_addr, |
+ const rtc::PacketTime& packet_time) { |
+ // No thread_checker in high frequency network function. |
+ // TODO(johan) check, if remote_addr is valid and legit. |
+ OnSocketReadPacket(socket, data, len, remote_addr, packet_time, |
+ false /*rtcp*/); |
+} |
+ |
+void RawUdpTransportChannel::OnRtcpSocketReadPacket( |
+ rtc::AsyncPacketSocket* socket, |
+ const char* data, |
+ size_t len, |
+ const rtc::SocketAddress& remote_addr, |
+ const rtc::PacketTime& packet_time) { |
+ // No thread_checker in high frequency network function. |
+ // TODO(johan) check, if remote_addr is valid and legit. |
+ OnSocketReadPacket(socket, data, len, remote_addr, packet_time, |
+ true /*rtcp*/); |
pthatcher1
2016/10/07 17:36:36
Please remove these and just have OnSocketReadPack
|
+} |
+ |
+int RawUdpTransportChannel::SendPacket(const char* data, |
+ size_t len, |
+ const rtc::PacketOptions& options, |
+ int flags) { |
+ // No thread_checker in high frequency network function. |
+ int32_t is_rtcp = 0; |
+ // TODO(johan): add logic to send rtcp packets over rtcp socket. |
+ int result = -1; |
+ if (!is_rtcp) { |
+ result = rtp_socket_->SendTo((const void*)data, len, remote_addr_, options); |
+ } |
pthatcher1
2016/10/07 17:36:36
Again, you don't need any of that. Just do socket
|
+ LOG(LS_VERBOSE) << "SendPacket() " << result; |
+ return result; |
+} |
+ |
+bool RawUdpTransportChannel::TryAllocateSockets() { |
+ RTC_DCHECK_RUN_ON(&network_thread_checker_); |
+ static constexpr uint16_t kMaxTries = 100; |
+ static constexpr uint16_t kMinPortNumber = 2000; |
+ // TODO(johan) provide configuration option for kMinPortNumber. |
+ rtc::SocketAddress rtp_socket_addr("0.0.0.0", 0); |
+ rtc::SocketAddress rtcp_socket_addr("0.0.0.0", 1); |
+ // TODO(johan) allocate sockets only once, and loop over |
+ // rtc::AsyncSocketAdapter::bind(). |
+ for (uint16_t count = 0; count < kMaxTries; ++count) { |
pthatcher1
2016/10/07 17:36:36
It seems like you should use a rtc::PacketSocketFa
johan
2016/10/11 13:36:09
rtc::PacketSocketFactory seems to be the right thi
|
+ uint16_t rtpport = kMinPortNumber + (2 * count); |
+ rtp_socket_addr.SetPort(rtpport); |
+ rtp_socket_.reset( |
+ rtc::AsyncUDPSocket::Create(socket_server_, rtp_socket_addr)); |
+ if (!rtp_socket_) { |
+ continue; |
+ } |
+ rtcp_socket_addr.SetPort(rtpport + 1); |
pthatcher1
2016/10/07 17:36:36
How important is this? Cause it's pretty obnoxiou
johan
2016/10/11 13:36:09
Hard requirement. RFC 3550 Section 11 describes "s
|
+ rtcp_socket_.reset( |
+ rtc::AsyncUDPSocket::Create(socket_server_, rtcp_socket_addr)); |
+ if (rtp_socket_ && rtcp_socket_) { |
+ LOG(INFO) << "Allocated Rtp socket with local port " << rtpport; |
+ rtp_socket_->SignalReadPacket.connect( |
+ this, &RawUdpTransportChannel::OnRtpSocketReadPacket); |
+ rtcp_socket_->SignalReadPacket.connect( |
+ this, &RawUdpTransportChannel::OnRtcpSocketReadPacket); |
+ local_candidate_.set_address(rtp_socket_addr); |
+ return true; |
+ } |
+ } |
+ rtp_socket_.reset(); |
+ rtcp_socket_.reset(); |
+ return false; |
+} |
+ |
+void RawUdpTransportChannel::MaybeStartGathering() { |
pthatcher1
2016/10/07 17:36:36
A better name for this would be Start(), which goe
johan
2016/10/11 13:36:09
Renaming depends on PacketTransportInterface.
|
+ RTC_DCHECK_RUN_ON(&network_thread_checker_); |
+ if (gathering_state_ != kIceGatheringNew) { |
+ LOG(INFO) << "candidates gathering already done, early return"; |
+ return; |
+ } |
+ SetGatheringState(kIceGatheringGathering); |
+ TryAllocateSockets(); |
Taylor Brandstetter
2016/10/07 18:24:03
Why does this return a bool if it's not used?
johan
2016/10/11 13:36:09
Should be used, will fix it.
|
+ SignalCandidateGathered(this, local_candidate_); |
+ SetGatheringState(kIceGatheringComplete); |
+} |
+ |
+void RawUdpTransportChannel::UpdateWritableState() { |
+ RTC_DCHECK_RUN_ON(&network_thread_checker_); |
+ bool writable = true; |
+ if (!rtp_socket_) { |
+ writable = false; |
+ LOG(INFO) << "rtp_socket_ is false"; |
+ } |
+ if (!remote_addr_.IsComplete()) { |
+ writable = false; |
+ LOG(INFO) << "remote_addr_ not complete"; |
+ } |
+ if (gathering_state_ != kIceGatheringComplete) { |
+ writable = false; |
+ LOG(INFO) << "gathering_state_ " << gathering_state_; |
+ } |
+ set_writable(writable); |
+} |
+ |
+void RawUdpTransportChannel::AddRemoteCandidate(const Candidate& candidate) { |
+ RTC_DCHECK_RUN_ON(&network_thread_checker_); |
+ // TODO(johan) check for ipv4, other settings. |
+ remote_candidate_ = candidate; |
+ remote_addr_ = candidate.address(); |
+ // TODO(johan) - only set STATE_COMPLETED if *both* local and remote addr are |
+ // set. Maybe use an rtc::Optional to indicate unset addr? |
pthatcher1
2016/10/07 17:36:36
Yes, rtc::Optional<UdpTransportChannelParameters>
|
+ SetTransportChannelState(STATE_COMPLETED); |
+ // TODO(johan) - set STATE_FAILED, if remote addr is invalid. |
+ UpdateWritableState(); |
+} |
+ |
+IceGatheringState RawUdpTransportChannel::gathering_state() const { |
+ RTC_DCHECK_RUN_ON(&network_thread_checker_); |
+ return gathering_state_; |
+} |
+ |
+TransportChannelState RawUdpTransportChannel::GetState() const { |
+ RTC_DCHECK_RUN_ON(&network_thread_checker_); |
+ return tch_state_; |
+} |
pthatcher1
2016/10/07 17:36:36
These could just go in the .h.
johan
2016/10/11 13:36:09
Acknowledged.
|
+ |
+void RawUdpTransportChannel::SetGatheringState( |
+ IceGatheringState new_gathering_state) { |
pthatcher1
2016/10/07 17:36:36
You don't need "new_"
johan
2016/10/11 13:36:10
Acknowledged.
|
+ RTC_DCHECK_RUN_ON(&network_thread_checker_); |
+ if (gathering_state_ != new_gathering_state) { |
+ gathering_state_ = new_gathering_state; |
+ SignalGatheringState(this); |
+ } |
+} |
+ |
+void RawUdpTransportChannel::SetTransportChannelState( |
+ TransportChannelState new_tch_state) { |
+ RTC_DCHECK_RUN_ON(&network_thread_checker_); |
+ if (tch_state_ != new_tch_state) { |
+ tch_state_ = new_tch_state; |
+ SignalStateChanged(this); |
+ } |
+} |
+} // namespace cricket |