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

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));
187  request_error(&request->r,
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 */
204  flow->write_block = calloc(1, flow->settings.maximum_block_size);
205  flow->read_block = calloc(1, flow->settings.maximum_block_size);
206  /* Controller flow ID is set in the daemon */
207  flow->id = flow->settings.flow_id;
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 
221  flow->state = GRIND_WAIT_CONNECT;
222  flow->fd = name2socket(flow, flow->source_settings.destination_host,
224  &flow->addr, &flow->addr_len,
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 */
256  if (!flow->source_settings.late_connect) {
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 
268  fg_list_push_back(&flows, flow);
269 
270  return 0;
271 }
int maximum_block_size
Application buffer size in bytes (option -U).
Definition: common.h:201
int requested_send_buffer_size
Request sender buffer in bytes (option -B).
Definition: common.h:196
void logging(int priority, const char *fmt,...)
Definition: fg_log.c:69
int set_flow_tcp_options(struct flow *flow)
Definition: daemon.c:1420
int do_connect(struct flow *flow)
Establishes a connection of a flow.
Definition: source.c:153
struct flow_source_settings source_settings
Definition: daemon.h:84
char destination_host[256]
Definition: daemon.h:65
void fg_pcap_go(struct flow *flow)
Start a tcpdump to capture traffic of the provided flow.
Definition: fg_pcap.c:314
void uninit_flow(struct flow *flow)
Definition: daemon.c:161
struct flow_settings settings
Definition: daemon.h:210
#define MAX_FLOWS_DAEMON
Maximal number of parallel flows supported by one daemon instance.
Definition: common.h:65
void init_flow(struct flow *flow, int is_source)
To initialize all flows to the default value.
Definition: daemon.c:892
struct flow_settings settings
Definition: daemon.h:83
#define DEBUG_MSG(LVL, MSG,...)
Print debug message to standard error.
Definition: debug.h:49
char * read_block
Definition: daemon.h:97
char * error
Definition: daemon.h:187
char * write_block
Definition: daemon.h:98
char * error
Definition: daemon.h:170
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
int requested_read_buffer_size
Request receiver buffer, advertised window in bytes (option -W).
Definition: common.h:198
struct request r
Definition: daemon.h:208
struct sockaddr * addr
Definition: daemon.h:119
struct flow_source_settings source_settings
Definition: daemon.h:211
enum flow_state_t state
Definition: daemon.h:77
socklen_t addr_len
Definition: daemon.h:120
int fd
Definition: daemon.h:80
char cc_alg[TCP_CA_NAME_MAX]
Definition: daemon.h:215
int flow_id
Flow ID maintained by controller.
Definition: common.h:186
int byte_counting
Enumerate bytes in payload instead of sending zeros (option -E).
Definition: common.h:229
void request_error(struct request *request, const char *fmt,...)
Definition: daemon.c:128
Definition: daemon.h:73
size_t fg_list_size(struct linked_list *const list)
Returns the number of elements in the list.
Definition: fg_list.c:211
int id
Definition: daemon.h:75
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
struct linked_list flows
Definition: daemon.c:99
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 }
int pmtu
Definition: daemon.h:114
#define err(...)
To report an error w/ the corresponding system error message.
Definition: fg_error.h:43
char connect_called
Definition: daemon.h:111
int get_pmtu(int fd)
Definition: fg_socket.c:193
struct sockaddr * addr
Definition: daemon.h:119
socklen_t addr_len
Definition: daemon.h:120
int fd
Definition: daemon.h:80
int id
Definition: daemon.h:75
void flow_error(struct flow *flow, const char *fmt,...)
Definition: daemon.c:115