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

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);
293  if (flow->requested_server_test_port &&
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);
305  if (flow->requested_server_test_port &&
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 }
const char * fg_nameinfo(const struct sockaddr *sa, socklen_t salen)
Definition: fg_socket.c:374
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
char connect_called
Definition: daemon.h:111
void fg_pcap_go(struct flow *flow)
Start a tcpdump to capture traffic of the provided flow.
Definition: fg_pcap.c:314
struct flow_settings settings
Definition: daemon.h:83
#define DEBUG_MSG(LVL, MSG,...)
Print debug message to standard error.
Definition: debug.h:49
Definition: daemon.h:60
int requested_read_buffer_size
Request receiver buffer, advertised window in bytes (option -W).
Definition: common.h:198
int listenfd_data
Definition: daemon.h:81
unsigned real_listen_receive_buffer_size
Definition: daemon.h:109
unsigned short requested_server_test_port
Definition: daemon.h:106
unsigned real_listen_send_buffer_size
Definition: daemon.h:108
enum flow_state_t state
Definition: daemon.h:77
int fd
Definition: daemon.h:80
int set_window_size_directed(int fd, int window, int direction)
Definition: fg_socket.c:78
void flow_error(struct flow *flow, const char *fmt,...)
Definition: daemon.c:115
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;
180  flow->write_block = calloc(1, flow->settings.maximum_block_size );
181  flow->read_block = calloc(1, flow->settings.maximum_block_size );
182  /* Controller flow ID is set in the daemon */
183  flow->id=flow->settings.flow_id;
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 =
204  flow->settings.bind_address[0]
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;
243  request->flow_id = flow->id;
244 
245  fg_list_push_back(&flows, flow);
246 
247  return;
248 }
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
#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 * 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
int listenfd_data
Definition: daemon.h:81
unsigned real_listen_receive_buffer_size
Definition: daemon.h:109
unsigned real_listen_send_buffer_size
Definition: daemon.h:108
static int create_listen_socket(struct flow *flow, char *bind_addr, unsigned short *listen_port)
Definition: destination.c:78
int flow_id
Flow ID maintained by controller.
Definition: common.h:186
int set_window_size_directed(int fd, int window, int direction)
Definition: fg_socket.c:78
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
void uninit_flow(struct flow *flow)
Definition: daemon.c:161
char bind_address[1000]
The interface address for the flow (used by daemon).
Definition: common.h:183
Definition: daemon.h:73
struct flow_settings settings
Definition: daemon.h:197
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
struct linked_list flows
Definition: daemon.c:99
void flow_error(struct flow *flow, const char *fmt,...)
Definition: daemon.c:115