blob: f2fd7e5211a423c67be3be281877ab63c822fdba [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:111/*
2 * Copyright 2004 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
Steve Anton10542f22019-01-11 17:11:0011#ifndef P2P_BASE_STUN_REQUEST_H_
12#define P2P_BASE_STUN_REQUEST_H_
henrike@webrtc.org269fb4b2014-10-28 22:20:1113
Yves Gerey3e707812018-11-28 15:47:4914#include <stddef.h>
15#include <stdint.h>
Jonas Olssona4d87372019-07-05 17:08:3316
Tomas Gunnarssonf22dfdd2022-04-13 09:07:3017#include <functional>
henrike@webrtc.org269fb4b2014-10-28 22:20:1118#include <map>
Tommi86aa03e2022-04-12 07:17:5719#include <memory>
henrike@webrtc.org269fb4b2014-10-28 22:20:1120#include <string>
Yves Gerey3e707812018-11-28 15:47:4921
Artem Titovc374d112022-06-16 19:27:4522#include "api/task_queue/pending_task_safety_flag.h"
Tommi7ef4f512022-06-14 12:51:2923#include "api/task_queue/task_queue_base.h"
Patrik Höglund56d94522019-11-18 14:53:3224#include "api/transport/stun.h"
Tommi7ef4f512022-06-14 12:51:2925#include "api/units/time_delta.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:1126
27namespace cricket {
28
29class StunRequest;
30
Tommif7b30e02022-07-06 10:26:4831const int kAllRequestsForTest = 0;
honghaiz6b9ab922016-01-05 17:06:1232
pthatcher94a2f212017-02-08 22:42:2233// Total max timeouts: 39.75 seconds
34// For years, this was 9.5 seconds, but for networks that experience moments of
35// high RTT (such as 40s on 2G networks), this doesn't work well.
36const int STUN_TOTAL_TIMEOUT = 39750; // milliseconds
37
henrike@webrtc.org269fb4b2014-10-28 22:20:1138// Manages a set of STUN requests, sending and resending until we receive a
39// response or determine that the request has timed out.
40class StunRequestManager {
pthatcher@webrtc.org0ba15332015-01-10 00:47:0241 public:
Tomas Gunnarssonf22dfdd2022-04-13 09:07:3042 StunRequestManager(
Tommi7ef4f512022-06-14 12:51:2943 webrtc::TaskQueueBase* thread,
Tomas Gunnarssonf22dfdd2022-04-13 09:07:3044 std::function<void(const void*, size_t, StunRequest*)> send_packet);
henrike@webrtc.org269fb4b2014-10-28 22:20:1145 ~StunRequestManager();
46
47 // Starts sending the given request (perhaps after a delay).
48 void Send(StunRequest* request);
49 void SendDelayed(StunRequest* request, int delay);
50
Tommif7b30e02022-07-06 10:26:4851 // If `msg_type` is kAllRequestsForTest, sends all pending requests right
52 // away. Otherwise, sends those that have a matching type right away. Only for
53 // testing.
Tommi7ef4f512022-06-14 12:51:2954 // TODO(tommi): Remove this method and update tests that use it to simulate
55 // production code.
Tommi86aa03e2022-04-12 07:17:5756 void FlushForTest(int msg_type);
Honghai Zhang85975432015-11-12 19:07:1257
Artem Titov2dbb4c92021-07-26 13:12:4158 // Returns true if at least one request with `msg_type` is scheduled for
honghaize2af9ef2016-03-03 16:27:4759 // transmission. For testing only.
Tommi7ef4f512022-06-14 12:51:2960 // TODO(tommi): Remove this method and update tests that use it to simulate
61 // production code.
Tommi86aa03e2022-04-12 07:17:5762 bool HasRequestForTest(int msg_type);
honghaize2af9ef2016-03-03 16:27:4763
henrike@webrtc.org269fb4b2014-10-28 22:20:1164 // Removes all stun requests that were added previously.
65 void Clear();
66
67 // Determines whether the given message is a response to one of the
68 // outstanding requests, and if so, processes it appropriately.
69 bool CheckResponse(StunMessage* msg);
70 bool CheckResponse(const char* data, size_t size);
71
Tommi25452572022-04-12 10:51:4072 // Called from a StunRequest when a timeout occurs.
73 void OnRequestTimedOut(StunRequest* request);
74
Tommi86aa03e2022-04-12 07:17:5775 bool empty() const;
76
Tommi7ef4f512022-06-14 12:51:2977 webrtc::TaskQueueBase* network_thread() const { return thread_; }
henrike@webrtc.org269fb4b2014-10-28 22:20:1178
Tomas Gunnarssonf22dfdd2022-04-13 09:07:3079 void SendPacket(const void* data, size_t size, StunRequest* request);
henrike@webrtc.org269fb4b2014-10-28 22:20:1180
pthatcher@webrtc.org0ba15332015-01-10 00:47:0281 private:
Tommi25452572022-04-12 10:51:4082 typedef std::map<std::string, std::unique_ptr<StunRequest>> RequestMap;
henrike@webrtc.org269fb4b2014-10-28 22:20:1183
Tommi7ef4f512022-06-14 12:51:2984 webrtc::TaskQueueBase* const thread_;
Tommi86aa03e2022-04-12 07:17:5785 RequestMap requests_ RTC_GUARDED_BY(thread_);
Tomas Gunnarssonf22dfdd2022-04-13 09:07:3086 const std::function<void(const void*, size_t, StunRequest*)> send_packet_;
henrike@webrtc.org269fb4b2014-10-28 22:20:1187};
88
89// Represents an individual request to be sent. The STUN message can either be
90// constructed beforehand or built on demand.
Tommi7ef4f512022-06-14 12:51:2991class StunRequest {
pthatcher@webrtc.org0ba15332015-01-10 00:47:0292 public:
Tommi86aa03e2022-04-12 07:17:5793 explicit StunRequest(StunRequestManager& manager);
94 StunRequest(StunRequestManager& manager,
Tommi278b19d2022-04-12 12:03:4095 std::unique_ptr<StunMessage> message);
Tommi7ef4f512022-06-14 12:51:2996 virtual ~StunRequest();
henrike@webrtc.org269fb4b2014-10-28 22:20:1197
henrike@webrtc.org269fb4b2014-10-28 22:20:1198 // The manager handling this request (if it has been scheduled for sending).
Tommi86aa03e2022-04-12 07:17:5799 StunRequestManager* manager() { return &manager_; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11100
101 // Returns the transaction ID of this request.
Tommi86aa03e2022-04-12 07:17:57102 const std::string& id() const { return msg_->transaction_id(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11103
Zach Stein92c42892018-11-28 19:38:52104 // Returns the reduced transaction ID of this request.
105 uint32_t reduced_transaction_id() const {
106 return msg_->reduced_transaction_id();
107 }
108
henrike@webrtc.org269fb4b2014-10-28 22:20:11109 // Returns the STUN type of the request message.
110 int type();
111
Artem Titov2dbb4c92021-07-26 13:12:41112 // Returns a const pointer to `msg_`.
henrike@webrtc.org269fb4b2014-10-28 22:20:11113 const StunMessage* msg() const;
114
115 // Time elapsed since last send (in ms)
honghaiz34b11eb2016-03-16 15:55:44116 int Elapsed() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11117
Jonas Oreland02ce5882023-11-15 09:53:40118 // Add method to explitly allow requests w/o password.
119 // - STUN_BINDINGs from StunPort to a stun server
120 // - The initial TURN_ALLOCATE_REQUEST
121 void SetAuthenticationRequired(bool val) { authentication_required_ = val; }
122 bool AuthenticationRequired() const { return authentication_required_; }
123
pthatcher@webrtc.org0ba15332015-01-10 00:47:02124 protected:
Tommi86aa03e2022-04-12 07:17:57125 friend class StunRequestManager;
henrike@webrtc.org269fb4b2014-10-28 22:20:11126
Tommi7ef4f512022-06-14 12:51:29127 // Called by StunRequestManager.
128 void Send(webrtc::TimeDelta delay);
129
130 // Called from FlushForTest.
131 // TODO(tommi): Remove when FlushForTest gets removed.
132 void ResetTasksForTest();
133
Tommi159f3132022-06-03 12:37:31134 StunMessage* mutable_msg() { return msg_.get(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11135
136 // Called when the message receives a response or times out.
137 virtual void OnResponse(StunMessage* response) {}
138 virtual void OnErrorResponse(StunMessage* response) {}
139 virtual void OnTimeout() {}
Peter Thatcher1cf6f812015-05-15 17:40:45140 // Called when the message is sent.
141 virtual void OnSent();
Tommi7ef4f512022-06-14 12:51:29142 // Returns the next delay for resends in milliseconds.
Peter Thatcher1cf6f812015-05-15 17:40:45143 virtual int resend_delay();
henrike@webrtc.org269fb4b2014-10-28 22:20:11144
Tommi86aa03e2022-04-12 07:17:57145 webrtc::TaskQueueBase* network_thread() const {
146 return manager_.network_thread();
147 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11148
Tommi86aa03e2022-04-12 07:17:57149 void set_timed_out();
150
151 private:
Tommi7ef4f512022-06-14 12:51:29152 void SendInternal();
153 // Calls `PostDelayedTask` to queue up a call to SendInternal after the
154 // specified timeout.
155 void SendDelayed(webrtc::TimeDelta delay);
henrike@webrtc.org269fb4b2014-10-28 22:20:11156
Tommi86aa03e2022-04-12 07:17:57157 StunRequestManager& manager_;
158 const std::unique_ptr<StunMessage> msg_;
159 int64_t tstamp_ RTC_GUARDED_BY(network_thread());
160 int count_ RTC_GUARDED_BY(network_thread());
161 bool timeout_ RTC_GUARDED_BY(network_thread());
Tommi7ef4f512022-06-14 12:51:29162 webrtc::ScopedTaskSafety task_safety_{
163 webrtc::PendingTaskSafetyFlag::CreateDetachedInactive()};
Jonas Oreland02ce5882023-11-15 09:53:40164 bool authentication_required_ = true;
henrike@webrtc.org269fb4b2014-10-28 22:20:11165};
166
167} // namespace cricket
168
Steve Anton10542f22019-01-11 17:11:00169#endif // P2P_BASE_STUN_REQUEST_H_