Skip to content

Commit 9accfc4

Browse files
net: Added a start for tracking TCP connections (WIP)
1 parent 62355e3 commit 9accfc4

1 file changed

Lines changed: 160 additions & 0 deletions

File tree

api/net/tcp/connection_tracker.hpp

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
// This file is a part of the IncludeOS unikernel - www.includeos.org
2+
//
3+
// Copyright 2017 Oslo and Akershus University College of Applied Sciences
4+
// and Alfred Bratterud
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
18+
#pragma once
19+
#ifndef NET_TCP_CONNECTION_TRACKER_HPP
20+
#define NET_TCP_CONNECTION_TRACKER_HPP
21+
22+
#include "packet.hpp"
23+
24+
namespace net {
25+
namespace tcp {
26+
27+
/**
28+
* @brief Class for tracking TCP connections by observing a packet flow.
29+
*/
30+
class Connection_tracker {
31+
public:
32+
enum class State : uint8_t {
33+
SYN_SENT,
34+
SYN_RECV,
35+
ESTABLISHED,
36+
CLOSE,
37+
INVALID
38+
};
39+
40+
static std::string to_string(State state)
41+
{
42+
switch(state)
43+
{
44+
case State::SYN_SENT: return "SYN_SENT";
45+
case State::SYN_RECV: return "SYN_RECV";
46+
case State::ESTABLISHED: return "ESTABLISHED";
47+
case State::CLOSE: return "CLOSE";
48+
default: return "INVALID";
49+
}
50+
}
51+
52+
using Tuple = std::pair<Socket, Socket>;
53+
54+
struct Entry {
55+
Socket src;
56+
Socket dst;
57+
State state;
58+
59+
Entry(const Tuple& t, State s)
60+
: src{t.first}, dst{t.second}, state{s}
61+
{}
62+
63+
std::string to_string() const
64+
{ return src.to_string() + " " + dst.to_string() + " " + Connection_tracker::to_string(state); }
65+
66+
};
67+
68+
using Close_handler = delegate<void(const Tuple&)>;
69+
using Connections = std::map<Tuple, Entry>;
70+
71+
public:
72+
Close_handler on_close;
73+
74+
void incoming(const tcp::Packet& pkt)
75+
{
76+
//printf("Incoming: %s\n", pkt.to_string().c_str());
77+
handle({pkt.destination(), pkt.source()}, pkt);
78+
}
79+
80+
void outgoing(const tcp::Packet& pkt)
81+
{
82+
//printf("Outgoing: %s\n", pkt.to_string().c_str());
83+
handle({pkt.source(), pkt.destination()}, pkt);
84+
}
85+
86+
void handle(const Tuple& tuple, const tcp::Packet& pkt)
87+
{
88+
auto it = entries.find(tuple);
89+
90+
if(it != entries.end())
91+
{
92+
do_state(it->second, pkt);
93+
}
94+
else
95+
{
96+
new_entry(tuple, pkt);
97+
}
98+
}
99+
100+
void new_entry(const Tuple& tuple, const tcp::Packet& pkt)
101+
{
102+
if(pkt.isset(SYN) and not pkt.isset(ACK))
103+
{
104+
entries.emplace(std::piecewise_construct,
105+
std::forward_as_tuple(tuple),
106+
std::forward_as_tuple(tuple, State::SYN_SENT));
107+
108+
//printf("SYN_SENT\n");
109+
}
110+
else
111+
{
112+
entries.emplace(std::piecewise_construct,
113+
std::forward_as_tuple(tuple),
114+
std::forward_as_tuple(tuple, State::INVALID));
115+
}
116+
}
117+
118+
void do_state(Entry& entry, const tcp::Packet& pkt)
119+
{
120+
if(UNLIKELY(pkt.isset(RST)))
121+
{
122+
entry.state = State::CLOSE;
123+
return;
124+
}
125+
126+
switch(entry.state)
127+
{
128+
case State::SYN_SENT:
129+
{
130+
if(pkt.isset(SYN) and pkt.isset(ACK)) {
131+
entry.state = State::SYN_RECV;
132+
//printf("Entry: %s\n", entry.to_string().c_str());
133+
}
134+
135+
return;
136+
}
137+
138+
case State::SYN_RECV:
139+
{
140+
if(pkt.isset(ACK)) {
141+
entry.state = State::ESTABLISHED;
142+
//printf("Entry: %s\n", entry.to_string().c_str());
143+
}
144+
}
145+
146+
default:
147+
return;
148+
}
149+
}
150+
151+
private:
152+
Connections entries;
153+
154+
};
155+
156+
} // < namespace tcp
157+
} // < namespace net
158+
159+
#endif
160+

0 commit comments

Comments
 (0)