summaryrefslogtreecommitdiff
path: root/readme.md
blob: 34ef88c8f5c7e4eee72a61a924ad8fbc1a9c6be6 (plain)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# Stellar: A stateful network functions development platform

A stateful network function could be a firewall, a load balancer, or an IDS. 

## Architecture

The stellar components are:

- **Packet IO** built an abstraction of network IO devices.
- **Session Manager** has a hash table for tracking sessions. The caller feeds packets to the session manager and may return triggered session events.
- **Plugin Manager** loads C/Lua plugins and manages per-plugin, per-session context. When the caller feeds an event to the plugin manager, it invokes plugin callbacks.
- **Protocol Decoders** are libraries that parse and extract information from the packet payload.
- **Active Queue Management** is queue management algorithm libraries that schedule packets by buffering, forwarding, marking, or dropping. A plugin creates a queue instance and enqueues packets as its needs. 
  - Question: Who consumes the dequeue events?

![stellar-high-level-design](./docs/imgs/stellar-high-level-design.svg)

## Concepts
Session is an abstract of Layer 4-7 connection, i.e., TCP Session, HTTP Session, DNS Session. 
- A session can derive child sessions.
- All session has three states, which are Opening, Active, Closing.
- State changes generate session events.

Event is something happened in a session, i.e., TCP OPENING, HTTP Request, Session Extra Data updates.

Session Extra Data is a developer defined data structure that attached to a session, it's lifetime is same as the session.

## Packet IO Library
```
struct stellar_packet;

packet_io_loop()
{
  packet_io_device_rx(&rx_pkt)
  //ingress processing: Tunnel decoding, IP defragmentation
  session_manager();
  plugin_manager();
  //egress processing: AMQ
  rl_group_id=pkt_get_group_id(rx_pkt);
  void *raw_pkt=pkt_get_raw(rx_pkt);
  AMQ_enqueue(group_id[], raw_pkt, pkt_sz);

}
```

## Plugin Manager

Plugin Management APIs

```
/*
 * The pm_session_dettach_me just sets the flag to disable this plugin and no longer call this event callback.
 * Before calling pm_session_dettach_me, the current plugin must release related resources for the current session.
 */
pm_session_dettach_me(session);

/*
 * The current plugin(cb2) takes over the current session, the pm_session_take_over setting flag disables other plugins,
 * and the current session does not call other plugins except for the SESSION_EVENT_CLOSING event.
 *
 *                               +-----+   +-----+   +-----+   +-----+
 * Plugin runtime callback list: | cb1 |-->| cb2 |-->| cb3 |-->| cb4 |
 *                               +-----+   +-----+   +-----+   +-----+
 *                                           /|\
 *                                            |
 *                         plugin cb2 run pm_session_take_over
 * 
 * A plugin(cb1/cb3/cb4) that is taken over, if the plugin was called before being taken over and has a registered SESSION_EVENT_CLOSING event,
 * it will be called again when the SESSION_EVENT_CLOSING event comes. Otherwise, the plugin will not be called.
 */
pm_session_take_over(session);
```

## Session Manager

Session Management APIs

```
session_drop_current_packet(session);
session_set_ratelimit_group(session, rl_group_id);
session_set_metadata(session, const char *key, void *value, size_t val_sz, free_callback);
session_get_metadata(session, const char *key, void **value, size_t *val_sz);
session_del_metadata(session, key)
session_lock(session, plug_id);
session_unlock(session, plug_id);

```
Plugin Example
```
plugin_entry(session, ctx)
{
  session_get_metadata(session, "fw_action", value);
  if(value==INTERCEPT)
  {
    //pm_session_dettach_me(session);
    return;
  }
  ret=check_security_policy(session);
  if(ret==INTERCEPT)
  {
    pm_session_take_over(session);
  }
  else if(ret==RATE_LIMIT)
  {
    group_id=security_policy_id;
    amq_group_create(group_id, CIR, CBS);
    session_set_ratelimit_group(session, group_id);
  }
}
```