diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 18:21:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 18:21:43 +0000 |
commit | c8c3bd06ef1a7248c8195d050d8a4075d051256e (patch) | |
tree | 419655deec1b0af0c5d3ec488693f1494fb20959 /src/iperf.h | |
parent | Initial commit. (diff) | |
download | iperf3-c8c3bd06ef1a7248c8195d050d8a4075d051256e.tar.xz iperf3-c8c3bd06ef1a7248c8195d050d8a4075d051256e.zip |
Adding upstream version 3.16.upstream/3.16
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/iperf.h')
-rw-r--r-- | src/iperf.h | 463 |
1 files changed, 463 insertions, 0 deletions
diff --git a/src/iperf.h b/src/iperf.h new file mode 100644 index 0000000..7b270bd --- /dev/null +++ b/src/iperf.h @@ -0,0 +1,463 @@ +/* + * iperf, Copyright (c) 2014-2020, 2023, The Regents of the University of + * California, through Lawrence Berkeley National Laboratory (subject + * to receipt of any required approvals from the U.S. Dept. of + * Energy). All rights reserved. + * + * If you have questions about your rights to use or distribute this + * software, please contact Berkeley Lab's Technology Transfer + * Department at TTD@lbl.gov. + * + * NOTICE. This software is owned by the U.S. Department of Energy. + * As such, the U.S. Government has been granted for itself and others + * acting on its behalf a paid-up, nonexclusive, irrevocable, + * worldwide license in the Software to reproduce, prepare derivative + * works, and perform publicly and display publicly. Beginning five + * (5) years after the date permission to assert copyright is obtained + * from the U.S. Department of Energy, and subject to any subsequent + * five (5) year renewals, the U.S. Government is granted for itself + * and others acting on its behalf a paid-up, nonexclusive, + * irrevocable, worldwide license in the Software to reproduce, + * prepare derivative works, distribute copies to the public, perform + * publicly and display publicly, and to permit others to do so. + * + * This code is distributed under a BSD style license, see the LICENSE + * file for complete information. + */ +#ifndef __IPERF_H +#define __IPERF_H + +#include "iperf_config.h" + +#include <sys/time.h> +#include <sys/types.h> +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif +#include <sys/select.h> +#include <sys/socket.h> +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif +#ifdef HAVE_LINUX_TCP_H +#include <linux/tcp.h> +#else +#include <netinet/tcp.h> +#endif +#include <net/if.h> // for IFNAMSIZ + +#if defined(HAVE_CPUSET_SETAFFINITY) +#include <sys/param.h> +#include <sys/cpuset.h> +#endif /* HAVE_CPUSET_SETAFFINITY */ + +#if defined(HAVE_INTTYPES_H) +# include <inttypes.h> +#else +# ifndef PRIu64 +# if sizeof(long) == 8 +# define PRIu64 "lu" +# else +# define PRIu64 "llu" +# endif +# endif +#endif + +#include "timer.h" +#include "queue.h" +#include "cjson.h" +#include "iperf_time.h" + +#if defined(HAVE_SSL) +#include <openssl/bio.h> +#include <openssl/evp.h> +#endif // HAVE_SSL + +#ifdef HAVE_PTHREAD +#include <pthread.h> +#endif // HAVE_PTHREAD + +/* + * Atomic types highly desired, but if not, we approximate what we need + * with normal integers and warn. + */ +#ifdef HAVE_STDATOMIC_H +#include <stdatomic.h> +#else +#warning "No <stdatomic.h> available." +typedef uint64_t atomic_uint_fast64_t; +#endif // HAVE_STDATOMIC_H + +#if !defined(__IPERF_API_H) +typedef uint_fast64_t iperf_size_t; +typedef atomic_uint_fast64_t atomic_iperf_size_t; +#endif // __IPERF_API_H + +struct iperf_interval_results +{ + atomic_iperf_size_t bytes_transferred; /* bytes transferred in this interval */ + struct iperf_time interval_start_time; + struct iperf_time interval_end_time; + float interval_duration; + + /* for UDP */ + int64_t interval_packet_count; + int64_t interval_outoforder_packets; + int64_t interval_cnt_error; + int64_t packet_count; + double jitter; + int64_t outoforder_packets; + int64_t cnt_error; + + int omitted; +#if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) && \ + defined(TCP_INFO) + struct tcp_info tcpInfo; /* getsockopt(TCP_INFO) for Linux, {Free,Net,Open}BSD */ +#else + /* Just placeholders, never accessed. */ + char *tcpInfo; +#endif + long interval_retrans; + long snd_cwnd; + long snd_wnd; + TAILQ_ENTRY(iperf_interval_results) irlistentries; + void *custom_data; + long rtt; + long rttvar; + long pmtu; +}; + +struct iperf_stream_result +{ + atomic_iperf_size_t bytes_received; + atomic_iperf_size_t bytes_sent; + atomic_iperf_size_t bytes_received_this_interval; + atomic_iperf_size_t bytes_sent_this_interval; + atomic_iperf_size_t bytes_sent_omit; + long stream_prev_total_retrans; + long stream_retrans; + long stream_max_rtt; + long stream_min_rtt; + long stream_sum_rtt; + int stream_count_rtt; + long stream_max_snd_cwnd; + long stream_max_snd_wnd; + struct iperf_time start_time; + struct iperf_time end_time; + struct iperf_time start_time_fixed; + double sender_time; + double receiver_time; + TAILQ_HEAD(irlisthead, iperf_interval_results) interval_results; + void *data; +}; + +#define COOKIE_SIZE 37 /* size of an ascii uuid */ +struct iperf_settings +{ + int domain; /* AF_INET or AF_INET6 */ + int socket_bufsize; /* window size for TCP */ + int blksize; /* size of read/writes (-l) */ + iperf_size_t rate; /* target data rate for application pacing*/ + iperf_size_t bitrate_limit; /* server's maximum allowed total data rate for all streams*/ + double bitrate_limit_interval; /* interval for averaging total data rate */ + int bitrate_limit_stats_per_interval; /* calculated number of stats periods for averaging total data rate */ + uint64_t fqrate; /* target data rate for FQ pacing*/ + int pacing_timer; /* pacing timer in microseconds */ + int burst; /* packets per burst */ + int mss; /* for TCP MSS */ + int ttl; /* IP TTL option */ + int tos; /* type of service bit */ + int flowlabel; /* IPv6 flow label */ + iperf_size_t bytes; /* number of bytes to send */ + iperf_size_t blocks; /* number of blocks (packets) to send */ + char unit_format; /* -f */ + int num_ostreams; /* SCTP initmsg settings */ + int dont_fragment; /* Whether to set IP flag Do-Not_Fragment */ +#if defined(HAVE_SSL) + char *authtoken; /* Authentication token */ + char *client_username; + char *client_password; + EVP_PKEY *client_rsa_pubkey; +#endif // HAVE_SSL + int connect_timeout; /* socket connection timeout, in ms */ + int idle_timeout; /* server idle time timeout */ + unsigned int snd_timeout; /* Timeout for sending tcp messages in active mode, in us */ + struct iperf_time rcv_timeout; /* Timeout for receiving messages in active mode, in us */ +}; + +struct iperf_test; + +struct iperf_stream +{ + struct iperf_test* test; + + pthread_t thr; + int done; + + /* configurable members */ + int local_port; + int remote_port; + int socket; + int id; + int sender; + /* XXX: is settings just a pointer to the same struct in iperf_test? if not, + should it be? */ + struct iperf_settings *settings; /* pointer to structure settings */ + + /* non configurable members */ + struct iperf_stream_result *result; /* structure pointer to result */ + Timer *send_timer; + int green_light; + int buffer_fd; /* data to send, file descriptor */ + char *buffer; /* data to send, mmapped */ + int pending_size; /* pending data to send */ + int diskfile_fd; /* file to send, file descriptor */ + int diskfile_left; /* remaining file data on disk */ + + /* + * for udp measurements - This can be a structure outside stream, and + * stream can have a pointer to this + */ + int64_t packet_count; + int64_t peer_packet_count; + int64_t peer_omitted_packet_count; + int64_t omitted_packet_count; + double jitter; + double prev_transit; + int64_t outoforder_packets; + int64_t omitted_outoforder_packets; + int64_t cnt_error; + int64_t omitted_cnt_error; + uint64_t target; + + struct sockaddr_storage local_addr; + struct sockaddr_storage remote_addr; + + int (*rcv) (struct iperf_stream * stream); + int (*snd) (struct iperf_stream * stream); + + /* chained send/receive routines for -F mode */ + int (*rcv2) (struct iperf_stream * stream); + int (*snd2) (struct iperf_stream * stream); + +// struct iperf_stream *next; + SLIST_ENTRY(iperf_stream) streams; + + void *data; +}; + +struct protocol { + int id; + char *name; + int (*accept)(struct iperf_test *); + int (*listen)(struct iperf_test *); + int (*connect)(struct iperf_test *); + int (*send)(struct iperf_stream *); + int (*recv)(struct iperf_stream *); + int (*init)(struct iperf_test *); + SLIST_ENTRY(protocol) protocols; +}; + +struct iperf_textline { + char *line; + TAILQ_ENTRY(iperf_textline) textlineentries; +}; + +struct xbind_entry { + char *name; + struct addrinfo *ai; + TAILQ_ENTRY(xbind_entry) link; +}; + +enum iperf_mode { + SENDER = 1, + RECEIVER = 0, + BIDIRECTIONAL = -1 +}; + +enum debug_level { + DEBUG_LEVEL_ERROR = 1, + DEBUG_LEVEL_WARN = 2, + DEBUG_LEVEL_INFO = 3, + DEBUG_LEVEL_DEBUG = 4, + DEBUG_LEVEL_MAX = 4 +}; + + +struct iperf_test +{ + pthread_mutex_t print_mutex; + + char role; /* 'c' lient or 's' erver */ + enum iperf_mode mode; + int sender_has_retransmits; + int other_side_has_retransmits; /* used if mode == BIDIRECTIONAL */ + struct protocol *protocol; + signed char state; + char *server_hostname; /* -c option */ + char *tmp_template; + char *bind_address; /* first -B option */ + char *bind_dev; /* bind to network device */ + TAILQ_HEAD(xbind_addrhead, xbind_entry) xbind_addrs; /* all -X opts */ + int bind_port; /* --cport option */ + int server_port; + int omit; /* duration of omit period (-O flag) */ + int duration; /* total duration of test (-t flag) */ + char *diskfile_name; /* -F option */ + int affinity, server_affinity; /* -A option */ +#if defined(HAVE_CPUSET_SETAFFINITY) + cpuset_t cpumask; +#endif /* HAVE_CPUSET_SETAFFINITY */ + char *title; /* -T option */ + char *extra_data; /* --extra-data */ + char *congestion; /* -C option */ + char *congestion_used; /* what was actually used */ + char *remote_congestion_used; /* what the other side used */ + char *pidfile; /* -P option */ + + char *logfile; /* --logfile option */ + FILE *outfile; + + int ctrl_sck; + int mapped_v4; + int listener; + int prot_listener; + + int ctrl_sck_mss; /* MSS for the control channel */ + +#if defined(HAVE_SSL) + char *server_authorized_users; + EVP_PKEY *server_rsa_private_key; + int server_skew_threshold; +#endif // HAVE_SSL + + /* boolean variables for Options */ + int daemon; /* -D option */ + int one_off; /* -1 option */ + int no_delay; /* -N option */ + int reverse; /* -R option */ + int bidirectional; /* --bidirectional */ + int verbose; /* -V option - verbose mode */ + int json_output; /* -J option - JSON output */ + int zerocopy; /* -Z option - use sendfile */ + int debug; /* -d option - enable debug */ + enum debug_level debug_level; /* -d option option - level of debug messages to show */ + int get_server_output; /* --get-server-output */ + int udp_counters_64bit; /* --use-64-bit-udp-counters */ + int forceflush; /* --forceflush - flushing output at every interval */ + int multisend; + int repeating_payload; /* --repeating-payload */ + int timestamps; /* --timestamps */ + char *timestamp_format; + + char *json_output_string; /* rendered JSON output if json_output is set */ + /* Select related parameters */ + int max_fd; + fd_set read_set; /* set of read sockets */ + fd_set write_set; /* set of write sockets */ + + /* Interval related members */ + int omitting; + double stats_interval; + double reporter_interval; + void (*stats_callback) (struct iperf_test *); + void (*reporter_callback) (struct iperf_test *); + Timer *omit_timer; + Timer *timer; + int done; + Timer *stats_timer; + Timer *reporter_timer; + + double cpu_util[3]; /* cpu utilization of the test - total, user, system */ + double remote_cpu_util[3]; /* cpu utilization for the remote host/client - total, user, system */ + + int num_streams; /* total streams in the test (-P) */ + + atomic_iperf_size_t bytes_sent; + atomic_iperf_size_t blocks_sent; + + atomic_iperf_size_t bytes_received; + atomic_iperf_size_t blocks_received; + + iperf_size_t bitrate_limit_stats_count; /* Number of stats periods accumulated for server's total bitrate average */ + iperf_size_t *bitrate_limit_intervals_traffic_bytes; /* Pointer to a cyclic array that includes the last interval's bytes transferred */ + iperf_size_t bitrate_limit_last_interval_index; /* Index of the last interval traffic inserted into the cyclic array */ + int bitrate_limit_exceeded; /* Set by callback routine when average data rate exceeded the server's bitrate limit */ + + int server_last_run_rc; /* Save last server run rc for next test */ + uint server_forced_idle_restarts_count; /* count number of forced server restarts to make sure it is not stack */ + uint server_forced_no_msg_restarts_count; /* count number of forced server restarts to make sure it is not stack */ + uint server_test_number; /* count number of tests performed by a server */ + + char cookie[COOKIE_SIZE]; +// struct iperf_stream *streams; /* pointer to list of struct stream */ + SLIST_HEAD(slisthead, iperf_stream) streams; + struct iperf_settings *settings; + + SLIST_HEAD(plisthead, protocol) protocols; + + /* callback functions */ + void (*on_new_stream)(struct iperf_stream *); + void (*on_test_start)(struct iperf_test *); + void (*on_connect)(struct iperf_test *); + void (*on_test_finish)(struct iperf_test *); + + /* cJSON handles for use when in -J mode */\ + cJSON *json_top; + cJSON *json_start; + cJSON *json_connected; + cJSON *json_intervals; + cJSON *json_end; + + /* Server output (use on client side only) */ + char *server_output_text; + cJSON *json_server_output; + + /* Server output (use on server side only) */ + TAILQ_HEAD(iperf_textlisthead, iperf_textline) server_output_list; + +}; + +/* default settings */ +#define PORT 5201 /* default port to listen on (don't use the same port as iperf2) */ +#define uS_TO_NS 1000 +#define mS_TO_US 1000 +#define SEC_TO_mS 1000 +#define SEC_TO_US 1000000LL +#define UDP_RATE (1024 * 1024) /* 1 Mbps */ +#define OMIT 0 /* seconds */ +#define DURATION 10 /* seconds */ + +#define SEC_TO_NS 1000000000LL /* too big for enum/const on some platforms */ +#define MAX_RESULT_STRING 4096 + +#define UDP_BUFFER_EXTRA 1024 + +/* constants for command line arg sanity checks */ +#define MB (1024 * 1024) +#define MAX_TCP_BUFFER (512 * MB) +#define MAX_BLOCKSIZE MB +/* Minimum size UDP send is the size of two 32-bit ints followed by a 64-bit int */ +#define MIN_UDP_BLOCKSIZE (4 + 4 + 8) +/* Maximum size UDP send is (64K - 1) - IP and UDP header sizes */ +#define MAX_UDP_BLOCKSIZE (65535 - 8 - 20) +#define MIN_INTERVAL 0.1 +#define MAX_INTERVAL 60.0 +#define MAX_TIME 86400 +#define MAX_BURST 1000 +#define MAX_MSS (9 * 1024) +#define MAX_STREAMS 128 + +#define TIMESTAMP_FORMAT "%c " + +extern int gerror; /* error value from getaddrinfo(3), for use in internal error handling */ + +/* UDP "connect" message and reply (textual value for Wireshark, etc. readability - legacy was numeric) */ +#define UDP_CONNECT_MSG 0x36373839 // "6789" - legacy value was 123456789 +#define UDP_CONNECT_REPLY 0x39383736 // "9876" - legacy value was 987654321 +#define LEGACY_UDP_CONNECT_REPLY 987654321 // Old servers may still reply with the legacy value + +/* In Reverse mode, maximum number of packets to wait for "accept" response - to handle out of order packets */ +#define MAX_REVERSE_OUT_OF_ORDER_PACKETS 2 + +#endif /* !__IPERF_H */ |