feat: --preload option
This commit is contained in:
parent
ce8883d6cd
commit
4b4750cb59
8 changed files with 84 additions and 18 deletions
|
|
@ -109,6 +109,14 @@ enum {
|
||||||
OPT_ARG_NONE, \
|
OPT_ARG_NONE, \
|
||||||
"Set the Don't Fragment bit" \
|
"Set the Don't Fragment bit" \
|
||||||
) \
|
) \
|
||||||
|
X( \
|
||||||
|
'l', \
|
||||||
|
"preload", \
|
||||||
|
required_argument, \
|
||||||
|
cli_handle_preload, \
|
||||||
|
OPT_ARG_UINT, \
|
||||||
|
"Send N packets in burst before normal loop" \
|
||||||
|
) \
|
||||||
X( \
|
X( \
|
||||||
'p', \
|
'p', \
|
||||||
"pattern", \
|
"pattern", \
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
extern const struct option_descriptor g_options[];
|
extern const struct option_descriptor g_options[];
|
||||||
|
|
||||||
int cli_handle_count(const char *arg, void *config);
|
int cli_handle_count(const char *arg, void *config);
|
||||||
|
int cli_handle_preload(const char *arg, void *config);
|
||||||
int cli_handle_pattern(const char *arg, void *config);
|
int cli_handle_pattern(const char *arg, void *config);
|
||||||
int cli_handle_dont_fragment(const char *arg, void *config);
|
int cli_handle_dont_fragment(const char *arg, void *config);
|
||||||
int cli_handle_deadline(const char *arg, void *config);
|
int cli_handle_deadline(const char *arg, void *config);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
/* Default configuration values */
|
/* Default configuration values */
|
||||||
#define DEFAULT_COUNT 0
|
#define DEFAULT_COUNT 0
|
||||||
|
#define DEFAULT_PRELOAD 1
|
||||||
#define DEFAULT_INTERVAL 1.0
|
#define DEFAULT_INTERVAL 1.0
|
||||||
#define DEFAULT_TTL 64
|
#define DEFAULT_TTL 64
|
||||||
#define DEFAULT_PACKET_SIZE 56
|
#define DEFAULT_PACKET_SIZE 56
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ struct ping_config
|
||||||
|
|
||||||
/* Options */
|
/* Options */
|
||||||
uint64_t count;
|
uint64_t count;
|
||||||
|
uint64_t preload;
|
||||||
double interval;
|
double interval;
|
||||||
uint8_t ttl;
|
uint8_t ttl;
|
||||||
size_t packet_size;
|
size_t packet_size;
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ FORCE:
|
||||||
libping_core_la_SOURCES = \
|
libping_core_la_SOURCES = \
|
||||||
cli/parse.c \
|
cli/parse.c \
|
||||||
cli/handlers/handle_count.c \
|
cli/handlers/handle_count.c \
|
||||||
|
cli/handlers/handle_preload.c \
|
||||||
cli/handlers/handle_pattern.c \
|
cli/handlers/handle_pattern.c \
|
||||||
cli/handlers/handle_dont_fragment.c \
|
cli/handlers/handle_dont_fragment.c \
|
||||||
cli/handlers/handle_deadline.c \
|
cli/handlers/handle_deadline.c \
|
||||||
|
|
|
||||||
14
src/ping/cli/handlers/handle_preload.c
Normal file
14
src/ping/cli/handlers/handle_preload.c
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include "ping/cli.h"
|
||||||
|
#include "internal/cli/parse_utils.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
cli_handle_preload(const char *arg, void *config_void)
|
||||||
|
{
|
||||||
|
struct ping_config *config = (struct ping_config *)config_void;
|
||||||
|
uint64_t preload;
|
||||||
|
|
||||||
|
if (0 != cli_parse_uint64(arg, &preload))
|
||||||
|
return CLI_ERROR;
|
||||||
|
config->preload = preload;
|
||||||
|
return CLI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
@ -31,6 +31,7 @@ init_config(struct ping_config *config)
|
||||||
{
|
{
|
||||||
memset(config, 0, sizeof(struct ping_config));
|
memset(config, 0, sizeof(struct ping_config));
|
||||||
config->count = DEFAULT_COUNT;
|
config->count = DEFAULT_COUNT;
|
||||||
|
config->preload = DEFAULT_PRELOAD;
|
||||||
config->interval = DEFAULT_INTERVAL;
|
config->interval = DEFAULT_INTERVAL;
|
||||||
config->ttl = DEFAULT_TTL;
|
config->ttl = DEFAULT_TTL;
|
||||||
config->packet_size = DEFAULT_PACKET_SIZE;
|
config->packet_size = DEFAULT_PACKET_SIZE;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
@ -9,47 +10,59 @@
|
||||||
#include "internal/ping/loop.h"
|
#include "internal/ping/loop.h"
|
||||||
|
|
||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
static int ping_one(const struct ping_config *config,
|
static icmp_handle_t *ping_create_handle(const struct ping_config *config);
|
||||||
struct destinations *dest, icmp_handle_t *handle);
|
static int ping_one(const struct ping_config *config, struct destinations
|
||||||
|
*dest, icmp_handle_t *handle);
|
||||||
static void ping_init_state(struct ping_state *state, struct ping_stats *stats,
|
static void ping_init_state(struct ping_state *state, struct ping_stats *stats,
|
||||||
struct ping_tracker *tracker, const struct ping_config *config,
|
struct ping_tracker *tracker, const struct ping_config *config,
|
||||||
struct in_addr dest, icmp_handle_t *handle);
|
struct in_addr dest, icmp_handle_t *handle);
|
||||||
|
static int ping_preload(struct ping_state *state, size_t payload_len);
|
||||||
/* -------------------- */
|
/* -------------------- */
|
||||||
|
|
||||||
int
|
int
|
||||||
ping_run(const struct ping_config *config)
|
ping_run(const struct ping_config *config)
|
||||||
{
|
{
|
||||||
icmp_handle_t *handle;
|
icmp_handle_t *handle;
|
||||||
int ret = 0 ;
|
int ret = 0;
|
||||||
size_t i = 0 ;
|
size_t i = 0;
|
||||||
|
|
||||||
if (0 == config->nb_destinations)
|
if (0 == config->nb_destinations)
|
||||||
return 1;
|
return 1;
|
||||||
handle = icmp_create();
|
handle = ping_create_handle(config);
|
||||||
if (NULL == handle)
|
if (NULL == handle)
|
||||||
{
|
|
||||||
dprintf(STDERR_FILENO, "%s: requires CAP_NET_RAW or root privileges\n",
|
|
||||||
g_prog_name);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
if (HAS_FLAG(config->flags, FLAG_DONT_FRAGMENT)
|
|
||||||
&& 0 != icmp_set_dont_fragment(handle))
|
|
||||||
{
|
|
||||||
ret = 1;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (i < config->nb_destinations)
|
while (i < config->nb_destinations)
|
||||||
{
|
{
|
||||||
if (0 != ping_one(config, &config->destinations[i], handle))
|
if (0 != ping_one(config, &config->destinations[i], handle))
|
||||||
ret = 1;
|
ret = 1;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
cleanup:
|
|
||||||
icmp_destroy(handle);
|
icmp_destroy(handle);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static icmp_handle_t *
|
||||||
|
ping_create_handle(const struct ping_config *config)
|
||||||
|
{
|
||||||
|
icmp_handle_t *handle;
|
||||||
|
|
||||||
|
handle = icmp_create();
|
||||||
|
if (NULL == handle)
|
||||||
|
{
|
||||||
|
dprintf(STDERR_FILENO, "%s: requires CAP_NET_RAW or root privileges\n",
|
||||||
|
g_prog_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (HAS_FLAG(config->flags, FLAG_DONT_FRAGMENT)
|
||||||
|
&& 0 != icmp_set_dont_fragment(handle))
|
||||||
|
{
|
||||||
|
dprintf(STDERR_FILENO, "%s: %s\n", g_prog_name, icmp_strerror(handle));
|
||||||
|
icmp_destroy(handle);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ping_one(const struct ping_config *config, struct destinations *dest,
|
ping_one(const struct ping_config *config, struct destinations *dest,
|
||||||
icmp_handle_t *handle)
|
icmp_handle_t *handle)
|
||||||
|
|
@ -62,9 +75,14 @@ ping_one(const struct ping_config *config, struct destinations *dest,
|
||||||
ping_init_state(&state, &stats, &tracker, config, dest->ip, handle);
|
ping_init_state(&state, &stats, &tracker, config, dest->ip, handle);
|
||||||
payload_len = config->packet_size;
|
payload_len = config->packet_size;
|
||||||
if (0 != ping_scheduler_init(&state))
|
if (0 != ping_scheduler_init(&state))
|
||||||
|
{
|
||||||
|
dprintf(STDERR_FILENO, "%s: sigaction: %s\n",
|
||||||
|
g_prog_name, strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
ping_output_start(config, dest, payload_len);
|
ping_output_start(config, dest, payload_len);
|
||||||
do_send(&state, payload_len);
|
if (0 != ping_preload(&state, payload_len))
|
||||||
|
return 1;
|
||||||
ping_loop(&state, payload_len);
|
ping_loop(&state, payload_len);
|
||||||
ping_output_summary(&state, dest);
|
ping_output_summary(&state, dest);
|
||||||
return tracker.nb_recv <= state.nb_errors;
|
return tracker.nb_recv <= state.nb_errors;
|
||||||
|
|
@ -86,3 +104,24 @@ ping_init_state(struct ping_state *state, struct ping_stats *stats,
|
||||||
state->handle = handle;
|
state->handle = handle;
|
||||||
icmp_get_time(&state->start_time);
|
icmp_get_time(&state->start_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ping_preload(struct ping_state *state, size_t payload_len)
|
||||||
|
{
|
||||||
|
const struct ping_config *config = state->config;
|
||||||
|
uint64_t i = 0;
|
||||||
|
|
||||||
|
while (i < config->preload && (0 == config->count ||
|
||||||
|
state->tracker->nb_sent < config->count))
|
||||||
|
{
|
||||||
|
do_send(state, payload_len);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (0 == config->preload && 0 != ping_scheduler_arm(config))
|
||||||
|
{
|
||||||
|
dprintf(STDERR_FILENO, "%s: setitimer: %s\n",
|
||||||
|
g_prog_name, strerror(errno));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue