Flowgrind
Advanced TCP traffic generator
fg_rpc_server.c File Reference

Flowgrindd rpcserver implementation. More...

#include "config.h"
#include <sys/utsname.h>
#include <syslog.h>
#include "common.h"
#include "daemon.h"
#include "fg_log.h"
#include "fg_error.h"
#include "fg_definitions.h"
#include "debug.h"
#include "fg_rpc_server.h"

Go to the source code of this file.

Functions

static xmlrpc_value * add_flow_destination (xmlrpc_env *const env, xmlrpc_value *const param_array, void *const user_data)
 Prepare data connection for destination endpoint. More...
 
static xmlrpc_value * add_flow_source (xmlrpc_env *const env, xmlrpc_value *const param_array, void *const user_data)
 Prepare data connection for source endpoint. More...
 
static int bind_rpc_server (char *bind_addr, unsigned port)
 
void init_rpc_server (struct fg_rpc_server *server, char *rpc_bind_addr, unsigned port)
 Initializes the xmlrpc server. More...
 
static xmlrpc_value * method_get_reports (xmlrpc_env *const env, xmlrpc_value *const param_array, void *const user_data)
 To get the reports from the daemon. More...
 
static xmlrpc_value * method_get_status (xmlrpc_env *const env, xmlrpc_value *const param_array, void *const user_data)
 
static xmlrpc_value * method_get_uuid (xmlrpc_env *const env, xmlrpc_value *const param_array, void *const user_data)
 To get the daemons UUID. More...
 
static xmlrpc_value * method_get_version (xmlrpc_env *const env, xmlrpc_value *const param_array, void *const user_data)
 
static xmlrpc_value * method_stop_flow (xmlrpc_env *const env, xmlrpc_value *const param_array, void *const user_data)
 
void run_rpc_server (struct fg_rpc_server *server)
 Enters the xmlrpc server mainloop. More...
 
static xmlrpc_value * start_flows (xmlrpc_env *const env, xmlrpc_value *const param_array, void *const user_data)
 

Detailed Description

Flowgrindd rpcserver implementation.

Definition in file fg_rpc_server.c.

Function Documentation

◆ add_flow_destination()

static xmlrpc_value* add_flow_destination ( xmlrpc_env *const  env,
xmlrpc_value *const  param_array,
void *const  user_data 
)
static

Prepare data connection for destination endpoint.

Flowgrind rpc server decode the information from the controller XML-RPC and construct the request data structure to add flow in the destination daemon. The request is dispatched to destination daemon. The destination daemon execute the request and send back the executed result in the request reply to the flowgrind rpc server. Flowgrind rpc server then encode the request reply information from the daemon and send back the data to the flowgrind controller through XML-RPC connection

Parameters
[in,out]envXML-RPC environment object
[in,out]param_arrayXML-RPC value
[in,out]user_dataunused arg return xmlrpc_value XML-RPC value

Definition at line 277 of file fg_rpc_server.c.

280 {
281  UNUSED_ARGUMENT(user_data);
282 
283  int rc, i;
284  xmlrpc_value *ret = 0;
285  char* cc_alg = 0;
286  char* bind_address = 0;
287  xmlrpc_value* extra_options = 0;
288 
289  struct flow_settings settings;
290 
292 
293  DEBUG_MSG(LOG_WARNING, "method add_flow_destination called");
294 
295  /* Parse our argument array. */
296  xmlrpc_decompose_value(env, param_array,
297  "("
298  "{s:s,*}"
299  "{s:i,*}"
300  "{s:d,s:d,s:d,s:d,s:d,*}"
301  "{s:i,s:i,*}"
302  "{s:i,*}"
303  "{s:b,s:b,s:b,s:b,s:b,*}"
304  "{s:i,s:i,*}"
305  "{s:i,s:d,s:d,*}" /* request */
306  "{s:i,s:d,s:d,*}" /* response */
307  "{s:i,s:d,s:d,*}" /* interpacket_gap */
308  "{s:b,s:b,s:i,s:i,*}"
309  "{s:s,*}"
310  "{s:i,s:i,s:i,s:i,s:i,*}"
311  "{s:s,*}" /* For libpcap dumps */
312  "{s:i,s:A,*}"
313  ")",
314 
315  /* general settings */
316  "bind_address", &bind_address,
317 
318  "flow_id", &settings.flow_id,
319 
320  "write_delay", &settings.delay[WRITE],
321  "write_duration", &settings.duration[WRITE],
322  "read_delay", &settings.delay[READ],
323  "read_duration", &settings.duration[READ],
324  "reporting_interval", &settings.reporting_interval,
325 
326  "requested_send_buffer_size", &settings.requested_send_buffer_size,
327  "requested_read_buffer_size", &settings.requested_read_buffer_size,
328 
329  "maximum_block_size", &settings.maximum_block_size,
330 
331  "traffic_dump", &settings.traffic_dump,
332  "so_debug", &settings.so_debug,
333  "route_record", &settings.route_record,
334  "pushy", &settings.pushy,
335  "shutdown", &settings.shutdown,
336 
337  "write_rate", &settings.write_rate,
338  "random_seed",&settings.random_seed,
339 
340  "traffic_generation_request_distribution", &settings.request_trafgen_options.distribution,
341  "traffic_generation_request_param_one", &settings.request_trafgen_options.param_one,
342  "traffic_generation_request_param_two", &settings.request_trafgen_options.param_two,
343 
344  "traffic_generation_response_distribution", &settings.response_trafgen_options.distribution,
345  "traffic_generation_response_param_one", &settings.response_trafgen_options.param_one,
346  "traffic_generation_response_param_two", &settings.response_trafgen_options.param_two,
347 
348  "traffic_generation_gap_distribution", &settings.interpacket_gap_trafgen_options.distribution,
349  "traffic_generation_gap_param_one", &settings.interpacket_gap_trafgen_options.param_one,
350  "traffic_generation_gap_param_two", &settings.interpacket_gap_trafgen_options.param_two,
351 
352  "flow_control", &settings.flow_control,
353  "byte_counting", &settings.byte_counting,
354  "cork", &settings.cork,
355  "nonagle", &settings.nonagle,
356 
357  "cc_alg", &cc_alg,
358 
359  "elcn", &settings.elcn,
360  "lcd", &settings.lcd,
361  "mtcp", &settings.mtcp,
362  "dscp", &settings.dscp,
363  "ipmtudiscover", &settings.ipmtudiscover,
364  "dump_prefix", &dump_prefix,
365  "num_extra_socket_options", &settings.num_extra_socket_options,
366  "extra_socket_options", &extra_options);
367 
368  if (env->fault_occurred)
369  goto cleanup;
370 
371 #ifndef HAVE_LIBPCAP
373  XMLRPC_FAIL(env, XMLRPC_TYPE_ERROR, "Daemon was asked to dump traffic, but wasn't compiled with libpcap support");
374 #endif
375 
376  /* Check for sanity */
377  if (strlen(bind_address) >= sizeof(settings.bind_address) - 1 ||
378  settings.delay[WRITE] < 0 || settings.duration[WRITE] < 0 ||
379  settings.delay[READ] < 0 || settings.duration[READ] < 0 ||
382  settings.write_rate < 0 ||
383  strlen(cc_alg) > TCP_CA_NAME_MAX ||
385  xmlrpc_array_size(env, extra_options) != settings.num_extra_socket_options) {
386  XMLRPC_FAIL(env, XMLRPC_TYPE_ERROR, "Flow settings incorrect");
387  }
388 
389  /* Parse extra socket options */
390  for (i = 0; i < settings.num_extra_socket_options; i++) {
391 
392  const unsigned char* buffer = 0;
393  size_t len;
394  xmlrpc_value *option, *level = 0, *optname = 0, *value = 0;
395  xmlrpc_array_read_item(env, extra_options, i, &option);
396 
397  if (!env->fault_occurred)
398  xmlrpc_struct_read_value(env, option, "level", &level);
399  if (!env->fault_occurred)
400  xmlrpc_struct_read_value(env, option, "optname", &optname);
401  if (!env->fault_occurred)
402  xmlrpc_struct_read_value(env, option, "value", &value);
403  if (!env->fault_occurred)
404  xmlrpc_read_int(env, level, &settings.extra_socket_options[i].level);
405  if (!env->fault_occurred)
406  xmlrpc_read_int(env, optname, &settings.extra_socket_options[i].optname);
407  if (!env->fault_occurred)
408  xmlrpc_read_base64(env, value, &len, &buffer);
409  if (level)
410  xmlrpc_DECREF(level);
411  if (optname)
412  xmlrpc_DECREF(optname);
413  if (value)
414  xmlrpc_DECREF(value);
415  if (!env->fault_occurred) {
417  free((void *)buffer);
418  XMLRPC_FAIL(env, XMLRPC_TYPE_ERROR, "Too long extra socket option length");
419  }
421  memcpy(settings.extra_socket_options[i].optval, buffer, len);
422  free((void *)buffer);
423  }
424  if (env->fault_occurred)
425  goto cleanup;
426  }
427 
428  strcpy(settings.cc_alg, cc_alg);
429  strcpy(settings.bind_address, bind_address);
430  DEBUG_MSG(LOG_WARNING, "bind_address=%s", bind_address);
431  request = malloc(sizeof(struct request_add_flow_destination));
432  request->settings = settings;
434 
435  if (rc == -1)
436  XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR, request->r.error); /* goto cleanup on failure */
437 
438  /* Return our result. */
439  ret = xmlrpc_build_value(env, "{s:i,s:i,s:i,s:i}",
440  "flow_id", request->flow_id,
441  "listen_data_port", request->listen_data_port,
442  "real_listen_send_buffer_size", request->real_listen_send_buffer_size,
443  "real_listen_read_buffer_size", request->real_listen_read_buffer_size);
444 
445 cleanup:
446  if (request)
448  free_all(cc_alg, bind_address);
449 
450  if (extra_options)
451  xmlrpc_DECREF(extra_options);
452 
453  if (env->fault_occurred)
454  logging(LOG_WARNING, "method add_flow_destination failed: %s",
455  env->fault_string);
456  else
457  DEBUG_MSG(LOG_WARNING, "method add_flow_destination successful");
458 
459  return ret;
460 }

◆ add_flow_source()

static xmlrpc_value* add_flow_source ( xmlrpc_env *const  env,
xmlrpc_value *const  param_array,
void *const  user_data 
)
static

Prepare data connection for source endpoint.

Flowgrind rpc server decode the information from the controller XML-RPC and construct the request data structure to add flow in the source daemon. The request is dispatched to source daemon. The source daemon execute the request and send back the executed result in the request reply to the flowgrind rpc server. Flowgrind rpc server then encode the request reply information from the daemon and send back the data to the flowgrind controller through XML-RPC connection

Parameters
[in,out]envXML-RPC environment object
[in,out]param_arrayXML-RPC value
[in,out]user_dataunused arg return xmlrpc_value XML-RPC value

Definition at line 62 of file fg_rpc_server.c.

65 {
66  UNUSED_ARGUMENT(user_data);
67 
68  int rc, i;
69  xmlrpc_value *ret = 0;
70  char* destination_host = 0;
71  char* cc_alg = 0;
72  char* bind_address = 0;
73  xmlrpc_value* extra_options = 0;
74 
75  struct flow_settings settings;
76  struct flow_source_settings source_settings;
77 
78  struct request_add_flow_source* request = 0;
79 
80  DEBUG_MSG(LOG_WARNING, "method add_flow_source called");
81 
82  /* Parse our argument array. */
83  xmlrpc_decompose_value(env, param_array,
84  "("
85  "{s:s,*}"
86  "{s:i,*}"
87  "{s:d,s:d,s:d,s:d,s:d,*}"
88  "{s:i,s:i,*}"
89  "{s:i,*}"
90  "{s:b,s:b,s:b,s:b,s:b,*}"
91  "{s:i,s:i,*}"
92  "{s:i,s:d,s:d,*}" /* request */
93  "{s:i,s:d,s:d,*}" /* response */
94  "{s:i,s:d,s:d,*}" /* interpacket_gap */
95  "{s:b,s:b,s:i,s:i,*}"
96  "{s:s,*}"
97  "{s:i,s:i,s:i,s:i,s:i,*}"
98  "{s:s,*}" /* for LIBPCAP dumps */
99  "{s:i,s:A,*}"
100  "{s:s,s:i,s:i,*}"
101  ")",
102 
103  /* general settings */
104  "bind_address", &bind_address,
105 
106  "flow_id", &settings.flow_id,
107 
108  "write_delay", &settings.delay[WRITE],
109  "write_duration", &settings.duration[WRITE],
110  "read_delay", &settings.delay[READ],
111  "read_duration", &settings.duration[READ],
112  "reporting_interval", &settings.reporting_interval,
113 
114  "requested_send_buffer_size", &settings.requested_send_buffer_size,
115  "requested_read_buffer_size", &settings.requested_read_buffer_size,
116 
117  "maximum_block_size", &settings.maximum_block_size,
118 
119  "traffic_dump", &settings.traffic_dump,
120  "so_debug", &settings.so_debug,
121  "route_record", &settings.route_record,
122  "pushy", &settings.pushy,
123  "shutdown", &settings.shutdown,
124 
125  "write_rate", &settings.write_rate,
126  "random_seed",&settings.random_seed,
127 
128  "traffic_generation_request_distribution", &settings.request_trafgen_options.distribution,
129  "traffic_generation_request_param_one", &settings.request_trafgen_options.param_one,
130  "traffic_generation_request_param_two", &settings.request_trafgen_options.param_two,
131 
132  "traffic_generation_response_distribution", &settings.response_trafgen_options.distribution,
133  "traffic_generation_response_param_one", &settings.response_trafgen_options.param_one,
134  "traffic_generation_response_param_two", &settings.response_trafgen_options.param_two,
135 
136  "traffic_generation_gap_distribution", &settings.interpacket_gap_trafgen_options.distribution,
137  "traffic_generation_gap_param_one", &settings.interpacket_gap_trafgen_options.param_one,
138  "traffic_generation_gap_param_two", &settings.interpacket_gap_trafgen_options.param_two,
139 
140  "flow_control", &settings.flow_control,
141  "byte_counting", &settings.byte_counting,
142  "cork", &settings.cork,
143  "nonagle", &settings.nonagle,
144 
145  "cc_alg", &cc_alg,
146 
147  "elcn", &settings.elcn,
148  "lcd", &settings.lcd,
149  "mtcp", &settings.mtcp,
150  "dscp", &settings.dscp,
151  "ipmtudiscover", &settings.ipmtudiscover,
152  "dump_prefix", &dump_prefix,
153  "num_extra_socket_options", &settings.num_extra_socket_options,
154  "extra_socket_options", &extra_options,
155 
156  /* source settings */
157  "destination_address", &destination_host,
158  "destination_port", &source_settings.destination_port,
159  "late_connect", &source_settings.late_connect);
160 
161  if (env->fault_occurred)
162  goto cleanup;
163 
164 #ifndef HAVE_LIBPCAP
166  XMLRPC_FAIL(env, XMLRPC_TYPE_ERROR, "Daemon was asked to dump traffic, but wasn't compiled with libpcap support");
167 #endif
168 
169  /* Check for sanity */
170  if (strlen(bind_address) >= sizeof(settings.bind_address) - 1 ||
171  settings.delay[WRITE] < 0 || settings.duration[WRITE] < 0 ||
172  settings.delay[READ] < 0 || settings.duration[READ] < 0 ||
175  strlen(destination_host) >= sizeof(source_settings.destination_host) - 1||
177  strlen(cc_alg) > TCP_CA_NAME_MAX ||
179  xmlrpc_array_size(env, extra_options) != settings.num_extra_socket_options ||
180  settings.dscp < 0 || settings.dscp > 255 ||
181  settings.write_rate < 0 ||
183  XMLRPC_FAIL(env, XMLRPC_TYPE_ERROR, "Flow settings incorrect");
184  }
185 
186  /* Parse extra socket options */
187  for (i = 0; i < settings.num_extra_socket_options; i++) {
188 
189  const unsigned char* buffer = 0;
190  size_t len;
191  xmlrpc_value *option, *level = 0, *optname = 0, *value = 0;
192  xmlrpc_array_read_item(env, extra_options, i, &option);
193 
194  if (!env->fault_occurred)
195  xmlrpc_struct_read_value(env, option, "level", &level);
196  if (!env->fault_occurred)
197  xmlrpc_struct_read_value(env, option, "optname", &optname);
198  if (!env->fault_occurred)
199  xmlrpc_struct_read_value(env, option, "value", &value);
200  if (!env->fault_occurred)
201  xmlrpc_read_int(env, level, &settings.extra_socket_options[i].level);
202  if (!env->fault_occurred)
203  xmlrpc_read_int(env, optname, &settings.extra_socket_options[i].optname);
204  if (!env->fault_occurred)
205  xmlrpc_read_base64(env, value, &len, &buffer);
206  if (level)
207  xmlrpc_DECREF(level);
208  if (optname)
209  xmlrpc_DECREF(optname);
210  if (value)
211  xmlrpc_DECREF(value);
212  if (!env->fault_occurred) {
214  free((void *)buffer);
215  XMLRPC_FAIL(env, XMLRPC_TYPE_ERROR, "Too long extra socket option length");
216  }
218  memcpy(settings.extra_socket_options[i].optval, buffer, len);
219  free((void *)buffer);
220  }
221  if (env->fault_occurred)
222  goto cleanup;
223  }
224 
225  strcpy(source_settings.destination_host, destination_host);
226  strcpy(settings.cc_alg, cc_alg);
227  strcpy(settings.bind_address, bind_address);
228 
229  request = malloc(sizeof(struct request_add_flow_source));
230  request->settings = settings;
231  request->source_settings = source_settings;
233 
234  if (rc == -1)
235  XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR, request->r.error); /* goto cleanup on failure */
236 
237  /* Return our result. */
238  ret = xmlrpc_build_value(env, "{s:i,s:s,s:i,s:i}",
239  "flow_id", request->flow_id,
240  "cc_alg", request->cc_alg,
241  "real_send_buffer_size", request->real_send_buffer_size,
242  "real_read_buffer_size", request->real_read_buffer_size);
243 
244 cleanup:
245  if (request)
247  free_all(destination_host, cc_alg, bind_address);
248 
249  if (extra_options)
250  xmlrpc_DECREF(extra_options);
251 
252  if (env->fault_occurred)
253  logging(LOG_WARNING, "method add_flow_source failed: %s",
254  env->fault_string);
255  else
256  DEBUG_MSG(LOG_WARNING, "method add_flow_source successful");
257 
258  return ret;
259 }

◆ bind_rpc_server()

static int bind_rpc_server ( char *  bind_addr,
unsigned  port 
)
static

Definition at line 784 of file fg_rpc_server.c.

784  {
785  int rc;
786  int fd;
787  int optval;
788  struct addrinfo hints, *res, *ressave;
789  char tmp_port[100];
790 
791  bzero(&hints, sizeof(struct addrinfo));
792  hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
793  hints.ai_family = AF_UNSPEC;
794  hints.ai_socktype = SOCK_STREAM;
795  sprintf(tmp_port, "%u", port);
796 
797  if ((rc = getaddrinfo(bind_addr, tmp_port,
798  &hints, &res)) != 0) {
799  critx( "Failed to find address to bind rpc_server: %s\n",
800  gai_strerror(rc));
801  return -1;
802  }
803  ressave = res;
804 
805  /* try to bind the first succeeding socket of
806  the returned addresses (libxmlrpc only supports one fd)
807  */
808  do {
809  fd = socket(res->ai_family, res->ai_socktype,
810  res->ai_protocol);
811  if (fd < 0)
812  continue;
813  /* ignore old client connections in TIME_WAIT */
814  optval = 1;
815  setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
816  /* Disable Nagle algorithm to reduce latency */
817  setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval));
818 
819  if (bind(fd, res->ai_addr, res->ai_addrlen) == 0)
820  break;
821 
822  close(fd);
823  } while ((res = res->ai_next) != NULL);
824 
825  if (res == NULL) {
826  crit("failed to bind RPC listen socket");
827  freeaddrinfo(ressave);
828  return -1;
829  }
830 
831  return fd;
832 }

◆ init_rpc_server()

void init_rpc_server ( struct fg_rpc_server server,
char *  rpc_bind_addr,
unsigned  port 
)

Initializes the xmlrpc server.

This function initializes the xmlrpc environment, registers exported methods and binds to the control port.

Definition at line 835 of file fg_rpc_server.c.

836 {
837  xmlrpc_registry * registryP;
838  xmlrpc_env *env = &(server->env);
839  memset(&(server->parms), 0, sizeof(server->parms));
840 
841  xmlrpc_env_init(env);
842  registryP = xmlrpc_registry_new(env);
843 
844  xmlrpc_registry_add_method(env, registryP, NULL, "add_flow_destination", &add_flow_destination, NULL);
845  xmlrpc_registry_add_method(env, registryP, NULL, "add_flow_source", &add_flow_source, NULL);
846  xmlrpc_registry_add_method(env, registryP, NULL, "start_flows", &start_flows, NULL);
847  xmlrpc_registry_add_method(env, registryP, NULL, "get_reports", &method_get_reports, NULL);
848  xmlrpc_registry_add_method(env, registryP, NULL, "stop_flow", &method_stop_flow, NULL);
849  xmlrpc_registry_add_method(env, registryP, NULL, "get_version", &method_get_version, NULL);
850  xmlrpc_registry_add_method(env, registryP, NULL, "get_status", &method_get_status, NULL);
851  xmlrpc_registry_add_method(env, registryP, NULL, "get_uuid", &method_get_uuid, NULL);
852 
853  /* In the modern form of the Abyss API, we supply parameters in memory
854  like a normal API. We select the modern form by setting
855  config_file_name to NULL:
856  */
857  server->parms.config_file_name = NULL;
858  server->parms.registryP = registryP;
859  server->parms.socket_bound = 1;
860  server->parms.log_file_name = NULL; /*"/tmp/xmlrpc_log";*/
861 
862  /* Increase HTTP keep-alive duration. Using defaults the amount of
863  * sockets in TIME_WAIT state would become too high.
864  */
865  server->parms.keepalive_timeout = 60;
866  server->parms.keepalive_max_conn = 1000;
867 
868  /* Disable introspection */
869  server->parms.dont_advertise = 1;
870 
871  logging(LOG_NOTICE, "running XML-RPC server on port %u", port);
872  printf("Running XML-RPC server...\n");
873 
874  server->parms.socket_handle = bind_rpc_server(rpc_bind_addr, port);
875 }

◆ method_get_reports()

static xmlrpc_value* method_get_reports ( xmlrpc_env *const  env,
xmlrpc_value *const  param_array,
void *const  user_data 
)
static

To get the reports from the daemon.

Flowgrind rpc server get the reports from the daemon and encode the information and send the report data to the controller through XML-RPC connection

Parameters
[in,out]envXML-RPC environment object
[in,out]param_arrayunused arg
[in,out]user_dataunused arg return xmlrpc_value XML-RPC value

Definition at line 518 of file fg_rpc_server.c.

521 {
522  int has_more;
523  xmlrpc_value *ret = 0, *item = 0;
524 
525  UNUSED_ARGUMENT(param_array);
526  UNUSED_ARGUMENT(user_data);
527 
528  DEBUG_MSG(LOG_NOTICE, "method get_reports called");
529 
530  struct report *report = get_reports(&has_more);
531 
532  ret = xmlrpc_array_new(env);
533 
534  /* Add information if there's more reports pending */
535  item = xmlrpc_int_new(env, has_more);
536  xmlrpc_array_append_item(env, ret, item);
537  xmlrpc_DECREF(item);
538 
539  while (report) {
540  xmlrpc_value *rv = xmlrpc_build_value(env,
541  "("
542  "{s:i,s:i,s:i,s:i,s:i,s:i,s:i}" /* Report data & timeval */
543  "{s:i,s:i,s:i,s:i}" /* bytes */
544  "{s:i,s:i,s:i,s:i}" /* block counts */
545  "{s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d}" /* RTT, IAT, Delay */
546  "{s:i,s:i}" /* MTU */
547  "{s:i,s:i,s:i,s:i,s:i}" /* TCP info */
548  "{s:i,s:i,s:i,s:i,s:i}" /* ... */
549  "{s:i,s:i,s:i,s:i,s:i}" /* ... */
550  "{s:i}"
551  ")",
552 
553  "id", report->id,
554  "endpoint",report->endpoint,
555  "type", report->type,
556  "begin_tv_sec", (int)report->begin.tv_sec,
557  "begin_tv_nsec", (int)report->begin.tv_nsec,
558  "end_tv_sec", (int)report->end.tv_sec,
559  "end_tv_nsec", (int)report->end.tv_nsec,
560 
561  "bytes_read_high", (int32_t)(report->bytes_read >> 32),
562  "bytes_read_low", (int32_t)(report->bytes_read & 0xFFFFFFFF),
563  "bytes_written_high", (int32_t)(report->bytes_written >> 32),
564  "bytes_written_low", (int32_t)(report->bytes_written & 0xFFFFFFFF),
565 
566  "request_blocks_read", report->request_blocks_read,
567  "request_blocks_written", report->request_blocks_written,
568  "response_blocks_read", report->response_blocks_read,
569  "response_blocks_written", report->response_blocks_written,
570 
571  "rtt_min", report->rtt_min,
572  "rtt_max", report->rtt_max,
573  "rtt_sum", report->rtt_sum,
574  "iat_min", report->iat_min,
575  "iat_max", report->iat_max,
576  "iat_sum", report->iat_sum,
577  "delay_min", report->delay_min,
578  "delay_max", report->delay_max,
579  "delay_sum", report->delay_sum,
580 
581  "pmtu", report->pmtu,
582  "imtu", report->imtu,
583 
584 /* Currently, not all members of the TCP_INFO socket option are used by the
585  * FreeBSD kernel. Other members will contain zeroes */
586  "tcpi_snd_cwnd", (int)report->tcp_info.tcpi_snd_cwnd,
587  "tcpi_snd_ssthresh", (int)report->tcp_info.tcpi_snd_ssthresh,
588  "tcpi_unacked", (int)report->tcp_info.tcpi_unacked,
589  "tcpi_sacked", (int)report->tcp_info.tcpi_sacked,
590  "tcpi_lost", (int)report->tcp_info.tcpi_lost,
591  "tcpi_retrans", (int)report->tcp_info.tcpi_retrans,
592  "tcpi_retransmits", (int)report->tcp_info.tcpi_retransmits,
593  "tcpi_fackets", (int)report->tcp_info.tcpi_fackets,
594  "tcpi_reordering", (int)report->tcp_info.tcpi_reordering,
595  "tcpi_rtt", (int)report->tcp_info.tcpi_rtt,
596  "tcpi_rttvar", (int)report->tcp_info.tcpi_rttvar,
597  "tcpi_rto", (int)report->tcp_info.tcpi_rto,
598  "tcpi_backoff", (int)report->tcp_info.tcpi_backoff,
599  "tcpi_ca_state", (int)report->tcp_info.tcpi_ca_state,
600  "tcpi_snd_mss", (int)report->tcp_info.tcpi_snd_mss,
601 
602  "status", report->status
603  );
604 
605  xmlrpc_array_append_item(env, ret, rv);
606 
607  xmlrpc_DECREF(rv);
608 
609  struct report *next = report->next;
610  free(report);
611  report = next;
612  }
613 
614  if (env->fault_occurred)
615  logging(LOG_WARNING, "method get_reports failed: %s",
616  env->fault_string);
617  else
618  DEBUG_MSG(LOG_WARNING, "method get_reports successful");
619 
620  return ret;
621 }

◆ method_get_status()

static xmlrpc_value* method_get_status ( xmlrpc_env *const  env,
xmlrpc_value *const  param_array,
void *const  user_data 
)
static

Definition at line 702 of file fg_rpc_server.c.

705 {
706  UNUSED_ARGUMENT(param_array);
707  UNUSED_ARGUMENT(user_data);
708 
709  int rc;
710  xmlrpc_value *ret = 0;
711  struct request_get_status *request = 0;
712 
713  DEBUG_MSG(LOG_WARNING, "method get_status called");
714 
715  request = malloc(sizeof(struct request_get_status));
717 
718  if (rc == -1)
719  XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR, request->r.error); /* goto cleanup on failure */
720 
721  /* Return our result. */
722  ret = xmlrpc_build_value(env, "{s:i,s:i}",
723  "started", request->started,
724  "num_flows", request->num_flows);
725 
726 cleanup:
727  if (request)
729 
730  if (env->fault_occurred)
731  logging(LOG_WARNING, "method get_status failed: %s",
732  env->fault_string);
733  else
734  DEBUG_MSG(LOG_WARNING, "method get_status successful");
735 
736  return ret;
737 }

◆ method_get_uuid()

static xmlrpc_value* method_get_uuid ( xmlrpc_env *const  env,
xmlrpc_value *const  param_array,
void *const  user_data 
)
static

To get the daemons UUID.

Flowgrind rpc server dispatch the request to get the daemon UUID based on the randomness. After getting these information flowgrind rpc server encode the information and send back the details to the controller through the XML-RPC connection.

Parameters
[in,out]envXML-RPC environment object
[in.out]param_array unused arg
[in,out]user_dataunused arg return xmlrpc_value XML-RPC value

Definition at line 752 of file fg_rpc_server.c.

755 {
756  UNUSED_ARGUMENT(param_array);
757  UNUSED_ARGUMENT(user_data);
758 
759  DEBUG_MSG(LOG_WARNING, "Method get_uuid called");
760 
761  xmlrpc_value *ret = 0;
762  struct request_get_uuid *request = malloc(sizeof(struct request_get_uuid));
763  int rc = dispatch_request((struct request*)request, REQUEST_GET_UUID);
764 
765  if (rc == -1)
766  XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR, request->r.error); /* goto cleanup on failure */
767 
768  /* Return our result. */
769  ret = xmlrpc_build_value(env, "{s:s}", "server_uuid", request->server_uuid);
770 
771 cleanup:
772  if (request)
774 
775  if (env->fault_occurred)
776  logging(LOG_WARNING, "Method get_uuid failed: %s", env->fault_string);
777  else
778  DEBUG_MSG(LOG_WARNING, "Method get_uuid successful");
779 
780  return ret;
781 }

◆ method_get_version()

static xmlrpc_value* method_get_version ( xmlrpc_env *const  env,
xmlrpc_value *const  param_array,
void *const  user_data 
)
static

Definition at line 669 of file fg_rpc_server.c.

672 {
673  UNUSED_ARGUMENT(param_array);
674  UNUSED_ARGUMENT(user_data);
675  struct utsname buf;
676 
677  xmlrpc_value *ret = 0;
678 
679  DEBUG_MSG(LOG_WARNING, "method get_version called");
680 
681  if (uname(&buf)) {
682  logging(LOG_WARNING, "uname() failed %s", strerror(errno));
683  exit(1);
684  }
685 
686  ret = xmlrpc_build_value(env, "{s:s,s:i,s:s,s:s}",
687  "version", FLOWGRIND_VERSION,
688  "api_version", FLOWGRIND_API_VERSION,
689  "os_name", buf.sysname,
690  "os_release", buf.release);
691 
692  if (env->fault_occurred)
693  logging(LOG_WARNING, "method get_version failed: %s",
694  env->fault_string);
695  else
696  DEBUG_MSG(LOG_WARNING, "method get_version successful");
697 
698  return ret;
699 }

◆ method_stop_flow()

static xmlrpc_value* method_stop_flow ( xmlrpc_env *const  env,
xmlrpc_value *const  param_array,
void *const  user_data 
)
static

Definition at line 623 of file fg_rpc_server.c.

626 {
627  UNUSED_ARGUMENT(user_data);
628 
629  int rc;
630  xmlrpc_value *ret = 0;
631  int flow_id;
632  struct request_stop_flow *request = 0;
633 
634  DEBUG_MSG(LOG_WARNING, "method stop_flow called");
635 
636  /* Parse our argument array. */
637  xmlrpc_decompose_value(env, param_array, "({s:i,*})",
638 
639  /* flow id */
640  "flow_id", &flow_id);
641 
642  if (env->fault_occurred)
643  goto cleanup;
644 
645  request = malloc(sizeof(struct request_stop_flow));
646  request->flow_id = flow_id;
648 
649  if (rc == -1)
650  XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR, request->r.error); /* goto cleanup on failure */
651 
652  /* Return our result. */
653  ret = xmlrpc_build_value(env, "()");
654 
655 cleanup:
656  if (request)
658 
659  if (env->fault_occurred)
660  logging(LOG_WARNING, "method stop_flow failed: %s",
661  env->fault_string);
662  else
663  DEBUG_MSG(LOG_WARNING, "method stop_flow successful");
664 
665  return ret;
666 }

◆ run_rpc_server()

void run_rpc_server ( struct fg_rpc_server server)

Enters the xmlrpc server mainloop.

Definition at line 878 of file fg_rpc_server.c.

879 {
880  xmlrpc_env *env = &(server->env);
881  xmlrpc_server_abyss(env, &(server->parms), XMLRPC_APSIZE(socket_handle));
882 
883  if (env->fault_occurred)
884  logging(LOG_ALERT, "XML-RPC Fault: %s (%d)", env->fault_string,
885  env->fault_code);
886  /* xmlrpc_server_abyss() never returns */
887 }

◆ start_flows()

static xmlrpc_value* start_flows ( xmlrpc_env *const  env,
xmlrpc_value *const  param_array,
void *const  user_data 
)
static

Definition at line 462 of file fg_rpc_server.c.

465 {
466  UNUSED_ARGUMENT(user_data);
467 
468  int rc;
469  xmlrpc_value *ret = 0;
470  int start_timestamp;
471  struct request_start_flows *request = 0;
472 
473  DEBUG_MSG(LOG_WARNING, "method start_flows called");
474 
475  /* Parse our argument array. */
476  xmlrpc_decompose_value(env, param_array, "({s:i,*})",
477 
478  /* general settings */
479  "start_timestamp", &start_timestamp);
480 
481  if (env->fault_occurred)
482  goto cleanup;
483 
484  request = malloc(sizeof(struct request_start_flows));
485  request->start_timestamp = start_timestamp;
487 
488  if (rc == -1)
489  XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR, request->r.error); /* goto cleanup on failure */
490 
491  /* Return our result. */
492  ret = xmlrpc_build_value(env, "i", 0);
493 
494 cleanup:
495  if (request)
497 
498  if (env->fault_occurred)
499  logging(LOG_WARNING, "method start_flows failed: %s",
500  env->fault_string);
501  else
502  DEBUG_MSG(LOG_WARNING, "method start_flows successful");
503 
504  return ret;
505 }
fg_tcp_info::tcpi_unacked
int tcpi_unacked
Definition: common.h:270
DEBUG_MSG
#define DEBUG_MSG(LVL, MSG,...)
Print debug message to standard error.
Definition: debug.h:49
REQUEST_STOP_FLOW
#define REQUEST_STOP_FLOW
Definition: daemon.h:176
report::id
int id
Definition: common.h:287
trafgen_options::distribution
enum distribution_t distribution
The stochastic distribution to draw values from.
Definition: common.h:168
WRITE
@ WRITE
Write operation.
Definition: common.h:106
fg_tcp_info::tcpi_rttvar
int tcpi_rttvar
Definition: common.h:278
request_stop_flow::flow_id
int flow_id
Definition: daemon.h:231
MAX_EXTRA_SOCKET_OPTIONS
#define MAX_EXTRA_SOCKET_OPTIONS
Max number of arbitrary extra socket options which may sent to the deamon.
Definition: common.h:68
request_add_flow_source::source_settings
struct flow_source_settings source_settings
Definition: daemon.h:211
request_get_status
Definition: daemon.h:247
flow_settings::random_seed
unsigned random_seed
Random seed to use (default: read /dev/urandom) (option -J).
Definition: common.h:223
report::rtt_max
double rtt_max
Maximum round-trip time.
Definition: common.h:323
REQUEST_GET_UUID
#define REQUEST_GET_UUID
Definition: daemon.h:178
fg_tcp_info::tcpi_reordering
int tcpi_reordering
Definition: common.h:276
add_flow_source
static xmlrpc_value * add_flow_source(xmlrpc_env *const env, xmlrpc_value *const param_array, void *const user_data)
Prepare data connection for source endpoint.
Definition: fg_rpc_server.c:62
report::rtt_sum
double rtt_sum
Accumulated round-trip time.
Definition: common.h:325
MAX_EXTRA_SOCKET_OPTION_VALUE_LENGTH
#define MAX_EXTRA_SOCKET_OPTION_VALUE_LENGTH
Ensures extra options are limited in length on both controller and deamon.
Definition: common.h:71
crit
#define crit(...)
To report an critical error w/ the corresponding system error message.
Definition: fg_error.h:36
get_reports
struct report * get_reports(int *has_more)
Definition: daemon.c:853
flow_settings::dscp
int dscp
DSCP value for TOS byte (option -D).
Definition: common.h:244
request_add_flow_destination::settings
struct flow_settings settings
Definition: daemon.h:197
flow_settings::requested_read_buffer_size
int requested_read_buffer_size
Request receiver buffer, advertised window in bytes (option -W).
Definition: common.h:198
flow_source_settings::destination_host
char destination_host[256]
Definition: daemon.h:65
report::delay_max
double delay_max
Maximum one-way delay.
Definition: common.h:317
port
static unsigned port
Definition: flowgrindd.c:95
report::request_blocks_written
unsigned request_blocks_written
Definition: common.h:302
logging
void logging(int priority, const char *fmt,...)
Definition: fg_log.c:69
report::bytes_read
unsigned long long bytes_read
Definition: common.h:295
request_add_flow_source::settings
struct flow_settings settings
Definition: daemon.h:210
request_add_flow_source::cc_alg
char cc_alg[TCP_CA_NAME_MAX]
Definition: daemon.h:215
method_get_uuid
static xmlrpc_value * method_get_uuid(xmlrpc_env *const env, xmlrpc_value *const param_array, void *const user_data)
To get the daemons UUID.
Definition: fg_rpc_server.c:752
report::iat_sum
double iat_sum
Accumulated inter-arrival time.
Definition: common.h:313
flow_settings::extra_socket_options
struct flow_settings::extra_socket_options extra_socket_options[MAX_EXTRA_SOCKET_OPTIONS]
fg_tcp_info::tcpi_sacked
int tcpi_sacked
Definition: common.h:271
READ
@ READ
Read operation.
Definition: common.h:108
UNUSED_ARGUMENT
#define UNUSED_ARGUMENT(x)
Suppress warning for unused argument.
Definition: fg_definitions.h:38
fg_tcp_info::tcpi_fackets
int tcpi_fackets
Definition: common.h:275
flow_settings::duration
double duration[2]
Duration of flow in seconds (option -T).
Definition: common.h:190
flow_settings::cork
int cork
Sets SO_DEBUG on test socket (option -O).
Definition: common.h:232
report::delay_min
double delay_min
Minimum one-way delay.
Definition: common.h:315
trafgen_options::param_two
double param_two
Second mathematical parameter of the distribution, if required.
Definition: common.h:172
flow_settings::byte_counting
int byte_counting
Enumerate bytes in payload instead of sending zeros (option -E).
Definition: common.h:229
flow_settings::cc_alg
char cc_alg[TCP_CA_NAME_MAX]
Set congestion control algorithm ALG on test socket (option -O).
Definition: common.h:236
flow_settings::response_trafgen_options
struct trafgen_options response_trafgen_options
Stochastic traffic generation settings for the response size.
Definition: common.h:251
request_start_flows::start_timestamp
int start_timestamp
Definition: daemon.h:224
flow_source_settings
Definition: daemon.h:63
report::next
struct report * next
Definition: common.h:338
request_stop_flow
Definition: daemon.h:227
fg_tcp_info::tcpi_backoff
int tcpi_backoff
Definition: common.h:280
flow_settings::extra_socket_options::optlen
int optlen
Definition: common.h:259
fg_tcp_info::tcpi_rtt
int tcpi_rtt
Definition: common.h:277
flow_settings::interpacket_gap_trafgen_options
struct trafgen_options interpacket_gap_trafgen_options
Stochastic traffic generation settings for the interpacket gap.
Definition: common.h:253
request_add_flow_destination
Definition: daemon.h:193
request_start_flows
Definition: daemon.h:220
rpc_bind_addr
static char * rpc_bind_addr
Definition: flowgrindd.c:98
report
Definition: common.h:286
flow_settings::traffic_dump
int traffic_dump
Dump traffic using libpcap (option -M).
Definition: common.h:204
method_get_status
static xmlrpc_value * method_get_status(xmlrpc_env *const env, xmlrpc_value *const param_array, void *const user_data)
Definition: fg_rpc_server.c:702
dispatch_request
int dispatch_request(struct request *request, int type)
Dispatch a request to daemon loop.
Definition: daemon.c:1489
flow_settings::ipmtudiscover
int ipmtudiscover
Set IP_MTU_DISCOVER on test socket (option -O).
Definition: common.h:246
flow_settings::extra_socket_options::optval
char optval[MAX_EXTRA_SOCKET_OPTION_VALUE_LENGTH]
Definition: common.h:260
fg_tcp_info::tcpi_retransmits
int tcpi_retransmits
Definition: common.h:274
flow_settings::maximum_block_size
int maximum_block_size
Application buffer size in bytes (option -U).
Definition: common.h:201
fg_tcp_info::tcpi_snd_mss
int tcpi_snd_mss
Definition: common.h:281
flow_source_settings::late_connect
int late_connect
Definition: daemon.h:68
flow_settings::flow_control
int flow_control
Stop flow if it is experiencing local congestion (option -C).
Definition: common.h:226
method_get_version
static xmlrpc_value * method_get_version(xmlrpc_env *const env, xmlrpc_value *const param_array, void *const user_data)
Definition: fg_rpc_server.c:669
request_add_flow_source
Definition: daemon.h:206
flow_settings::flow_id
int flow_id
Flow ID maintained by controller.
Definition: common.h:186
fg_rpc_server::env
xmlrpc_env env
Environment used by the Abyss server.
Definition: fg_rpc_server.h:52
request
Definition: daemon.h:179
report::iat_max
double iat_max
Maximum inter-arrival time.
Definition: common.h:311
flow_settings::num_extra_socket_options
int num_extra_socket_options
Definition: common.h:262
flow_settings::pushy
int pushy
Do not iterate through select() to continue sending in case block size did not suffice to fill sendin...
Definition: common.h:213
critx
#define critx(...)
To report an critical error w/o a system error message.
Definition: fg_error.h:40
flow_settings::nonagle
int nonagle
Disable nagle algorithm on test socket (option -O).
Definition: common.h:234
request::error
char * error
Definition: daemon.h:187
method_get_reports
static xmlrpc_value * method_get_reports(xmlrpc_env *const env, xmlrpc_value *const param_array, void *const user_data)
To get the reports from the daemon.
Definition: fg_rpc_server.c:518
MIN_BLOCK_SIZE
#define MIN_BLOCK_SIZE
Minium block (message) size we can send.
Definition: common.h:79
report::bytes_written
unsigned long long bytes_written
Definition: common.h:296
flow_settings::reporting_interval
double reporting_interval
Interval to report flow on screen (option -i).
Definition: common.h:193
flow_settings::write_rate
int write_rate
The actual rate we should send.
Definition: common.h:220
flow_settings::elcn
int elcn
Set TCP_ELCN (20) on test socket (option -O).
Definition: common.h:238
add_flow_destination
static xmlrpc_value * add_flow_destination(xmlrpc_env *const env, xmlrpc_value *const param_array, void *const user_data)
Prepare data connection for destination endpoint.
Definition: fg_rpc_server.c:277
fg_tcp_info::tcpi_ca_state
int tcpi_ca_state
Definition: common.h:282
FLOWGRIND_VERSION
#define FLOWGRIND_VERSION
Flowgrind version number.
Definition: common.h:44
bind_rpc_server
static int bind_rpc_server(char *bind_addr, unsigned port)
Definition: fg_rpc_server.c:784
report::pmtu
unsigned pmtu
Discovered Path MTU.
Definition: common.h:332
flow_settings::delay
double delay[2]
Delay of flow in seconds (option -Y).
Definition: common.h:188
REQUEST_GET_STATUS
#define REQUEST_GET_STATUS
Definition: daemon.h:177
report::status
int status
Definition: common.h:336
flow_settings::lcd
int lcd
Set TCP_LCD (21) on test socket (option -O).
Definition: common.h:240
free_all
#define free_all(...)
To free() an arbitrary number of variables.
Definition: fg_definitions.h:59
report::delay_sum
double delay_sum
Accumulated one-way delay.
Definition: common.h:319
request_get_uuid
structure for getting the UUID.
Definition: daemon.h:240
report::response_blocks_written
unsigned response_blocks_written
Definition: common.h:304
report::type
enum report_t type
Report type - either INTERVAL or FINAL report.
Definition: common.h:291
dump_prefix
char * dump_prefix
Definition: daemon.c:90
flow_settings::shutdown
int shutdown
Shutdown socket after test flow (option -N).
Definition: common.h:215
fg_tcp_info::tcpi_lost
int tcpi_lost
Definition: common.h:272
method_stop_flow
static xmlrpc_value * method_stop_flow(xmlrpc_env *const env, xmlrpc_value *const param_array, void *const user_data)
Definition: fg_rpc_server.c:623
report::endpoint
enum endpoint_t endpoint
Daemon endpoint - either source or destination.
Definition: common.h:289
flow_settings::extra_socket_options::level
int level
Definition: common.h:257
report::imtu
unsigned imtu
Interface MTU.
Definition: common.h:334
fg_tcp_info::tcpi_retrans
int tcpi_retrans
Definition: common.h:273
start_flows
static xmlrpc_value * start_flows(xmlrpc_env *const env, xmlrpc_value *const param_array, void *const user_data)
Definition: fg_rpc_server.c:462
TCP_CA_NAME_MAX
#define TCP_CA_NAME_MAX
Max size of the congestion control algorithm specifier string.
Definition: common.h:75
report::end
struct timespec end
Definition: common.h:293
report::tcp_info
struct fg_tcp_info tcp_info
Definition: common.h:329
REQUEST_START_FLOWS
#define REQUEST_START_FLOWS
Definition: daemon.h:175
fg_tcp_info::tcpi_snd_ssthresh
int tcpi_snd_ssthresh
Definition: common.h:269
fg_tcp_info::tcpi_snd_cwnd
int tcpi_snd_cwnd
Definition: common.h:268
report::request_blocks_read
unsigned request_blocks_read
Definition: common.h:301
flow_settings::mtcp
int mtcp
Set TCP_MTCP (15) on test socket (option -O).
Definition: common.h:242
flow_source_settings::destination_port
int destination_port
Definition: daemon.h:66
report::rtt_min
double rtt_min
Minimum round-trip time.
Definition: common.h:321
trafgen_options::param_one
double param_one
First mathemathical parameter of the distribution.
Definition: common.h:170
flow_settings::request_trafgen_options
struct trafgen_options request_trafgen_options
Stochastic traffic generation settings for the request size.
Definition: common.h:249
flow_settings::bind_address
char bind_address[1000]
The interface address for the flow (used by daemon).
Definition: common.h:183
fg_rpc_server::parms
xmlrpc_server_abyss_parms parms
Parameters of the XMLrpc server.
Definition: fg_rpc_server.h:54
REQUEST_ADD_SOURCE
#define REQUEST_ADD_SOURCE
Definition: daemon.h:174
REQUEST_ADD_DESTINATION
#define REQUEST_ADD_DESTINATION
Definition: daemon.h:173
report::begin
struct timespec begin
Definition: common.h:292
flow_settings::so_debug
int so_debug
Sets SO_DEBUG on test socket (option -O).
Definition: common.h:206
flow_settings::extra_socket_options::optname
int optname
Definition: common.h:258
fg_tcp_info::tcpi_rto
int tcpi_rto
Definition: common.h:279
FLOWGRIND_API_VERSION
#define FLOWGRIND_API_VERSION
XML-RPC API version in integer representation.
Definition: common.h:52
report::iat_min
double iat_min
Minimum inter-arrival time.
Definition: common.h:309
flow_settings::requested_send_buffer_size
int requested_send_buffer_size
Request sender buffer in bytes (option -B).
Definition: common.h:196
report::response_blocks_read
unsigned response_blocks_read
Definition: common.h:303
flow_settings::route_record
int route_record
Sets ROUTE_RECORD on test socket (option -O).
Definition: common.h:208
flow_settings
Settings that describe a flow between from a endpoint's perspective.
Definition: common.h:181