1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2015 Natale Patriciello <natale.patriciello@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  */
19 #ifndef TCPERRORCHANNEL_H
20 #define TCPERRORCHANNEL_H
21 
22 #include "ns3/error-model.h"
23 #include "ns3/tcp-header.h"
24 #include "ns3/ipv4-header.h"
25 
26 namespace ns3 {
27 
28 /**
29  * \ingroup internet-test
30  * \ingroup tests
31  *
32  * \brief A general (TCP-aware) error model.
33  *
34  * The class is responsible to take away the IP and TCP header from the packet,
35  * and then to interrogate the method ShouldDrop, dropping the packet accordingly
36  * to the returned value.
37  */
38 class TcpGeneralErrorModel : public ErrorModel
39 {
40 public:
41   /**
42    * \brief Get the type ID.
43    * \return the object TypeId
44    */
45   static TypeId GetTypeId (void);
46   TcpGeneralErrorModel ();
47 
48   /**
49    * \brief Set the drop callback.
50    * \param cb The callback to be set.
51    */
SetDropCallback(Callback<void,const Ipv4Header &,const TcpHeader &,Ptr<const Packet>> cb)52   void SetDropCallback (Callback<void, const Ipv4Header&, const TcpHeader&, Ptr<const Packet> > cb)
53   {
54     m_dropCallback = cb;
55   }
56 
57 protected:
58   /**
59    * \brief Check if the packet should be dropped.
60    * \param ipHeader The packet IPv4 header.
61    * \param tcpHeader The packet TCP header.
62    * \param packetSize The packet size.
63    * \returns True if the packet should be dropped.
64    */
65   virtual bool ShouldDrop (const Ipv4Header &ipHeader, const TcpHeader &tcpHeader,
66                            uint32_t packetSize) = 0;
67 
68 
69 private:
70   virtual bool DoCorrupt (Ptr<Packet> p);
71   Callback<void, const Ipv4Header&, const TcpHeader&, Ptr<const Packet> > m_dropCallback; //!< Drop callback.
72 };
73 
74 /**
75  * \ingroup internet-test
76  * \ingroup tests
77  *
78  * \brief An error model TCP aware: it drops the sequence number declared.
79  *
80  * \see AddSeqToKill
81  */
82 class TcpSeqErrorModel : public TcpGeneralErrorModel
83 {
84 public:
85   /**
86    * \brief Get the type ID.
87    * \return the object TypeId
88    */
89   static TypeId GetTypeId (void);
TcpSeqErrorModel()90   TcpSeqErrorModel () : TcpGeneralErrorModel () { }
91 
92   /**
93    * \brief Add the sequence number to the list of segments to be killed
94    *
95    * Calling x times this function indicates that you want to kill
96    * the segment x times.
97    *
98    * \param seq sequence number to be killed
99    */
AddSeqToKill(const SequenceNumber32 & seq)100   void AddSeqToKill (const SequenceNumber32 &seq)
101   {
102     m_seqToKill.insert(m_seqToKill.end(), seq);
103   }
104 
105 protected:
106   virtual bool ShouldDrop (const Ipv4Header &ipHeader, const TcpHeader &tcpHeader,
107                            uint32_t packetSize);
108 
109 protected:
110   std::list<SequenceNumber32> m_seqToKill; //!< List of the sequence numbers to be dropped.
111 
112 private:
113   virtual void DoReset (void);
114 };
115 
116 /**
117  * \ingroup internet-test
118  * \ingroup tests
119  *
120  * \brief Error model which drop packets with specified TCP flags.
121  *
122  * Set the flags with SetFlagToKill and the number of the packets with such flags
123  * which should be killed.
124  *
125  * \see SetFlagToKill
126  * \see SetKillRepeat
127  *
128  */
129 class TcpFlagErrorModel : public TcpGeneralErrorModel
130 {
131 public:
132   /**
133    * \brief Get the type ID.
134    * \return the object TypeId
135    */
136   static TypeId GetTypeId (void);
137   TcpFlagErrorModel ();
138 
139   /**
140    * \brief Set the flags of the segment that should be killed
141    *
142    * \param flags Flags
143    */
SetFlagToKill(TcpHeader::Flags_t flags)144   void SetFlagToKill (TcpHeader::Flags_t flags)
145   {
146     m_flagsToKill = flags;
147   }
148 
149   /**
150    * \brief Set how many packets should be killed
151    *
152    * If the flags are the same, this specified the numbers of drops:
153    *
154    * # -1 for infinite drops
155    * # 0  for no drops
156    * # >1 the number of drops
157    *
158    * \param killNumber Specifies the number of times the packet should be killed
159    */
SetKillRepeat(int16_t killNumber)160   void SetKillRepeat (int16_t killNumber)
161   {
162     m_killNumber = killNumber;
163   }
164 
165 protected:
166   virtual bool ShouldDrop (const Ipv4Header &ipHeader, const TcpHeader &tcpHeader,
167                            uint32_t packetSize);
168 
169 protected:
170   TcpHeader::Flags_t m_flagsToKill; //!< Flags a packet should have to be dropped.
171   int16_t m_killNumber;  //!< The number of times the packet should be killed.
172 
173 private:
174   virtual void DoReset (void);
175 };
176 
177 } // namespace ns3
178 
179 #endif // TCPERRORCHANNEL_H
180