NSIS-ka
A free C++ implementation of NSIS protocols

root/natfw-nslp/trunk/src/natfw_daemon.cpp @ 2273

Revision 2273, 5.6 KB (checked in by stud-matfried, 7 years ago)

Renamed the benchmark class to benchmark_journal.
We will need the name "benchmark" later.

  • Property svn:keywords set to Id HeadURL
Line 
1#include "logfile.h"
2#include "threads.h"
3#include "threadsafe_db.h"
4#include "queuemanager.h"
5
6#include "apimessage.h" // from NTLP
7
8#include "natfw_config.h"
9#include "msg/natfw_ie.h"
10#include "msg/natfw_msg.h"
11#include "dispatcher.h"
12#include "natfw_daemon.h"
13#include "benchmark_journal.h"
14
15
16using namespace protlib;
17using namespace protlib::log;
18using namespace natfw;
19using namespace natfw::msg;
20
21
22#define LogError(msg) ERRLog("natfw_daemon", msg)
23#define LogWarn(msg) WLog("natfw_daemon", msg)
24#define LogInfo(msg) ILog("natfw_daemon", msg)
25#define LogDebug(msg) DLog("natfw_daemon", msg)
26
27
28#ifdef BENCHMARK
29  benchmark_journal journal(1000, "benchmark_journal.txt");
30#endif
31
32
33/**
34 * Constructor.
35 */
36natfw_daemon::natfw_daemon(const natfw_daemon_param &param)
37                : Thread(param), config(param.config),
38                  session_mgr(&config), nat_mgr(&config),
39                  rule_installer(NULL), ntlp_starter(NULL) {
40
41        startup();
42}
43
44
45/**
46 * Destructor.
47 */
48natfw_daemon::~natfw_daemon() {
49        shutdown();
50}
51
52
53/**
54 * Called exactly once before the first thread executes main_loop.
55 */
56void natfw_daemon::startup() {
57        LogInfo("starting NATFW daemon ...");
58
59        /*
60         * Instantiate an operating system dependent policy rule installer.
61         * We use the iptables policy rule installer only on NF nodes which
62         * have it enabled in the configuration. NIs and NRs don't have to
63         * install policy rules.
64         */
65        if ( config.get_nf_install_policy_rules() == true
66                        && (config.is_nf_nat() || config.is_nf_firewall()) )
67                rule_installer = new iptables_policy_rule_installer(&config);
68        else
69                rule_installer = new nop_policy_rule_installer(&config);
70
71        try {
72                rule_installer->setup();
73        }
74        catch ( policy_rule_installer_error &e ) {
75                LogError("unable to setup the policy rule installer: " << e);
76        }
77
78        /*
79         * Start the GIST thread.
80         */
81        NTLPStarterParam param(
82                config.get_gist_port_udp(),
83                config.get_gist_port_tcp(),
84                config.get_gist_port_tls(),
85                0                               // SCTP port. Disabled.
86        );
87        param.refreshtime = 5000;       // in milliseconds
88        param.debug_tp = false;
89        param.latestate = true;
90
91        if ( config.has_ipv4_address() )
92                param.localaddrv4 = config.get_ipv4_addresses();
93
94        if ( config.has_ipv6_address() )
95                param.localaddrv6 = config.get_ipv6_addresses();
96
97        ntlp_starter
98                = new ThreadStarter<NTLPStarter, NTLPStarterParam>(1, param);
99        ntlp_starter->start_processing();
100
101
102        /*
103         * Register our input queue with the queue manager.
104         */
105        QueueManager::instance()->register_queue(
106                get_fqueue(), natfw_config::INPUT_QUEUE_ADDRESS);
107
108        /*
109         * Register the queue created above with the NTLP. The NTLP will then
110         * append all NATFW messages it receives to our input queue.
111         */
112        ntlp::APIMsg *api_msg = new ntlp::APIMsg();
113        api_msg->set_source(natfw_config::INPUT_QUEUE_ADDRESS);
114        api_msg->set_register(natfw_config::NSLP_ID, 0); // NSLPID, RAO
115
116        /*
117         * TODO: We have no way to find out if the NTLP thread is up and has
118         * already registered an input queue. Because of this, we try to send
119         * our registration message until there is a queue to accept it.
120         */
121        bool success;
122        do {
123                success = api_msg->send_to(natfw_config::OUTPUT_QUEUE_ADDRESS);
124                sleep(1);
125        }
126        while ( ! success );
127        assert( success );
128
129
130        LogDebug("NAFTW daemon startup complete");
131}
132
133
134/**
135 * Called exactly once after the last thread executes main_loop.
136 *
137 * TODO: at least I hope there are no active threads left!
138 */
139void natfw_daemon::shutdown() {
140        LogDebug("NATFW daemon shutting down ...");
141
142        try {
143                rule_installer->remove_all();
144        }
145        catch ( policy_rule_installer_error &e ) {
146                LogError("unable to remove the installed policy rules: " << e);
147                LogError("You have to remove them manually!");
148        }
149
150        // Shut down the NTLP threads.
151        ntlp_starter->stop_processing();
152        ntlp_starter->wait_until_stopped();
153
154        delete ntlp_starter;
155
156        delete rule_installer;
157
158        QueueManager::instance()->unregister_queue(
159                        natfw_config::INPUT_QUEUE_ADDRESS);
160
161        LogInfo("NATFW deamon shutdown complete");
162}
163
164
165/**
166 * The implementation of the main routine of a worker thread.
167 */
168void natfw_daemon::main_loop(uint32 thread_id) {
169
170        /*
171         * The dispatcher handles incoming messages. It is the top-level state
172         * machine which delegates work to the state machines on session level.
173         *
174         * For each main_loop, and thus POSIX thread, there is a dispatcher.
175         */
176        dispatcher disp(&session_mgr, &nat_mgr, rule_installer, &config);
177        gistka_mapper mapper;
178
179
180        /*
181         * Wait for messages in the input queue and process them.
182         */
183        LogInfo("dispatcher thread #"
184                        << thread_id << " waiting for incoming messages ...");
185
186        FastQueue *natfw_input = get_fqueue();
187
188        while ( get_state() == Thread::STATE_RUN ) {
189                // A timeout makes sure the loop condition is checked regularly.
190                message *msg = natfw_input->dequeue_timedwait(1000);
191
192                if ( msg == NULL )
193                        continue;       // no message in the queue
194
195                LogDebug("dispatcher thread #" << thread_id
196                        << " processing received message #" << msg->get_id());
197
198                MP(benchmark_journal::PRE_PROCESSING);
199
200                // Analyze message and create an event from it.
201                event *evt = mapper.map_to_event(msg);
202
203                // Then feed the event to the dispatcher.
204                if ( evt != NULL ) {
205                        MP(benchmark_journal::PRE_DISPATCHER);
206                        disp.process(evt);
207                        MP(benchmark_journal::POST_DISPATCHER);
208                        delete evt;
209                }
210
211                delete msg;
212
213                MP(benchmark_journal::POST_PROCESSING);
214        }
215}
216
217
218void natfw::init_framework() {
219        /*
220         * Initialize libraries.
221         */
222        tsdb::init();
223        SSL_library_init();             // TODO: seed random generator
224        OpenSSL_add_ssl_algorithms();
225        SSL_load_error_strings();
226        NATFW_IEManager::register_known_ies();
227}
228
229
230void natfw::cleanup_framework() {
231        QueueManager::clear();
232        NATFW_IEManager::clear();
233        //tsdb::end();
234        LogError("natfw::cleanup_framework() doesn't call tsdb::end()!");
235}
236
237// EOF
Note: See TracBrowser for help on using the browser.