TunnelController.hh
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
17 #ifndef HH_SENF_Ext_NetEmu_P2PTunnel_TunnelController_
18 #define HH_SENF_Ext_NetEmu_P2PTunnel_TunnelController_ 1
19 
20 // Custom includes
21 #include <boost/multi_index_container.hpp>
22 #include <boost/multi_index/ordered_index.hpp>
31 
32 //-/////////////////////////////////////////////////////////////////////////////////////////////////
33 namespace senf {
34 namespace emu {
35 
36  // forward declarations:
37  class TunnelInterfaceBase;
38  class TunnelServerInterface;
39  class TunnelClientInterface;
40 
43 
44  namespace tunnel {
46  typedef std::map<CapacityDirection, unsigned> Capacity;
47  }
48 
49 namespace detail {
50 
52  {
54 
55  unsigned rxPackets;
56  unsigned rxData;
57  unsigned rxControl;
58  unsigned rxIgnored;
59 
60  unsigned txPackets;
61  unsigned txSent;
62  unsigned txError;
63  unsigned txOverrun;
64  unsigned txDSQDropped;
65 
67  void reset();
68  senf::ClockService::clock_type duration() const;
69  TunnelIOStatistics stats();
70  void dump(std::ostream & os) const;
71  std::string dump() const;
72  };
73 
75  {
76  public:
77  // The tunnel's MAC header must be accounted for, as it counts as payload in this case, while the Ethernet Fragmenter would exclude it
78  static const unsigned TunnelOverhead = 46u; // IPv4 (20) + UDP (8) + TunnelHeader (4) + Tunnel MAC (14)
79 
82 
83  PacketType readPacket(Handle & handle);
84  bool writePacket(Handle & handle, PacketType packet);
85 
86  ClockService::clock_type timeout() const;
87  void timeout(ClockService::clock_type t);
88 
89  ppi::QueueingAlgorithm & qAlgorithm() const;
90  void qAlgorithm(ppi::QueueingAlgorithm::ptr qAlgorithm);
91 
92  void dumpInfo(std::ostream & os);
93 
94  unsigned fragmentationCount();
95 
96  protected:
98  virtual ~TunnelControllerBase() {};
99 
100  bool sendPkt(Handle & handle, MACAddress const & dstMAC, senf::EthernetPacket pkt);
101  void do_sendPkt(Handle & handle, senf::EthernetPacket & pkt, std::pair<senf::INet6SocketAddress,unsigned> const & txInfo);
102  void do_sendPkt(Handle & handle, senf::EthernetPacket & pkt);
103  void flushQueue(Handle & handle);
104 
105  static bool isTunnelCtrlPacket(EthernetPacket const & eth);
106  void sendCtrlPacket(Handle & handle, MACAddress const & dstMAC, boost::uint8_t code);
107  void sendCtrlPacket(Handle & handle, MACAddress const & dstMAC, TunnelCtrlPacket ctrlPacket);
108 
109  virtual void v_prependTHdr(EthernetPacket & eth) = 0;
110  virtual std::pair<INet6SocketAddress,unsigned> v_getTxInfo(Packet const & eth) const = 0;
111 
112  private:
113  virtual void v_handleCtrlPacket(EthernetPacket const & ctrlPacket, INet6SocketAddress const & srcAddr, Handle & handle) = 0;
114  virtual signed v_processSequenceNumber(TunnelHeaderPacket const & thdr, INet6SocketAddress const & srcAddr) = 0;
115  virtual bool v_writePacket(Handle & handle, PacketType & packet) = 0;
116  virtual void v_dumpInfo(std::ostream & os) const = 0;
117  virtual void v_timeoutChanged() {};
118 
119  ClockService::clock_type timeout_;
120  TunnelInterfaceBase & interface_;
121  boost::scoped_ptr<ppi::QueueingAlgorithm> qAlgo_;
122  EthernetFragmenter fragmenter_;
123  EthernetReassembler reassembler_;
124  TunnelIOStatistics stats_;
125  protected:
127  };
128 
129 
131  : public TunnelControllerBase
132  {
133  public:
135 
138  void terminateAllClients(Handle handle);
139  unsigned capacity(MACAddress const & clientAddr, tunnel::CapacityDirection direction) const;
140 
141  unsigned fragmentationThreshold(MACAddress const & clientAddr) const;
142  void fragmentationThreshold(MACAddress const & clientAddr, unsigned mtu);
143 
144  protected:
145  void v_prependTHdr(EthernetPacket & eth) override;
146  std::pair<INet6SocketAddress,unsigned> v_getTxInfo(Packet const & eth) const override;
147 
148  private:
149  void v_handleCtrlPacket(EthernetPacket const & ctrlPacket, INet6SocketAddress const & srcAddr, Handle & handle) override;
150  signed v_processSequenceNumber(TunnelHeaderPacket const & thdr, INet6SocketAddress const & srcAddr) override;
151  bool v_writePacket(Handle & handle, PacketType & packet) override;
152  void v_dumpInfo(std::ostream & os) const override;
153  void sendSetupRequest();
154  void processTimeout();
155  void resetTimer();
156 
157  struct TunnelClient
158  {
159  MACAddress macAddr;
160  INet6SocketAddress inetAddr;
162  tunnel::Capacity capacity;
163  unsigned txSeqNo;
164  unsigned rxSeqNo;
165  unsigned reSyncs;
166  unsigned fragmentationThreshold;
167 
168  struct incrTxSeqNo {
169  void operator()(TunnelClient & client){
170  client.txSeqNo = (client.txSeqNo + 1) % 0x20000;
171  }
172  };
173  struct incReSyncs {
174  void operator()(TunnelClient & client){
175  client.reSyncs++;
176  }
177  };
178  struct updateRxSeqNo {
179  unsigned seqno;
180  updateRxSeqNo(unsigned _seqno)
181  : seqno(_seqno) {} ;
182  void operator()(TunnelClient & client){
183  client.rxSeqNo = seqno;
184  }
185  };
188  updateFragmentationThreshold(unsigned _fragmentationThreshold)
189  : fragmentationThreshold(_fragmentationThreshold) {} ;
190  void operator()(TunnelClient & client){
191  client.fragmentationThreshold = fragmentationThreshold;
192  }
193  };
194  struct updateLastSeen {
195  void operator()(TunnelClient & client) {
196  client.lastSeen = scheduler::now();
197  }
198  };
199  struct updateInetAddr {
202  : inetAddr(_inetAddr) {}
203  void operator()(TunnelClient & client) {
204  client.inetAddr = inetAddr;
205  }
206  };
207  struct updateCapacity {
209  unsigned capacity;
210  updateCapacity(tunnel::CapacityDirection _direction, unsigned _capacity)
211  : direction(_direction), capacity(_capacity) {}
212  void operator()(TunnelClient & client) {
213  client.capacity[direction] = capacity;
214  }
215  };
216 
217  TunnelClient(MACAddress const & _macAddr, INet6SocketAddress const & _inetAddr)
218  : macAddr(_macAddr), inetAddr(_inetAddr), lastSeen(scheduler::now()), txSeqNo(0), rxSeqNo(0xffffffff), reSyncs(0),
219  fragmentationThreshold(1280u) {}
220  };
221 
222  struct ByLastSeen {};
223  struct ByINetAddr {};
224  struct ByMACAddr {};
225  struct ClientIndexes
226  : public boost::multi_index::indexed_by<
227  boost::multi_index::ordered_non_unique<
228  boost::multi_index::tag<ByLastSeen>,
229  BOOST_MULTI_INDEX_MEMBER(TunnelClient, ClockService::clock_type, lastSeen)>,
230  boost::multi_index::ordered_unique<
231  boost::multi_index::tag<ByMACAddr>,
232  BOOST_MULTI_INDEX_MEMBER(TunnelClient, MACAddress, macAddr)>,
233  boost::multi_index::ordered_unique<
234  boost::multi_index::tag<ByINetAddr>,
235  BOOST_MULTI_INDEX_MEMBER(TunnelClient, INet6SocketAddress, inetAddr)> >
236  {};
237 
238  typedef boost::multi_index_container<TunnelClient, ClientIndexes> Clients;
239  typedef Clients::index<ByLastSeen>::type Clients_by_lastSeen;
240  typedef Clients::index<ByMACAddr>::type Clients_by_macAddr;
241  typedef Clients::index<ByINetAddr>::type Clients_by_inetAddr;
242 
243  Clients clients_;
244  Clients_by_lastSeen & clients_by_lastSeen_;
245  Clients_by_macAddr & clients_by_macAddr_;
246  Clients_by_inetAddr & clients_by_inetAddr_;
247 
248  scheduler::TimerEvent timer_;
249  };
250 
251 
253  : public TunnelControllerBase
254  {
255  public:
257 
260 
261  bool established() const;
262  void reset();
263 
264  void serverAddress(INet6SocketAddress const & address);
265  INet6SocketAddress const & serverAddress() const;
266 
267  unsigned fragmentationThreshold() const;
268  void fragmentationThreshold(unsigned mtu);
269 
270  protected:
271  void v_prependTHdr(EthernetPacket & eth) override;
272  std::pair<INet6SocketAddress,unsigned> v_getTxInfo(Packet const & eth) const override;
273 
274  private:
275  void v_handleCtrlPacket(EthernetPacket const & ctrlPacket, INet6SocketAddress const & srcAddr, Handle & handle) override;
276  signed v_processSequenceNumber(TunnelHeaderPacket const & thdr, INet6SocketAddress const & srcAddr) override;
277  bool v_writePacket(Handle & handle, PacketType & packet) override;
278  void v_dumpInfo(std::ostream & os) const override;
279  void v_timeoutChanged() override;
280  void sendSetupRequest();
281  void processTimeout();
282 
283  TunnelClientInterface & interface_;
284  bool established_;
285  scheduler::TimerEvent timer_;
286  ClockService::clock_type echoInterval_;
287  ClockService::clock_type serverLastSeen_;
288  senf::MACAddress serverMAC_;
289  INet6SocketAddress serverINet_;
290  unsigned txSeqNo_;
291  unsigned rxSeqNo_;
292  unsigned fragmentationThreshold_;
293  unsigned setupRequests_;
294  unsigned reSyncs_;
295  unsigned reordered_;
296  unsigned duplicate_;
297  };
298 
299 }}}
300 
301 //-/////////////////////////////////////////////////////////////////////////////////////////////////
302 #endif
303 
304 
305 // Local Variables:
306 // mode: c++
307 // fill-column: 100
308 // comment-column: 40
309 // c-file-style: "senf"
310 // indent-tabs-mode: nil
311 // ispell-local-dictionary: "american"
312 // compile-command: "scons -u test"
313 // End:
config::time_type clock_type
std::map< CapacityDirection, unsigned > Capacity
u8 type
ProtocolClientSocketHandle< UDPv6SocketProtocol > UDPv6ClientSocketHandle
std::uint32_t lastSeen
std::unique_ptr< QueueingAlgorithm > ptr
senf::ClockService::clock_type tstamp
void dump(std::ostream &os, DirectoryNode &dir=root())
SENF_PACKET_FWD_DECL(TunnelCtrlPacket)
Tunnel Server Interface.
senf::Detail::DifferenceSigned seqNoDiff_
updateCapacity(tunnel::CapacityDirection _direction, unsigned _capacity)
ConcretePacket< TunnelCtrlPacketType > TunnelCtrlPacket
ConcretePacket< EthernetPacketType > EthernetPacket
senf::ConcretePacket< TunnelHeaderPacketType > TunnelHeaderPacket