1 /* 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 11 #ifndef P2P_BASE_STUN_REQUEST_H_ 12 #define P2P_BASE_STUN_REQUEST_H_ 13 14 #include <stddef.h> 15 #include <stdint.h> 16 17 #include <map> 18 #include <string> 19 20 #include "api/transport/stun.h" 21 #include "rtc_base/message_handler.h" 22 #include "rtc_base/third_party/sigslot/sigslot.h" 23 #include "rtc_base/thread.h" 24 25 namespace cricket { 26 27 class StunRequest; 28 29 const int kAllRequests = 0; 30 31 // Total max timeouts: 39.75 seconds 32 // For years, this was 9.5 seconds, but for networks that experience moments of 33 // high RTT (such as 40s on 2G networks), this doesn't work well. 34 const int STUN_TOTAL_TIMEOUT = 39750; // milliseconds 35 36 // Manages a set of STUN requests, sending and resending until we receive a 37 // response or determine that the request has timed out. 38 class StunRequestManager { 39 public: 40 explicit StunRequestManager(rtc::Thread* thread); 41 ~StunRequestManager(); 42 43 // Starts sending the given request (perhaps after a delay). 44 void Send(StunRequest* request); 45 void SendDelayed(StunRequest* request, int delay); 46 47 // If |msg_type| is kAllRequests, sends all pending requests right away. 48 // Otherwise, sends those that have a matching type right away. 49 // Only for testing. 50 void Flush(int msg_type); 51 52 // Returns true if at least one request with |msg_type| is scheduled for 53 // transmission. For testing only. 54 bool HasRequest(int msg_type); 55 56 // Removes a stun request that was added previously. This will happen 57 // automatically when a request succeeds, fails, or times out. 58 void Remove(StunRequest* request); 59 60 // Removes all stun requests that were added previously. 61 void Clear(); 62 63 // Determines whether the given message is a response to one of the 64 // outstanding requests, and if so, processes it appropriately. 65 bool CheckResponse(StunMessage* msg); 66 bool CheckResponse(const char* data, size_t size); 67 empty()68 bool empty() { return requests_.empty(); } 69 70 // Set the Origin header for outgoing stun messages. set_origin(const std::string & origin)71 void set_origin(const std::string& origin) { origin_ = origin; } 72 73 // Raised when there are bytes to be sent. 74 sigslot::signal3<const void*, size_t, StunRequest*> SignalSendPacket; 75 76 private: 77 typedef std::map<std::string, StunRequest*> RequestMap; 78 79 rtc::Thread* thread_; 80 RequestMap requests_; 81 std::string origin_; 82 83 friend class StunRequest; 84 }; 85 86 // Represents an individual request to be sent. The STUN message can either be 87 // constructed beforehand or built on demand. 88 class StunRequest : public rtc::MessageHandler { 89 public: 90 StunRequest(); 91 explicit StunRequest(StunMessage* request); 92 ~StunRequest() override; 93 94 // Causes our wrapped StunMessage to be Prepared 95 void Construct(); 96 97 // The manager handling this request (if it has been scheduled for sending). manager()98 StunRequestManager* manager() { return manager_; } 99 100 // Returns the transaction ID of this request. id()101 const std::string& id() { return msg_->transaction_id(); } 102 103 // Returns the reduced transaction ID of this request. reduced_transaction_id()104 uint32_t reduced_transaction_id() const { 105 return msg_->reduced_transaction_id(); 106 } 107 108 // the origin value origin()109 const std::string& origin() const { return origin_; } set_origin(const std::string & origin)110 void set_origin(const std::string& origin) { origin_ = origin; } 111 112 // Returns the STUN type of the request message. 113 int type(); 114 115 // Returns a const pointer to |msg_|. 116 const StunMessage* msg() const; 117 118 // Returns a mutable pointer to |msg_|. 119 StunMessage* mutable_msg(); 120 121 // Time elapsed since last send (in ms) 122 int Elapsed() const; 123 124 protected: 125 int count_; 126 bool timeout_; 127 std::string origin_; 128 129 // Fills in a request object to be sent. Note that request's transaction ID 130 // will already be set and cannot be changed. Prepare(StunMessage * request)131 virtual void Prepare(StunMessage* request) {} 132 133 // Called when the message receives a response or times out. OnResponse(StunMessage * response)134 virtual void OnResponse(StunMessage* response) {} OnErrorResponse(StunMessage * response)135 virtual void OnErrorResponse(StunMessage* response) {} OnTimeout()136 virtual void OnTimeout() {} 137 // Called when the message is sent. 138 virtual void OnSent(); 139 // Returns the next delay for resends. 140 virtual int resend_delay(); 141 142 private: 143 void set_manager(StunRequestManager* manager); 144 145 // Handles messages for sending and timeout. 146 void OnMessage(rtc::Message* pmsg) override; 147 148 StunRequestManager* manager_; 149 StunMessage* msg_; 150 int64_t tstamp_; 151 152 friend class StunRequestManager; 153 }; 154 155 } // namespace cricket 156 157 #endif // P2P_BASE_STUN_REQUEST_H_ 158