• 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   // Sets the next port number to use for testing.
114   void SetNextPortForTesting(uint16 port);
115 
116  protected:
117   // Returns a new IP not used before in this network.
118   IPAddress GetNextIP(int family);
119   uint16 GetNextPort();
120 
121   VirtualSocket* CreateSocketInternal(int family, int type);
122 
123   // Binds the given socket to addr, assigning and IP and Port if necessary
124   int Bind(VirtualSocket* socket, SocketAddress* addr);
125 
126   // Binds the given socket to the given (fully-defined) address.
127   int Bind(VirtualSocket* socket, const SocketAddress& addr);
128 
129   // Find the socket bound to the given address
130   VirtualSocket* LookupBinding(const SocketAddress& addr);
131 
132   int Unbind(const SocketAddress& addr, VirtualSocket* socket);
133 
134   // Adds a mapping between this socket pair and the socket.
135   void AddConnection(const SocketAddress& client,
136                      const SocketAddress& server,
137                      VirtualSocket* socket);
138 
139   // Find the socket pair corresponding to this server address.
140   VirtualSocket* LookupConnection(const SocketAddress& client,
141                                   const SocketAddress& server);
142 
143   void RemoveConnection(const SocketAddress& client,
144                         const SocketAddress& server);
145 
146   // Connects the given socket to the socket at the given address
147   int Connect(VirtualSocket* socket, const SocketAddress& remote_addr,
148               bool use_delay);
149 
150   // Sends a disconnect message to the socket at the given address
151   bool Disconnect(VirtualSocket* socket);
152 
153   // Sends the given packet to the socket at the given address (if one exists).
154   int SendUdp(VirtualSocket* socket, const char* data, size_t data_size,
155               const SocketAddress& remote_addr);
156 
157   // Moves as much data as possible from the sender's buffer to the network
158   void SendTcp(VirtualSocket* socket);
159 
160   // Places a packet on the network.
161   void AddPacketToNetwork(VirtualSocket* socket, VirtualSocket* recipient,
162                           uint32 cur_time, const char* data, size_t data_size,
163                           size_t header_size, bool ordered);
164 
165   // Removes stale packets from the network
166   void PurgeNetworkPackets(VirtualSocket* socket, uint32 cur_time);
167 
168   // Computes the number of milliseconds required to send a packet of this size.
169   uint32 SendDelay(uint32 size);
170 
171   // Returns a random transit delay chosen from the appropriate distribution.
172   uint32 GetRandomTransitDelay();
173 
174   // Basic operations on functions.  Those that return a function also take
175   // ownership of the function given (and hence, may modify or delete it).
176   static Function* Accumulate(Function* f);
177   static Function* Invert(Function* f);
178   static Function* Resample(Function* f, double x1, double x2, uint32 samples);
179   static double Evaluate(Function* f, double x);
180 
181   // NULL out our message queue if it goes away. Necessary in the case where
182   // our lifetime is greater than that of the thread we are using, since we
183   // try to send Close messages for all connected sockets when we shutdown.
OnMessageQueueDestroyed()184   void OnMessageQueueDestroyed() { msg_queue_ = NULL; }
185 
186   // Determine if two sockets should be able to communicate.
187   // We don't (currently) specify an address family for sockets; instead,
188   // the currently bound address is used to infer the address family.
189   // Any socket that is not explicitly bound to an IPv4 address is assumed to be
190   // dual-stack capable.
191   // This function tests if two addresses can communicate, as well as the
192   // sockets to which they may be bound (the addresses may or may not yet be
193   // bound to the sockets).
194   // First the addresses are tested (after normalization):
195   // If both have the same family, then communication is OK.
196   // If only one is IPv4 then false, unless the other is bound to ::.
197   // This applies even if the IPv4 address is 0.0.0.0.
198   // The socket arguments are optional; the sockets are checked to see if they
199   // were explicitly bound to IPv6-any ('::'), and if so communication is
200   // permitted.
201   // NB: This scheme doesn't permit non-dualstack IPv6 sockets.
202   static bool CanInteractWith(VirtualSocket* local, VirtualSocket* remote);
203 
204  private:
205   friend class VirtualSocket;
206 
207   typedef std::map<SocketAddress, VirtualSocket*> AddressMap;
208   typedef std::map<SocketAddressPair, VirtualSocket*> ConnectionMap;
209 
210   SocketServer* server_;
211   bool server_owned_;
212   MessageQueue* msg_queue_;
213   bool stop_on_idle_;
214   uint32 network_delay_;
215   in_addr next_ipv4_;
216   in6_addr next_ipv6_;
217   uint16 next_port_;
218   AddressMap* bindings_;
219   ConnectionMap* connections_;
220 
221   uint32 bandwidth_;
222   uint32 network_capacity_;
223   uint32 send_buffer_capacity_;
224   uint32 recv_buffer_capacity_;
225   uint32 delay_mean_;
226   uint32 delay_stddev_;
227   uint32 delay_samples_;
228   Function* delay_dist_;
229   CriticalSection delay_crit_;
230 
231   double drop_prob_;
232   DISALLOW_EVIL_CONSTRUCTORS(VirtualSocketServer);
233 };
234 
235 }  // namespace rtc
236 
237 #endif  // WEBRTC_BASE_VIRTUALSOCKETSERVER_H_
238