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