summaryrefslogtreecommitdiffstats
path: root/src/iperf.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/iperf.h')
-rw-r--r--src/iperf.h463
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 */