helloBye3MemPool.cpp
Go to the documentation of this file.
1 #ifndef HELLOBYE3PROTO_CPP
2 #define HELLOBYE3PROTO_CPP
3 
4 #include <cstdlib>
5 #include <sstream>
6 #include <stdexcept>
7 
8 #include <rte_errno.h>
9 #include <rte_mempool.h>
10 
11 #include "IPv4_5TupleL2Ident.hpp"
12 #include "headers.hpp"
13 #include "helloBye3MemPool.hpp"
14 #include "mbuf.hpp"
15 #include "samplePacket.hpp"
16 
17 // using namespace Headers;
18 // using namespace std;
19 
20 namespace HelloBye3MemPool {
21 
22 namespace Server {
23 
24 static struct rte_mempool *mempool;
25 static std::mutex mempoolMtx;
26 
28  (void)id;
29  struct server *s;
30  if (rte_mempool_get(mempool, reinterpret_cast<void **>(&s)) != 0) {
31  throw std::runtime_error("HelloBye3MemPool::Server::factory() mempool is empty");
32  }
33  s->serverCookie = rand() % 256;
34  s->clientCookie = 0;
35  return s;
36 };
37 
38 void runHello(StateMachine<Identifier<mbuf>, mbuf>::State &state, mbuf *pkt,
39  StateMachine<Identifier<mbuf>, mbuf>::FunIface &funIface) {
40 
41  server *s = reinterpret_cast<struct server *>(state.stateData);
42 
43  // Get info from packet
44  Headers::Ethernet *ether = reinterpret_cast<Headers::Ethernet *>(pkt->getData());
45  Headers::IPv4 *ipv4 = reinterpret_cast<Headers::IPv4 *>(ether->getPayload());
46  Headers::Udp *udp = reinterpret_cast<Headers::Udp *>(ipv4->getPayload());
47 
48  struct msg *msg = reinterpret_cast<struct msg *>(udp->getPayload());
49 
50  D(std::cout << "HelloBye3MemPool::Server::runHello() pkt: " << (void *)pkt->getData()
51  << ", ident: " << msg->ident << std::endl;)
52 
53  if (msg->role != 0) {
54  // std::abort();
55  std::cout
56  << "HelloBye3MemPool::Server::runHello() client hello wrong - role not client"
57  << std::endl;
58  funIface.transition(States::Terminate);
59  rte_mempool_put(mempool, reinterpret_cast<void *>(s));
60  funIface.freePkt();
61  return;
62  }
63 
64  if (msg->msg != 0) {
65  // std::abort();
66  std::cout << "HelloBye3MemPool::Server::runHello() client hello wrong - msg not hello"
67  << std::endl;
68  funIface.transition(States::Terminate);
69  rte_mempool_put(mempool, reinterpret_cast<void *>(s));
70  funIface.freePkt();
71  return;
72  }
73 
74  // Get client cookie
75  s->clientCookie = msg->cookie;
76  D(std::cout << "HelloBye3MemPool::Server::runHello() clientCookie: "
77  << static_cast<int>(s->clientCookie) << std::endl;)
78 
81  msg->cookie = s->serverCookie;
82 
83  // Set the IP header stuff
84  // Leave the payload length alone for now...
85 
86  ipv4->ttl = 64;
87  uint32_t tmp = ipv4->dstIP;
88  ipv4->dstIP = ipv4->srcIP;
89  ipv4->srcIP = tmp;
90  ipv4->checksum = 0;
91 
92  // Set UDP checksum to 0 and hope for the best
93 
94  udp->checksum = 0;
95  uint16_t tmp16 = udp->dstPort;
96  udp->dstPort = udp->srcPort;
97  udp->srcPort = tmp16;
98 
99  funIface.transition(States::Bye);
100 };
101 
102 void runBye(StateMachine<Identifier<mbuf>, mbuf>::State &state, mbuf *pkt,
103  StateMachine<Identifier<mbuf>, mbuf>::FunIface &funIface) {
104 
105  server *s = reinterpret_cast<struct server *>(state.stateData);
106 
107  // Get info from packet
108  Headers::Ethernet *ether = reinterpret_cast<Headers::Ethernet *>(pkt->getData());
109  Headers::IPv4 *ipv4 = reinterpret_cast<Headers::IPv4 *>(ether->getPayload());
110  Headers::Udp *udp = reinterpret_cast<Headers::Udp *>(ipv4->getPayload());
111 
112  struct msg *msg = reinterpret_cast<struct msg *>(udp->getPayload());
113 
114  if ((msg->role != msg::ROLE_CLIENT) || (msg->msg != msg::MSG_BYE)) {
115  std::cout << "HelloBye3MemPool::Server::runBye() msg fields wrong" << std::endl;
116  funIface.transition(States::Terminate);
117  rte_mempool_put(mempool, reinterpret_cast<void *>(s));
118  funIface.freePkt();
119  return;
120  }
121 
122  if (msg->cookie != s->serverCookie) {
123  std::cout << "HelloBye3MemPool::Server::runBye() Client sent over wrong cookie"
124  << std::endl;
125  funIface.transition(States::Terminate);
126  rte_mempool_put(mempool, reinterpret_cast<void *>(s));
127  funIface.freePkt();
128  return;
129  }
130 
131  // Prepare new packet
132  msg->cookie = s->clientCookie;
134  msg->msg = msg::MSG_BYE;
135 
136  // Set the IP header stuff
137  // Leave the payload length alone for now...
138  ipv4->ttl = 64;
139  uint32_t tmp = ipv4->dstIP;
140  ipv4->dstIP = ipv4->srcIP;
141  ipv4->srcIP = tmp;
142  ipv4->checksum = 0;
143 
144  // Set UDP checksum to 0 and hope for the best
145  udp->checksum = 0;
146  uint16_t tmp16 = udp->dstPort;
147  udp->dstPort = udp->srcPort;
148  udp->srcPort = tmp16;
149 
150  // We are done after this -> transition to Terminate
151  funIface.transition(States::Terminate);
152  rte_mempool_put(mempool, reinterpret_cast<void *>(s));
153 };
154 }; // namespace Server
155 
156 namespace Client {
157 
158 static struct rte_mempool *mempool;
159 static std::mutex mempoolMtx;
160 
162  uint32_t srcIp, uint32_t dstIp, uint16_t srcPort, uint16_t dstPort, uint64_t ident) {
163 
164  struct client *c;
165  if (rte_mempool_get(mempool, reinterpret_cast<void **>(&c)) != 0) {
166  throw std::runtime_error("HelloBye3MemPool::Client::createHello() mempool is empty");
167  }
168 
169  c->srcIp = srcIp;
170  c->dstIp = dstIp;
171  c->srcPort = srcPort;
172  c->dstPort = dstPort;
173  c->ident = ident;
174  c->clientCookie = rand() % 256;
175  c->serverCookie = 0;
176 
177  StateMachine<Identifier<mbuf>, mbuf>::State state(
178  States::Hello, reinterpret_cast<void *>(c));
179  return state;
180 };
181 
182 void runHello(StateMachine<Identifier<mbuf>, mbuf>::State &state, mbuf *pkt,
183  StateMachine<Identifier<mbuf>, mbuf>::FunIface &funIface) {
184 
185  client *c = reinterpret_cast<struct client *>(state.stateData);
186 
187  memset(pkt->getData(), 0, pkt->getDataLen());
188 
189  // Get info from packet
190  Headers::Ethernet *ether = reinterpret_cast<Headers::Ethernet *>(pkt->getData());
191  Headers::IPv4 *ipv4 = reinterpret_cast<Headers::IPv4 *>(ether->getPayload());
192 
193  // Set the IP header stuff
194  // Leave the payload length alone for now...
195  ipv4->setVersion();
196  ipv4->setIHL(5);
197  ipv4->ttl = 64;
198  ipv4->setLength(100 - 14);
199  ipv4->setDstIP(c->dstIp);
200  ipv4->setSrcIP(c->srcIp);
201  ipv4->setProtoUDP();
202  ipv4->checksum = 0;
203 
204  Headers::Udp *udp = reinterpret_cast<Headers::Udp *>(ipv4->getPayload());
205  struct msg *msg = reinterpret_cast<struct msg *>(udp->getPayload());
206 
207  // Prepare msg
208  msg->ident = c->ident;
210  msg->cookie = c->clientCookie;
212 
213  ether->ethertype = htons(0x0800);
214 
215  // Set UDP checksum to 0 and hope for the best
216  udp->checksum = 0;
217  udp->setDstPort(c->dstPort);
218  udp->setSrcPort(c->srcPort);
219  udp->setPayloadLength(50);
220 
221  funIface.transition(States::Bye);
222 };
223 
224 void runBye(StateMachine<Identifier<mbuf>, mbuf>::State &state, mbuf *pkt,
225  StateMachine<Identifier<mbuf>, mbuf>::FunIface &funIface) {
226 
227  client *c = reinterpret_cast<struct client *>(state.stateData);
228 
229  // Get info from packet
230  Headers::Ethernet *ether = reinterpret_cast<Headers::Ethernet *>(pkt->getData());
231  Headers::IPv4 *ipv4 = reinterpret_cast<Headers::IPv4 *>(ether->getPayload());
232  Headers::Udp *udp = reinterpret_cast<Headers::Udp *>(ipv4->getPayload());
233 
234  struct msg *msg = reinterpret_cast<struct msg *>(udp->getPayload());
235 
236  D(std::cout << "HelloBye3MemPool::Client::runBye() function called, ident:" << msg->ident
237  << std::endl;)
238 
239  if ((msg->role != msg::ROLE_SERVER) || (msg->msg != msg::MSG_HELLO)) {
240  std::cout << "HelloBye3MemPool::Client::runBye() msg fields wrong" << std::endl;
241  funIface.transition(States::Terminate);
242  rte_mempool_put(mempool, reinterpret_cast<void *>(c));
243  funIface.freePkt();
244  return;
245  }
246 
247  // Get server cookie
248  c->serverCookie = msg->cookie;
249 
250  msg->cookie = c->serverCookie;
252  msg->msg = msg::MSG_BYE;
253 
254  // Set the IP header stuff
255  // Leave the payload length alone for now...
256  ipv4->ttl = 64;
257  uint32_t tmp = ipv4->dstIP;
258  ipv4->dstIP = ipv4->srcIP;
259  ipv4->srcIP = tmp;
260  ipv4->checksum = 0;
261 
262  // Set UDP checksum to 0 and hope for the best
263  udp->checksum = 0;
264  uint16_t tmp16 = udp->dstPort;
265  udp->dstPort = udp->srcPort;
266  udp->srcPort = tmp16;
267 
268  D(std::cout << "HelloBye3MemPool::Client::runBye() Dump of outgoing packet" << std::endl;)
269  D(hexdump(pkt->getData(), 64);)
270 
271  // We need to wait for the server reply
272  funIface.transition(States::RecvBye);
273 };
274 
275 void runRecvBye(StateMachine<Identifier<mbuf>, mbuf>::State &state, mbuf *pkt,
276  StateMachine<Identifier<mbuf>, mbuf>::FunIface &funIface) {
277 
278  client *c = reinterpret_cast<struct client *>(state.stateData);
279 
280  // Get info from packet
281  Headers::Ethernet *ether = reinterpret_cast<Headers::Ethernet *>(pkt->getData());
282  Headers::IPv4 *ipv4 = reinterpret_cast<Headers::IPv4 *>(ether->getPayload());
283  Headers::Udp *udp = reinterpret_cast<Headers::Udp *>(ipv4->getPayload());
284 
285  struct msg *msg = reinterpret_cast<struct msg *>(udp->getPayload());
286 
287  if ((msg->role != msg::ROLE_SERVER) || (msg->msg != msg::MSG_BYE)) {
288  std::cout << "HelloBye3MemPool::Client::runRecvBye() msg fields wrong" << std::endl;
289  funIface.transition(States::Terminate);
290  rte_mempool_put(mempool, reinterpret_cast<void *>(c));
291  funIface.freePkt();
292  return;
293  }
294 
295  if (msg->cookie != c->clientCookie) {
296  std::cout << "HelloBye3MemPool::Client::runRecvBye() Server sent over wrong cookie"
297  << std::endl;
298  std::cout << "Expected: " << static_cast<int>(c->clientCookie);
299  std::cout << ", Got: " << static_cast<int>(msg->cookie) << std::endl;
300  funIface.transition(States::Terminate);
301  rte_mempool_put(mempool, reinterpret_cast<void *>(c));
302  funIface.freePkt();
303  return;
304  }
305 
306  funIface.freePkt();
307 
308  // We are done after this -> transition to Terminate
309  funIface.transition(States::Terminate);
310  rte_mempool_put(mempool, reinterpret_cast<void *>(c));
311 };
312 }; // namespace Client
313 }; // namespace HelloBye3MemPool
314 
315 extern "C" {
316 
317 /*
318  * Server
319  */
320 
322 
323  srand(time(NULL));
324 
325  HelloBye3MemPool::Server::mempoolMtx.lock();
326  if (HelloBye3MemPool::Server::mempool == nullptr) {
327  HelloBye3MemPool::Server::mempool = rte_mempool_create("Server MemPool", 8192,
328  sizeof(HelloBye3MemPool::Server::server), 128, 0, NULL, NULL, NULL, NULL,
329  SOCKET_ID_ANY, 0);
330  if (HelloBye3MemPool::Server::mempool == nullptr) {
331  std::cout << "HelloBye3MemPool_Server_init() mempool creation failed"
332  << std::endl;
333  std::cout << "Error: " << rte_strerror(rte_errno) << std::endl;
334  std::abort();
335  }
336  }
337  HelloBye3MemPool::Server::mempoolMtx.unlock();
338 
340 
341  obj->registerEndStateID(HelloBye3MemPool::Server::States::Terminate);
342  obj->registerStartStateID(
344 
345  obj->registerFunction(
347  obj->registerFunction(
349 
350  return obj;
351 };
352 
353 void *HelloBye3MemPool_Server_process(void *obj, struct rte_mbuf **inPkts,
354  unsigned int inCount, unsigned int *sendCount, unsigned int *freeCount) {
355 
356  BufArray<mbuf> *inPktsBA =
357  new BufArray<mbuf>(reinterpret_cast<mbuf **>(inPkts), inCount, true);
358 
359  auto *sm =
360  reinterpret_cast<StateMachine<HelloBye3MemPool::Identifier<mbuf>, mbuf> *>(obj);
361  sm->runPktBatch(*inPktsBA);
362  *sendCount = inPktsBA->getSendCount();
363  *freeCount = inPktsBA->getFreeCount();
364 
365  return inPktsBA;
366 };
367 
369  void *obj, struct rte_mbuf **sendPkts, struct rte_mbuf **freePkts) {
370  BufArray<mbuf> *inPktsBA = reinterpret_cast<BufArray<mbuf> *>(obj);
371 
372  inPktsBA->getSendBufs(reinterpret_cast<mbuf **>(sendPkts));
373  inPktsBA->getFreeBufs(reinterpret_cast<mbuf **>(freePkts));
374 
375  delete (inPktsBA);
376 };
377 
379  delete (reinterpret_cast<StateMachine<HelloBye3MemPool::Identifier<mbuf>, mbuf> *>(obj));
380  rte_mempool_free(HelloBye3MemPool::Server::mempool);
381 };
382 
383 /*
384  * Client
385  */
386 
388 
389  srand(time(NULL));
390 
391  HelloBye3MemPool::Client::mempoolMtx.lock();
392  if (HelloBye3MemPool::Client::mempool == nullptr) {
393  HelloBye3MemPool::Client::mempool = rte_mempool_create("Client MemPool", 8192,
394  sizeof(HelloBye3MemPool::Client::client), 128, 0, NULL, NULL, NULL, NULL,
395  SOCKET_ID_ANY, 0);
396  if (HelloBye3MemPool::Client::mempool == nullptr) {
397  std::cout << "HelloBye3MemPool_Client_init() mempool creation failed"
398  << std::endl;
399  std::cout << "Error: " << rte_strerror(rte_errno) << std::endl;
400  std::abort();
401  }
402  }
403  HelloBye3MemPool::Client::mempoolMtx.unlock();
404 
406 
407  obj->registerEndStateID(HelloBye3MemPool::Client::States::Terminate);
408 
409  obj->registerFunction(
411  obj->registerFunction(
413  obj->registerFunction(
415 
416  return obj;
417 };
418 
419 void *HelloBye3MemPool_Client_connect(void *obj, struct rte_mbuf **inPkts,
420  unsigned int inCount, unsigned int *sendCount, unsigned int *freeCount, uint32_t srcIP,
421  uint32_t dstIP, uint16_t srcPort, uint16_t dstPort, uint64_t ident) {
422 
423  auto *sm =
424  reinterpret_cast<StateMachine<HelloBye3MemPool::Identifier<mbuf>, mbuf> *>(obj);
425 
426  BufArray<mbuf> *inPktsBA =
427  new BufArray<mbuf>(reinterpret_cast<mbuf **>(inPkts), inCount, true);
428 
430  cID.ident = ident;
431 
432  auto state = HelloBye3MemPool::Client::createHello(srcIP, dstIP, srcPort, dstPort, ident);
433 
434  sm->addState(cID, state, *inPktsBA);
435 
436  *sendCount = inPktsBA->getSendCount();
437  *freeCount = inPktsBA->getFreeCount();
438 
439  return inPktsBA;
440 };
441 
443  void *obj, struct rte_mbuf **sendPkts, struct rte_mbuf **freePkts) {
444  BufArray<mbuf> *inPktsBA = reinterpret_cast<BufArray<mbuf> *>(obj);
445 
446  inPktsBA->getSendBufs(reinterpret_cast<mbuf **>(sendPkts));
447  inPktsBA->getFreeBufs(reinterpret_cast<mbuf **>(freePkts));
448 
449  delete (inPktsBA);
450 };
451 
452 void *HelloBye3MemPool_Client_process(void *obj, struct rte_mbuf **inPkts,
453  unsigned int inCount, unsigned int *sendCount, unsigned int *freeCount) {
454  BufArray<mbuf> *inPktsBA =
455  new BufArray<mbuf>(reinterpret_cast<mbuf **>(inPkts), inCount, true);
456 
457  auto *sm =
458  reinterpret_cast<StateMachine<HelloBye3MemPool::Identifier<mbuf>, mbuf> *>(obj);
459  sm->runPktBatch(*inPktsBA);
460  *sendCount = inPktsBA->getSendCount();
461  *freeCount = inPktsBA->getFreeCount();
462 
463  return inPktsBA;
464 };
465 
467  delete (reinterpret_cast<StateMachine<HelloBye3MemPool::Identifier<mbuf>, mbuf> *>(obj));
468  rte_mempool_free(HelloBye3MemPool::Client::mempool);
469 };
470 };
471 #endif /* HELLOBYE3PROTO_CPP */
static constexpr StateID Terminate
uint16_t checksum
header checksum
Definition: headers.hpp:122
void * HelloBye3MemPool_Client_init()
Init a HelloBye client.
void setSrcIP(uint32_t ip)
Set the source ip.
Definition: headers.hpp:129
void setProtoUDP()
Set the protocol to UDP.
Definition: headers.hpp:120
uint16_t getDataLen()
Definition: mbuf.hpp:11
Representation of the IPv4 header.
Definition: headers.hpp:65
State machine framework.
StateMachine< Identifier< mbuf >, mbuf >::State createHello(uint32_t srcIp, uint32_t dstIp, uint16_t srcPort, uint16_t dstPort, uint64_t ident)
uint32_t dstIP
destination IPv4 address
Definition: headers.hpp:124
void HelloBye3MemPool_Client_getPkts(void *obj, struct rte_mbuf **sendPkts, struct rte_mbuf **freePkts)
Get the packets to send and free.
void * getPayload()
Get the SDU.
Definition: headers.hpp:149
uint8_t ttl
Time to live.
Definition: headers.hpp:106
void setSrcPort(uint16_t p)
Set the source port.
Definition: headers.hpp:218
void runBye(StateMachine< Identifier< mbuf >, mbuf >::State &state, mbuf *pkt, StateMachine< Identifier< mbuf >, mbuf >::FunIface &funIface)
void runRecvBye(StateMachine< Identifier< mbuf >, mbuf >::State &state, mbuf *pkt, StateMachine< Identifier< mbuf >, mbuf >::FunIface &funIface)
void setDstIP(uint32_t ip)
Set the destination ip.
Definition: headers.hpp:134
static constexpr StateID Bye
void runBye(StateMachine< Identifier< mbuf >, mbuf >::State &state, mbuf *pkt, StateMachine< Identifier< mbuf >, mbuf >::FunIface &funIface)
void * HelloBye3MemPool_Server_process(void *obj, struct rte_mbuf **inPkts, unsigned int inCount, unsigned int *sendCount, unsigned int *freeCount)
Process a batch of packets.
uint32_t getFreeCount() const
Get the number of packets currently marked as free.
Definition: bufArray.hpp:166
Representation of the etherner header.
Definition: headers.hpp:15
uint32_t srcIP
source IPv4 address
Definition: headers.hpp:123
void setIHL(uint8_t len)
Sets the IP header length.
Definition: headers.hpp:81
void setDstPort(uint16_t p)
Set the destination port.
Definition: headers.hpp:223
static constexpr uint8_t MSG_HELLO
void hexdump(const void *data, int dataLen)
Dump hex data.
Definition: hexdump.cpp:12
Representation of the UDP header.
Definition: headers.hpp:209
void * getPayload()
Get the SDU.
Definition: headers.hpp:248
static constexpr uint8_t MSG_BYE
static constexpr StateID RecvBye
void HelloBye3MemPool_Client_free(void *obj)
Free recources used by the state machine.
#define D(x)
Definition: common.hpp:10
void * HelloBye3MemPool_Client_process(void *obj, struct rte_mbuf **inPkts, unsigned int inCount, unsigned int *sendCount, unsigned int *freeCount)
Process a batch of packets.
void HelloBye3MemPool_Server_free(void *obj)
Free recources used by the state machine.
uint16_t srcPort
Source port.
Definition: headers.hpp:210
void * HelloBye3MemPool_Server_init()
Init a HelloBye server.
void runHello(StateMachine< Identifier< mbuf >, mbuf >::State &state, mbuf *pkt, StateMachine< Identifier< mbuf >, mbuf >::FunIface &funIface)
static constexpr uint8_t ROLE_CLIENT
uint32_t getSendCount() const
Get the number of packets currently marked as send.
Definition: bufArray.hpp:151
void setPayloadLength(uint16_t length)
Set the length of the L4-SDU (UDP payload)
Definition: headers.hpp:243
uint16_t dstPort
Destination port.
Definition: headers.hpp:211
Wrapper aroung DPDK rte_mbuf.
Definition: mbuf.hpp:9
static constexpr StateID Hello
static constexpr uint8_t ROLE_SERVER
static constexpr StateID Terminate
void getSendBufs(Packet **sendBufs) const
Get all the packets which are to be sent.
Definition: bufArray.hpp:175
void HelloBye3MemPool_Server_getPkts(void *obj, struct rte_mbuf **sendPkts, struct rte_mbuf **freePkts)
Get the packets to send and free.
void getFreeBufs(Packet **freeBufs) const
Get all the packets which are to be freed.
Definition: bufArray.hpp:193
void setLength(uint16_t len)
Definition: headers.hpp:164
uint16_t checksum
Checksum.
Definition: headers.hpp:213
void * getData()
Definition: mbuf.hpp:10
void * HelloBye3MemPool_Client_connect(void *obj, struct rte_mbuf **inPkts, unsigned int inCount, unsigned int *sendCount, unsigned int *freeCount, uint32_t srcIP, uint32_t dstIP, uint16_t srcPort, uint16_t dstPort, uint64_t ident)
Open a connection to a server.
Wrapper around MoonGen bufarrays.
Definition: bufArray.hpp:42
static constexpr StateID Hello
void * factory(Identifier< mbuf >::ConnectionID id)
void setVersion()
Set the version field to 4.
Definition: headers.hpp:73
void runHello(StateMachine< Identifier< mbuf >, mbuf >::State &state, mbuf *pkt, StateMachine< Identifier< mbuf >, mbuf >::FunIface &funIface)
void * getPayload()
Get the SDU.
Definition: headers.hpp:23