summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/p2p/base/stun_request.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/p2p/base/stun_request.h')
-rw-r--r--third_party/libwebrtc/p2p/base/stun_request.h162
1 files changed, 162 insertions, 0 deletions
diff --git a/third_party/libwebrtc/p2p/base/stun_request.h b/third_party/libwebrtc/p2p/base/stun_request.h
new file mode 100644
index 0000000000..6e83be3830
--- /dev/null
+++ b/third_party/libwebrtc/p2p/base/stun_request.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2004 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.
+ */
+
+#ifndef P2P_BASE_STUN_REQUEST_H_
+#define P2P_BASE_STUN_REQUEST_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <string>
+
+#include "api/task_queue/pending_task_safety_flag.h"
+#include "api/task_queue/task_queue_base.h"
+#include "api/transport/stun.h"
+#include "api/units/time_delta.h"
+
+namespace cricket {
+
+class StunRequest;
+
+const int kAllRequestsForTest = 0;
+
+// Total max timeouts: 39.75 seconds
+// For years, this was 9.5 seconds, but for networks that experience moments of
+// high RTT (such as 40s on 2G networks), this doesn't work well.
+const int STUN_TOTAL_TIMEOUT = 39750; // milliseconds
+
+// Manages a set of STUN requests, sending and resending until we receive a
+// response or determine that the request has timed out.
+class StunRequestManager {
+ public:
+ StunRequestManager(
+ webrtc::TaskQueueBase* thread,
+ std::function<void(const void*, size_t, StunRequest*)> send_packet);
+ ~StunRequestManager();
+
+ // Starts sending the given request (perhaps after a delay).
+ void Send(StunRequest* request);
+ void SendDelayed(StunRequest* request, int delay);
+
+ // If `msg_type` is kAllRequestsForTest, sends all pending requests right
+ // away. Otherwise, sends those that have a matching type right away. Only for
+ // testing.
+ // TODO(tommi): Remove this method and update tests that use it to simulate
+ // production code.
+ void FlushForTest(int msg_type);
+
+ // Returns true if at least one request with `msg_type` is scheduled for
+ // transmission. For testing only.
+ // TODO(tommi): Remove this method and update tests that use it to simulate
+ // production code.
+ bool HasRequestForTest(int msg_type);
+
+ // Removes all stun requests that were added previously.
+ void Clear();
+
+ // Determines whether the given message is a response to one of the
+ // outstanding requests, and if so, processes it appropriately.
+ bool CheckResponse(StunMessage* msg);
+ bool CheckResponse(const char* data, size_t size);
+
+ // Called from a StunRequest when a timeout occurs.
+ void OnRequestTimedOut(StunRequest* request);
+
+ bool empty() const;
+
+ webrtc::TaskQueueBase* network_thread() const { return thread_; }
+
+ void SendPacket(const void* data, size_t size, StunRequest* request);
+
+ private:
+ typedef std::map<std::string, std::unique_ptr<StunRequest>> RequestMap;
+
+ webrtc::TaskQueueBase* const thread_;
+ RequestMap requests_ RTC_GUARDED_BY(thread_);
+ const std::function<void(const void*, size_t, StunRequest*)> send_packet_;
+};
+
+// Represents an individual request to be sent. The STUN message can either be
+// constructed beforehand or built on demand.
+class StunRequest {
+ public:
+ explicit StunRequest(StunRequestManager& manager);
+ StunRequest(StunRequestManager& manager,
+ std::unique_ptr<StunMessage> message);
+ virtual ~StunRequest();
+
+ // The manager handling this request (if it has been scheduled for sending).
+ StunRequestManager* manager() { return &manager_; }
+
+ // Returns the transaction ID of this request.
+ const std::string& id() const { return msg_->transaction_id(); }
+
+ // Returns the reduced transaction ID of this request.
+ uint32_t reduced_transaction_id() const {
+ return msg_->reduced_transaction_id();
+ }
+
+ // Returns the STUN type of the request message.
+ int type();
+
+ // Returns a const pointer to `msg_`.
+ const StunMessage* msg() const;
+
+ // Time elapsed since last send (in ms)
+ int Elapsed() const;
+
+ protected:
+ friend class StunRequestManager;
+
+ // Called by StunRequestManager.
+ void Send(webrtc::TimeDelta delay);
+
+ // Called from FlushForTest.
+ // TODO(tommi): Remove when FlushForTest gets removed.
+ void ResetTasksForTest();
+
+ StunMessage* mutable_msg() { return msg_.get(); }
+
+ // Called when the message receives a response or times out.
+ virtual void OnResponse(StunMessage* response) {}
+ virtual void OnErrorResponse(StunMessage* response) {}
+ virtual void OnTimeout() {}
+ // Called when the message is sent.
+ virtual void OnSent();
+ // Returns the next delay for resends in milliseconds.
+ virtual int resend_delay();
+
+ webrtc::TaskQueueBase* network_thread() const {
+ return manager_.network_thread();
+ }
+
+ void set_timed_out();
+
+ private:
+ void SendInternal();
+ // Calls `PostDelayedTask` to queue up a call to SendInternal after the
+ // specified timeout.
+ void SendDelayed(webrtc::TimeDelta delay);
+
+ StunRequestManager& manager_;
+ const std::unique_ptr<StunMessage> msg_;
+ int64_t tstamp_ RTC_GUARDED_BY(network_thread());
+ int count_ RTC_GUARDED_BY(network_thread());
+ bool timeout_ RTC_GUARDED_BY(network_thread());
+ webrtc::ScopedTaskSafety task_safety_{
+ webrtc::PendingTaskSafetyFlag::CreateDetachedInactive()};
+};
+
+} // namespace cricket
+
+#endif // P2P_BASE_STUN_REQUEST_H_