 |
Flowgrind
Advanced TCP traffic generator
|
Routines used by the Flowgrind daemon.
More...
#include "config.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdbool.h>
#include <strings.h>
#include <signal.h>
#include <string.h>
#include <fcntl.h>
#include <math.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/param.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
#include <time.h>
#include <syslog.h>
#include <sys/time.h>
#include <netdb.h>
#include <pthread.h>
#include <inttypes.h>
#include <float.h>
#include <uuid/uuid.h>
#include "common.h"
#include "debug.h"
#include "fg_error.h"
#include "fg_math.h"
#include "fg_definitions.h"
#include "fg_socket.h"
#include "fg_time.h"
#include "fg_log.h"
#include "daemon.h"
#include "source.h"
#include "destination.h"
#include "trafgen.h"
#include "fg_pcap.h"
Go to the source code of this file.
|
void | add_report (struct report *report) |
|
int | apply_extra_socket_options (struct flow *flow) |
|
void * | daemon_main (void *ptr __attribute__((unused))) |
|
int | dispatch_request (struct request *request, int type) |
| Dispatch a request to daemon loop. More...
|
|
static int | flow_block_scheduled (struct timespec *now, struct flow *flow) |
|
void | flow_error (struct flow *flow, const char *fmt,...) |
|
static int | flow_in_delay (struct timespec *now, struct flow *flow, int direction) |
|
static int | flow_sending (struct timespec *now, struct flow *flow, int direction) |
|
struct report * | get_reports (int *has_more) |
|
int | get_tcp_info (struct flow *flow, struct fg_tcp_info *info) |
|
void | get_uuid_string (char *uuid_str) |
| To generate daemon UUID. More...
|
|
void | init_flow (struct flow *flow, int is_source) |
| To initialize all flows to the default value. More...
|
|
static int | prepare_fds () |
|
static int | prepare_rfds (struct timespec *now, struct flow *flow, fd_set *rfds) |
|
static void | prepare_wfds (struct timespec *now, struct flow *flow, fd_set *wfds) |
|
static void | process_delay (struct flow *flow) |
|
static void | process_iat (struct flow *flow) |
|
static void | process_requests () |
| To process the request issued from the controller. More...
|
|
static void | process_rtt (struct flow *flow) |
|
static void | process_select (fd_set *rfds, fd_set *wfds, fd_set *efds) |
|
static int | read_data (struct flow *flow) |
|
void | remove_flow (struct flow *const flow) |
|
static void | report_flow (struct flow *flow, int type) |
| To prepare a report, report type is either INTERVAL or FINAL. More...
|
|
void | request_error (struct request *request, const char *fmt,...) |
|
static void | send_response (struct flow *flow, int requested_response_block_size) |
|
int | set_flow_tcp_options (struct flow *flow) |
|
static void | start_flows (struct request_start_flows *request) |
|
static void | stop_flow (struct request_stop_flow *request) |
|
static void | timer_check () |
|
static int | try_read_n_bytes (struct flow *flow, int bytes) |
|
void | uninit_flow (struct flow *flow) |
|
static int | write_data (struct flow *flow) |
|
Routines used by the Flowgrind daemon.
Definition in file daemon.c.
◆ CONGESTION_LIMIT
#define CONGESTION_LIMIT 10000 |
◆ CPY_INFO_MEMBER
#define CPY_INFO_MEMBER |
( |
|
a | ) |
info->a = (int) tmp_info.a; |
◆ SOL_TCP
#define SOL_TCP IPPROTO_TCP |
◆ add_report()
void add_report |
( |
struct report * |
report | ) |
|
Definition at line 827 of file daemon.c.
829 DEBUG_MSG(LOG_DEBUG,
"add_report trying to lock mutex");
830 pthread_mutex_lock(&
mutex);
831 DEBUG_MSG(LOG_DEBUG,
"add_report aquired mutex");
835 pthread_mutex_unlock(&
mutex);
849 pthread_mutex_unlock(&
mutex);
850 DEBUG_MSG(LOG_DEBUG,
"add_report unlocked mutex");
◆ apply_extra_socket_options()
int apply_extra_socket_options |
( |
struct flow * |
flow | ) |
|
Definition at line 1378 of file daemon.c.
1382 const struct extra_socket_options *option =
1385 switch (option->level) {
1396 level = IPPROTO_SCTP;
1399 level = IPPROTO_TCP;
1402 level = IPPROTO_UDP;
1410 res = setsockopt(
flow->
fd, level, option->optname,
1411 option->optval, option->optlen);
1415 option->optname, strerror(errno));
◆ daemon_main()
void* daemon_main |
( |
void *ptr |
__attribute__(unused) | ) |
|
Definition at line 800 of file daemon.c.
802 struct timespec timeout;
808 DEBUG_MSG(LOG_DEBUG,
"calling pselect() need_timeout: %i",
811 need_timeout ? &timeout : 0, NULL);
815 crit(
"pselect() failed");
817 DEBUG_MSG(LOG_DEBUG,
"pselect() finished");
◆ dispatch_request()
int dispatch_request |
( |
struct request * |
request, |
|
|
int |
type |
|
) |
| |
Dispatch a request to daemon loop.
Is called by the rpc server to feed in requests to the daemon.
Definition at line 1489 of file daemon.c.
1491 pthread_cond_t cond;
1498 if (pthread_cond_init(&cond, NULL)) {
1504 pthread_mutex_lock(&
mutex);
1516 pthread_cond_wait(&cond, &
mutex);
1518 pthread_mutex_unlock(&
mutex);
◆ flow_block_scheduled()
static int flow_block_scheduled |
( |
struct timespec * |
now, |
|
|
struct flow * |
flow |
|
) |
| |
|
inlinestatic |
◆ flow_error()
void flow_error |
( |
struct flow * |
flow, |
|
|
const char * |
fmt, |
|
|
|
... |
|
) |
| |
Definition at line 119 of file daemon.c.
125 vsnprintf(str, 1000, fmt, ap);
127 str[
sizeof(str) - 1] = 0;
◆ flow_in_delay()
static int flow_in_delay |
( |
struct timespec * |
now, |
|
|
struct flow * |
flow, |
|
|
int |
direction |
|
) |
| |
|
inlinestatic |
◆ flow_sending()
static int flow_sending |
( |
struct timespec * |
now, |
|
|
struct flow * |
flow, |
|
|
int |
direction |
|
) |
| |
|
inlinestatic |
◆ get_reports()
struct report* get_reports |
( |
int * |
has_more | ) |
|
Definition at line 853 of file daemon.c.
855 const unsigned max_reports = 50;
858 DEBUG_MSG(LOG_DEBUG,
"get_reports trying to lock mutex");
859 pthread_mutex_lock(&
mutex);
860 DEBUG_MSG(LOG_DEBUG,
"get_reports aquired mutex");
871 for (
unsigned i = 0; i < max_reports - 1; i++)
881 pthread_mutex_unlock(&
mutex);
882 DEBUG_MSG(LOG_DEBUG,
"get_reports unlocked mutex");
◆ get_tcp_info()
- Todo:
- FreeBSD 9.1 doesn't fill these members, but maybe FreeBSD 10.0 will fill it, so get rid of this ifdef
Definition at line 650 of file daemon.c.
653 struct tcp_info tmp_info;
654 socklen_t info_len =
sizeof(tmp_info);
658 rc = getsockopt(
flow->
fd, IPPROTO_TCP, TCP_INFO, &tmp_info, &info_len);
660 warn(
"getsockopt() failed");
663 #define CPY_INFO_MEMBER(a) info->a = (int) tmp_info.a;
◆ get_uuid_string()
void get_uuid_string |
( |
char * |
uuid_str | ) |
|
To generate daemon UUID.
Generate the daemon UUID and convert the UUID to a string data. UUID is generated by daemon only once and stored in the global variable. The daemon return the same UUID for all the flows it maintaining. This UUID is taken as a reference to identify the daemon in the controller.
- Parameters
-
[in,out] | uuid_str | daemons UUID |
Definition at line 1536 of file daemon.c.
1539 static char server_uuid[38] =
"";
1541 if (!strlen(server_uuid)) {
1542 uuid_generate_time(uuid);
1543 uuid_unparse(uuid,uuid_str);
1544 memset(server_uuid,0,
sizeof(server_uuid));
1545 strcpy(server_uuid,uuid_str);
1548 strcpy(uuid_str,server_uuid);
◆ init_flow()
void init_flow |
( |
struct flow * |
flow, |
|
|
int |
is_source |
|
) |
| |
To initialize all flows to the default value.
The daemon maintain all its data in its flow
statistics data structure. These data are initialize to the default value or zero value according to their metrics details.
- Parameters
-
[in,out] | flow | flow structure maintained by a daemon |
[in] | is_source | to determine flow endpoint i.e. source or destination |
Definition at line 896 of file daemon.c.
898 memset(
flow, 0,
sizeof(
struct flow));
◆ prepare_fds()
static int prepare_fds |
( |
| ) |
|
|
static |
Definition at line 267 of file daemon.c.
269 DEBUG_MSG(LOG_DEBUG,
"prepare_fds() called, number of flows: %zu",
◆ prepare_rfds()
static int prepare_rfds |
( |
struct timespec * |
now, |
|
|
struct flow * |
flow, |
|
|
fd_set * |
rfds |
|
) |
| |
|
static |
Definition at line 233 of file daemon.c.
239 warnx(
"server flow %u missed to shutdown",
flow->
id);
240 rc = shutdown(
flow->
fd, SHUT_RD);
242 warn(
"shutdown SHUT_RD failed");
248 DEBUG_MSG(LOG_ERR,
"late connecting test socket for flow %d "
259 DEBUG_MSG(LOG_DEBUG,
"adding sock of flow %d to rfds",
◆ prepare_wfds()
static void prepare_wfds |
( |
struct timespec * |
now, |
|
|
struct flow * |
flow, |
|
|
fd_set * |
wfds |
|
) |
| |
|
static |
Definition at line 199 of file daemon.c.
204 DEBUG_MSG(LOG_WARNING,
"flow %i not started yet (delayed)",
212 DEBUG_MSG(LOG_DEBUG,
"adding sock of flow %d to wfds",
216 DEBUG_MSG(LOG_DEBUG,
"no block for flow %d scheduled "
222 DEBUG_MSG(LOG_WARNING,
"shutting down flow %d (WR)",
224 rc = shutdown(
flow->
fd,SHUT_WR);
226 warn(
"shutdown() SHUT_WR failed");
◆ process_delay()
static void process_delay |
( |
struct flow * |
flow | ) |
|
|
static |
Definition at line 1267 of file daemon.c.
1269 double current_delay = .0;
1270 struct timespec now;
1271 struct timespec *data = (
struct timespec *)
1277 if (current_delay < 0) {
1278 logging(LOG_NOTICE,
"calculated malformed delay of flow "
1279 "%d (rtt = %.3lfms) (clocks out-of-sync?), ignoring",
1280 flow->
id, current_delay * 1e3);
1281 current_delay = NAN;
1284 if (!isnan(current_delay)) {
1294 DEBUG_MSG(LOG_NOTICE,
"processed delay of flow %d (%.3lfms)",
1295 flow->
id, current_delay * 1e3);
◆ process_iat()
static void process_iat |
( |
struct flow * |
flow | ) |
|
|
static |
Definition at line 1234 of file daemon.c.
1236 double current_iat = .0;
1237 struct timespec now;
1247 if (current_iat < 0) {
1248 logging(LOG_CRIT,
"calculated malformed iat of flow %d "
1249 "(iat = %.3lfms) (clock skew?), ignoring",
1250 flow->
id, current_iat * 1e3);
1256 if (!isnan(current_iat)) {
1263 DEBUG_MSG(LOG_NOTICE,
"processed IAT of flow %d (%.3lfms)",
1264 flow->
id, current_iat * 1e3);
◆ process_requests()
static void process_requests |
( |
| ) |
|
|
static |
To process the request issued from the controller.
The daemon reads the request from the controller, and executes the issued request type from the controller. The daemons have separate data structure for each request type.
Definition at line 446 of file daemon.c.
449 DEBUG_MSG(LOG_DEBUG,
"process_requests trying to lock mutex");
450 pthread_mutex_lock(&
mutex);
451 DEBUG_MSG(LOG_DEBUG,
"process_requests locked mutex");
505 pthread_mutex_unlock(&
mutex);
506 DEBUG_MSG(LOG_DEBUG,
"process_requests unlocked mutex");
◆ process_rtt()
static void process_rtt |
( |
struct flow * |
flow | ) |
|
|
static |
Definition at line 1204 of file daemon.c.
1206 double current_rtt = .0;
1207 struct timespec now;
1208 struct timespec *data = (
struct timespec *)
1214 if (current_rtt < 0) {
1215 logging(LOG_CRIT,
"received malformed rtt block of flow %d "
1216 "(rtt = %.3lfms), ignoring",
flow->
id, current_rtt * 1e3);
1222 if (!isnan(current_rtt)) {
1230 DEBUG_MSG(LOG_NOTICE,
"processed RTT of flow %d (%.3lfms)",
1231 flow->
id, current_rtt * 1e3);
◆ process_select()
static void process_select |
( |
fd_set * |
rfds, |
|
|
fd_set * |
wfds, |
|
|
fd_set * |
efds |
|
) |
| |
|
static |
Definition at line 729 of file daemon.c.
736 DEBUG_MSG(LOG_DEBUG,
"processing pselect() for flow %d",
741 DEBUG_MSG(LOG_DEBUG,
"ready for accept");
753 int error_number, rc;
754 socklen_t error_number_size =
755 sizeof(error_number);
756 DEBUG_MSG(LOG_DEBUG,
"sock of flow %d in efds",
758 rc = getsockopt(
flow->
fd, SOL_SOCKET,
760 (
void *)&error_number,
763 warn(
"failed to get errno for"
764 "non-blocking connect");
767 if (error_number != 0) {
768 warnc(error_number,
"connect");
774 DEBUG_MSG(LOG_ERR,
"write_data() failed");
780 DEBUG_MSG(LOG_ERR,
"read_data() failed");
◆ read_data()
static int read_data |
( |
struct flow * |
flow | ) |
|
|
static |
- Todo:
- process_rtt(), process_iat(), and process_delay () call all gettime(). Quite inefficient...
Definition at line 1113 of file daemon.c.
1117 int requested_response_block_size = 0;
1135 logging(LOG_WARNING,
"flow %d parsed illegal cbs %d, "
1136 "ignoring (max: %d)",
flow->
id, optint,
1141 if (optint == -1 || optint == 0 ||
1144 requested_response_block_size = optint;
1146 logging(LOG_WARNING,
"flow %d parsed illegal qbs %d, "
1147 "ignoring (max: %d)",
flow->
id, optint,
1150 if (requested_response_block_size == -1) {
1151 DEBUG_MSG(LOG_NOTICE,
"processing response block on "
1152 "flow %d size: %d",
flow->
id,
1155 DEBUG_MSG(LOG_NOTICE,
"processing request block on "
1156 "flow %d size: %d, request: %d",
flow->
id,
1158 requested_response_block_size);
1178 if (requested_response_block_size == -1) {
1192 if (requested_response_block_size >=
1195 requested_response_block_size);
◆ remove_flow()
void remove_flow |
( |
struct flow *const |
flow | ) |
|
◆ report_flow()
static void report_flow |
( |
struct flow * |
flow, |
|
|
int |
type |
|
) |
| |
|
static |
To prepare a report, report type is either INTERVAL or FINAL.
The daemon report the test data and results according to time duration for reporting interval. The daemon maintain all its data in its flow
statistics data structure. These data are stored in the report data structure and reported to the controller.The flow id, flow endpoint (source or destination) and report type
(interval or final) are used to identify the flow report in controller.
- Parameters
-
[in,out] | flow | flow structure maintained by a daemon |
[in] | type | To determine report type i.e. interval or final |
Definition at line 522 of file daemon.c.
524 DEBUG_MSG(LOG_DEBUG,
"report_flow called for flow %d (type %d)",
644 DEBUG_MSG(LOG_DEBUG,
"report_flow finished for flow %d (type %d)",
◆ request_error()
void request_error |
( |
struct request * |
request, |
|
|
const char * |
fmt, |
|
|
|
... |
|
) |
| |
Definition at line 132 of file daemon.c.
138 vsnprintf(str, 1000, fmt, ap);
140 str[
sizeof(str) - 1] = 0;
◆ send_response()
static void send_response |
( |
struct flow * |
flow, |
|
|
int |
requested_response_block_size |
|
) |
| |
|
static |
Definition at line 1298 of file daemon.c.
1307 htonl(requested_response_block_size);
1320 DEBUG_MSG(LOG_DEBUG,
"wrote new response data to out buffer bs = %d, "
1321 "rqs = %d on flow %d",
1331 requested_response_block_size -
1334 DEBUG_MSG(LOG_NOTICE,
"send %d bytes response (rqs %d) on flow "
1335 "%d", rc, requested_response_block_size,
flow->
id);
1338 if (errno == EAGAIN) {
1339 DEBUG_MSG(LOG_DEBUG,
"%s, still trying to send "
1340 "response block (write queue hit "
1341 "limit)", strerror(errno));
1345 logging(LOG_WARNING,
"tried to send "
1346 "response block %d times without "
1347 "success, dropping (%s)",
1348 try, strerror(errno));
1352 logging(LOG_WARNING,
"premature end of test: "
1353 "%s, abort flow", strerror(errno));
1363 (
unsigned)requested_response_block_size) {
1365 (
unsigned)requested_response_block_size);
◆ set_flow_tcp_options()
int set_flow_tcp_options |
( |
struct flow * |
flow | ) |
|
Definition at line 1424 of file daemon.c.
1431 "algorithm: %s", strerror(errno));
◆ start_flows()
Definition at line 333 of file daemon.c.
335 struct timespec start;
339 if (start.tv_sec <
request->start_timestamp) {
342 start.tv_sec =
request->start_timestamp;
357 for (
int j = 0; j < 2; j++) {
◆ stop_flow()
Definition at line 382 of file daemon.c.
384 DEBUG_MSG(LOG_DEBUG,
"stop_flow forcefully unlocked mutex");
385 pthread_mutex_unlock(&
mutex);
◆ timer_check()
static void timer_check |
( |
| ) |
|
|
static |
Definition at line 691 of file daemon.c.
704 DEBUG_MSG(LOG_DEBUG,
"processing timer_check() for flow %d",
726 DEBUG_MSG(LOG_DEBUG,
"finished timer_check()");
◆ try_read_n_bytes()
static int try_read_n_bytes |
( |
struct flow * |
flow, |
|
|
int |
bytes |
|
) |
| |
|
inlinestatic |
Definition at line 1054 of file daemon.c.
1062 struct cmsghdr *cmsg;
1068 iov.iov_len = bytes;
1070 msg.msg_name = NULL;
1071 msg.msg_namelen = 0;
1074 msg.msg_control = cbuf;
1075 msg.msg_controllen =
sizeof(cbuf);
1077 rc = recvmsg(
flow->
fd, &msg, 0);
1079 DEBUG_MSG(LOG_DEBUG,
"tried reading %d bytes, got %d", bytes, rc);
1082 if (errno == EAGAIN)
1089 DEBUG_MSG(LOG_ERR,
"server shut down test socket of flow %d",
1092 warnx(
"premature shutdown of server flow");
1105 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
1106 DEBUG_MSG(LOG_NOTICE,
"flow %d received cmsg: type = %u, len = %u",
1107 flow->
id, cmsg->cmsg_type, (socklen_t) cmsg->cmsg_len);
◆ uninit_flow()
void uninit_flow |
( |
struct flow * |
flow | ) |
|
Definition at line 165 of file daemon.c.
177 logging(LOG_WARNING,
"failed to cancel dump thread: %s",
183 logging(LOG_WARNING,
"failed to join dump thread: %s",
◆ write_data()
static int write_data |
( |
struct flow * |
flow | ) |
|
|
static |
Definition at line 937 of file daemon.c.
940 int response_block_size = 0;
941 double interpacket_gap = .0;
955 htonl(response_block_size);
961 DEBUG_MSG(LOG_DEBUG,
"wrote new request data to out "
962 "buffer bs = %d, rqs = %d, on flow %d",
975 if (errno == EAGAIN) {
976 logging(LOG_WARNING,
"write queue limit hit for "
980 DEBUG_MSG(LOG_WARNING,
"write() returned %d on flow %d, "
989 DEBUG_MSG(LOG_CRIT,
"flow %d sent zero bytes. what "
990 "does that mean?",
flow->
id);
994 DEBUG_MSG(LOG_DEBUG,
"flow %d sent %d request bytes of %u "
995 "(before = %u)",
flow->
id, rc,
1020 if (interpacket_gap) {
1025 char timestamp[30] =
"";
1027 timestamp,
sizeof(timestamp),
true);
1029 "congestion on flow %u new "
1030 "block scheduled for %s, "
1031 "%.6lfs before now",
1043 DEBUG_MSG(LOG_NOTICE,
"failed to recork test "
1044 "socket for flow %d: %s",
1045 flow->
id, strerror(errno));
◆ daemon_pipe
◆ daemon_thread
◆ dump_dir
◆ dump_prefix
◆ efds
◆ flows
◆ maxfd
◆ mutex
◆ pending_reports
unsigned pending_reports = 0 |
◆ reports
◆ reports_last
struct report* reports_last = 0 |
◆ requests
◆ requests_last
◆ rfds
◆ started
◆ wfds
#define DEBUG_MSG(LVL, MSG,...)
Print debug message to standard error.
unsigned response_blocks_read
#define REQUEST_STOP_FLOW
@ INTERVAL
Intermediated interval report.
static void prepare_wfds(struct timespec *now, struct flow *flow, fd_set *wfds)
#define ASSIGN_MAX(s, c)
Assign value if it's greater than current one.
int apply_extra_socket_options(struct flow *flow)
double delay_sum
Accumulated one-way delay.
unsigned current_read_block_size
void time_add(struct timespec *tp, double seconds)
Add an amount of time seconds to a specific point in time tp.
unsigned random_seed
Random seed to use (default: read /dev/urandom) (option -J).
double iat_min
Minimum interarrival time.
size_t fg_list_size(struct linked_list *const list)
Returns the number of elements in the list.
double rtt_max
Maximum round-trip time.
double time_diff(const struct timespec *tp1, const struct timespec *tp2)
Returns the time difference between two the specific points in time tp1 and tp2.
void request_error(struct request *request, const char *fmt,...)
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.
double rtt_sum
Accumulated round-trip time.
int accept_data(struct flow *flow)
#define crit(...)
To report an critical error w/ the corresponding system error message.
int dscp
DSCP value for TOS byte (option -D).
double delay_max
Maximum one-way delay.
int fg_list_remove(struct linked_list *const list, const void *const data)
Removes from the list the first element whose data points to data.
bool time_is_after(const struct timespec *tp1, const struct timespec *tp2)
Returns true if second point in time tp2 is chronologically after the first point in time tp1.
unsigned request_blocks_written
#define DEFAULT_SELECT_TIMEOUT
Time select() will block waiting for a file descriptor to become ready.
int next_response_block_size(struct flow *flow)
void logging(int priority, const char *fmt,...)
double rtt_sum
Accumulated round-trip time.
int set_non_blocking(int fd)
unsigned long long bytes_read
double iat_sum
Accumulated inter-arrival time.
struct flow_settings::extra_socket_options extra_socket_options[MAX_EXTRA_SOCKET_OPTIONS]
struct fg_tcp_info tcp_info
#define UNUSED_ARGUMENT(x)
Suppress warning for unused argument.
@ DESTINATION
Endpoint that accepts the connection.
double delay_max
Maximum one-way delay.
double duration[2]
Duration of flow in seconds (option -T).
struct flow_source_settings source_settings
#define warnx(...)
To report a warning w/ a system error message.
int cork
Sets SO_DEBUG on test socket (option -O).
double delay_min
Minimum one-way delay.
static void start_flows(struct request_start_flows *request)
static void report_flow(struct flow *flow, int type)
To prepare a report, report type is either INTERVAL or FINAL.
void * data
Pointer to user defined data stored with this node.
struct timespec next_write_block_timestamp
char cc_alg[TCP_CA_NAME_MAX]
Set congestion control algorithm ALG on test socket (option -O).
double delay_min
Minimum one-way delay.
struct flow_settings settings
struct timespec last_report_time
int set_dscp(int fd, int dscp)
#define CPY_INFO_MEMBER(a)
#define ASSIGN_MIN(s, c)
Assign value if it less than current one.
void get_uuid_string(char *uuid_str)
To generate daemon UUID.
unsigned long long bytes_written
void uninit_flow(struct flow *flow)
double time_diff_now(const struct timespec *tp)
Returns time difference between now and the specific point in time tp.
double rtt_max
Maximum round-trip time.
int traffic_dump
Dump traffic using libpcap (option -M).
struct report * reports_last
unsigned current_block_bytes_read
int ipmtudiscover
Set IP_MTU_DISCOVER on test socket (option -O).
int set_tcp_nodelay(int fd)
static void process_iat(struct flow *flow)
int maximum_block_size
Application buffer size in bytes (option -U).
int set_so_elcn(int fd, int val)
int flow_control
Stop flow if it is experiencing local congestion (option -C).
unsigned response_blocks_written
int toggle_tcp_cork(int fd)
double iat_max
Maximum inter-arrival time.
const char * ctimespec_r(const struct timespec *tp, char *buf, size_t size, bool ns)
Converts timespec struct tp into a null-terminated string.
unsigned current_write_block_size
struct request * requests_last
struct request * requests
int num_extra_socket_options
static void process_delay(struct flow *flow)
int pushy
Do not iterate through select() to continue sending in case block size did not suffice to fill sendin...
static int flow_sending(struct timespec *now, struct flow *flow, int direction)
void init_math_functions(struct flow *flow, unsigned long seed)
static void stop_flow(struct request_stop_flow *request)
int nonagle
Disable nagle algorithm on test socket (option -O).
int set_ip_mtu_discover(int fd)
#define MIN_BLOCK_SIZE
Minium block (message) size we can send.
static int flow_in_delay(struct timespec *now, struct flow *flow, int direction)
static int prepare_rfds(struct timespec *now, struct flow *flow, fd_set *rfds)
unsigned long long bytes_written
static void process_requests()
To process the request issued from the controller.
double reporting_interval
Interval to report flow on screen (option -i).
static int write_data(struct flow *flow)
int set_route_record(int fd)
static int try_read_n_bytes(struct flow *flow, int bytes)
@ SOURCE
Endpoint that opens the connection.
int elcn
Set TCP_ELCN (20) on test socket (option -O).
unsigned request_blocks_read
unsigned pmtu
Discovered Path MTU.
Flowgrind's data block layout.
void flow_error(struct flow *flow, const char *fmt,...)
struct timespec last_block_read
static void send_response(struct flow *flow, int requested_response_block_size)
double delay[2]
Delay of flow in seconds (option -Y).
unsigned congestion_counter
#define REQUEST_GET_STATUS
static void process_select(fd_set *rfds, fd_set *wfds, fd_set *efds)
#define warn(...)
To report a warning w/ the corresponding system error message.
int lcd
Set TCP_LCD (21) on test socket (option -O).
#define free_all(...)
To free() an arbitrary number of variables.
double delay_sum
Accumulated one-way delay.
static int flow_block_scheduled(struct timespec *now, struct flow *flow)
pthread_cond_t * condition
structure for getting the UUID.
unsigned response_blocks_written
struct timespec last_block_written
void free_math_functions(struct flow *flow)
struct timespec data
Sending timestap for calculating delay and RTT.
struct request r
Daemon thread process the request r.
int get_tcp_info(struct flow *flow, struct fg_tcp_info *info)
struct timespec stop_timestamp[2]
unsigned long long bytes_read
struct timespec start_timestamp[2]
struct timespec next_report_time
double next_interpacket_gap(struct flow *flow)
enum report_t type
Report type - either INTERVAL or FINAL report.
unsigned request_blocks_written
#define warnc(code,...)
To report a warning w/ the system error message 'code'.
int shutdown
Shutdown socket after test flow (option -N).
Single element in a doubly linked list.
double iat_max
Maximum interarrival time.
int next_request_block_size(struct flow *flow)
static int read_data(struct flow *flow)
void remove_flow(struct flow *const flow)
double rtt_min
Minimum round-trip time.
struct timespec data2
Used to access 64bit timespec on 32bit arch.
void add_report(struct report *report)
enum endpoint_t endpoint
Daemon endpoint - either source or destination.
unsigned imtu
Interface MTU.
struct timespec first_report_time
void add_flow_destination(struct request_add_flow_destination *request)
To set daemon flow as destination endpoint.
struct list_node * next
Pointer to the previous node in the list.
int do_connect(struct flow *flow)
Establishes a connection of a flow.
struct fg_tcp_info tcp_info
#define REQUEST_START_FLOWS
unsigned current_block_bytes_written
static void timer_check()
unsigned request_blocks_read
int mtcp
Set TCP_MTCP (15) on test socket (option -O).
int set_congestion_control(int fd, const char *cc_alg)
double rtt_min
Minimum round-trip time.
double iat_sum
Accumulated interarrival time.
static void process_rtt(struct flow *flow)
#define REQUEST_ADD_SOURCE
#define REQUEST_ADD_DESTINATION
int so_debug
Sets SO_DEBUG on test socket (option -O).
int gettime(struct timespec *tp)
Returns the current wall-clock time with nanosecond precision.
double iat_min
Minimum inter-arrival time.
const struct list_node * fg_list_front(struct linked_list *const list)
Returns the first element of the list.
unsigned response_blocks_read
int route_record
Sets ROUTE_RECORD on test socket (option -O).
struct flow::statistics statistics[2]