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 WEBRTC_P2P_BASE_STUNREQUEST_H_
12 #define WEBRTC_P2P_BASE_STUNREQUEST_H_
13 
14 #include <map>
15 #include <string>
16 #include "webrtc/p2p/base/stun.h"
17 #include "webrtc/base/sigslot.h"
18 #include "webrtc/base/thread.h"
19 
20 namespace cricket {
21 
22 class StunRequest;
23 
24 // Manages a set of STUN requests, sending and resending until we receive a
25 // response or determine that the request has timed out.
26 class StunRequestManager {
27  public:
28   StunRequestManager(rtc::Thread* thread);
29   ~StunRequestManager();
30 
31   // Starts sending the given request (perhaps after a delay).
32   void Send(StunRequest* request);
33   void SendDelayed(StunRequest* request, int delay);
34 
35   // Removes a stun request that was added previously.  This will happen
36   // automatically when a request succeeds, fails, or times out.
37   void Remove(StunRequest* request);
38 
39   // Removes all stun requests that were added previously.
40   void Clear();
41 
42   // Determines whether the given message is a response to one of the
43   // outstanding requests, and if so, processes it appropriately.
44   bool CheckResponse(StunMessage* msg);
45   bool CheckResponse(const char* data, size_t size);
46 
empty()47   bool empty() { return requests_.empty(); }
48 
49   // Set the Origin header for outgoing stun messages.
set_origin(const std::string & origin)50   void set_origin(const std::string& origin) { origin_ = origin; }
51 
52   // Raised when there are bytes to be sent.
53   sigslot::signal3<const void*, size_t, StunRequest*> SignalSendPacket;
54 
55  private:
56   typedef std::map<std::string, StunRequest*> RequestMap;
57 
58   rtc::Thread* thread_;
59   RequestMap requests_;
60   std::string origin_;
61 
62   friend class StunRequest;
63 };
64 
65 // Represents an individual request to be sent.  The STUN message can either be
66 // constructed beforehand or built on demand.
67 class StunRequest : public rtc::MessageHandler {
68  public:
69   StunRequest();
70   StunRequest(StunMessage* request);
71   virtual ~StunRequest();
72 
73   // Causes our wrapped StunMessage to be Prepared
74   void Construct();
75 
76   // The manager handling this request (if it has been scheduled for sending).
manager()77   StunRequestManager* manager() { return manager_; }
78 
79   // Returns the transaction ID of this request.
id()80   const std::string& id() { return msg_->transaction_id(); }
81 
82   // the origin value
origin()83   const std::string& origin() const { return origin_; }
set_origin(const std::string & origin)84   void set_origin(const std::string& origin) { origin_ = origin; }
85 
86   // Returns the STUN type of the request message.
87   int type();
88 
89   // Returns a const pointer to |msg_|.
90   const StunMessage* msg() const;
91 
92   // Time elapsed since last send (in ms)
93   uint32 Elapsed() const;
94 
95  protected:
96   int count_;
97   bool timeout_;
98   std::string origin_;
99 
100   // Fills in a request object to be sent.  Note that request's transaction ID
101   // will already be set and cannot be changed.
Prepare(StunMessage * request)102   virtual void Prepare(StunMessage* request) {}
103 
104   // Called when the message receives a response or times out.
OnResponse(StunMessage * response)105   virtual void OnResponse(StunMessage* response) {}
OnErrorResponse(StunMessage * response)106   virtual void OnErrorResponse(StunMessage* response) {}
OnTimeout()107   virtual void OnTimeout() {}
108   virtual int GetNextDelay();
109 
110  private:
111   void set_manager(StunRequestManager* manager);
112 
113   // Handles messages for sending and timeout.
114   void OnMessage(rtc::Message* pmsg);
115 
116   StunRequestManager* manager_;
117   StunMessage* msg_;
118   uint32 tstamp_;
119 
120   friend class StunRequestManager;
121 };
122 
123 }  // namespace cricket
124 
125 #endif  // WEBRTC_P2P_BASE_STUNREQUEST_H_
126