helloBye2Proto.hpp
Go to the documentation of this file.
1 #ifndef HELLOBYE2PROTO_HPP
2 #define HELLOBYE2PROTO_HPP
3 
4 #include <mutex>
5 #include <sstream>
6 
7 #include "common.hpp"
8 #include "exceptions.hpp"
9 #include "headers.hpp"
10 #include "stateMachine.hpp"
11 
12 namespace HelloBye2 {
13 
14 struct __attribute__((packed)) msg {
15  uint64_t ident;
16  uint8_t role;
17  uint8_t msg;
18  uint8_t cookie;
19 
20  static constexpr uint8_t ROLE_CLIENT = 0;
21  static constexpr uint8_t ROLE_SERVER = 1;
22 
23  static constexpr uint8_t MSG_HELLO = 0;
24  static constexpr uint8_t MSG_BYE = 1;
25 };
26 
27 /*
28  * ===================================
29  * Identifier
30  * ===================================
31  *
32  */
33 
34 template <typename Packet> class Identifier {
35 public:
36  class ConnectionID {
37  public:
38  uint64_t ident;
39 
40  bool operator==(const ConnectionID &c) const { return ident == c.ident; };
41  bool operator<(const ConnectionID &c) const { return ident < c.ident; };
42  operator std::string() const {
43  std::stringstream sstream;
44  sstream << ident;
45  return sstream.str();
46  };
48  ConnectionID() : ident(0){};
49  ConnectionID(uint64_t i) : ident(i){};
50  };
51  struct Hasher {
52  uint64_t operator()(const ConnectionID &c) const { return c.ident; };
53  };
54  static ConnectionID identify(Packet *pkt) {
55  Headers::Ethernet *eth = reinterpret_cast<Headers::Ethernet *>(pkt->getData());
57  throw new PacketNotIdentified();
58  }
59 
60  Headers::IPv4 *ipv4 = reinterpret_cast<Headers::IPv4 *>(eth->getPayload());
61  if (ipv4->proto != Headers::IPv4::PROTO_UDP) {
62  throw new PacketNotIdentified();
63  }
64 
65  Headers::Udp *udp = reinterpret_cast<Headers::Udp *>(ipv4->getPayload());
66 
67  struct msg *msg = reinterpret_cast<struct msg *>(udp->getPayload());
68  return msg->ident;
69  };
70 };
71 
72 /*
73  * ===================================
74  * Forward declarations
75  * ===================================
76  *
77  */
78 
79 namespace Server {
80 template <class Identifier, class Packet> class Hello;
81 template <class Identifier, class Packet> class Bye;
82 }; // namespace Server
83 
84 namespace Client {
85 template <class Identifier, class Packet> class Hello;
86 template <class Identifier, class Packet> class Bye;
87 template <class Identifier, class Packet> class RecvBye;
88 } // namespace Client
89 
90 /*
91  * ===================================
92  * Client Config
93  * ===================================
94  *
95  */
96 
97 /*
98 class HelloBye2ClientConfig {
99 private:
100  uint32_t srcIp;
101  uint16_t dstPort;
102 
103  static HelloBye2ClientConfig *instance;
104  static std::mutex mtx;
105  HelloBye2ClientConfig() : srcIp(0), dstPort(0){};
106 
107 public:
108  auto getSrcIP() { return srcIp; }
109  auto getDstPort() { return dstPort; }
110 
111  void setSrcIP(uint32_t newIP) { srcIp = newIP; }
112  void setDstPort(uint16_t newPort) { dstPort = newPort; }
113 
114  static void createInstance() {
115  std::lock_guard<std::mutex> lock(mtx);
116  if (instance == nullptr) {
117  instance = new HelloBye2ClientConfig;
118  }
119  }
120 
121  static HelloBye2ClientConfig *getInstance() { return instance; }
122 };
123 */
124 
126 private:
127  uint32_t srcIp;
128  uint16_t dstPort;
129 
130 public:
132  static HelloBye2ClientConfig instance;
133  return instance;
134  }
135 
138  void operator=(HelloBye2ClientConfig const &) = delete;
139 
140  auto getSrcIP() { return srcIp; }
141  auto getDstPort() { return dstPort; }
142 
143  void setSrcIP(uint32_t newIP) { srcIp = newIP; }
144  void setDstPort(uint16_t newPort) { dstPort = newPort; }
145 };
146 
147 /*
148  * ===================================
149  * Server Hello
150  * ===================================
151  *
152  */
153 
154 namespace Server {
155 
156 struct States {
157  static constexpr StateID Hello = 0;
158  static constexpr StateID Bye = 1;
159  static constexpr StateID Terminate = 2;
160 };
161 
162 template <class Identifier, class Packet> class Hello {
164  friend class Bye<Identifier, Packet>;
165 
166 private:
167  uint8_t clientCookie;
168  uint8_t serverCookie;
169 
170 public:
171  Hello();
172 
173  static void *factory(typename Identifier::ConnectionID id) {
174  (void)id;
175  return new Hello();
176  }
177 
178  PROD_INLINE void fun(
179  typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface);
180 
181  static void run(typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface) {
182  Hello *t = reinterpret_cast<Hello *>(state.stateData);
183  t->fun(state, pkt, funIface);
184 
185  // Finish transision to other state
186  if (state.state == States::Bye) {
187  state.stateData = new Bye<Identifier, Packet>(t);
188  delete (t);
189  } else if (state.state == States::Terminate) {
190  delete (t);
191  }
192  }
193 };
194 
195 /*
196  * ===================================
197  * Server Bye
198  * ===================================
199  *
200  */
201 
202 template <class Identifier, class Packet> class Bye {
204 
205 private:
206  int clientCookie;
207  int serverCookie;
208 
209 public:
210  Bye(const Hello<Identifier, Packet> *in);
211 
212  PROD_INLINE void fun(
213  typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface);
214 
215  static void run(typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface) {
216  Bye *t = reinterpret_cast<Bye *>(state.stateData);
217  t->fun(state, pkt, funIface);
218  if (state.state == States::Terminate) {
219  delete (t);
220  }
221  }
222 };
223 
224 }; // namespace Server
225 
226 namespace Client {
227 
228 struct States {
229  static constexpr StateID Hello = 0;
230  static constexpr StateID Bye = 1;
231  static constexpr StateID RecvBye = 2;
232  static constexpr StateID Terminate = 3;
233 };
234 
235 /*
236  * ===================================
237  * Client Hello
238  * ===================================
239  *
240  */
241 
242 template <class Identifier, class Packet> class Hello {
244  friend class Bye<Identifier, Packet>;
245 
246 private:
247  int clientCookie;
248  uint32_t dstIp;
249  uint16_t srcPort;
250  uint64_t ident;
251 
252 public:
253  Hello(uint32_t dstIp, uint16_t srcPort, uint64_t ident);
254 
255  PROD_INLINE void fun(
256  typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface);
257 
258  static void run(typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface) {
259  Hello *t = reinterpret_cast<Hello *>(state.stateData);
260  t->fun(state, pkt, funIface);
261 
262  // Finish transision to other state
263  if (state.state == States::Bye) {
264  state.stateData = new Bye<Identifier, Packet>(t);
265  delete (t);
266  } else if (state.state == States::Terminate) {
267  delete (t);
268  }
269  }
270 };
271 
272 /*
273  * ===================================
274  * Client Bye
275  * ===================================
276  *
277  */
278 
279 template <class Identifier, class Packet> class Bye {
281  friend class RecvBye<Identifier, Packet>;
282 
283 private:
284  int clientCookie;
285  int serverCookie;
286 
287 public:
288  Bye(const Hello<Identifier, Packet> *in);
289 
290  PROD_INLINE void fun(
291  typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface);
292 
293  static void run(typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface) {
294  Bye *t = reinterpret_cast<Bye *>(state.stateData);
295  t->fun(state, pkt, funIface);
296 
297  // Finish transision to other state
298  if (state.state == States::RecvBye) {
299  state.stateData = new RecvBye<Identifier, Packet>(t);
300  delete (t);
301  } else if (state.state == States::Terminate) {
302  delete (t);
303  }
304  }
305 };
306 
307 /*
308  * ===================================
309  * Client RecvBye
310  * ===================================
311  *
312  */
313 
314 template <class Identifier, class Packet> class RecvBye {
316 
317 private:
318  int clientCookie;
319  int serverCookie;
320 
321 public:
322  RecvBye(const Bye<Identifier, Packet> *in);
323 
324  PROD_INLINE void fun(
325  typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface);
326 
327  static void run(typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface) {
328  RecvBye *t = reinterpret_cast<RecvBye *>(state.stateData);
329  t->fun(state, pkt, funIface);
330 
331  if (state.state == States::Terminate) {
332  delete (t);
333  }
334  }
335 };
336 }; // namespace Client
337 }; // namespace HelloBye2
338 
339 /*
340  * YCM definition is a workaround for a libclang bug
341  * When compiling, YCM should never be set.
342  * Set YCM in a libclang based IDE in order to avoid errors
343  */
344 #ifndef YCM
345 #include "../src/helloBye2Proto.cpp"
346 #endif
347 
348 #endif /* HELLOBYEPROTO_HPP */
PROD_INLINE void fun(typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface)
#define PROD_INLINE
Definition: common.hpp:16
static void run(typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface)
static constexpr uint16_t ETHERTYPE_IPv4
Definition: headers.hpp:46
ConnectionID(const ConnectionID &c)
static HelloBye2ClientConfig & getInstance()
static constexpr StateID Terminate
Representation of the IPv4 header.
Definition: headers.hpp:65
void * getPayload()
Get the SDU.
Definition: headers.hpp:149
Bye(const Hello< Identifier, Packet > *in)
Hello(uint32_t dstIp, uint16_t srcPort, uint64_t ident)
Main interface for the needs of a state function.
static constexpr StateID Bye
static constexpr StateID RecvBye
PROD_INLINE void fun(typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface)
static constexpr StateID Terminate
Representation of the etherner header.
Definition: headers.hpp:15
static constexpr StateID Bye
void operator=(HelloBye2ClientConfig const &)=delete
PROD_INLINE void fun(typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface)
Representation of the UDP header.
Definition: headers.hpp:209
void setDstPort(uint16_t newPort)
void * getPayload()
Get the SDU.
Definition: headers.hpp:248
RecvBye(const Bye< Identifier, Packet > *in)
static void run(typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface)
uint16_t getEthertype()
Get the ethertype.
Definition: headers.hpp:44
bool operator<(const ConnectionID &c) const
uint8_t proto
next protocol
Definition: headers.hpp:107
bool operator==(const ConnectionID &c) const
static constexpr uint8_t PROTO_UDP
Definition: headers.hpp:111
uint64_t operator()(const ConnectionID &c) const
static void run(typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface)
static void * factory(typename Identifier::ConnectionID id)
static void run(typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface)
static void run(typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface)
uint16_t StateID
Definition: common.hpp:19
PROD_INLINE void fun(typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface)
static ConnectionID identify(Packet *pkt)
Represents one connection.
PROD_INLINE void fun(typename SM::State &state, Packet *pkt, typename SM::FunIface &funIface)
Bye(const Hello< Identifier, Packet > *in)
void * getPayload()
Get the SDU.
Definition: headers.hpp:23