Flowgrind
Advanced TCP traffic generator
source.h File Reference

Routines used by Flowgrind to setup the source for a test flow. More...

#include "config.h"

Go to the source code of this file.

Functions

int add_flow_source (struct request_add_flow_source *request)
 To set daemon flow as source endpoint. More...
 
int do_connect (struct flow *flow)
 Establishes a connection of a flow. More...
 

Detailed Description

Routines used by Flowgrind to setup the source for a test flow.

Definition in file source.h.

Function Documentation

◆ add_flow_source()

int add_flow_source ( struct request_add_flow_source request)

To set daemon flow as source endpoint.

To set the flow options and settings as source endpoint. Depending upon the late connection option the data connection is established to connect the destination daemon listening port address with source daemon.

Parameters
[in,out]requestContain the test option and parameter for daemon source endpoint

Definition at line 177 of file source.c.

178 {
179 #ifdef HAVE_SO_TCP_CONGESTION
180  socklen_t opt_len = 0;
181 #endif /* HAVE_SO_TCP_CONGESTION */
182  struct flow *flow;
183 
185  logging(LOG_WARNING, "can not accept another flow, already "
186  "handling %zu flows", fg_list_size(&flows));
188  "Can not accept another flow, already "
189  "handling %zu flows.", fg_list_size(&flows));
190  return -1;
191  }
192 
193  flow = malloc(sizeof(struct flow));
194  if (!flow) {
195  logging(LOG_ALERT, "could not allocate memory for flow");
196  return -1;
197  }
198 
199  init_flow(flow, 1);
200 
201  flow->settings = request->settings;
202  flow->source_settings = request->source_settings;
203  /* be greedy with buffer sizes */
206  /* Controller flow ID is set in the daemon */
208  if (flow->write_block == NULL || flow->read_block == NULL) {
209  logging(LOG_ALERT, "could not allocate memory for read/write "
210  "blocks");
211  request_error(&request->r, "could not allocate memory for read/write blocks");
212  uninit_flow(flow);
213  return -1;
214  }
215  if (flow->settings.byte_counting) {
216  int byte_idx;
217  for (byte_idx = 0; byte_idx < flow->settings.maximum_block_size; byte_idx++)
218  *(flow->write_block + byte_idx) = (unsigned char)(byte_idx & 0xff);
219  }
220 
224  &flow->addr, &flow->addr_len,
225  flow->settings.requested_read_buffer_size, &request->real_read_buffer_size,
226  flow->settings.requested_send_buffer_size, &request->real_send_buffer_size);
227  if (flow->fd == -1) {
228  logging(LOG_ALERT, "could not create data socket: %s",
229  flow->error);
230  request_error(&request->r, "Could not create data socket: %s", flow->error);
231  uninit_flow(flow);
232  return -1;
233  }
234 
235  if (set_flow_tcp_options(flow) == -1) {
236  request->r.error = flow->error;
237  flow->error = NULL;
238  uninit_flow(flow);
239  return -1;
240  }
241 
242 #ifdef HAVE_SO_TCP_CONGESTION
243  opt_len = sizeof(request->cc_alg);
244  if (getsockopt(flow->fd, IPPROTO_TCP, TCP_CONGESTION,
245  request->cc_alg, &opt_len) == -1) {
246  request_error(&request->r, "failed to determine actual congestion control algorithm: %s",
247  strerror(errno));
248  uninit_flow(flow);
249  return -1;
250  }
251 #endif /* HAVE_SO_TCP_CONGESTION */
252 
253 #ifdef HAVE_LIBPCAP
254  fg_pcap_go(flow);
255 #endif /* HAVE_LIBPCAP */
257  DEBUG_MSG(4, "(early) connecting test socket (fd=%u)", flow->fd);
258  if (do_connect(flow) == -1) {
259  request->r.error = flow->error;
260  flow->error = NULL;
261  uninit_flow(flow);
262  return -1;
263  }
264  }
265 
266  request->flow_id = flow->id;
267 
269 
270  return 0;
271 }

◆ do_connect()

int do_connect ( struct flow flow)

Establishes a connection of a flow.

Establishes a connection to the destination daemon listening port, and marks the flow as connected.

Parameters
[in,out]flowFlow to connect.

Definition at line 153 of file source.c.

153  {
154  int rc;
155 
156  rc = connect(flow->fd, flow->addr, flow->addr_len);
157  if (rc == -1 && errno != EINPROGRESS) {
158  flow_error(flow, "connect() failed: %s",
159  strerror(errno));
160  err("failed to connect flow %u", flow->id);
161  return rc;
162  }
163  flow->connect_called = 1;
164  flow->pmtu = get_pmtu(flow->fd);
165  return 0;
166 }
DEBUG_MSG
#define DEBUG_MSG(LVL, MSG,...)
Print debug message to standard error.
Definition: debug.h:49
fg_list_size
size_t fg_list_size(struct linked_list *const list)
Returns the number of elements in the list.
Definition: fg_list.c:211
flow::connect_called
char connect_called
Definition: daemon.h:111
flow
Definition: daemon.h:73
request_error
void request_error(struct request *request, const char *fmt,...)
Definition: daemon.c:132
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
name2socket
static int name2socket(struct flow *flow, char *server_name, unsigned port, struct sockaddr **saptr, socklen_t *lenp, const int read_buffer_size_req, int *read_buffer_size, const int send_buffer_size_req, int *send_buffer_size)
Definition: source.c:76
set_flow_tcp_options
int set_flow_tcp_options(struct flow *flow)
Definition: daemon.c:1424
logging
void logging(int priority, const char *fmt,...)
Definition: fg_log.c:69
MAX_FLOWS_DAEMON
#define MAX_FLOWS_DAEMON
Maximal number of parallel flows supported by one daemon instance.
Definition: common.h:65
flow::source_settings
struct flow_source_settings source_settings
Definition: daemon.h:84
flow::pmtu
int pmtu
Definition: daemon.h:114
flow_settings::byte_counting
int byte_counting
Enumerate bytes in payload instead of sending zeros (option -E).
Definition: common.h:229
flow::settings
struct flow_settings settings
Definition: daemon.h:83
flow::read_block
char * read_block
Definition: daemon.h:97
init_flow
void init_flow(struct flow *flow, int is_source)
To initialize all flows to the default value.
Definition: daemon.c:896
err
#define err(...)
To report an error w/ the corresponding system error message.
Definition: fg_error.h:43
flow_settings::maximum_block_size
int maximum_block_size
Application buffer size in bytes (option -U).
Definition: common.h:201
flow_source_settings::late_connect
int late_connect
Definition: daemon.h:68
fg_pcap_go
void fg_pcap_go(struct flow *flow)
Start a tcpdump to capture traffic of the provided flow.
Definition: fg_pcap.c:314
flow_settings::flow_id
int flow_id
Flow ID maintained by controller.
Definition: common.h:186
request
Definition: daemon.h:179
flow::error
char * error
Definition: daemon.h:170
GRIND_WAIT_CONNECT
@ GRIND_WAIT_CONNECT
Definition: daemon.h:56
get_pmtu
int get_pmtu(int fd)
Definition: fg_socket.c:193
request::error
char * error
Definition: daemon.h:187
flow::addr_len
socklen_t addr_len
Definition: daemon.h:120
flow::fd
int fd
Definition: daemon.h:80
flow_error
void flow_error(struct flow *flow, const char *fmt,...)
Definition: daemon.c:119
flow::addr
struct sockaddr * addr
Definition: daemon.h:119
flow::write_block
char * write_block
Definition: daemon.h:98
fg_list_push_back
int fg_list_push_back(struct linked_list *const list, void *const data)
Inserts a new element at the end of the list.
Definition: fg_list.c:167
flow::state
enum flow_state_t state
Definition: daemon.h:77
flow::id
int id
Definition: daemon.h:75
do_connect
int do_connect(struct flow *flow)
Establishes a connection of a flow.
Definition: source.c:153
flows
struct linked_list flows
Definition: daemon.c:103
flow_source_settings::destination_port
int destination_port
Definition: daemon.h:66
uninit_flow
void uninit_flow(struct flow *flow)
Definition: daemon.c:165
flow_settings::requested_send_buffer_size
int requested_send_buffer_size
Request sender buffer in bytes (option -B).
Definition: common.h:196