• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_BASE_VIRTUALSOCKETSERVER_H_
12 #define WEBRTC_BASE_VIRTUALSOCKETSERVER_H_
13 
14 #include <assert.h>
15 
16 #include <deque>
17 #include <map>
18 
19 #include "webrtc/base/messagequeue.h"
20 #include "webrtc/base/socketserver.h"
21 
22 namespace rtc {
23 
24 class VirtualSocket;
25 class SocketAddressPair;
26 
27 // Simulates a network in the same manner as a loopback interface.  The
28 // interface can create as many addresses as you want.  All of the sockets
29 // created by this network will be able to communicate with one another, unless
30 // they are bound to addresses from incompatible families.
31 class VirtualSocketServer : public SocketServer, public sigslot::has_slots<> {
32  public:
33   // TODO: Add "owned" parameter.
34   // If "owned" is set, the supplied socketserver will be deleted later.
35   explicit VirtualSocketServer(SocketServer* ss);
36   virtual ~VirtualSocketServer();
37 
socketserver()38   SocketServer* socketserver() { return server_; }
39 
40   // Limits the network bandwidth (maximum bytes per second).  Zero means that
41   // all sends occur instantly.  Defaults to 0.
bandwidth()42   uint32 bandwidth() const { return bandwidth_; }
set_bandwidth(uint32 bandwidth)43   void set_bandwidth(uint32 bandwidth) { bandwidth_ = bandwidth; }
44 
45   // Limits the amount of data which can be in flight on the network without
46   // packet loss (on a per sender basis).  Defaults to 64 KB.
network_capacity()47   uint32 network_capacity() const { return network_capacity_; }
set_network_capacity(uint32 capacity)48   void set_network_capacity(uint32 capacity) {
49     network_capacity_ = capacity;
50   }
51 
52   // The amount of data which can be buffered by tcp on the sender's side
send_buffer_capacity()53   uint32 send_buffer_capacity() const { return send_buffer_capacity_; }
set_send_buffer_capacity(uint32 capacity)54   void set_send_buffer_capacity(uint32 capacity) {
55     send_buffer_capacity_ = capacity;
56   }
57 
58   // The amount of data which can be buffered by tcp on the receiver's side
recv_buffer_capacity()59   uint32 recv_buffer_capacity() const { return recv_buffer_capacity_; }
set_recv_buffer_capacity(uint32 capacity)60   void set_recv_buffer_capacity(uint32 capacity) {
61     recv_buffer_capacity_ = capacity;
62   }
63 
64   // Controls the (transit) delay for packets sent in the network.  This does
65   // not inclue the time required to sit in the send queue.  Both of these
66   // values are measured in milliseconds.  Defaults to no delay.
delay_mean()67   uint32 delay_mean() const { return delay_mean_; }
delay_stddev()68   uint32 delay_stddev() const { return delay_stddev_; }
delay_samples()69   uint32 delay_samples() const { return delay_samples_; }
set_delay_mean(uint32 delay_mean)70   void set_delay_mean(uint32 delay_mean) { delay_mean_ = delay_mean; }
set_delay_stddev(uint32 delay_stddev)71   void set_delay_stddev(uint32 delay_stddev) {
72     delay_stddev_ = delay_stddev;
73   }
set_delay_samples(uint32 delay_samples)74   void set_delay_samples(uint32 delay_samples) {
75     delay_samples_ = delay_samples;
76   }
77 
78   // If the (transit) delay parameters are modified, this method should be
79   // called to recompute the new distribution.
80   void UpdateDelayDistribution();
81 
82   // Controls the (uniform) probability that any sent packet is dropped.  This
83   // is separate from calculations to drop based on queue size.
drop_probability()84   double drop_probability() { return drop_prob_; }
set_drop_probability(double drop_prob)85   void set_drop_probability(double drop_prob) {
86     assert((0 <= drop_prob) && (drop_prob <= 1));
87     drop_prob_ = drop_prob;
88   }
89 
90   // SocketFactory:
91   virtual Socket* CreateSocket(int type);
92   virtual Socket* CreateSocket(int family, int type);
93 
94   virtual AsyncSocket* CreateAsyncSocket(int type);
95   virtual AsyncSocket* CreateAsyncSocket(int family, int type);
96 
97   // SocketServer:
98   virtual void SetMessageQueue(MessageQueue* queue);
99   virtual bool Wait(int cms, bool process_io);
100   virtual void WakeUp();
101 
102   typedef std::pair<double, double> Point;
103   typedef std::vector<Point> Function;
104 
105   static Function* CreateDistribution(uint32 mean, uint32 stddev,
106                                       uint32 samples);
107 
108   // Similar to Thread::ProcessMessages, but it only processes messages until
109   // there are no immediate messages or pending network traffic.  Returns false
110   // if Thread::Stop() was called.
111   bool ProcessMessagesUntilIdle();
112 
113  protected:
114   // Returns a new IP not used before in this network.
115   IPAddress GetNextIP(int family);
116   uint16 GetNextPort();
117 
118   VirtualSocket* CreateSocketInternal(int family, int type);
119 
120   // Binds the given socket to addr, assigning and IP and Port if necessary
121   int Bind(VirtualSocket* socket, SocketAddress* addr);
122 
123   // Binds the given socket to the given (fully-defined) address.
124   int Bind(VirtualSocket* socket, const SocketAddress& addr);
125 
126   // Find the socket bound to the given address
127   VirtualSocket* LookupBinding(const SocketAddress& addr);
128 
129   int Unbind(const SocketAddress& addr, VirtualSocket* socket);
130 
131   // Adds a mapping between this socket pair and the socket.
132   void AddConnection(const SocketAddress& client,
133                      const SocketAddress& server,
134                      VirtualSocket* socket);
135 
136   // Find the socket pair corresponding to this server address.
137   VirtualSocket* LookupConnection(const SocketAddress& client,
138                                   const SocketAddress& server);
139 
140   void RemoveConnection(const SocketAddress& client,
141                         const SocketAddress& server);
142 
143   // Connects the given socket to the socket at the given address
144   int Connect(VirtualSocket* socket, const SocketAddress& remote_addr,
145               bool use_delay);
146 
147   // Sends a disconnect message to the socket at the given address
148   bool Disconnect(VirtualSocket* socket);
149 
150   // Sends the given packet to the socket at the given address (if one exists).
151   int SendUdp(VirtualSocket* socket, const char* data, size_t data_size,
152               const SocketAddress& remote_addr);
153 
154   // Moves as much data as possible from the sender's buffer to the network
155   void SendTcp(VirtualSocket* socket);
156 
157   // Places a packet on the network.
158   void AddPacketToNetwork(VirtualSocket* socket, VirtualSocket* recipient,
159                           uint32 cur_time, const char* data, size_t data_size,
160                           size_t header_size, bool ordered);
161 
162   // Removes stale packets from the network
163   void PurgeNetworkPackets(VirtualSocket* socket, uint32 cur_time);
164 
165   // Computes the number of milliseconds required to send a packet of this size.
166   uint32 SendDelay(uint32 size);
167 
168   // Returns a random transit delay chosen from the appropriate distribution.
169   uint32 GetRandomTransitDelay();
170 
171   // Basic operations on functions.  Those that return a function also take
172   // ownership of the function given (and hence, may modify or delete it).
173   static Function* Accumulate(Function* f);
174   static Function* Invert(Function* f);
175   static Function* Resample(Function* f, double x1, double x2, uint32 samples);
176   static double Evaluate(Function* f, double x);
177 
178   // NULL out our message queue if it goes away. Necessary in the case where
179   // our lifetime is greater than that of the thread we are using, since we
180   // try to send Close messages for all connected sockets when we shutdown.
OnMessageQueueDestroyed()181   void OnMessageQueueDestroyed() { msg_queue_ = NULL; }
182 
183   // Determine if two sockets should be able to communicate.
184   // We don't (currently) specify an address family for sockets; instead,
185   // the currently bound address is used to infer the address family.
186   // Any socket that is not explicitly bound to an IPv4 address is assumed to be
187   // dual-stack capable.
188   // This function tests if two addresses can communicate, as well as the
189   // sockets to which they may be bound (the addresses may or may not yet be
190   // bound to the sockets).
191   // First the addresses are tested (after normalization):
192   // If both have the same family, then communication is OK.
193   // If only one is IPv4 then false, unless the other is bound to ::.
194   // This applies even if the IPv4 address is 0.0.0.0.
195   // The socket arguments are optional; the sockets are checked to see if they
196   // were explicitly bound to IPv6-any ('::'), and if so communication is
197   // permitted.
198   // NB: This scheme doesn't permit non-dualstack IPv6 sockets.
199   static bool CanInteractWith(VirtualSocket* local, VirtualSocket* remote);
200 
201  private:
202   friend class VirtualSocket;
203 
204   typedef std::map<SocketAddress, VirtualSocket*> AddressMap;
205   typedef std::map<SocketAddressPair, VirtualSocket*> ConnectionMap;
206 
207   SocketServer* server_;
208   bool server_owned_;
209   MessageQueue* msg_queue_;
210   bool stop_on_idle_;
211   uint32 network_delay_;
212   in_addr next_ipv4_;
213   in6_addr next_ipv6_;
214   uint16 next_port_;
215   AddressMap* bindings_;
216   ConnectionMap* connections_;
217 
218   uint32 bandwidth_;
219   uint32 network_capacity_;
220   uint32 send_buffer_capacity_;
221   uint32 recv_buffer_capacity_;
222   uint32 delay_mean_;
223   uint32 delay_stddev_;
224   uint32 delay_samples_;
225   Function* delay_dist_;
226   CriticalSection delay_crit_;
227 
228   double drop_prob_;
229   DISALLOW_EVIL_CONSTRUCTORS(VirtualSocketServer);
230 };
231 
232 }  // namespace rtc
233 
234 #endif  // WEBRTC_BASE_VIRTUALSOCKETSERVER_H_
235