diff --git a/README.md b/README.md index 497c59b..c182a5e 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,63 @@ # Netem Tool -This tool uses the 3-way TCP handshake to measure the real RTT of a TCP connection. +This tool uses a 3-way TCP handshake to measure the real RTT of a TCP connection. +The gathered information can be used to configure the Linux network emulation queing discipline (see tc-netem(8)). + +It is possible to directly pass the results of the RTT probes to the Kernel. +Therefore it allows to simulate an existing network connection in realtime. +Alternatively, the measurements can be stored and replayed later. + +One use case might be to test your application, equipement, protocols against sudden changes of the link quality. +It also allows to generate custom delay distributions which can be used with tc-netem(8). ### Usage -###### Use case 1: collect probing measurements +###### Use case 1: collect RTT measurements Run TCP SYN/ACK probes to measure round-trip-time (RTT): - ./netem probe 8.8.8.8 > probing.dat + ./netem probe 8.8.8.8 53 > measurements.dat -###### Use case 2: convert measurements into delay distribution table +###### Use case 2a: convert measurements into delay distribution table Collect measurements to build a tc-netem(8) delay distribution table -###### Use case 3 + ./netem dist generate < measurements.dat > google_dns.dist + +###### Use case 2b: generate distribution from measurements and load it to the Kernel + + ./netem dist load < probing.dat + +###### Use case 3: on-the-fly link simulation The output of this command and be stored in a file or directly passed to the `emulate` subcommand: - ./netem probe 8.8.8.8 | ./netem emulate - ./netem emulate < probing.dat + ./netem probe 8.8.8.8 53 | ./netem emulate + +or + + ./netem emulate < measurements.dat + +###### Use case 4: Limit the effect of the network emulation to a specific application To apply the network emulation only to a limit stream of packets, you can use the `mark` tool: + ./netem -m 0xCD dist load < measurements.dat sudo LD_PRELOAD=${PWD}/mark.so MARK=0xCD ping google.de Please make sure the specify the environmental variables after the sudo command! This is necessary, as `ping` is a SUID program. The dynamic linker strips certain enviromental variables (as `LD_PRELOAD`) for security reasons! +### ToDo + +Add more metrics: + + - loss + - duplication + - corruption + - reordering + ### Building ##### Install libnl diff --git a/config.h b/config.h index f7a972f..0398d0d 100644 --- a/config.h +++ b/config.h @@ -14,9 +14,8 @@ struct config { int mark; int mask; int interval; - int rate; int limit; - + double rate; char *dev; }; diff --git a/main.c b/main.c index 55e7a6f..57f2145 100644 --- a/main.c +++ b/main.c @@ -26,6 +26,7 @@ int running = 1; /* Default settings */ struct config cfg = { .limit = 100, + .rate = 1, .mark = 0xCD, .mask = 0xFFFFFFFF, .dev = "eth0" @@ -45,15 +46,14 @@ int main(int argc, char *argv[]) if (argc < 2) { printf("usage: %s CMD [OPTIONS]\n", argv[0]); printf(" CMD can be one of:\n"); - printf(" live \n"); - printf(" probe \n"); - printf(" emulate \n"); + printf(" probe IP PORT\n"); + printf(" emulate\n"); printf("\n"); printf(" OPTIONS:\n"); printf(" -m --mark N apply emulation only to packet buffers with mark N\n"); printf(" -M --mask N an optional mask for the fw mark\n"); printf(" -i --interval N update the emulation parameters every N seconds\n"); - printf(" -r --rate the packet rate used for measurements\n"); + printf(" -r --rate rate limit used for measurements and updates of network emulation\n"); printf(" -l --limit how many probes should we sent\n"); printf(" -d --dev network interface\n"); @@ -82,7 +82,7 @@ int main(int argc, char *argv[]) /* Parse Arguments */ char c, *endptr; - while ((c = getopt (argc-1, argv+1, "h:m:M:i:l:d:")) != -1) { + while ((c = getopt (argc-1, argv+1, "h:m:M:i:l:d:r:")) != -1) { switch (c) { case 'm': cfg.mark = strtoul(optarg, &endptr, 0); @@ -94,7 +94,7 @@ int main(int argc, char *argv[]) cfg.interval = strtoul(optarg, &endptr, 10); goto check; case 'r': - cfg.rate = strtoul(optarg, &endptr, 10); + cfg.rate = strtof(optarg, &endptr); goto check; case 'l': cfg.limit = strtoul(optarg, &endptr, 10); diff --git a/timing.c b/timing.c index ea9956d..ac7498a 100644 --- a/timing.c +++ b/timing.c @@ -5,6 +5,13 @@ * @license GPLv3 *********************************************************************************/ +#define _POSIX_C_SOURCE 199309L + +#include + +#include +#include + #include "timing.h" uint64_t timerfd_wait(int fd) diff --git a/timing.h b/timing.h index cd37911..afbb3f8 100644 --- a/timing.h +++ b/timing.h @@ -5,17 +5,11 @@ * @license GPLv3 *********************************************************************************/ -#ifndef _TIME_H_ -#define _TIME_H_ +#ifndef _TIMING_H_ +#define _TIMING_H_ -#define _POSIX_C_SOURCE 199309L - -#include #include #include - -#include -#include /** Wait until timer elapsed *