diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 14 | ||||
-rw-r--r-- | src/Makefile.in | 70 | ||||
-rw-r--r-- | src/cjson.c | 786 | ||||
-rw-r--r-- | src/cjson.h | 184 | ||||
-rw-r--r-- | src/dscp.c | 5 | ||||
-rwxr-xr-x[-rw-r--r--] | src/iperf.h | 18 | ||||
-rw-r--r-- | src/iperf3.1 | 37 | ||||
-rwxr-xr-x[-rw-r--r--] | src/iperf_api.c | 352 | ||||
-rwxr-xr-x[-rw-r--r--] | src/iperf_api.h | 38 | ||||
-rw-r--r-- | src/iperf_auth.c | 83 | ||||
-rw-r--r-- | src/iperf_auth.h | 1 | ||||
-rw-r--r-- | src/iperf_client_api.c | 27 | ||||
-rw-r--r-- | src/iperf_config.h.in | 2 | ||||
-rw-r--r-- | src/iperf_error.c | 50 | ||||
-rw-r--r-- | src/iperf_locale.c | 16 | ||||
-rw-r--r-- | src/iperf_locale.h | 6 | ||||
-rw-r--r-- | src/iperf_sctp.c | 86 | ||||
-rw-r--r-- | src/iperf_server_api.c | 32 | ||||
-rw-r--r-- | src/iperf_tcp.c | 1 | ||||
-rw-r--r-- | src/iperf_udp.c | 29 | ||||
-rw-r--r-- | src/iperf_util.c | 8 | ||||
-rw-r--r-- | src/iperf_util.h | 2 | ||||
-rw-r--r-- | src/main.c | 3 | ||||
-rw-r--r-- | src/net.c | 5 | ||||
-rw-r--r-- | src/net.h | 4 | ||||
-rw-r--r-- | src/private.pem | 27 | ||||
-rw-r--r-- | src/public.pem | 9 | ||||
-rw-r--r-- | src/t_api.c | 14 | ||||
-rw-r--r-- | src/t_auth.c | 125 | ||||
-rw-r--r-- | src/tcp_info.c | 4 | ||||
-rw-r--r-- | src/timer.h | 2 |
31 files changed, 406 insertions, 1634 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 11d3e17..5be8562 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,9 +1,9 @@ lib_LTLIBRARIES = libiperf.la # Build and install an iperf library bin_PROGRAMS = iperf3 # Build and install an iperf binary if ENABLE_PROFILING -noinst_PROGRAMS = t_timer t_units t_uuid t_api t_auth iperf3_profile # Build, but don't install the test programs and a profiled version of iperf3 +noinst_PROGRAMS = t_timer t_units t_uuid t_api iperf3_profile # Build, but don't install the test programs and a profiled version of iperf3 else -noinst_PROGRAMS = t_timer t_units t_uuid t_api t_auth # Build, but don't install the test programs +noinst_PROGRAMS = t_timer t_units t_uuid t_api # Build, but don't install the test programs endif include_HEADERS = iperf_api.h # Defines the headers that get installed with the program @@ -52,7 +52,7 @@ iperf3_LDADD = libiperf.la iperf3_LDFLAGS = -g if ENABLE_PROFILING -# If the iperf-profiled-binary is enabled +# If the iperf-profiled-binary is enabled (and this condition is true by default) # Specify the sources and various flags for the profiled iperf binary. This # binary recompiles all the source files to make sure they are all profiled. iperf3_profile_SOURCES = main.c \ @@ -84,11 +84,6 @@ t_api_CFLAGS = -g t_api_LDFLAGS = t_api_LDADD = libiperf.la -t_auth_SOURCES = t_auth.c -t_auth_CFLAGS = -g -t_auth_LDFLAGS = -t_auth_LDADD = libiperf.la - # Specify which tests to run during a "make check" @@ -96,7 +91,6 @@ TESTS = \ t_timer \ t_units \ t_uuid \ - t_api \ - t_auth + t_api dist_man_MANS = iperf3.1 libiperf.3 diff --git a/src/Makefile.in b/src/Makefile.in index 271ef6c..619cd45 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.2 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2020 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -93,17 +93,15 @@ host_triplet = @host@ bin_PROGRAMS = iperf3$(EXEEXT) @ENABLE_PROFILING_FALSE@noinst_PROGRAMS = t_timer$(EXEEXT) \ @ENABLE_PROFILING_FALSE@ t_units$(EXEEXT) t_uuid$(EXEEXT) \ -@ENABLE_PROFILING_FALSE@ t_api$(EXEEXT) t_auth$(EXEEXT) +@ENABLE_PROFILING_FALSE@ t_api$(EXEEXT) @ENABLE_PROFILING_TRUE@noinst_PROGRAMS = t_timer$(EXEEXT) \ @ENABLE_PROFILING_TRUE@ t_units$(EXEEXT) t_uuid$(EXEEXT) \ -@ENABLE_PROFILING_TRUE@ t_api$(EXEEXT) t_auth$(EXEEXT) \ -@ENABLE_PROFILING_TRUE@ iperf3_profile$(EXEEXT) +@ENABLE_PROFILING_TRUE@ t_api$(EXEEXT) iperf3_profile$(EXEEXT) TESTS = t_timer$(EXEEXT) t_units$(EXEEXT) t_uuid$(EXEEXT) \ - t_api$(EXEEXT) t_auth$(EXEEXT) + t_api$(EXEEXT) subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/config/ax_check_openssl.m4 \ - $(top_srcdir)/config/iperf_config_static_bin.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) @@ -200,12 +198,6 @@ t_api_DEPENDENCIES = libiperf.la t_api_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(t_api_CFLAGS) $(CFLAGS) \ $(t_api_LDFLAGS) $(LDFLAGS) -o $@ -am_t_auth_OBJECTS = t_auth-t_auth.$(OBJEXT) -t_auth_OBJECTS = $(am_t_auth_OBJECTS) -t_auth_DEPENDENCIES = libiperf.la -t_auth_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(t_auth_CFLAGS) $(CFLAGS) \ - $(t_auth_LDFLAGS) $(LDFLAGS) -o $@ am_t_timer_OBJECTS = t_timer-t_timer.$(OBJEXT) t_timer_OBJECTS = $(am_t_timer_OBJECTS) t_timer_DEPENDENCIES = libiperf.la @@ -264,10 +256,9 @@ am__depfiles_remade = ./$(DEPDIR)/cjson.Plo ./$(DEPDIR)/dscp.Plo \ ./$(DEPDIR)/iperf_tcp.Plo ./$(DEPDIR)/iperf_time.Plo \ ./$(DEPDIR)/iperf_udp.Plo ./$(DEPDIR)/iperf_util.Plo \ ./$(DEPDIR)/net.Plo ./$(DEPDIR)/t_api-t_api.Po \ - ./$(DEPDIR)/t_auth-t_auth.Po ./$(DEPDIR)/t_timer-t_timer.Po \ - ./$(DEPDIR)/t_units-t_units.Po ./$(DEPDIR)/t_uuid-t_uuid.Po \ - ./$(DEPDIR)/tcp_info.Plo ./$(DEPDIR)/timer.Plo \ - ./$(DEPDIR)/units.Plo + ./$(DEPDIR)/t_timer-t_timer.Po ./$(DEPDIR)/t_units-t_units.Po \ + ./$(DEPDIR)/t_uuid-t_uuid.Po ./$(DEPDIR)/tcp_info.Plo \ + ./$(DEPDIR)/timer.Plo ./$(DEPDIR)/units.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -288,12 +279,11 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libiperf_la_SOURCES) $(iperf3_SOURCES) \ - $(iperf3_profile_SOURCES) $(t_api_SOURCES) $(t_auth_SOURCES) \ - $(t_timer_SOURCES) $(t_units_SOURCES) $(t_uuid_SOURCES) + $(iperf3_profile_SOURCES) $(t_api_SOURCES) $(t_timer_SOURCES) \ + $(t_units_SOURCES) $(t_uuid_SOURCES) DIST_SOURCES = $(libiperf_la_SOURCES) $(iperf3_SOURCES) \ $(am__iperf3_profile_SOURCES_DIST) $(t_api_SOURCES) \ - $(t_auth_SOURCES) $(t_timer_SOURCES) $(t_units_SOURCES) \ - $(t_uuid_SOURCES) + $(t_timer_SOURCES) $(t_units_SOURCES) $(t_uuid_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -304,8 +294,8 @@ man3dir = $(mandir)/man3 NROFF = nroff MANS = $(dist_man_MANS) HEADERS = $(include_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ - iperf_config.h.in +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)iperf_config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. @@ -674,7 +664,7 @@ iperf3_CFLAGS = -g iperf3_LDADD = libiperf.la iperf3_LDFLAGS = -g -# If the iperf-profiled-binary is enabled +# If the iperf-profiled-binary is enabled (and this condition is true by default) # Specify the sources and various flags for the profiled iperf binary. This # binary recompiles all the source files to make sure they are all profiled. @ENABLE_PROFILING_TRUE@iperf3_profile_SOURCES = main.c \ @@ -701,10 +691,6 @@ t_api_SOURCES = t_api.c t_api_CFLAGS = -g t_api_LDFLAGS = t_api_LDADD = libiperf.la -t_auth_SOURCES = t_auth.c -t_auth_CFLAGS = -g -t_auth_LDFLAGS = -t_auth_LDADD = libiperf.la dist_man_MANS = iperf3.1 libiperf.3 all: iperf_config.h $(MAKE) $(AM_MAKEFLAGS) all-am @@ -866,10 +852,6 @@ t_api$(EXEEXT): $(t_api_OBJECTS) $(t_api_DEPENDENCIES) $(EXTRA_t_api_DEPENDENCIE @rm -f t_api$(EXEEXT) $(AM_V_CCLD)$(t_api_LINK) $(t_api_OBJECTS) $(t_api_LDADD) $(LIBS) -t_auth$(EXEEXT): $(t_auth_OBJECTS) $(t_auth_DEPENDENCIES) $(EXTRA_t_auth_DEPENDENCIES) - @rm -f t_auth$(EXEEXT) - $(AM_V_CCLD)$(t_auth_LINK) $(t_auth_OBJECTS) $(t_auth_LDADD) $(LIBS) - t_timer$(EXEEXT): $(t_timer_OBJECTS) $(t_timer_DEPENDENCIES) $(EXTRA_t_timer_DEPENDENCIES) @rm -f t_timer$(EXEEXT) $(AM_V_CCLD)$(t_timer_LINK) $(t_timer_OBJECTS) $(t_timer_LDADD) $(LIBS) @@ -922,7 +904,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_util.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_api-t_api.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_auth-t_auth.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_timer-t_timer.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_units-t_units.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_uuid-t_uuid.Po@am__quote@ # am--include-marker @@ -1237,20 +1218,6 @@ t_api-t_api.obj: t_api.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(t_api_CFLAGS) $(CFLAGS) -c -o t_api-t_api.obj `if test -f 't_api.c'; then $(CYGPATH_W) 't_api.c'; else $(CYGPATH_W) '$(srcdir)/t_api.c'; fi` -t_auth-t_auth.o: t_auth.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(t_auth_CFLAGS) $(CFLAGS) -MT t_auth-t_auth.o -MD -MP -MF $(DEPDIR)/t_auth-t_auth.Tpo -c -o t_auth-t_auth.o `test -f 't_auth.c' || echo '$(srcdir)/'`t_auth.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/t_auth-t_auth.Tpo $(DEPDIR)/t_auth-t_auth.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t_auth.c' object='t_auth-t_auth.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(t_auth_CFLAGS) $(CFLAGS) -c -o t_auth-t_auth.o `test -f 't_auth.c' || echo '$(srcdir)/'`t_auth.c - -t_auth-t_auth.obj: t_auth.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(t_auth_CFLAGS) $(CFLAGS) -MT t_auth-t_auth.obj -MD -MP -MF $(DEPDIR)/t_auth-t_auth.Tpo -c -o t_auth-t_auth.obj `if test -f 't_auth.c'; then $(CYGPATH_W) 't_auth.c'; else $(CYGPATH_W) '$(srcdir)/t_auth.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/t_auth-t_auth.Tpo $(DEPDIR)/t_auth-t_auth.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t_auth.c' object='t_auth-t_auth.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(t_auth_CFLAGS) $(CFLAGS) -c -o t_auth-t_auth.obj `if test -f 't_auth.c'; then $(CYGPATH_W) 't_auth.c'; else $(CYGPATH_W) '$(srcdir)/t_auth.c'; fi` - t_timer-t_timer.o: t_timer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(t_timer_CFLAGS) $(CFLAGS) -MT t_timer-t_timer.o -MD -MP -MF $(DEPDIR)/t_timer-t_timer.Tpo -c -o t_timer-t_timer.o `test -f 't_timer.c' || echo '$(srcdir)/'`t_timer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/t_timer-t_timer.Tpo $(DEPDIR)/t_timer-t_timer.Po @@ -1627,13 +1594,6 @@ t_api.log: t_api$(EXEEXT) --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -t_auth.log: t_auth$(EXEEXT) - @p='t_auth$(EXEEXT)'; \ - b='t_auth'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ @@ -1766,7 +1726,6 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/iperf_util.Plo -rm -f ./$(DEPDIR)/net.Plo -rm -f ./$(DEPDIR)/t_api-t_api.Po - -rm -f ./$(DEPDIR)/t_auth-t_auth.Po -rm -f ./$(DEPDIR)/t_timer-t_timer.Po -rm -f ./$(DEPDIR)/t_units-t_units.Po -rm -f ./$(DEPDIR)/t_uuid-t_uuid.Po @@ -1852,7 +1811,6 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/iperf_util.Plo -rm -f ./$(DEPDIR)/net.Plo -rm -f ./$(DEPDIR)/t_api-t_api.Po - -rm -f ./$(DEPDIR)/t_auth-t_auth.Po -rm -f ./$(DEPDIR)/t_timer-t_timer.Po -rm -f ./$(DEPDIR)/t_units-t_units.Po -rm -f ./$(DEPDIR)/t_uuid-t_uuid.Po diff --git a/src/cjson.c b/src/cjson.c index bf0b8b4..a31874d 100644 --- a/src/cjson.c +++ b/src/cjson.c @@ -23,39 +23,23 @@ /* cJSON */ /* JSON parser in C. */ -/* disable warnings about old C89 functions in MSVC */ -#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) -#define _CRT_SECURE_NO_DEPRECATE -#endif - #ifdef __GNUC__ #pragma GCC visibility push(default) #endif -#if defined(_MSC_VER) -#pragma warning (push) -/* disable warning about single line comments in system headers */ -#pragma warning (disable : 4001) -#endif #include <string.h> #include <stdio.h> #include <math.h> #include <stdlib.h> +#include <float.h> #include <limits.h> #include <ctype.h> -#include <float.h> #ifdef HAVE_STDINT_H #include <stdint.h> #endif #include <sys/types.h> - -#ifdef ENABLE_LOCALES #include <locale.h> -#endif -#if defined(_MSC_VER) -#pragma warning (pop) -#endif #ifdef __GNUC__ #pragma GCC visibility pop #endif @@ -63,28 +47,9 @@ #include "cjson.h" /* define our own boolean type */ -#ifdef true -#undef true -#endif #define true ((cJSON_bool)1) - -#ifdef false -#undef false -#endif #define false ((cJSON_bool)0) -/* define isnan and isinf for ANSI C, if in C99 or above, isnan and isinf has been defined in math.h */ -#ifndef isinf -#define isinf(d) (isnan((d - d)) && !isnan(d)) -#endif -#ifndef isnan -#define isnan(d) (d != d) -#endif - -#ifndef NAN -#define NAN 0.0/0.0 -#endif - typedef struct { const unsigned char *json; size_t position; @@ -103,28 +68,8 @@ CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void) return (const char*) (global_error.json + global_error.position); } -CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item) -{ - if (!cJSON_IsString(item)) - { - return NULL; - } - - return item->valuestring; -} - -CJSON_PUBLIC(double) cJSON_GetNumberValue(cJSON *item) -{ - if (!cJSON_IsNumber(item)) - { - return NAN; - } - - return item->valuedouble; -} - /* This is a safeguard to prevent copy-pasters from using incompatible C and header files */ -#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 13) +#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 5) || (CJSON_VERSION_PATCH != 2) #error cJSON.h and cJSON.c have different versions. Make sure that both have the same. #endif @@ -162,35 +107,12 @@ static int case_insensitive_strcmp(const unsigned char *string1, const unsigned typedef struct internal_hooks { - void *(CJSON_CDECL *allocate)(size_t size); - void (CJSON_CDECL *deallocate)(void *pointer); - void *(CJSON_CDECL *reallocate)(void *pointer, size_t size); + void *(*allocate)(size_t size); + void (*deallocate)(void *pointer); + void *(*reallocate)(void *pointer, size_t size); } internal_hooks; -#if defined(_MSC_VER) -/* work around MSVC error C2322: '...' address of dllimport '...' is not static */ -static void * CJSON_CDECL internal_malloc(size_t size) -{ - return malloc(size); -} -static void CJSON_CDECL internal_free(void *pointer) -{ - free(pointer); -} -static void * CJSON_CDECL internal_realloc(void *pointer, size_t size) -{ - return realloc(pointer, size); -} -#else -#define internal_malloc malloc -#define internal_free free -#define internal_realloc realloc -#endif - -/* strlen of character literals resolved at compile time */ -#define static_strlen(string_literal) (sizeof(string_literal) - sizeof("")) - -static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc }; +static internal_hooks global_hooks = { malloc, free, realloc }; static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks) { @@ -203,8 +125,7 @@ static unsigned char* cJSON_strdup(const unsigned char* string, const internal_h } length = strlen((const char*)string) + sizeof(""); - copy = (unsigned char*)hooks->allocate(length); - if (copy == NULL) + if (!(copy = (unsigned char*)hooks->allocate(length))) { return NULL; } @@ -283,12 +204,8 @@ CJSON_PUBLIC(void) cJSON_Delete(cJSON *item) /* get the decimal point character of the current locale */ static unsigned char get_decimal_point(void) { -#ifdef ENABLE_LOCALES struct lconv *lconv = localeconv(); return (unsigned char) lconv->decimal_point[0]; -#else - return '.'; -#endif } typedef struct @@ -302,6 +219,7 @@ typedef struct /* check if the given size is left to read in a given parse buffer (starting with 1) */ #define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length)) +#define cannot_read(buffer, size) (!can_read(buffer, size)) /* check if the buffer can be accessed at the given index (starting with 0) */ #define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length)) #define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index)) @@ -370,7 +288,7 @@ loop_end: { item->valueint = LLONG_MAX; } - else if (number <= (double)LLONG_MIN) + else if (number <= LLONG_MIN) { item->valueint = LLONG_MIN; } @@ -392,7 +310,7 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number) { object->valueint = LLONG_MAX; } - else if (number <= (double)LLONG_MIN) + else if (number <= LLONG_MIN) { object->valueint = LLONG_MIN; } @@ -404,33 +322,6 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number) return object->valuedouble = number; } -CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring) -{ - char *copy = NULL; - /* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */ - if (!(object->type & cJSON_String) || (object->type & cJSON_IsReference)) - { - return NULL; - } - if (strlen(valuestring) <= strlen(object->valuestring)) - { - strcpy(object->valuestring, valuestring); - return object->valuestring; - } - copy = (char*) cJSON_strdup((const unsigned char*)valuestring, &global_hooks); - if (copy == NULL) - { - return NULL; - } - if (object->valuestring != NULL) - { - cJSON_free(object->valuestring); - } - object->valuestring = copy; - - return copy; -} - typedef struct { unsigned char *buffer; @@ -459,9 +350,9 @@ static unsigned char* ensure(printbuffer * const p, size_t needed) return NULL; } - if (needed > SIZE_MAX) + if (needed > LLONG_MAX) { - /* sizes bigger than SIZE_MAX are currently not supported */ + /* sizes bigger than LLONG_MAX are currently not supported */ return NULL; } @@ -476,12 +367,12 @@ static unsigned char* ensure(printbuffer * const p, size_t needed) } /* calculate new buffer size */ - if (needed > (SIZE_MAX / 2)) + if (needed > (LLONG_MAX / 2)) { - /* overflow of int, use SIZE_MAX if possible */ - if (needed <= SIZE_MAX) + /* overflow of int, use LLONG_MAX if possible */ + if (needed <= LLONG_MAX) { - newsize = SIZE_MAX; + newsize = LLONG_MAX; } else { @@ -497,14 +388,6 @@ static unsigned char* ensure(printbuffer * const p, size_t needed) { /* reallocate with realloc if available */ newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize); - if (newbuffer == NULL) - { - p->hooks.deallocate(p->buffer); - p->length = 0; - p->buffer = NULL; - - return NULL; - } } else { @@ -543,13 +426,6 @@ static void update_offset(printbuffer * const buffer) buffer->offset += strlen((const char*)buffer_pointer); } -/* securely comparison of floating-point variables */ -static cJSON_bool compare_double(double a, double b) -{ - double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b); - return (fabs(a - b) <= maxVal * DBL_EPSILON); -} - /* Render the number nicely from the given item into a string. */ static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer) { @@ -557,9 +433,9 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out double d = item->valuedouble; int length = 0; size_t i = 0; - unsigned char number_buffer[26] = {0}; /* temporary buffer to print the number into */ + unsigned char number_buffer[26]; /* temporary buffer to print the number into */ unsigned char decimal_point = get_decimal_point(); - double test = 0.0; + double test; if (output_buffer == NULL) { @@ -567,7 +443,7 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out } /* This checks for NaN and Infinity */ - if (isnan(d) || isinf(d)) + if ((d * 0) != 0) { length = sprintf((char*)number_buffer, "null"); } @@ -577,21 +453,21 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out length = sprintf((char*)number_buffer, "%1.15g", d); /* Check whether the original double can be recovered */ - if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d)) + if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || ((double)test != d)) { /* If not, print with 17 decimal places of precision */ length = sprintf((char*)number_buffer, "%1.17g", d); } } - /* sprintf failed or buffer overrun occurred */ + /* sprintf failed or buffer overrun occured */ if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1))) { return false; } /* reserve appropriate space in the output */ - output_pointer = ensure(output_buffer, (size_t)length + sizeof("")); + output_pointer = ensure(output_buffer, (size_t)length); if (output_pointer == NULL) { return false; @@ -1047,11 +923,6 @@ static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer) return NULL; } - if (cannot_access_at_index(buffer, 0)) - { - return buffer; - } - while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32)) { buffer->offset++; @@ -1065,39 +936,8 @@ static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer) return buffer; } -/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */ -static parse_buffer *skip_utf8_bom(parse_buffer * const buffer) -{ - if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0)) - { - return NULL; - } - - if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0)) - { - buffer->offset += 3; - } - - return buffer; -} - -CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated) -{ - size_t buffer_length; - - if (NULL == value) - { - return NULL; - } - - /* Adding null character size due to require_null_terminated. */ - buffer_length = strlen(value) + sizeof(""); - - return cJSON_ParseWithLengthOpts(value, buffer_length, return_parse_end, require_null_terminated); -} - /* Parse an object - create a new root, and populate. */ -CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated) +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated) { parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } }; cJSON *item = NULL; @@ -1106,13 +946,13 @@ CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer global_error.json = NULL; global_error.position = 0; - if (value == NULL || 0 == buffer_length) + if (value == NULL) { goto fail; } buffer.content = (const unsigned char*)value; - buffer.length = buffer_length; + buffer.length = strlen((const char*)value) + sizeof(""); buffer.offset = 0; buffer.hooks = global_hooks; @@ -1122,7 +962,7 @@ CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer goto fail; } - if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer)))) + if (!parse_value(item, buffer_skip_whitespace(&buffer))) { /* parse failure. ep is set. */ goto fail; @@ -1169,8 +1009,10 @@ fail: { *return_parse_end = (const char*)local_error.json + local_error.position; } - - global_error = local_error; + else + { + global_error = local_error; + } } return NULL; @@ -1182,24 +1024,17 @@ CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value) return cJSON_ParseWithOpts(value, 0, 0); } -CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length) -{ - return cJSON_ParseWithLengthOpts(value, buffer_length, 0, 0); -} - -#define cjson_min(a, b) (((a) < (b)) ? (a) : (b)) +#define cjson_min(a, b) ((a < b) ? a : b) static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks) { - static const size_t default_buffer_size = 256; printbuffer buffer[1]; unsigned char *printed = NULL; memset(buffer, 0, sizeof(buffer)); /* create buffer */ - buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size); - buffer->length = default_buffer_size; + buffer->buffer = (unsigned char*) hooks->allocate(256); buffer->format = format; buffer->hooks = *hooks; if (buffer->buffer == NULL) @@ -1217,11 +1052,11 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i /* check if reallocate is available */ if (hooks->reallocate != NULL) { - printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1); + printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->length); + buffer->buffer = NULL; if (printed == NULL) { goto fail; } - buffer->buffer = NULL; } else /* otherwise copy the JSON over to a new buffer */ { @@ -1287,27 +1122,26 @@ CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON if (!print_value(item, &p)) { - global_hooks.deallocate(p.buffer); return NULL; } return (char*)p.buffer; } -CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format) +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const cJSON_bool fmt) { printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; - if ((length < 0) || (buffer == NULL)) + if (len < 0) { return false; } - p.buffer = (unsigned char*)buffer; - p.length = (size_t)length; + p.buffer = (unsigned char*)buf; + p.length = (size_t)len; p.offset = 0; p.noalloc = true; - p.format = format; + p.format = fmt; p.hooks = global_hooks; return print_value(item, &p); @@ -1365,6 +1199,7 @@ static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buf return parse_object(item, input_buffer); } + return false; } @@ -1415,6 +1250,10 @@ static cJSON_bool print_value(const cJSON * const item, printbuffer * const outp size_t raw_length = 0; if (item->valuestring == NULL) { + if (!output_buffer->noalloc) + { + output_buffer->hooks.deallocate(output_buffer->buffer); + } return false; } @@ -1660,7 +1499,7 @@ static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_bu buffer_skip_whitespace(input_buffer); if (!parse_string(current_item, input_buffer)) { - goto fail; /* failed to parse name */ + goto fail; /* faile to parse name */ } buffer_skip_whitespace(input_buffer); @@ -1780,7 +1619,7 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out update_offset(output_buffer); /* print comma if not last */ - length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0)); + length = (size_t) ((output_buffer->format ? 1 : 0) + (current_item->next ? 1 : 0)); output_pointer = ensure(output_buffer, length + 1); if (output_pointer == NULL) { @@ -1824,25 +1663,17 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out /* Get Array size/item / object item. */ CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array) { - cJSON *child = NULL; - size_t size = 0; - - if (array == NULL) - { - return 0; - } - - child = array->child; - - while(child != NULL) + cJSON *c = array->child; + size_t i = 0; + while(c) { - size++; - child = child->next; + i++; + c = c->next; } /* FIXME: Can overflow here. Cannot be fixed without breaking the API */ - return (int)size; + return (int)i; } static cJSON* get_array_item(const cJSON *array, size_t index) @@ -1886,7 +1717,7 @@ static cJSON *get_object_item(const cJSON * const object, const char * const nam current_element = object->child; if (case_sensitive) { - while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0)) + while ((current_element != NULL) && (strcmp(name, current_element->string) != 0)) { current_element = current_element->next; } @@ -1899,10 +1730,6 @@ static cJSON *get_object_item(const cJSON * const object, const char * const nam } } - if ((current_element == NULL) || (current_element->string == NULL)) { - return NULL; - } - return current_element; } @@ -1931,263 +1758,88 @@ static void suffix_object(cJSON *prev, cJSON *item) /* Utility for handling references. */ static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks) { - cJSON *reference = NULL; - if (item == NULL) - { - return NULL; - } - - reference = cJSON_New_Item(hooks); - if (reference == NULL) + cJSON *ref = cJSON_New_Item(hooks); + if (!ref) { return NULL; } - - memcpy(reference, item, sizeof(cJSON)); - reference->string = NULL; - reference->type |= cJSON_IsReference; - reference->next = reference->prev = NULL; - return reference; + memcpy(ref, item, sizeof(cJSON)); + ref->string = NULL; + ref->type |= cJSON_IsReference; + ref->next = ref->prev = NULL; + return ref; } -static cJSON_bool add_item_to_array(cJSON *array, cJSON *item) +/* Add item to array/object. */ +CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item) { cJSON *child = NULL; - if ((item == NULL) || (array == NULL) || (array == item)) + if ((item == NULL) || (array == NULL)) { - return false; + return; } child = array->child; - /* - * To find the last item in array quickly, we use prev in array - */ + if (child == NULL) { /* list is empty, start new one */ array->child = item; - item->prev = item; - item->next = NULL; } else { /* append to the end */ - if (child->prev) + while (child->next) { - suffix_object(child->prev, item); - array->child->prev = item; - } - else - { - while (child->next) - { - child = child->next; - } - suffix_object(child, item); - array->child->prev = item; + child = child->next; } + suffix_object(child, item); } - - return true; } -/* Add item to array/object. */ -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item) +CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) { - return add_item_to_array(array, item); + /* call cJSON_AddItemToObjectCS for code reuse */ + cJSON_AddItemToObjectCS(object, (char*)cJSON_strdup((const unsigned char*)string, &global_hooks), item); + /* remove cJSON_StringIsConst flag */ + item->type &= ~cJSON_StringIsConst; } -#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) +#if defined (__clang__) || ((__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) #pragma GCC diagnostic push #endif #ifdef __GNUC__ #pragma GCC diagnostic ignored "-Wcast-qual" #endif -/* helper function to cast away const */ -static void* cast_away_const(const void* string) -{ - return (void*)string; -} -#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) - #pragma GCC diagnostic pop -#endif - - -static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key) -{ - char *new_key = NULL; - int new_type = cJSON_Invalid; - - if ((object == NULL) || (string == NULL) || (item == NULL) || (object == item)) - { - return false; - } - - if (constant_key) - { - new_key = (char*)cast_away_const(string); - new_type = item->type | cJSON_StringIsConst; - } - else - { - new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks); - if (new_key == NULL) - { - return false; - } - - new_type = item->type & ~cJSON_StringIsConst; - } - - if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) - { - hooks->deallocate(item->string); - } - - item->string = new_key; - item->type = new_type; - - return add_item_to_array(object, item); -} - -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) -{ - return add_item_to_object(object, string, item, &global_hooks, false); -} /* Add an item to an object with constant string as key */ -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) -{ - return add_item_to_object(object, string, item, &global_hooks, true); -} - -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) -{ - if (array == NULL) - { - return false; - } - - return add_item_to_array(array, create_reference(item, &global_hooks)); -} - -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) +CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) { - if ((object == NULL) || (string == NULL)) - { - return false; - } - - return add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false); -} - -CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name) -{ - cJSON *null = cJSON_CreateNull(); - if (add_item_to_object(object, name, null, &global_hooks, false)) - { - return null; - } - - cJSON_Delete(null); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name) -{ - cJSON *true_item = cJSON_CreateTrue(); - if (add_item_to_object(object, name, true_item, &global_hooks, false)) - { - return true_item; - } - - cJSON_Delete(true_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name) -{ - cJSON *false_item = cJSON_CreateFalse(); - if (add_item_to_object(object, name, false_item, &global_hooks, false)) - { - return false_item; - } - - cJSON_Delete(false_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean) -{ - cJSON *bool_item = cJSON_CreateBool(boolean); - if (add_item_to_object(object, name, bool_item, &global_hooks, false)) - { - return bool_item; - } - - cJSON_Delete(bool_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number) -{ - cJSON *number_item = cJSON_CreateNumber(number); - if (add_item_to_object(object, name, number_item, &global_hooks, false)) - { - return number_item; - } - - cJSON_Delete(number_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string) -{ - cJSON *string_item = cJSON_CreateString(string); - if (add_item_to_object(object, name, string_item, &global_hooks, false)) + if (!item) { - return string_item; + return; } - - cJSON_Delete(string_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw) -{ - cJSON *raw_item = cJSON_CreateRaw(raw); - if (add_item_to_object(object, name, raw_item, &global_hooks, false)) + if (!(item->type & cJSON_StringIsConst) && item->string) { - return raw_item; + global_hooks.deallocate(item->string); } - - cJSON_Delete(raw_item); - return NULL; + item->string = (char*)string; + item->type |= cJSON_StringIsConst; + cJSON_AddItemToArray(object, item); } +#if defined (__clang__) || ((__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic pop +#endif -CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name) +CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) { - cJSON *object_item = cJSON_CreateObject(); - if (add_item_to_object(object, name, object_item, &global_hooks, false)) - { - return object_item; - } - - cJSON_Delete(object_item); - return NULL; + cJSON_AddItemToArray(array, create_reference(item, &global_hooks)); } -CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name) +CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) { - cJSON *array = cJSON_CreateArray(); - if (add_item_to_object(object, name, array, &global_hooks, false)) - { - return array; - } - - cJSON_Delete(array); - return NULL; + cJSON_AddItemToObject(object, string, create_reference(item, &global_hooks)); } CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item) @@ -2197,7 +1849,7 @@ CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const it return NULL; } - if (item != parent->child) + if (item->prev != NULL) { /* not the first element */ item->prev->next = item->next; @@ -2260,19 +1912,20 @@ CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const } /* Replace array/object items with new ones. */ -CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) +CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) { cJSON *after_inserted = NULL; if (which < 0) { - return false; + return; } after_inserted = get_array_item(array, (size_t)which); if (after_inserted == NULL) { - return add_item_to_array(array, newitem); + cJSON_AddItemToArray(array, newitem); + return; } newitem->next = after_inserted; @@ -2286,12 +1939,11 @@ CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON { newitem->prev->next = newitem; } - return true; } CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement) { - if ((parent == NULL) || (replacement == NULL) || (item == NULL)) + if ((parent == NULL) || (replacement == NULL)) { return false; } @@ -2308,20 +1960,14 @@ CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON { replacement->next->prev = replacement; } + if (replacement->prev != NULL) + { + replacement->prev->next = replacement; + } if (parent->child == item) { parent->child = replacement; } - else - { /* - * To find the last item in array quickly, we use prev in array. - * We can't modify the last item's next pointer where this item was the parent's child - */ - if (replacement->prev != NULL) - { - replacement->prev->next = replacement; - } - } item->next = NULL; item->prev = NULL; @@ -2330,42 +1976,24 @@ CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON return true; } -CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) +CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) { if (which < 0) { - return false; - } - - return cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem); -} - -static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive) -{ - if ((replacement == NULL) || (string == NULL)) - { - return false; - } - - /* replace the name in the replacement */ - if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL)) - { - cJSON_free(replacement->string); + return; } - replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); - replacement->type &= ~cJSON_StringIsConst; - return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement); + cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem); } -CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) +CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) { - return replace_item_in_object(object, string, newitem, false); + cJSON_ReplaceItemViaPointer(object, cJSON_GetObjectItem(object, string), newitem); } -CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) +CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) { - return replace_item_in_object(object, string, newitem, true); + cJSON_ReplaceItemViaPointer(object, cJSON_GetObjectItemCaseSensitive(object, string), newitem); } /* Create basic types: */ @@ -2402,12 +2030,12 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void) return item; } -CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean) +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool b) { cJSON *item = cJSON_New_Item(&global_hooks); if(item) { - item->type = boolean ? cJSON_True : cJSON_False; + item->type = b ? cJSON_True : cJSON_False; } return item; @@ -2426,7 +2054,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num) { item->valueint = LLONG_MAX; } - else if (num <= (double)LLONG_MIN) + else if (num <= LLONG_MIN) { item->valueint = LLONG_MIN; } @@ -2456,39 +2084,6 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string) return item; } -CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string) -{ - cJSON *item = cJSON_New_Item(&global_hooks); - if (item != NULL) - { - item->type = cJSON_String | cJSON_IsReference; - item->valuestring = (char*)cast_away_const(string); - } - - return item; -} - -CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child) -{ - cJSON *item = cJSON_New_Item(&global_hooks); - if (item != NULL) { - item->type = cJSON_Object | cJSON_IsReference; - item->child = (cJSON*)cast_away_const(child); - } - - return item; -} - -CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) { - cJSON *item = cJSON_New_Item(&global_hooks); - if (item != NULL) { - item->type = cJSON_Array | cJSON_IsReference; - item->child = (cJSON*)cast_away_const(child); - } - - return item; -} - CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw) { cJSON *item = cJSON_New_Item(&global_hooks); @@ -2536,7 +2131,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count) cJSON *p = NULL; cJSON *a = NULL; - if ((count < 0) || (numbers == NULL)) + if (count < 0) { return NULL; } @@ -2571,7 +2166,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count) cJSON *p = NULL; cJSON *a = NULL; - if ((count < 0) || (numbers == NULL)) + if (count < 0) { return NULL; } @@ -2607,7 +2202,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count) cJSON *p = NULL; cJSON *a = NULL; - if ((count < 0) || (numbers == NULL)) + if (count < 0) { return NULL; } @@ -2636,14 +2231,14 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count) return a; } -CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count) +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count) { size_t i = 0; cJSON *n = NULL; cJSON *p = NULL; cJSON *a = NULL; - if ((count < 0) || (strings == NULL)) + if (count < 0) { return NULL; } @@ -2752,96 +2347,63 @@ fail: return NULL; } -static void skip_oneline_comment(char **input) +CJSON_PUBLIC(void) cJSON_Minify(char *json) { - *input += static_strlen("//"); - - for (; (*input)[0] != '\0'; ++(*input)) + unsigned char *into = (unsigned char*)json; + while (*json) { - if ((*input)[0] == '\n') { - *input += static_strlen("\n"); - return; + if (*json == ' ') + { + json++; } - } -} - -static void skip_multiline_comment(char **input) -{ - *input += static_strlen("/*"); - - for (; (*input)[0] != '\0'; ++(*input)) - { - if (((*input)[0] == '*') && ((*input)[1] == '/')) + else if (*json == '\t') { - *input += static_strlen("*/"); - return; + /* Whitespace characters. */ + json++; } - } -} - -static void minify_string(char **input, char **output) { - (*output)[0] = (*input)[0]; - *input += static_strlen("\""); - *output += static_strlen("\""); - - - for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) { - (*output)[0] = (*input)[0]; - - if ((*input)[0] == '\"') { - (*output)[0] = '\"'; - *input += static_strlen("\""); - *output += static_strlen("\""); - return; - } else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) { - (*output)[1] = (*input)[1]; - *input += static_strlen("\""); - *output += static_strlen("\""); + else if (*json == '\r') + { + json++; } - } -} - -CJSON_PUBLIC(void) cJSON_Minify(char *json) -{ - char *into = json; - - if (json == NULL) - { - return; - } - - while (json[0] != '\0') - { - switch (json[0]) + else if (*json=='\n') { - case ' ': - case '\t': - case '\r': - case '\n': + json++; + } + else if ((*json == '/') && (json[1] == '/')) + { + /* double-slash comments, to end of line. */ + while (*json && (*json != '\n')) + { json++; - break; - - case '/': - if (json[1] == '/') - { - skip_oneline_comment(&json); - } - else if (json[1] == '*') + } + } + else if ((*json == '/') && (json[1] == '*')) + { + /* multiline comments. */ + while (*json && !((*json == '*') && (json[1] == '/'))) + { + json++; + } + json += 2; + } + else if (*json == '\"') + { + /* string literals, which are \" sensitive. */ + *into++ = (unsigned char)*json++; + while (*json && (*json != '\"')) + { + if (*json == '\\') { - skip_multiline_comment(&json); - } else { - json++; + *into++ = (unsigned char)*json++; } - break; - - case '\"': - minify_string(&json, (char**)&into); - break; - - default: - into[0] = json[0]; - json++; - into++; + *into++ = (unsigned char)*json++; + } + *into++ = (unsigned char)*json++; + } + else + { + /* All other characters. */ + *into++ = (unsigned char)*json++; } } @@ -2988,7 +2550,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons return true; case cJSON_Number: - if (compare_double(a->valuedouble, b->valuedouble)) + if (a->valuedouble == b->valuedouble) { return true; } @@ -3023,22 +2585,16 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons b_element = b_element->next; } - /* one of the arrays is longer than the other */ - if (a_element != b_element) { - return false; - } - return true; } case cJSON_Object: { cJSON *a_element = NULL; - cJSON *b_element = NULL; cJSON_ArrayForEach(a_element, a) { /* TODO This has O(n^2) runtime, which is horrible! */ - b_element = get_object_item(b, a_element->string, case_sensitive); + cJSON *b_element = get_object_item(b, a_element->string, case_sensitive); if (b_element == NULL) { return false; @@ -3050,22 +2606,6 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons } } - /* doing this twice, once on a and b to prevent true comparison if a subset of b - * TODO: Do this the proper way, this is just a fix for now */ - cJSON_ArrayForEach(b_element, b) - { - a_element = get_object_item(a, b_element->string, case_sensitive); - if (a_element == NULL) - { - return false; - } - - if (!cJSON_Compare(b_element, a_element, case_sensitive)) - { - return false; - } - } - return true; } diff --git a/src/cjson.h b/src/cjson.h index 03bc353..fa7cb73 100644 --- a/src/cjson.h +++ b/src/cjson.h @@ -33,60 +33,10 @@ extern "C" { #endif -#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) -#define __WINDOWS__ -#endif - -#ifdef __WINDOWS__ - -/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options: - -CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols -CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default) -CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol - -For *nix builds that support visibility attribute, you can define similar behavior by - -setting default visibility to hidden by adding --fvisibility=hidden (for gcc) -or --xldscope=hidden (for sun cc) -to CFLAGS - -then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does - -*/ - -#define CJSON_CDECL __cdecl -#define CJSON_STDCALL __stdcall - -/* export symbols by default, this is necessary for copy pasting the C and header file */ -#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS) -#define CJSON_EXPORT_SYMBOLS -#endif - -#if defined(CJSON_HIDE_SYMBOLS) -#define CJSON_PUBLIC(type) type CJSON_STDCALL -#elif defined(CJSON_EXPORT_SYMBOLS) -#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL -#elif defined(CJSON_IMPORT_SYMBOLS) -#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL -#endif -#else /* !__WINDOWS__ */ -#define CJSON_CDECL -#define CJSON_STDCALL - -#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY) -#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type -#else -#define CJSON_PUBLIC(type) type -#endif -#endif - /* project version */ #define CJSON_VERSION_MAJOR 1 -#define CJSON_VERSION_MINOR 7 -#define CJSON_VERSION_PATCH 13 +#define CJSON_VERSION_MINOR 5 +#define CJSON_VERSION_PATCH 2 #include <stddef.h> @@ -129,13 +79,55 @@ typedef struct cJSON typedef struct cJSON_Hooks { - /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */ - void *(CJSON_CDECL *malloc_fn)(size_t sz); - void (CJSON_CDECL *free_fn)(void *ptr); + void *(*malloc_fn)(size_t sz); + void (*free_fn)(void *ptr); } cJSON_Hooks; typedef int cJSON_bool; +#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) +#define __WINDOWS__ +#endif +#ifdef __WINDOWS__ + +/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 2 define options: + +CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols +CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default) +CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol + +For *nix builds that support visibility attribute, you can define similar behavior by + +setting default visibility to hidden by adding +-fvisibility=hidden (for gcc) +or +-xldscope=hidden (for sun cc) +to CFLAGS + +then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does + +*/ + +/* export symbols by default, this is necessary for copy pasting the C and header file */ +#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_EXPORT_SYMBOLS +#endif + +#if defined(CJSON_HIDE_SYMBOLS) +#define CJSON_PUBLIC(type) type __stdcall +#elif defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllexport) type __stdcall +#elif defined(CJSON_IMPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllimport) type __stdcall +#endif +#else /* !WIN32 */ +#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY) +#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type +#else +#define CJSON_PUBLIC(type) type +#endif +#endif + /* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them. * This is to prevent stack overflows. */ #ifndef CJSON_NESTING_LIMIT @@ -151,12 +143,6 @@ CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks); /* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */ /* Supply a block of JSON, and this returns a cJSON object you can interrogate. */ CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); -CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length); -/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ -/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */ -CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated); -CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated); - /* Render a cJSON entity to text for transfer/storage. */ CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); /* Render a cJSON entity to text for transfer/storage without any formatting. */ @@ -167,11 +153,11 @@ CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON /* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */ CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format); /* Delete a cJSON entity and all subentities. */ -CJSON_PUBLIC(void) cJSON_Delete(cJSON *item); +CJSON_PUBLIC(void) cJSON_Delete(cJSON *c); /* Returns the number of items in an array (or object). */ CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array); -/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */ +/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index); /* Get item "string" from object. Case insensitive. */ CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string); @@ -180,10 +166,6 @@ CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *st /* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); -/* Check item type and return its value */ -CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item); -CJSON_PUBLIC(double) cJSON_GetNumberValue(cJSON *item); - /* These functions check the type of an item */ CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item); @@ -208,33 +190,24 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw); CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void); CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void); -/* Create a string where valuestring references a string so - * it will not be freed by cJSON_Delete */ -CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string); -/* Create an object/array that only references it's elements so - * they will not be freed by cJSON_Delete */ -CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child); -CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child); - -/* These utilities create an Array of count items. - * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/ +/* These utilities create an Array of count items. */ CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); -CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count); /* Append item to the specified array/object. */ -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item); -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); +CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); /* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before * writing to `item->string` */ -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); +CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); +CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); -/* Remove/Detach items from Arrays/Objects. */ +/* Remove/Detatch items from Arrays/Objects. */ CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item); CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which); CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which); @@ -244,47 +217,44 @@ CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string) CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string); /* Update array items. */ -CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ +CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement); -CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); -CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); -CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); +CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); +CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); +CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); /* Duplicate a cJSON item */ CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); /* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will - * need to be released. With recurse!=0, it will duplicate any children connected to the item. - * The item->next and ->prev pointers are always zero on return from Duplicate. */ +need to be released. With recurse!=0, it will duplicate any children connected to the item. +The item->next and ->prev pointers are always zero on return from Duplicate. */ /* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal. * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive); -/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings. - * The input pointer json cannot point to a read-only address area, such as a string constant, - * but should point to a readable and writable adress area. */ + +/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ +/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error. If not, then cJSON_GetErrorPtr() does the job. */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated); + CJSON_PUBLIC(void) cJSON_Minify(char *json); -/* Helper functions for creating and adding items to an object at the same time. - * They return the added item or NULL on failure. */ -CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name); -CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name); -CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name); -CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean); -CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number); -CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string); -CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw); -CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name); -CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name); +/* Macros for creating things quickly. */ +#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) +#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) +#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) +#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b)) +#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) +#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) +#define cJSON_AddRawToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateRaw(s)) /* When assigning an integer value, it needs to be propagated to valuedouble too. */ #define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) /* helper for the cJSON_SetNumberValue macro */ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); #define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) -/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */ -CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring); -/* Macro for iterating over an array or object */ +/* Macro for iterating over an array */ #define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next) /* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */ @@ -27,7 +27,6 @@ #include <stdio.h> #include <string.h> -#include <strings.h> #include <stdlib.h> #include <inttypes.h> @@ -43,10 +42,10 @@ const char * iptos2str(int iptos); * Definitions for IP type of service (ip_tos) */ -#ifdef HAVE_NETINET_IN_SYSTM_H +#if HAVE_NETINET_IN_SYSTM_H #include <netinet/in_systm.h> #endif -#ifdef HAVE_NETINET_IP_H +#if HAVE_NETINET_IP_H #include <netinet/ip.h> #endif diff --git a/src/iperf.h b/src/iperf.h index 5b1da46..6ce77f5 100644..100755 --- a/src/iperf.h +++ b/src/iperf.h @@ -1,5 +1,5 @@ /* - * iperf, Copyright (c) 2014-2020, The Regents of the University of + * iperf, Copyright (c) 2014-2019, 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. @@ -68,9 +68,7 @@ #include <openssl/evp.h> #endif // HAVE_SSL -#if !defined(__IPERF_API_H) typedef uint64_t iperf_size_t; -#endif // __IPERF_API_H struct iperf_interval_results { @@ -137,10 +135,7 @@ 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 avaraging total data rate */ - int bitrate_limit_stats_per_interval; /* calculated number of stats periods for averaging total data rate */ + uint64_t rate; /* target data rate for application pacing*/ uint64_t fqrate; /* target data rate for FQ pacing*/ int pacing_timer; /* pacing timer in microseconds */ int burst; /* packets per burst */ @@ -303,8 +298,6 @@ struct iperf_test 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 */ @@ -335,11 +328,6 @@ struct iperf_test iperf_size_t bytes_received; 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 insrted into the cyclic array */ - int bitrate_limit_exceeded; /* Set by callback routine when average data rate exceeded the server's bitrate limit */ - char cookie[COOKIE_SIZE]; // struct iperf_stream *streams; /* pointer to list of struct stream */ SLIST_HEAD(slisthead, iperf_stream) streams; @@ -397,8 +385,6 @@ struct iperf_test #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 */ #endif /* !__IPERF_H */ diff --git a/src/iperf3.1 b/src/iperf3.1 index 97d66ed..8b08fcb 100644 --- a/src/iperf3.1 +++ b/src/iperf3.1 @@ -1,4 +1,4 @@ -.TH IPERF3 1 "July 2020" ESnet "User Manuals" +.TH IPERF3 1 "June 2018" ESnet "User Manuals" .SH NAME iperf3 \- perform network throughput tests .SH SYNOPSIS @@ -153,14 +153,6 @@ send output to a log file. force flushing output at every interval. Used to avoid buffering when sending output to pipe. .TP -.BR --timestamps " [\fIformat\fR]" -prepend a timestamp at the start of each output line. -By default, timestamps have the format emitted by -.BR ctime ( 1 ). -Optionally, a format specification can be passed to customize the -timestamps, see -.BR strftime ( 3 ). -.TP .BR -d ", " --debug " " emit debugging output. Primarily (perhaps exclusively) of use to developers. @@ -185,15 +177,6 @@ write a file with the process ID, most useful when running as a daemon. .BR -1 ", " --one-off handle one client connection, then exit. .TP -.BR --server-bitrate-limit " \fIn\fR[KMGT]" -set a limit on the server side, which will cause a test to abort if -the client specifies a test of more than \fIn\fR bits per second, or -if the average data sent or received by the client (including all data -streams) is greater than \fIn\fR bits per second. The default limit -is zero, which implies no limit. The interval over which to average -the data rate is 5 seconds by default, but can be specified by adding -a '/' and a number to the bitrate specifier. -.TP .BR --rsa-private-key-path " \fIfile\fR" path to the RSA private key (not password-protected) used to decrypt authentication credentials from the client (if built with OpenSSL @@ -226,7 +209,7 @@ connection establishment. Providing a shorter value may speed up detection of a down iperf3 server. .TP -.BR -b ", " --bitrate " \fIn\fR[KMGT]" +.BR -b ", " --bitrate " \fIn\fR[KM]" set target bitrate to \fIn\fR bits/sec (default 1 Mbit/sec for UDP, unlimited for TCP/SCTP). If there are multiple streams (\-P flag), the throughput limit is applied @@ -243,7 +226,7 @@ Compare with the \--fq-rate flag. This option replaces the \--bandwidth flag, which is now deprecated but (at least for now) still accepted. .TP -.BR --pacing-timer " \fIn\fR[KMGT]" +.BR --pacing-timer " \fIn\fR[KMG]" set pacing timer interval in microseconds (default 1000 microseconds, or 1 ms). This controls iperf3's internal pacing timer for the \-b/\--bitrate @@ -253,7 +236,7 @@ Smaller values of the pacing timer parameter smooth out the traffic emitted by iperf3, but potentially at the cost of performance due to more frequent timer processing. .TP -.BR --fq-rate " \fIn\fR[KMGT]" +.BR --fq-rate " \fIn\fR[KM]" Set a rate to be used with fair-queueing based socket-level pacing, in bits per second. This pacing (if specified) will be in addition to any pacing due to @@ -270,13 +253,13 @@ It is equivalent to specifying --fq-rate=0. .BR -t ", " --time " \fIn\fR" time in seconds to transmit for (default 10 secs) .TP -.BR -n ", " --bytes " \fIn\fR[KMGT]" +.BR -n ", " --bytes " \fIn\fR[KM]" number of bytes to transmit (instead of \-t) .TP -.BR -k ", " --blockcount " \fIn\fR[KMGT]" +.BR -k ", " --blockcount " \fIn\fR[KM]" number of blocks (packets) to transmit (instead of \-t or \-n) .TP -.BR -l ", " --length " \fIn\fR[KMGT]" +.BR -l ", " --length " \fIn\fR[KM]" length of buffer to read or write. For TCP tests, the default value is 128KB. In the case of UDP, iperf3 tries to dynamically determine a reasonable @@ -295,11 +278,7 @@ number of parallel client streams to run. Note that iperf3 is single threaded, s reverse the direction of a test, so that the server sends data to the client .TP -.BR --bidir -test in both directions (normal and reverse), with both the client and -server sending and receiving data simultaneously -.TP -.BR -w ", " --window " \fIn\fR[KMGT]" +.BR -w ", " --window " \fIn\fR[KM]" window size / socket buffer size (this gets sent to the server and used on that side too) .TP .BR -M ", " --set-mss " \fIn\fR" diff --git a/src/iperf_api.c b/src/iperf_api.c index 88fed30..e1bbfa5 100644..100755 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -1,5 +1,5 @@ /* - * iperf, Copyright (c) 2014-2020, The Regents of the University of + * iperf, Copyright (c) 2014-2019, 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. @@ -57,17 +57,12 @@ #include <sched.h> #include <setjmp.h> #include <stdarg.h> -#include <math.h> #if defined(HAVE_CPUSET_SETAFFINITY) #include <sys/param.h> #include <sys/cpuset.h> #endif /* HAVE_CPUSET_SETAFFINITY */ -#if defined(__CYGWIN__) || defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) -#define CPU_SETSIZE __CPU_SETSIZE -#endif /* __CYGWIN__, _WIN32, _WIN64, __WINDOWS__ */ - #if defined(HAVE_SETPROCESSAFFINITYMASK) #include <Windows.h> #endif /* HAVE_SETPROCESSAFFINITYMASK */ @@ -77,9 +72,9 @@ #include "iperf_api.h" #include "iperf_udp.h" #include "iperf_tcp.h" -#if defined(HAVE_SCTP_H) +#if defined(HAVE_SCTP) #include "iperf_sctp.h" -#endif /* HAVE_SCTP_H */ +#endif /* HAVE_SCTP */ #include "timer.h" #include "cjson.h" @@ -120,7 +115,7 @@ usage_long(FILE *f) } -void warning(const char *str) +void warning(char *str) { fprintf(stderr, "warning: %s\n", str); } @@ -165,24 +160,6 @@ iperf_get_test_rate(struct iperf_test *ipt) } uint64_t -iperf_get_test_bitrate_limit(struct iperf_test *ipt) -{ - return ipt->settings->bitrate_limit; -} - -double -iperf_get_test_bitrate_limit_interval(struct iperf_test *ipt) -{ - return ipt->settings->bitrate_limit_interval; -} - -int -iperf_get_test_bitrate_limit_stats_per_interval(struct iperf_test *ipt) -{ - return ipt->settings->bitrate_limit_stats_per_interval; -} - -uint64_t iperf_get_test_fqrate(struct iperf_test *ipt) { return ipt->settings->fqrate; @@ -261,18 +238,6 @@ iperf_get_test_num_streams(struct iperf_test *ipt) } int -iperf_get_test_timestamps(struct iperf_test *ipt) -{ - return ipt->timestamps; -} - -const char * -iperf_get_test_timestamp_format(struct iperf_test *ipt) -{ - return ipt->timestamp_format; -} - -int iperf_get_test_repeating_payload(struct iperf_test *ipt) { return ipt->repeating_payload; @@ -375,12 +340,6 @@ iperf_get_test_no_delay(struct iperf_test *ipt) return ipt->no_delay; } -int -iperf_get_test_connect_timeout(struct iperf_test *ipt) -{ - return ipt->settings->connect_timeout; -} - /************** Setter routines for some fields inside iperf_test *************/ void @@ -432,7 +391,7 @@ iperf_set_test_blksize(struct iperf_test *ipt, int blksize) } void -iperf_set_test_logfile(struct iperf_test *ipt, const char *logfile) +iperf_set_test_logfile(struct iperf_test *ipt, char *logfile) { ipt->logfile = strdup(logfile); } @@ -444,24 +403,6 @@ iperf_set_test_rate(struct iperf_test *ipt, uint64_t rate) } void -iperf_set_test_bitrate_limit_maximum(struct iperf_test *ipt, uint64_t total_rate) -{ - ipt->settings->bitrate_limit = total_rate; -} - -void -iperf_set_test_bitrate_limit_interval(struct iperf_test *ipt, uint64_t bitrate_limit_interval) -{ - ipt->settings->bitrate_limit_interval = bitrate_limit_interval; -} - -void -iperf_set_test_bitrate_limit_stats_per_interval(struct iperf_test *ipt, uint64_t bitrate_limit_stats_per_interval) -{ - ipt->settings->bitrate_limit_stats_per_interval = bitrate_limit_stats_per_interval; -} - -void iperf_set_test_fqrate(struct iperf_test *ipt, uint64_t fqrate) { ipt->settings->fqrate = fqrate; @@ -515,18 +456,6 @@ iperf_set_test_repeating_payload(struct iperf_test *ipt, int repeating_payload) ipt->repeating_payload = repeating_payload; } -void -iperf_set_test_timestamps(struct iperf_test *ipt, int timestamps) -{ - ipt->timestamps = timestamps; -} - -void -iperf_set_test_timestamp_format(struct iperf_test *ipt, const char *tf) -{ - ipt->timestamp_format = strdup(tf); -} - static void check_sender_has_retransmits(struct iperf_test *ipt) { @@ -541,9 +470,7 @@ iperf_set_test_role(struct iperf_test *ipt, char role) { ipt->role = role; if (!ipt->reverse) { - if (ipt->bidirectional) - ipt->mode = BIDIRECTIONAL; - else if (role == 'c') + if (role == 'c') ipt->mode = SENDER; else if (role == 's') ipt->mode = RECEIVER; @@ -557,13 +484,13 @@ iperf_set_test_role(struct iperf_test *ipt, char role) } void -iperf_set_test_server_hostname(struct iperf_test *ipt, const char *server_hostname) +iperf_set_test_server_hostname(struct iperf_test *ipt, char *server_hostname) { ipt->server_hostname = strdup(server_hostname); } void -iperf_set_test_template(struct iperf_test *ipt, const char *tmp_template) +iperf_set_test_template(struct iperf_test *ipt, char *tmp_template) { ipt->tmp_template = strdup(tmp_template); } @@ -618,38 +545,26 @@ iperf_set_test_unit_format(struct iperf_test *ipt, char unit_format) #if defined(HAVE_SSL) void -iperf_set_test_client_username(struct iperf_test *ipt, const char *client_username) +iperf_set_test_client_username(struct iperf_test *ipt, char *client_username) { - ipt->settings->client_username = strdup(client_username); + ipt->settings->client_username = client_username; } void -iperf_set_test_client_password(struct iperf_test *ipt, const char *client_password) +iperf_set_test_client_password(struct iperf_test *ipt, char *client_password) { - ipt->settings->client_password = strdup(client_password); + ipt->settings->client_password = client_password; } void -iperf_set_test_client_rsa_pubkey(struct iperf_test *ipt, const char *client_rsa_pubkey_base64) +iperf_set_test_client_rsa_pubkey(struct iperf_test *ipt, char *client_rsa_pubkey_base64) { ipt->settings->client_rsa_pubkey = load_pubkey_from_base64(client_rsa_pubkey_base64); } - -void -iperf_set_test_server_authorized_users(struct iperf_test *ipt, const char *server_authorized_users) -{ - ipt->server_authorized_users = strdup(server_authorized_users); -} - -void -iperf_set_test_server_rsa_privkey(struct iperf_test *ipt, const char *server_rsa_privkey_base64) -{ - ipt->server_rsa_private_key = load_privkey_from_base64(server_rsa_privkey_base64); -} #endif // HAVE_SSL void -iperf_set_test_bind_address(struct iperf_test *ipt, const char *bnd_address) +iperf_set_test_bind_address(struct iperf_test *ipt, char *bnd_address) { ipt->bind_address = strdup(bnd_address); } @@ -673,9 +588,9 @@ iperf_set_test_tos(struct iperf_test *ipt, int tos) } void -iperf_set_test_extra_data(struct iperf_test *ipt, const char *dat) +iperf_set_test_extra_data(struct iperf_test *ipt, char *dat) { - ipt->extra_data = strdup(dat); + ipt->extra_data = dat; } void @@ -694,13 +609,6 @@ iperf_set_test_no_delay(struct iperf_test* ipt, int no_delay) ipt->no_delay = no_delay; } -void -iperf_set_test_connect_timeout(struct iperf_test* ipt, int ct) -{ - ipt->settings->connect_timeout = ct; -} - - /********************** Get/set test protocol structure ***********************/ struct protocol * @@ -847,7 +755,7 @@ iperf_on_connect(struct iperf_test *test) } } if (test->settings->rate) - iperf_printf(test, " Target Bitrate: %"PRIu64"\n", test->settings->rate); + iperf_printf(test, " Target Bitrate: %llu\n", test->settings->rate); } } @@ -877,7 +785,6 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) {"udp", no_argument, NULL, 'u'}, {"bitrate", required_argument, NULL, 'b'}, {"bandwidth", required_argument, NULL, 'b'}, - {"server-bitrate-limit", required_argument, NULL, OPT_SERVER_BITRATE_LIMIT}, {"time", required_argument, NULL, 't'}, {"bytes", required_argument, NULL, 'n'}, {"blockcount", required_argument, NULL, 'k'}, @@ -902,7 +809,6 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) {"omit", required_argument, NULL, 'O'}, {"file", required_argument, NULL, 'F'}, {"repeating-payload", no_argument, NULL, OPT_REPEATING_PAYLOAD}, - {"timestamps", optional_argument, NULL, OPT_TIMESTAMPS}, #if defined(HAVE_CPU_AFFINITY) {"affinity", required_argument, NULL, 'A'}, #endif /* HAVE_CPU_AFFINITY */ @@ -911,7 +817,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) {"congestion", required_argument, NULL, 'C'}, {"linux-congestion", required_argument, NULL, 'C'}, #endif /* HAVE_TCP_CONGESTION */ -#if defined(HAVE_SCTP_H) +#if defined(HAVE_SCTP) {"sctp", no_argument, NULL, OPT_SCTP}, {"nstreams", required_argument, NULL, OPT_NUMSTREAMS}, {"xbind", required_argument, NULL, 'X'}, @@ -1031,14 +937,14 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) client_flag = 1; break; case OPT_SCTP: -#if defined(HAVE_SCTP_H) +#if defined(HAVE_SCTP) set_protocol(test, Psctp); client_flag = 1; break; -#else /* HAVE_SCTP_H */ +#else /* HAVE_SCTP */ i_errno = IEUNIMP; return -1; -#endif /* HAVE_SCTP_H */ +#endif /* HAVE_SCTP */ case OPT_NUMSTREAMS: #if defined(linux) || defined(__FreeBSD__) @@ -1064,21 +970,6 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) rate_flag = 1; client_flag = 1; break; - case OPT_SERVER_BITRATE_LIMIT: - slash = strchr(optarg, '/'); - if (slash) { - *slash = '\0'; - ++slash; - test->settings->bitrate_limit_interval = atof(slash); - if (test->settings->bitrate_limit_interval != 0 && /* Using same Max/Min limits as for Stats Interval */ - (test->settings->bitrate_limit_interval < MIN_INTERVAL || test->settings->bitrate_limit_interval > MAX_INTERVAL) ) { - i_errno = IETOTALINTERVAL; - return -1; - } - } - test->settings->bitrate_limit = unit_atof_rate(optarg); - server_flag = 1; - break; case 't': test->duration = atoi(optarg); if (test->duration > MAX_TIME) { @@ -1227,15 +1118,6 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) test->repeating_payload = 1; client_flag = 1; break; - case OPT_TIMESTAMPS: - iperf_set_test_timestamps(test, 1); - if (optarg) { - iperf_set_test_timestamp_format(test, optarg); - } - else { - iperf_set_test_timestamp_format(test, TIMESTAMP_FORMAT); - } - break; case 'O': test->omit = atoi(optarg); if (test->omit < 0 || test->omit > 60) { @@ -1379,9 +1261,14 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) if ((client_password = getenv("IPERF3_PASSWORD")) != NULL) client_password = strdup(client_password); else if (iperf_getpass(&client_password, &s, stdin) < 0){ - i_errno = IESETCLIENTAUTH; return -1; } + + if (strlen(client_username) > 20 || strlen(client_password) > 20){ + i_errno = IESETCLIENTAUTH; + return -1; + } + if (test_load_pubkey_from_file(client_rsa_public_key) < 0){ i_errno = IESETCLIENTAUTH; return -1; @@ -1462,13 +1349,6 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) return -1; } - /* Set Total-rate average interval to multiplicity of State interval */ - if (test->settings->bitrate_limit_interval != 0) { - test->settings->bitrate_limit_stats_per_interval = - (test->settings->bitrate_limit_interval <= test->stats_interval ? - 1 : round(test->settings->bitrate_limit_interval/test->stats_interval) ); - } - /* Show warning if JSON output is used with explicit report format */ if ((test->json_output) && (test->settings->unit_format != 'a')) { warning("Report format (-f) flag ignored with JSON output (-J)"); @@ -1517,7 +1397,7 @@ iperf_check_throttle(struct iperf_stream *sp, struct iperf_time *nowP) double seconds; uint64_t bits_per_second; - if (sp->test->done || sp->test->settings->rate == 0 || sp->test->settings->burst != 0) + if (sp->test->done) return; iperf_time_diff(&sp->result->start_time_fixed, nowP, &temp_time); seconds = iperf_time_in_secs(&temp_time); @@ -1531,45 +1411,6 @@ iperf_check_throttle(struct iperf_stream *sp, struct iperf_time *nowP) } } -/* Verify that average traffic is not greater than the specifid limit */ -void -iperf_check_total_rate(struct iperf_test *test, iperf_size_t last_interval_bytes_transferred) -{ - double seconds; - uint64_t bits_per_second; - iperf_size_t total_bytes; - int i; - - if (test->done || test->settings->bitrate_limit == 0) // Continue only if check should be done - return; - - /* Add last inetrval's transffered bytes to the array */ - if (++test->bitrate_limit_last_interval_index >= test->settings->bitrate_limit_stats_per_interval) - test->bitrate_limit_last_interval_index = 0; - test->bitrate_limit_intervals_traffic_bytes[test->bitrate_limit_last_interval_index] = last_interval_bytes_transferred; - - /* Ensure that enough stats periods passed to allow averaging throughput */ - test->bitrate_limit_stats_count += 1; - if (test->bitrate_limit_stats_count < test->settings->bitrate_limit_stats_per_interval) - return; - - /* Calculating total bytes traffic to be averaged */ - for (total_bytes = 0, i = 0; i < test->settings->bitrate_limit_stats_per_interval; i++) { - total_bytes += test->bitrate_limit_intervals_traffic_bytes[i]; - } - - seconds = test->stats_interval * test->settings->bitrate_limit_stats_per_interval; - bits_per_second = total_bytes * 8 / seconds; - if (test->debug) { - iperf_printf(test,"Interval %" PRIu64 " - throughput %" PRIu64 " bps (limit %" PRIu64 ")\n", test->bitrate_limit_stats_count, bits_per_second, test->settings->bitrate_limit); - } - - if (bits_per_second > test->settings->bitrate_limit) { - iperf_err(test, "Total throughput of %" PRIu64 " bps exceeded %" PRIu64 " bps limit", bits_per_second, test->settings->bitrate_limit); - test->bitrate_limit_exceeded = 1; - } -} - int iperf_send(struct iperf_test *test, fd_set *write_setP) { @@ -1601,7 +1442,8 @@ iperf_send(struct iperf_test *test, fd_set *write_setP) streams_active = 1; test->bytes_sent += r; ++test->blocks_sent; - iperf_check_throttle(sp, &now); + if (test->settings->rate != 0 && test->settings->burst == 0) + iperf_check_throttle(sp, &now); if (multisend > 1 && test->settings->bytes != 0 && test->bytes_sent >= test->settings->bytes) break; if (multisend > 1 && test->settings->blocks != 0 && test->blocks_sent >= test->settings->blocks) @@ -1614,8 +1456,7 @@ iperf_send(struct iperf_test *test, fd_set *write_setP) if (test->settings->burst != 0) { iperf_time_now(&now); SLIST_FOREACH(sp, &test->streams, streams) - if (sp->sender) - iperf_check_throttle(sp, &now); + iperf_check_throttle(sp, &now); } if (write_setP != NULL) SLIST_FOREACH(sp, &test->streams, streams) @@ -1697,7 +1538,7 @@ iperf_create_send_timers(struct iperf_test * test) } SLIST_FOREACH(sp, &test->streams, streams) { sp->green_light = 1; - if (test->settings->rate != 0 && sp->sender) { + if (test->settings->rate != 0) { cd.p = sp; sp->send_timer = tmr_create(NULL, send_timer_proc, cd, test->settings->pacing_timer, 1); if (sp->send_timer == NULL) { @@ -1718,18 +1559,15 @@ int test_is_authorized(struct iperf_test *test){ if (test->settings->authtoken){ char *username = NULL, *password = NULL; time_t ts; - int rc = decode_auth_setting(test->debug, test->settings->authtoken, test->server_rsa_private_key, &username, &password, &ts); - if (rc) { - return -1; - } + decode_auth_setting(test->debug, test->settings->authtoken, test->server_rsa_private_key, &username, &password, &ts); int ret = check_authentication(username, password, ts, test->server_authorized_users); if (ret == 0){ - iperf_printf(test, report_authentication_succeeded, username, ts); + iperf_printf(test, report_authetication_successed, username, ts); free(username); free(password); return 0; } else { - iperf_printf(test, report_authentication_failed, username, ts); + iperf_printf(test, report_authetication_failed, username, ts); free(username); free(password); return -1; @@ -1789,7 +1627,6 @@ iperf_exchange_parameters(struct iperf_test *test) } return -1; } - FD_SET(s, &test->read_set); test->max_fd = (s > test->max_fd) ? s : test->max_fd; test->prot_listener = s; @@ -1893,25 +1730,15 @@ send_parameters(struct iperf_test *test) if (test->repeating_payload) cJSON_AddNumberToObject(j, "repeating_payload", test->repeating_payload); #if defined(HAVE_SSL) - /* Send authentication parameters */ - if (test->settings->client_username && test->settings->client_password && test->settings->client_rsa_pubkey){ - int rc = encode_auth_setting(test->settings->client_username, test->settings->client_password, test->settings->client_rsa_pubkey, &test->settings->authtoken); - - if (rc) { - cJSON_Delete(j); - i_errno = IESENDPARAMS; - return -1; - } - - cJSON_AddStringToObject(j, "authtoken", test->settings->authtoken); - } + if (test->settings->client_username && test->settings->client_password && test->settings->client_rsa_pubkey){ + encode_auth_setting(test->settings->client_username, test->settings->client_password, test->settings->client_rsa_pubkey, &test->settings->authtoken); + cJSON_AddStringToObject(j, "authtoken", test->settings->authtoken); + } #endif // HAVE_SSL cJSON_AddStringToObject(j, "client_version", IPERF_VERSION); if (test->debug) { - char *str = cJSON_Print(j); - printf("send_parameters:\n%s\n", str); - cJSON_free(str); + printf("send_parameters:\n%s\n", cJSON_Print(j)); } if (JSON_write(test->ctrl_sck, j) < 0) { @@ -1941,7 +1768,7 @@ get_parameters(struct iperf_test *test) char *str; str = cJSON_Print(j); printf("get_parameters:\n%s\n", str ); - cJSON_free(str); + free(str); } if ((j_p = cJSON_GetObjectItem(j, "tcp")) != NULL) @@ -2006,8 +1833,8 @@ get_parameters(struct iperf_test *test) #endif //HAVE_SSL if (test->mode && test->protocol->id == Ptcp && has_tcpinfo_retransmits()) test->sender_has_retransmits = 1; - if (test->settings->rate) - cJSON_AddNumberToObject(test->json_start, "target_bitrate", test->settings->rate); + if (test->settings->rate) + cJSON_AddNumberToObject(test->json_start, "target_bitrate", test->settings->rate); cJSON_Delete(j); } return r; @@ -2108,7 +1935,7 @@ send_results(struct iperf_test *test) if (r == 0 && test->debug) { char *str = cJSON_Print(j); printf("send_results\n%s\n", str); - cJSON_free(str); + free(str); } if (r == 0 && JSON_write(test->ctrl_sck, j) < 0) { i_errno = IESENDRESULTS; @@ -2166,7 +1993,7 @@ get_results(struct iperf_test *test) if (test->debug) { char *str = cJSON_Print(j); printf("get_results\n%s\n", str); - cJSON_free(str); + free(str); } test->remote_cpu_util[0] = j_cpu_util_total->valuedouble; @@ -2303,7 +2130,7 @@ JSON_write(int fd, cJSON *json) if (Nwrite(fd, str, hsize, Ptcp) < 0) r = -1; } - cJSON_free(str); + free(str); } return r; } @@ -2425,14 +2252,6 @@ iperf_new_test() } memset(test->settings, 0, sizeof(struct iperf_settings)); - test->bitrate_limit_intervals_traffic_bytes = (iperf_size_t *) malloc(sizeof(iperf_size_t) * MAX_INTERVAL); - if (!test->bitrate_limit_intervals_traffic_bytes) { - free(test); - i_errno = IENEWTEST; - return NULL; - } - memset(test->bitrate_limit_intervals_traffic_bytes, 0, sizeof(sizeof(iperf_size_t) * MAX_INTERVAL)); - /* By default all output goes to stdout */ test->outfile = stdout; @@ -2466,9 +2285,9 @@ int iperf_defaults(struct iperf_test *testp) { struct protocol *tcp, *udp; -#if defined(HAVE_SCTP_H) +#if defined(HAVE_SCTP) struct protocol *sctp; -#endif /* HAVE_SCTP_H */ +#endif /* HAVE_SCTP */ testp->omit = OMIT; testp->duration = DURATION; @@ -2500,9 +2319,6 @@ iperf_defaults(struct iperf_test *testp) testp->settings->socket_bufsize = 0; /* use autotuning */ testp->settings->blksize = DEFAULT_TCP_BLKSIZE; testp->settings->rate = 0; - testp->settings->bitrate_limit = 0; - testp->settings->bitrate_limit_interval = 5; - testp->settings->bitrate_limit_stats_per_interval = 0; testp->settings->fqrate = 0; testp->settings->pacing_timer = 1000; testp->settings->burst = 0; @@ -2550,7 +2366,7 @@ iperf_defaults(struct iperf_test *testp) set_protocol(testp, Ptcp); -#if defined(HAVE_SCTP_H) +#if defined(HAVE_SCTP) sctp = protocol_new(); if (!sctp) { protocol_free(tcp); @@ -2568,7 +2384,7 @@ iperf_defaults(struct iperf_test *testp) sctp->init = iperf_sctp_init; SLIST_INSERT_AFTER(udp, sctp, protocols); -#endif /* HAVE_SCTP_H */ +#endif /* HAVE_SCTP */ testp->on_new_stream = iperf_on_new_stream; testp->on_test_start = iperf_on_test_start; @@ -2644,8 +2460,6 @@ iperf_free_test(struct iperf_test *test) free(test->congestion_used); if (test->remote_congestion_used) free(test->remote_congestion_used); - if (test->timestamp_format) - free(test->timestamp_format); if (test->omit_timer != NULL) tmr_cancel(test->omit_timer); if (test->timer != NULL) @@ -2662,15 +2476,6 @@ iperf_free_test(struct iperf_test *test) free(prot); } - if (test->logfile) { - free(test->logfile); - test->logfile = NULL; - if (test->outfile) { - fclose(test->outfile); - test->outfile = NULL; - } - } - if (test->server_output_text) { free(test->server_output_text); test->server_output_text = NULL; @@ -2702,10 +2507,6 @@ iperf_free_test(struct iperf_test *test) } } - /* Free interval's traffic array for avrage rate calculations */ - if (test->bitrate_limit_intervals_traffic_bytes != NULL) - free(test->bitrate_limit_intervals_traffic_bytes); - /* XXX: Why are we setting these values to NULL? */ // test->streams = NULL; test->stats_callback = NULL; @@ -2718,7 +2519,6 @@ void iperf_reset_test(struct iperf_test *test) { struct iperf_stream *sp; - int i; /* Free streams */ while (!SLIST_EMPTY(&test->streams)) { @@ -2772,13 +2572,6 @@ iperf_reset_test(struct iperf_test *test) test->other_side_has_retransmits = 0; - test->bitrate_limit_stats_count = 0; - test->bitrate_limit_last_interval_index = 0; - test->bitrate_limit_exceeded = 0; - - for (i = 0; i < MAX_INTERVAL; i++) - test->bitrate_limit_intervals_traffic_bytes[i] = 0; - test->reverse = 0; test->bidirectional = 0; test->no_delay = 0; @@ -2882,16 +2675,12 @@ iperf_stats_callback(struct iperf_test *test) struct iperf_stream_result *rp = NULL; struct iperf_interval_results *irp, temp; struct iperf_time temp_time; - iperf_size_t total_interval_bytes_transferred = 0; temp.omitted = test->omitting; SLIST_FOREACH(sp, &test->streams, streams) { rp = sp->result; temp.bytes_transferred = sp->sender ? rp->bytes_sent_this_interval : rp->bytes_received_this_interval; - - // Total bytes transferred this interval - total_interval_bytes_transferred += rp->bytes_sent_this_interval + rp->bytes_received_this_interval; - + irp = TAILQ_LAST(&rp->interval_results, irlisthead); /* result->end_time contains timestamp of previous interval */ if ( irp != NULL ) /* not the 1st interval */ @@ -2950,11 +2739,6 @@ iperf_stats_callback(struct iperf_test *test) add_to_interval_list(rp, &temp); rp->bytes_sent_this_interval = rp->bytes_received_this_interval = 0; } - - /* Verify that total server's throughput is not above specified limit */ - if (test->role == 's') { - iperf_check_total_rate(test, total_interval_bytes_transferred); - } } /** @@ -3633,9 +3417,7 @@ iperf_print_results(struct iperf_test *test) /* Print server output if we're on the client and it was requested/provided */ if (test->role == 'c' && iperf_get_test_get_server_output(test) && !test->json_output) { if (test->json_server_output) { - char *str = cJSON_Print(test->json_server_output); - iperf_printf(test, "\nServer JSON output:\n%s\n", str); - cJSON_free(str); + iperf_printf(test, "\nServer JSON output:\n%s\n", cJSON_Print(test->json_server_output)); cJSON_Delete(test->json_server_output); test->json_server_output = NULL; } @@ -4067,15 +3849,9 @@ diskfile_recv(struct iperf_stream *sp) void iperf_catch_sigend(void (*handler)(int)) { -#ifdef SIGINT signal(SIGINT, handler); -#endif -#ifdef SIGTERM signal(SIGTERM, handler); -#endif -#ifdef SIGHUP signal(SIGHUP, handler); -#endif } /** @@ -4219,8 +3995,6 @@ iperf_json_finish(struct iperf_test *test) return -1; fprintf(test->outfile, "%s\n", test->json_output_string); iflush(test); - cJSON_free(test->json_output_string); - test->json_output_string = NULL; cJSON_Delete(test->json_top); test->json_top = test->json_start = test->json_connected = test->json_intervals = test->json_server_output = test->json_end = NULL; return 0; @@ -4314,24 +4088,11 @@ iperf_clearaffinity(struct iperf_test *test) #endif /* neither HAVE_SCHED_SETAFFINITY nor HAVE_CPUSET_SETAFFINITY nor HAVE_SETPROCESSAFFINITYMASK */ } -char iperf_timestr[100]; - int iperf_printf(struct iperf_test *test, const char* format, ...) { va_list argp; int r = -1; - time_t now; - struct tm *ltm = NULL; - char *ct = NULL; - - /* Timestamp if requested */ - if (iperf_get_test_timestamps(test)) { - time(&now); - ltm = localtime(&now); - strftime(iperf_timestr, sizeof(iperf_timestr), iperf_get_test_timestamp_format(test), ltm); - ct = iperf_timestr; - } /* * There are roughly two use cases here. If we're the client, @@ -4346,9 +4107,6 @@ iperf_printf(struct iperf_test *test, const char* format, ...) * to be buffered up anyway. */ if (test->role == 'c') { - if (ct) { - fprintf(test->outfile, "%s", ct); - } if (test->title) fprintf(test->outfile, "%s: ", test->title); va_start(argp, format); @@ -4357,12 +4115,8 @@ iperf_printf(struct iperf_test *test, const char* format, ...) } else if (test->role == 's') { char linebuffer[1024]; - int i = 0; - if (ct) { - i = sprintf(linebuffer, "%s", ct); - } va_start(argp, format); - r = vsnprintf(linebuffer + i, sizeof(linebuffer), format, argp); + r = vsnprintf(linebuffer, sizeof(linebuffer), format, argp); va_end(argp); fprintf(test->outfile, "%s", linebuffer); diff --git a/src/iperf_api.h b/src/iperf_api.h index a51b773..f9f964e 100644..100755 --- a/src/iperf_api.h +++ b/src/iperf_api.h @@ -1,5 +1,5 @@ /* - * iperf, Copyright (c) 2014-2020, The Regents of the University of + * iperf, Copyright (c) 2014-2019, 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. @@ -45,10 +45,6 @@ struct iperf_interval_results; struct iperf_stream; struct iperf_time; -#if !defined(__IPERF_H) -typedef uint64_t iperf_size_t; -#endif // __IPERF_H - /* default settings */ #define Ptcp SOCK_STREAM #define Pudp SOCK_DGRAM @@ -77,8 +73,6 @@ typedef uint64_t iperf_size_t; #define OPT_REPEATING_PAYLOAD 18 #define OPT_EXTRA_DATA 19 #define OPT_BIDIRECTIONAL 20 -#define OPT_SERVER_BITRATE_LIMIT 21 -#define OPT_TIMESTAMPS 22 /* states */ #define TEST_START 1 @@ -119,8 +113,6 @@ double iperf_get_test_reporter_interval( struct iperf_test* ipt ); double iperf_get_test_stats_interval( struct iperf_test* ipt ); int iperf_get_test_num_streams( struct iperf_test* ipt ); int iperf_get_test_repeating_payload( struct iperf_test* ipt ); -int iperf_get_test_timestamps( struct iperf_test* ipt ); -const char* iperf_get_test_timestamp_format( struct iperf_test* ipt ); int iperf_get_test_server_port( struct iperf_test* ipt ); char* iperf_get_test_server_hostname( struct iperf_test* ipt ); char* iperf_get_test_template( struct iperf_test* ipt ); @@ -136,7 +128,6 @@ int iperf_get_test_tos( struct iperf_test* ipt ); char* iperf_get_extra_data( struct iperf_test* ipt ); char* iperf_get_iperf_version(void); int iperf_get_test_no_delay( struct iperf_test* ipt ); -int iperf_get_test_connect_timeout( struct iperf_test* ipt ); /* Setter routines for some fields inside iperf_test. */ void iperf_set_verbose( struct iperf_test* ipt, int verbose ); @@ -147,7 +138,7 @@ void iperf_set_test_reporter_interval( struct iperf_test* ipt, double reporter_i void iperf_set_test_stats_interval( struct iperf_test* ipt, double stats_interval ); void iperf_set_test_state( struct iperf_test* ipt, signed char state ); void iperf_set_test_blksize( struct iperf_test* ipt, int blksize ); -void iperf_set_test_logfile( struct iperf_test* ipt, const char *logfile ); +void iperf_set_test_logfile( struct iperf_test* ipt, char *logfile ); void iperf_set_test_rate( struct iperf_test* ipt, uint64_t rate ); void iperf_set_test_pacing_timer( struct iperf_test* ipt, int pacing_timer ); void iperf_set_test_bytes( struct iperf_test* ipt, uint64_t bytes ); @@ -157,34 +148,28 @@ void iperf_set_test_server_port( struct iperf_test* ipt, int server_port ); void iperf_set_test_socket_bufsize( struct iperf_test* ipt, int socket_bufsize ); void iperf_set_test_num_streams( struct iperf_test* ipt, int num_streams ); void iperf_set_test_repeating_payload( struct iperf_test* ipt, int repeating_payload ); -void iperf_set_test_timestamps( struct iperf_test* ipt, int timestamps ); -void iperf_set_test_timestamp_format( struct iperf_test*, const char *tf ); void iperf_set_test_role( struct iperf_test* ipt, char role ); -void iperf_set_test_server_hostname( struct iperf_test* ipt, const char* server_hostname ); -void iperf_set_test_template( struct iperf_test *ipt, const char *tmp_template ); +void iperf_set_test_server_hostname( struct iperf_test* ipt, char* server_hostname ); +void iperf_set_test_template( struct iperf_test *ipt, char *tmp_template ); void iperf_set_test_reverse( struct iperf_test* ipt, int reverse ); void iperf_set_test_json_output( struct iperf_test* ipt, int json_output ); int iperf_has_zerocopy( void ); void iperf_set_test_zerocopy( struct iperf_test* ipt, int zerocopy ); void iperf_set_test_get_server_output( struct iperf_test* ipt, int get_server_output ); -void iperf_set_test_bind_address( struct iperf_test* ipt, const char *bind_address ); +void iperf_set_test_bind_address( struct iperf_test* ipt, char *bind_address ); void iperf_set_test_udp_counters_64bit( struct iperf_test* ipt, int udp_counters_64bit ); void iperf_set_test_one_off( struct iperf_test* ipt, int one_off ); void iperf_set_test_tos( struct iperf_test* ipt, int tos ); -void iperf_set_test_extra_data( struct iperf_test* ipt, const char *dat ); +void iperf_set_extra_data( struct iperf_test* ipt, char *dat); void iperf_set_test_bidirectional( struct iperf_test* ipt, int bidirectional); void iperf_set_test_no_delay( struct iperf_test* ipt, int no_delay); #if defined(HAVE_SSL) -void iperf_set_test_client_username(struct iperf_test *ipt, const char *client_username); -void iperf_set_test_client_password(struct iperf_test *ipt, const char *client_password); -void iperf_set_test_client_rsa_pubkey(struct iperf_test *ipt, const char *client_rsa_pubkey_base64); -void iperf_set_test_server_authorized_users(struct iperf_test *ipt, const char *server_authorized_users); -void iperf_set_test_server_rsa_privkey(struct iperf_test *ipt, const char *server_rsa_privkey_base64); +void iperf_set_test_client_username(struct iperf_test *ipt, char *client_username); +void iperf_set_test_client_password(struct iperf_test *ipt, char *client_password); +void iperf_set_test_client_rsa_pubkey(struct iperf_test *ipt, char *client_rsa_pubkey_base64); #endif // HAVE_SSL -void iperf_set_test_connect_timeout(struct iperf_test *ipt, int ct); - /** * exchange_parameters - handles the param_Exchange part for client * @@ -278,7 +263,7 @@ void iperf_catch_sigend(void (*handler)(int)); void iperf_got_sigend(struct iperf_test *test) __attribute__ ((noreturn)); void usage(void); void usage_long(FILE * f); -void warning(const char *); +void warning(char *); int iperf_exchange_results(struct iperf_test *); int iperf_init_test(struct iperf_test *); int iperf_create_send_timers(struct iperf_test *); @@ -311,7 +296,6 @@ int iperf_accept(struct iperf_test *); int iperf_handle_message_server(struct iperf_test *); int iperf_create_pidfile(struct iperf_test *); int iperf_delete_pidfile(struct iperf_test *); -void iperf_check_total_rate(struct iperf_test *, iperf_size_t); /* JSON output routines. */ int iperf_json_start(struct iperf_test *); @@ -359,8 +343,6 @@ enum { IEBADFORMAT = 24, // Bad format argument to -f IEREVERSEBIDIR = 25, // Iperf cannot be both reverse and bidirectional IEBADPORT = 26, // Bad port number - IETOTALRATE = 27, // Total required bandwidth is larger than server's limit - IETOTALINTERVAL = 28, // Invalid time interval for calculating average data rate /* Test errors */ IENEWTEST = 100, // Unable to create a new test (check perror) IEINITTEST = 101, // Test initialization failed (check perror) diff --git a/src/iperf_auth.c b/src/iperf_auth.c index eb4610f..9965e19 100644 --- a/src/iperf_auth.c +++ b/src/iperf_auth.c @@ -1,5 +1,5 @@ /* - * iperf, Copyright (c) 2014-2020, The Regents of the University of + * iperf, Copyright (c) 2014-2018, 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. @@ -43,9 +43,6 @@ #include <openssl/pem.h> #include <openssl/sha.h> #include <openssl/buffer.h> -#include <openssl/err.h> - -const char *auth_text_format = "user: %s\npwd: %s\nts: %ld"; void sha256(const char *string, char outputBuffer[65]) { @@ -154,6 +151,7 @@ int Base64Decode(const char* b64message, unsigned char** buffer, size_t* length) return (0); //success } + EVP_PKEY *load_pubkey_from_file(const char *file) { BIO *key = NULL; EVP_PKEY *pkey = NULL; @@ -161,7 +159,7 @@ EVP_PKEY *load_pubkey_from_file(const char *file) { if (file) { key = BIO_new_file(file, "r"); pkey = PEM_read_bio_PUBKEY(key, NULL, NULL, NULL); - + BIO_free(key); } return (pkey); @@ -174,9 +172,7 @@ EVP_PKEY *load_pubkey_from_base64(const char *buffer) { BIO* bio = BIO_new(BIO_s_mem()); BIO_write(bio, key, key_len); - free(key); EVP_PKEY *pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); - BIO_free(bio); return (pkey); } @@ -193,18 +189,6 @@ EVP_PKEY *load_privkey_from_file(const char *file) { return (pkey); } -EVP_PKEY *load_privkey_from_base64(const char *buffer) { - unsigned char *key = NULL; - size_t key_len; - Base64Decode(buffer, &key, &key_len); - - BIO* bio = BIO_new(BIO_s_mem()); - BIO_write(bio, key, key_len); - free(key); - EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); - BIO_free(bio); - return (pkey); -} int test_load_pubkey_from_file(const char *file){ EVP_PKEY *key = load_pubkey_from_file(file); @@ -243,11 +227,6 @@ int encrypt_rsa_message(const char *plaintext, EVP_PKEY *public_key, unsigned ch OPENSSL_free(rsa_buffer); BIO_free(bioBuff); - if (encryptedtext_len < 0) { - /* We probably shoudln't be printing stuff like this */ - fprintf(stderr, "%s\n", ERR_error_string(ERR_get_error(), NULL)); - } - return encryptedtext_len; } @@ -270,43 +249,24 @@ int decrypt_rsa_message(const unsigned char *encryptedtext, const int encryptedt OPENSSL_free(rsa_buffer); BIO_free(bioBuff); - if (plaintext_len < 0) { - /* We probably shoudln't be printing stuff like this */ - fprintf(stderr, "%s\n", ERR_error_string(ERR_get_error(), NULL)); - } - return plaintext_len; } int encode_auth_setting(const char *username, const char *password, EVP_PKEY *public_key, char **authtoken){ time_t t = time(NULL); time_t utc_seconds = mktime(localtime(&t)); - - /* - * Compute a pessimistic/conservative estimate of storage required. - * It's OK to allocate too much storage but too little is bad. - */ - const int text_len = strlen(auth_text_format) + strlen(username) + strlen(password) + 32; - char *text = (char *) calloc(text_len, sizeof(char)); - if (text == NULL) { - return -1; - } - snprintf(text, text_len, auth_text_format, username, password, utc_seconds); - + char text[150]; + sprintf (text, "user: %s\npwd: %s\nts: %ld", username, password, utc_seconds); unsigned char *encrypted = NULL; int encrypted_len; encrypted_len = encrypt_rsa_message(text, public_key, &encrypted); - free(text); - if (encrypted_len < 0) { - return -1; - } Base64Encode(encrypted, encrypted_len, authtoken); OPENSSL_free(encrypted); return (0); //success } -int decode_auth_setting(int enable_debug, const char *authtoken, EVP_PKEY *private_key, char **username, char **password, time_t *ts){ +int decode_auth_setting(int enable_debug, char *authtoken, EVP_PKEY *private_key, char **username, char **password, time_t *ts){ unsigned char *encrypted_b64 = NULL; size_t encrypted_len_b64; Base64Decode(authtoken, &encrypted_b64, &encrypted_len_b64); @@ -314,36 +274,19 @@ int decode_auth_setting(int enable_debug, const char *authtoken, EVP_PKEY *priva unsigned char *plaintext = NULL; int plaintext_len; plaintext_len = decrypt_rsa_message(encrypted_b64, encrypted_len_b64, private_key, &plaintext); - free(encrypted_b64); - if (plaintext_len < 0) { - return -1; - } plaintext[plaintext_len] = '\0'; + free(encrypted_b64); - char *s_username, *s_password; - s_username = (char *) calloc(plaintext_len, sizeof(char)); - if (s_username == NULL) { - return -1; - } - s_password = (char *) calloc(plaintext_len, sizeof(char)); - if (s_password == NULL) { - free(s_username); - return -1; - } - - int rc = sscanf((char *) plaintext, auth_text_format, s_username, s_password, ts); - if (rc != 3) { - free(s_password); - free(s_username); - return -1; - } - + char s_username[20], s_password[20]; + sscanf ((char *)plaintext,"user: %s\npwd: %s\nts: %ld", s_username, s_password, ts); if (enable_debug) { printf("Auth Token Content:\n%s\n", plaintext); printf("Auth Token Credentials:\n--> %s %s\n", s_username, s_password); } - *username = s_username; - *password = s_password; + *username = (char *) calloc(21, sizeof(char)); + *password = (char *) calloc(21, sizeof(char)); + strncpy(*username, s_username, 20); + strncpy(*password, s_password, 20); OPENSSL_free(plaintext); return (0); } diff --git a/src/iperf_auth.h b/src/iperf_auth.h index 0dd6c4c..0c6fb0f 100644 --- a/src/iperf_auth.h +++ b/src/iperf_auth.h @@ -34,7 +34,6 @@ int test_load_private_key_from_file(const char *private_keyfile); EVP_PKEY *load_pubkey_from_file(const char *file); EVP_PKEY *load_pubkey_from_base64(const char *buffer); EVP_PKEY *load_privkey_from_file(const char *file); -EVP_PKEY *load_privkey_from_base64(const char *buffer); int encode_auth_setting(const char *username, const char *password, EVP_PKEY *public_key, char **authtoken); int decode_auth_setting(int enable_debug, const char *authtoken, EVP_PKEY *private_key, char **username, char **password, time_t *ts); int check_authentication(const char *username, const char *password, const time_t ts, const char *filename); diff --git a/src/iperf_client_api.c b/src/iperf_client_api.c index d0edf7d..20ea6fd 100644 --- a/src/iperf_client_api.c +++ b/src/iperf_client_api.c @@ -1,5 +1,5 @@ /* - * iperf, Copyright (c) 2014-2020, The Regents of the University of + * iperf, Copyright (c) 2014-2018, 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. @@ -478,7 +478,7 @@ iperf_run_client(struct iperf_test * test) /* Start the client and connect to the server */ if (iperf_connect(test) < 0) - goto cleanup_and_fail; + return -1; /* Begin calculating CPU utilization */ cpu_util(NULL); @@ -492,12 +492,12 @@ iperf_run_client(struct iperf_test * test) result = select(test->max_fd + 1, &read_set, &write_set, NULL, timeout); if (result < 0 && errno != EINTR) { i_errno = IESELECT; - goto cleanup_and_fail; + return -1; } if (result > 0) { if (FD_ISSET(test->ctrl_sck, &read_set)) { if (iperf_handle_message_client(test) < 0) { - goto cleanup_and_fail; + return -1; } FD_CLR(test->ctrl_sck, &read_set); } @@ -521,17 +521,17 @@ iperf_run_client(struct iperf_test * test) if (test->mode == BIDIRECTIONAL) { if (iperf_send(test, &write_set) < 0) - goto cleanup_and_fail; + return -1; if (iperf_recv(test, &read_set) < 0) - goto cleanup_and_fail; + return -1; } else if (test->mode == SENDER) { // Regular mode. Client sends. if (iperf_send(test, &write_set) < 0) - goto cleanup_and_fail; + return -1; } else { // Reverse mode. Client receives. if (iperf_recv(test, &read_set) < 0) - goto cleanup_and_fail; + return -1; } @@ -557,7 +557,7 @@ iperf_run_client(struct iperf_test * test) cpu_util(test->cpu_util); test->stats_callback(test); if (iperf_set_send_state(test, TEST_END) != 0) - goto cleanup_and_fail; + return -1; } } // If we're in reverse mode, continue draining the data @@ -567,7 +567,7 @@ iperf_run_client(struct iperf_test * test) // from the client side. else if (test->mode == RECEIVER && test->state == TEST_END) { if (iperf_recv(test, &read_set) < 0) - goto cleanup_and_fail; + return -1; } } @@ -582,11 +582,4 @@ iperf_run_client(struct iperf_test * test) iflush(test); return 0; - - cleanup_and_fail: - iperf_client_end(test); - if (test->json_output) - iperf_json_finish(test); - iflush(test); - return -1; } diff --git a/src/iperf_config.h.in b/src/iperf_config.h.in index 1a7cbec..e543cbd 100644 --- a/src/iperf_config.h.in +++ b/src/iperf_config.h.in @@ -40,7 +40,7 @@ #undef HAVE_SCHED_SETAFFINITY /* Have SCTP support. */ -#undef HAVE_SCTP_H +#undef HAVE_SCTP /* Define to 1 if you have the `sendfile' function. */ #undef HAVE_SENDFILE diff --git a/src/iperf_error.c b/src/iperf_error.c index cfe4cbd..fd3cccc 100644 --- a/src/iperf_error.c +++ b/src/iperf_error.c @@ -1,5 +1,5 @@ /* - * iperf, Copyright (c) 2014-2020, The Regents of the University of + * iperf, Copyright (c) 2014-2019, 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. @@ -35,25 +35,12 @@ int gerror; -char iperf_timestrerr[100]; - /* Do a printf to stderr. */ void iperf_err(struct iperf_test *test, const char *format, ...) { va_list argp; char str[1000]; - time_t now; - struct tm *ltm = NULL; - char *ct = NULL; - - /* Timestamp if requested */ - if (test != NULL && test->timestamps) { - time(&now); - ltm = localtime(&now); - strftime(iperf_timestrerr, sizeof(iperf_timestrerr), test->timestamp_format, ltm); - ct = iperf_timestrerr; - } va_start(argp, format); vsnprintf(str, sizeof(str), format, argp); @@ -61,15 +48,9 @@ iperf_err(struct iperf_test *test, const char *format, ...) cJSON_AddStringToObject(test->json_top, "error", str); else if (test && test->outfile && test->outfile != stdout) { - if (ct) { - fprintf(test->outfile, "%s", ct); - } fprintf(test->outfile, "iperf3: %s\n", str); } else { - if (ct) { - fprintf(stderr, "%s", ct); - } fprintf(stderr, "iperf3: %s\n", str); } va_end(argp); @@ -81,17 +62,6 @@ iperf_errexit(struct iperf_test *test, const char *format, ...) { va_list argp; char str[1000]; - time_t now; - struct tm *ltm = NULL; - char *ct = NULL; - - /* Timestamp if requested */ - if (test != NULL && test->timestamps) { - time(&now); - ltm = localtime(&now); - strftime(iperf_timestrerr, sizeof(iperf_timestrerr), "%c ", ltm); - ct = iperf_timestrerr; - } va_start(argp, format); vsnprintf(str, sizeof(str), format, argp); @@ -100,15 +70,9 @@ iperf_errexit(struct iperf_test *test, const char *format, ...) iperf_json_finish(test); } else if (test && test->outfile && test->outfile != stdout) { - if (ct) { - fprintf(test->outfile, "%s", ct); - } fprintf(test->outfile, "iperf3: %s\n", str); } else { - if (ct) { - fprintf(stderr, "%s", ct); - } fprintf(stderr, "iperf3: %s\n", str); } va_end(argp); @@ -170,10 +134,10 @@ iperf_strerror(int int_errno) snprintf(errstr, len, "bad TOS value (must be between 0 and 255 inclusive)"); break; case IESETCLIENTAUTH: - snprintf(errstr, len, "you must specify a username, password, and path to a valid RSA public key"); + snprintf(errstr, len, "you must specify username (max 20 chars), password (max 20 chars) and a path to a valid public rsa client to be used"); break; case IESETSERVERAUTH: - snprintf(errstr, len, "you must specify a path to a valid RSA private key and a user credential file"); + snprintf(errstr, len, "you must specify path to a valid private rsa server to be used and a user credential file"); break; case IEBADFORMAT: snprintf(errstr, len, "bad format specifier (valid formats are in the set [kmgtKMGT])"); @@ -421,13 +385,7 @@ iperf_strerror(int int_errno) case IEREVERSEBIDIR: snprintf(errstr, len, "cannot be both reverse and bidirectional"); break; - case IETOTALRATE: - snprintf(errstr, len, "total required bandwidth is larger than server limit"); - break; - default: - snprintf(errstr, len, "int_errno=%d", int_errno); - perr = 1; - break; + } /* Append the result of strerror() or gai_strerror() if appropriate */ diff --git a/src/iperf_locale.c b/src/iperf_locale.c index d5a5354..0d8a7ec 100644 --- a/src/iperf_locale.c +++ b/src/iperf_locale.c @@ -1,5 +1,5 @@ /*--------------------------------------------------------------- - * iperf, Copyright (c) 2014-2020, The Regents of the University of + * iperf, Copyright (c) 2014-2018, 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. @@ -109,9 +109,6 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n" " -J, --json output in JSON format\n" " --logfile f send output to a log file\n" " --forceflush force flushing output at every interval\n" - " --timestamps <format> emit a timestamp at the start of each output line\n" - " (using optional format string as per strftime(3))\n" - " -d, --debug emit debugging output\n" " -v, --version show version information and quit\n" " -h, --help show this message and quit\n" @@ -120,9 +117,6 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n" " -D, --daemon run the server as a daemon\n" " -I, --pidfile file write PID file\n" " -1, --one-off handle one client connection then exit\n" - " --server-bitrate-limit #[KMG][/#] server's total bit rate limit (default 0 = no limit)\n" - " (optional slash and number of secs interval for averaging\n" - " total data rate. Default is 5 seconds)\n" #if defined(HAVE_SSL) " --rsa-private-key-path path to the RSA private key used to decrypt\n" " authentication credentials\n" @@ -131,11 +125,11 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n" #endif //HAVE_SSL "Client specific:\n" " -c, --client <host> run in client mode, connecting to <host>\n" -#if defined(HAVE_SCTP_H) +#if defined(HAVE_SCTP) " --sctp use SCTP rather than TCP\n" " -X, --xbind <name> bind SCTP association to links\n" " --nstreams # number of SCTP streams\n" -#endif /* HAVE_SCTP_H */ +#endif /* HAVE_SCTP */ " -u, --udp use UDP rather than TCP\n" " --connect-timeout # timeout for control connection setup (ms)\n" " -b, --bitrate #[KMG][/#] target bitrate in bits/sec (0 for unlimited)\n" @@ -278,10 +272,10 @@ const char report_time[] = const char report_connecting[] = "Connecting to host %s, port %d\n"; -const char report_authentication_succeeded[] = +const char report_authetication_successed[] = "Authentication successed for user '%s' ts %ld\n"; -const char report_authentication_failed[] = +const char report_authetication_failed[] = "Authentication failed for user '%s' ts %ld\n"; const char report_reverse[] = diff --git a/src/iperf_locale.h b/src/iperf_locale.h index 15bdcdb..ad784a6 100644 --- a/src/iperf_locale.h +++ b/src/iperf_locale.h @@ -1,5 +1,5 @@ /* - * iperf, Copyright (c) 2014-2020, The Regents of the University of + * iperf, Copyright (c) 2014-2018, 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. @@ -54,8 +54,8 @@ extern const char report_reverse[] ; extern const char report_accepted[] ; extern const char report_cookie[] ; extern const char report_connected[] ; -extern const char report_authentication_succeeded[] ; -extern const char report_authentication_failed[] ; +extern const char report_authetication_successed[] ; +extern const char report_authetication_failed[] ; extern const char report_window[] ; extern const char report_autotune[] ; extern const char report_omit_done[] ; diff --git a/src/iperf_sctp.c b/src/iperf_sctp.c index e0c1ec1..06e1e23 100644 --- a/src/iperf_sctp.c +++ b/src/iperf_sctp.c @@ -57,7 +57,7 @@ int iperf_sctp_recv(struct iperf_stream *sp) { -#if defined(HAVE_SCTP_H) +#if defined(HAVE_SCTP) int r; r = Nread(sp->socket, sp->buffer, sp->settings->blksize, Psctp); @@ -78,7 +78,7 @@ iperf_sctp_recv(struct iperf_stream *sp) #else i_errno = IENOSCTP; return -1; -#endif /* HAVE_SCTP_H */ +#endif /* HAVE_SCTP */ } @@ -89,7 +89,7 @@ iperf_sctp_recv(struct iperf_stream *sp) int iperf_sctp_send(struct iperf_stream *sp) { -#if defined(HAVE_SCTP_H) +#if defined(HAVE_SCTP) int r; r = Nwrite(sp->socket, sp->buffer, sp->settings->blksize, Psctp); @@ -103,7 +103,7 @@ iperf_sctp_send(struct iperf_stream *sp) #else i_errno = IENOSCTP; return -1; -#endif /* HAVE_SCTP_H */ +#endif /* HAVE_SCTP */ } @@ -115,7 +115,7 @@ iperf_sctp_send(struct iperf_stream *sp) int iperf_sctp_accept(struct iperf_test * test) { -#if defined(HAVE_SCTP_H) +#if defined(HAVE_SCTP) int s; signed char rbuf = ACCESS_DENIED; char cookie[COOKIE_SIZE]; @@ -131,14 +131,12 @@ iperf_sctp_accept(struct iperf_test * test) if (Nread(s, cookie, COOKIE_SIZE, Psctp) < 0) { i_errno = IERECVCOOKIE; - close(s); return -1; } - if (strncmp(test->cookie, cookie, COOKIE_SIZE) != 0) { + if (strcmp(test->cookie, cookie) != 0) { if (Nwrite(s, (char*) &rbuf, sizeof(rbuf), Psctp) < 0) { i_errno = IESENDMESSAGE; - close(s); return -1; } close(s); @@ -148,7 +146,7 @@ iperf_sctp_accept(struct iperf_test * test) #else i_errno = IENOSCTP; return -1; -#endif /* HAVE_SCTP_H */ +#endif /* HAVE_SCTP */ } @@ -159,7 +157,7 @@ iperf_sctp_accept(struct iperf_test * test) int iperf_sctp_listen(struct iperf_test *test) { -#if defined(HAVE_SCTP_H) +#if defined(HAVE_SCTP) struct addrinfo hints, *res; char portstr[6]; int s, opt, saved_errno; @@ -191,26 +189,6 @@ iperf_sctp_listen(struct iperf_test *test) return -1; } - if ((opt = test->settings->socket_bufsize)) { - int saved_errno; - if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) < 0) { - saved_errno = errno; - close(s); - freeaddrinfo(res); - errno = saved_errno; - i_errno = IESETBUF; - return -1; - } - if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt)) < 0) { - saved_errno = errno; - close(s); - freeaddrinfo(res); - errno = saved_errno; - i_errno = IESETBUF; - return -1; - } - } - #if defined(IPV6_V6ONLY) && !defined(__OpenBSD__) if (res->ai_family == AF_INET6 && (test->settings->domain == AF_UNSPEC || test->settings->domain == AF_INET6)) { @@ -242,11 +220,9 @@ iperf_sctp_listen(struct iperf_test *test) /* servers must call sctp_bindx() _instead_ of bind() */ if (!TAILQ_EMPTY(&test->xbind_addrs)) { - if (iperf_sctp_bindx(test, s, IPERF_SCTP_SERVER)) { - close(s); - freeaddrinfo(res); + freeaddrinfo(res); + if (iperf_sctp_bindx(test, s, IPERF_SCTP_SERVER)) return -1; - } } else if (bind(s, (struct sockaddr *) res->ai_addr, res->ai_addrlen) < 0) { saved_errno = errno; @@ -270,7 +246,7 @@ iperf_sctp_listen(struct iperf_test *test) #else i_errno = IENOSCTP; return -1; -#endif /* HAVE_SCTP_H */ +#endif /* HAVE_SCTP */ } @@ -281,7 +257,7 @@ iperf_sctp_listen(struct iperf_test *test) int iperf_sctp_connect(struct iperf_test *test) { -#if defined(HAVE_SCTP_H) +#if defined(HAVE_SCTP) int s, opt, saved_errno; char portstr[6]; struct addrinfo hints, *local_res, *server_res; @@ -316,26 +292,6 @@ iperf_sctp_connect(struct iperf_test *test) return -1; } - if ((opt = test->settings->socket_bufsize)) { - int saved_errno; - if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) < 0) { - saved_errno = errno; - close(s); - freeaddrinfo(server_res); - errno = saved_errno; - i_errno = IESETBUF; - return -1; - } - if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt)) < 0) { - saved_errno = errno; - close(s); - freeaddrinfo(server_res); - errno = saved_errno; - i_errno = IESETBUF; - return -1; - } - } - /* * Various ways to bind the local end of the connection. * 1. --bind (with or without --cport). @@ -477,11 +433,8 @@ iperf_sctp_connect(struct iperf_test *test) /* clients must call bind() followed by sctp_bindx() before connect() */ if (!TAILQ_EMPTY(&test->xbind_addrs)) { - if (iperf_sctp_bindx(test, s, IPERF_SCTP_CLIENT)) { - freeaddrinfo(server_res); - close(s); + if (iperf_sctp_bindx(test, s, IPERF_SCTP_CLIENT)) return -1; - } } /* TODO support sctp_connectx() to avoid heartbeating. */ @@ -493,12 +446,12 @@ iperf_sctp_connect(struct iperf_test *test) i_errno = IESTREAMCONNECT; return -1; } + freeaddrinfo(server_res); /* Send cookie for verification */ if (Nwrite(s, test->cookie, COOKIE_SIZE, Psctp) < 0) { saved_errno = errno; close(s); - freeaddrinfo(server_res); errno = saved_errno; i_errno = IESENDCOOKIE; return -1; @@ -522,12 +475,11 @@ iperf_sctp_connect(struct iperf_test *test) return -1; } - freeaddrinfo(server_res); return s; #else i_errno = IENOSCTP; return -1; -#endif /* HAVE_SCTP_H */ +#endif /* HAVE_SCTP */ } @@ -535,12 +487,12 @@ iperf_sctp_connect(struct iperf_test *test) int iperf_sctp_init(struct iperf_test *test) { -#if defined(HAVE_SCTP_H) +#if defined(HAVE_SCTP) return 0; #else i_errno = IENOSCTP; return -1; -#endif /* HAVE_SCTP_H */ +#endif /* HAVE_SCTP */ } @@ -552,7 +504,7 @@ iperf_sctp_init(struct iperf_test *test) int iperf_sctp_bindx(struct iperf_test *test, int s, int is_server) { -#if defined(HAVE_SCTP_H) +#if defined(HAVE_SCTP) struct addrinfo hints; char portstr[6]; char *servname; @@ -701,5 +653,5 @@ out: #else i_errno = IENOSCTP; return -1; -#endif /* HAVE_SCTP_H */ +#endif /* HAVE_SCTP */ } diff --git a/src/iperf_server_api.c b/src/iperf_server_api.c index e2ddf7f..40d99bc 100644 --- a/src/iperf_server_api.c +++ b/src/iperf_server_api.c @@ -1,5 +1,5 @@ /* - * iperf, Copyright (c) 2014-2020 The Regents of the University of + * iperf, Copyright (c) 2014-2018 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. @@ -354,15 +354,6 @@ create_server_omit_timer(struct iperf_test * test) static void cleanup_server(struct iperf_test *test) { - struct iperf_stream *sp; - - /* Close open streams */ - SLIST_FOREACH(sp, &test->streams, streams) { - FD_CLR(sp->socket, &test->read_set); - FD_CLR(sp->socket, &test->write_set); - close(sp->socket); - } - /* Close open test sockets */ if (test->ctrl_sck) { close(test->ctrl_sck); @@ -446,20 +437,12 @@ iperf_run_server(struct iperf_test *test) while (test->state != IPERF_DONE) { - // Check if average transfer rate was exceeded (condition set in the callback routines) - if (test->bitrate_limit_exceeded) { - cleanup_server(test); - i_errno = IETOTALRATE; - return -1; - } - memcpy(&read_set, &test->read_set, sizeof(fd_set)); memcpy(&write_set, &test->write_set, sizeof(fd_set)); iperf_time_now(&now); timeout = tmr_timeout(&now); result = select(test->max_fd + 1, &read_set, &write_set, NULL, timeout); - if (result < 0 && errno != EINTR) { cleanup_server(test); i_errno = IESELECT; @@ -613,17 +596,6 @@ iperf_run_server(struct iperf_test *test) } } test->prot_listener = -1; - - /* Ensure that total requested data rate is not above limit */ - iperf_size_t total_requested_rate = test->num_streams * test->settings->rate * (test->mode == BIDIRECTIONAL? 2 : 1); - if (test->settings->bitrate_limit > 0 && total_requested_rate > test->settings->bitrate_limit) { - iperf_err(test, "Client total requested throughput rate of %" PRIu64 " bps exceeded %" PRIu64 " bps limit", - total_requested_rate, test->settings->bitrate_limit); - cleanup_server(test); - i_errno = IETOTALRATE; - return -1; - } - if (iperf_set_send_state(test, TEST_START) != 0) { cleanup_server(test); return -1; @@ -675,7 +647,7 @@ iperf_run_server(struct iperf_test *test) return -1; } } - } + } } if (result == 0 || diff --git a/src/iperf_tcp.c b/src/iperf_tcp.c index 47252d0..232aaa1 100644 --- a/src/iperf_tcp.c +++ b/src/iperf_tcp.c @@ -29,7 +29,6 @@ #include <string.h> #include <errno.h> #include <unistd.h> -#include <arpa/inet.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> diff --git a/src/iperf_udp.c b/src/iperf_udp.c index 2fd7bf5..3d37dab 100644 --- a/src/iperf_udp.c +++ b/src/iperf_udp.c @@ -1,5 +1,5 @@ /* - * iperf, Copyright (c) 2014-2020, The Regents of the University of + * iperf, Copyright (c) 2014-2018, 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. @@ -30,7 +30,6 @@ #include <errno.h> #include <unistd.h> #include <assert.h> -#include <arpa/inet.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> @@ -52,13 +51,7 @@ #if defined(HAVE_INTTYPES_H) # include <inttypes.h> #else -# ifndef PRIu64 -# if sizeof(long) == 8 -# define PRIu64 "lu" -# else -# define PRIu64 "llu" -# endif -# endif +# define PRIu64 "llu" #endif /* iperf_udp_recv @@ -72,7 +65,6 @@ iperf_udp_recv(struct iperf_stream *sp) uint64_t pcount; int r; int size = sp->settings->blksize; - int first_packet = 0; double transit = 0, d = 0; struct iperf_time sent_time, arrival_time, temp_time; @@ -88,19 +80,9 @@ iperf_udp_recv(struct iperf_stream *sp) /* Only count bytes received while we're in the correct state. */ if (sp->test->state == TEST_RUNNING) { - - /* - * For jitter computation below, it's important to know if this - * packet is the first packet received. - */ - if (sp->result->bytes_received == 0) { - first_packet = 1; - } - sp->result->bytes_received += r; sp->result->bytes_received_this_interval += r; - /* Dig the various counters out of the incoming UDP packet */ if (sp->test->udp_counters_64bit) { memcpy(&sec, sp->buffer, sizeof(sec)); memcpy(&usec, sp->buffer+4, sizeof(usec)); @@ -167,7 +149,7 @@ iperf_udp_recv(struct iperf_stream *sp) /* Log the out-of-order packet */ if (sp->test->debug) - fprintf(stderr, "OUT OF ORDER - incoming packet sequence %" PRIu64 " but expected sequence %d on stream %d", pcount, sp->packet_count + 1, sp->socket); + fprintf(stderr, "OUT OF ORDER - incoming packet sequence %" PRIu64 " but expected sequence %d on stream %d", pcount, sp->packet_count, sp->socket); } /* @@ -185,11 +167,6 @@ iperf_udp_recv(struct iperf_stream *sp) iperf_time_diff(&arrival_time, &sent_time, &temp_time); transit = iperf_time_in_secs(&temp_time); - - /* Hack to handle the first packet by initializing prev_transit. */ - if (first_packet) - sp->prev_transit = transit; - d = transit - sp->prev_transit; if (d < 0) d = -d; diff --git a/src/iperf_util.c b/src/iperf_util.c index 9ca1eec..412397a 100644 --- a/src/iperf_util.c +++ b/src/iperf_util.c @@ -111,7 +111,7 @@ void fill_with_repeating_pattern(void *out, size_t outsize) */ void -make_cookie(const char *cookie) +make_cookie(char *cookie) { unsigned char *out = (unsigned char*)cookie; size_t pos; @@ -267,7 +267,7 @@ get_optional_features(void) numfeatures++; #endif /* HAVE_FLOWLABEL */ -#if defined(HAVE_SCTP_H) +#if defined(HAVE_SCTP) if (numfeatures > 0) { strncat(features, ", ", sizeof(features) - strlen(features) - 1); @@ -275,7 +275,7 @@ get_optional_features(void) strncat(features, "SCTP", sizeof(features) - strlen(features) - 1); numfeatures++; -#endif /* HAVE_SCTP_H */ +#endif /* HAVE_SCTP */ #if defined(HAVE_TCP_CONGESTION) if (numfeatures > 0) { @@ -402,7 +402,7 @@ iperf_json_printf(const char *format, ...) /* Debugging routine to dump out an fd_set. */ void -iperf_dump_fdset(FILE *fp, const char *str, int nfds, fd_set *fds) +iperf_dump_fdset(FILE *fp, char *str, int nfds, fd_set *fds) { int fd; int comma; diff --git a/src/iperf_util.h b/src/iperf_util.h index b109af2..76bfd20 100644 --- a/src/iperf_util.h +++ b/src/iperf_util.h @@ -54,7 +54,7 @@ const char* get_optional_features(void); cJSON* iperf_json_printf(const char *format, ...); -void iperf_dump_fdset(FILE *fp, const char *str, int nfds, fd_set *fds); +void iperf_dump_fdset(FILE *fp, char *str, int nfds, fd_set *fds); #ifndef HAVE_DAEMON extern int daemon(int nochdir, int noclose); @@ -44,10 +44,9 @@ #include "iperf.h" #include "iperf_api.h" -#include "iperf_util.h" +#include "units.h" #include "iperf_locale.h" #include "net.h" -#include "units.h" static int run(struct iperf_test *test); @@ -29,7 +29,6 @@ #include <stdio.h> #include <unistd.h> #include <errno.h> -#include <arpa/inet.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> @@ -121,7 +120,7 @@ timeout_connect(int s, const struct sockaddr *name, socklen_t namelen, /* make connection to server */ int -netdial(int domain, int proto, const char *local, int local_port, const char *server, int port, int timeout) +netdial(int domain, int proto, char *local, int local_port, char *server, int port, int timeout) { struct addrinfo hints, *local_res, *server_res; int s, saved_errno; @@ -218,7 +217,7 @@ netdial(int domain, int proto, const char *local, int local_port, const char *se /***************************************************************/ int -netannounce(int domain, int proto, const char *local, int port) +netannounce(int domain, int proto, char *local, int port) { struct addrinfo hints, *res; char portstr[6]; @@ -28,8 +28,8 @@ #define __NET_H int timeout_connect(int s, const struct sockaddr *name, socklen_t namelen, int timeout); -int netdial(int domain, int proto, const char *local, int local_port, const char *server, int port, int timeout); -int netannounce(int domain, int proto, const char *local, int port); +int netdial(int domain, int proto, char *local, int local_port, char *server, int port, int timeout); +int netannounce(int domain, int proto, char *local, int port); int Nread(int fd, char *buf, size_t count, int prot); int Nwrite(int fd, const char *buf, size_t count, int prot) /* __attribute__((hot)) */; int has_sendfile(void); diff --git a/src/private.pem b/src/private.pem deleted file mode 100644 index 8b1c5b6..0000000 --- a/src/private.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAwVbvPf/eDIZKmEVth9+VPgSx1RkXOAPCJ5tl51bcYoy9P10N -noutsTK/64VclIuyUDUdAw81Vu5tYRcBeB8Jllp02xL8kPo0IROsT3wmMYbPziUG -/I2988sAP9mL8QbtKydnADHMikfadfyPkfxW2naFtquWT/vKKVkhC2LHJyTpmAVj -pp6R9LDDu/YY0/kb5DvYPpe62xgNWjNVIhABu3R+StAAL25SaLXuaGSVpDe6Sphn -TqVf+LmKCkZmSMSfQoozXomNyFpLU8ODoV3QyHYi6QSWWFtU6gu0uso/9pfRFjbN -GV9lxokKNz/cZGyu0SFddMiTGrt24NROi0RHwwIDAQABAoIBACVG+cHef5WyntdV -K5UzCrd2eEM6HzvxnZG9aJx+JufpcuOwsVuMWuT7f/2NLRiHBs5oLzvTxtkIB5bc -tK/QbCzNLBLBSmk5lKt7+5EnwsVx1MdOZFZ1jdZfoaCt9Ul3qGrVogprj6Bp0jlF -hPkEyko85/McilLJnWTzhmeHmBZ3tOJ9LWHgVdXGXZx/pBuxZ+UB/xgZdvdZK86F -xndWqD8lvfpoSsVwzCORdXvQWs78CtT2KXYvt8S6mrLMoIoHLO/1rwwKKoZfFuja -NouN36PGaSo4/9O1d11/s9zwdJH3ShozY0Fao8I3XhdH0uvTirmAEPh7U1Lo71pP -ksUvbUECgYEA/7p1Bg/XsSK72KgJ695B2hi8g9+wv0eKCpGwkKJQZKE338it8zIn -+JMaeDjObLhb4B2QP/3iL0mdU2mJzm0X8hYCKqBdyICb9wixznLLAej+uw2j60Ef -tlGenCqAkVL3pRS5txztNhFsXx3JwxCSj4zwmVm5oyxkpAeuwvZ1cPkCgYEAwYuC -6nPlRf6GEf/MuHCziaCCPrDm1u472uspxHn41crw6BaMl5xcmr0Z8O7heOtlVmMl -Mn3gfIbd/NGyjs8ejmWcO5mZHtESGM/zAaVyu7bn3ij37OEndbEpZsCpRtxvtaji -MTMwhdV2xteJ0+KCtg66ziSyJv3krQTEW8DZKZsCgYB8BcnLbtOErPu9T4HASsJV -K7oBmvL1UZS5G38uJgonQ6j9dy4lzCVmgLFNrP8v6xljz/Ktlkuj82fBlGWpH2+F -kPbsBWp2WylI3YaeQT4DZyRjQ3JEHglrOppZ0qMX180S2sJW9Eh2+Gw+lQvM9rSd -uhTVypYldNo6Ux+GnlDGwQKBgQC/6W4uvCyjcvXN8y8z08yysw1yzEaY6DFBqd0I -jUlH9Ktb9sABtXG9nbSTSssX85HQTw8bOeXWlISZo/TB1m4eFHMORgemnviq0cfL -4hoaOAtCJq1vnPJbqQe8c11mfj3mi0d+MZvzmO7ly+NGzlt92q0wqwJb13VgelGa -CWdL8QKBgQD1ABK8WJuMowihrQsLaUxNO/1hsN8CP/rjoi9D5NdSFt5zzcC3D/RA -m42ScOaAFIh44Js5aAROvbDqIlelhwRlmutP/lYyQRZDZm7X6u/bKuqK4H/sM6ZB -SICe2eWFvbKexI7QnreRltOWIFrNoZy9FdELM8DS+kePAlVt7c83Uw== ------END RSA PRIVATE KEY----- diff --git a/src/public.pem b/src/public.pem deleted file mode 100644 index 71f4f13..0000000 --- a/src/public.pem +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwVbvPf/eDIZKmEVth9+V -PgSx1RkXOAPCJ5tl51bcYoy9P10NnoutsTK/64VclIuyUDUdAw81Vu5tYRcBeB8J -llp02xL8kPo0IROsT3wmMYbPziUG/I2988sAP9mL8QbtKydnADHMikfadfyPkfxW -2naFtquWT/vKKVkhC2LHJyTpmAVjpp6R9LDDu/YY0/kb5DvYPpe62xgNWjNVIhAB -u3R+StAAL25SaLXuaGSVpDe6SphnTqVf+LmKCkZmSMSfQoozXomNyFpLU8ODoV3Q -yHYi6QSWWFtU6gu0uso/9pfRFjbNGV9lxokKNz/cZGyu0SFddMiTGrt24NROi0RH -wwIDAQAB ------END PUBLIC KEY----- diff --git a/src/t_api.c b/src/t_api.c index f5e0984..0669917 100644 --- a/src/t_api.c +++ b/src/t_api.c @@ -1,5 +1,5 @@ /* - * iperf, Copyright (c) 2017-2020, The Regents of the University of + * iperf, Copyright (c) 2017, 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. @@ -45,21 +45,9 @@ int main(int argc, char **argv) { const char *ver; - struct iperf_test *test; - int sint, gint; ver = iperf_get_iperf_version(); assert(strcmp(ver, IPERF_VERSION) == 0); - test = iperf_new_test(); - assert(test != NULL); - - iperf_defaults(test); - - sint = 10; - iperf_set_test_connect_timeout(test, sint); - gint = iperf_get_test_connect_timeout(test); - assert(sint == gint); - return 0; } diff --git a/src/t_auth.c b/src/t_auth.c deleted file mode 100644 index ff9cffe..0000000 --- a/src/t_auth.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * iperf, Copyright (c) 2020, 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. - */ -#include "iperf_config.h" - -#include <assert.h> -#ifdef HAVE_STDINT_H -#include <stdint.h> -#endif -#include <stdio.h> -#include <string.h> - -#include "iperf.h" -#include "iperf_api.h" -#if defined(HAVE_SSL) -#include "iperf_auth.h" -#endif /* HAVE_SSL */ - -#include "version.h" - -#include "units.h" - -#if defined(HAVE_SSL) -int test_authtoken(const char *authUser, const char *authPassword, EVP_PKEY *pubkey, EVP_PKEY *privkey); - -int -main(int argc, char **argv) -{ - /* sha256 */ - void sha256(const char *string, char outputBuffer[65]); - const char sha256String[] = "This is a SHA256 test."; - const char sha256Digest[] = "4816482f8b4149f687a1a33d61a0de6b611364ec0fb7adffa59ff2af672f7232"; /* echo -n "This is a SHA256 test." | shasum -a256 */ - char sha256Output[65]; - - sha256(sha256String, sha256Output); - assert(strcmp(sha256Output, sha256Digest) == 0); - - /* Base64{Encode,Decode} */ - int Base64Encode(const unsigned char* buffer, const size_t length, char** b64text); - int Base64Decode(const char* b64message, unsigned char** buffer, size_t* length); - const char base64String[] = "This is a Base64 test."; - char *base64Text; - char *base64Decode; - size_t base64DecodeLength; - const char base64EncodeCheck[] = "VGhpcyBpcyBhIEJhc2U2NCB0ZXN0Lg=="; /* echo -n "This is a Base64 test." | b64encode -r - */ - - assert(Base64Encode((unsigned char *) base64String, strlen(base64String), &base64Text) == 0); - assert(strcmp(base64Text, base64EncodeCheck) == 0); - assert(Base64Decode(base64Text, (unsigned char **) &base64Decode, &base64DecodeLength) == 0); - assert(strcmp(base64String, base64Decode) == 0); - - /* public/private key tests */ - const char *pubkeyfile = "public.pem"; - const char *privkeyfile = "private.pem"; - - /* built-in tests */ - assert(test_load_pubkey_from_file(pubkeyfile) == 0); - assert(test_load_private_key_from_file(privkeyfile) == 0); - - /* load public key pair for use in further tests */ - EVP_PKEY *pubkey, *privkey; - pubkey = load_pubkey_from_file(pubkeyfile); - assert(pubkey); - privkey = load_privkey_from_file(privkeyfile); - assert(privkey); - - /* authentication token tests */ - assert(test_authtoken("kilroy", "fubar", pubkey, privkey) == 0); - - /* This should fail because the data is way too long for the RSA key */ - /* assert(test_authtoken("kilroykilroykilroykilroykilroykilroykilroykilroykilroykilroykilroykilroykilroykilroykilroykilroykilroykilroykilroykilroykilroykilroykilroykilroykilroykilroy", "fubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubarfubar", pubkey, privkey) < 0); */ - - return 0; -} - -int -test_authtoken(const char *authUser, const char *authPassword, EVP_PKEY *pubkey, EVP_PKEY *privkey) { - char *authToken; - char *decodeUser; - char *decodePassword; - time_t decodeTime; - - assert(encode_auth_setting(authUser, authPassword, pubkey, &authToken) == 0); - assert(decode_auth_setting(0, authToken, privkey, &decodeUser, &decodePassword, &decodeTime) == 0); - - assert(strcmp(decodeUser, authUser) == 0); - assert(strcmp(decodePassword, authPassword) == 0); - - time_t now = time(NULL); - - assert(now - decodeTime >= 0); /* time has to go forwards */ - assert(now - decodeTime <= 1); /* shouldn't take more than a second to run */ - - return 0; -} -#else -int -main(int argc, char **argv) -{ - return 0; -} -#endif /* HAVE_SSL */ diff --git a/src/tcp_info.c b/src/tcp_info.c index d63e5b4..bfbb9ea 100644 --- a/src/tcp_info.c +++ b/src/tcp_info.c @@ -197,13 +197,13 @@ get_pmtu(struct iperf_interval_results *irp) void build_tcpinfo_message(struct iperf_interval_results *r, char *message) { -#if defined(linux) && defined(TCP_INFO) +#if defined(linux) sprintf(message, report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd, r->tcpInfo.tcpi_snd_ssthresh, r->tcpInfo.tcpi_rcv_ssthresh, r->tcpInfo.tcpi_unacked, r->tcpInfo.tcpi_sacked, r->tcpInfo.tcpi_lost, r->tcpInfo.tcpi_retrans, r->tcpInfo.tcpi_fackets, r->tcpInfo.tcpi_rtt, r->tcpInfo.tcpi_reordering); #endif -#if defined(__FreeBSD__) && defined(TCP_INFO) +#if defined(__FreeBSD__) sprintf(message, report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd, r->tcpInfo.tcpi_rcv_space, r->tcpInfo.tcpi_snd_ssthresh, r->tcpInfo.tcpi_rtt); #endif diff --git a/src/timer.h b/src/timer.h index 58c3db8..301cdf3 100644 --- a/src/timer.h +++ b/src/timer.h @@ -31,8 +31,6 @@ #define __TIMER_H #include <time.h> -#include <sys/time.h> - #include "iperf_time.h" /* TimerClientData is an opaque value that tags along with a timer. The |