pax_global_header00006660000000000000000000000064127654725060014530gustar00rootroot0000000000000052 comment=3bd5d0fb73ae2d4da91f2add16e01c221b2cee0b httping-2.5/000077500000000000000000000000001276547250600130535ustar00rootroot00000000000000httping-2.5/Makefile000066400000000000000000000077311276547250600145230ustar00rootroot00000000000000# The GPL applies to this program. # In addition, as a special exception, the copyright holders give # permission to link the code of portions of this program with the # OpenSSL library under certain conditions as described in each # individual source file, and distribute linked combinations # including the two. # You must obey the GNU General Public License in all respects # for all of the code used other than OpenSSL. If you modify # file(s) with this exception, you may extend this exception to your # version of the file(s), but you are not obligated to do so. If you # do not wish to do so, delete this exception statement from your # version. If you delete this exception statement from all source # files in the program, then also delete it here. -include makefile.inc # *** configure script *** # support for tcp fast open? #TFO=yes # disable SSL? (no = disable so the default is use openssl) # SSL=no # enable NCURSES interface? #NC=yes # do fft in ncurses interface? (requires libfftw3) #FW=yes ############# do not change anything below here ############# include version TARGET=httping LOCALEDIR=/usr/share/locale DEBUG=yes WFLAGS=-Wall -W -Wextra -pedantic -D_FORTIFY_SOURCE=2 OFLAGS= CFLAGS+=$(WFLAGS) $(OFLAGS) -DVERSION=\"$(VERSION)\" -DLOCALEDIR=\"$(LOCALEDIR)\" LDFLAGS+=-lm PACKAGE=$(TARGET)-$(VERSION) PREFIX?=/usr BINDIR=$(PREFIX)/bin MANDIR=$(PREFIX)/share/man DOCDIR=$(PREFIX)/share/doc/$(TARGET) INSTALL=install INSTALLDIR=$(INSTALL) -m 0755 -d INSTALLBIN=$(INSTALL) -m 0755 INSTALLMAN=$(INSTALL) -m 0644 INSTALLDOC=$(INSTALL) -m 0644 STRIP=/usr/bin/strip RMDIR=/bin/rm -rf MKDIR=/bin/mkdir ARCHIVE=/bin/tar cf - COMPRESS=/bin/gzip -9 TRANSLATIONS=nl.mo ru.mo OBJS=gen.o http.o io.o error.o utils.o main.o tcp.o res.o socks5.o kalman.o cookies.o help.o colors.o MAN_EN=httping.1 MAN_NL=httping-nl.1 MAN_RU=httping-ru.1 DOCS=license.txt license.OpenSSL readme.txt ifeq ($(SSL),no) CFLAGS+=-DNO_SSL else OBJS+=mssl.o LDFLAGS+=-lssl -lcrypto endif ifeq ($(TFO),yes) CFLAGS+=-DTCP_TFO endif ifeq ($(NC),yes) CFLAGS+=-DNC OBJS+=nc.o LDFLAGS+=-lncursesw endif ifeq ($(FW),yes) CFLAGS+=-DFW OBJS+=fft.o LDFLAGS+=-lfftw3 endif ifeq ($(DEBUG),yes) CFLAGS+=-D_DEBUG -ggdb LDFLAGS+=-g endif ifeq ($(ARM),yes) CC=arm-linux-gcc endif all: $(TARGET) $(TRANSLATIONS) $(TARGET): $(OBJS) $(CC) $(WFLAGS) $(OBJS) $(LDFLAGS) -o $(TARGET) # # Oh, blatant plug: http://www.vanheusden.com/wishlist.php install: $(TARGET) $(TRANSLATIONS) $(INSTALLDIR) $(DESTDIR)/$(BINDIR) $(INSTALLBIN) $(TARGET) $(DESTDIR)/$(BINDIR) $(INSTALLDIR) $(DESTDIR)/$(MANDIR)/man1 $(INSTALLMAN) $(MAN_EN) $(DESTDIR)/$(MANDIR)/man1 $(INSTALLDIR) $(DESTDIR)/$(MANDIR)/nl/man1 $(INSTALLMAN) $(MAN_NL) $(DESTDIR)/$(MANDIR)/nl/man1 $(INSTALLDIR) $(DESTDIR)/$(MANDIR)/ru/man1 $(INSTALLMAN) $(MAN_RU) $(DESTDIR)/$(MANDIR)/ru/man1 $(INSTALLDIR) $(DESTDIR)/$(DOCDIR) $(INSTALLDOC) $(DOCS) $(DESTDIR)/$(DOCDIR) ifneq ($(DEBUG),yes) $(STRIP) $(DESTDIR)/$(BINDIR)/$(TARGET) endif mkdir -p $(DESTDIR)/$(PREFIX)/share/locale/nl/LC_MESSAGES cp nl.mo $(DESTDIR)/$(PREFIX)/share/locale/nl/LC_MESSAGES/httping.mo mkdir -p $(DESTDIR)/$(PREFIX)/share/locale/ru/LC_MESSAGES cp ru.mo $(DESTDIR)/$(PREFIX)/share/locale/ru/LC_MESSAGES/httping.mo makefile.inc: ./configure nl.mo: nl.po msgfmt -o nl.mo nl.po ru.mo: ru.po msgfmt -o ru.mo ru.po clean: $(RMDIR) $(OBJS) $(TARGET) *~ core cov-int *.mo distclean: clean rm -f makefile.inc package: # source package $(RMDIR) $(PACKAGE)* $(MKDIR) $(PACKAGE) $(INSTALLDOC) *.c *.h configure Makefile *.po version $(MAN_EN) $(MAN_NL) $(MAN_RU) $(DOCS) $(PACKAGE) $(INSTALLBIN) configure $(PACKAGE) $(ARCHIVE) $(PACKAGE) | $(COMPRESS) > $(PACKAGE).tgz $(RMDIR) $(PACKAGE) check: makefile.inc cppcheck -v --force -j 3 --enable=all --std=c++11 --inconclusive -I. . 2> err.txt # make clean scan-build make coverity: makefile.inc make clean rm -rf cov-int CC=gcc cov-build --dir cov-int make all tar vczf ~/site/coverity/httping.tgz README cov-int/ putsite -q /home/folkert/.coverity-hp.sh httping-2.5/colors.c000066400000000000000000000020111276547250600145120ustar00rootroot00000000000000#include "colors.h" const char *c_error = ""; const char *c_normal = ""; const char *c_very_normal = ""; const char *c_red = ""; const char *c_blue = ""; const char *c_green = ""; const char *c_yellow = ""; const char *c_magenta = ""; const char *c_cyan = ""; const char *c_white = ""; const char *c_bright = ""; void set_colors(char nc) { if (nc) { c_red = COLOR_ESCAPE "1"; c_blue = COLOR_ESCAPE "2"; c_green = COLOR_ESCAPE "3"; c_yellow = COLOR_ESCAPE "4"; c_magenta = COLOR_ESCAPE "5"; c_cyan = COLOR_ESCAPE "6"; c_white = COLOR_ESCAPE "7"; c_bright = COLOR_ESCAPE "8"; c_normal = COLOR_ESCAPE "9"; c_very_normal = COLOR_ESCAPE "7" COLOR_ESCAPE "9"; c_error = COLOR_ESCAPE "1"; } else { c_red = "\033[31;40m"; c_blue = "\033[34;40m"; c_green = "\033[32;40m"; c_yellow = "\033[33;40m"; c_magenta = "\033[35;40m"; c_cyan = "\033[36;40m"; c_white = "\033[37;40m"; c_bright = "\033[1;40m"; c_normal = "\033[0;37;40m"; c_very_normal = "\033[0m"; c_error = "\033[1;4;40m"; } } httping-2.5/colors.h000066400000000000000000000005631276547250600145310ustar00rootroot00000000000000extern const char *c_error; extern const char *c_normal; extern const char *c_very_normal; extern const char *c_red; extern const char *c_blue; extern const char *c_green; extern const char *c_yellow; extern const char *c_magenta; extern const char *c_cyan; extern const char *c_white; extern const char *c_bright; #define COLOR_ESCAPE "\001" void set_colors(char nc); httping-2.5/configure000077500000000000000000000036441276547250600147710ustar00rootroot00000000000000#! /bin/sh FILE=`mktemp` FILE2=`mktemp` echo \*\*\* HTTPing v`grep VERSION version | cut -d = -f 2` configure script \*\*\* echo if [ -z "$CC" ] then CC=gcc fi F_TFO=0 F_NC=0 F_OS=0 F_FW=0 for var in "$@" do case "$var" in --with-tfo) F_TFO=1 ;; --with-ncurses) F_NC=1 ;; --with-openssl) F_OS=1 ;; --with-fftw3) F_FW=1 ;; --help) echo "--with-tfo force enable tcp fast open" echo "--with-ncurses force enable ncurses" echo "--with-openssl force enable openssl" echo "--with-fftw3 force enable fftw3" exit 0 ;; *) echo WARNING: Command line parameter \"$var\" is not understood. echo Re-run this script with --help to see a list of switches. ;; esac done $CC -O0 -o $FILE test_TFO.c 2> $FILE2 if [ $? -eq 0 ] || [ $F_TFO -eq 1 ] ; then echo \+ system supports TCP fast open TFO="TFO=yes" else echo \- this system does NOT support TCP fast open - this is an optional feature TFO="" fi $CC -O0 -o $FILE test_ncurses.c -lncursesw 2> $FILE2 if [ $? -eq 0 ] || [ $F_NC -eq 1 ] ; then echo \+ system has ncurses development libraries NC="NC=yes" else echo \- this system does NOT have the ncurses development libraries - they are optional NC="" fi $CC -O0 -o $FILE test_openssl.c -lssl -lcrypto 2> $FILE2 if [ $? -eq 0 ] || [ $F_OS -eq 1 ] ; then echo \+ system has OpenSSL development libraries SSL="SSL=yes" else echo \- this system does NOT have the OpenSSL development libraries - they are optional SSL="SSL=no" fi $CC -O0 -o $FILE test_fftw3.c -lfftw3 2> $FILE2 if [ $? -eq 0 ] || [ $F_FW -eq 1 ] ; then echo \+ system has FFTW3 development libraries FW="FW=yes" else echo \- this system does NOT have the FFTW3 development libraries - they are optional and only useful when also including ncurses FW="" fi > makefile.inc echo $NC >> makefile.inc echo $SSL >> makefile.inc echo $TFO >> makefile.inc echo $FW >> makefile.inc rm -f $FILE $FILE2 echo httping-2.5/cookies.c000066400000000000000000000046631276547250600146640ustar00rootroot00000000000000#include #include #include "utils.h" void add_cookie(char ***cookies, int *n_cookies, char *in) { char *in_copy = strdup(in), *is = strchr(in_copy, '='); int index = 0, found_at = -1; if (is) *is = 0x00; for(index=0; index<*n_cookies; index++) { char *dummy = strdup((*cookies)[index]); is = strchr(dummy, '='); if (is) *is = 0x00; if (strcmp(in_copy, dummy) == 0) { found_at = index; free(dummy); break; } free(dummy); } if (found_at >= 0) { free((*cookies)[found_at]); (*cookies)[found_at] = strdup(in); } else { *cookies = (char **)realloc(*cookies, (*n_cookies + 1) * sizeof(char *)); (*cookies)[*n_cookies] = strdup(in); (*n_cookies)++; } free(in_copy); } void combine_cookie_lists(char ***destc, int *n_dest, char **src, int n_src) { int loop = 0; *destc = (char **)realloc(*destc, (*n_dest + n_src) * sizeof(char *)); for(loop=0; loop #include #include #include #include #include #include #include char last_error[4096] = { 0 }; void error_exit(char *format, ...) { int e = errno; va_list ap; va_start(ap, format); (void)vfprintf(stderr, format, ap); va_end(ap); fprintf(stderr, gettext("\n\nerrno=%d which means %s (if applicable)\n"), e, strerror(e)); exit(1); } void set_error(const char *fmt, ...) { int buffer_size = sizeof last_error; va_list ap; if (last_error[0]) fprintf(stderr, "%s\n", last_error); va_start(ap, fmt); if (vsnprintf(last_error, sizeof last_error, fmt, ap) >= buffer_size) error_exit(gettext("Error message '%s' truncated"), last_error); va_end(ap); } void clear_error() { last_error[0] = 0x00; } char * get_error() { return last_error; } httping-2.5/error.h000066400000000000000000000003261276547250600143560ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ void error_exit(const char *format, ...); void set_error(const char *str, ...); void clear_error(void); char * get_error(void); httping-2.5/fft.c000066400000000000000000000024531276547250600140020ustar00rootroot00000000000000#include #include #include #include #include #include "error.h" double *pin = NULL; fftw_complex *pout = NULL; fftw_plan plan; int sample_rate = 44100; void fft_init(int sample_rate_in) { sample_rate = sample_rate_in; pin = (double *)malloc(sizeof(double) * sample_rate_in); if (!pin) error_exit(gettext("failed allocating memory for fft (1)")); pout = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * sample_rate_in + 1); if (!pout) error_exit(gettext("failed allocating memory for fft (2)")); /* init fftw */ plan = fftw_plan_dft_r2c_1d(sample_rate_in, pin, pout, FFTW_ESTIMATE); if (!plan) error_exit(gettext("failed calculating plan for fft")); } void fft_free(void) { if (pin) { fftw_free(pout); free(pin); } fftw_destroy_plan(plan); } void fft_stop(void) { fftw_cleanup(); } void fft_do(double *in, double *output_mag, double *output_phase) { int loop = 0; memcpy(pin, in, sizeof(double) * sample_rate); /* calc fft */ fftw_execute(plan); for(loop=0; loop<(sample_rate / 2) + 1; loop++) { double real = pout[loop][0]; double img = pout[loop][1]; /* magnitude */ output_mag[loop] = sqrt(pow(real, 2.0) + pow(img, 2.0)); /* phase */ output_phase[loop] = (real == 0 && img == 0) ? 0 : atan2(real, img); } } httping-2.5/fft.h000066400000000000000000000002201276547250600137750ustar00rootroot00000000000000void fft_init(int sample_rate_in); void fft_free(void); void fft_do(double *in, double *output_mag, double *output_phase); void fft_stop(void); httping-2.5/gen.c000066400000000000000000000032541276547250600137740ustar00rootroot00000000000000#include #include #include "gen.h" void init_statst(stats_t *data) { memset(data, 0x00, sizeof(stats_t)); data -> min = MY_DOUBLE_INF; data -> max = -data -> min; } void update_statst(stats_t *data, double in) { data -> cur = in; data -> min = min(data -> min, in); data -> max = max(data -> max, in); data -> avg += in; data -> sd += in * in; (data -> n)++; data -> valid = 1; data -> cur_valid = 1; } void reset_statst_cur(stats_t *data) { data -> cur_valid = 0; } double calc_sd(stats_t *in) { double avg = 0.0; if (in -> n == 0 || !in -> valid) return 0; avg = in -> avg / (double)in -> n; return sqrt((in -> sd / (double)in -> n) - pow(avg, 2.0)); } /* Base64 encoding start */ const char *alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; void encode_tryptique(char source[3], char result[4]) /* Encode 3 char in B64, result give 4 Char */ { int tryptique, i; tryptique = source[0]; tryptique *= 256; tryptique += source[1]; tryptique *= 256; tryptique += source[2]; for (i=0; i<4; i++) { result[3-i] = alphabet[tryptique%64]; tryptique /= 64; } } int enc_b64(char *source, int source_lenght, char *target) { /* Divide string /3 and encode trio */ while (source_lenght >= 3) { encode_tryptique(source, target); source_lenght -= 3; source += 3; target += 4; } /* Add padding to the rest */ if (source_lenght > 0) { char pad[3]; memset(pad, 0, sizeof pad); memcpy(pad, source, source_lenght); encode_tryptique(pad, target); target[3] = '='; if (source_lenght == 1) target[2] = '='; target += 4; } target[0] = 0; return 1; } /* Base64 encoding END */ httping-2.5/gen.h000066400000000000000000000021301276547250600137710ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #ifndef __GEN_H__ #define __GEN_H__ #define RC_OK 0 #define RC_SHORTREAD -1 #define RC_SHORTWRITE -1 #define RC_TIMEOUT -2 #define RC_CTRLC -3 #define RC_INVAL -4 #define RECV_BUFFER_SIZE (128 * 1024) #define SPAM_FILE "/tmp/httping.dat" #define MAX_SHOW_SUPPRESSION 3 #ifdef NO_SSL #define SSL void #define SSL_CTX void #define BIO void #endif #define PI (4 * atan(1.0)) #define MY_DOUBLE_INF 999999999999999.9 #ifdef TCP_TFO #ifndef MSG_FASTOPEN #define MSG_FASTOPEN 0x20000000 #endif #ifndef TCP_FASTOPEN #define TCP_FASTOPEN 23 #endif #ifndef TCPI_OPT_SYN_DATA #define TCPI_OPT_SYN_DATA 32 #endif #endif #define min(x, y) ((x) < (y) ? (x) : (y)) #define max(x, y) ((x) > (y) ? (x) : (y)) typedef struct { double cur, min, avg, max, sd; int n; char valid, cur_valid; } stats_t; int enc_b64(char *source, int source_lenght, char *target); void init_statst(stats_t *data); void update_statst(stats_t *data, double in); void reset_statst_cur(stats_t *data); double calc_sd(stats_t *in); #endif httping-2.5/help.c000066400000000000000000000301331276547250600141470ustar00rootroot00000000000000#include #include #include #include #include #include #include "gen.h" #include "main.h" #include "help.h" #include "utils.h" void new_version_alert(void) { char new_version = 0; FILE *fh = fopen(SPAM_FILE, "r"); if (!fh) new_version = 1; else { char buffer[4096], *dummy = 0x00; fgets(buffer, sizeof buffer, fh); fclose(fh); dummy = strchr(buffer, '\n'); if (dummy) *dummy = 0x00; if (strcmp(buffer, VERSION) != 0) new_version = 1; } if (new_version) { struct utsname buf; FILE *fh = fopen(SPAM_FILE, "w"); if (fh) { fprintf(fh, "%s\n", VERSION); fclose(fh); } printf("Welcome to the new HTTPing version " VERSION "!\n\n"); #ifdef NC printf("Did you know that with -K you can start a fullscreen GUI version with nice graphs and lots more information? And that you can disable the moving graphs with -D?\n"); #ifndef FW printf("And if you compile this program with libfftw3, that it can also show a fourier transform of the measured values?\n"); #endif #else printf("Did you know that if you compile this program with NCURSES, that it then includes a nice GUI with lots more information and graphs?\n"); #endif #if !defined(TCP_TFO) && defined(linux) if (uname(&buf) == 0) { char **rparts = NULL; int n_rparts = 0; split_string(buf.release, ".", &rparts, &n_rparts); if (n_rparts >= 2 && ((atoi(rparts[0]) >= 3 && atoi(rparts[1]) >= 6) || atoi(rparts[0]) >= 4)) printf("This program supports TCP Fast Open! (if compiled in and only on Linux kernels 3.6 or more recent) See the readme.txt how to enable this.\n"); free_splitted_string(rparts, n_rparts); } #endif printf("\n\n"); } } void version(void) { fprintf(stderr, gettext("HTTPing v" VERSION ", (C) 2003-2016 folkert@vanheusden.com\n")); #ifndef NO_SSL fprintf(stderr, gettext(" * SSL support included (-l)\n")); #endif #ifdef NC #ifdef FW fprintf(stderr, gettext(" * ncurses interface with FFT included (-K)\n")); #else fprintf(stderr, gettext(" * ncurses interface included (-K)\n")); #endif #endif #ifdef TCP_TFO fprintf(stderr, gettext(" * TFO (TCP fast open) support included (-F)\n")); #endif fprintf(stderr, gettext("\n")); } void format_help(const char *short_str, const char *long_str, const char *descr) { int par_width = SWITCHES_COLUMN_WIDTH, max_wrap_width = par_width / 2, cur_par_width = 0; int descr_width = max_x - (par_width + 1); char *line = NULL, *p = (char *)descr; char first = 1; if (long_str && short_str) str_add(&line, "%-4s / %s", short_str, long_str); else if (long_str) str_add(&line, "%s", long_str); else str_add(&line, "%s", short_str); cur_par_width = fprintf(stderr, "%-*s ", par_width, line); free(line); if (par_width + 1 >= max_x || cur_par_width >= max_x) { fprintf(stderr, "%s\n", descr); return; } for(;strlen(p);) { char *n = NULL, *kn = NULL, *copy = NULL; int n_len = 0, len_after_ww = 0, len_before_ww = 0; int str_len = 0, cur_descr_width = first ? max_x - cur_par_width : descr_width; while(*p == ' ') p++; str_len = strlen(p); if (!str_len) break; len_before_ww = min(str_len, cur_descr_width); n = &p[len_before_ww]; kn = n; if (str_len > cur_descr_width) { while (*n != ' ' && n_len < max_wrap_width) { n--; n_len++; } if (n_len >= max_wrap_width) n = kn; } len_after_ww = (int)(n - p); if (len_after_ww <= 0) break; copy = (char *)malloc(len_after_ww + 1); memcpy(copy, p, len_after_ww); copy[len_after_ww] = 0x00; if (first) first = 0; else fprintf(stderr, "%*s ", par_width, ""); fprintf(stderr, "%s\n", copy); free(copy); p = n; } } void usage(const char *me) { char *dummy = NULL, has_color = 0; char host[256] = { 0 }; /* where to connect to */ fprintf(stderr, gettext(" *** where to connect to ***\n")); format_help("-g x", "--url", gettext("URL to ping (e.g. -g http://localhost/)")); format_help("-h x", "--hostname", gettext("hostname to ping (e.g. localhost) - use either -g or -h")); format_help("-p x", "--port", gettext("portnumber (e.g. 80) - use with -h")); format_help("-6", "--ipv6", gettext("use IPv6 when resolving/connecting")); #ifndef NO_SSL format_help("-l", "--use-ssl", gettext("connect using SSL. pinging an https URL automatically enables this setting")); #endif fprintf(stderr, gettext("\n")); /* proxy settings */ fprintf(stderr, gettext(" *** proxy settings ***\n")); format_help("-x x", "--proxy", gettext("x should be \"host:port\" which are the network settings of the http/https proxy server. ipv6 ip-address should be \"[ip:address]:port\"")); format_help("-E", NULL, gettext("fetch proxy settings from environment variables")); format_help(NULL, "--proxy-user x", gettext("username for authentication against proxy")); format_help(NULL, "--proxy-password x", gettext("password for authentication against proxy")); format_help(NULL, "--proxy-password-file x", gettext("read password for proxy authentication from file x")); format_help("-5", NULL, gettext("proxy is a socks5 server")); format_help(NULL, "--proxy-buster x", gettext("adds \"&x=[random value]\" to the request URL")); fprintf(stderr, gettext("\n")); /* timing settings */ fprintf(stderr, gettext(" *** timing settings ***\n")); format_help("-c x", "--count", gettext("how many times to ping")); format_help("-i x", "--interval", gettext("delay between each ping")); format_help("-t x", "--timeout", gettext("timeout (default: 30s)")); format_help(NULL, "--ai / --adaptive-interval", gettext("execute pings at multiples of interval relative to start, automatically enabled in ncurses output mode")); format_help("-f", "--flood", gettext("flood connect (no delays)")); fprintf(stderr, gettext("\n")); /* http settings */ fprintf(stderr, gettext(" *** HTTP settings ***\n")); format_help("-Z", "--no-cache", gettext("ask any proxies on the way not to cache the requests")); format_help(NULL, "--divert-connect", gettext("connect to a different host than in the URL given")); format_help(NULL, "--keep-cookies", gettext("return the cookies given by the HTTP server in the following request(s)")); format_help(NULL, "--no-host-header", gettext("do not add \"Host:\"-line to the request headers")); format_help("-Q", "--persistent-connections", gettext("use a persistent connection, i.e. reuse the same TCP connection for multiple HTTP requests. usually possible when 'Connection: Keep-Alive' is sent by server. adds a 'C' to the output if httping had to reconnect")); format_help("-I x", "--user-agent", gettext("use 'x' for the UserAgent header")); format_help("-R x", "--referer", gettext("use 'x' for the Referer header")); format_help(NULL, "--header", gettext("adds an extra request-header")); fprintf(stderr, gettext("\n")); /* network settings */ fprintf(stderr, gettext(" *** networking settings ***\n")); format_help(NULL, "--max-mtu", gettext("limit the MTU size")); format_help(NULL, "--no-tcp-nodelay", gettext("do not disable Naggle")); format_help(NULL, "--recv-buffer", gettext("receive buffer size")); format_help(NULL, "--tx-buffer", gettext("transmit buffer size")); format_help("-r", "--resolve-once", gettext("resolve hostname only once (useful when pinging roundrobin DNS: also takes the first DNS lookup out of the loop so that the first measurement is also correct)")); format_help("-W", NULL, gettext("do not abort the program if resolving failed: keep retrying")); format_help("-y x", "--bind-to", gettext("bind to an ip-address (and thus interface) with an optional port")); #ifdef TCP_TFO format_help("-F", "--tcp-fast-open", gettext("\"TCP fast open\" (TFO), reduces the latency of TCP connects")); #endif #ifdef linux format_help(NULL, "--priority", gettext("set priority of packets")); #endif format_help(NULL, "--tos", gettext("set TOS (type of service)")); fprintf(stderr, gettext("\n")); /* http authentication */ fprintf(stderr, gettext(" *** HTTP authentication ***\n")); format_help("-A", "--basic-auth", gettext("activate (\"basic\") authentication")); format_help("-U x", "--username", gettext("username for authentication")); format_help("-P x", "--password", gettext("password for authentication")); format_help("-T x", NULL, gettext("read the password fom the file 'x' (replacement for -P)")); fprintf(stderr, gettext("\n")); /* output settings */ fprintf(stderr, gettext(" *** output settings ***\n")); format_help("-s", "--show-statuscodes", gettext("show statuscodes")); format_help("-S", "--split-time", gettext("split measured time in its individual components (resolve, connect, send, etc.")); format_help(NULL, "--threshold-red", gettext("from what ping value to show the value in red (must be bigger than yellow), only in color mode (-Y)")); format_help(NULL, "--threshold-yellow", gettext("from what ping value to show the value in yellow")); format_help(NULL, "--threshold-show", gettext("from what ping value to show the results")); format_help(NULL, "--timestamp / --ts", gettext("put a timestamp before the measured values, use -v to include the date and -vv to show in microseconds")); format_help(NULL, "--aggregate x[,y[,z]]", gettext("show an aggregate each x[/y[/z[/etc]]] seconds")); #ifndef NO_SSL format_help("-z", "--show-fingerprint", gettext("show fingerprint (SSL)")); #endif format_help("-v", NULL, gettext("verbose mode")); fprintf(stderr, gettext("\n")); /* GET settings */ fprintf(stderr, gettext(" *** \"GET\" (instead of HTTP \"HEAD\") settings ***\n")); format_help("-G", "--get-request", gettext("do a GET request instead of HEAD (read the contents of the page as well)")); format_help("-b", "--show-transfer-speed", gettext("show transfer speed in KB/s (use with -G)")); format_help("-B", "--show-xfer-speed-compressed", gettext("like -b but use compression if available")); format_help("-L x", "--data-limit", gettext("limit the amount of data transferred (for -b) to 'x' (in bytes)")); format_help("-X", "--show-kb", gettext("show the number of KB transferred (for -b)")); fprintf(stderr, gettext("\n")); /* output mode settings */ fprintf(stderr, gettext(" *** output mode settings ***\n")); format_help("-q", "--quiet", gettext("quiet, only returncode")); format_help("-m", "--parseable-output", gettext("give machine parseable output (see also -o and -e)")); format_help("-M", NULL, gettext("json output, cannot be combined with -m")); format_help("-o rc,rc,...", "--ok-result-codes", gettext("what http results codes indicate 'ok' comma separated WITHOUT spaces inbetween default is 200, use with -e")); format_help("-e x", "--result-string", gettext("string to display when http result code doesn't match")); format_help("-n warn,crit", "--nagios-mode-1 / --nagios-mode-2", gettext("Nagios-mode: return 1 when avg. response time >= warn, 2 if >= crit, otherwhise return 0")); format_help("-N x", NULL, gettext("Nagios mode 2: return 0 when all fine, 'x' when anything failes")); format_help("-C cookie=value", "--cookie", gettext("add a cookie to the request")); format_help("-Y", "--colors", gettext("add colors")); format_help("-a", "--audible-ping", gettext("audible ping")); fprintf(stderr, gettext("\n")); /* GUI/ncurses mode */ #if defined(NC) fprintf(stderr, gettext(" *** GUI/ncurses mode settings ***\n")); format_help("-K", "--ncurses / --gui", gettext("ncurses/GUI mode")); #if defined(FW) format_help(NULL, "--draw-phase", gettext("draw phase (fourier transform) in gui")); #endif format_help(NULL, "--slow-log", gettext("when the duration is x or more, show ping line in the slow log window (the middle window)")); format_help(NULL, "--graph-limit x", gettext("do not scale to values above x")); format_help("-D", "--no-graph", gettext("do not show graphs (in ncurses/GUI mode)")); fprintf(stderr, gettext("\n")); #endif format_help("-V", "--version", gettext("show the version")); fprintf(stderr, gettext("\n")); dummy = getenv("TERM"); if (dummy) { if (strstr(dummy, "ANSI") || strstr(dummy, "xterm") || strstr(dummy, "screen")) has_color = 1; } if (gethostname(host, sizeof host)) strcpy(host, "localhost"); fprintf(stderr, gettext("Example:\n")); fprintf(stderr, "\t%s %s%s -s -Z\n\n", me, host, has_color ? " -Y" : ""); new_version_alert(); } httping-2.5/help.h000066400000000000000000000002061276547250600141520ustar00rootroot00000000000000#define SWITCHES_COLUMN_WIDTH 24 void new_version_alert(void); void version(void); void help_long(void); void usage(const char *me); httping-2.5/http.c000066400000000000000000000041071276547250600142000ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #include #include #include #include #ifndef NO_SSL #include #include "mssl.h" #endif #include "gen.h" #include "http.h" #include "io.h" #include "utils.h" int get_HTTP_headers(int socket_h, SSL *ssl_h, char **headers, int *overflow, double timeout) { char *term = NULL; int len_in=0, len=4096; char *buffer = (char *)malloc(len + 1); int rc = RC_OK; *headers = NULL; memset(buffer, 0x00, len); for(;;) { int rrc = -1; int now_n = len - len_in; #ifndef NO_SSL if (ssl_h) rrc = SSL_read(ssl_h, &buffer[len_in], now_n); else #endif rrc = read_to(socket_h, &buffer[len_in], now_n, timeout); if (rrc == 0 || rrc == RC_SHORTREAD) /* socket closed before request was read? */ { rc = RC_SHORTREAD; break; } else if (rrc < 0) { free(buffer); return rrc; } len_in += rrc; assert(len_in >= 0); assert(len_in <= len); buffer[len_in] = 0x00; if (strstr(buffer, "\r\n\r\n") != NULL) break; if (len_in >= len) { len <<= 1; buffer = (char *)realloc(buffer, len + 1); } } *headers = buffer; term = strstr(buffer, "\r\n\r\n"); if (term) *overflow = len_in - (term - buffer + 4); else *overflow = 0; return rc; } int dumb_get_HTTP_headers(int socket_h, char **headers, double timeout) { int len_in=0, len=4096; char *buffer = (char *)malloc(len); int rc = RC_OK; *headers = NULL; for(;;) { int rrc = read_to(socket_h, &buffer[len_in], 1, timeout); if (rrc == 0 || rrc == RC_SHORTREAD) /* socket closed before request was read? */ { rc = RC_SHORTREAD; break; } else if (rrc == RC_TIMEOUT) /* timeout */ { free(buffer); return RC_TIMEOUT; } len_in += rrc; buffer[len_in] = 0x00; if (memcmp(&buffer[len_in - 4], "\r\n\r\n", 4) == 0) break; if (memcmp(&buffer[len_in - 2], "\n\n", 2) == 0) /* broken proxies */ break; if (len_in == (len - 1)) { len <<= 1; buffer = (char *)realloc(buffer, len); } } *headers = buffer; return rc; } httping-2.5/http.h000066400000000000000000000003761276547250600142110ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ int get_HTTP_headers(int socket_h, SSL *ssl_h, char **headers, int *overflow, double timeout); int dumb_get_HTTP_headers(int socket_h, char **headers, double timeout); httping-2.5/httping-nl.1000066400000000000000000000174261276547250600152330ustar00rootroot00000000000000.\" Copyright Folkert van Heusden, 2003-2016 .\" .\" This file may be copied under the conditions described .\" in the GNU GENERAL PUBLIC LICENSE, version 2 .\" that can be found on the website of the free software .\" foundation. .\" .TH HTTPING 1 2016-09 "httping" .SH NAME httping - meten van de latency en doorvoorsnelheid van een http server .SH SAMENVATTING .BI "httping [" opties "] .sp een aantal opties: .BI "[\-g URL] [\-h systeem naam] [\-p port nummer] [\-x proxy systeem naam:port] [\-c aantal] [\-i interval] [\-t duur limiet] [\-s] [\-K] [\-Y] .SH BESCHRIJVING The program Het programma .B httping meet de latency van een http server. Sinds versie 1.0.6 kan ook de dooorvoorsnelheid gemeten worden. .PP .SH OPTIES .TP .B "\-5" De geselecteerde server is een SOCKS5 server. .TP .B "\-6" Schakel IPv6 mode in. Standaard instelling is IPv4. .TP .B "\-a" Hoorbare ping .TP .B "\-b" Gebruik deze optie samen met \-G. HTTPing zal dan de doorvoorsnelheid (in kB/s) tonen. .TP .B "\-B" Gebruik deze optie samen met \-G. HTTPing zal dan de doorvoorsnelheid (in kB/s) tonen. HTTPing zal echter vragen aan de webserver of deze de data comprimeerd. .TP .B "\-c aantal" Hoevaak te pingen. .TP .B "\-D" Teken geen grafieken (in ncurses (\-K) mode). .TP .B "\-e str" Als de status-code anders is dan die ingesteld is met \-o, dan zal 'str' getoond worden. .TP .B "\-E" Haal de proxy instellingen uit omgevings variabelen. .TP .B "\-F" Probeer verbindingen met "TFO (TCP Fast open)" op te zetten. Dit werkt alleen met Linux kernel 3.7 of recenter. .TP .B "\-f" Ping zo snel als mogelijk achter elkaar. .TP .B "\-G" Doe een GET-verzoek in plaats van een HEAD-verzoek. Daarmee wordt ook de pagina-inhoud opgehaald. .TP .B "\-g URL" Kies welke URL gepinged moet worden. Bijvoorbeeld: http://www.microsoft.com/ .TP .B "\-h systeem naam" In plaats van een URL kan men ook alleen een systeem naam opgeven. .TP .B "\-I str" Welke "UserAgent" te sturen naar de webserver. .TP .B "\-i interval" Hoeveel seconden (of delen daarvan) te wachten tussen het verzenden van iedere ping. .TP .B "\-K" Gebruik de ncurses gebruikers interface. .TP .B "\-L x" In combinatie met \-G zet dit een limiet op hoeveel data er binnengehaald wordt. .TP .B "\-l" Maak een SSL verbinding. Dit vereist een https-URL. .TP .B "\-m" Geef output die makkelijker met een script te bewerken is. .TP .B "\-N x" Nagios-mode 1: geef 1 terug als de gemiddel reaktie snelheid >= "warn" en 2 als die snelheid >= "crit", anders geef 0 terug. Nagios mode 2: geef 0 terug als alles goed ging, anders 'x'. .TP .B "\-n warn,crit" Schakelt HTTPing naar Nagios-plugin mode 1. Geef afsluit code 1 als de gemiddelde response tijd groter is dan 'warn', geef 2 terug als die tijd groter is dan 'crit'. Anders 0. .TP .B "\-o x,x,..." Selecteer de HTTP status-codes die als 'ok' beschouwd worden. .TP .B "\-p portnumber" Gebruik dit on combinatie met h. Het zet het port-nummer om te pingen. .TP .B "\-Q" Gebruik een blijvende verbinding, dat wil zeggen hergebruiken dezelfde TCP-verbinding voor meerdere HTTP-verzoeken. Meestal mogelijk wanneer 'Connection: Keep-Alive' is verzonden door de server. Als het bestemmingssysteem de verbinding verbroken heeft, dan zal HTTPing een \"C\" toevoegen aan de uitvoer. .TP .B "\-q" Geef geen uitvoer, alleen een teruggave code. .TP .B "\-R str" Welke "Referer" te zenden naar de webserver. .TP .B "\-r" Eenmalig systeemnaam vertalen (dit is zinvol bij het pingen van een roterende DNS, bovendien haalt het de eerste vertaling uit de ping lus zodat de 1e ping niet een bovengemiddelde tijd duurt). .TP .B "\-S" Toon alle individuele componenten (verbinden, zenden, etc) van de gemeten tijden. .TP .B "\-s" Toon de HTTP statuscodes. .TP .B "\-T x" Lees de toegangscode voor website authenticatie uit bestand 'x'. .TP .B "\-t timeout" Hoelang te wachten op een reactie van de webserver. .TP .B "\-U" Gebruik authenticatie bij toegang tot de website. Combineer dit met \-P of \-T. .TP .B "\-v" Toon meer details. .TP .B "\-W" Stop HTTPing niet als het opzoeken van de server naam niet lukt. .TP .B "\-X" Gebruik deze in combinatie met \-G. Toon hoeveel data er ontvangen werd. .TP .B "\-x proxyhost[:port] Gebruik een proxy server om een verbinding op te zetten. .TP .B "\-Y" Gebruik kleuren. .TP .B "\-z" Toon de vingerafdruk van de X.509 certificaten bij het opzetten van een SSL verbinding. .TP .B "\-\-abbreviate" Kort waardes af wanneer ze groter zijn dan 1000/1000000/etc. .TP .B "\-\-adaptive-interval" or "\-\-ai" Zorg ervoor dat pings steeds met dezelfde interval uitgevoerd worden, relatief tot het start tijdstip. deze instelling wordt automatisch aangezet in "ncurses"\-mode. .TP .B "\-\-aggregates x[,y[,z[,etc.]]]" Toon cumulatief de waardes van x[/y[/etc]] seconden. .TP .B "\-\-divert\-connect x" Gebruik niet de systeemnaam uit de URL om naar te verbinden. Verbind naar 'x'. .TP .B "\-\-draw-phase" Toon fase diagram. .TP .B "\-\-graph\-limit x" Bij het bepalen van de grafiek-bandbreedte: negeer waardes hoger dan x. .TP .B "\-\-header x" Voeg een extra verzoek-regel toe. .TP .B "\-\-keep\-cookies" Als de HTTP server cookies geeft, zend die dan mee terug bij volgende pings. .TP .B "\-\-max\-mtu x" Welke MTU te gebruiken. Kan niet groter zijn dan de MTU van de netwerk adapter. .TP .B "\-\-no\-host\-header" Voeg niet een "Host:"\-regel toe aan het verzoek. .TP .B "\-\-no\-tcp\-nodelay" Zet het Naggle-algorithme niet uit. .TP .B "\-\-priority x" Geef packets een bepaalde prioriteit. .TP .B "\-\-tos x" Configureer de TOS. .TP .B "\-\-proxy\-user x" Gebruikersnaam voor proxy authenticatie. .TP .B "\-\-proxy\-password x" Toegangscode voor proxy authenticatie. .TP .B "\-\-proxy\-password-file x" Lees toegangscode voor proxy authenticatie uit bestand 'x'. .TP .B "\-\-recv-buffer x" Configureer de grootte van de ontvangst buffer. .TP .B "\-\-slow\-log x" Als een ping-tijd meer dan x is, toon het resultaat dan in het middelste venster. .TP .B "\-\-threshold\-red x" Toon metingen in rood als de gemeten waarde meer dan x is. .TP .B "\-\-threshold\-yellow x" Toon metingen in geel als de gemeten waarde meer dan x is. .TP .B "\-\-threshold\-show x" Toon metingen alleen als ze hoger dan x zijn. .TP .B "\-\-timestamp" or "\-\-ts" Voeg een een tijdstempel toe aan de uitvoer. Gebruik \-v om ook een datum te zien en \-vv om ook microseconden te zien. .TP .B "\-\-tx-buffer x" Configureer de grootte van de zend-buffer. .TP .B "\-V" Toon versie informatie. .SH UITVOER In de \-S mode zal iets als "tijd=0.08+24.09+23.17+15.64+0.02=62.98 ms" getoond worden. De eerste waarde is hoe lang het duurde om de systeem naam te vertalen, de 2e waarde hoe lang het duurde om te verbinden, de 3e waarde geeft aan hoe lang het duurde om het verzoek te verzenden en de 4e waarde is hoelang het duurde voordat de http-server een antwoord formuleerde en terugzond. de 5e waarde geeft aan hoelang het duurde om de socket te sluiten. .SH GRAFIEK De grafiek in ncurses mode gebruikt een aantal kleuren. Groen: de waarde is minder dan de ondergrens. Rood: de waarde is hoger dan de bovengrens. Blauw: de waarde is gelimiteerd door '\-\-graph\-limit'. Cyaan: er is geen meetwaarde. .SH TOETSEN Druk + om het programma af te breken. Er zal dan een samenvatting getoond worden. In ncurses mode: + ververst het scherm, H stopt (en hervat) de grafieken en ook q zal het programma stoppen. .SH VOORBEELDEN .TP .B "httping \-g http://localhost/" Ping de HTTP server op URL http://localhost/ .TP .B "httping \-h localhost \-p 1000" Ping de HTTP server op systeem 'localhost' en port nummer 1000. .TP .SH BUGS Geen. .SH "ZIE OOK" .BR http://www.vanheusden.com/httping/ .SH NOTITIES Deze man-page beschrijft .B httping versie 2.3: andere versies kunnen iets of wat verschillen. Stuur a.u.b. correcties, toevingen en foutraporten naar mail@vanheusden.com Wanneer u een donatie wilt doen, dan kunt u Bitcoins sturen naar: 1N5Sn4jny4xVwTwSYLnf7WnFQEGoVRmTQF httping-2.5/httping-ru.1000066400000000000000000000405001276547250600152350ustar00rootroot00000000000000.\" Copyright Folkert van Heusden, 2003-2016 .\" .\" This file may be copied under the conditions described .\" in the GNU GENERAL PUBLIC LICENSE, version 2 .\" that can be found on the website of the free software .\" foundation. .\" .TH HTTPING 1 2016-09 "httping" .SH ИМЯ httping - измеряет задержку и пропускную способность веб-сервера .SH СИНТАКСИС .BI "httping [" опции "] .sp опции: .BI "[\-g url] [\-h имя_хоста] [\-p номер_порта] [\-x прокси_хост:порт] [\-c число] [\-i интервал] [\-t тайм-аут] [\-s] [\-G] [\-b] [\-L предел_передачи] [\-X] [\-l] [\-z] [\-f] [\-m] [\-o ко,...] [\-e строка]" .BI "[\-I UserAgent строка] [\-R Referer строка] [\-r] [\-n warn,crit] [\-N режим] [\-q] [\-V]" .SH ОПИСАНИЕ Утилита .B httping позволяет измерять задержку веб-сервера. Начиная с версии 1.0.6 также есть возможность измерять пропускную способность. .PP .SH ОПЦИИ .TP .B "\-5" Выбранный прокси-сервер — это SOCKS5 сервер. .TP .B "\-6" Включить режим IPv6. По умолчанию IPv4. .TP .B "\-a" Слышимый пинг .TP .B "\-b" Используйте этот переключатель вместе с '-\G'. Когда эта опция используется, показывается пропускная способность (в КБ/с). .TP .B "\-B" Используйте этот переключатель вместе с '-\G'. Просит HTTP сервер сжимать возвращаемые данные: это позволит уменьшить важность пропускной способности вашего соединения, увеличивая важность вычислительной мощности HTTP сервера. .TP .B "\-c число" Сколько проб отправить перед тем как выйти. .TP .B "\-D" Не рисовать графики в режиме ncurses (-\K). .TP .B "\-e строка" Когда код ответа отличается от указанных в '\-o', отображать данную строку. .TP .B "\-E" Получить настройки прокси-сервера из переменных окружения ('http_proxy' и 'https_proxy'). .TP .B "\-F" Попытаться использовать TCP Fast Open подключаясь к серверу (для Linux ядра версии 3.7 и более) .TP .B "\-f" Флуд пинг: не сидеть сложа руки между каждым пингом, а пинговать быстро, насколько компьютер и сеть позволит вам. .TP .B "\-G" Делать GET запрос вместо HEAD запроса: это значит, что полная страница/файл будет передан. Обратите внимание, в данном случае вы больше не измеряете задержку! .TP .B "\-g URL" Устанавливает URL для проб. К примеру: http://localhost/ .TP .B "\-h имя_хоста" Вместо '\-g' вы можете также использовать '\-h' чтобы установить имя хоста, к примеру: \-h localhost .TP .B "\-I строка" UserAgent строка для отправки веб-серверу (по умолчанию 'HTTPing <версия>'). .TP .B "\-i interval" Сколько секунд между отправкой каждой пробы. .TP .B "\-K" Включить пользовательский интерфейс ncurses. .TP .B "\-L x" Используйте этот переключатель вместе с '\-G'. Ограничивает объем передаваемых данных значением 'х'. Обратите внимание, это влияет только на содержание страницы/файла, а не на заголовки. .TP .B "\-l" Подключаться с помощью SSL: чтобы это работало вы должны задать 'https' URL или номер порта 443. .TP .B "\-m" Показывать машиночитаемый вывод (смотрите также '\-o' и '\-e'). .TP .B "\-N x" Переключает HTTPing в режим 2 Nagios плагина: возвращает 0, когда все хорошо, "х", когда что-то не так. Т.е.: 1 => Nagios состояние warning, 2 => Nagios состояние critical. .TP .B "\-n warn,crit" Переключает HTTPing в режим 1 Nagios плагина: возвращает код выхода '1', когда среднее время отклика больше "warn", и возвращает код выхода '2', когда время на средний отклик больше "crit". Во всех остальных случаях возвращает код выхода '0'. .TP .B "\-o x,x,..." Устанавливает HTTP-коды, которые рассматриваются как ОК-состояния (только с '\-m'). .TP .B "\-p portnumber" \-p может быть использован вместе с \-h. \-p выбирает номер_порта для пробы. .TP .B "\-q" Без подробностей, возвращать только код выхода. .TP .B "\-R строка" Referer строка для отправки на веб-сервер. .TP .B "\-Q" Использовать постоянное соединение, т.е. переиспользовать то же самое TCP соединение для нескольких HTTP запросов. обычно возможно когда 'Connection: Keep-Alive' отправлено сервером. добавляет 'C' в вывод если httping был вынужден переподключиться .TP .B "\-r" Резолвить имя хоста только раз: это убирает резолвинг из цикла, так что латентность DNS не измеряется. Также полезно когда вы хотите измерить только 1 веб-сервер, а DNS возвращает новый IP-адрес на каждом резолве ('round robin'). .TP .B "\-S" Разделяет измеряемую задержку на время для подключения и на время обмена запросом с HTTP сервером. .TP .B "\-s" Когда транзакция успешна завершена, показывать HTTP код ответа (200, 404 и т.д.). .TP .B "\-T x" Читать пароль для аутентификации веб-сайта из файла 'х' (вместо ввода его в командной строке). .TP .B "\-t тайм-аут" Как долго ждать ответа с другой стороны. .TP .B "\-U" Включить аутентификацию для веб-сайта. Устанавливайте имя пользователя с помощью \-U, пароль с помощью \-P (или используйте \-T, чтобы прочитать пароль из файла). .TP .B "\-v" Увеличить уровень подробностей. Покажет в выводе стандартное отклонение и даты. .TP .B "\-W" Не прерывать программу если резолвинг не удался. .TP .B "\-X" Используйте этот переключатель вместе с '\-G'. Для каждого пинга показывать количество переданных данных (за исключением заголовков). .TP .B "\-x прокси_хост[:порт] Совершать пробу с помощью прокси сервера. Обратите внимание, вы также измеряете задержку работы с прокси сервером! .TP .B "\-Y" Включить цвета .TP .B "\-z" При подключении с помощью SSL, показывать фингерпринт X509 сертификата(ов) пиров. .TP .B "\-\-abbreviate" Сокращать значения больше, чем тысяча, миллион, миллиард, и т.д. .TP .B "\-\-adaptive-interval" или "\-\-ai" (Пытается) исполнять пинг на одном интервале. Например, если интервал установлен в 1.0 секунду и t[n] от пинга до пинга является 500s с длительностью 250 мс, то следующий пинг (t[n+1]) произойдет на 501 секунде, а не на 501.25 секунде. Конечно, когда длительность пинга > больше, чем интервал, пинг будет "пропущен" (не в буквальном смысле: последовательный номер продолжится) и t[n+1] будет на 502-й секунде вместо ожидаемой 501-й. Это полезно, например, в режиме вывода библиотеки, где FFT вычисляется по длительности пинга. .TP .B "\-\-aggregates x[,y[,z[,т.д.]]]" Показывать совокупный результат каждые x[,y[,z[,т.д.]]] секунд. .TP .B "\-\-divert\-connect x" Не обращать внимания на имя хоста в URL и вместо этого подключаться к 'х'. Данный ранее URL будет запрошен у 'х'. .TP .B "\-\-draw-phase" Рисовать не только величину преобразования Фурье, но также и фазу. .TP .B "\-\-graph\-limit x" Если измеренные значения больше, чем х, то ограничить их х. .TP .B "\-\-header x" Добавить дополнительный заголовок запроса 'х'. .TP .B "\-\-keep\-cookies" Когда сервер отправляет куки, оно будет отправлено назад в следующем запросе. .TP .B "\-\-max\-mtu x" Максимальное значение MTU для использования. Не может быть больше, чем MTU сетевого интерфейса. .TP .B "\-\-no\-host\-header" Не ставить "Host:" заголовок в заголовки запроса. .TP .B "\-\-no\-tcp\-nodelay" Не отключать "задержку TCP" (Naggle). .TP .B "\-\-priority x" Установить приоритет пакетов. .TP .B "\-\-tos x" Установить тип сервиса. .TP .B "\-\-proxy\-user x" Использовать имя пользователя 'х' для аутентификации на прокси-сервере (http/socks5) (опционально). .TP .B "\-\-proxy\-password x" Использовать пароль 'х' для аутентификации на прокси-сервере (http/socks5) (опционально). .TP .B "\-\-proxy\-password-file x" Читать пароль из файла 'х' для аутентификации на прокси-сервере (http/socks5) (опционально). .TP .B "\-\-recv-buffer x" Установить размер буфера приема (в байтах). .TP .B "\-\-slow\-log x" Когда длительность больше или равна x, показывать строку пинга в окне медленного журнала (среднее окно). .TP .B "\-\-threshold\-red x" Если измеренный пинг выше, чем х (и \-Y установлен), то показываемое значение будет покрашено в красный. Если вы также используете \-\-threshold\-yellow, то это значение должно быть больше. .TP .B "\-\-threshold\-yellow x" Если измеренный пинг выше, чем х (и \-Y установлен), то показываемое значение будет покрашено в желтый. .TP .B "\-\-threshold\-show x" Если измеренный пинг выше, чем х, то результат будет отображен (по умолчанию отображается всегда). Значение х в мс. .TP .B "\-\-timestamp" or "\-\-ts" Показывать таймстамп перед строками с результатами. Используйте опцию \-v, чтобы показывать также и дату. .TP .B "\-\-tx-buffer x" Установить размер буфера передачи (в байтах). .TP .B "\-V" Показать версию и выйти. .SH ВЫВОД В режиме разделения экрана (\-S) вы увидите что-то вроде "время=0.08+24.09+23.17+15.64+0.02=62.98 мс". Первое значение — это время, которое потребовалось, чтобы зарезолвить имя хоста (или 'Н/Д', если оно не резолвилось на этой итерации, например, в режиме "резолвить один раз" (\-r)), затем время, которое потребовалось для подключения (Или \-1 в, например, постоянных соединениях (\-Q, HTTP v1.1)), после этого время, которое потребовалось, чтобы произвести операцию записи, затем, то время, которое потребовалось для HTTP сервера, чтобы обработать запрос и отправить его обратно и, наконец, время, которое потребовалось, чтобы закрыть соединение. .SH ГРАФИК График в ncurses использует цвета для кодирования смысла. Зеленый: значение меньше, чем 1 блок. Красный: значение не укладывается в график. Синий: значение было ограничено опцией -\-\-graph\-limit. Бирюзовый: нет измерения для этого момента времени. .SH КЛАВИШИ Нажмите + , чтобы выйти из программы. Это отобразит краткую информацию о том, что было измерено. В графическом интерфейсе ncurses, нажмите клавишу + для принудительной перерисовки экрана. Нажмите 'H', чтобы остановить графики (и снова, чтобы продолжить). Нажмите 'q', чтобы остановить программу (или + ). .SH ПРИМЕРЫ .TP .B "httping \-g http://localhost/" Исполнить пинг к веб-серверу на хосте "localhost". .TP .B "httping \-h localhost \-p 1000" Исполнить пинг к веб-серверу на хосте "localhost" с номером порта 1000. .TP .B "httping \-l \-g https://localhost/" Исполнить пинг к веб-серверу на хосте "localhost" с помощью соединения SSL. .TP .B "httping \-g http://localhost/ -U username -P password" Исполнить пинг к веб-серверу на хосте "localhost", используя HTTP Basic Authentication.. .SH БАГИ Нету. В этой программе полностью отсутствуют баги. .SH "СМОТРИТЕ ТАКЖЕ" .BR http://www.vanheusden.com/httping/ .SH ЗАМЕТКИ Эта страница описывает .B httping , который содержится в пакете httping-2.3; другие версии могут немного отличаться. Пожалуйста, отправляйте исправления и дополнения на mail@vanheusden.com. Сообщить об ошибках в программе можно по адресу mail@vanheusden.com. Пожалуйста, рассмотрите возможность отправки Биткоинов по адресу 1N5Sn4jny4xVwTwSYLnf7WnFQEGoVRmTQF httping-2.5/httping.1000066400000000000000000000231021276547250600146100ustar00rootroot00000000000000.\" Copyright Folkert van Heusden, 2003-2016 .\" .\" This file may be copied under the conditions described .\" in the GNU GENERAL PUBLIC LICENSE, version 2 .\" that can be found on the website of the free software .\" foundation. .\" .TH HTTPING 1 2016-09 "httping" .SH NAME httping - measure the latency and throughput of a webserver .SH SYNOPSIS .BI "httping [" options "] .sp options: .BI "[\-g url] [\-h hostname] [\-p portnumber] [\-x proxyhost:port] [\-c count] [\-i interval] [\-t timeout] [\-s] [\-G] [\-b] [\-L xferlimit] [\-X] [\-l] [\-z] [\-f] [\-m] [\-o rc,...] [\-e string]" .BI "[\-I useragent string] [\-R referer string] [\-r] [\-n warn,crit] [\-N mode] [\-q] [\-V]" .SH DESCRIPTION The program .B httping lets you measure the latency of a webserver. Since version 1.0.6 also the throughput can be measured. .PP .SH OPTIONS .TP .B "\-5" The proxy server selected is a SOCKS5 server. .TP .B "\-6" Enable IPv6 mode. Default is IPv4. .TP .B "\-a" Audible ping .TP .B "\-b" Use this switch together with '\-G'. When this option is used, the transferspeed (in KB/s) is shown. .TP .B "\-B" Use this switch together with '\-G'. Ask the HTTP server to compress the returned data: this will reduce the influence of the bandwidth of your connection while increasing the influence of the processorpower of the HTTP server. .TP .B "\-c count" How many probes to send before exiting. .TP .B "\-D" Do not draw graphs in ncurses mode (\-K). .TP .B "\-e str" When the status-code differs from the ones selected with '\-o', the given string is displayed. .TP .B "\-E" Retrieve proxy settings from environment variables ('http_proxy' and 'https_proxy'). .TP .B "\-F" Attempt TCP Fast Open while trying to connect to a server (for Linux, version 3.7 onwards of the kernel) .TP .B "\-f" Flood ping: do not sit idle between each ping but ping as fast as the computer and network allow you to. .TP .B "\-G" Do a GET request instead of a HEAD request: this means that also the complete page/file must be transferred. Note that in this case you're no longer measuring the latency! .TP .B "\-g url" This selects the url to probe. E.g.: http://localhost/ .TP .B "\-h hostname" Instead of '\-g' one can also set a hostname to probe with \-h: \-h localhost .TP .B "\-I str" UserAgent-string to send to the webserver (instead of 'HTTPing '). .TP .B "\-i interval" How many seconds to sleep between every probe sent. .TP .B "\-K" Enable ncurses user interface. .TP .B "\-L x" Use this switch together with '\-G'. Limit the amount of data transferred to 'x'. Note that this only affects the content of the page/file and not the headerdata. .TP .B "\-l" Connect using SSL: for this to work you need to give a 'https'-url or a 443 portnumber. .TP .B "\-m" Show machine readable output (also check '\-o' and '\-e'). .TP .B "\-N x" Switches HTTPing to Nagios-plugin mode 2: return 0 when everything is fine, 'x' when anything fails. E.g.: 1 => Nagios warning state, 2 => Nagios critical state. .TP .B "\-n warn,crit" Switches HTTPing to Nagios-plugin mode 1: return exitcode '1' when the average response time is bigger then 'warn', return exitcode '2' when the the average response time is bigger then 'crit'. In all other cases return exitcode '0'. .TP .B "\-o x,x,..." This selects the HTTP status-codes which are regarded as an OK-state (only with '\-m'). .TP .B "\-p portnumber" \-p can be used together with \-h. \-p selects the portnumber to probe. .TP .B "\-q" Be quiet, only return an exit-code. .TP .B "\-R str" Referer-string to send to the webserver. .TP .B "\-Q" Use a persistent connection, i.e. reuse the same TCP connection for multiple HTTP requests. Usually possible when 'Connection: Keep-Alive' is sent by server. Adds a 'C' to the output if httping had to reconnect. .TP .B "\-r" Only resolve the hostname once: this takes the resolving out of the loop so that the latency of the DNS is not measured. Also useful when you want to measure only 1 webserver while the DNS returns a different ip-address for each resolve ('roundrobin'). .TP .B "\-S" Split measured latency in time to connect and time to exchange a request with the HTTP server. .TP .B "\-s" When a successfull transaction was done, show the HTTP statuscode (200, 404, etc.). .TP .B "\-T x" Read the password for website authentication from file 'x' (instead of entering it on the command line). .TP .B "\-t timeout" How long to wait for answer from the other side. .TP .B "\-U" Enable authentication against website. Set username with \-U, set password with \-P (or \-T to read the password from a file). .TP .B "\-v" Increase verbosity mode. To show standard deviation and dates in output. .TP .B "\-W" Do not abort program if resolving fails. .TP .B "\-X" Use this switch together with '\-G'. For each "ping" show the amount of data transferred (excluding the headers). .TP .B "\-x proxyhost[:port] Probe using a proxyserver. Note that you're also measuring the latency of the proxyserver! .TP .B "\-Y" Enable colors .TP .B "\-z" When connecting using SSL, display the fingerprint of the X509 certificate(s) of the peer. .TP .B "\-\-abbreviate" Abbreviate values bigger than thousand, million, billion, etc. .TP .B "\-\-adaptive-interval" or "\-\-ai" (Try to) ping on the same interval. E.g. if interval is set to 1.0 seconds and ping a ping t[n] occurs at 500s with duration 250ms, then the next ping (t[n+1]) will happen at 501 seconds and not at 501.25 seconds. Of course when the ping duration is > bigger than the interval, a ping will be "skipped" (not literally: the sequence number will continue) and t[n+1] will then be e.g. 502s instead of the expected 501s. This is useful for example in the ncurses output mode where an fft is calculated over the ping times. .TP .B "\-\-aggregates x[,y[,z[,etc.]]]" Show aggregates every x[/y[/z[/etc]]] seconds. .TP .B "\-\-divert\-connect x" Ignore the hostname in the URL and connect to 'x' instead. The given URL will be requested at 'x'. .TP .B "\-\-draw-phase" Not only draw the magnitude of the fourier transform, draw the phase as well. .TP .B "\-\-graph\-limit x" If values measured are bigger than x, then they're limitted to x. .TP .B "\-\-header x" Add an additional request-header 'x'. .TP .B "\-\-keep\-cookies" When the server sends a cookie, it will be returned in the next request. .TP .B "\-\-max\-mtu x" Maximum MTU to use. Cannot be larger than network interface MTU. .TP .B "\-\-no\-host\-header" Do not put a "Host:"\-header in the request header. .TP .B "\-\-no\-tcp\-nodelay" Do not disable "tcp delay" (Naggle). .TP .B "\-\-priority x" Set priority of packets. .TP .B "\-\-tos x" Set type of service. .TP .B "\-\-proxy\-user x" Use username 'x' to authenticate against proxy (http/socks5) server (optional). .TP .B "\-\-proxy\-password x" Use password 'x' to authenticate against proxy (http/socks5) server (optional). .TP .B "\-\-proxy\-password-file x" Read password from file 'x' to authenticate against proxy (http/socks5) server (optional). .TP .B "\-\-recv-buffer x" Set the size of the receive buffer (in bytes). .TP .B "\-\-slow\-log x" When the duration is x or more, show ping line in the slow log window (the middle window). .TP .B "\-\-threshold\-red x" If the measured threshold is higher than x (and \-Y is given), then the shown value is colored red. If you also use \-\-threshold\-yellow, then this value must be bigger. .TP .B "\-\-threshold\-yellow x" If the measured threshold is higher than x (and \-Y is given), then the shown value is colored yellow. .TP .B "\-\-threshold\-show x" If the measured threshold is higher than x, then the result is shown (default is show always). The value x is in ms. .TP .B "\-\-timestamp" or "\-\-ts" Put a timestamp before the result-lines. Use \-v to also show a date. .TP .B "\-\-tx-buffer x" Set the size of the transmit buffer (in bytes). .TP .B "\-V" Show the version and exit. .SH OUTPUT In split mode (\-S) something like "time=0.08+24.09+23.17+15.64+0.02=62.98 ms" is shown. The first value is the time it took to resolve the hostname (or 'n/a' if it did not resolve in this iteration, e.g. in "resolve once" (\-r) mode), then the time it took to connect (or \-1 for example in persistent connection (\-Q, HTTP v1.1), after that the time it took to put the request on the wire, then the time it took for the HTTP server to process the request and send it back and lastly the time it took to close the connection. .SH GRAPH The graph in the ncurses uses colors to encode a meaning. Green: value is less than 1 block. Red: the value did not fit in the graph. Blue: the value was limitted by \-\-graph\-limit. Cyan: no measurement for that point in time. .SH KEYS Press + to exit the program. It will display a summary of what was measured. In the ncurses gui, press + to forcibly redraw the screen. Press 'H' to halt the graphs (and again to continue). Press 'q' to stop the program ( + will work too). .SH EXAMPLES .TP .B "httping \-g http://localhost/" Ping the webserver on host 'localhost'. .TP .B "httping \-h localhost \-p 1000" Ping the webserver on host 'localhost' and portnumber 1000. .TP .B "httping \-l \-g https://localhost/" Ping the webserver on host 'localhost' using an SSL connection. .TP .B "httping \-g http://localhost/ -U username -P password" Ping the webserver on host 'localhost' using the Basic HTTP Authentication. .SH BUGS None. This program is totally bug-free. .SH "SEE ALSO" .BR http://www.vanheusden.com/httping/ .SH NOTES This page describes .B httping as found in the httping-2.3 package; other versions may differ slightly. Please mail corrections and additions to mail@vanheusden.com. Report bugs in the program to mail@vanheusden.com. Please consider sending bitcoins to 1N5Sn4jny4xVwTwSYLnf7WnFQEGoVRmTQF httping-2.5/io.c000066400000000000000000000064211276547250600136310ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #include #include #include #include #include #include #include #include #include #include #include #include "gen.h" #include "error.h" ssize_t read_to(int fd, char *whereto, size_t len, double timeout) { for(;;) { ssize_t rc; struct timeval to; fd_set rfds; FD_ZERO(&rfds); FD_SET(fd, &rfds); to.tv_sec = (long)(timeout / 1000.0); to.tv_usec = (long)(timeout * 1000.0) % 1000000; rc = select(fd + 1, &rfds, NULL, NULL, &to); if (rc == 0) return RC_TIMEOUT; else if (rc == -1) { if (errno == EAGAIN) continue; if (errno == EINTR) return RC_CTRLC; set_error(gettext("read_to::select failed: %s"), strerror(errno)); return RC_SHORTREAD; } return read(fd, whereto, len); } } ssize_t myread(int fd, char *whereto, size_t len, double timeout) { ssize_t cnt=0; while(len>0) { ssize_t rc; struct timeval to; fd_set rfds; FD_ZERO(&rfds); FD_SET(fd, &rfds); to.tv_sec = (long)(timeout / 1000.0); to.tv_usec = (long)(timeout * 1000.0) % 1000000; rc = select(fd + 1, &rfds, NULL, NULL, &to); if (rc == 0) return RC_TIMEOUT; else if (rc == -1) { if (errno == EAGAIN) continue; if (errno == EINTR) return RC_CTRLC; set_error(gettext("myread::select failed: %s"), strerror(errno)); return RC_SHORTREAD; } if (FD_ISSET(fd, &rfds)) { rc = read(fd, whereto, len); if (rc == -1) { if (errno == EAGAIN) continue; if (errno == EINTR) return RC_CTRLC; set_error(gettext("myread::read failed: %s"), strerror(errno)); return RC_SHORTREAD; } else if (rc == 0) break; else { whereto += rc; len -= rc; cnt += rc; } } } return cnt; } ssize_t mywrite(int fd, char *wherefrom, size_t len, double timeout) { ssize_t cnt=0; while(len>0) { ssize_t rc; struct timeval to; fd_set wfds; FD_ZERO(&wfds); FD_SET(fd, &wfds); to.tv_sec = (long)(timeout / 1000.0); to.tv_usec = (long)(timeout * 1000.0) % 1000000; rc = select(fd + 1, NULL, &wfds, NULL, &to); if (rc == 0) return RC_TIMEOUT; else if (rc == -1) { if (errno == EAGAIN) continue; if (errno == EINTR) return RC_CTRLC; set_error(gettext("mywrite::select failed: %s"), strerror(errno)); return RC_SHORTWRITE; } rc = write(fd, wherefrom, len); if (rc == -1) { if (errno == EAGAIN) continue; if (errno == EINTR) return RC_CTRLC; set_error(gettext("mywrite::write failed: %s"), strerror(errno)); return RC_SHORTWRITE; } else if (rc == 0) break; else { wherefrom += rc; len -= rc; cnt += rc; } } return cnt; } int set_fd_nonblocking(int fd) { /* set fd to non-blocking */ if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { fprintf(stderr, gettext("set_fd_nonblocking failed! (%s)\n"), strerror(errno)); return -1; } return 0; } int set_fd_blocking(int fd) { /* set fd to blocking */ if (fcntl(fd, F_SETFL, 0) == -1) { fprintf(stderr, gettext("set_fd_blocking failed! (%s)\n"), strerror(errno)); return -1; } return 0; } httping-2.5/io.h000066400000000000000000000005461276547250600136400ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ ssize_t read_to(int fd, char *whereto, size_t len, double timeout); ssize_t myread(int fd, char *whereto, size_t len, double timeout); ssize_t mywrite(int fd, const char *wherefrom, size_t len, double timeout); int set_fd_nonblocking(int fd); int set_fd_blocking(int fd); httping-2.5/kalman.c000066400000000000000000000036021276547250600144630ustar00rootroot00000000000000/* #define _TEST */ #include #ifdef _TEST #include #include #endif double x_est_last = 0.0, P_last = 0.0, Q = 0.0, R = 0.0, K = 0.0, P = 0.0, P_temp = 0.0, x_temp_est = 0.0, x_est = 0.0, z_measured = 0.0, z_real = 0.0, sum_error_kalman = 0.0, sum_error_measure = 0.0; char first = 1; void kalman_init(double ideal_value) { /* initial values for the kalman filter */ x_est_last = 0; P_last = 0; /* the noise in the system (FIXME?) */ Q = 0.022; R = 0.617; z_real = ideal_value; /* 0.5; the ideal value we wish to measure */ first = 1; } double kalman_do(double z_measured) { /* initialize with a measurement */ if (first) { first = 0; x_est_last = z_measured; } /* do a prediction */ x_temp_est = x_est_last; P_temp = P_last + Q; /* calculate the Kalman gain */ K = P_temp * (1.0/(P_temp + R)); /* measure */ /*z_measured = z_real + frand()*0.09; the real measurement plus noise*/ /* correct */ x_est = x_temp_est + K * (z_measured - x_temp_est); P = (1- K) * P_temp; /* we have our new system */ #ifdef _TEST printf("Ideal position: %6.3f \n",z_real); printf("Mesaured position: %6.3f [diff:%.3f]\n",z_measured,fabs(z_real-z_measured)); printf("Kalman position: %6.3f [diff:%.3f]\n",x_est,fabs(z_real - x_est)); #endif sum_error_kalman += fabs(z_real - x_est); sum_error_measure += fabs(z_real-z_measured); /* update our last's */ P_last = P; x_est_last = x_est; #ifdef _TEST printf("Total error if using raw measured: %f\n",sum_error_measure); printf("Total error if using kalman filter: %f\n",sum_error_kalman); printf("Reduction in error: %d%% \n",100-(int)((sum_error_kalman/sum_error_measure)*100)); #endif return x_est; } #ifdef _TEST int main(int argc, char *argv[]) { kalman_init(0.0); for(int loop=0; loop<25; loop++) { double v = drand48(); printf("%d] %f %f\n", loop + 1, v, kalman_do(v)); } return 0; } #endif httping-2.5/kalman.h000066400000000000000000000002331276547250600144650ustar00rootroot00000000000000/* taken (and adapted) from http://www.dzone.com/snippets/simple-kalman-filter-c */ void kalman_init(double ideal_value); double kalman_do(double value); httping-2.5/license.OpenSSL000066400000000000000000000000301276547250600156730ustar00rootroot00000000000000Please see license.txt. httping-2.5/license.txt000066400000000000000000000016021276547250600152350ustar00rootroot00000000000000HTTPing is (C) 2003-2016 by folkert@vanheusden.com The AGPL version 3 applies to this program. That document can be found on the website of the free software foundation. In addition, as a special exception, the copyright holder gives permission to link the code of portions of this program with the OpenSSL library under certain conditions as described in each individual source file, and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than OpenSSL. If you modify file(s) with this exception, you may extend this exception to your version of the file(s), but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. If you delete this exception statement from all source files in the program, then also delete it here. httping-2.5/main.c000066400000000000000000001566571276547250600141670ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef NO_SSL #include #include "mssl.h" #endif #include #include #include #if defined(sun) || defined(__sun) #include #endif #ifdef NC #include #endif #include "gen.h" #include "help.h" #include "colors.h" #include "http.h" #include "io.h" #include "tcp.h" #include "res.h" #include "utils.h" #include "error.h" #include "socks5.h" #ifdef NC #include "nc.h" #endif #include "cookies.h" volatile int stop = 0; int quiet = 0; char machine_readable = 0; char json_output = 0; char show_ts = 0; int max_x = 80, max_y = 24; char nagios_mode = 0; char ncurses_mode = 0; int fd = -1; volatile char got_sigquit = 0; void handler_quit(int s) { signal(SIGQUIT, handler_quit); got_sigquit = 1; } void determine_terminal_size(int *max_y, int *max_x) { struct winsize size; *max_x = *max_y = 0; if (!isatty(1)) { *max_y = 24; *max_x = 80; } #ifdef TIOCGWINSZ else if (ioctl(1, TIOCGWINSZ, &size) == 0) { *max_y = size.ws_row; *max_x = size.ws_col; } #endif if (!*max_x || !*max_y) { char *dummy = getenv("COLUMNS"); if (dummy) *max_x = atoi(dummy); else *max_x = 80; dummy = getenv("LINES"); if (dummy) *max_y = atoi(dummy); else *max_y = 24; } } void emit_statuslines(double run_time) { #ifdef NC if (ncurses_mode) { time_t t = time(NULL); char *t_str = ctime(&t); char *dummy = strchr(t_str, '\n'); if (dummy) *dummy = 0x00; status_line(gettext("%s, run time: %.3fs, press ctrl + c to stop"), t_str, run_time); } #else (void)run_time; #endif } void emit_headers(char *in) { #ifdef NC static char shown = 0; int len_in = -1; if (!shown && ncurses_mode && in != NULL && (len_in = strlen(in) - 4) > 0) { int pos = 0, pos_out = 0; char *copy = (char *)malloc(len_in + 1), *dummy = NULL; for(pos=0; pos 1) printf(", \n"); printf("{ "); printf("\"status\" : \"%d\", ", ok); printf("\"seq\" : \"%d\", ", seq); printf("\"start_ts\" : \"%f\", ", start_ts); if (t_resolve!=NULL && t_resolve -> cur_valid) printf("\"resolve_ms\" : \"%e\", ", t_resolve -> cur); else printf("\"resolve_ms\" : \"%e\", ",-1.0); if (t_connect!=NULL && t_connect -> cur_valid) printf("\"connect_ms\" : \"%e\", ", t_connect -> cur); else printf("\"connect_ms\" : \"%e\", ",-1.0); printf("\"request_ms\" : \"%e\", ", t_request -> cur); printf("\"total_ms\" : \"%e\", ", t_total -> cur); printf("\"http_code\" : \"%d\", ", http_code); printf("\"msg\" : \"%s\", ", msg); printf("\"header_size\" : \"%d\", ", header_size); printf("\"data_size\" : \"%d\", ", data_size); printf("\"bps\" : \"%f\", ", Bps); printf("\"host\" : \"%s\", ", host); printf("\"ssl_fingerprint\" : \"%s\", ", ssl_fp ? ssl_fp : ""); printf("\"time_offset\" : \"%f\", ", toff_diff_ts); printf("\"tfo_success\" : \"%s\", ", tfo_success ? "true" : "false"); if (t_ssl -> cur_valid) printf("\"ssl_ms\" : \"%e\", ", t_ssl -> cur); printf("\"tfo_succes\" : \"%s\", ", tfo_success ? "true" : "false"); if (t_ssl !=NULL && t_ssl -> cur_valid) printf("\"ssl_ms\" : \"%e\", ", t_ssl -> cur); printf("\"write\" : \"%e\", ", t_write -> cur); printf("\"close\" : \"%e\", ", t_close -> cur); printf("\"cookies\" : \"%d\", ", n_cookies); if (stats_to != NULL && stats_to -> cur_valid) printf("\"to\" : \"%e\", ", stats_to -> cur); if (tcp_rtt_stats !=NULL && tcp_rtt_stats -> cur_valid) printf("\"tcp_rtt_stats\" : \"%e\", ", tcp_rtt_stats -> cur); printf("\"re_tx\" : \"%d\", ", re_tx); printf("\"pmtu\" : \"%d\", ", pmtu); printf("\"tos\" : \"%02x\" ", recv_tos); printf("}"); } char *get_ts_str(int verbose) { char buffer[4096] = { 0 }; struct tm *tvm = NULL; struct timeval tv; (void)gettimeofday(&tv, NULL); tvm = localtime(&tv.tv_sec); if (verbose == 1) sprintf(buffer, "%04d/%02d/%02d ", tvm -> tm_year + 1900, tvm -> tm_mon + 1, tvm -> tm_mday); else if (verbose >= 2) sprintf(buffer, "%.6f", get_ts()); if (verbose <= 1) sprintf(&buffer[strlen(buffer)], "%02d:%02d:%02d.%03d", tvm -> tm_hour, tvm -> tm_min, tvm -> tm_sec, (int)(tv.tv_usec / 1000)); return strdup(buffer); } void emit_error(int verbose, int seq, double start_ts) { char *ts = show_ts ? get_ts_str(verbose) : NULL; #ifdef NC if (ncurses_mode) { slow_log("\n%s%s", ts ? ts : "", get_error()); update_terminal(); } else #endif if (!quiet && !machine_readable && !nagios_mode && !json_output) printf("%s%s%s%s\n", ts ? ts : "", c_error, get_error(), c_normal); if (json_output) emit_json(0, seq, start_ts, NULL, NULL, NULL, -1, get_error(), -1, -1, -1, "", "", -1, 0, NULL, NULL, NULL, 0, NULL, NULL, 0, 0, 0, NULL); clear_error(); free(ts); fflush(NULL); } void handler(int sig) { #ifdef NC if (sig == SIGWINCH) win_resize = 1; else #endif { if (!json_output) fprintf(stderr, gettext("Got signal %d\n"), sig); stop = 1; } } char * read_file(const char *file) { char buffer[4096] = { 0 }, *lf = NULL; FILE *fh = fopen(file, "rb"); if (!fh) error_exit(gettext("Cannot open password-file %s"), file); if (!fgets(buffer, sizeof buffer, fh)) error_exit(gettext("Problem reading password from file %s"), file); fclose(fh); lf = strchr(buffer, '\n'); if (lf) *lf = 0x00; return strdup(buffer); } char * create_http_request_header(const char *get, char use_proxy_host, char get_instead_of_head, char persistent_connections, const char *hostname, const char *useragent, const char *referer, char ask_compression, char no_cache, const char *auth_usr, const char *auth_password, char **static_cookies, int n_static_cookies, char **dynamic_cookies, int n_dynamic_cookies, const char *proxy_buster, const char *proxy_user, const char *proxy_password, char **additional_headers, int n_additional_headers) { int index; char *request = NULL; char pb[128] = { 0 }; if (proxy_buster) { if (strchr(get, '?')) pb[0] = '&'; else pb[0] = '?'; snprintf(pb + 1, sizeof pb - 1, "%s=%ld", proxy_buster, lrand48()); } if (use_proxy_host) str_add(&request, "%s %s%s HTTP/1.%c\r\n", get_instead_of_head?"GET":"HEAD", get, pb, persistent_connections?'1':'0'); else { const char *dummy = get, *slash = NULL; if (strncasecmp(dummy, "http://", 7) == 0) dummy += 7; else if (strncasecmp(dummy, "https://", 7) == 0) dummy += 8; slash = strchr(dummy, '/'); if (slash) str_add(&request, "%s %s HTTP/1.%c\r\n", get_instead_of_head?"GET":"HEAD", slash, persistent_connections?'1':'0'); else str_add(&request, "%s / HTTP/1.%c\r\n", get_instead_of_head?"GET":"HEAD", persistent_connections?'1':'0'); } if (hostname) str_add(&request, "Host: %s\r\n", hostname); if (useragent) str_add(&request, "User-Agent: %s\r\n", useragent); else str_add(&request, "User-Agent: HTTPing v" VERSION "\r\n"); if (referer) str_add(&request, "Referer: %s\r\n", referer); if (ask_compression) str_add(&request, "Accept-Encoding: gzip,deflate\r\n"); if (no_cache) { str_add(&request, "Pragma: no-cache\r\n"); str_add(&request, "Cache-Control: no-cache\r\n"); } /* Basic Authentification */ if (auth_usr) { char auth_string[256] = { 0 }; char b64_auth_string[512] = { 0 }; sprintf(auth_string, "%s:%s", auth_usr, auth_password); enc_b64(auth_string, strlen(auth_string), b64_auth_string); str_add(&request, "Authorization: Basic %s\r\n", b64_auth_string); } /* proxy authentication */ if (proxy_user) { char ppa_string[256] = { 0 }; char b64_ppa_string[512] = { 0 }; sprintf(ppa_string, "%s:%s", proxy_user, proxy_password); enc_b64(ppa_string, strlen(ppa_string), b64_ppa_string); str_add(&request, "Proxy-Authorization: Basic %s\r\n", b64_ppa_string); } /* Cookie insertion */ for(index=0; index= sizeof in_use) error_exit(gettext("URL too big, HTTPing has a %d bytes limit"), sizeof in_use - 1); /* make url complete, if not already */ if (strncasecmp(in, "http://", 7) == 0 || strncasecmp(in, "https://", 8) == 0) /* complete url? */ { snprintf(in_use, sizeof in_use - 1, "%s", in); if (strchr(&in[8], '/') == NULL) in_use[strlen(in_use)] = '/'; } else if (strchr(in, '/')) /* hostname + location without 'http://'? */ sprintf(in_use, "http://%s", in); else if (use_ssl) sprintf(in_use, "https://%s/", in); else sprintf(in_use, "http://%s/", in); /* sanity check */ if (strncasecmp(in_use, "http://", 7) == 0 && use_ssl) error_exit(gettext("using \"http://\" with SSL enabled (-l)")); *complete_url = strdup(in_use); /* fetch hostname */ if (strncasecmp(in_use, "http://", 7) == 0) *hostname = strdup(&in_use[7]); else /* https */ *hostname = strdup(&in_use[8]); dummy = strchr(*hostname, '/'); if (dummy) *dummy = 0x00; /* fetch port number */ if (use_ssl || strncasecmp(in, "https://", 8) == 0) *portnr = 443; else *portnr = 80; if (!use_ipv6) { char *at = strchr(*hostname, '@'); char *colon = strchr(*hostname, ':'); char *colon2 = colon ? strchr(colon + 1, ':') : NULL; if (colon2) { *colon2 = 0x00; *portnr = atoi(colon2 + 1); if (at) { *colon = 0x00; *at = 0x00; *auth_user = strdup(*hostname); *auth_password = strdup(colon + 1); } } else if (colon) { if (colon < at) { *colon = 0x00; *at = 0x00; *auth_user = strdup(*hostname); *auth_password = strdup(colon + 1); } else if (at) { *at = 0x00; *auth_user = strdup(*hostname); } else { *colon = 0x00; *portnr = atoi(colon + 1); } } } /* fetch path */ dummy = strchr(&in_use[8], '/'); if (dummy) *path = strdup(dummy); else *path = strdup("/"); } typedef struct { int interval, last_ts; double value, sd, min, max; int n_values; } aggregate_t; void set_aggregate(char *in, int *n_aggregates, aggregate_t **aggregates) { char *dummy = in; *n_aggregates = 0; for(;dummy;) { (*n_aggregates)++; *aggregates = (aggregate_t *)realloc(*aggregates, *n_aggregates * sizeof(aggregate_t)); memset(&(*aggregates)[*n_aggregates - 1], 0x00, sizeof(aggregate_t)); (*aggregates)[*n_aggregates - 1].interval = atoi(dummy); (*aggregates)[*n_aggregates - 1].max = -MY_DOUBLE_INF; (*aggregates)[*n_aggregates - 1].min = MY_DOUBLE_INF; dummy = strchr(dummy, ','); if (dummy) dummy++; } } void do_aggregates(double cur_ms, int cur_ts, int n_aggregates, aggregate_t *aggregates, int verbose, char show_ts) { int index=0; /* update measurements */ for(index=0; index aggregates[index].max) aggregates[index].max = cur_ms; aggregates[index].sd += cur_ms * cur_ms; aggregates[index].n_values++; } /* emit */ for(index=0; index 0; index++) { aggregate_t *a = &aggregates[index]; if (cur_ts - a -> last_ts >= a -> interval) { char *line = NULL; double avg = a -> n_values ? a -> value / (double)a -> n_values : -1.0; char *ts = get_ts_str(verbose); str_add(&line, "%s", show_ts ? ts : ""); free(ts); str_add(&line, gettext("AGG[%d]: %d values, min/avg/max%s = %.1f/%.1f/%.1f"), a -> interval, a -> n_values, verbose ? gettext("/sd") : "", a -> min, avg, a -> max); if (verbose) { double sd = -1.0; if (a -> n_values) sd = sqrt((a -> sd / (double)a -> n_values) - pow(avg, 2.0)); str_add(&line, "/%.1f", sd); } str_add(&line, " ms"); #ifdef NC if (ncurses_mode) slow_log("\n%s", line); else #endif printf("%s\n", line); free(line); aggregates[index].value = aggregates[index].sd = 0.0; aggregates[index].min = MY_DOUBLE_INF; aggregates[index].max = -MY_DOUBLE_INF; aggregates[index].n_values = 0; aggregates[index].last_ts = cur_ts; } } } void fetch_proxy_settings(char **proxy_user, char **proxy_password, char **proxy_host, int *proxy_port, char use_ssl, char use_ipv6) { char *str = getenv(use_ssl ? "https_proxy" : "http_proxy"); if (!str) { /* FIXME from wgetrc/curlrc? */ } if (str) { char *path = NULL, *url = NULL; interpret_url(str, &path, proxy_host, proxy_port, use_ipv6, use_ssl, &url, proxy_user, proxy_password); free(url); free(path); } } void parse_nagios_settings(const char *in, double *nagios_warn, double *nagios_crit) { char *dummy = strchr(in, ','); if (!dummy) error_exit(gettext("-n: missing parameter\n")); *nagios_warn = atof(in); *nagios_crit = atof(dummy + 1); } void parse_bind_to(const char *in, struct sockaddr_in *bind_to_4, struct sockaddr_in6 *bind_to_6, struct sockaddr_in **bind_to) { char *dummy = strchr(in, ':'); if (dummy) { *bind_to = (struct sockaddr_in *)bind_to_6; memset(bind_to_6, 0x00, sizeof *bind_to_6); bind_to_6 -> sin6_family = AF_INET6; if (inet_pton(AF_INET6, in, &bind_to_6 -> sin6_addr) != 1) error_exit(gettext("cannot convert ip address '%s' (for -y)\n"), in); } else { *bind_to = (struct sockaddr_in *)bind_to_4; memset(bind_to_4, 0x00, sizeof *bind_to_4); bind_to_4 -> sin_family = AF_INET; if (inet_pton(AF_INET, in, &bind_to_4 -> sin_addr) != 1) error_exit(gettext("cannot convert ip address '%s' (for -y)\n"), in); } } time_t parse_date_from_response_headers(const char *in) { char *date = NULL, *komma = NULL; if (in == NULL) return -1; date = strstr(in, "\nDate:"); komma = date ? strchr(date, ',') : NULL; if (date && komma) { struct tm tm; memset(&tm, 0x00, sizeof tm); /* 22 Feb 2015 09:13:56 */ if (strptime(komma + 1, "%d %b %Y %H:%M:%S %Z", &tm)) return mktime(&tm); } return -1; } int calc_page_age(const char *in, const time_t their_ts) { int age = -1; if (in != NULL && their_ts > 0) { char *date = strstr(in, "\nLast-Modified:"); char *komma = date ? strchr(date, ',') : NULL; if (date && komma) { struct tm tm; memset(&tm, 0x00, sizeof tm); /* 22 Feb 2015 09:13:56 */ if (strptime(komma + 1, "%d %b %Y %H:%M:%S %Z", &tm)) age = their_ts - mktime(&tm); } } return age; } const char *get_location(const char *host, int port, char use_ssl, char *reply) { if (reply) { char *copy = strdup(reply); char *head = strstr(copy, "\nLocation:"); char *lf = head ? strchr(head + 1, '\n') : NULL; if (head) { char *buffer = NULL; char *dest = head + 11; if (lf) *lf = 0x00; if (memcmp(dest, "http", 4) == 0) str_add(&buffer, "%s", dest); else str_add(&buffer, "http%s://%s:%d%s", use_ssl ? "s" : "", host, port, dest); free(copy); return buffer; } free(copy); } return NULL; } char check_compressed(const char *reply) { if (reply != NULL) { char *encoding = strstr(reply, "\nContent-Encoding:"); if (encoding) { char *dummy = strchr(encoding + 1, '\r'); if (dummy) *dummy = 0x00; dummy = strchr(encoding + 1, '\n'); if (dummy) *dummy = 0x00; if (strstr(encoding, "gzip") == 0 || strstr(encoding, "deflate") == 0) return 1; } } return 0; } int nagios_result(int ok, int nagios_mode, int nagios_exit_code, double avg_httping_time, double nagios_warn, double nagios_crit) { if (nagios_mode == 1) { if (ok == 0) { printf(gettext("CRITICAL - connecting failed: %s"), get_error()); return 2; } else if (avg_httping_time >= nagios_crit) { printf(gettext("CRITICAL - average httping-time is %.1f\n"), avg_httping_time); return 2; } else if (avg_httping_time >= nagios_warn) { printf(gettext("WARNING - average httping-time is %.1f\n"), avg_httping_time); return 1; } printf(gettext("OK - average httping-time is %.1f (%s)|ping=%f\n"), avg_httping_time, get_error(), avg_httping_time); return 0; } else if (nagios_mode == 2) { const char *err = get_error(); if (ok && err[0] == 0x00) { printf(gettext("OK - all fine, avg httping time is %.1f|ping=%f\n"), avg_httping_time, avg_httping_time); return 0; } printf(gettext("%s: - failed: %s"), nagios_exit_code == 1?"WARNING":(nagios_exit_code == 2?"CRITICAL":"ERROR"), err); return nagios_exit_code; } return -1; } void proxy_to_host_and_port(char *in, char **proxy_host, int *proxy_port) { if (in[0] == '[') { char *dummy = NULL; *proxy_host = strdup(in + 1); dummy = strchr(*proxy_host, ']'); if (dummy) { *dummy = 0x00; /* +2: ']:' */ *proxy_port = atoi(dummy + 2); } } else { char *dummy = strchr(in, ':'); *proxy_host = in; if (dummy) { *dummy=0x00; *proxy_port = atoi(dummy + 1); } } } void stats_close(int *fd, stats_t *t_close, char is_failure) { double t_start = get_ts(), t_end = -1;; if (is_failure) failure_close(*fd); else close(*fd); *fd = -1; t_end = get_ts(); update_statst(t_close, (t_end - t_start) * 1000.0); } void add_header(char ***additional_headers, int *n_additional_headers, const char *in) { *additional_headers = (char **)realloc(*additional_headers, (*n_additional_headers + 1) * sizeof(char **)); (*additional_headers)[*n_additional_headers] = strdup(in); (*n_additional_headers)++; } void free_headers(char **additional_headers, int n_additional_headers) { int index = 0; for(index=0; index 0) fprintf(stderr, gettext("internal error! (curncount)\n")); if (count == -1) dummy = curncount; printf(gettext("%s%d%s connects, %s%d%s ok, %s%3.2f%%%s failed, time %s%s%.0fms%s\n"), c_yellow, curncount, c_normal, c_green, ok, c_normal, c_red, (((double)err) / ((double)dummy)) * 100.0, c_normal, c_blue, c_bright, total_took * 1000.0, c_normal); if (ok > 0) { printf(gettext("round-trip min/avg/max%s = %s%.1f%s/%s%.1f%s/%s%.1f%s"), verbose ? gettext("/sd") : "", c_bright, t_total -> min, c_normal, c_bright, avg_httping_time, c_normal, c_bright, t_total -> max, c_normal); if (verbose) { double sd_final = t_total -> n ? sqrt((t_total -> sd / (double)t_total -> n) - pow(avg_httping_time, 2.0)) : -1.0; printf("/%.1f", sd_final); } printf(" ms\n"); if (bps) printf(gettext("Transfer speed: min/avg/max = %s%f%s/%s%f%s/%s%f%s KB\n"), c_bright, bps -> Bps_min / 1024, c_normal, c_bright, (bps -> Bps_avg / (double)ok) / 1024.0, c_normal, c_bright, bps -> Bps_max / 1024.0, c_normal); } } int main(int argc, char *argv[]) { double started_at = -1; char do_fetch_proxy_settings = 0; char *hostname = NULL; char *proxy_host = NULL, *proxy_user = NULL, *proxy_password = NULL; int proxy_port = 8080; int portnr = 80; char *get = NULL, *request = NULL; int req_len = 0; int c = 0; int count = -1, curncount = 0; double wait = 1.0; char wait_set = 0; int audible = 0; int ok = 0, err = 0; double timeout = 30.0; char show_statuscodes = 0; char use_ssl = 0; const char *ok_str = "200"; const char *err_str = "-1"; const char *useragent = NULL; const char *referer = NULL; const char *auth_password = NULL; const char *auth_usr = NULL; char **static_cookies = NULL, **dynamic_cookies = NULL; int n_static_cookies = 0, n_dynamic_cookies = 0; char resolve_once = 0; char have_resolved = 0; double nagios_warn=0.0, nagios_crit=0.0; int nagios_exit_code = 2; double avg_httping_time = -1.0; int get_instead_of_head = 0; char show_Bps = 0, ask_compression = 0; bps_t bps; int Bps_limit = -1; char show_bytes_xfer = 0, show_fp = 0; SSL *ssl_h = NULL; BIO *s_bio = NULL; struct sockaddr_in *bind_to = NULL; struct sockaddr_in bind_to_4; struct sockaddr_in6 bind_to_6; char split = 0, use_ipv6 = 0; char persistent_connections = 0, persistent_did_reconnect = 0; char no_cache = 0; char use_tfo = 0; char abort_on_resolve_failure = 1; double offset_yellow = -1, offset_red = -1; char colors = 0; int verbose = 0; double offset_show = -1.0; char add_host_header = 1; char *proxy_buster = NULL; char proxy_is_socks5 = 0; char *url = NULL, *complete_url = NULL; int n_aggregates = 0; aggregate_t *aggregates = NULL; char *au_dummy = NULL, *ap_dummy = NULL; stats_t t_connect, t_request, t_total, t_resolve, t_write, t_ssl, t_close, stats_to, tcp_rtt_stats, stats_header_size; char first_resolve = 1; double graph_limit = MY_DOUBLE_INF; char nc_graph = 1; char adaptive_interval = 0; double show_slow_log = MY_DOUBLE_INF; char use_tcp_nodelay = 1; int max_mtu = -1; int write_sleep = 500; /* in us (microseconds), determines resolution of transmit time determination */ char keep_cookies = 0; char abbreviate = 0; char *divert_connect = NULL; int recv_buffer_size = -1, tx_buffer_size = -1; int priority = -1, send_tos = -1; char **additional_headers = NULL; int n_additional_headers = 0; #ifndef NO_SSL SSL_CTX *client_ctx = NULL; #endif struct sockaddr_in6 addr; struct addrinfo *ai = NULL, *ai_use = NULL; struct addrinfo *ai_proxy = NULL, *ai_use_proxy = NULL; static struct option long_options[] = { {"aggregate", 1, NULL, 9 }, {"url", 1, NULL, 'g' }, {"hostname", 1, NULL, 'h' }, {"port", 1, NULL, 'p' }, {"proxy", 1, NULL, 'x' }, {"count", 1, NULL, 'c' }, {"persistent-connections", 0, NULL, 'Q' }, {"interval", 1, NULL, 'i' }, {"timeout", 1, NULL, 't' }, {"ipv6", 0, NULL, '6' }, {"show-statuscodes", 0, NULL, 's' }, {"split-time", 0, NULL, 'S' }, {"get-request", 0, NULL, 'G' }, {"show-transfer-speed", 0, NULL, 'b' }, {"show-xfer-speed-compressed", 0, NULL, 'B' }, {"data-limit", 1, NULL, 'L' }, {"show-kb", 0, NULL, 'X' }, {"no-cache", 0, NULL, 'Z' }, #ifndef NO_SSL {"use-ssl", 0, NULL, 'l' }, {"show-fingerprint", 0, NULL, 'z' }, #endif {"flood", 0, NULL, 'f' }, {"audible-ping", 0, NULL, 'a' }, {"parseable-output", 0, NULL, 'm' }, {"ok-result-codes", 1, NULL, 'o' }, {"result-string", 1, NULL, 'e' }, {"user-agent", 1, NULL, 'I' }, {"referer", 1, NULL, 'S' }, {"resolve-once",0, NULL, 'r' }, {"nagios-mode-1", 1, NULL, 'n' }, {"nagios-mode-2", 1, NULL, 'n' }, {"bind-to", 1, NULL, 'y' }, {"quiet", 0, NULL, 'q' }, {"username", 1, NULL, 'U' }, {"password", 1, NULL, 'P' }, {"cookie", 1, NULL, 'C' }, {"colors", 0, NULL, 'Y' }, {"offset-yellow", 1, NULL, 1 }, {"threshold-yellow", 1, NULL, 1 }, {"offset-red", 1, NULL, 2 }, {"threshold-red", 1, NULL, 2 }, {"offset-show", 1, NULL, 3 }, {"show-offset", 1, NULL, 3 }, {"threshold-show", 1, NULL, 3 }, {"show-threshold", 1, NULL, 3 }, {"timestamp", 0, NULL, 4 }, {"ts", 0, NULL, 4 }, {"no-host-header", 0, NULL, 5 }, {"proxy-buster", 1, NULL, 6 }, {"proxy-user", 1, NULL, 7 }, {"proxy-password", 1, NULL, 8 }, {"proxy-password-file", 1, NULL, 10 }, {"graph-limit", 1, NULL, 11 }, {"adaptive-interval", 0, NULL, 12 }, {"ai", 0, NULL, 12 }, {"slow-log", 0, NULL, 13 }, {"draw-phase", 0, NULL, 14 }, {"no-tcp-nodelay", 0, NULL, 15 }, {"max-mtu", 1, NULL, 16 }, {"keep-cookies", 0, NULL, 17 }, {"abbreviate", 0, NULL, 18 }, {"divert-connect", 1, NULL, 19 }, {"recv-buffer", 1, NULL, 20 }, {"tx-buffer", 1, NULL, 21 }, {"priority", 1, NULL, 23 }, {"tos", 1, NULL, 24 }, {"header", 1, NULL, 25 }, #ifdef NC {"ncurses", 0, NULL, 'K' }, {"gui", 0, NULL, 'K' }, #ifdef FW {"no-graph", 0, NULL, 'D' }, #endif #endif {"version", 0, NULL, 'V' }, {"help", 0, NULL, 22 }, {NULL, 0, NULL, 0 } }; bps.Bps_min = 1 << 30; bps.Bps_max = -bps.Bps_min; bps.Bps_avg = 0; setlocale(LC_ALL, ""); bindtextdomain("httping", LOCALEDIR); textdomain("httping"); init_statst(&t_resolve); init_statst(&t_connect); init_statst(&t_write); init_statst(&t_request); init_statst(&t_total); init_statst(&t_ssl); init_statst(&t_close); init_statst(&stats_to); #if defined(linux) || defined(__FreeBSD__) init_statst(&tcp_rtt_stats); #endif init_statst(&stats_header_size); determine_terminal_size(&max_y, &max_x); signal(SIGPIPE, SIG_IGN); while((c = getopt_long(argc, argv, "DKEA5MvYWT:ZQ6Sy:XL:bBg:h:p:c:i:Gx:t:o:e:falqsmV?I:R:rn:N:zP:U:C:F", long_options, NULL)) != -1) { switch(c) { case 25: add_header(&additional_headers, &n_additional_headers, optarg); break; case 24: send_tos = atoi(optarg); break; case 23: #ifdef linux priority = atoi(optarg); #else error_exit("Setting the network priority is only supported on Linux.\n"); #endif break; case 21: tx_buffer_size = atoi(optarg); break; case 20: recv_buffer_size = atoi(optarg); break; case 19: divert_connect = optarg; break; case 18: abbreviate = 1; break; case 17: keep_cookies = 1; break; case 16: max_mtu = atoi(optarg); break; case 15: use_tcp_nodelay = 0; break; #ifdef NC case 14: draw_phase = 1; break; #endif case 13: show_slow_log = atof(optarg); break; case 12: adaptive_interval = 1; break; case 11: graph_limit = atof(optarg); break; #ifdef NC case 'K': ncurses_mode = 1; adaptive_interval = 1; if (!wait_set) wait = 0.5; break; #ifdef FW case 'D': nc_graph = 0; break; #endif #endif case 'E': do_fetch_proxy_settings = 1; break; case 'A': fprintf(stderr, gettext("\n *** -A is no longer required ***\n\n")); break; case 'M': json_output = 1; break; case 'v': verbose++; break; case 1: offset_yellow = atof(optarg); break; case 2: offset_red = atof(optarg); break; case 3: offset_show = atof(optarg); break; case 4: show_ts = 1; break; case 5: add_host_header = 0; break; case 6: proxy_buster = optarg; break; case '5': proxy_is_socks5 = 1; break; case 7: proxy_user = optarg; break; case 8: proxy_password = optarg; break; case 9: set_aggregate(optarg, &n_aggregates, &aggregates); break; case 10: proxy_password = read_file(optarg); break; case 'Y': colors = 1; break; case 'W': abort_on_resolve_failure = 0; break; case 'T': auth_password = read_file(optarg); break; case 'Z': no_cache = 1; break; case '6': use_ipv6 = 1; break; case 'S': split = 1; break; case 'Q': persistent_connections = 1; break; case 'y': parse_bind_to(optarg, &bind_to_4, &bind_to_6, &bind_to); break; case 'z': show_fp = 1; break; case 'X': show_bytes_xfer = 1; break; case 'L': Bps_limit = atoi(optarg); break; case 'B': show_Bps = 1; ask_compression = 1; break; case 'b': show_Bps = 1; break; case 'e': err_str = optarg; break; case 'o': ok_str = optarg; break; case 'x': proxy_to_host_and_port(optarg, &proxy_host, &proxy_port); break; case 'g': url = optarg; break; case 'r': resolve_once = 1; break; case 'h': free(url); url = NULL; str_add(&url, "http://%s/", optarg); break; case 'p': portnr = atoi(optarg); break; case 'c': count = atoi(optarg); break; case 'i': wait = atof(optarg); if (wait < 0.0) error_exit(gettext("-i cannot have a value smaller than zero")); wait_set = 1; break; case 't': timeout = atof(optarg); break; case 'I': useragent = optarg; break; case 'R': referer = optarg; break; case 'a': audible = 1; break; case 'f': wait = 0; wait_set = 1; adaptive_interval = 0; break; case 'G': get_instead_of_head = 1; break; #ifndef NO_SSL case 'l': use_ssl = 1; break; #endif case 'm': machine_readable = 1; break; case 'q': quiet = 1; break; case 's': show_statuscodes = 1; break; case 'V': version(); return 0; case 'n': if (nagios_mode) error_exit(gettext("-n and -N are mutual exclusive\n")); else nagios_mode = 1; parse_nagios_settings(optarg, &nagios_warn, &nagios_crit); break; case 'N': if (nagios_mode) error_exit(gettext("-n and -N are mutual exclusive\n")); nagios_mode = 2; nagios_exit_code = atoi(optarg); break; case 'P': auth_password = optarg; break; case 'U': auth_usr = optarg; break; case 'C': add_cookie(&static_cookies, &n_static_cookies, optarg); break; case 'F': #ifdef TCP_TFO use_tfo = 1; #else fprintf(stderr, gettext("Warning: TCP TFO is not supported. Disabling.\n")); #endif break; case 22: version(); usage(argv[0]); return 0; case '?': default: fprintf(stderr, "\n"); version(); fprintf(stderr, gettext("\n\nPlease run:\n\t%s --help\nto see a list of options.\n\n"), argv[0]); return 1; } } if (do_fetch_proxy_settings) fetch_proxy_settings(&proxy_user, &proxy_password, &proxy_host, &proxy_port, use_ssl, use_ipv6); if (optind < argc) url = argv[optind]; if (!url) { fprintf(stderr, gettext("No URL/host to ping given\n\n")); return 1; } if (machine_readable + json_output + ncurses_mode > 1) error_exit(gettext("Cannot combine -m, -M and -K")); if ((machine_readable || json_output) && n_aggregates > 0) error_exit(gettext("Aggregates can only be used in non-machine/json-output mode")); clear_error(); if (!(get_instead_of_head || use_ssl) && show_Bps) error_exit(gettext("-b/-B can only be used when also using -G (GET instead of HEAD) or -l (use SSL)\n")); if (colors) set_colors(ncurses_mode); if (!machine_readable && !json_output) printf("%s%s", c_normal, c_white); interpret_url(url, &get, &hostname, &portnr, use_ipv6, use_ssl, &complete_url, &au_dummy, &ap_dummy); if (!auth_usr) auth_usr = au_dummy; if (!auth_password) auth_password = ap_dummy; #ifdef NC if (ncurses_mode) { if (wait == 0.0) wait = 0.001; init_ncurses_ui(graph_limit, 1.0 / wait, colors); } #endif if (strncmp(complete_url, "https://", 8) == 0 && !use_ssl) { use_ssl = 1; #ifdef NC if (ncurses_mode) { slow_log(gettext("\nAuto enabling SSL due to https-URL\n")); update_terminal(); } else #endif { fprintf(stderr, gettext("Auto enabling SSL due to https-URL\n")); } } if (use_tfo && use_ssl) error_exit(gettext("TCP Fast open and SSL not supported together\n")); if (verbose) { #ifdef NC if (ncurses_mode) { slow_log(gettext("\nConnecting to host %s, port %d and requesting file %s"), hostname, portnr, get); if (proxy_host) slow_log(gettext("\nUsing proxyserver: %s:%d"), proxy_host, proxy_port); } else #endif { printf(gettext("Connecting to host %s, port %d and requesting file %s\n\n"), hostname, portnr, get); if (proxy_host) fprintf(stderr, gettext("Using proxyserver: %s:%d\n"), proxy_host, proxy_port); } } #ifndef NO_SSL if (use_ssl) { client_ctx = initialize_ctx(ask_compression); if (!client_ctx) { set_error(gettext("problem creating SSL context")); goto error_exit; } } #endif if (!quiet && !machine_readable && !nagios_mode && !json_output) { #ifdef NC if (ncurses_mode) slow_log("\nPING %s:%d (%s):", hostname, portnr, get); else #endif printf("PING %s%s:%s%d%s (%s):\n", c_green, hostname, c_bright, portnr, c_normal, get); } if (json_output) printf("[\n"); if (adaptive_interval && wait <= 0.0) error_exit(gettext("Interval must be > 0 when using adaptive interval")); signal(SIGINT, handler); signal(SIGTERM, handler); signal(SIGQUIT, handler_quit); timeout *= 1000.0; /* change to ms */ /* if (follow_30x) { get headers const char *get_location(const char *host, int port, char use_ssl, char *reply) set new host/port/path/etc } */ started_at = get_ts(); if (proxy_host) { #ifdef NC if (ncurses_mode) { slow_log(gettext("\nResolving hostname %s"), proxy_host); update_terminal(); } #endif if (resolve_host(proxy_host, &ai_proxy, use_ipv6, proxy_port) == -1) error_exit(get_error()); ai_use_proxy = select_resolved_host(ai_proxy, use_ipv6); if (!ai_use_proxy) error_exit(gettext("No valid IPv4 or IPv6 address found for %s"), proxy_host); } else if (resolve_once) { char *res_host = divert_connect ? divert_connect : hostname; #ifdef NC if (ncurses_mode) { slow_log(gettext("\nResolving hostname %s"), res_host); update_terminal(); } #endif if (resolve_host(res_host, &ai, use_ipv6, portnr) == -1) { err++; emit_error(verbose, -1, started_at); have_resolved = 0; if (abort_on_resolve_failure) error_exit(get_error()); } ai_use = select_resolved_host(ai, use_ipv6); if (!ai_use) { set_error(gettext("No valid IPv4 or IPv6 address found for %s"), res_host); if (abort_on_resolve_failure) error_exit(get_error()); /* do not emit the resolve-error here: as 'have_resolved' is set to 0 next, the program will try to resolve again anyway this prevents a double error-message while err is increased only once */ have_resolved = 0; } if (have_resolved) get_addr(ai_use, &addr); } if (persistent_connections) fd = -1; while((curncount < count || count == -1) && stop == 0) { double dstart = -1.0, dend = -1.0, dafter_connect = 0.0, dafter_resolve = 0.0, dafter_write_complete = 0.0; char *reply = NULL; double Bps = 0; char is_compressed = 0; long long int bytes_transferred = 0; time_t their_ts = 0; int age = -1; char *sc = NULL, *scdummy = NULL; char *fp = NULL; int re_tx = 0, pmtu = 0, recv_tos = 0; socklen_t recv_tos_len = sizeof recv_tos; dstart = get_ts(); for(;;) { char did_reconnect = 0; int rc = -1; int persistent_tries = 0; int len = 0, overflow = 0, headers_len = 0; char req_sent = 0; double dummy_ms = 0.0; double their_est_ts = -1.0, toff_diff_ts = -1.0; char tfo_success = 0; double ssl_handshake = 0.0; char cur_have_resolved = 0; #if defined(linux) || defined(__FreeBSD__) struct tcp_info info; socklen_t info_len = sizeof(struct tcp_info); #endif curncount++; persistent_loop: if ((!resolve_once || (resolve_once == 1 && have_resolved == 0)) && fd == -1 && proxy_host == NULL) { char *res_host = divert_connect ? divert_connect : hostname; memset(&addr, 0x00, sizeof addr); #ifdef NC if (ncurses_mode && first_resolve) { slow_log(gettext("\nResolving hostname %s"), res_host); update_terminal(); first_resolve = 0; } #endif if (ai) { freeaddrinfo(ai); ai_use = ai = NULL; } if (resolve_host(res_host, &ai, use_ipv6, portnr) == -1) { err++; emit_error(verbose, curncount, dstart); if (abort_on_resolve_failure) error_exit(get_error()); break; } ai_use = select_resolved_host(ai, use_ipv6); if (!ai_use) { set_error(gettext("No valid IPv4 or IPv6 address found for %s"), res_host); emit_error(verbose, curncount, dstart); err++; if (abort_on_resolve_failure) error_exit(get_error()); break; } get_addr(ai_use, &addr); cur_have_resolved = have_resolved = 1; } if (cur_have_resolved) { dafter_resolve = get_ts(); dummy_ms = (dafter_resolve - dstart) * 1000.0; update_statst(&t_resolve, dummy_ms); } free(request); request = create_http_request_header(proxy_host ? complete_url : get, proxy_host ? 1 : 0, get_instead_of_head, persistent_connections, add_host_header ? hostname : NULL, useragent, referer, ask_compression, no_cache, auth_usr, auth_password, static_cookies, n_static_cookies, dynamic_cookies, keep_cookies ? n_dynamic_cookies : 0, proxy_buster, proxy_user, proxy_password, additional_headers, n_additional_headers); req_len = strlen(request); if (req_len >= 4096) { char *line = NULL; static int notify_cnt = 0; notify_cnt++; if (notify_cnt == MAX_SHOW_SUPPRESSION + 1) str_add(&line, gettext("Will no longer inform about request headers too large.")); else if (notify_cnt <= MAX_SHOW_SUPPRESSION) str_add(&line, gettext("Request headers > 4KB! (%d bytes) This may give failures with some HTTP servers."), req_len); if (line) { #ifdef NC if (ncurses_mode) slow_log("\n%s", line); else #endif printf("%s\n", line); } free(line); } if ((persistent_connections && fd < 0) || !persistent_connections) { int rc = -1; struct addrinfo *ai_dummy = proxy_host ? ai_use_proxy : ai_use; fd = create_socket((struct sockaddr *)bind_to, ai_dummy, recv_buffer_size, tx_buffer_size, max_mtu, use_tcp_nodelay, priority, send_tos); if (fd < 0) rc = fd; /* FIXME need to fix this, this is ugly */ else if (proxy_host) { if (proxy_is_socks5) rc = socks5connect(fd, ai_dummy, timeout, proxy_user, proxy_password, hostname, portnr, abort_on_resolve_failure); #ifndef NO_SSL else if (use_ssl) rc = connect_ssl_proxy(fd, ai_dummy, timeout, proxy_user, proxy_password, hostname, portnr, &use_tfo); #endif else rc = connect_to(fd, ai_dummy, timeout, &use_tfo, request, req_len, &req_sent); } else { rc = connect_to(fd, ai_dummy, timeout, &use_tfo, request, req_len, &req_sent); } if (rc < 0) { failure_close(fd); fd = rc; /* FIXME need to fix this */ } did_reconnect = 1; } if (fd == RC_CTRLC) /* ^C pressed */ break; if (fd < 0) { emit_error(verbose, curncount, dstart); fd = -1; } if (fd >= 0) { /* set fd blocking */ if (set_fd_blocking(fd) == -1) /* FIXME redundant? already in connect_to etc? */ { stats_close(&fd, &t_close, 1); break; } #ifndef NO_SSL if (use_ssl && ssl_h == NULL) { int rc = connect_ssl(fd, client_ctx, &ssl_h, &s_bio, timeout, &ssl_handshake); if (rc == 0) update_statst(&t_ssl, ssl_handshake); else { stats_close(&fd, &t_close, 1); fd = rc; if (persistent_connections && ++persistent_tries < 2) { persistent_did_reconnect = 1; goto persistent_loop; } } } #endif } dafter_connect = get_ts(); if (did_reconnect) { if (cur_have_resolved) dummy_ms = (dafter_connect - dafter_resolve) * 1000.0; else dummy_ms = (dafter_connect - dstart) * 1000.0; update_statst(&t_connect, dummy_ms - ssl_handshake); } if (fd < 0) { if (fd == RC_TIMEOUT) set_error(gettext("timeout connecting to host")); emit_error(verbose, curncount, dstart); err++; fd = -1; break; } #ifndef NO_SSL if (use_ssl) rc = WRITE_SSL(ssl_h, request, req_len, timeout); else #endif { if (!req_sent) rc = mywrite(fd, request, req_len, timeout); else rc = req_len; } /* wait for data transmit(!) to complete, e.g. until the transmitbuffers are empty and the data was sent to the next hop */ #ifndef __CYGWIN__ for(;;) { int bytes_left = 0; int i_rc = ioctl(fd, TIOCOUTQ, &bytes_left); if (i_rc == -1 || bytes_left == 0 || stop) break; dafter_write_complete = get_ts(); if ((dafter_write_complete - dafter_connect) * 1000.0 >= timeout) break; /* this keeps it somewhat from becoming a busy loop * I know of no other way to wait for the kernel to * finish the transmission */ usleep(write_sleep); } #endif dafter_write_complete = get_ts(); dummy_ms = (dafter_write_complete - dafter_connect) * 1000.0; update_statst(&t_write, dummy_ms); if (rc != req_len) { if (persistent_connections) { if (++persistent_tries < 2) { stats_close(&fd, &t_close, 0); persistent_did_reconnect = 1; goto persistent_loop; } } if (rc == -1) set_error(gettext("error sending request to host")); else if (rc == RC_TIMEOUT) set_error(gettext("timeout sending to host")); else if (rc == RC_INVAL) set_error(gettext("retrieved invalid data from host")); else if (rc == RC_CTRLC) {/* ^C */} else if (rc == 0) set_error(gettext("connection prematurely closed by peer")); emit_error(verbose, curncount, dstart); stats_close(&fd, &t_close, 1); err++; break; } #if defined(linux) || defined(__FreeBSD__) #ifdef NC if (!use_ssl && ncurses_mode) { struct timeval tv; int t_rc = -1; fd_set rfds; FD_ZERO(&rfds); FD_SET(fd, &rfds); tv.tv_sec = (long)(timeout / 1000.0) % 1000000; tv.tv_usec = (long)(timeout * 1000.0) % 1000000; t_rc = select(fd + 1, &rfds, NULL, NULL, &tv); #ifdef linux if (t_rc == 1 && \ FD_ISSET(fd, &rfds) && \ getsockopt(fd, IPPROTO_TCP, TCP_INFO, &info, &info_len) == 0 && \ info.tcpi_unacked > 0) { static int in_transit_cnt = 0; in_transit_cnt++; if (in_transit_cnt == MAX_SHOW_SUPPRESSION + 1) slow_log(gettext("\nNo longer emitting message about \"still data in transit\"")); else if (in_transit_cnt <= MAX_SHOW_SUPPRESSION) slow_log(gettext("\nHTTP server started sending data with %d bytes still in transit"), info.tcpi_unacked); } #endif if (t_rc == 0) { stats_close(&fd, &t_close, 1); rc = RC_TIMEOUT; set_error(gettext("timeout sending to host")); emit_error(verbose, curncount, dstart); err++; break; } } #endif if (getsockopt(fd, IPPROTO_IP, IP_TOS, &recv_tos, &recv_tos_len) == -1) { set_error(gettext("failed to obtain TOS info")); recv_tos = -1; } #endif rc = get_HTTP_headers(fd, ssl_h, &reply, &overflow, timeout); #ifdef NC if (ncurses_mode && !get_instead_of_head && overflow > 0) { static int more_data_cnt = 0; more_data_cnt++; if (more_data_cnt == MAX_SHOW_SUPPRESSION + 1) slow_log(gettext("\nNo longer emitting message about \"more data than response headers\"")); else if (more_data_cnt <= MAX_SHOW_SUPPRESSION) slow_log(gettext("\nHTTP server sent more data than just the response headers")); } #endif emit_headers(reply); if (reply) { free_cookies(dynamic_cookies, n_dynamic_cookies); dynamic_cookies = NULL; n_dynamic_cookies = 0; get_cookies(reply, &dynamic_cookies, &n_dynamic_cookies, &static_cookies, &n_static_cookies); } if ((show_statuscodes || machine_readable || json_output || ncurses_mode) && reply != NULL) { /* statuscode is in first line behind * 'HTTP/1.x' */ char *dummy = strchr(reply, ' '); if (dummy) { sc = strdup(dummy + 1); /* lines are normally terminated with a * CR/LF */ dummy = strchr(sc, '\r'); if (dummy) *dummy = 0x00; dummy = strchr(sc, '\n'); if (dummy) *dummy = 0x00; } } their_ts = parse_date_from_response_headers(reply); age = calc_page_age(reply, their_ts); is_compressed = check_compressed(reply); if (persistent_connections && show_bytes_xfer && reply != NULL) { char *length = strstr(reply, "\nContent-Length:"); if (!length) { set_error(gettext("'Content-Length'-header missing!")); emit_error(verbose, curncount, dstart); stats_close(&fd, &t_close, 1); break; } len = atoi(&length[17]); } headers_len = 0; if (reply) { headers_len = strlen(reply) + 4 - overflow; free(reply); reply = NULL; } update_statst(&stats_header_size, headers_len); if (rc < 0) { if (persistent_connections) { if (++persistent_tries < 2) { stats_close(&fd, &t_close, 0); persistent_did_reconnect = 1; goto persistent_loop; } } if (rc == RC_SHORTREAD) set_error(gettext("short read during receiving reply-headers from host")); else if (rc == RC_TIMEOUT) set_error(gettext("timeout while receiving reply-headers from host")); emit_error(verbose, curncount, dstart); stats_close(&fd, &t_close, 1); err++; break; } ok++; if (get_instead_of_head && show_Bps) { int buffer_size = RECV_BUFFER_SIZE; char *buffer = (char *)malloc(buffer_size); double dl_start = get_ts(), dl_end; double cur_limit = Bps_limit; if (persistent_connections) { if (cur_limit == -1 || len < cur_limit) cur_limit = len - overflow; } for(;;) { int n = cur_limit != -1 ? min(cur_limit - bytes_transferred, buffer_size) : buffer_size; int rc = read(fd, buffer, n); if (rc == -1) { if (errno != EINTR && errno != EAGAIN) error_exit(gettext("read of response body dataa failed")); } else if (rc == 0) { break; } bytes_transferred += rc; if (cur_limit != -1 && bytes_transferred >= cur_limit) break; } free(buffer); dl_end = get_ts(); Bps = (double)bytes_transferred / max(dl_end - dl_start, 0.000001); bps.Bps_min = min(bps.Bps_min, Bps); bps.Bps_max = max(bps.Bps_max, Bps); bps.Bps_avg += Bps; } dend = get_ts(); #ifndef NO_SSL if (use_ssl) { if ((show_fp || json_output || ncurses_mode) && ssl_h != NULL) fp = get_fingerprint(ssl_h); if (!persistent_connections) { if (close_ssl_connection(ssl_h) == -1) { set_error(gettext("error shutting down ssl")); emit_error(verbose, curncount, dstart); } SSL_free(ssl_h); ssl_h = NULL; s_bio = NULL; } } #endif #if defined(linux) || defined(__FreeBSD__) if (getsockopt(fd, IPPROTO_TCP, TCP_INFO, &info, &info_len) == 0) { #ifdef TCP_TFO if (info.tcpi_options & TCPI_OPT_SYN_DATA) tfo_success = 1; #endif update_statst(&tcp_rtt_stats, (double)info.tcpi_rtt / 1000.0); #ifdef linux re_tx = info.tcpi_retransmits; pmtu = info.tcpi_pmtu; #endif } #endif if (!persistent_connections) stats_close(&fd, &t_close, 0); dummy_ms = (dend - dafter_write_complete) * 1000.0; update_statst(&t_request, dummy_ms); dummy_ms = (dend - dstart) * 1000.0; update_statst(&t_total, dummy_ms); their_est_ts = (dend + dafter_connect) / 2.0; /* estimate of when other end started replying */ toff_diff_ts = ((double)their_ts - their_est_ts) * 1000.0; update_statst(&stats_to, toff_diff_ts); if (json_output) { char current_host[4096] = { 0 }; if (proxy_host) snprintf(current_host, sizeof current_host, "%s", hostname); else if (getnameinfo((const struct sockaddr *)&addr, sizeof addr, current_host, sizeof current_host, NULL, 0, NI_NUMERICHOST) == -1) snprintf(current_host, sizeof current_host, gettext("getnameinfo() failed: %d (%s)"), errno, strerror(errno)); emit_json(1, curncount, dstart, &t_resolve, &t_connect, &t_request, atoi(sc ? sc : "-1"), sc ? sc : "?", headers_len, len, Bps, current_host, fp, toff_diff_ts, tfo_success, &t_ssl, &t_write, &t_close, n_dynamic_cookies, &stats_to, &tcp_rtt_stats, re_tx, pmtu, recv_tos, &t_total); } else if (machine_readable) { if (sc) { char *dummy = strchr(sc, ' '); if (dummy) *dummy = 0x00; if (strstr(ok_str, sc)) printf("%f", t_total.cur); else printf("%s", err_str); if (show_statuscodes) printf(" %s", sc); } else { printf("%s", err_str); } if(audible) putchar('\a'); printf("\n"); } else if (!quiet && !nagios_mode && t_total.cur >= offset_show) { char *tot_str = NULL; const char *i6_bs = "", *i6_be = ""; char *line = NULL; const char *ms_color = c_green; char current_host[4096] = { 0 }; char *operation = !persistent_connections ? gettext("connected to") : gettext("pinged host"); const char *sep = c_bright, *unsep = c_normal; if (show_ts || ncurses_mode) { char *ts = get_ts_str(verbose); if (ncurses_mode) str_add(&line, "[%s] ", ts); else str_add(&line, "%s ", ts); free(ts); } if (curncount & 1) { str_add(&line, "%s", c_bright); sep = c_normal; unsep = c_bright; } if (proxy_host) snprintf(current_host, sizeof current_host, "%s", hostname); else if (getnameinfo((const struct sockaddr *)&addr, sizeof addr, current_host, sizeof current_host, NULL, 0, NI_NUMERICHOST) == -1) snprintf(current_host, sizeof current_host, gettext("getnameinfo() failed: %d (%s)"), errno, strerror(errno)); if (addr.sin6_family == AF_INET6) { i6_bs = "["; i6_be = "]"; } if (offset_red > 0.0 && t_total.cur >= offset_red) ms_color = c_red; else if (offset_yellow > 0.0 && t_total.cur >= offset_yellow) ms_color = c_yellow; if (!ncurses_mode) str_add(&line, "%s%s ", c_white, operation); if (persistent_connections && show_bytes_xfer) str_add(&line, gettext("%s%s%s%s%s:%s%d%s (%d/%d bytes), seq=%s%d%s "), c_red, i6_bs, current_host, i6_be, c_white, c_yellow, portnr, c_white, headers_len, len, c_blue, curncount-1, c_white); else str_add(&line, gettext("%s%s%s%s%s:%s%d%s (%d bytes), seq=%s%d%s "), c_red, i6_bs, current_host, i6_be, c_white, c_yellow, portnr, c_white, headers_len, c_blue, curncount-1, c_white); tot_str = format_value(t_total.cur, 6, 2, abbreviate); if (split) { char *res_str = t_resolve.cur_valid ? format_value(t_resolve.cur, 6, 2, abbreviate) : strdup(gettext(" n/a")); char *con_str = t_connect.cur_valid ? format_value(t_connect.cur, 6, 2, abbreviate) : strdup(gettext(" n/a")); char *wri_str = format_value(t_write.cur, 6, 2, abbreviate); char *req_str = format_value(t_request.cur, 6, 2, abbreviate); char *clo_str = format_value(t_close.cur, 6, 2, abbreviate); str_add(&line, gettext("time=%s+%s+%s+%s+%s%s=%s%s%s%s ms %s%s%s"), res_str, con_str, wri_str, req_str, clo_str, sep, unsep, ms_color, tot_str, c_white, c_cyan, sc?sc:"", c_white); free(clo_str); free(req_str); free(wri_str); free(con_str); free(res_str); } else { str_add(&line, gettext("time=%s%s%s ms %s%s%s"), ms_color, tot_str, c_white, c_cyan, sc?sc:"", c_white); } free(tot_str); if (persistent_did_reconnect) { str_add(&line, " %sC%s", c_magenta, c_white); persistent_did_reconnect = 0; } if (show_Bps) { str_add(&line, " %dKB/s", (int)Bps / 1024); if (show_bytes_xfer) str_add(&line, " %dKB", (int)(bytes_transferred / 1024)); if (ask_compression) { str_add(&line, " ("); if (!is_compressed) str_add(&line, gettext("not ")); str_add(&line, gettext("compressed)")); } } if (use_ssl && show_fp && fp != NULL) { str_add(&line, " %s", fp); } if (verbose > 0 && their_ts > 0) { /* if diff_ts > 0, then their clock is running too fast */ str_add(&line, gettext(" toff=%d"), (int)toff_diff_ts); } if (verbose > 0 && age > 0) str_add(&line, gettext(" age=%d"), age); str_add(&line, "%s", c_normal); if (audible) { #ifdef NC my_beep(); #else putchar('\a'); #endif } #ifdef TCP_TFO if (tfo_success) str_add(&line, " F"); #endif #ifdef NC if (ncurses_mode) { if (dummy_ms >= show_slow_log) slow_log("\n%s", line); else fast_log("\n%s", line); } else #endif { printf("%s\n", line); } do_aggregates(t_total.cur, (int)(get_ts() - started_at), n_aggregates, aggregates, verbose, show_ts); free(line); } if (show_statuscodes && ok_str != NULL && sc != NULL) { scdummy = strchr(sc, ' '); if (scdummy) *scdummy = 0x00; if (strstr(ok_str, sc) == NULL) { ok--; err++; } } if (got_sigquit && !quiet && !machine_readable && !nagios_mode && !json_output) { got_sigquit = 0; stats_line(0, complete_url, count, curncount, err, ok, started_at, verbose, &t_total, avg_httping_time, show_Bps ? &bps : NULL); } break; } emit_statuslines(get_ts() - started_at); #ifdef NC if (ncurses_mode) update_stats(&t_resolve, &t_connect, &t_request, &t_total, &t_ssl, curncount, err, sc, fp, use_tfo, nc_graph, &stats_to, &tcp_rtt_stats, re_tx, pmtu, recv_tos, &t_close, &t_write, n_dynamic_cookies, abbreviate, &stats_header_size); #endif free(sc); free(fp); #ifdef NC if (ncurses_mode) update_terminal(); else #endif fflush(NULL); if (!stop && wait > 0) { double cur_sleep = wait; if (adaptive_interval) { double now = get_ts(); double interval_left = fmod(now - started_at, wait); if (interval_left <= 0.0) cur_sleep = wait; else cur_sleep = wait - interval_left; } usleep((useconds_t)(cur_sleep * 1000000.0)); } reset_statst_cur(&t_resolve); reset_statst_cur(&t_connect); reset_statst_cur(&t_ssl); reset_statst_cur(&t_write); reset_statst_cur(&t_request); reset_statst_cur(&t_close); reset_statst_cur(&t_total); reset_statst_cur(&stats_to); #if defined(linux) || defined(__FreeBSD__) reset_statst_cur(&tcp_rtt_stats); #endif } #ifdef NC if (ncurses_mode) end_ncurses(); #endif if (colors) set_colors(0); if (ok) avg_httping_time = t_total.avg / (double)t_total.n; else avg_httping_time = -1.0; if (!quiet && !machine_readable && !nagios_mode && !json_output) stats_line(1, complete_url, count, curncount, err, ok, started_at, verbose, &t_total, avg_httping_time, show_Bps ? &bps : NULL); error_exit: if (nagios_mode) return nagios_result(ok, nagios_mode, nagios_exit_code, avg_httping_time, nagios_warn, nagios_crit); if (!json_output && !machine_readable) printf("%s", c_very_normal); if (json_output) printf("\n]\n"); free_cookies(static_cookies, n_static_cookies); free_cookies(dynamic_cookies, n_dynamic_cookies); freeaddrinfo(ai); free(request); free(get); free(hostname); free(complete_url); free_headers(additional_headers, n_additional_headers); free(aggregates); #ifndef NO_SSL if (use_ssl) { SSL_CTX_free(client_ctx); shutdown_ssl(); } #endif fflush(NULL); if (ok) return 0; else return 127; } httping-2.5/main.h000066400000000000000000000002431276547250600141470ustar00rootroot00000000000000extern volatile int stop; extern volatile char got_sigquit; extern int max_x, max_y; void determine_terminal_size(int *max_y, int *max_x); void handler(int sig); httping-2.5/mssl.c000066400000000000000000000205261276547250600142020ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "error.h" #include "gen.h" #include "mssl.h" #include "tcp.h" #include "io.h" #include "http.h" #include "utils.h" #include "main.h" BIO *bio_err = NULL; void shutdown_ssl(void) { BIO_free(bio_err); ERR_free_strings(); ERR_remove_state(0); ENGINE_cleanup(); CONF_modules_free(); EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); } int close_ssl_connection(SSL *const ssl_h) { int rc = SSL_shutdown(ssl_h); if (!rc) rc = SSL_shutdown(ssl_h); /* ignoring failures: the socket will be closed anyway later on so any openssl failures won't do any harm if (rc == -1) { fprintf(stderr, "SSL_shutdown failed: %s\n", strerror(errno)); return -1; } */ return 0; } int READ_SSL(SSL *const ssl_h, char *whereto, int len, const double timeout) { const int cnt = len; const int fd = SSL_get_rfd(ssl_h); double end = get_ts() + timeout; while(len > 0 && !got_sigquit) { int rc = -1; fd_set rfds, wfds; struct timeval tv; double now = get_ts(), left = end - now; if (left <= 0.0) { set_error(gettext("Time-out on SSL connection")); return -1; } FD_ZERO(&rfds); FD_SET(fd, &rfds); FD_ZERO(&wfds); /* yes, see openssl */ FD_SET(fd, &wfds); tv.tv_sec = left; tv.tv_usec = (left - tv.tv_sec) * 1000000; rc = select(fd + 1, &rfds, &wfds, NULL, &tv); if (rc == -1) { if (errno != EINTR && errno != EAGAIN) set_error(gettext("READ_SSL: io-error: %s"), strerror(errno)); return -1; } if (rc == 0) { set_error(gettext("Time-out on SSL connection (READ)")); return -1; } rc = SSL_read(ssl_h, whereto, len); if (rc == -1) { if (errno != EINTR && errno != EAGAIN) set_error(gettext("READ_SSL: io-error: %s"), strerror(errno)); return -1; } if (rc == 0) return 0; whereto += rc; len -= rc; } return cnt; } int WRITE_SSL(SSL *const ssl_h, const char *wherefrom, int len, const double timeout) { const int cnt = len; const int fd = SSL_get_wfd(ssl_h); double end = get_ts() + timeout; while(len > 0 && !got_sigquit) { int rc = -1; fd_set rfds, wfds; struct timeval tv; double now = get_ts(), left = end - now; if (left <= 0.0) { set_error(gettext("Time-out on SSL connection")); return -1; } FD_ZERO(&rfds); /* yes, that's correct */ FD_SET(fd, &rfds); FD_ZERO(&wfds); FD_SET(fd, &wfds); tv.tv_sec = left; tv.tv_usec = (left - tv.tv_sec) * 1000000; rc = select(fd + 1, &rfds, &wfds, NULL, &tv); if (rc == -1) { if (errno != EINTR && errno != EAGAIN) set_error(gettext("WRITE_SSL: io-error: %s"), strerror(errno)); return -1; } if (rc == 0) { set_error(gettext("Time-out on SSL connection (write)")); return -1; } rc = SSL_write(ssl_h, wherefrom, len); if (rc == -1) { if (errno != EINTR && errno != EAGAIN) set_error(gettext("WRITE_SSL: io-error: %s"), strerror(errno)); return -1; } if (rc == 0) return 0; wherefrom += rc; len -= rc; } return cnt; } int connect_ssl(const int fd, SSL_CTX *const client_ctx, SSL **const ssl_h, BIO **const s_bio, const double timeout, double *const ssl_handshake) { double dstart = get_ts(); double end = get_ts() + timeout; struct timeval tv; tv.tv_sec = (long)(timeout / 1000.0); tv.tv_usec = (long)(timeout * 1000.0) % 1000000; *ssl_handshake = -1.0; if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv) == -1) { set_error(gettext("problem setting receive timeout (%s)"), strerror(errno)); return -1; } if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv) == -1) { set_error(gettext("problem setting transmit timeout (%s)"), strerror(errno)); return -1; } *ssl_h = SSL_new(client_ctx); *s_bio = BIO_new_socket(fd, BIO_NOCLOSE); SSL_set_bio(*ssl_h, *s_bio, *s_bio); if (set_fd_nonblocking(fd) == -1) return RC_INVAL; do { int rc = SSL_connect(*ssl_h); if (rc <= 0) { int err = SSL_get_error(*ssl_h, rc); if (err == SSL_ERROR_WANT_CONNECT || err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) { struct timeval tv; fd_set fds; double left = end - get_ts(); if (left <= 0) { set_error(gettext("Time-out during SSL handshake")); return -1; } tv.tv_sec = left; tv.tv_usec = (left - tv.tv_sec) * 1000000; FD_ZERO(&fds); FD_SET(fd, &fds); if (err == SSL_ERROR_WANT_READ) rc = select(fd + 1, &fds, NULL, NULL, &tv); else rc = select(fd + 1, NULL, &fds, NULL, &tv); } else { set_error(gettext("SSL handshake error: %s"), SSL_get_error(*ssl_h, err)); return -1; } } } while (!SSL_is_init_finished(*ssl_h) && !got_sigquit); if (got_sigquit) return -1; *ssl_handshake = get_ts() - dstart; if (set_fd_blocking(fd) == -1) return -1; return 0; } SSL_CTX * initialize_ctx(const char ask_compression) { const SSL_METHOD *meth = NULL; SSL_CTX *ctx = NULL; if (!bio_err) { SSL_library_init(); SSL_load_error_strings(); ERR_load_crypto_strings(); /* error write context */ bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); } /* create context */ meth = SSLv23_method(); ctx = SSL_CTX_new(meth); #ifdef SSL_OP_NO_COMPRESSION if (!ask_compression) SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION); #endif return ctx; } char * get_fingerprint(SSL *const ssl_h) { char *string = NULL; unsigned char fp_digest[EVP_MAX_MD_SIZE]; X509 *x509_data = SSL_get_peer_certificate(ssl_h); if (x509_data) { unsigned int fp_digest_size = sizeof fp_digest; memset(fp_digest, 0x00, fp_digest_size); if (X509_digest(x509_data, EVP_md5(), fp_digest, &fp_digest_size)) { string = (char *)malloc(MD5_DIGEST_LENGTH * 3 + 1); if (string) { int loop, pos =0; for(loop=0; loop #include #include #include void shutdown_ssl(void); int close_ssl_connection(SSL *const ssl_h); int READ_SSL(SSL *const ssl_h, char *whereto, int len, const double timeout); int WRITE_SSL(SSL *const ssl_h, const char *whereto, int len, const double timeout); int connect_ssl(const int fd, SSL_CTX *const client_ctx, SSL **const ssl_h, BIO **const s_bio, const double timeout, double *const ssl_handshake); SSL_CTX * initialize_ctx(const char ask_compression); char * get_fingerprint(SSL *const ssl_h); int connect_ssl_proxy(const int fd, struct addrinfo *const ai, const double timeout, const char *const proxy_user, const char *const proxy_password, const char *const hostname, const int portnr, char *const tfo); httping-2.5/nc.c000066400000000000000000000435351276547250600136310ustar00rootroot00000000000000#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include "error.h" #include "colors.h" #include "gen.h" #include "main.h" #include "kalman.h" #ifdef FW #include "fft.h" #endif #include "utils.h" char win_resize = 0; WINDOW *w_stats = NULL, *w_line1 = NULL, *w_slow = NULL, *w_line2 = NULL, *w_fast = NULL; int stats_h = 10; int logs_n = 0, slow_n = 0, fast_n = 0; char **slow_history = NULL, **fast_history = NULL; int window_history_n = 0; char use_colors = 0; double graph_limit = MY_DOUBLE_INF; double hz = 1.0; double *history = NULL, *history_temp = NULL, *history_fft_magn = NULL, *history_fft_phase = NULL; char *history_set = NULL; int history_n = 0; char draw_phase = 0; char pause_graphs = 0; typedef enum { C_WHITE = 0, C_GREEN, C_YELLOW, C_BLUE, C_MAGENTA, C_CYAN, C_RED } color_t; void update_terminal(void) { wnoutrefresh(w_stats); wnoutrefresh(w_slow); wnoutrefresh(w_fast); doupdate(); } void create_windows(void) { char *r_a = gettext("realloc issue"); int nr = 0; if (w_stats) { delwin(w_stats); delwin(w_line1); delwin(w_slow); delwin(w_line2); delwin(w_fast); } #ifdef FW fft_free(); fft_init(max_x); #endif if (max_x > history_n) { history = (double *)realloc(history, sizeof(double) * max_x); if (!history) error_exit(r_a); history_temp = (double *)realloc(history_temp, sizeof(double) * max_x); if (!history_temp) error_exit(r_a); /* halve of it is enough really */ history_fft_magn = (double *)realloc(history_fft_magn, sizeof(double) * max_x); if (!history_fft_magn) error_exit(r_a); history_fft_phase = (double *)realloc(history_fft_phase, sizeof(double) * max_x); if (!history_fft_phase) error_exit(r_a); history_set = (char *)realloc(history_set, sizeof(char) * max_x); if (!history_set) error_exit(r_a); memset(&history[history_n], 0x00, (max_x - history_n) * sizeof(double)); memset(&history_set[history_n], 0x00, (max_x - history_n) * sizeof(char)); history_n = max_x; } if ((int)max_y > window_history_n) { slow_history = (char **)realloc(slow_history, sizeof(char *) * max_y); if (!slow_history) error_exit(r_a); fast_history = (char **)realloc(fast_history, sizeof(char *) * max_y); if (!fast_history) error_exit(r_a); memset(&slow_history[window_history_n], 0x00, (max_y - window_history_n) * sizeof(char *)); memset(&fast_history[window_history_n], 0x00, (max_y - window_history_n) * sizeof(char *)); window_history_n = max_y; } w_stats = newwin(stats_h, max_x, 0, 0); scrollok(w_stats, false); w_line1 = newwin(1, max_x, stats_h, 0); scrollok(w_line1, false); wnoutrefresh(w_line1); logs_n = max_y - (stats_h + 1 + 1); fast_n = logs_n * 11 / 20; slow_n = logs_n - fast_n; w_slow = newwin(slow_n, max_x, (stats_h + 1), 0); scrollok(w_slow, true); w_line2 = newwin(1, max_x, (stats_h + 1) + slow_n, 0); scrollok(w_line2, false); wnoutrefresh(w_line2); w_fast = newwin(fast_n, max_x, (stats_h + 1) + slow_n + 1, 0); scrollok(w_fast, true); wattron(w_line1, A_REVERSE); wattron(w_line2, A_REVERSE); for(nr=0; nr= 0; index--) { if (slow_history[index]) myprint(w_slow, slow_history[index]); if (fast_history[index]) myprint(w_fast, fast_history[index]); } doupdate(); win_resize = 0; } void init_ncurses_ui(double graph_limit_in, double hz_in, char use_colors_in) { graph_limit = graph_limit_in; hz = hz_in; use_colors = use_colors_in; initscr(); start_color(); keypad(stdscr, TRUE); intrflush(stdscr, FALSE); noecho(); refresh(); nodelay(stdscr, FALSE); meta(stdscr, TRUE); /* enable 8-bit input */ idlok(stdscr, TRUE); /* may give a little clunky screenredraw */ idcok(stdscr, TRUE); /* may give a little clunky screenredraw */ leaveok(stdscr, FALSE); init_pair(C_WHITE, COLOR_WHITE, COLOR_BLACK); init_pair(C_CYAN, COLOR_CYAN, COLOR_BLACK); init_pair(C_MAGENTA, COLOR_MAGENTA, COLOR_BLACK); init_pair(C_BLUE, COLOR_BLUE, COLOR_BLACK); init_pair(C_YELLOW, COLOR_YELLOW, COLOR_BLACK); init_pair(C_GREEN, COLOR_GREEN, COLOR_BLACK); init_pair(C_RED, COLOR_RED, COLOR_BLACK); kalman_init(0.0); recreate_terminal(); } void end_ncurses(void) { int index = 0; for(index=0; index= end_y; y--) mvwchgat(win, y, x, 1, A_REVERSE, C_YELLOW, dummy); if (limitter) mvwchgat(win, 0, x, 1, A_REVERSE, C_BLUE, dummy); else if (overflow) mvwchgat(win, 0, x, 1, A_REVERSE, C_RED, dummy); else if (height == 0) mvwchgat(win, win_h - 1, x, 1, A_REVERSE, C_GREEN, dummy); } void draw_rad_column(WINDOW *win, int x, double val) { void *dummy = NULL; int y = 0, end_y = 0, win_h = 0, win_w = 0; int center_y = 0; getmaxyx(win, win_h, win_w); (void)win_w; /* silence warnings */ center_y = win_h / 2; end_y = (int)((double)(win_h / 2) * ((val / PI) + 1.0)); if (end_y > center_y) { for(y=center_y; y 0 ? history[index - 1] : 0; if (val > graph_limit) val = graph_limit; history_temp[index] = val; } fft_do(history_temp, history_fft_magn, history_fft_phase); for(index=1; index mx_mag) { mx_mag = history_fft_magn[index]; highest = index; } } highest_freq = (hz / (double)max_x) * (double)highest; avg_freq_index /= total_val; avg_freq = (hz / (double)max_x) * avg_freq_index; wattron(w_line1, A_REVERSE); myprintloc(w_line1, 0, 38, gettext("highest: %6.2fHz, avg: %6.2fHz"), highest_freq, avg_freq); wattroff(w_line1, A_REVERSE); wnoutrefresh(w_line1); dummy = max_x / 2 + 1; if (draw_phase) { int y = 0; for(y=0; y ma) continue; avg2 += val; sd2 += val * val; n2++; } if (n2) { avg2 /= (double)n2; sd2 = sqrt((sd2 / (double)n2) - pow(avg2, 2.0)); mi = max(mi, avg2 - sd2); ma = min(ma, avg2 + sd2); diff = ma - mi; if (diff == 0.0) diff = 1.0; wattron(w_line1, A_REVERSE); myprintloc(w_line1, 0, 0, gettext("graph range: %7.2fms - %7.2fms "), mi, ma); wattroff(w_line1, A_REVERSE); wnoutrefresh(w_line1); /* fprintf(stderr, "%d| %f %f %f %f\n", h_stats.n, mi, avg, ma, sd); */ for(index=0; index 1.0) { height = 1.0; overflow = 1; } i_h = (int)(height * stats_h); /* fprintf(stderr, "%d %f %f %d %d\n", index, history[index], height, i_h, overflow); */ draw_column(w_stats, x, i_h, overflow, limitter); } } } void show_stats_t(int y, int x, char *header, stats_t *data, char abbreviate) { if (data -> valid) { char *cur_str = format_value(data -> cur, 6, 2, abbreviate); char *min_str = format_value(data -> min, 6, 2, abbreviate); char *avg_str = format_value(data -> avg / (double)data -> n, 6, 2, abbreviate); char *max_str = format_value(data -> max, 6, 2, abbreviate); char *sd_str = format_value(calc_sd(data), 6, 2, abbreviate); myprintloc(w_stats, y, x, "%s: %s %s %s %s %s", header, data -> cur_valid ? cur_str : gettext(" n/a"), min_str, avg_str, max_str, sd_str); free(sd_str); free(max_str); free(avg_str); free(min_str); free(cur_str); } else { myprintloc(w_stats, y, x, gettext("%s: n/a"), header); } } void update_stats(stats_t *resolve, stats_t *connect, stats_t *request, stats_t *total, stats_t *ssl_setup, int n_ok, int n_fail, const char *last_connect_str, const char *fp, char use_tfo, char dg, stats_t *st_to, stats_t *tcp_rtt_stats, int re_tx, int pmtu, int tos, stats_t *close_st, stats_t *t_write, int n_cookies, char abbreviate, stats_t *stats_header_size) { double k = 0.0; char force_redraw = 0; struct pollfd p = { 0, POLLIN, 0 }; werase(w_stats); if (n_ok) { char buffer[4096] = { 0 }, *scc_str = NULL, *kalman_str = NULL; int buflen = 0; myprintloc(w_stats, 0, 0, " %6s %6s %6s %6s %6s", gettext("latest"), gettext("min"), gettext("avg"), gettext("max"), gettext("sd")); show_stats_t(1, 0, gettext("resolve"), resolve, abbreviate); show_stats_t(2, 0, gettext("connect"), connect, abbreviate); show_stats_t(3, 0, gettext("ssl "), ssl_setup, abbreviate); show_stats_t(4, 0, gettext("send "), t_write, abbreviate); show_stats_t(5, 0, gettext("request"), request, abbreviate); show_stats_t(6, 0, gettext("close "), close_st, abbreviate); show_stats_t(7, 0, gettext("total "), total, abbreviate); scc_str = format_value(get_cur_scc(), 5, 3, abbreviate); kalman_str = format_value(kalman_do(total -> cur), 5, 3, abbreviate); myprintloc(w_stats, 8, 0, gettext("ok: %3d, fail: %3d%s, scc: %s, kalman: %s"), n_ok, n_fail, use_tfo ? gettext(", with TFO") : "", scc_str, kalman_str); free(kalman_str); free(scc_str); if (max_x >= 44 * 2 + 1) { double trend = calc_trend(); char trend_dir = ' '; myprintloc(w_stats, 0, 45, " %6s %6s %6s %6s %6s", gettext("cur"), gettext("min"), gettext("avg"), gettext("max"), gettext("sd")); show_stats_t(1, 45, gettext("t offst"), st_to, abbreviate); #if defined(linux) || defined(__FreeBSD__) show_stats_t(2, 45, gettext("tcp rtt"), tcp_rtt_stats, abbreviate); #endif show_stats_t(3, 45, gettext("headers"), stats_header_size, abbreviate); if (trend < 0) trend_dir = '-'; else if (trend > 0) trend_dir = '+'; myprintloc(w_stats, 8, 48, gettext("# cookies: %d"), n_cookies); #ifdef linux myprintloc(w_stats, 9, 48, gettext("trend: %c%6.2f%%, re-tx: %2d, pmtu: %5d, TOS: %02x"), trend_dir, fabs(trend), re_tx, pmtu, tos); #else myprintloc(w_stats, 9, 48, gettext("trend: %c%6.2f%%, TOS: %02x"), trend_dir, fabs(trend), tos); #endif } buflen = snprintf(buffer, sizeof buffer, gettext("HTTP rc: %s, SSL fp: %s"), last_connect_str, fp ? fp : gettext("n/a")); if (buflen <= max_x) myprintloc(w_stats, 9, 0, "%s", buffer); else { static char prev_sf[48] = { 0 }; myprintloc(w_stats, 9, 0, gettext("http result code: %s"), last_connect_str); if (fp && strcmp(prev_sf, fp)) { slow_log(gettext("\nSSL fingerprint: %s"), fp); memcpy(prev_sf, fp, 47); } } } memmove(&history[1], &history[0], (history_n - 1) * sizeof(double)); memmove(&history_set[1], &history_set[0], (history_n - 1) * sizeof(char)); history[0]= total -> cur; history_set[0] = 1; if (poll(&p, 1, 0) == 1 && p.revents == POLLIN) { int c = getch(); if (c == 12) /* ^L */ force_redraw = 1; if (c == 'H') pause_graphs = !pause_graphs; if (c == 'q') stop = 1; } if (dg && !pause_graphs) { draw_graph(k); #ifdef FW draw_fft(); #endif } wnoutrefresh(w_stats); if (win_resize || force_redraw) recreate_terminal(); } httping-2.5/nc.h000066400000000000000000000012661276547250600136310ustar00rootroot00000000000000#include extern char win_resize; extern char draw_phase; void init_ncurses_ui(double graph_limit_in, double hz_in, char use_colors); void end_ncurses(void); void fast_log(const char *fmt, ...); void slow_log(const char *fmt, ...); void my_beep(void); void update_terminal(void); void status_line(char *fmt, ...); void update_stats(stats_t *resolve, stats_t *connect, stats_t *request, stats_t *total, stats_t *ssl_setup, int n_ok, int n_fail, const char *last_connect_str, const char *fp, char use_tfo, char dg, stats_t *st_to, stats_t *tcp_rtt_stats, int re_tx, int pmtu, int tos, stats_t *close_st, stats_t *t_write, int n_cookies, char abbreviate, stats_t *stats_header_size); httping-2.5/nl.po000066400000000000000000000733221276547250600140330ustar00rootroot00000000000000# Dutch translations for HTTPing package. # Copyright (C) 2016 folkert van heusden # This file is distributed under the same license as the HTTPing package. # folkert van heusden , 2016. # Translated by Joris Zwart - http://joriszwart.nl/ # msgid "" msgstr "" "Project-Id-Version: HTTPing\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-05-04 15:29+0200\n" "PO-Revision-Date: 2015-05-04 18:41+0100\n" "Last-Translator: Joris Zwart \n" "Language-Team: Dutch\n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-Language: Dutch\n" "X-Poedit-Country: NETHERLANDS\n" #: error.c:23 #, c-format msgid "" "\n" "\n" "errno=%d which means %s (if applicable)\n" msgstr "" "\n" "\n" "errno=%d en dat betekent: %s (indien van toepassing)\n" #: error.c:39 #, c-format msgid "Error message '%s' truncated" msgstr "De foutmelding '%s' past niet in de buffer." #: fft.c:21 msgid "failed allocating memory for fft (1)" msgstr "Geheugentoewijzingsprobleem voor 'fft (1)'." #: fft.c:25 msgid "failed allocating memory for fft (2)" msgstr "Geheugentoewijzingsprobleem voor 'fft (2)'." #: fft.c:30 msgid "failed calculating plan for fft" msgstr "Probleem bij het voorbereiden van de FFT berekening." #: help.c:77 #, c-format msgid "HTTPing v" msgstr "HTTPing versie " msgid "adds an extra request-header" msgstr "voeg een extra verzoek-regel toe" #: help.c:79 #, c-format msgid " * SSL support included (-l)\n" msgstr " * Ondersteuning voor SSL (-l)\n" #: help.c:84 #, c-format msgid " * ncurses interface with FFT included (-K)\n" msgstr " * ncurses gebruikersinterface met fourier transformatie berekening (-K)\n" #: help.c:86 #, c-format msgid " * ncurses interface included (-K)\n" msgstr " * ncurses gebruikersinterface (-K)\n" #: help.c:91 #, c-format msgid " * TFO (TCP fast open) support included (-F)\n" msgstr " * Ondersteuning voor 'TFO (TCP fast open)' (-F)\n" #: help.c:93 #: help.c:293 #, c-format msgid "\n" msgstr "\n" #: help.c:176 #, c-format msgid " *** where to connect to ***\n" msgstr " *** adresspecificaties ***\n" #: help.c:177 msgid "URL to ping (e.g. -g http://localhost/)" msgstr "URL om te pingen (bijvoorbeeld -g http://localhost/)" #: help.c:178 msgid "hostname to ping (e.g. localhost) - use either -g or -h" msgstr "Systeemnaam om te pingen (bijvoorbeeld localhost). -g en -h kunnen niet gecombineerd worden" #: help.c:179 msgid "portnumber (e.g. 80) - use with -h" msgstr "poortnummer (bijv. 80), voor gebruik in combinatie met -h" #: help.c:180 msgid "use IPv6 when resolving/connecting" msgstr "gebruik IPv6 bij het omzetten van een systeemnaam en bij het maken van een verbinding" #: help.c:182 msgid "connect using SSL. pinging an https URL automatically enables this setting" msgstr "gebruik SSL encryptie. Wanneer men een https-URL kiest, dan zal deze optie automatisch ingeschakeld worden." #: help.c:187 #, c-format msgid " *** proxy settings ***\n" msgstr " *** proxy instellingen ***\n" #: help.c:188 msgid "x should be \"host:port\" which are the network settings of the http/https proxy server. ipv6 ip-address should be \"[ip:address]:port\"" msgstr "x moet zijn \"host:port\", dat zijn de parameters van de http/https proxyserver. ipv6 ip-adressen moeten opgebouwd zijn als volgt: \"[ip:adres]:port\"" #: help.c:189 msgid "fetch proxy settings from environment variables" msgstr "haal de proxy-instellingen uit de omgevingsvariabelen" #: help.c:190 msgid "username for authentication against proxy" msgstr "gebruikersnaam voor proxy-authenticatie" #: help.c:191 msgid "password for authentication against proxy" msgstr "toegangscode voor proxy-authenticatie" #: help.c:192 msgid "read password for proxy authentication from file x" msgstr "lees toegangscode voor proxy-authenticatie uit bestand x" #: help.c:193 msgid "proxy is a socks5 server" msgstr "de proxy is een socks5 systeem" #: help.c:194 msgid "adds \"&x=[random value]\" to the request URL" msgstr "voeg een \"&x=[willekeurig getal]\" aan de geselecteerde URL" #: help.c:198 #, c-format msgid " *** timing settings ***\n" msgstr " *** tijdsinstellingen ***\n" #: help.c:199 msgid "how many times to ping" msgstr "hoe vaak te pingen" #: help.c:200 msgid "delay between each ping" msgstr "pauze tussen iedere ping" #: help.c:201 msgid "timeout (default: 30s)" msgstr "hoelang te wachten op een server die niet reageert (standaard waarde: 30 seconden)" #: help.c:202 msgid "execute pings at multiples of interval relative to start, automatically enabled in ncurses output mode" msgstr "zorg ervoor dat pings steeds met dezelfde interval uitgevoerd worden, relatief tot het start tijdstip. deze instelling wordt automatisch aangezet in \"ncurses\"-mode" #: help.c:203 msgid "flood connect (no delays)" msgstr "geen vertraging tussen iedere ping" #: help.c:207 #, c-format msgid " *** HTTP settings ***\n" msgstr " *** HTTP-instellingen ***\n" #: help.c:208 msgid "ask any proxies on the way not to cache the requests" msgstr "vraag aan de proxy-sysstemen in de route tussen het lokale systeem en het bestemmingssysteem om de verzoeken niet te cachen" #: help.c:209 msgid "connect to a different host than in the URL given" msgstr "verbind en zend de URL-verzoeken naar een ander systeem dan wat in de URL is opgegeven" #: help.c:210 msgid "return the cookies given by the HTTP server in the following request(s)" msgstr "als de HTTP-server cookies geeft, zend die dan mee terug bij volgende pings" #: help.c:211 msgid "do not add \"Host:\"-line to the request headers" msgstr "voeg geen \"Host:\"-regel in het verbindingsverzoek" #: help.c:212 msgid "use a persistent connection, i.e. reuse the same TCP connection for multiple HTTP requests. usually possible when 'Connection: Keep-Alive' is sent by server. adds a 'C' to the output if httping had to reconnect" msgstr "gebruik een blijvende verbinding, dat wil zeggen hergebruiken dezelfde TCP-verbinding voor meerdere HTTP-verzoeken. meestal mogelijk wanneer 'Connection: Keep-Alive' is verzonden door de server. als het bestemmingssysteem de verbinding verbroken heeft, dan zal HTTPing een \"C\" toevoegen aan de uitvoer" #: help.c:213 msgid "use 'x' for the UserAgent header" msgstr "gebruik 'x' in de UserAgent verzoekinstellingen" #: help.c:214 msgid "use 'x' for the Referer header" msgstr "gebruik 'x' in de Referer verzoekinstellingen" #: help.c:218 #, c-format msgid " *** networking settings ***\n" msgstr " *** netwerk instellingen ***\n" #: help.c:219 msgid "limit the MTU size" msgstr "beperkt de MTU omvang" #: help.c:220 msgid "do not disable Naggle" msgstr "zet het Naggle-algorithme niet uit" #: help.c:221 msgid "receive buffer size" msgstr "ontvangst buffer omvang" #: help.c:222 msgid "transmit buffer size" msgstr "verzend buffer omvang" #: help.c:223 msgid "resolve hostname only once (useful when pinging roundrobin DNS: also takes the first DNS lookup out of the loop so that the first measurement is also correct)" msgstr "eenmalig systeemnaam vertalen (dit is zinvol bij het pingen van een roterende DNS, bovendien haalt het de eerste vertaling uit de ping lus zodat de 1e ping niet een bovengemiddelde tijd duurt)" #: help.c:224 msgid "do not abort the program if resolving failed: keep retrying" msgstr "breek het programma niet af als de systeemnaamvertaling mislukt is" #: help.c:225 msgid "bind to an ip-address (and thus interface) with an optional port" msgstr "stuur verzoeken via een specifieke netwerk adapter, eventueel zelfs vanaf een specifieke port" #: help.c:227 msgid "\"TCP fast open\" (TFO), reduces the latency of TCP connects" msgstr "\"TCP fast open\" (TFO), dit verlaagt de latency van opvolgende TCP verbindingen" #: help.c:229 msgid "set priority of packets" msgstr "zet prioriteit van pakketten" #: help.c:230 msgid "set TOS (type of service)" msgstr "zet de TOS (diensttype)" #: help.c:234 #, c-format msgid " *** HTTP authentication ***\n" msgstr " *** HTTP authenticatie ***\n" #: help.c:235 msgid "activate (\"basic\") authentication" msgstr "activeer (\"basic\")-authenticatie" #: help.c:236 msgid "username for authentication" msgstr "gebruikersnaam voor authenticatie" #: help.c:237 msgid "password for authentication" msgstr "toegangscode voor authenticatie" #: help.c:238 msgid "read the password fom the file 'x' (replacement for -P)" msgstr "lees de toegangscode uit bestand 'x'" #: help.c:242 #, c-format msgid " *** output settings ***\n" msgstr " *** uitvoerinstellingen ***\n" #: help.c:243 msgid "show statuscodes" msgstr "toon statuscodes" #: help.c:244 msgid "split measured time in its individual components (resolve, connect, send, etc." msgstr "toon alle individuele componenten (verbinden, zenden, etc) van de gemeten tijden" #: help.c:245 msgid "from what ping value to show the value in red (must be bigger than yellow), only in color mode (-Y)" msgstr "toon de waardes in rood vanaf welke gemeten tijden" #: help.c:246 msgid "from what ping value to show the value in yellow" msgstr "toon de waardes in 't geel vanaf welke gemeten tijden" #: help.c:247 msgid "from what ping value to show the results" msgstr "filter alle metingen die beneden deze waarde vallen" #: help.c:248 msgid "put a timestamp before the measured values, use -v to include the date and -vv to show in microseconds" msgstr "toon een tijdstempel voor iedere gemeten waarde. gebruik -v om ook de datum te zien en -vv om ook microseconden te zien" #: help.c:249 msgid "show an aggregate each x[/y[/z[/etc]]] seconds" msgstr "toon cumulatief de waardes van x[/y[/etc]] seconden" #: help.c:251 msgid "show fingerprint (SSL)" msgstr "toon een vingerafdruk voor de SSL-verbinding" #: help.c:253 msgid "verbose mode" msgstr "toon meer details" #: help.c:257 #, c-format msgid " *** \"GET\" (instead of HTTP \"HEAD\") settings ***\n" msgstr " *** \"GET\" (in plaats van HTTP \"HEAD\") instellingen ***\n" #: help.c:258 msgid "do a GET request instead of HEAD (read the contents of the page as well)" msgstr "doe een GET verzoek in plaats van een HEAD verzoek en haal ook de inhoud van een pagina op" #: help.c:259 msgid "show transfer speed in KB/s (use with -G)" msgstr "toon de verzendsnelheid in KB/s (gebruik in combinatie met -G)" #: help.c:260 msgid "like -b but use compression if available" msgstr "zoals -b maar gebruik compressie als het HTTP systeem dit ondersteunt" #: help.c:261 msgid "limit the amount of data transferred (for -b) to 'x' (in bytes)" msgstr "limiteer de hoeveelheid verzonden data (ism -b) tot 'x' bytes" #: help.c:262 msgid "show the number of KB transferred (for -b)" msgstr "toon de totaal verzonden hoeveelheid data (in KB, ism -b)" #: help.c:266 #, c-format msgid " *** output mode settings ***\n" msgstr " *** uitvoer modeinstellingen ***\n" #: help.c:267 msgid "quiet, only returncode" msgstr "toon niets, geef alleen een resultaatwaarde terug" #: help.c:268 msgid "give machine parseable output (see also -o and -e)" msgstr "toon resultaat in computervriendelijkformaat (zie ook -o en -e)" #: help.c:269 msgid "json output, cannot be combined with -m" msgstr "json uitvoer, kan niet met -m gecombineerd worden" #: help.c:270 msgid "what http results codes indicate 'ok' comma separated WITHOUT spaces inbetween default is 200, use with -e" msgstr "welke HTTP statuscodes als 'ok' te beschouwen. dit moet een met komma gescheiden lijst (geen spaties) zijn. de standaard waarde is 200. gebruik deze instelling ism -e" #: help.c:271 msgid "string to display when http result code doesn't match" msgstr "wat te laten zien als de HTTP statuscodes niet overeenkomen" #: help.c:272 msgid "Nagios-mode: return 1 when avg. response time >= warn, 2 if >= crit, otherwhise return 0" msgstr "Nagios-mode 1: geef 1 terug als de gemiddelde reactiesnelheid >= \"warn\" en 2 als die snelheid >= \"crit\", anders geef 0 terug" #: help.c:273 msgid "Nagios mode 2: return 0 when all fine, 'x' when anything failes" msgstr "Nagios mode 2: geef 0 terug als alles goed ging, anders 'x'" #: help.c:274 msgid "add a cookie to the request" msgstr "voeg een cookie toe aan het HTTP-verzoek" #: help.c:275 msgid "add colors" msgstr "gebruik kleuren" #: help.c:276 msgid "audible ping" msgstr "hoorbare piep" #: help.c:281 #, c-format msgid " *** GUI/ncurses mode settings ***\n" msgstr " *** grafische interface/ncurses mode instellingen ***\n" #: help.c:282 msgid "ncurses/GUI mode" msgstr "ncurses/GUI mode" #: help.c:284 msgid "draw phase (fourier transform) in gui" msgstr "toon fasediagram" #: help.c:286 msgid "when the duration is x or more, show ping line in the slow log window (the middle window)" msgstr "als de tijdmetingen groter zijn dan x, toon dan het resultaat in het middelste venster" #: help.c:287 msgid "do not scale to values above x" msgstr "schaal niet naar waardes boven 'x'" #: help.c:288 msgid "do not show graphs (in ncurses/GUI mode)" msgstr "toon geen grafieken" #: help.c:292 msgid "show the version" msgstr "toon de versie van dit programma" #: help.c:305 #, c-format msgid "Voorbeeld:\n" msgstr "" #: io.c:43 #: io.c:78 #, c-format msgid "myread::select failed: %s" msgstr "leesfout: %s" #: io.c:94 #, c-format msgid "myread::read failed: %s" msgstr "leesfout: %s" #: io.c:138 #, c-format msgid "mywrite::select failed: %s" msgstr "selecteer fout: %s" #: io.c:152 #, c-format msgid "mywrite::write failed: %s" msgstr "schrijffout: %s" #: io.c:174 #, c-format msgid "set_fd_nonblocking failed! (%s)\n" msgstr "\"set_fd_nonblocking\" fout: %s\n" #: io.c:187 #, c-format msgid "set_fd_blocking failed! (%s)\n" msgstr "\"set_fd_blocking\" fout: %s\n" #: main.c:109 #: main.c:108 #, c-format msgid "%s, run time: %.3fs, press ctrl + c to stop" msgstr "%s, loop tijd: %.3fs, druk op ctrl + c om het programma te stoppen" #: main.c:244 #: main.c:243 #, c-format msgid "Got signal %d\n" msgstr "Signaal %d\n" #: main.c:255 #: main.c:254 #, c-format msgid "Cannot open password-file %s" msgstr "Kan het toegangscodebestand '%s' niet openen" #: main.c:258 #: main.c:257 #, c-format msgid "Problem reading password from file %s" msgstr "Probleem bij het lezen van de toegangscode uit bestand '%s'" #: main.c:365 #: main.c:364 #, c-format msgid "URL too big, HTTPing has a %d bytes limit" msgstr "URL is te groot, HTTPing heeft daar een limiet van %d bytes op" #: main.c:384 #: main.c:383 msgid "using \"http://\" with SSL enabled (-l)" msgstr "\"http://\" gebruikt met SSL ingeschakeld (-l)" #: main.c:519 #: main.c:518 #, c-format msgid "AGG[%d]: %d values, min/avg/max%s = %.1f/%.1f/%.1f" msgstr "CUM[%d]: %d waardes, min/gem/max%s = %.1f/%.1f/%.1f" #: main.c:519 #: main.c:2294 #: main.c:518 #: main.c:2289 msgid "/sd" msgstr "/sd" #: main.c:576 #: main.c:575 msgid "-n: missing parameter\n" msgstr "-n: ontbrekende parameter\n" #: main.c:594 #: main.c:603 #: main.c:593 #: main.c:602 #, c-format msgid "cannot convert ip address '%s' (for -y)\n" msgstr "kan het IP-adres '%s' niet vertalen (-y)\n" #: main.c:710 #: main.c:709 #, c-format msgid "CRITICAL - connecting failed: %s" msgstr "KRITIEK - verbinding mislukt: %s" #: main.c:715 #: main.c:714 #, c-format msgid "CRITICAL - average httping-time is %.1f\n" msgstr "KRITIEK - gemiddelde HTTPing tijd is %.1f\n" #: main.c:720 #: main.c:719 #, c-format msgid "WARNING - average httping-time is %.1f\n" msgstr "WAARSCHUWING - gemiddelde HTTPing tijd is %.1f\n" #: main.c:724 #: main.c:723 #, c-format msgid "OK - average httping-time is %.1f (%s)|ping=%f\n" msgstr "OK - gemiddelde HTTPing-tijd is %.1f (%s)|ping=%f\n" #: main.c:734 #: main.c:733 #, c-format msgid "OK - all fine, avg httping time is %.1f|ping=%f\n" msgstr "OK - gemiddelde HTTPing-tijd is %.1f|ping=%f\n" #: main.c:738 #: main.c:737 #, c-format msgid "%s: - failed: %s" msgstr "%s: - mislukt: %s" #: main.c:1025 #: main.c:1020 #, c-format msgid "" "\n" " *** -A is no longer required ***\n" "\n" msgstr "" "\n" " *** -A is niet langer nodig ***\n" "\n" #: main.c:1170 #: main.c:1165 msgid "-i cannot have a value smaller than zero" msgstr "-i waarde kan niet kleiner dan 0 zijn" #: main.c:1224 #: main.c:1232 #: main.c:1219 #: main.c:1227 msgid "-n and -N are mutual exclusive\n" msgstr "-n en -N zijn wederzijds uitsluitende\n" #: main.c:1253 #: main.c:1248 #, c-format msgid "Warning: TCP TFO is not supported. Disabling.\n" msgstr "Let op: TCP TFO is niet ondersteund.\n" #: main.c:1269 #: main.c:1264 #, c-format msgid "" "\n" "\n" "Please run:\n" "\t%s --help\n" "to see a list of options.\n" "\n" msgstr "" "\n" "\n" "Start:\n" "\t%s --help\n" "om een lijst van opties te zien.\n" "\n" #: main.c:1281 #, c-format msgid "" "No URL/host to ping given\n" "\n" msgstr "" "Geen URL of systeemnaam gespecificeerd om te pingen\n" "\n" #: main.c:1291 #: main.c:1286 msgid "Cannot combine -m, -M and -K" msgstr "-m, -M en -K kunnen niet gecombineerd worden" #: main.c:1294 #: main.c:1289 msgid "Aggregates can only be used in non-machine/json-output mode" msgstr "Cumulatieven kunnen niet in machine-uitvoer/json-uitvoer modi gebruikt worden" #: main.c:1299 #: main.c:1294 msgid "-b/-B can only be used when also using -G (GET instead of HEAD) or -l (use SSL)\n" msgstr "-b/-B kunnen alleen gebruikt worden ism -G or -l\n" #: main.c:1302 #: main.c:1297 msgid "TCP Fast open and SSL not supported together\n" msgstr "\"TCP Fast open\" en SSL kunnen niet gecombineerd worden\n" #: main.c:1332 #: main.c:1327 msgid "" "\n" "Auto enabling SSL due to https-URL" msgstr "" "\n" "SSL ingeschakeld vanwege https-URL" #: main.c:1338 #: main.c:1333 #, c-format msgid "Auto enabling SSL due to https-URL" msgstr "SSL ingeschakeld vanwege https-URL" #: main.c:1347 #: main.c:1342 #, c-format msgid "" "\n" "Connecting to host %s, port %d and requesting file %s" msgstr "" "\n" "Verbinden met %s:%d en opvragen van bestand %s" #: main.c:1350 #: main.c:1345 #, c-format msgid "" "\n" "Using proxyserver: %s:%d" msgstr "" "\n" "Proxy %s:%d wordt gebruikt" #: main.c:1355 #: main.c:1350 #, c-format msgid "" "Connecting to host %s, port %d and requesting file %s\n" "\n" msgstr "" "Verbinden met %s:%d en opvragen van bestand %s\n" "\n" #: main.c:1358 #: main.c:1353 #, c-format msgid "Using proxyserver: %s:%d\n" msgstr "Proxy: %s:%d\n" #: main.c:1369 #: main.c:1364 msgid "problem creating SSL context" msgstr "Probleem bij aanmaken SSL-context" #: main.c:1389 #: main.c:1384 msgid "Interval must be > 0 when using adaptive interval" msgstr "Interval moet groter dan 0 zijn bij adaptieve interval" #: main.c:1417 #: main.c:1435 #: main.c:1519 #: main.c:1412 #: main.c:1430 #: main.c:1514 #, c-format msgid "" "\n" "Resolving hostname %s" msgstr "" "\n" "Vertalen systeemnaam '%s'" #: main.c:1427 #: main.c:1452 #: main.c:1545 #: main.c:1422 #: main.c:1447 #: main.c:1540 #, c-format msgid "No valid IPv4 or IPv6 address found for %s" msgstr "Geen geldig IPv4 of IPv6 adres gevonden voor '%s'" #: main.c:1579 #: main.c:1574 msgid "Will no longer inform about request headers too large." msgstr "Zal niet langer meldingen tonen over te grote verzoeken." #: main.c:1581 #: main.c:1576 #, c-format msgid "Request headers > 4KB! (%d bytes) This may give failures with some HTTP servers." msgstr "Verzoek is groter dan 4KB! (%d bytes) Dit kan problemen opleveren met sommige HTTP-servers." #: main.c:1685 #: main.c:1680 msgid "timeout connecting to host" msgstr "systeem reageerde niet op tijd" #: main.c:1748 #: main.c:1743 msgid "error sending request to host" msgstr "probleem bij verzenden verzoek naar systeem" #: main.c:1750 #: main.c:1800 #: main.c:1745 #: main.c:1795 msgid "timeout sending to host" msgstr "systeem reageerde niet op tijd bij verzenden verzoek" #: main.c:1752 #: main.c:1747 msgid "retrieved invalid data from host" msgstr "ongeldige data ontvangen van systeem" #: main.c:1756 #: main.c:1751 msgid "connection prematurely closed by peer" msgstr "verbinding voortijdig gesloten door systeem" #: main.c:1790 #: main.c:1785 msgid "" "\n" "No longer emitting message about \"still data in transit\"" msgstr "" "\n" "Er zullen geen meldingen meer getoond worden over data die nog getransporteerd wordt." #: main.c:1792 #: main.c:1787 #, c-format msgid "" "\n" "HTTP server started sending data with %d bytes still in transit" msgstr "" "\n" "HTTP server begon al een reaktie te versturen terwijl er nog %d bytes onderweg waren" #: main.c:1813 #: main.c:1808 msgid "failed to obtain TOS info" msgstr "probleem bij ophalen TOS-informatie" #: main.c:1827 #: main.c:1822 msgid "" "\n" "No longer emitting message about \"more data than response headers\"" msgstr "" "\n" "De melding \"HTTP server verzond meer data dan alleen de antwoord metadata\" zal niet meer getoond worden." #: main.c:1829 #: main.c:1824 msgid "" "\n" "HTTP server sent more data than just the response headers" msgstr "" "\n" "HTTP server verzond meer data dan alleen de antwoord metadata" #: main.c:1878 #: main.c:1873 msgid "'Content-Length'-header missing!" msgstr "'Content-Length' metadata ontbreekt" #: main.c:1910 #: main.c:1905 msgid "short read during receiving reply-headers from host" msgstr "ontvangprobleem bij metadata van systeem" #: main.c:1912 #: main.c:1907 msgid "timeout while receiving reply-headers from host" msgstr "geen reactie bij ontvangen metadata van systeem" #: main.c:1945 #: main.c:1940 msgid "read of response body dataa failed" msgstr "lezen van reactiedata mislukt" #: main.c:1980 #: main.c:1975 msgid "error shutting down ssl" msgstr "probleem bij stoppen SSL-verbinding" #: main.c:2026 #: main.c:2087 #: main.c:2021 #: main.c:2082 #, c-format msgid "getnameinfo() failed: %d (%s)" msgstr "getnameinfo() faalde: %d (%s)" #: main.c:2061 #: main.c:2056 msgid "connected to" msgstr "verbinden met" #: main.c:2061 #: main.c:2056 msgid "pinged host" msgstr "gepingde systeem" #: main.c:2105 #: main.c:2100 #, c-format msgid "%s%s%s%s%s:%s%d%s (%d/%d bytes), seq=%s%d%s " msgstr "%s%s%s%s%s:%s%d%s (%d/%d bytes), volgnr=%s%d%s " #: main.c:2107 #: main.c:2102 #, c-format msgid "%s%s%s%s%s:%s%d%s (%d bytes), seq=%s%d%s " msgstr "%s%s%s%s%s:%s%d%s (%d bytes), volgnr=%s%d%s " #: main.c:2113 #: main.c:2114 #: nc.c:721 #: main.c:2108 #: main.c:2109 msgid " n/a" msgstr " ---" #: main.c:2119 #: main.c:2114 #, c-format msgid "time=%s+%s+%s+%s+%s%s=%s%s%s%s ms %s%s%s" msgstr "tijd=%s+%s+%s+%s+%s%s=%s%s%s%s ms %s%s%s" #: main.c:2129 #: main.c:2124 #, c-format msgid "time=%s%s%s ms %s%s%s" msgstr "tijd=%s%s%s ms %s%s%s" #: main.c:2149 #: main.c:2144 msgid "not " msgstr "niet " #: main.c:2150 #: main.c:2145 msgid "compressed)" msgstr "gecomprimeerd)" #: main.c:2162 #: main.c:2157 #, c-format msgid " toff=%d" msgstr " tijdoffset=%d" #: main.c:2166 #: main.c:2161 #, c-format msgid " age=%d" msgstr " leeftijd=%d" #: main.c:2282 #: main.c:2277 #, c-format msgid "--- %s ping statistics ---\n" msgstr "--- %s ping statistieken ---\n" #: main.c:2285 #: main.c:2280 #, c-format msgid "internal error! (curncount)\n" msgstr "interne fout! (curncount)\n" #: main.c:2290 #: main.c:2285 #, c-format msgid "%s%d%s connects, %s%d%s ok, %s%3.2f%%%s failed, time %s%s%.0fms%s\n" msgstr "%s%d%s verbindingen, %s%d%s ok, %s%3.2f%%%s mislukt, tijd %s%s%.0fms%s\n" #: main.c:2294 #: main.c:2289 #, c-format msgid "round-trip min/avg/max%s = %s%.1f%s/%s%.1f%s/%s%.1f%s" msgstr "retour min/gem/max%s = %s%.1f%s/%s%.1f%s/%s%.1f%s" #: main.c:2305 #: main.c:2300 #, c-format msgid "Transfer speed: min/avg/max = %s%f%s/%s%f%s/%s%f%s KB\n" msgstr "Verzendsnelheid: min/gem/max = %s%f%s/%s%f%s/%s%f%s KB\n" #: mssl.c:79 #, c-format msgid "READ_SSL: io-error: %s" msgstr "SSL lezen, I/O fout: %s" #: mssl.c:110 #, c-format msgid "WRITE_SSL: io-error: %s" msgstr "SSL schrijven, I/O fout: %s" #: mssl.c:141 #, c-format msgid "problem setting receive timeout (%s)" msgstr "probleem bij instellen ontvangsttijdslimiet (%s)" #: mssl.c:147 #, c-format msgid "problem setting transmit timeout (%s)" msgstr "probleem bij instellen verzendtijdslimiet (%s)" #: mssl.c:159 #, c-format msgid "problem starting SSL connection: %d" msgstr "probleem bij starten SSL verbinding: %d" #: mssl.c:259 msgid "Problem sending request to proxy" msgstr "Probleem bij verzenden verzoek naar proxy" #: mssl.c:268 msgid "Problem retrieving proxy response" msgstr "Probleem in ontvangen proxyreactie" #: mssl.c:282 msgid "Invalid proxy response headers" msgstr "Ongeldige proxyreactie" #: mssl.c:289 #, c-format msgid "Proxy indicated error: %s" msgstr "Proxy gaf een fout aan: %s" #: nc.c:57 msgid "realloc issue" msgstr "geheugenfout" #: nc.c:542 #, c-format msgid "highest: %6.2fHz, avg: %6.2fHz" msgstr "hoogste: %6.2fHz, gem: %6.2fHz" #: nc.c:668 #, c-format msgid "graph range: %7.2fms - %7.2fms " msgstr "grafiekbandbreedte: %7.2fms - %7.2fms " #: nc.c:732 #, c-format msgid "%s: n/a" msgstr "%s: ---" #: nc.c:749 msgid "latest" msgstr "laatste" #: nc.c:749 #: nc.c:769 msgid "min" msgstr "min" #: nc.c:749 #: nc.c:769 msgid "avg" msgstr "gem" #: nc.c:749 #: nc.c:769 msgid "max" msgstr "max" #: nc.c:749 #: nc.c:769 msgid "sd" msgstr "sd" #: nc.c:750 msgid "resolve" msgstr "vertaal" #: nc.c:751 msgid "connect" msgstr "verbind" #: nc.c:752 msgid "ssl " msgstr "ssl " #: nc.c:753 msgid "send " msgstr "zend " #: nc.c:754 msgid "request" msgstr "verzoek" #: nc.c:755 msgid "close " msgstr "sluiten" #: nc.c:756 msgid "total " msgstr "totaal " #: nc.c:760 #, c-format msgid "ok: %3d, fail: %3d%s, scc: %s, kalman: %s" msgstr "ok: %2d, mislukt: %2d%s, scc: %s, Kalman: %s" #: nc.c:760 msgid ", with TFO" msgstr ", met TFO" #: nc.c:769 msgid "cur" msgstr "nu" #: nc.c:770 msgid "t offst" msgstr "t offst" #: nc.c:773 msgid "tcp rtt" msgstr "TCP RTT" #: nc.c:775 msgid "headers" msgstr "meta " #: nc.c:782 #, c-format msgid "# cookies: %d" msgstr "# cookies: %d" #: nc.c:784 #, c-format msgid "trend: %c%6.2f%%, re-tx: %2d, pmtu: %5d, TOS: %02x" msgstr "trend: %c%6.2f%%, re-tx: %2d, pmtu: %5d, TOS: %02x" #: nc.c:787 #, c-format msgid "HTTP rc: %s, SSL fp: %s" msgstr "HTTP rc: %s, SSL va: %s" #: nc.c:787 msgid "n/a" msgstr "---" #: nc.c:795 #, c-format msgid "http result code: %s" msgstr "HTTP statuscode: %s" #: nc.c:799 #, c-format msgid "" "\n" "SSL fingerprint: %s" msgstr "" "\n" "SSL vingerafdruk: %s" #: res.c:36 #, c-format msgid "Resolving %s %sfailed: %s" msgstr "Vertalen %s %smislukt: %s" #: res.c:36 msgid "(IPv6) " msgstr "(IPv6) " #: res.c:71 #, c-format msgid "Problem resolving %s (IPv4): %s" msgstr "Probleem vertalen %s (IPv4): %s" #: socks5.c:56 #, c-format msgid "socks5connect: reply with requested authentication method does not say version 5 (%02x)" msgstr "socks5connect: reactie geeft niet versie 5 aan (%02x)" #: socks5.c:70 #, c-format msgid "socks5connect: socks5 refuses our authentication methods: %02x" msgstr "socks5connect: socks5 systeem wijst onze authenticatie methode af: %02x" #: socks5.c:81 msgid "socks5connect: socks5 server requests username/password authentication" msgstr "socks5connect: systeem vraagt gebruikersnaamauthenticatie" #: socks5.c:90 msgid "socks5connect: failed transmitting username/password to socks5 server" msgstr "socks5connect: probleem bij verzenden gebrukersnaam/toegangscode naar systeem" #: socks5.c:96 msgid "socks5connect: failed receiving authentication reply" msgstr "socks5connect: authenticatie reactie ontvangen mislukt" #: socks5.c:102 msgid "socks5connect: password authentication failed" msgstr "socks5connect: authenticatie faalde" #: socks5.c:116 #, c-format msgid "Cannot resolve %s" msgstr "Kan %s niet vertalen" #: socks5.c:133 msgid "socks5connect: failed to transmit associate request" msgstr "socks5connect: \"associatie\"-verzoek verzenden mislukt" #: socks5.c:139 msgid "socks5connect: command reply receive failure" msgstr "socks5connect: commando-reactie ontvangen mislukt" #: socks5.c:146 #, c-format msgid "socks5connect: bind request replies with version other than 0x05 (%02x)" msgstr "socks5connect: verbindingsreactie geeft ander versienummer (%02x) dan 0x05 terug" #: socks5.c:152 #, c-format msgid "socks5connect: failed to connect (%02x)" msgstr "socks5connect: verbinden mislukt (%02x)" #: socks5.c:158 #, c-format msgid "socks5connect: only accepting bind-replies with IPv4 address (%02x)" msgstr "socks5connect: alleen \"bind\"-reakties voor IPv4 ondersteund (%02x)" #: tcp.c:31 #: tcp.c:42 #, c-format msgid "could not set TCP_NODELAY on socket (%s)" msgstr "kan TCP_NODELAY niet inschakelen op verbinding (%s)" #: tcp.c:57 #, c-format msgid "problem creating socket (%s)" msgstr "probleem bij maken socket (%s)" #: tcp.c:69 #, c-format msgid "error setting sockopt to interface (%s)" msgstr "sockopt zetten op adapter mislukt (%s)" #: tcp.c:75 #, c-format msgid "error binding to interface (%s)" msgstr "probleem bij binden aan adapter (%s)" #: tcp.c:84 #, c-format msgid "error setting MTU size (%s)" msgstr "probleem bij instellen MTU-grootte (%s)" #: tcp.c:101 #, c-format msgid "error setting transmit buffer size (%s)" msgstr "probleem bij instellen verzendbuffergrootte (%s)" #: tcp.c:110 #, c-format msgid "error setting receive buffer size (%s)" msgstr "probleem bij instellen ontvangstbuffergrootte (%s)" #: tcp.c:119 #, c-format msgid "error setting priority (%s)" msgstr "probleem bij instellen prioriteit (%s)" #: tcp.c:128 msgid "failed to set TOS info" msgstr "probleem bij instellen TOS-info" #: tcp.c:165 #, c-format msgid "TCP TFO Not Supported. Please check if \"/proc/sys/net/ipv4/tcp_fastopen\" is 1. Disabling TFO for now.\n" msgstr "TCP TFO is niet ondersteund. Controleer of \"/proc/sys/net/ipv4/tcp_fastopen\" de waarde 1 bevat.\n" #: tcp.c:195 #, c-format msgid "problem connecting to host: %s" msgstr "probleem bij verbinden met systeem: %s" #: tcp.c:208 msgid "connect time out" msgstr "verbindingstimeout" #: tcp.c:216 #, c-format msgid "select() failed: %s" msgstr "select() mislukt: %s" #: tcp.c:228 #, c-format msgid "getsockopt failed (%s)" msgstr "getsockopt mislukt (%s)" #: tcp.c:240 #, c-format msgid "could not connect (%s)" msgstr "kan niet verbinden (%s)" #: utils.c:25 msgid "gettimeofday failed" msgstr "gettimeofday mislukt" #~ #: main.c:1276 main.c:1271 #~ msgid "Cannot combine maximum MTU size setting with proxy connections or SSL" #~ msgstr "" httping-2.5/readme.txt000066400000000000000000000026241276547250600150550ustar00rootroot00000000000000Installation: ------------ make install This will first invoke the 'configure'-script and then build the sources. You can also run 'configure' manually. Then the following switches apply: --with-tfo force enable tcp fast open --with-ncurses force enable ncurses --with-openssl force enable openssl --with-fftw3 force enable fftw3 Please note that TCP fast open requires a Linux kernel of version 3.7 or more recent. 'fftw3' support is only useful if you include the ncurses interface. Debian package names: ncurses requires libncursesw5-dev fftw3 requires libfftw3-dev openssl requires libssl-dev Usage: ----- httping www.vanheusden.com See: httping -h for a list of commandline switches. Also check the man-page. plot-json.py is a script to convert the json-output of httping to a script for gnuplot. If this script fails with the following error: ValueError: Expecting object: [...] then make sure the json-file ends with a ']' (without the quotes). In some cases this character is missing. Thanks to Thanatos for cookie and authentication support. Many thanks to Olaf van der Spek for lots of bug-reports, testing, ideas and suggestions. For everything more or less related to 'httping', please feel free to contact me on: mail@vanheusden.com Please support my opensource development: http://www.vanheusden.com/wishlist.php Or send any surplus bitcoins to 1N5Sn4jny4xVwTwSYLnf7WnFQEGoVRmTQF httping-2.5/res.c000066400000000000000000000033741276547250600140170ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #include #include #include #include #include #include #include #include #include #include #include "gen.h" #include "res.h" #include "error.h" int resolve_host(const char *host, struct addrinfo **ai, char use_ipv6, int portnr) { int rc = -1; char servname[10]; struct addrinfo myaddr; memset(&myaddr, 0, sizeof myaddr); /* myaddr.ai_flags = AI_PASSIVE; */ myaddr.ai_socktype = SOCK_STREAM; myaddr.ai_protocol = IPPROTO_TCP; myaddr.ai_family = use_ipv6 ? AF_INET6 : AF_INET; snprintf(servname, sizeof servname, "%d", portnr); rc = getaddrinfo(host, servname, &myaddr, ai); if (rc != 0) set_error(gettext("Resolving %s %sfailed: %s"), host, use_ipv6 ? gettext("(IPv6) ") : "", gai_strerror(rc)); return rc; } struct addrinfo * select_resolved_host(struct addrinfo *ai, char use_ipv6) { struct addrinfo *p = ai; while(p) { if (p -> ai_family == AF_INET6 && use_ipv6) return p; if (p -> ai_family == AF_INET) return p; p = p -> ai_next; } return NULL; } void get_addr(struct addrinfo *ai_use, struct sockaddr_in6 *addr) { memcpy(addr, ai_use->ai_addr, ai_use->ai_addrlen); } #define incopy(a) *((struct in_addr *)a) int resolve_host_ipv4(const char *host, struct sockaddr_in *addr) { struct hostent *hostdnsentries = gethostbyname(host); if (hostdnsentries == NULL) { set_error(gettext("Problem resolving %s (IPv4): %s"), host, hstrerror(h_errno)); return -1; } /* create address structure */ addr -> sin_family = hostdnsentries -> h_addrtype; addr -> sin_addr = incopy(hostdnsentries -> h_addr_list[0]); return 0; } httping-2.5/res.h000066400000000000000000000006561276547250600140240ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #define incopy(a) *((struct in_addr *)a) int resolve_host(const char *host, struct addrinfo **ai, char use_ipv6, int portnr); struct addrinfo * select_resolved_host(struct addrinfo *ai, char use_ipv6); void get_addr(struct addrinfo *ai_use, struct sockaddr_in6 *addr); int resolve_host_ipv4(const char *host, struct sockaddr_in *addr); httping-2.5/ru.po000066400000000000000000001077431276547250600140550ustar00rootroot00000000000000# Russian translation for HTTPing package. # Copyright (C) 2016 folkert van heusden # This file is distributed under the same license as the HTTPing package. # folkert van heusden , 2016. # Translated by Way, No - http://noway421.github.io/ # msgid "" msgstr "" "Project-Id-Version: HTTPing\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-05-04 15:29+0200\n" "PO-Revision-Date: 2016-07-13 16:00+1100\n" "Last-Translator: Way, No \n" "Language-Team: Russian\n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11) ? 0 : ((n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20)) ? 1 : 2);\n" "X-Poedit-Language: Russian\n" "X-Poedit-Country: RUSSIAN FEDERATION\n" #: error.c:23 #, c-format msgid "" "\n" "\n" "errno=%d which means %s (if applicable)\n" msgstr "" "\n" "\n" "errno=%d что значит: %s (если применимо)\n" #: error.c:39 #, c-format msgid "Error message '%s' truncated" msgstr "Сообщение об ошибке '%s' урезано." #: fft.c:21 msgid "failed allocating memory for fft (1)" msgstr "не удалось выделить память для fft (1)." #: fft.c:25 msgid "failed allocating memory for fft (2)" msgstr "не удалось выделить память для fft (2)." #: fft.c:30 msgid "failed calculating plan for fft" msgstr "не удалось вычислить план для fft." #: help.c:77 #, c-format msgid "HTTPing v" msgstr "HTTPing версия" msgid "adds an extra request-header" msgstr "добавляет дополнительный заголовок запроса" #: help.c:79 #, c-format msgid " * SSL support included (-l)\n" msgstr " * SSL поддержка включена (-l)\n" #: help.c:84 #, c-format msgid " * ncurses interface with FFT included (-K)\n" msgstr " * ncurses интерфейс с FFT включен (-K)\n" #: help.c:86 #, c-format msgid " * ncurses interface included (-K)\n" msgstr " * ncurses интерфейс включен (-K)\n" #: help.c:91 #, c-format msgid " * TFO (TCP fast open) support included (-F)\n" msgstr " * TFO (TCP fast open) поддержка включена' (-F)\n" #: help.c:93 #: help.c:293 #, c-format msgid "\n" msgstr "\n" #: help.c:176 #, c-format msgid " *** where to connect to ***\n" msgstr " *** куда подключаться ***\n" #: help.c:177 msgid "URL to ping (e.g. -g http://localhost/)" msgstr "URL для пинга (к примеру, -g http://localhost/)" #: help.c:178 msgid "hostname to ping (e.g. localhost) - use either -g or -h" msgstr "имя хоста для пинга (к примеру, localhost) - используйте -g или -h" #: help.c:179 msgid "portnumber (e.g. 80) - use with -h" msgstr "номер порта (к примеру, 80), используется с -h" #: help.c:180 msgid "use IPv6 when resolving/connecting" msgstr "использовать IPv6 для резолва/подключения" #: help.c:182 msgid "connect using SSL. pinging an https URL automatically enables this setting" msgstr "подключаться с SSL. при пинге https URL эта опция включается автоматически" #: help.c:187 #, c-format msgid " *** proxy settings ***\n" msgstr " *** настройки proxy ***\n" #: help.c:188 msgid "x should be \"host:port\" which are the network settings of the http/https proxy server. ipv6 ip-address should be \"[ip:address]:port\"" msgstr "x должен быть \"host:port\", т.е. сетевыми настройками http/https прокси сервера. ipv6 адрес должен быть в формате \"[ip:address]:port\"" #: help.c:189 msgid "fetch proxy settings from environment variables" msgstr "читать настройки прокси из переменных окружения" #: help.c:190 msgid "username for authentication against proxy" msgstr "имя пользователя для прокси аутентификации" #: help.c:191 msgid "password for authentication against proxy" msgstr "пароль для прокси аутентификации" #: help.c:192 msgid "read password for proxy authentication from file x" msgstr "читать пароль для прокси аутентификации из файла x" #: help.c:193 msgid "proxy is a socks5 server" msgstr "прокси является socks5 сервером" #: help.c:194 msgid "adds \"&x=[random value]\" to the request URL" msgstr "добавляет \"&x=[случайное значение]\" к URL запроса" #: help.c:198 #, c-format msgid " *** timing settings ***\n" msgstr " *** настройки времени ***\n" #: help.c:199 msgid "how many times to ping" msgstr "сколько раз исполнять пинг" #: help.c:200 msgid "delay between each ping" msgstr "задержка между каждым пингом" #: help.c:201 msgid "timeout (default: 30s)" msgstr "тайм-аут (по умолчанию: 30 секунд)" #: help.c:202 msgid "execute pings at multiples of interval relative to start, automatically enabled in ncurses output mode" msgstr "выполнять пинги пропорционально интервалам относительно начала, автоматически включено в ncurses режиме вывода" #: help.c:203 msgid "flood connect (no delays)" msgstr "подключение в режиме флуда (без задержек)" #: help.c:207 #, c-format msgid " *** HTTP settings ***\n" msgstr " *** HTTP настройки ***\n" #: help.c:208 msgid "ask any proxies on the way not to cache the requests" msgstr "просить все прокси по пути не кэшировать запросы" #: help.c:209 msgid "connect to a different host than in the URL given" msgstr "подключиться к другому хосту, отличному от данного в URL" #: help.c:210 msgid "return the cookies given by the HTTP server in the following request(s)" msgstr "возвращать куки выданные HTTP сервером в следующем запросе(ах)" #: help.c:211 msgid "do not add \"Host:\"-line to the request headers" msgstr "не добавлять \"Host:\" строку к заголовку запроса" #: help.c:212 msgid "use a persistent connection, i.e. reuse the same TCP connection for multiple HTTP requests. usually possible when 'Connection: Keep-Alive' is sent by server. adds a 'C' to the output if httping had to reconnect" msgstr "использовать постоянное соединение, т.е. переиспользовать то же самое TCP соединение для нескольких HTTP запросов. обычно возможно когда 'Connection: Keep-Alive' отправлено сервером. добавляет 'C' в вывод если httping был вынужден переподключиться" #: help.c:213 msgid "use 'x' for the UserAgent header" msgstr "использовать 'x' в качестве заголовка UserAgent" #: help.c:214 msgid "use 'x' for the Referer header" msgstr "использовать 'x' в качестве заголовка Referer" #: help.c:218 #, c-format msgid " *** networking settings ***\n" msgstr " *** настройки сети ***\n" #: help.c:219 msgid "limit the MTU size" msgstr "ограничивать размер MTU" #: help.c:220 msgid "do not disable Naggle" msgstr "не отключать алгоритм Naggle" #: help.c:221 msgid "receive buffer size" msgstr "размер буфера приема" #: help.c:222 msgid "transmit buffer size" msgstr "размер буфера передачи" #: help.c:223 msgid "resolve hostname only once (useful when pinging roundrobin DNS: also takes the first DNS lookup out of the loop so that the first measurement is also correct)" msgstr "резолвить имя хоста только один раз (полезно, когда пингуется round robin DNS: также берется первый DNS ответ из цикла таким образом, что первое измерение тоже корректно)" #: help.c:224 msgid "do not abort the program if resolving failed: keep retrying" msgstr "не выходить из программы если резолвинг не удался: продолжать попытки" #: help.c:225 msgid "bind to an ip-address (and thus interface) with an optional port" msgstr "биндиться на ip адрес (и, соответственно, интерфейс), опционально на порт" #: help.c:227 msgid "\"TCP fast open\" (TFO), reduces the latency of TCP connects" msgstr "\"TCP fast open\" (TFO), уменьшает задержку TCP подключений" #: help.c:229 msgid "set priority of packets" msgstr "устанавливать приоритет пакетов" #: help.c:230 msgid "set TOS (type of service)" msgstr "устанавливать TOS (тип сервиса)" #: help.c:234 #, c-format msgid " *** HTTP authentication ***\n" msgstr " *** HTTP аутентификация ***\n" #: help.c:235 msgid "activate (\"basic\") authentication" msgstr "активировать (\"basic\") аутентификацию" #: help.c:236 msgid "username for authentication" msgstr "имя пользователя для аутентификации" #: help.c:237 msgid "password for authentication" msgstr "пароль для аутентификации" #: help.c:238 msgid "read the password fom the file 'x' (replacement for -P)" msgstr "читать пароль из файла 'x' (замена -P)" #: help.c:242 #, c-format msgid " *** output settings ***\n" msgstr " *** настройки вывода ***\n" #: help.c:243 msgid "show statuscodes" msgstr "показывать коды ответа" #: help.c:244 msgid "split measured time in its individual components (resolve, connect, send, etc." msgstr "разделять замеренное время на индивидуальные составляющие (резолв, подключение, отправка и т.п.)" #: help.c:245 msgid "from what ping value to show the value in red (must be bigger than yellow), only in color mode (-Y)" msgstr "начиная от какого значения пинга показывать значение красным (должно быть больше, чем желтое), только в цветном режиме (-Y)" #: help.c:246 msgid "from what ping value to show the value in yellow" msgstr "начиная от какого значения пинга показывать значение желтым" #: help.c:247 msgid "from what ping value to show the results" msgstr "начиная от какого значения пинга показывать результаты" #: help.c:248 msgid "put a timestamp before the measured values, use -v to include the date and -vv to show in microseconds" msgstr "показывать таймстамп перед измеренными значениями, используйте -v, чтобы включить дату и -vv, чтобы показывать микросекунды" #: help.c:249 msgid "show an aggregate each x[/y[/z[/etc]]] seconds" msgstr "показывать совокупный результат каждые x[/y[/z[/т.д.]]] секунд" #: help.c:251 msgid "show fingerprint (SSL)" msgstr "показывать фингерпринт (SSL)" #: help.c:253 msgid "verbose mode" msgstr "показывать подробности (verbose)" #: help.c:257 #, c-format msgid " *** \"GET\" (instead of HTTP \"HEAD\") settings ***\n" msgstr " *** \"GET\" (вместо HTTP \"HEAD\") настройки ***\n" #: help.c:258 msgid "do a GET request instead of HEAD (read the contents of the page as well)" msgstr "делать GET запрос вместо HEAD запроса (читать содержимое страницы в том числе)" #: help.c:259 msgid "show transfer speed in KB/s (use with -G)" msgstr "показывать скорость передачи в КБ/с (используется с -G)" #: help.c:260 msgid "like -b but use compression if available" msgstr "как и -b но использовать сжатие если доступно" #: help.c:261 msgid "limit the amount of data transferred (for -b) to 'x' (in bytes)" msgstr "ограничить количество переданных данных (для -b) до 'x' байт" #: help.c:262 msgid "show the number of KB transferred (for -b)" msgstr "показывать количество переданных данных в КБ (для -b)" #: help.c:266 #, c-format msgid " *** output mode settings ***\n" msgstr " *** настройки режима вывода ***\n" #: help.c:267 msgid "quiet, only returncode" msgstr "тихий режим, возвращать только код возврата" #: help.c:268 msgid "give machine parseable output (see also -o and -e)" msgstr "выдавать машиночитаемый вывод (смотрите также -o и -e)" #: help.c:269 msgid "json output, cannot be combined with -m" msgstr "json вывод, не может быть использовано вместе с -m" #: help.c:270 msgid "what http results codes indicate 'ok' comma separated WITHOUT spaces inbetween default is 200, use with -e" msgstr "какие HTTP коды ответа считать за 'ok'. разделять запятыми БЕЗ пробелов, по умолчанию 200, использовать вместе с -e" #: help.c:271 msgid "string to display when http result code doesn't match" msgstr "строка для показа когда код ответа HTTP не совпадает" #: help.c:272 msgid "Nagios-mode: return 1 when avg. response time >= warn, 2 if >= crit, otherwhise return 0" msgstr "Nagios-mode 1: возвращать 1 когда сред. времени ответа >= \"warn\", 2 когда оно >= \"crit\", в остальных случаях возвращать 0" #: help.c:273 msgid "Nagios mode 2: return 0 when all fine, 'x' when anything failes" msgstr "Nagios mode 2: возвращать 0 когда все в порядке, 'x' когда что-то идет не так" #: help.c:274 msgid "add a cookie to the request" msgstr "добавлять куки к запросу" #: help.c:275 msgid "add colors" msgstr "добавлять цвета" #: help.c:276 msgid "audible ping" msgstr "слышимый пинг" #: help.c:281 #, c-format msgid " *** GUI/ncurses mode settings ***\n" msgstr " *** Настройки режима GUI/ncurses ***\n" #: help.c:282 msgid "ncurses/GUI mode" msgstr "ncurses/GUI режим" #: help.c:284 msgid "draw phase (fourier transform) in gui" msgstr "рисовать фазу (преобразование Фурье) в GUI" #: help.c:286 msgid "when the duration is x or more, show ping line in the slow log window (the middle window)" msgstr "когда длительность больше или равна x, показывать строку пинга в окне медленного журнала (среднее окно)" #: help.c:287 msgid "do not scale to values above x" msgstr "не масштабировать значения больше 'x'" #: help.c:288 msgid "do not show graphs (in ncurses/GUI mode)" msgstr "не показывать графики (в ncurses/GUI режиме)" #: help.c:292 msgid "show the version" msgstr "показывать версию" #: help.c:305 #, c-format msgid "Voorbeeld:\n" msgstr "Пример:\n" #: io.c:43 #: io.c:78 #, c-format msgid "myread::select failed: %s" msgstr "myread::select потерпел неудачу: %s" #: io.c:94 #, c-format msgid "myread::read failed: %s" msgstr "myread::read потерпел неудачу: %s" #: io.c:138 #, c-format msgid "mywrite::select failed: %s" msgstr "mywrite::select потерпел неудачу: %s" #: io.c:152 #, c-format msgid "mywrite::write failed: %s" msgstr "mywrite::write потерпел неудачу: %s" #: io.c:174 #, c-format msgid "set_fd_nonblocking failed! (%s)\n" msgstr "set_fd_nonblocking потерпел неудачу! (%s)\n" #: io.c:187 #, c-format msgid "set_fd_blocking failed! (%s)\n" msgstr "set_fd_blocking потерпел неудачу! (%s)\n" #: main.c:109 #: main.c:108 #, c-format msgid "%s, run time: %.3fs, press ctrl + c to stop" msgstr "%s, время работы: %.3fs, нажмите ctrl + c, чтобы остановить" #: main.c:244 #: main.c:243 #, c-format msgid "Got signal %d\n" msgstr "Есть сигнал %d\n" #: main.c:255 #: main.c:254 #, c-format msgid "Cannot open password-file %s" msgstr "Не получается открыть файл пароля %s" #: main.c:258 #: main.c:257 #, c-format msgid "Problem reading password from file %s" msgstr "Проблема чтения пароля из файла %s" #: main.c:365 #: main.c:364 #, c-format msgid "URL too big, HTTPing has a %d bytes limit" msgstr "URL слишком длинный, HTTPing имеет лимит %d байт" #: main.c:384 #: main.c:383 msgid "using \"http://\" with SSL enabled (-l)" msgstr "Используем \"http://\" с включенным SSL (-l)" #: main.c:519 #: main.c:518 #, c-format msgid "AGG[%d]: %d values, min/avg/max%s = %.1f/%.1f/%.1f" msgstr "СВКПН[%d]: %d значений, мин/сред/макс%s = %.1f/%.1f/%.1f" #: main.c:519 #: main.c:2294 #: main.c:518 #: main.c:2289 msgid "/sd" msgstr "/sd" #: main.c:576 #: main.c:575 msgid "-n: missing parameter\n" msgstr "-n: отсутствующий параметр\n" #: main.c:594 #: main.c:603 #: main.c:593 #: main.c:602 #, c-format msgid "cannot convert ip address '%s' (for -y)\n" msgstr "не получается конвертировать IP адрес '%s' (для -y)\n" #: main.c:710 #: main.c:709 #, c-format msgid "CRITICAL - connecting failed: %s" msgstr "КРИТИЧНО - подключение не удалось: %s" #: main.c:715 #: main.c:714 #, c-format msgid "CRITICAL - average httping-time is %.1f\n" msgstr "КРИТИЧНО - среднее httping-время %.1f\n" #: main.c:720 #: main.c:719 #, c-format msgid "WARNING - average httping-time is %.1f\n" msgstr "ПРЕДУПРЕЖДЕНИЕ - среднее httping-время %.1f\n" #: main.c:724 #: main.c:723 #, c-format msgid "OK - average httping-time is %.1f (%s)|ping=%f\n" msgstr "OK - среднее httping-время %.1f (%s)|ping=%f\n" #: main.c:734 #: main.c:733 #, c-format msgid "OK - all fine, avg httping time is %.1f|ping=%f\n" msgstr "OK - все в порядке, сред httping время %.1f|ping=%f\n" #: main.c:738 #: main.c:737 #, c-format msgid "%s: - failed: %s" msgstr "%s: - не удалось: %s" #: main.c:1025 #: main.c:1020 #, c-format msgid "" "\n" " *** -A is no longer required ***\n" "\n" msgstr "" "\n" " *** -A больше не требуется ***\n" "\n" #: main.c:1170 #: main.c:1165 msgid "-i cannot have a value smaller than zero" msgstr "-i не может иметь значение меньше нуля" #: main.c:1224 #: main.c:1232 #: main.c:1219 #: main.c:1227 msgid "-n and -N are mutual exclusive\n" msgstr "-n и -N являются взаимоисключающими\n" #: main.c:1253 #: main.c:1248 #, c-format msgid "Warning: TCP TFO is not supported. Disabling.\n" msgstr "Предупреждение: TCP TFO не поддерживается. Отключаем.\n" #: main.c:1269 #: main.c:1264 #, c-format msgid "" "\n" "\n" "Please run:\n" "\t%s --help\n" "to see a list of options.\n" "\n" msgstr "" "\n" "\n" "Пожалуйста выполните:\n" "\t%s --help\n" "чтобы посмотреть список опций.\n" "\n" #: main.c:1281 #, c-format msgid "" "No URL/host to ping given\n" "\n" msgstr "" "Никакого URL/хоста для пинга не дано\n" "\n" #: main.c:1291 #: main.c:1286 msgid "Cannot combine -m, -M and -K" msgstr "Нельзя совместить -m, -M и -K" #: main.c:1294 #: main.c:1289 msgid "Aggregates can only be used in non-machine/json-output mode" msgstr "Вывод совокупностей может быть только использован в немашиночитаемом/json-вывод режиме" #: main.c:1299 #: main.c:1294 msgid "-b/-B can only be used when also using -G (GET instead of HEAD) or -l (use SSL)\n" msgstr "-b/-B может быть использован только при использовании -G (GET вместо HEAD) или -l (использовать SSL)\n" #: main.c:1302 #: main.c:1297 msgid "TCP Fast open and SSL not supported together\n" msgstr "TCP Fast open и SSL не поддерживаются вместе\n" #: main.c:1332 #: main.c:1327 msgid "" "\n" "Auto enabling SSL due to https-URL" msgstr "" "\n" "Автоматически включаем SSL ввиду https URL" #: main.c:1338 #: main.c:1333 #, c-format msgid "Auto enabling SSL due to https-URL" msgstr "Автоматически включаем SSL ввиду https-URL" #: main.c:1347 #: main.c:1342 #, c-format msgid "" "\n" "Connecting to host %s, port %d and requesting file %s" msgstr "" "\n" "Подключаемся к хосту %s, порт %d и запрашиваем файл %s" #: main.c:1350 #: main.c:1345 #, c-format msgid "" "\n" "Using proxyserver: %s:%d" msgstr "" "\n" "Используем прокси сервер: %s:%d" #: main.c:1355 #: main.c:1350 #, c-format msgid "" "Connecting to host %s, port %d and requesting file %s\n" "\n" msgstr "" "Подключаемся к хосту %s, порт %d и запрашиваем файл %s\n" "\n" #: main.c:1358 #: main.c:1353 #, c-format msgid "Using proxyserver: %s:%d\n" msgstr "Используем прокси сервер: %s:%d\n" #: main.c:1369 #: main.c:1364 msgid "problem creating SSL context" msgstr "Проблема при создании SSL контекста" #: main.c:1389 #: main.c:1384 msgid "Interval must be > 0 when using adaptive interval" msgstr "Интервал должен быть больше нуля при использовании адаптивного интервала" #: main.c:1417 #: main.c:1435 #: main.c:1519 #: main.c:1412 #: main.c:1430 #: main.c:1514 #, c-format msgid "" "\n" "Resolving hostname %s" msgstr "" "\n" "Резолвим имя хоста %s" #: main.c:1427 #: main.c:1452 #: main.c:1545 #: main.c:1422 #: main.c:1447 #: main.c:1540 #, c-format msgid "No valid IPv4 or IPv6 address found for %s" msgstr "Валидный IPv4 или IPv6 адрес не найден для %s" #: main.c:1579 #: main.c:1574 msgid "Will no longer inform about request headers too large." msgstr "Больше не сообщать о слишком больших заголовках запроса." #: main.c:1581 #: main.c:1576 #, c-format msgid "Request headers > 4KB! (%d bytes) This may give failures with some HTTP servers." msgstr "Заголовок запроса > 4КБ! (%d байт) Это может привести к ошибке на некоторых HTTP серверах." #: main.c:1685 #: main.c:1680 msgid "timeout connecting to host" msgstr "тайм-аут при подключении к хосту" #: main.c:1748 #: main.c:1743 msgid "error sending request to host" msgstr "ошибка при отправке запроса к хосту" #: main.c:1750 #: main.c:1800 #: main.c:1745 #: main.c:1795 msgid "timeout sending to host" msgstr "тайм-аут при отправке к хосту" #: main.c:1752 #: main.c:1747 msgid "retrieved invalid data from host" msgstr "получены неправильные данные от хоста" #: main.c:1756 #: main.c:1751 msgid "connection prematurely closed by peer" msgstr "подключение преждевременно закрыто пиром" #: main.c:1790 #: main.c:1785 msgid "" "\n" "No longer emitting message about \"still data in transit\"" msgstr "" "\n" "Больше не выводить сообщение о \"данных еще в пути\"" #: main.c:1792 #: main.c:1787 #, c-format msgid "" "\n" "HTTP server started sending data with %d bytes still in transit" msgstr "" "\n" "HTTP начал отправлять данные в то время как %d байт еще в пути" #: main.c:1813 #: main.c:1808 msgid "failed to obtain TOS info" msgstr "ошибка при получении TOS информации" #: main.c:1827 #: main.c:1822 msgid "" "\n" "No longer emitting message about \"more data than response headers\"" msgstr "" "\n" "Больше не выводить сообщение о \"больше данных сверх заголовков ответа\"" #: main.c:1829 #: main.c:1824 msgid "" "\n" "HTTP server sent more data than just the response headers" msgstr "" "\n" "HTTP сервер отправил больше данных сверх заголовков ответа" #: main.c:1878 #: main.c:1873 msgid "'Content-Length'-header missing!" msgstr "'Content-Length' заголовок отсутствует!" #: main.c:1910 #: main.c:1905 msgid "short read during receiving reply-headers from host" msgstr "короткое чтение во время получения заголовков ответа от хоста" #: main.c:1912 #: main.c:1907 msgid "timeout while receiving reply-headers from host" msgstr "тайм-аут при получении заголовков ответа от хоста" #: main.c:1945 #: main.c:1940 msgid "read of response body dataa failed" msgstr "неудача при чтении тела ответа" #: main.c:1980 #: main.c:1975 msgid "error shutting down ssl" msgstr "ошибка при завершении SSL" #: main.c:2026 #: main.c:2087 #: main.c:2021 #: main.c:2082 #, c-format msgid "getnameinfo() failed: %d (%s)" msgstr "getnameinfo() не удался: %d (%s)" #: main.c:2061 #: main.c:2056 msgid "connected to" msgstr "подключено к" #: main.c:2061 #: main.c:2056 msgid "pinged host" msgstr "пингуемый хост" #: main.c:2105 #: main.c:2100 #, c-format msgid "%s%s%s%s%s:%s%d%s (%d/%d bytes), seq=%s%d%s " msgstr "%s%s%s%s%s:%s%d%s (%d/%d байт), поряд.н.=%s%d%s " #: main.c:2107 #: main.c:2102 #, c-format msgid "%s%s%s%s%s:%s%d%s (%d bytes), seq=%s%d%s " msgstr "%s%s%s%s%s:%s%d%s (%d bytes), поряд.н.=%s%d%s " #: main.c:2113 #: main.c:2114 #: nc.c:721 #: main.c:2108 #: main.c:2109 msgid " n/a" msgstr " н/д" #: main.c:2119 #: main.c:2114 #, c-format msgid "time=%s+%s+%s+%s+%s%s=%s%s%s%s ms %s%s%s" msgstr "время=%s+%s+%s+%s+%s%s=%s%s%s%s мс %s%s%s" #: main.c:2129 #: main.c:2124 #, c-format msgid "time=%s%s%s ms %s%s%s" msgstr "время=%s%s%s мс %s%s%s" #: main.c:2149 #: main.c:2144 msgid "not " msgstr "не " #: main.c:2150 #: main.c:2145 msgid "compressed)" msgstr "сжатый)" #: main.c:2162 #: main.c:2157 #, c-format msgid " toff=%d" msgstr " t сдвиг=%d" #: main.c:2166 #: main.c:2161 #, c-format msgid " age=%d" msgstr " возраст=%d" #: main.c:2282 #: main.c:2277 #, c-format msgid "--- %s ping statistics ---\n" msgstr "--- %s статистика пинга ---\n" #: main.c:2285 #: main.c:2280 #, c-format msgid "internal error! (curncount)\n" msgstr "внутренняя ошибка! (curncount)\n" #: main.c:2290 #: main.c:2285 #, c-format msgid "%s%d%s connects, %s%d%s ok, %s%3.2f%%%s failed, time %s%s%.0fms%s\n" msgstr "%s%d%s подключений, %s%d%s ok, %s%3.2f%%%s неудавшихся, время %s%s%.0fмс%s\n" #: main.c:2294 #: main.c:2289 #, c-format msgid "round-trip min/avg/max%s = %s%.1f%s/%s%.1f%s/%s%.1f%s" msgstr "туда-сюда мин/сред/макс%s = %s%.1f%s/%s%.1f%s/%s%.1f%s" #: main.c:2305 #: main.c:2300 #, c-format msgid "Transfer speed: min/avg/max = %s%f%s/%s%f%s/%s%f%s KB\n" msgstr "Скорость передачи: мин/сред/макс = %s%f%s/%s%f%s/%s%f%s КБ\n" #: mssl.c:79 #, c-format msgid "READ_SSL: io-error: %s" msgstr "SSL чтение, I/O ошибка: %s" #: mssl.c:110 #, c-format msgid "WRITE_SSL: io-error: %s" msgstr "SSL запись, I/O ошибка: %s" #: mssl.c:141 #, c-format msgid "problem setting receive timeout (%s)" msgstr "проблема при установке тайм-аута приема (%s)" #: mssl.c:147 #, c-format msgid "problem setting transmit timeout (%s)" msgstr "проблема при установке тайм-аута передачи (%s)" #: mssl.c:159 #, c-format msgid "problem starting SSL connection: %d" msgstr "проблема при старте SSL соединения: %d" #: mssl.c:259 msgid "Problem sending request to proxy" msgstr "Проблема при отправке запроса к прокси" #: mssl.c:268 msgid "Problem retrieving proxy response" msgstr "Проблема при получении ответа от прокси" #: mssl.c:282 msgid "Invalid proxy response headers" msgstr "Неверные заголовки ответа от прокси" #: mssl.c:289 #, c-format msgid "Proxy indicated error: %s" msgstr "Proxy сообщила об ошибке: %s" #: nc.c:57 msgid "realloc issue" msgstr "realloc проблема" #: nc.c:542 #, c-format msgid "highest: %6.2fHz, avg: %6.2fHz" msgstr "наибольшее: %6.2fHz, сред: %6.2fHz" #: nc.c:668 #, c-format msgid "graph range: %7.2fms - %7.2fms " msgstr "диапазон графика: %7.2fмс - %7.2fмс " #: nc.c:732 #, c-format msgid "%s: n/a" msgstr "%s: н/д" #: nc.c:749 msgid "latest" msgstr "последний" #: nc.c:749 #: nc.c:769 msgid "min" msgstr "мин" #: nc.c:749 #: nc.c:769 msgid "avg" msgstr "сред" #: nc.c:749 #: nc.c:769 msgid "max" msgstr "макс" #: nc.c:749 #: nc.c:769 msgid "sd" msgstr "sd" #: nc.c:750 msgid "resolve" msgstr "резолвить" #: nc.c:751 msgid "connect" msgstr "подключаться" #: nc.c:752 msgid "ssl " msgstr "ssl " #: nc.c:753 msgid "send " msgstr "отправлять " #: nc.c:754 msgid "request" msgstr "запрос" #: nc.c:755 msgid "close " msgstr "закрыть" #: nc.c:756 msgid "total " msgstr "всего " #: nc.c:760 #, c-format msgid "ok: %3d, fail: %3d%s, scc: %s, kalman: %s" msgstr "ОК: %2d, неудача: %2d%s, scc: %s, Kalman: %s" #: nc.c:760 msgid ", with TFO" msgstr ", с TFO" #: nc.c:769 msgid "cur" msgstr "тек." #: nc.c:770 msgid "t offst" msgstr "t сдвиг" #: nc.c:773 msgid "tcp rtt" msgstr "TCP RTT" #: nc.c:775 msgid "headers" msgstr "заголовки" #: nc.c:782 #, c-format msgid "# cookies: %d" msgstr "# куки: %d" #: nc.c:784 #, c-format msgid "trend: %c%6.2f%%, re-tx: %2d, pmtu: %5d, TOS: %02x" msgstr "тренд: %c%6.2f%%, re-tx: %2d, pmtu: %5d, TOS: %02x" #: nc.c:787 #, c-format msgid "HTTP rc: %s, SSL fp: %s" msgstr "HTTP rc: %s, SSL fp: %s" #: nc.c:787 msgid "n/a" msgstr "Н/Д" #: nc.c:795 #, c-format msgid "http result code: %s" msgstr "HTTP код ответа: %s" #: nc.c:799 #, c-format msgid "" "\n" "SSL fingerprint: %s" msgstr "" "\n" "SSL фингерпринт: %s" #: res.c:36 #, c-format msgid "Resolving %s %sfailed: %s" msgstr "Резолв %s %sне удался: %s" #: res.c:36 msgid "(IPv6) " msgstr "(IPv6) " #: res.c:71 #, c-format msgid "Problem resolving %s (IPv4): %s" msgstr "Проблема при резолве %s (IPv4): %s" #: socks5.c:56 #, c-format msgid "socks5connect: reply with requested authentication method does not say version 5 (%02x)" msgstr "socks5connect: ответ с запрошенным аутентификационным методом не выдает версию 5 (%02x)" #: socks5.c:70 #, c-format msgid "socks5connect: socks5 refuses our authentication methods: %02x" msgstr "socks5connect: socks5 отказывается от наших аутентификационных методов: %02x" #: socks5.c:81 msgid "socks5connect: socks5 server requests username/password authentication" msgstr "socks5connect: socks5 сервер запрашивает аутентификацию основанную на имени пользователя/пароле" #: socks5.c:90 msgid "socks5connect: failed transmitting username/password to socks5 server" msgstr "socks5connect: не удалось передать имя пользователя/пароль socks5 серверу" #: socks5.c:96 msgid "socks5connect: failed receiving authentication reply" msgstr "socks5connect: не удалось получить ответ аутентификации" #: socks5.c:102 msgid "socks5connect: password authentication failed" msgstr "socks5connect: аутентификация по паролю не удалась" #: socks5.c:116 #, c-format msgid "Cannot resolve %s" msgstr "Не получается резолв %s" #: socks5.c:133 msgid "socks5connect: failed to transmit associate request" msgstr "socks5connect: не удалось передать associate запрос" #: socks5.c:139 msgid "socks5connect: command reply receive failure" msgstr "socks5connect: ошибка при получение command ответа" #: socks5.c:146 #, c-format msgid "socks5connect: bind request replies with version other than 0x05 (%02x)" msgstr "socks5connect: bind запрос отвечает с версией отличной от 0x05 (%02x)" #: socks5.c:152 #, c-format msgid "socks5connect: failed to connect (%02x)" msgstr "socks5connect: не удалось подключиться (%02x)" #: socks5.c:158 #, c-format msgid "socks5connect: only accepting bind-replies with IPv4 address (%02x)" msgstr "socks5connect: только принимаем bind ответы с IPv4 адресом (%02x)" #: tcp.c:31 #: tcp.c:42 #, c-format msgid "could not set TCP_NODELAY on socket (%s)" msgstr "не удалось установить TCP_NODELAY на сокет (%s)" #: tcp.c:57 #, c-format msgid "problem creating socket (%s)" msgstr "проблема при создании сокета (%s)" #: tcp.c:69 #, c-format msgid "error setting sockopt to interface (%s)" msgstr "проблема при установке sockopt на интерфейс (%s)" #: tcp.c:75 #, c-format msgid "error binding to interface (%s)" msgstr "проблема при биндинге к интерфейсу (%s)" #: tcp.c:84 #, c-format msgid "error setting MTU size (%s)" msgstr "ошибка при установке размера MTU (%s)" #: tcp.c:101 #, c-format msgid "error setting transmit buffer size (%s)" msgstr "ошибка при установке размера буфера передачи (%s)" #: tcp.c:110 #, c-format msgid "error setting receive buffer size (%s)" msgstr "ошибка при установке размера буфера приема (%s)" #: tcp.c:119 #, c-format msgid "error setting priority (%s)" msgstr "ошибка при установке приоритета (%s)" #: tcp.c:128 msgid "failed to set TOS info" msgstr "не удалось установить TOS информацию" #: tcp.c:165 #, c-format msgid "TCP TFO Not Supported. Please check if \"/proc/sys/net/ipv4/tcp_fastopen\" is 1. Disabling TFO for now.\n" msgstr "TCP TFO не поддерживается. Пожалуйста проверьте равняется ли \"/proc/sys/net/ipv4/tcp_fastopen\" единице. Пока что, отключаем TFO. \n" #: tcp.c:195 #, c-format msgid "problem connecting to host: %s" msgstr "проблема при подключении к хосту: %s" #: tcp.c:208 msgid "connect time out" msgstr "тайм-аут при подключении" #: tcp.c:216 #, c-format msgid "select() failed: %s" msgstr "select() не удался: %s" #: tcp.c:228 #, c-format msgid "getsockopt failed (%s)" msgstr "getsockopt не удался (%s)" #: tcp.c:240 #, c-format msgid "could not connect (%s)" msgstr "не смог подключиться (%s)" #: utils.c:25 msgid "gettimeofday failed" msgstr "gettimeofday не удался" #~ #: main.c:1276 main.c:1271 #~ msgid "Cannot combine maximum MTU size setting with proxy connections or SSL" #~ msgstr "Нельзя совмещать настройку максимального размера MTU с прокси соединениями или SSL" httping-2.5/socks5.c000066400000000000000000000103561276547250600144330ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include #include "error.h" #include "gen.h" #include "io.h" #include "res.h" #include "tcp.h" int socks5connect(int fd, struct addrinfo *ai, double timeout, const char *socks5_username, const char *socks5_password, const char *host, int port, char abort_on_resolve_failure) { struct sockaddr_in sai; uint32_t addr = 0; unsigned char io_buffer[256] = { 0 }; int io_len = 0, rc = -1; if ((rc = connect_to(fd, ai, timeout, NULL, NULL, 0, NULL)) == -1) return rc; /* inform socks server about the auth. methods we support */ if (socks5_username != NULL) { io_buffer[0] = 0x05; /* version */ io_buffer[1] = 2; /* 2 authentication methods */ io_buffer[2] = 0x00; /* method 1: no authentication */ io_buffer[3] = 0x02; /* method 2: username/password */ io_len = 4; } else { io_buffer[0] = 0x05; /* version */ io_buffer[1] = 1; /* 2 authentication methods */ io_buffer[2] = 0x00; /* method 1: no authentication */ io_len = 3; } if ((rc = mywrite(fd, (char *)io_buffer, io_len, timeout)) < 0) return rc; /* wait for reply telling selected authentication method */ if ((rc = myread(fd, (char *)io_buffer, 2, timeout)) < 0) return rc; if (io_buffer[0] != 0x05) { set_error(gettext("socks5connect: reply with requested authentication method does not say version 5 (%02x)"), io_buffer[0]); return RC_INVAL; } if (io_buffer[1] == 0x00) { /* printf("socks5connect: \"no authentication at all\" selected by server\n"); */ } else if (io_buffer[1] == 0x02) { /* printf("socks5connect: selected username/password authentication\n"); */ } else { set_error(gettext("socks5connect: socks5 refuses our authentication methods: %02x"), io_buffer[1]); return RC_INVAL; } /* in case the socks5 server asks us to authenticate, do so */ if (io_buffer[1] == 0x02) { int io_len = 0; if (socks5_username == NULL || socks5_password == NULL) { set_error(gettext("socks5connect: socks5 server requests username/password authentication")); return RC_INVAL; } io_buffer[0] = 0x01; /* version */ io_len = snprintf((char *)&io_buffer[1], sizeof io_buffer - 1, "%c%s%c%s", (int)strlen(socks5_username), socks5_username, (int)strlen(socks5_password), socks5_password); if ((rc = mywrite(fd, (char *)io_buffer, io_len + 1, timeout)) < 0) { set_error(gettext("socks5connect: failed transmitting username/password to socks5 server")); return rc; } if ((rc = myread(fd, (char *)io_buffer, 2, timeout)) < 0) { set_error(gettext("socks5connect: failed receiving authentication reply")); return rc; } if (io_buffer[1] != 0x00) { set_error(gettext("socks5connect: password authentication failed")); return RC_INVAL; } } /* ask socks5 server to associate with server */ io_buffer[0] = 0x05; /* version */ io_buffer[1] = 0x01; /* connect to */ io_buffer[2] = 0x00; /* reserved */ io_buffer[3] = 0x01; /* ipv4 */ if (resolve_host_ipv4(host, &sai) == -1) { if (abort_on_resolve_failure) error_exit(gettext("Cannot resolve %s"), host); return RC_INVAL; } addr = ntohl(sai.sin_addr.s_addr); io_buffer[4] = (addr >> 24) & 255; io_buffer[5] = (addr >> 16) & 255; io_buffer[6] = (addr >> 8) & 255; io_buffer[7] = (addr ) & 255; io_buffer[8] = (port >> 8) & 255; io_buffer[9] = (port ) & 255; if ((rc = mywrite(fd, (char *)io_buffer, 10, timeout)) < 0) { set_error(gettext("socks5connect: failed to transmit associate request")); return rc; } if ((rc = myread(fd, (char *)io_buffer, 10, timeout)) < 0) { set_error(gettext("socks5connect: command reply receive failure")); return rc; } /* verify reply */ if (io_buffer[0] != 0x05) { set_error(gettext("socks5connect: bind request replies with version other than 0x05 (%02x)"), io_buffer[0]); return RC_INVAL; } if (io_buffer[1] != 0x00) { set_error(gettext("socks5connect: failed to connect (%02x)"), io_buffer[1]); return RC_INVAL; } if (io_buffer[3] != 0x01) { set_error(gettext("socks5connect: only accepting bind-replies with IPv4 address (%02x)"), io_buffer[3]); return RC_INVAL; } return RC_OK; } httping-2.5/socks5.h000066400000000000000000000002651276547250600144360ustar00rootroot00000000000000int socks5connect(int fd, struct addrinfo *ai, double timeout, const char *socks5_username, const char *socks5_password, const char *host, int port, char abort_on_resolve_failure); httping-2.5/tcp.c000066400000000000000000000120341276547250600140050ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #include #include #include #include #include #include #include #include #include #include #include #include #include "error.h" #include "gen.h" #include "io.h" #include "main.h" #include "tcp.h" void failure_close(int fd) { struct linger sl; sl.l_onoff = 1; sl.l_linger = 0; if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &sl, sizeof sl) == -1) set_error(gettext("could not set TCP_NODELAY on socket (%s)"), strerror(errno)); close(fd); } int set_no_delay(int fd) { int flag = 1; if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)) == -1) { set_error(gettext("could not set TCP_NODELAY on socket (%s)"), strerror(errno)); return -1; } return 0; } int create_socket(struct sockaddr *bind_to, struct addrinfo *ai, int recv_buffer_size, int tx_buffer_size, int max_mtu, char use_no_delay, int priority, int tos) { int fd = -1; /* create socket */ fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (fd == -1) { set_error(gettext("problem creating socket (%s)"), strerror(errno)); return RC_INVAL; } /* go through a specific interface? */ if (bind_to) { int set = 1; /* set reuse flags */ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &set, sizeof set) == -1) { set_error(gettext("error setting sockopt to interface (%s)"), strerror(errno)); close(fd); return RC_INVAL; } if (bind(fd, bind_to, sizeof *bind_to) == -1) { set_error(gettext("error binding to interface (%s)"), strerror(errno)); close(fd); return RC_INVAL; } } if (max_mtu >= 0) { if (setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, &max_mtu, sizeof max_mtu) == -1) { set_error(gettext("error setting MTU size (%s)"), strerror(errno)); close(fd); return RC_INVAL; } } if (use_no_delay) { int rc = -1; if ((rc = set_no_delay(fd)) != 0) return rc; } if (tx_buffer_size > 0) { if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *)&tx_buffer_size, sizeof tx_buffer_size) == -1) { set_error(gettext("error setting transmit buffer size (%s)"), strerror(errno)); close(fd); return RC_INVAL; } } if (recv_buffer_size > 0) { if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&recv_buffer_size, sizeof recv_buffer_size) == -1) { set_error(gettext("error setting receive buffer size (%s)"), strerror(errno)); close(fd); return RC_INVAL; } } #ifdef linux if (priority >= 0) { if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (char *)&priority, sizeof priority) == -1) { set_error(gettext("error setting priority (%s)"), strerror(errno)); close(fd); return RC_INVAL; } } #endif if (tos >= 0) { if (setsockopt(fd, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof tos) == -1) { set_error(gettext("failed to set TOS info")); close(fd); return RC_INVAL; } } return fd; } int connect_to(int fd, struct addrinfo *ai, double timeout, char *tfo, char *msg, int msg_len, char *msg_accepted) { int rc = -1; struct timeval to; fd_set wfds; /* make fd nonblocking */ if (set_fd_nonblocking(fd) == -1) return RC_INVAL; /* wait for connection */ FD_ZERO(&wfds); FD_SET(fd, &wfds); to.tv_sec = (long)(timeout / 1000.0); to.tv_usec = (long)(timeout * 1000.0) % 1000000; /* connect to peer */ #ifdef TCP_TFO if (tfo && *tfo) { rc = sendto(fd, msg, msg_len, MSG_FASTOPEN, ai -> ai_addr, ai -> ai_addrlen); if(rc == msg_len) *msg_accepted = 1; if(errno == 0) return RC_OK; if(errno == ENOTSUP) { printf(gettext("TCP TFO Not Supported. Please check if \"/proc/sys/net/ipv4/tcp_fastopen\" is 1. Disabling TFO for now.\n")); *tfo = 0; goto old_connect; } } else #else (void)tfo; (void)msg; (void)msg_len; (void)msg_accepted; #endif { int rc = -1; old_connect: rc = connect(fd, ai -> ai_addr, ai -> ai_addrlen); if (rc == 0) { /* connection made, return */ return RC_OK; } if (rc == -1) { /* problem connecting */ if (errno != EINPROGRESS) { set_error(gettext("problem connecting to host: %s"), strerror(errno)); return RC_INVAL; } } } if (stop) return RC_CTRLC; /* wait for connection */ rc = select(fd + 1, NULL, &wfds, NULL, &to); if (rc == 0) { set_error(gettext("connect time out")); return RC_TIMEOUT; /* timeout */ } else if (rc == -1) { if (errno == EINTR) return RC_CTRLC;/* ^C pressed */ set_error(gettext("select() failed: %s"), strerror(errno)); return RC_INVAL; /* error */ } else { int optval=0; socklen_t optvallen = sizeof optval; /* see if the connect succeeded or failed */ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &optval, &optvallen) == -1) { set_error(gettext("getsockopt failed (%s)"), strerror(errno)); return RC_INVAL; } /* no error? */ if (optval == 0) return RC_OK; /* don't ask */ errno = optval; } set_error(gettext("could not connect (%s)"), strerror(errno)); return RC_INVAL; } httping-2.5/tcp.h000066400000000000000000000006111276547250600140100ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ int create_socket(struct sockaddr *bind_to, struct addrinfo *ai, int recv_buffer_size, int tx_buffer_size, int max_mtu, char use_no_delay, int priority, int tos); int connect_to(int fd, struct addrinfo *ai, double timeout, char *tfo, char *msg, int msg_len, char *msg_accepted); void failure_close(int fd); httping-2.5/test_TFO.c000066400000000000000000000014011276547250600147020ustar00rootroot00000000000000#include #include #include #include #include #include #include #include int main(void) { int sfd = 0; int qlen = 5; if ((sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { fprintf(stderr, "socket(): %s\n", strerror(errno)); exit(EXIT_FAILURE); } #ifdef TCP_FASTOPEN if (setsockopt(sfd, SOL_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen)) == -1) { fprintf(stderr, "setsockopt(): %s\n", strerror(errno)); exit(EXIT_FAILURE); } #else fprintf(stderr, "TCP_FASTOPEN: undefined\n"); return EXIT_FAILURE; #endif return EXIT_SUCCESS; } httping-2.5/test_fftw3.c000066400000000000000000000003711276547250600153100ustar00rootroot00000000000000#include int main(int argc, char *argv[]) { /* note: it only needs to compile */ void *dummy = fftw_malloc(4096); double *dummyd = (double *)dummy; void *plan = fftw_plan_dft_r2c_1d(12345, dummyd, NULL, FFTW_ESTIMATE); return 0; } httping-2.5/test_ncurses.c000066400000000000000000000001231276547250600157340ustar00rootroot00000000000000#include int main(int argc, char *argv[]) { initscr(); return 0; } httping-2.5/test_ncurses2.c000066400000000000000000000001331276547250600160170ustar00rootroot00000000000000#include int main(int argc, char *argv[]) { initscr(); return 0; } httping-2.5/test_openssl.c000066400000000000000000000014051276547250600157410ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #include #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { BIO *bio_err = NULL; SSL_library_init(); SSL_load_error_strings(); ERR_load_crypto_strings(); /* error write context */ bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); const SSL_METHOD *meth = SSLv23_method(); SSL_CTX *ctx = SSL_CTX_new(meth); /***/ BIO_free(bio_err); ERR_free_strings(); ERR_remove_state(0); ENGINE_cleanup(); CONF_modules_free(); EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); return 0; } httping-2.5/utils.c000066400000000000000000000040301276547250600143540ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include "error.h" #include "utils.h" double get_ts(void) { struct timeval ts; struct timezone tz; if (gettimeofday(&ts, &tz) == -1) error_exit(gettext("gettimeofday failed")); return (double)ts.tv_sec + ((double)ts.tv_usec)/1000000.0 + (double)(tz.tz_minuteswest * 60); } void split_string(const char *in, const char *split, char ***list, int *list_n) { char *copy = strdup(in), *pc = copy; int split_len = strlen(split); for(;;) { char *term = strstr(pc, split); if (term) *term = 0x00; *list = (char **)realloc(*list, (*list_n + 1) * sizeof(char *)); (*list)[*list_n] = strdup(pc); (*list_n)++; if (!term) break; pc = term + split_len; } free(copy); } void free_splitted_string(char **list, int n) { int index=0; for(index=0; index= GIGA) { div = GIGA; mul = "G"; } else if (a >= MEGA) { div = MEGA; mul = "M"; } else if (a >= KILO) { div = KILO; mul = "k"; } if (mul[0]) digits_sig--; (void)asprintf(&out, "%*.*f%s", digits_sig, digits_nsig, value / div, mul); return out; } httping-2.5/utils.h000066400000000000000000000010161276547250600143620ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ double get_ts(void); void split_string(const char *in, const char *split, char ***list, int *list_n); void free_splitted_string(char **list, int n); void str_add(char **to, const char *what, ...); #define GIGA 1000000000.0 #define MEGA 1000000.0 #define KILO 1000.0 char * format_value(double value, int digits_sig, int digits_nsig, char abbreviate); #define min(x, y) ((x) < (y) ? (x) : (y)) #define max(x, y) ((x) > (y) ? (x) : (y)) httping-2.5/version000066400000000000000000000000141276547250600144560ustar00rootroot00000000000000VERSION=2.5