Flowgrind
Advanced TCP traffic generator
destination.h File Reference

Routines used to setup a Flowgrind destination for a test. More...

#include "config.h"

Go to the source code of this file.

Functions

int accept_data (struct flow *flow)
 
void add_flow_destination (struct request_add_flow_destination *request)
 To set daemon flow as destination endpoint. More...
 

Detailed Description

Routines used to setup a Flowgrind destination for a test.

Definition in file destination.h.

Function Documentation

◆ accept_data()

int accept_data ( struct flow flow)
Bug:
: currently we use portable select() API, which is limited by the number of bits in an fd_set

Definition at line 250 of file destination.c.

251 {
252  struct sockaddr_storage caddr;
253  socklen_t addrlen = sizeof(caddr);
254  unsigned real_send_buffer_size;
255  unsigned real_receive_buffer_size;
256 
257  flow->fd = accept(flow->listenfd_data, (struct sockaddr *)&caddr,
258  &addrlen);
259  if (flow->fd == -1) {
260  /* try again later .... */
261  if (errno == EINTR || errno == EAGAIN)
262  return 0;
263  logging(LOG_ALERT, "accept() failed: %s", strerror(errno));
264  return -1;
265  }
266 
267  /* FIXME: currently we use portable select() API, which
268  * is limited by the number of bits in an fd_set */
269  if (flow->fd >= FD_SETSIZE) {
270  logging(LOG_ALERT, "too many file descriptors are "
271  "already in use by this daemon (FD number=%u)", flow->fd);
272  flow_error(flow, "failed to add test connection: too many"
273  "file descriptors in use by this daemon");
274  close(flow->fd);
275  return -1;
276  }
277 
278  if (close(flow->listenfd_data) == -1)
279  logging(LOG_WARNING, "close() failed");
280  flow->listenfd_data = -1;
281 
282  logging(LOG_NOTICE, "client %s connected for testing (fd=%u)",
283  fg_nameinfo((struct sockaddr *)&caddr, addrlen), flow->fd);
284 
285 #ifdef HAVE_LIBPCAP
286  fg_pcap_go(flow);
287 #endif /* HAVE_LIBPCAP */
288 
289  real_send_buffer_size =
292  SO_SNDBUF);
294  flow->real_listen_send_buffer_size != real_send_buffer_size) {
295  logging(LOG_WARNING, "failed to set send buffer size of test "
296  "socket to send buffer size size of listen socket "
297  "(listen = %u, test = %u)",
298  flow->real_listen_send_buffer_size, real_send_buffer_size);
299  return -1;
300  }
301  real_receive_buffer_size =
304  SO_RCVBUF);
306  flow->real_listen_receive_buffer_size != real_receive_buffer_size) {
307  logging(LOG_WARNING, "failed to set receive buffer size "
308  "(advertised window) of test socket to receive "
309  "buffer size of listen socket (listen = %u, "
310  "test = %u)", flow->real_listen_receive_buffer_size,
311  real_receive_buffer_size);
312  return -1;
313  }
314  if (set_flow_tcp_options(flow) == -1)
315  return -1;
316  DEBUG_MSG(LOG_NOTICE, "data socket accepted");
317  flow->state = GRIND;
318  flow->connect_called = 1;
319 
320  return 0;
321 }

◆ add_flow_destination()

void add_flow_destination ( struct request_add_flow_destination request)

To set daemon flow as destination endpoint.

To set the flow options and settings as destination endpoint. Listening port created and send back to the controller in the same request structure

Parameters
[in,out]requestcontain the test option and parameter for destination source endpoint
Bug:
: currently we use portable select() API, which is limited by the number of bits in an fd_set

Definition at line 158 of file destination.c.

159 {
160  struct flow *flow;
161  unsigned short server_data_port;
162 
164  logging(LOG_WARNING, "can not accept another flow, already "
165  "handling %zu flows", fg_list_size(&flows));
166  request_error(&request->r, "Can not accept another flow, "
167  "already handling %zu flows.", fg_list_size(&flows));
168  return;
169  }
170 
171  flow = malloc(sizeof(struct flow));
172  if (!flow) {
173  logging(LOG_ALERT, "could not allocate memory for flow");
174  return;
175  }
176 
177  init_flow(flow, 0);
178 
179  flow->settings = request->settings;
182  /* Controller flow ID is set in the daemon */
184  if (flow->write_block == NULL || flow->read_block == NULL) {
185  logging(LOG_ALERT, "could not allocate memory for read/write "
186  "blocks");
187  request_error(&request->r, "could not allocate memory "
188  "for read/write blocks");
189  uninit_flow(flow);
190  return;
191  }
192 
193  if (flow->settings.byte_counting) {
194  int byte_idx;
195  for (byte_idx = 0; byte_idx < flow->settings.maximum_block_size;
196  byte_idx++)
197  *(flow->write_block + byte_idx) =
198  (unsigned char)(byte_idx & 0xff);
199  }
200 
201  /* Create listen socket for data connection */
202  if ((flow->listenfd_data =
205  ? flow->settings.bind_address : 0,
206  &server_data_port)) == -1) {
207  logging(LOG_ALERT, "could not create listen socket for "
208  "data connection: %s", flow->error);
209  request_error(&request->r, "could not create listen socket "
210  "for data connection: %s", flow->error);
211  uninit_flow(flow);
212  return;
213  } else {
214  /* FIXME: currently we use portable select() API, which
215  * is limited by the number of bits in an fd_set */
216  if (flow->listenfd_data >= FD_SETSIZE) {
217  logging(LOG_ALERT, "failed to add listen socket: "
218  "fd number too high (fd=%u)", flow->listenfd_data);
219  flow_error(flow, "failed to add listen socket: too many"
220  "file descriptors in use by this daemon");
221  uninit_flow(flow);
222  return;
223  }
224  DEBUG_MSG(LOG_WARNING, "listening on %s port %u for data "
225  "connection (fd=%u)", flow->settings.bind_address,
226  server_data_port, flow->listenfd_data);
227  }
228 
232  SO_SNDBUF);
236  SO_RCVBUF);
237 
238  request->listen_data_port = (int)server_data_port;
239  request->real_listen_send_buffer_size =
241  request->real_listen_read_buffer_size =
243  request->flow_id = flow->id;
244 
246 
247  return;
248 }
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
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
GRIND
@ GRIND
Definition: daemon.h:60
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
flow_settings::maximum_block_size
int maximum_block_size
Application buffer size in bytes (option -U).
Definition: common.h:201
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
flow::listenfd_data
int listenfd_data
Definition: daemon.h:81
flow::real_listen_receive_buffer_size
unsigned real_listen_receive_buffer_size
Definition: daemon.h:109
flow::fd
int fd
Definition: daemon.h:80
flow::real_listen_send_buffer_size
unsigned real_listen_send_buffer_size
Definition: daemon.h:108
flow_error
void flow_error(struct flow *flow, const char *fmt,...)
Definition: daemon.c: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
set_window_size_directed
int set_window_size_directed(int fd, int window, int direction)
Definition: fg_socket.c:78
flow::requested_server_test_port
unsigned short requested_server_test_port
Definition: daemon.h:106
flow::id
int id
Definition: daemon.h:75
fg_nameinfo
const char * fg_nameinfo(const struct sockaddr *sa, socklen_t salen)
Definition: fg_socket.c:374
flows
struct linked_list flows
Definition: daemon.c:103
uninit_flow
void uninit_flow(struct flow *flow)
Definition: daemon.c:165
flow_settings::bind_address
char bind_address[1000]
The interface address for the flow (used by daemon).
Definition: common.h:183
create_listen_socket
static int create_listen_socket(struct flow *flow, char *bind_addr, unsigned short *listen_port)
Definition: destination.c:78
flow_settings::requested_send_buffer_size
int requested_send_buffer_size
Request sender buffer in bytes (option -B).
Definition: common.h:196