diff options
Diffstat (limited to 'third_party/libwebrtc/p2p/base/stun_request.h')
-rw-r--r-- | third_party/libwebrtc/p2p/base/stun_request.h | 162 |
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_ |