1 /**
2  * @file daemon.h
3  * @brief Routines used by the Flowgrind daemon
4  */
5 
6 /*
7  * Copyright (C) 2010-2013 Christian Samsel <christian.samsel@rwth-aachen.de>
8  * Copyright (C) 2009 Tim Kosse <tim.kosse@gmx.de>
9  * Copyright (C) 2007-2008 Daniel Schaffrath <daniel.schaffrath@mac.com>
10  *
11  * This file is part of Flowgrind.
12  *
13  * Flowgrind is free software: you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation, either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * Flowgrind is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with Flowgrind.  If not, see <http://www.gnu.org/licenses/>.
25  *
26  */
27 
28 #ifndef _DAEMON_H_
29 #define _DAEMON_H_
30 
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif /* HAVE_CONFIG_H */
34 
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 
38 #ifdef HAVE_LIBGSL
39 #include <gsl/gsl_rng.h>
40 #endif /* HAVE_LIBGSL */
41 
42 #include "common.h"
43 #include "fg_list.h"
44 
45 #include <xmlrpc-c/base.h>
46 #include <xmlrpc-c/server.h>
47 #include <xmlrpc-c/server_abyss.h>
48 #include <xmlrpc-c/util.h>
49 
50 /** Time select() will block waiting for a file descriptor to become ready. */
51 #define DEFAULT_SELECT_TIMEOUT  10000000
52 
53 enum flow_state_t
54 {
55 	/* SOURCE */
56 	GRIND_WAIT_CONNECT = 0,
57 	/* DESTINATION */
58 	GRIND_WAIT_ACCEPT,
59 	/* RUN */
60 	GRIND,
61 };
62 
63 struct flow_source_settings
64 {
65 	char destination_host[256];
66 	int destination_port;
67 
68 	int late_connect;
69 
70 	pthread_cond_t* add_source_condition;
71 };
72 
73 struct flow
74 {
75 	int id;
76 
77 	enum flow_state_t state;
78 	enum endpoint_t endpoint;
79 
80 	int fd;
81 	int listenfd_data;
82 
83 	struct flow_settings settings;
84 	struct flow_source_settings source_settings;
85 
86 	struct timespec start_timestamp[2];
87 	struct timespec stop_timestamp[2];
88 	struct timespec last_block_read;
89 	struct timespec last_block_written;
90 
91 	struct timespec first_report_time;
92 	struct timespec last_report_time;
93 	struct timespec next_report_time;
94 
95 	struct timespec next_write_block_timestamp;
96 
97 	char *read_block;
98 	char *write_block;
99 
100 	unsigned current_write_block_size;
101 	unsigned current_read_block_size;
102 
103 	unsigned current_block_bytes_read;
104 	unsigned current_block_bytes_written;
105 
106 	unsigned short requested_server_test_port;
107 
108 	unsigned real_listen_send_buffer_size;
109 	unsigned real_listen_receive_buffer_size;
110 
111 	char connect_called;
112 	char finished[2];
113 
114 	int pmtu;
115 
116 	unsigned congestion_counter;
117 
118 	/* Used for do_connect for source flows */
119 	struct sockaddr *addr;
120 	socklen_t addr_len;
121 
122 	struct statistics {
123 #ifdef HAVE_UNSIGNED_LONG_LONG_INT
124 		unsigned long long bytes_read;
125 		unsigned long long bytes_written;
126 #else /* HAVE_UNSIGNED_LONG_LONG_INT */
127 		long bytes_read;
128 		long bytes_written;
129 #endif /* HAVE_UNSIGNED_LONG_LONG_INT */
130 		unsigned request_blocks_read;
131 		unsigned request_blocks_written;
132 		unsigned response_blocks_read;
133 		unsigned response_blocks_written;
134 
135 		/* TODO Create an array for IAT / RTT and delay */
136 
137 		/** Minimum interarrival time. */
138 		double iat_min;
139 		/** Maximum interarrival time. */
140 		double iat_max;
141 		/** Accumulated interarrival time. */
142 		double iat_sum;
143 		/** Minimum one-way delay. */
144 		double delay_min;
145 		/** Maximum one-way delay. */
146 		double delay_max;
147 		/** Accumulated one-way delay. */
148 		double delay_sum;
149 		/** Minimum round-trip time. */
150 		double rtt_min;
151 		/** Maximum round-trip time. */
152 		double rtt_max;
153 		/** Accumulated round-trip time. */
154 		double rtt_sum;
155 
156 		int has_tcp_info;
157 		struct fg_tcp_info tcp_info;
158 	} statistics[2];
159 
160 #ifdef HAVE_LIBPCAP
161 	pthread_t pcap_thread;
162 	struct pcap_t *pcap_handle;
163 	struct pcap_dumper_t *pcap_dumper;
164 #endif /* HAVE_LIBPCAP */
165 
166 #ifdef HAVE_LIBGSL
167 	gsl_rng * r;
168 #endif /* HAVE_LIBGSL */
169 
170 	char* error;
171 };
172 
173 #define REQUEST_ADD_DESTINATION 0
174 #define REQUEST_ADD_SOURCE 1
175 #define REQUEST_START_FLOWS 2
176 #define REQUEST_STOP_FLOW 3
177 #define REQUEST_GET_STATUS 4
178 #define REQUEST_GET_UUID 5
179 struct request
180 {
181 	char type;
182 
183 	/* We signal this condition once the daemon thread
184 	 * has processed the request */
185 	pthread_cond_t* condition;
186 
187 	char* error;
188 
189 	struct request *next;
190 };
191 extern struct request *requests, *requests_last;
192 
193 struct request_add_flow_destination
194 {
195 	struct request r;
196 
197 	struct flow_settings settings;
198 
199 	/* The request reply */
200 	int flow_id;
201 	int listen_data_port;
202 	int real_listen_send_buffer_size;
203 	int real_listen_read_buffer_size;
204 };
205 
206 struct request_add_flow_source
207 {
208 	struct request r;
209 
210 	struct flow_settings settings;
211 	struct flow_source_settings source_settings;
212 
213 	/* The request reply */
214 	int flow_id;
215 	char cc_alg[TCP_CA_NAME_MAX];
216 	int real_send_buffer_size;
217 	int real_read_buffer_size;
218 };
219 
220 struct request_start_flows
221 {
222 	struct request r;
223 
224 	int start_timestamp;
225 };
226 
227 struct request_stop_flow
228 {
229 	struct request r;
230 
231 	int flow_id;
232 };
233 
234 /**
235  * @brief structure for getting the UUID.
236  *
237  * Structure is used to get the UUID from the daemon and send back the UUID
238  * in request format
239  */
240 struct request_get_uuid
241 {
242 	struct request r;     /**< Daemon thread process the request r. */
243 
244 	char server_uuid[38]; /**< UUID from the daemon. */
245 };
246 
247 struct request_get_status
248 {
249 	struct request r;
250 
251 	int started;
252 	int num_flows;
253 };
254 
255 extern pthread_t daemon_thread;
256 
257 /* Through this pipe we wakeup the thread from select */
258 extern int daemon_pipe[2];
259 
260 extern char started;
261 extern pthread_mutex_t mutex;
262 extern struct linked_list flows;
263 extern struct report* reports;
264 extern struct report* reports_last;
265 extern unsigned pending_reports;
266 
267 /* Gets 50 reports. There may be more pending but there's a limit on how
268  * large a reply can get */
269 struct report* get_reports(int *has_more);
270 
271 extern char *dump_prefix;
272 extern char *dump_dir;
273 
274 void *daemon_main(void* ptr);
275 void add_report(struct report* report);
276 void flow_error(struct flow *flow, const char *fmt, ...);
277 void request_error(struct request *request, const char *fmt, ...);
278 int set_flow_tcp_options(struct flow *flow);
279 
280 /** Dispatch a request to daemon loop.
281  * Is called by the rpc server to feed in requests to the daemon. */
282  int dispatch_request(struct request *request, int type);
283 
284 /**
285  * To generate daemon UUID
286  *
287  * Generate the daemon UUID and convert the UUID to a string data.
288  * UUID is generated by daemon only once and stored in the global variable.
289  * The daemon return the same UUID for all the flows it maintaining.
290  * This UUID is taken as a reference to identify the daemon in the controller.
291  *
292  * @param[in,out] uuid_str daemons UUID
293  */
294  void get_uuid_string(char *uuid_str);
295 #endif /* _DAEMON_H_ */
296