xref: /aosp_15_r20/external/webrtc/p2p/base/stun_request.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #ifndef P2P_BASE_STUN_REQUEST_H_
12*d9f75844SAndroid Build Coastguard Worker #define P2P_BASE_STUN_REQUEST_H_
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include <stddef.h>
15*d9f75844SAndroid Build Coastguard Worker #include <stdint.h>
16*d9f75844SAndroid Build Coastguard Worker 
17*d9f75844SAndroid Build Coastguard Worker #include <functional>
18*d9f75844SAndroid Build Coastguard Worker #include <map>
19*d9f75844SAndroid Build Coastguard Worker #include <memory>
20*d9f75844SAndroid Build Coastguard Worker #include <string>
21*d9f75844SAndroid Build Coastguard Worker 
22*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/pending_task_safety_flag.h"
23*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/task_queue_base.h"
24*d9f75844SAndroid Build Coastguard Worker #include "api/transport/stun.h"
25*d9f75844SAndroid Build Coastguard Worker #include "api/units/time_delta.h"
26*d9f75844SAndroid Build Coastguard Worker 
27*d9f75844SAndroid Build Coastguard Worker namespace cricket {
28*d9f75844SAndroid Build Coastguard Worker 
29*d9f75844SAndroid Build Coastguard Worker class StunRequest;
30*d9f75844SAndroid Build Coastguard Worker 
31*d9f75844SAndroid Build Coastguard Worker const int kAllRequestsForTest = 0;
32*d9f75844SAndroid Build Coastguard Worker 
33*d9f75844SAndroid Build Coastguard Worker // Total max timeouts: 39.75 seconds
34*d9f75844SAndroid Build Coastguard Worker // For years, this was 9.5 seconds, but for networks that experience moments of
35*d9f75844SAndroid Build Coastguard Worker // high RTT (such as 40s on 2G networks), this doesn't work well.
36*d9f75844SAndroid Build Coastguard Worker const int STUN_TOTAL_TIMEOUT = 39750;  // milliseconds
37*d9f75844SAndroid Build Coastguard Worker 
38*d9f75844SAndroid Build Coastguard Worker // Manages a set of STUN requests, sending and resending until we receive a
39*d9f75844SAndroid Build Coastguard Worker // response or determine that the request has timed out.
40*d9f75844SAndroid Build Coastguard Worker class StunRequestManager {
41*d9f75844SAndroid Build Coastguard Worker  public:
42*d9f75844SAndroid Build Coastguard Worker   StunRequestManager(
43*d9f75844SAndroid Build Coastguard Worker       webrtc::TaskQueueBase* thread,
44*d9f75844SAndroid Build Coastguard Worker       std::function<void(const void*, size_t, StunRequest*)> send_packet);
45*d9f75844SAndroid Build Coastguard Worker   ~StunRequestManager();
46*d9f75844SAndroid Build Coastguard Worker 
47*d9f75844SAndroid Build Coastguard Worker   // Starts sending the given request (perhaps after a delay).
48*d9f75844SAndroid Build Coastguard Worker   void Send(StunRequest* request);
49*d9f75844SAndroid Build Coastguard Worker   void SendDelayed(StunRequest* request, int delay);
50*d9f75844SAndroid Build Coastguard Worker 
51*d9f75844SAndroid Build Coastguard Worker   // If `msg_type` is kAllRequestsForTest, sends all pending requests right
52*d9f75844SAndroid Build Coastguard Worker   // away. Otherwise, sends those that have a matching type right away. Only for
53*d9f75844SAndroid Build Coastguard Worker   // testing.
54*d9f75844SAndroid Build Coastguard Worker   // TODO(tommi): Remove this method and update tests that use it to simulate
55*d9f75844SAndroid Build Coastguard Worker   // production code.
56*d9f75844SAndroid Build Coastguard Worker   void FlushForTest(int msg_type);
57*d9f75844SAndroid Build Coastguard Worker 
58*d9f75844SAndroid Build Coastguard Worker   // Returns true if at least one request with `msg_type` is scheduled for
59*d9f75844SAndroid Build Coastguard Worker   // transmission. For testing only.
60*d9f75844SAndroid Build Coastguard Worker   // TODO(tommi): Remove this method and update tests that use it to simulate
61*d9f75844SAndroid Build Coastguard Worker   // production code.
62*d9f75844SAndroid Build Coastguard Worker   bool HasRequestForTest(int msg_type);
63*d9f75844SAndroid Build Coastguard Worker 
64*d9f75844SAndroid Build Coastguard Worker   // Removes all stun requests that were added previously.
65*d9f75844SAndroid Build Coastguard Worker   void Clear();
66*d9f75844SAndroid Build Coastguard Worker 
67*d9f75844SAndroid Build Coastguard Worker   // Determines whether the given message is a response to one of the
68*d9f75844SAndroid Build Coastguard Worker   // outstanding requests, and if so, processes it appropriately.
69*d9f75844SAndroid Build Coastguard Worker   bool CheckResponse(StunMessage* msg);
70*d9f75844SAndroid Build Coastguard Worker   bool CheckResponse(const char* data, size_t size);
71*d9f75844SAndroid Build Coastguard Worker 
72*d9f75844SAndroid Build Coastguard Worker   // Called from a StunRequest when a timeout occurs.
73*d9f75844SAndroid Build Coastguard Worker   void OnRequestTimedOut(StunRequest* request);
74*d9f75844SAndroid Build Coastguard Worker 
75*d9f75844SAndroid Build Coastguard Worker   bool empty() const;
76*d9f75844SAndroid Build Coastguard Worker 
network_thread()77*d9f75844SAndroid Build Coastguard Worker   webrtc::TaskQueueBase* network_thread() const { return thread_; }
78*d9f75844SAndroid Build Coastguard Worker 
79*d9f75844SAndroid Build Coastguard Worker   void SendPacket(const void* data, size_t size, StunRequest* request);
80*d9f75844SAndroid Build Coastguard Worker 
81*d9f75844SAndroid Build Coastguard Worker  private:
82*d9f75844SAndroid Build Coastguard Worker   typedef std::map<std::string, std::unique_ptr<StunRequest>> RequestMap;
83*d9f75844SAndroid Build Coastguard Worker 
84*d9f75844SAndroid Build Coastguard Worker   webrtc::TaskQueueBase* const thread_;
85*d9f75844SAndroid Build Coastguard Worker   RequestMap requests_ RTC_GUARDED_BY(thread_);
86*d9f75844SAndroid Build Coastguard Worker   const std::function<void(const void*, size_t, StunRequest*)> send_packet_;
87*d9f75844SAndroid Build Coastguard Worker };
88*d9f75844SAndroid Build Coastguard Worker 
89*d9f75844SAndroid Build Coastguard Worker // Represents an individual request to be sent.  The STUN message can either be
90*d9f75844SAndroid Build Coastguard Worker // constructed beforehand or built on demand.
91*d9f75844SAndroid Build Coastguard Worker class StunRequest {
92*d9f75844SAndroid Build Coastguard Worker  public:
93*d9f75844SAndroid Build Coastguard Worker   explicit StunRequest(StunRequestManager& manager);
94*d9f75844SAndroid Build Coastguard Worker   StunRequest(StunRequestManager& manager,
95*d9f75844SAndroid Build Coastguard Worker               std::unique_ptr<StunMessage> message);
96*d9f75844SAndroid Build Coastguard Worker   virtual ~StunRequest();
97*d9f75844SAndroid Build Coastguard Worker 
98*d9f75844SAndroid Build Coastguard Worker   // The manager handling this request (if it has been scheduled for sending).
manager()99*d9f75844SAndroid Build Coastguard Worker   StunRequestManager* manager() { return &manager_; }
100*d9f75844SAndroid Build Coastguard Worker 
101*d9f75844SAndroid Build Coastguard Worker   // Returns the transaction ID of this request.
id()102*d9f75844SAndroid Build Coastguard Worker   const std::string& id() const { return msg_->transaction_id(); }
103*d9f75844SAndroid Build Coastguard Worker 
104*d9f75844SAndroid Build Coastguard Worker   // Returns the reduced transaction ID of this request.
reduced_transaction_id()105*d9f75844SAndroid Build Coastguard Worker   uint32_t reduced_transaction_id() const {
106*d9f75844SAndroid Build Coastguard Worker     return msg_->reduced_transaction_id();
107*d9f75844SAndroid Build Coastguard Worker   }
108*d9f75844SAndroid Build Coastguard Worker 
109*d9f75844SAndroid Build Coastguard Worker   // Returns the STUN type of the request message.
110*d9f75844SAndroid Build Coastguard Worker   int type();
111*d9f75844SAndroid Build Coastguard Worker 
112*d9f75844SAndroid Build Coastguard Worker   // Returns a const pointer to `msg_`.
113*d9f75844SAndroid Build Coastguard Worker   const StunMessage* msg() const;
114*d9f75844SAndroid Build Coastguard Worker 
115*d9f75844SAndroid Build Coastguard Worker   // Time elapsed since last send (in ms)
116*d9f75844SAndroid Build Coastguard Worker   int Elapsed() const;
117*d9f75844SAndroid Build Coastguard Worker 
118*d9f75844SAndroid Build Coastguard Worker  protected:
119*d9f75844SAndroid Build Coastguard Worker   friend class StunRequestManager;
120*d9f75844SAndroid Build Coastguard Worker 
121*d9f75844SAndroid Build Coastguard Worker   // Called by StunRequestManager.
122*d9f75844SAndroid Build Coastguard Worker   void Send(webrtc::TimeDelta delay);
123*d9f75844SAndroid Build Coastguard Worker 
124*d9f75844SAndroid Build Coastguard Worker   // Called from FlushForTest.
125*d9f75844SAndroid Build Coastguard Worker   // TODO(tommi): Remove when FlushForTest gets removed.
126*d9f75844SAndroid Build Coastguard Worker   void ResetTasksForTest();
127*d9f75844SAndroid Build Coastguard Worker 
mutable_msg()128*d9f75844SAndroid Build Coastguard Worker   StunMessage* mutable_msg() { return msg_.get(); }
129*d9f75844SAndroid Build Coastguard Worker 
130*d9f75844SAndroid Build Coastguard Worker   // Called when the message receives a response or times out.
OnResponse(StunMessage * response)131*d9f75844SAndroid Build Coastguard Worker   virtual void OnResponse(StunMessage* response) {}
OnErrorResponse(StunMessage * response)132*d9f75844SAndroid Build Coastguard Worker   virtual void OnErrorResponse(StunMessage* response) {}
OnTimeout()133*d9f75844SAndroid Build Coastguard Worker   virtual void OnTimeout() {}
134*d9f75844SAndroid Build Coastguard Worker   // Called when the message is sent.
135*d9f75844SAndroid Build Coastguard Worker   virtual void OnSent();
136*d9f75844SAndroid Build Coastguard Worker   // Returns the next delay for resends in milliseconds.
137*d9f75844SAndroid Build Coastguard Worker   virtual int resend_delay();
138*d9f75844SAndroid Build Coastguard Worker 
network_thread()139*d9f75844SAndroid Build Coastguard Worker   webrtc::TaskQueueBase* network_thread() const {
140*d9f75844SAndroid Build Coastguard Worker     return manager_.network_thread();
141*d9f75844SAndroid Build Coastguard Worker   }
142*d9f75844SAndroid Build Coastguard Worker 
143*d9f75844SAndroid Build Coastguard Worker   void set_timed_out();
144*d9f75844SAndroid Build Coastguard Worker 
145*d9f75844SAndroid Build Coastguard Worker  private:
146*d9f75844SAndroid Build Coastguard Worker   void SendInternal();
147*d9f75844SAndroid Build Coastguard Worker   // Calls `PostDelayedTask` to queue up a call to SendInternal after the
148*d9f75844SAndroid Build Coastguard Worker   // specified timeout.
149*d9f75844SAndroid Build Coastguard Worker   void SendDelayed(webrtc::TimeDelta delay);
150*d9f75844SAndroid Build Coastguard Worker 
151*d9f75844SAndroid Build Coastguard Worker   StunRequestManager& manager_;
152*d9f75844SAndroid Build Coastguard Worker   const std::unique_ptr<StunMessage> msg_;
153*d9f75844SAndroid Build Coastguard Worker   int64_t tstamp_ RTC_GUARDED_BY(network_thread());
154*d9f75844SAndroid Build Coastguard Worker   int count_ RTC_GUARDED_BY(network_thread());
155*d9f75844SAndroid Build Coastguard Worker   bool timeout_ RTC_GUARDED_BY(network_thread());
156*d9f75844SAndroid Build Coastguard Worker   webrtc::ScopedTaskSafety task_safety_{
157*d9f75844SAndroid Build Coastguard Worker       webrtc::PendingTaskSafetyFlag::CreateDetachedInactive()};
158*d9f75844SAndroid Build Coastguard Worker };
159*d9f75844SAndroid Build Coastguard Worker 
160*d9f75844SAndroid Build Coastguard Worker }  // namespace cricket
161*d9f75844SAndroid Build Coastguard Worker 
162*d9f75844SAndroid Build Coastguard Worker #endif  // P2P_BASE_STUN_REQUEST_H_
163