-
Notifications
You must be signed in to change notification settings - Fork 390
/
proto.cc
70 lines (59 loc) · 2.18 KB
/
proto.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/*
* Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
*/
#include "base/os.h"
#include "pkt/proto.h"
#include "pkt/agent_stats.h"
#include "pkt/proto_handler.h"
#include "pkt/pkt_init.h"
////////////////////////////////////////////////////////////////////////////////
Proto::Proto(Agent *agent, const char *task_name, PktHandler::PktModuleName mod,
boost::asio::io_service &io)
: agent_(agent), module_(mod), trace_(true), free_buffer_(false), io_(io),
work_queue_(TaskScheduler::GetInstance()->GetTaskId(task_name), mod,
boost::bind(&Proto::ProcessProto, this, _1)) {
agent->pkt()->pkt_handler()->Register(mod, this);
}
Proto::Proto(Agent *agent, const char *task_name, PktHandler::PktModuleName mod,
boost::asio::io_service &io, uint32_t workq_iterations) :
agent_(agent), module_(mod), trace_(true), free_buffer_(false), io_(io),
work_queue_(TaskScheduler::GetInstance()->GetTaskId(task_name), mod,
boost::bind(&Proto::ProcessProto, this, _1), workq_iterations,
workq_iterations) {
agent->pkt()->pkt_handler()->Register(mod, this);
}
Proto::~Proto() {
work_queue_.Shutdown();
}
void Proto::FreeBuffer(PktInfo *msg) {
msg->pkt = NULL;
msg->eth = NULL;
msg->arp = NULL;
msg->ip = NULL;
msg->transp.tcp = NULL;
msg->data = NULL;
msg->reset_packet_buffer();
}
bool Proto::Enqueue(boost::shared_ptr<PktInfo> msg) {
if (Validate(msg.get()) == false) {
return true;
}
if (free_buffer_) {
FreeBuffer(msg.get());
}
return work_queue_.Enqueue(msg);
}
// PktHandler enqueues the packet as-is without decoding based on "cmd" in
// agent_hdr. Decode the pacekt first. Its possible that protocol handler may
// change based on packet decode
bool Proto::ProcessProto(boost::shared_ptr<PktInfo> msg_info) {
PktHandler *pkt_handler = agent_->pkt()->pkt_handler();
assert(msg_info->module != PktHandler::INVALID);
if (trace_) {
pkt_handler->AddPktTrace(module_, PktTrace::In, msg_info.get());
}
ProtoHandler *handler = AllocProtoHandler(msg_info, io_);
if (handler->Run())
delete handler;
return true;
}