diff --git a/SRC/echoping.c b/SRC/echoping.c index 5e01795..4a042b8 100644 --- a/SRC/echoping.c +++ b/SRC/echoping.c @@ -1,1559 +1,1417 @@ /* * echoping : uses the TCP echo (or other TCP or UDP protocols) * service to measure (roughly) response times. - * + * * Written by Stephane Bortzmeyer . See - * the AUTHORS file for other contributors. - * + * the AUTHORS file for other contributors. + * * $Id$ * * */ -char *progname; +char *progname; #include "echoping.h" /* * An option to define only if you want to drive echoping from another * process. Useless but harmless otherwise. In practice, while OSF/1 is happy - * with it, SunOS refuses to use fflush on a NULL and Linux fails. + * with it, SunOS refuses to use fflush on a NULL and Linux fails. */ #undef FLUSH_OUTPUT /* Not really supported, see the TODO */ /* Global variables for main and printstats */ -int return_code = 0; -int rc; -unsigned int number = 1; -struct timeval max, min, total, median, stddev, temp; -struct timeval conntv, connectedtv, sendtv, recvtv; -unsigned int successes, attempts = 0; -unsigned int size = DEFLINE; -unsigned int j = 0; +int return_code = 0; +int rc; +unsigned int number = 1; +struct timeval max, min, total, median, stddev, temp; +struct timeval conntv, connectedtv, sendtv, recvtv; +unsigned int successes, attempts = 0; +unsigned int size = DEFLINE; +unsigned int j = 0; -int family = PF_UNSPEC; +int family = PF_UNSPEC; -struct result results[MAX_ITERATIONS]; -struct timeval good_results[MAX_ITERATIONS]; -extern int tvcmp (); +struct result results[MAX_ITERATIONS]; +struct timeval good_results[MAX_ITERATIONS]; +extern int tvcmp(); int -main (argc, argv) - int argc; - const char *argv[]; +main(argc, argv) + int argc; + const char *argv[]; { - int result; - int remaining = argc; - char **leftover; + int result; + int remaining = argc; + char **leftover; - int sockfd = -1; - struct addrinfo hints, hints_numeric, *res; - int error; - char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; + int sockfd = -1; + struct addrinfo hints, hints_numeric, *res; + int error; + char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; #ifdef NI_WITHSCOPEID - const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID; + const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID; #else - const int niflags = NI_NUMERICHOST | NI_NUMERICSERV; + const int niflags = NI_NUMERICHOST | NI_NUMERICSERV; #endif - FILE *files = NULL; - CHANNEL channel; - int verbose = FALSE; - int dump_config = FALSE; - int module_find = FALSE; - int n, nr = 0; + FILE *files = NULL; + CHANNEL channel; + int verbose = FALSE; + int dump_config = FALSE; + int module_find = FALSE; + int n, nr = 0; #ifdef OPENSSL - int sslcode; - char rand_file[MAX_LINE]; + int sslcode; + char rand_file[MAX_LINE]; #endif - char *sendline, recvline[MAX_LINE + 1]; - boolean accept_http_redirects = FALSE; + char *sendline, recvline[MAX_LINE + 1]; + boolean accept_http_redirects = FALSE; + char *http_hostname = NULL; #ifdef ICP - char retcode[DEFLINE]; - int length; + char retcode[DEFLINE]; + int length; #endif - struct timeval newtv, oldtv; - void printstats (); + struct timeval newtv, oldtv; + void printstats(); #ifdef HAVE_USLEEP - float wait = 1.0; + float wait = 1.0; #else - unsigned int wait = 1; -#endif - unsigned char fill = ' '; - char *fill_s; - boolean fill_requested = FALSE; - unsigned int i = 0; - char *plugin_name, *complete_plugin_name = NULL; - char *ext; - void *plugin = NULL; - int plugin_result; + unsigned int wait = 1; +#endif + unsigned char fill = ' '; + char *fill_s; + boolean fill_requested = FALSE; + unsigned int i = 0; + char *plugin_name, *complete_plugin_name = NULL; + char *ext; + void *plugin = NULL; + int plugin_result; - void to_alarm (); /* our alarm() signal handler */ - void interrupted (); - unsigned int timeout = 10; - boolean timeout_requested = 0; - boolean size_requested = 0; - char *url = ""; + void to_alarm(); /* our alarm() signal handler */ + void interrupted(); + unsigned int timeout = 10; + boolean timeout_requested = 0; + boolean size_requested = 0; + char *url = ""; #if USE_SIGACTION - struct sigaction mysigaction; + struct sigaction mysigaction; #endif - char *plugin_port_name, *port_name; - boolean plugin_raw = FALSE; - boolean port_to_use = USE_ECHO; - boolean http = 0; - boolean smtp = 0; - boolean discard = 0; - boolean chargen = 0; - boolean udp = 0; - boolean icp = 0; + char *plugin_port_name, *port_name; + boolean plugin_raw = FALSE; + boolean port_to_use = USE_ECHO; + boolean http = 0; + boolean smtp = 0; + boolean discard = 0; + boolean chargen = 0; + boolean udp = 0; + boolean icp = 0; - boolean nocache = 0; + boolean nocache = 0; #ifdef ICP - icp_opcode opcode = ICP_OP_QUERY; + icp_opcode opcode = ICP_OP_QUERY; #endif - boolean ttcp = 0; - boolean tcp = 0; - boolean ssl = 0; + boolean ttcp = 0; + boolean tcp = 0; + boolean ssl = 0; - boolean stop_at_newlines = 1; + boolean stop_at_newlines = 1; #ifdef OPENSSL - SSL_METHOD *meth; - SSL_CTX *ctx = NULL; - SSL *sslh = NULL; + SSL_METHOD *meth; + SSL_CTX *ctx = NULL; + SSL *sslh = NULL; #endif #ifdef GNUTLS - gnutls_session session; - gnutls_certificate_credentials xcred; - int tls_result; - const int cert_type_priority[3] = { GNUTLS_CRT_X509, - GNUTLS_CRT_OPENPGP, 0 - }; + gnutls_session session; + gnutls_certificate_credentials xcred; + int tls_result; + const int cert_type_priority[3] = {GNUTLS_CRT_X509, + GNUTLS_CRT_OPENPGP, 0 + }; #endif - int priority; - int priority_requested = 0; - int tos; - int tos_requested = 0; - char *p; - echoping_options global_options; + int priority; + int priority_requested = 0; + int tos; + int tos_requested = 0; + char *p; + echoping_options global_options; - /* popt variables */ - const struct poptOption options[] = { - {"verbose", 'v', POPT_ARG_NONE, &verbose, 'v'}, - {"dump-configuration", 'V', POPT_ARG_NONE, &dump_config, 'V', - "Displays echoping compiled-in configuration"}, - {"help", '?', POPT_ARG_NONE, NULL, '?'}, - {"size", 's', POPT_ARG_INT, &size, 's'}, - {"number", 'n', POPT_ARG_INT, &number, 'n', "Number of iterations"}, + /* popt variables */ + const struct poptOption options[] = { + {"verbose", 'v', POPT_ARG_NONE, &verbose, 'v'}, + {"dump-configuration", 'V', POPT_ARG_NONE, &dump_config, 'V', + "Displays echoping compiled-in configuration"}, + {"help", '?', POPT_ARG_NONE, NULL, '?'}, + {"size", 's', POPT_ARG_INT, &size, 's'}, + {"number", 'n', POPT_ARG_INT, &number, 'n', "Number of iterations"}, #ifdef HAVE_USLEEP - {"wait", 'w', POPT_ARG_FLOAT, &wait, 'w', "Delay between iterations"}, + {"wait", 'w', POPT_ARG_FLOAT, &wait, 'w', "Delay between iterations"}, #else - {"wait", 'w', POPT_ARG_INT, &wait, 'w', "Delay between iterations"}, -#endif - {"discard", 'd', POPT_ARG_NONE, &discard, 'd'}, - {"chargen", 'c', POPT_ARG_NONE, &chargen, 'c'}, - {"http", 'h', POPT_ARG_STRING, &url, 'h'}, - {"accept-http-redirects", 'R', POPT_ARG_NONE, &accept_http_redirects, 'R', - "Accept HTTP return codes 3xx (redirections)"}, - {"icp", 'i', POPT_ARG_STRING, &url, 'i', - "ICP protocol, for Web proxies/caches"}, - {"ttcp", 'r', POPT_ARG_NONE, &ttcp, 'r', - "Use the T/TCP protocol (Transaction TCP)"}, - {"udp", 'u', POPT_ARG_NONE, &udp, 'u'}, - {"timeout", 't', POPT_ARG_INT, &timeout, 't'}, - {"fill", 'f', POPT_ARG_STRING, &fill_s, 'f'}, - {"smtp", 'S', POPT_ARG_NONE, &smtp, 'S'}, - {"ssl", 'C', POPT_ARG_NONE, &ssl, 'C'}, - {"priority", 'p', POPT_ARG_INT, &priority, 'p'}, - {"type-of-service", 'P', POPT_ARG_INT, &tos, 'P'}, - {"check-original", 'a', POPT_ARG_NONE, NULL, 'a', - "For HTTP through a proxy/cache"}, - {"ignore-cache", 'A', POPT_ARG_NONE, NULL, 'A', - "For HTTP through a proxy/cache"}, - {"ipv4", '4', POPT_ARG_NONE, NULL, '4'}, - {"ipv6", '6', POPT_ARG_NONE, NULL, '6'}, - {"module", 'm', POPT_ARG_STRING, &plugin_name, 'm', - "Loads the given plugin"}, - POPT_TABLEEND - }; - poptContext poptcon; + {"wait", 'w', POPT_ARG_INT, &wait, 'w', "Delay between iterations"}, +#endif + {"discard", 'd', POPT_ARG_NONE, &discard, 'd'}, + {"chargen", 'c', POPT_ARG_NONE, &chargen, 'c'}, + {"http", 'h', POPT_ARG_STRING, &url, 'h'}, + {"accept-http-redirects", 'R', POPT_ARG_NONE, &accept_http_redirects, 'R', + "Accept HTTP return codes 3xx (redirections)"}, + {"hostname", 'H', POPT_ARG_STRING, &http_hostname, 'H', "Hostname to use in HTTP Host: header"}, + {"icp", 'i', POPT_ARG_STRING, &url, 'i', + "ICP protocol, for Web proxies/caches"}, + {"ttcp", 'r', POPT_ARG_NONE, &ttcp, 'r', + "Use the T/TCP protocol (Transaction TCP)"}, + {"udp", 'u', POPT_ARG_NONE, &udp, 'u'}, + {"timeout", 't', POPT_ARG_INT, &timeout, 't'}, + {"fill", 'f', POPT_ARG_STRING, &fill_s, 'f'}, + {"smtp", 'S', POPT_ARG_NONE, &smtp, 'S'}, + {"ssl", 'C', POPT_ARG_NONE, &ssl, 'C'}, + {"priority", 'p', POPT_ARG_INT, &priority, 'p'}, + {"type-of-service", 'P', POPT_ARG_INT, &tos, 'P'}, + {"check-original", 'a', POPT_ARG_NONE, NULL, 'a', + "For HTTP through a proxy/cache"}, + {"ignore-cache", 'A', POPT_ARG_NONE, NULL, 'A', + "For HTTP through a proxy/cache"}, + {"ipv4", '4', POPT_ARG_NONE, NULL, '4'}, + {"ipv6", '6', POPT_ARG_NONE, NULL, '6'}, + {"module", 'm', POPT_ARG_STRING, &plugin_name, 'm', + "Loads the given plugin"}, + POPT_TABLEEND + }; + poptContext poptcon; - global_options.udp = FALSE; - global_options.ttcp = FALSE; - global_options.verbose = FALSE; + global_options.udp = FALSE; + global_options.ttcp = FALSE; + global_options.verbose = FALSE; - null_timeval.tv_sec = 0; - null_timeval.tv_usec = 0; - max_timeval.tv_sec = 1000000000; - max_timeval.tv_usec = 999999; + null_timeval.tv_sec = 0; + null_timeval.tv_usec = 0; + max_timeval.tv_sec = 1000000000; + max_timeval.tv_usec = 999999; - return_code = 0; - number = 1; - total = null_timeval; - median = null_timeval; - max = null_timeval; - min = max_timeval; - stddev = null_timeval; - port_name = malloc (NI_MAXSERV); - strcpy (port_name, ECHO_TCP_PORT); + return_code = 0; + number = 1; + total = null_timeval; + median = null_timeval; + max = null_timeval; + min = max_timeval; + stddev = null_timeval; + port_name = malloc(NI_MAXSERV); + strcpy(port_name, ECHO_TCP_PORT); - for (i = 0; i <= MAX_ITERATIONS; i++) - { - results[i].valid = 0; - } - progname = (char *) argv[0]; + for (i = 0; i <= MAX_ITERATIONS; i++) { + results[i].valid = 0; + } + progname = (char *) argv[0]; - poptcon = - poptGetContext (NULL, argc, argv, options, POPT_CONTEXT_POSIXMEHARDER); + poptcon = + poptGetContext(NULL, argc, argv, options, POPT_CONTEXT_POSIXMEHARDER); - while ((result = poptGetNextOpt (poptcon)) != -1) - { - if (result < -1) - { - fprintf (stderr, "%s: %s\n", - poptBadOption (poptcon, POPT_BADOPTION_NOALIAS), - poptStrerror (result)); - usage (poptcon); + while ((result = poptGetNextOpt(poptcon)) != -1) { + if (result < -1) { + fprintf(stderr, "%s: %s\n", + poptBadOption(poptcon, POPT_BADOPTION_NOALIAS), + poptStrerror(result)); + usage(poptcon); + } + remaining--; + switch ((char) result) { + case '?': + poptPrintHelp(poptcon, stdout, 0); + fprintf(stdout, " hostname [plugin-options...]\n"); + fprintf(stdout, + " (You can get a list of available plugins with \"ls %s\")\n", + PLUGINS_DIR); + exit(0); + case 'V': + printf("%s\n", COMPILATION_OPTIONS); + exit(0); + case 'v': + break; + case 'r': + break; + case 'u': + break; + case 'C': + break; + case 'd': + strcpy(port_name, DISCARD_TCP_PORT); + port_to_use = USE_DISCARD; + break; + case 'c': + strcpy(port_name, CHARACTER_GENERATOR_TCP_PORT); + port_to_use = USE_CHARGEN; + stop_at_newlines = 0; + break; + case 'i': + remaining--; + strcpy(port_name, DEFAULT_ICP_UDP_PORT); + port_to_use = USE_ICP; + udp = 1; + icp = 1; + break; + case 'h': + remaining--; + strcpy(port_name, DEFAULT_HTTP_TCP_PORT); + port_to_use = USE_HTTP; + http = 1; + break; + case 'R': + accept_http_redirects = TRUE; + break; + case 'H': + remaining--; + break; + case 'a': + nocache = 1; + break; + case 'A': + nocache = 2; + break; + case 'f': + remaining--; + if (strlen(fill_s) > 1) + err_quit("Argument --fill should be a one-character string"); + fill = fill_s[0]; + fill_requested = 1; + break; + case 'S': + strcpy(port_name, "smtp"); + port_to_use = USE_SMTP; + break; + case 'p': + remaining--; + priority_requested = 1; + break; + case 'P': + remaining--; + tos_requested = 1; + break; + case 's': + remaining--; + if (size > MAX_LINE) { + (void) fprintf(stderr, + "%s: packet size too large, max is %d.\n", + progname, MAX_LINE); + exit(1); + } + if (size <= 0) { + (void) fprintf(stderr, "%s: illegal packet size.\n", progname); + exit(1); + } + size_requested = 1; + break; + case 't': + remaining--; + timeout_requested = 1; + if (size <= 0) { + (void) fprintf(stderr, "%s: illegal timeout.\n", progname); + exit(1); + } + break; + case 'n': + remaining--; + if (number > MAX_ITERATIONS) { + (void) fprintf(stderr, + "%s: number of iterations too large, max is %d.\n", + progname, MAX_ITERATIONS); + exit(1); + } + if (number <= 0) { + (void) fprintf(stderr, + "%s: illegal number of iterations.\n", + progname); + exit(1); + } + break; + case 'w': + remaining--; + if (wait <= 0) + /* + * atoi returns zero when there is an error. + * So we cannot use '-w 0' to specify no + * waiting. + */ + { + (void) fprintf(stderr, + "%s: illegal waiting time.\n", progname); + exit(1); + } + break; + case '4': + family = AF_INET; + break; + case '6': + family = AF_INET6; + break; + case 'm': + remaining--; + module_find = TRUE; + break; + default: + printf("Unknown character option %d (%c)", result, (char) result); + usage(poptcon); + } + } + if (udp && ((port_to_use == USE_CHARGEN) || + (port_to_use == USE_HTTP) || (port_to_use == USE_SMTP))) { + (void) fprintf(stderr, + "%s: I don't know how to use this port with UDP.\n", + progname); + exit(1); } - remaining--; - switch ((char) result) - { - case '?': - poptPrintHelp (poptcon, stdout, 0); - fprintf (stdout, " hostname [plugin-options...]\n"); - fprintf (stdout, - " (You can get a list of available plugins with \"ls %s\")\n", - PLUGINS_DIR); - exit (0); - case 'V': - printf ("%s\n", COMPILATION_OPTIONS); - exit (0); - case 'v': - break; - case 'r': - break; - case 'u': - break; - case 'C': - break; - case 'd': - strcpy (port_name, DISCARD_TCP_PORT); - port_to_use = USE_DISCARD; - break; - case 'c': - strcpy (port_name, CHARACTER_GENERATOR_TCP_PORT); - port_to_use = USE_CHARGEN; - stop_at_newlines = 0; - break; - case 'i': - remaining--; - strcpy (port_name, DEFAULT_ICP_UDP_PORT); - port_to_use = USE_ICP; - udp = 1; - icp = 1; - break; - case 'h': - remaining--; - strcpy (port_name, DEFAULT_HTTP_TCP_PORT); - port_to_use = USE_HTTP; - http = 1; - break; - case 'R': - accept_http_redirects = TRUE; - break; - case 'a': - nocache = 1; - break; - case 'A': - nocache = 2; - break; - case 'f': - remaining--; - if (strlen (fill_s) > 1) - err_quit ("Argument --fill should be a one-character string"); - fill = fill_s[0]; - fill_requested = 1; - break; - case 'S': - strcpy (port_name, "smtp"); - port_to_use = USE_SMTP; - break; - case 'p': - remaining--; - priority_requested = 1; - break; - case 'P': - remaining--; - tos_requested = 1; - break; - case 's': - remaining--; - if (size > MAX_LINE) - { - (void) fprintf (stderr, - "%s: packet size too large, max is %d.\n", - progname, MAX_LINE); - exit (1); - } - if (size <= 0) - { - (void) fprintf (stderr, "%s: illegal packet size.\n", progname); - exit (1); - } - size_requested = 1; - break; - case 't': - remaining--; - timeout_requested = 1; - if (size <= 0) - { - (void) fprintf (stderr, "%s: illegal timeout.\n", progname); - exit (1); - } - break; - case 'n': - remaining--; - if (number > MAX_ITERATIONS) - { - (void) fprintf (stderr, - "%s: number of iterations too large, max is %d.\n", - progname, MAX_ITERATIONS); - exit (1); - } - if (number <= 0) - { - (void) fprintf (stderr, - "%s: illegal number of iterations.\n", - progname); - exit (1); - } - break; - case 'w': - remaining--; - if (wait <= 0) - /* atoi returns zero when there is an error. So we cannot use - '-w 0' to specify no waiting. */ - { - (void) fprintf (stderr, - "%s: illegal waiting time.\n", progname); - exit (1); - } - break; - case '4': - family = AF_INET; - break; - case '6': - family = AF_INET6; - break; - case 'm': - remaining--; - module_find = TRUE; - break; - default: - printf ("Unknown character option %d (%c)", result, (char) result); - usage (poptcon); + if ((http || smtp) && (fill_requested)) { + (void) fprintf(stderr, + "%s: Filling incompatible with HTTP connections.\n", + progname); + exit(1); } - } - if (udp && ((port_to_use == USE_CHARGEN) || - (port_to_use == USE_HTTP) || (port_to_use == USE_SMTP))) - { - (void) fprintf (stderr, - "%s: I don't know how to use this port with UDP.\n", - progname); - exit (1); - } - if ((http || smtp) && (fill_requested)) - { - (void) fprintf (stderr, - "%s: Filling incompatible with HTTP connections.\n", - progname); - exit (1); - } #ifndef USE_TTCP - if (ttcp) - { - (void) fprintf (stderr, - "%s: not compiled with T/TCP support.\n", progname); - exit (1); - } + if (ttcp) { + (void) fprintf(stderr, + "%s: not compiled with T/TCP support.\n", progname); + exit(1); + } #endif #if ! (defined(OPENSSL) || defined(GNUTLS)) - if (ssl) - { - (void) fprintf (stderr, + if (ssl) { + (void) fprintf(stderr, "%s: not compiled with SSL/TLS support.\n", progname); - exit (1); - } + exit(1); + } #endif #ifndef HTTP - if (http) - { - (void) fprintf (stderr, - "%s: Not compiled with HTTP support.\n", progname); - exit (1); - } + if (http) { + (void) fprintf(stderr, + "%s: Not compiled with HTTP support.\n", progname); + exit(1); + } #endif #ifndef SMTP - if (smtp) - { - (void) fprintf (stderr, - "%s: Not compiled with SMTP support.\n", progname); - exit (1); - } + if (smtp) { + (void) fprintf(stderr, + "%s: Not compiled with SMTP support.\n", progname); + exit(1); + } #endif #ifndef ICP - if (icp) - { - (void) fprintf (stderr, - "%s: Not compiled with ICP support.\n", progname); - exit (1); - } -#endif - if ((http || smtp) && size_requested) - { - (void) fprintf (stderr, - "%s: %s and message size specification are incompatible.\n", - progname, http ? "HTTP" : "SMTP"); - exit (1); - } - if (ssl && !http) - { - (void) fprintf (stderr, - "%s: SSL is only supported for HTTP requests.\n", - progname); - exit (1); - } - if (udp && ttcp) - { - (void) fprintf (stderr, - "%s: UDP and T/TCP are incompatible.\n", progname); - exit (1); - } - if (ssl && http) - { - strcpy (port_name, DEFAULT_HTTPS_TCP_PORT); - } - if (!http && accept_http_redirects) - { - (void) fprintf (stderr, - "%s: accept-http-redirects does not make sens if you do not use HTTP.\n", - progname); - exit (1); - } + if (icp) { + (void) fprintf(stderr, + "%s: Not compiled with ICP support.\n", progname); + exit(1); + } +#endif + if ((http || smtp) && size_requested) { + (void) fprintf(stderr, + "%s: %s and message size specification are incompatible.\n", + progname, http ? "HTTP" : "SMTP"); + exit(1); + } + if (ssl && !http) { + (void) fprintf(stderr, + "%s: SSL is only supported for HTTP requests.\n", + progname); + exit(1); + } + if (udp && ttcp) { + (void) fprintf(stderr, + "%s: UDP and T/TCP are incompatible.\n", progname); + exit(1); + } + if (ssl && http) { + strcpy(port_name, DEFAULT_HTTPS_TCP_PORT); + } + if (!http && accept_http_redirects) { + (void) fprintf(stderr, + "%s: accept-http-redirects does not make sens if you do not use HTTP.\n", + progname); + exit(1); + } #ifndef USE_TOS - if (tos_requested) - { - (void) fprintf (stderr, - "%s: Not compiled with Type Of Service support.\n", - progname); - exit (1); - } + if (tos_requested) { + (void) fprintf(stderr, + "%s: Not compiled with Type Of Service support.\n", + progname); + exit(1); + } #endif #ifndef USE_PRIORITY - if (priority_requested) - { - (void) fprintf (stderr, - "%s: Not compiled with socket priority support.\n", - progname); - exit (1); - } -#endif - remaining--; /* No argv[0] this time */ - leftover = (char **) &argv[argc - remaining]; - if (plugin_name) - { - ext = strstr (plugin_name, ".so"); - if ((ext == NULL) || (strcmp (ext, ".so") != 0)) - sprintf (plugin_name, "%s.so", plugin_name); - plugin = dlopen (plugin_name, RTLD_NOW); - if (!plugin) - { - /* Retries with the absolute name */ - complete_plugin_name = (char *) malloc (MAX_LINE); - sprintf (complete_plugin_name, "%s/%s", PLUGINS_DIR, plugin_name); - plugin = dlopen (complete_plugin_name, RTLD_NOW); + if (priority_requested) { + (void) fprintf(stderr, + "%s: Not compiled with socket priority support.\n", + progname); + exit(1); } - if (!plugin) - { +#endif + remaining--; /* No argv[0] this time */ + leftover = (char **) &argv[argc - remaining]; + if (plugin_name) { + ext = strstr(plugin_name, ".so"); + if ((ext == NULL) || (strcmp(ext, ".so") != 0)) + sprintf(plugin_name, "%s.so", plugin_name); + plugin = dlopen(plugin_name, RTLD_NOW); + if (!plugin) { + /* Retries with the absolute name */ + complete_plugin_name = (char *) malloc(MAX_LINE); + sprintf(complete_plugin_name, "%s/%s", PLUGINS_DIR, plugin_name); + plugin = dlopen(complete_plugin_name, RTLD_NOW); + } + if (!plugin) { #if DEBIAN - /* A bit of help for the poor user */ - fprintf (stderr, "You may have to load the recommended packages " - "to run this plugin.\n" - "'dpkg -s echoping | grep Recommends' to know them.\n\n"); -#endif - err_sys - ("Cannot load \"%s\" (I tried the short name, then the complete name in \"%s\"): %s", - plugin_name, PLUGINS_DIR, dlerror ()); - } - plugin_init = dlsym (plugin, "init"); - if (!plugin_init) - { - err_sys ("Cannot find init in %s: %s", plugin_name, dlerror ()); + /* A bit of help for the poor user */ + fprintf(stderr, "You may have to load the recommended packages " + "to run this plugin.\n" + "'dpkg -s echoping | grep Recommends' to know them.\n\n"); +#endif + err_sys + ("Cannot load \"%s\" (I tried the short name, then the complete name in \"%s\"): %s", + plugin_name, PLUGINS_DIR, dlerror()); + } + plugin_init = dlsym(plugin, "init"); + if (!plugin_init) { + err_sys("Cannot find init in %s: %s", plugin_name, dlerror()); + } + global_options.udp = udp; + global_options.ttcp = ttcp; + global_options.verbose = verbose; + if (family == AF_INET) + global_options.only_ipv4 = 1; + else + global_options.only_ipv4 = 0; + if (family == AF_INET6) + global_options.only_ipv6 = 1; + else + global_options.only_ipv6 = 0; + plugin_port_name = + plugin_init(remaining, (const char **) leftover, global_options); + if (plugin_port_name != NULL) { + strcpy(port_name, plugin_port_name); + plugin_raw = FALSE; + plugin_start = dlsym(plugin, "start"); + if (!plugin_start) { + err_sys("Cannot find start in %s: %s", plugin_name, + dlerror()); + } + } else { + port_name = 0; + plugin_raw = TRUE; + plugin_raw_start = dlsym(plugin, "start_raw"); + if (!plugin_raw_start) { + err_sys("Cannot find start_raw in %s: %s", plugin_name, + dlerror()); + } + } + plugin_execute = dlsym(plugin, "execute"); + if (!plugin_execute) { + err_sys("Cannot find execute in %s: %s", plugin_name, dlerror()); + } + plugin_terminate = dlsym(plugin, "terminate"); + if (!plugin_terminate) { + err_sys("Cannot find terminate in %s: %s", plugin_name, + dlerror()); + } } - global_options.udp = udp; - global_options.ttcp = ttcp; - global_options.verbose = verbose; - if (family == AF_INET) - global_options.only_ipv4 = 1; - else - global_options.only_ipv4 = 0; - if (family == AF_INET6) - global_options.only_ipv6 = 1; - else - global_options.only_ipv6 = 0; - plugin_port_name = - plugin_init (remaining, (const char **) leftover, global_options); - if (plugin_port_name != NULL) - { - strcpy (port_name, plugin_port_name); - plugin_raw = FALSE; - plugin_start = dlsym (plugin, "start"); - if (!plugin_start) - { - err_sys ("Cannot find start in %s: %s", plugin_name, - dlerror ()); - } + if (!udp && !ttcp) { + tcp = 1; } - else - { - port_name = 0; - plugin_raw = TRUE; - plugin_raw_start = dlsym (plugin, "start_raw"); - if (!plugin_raw_start) - { - err_sys ("Cannot find start_raw in %s: %s", plugin_name, - dlerror ()); - } + if (remaining == 0) { + (void) fprintf(stderr, "No host name indicated\n"); + usage(poptcon); } - plugin_execute = dlsym (plugin, "execute"); - if (!plugin_execute) - { - err_sys ("Cannot find execute in %s: %s", plugin_name, dlerror ()); + if (!module_find && remaining != 1) { + printf("%d args remaining, should be 1\n", remaining); + usage(poptcon); } - plugin_terminate = dlsym (plugin, "terminate"); - if (!plugin_terminate) - { - err_sys ("Cannot find terminate in %s: %s", plugin_name, - dlerror ()); + if (verbose) { + printf("\nThis is %s, version %s.\n\n", progname, VERSION); } - } - if (!udp && !ttcp) - { - tcp = 1; - } - if (remaining == 0) - { - (void) fprintf (stderr, "No host name indicated\n"); - usage (poptcon); - } - if (!module_find && remaining != 1) - { - printf ("%d args remaining, should be 1\n", remaining); - usage (poptcon); - } - if (verbose) - { - printf ("\nThis is %s, version %s.\n\n", progname, VERSION); - } - server = leftover[0]; + server = leftover[0]; #ifdef LIBIDN - locale_server = server; - utf8_server = stringprep_locale_to_utf8 (server); - if (utf8_server) - server = utf8_server; - else - err_quit ("Cannot convert %s to UTF-8 encoding: wrong locale (%s)?", - server, stringprep_locale_charset ()); -#endif - if (!http && !icp) - { - for (p = server; *p && (*p != ':'); p++) - { - } - if (*p && (*p == ':')) - { - (void) fprintf (stderr, - "%s: The syntax hostname:port is only for HTTP or ICP\n", - progname); - exit (1); + locale_server = server; + utf8_server = stringprep_locale_to_utf8(server); + if (utf8_server) + server = utf8_server; + else + err_quit("Cannot convert %s to UTF-8 encoding: wrong locale (%s)?", + server, stringprep_locale_charset()); +#endif + if (!http && !icp) { + for (p = server; *p && (*p != ':'); p++) { + } + if (*p && (*p == ':')) { + (void) fprintf(stderr, + "%s: The syntax hostname:port is only for HTTP or ICP\n", + progname); + exit(1); + } } - } - signal (SIGINT, interrupted); - memset (&hints, 0, sizeof (hints)); - hints.ai_family = family; - hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM; + signal(SIGINT, interrupted); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = family; + hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM; #ifdef HTTP - if (http || icp) - { - char *text_port = NULL; + if (http || icp) { + char *text_port = NULL; - if (*server == '[') - { /* RFC 2732 */ - server++; - for (p = server; *p && *p != ']'; p++) - { - } - p++; - if (*p == ':') - { - p--; - *p = 0; - text_port = p + 2; - strncpy (port_name, text_port, NI_MAXSERV); - } - else - { - p--; - if (*p == ']') - { - /* No port number */ - *p = 0; - } - else - { - (void) fprintf (stderr, - "%s: Invalid syntax for IPv6 address.\n", - progname); - exit (1); - } - } - } - else - { - for (p = server; *p; p++) - { - if (*p == ':') - { - *p = 0; - text_port = p + 1; - if (strcmp (text_port, "")) /* See bug #850672 */ - strncpy (port_name, text_port, NI_MAXSERV); + if (*server == '[') { /* RFC 2732 */ + server++; + for (p = server; *p && *p != ']'; p++) { + } + p++; + if (*p == ':') { + p--; + *p = 0; + text_port = p + 2; + strncpy(port_name, text_port, NI_MAXSERV); + } else { + p--; + if (*p == ']') { + /* No port number */ + *p = 0; + } else { + (void) fprintf(stderr, + "%s: Invalid syntax for IPv6 address.\n", + progname); + exit(1); + } + } + } else { + for (p = server; *p; p++) { + if (*p == ':') { + *p = 0; + text_port = p + 1; + if (strcmp(text_port, "")) /* See bug #850672 */ + strncpy(port_name, text_port, NI_MAXSERV); + } + } } - } - } - if (text_port == NULL || !strcmp (text_port, "")) - { - error = getaddrinfo (server, port_name, &hints, &res); - if (error) - { - if (error == EAI_SERVICE) - { - if (strcmp (port_name, DEFAULT_HTTP_TCP_PORT) == 0) - { - strcpy (port_name, "80"); - } - else if (strcmp (port_name, DEFAULT_HTTPS_TCP_PORT) == 0) - { - strcpy (port_name, "443"); - } - else if (strcmp (port_name, DEFAULT_ICP_UDP_PORT) == 0) - { - strcpy (port_name, "3130"); - } + if (text_port == NULL || !strcmp(text_port, "")) { + error = getaddrinfo(server, port_name, &hints, &res); + if (error) { + if (error == EAI_SERVICE) { + if (strcmp(port_name, DEFAULT_HTTP_TCP_PORT) == 0) { + strcpy(port_name, "80"); + } else if (strcmp(port_name, DEFAULT_HTTPS_TCP_PORT) == 0) { + strcpy(port_name, "443"); + } else if (strcmp(port_name, DEFAULT_ICP_UDP_PORT) == 0) { + strcpy(port_name, "3130"); + } + } + } } - } } - } #endif #ifdef LIBIDN - /* Check if it is an address or a name (libidn will have trouble with - IPv6 addresses otherwise) */ - memset (&hints_numeric, 0, sizeof (hints_numeric)); - hints_numeric.ai_family = family; - hints_numeric.ai_flags = AI_NUMERICHOST; - error = getaddrinfo (server, port_name, &hints_numeric, &res); - if (error && error == EAI_NONAME) /* A name, not an address */ - { - if ((result = - idna_to_ascii_8z (utf8_server, &ace_server, - IDNA_USE_STD3_ASCII_RULES)) != IDNA_SUCCESS) - { - if (result == IDNA_CONTAINS_LDH) - err_quit ("Illegal name for host: %s", server); /* foo@bar or - similar errors */ - else - err_quit ("IDN error for host: %s %d", server, result); - } - if (strcmp (utf8_server, ace_server)) - { - if (verbose) - printf ("ACE name of the server: %s\n", ace_server); - server = ace_server; - } - } /* Else it is an address, do not IDNize it */ -#endif - if (!plugin || !plugin_raw) - { - error = getaddrinfo (server, port_name, &hints, &res); - if (error) - { - err_quit ("getaddrinfo error for host: %s %s", - server, gai_strerror (error)); - } - - if (getnameinfo (res->ai_addr, res->ai_addrlen, hbuf, sizeof (hbuf), - pbuf, sizeof (pbuf), niflags) != 0) - { - strcpy (hbuf, "?"); - strcpy (pbuf, "?"); + /* + * Check if it is an address or a name (libidn will have trouble with + * IPv6 addresses otherwise) + */ + memset(&hints_numeric, 0, sizeof(hints_numeric)); + hints_numeric.ai_family = family; + hints_numeric.ai_flags = AI_NUMERICHOST; + error = getaddrinfo(server, port_name, &hints_numeric, &res); + if (error && error == EAI_NONAME) { /* A name, not an address */ + if ((result = + idna_to_ascii_8z(utf8_server, &ace_server, + IDNA_USE_STD3_ASCII_RULES)) != IDNA_SUCCESS) { + if (result == IDNA_CONTAINS_LDH) + err_quit("Illegal name for host: %s", server); /* foo@bar or similar + * errors */ + else + err_quit("IDN error for host: %s %d", server, result); + } + if (strcmp(utf8_server, ace_server)) { + if (verbose) + printf("ACE name of the server: %s\n", ace_server); + server = ace_server; + } + } /* Else it is an address, do not IDNize it */ +#endif + if (!plugin || !plugin_raw) { + error = getaddrinfo(server, port_name, &hints, &res); + if (error) { + err_quit("getaddrinfo error for host: %s %s", + server, gai_strerror(error)); + } + if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), + pbuf, sizeof(pbuf), niflags) != 0) { + strcpy(hbuf, "?"); + strcpy(pbuf, "?"); + } } - } - if (plugin) - { - if (verbose) - { - printf ("Running start() for the plugin %s...\n", plugin_name); + if (plugin) { + if (verbose) { + printf("Running start() for the plugin %s...\n", plugin_name); + } + if (plugin_raw) + plugin_raw_start(); + else + plugin_start(res); } - if (plugin_raw) - plugin_raw_start (); - else - plugin_start (res); - } #ifdef HTTP - if (http) - { - sendline = make_http_sendline (url, server, atoi (pbuf), nocache); - } - else + if (http) { + if (http_hostname != NULL) + server = http_hostname; + sendline = make_http_sendline(url, server, atoi(pbuf), nocache); + } else #endif #ifdef SMTP - if (smtp) - { - sendline = "QUIT\r\n"; /* Surprises some SMTP servers which log - a frightening NOQUEUE. Anyone knows - better? */ - } - else + if (smtp) { + sendline = "QUIT\r\n"; /* Surprises some SMTP servers which + * log a frightening NOQUEUE. Anyone + * knows better? */ + } else #endif #ifdef ICP - if (icp) - { - if (res->ai_family == AF_INET) - { - sendline = - make_icp_sendline (url, &(res->ai_addr), opcode, &length); - } - else - { + if (icp) { + if (res->ai_family == AF_INET) { + sendline = + make_icp_sendline(url, &(res->ai_addr), opcode, &length); + } else { - /* TODO: we should be able to create a ICP hostid for IPv6 addresses... - See the Squid IPv6 patch at - http://devel.squid-cache.org/projects.html#ipv6, for instance the - following code. */ - sendline = make_icp_sendline (url, (void *) NULL, opcode, &length); - /* - - headerp->shostid = theOutICPAddr.s_addr; - + ** FIXME ** we should get more unique data from IPv6 address - +xmemcpy (&headerp->shostid, &theOutICPAddr, - sizeof (headerp->shostid)); - */ + /* + * TODO: we should be able to create a ICP hostid for + * IPv6 addresses... See the Squid IPv6 patch at + * http://devel.squid-cache.org/projects.html#ipv6, + * for instance the following code. + */ + sendline = make_icp_sendline(url, (void *) NULL, opcode, &length); + /* + - headerp->shostid = theOutICPAddr.s_addr; + + ** FIXME ** we should get more unique data from IPv6 address + +xmemcpy (&headerp->shostid, &theOutICPAddr, + sizeof (headerp->shostid)); + */ + } + } else +#endif + if (!fill_requested) { + sendline = random_string(size); + } else { + sendline = (char *) malloc(size + 1); + for (i = 0; i < size; i++) + sendline[i] = fill; + sendline[size] = 0; } - } - else -#endif - if (!fill_requested) - { - sendline = random_string (size); - } - else - { - sendline = (char *) malloc (size + 1); - for (i = 0; i < size; i++) - sendline[i] = fill; - sendline[size] = 0; - } - n = strlen (sendline); + n = strlen(sendline); #ifdef OPENSSL - if (ssl) - { - SSL_load_error_strings (); - SSLeay_add_ssl_algorithms (); - /* The following RAND_ calls are only for systems insecure - enough to fail to have /dev/urandom. Bug #132001 */ - RAND_file_name (rand_file, sizeof (rand_file)); - RAND_write_file (rand_file); - RAND_load_file (rand_file, 1024); - meth = SSLv23_client_method (); - if ((ctx = SSL_CTX_new (meth)) == NULL) - err_sys ("Cannot create a new SSL context"); - /* Bug reported by Sebastian Siewior - . It seems that OpenSSL crashes - on non blocking sockets when trying to close them (OpenSSL - will try write on a closed socket). */ + if (ssl) { + SSL_load_error_strings(); + SSLeay_add_ssl_algorithms(); + /* + * The following RAND_ calls are only for systems insecure + * enough to fail to have /dev/urandom. Bug #132001 + */ + RAND_file_name(rand_file, sizeof(rand_file)); + RAND_write_file(rand_file); + RAND_load_file(rand_file, 1024); + meth = SSLv23_client_method(); + if ((ctx = SSL_CTX_new(meth)) == NULL) + err_sys("Cannot create a new SSL context"); + /* + * Bug reported by Sebastian Siewior + * . It seems that OpenSSL + * crashes on non blocking sockets when trying to close them + * (OpenSSL will try write on a closed socket). + */ #ifdef USE_SIGACTION - mysigaction.sa_handler = SIG_IGN; - sigemptyset (&mysigaction.sa_mask); - if ((sigaction (SIGPIPE, &mysigaction, NULL)) < 0) - ; /* Ignore it */ + mysigaction.sa_handler = SIG_IGN; + sigemptyset(&mysigaction.sa_mask); + if ((sigaction(SIGPIPE, &mysigaction, NULL)) < 0); /* Ignore it */ #else - signal (SIGPIPE, SIG_IGN); + signal(SIGPIPE, SIG_IGN); #endif - } + } #endif #ifdef GNUTLS - if (ssl) - { - gnutls_global_init (); - gnutls_certificate_allocate_credentials (&xcred); - /* gnutls_certificate_set_x509_trust_file(xcred, CAFILE, GNUTLS_X509_FMT_PEM); */ - } + if (ssl) { + gnutls_global_init(); + gnutls_certificate_allocate_credentials(&xcred); + /* + * gnutls_certificate_set_x509_trust_file(xcred, CAFILE, + * GNUTLS_X509_FMT_PEM); + */ + } #endif - for (i = 1; i <= number; i++) - { - timeout_flag = 0; - if (timeout_requested) - alarm (timeout); - if (i > 1) - { + for (i = 1; i <= number; i++) { + timeout_flag = 0; + if (timeout_requested) + alarm(timeout); + if (i > 1) { #ifdef HAVE_USLEEP - usleep (wait * 1000000); + usleep(wait * 1000000); #else - sleep (wait); + sleep(wait); #endif - } - attempts++; + } + attempts++; #ifdef OPENSSL - if (ssl) - /* Despite what the OpenSSL documentation says, we must - allocate a new SSL structure at each iteration, otherwise, - *some* SSL servers fail at the second iteration with: - error:1406D0D9:SSL routines:GET_SERVER_HELLO:reuse cert type not zero - Bug #130151 */ - if ((sslh = SSL_new (ctx)) == NULL) - err_sys ("Cannot initialize SSL context"); -#endif - /* - * Open a socket. - */ - if (!plugin) - { - if ((sockfd = - socket (res->ai_family, res->ai_socktype, - res->ai_protocol)) < 0) - err_sys ("Can't open socket"); - if (udp) - { - struct addrinfo hints2, *res2; + if (ssl) + /* + * Despite what the OpenSSL documentation says, we + * must allocate a new SSL structure at each + * iteration, otherwise, some* SSL servers fail at + * the second iteration with: error:1406D0D9:SSL + * routines:GET_SERVER_HELLO:reuse cert type not zero + * Bug #130151 + */ + if ((sslh = SSL_new(ctx)) == NULL) + err_sys("Cannot initialize SSL context"); +#endif + /* + * Open a socket. + */ + if (!plugin) { + if ((sockfd = + socket(res->ai_family, res->ai_socktype, + res->ai_protocol)) < 0) + err_sys("Can't open socket"); + if (udp) { + struct addrinfo hints2, *res2; - memset (&hints2, 0, sizeof (hints2)); - hints2.ai_family = res->ai_family; - hints2.ai_flags = AI_PASSIVE; - hints2.ai_socktype = SOCK_DGRAM; - error = getaddrinfo (NULL, "0", &hints2, &res2); - if (error) - { - err_sys ("getaddrinfo error"); - } - if (bind (sockfd, res2->ai_addr, res2->ai_addrlen) < 0) - { - err_sys ("bind error"); - } - } + memset(&hints2, 0, sizeof(hints2)); + hints2.ai_family = res->ai_family; + hints2.ai_flags = AI_PASSIVE; + hints2.ai_socktype = SOCK_DGRAM; + error = getaddrinfo(NULL, "0", &hints2, &res2); + if (error) { + err_sys("getaddrinfo error"); + } + if (bind(sockfd, res2->ai_addr, res2->ai_addrlen) < 0) { + err_sys("bind error"); + } + } #ifdef USE_PRIORITY - if (priority_requested) - { - if (verbose) - { - printf ("Setting socket priority to %d (0x%02x)\n", - priority, (unsigned int) priority); - } - if (setsockopt (sockfd, - SOL_SOCKET, - SO_PRIORITY, - (void *) &priority, - (socklen_t) sizeof (priority))) - { - err_sys ("Failed setting socket priority"); - } - } + if (priority_requested) { + if (verbose) { + printf("Setting socket priority to %d (0x%02x)\n", + priority, (unsigned int) priority); + } + if (setsockopt(sockfd, + SOL_SOCKET, + SO_PRIORITY, + (void *) &priority, + (socklen_t) sizeof(priority))) { + err_sys("Failed setting socket priority"); + } + } #endif #if USE_TOS - if (tos_requested) - { - if (verbose) - { - printf ("Setting IP type of service octet to %d (0x%02x)\n", - tos, (unsigned int) tos); - } - if (setsockopt (sockfd, - SOL_IP, - IP_TOS, (void *) &tos, - (socklen_t) sizeof (tos))) - { - err_sys ("Failed setting IP type of service octet"); - } - } + if (tos_requested) { + if (verbose) { + printf("Setting IP type of service octet to %d (0x%02x)\n", + tos, (unsigned int) tos); + } + if (setsockopt(sockfd, + SOL_IP, + IP_TOS, (void *) &tos, + (socklen_t) sizeof(tos))) { + err_sys("Failed setting IP type of service octet"); + } + } #endif - } - if (verbose) - { - if (!plugin) - { - if (tcp) - { - printf - ("Trying to connect to internet address %s %s to transmit %u bytes...\n", - hbuf, pbuf, n); } + if (verbose) { + if (!plugin) { + if (tcp) { + printf + ("Trying to connect to internet address %s %s to transmit %u bytes...\n", + hbuf, pbuf, n); + } #ifdef ICP - if (icp) - { - printf - ("Trying to send an ICP packet of %u bytes to the internet address %s...\n", - length, hbuf); - } -#endif - else - { - printf - ("Trying to send %u bytes to internet address %s...\n", - size, hbuf); + if (icp) { + printf + ("Trying to send an ICP packet of %u bytes to the internet address %s...\n", + length, hbuf); + } +#endif + else { + printf + ("Trying to send %u bytes to internet address %s...\n", + size, hbuf); + } + } else { + if (plugin_raw) + printf("Trying to call plugin %s...\n", plugin_name); + else + printf + ("Trying to call plugin %s for internet address %s %s...\n", + plugin_name, hbuf, pbuf); + } } - } - else - { - if (plugin_raw) - printf ("Trying to call plugin %s...\n", plugin_name); - else - printf - ("Trying to call plugin %s for internet address %s %s...\n", - plugin_name, hbuf, pbuf); - } - } #ifdef FLUSH_OUTPUT - if (fflush ((FILE *) NULL) != 0) - { - err_sys ("I cannot flush"); - } + if (fflush((FILE *) NULL) != 0) { + err_sys("I cannot flush"); + } #endif - if ((tcp || plugin) && timeout_requested) /* echoping's timeout has a different semantic in TCP and UDP */ - { + if ((tcp || plugin) && timeout_requested) { /* echoping's timeout + * has a different + * semantic in TCP and + * UDP */ #ifdef USE_SIGACTION - mysigaction.sa_handler = to_alarm; - sigemptyset (&mysigaction.sa_mask); - /* Default behavior doesn't seem portable? */ + mysigaction.sa_handler = to_alarm; + sigemptyset(&mysigaction.sa_mask); + /* Default behavior doesn't seem portable? */ #ifdef SA_INTERRUPT - mysigaction.sa_flags = SA_INTERRUPT; + mysigaction.sa_flags = SA_INTERRUPT; #else - mysigaction.sa_flags = (int) 0; + mysigaction.sa_flags = (int) 0; #endif - if ((sigaction (SIGALRM, &mysigaction, NULL)) < 0) - err_sys ("Cannot set signal handler"); + if ((sigaction(SIGALRM, &mysigaction, NULL)) < 0) + err_sys("Cannot set signal handler"); #else - signal (SIGALRM, to_alarm); + signal(SIGALRM, to_alarm); #endif - timeout_flag = 0; /* for signal handler */ - alarm (timeout); - } - (void) gettimeofday (&oldtv, (struct timezone *) NULL); - if (plugin) - { - plugin_result = plugin_execute (); - if (plugin_result == -2) - err_quit (""); - } - else - { - if (!ttcp && !icp) - { - /* - * Connect to the server. - */ - (void) gettimeofday (&conntv, (struct timezone *) NULL); - if (connect (sockfd, res->ai_addr, res->ai_addrlen) < 0) - { - if ((errno == EINTR) && (timeout_flag)) - { - printf ("Timeout while connecting\n"); - close (sockfd); - continue; -#ifdef FLUSH_OUTPUT - if (fflush ((FILE *) NULL) != 0) - { - err_sys ("I cannot flush"); - } -#endif - } - else - err_sys ("Can't connect to server"); + timeout_flag = 0; /* for signal handler */ + alarm(timeout); } - else - { - if (tcp) - { - (void) gettimeofday (&connectedtv, - (struct timezone *) NULL); - temp = connectedtv; - tvsub (&temp, &conntv); - if (verbose) - { - printf ("Connected...\n"); - printf ("TCP Latency: %d.%06d seconds\n", - (int) temp.tv_sec, (int) temp.tv_usec); - } - } - } - if (verbose && tcp) - { + (void) gettimeofday(&oldtv, (struct timezone *) NULL); + if (plugin) { + plugin_result = plugin_execute(); + if (plugin_result == -2) + err_quit(""); + } else { + if (!ttcp && !icp) { + /* + * Connect to the server. + */ + (void) gettimeofday(&conntv, (struct timezone *) NULL); + if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0) { + if ((errno == EINTR) && (timeout_flag)) { + printf("Timeout while connecting\n"); + close(sockfd); + continue; #ifdef FLUSH_OUTPUT - if (fflush ((FILE *) NULL) != 0) - { - err_sys ("I cannot flush"); - } -#endif - } - if (!udp && !ssl) - if ((files = fdopen (sockfd, "r")) == NULL) - err_sys ("Cannot fdopen"); + if (fflush((FILE *) NULL) != 0) { + err_sys("I cannot flush"); + } +#endif + } else + err_sys("Can't connect to server"); + } else { + if (tcp) { + (void) gettimeofday(&connectedtv, + (struct timezone *) NULL); + temp = connectedtv; + tvsub(&temp, &conntv); + if (verbose) { + printf("Connected...\n"); + printf("TCP Latency: %d.%06d seconds\n", + (int) temp.tv_sec, (int) temp.tv_usec); + } + } + } + if (verbose && tcp) { +#ifdef FLUSH_OUTPUT + if (fflush((FILE *) NULL) != 0) { + err_sys("I cannot flush"); + } +#endif + } + if (!udp && !ssl) + if ((files = fdopen(sockfd, "r")) == NULL) + err_sys("Cannot fdopen"); #ifdef OPENSSL - if (ssl) - { - SSL_set_fd (sslh, sockfd); - if (SSL_connect (sslh) == -1) - if ((errno == EINTR) && (timeout_flag)) - { - printf ("Timeout while starting SSL\n"); - close (sockfd); - continue; - } - if (verbose) - printf ("SSL connection using %s\n", - SSL_get_cipher (sslh)); - /* We could check the server's certificate or other funny - things */ - } + if (ssl) { + SSL_set_fd(sslh, sockfd); + if (SSL_connect(sslh) == -1) + if ((errno == EINTR) && (timeout_flag)) { + printf("Timeout while starting SSL\n"); + close(sockfd); + continue; + } + if (verbose) + printf("SSL connection using %s\n", + SSL_get_cipher(sslh)); + /* + * We could check the server's + * certificate or other funny things + */ + } #endif #ifdef GNUTLS - if (ssl) - { - tls_result = gnutls_init (&session, GNUTLS_CLIENT); - if (tls_result != 0) - err_sys ("Cannot create a new TLS session"); - gnutls_set_default_priority (session); - gnutls_certificate_type_set_priority (session, + if (ssl) { + tls_result = gnutls_init(&session, GNUTLS_CLIENT); + if (tls_result != 0) + err_sys("Cannot create a new TLS session"); + gnutls_set_default_priority(session); + gnutls_certificate_type_set_priority(session, cert_type_priority); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, - xcred); - gnutls_transport_set_ptr (session, - (gnutls_transport_ptr) sockfd); - tls_result = gnutls_handshake (session); - if (tls_result < 0) - { - if ((errno == EINTR) && (timeout_flag)) - { - printf ("Timeout while starting TLS\n"); - close (sockfd); - continue; + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, + xcred); + gnutls_transport_set_ptr(session, + (gnutls_transport_ptr) sockfd); + tls_result = gnutls_handshake(session); + if (tls_result < 0) { + if ((errno == EINTR) && (timeout_flag)) { + printf("Timeout while starting TLS\n"); + close(sockfd); + continue; + } else { + err_sys("Cannot start the TLS session: %s", + gnutls_strerror(tls_result)); + } + } + if (verbose) + printf("TLS connection using \"%s\"\n", + gnutls_cipher_get_name(gnutls_cipher_get + (session))); + /* + * We could check the server's + * certificate or other funny things. + * See + * http://www.gnu.org/software/gnutls/ + * documentation/gnutls/gnutls.html#SE + * CTION00622000000000000000 + */ + } +#endif } - else - { - err_sys ("Cannot start the TLS session: %s", - gnutls_strerror (tls_result)); + /* Not T/TCP */ + else { + /* No initial connection */ } - } - if (verbose) - printf ("TLS connection using \"%s\"\n", - gnutls_cipher_get_name (gnutls_cipher_get - (session))); - /* We could check the server's certificate or other funny - things. See http://www.gnu.org/software/gnutls/documentation/gnutls/gnutls.html#SECTION00622000000000000000 */ - } -#endif - } - /* Not T/TCP */ - else - { - /* No initial connection */ - } - if ((port_to_use == USE_ECHO) || (port_to_use == USE_DISCARD) || - (port_to_use == USE_HTTP) || (port_to_use == USE_ICP) || - (port_to_use == USE_SMTP)) - { + if ((port_to_use == USE_ECHO) || (port_to_use == USE_DISCARD) || + (port_to_use == USE_HTTP) || (port_to_use == USE_ICP) || + (port_to_use == USE_SMTP)) { #ifdef USE_TTCP - if (ttcp) - { - if (sendto (sockfd, sendline, n, MSG_EOF, - res->ai_addr, res->ai_addrlen) != n) - err_sys ("sendto error on socket"); - if (verbose) - { - printf ("T/TCP connection done\n"); - } - } - else -#endif - if (!udp) - { - if (!ssl) - { - /* Write something to the server */ - if (writen (sockfd, sendline, n) != n) - { - if ((nr < 0 || nr != n) && timeout_flag) - { - printf - ("Timeout while writing (%d byte(s) written so far)\n", - (nr == -1) ? 0 : nr); - nr = n; - close (sockfd); - continue; - } - else - err_sys ("writen error on TCP socket %d", sockfd); - } - } + if (ttcp) { + if (sendto(sockfd, sendline, n, MSG_EOF, + res->ai_addr, res->ai_addrlen) != n) + err_sys("sendto error on socket"); + if (verbose) { + printf("T/TCP connection done\n"); + } + } else +#endif + if (!udp) { + if (!ssl) { + /* + * Write something to the + * server + */ + if (writen(sockfd, sendline, n) != n) { + if ((nr < 0 || nr != n) && timeout_flag) { + printf + ("Timeout while writing (%d byte(s) written so far)\n", + (nr == -1) ? 0 : nr); + nr = n; + close(sockfd); + continue; + } else + err_sys("writen error on TCP socket %d", sockfd); + } + } #ifdef OPENSSL - else - { - if ((rc = SSL_write (sslh, sendline, n)) != n) - { - if ((nr < 0 || nr != n) && timeout_flag) - { - nr = n; - printf ("Timeout while writing\n"); - close (sockfd); - continue; - } - else - { - sslcode = ERR_get_error (); - err_sys ("SSL_write error on socket: %s", - ERR_error_string (sslcode, NULL)); - } - } - } + else { + if ((rc = SSL_write(sslh, sendline, n)) != n) { + if ((nr < 0 || nr != n) && timeout_flag) { + nr = n; + printf("Timeout while writing\n"); + close(sockfd); + continue; + } else { + sslcode = ERR_get_error(); + err_sys("SSL_write error on socket: %s", + ERR_error_string(sslcode, NULL)); + } + } + } #endif #ifdef GNUTLS - else - { - if ((rc = - gnutls_record_send (session, sendline, - strlen (sendline))) != n) - { - if ((nr < 0 || nr != n) && timeout_flag) - { - nr = n; - printf ("Timeout while writing\n"); - close (sockfd); - continue; - } - else - { - err_sys - ("gnutls_record_send error %d on socket: %s", - rc, gnutls_strerror (rc)); - } - } - } -#endif - } - else - { + else + { + if ((rc = + gnutls_record_send(session, sendline, + strlen(sendline))) != n) { + if ((nr < 0 || nr != n) && timeout_flag) { + nr = n; + printf("Timeout while writing\n"); + close(sockfd); + continue; + } else { + err_sys + ("gnutls_record_send error %d on socket: %s", + rc, gnutls_strerror(rc)); + } + } + } +#endif + } else { #ifdef ICP - if (icp) - { - if (sendto (sockfd, sendline, length, 0, - res->ai_addr, res->ai_addrlen) != length) - err_sys ("sendto error on socket"); - } - else -#endif - /* - * if (sendto(sockfd, sendline, n, 0, - * &serv_addr, sizeof(serv_addr)) != n) - * err_sys("sendto error on socket"); - */ - if (send (sockfd, sendline, n, 0) != n) - err_sys ("send error on socket"); - } - if (verbose) - { - (void) gettimeofday (&sendtv, (struct timezone *) NULL); + if (icp) { + if (sendto(sockfd, sendline, length, 0, + res->ai_addr, res->ai_addrlen) != length) + err_sys("sendto error on socket"); + } else +#endif + /* + * if (sendto(sockfd, sendline, n, 0, + * &serv_addr, sizeof(serv_addr)) != n) + * err_sys("sendto error on socket"); + */ + if (send(sockfd, sendline, n, 0) != n) + err_sys("send error on socket"); + } + if (verbose) { + (void) gettimeofday(&sendtv, (struct timezone *) NULL); #ifdef ICP - if (icp) - printf ("Sent (%d bytes)...\n", length); - else + if (icp) + printf("Sent (%d bytes)...\n", length); + else #endif - printf ("Sent (%d bytes)...\n", n); + printf("Sent (%d bytes)...\n", n); #ifdef FLUSH_OUTPUT - if (fflush ((FILE *) NULL) != 0) - { - err_sys ("I cannot flush"); - } + if (fflush((FILE *) NULL) != 0) { + err_sys("I cannot flush"); + } #endif - } - } - - if (tcp && !discard) - { - fd_set mask; - int n = 0; + } + } + if (tcp && !discard) { + fd_set mask; + int n = 0; - FD_ZERO (&mask); + FD_ZERO(&mask); - if (!(http && ssl)) - n = fileno (files); + if (!(http && ssl)) + n = fileno(files); #ifdef OPENSSL - else - { - n = SSL_get_fd (sslh); - } + else { + n = SSL_get_fd(sslh); + } #endif #ifdef GNUTLS - else - { - n = sockfd; - } -#endif - FD_SET (n, &mask); - if (select (n + 1, &mask, 0, 0, NULL) > 0) - { - (void) gettimeofday (&recvtv, (struct timezone *) NULL); - temp = recvtv; - tvsub (&temp, &sendtv); - if (verbose) - printf ("Application Latency: %d.%06d seconds\n", - (int) temp.tv_sec, (int) temp.tv_usec); - } - - } - - if ((port_to_use == USE_ECHO) || (port_to_use == USE_CHARGEN) || - (port_to_use == USE_HTTP) || (port_to_use == USE_ICP) || - (port_to_use == USE_SMTP)) - { - if (!udp) - { - if (!http && !smtp && !discard) - { - /* Read from the server */ - nr = readline (files, recvline, n, stop_at_newlines); - } - else if (discard) - { - /* No reply, no read */ - } + else + { + n = sockfd; + } +#endif + FD_SET(n, &mask); + if (select(n + 1, &mask, 0, 0, NULL) > 0) { + (void) gettimeofday(&recvtv, (struct timezone *) NULL); + temp = recvtv; + tvsub(&temp, &sendtv); + if (verbose) + printf("Application Latency: %d.%06d seconds\n", + (int) temp.tv_sec, (int) temp.tv_usec); + } + } + if ((port_to_use == USE_ECHO) || (port_to_use == USE_CHARGEN) || + (port_to_use == USE_HTTP) || (port_to_use == USE_ICP) || + (port_to_use == USE_SMTP)) { + if (!udp) { + if (!http && !smtp && !discard) { + /* Read from the server */ + nr = readline(files, recvline, n, stop_at_newlines); + } else if (discard) { + /* No reply, no read */ + } #ifdef HTTP - else if (http) - { - if (!ssl) - channel.fs = files; + else if (http) { + if (!ssl) + channel.fs = files; #ifdef OPENSSL - else - channel.ssl = sslh; + else + channel.ssl = sslh; #endif #ifdef GNUTLS - else - channel.tls = session; + else + channel.tls = session; #endif - nr = - read_from_server (channel, ssl, - accept_http_redirects); - } + nr = + read_from_server(channel, ssl, + accept_http_redirects); + } #endif #ifdef SMTP - else if (smtp) - { - nr = smtp_read_response_from_server (files); - } + else if (smtp) { + nr = smtp_read_response_from_server(files); + } #endif - } - else - { + } else { #ifdef USE_SIGACTION - mysigaction.sa_handler = to_alarm; - sigemptyset (&mysigaction.sa_mask); + mysigaction.sa_handler = to_alarm; + sigemptyset(&mysigaction.sa_mask); #ifdef SA_INTERRUPT - mysigaction.sa_flags = SA_INTERRUPT; + mysigaction.sa_flags = SA_INTERRUPT; #else - mysigaction.sa_flags = (int) 0; + mysigaction.sa_flags = (int) 0; #endif - if ((sigaction (SIGALRM, &mysigaction, NULL)) < 0) - err_sys ("Cannot set signal handler"); + if ((sigaction(SIGALRM, &mysigaction, NULL)) < 0) + err_sys("Cannot set signal handler"); #else - signal (SIGALRM, to_alarm); + signal(SIGALRM, to_alarm); #endif - timeout_flag = 0; /* for signal handler */ + timeout_flag = 0; /* for signal handler */ #ifdef ICP - if (icp) - { - nr = recv_icp (sockfd, recvline, retcode); - if (verbose) - { - printf ("%s\n", retcode); - } - } - else - { -#endif - nr = recv (sockfd, recvline, n, 0); - /* - * nr = recvfrom(sockfd, recvline, n, 0, - * (struct sockaddr *) 0, (int *) 0); - * recvfrom fails on SunOS on connected - * sockets. - */ - /* - * Todo: in UDP, we should loop to read: we - * can have several reads necessary. - */ - if ((nr < 0) && (errno == EINTR) && (timeout_flag)) - { - nr = n; - printf ("Timeout\n"); + if (icp) { + nr = recv_icp(sockfd, recvline, retcode); + if (verbose) { + printf("%s\n", retcode); + } + } else { +#endif + nr = recv(sockfd, recvline, n, 0); + /* + * nr = recvfrom(sockfd, recvline, n, 0, + * (struct sockaddr *) 0, (int *) 0); + * recvfrom fails on SunOS on connected + * sockets. + */ + /* + * Todo: in UDP, we should loop to read: we + * can have several reads necessary. + */ + if ((nr < 0) && (errno == EINTR) && (timeout_flag)) { + nr = n; + printf("Timeout\n"); #ifdef FLUSH_OUTPUT - if (fflush ((FILE *) NULL) != 0) - { - err_sys ("I cannot flush"); - } + if (fflush((FILE *) NULL) != 0) { + err_sys("I cannot flush"); + } #endif - } + } #ifdef ICP - } -#endif - } - if (!http && !icp && !smtp && !discard) - { - if ((nr < 0 || nr != n) && timeout_flag) - /* if ((nr < 0 || nr != n) && (errno == EINTR) && timeout_flag) */ - { - printf ("Timeout while reading (%d byte(s) read)\n", - (nr == -1) ? 0 : nr); - nr = n; + } +#endif + } + if (!http && !icp && !smtp && !discard) { + if ((nr < 0 || nr != n) && timeout_flag) + /* + * if ((nr < 0 || nr != n) && + * (errno == EINTR) && + * timeout_flag) + */ + { + printf("Timeout while reading (%d byte(s) read)\n", + (nr == -1) ? 0 : nr); + nr = n; #ifdef FLUSH_OUTPUT - if (fflush ((FILE *) NULL) != 0) - { - err_sys ("I cannot flush"); - } -#endif - close (sockfd); - continue; - } - if (nr < 0 || nr != n) - err_sys - ("readline error: %d bytes read, %d bytes requested", - nr, n); - } - else - /* This is probably HTTP */ - { - /* printf ("DEBUG: received %d bytes (flag is %d, errno is %d)\n", nr, timeout_flag, errno); */ - if ((errno == EINTR) && timeout_flag) - { - printf - ("Timeout while reading (%d byte(s) read so far)\n", - (nr == -1) ? 0 : nr); + if (fflush((FILE *) NULL) != 0) { + err_sys("I cannot flush"); + } +#endif + close(sockfd); + continue; + } + if (nr < 0 || nr != n) + err_sys + ("readline error: %d bytes read, %d bytes requested", + nr, n); + } else + /* This is probably HTTP */ + { + /* + * printf ("DEBUG: received %d bytes + * (flag is %d, errno is %d)\n", nr, + * timeout_flag, errno); + */ + if ((errno == EINTR) && timeout_flag) { + printf + ("Timeout while reading (%d byte(s) read so far)\n", + (nr == -1) ? 0 : nr); #ifdef FLUSH_OUTPUT - if (fflush ((FILE *) NULL) != 0) - { - err_sys ("I cannot flush"); + if (fflush((FILE *) NULL) != 0) { + err_sys("I cannot flush"); + } +#endif + close(sockfd); + continue; + } + if (nr < 0) { + err_ret("Error reading HTTP reply"); + } + } + if (verbose) + printf("%d bytes read from server.\n", nr); } -#endif - close (sockfd); - continue; - } - if (nr < 0) - { - err_ret ("Error reading HTTP reply"); - } - } - if (verbose) - printf ("%d bytes read from server.\n", nr); - } - } /* That's all, folks */ - alarm (0); - if (http) - { + } /* That's all, folks */ + alarm(0); + if (http) { #ifdef OPENSSL - if (ssl) - SSL_shutdown (channel.ssl); - else + if (ssl) + SSL_shutdown(channel.ssl); + else #endif #ifdef GNUTLS - if (ssl) - shutdown (sockfd, SHUT_RDWR); - else + if (ssl) + shutdown(sockfd, SHUT_RDWR); + else #endif - fclose (channel.fs); - } - close (sockfd); + fclose(channel.fs); + } + close(sockfd); - (void) gettimeofday (&newtv, (struct timezone *) NULL); - temp = newtv; - tvsub (&temp, &oldtv); - if (!timeout_flag) - { - tvadd (&total, &temp); + (void) gettimeofday(&newtv, (struct timezone *) NULL); + temp = newtv; + tvsub(&temp, &oldtv); + if (!timeout_flag) { + tvadd(&total, &temp); - /* Check */ - if (!plugin) - { - if (port_to_use == USE_ECHO) - { - if (strcmp (sendline, recvline) != 0) - { - printf (" I wrote:\n%s\n", sendline); - printf (" and I got back:\n%s\n", recvline); - err_quit ("Strange server"); - } - if (verbose) - { - printf ("Checked\n"); + /* Check */ + if (!plugin) { + if (port_to_use == USE_ECHO) { + if (strcmp(sendline, recvline) != 0) { + printf(" I wrote:\n%s\n", sendline); + printf(" and I got back:\n%s\n", recvline); + err_quit("Strange server"); + } + if (verbose) { + printf("Checked\n"); #ifdef FLUSH_OUTPUT - if (fflush ((FILE *) NULL) != 0) - { - err_sys ("I cannot flush"); + if (fflush((FILE *) NULL) != 0) { + err_sys("I cannot flush"); + } +#endif + } + } + if (port_to_use == USE_CHARGEN) { + sendline = CHARGENERATED; + recvline[strlen(sendline)] = 0; + if (strcmp(sendline, recvline) != 0) { + /* + * TODO: it does not work if + * the size is lower than the + * length of CHARGENERATED + */ + printf(" I got back:\n%s\n", recvline); + printf(" instead of the most common:\n%s\n", sendline); + err_ret("Strange server"); + } + if (verbose) { + printf("Checked\n"); + } + } + } + tvsub(&newtv, &oldtv); + tvmin(&min, &newtv); + tvmax(&max, &newtv); + printf("Elapsed time: %d.%06d seconds\n", + (int) newtv.tv_sec, (int) newtv.tv_usec); +#ifdef FLUSH_OUTPUT + if (fflush((FILE *) NULL) != 0) { + err_sys("I cannot flush"); } #endif - } + results[i - 1].valid = 1; + results[i - 1].timevalue = newtv; + successes++; } - if (port_to_use == USE_CHARGEN) - { - sendline = CHARGENERATED; - recvline[strlen (sendline)] = 0; - if (strcmp (sendline, recvline) != 0) - { - /* TODO: it does not work if the size is lower than the - length of CHARGENERATED */ - printf (" I got back:\n%s\n", recvline); - printf (" instead of the most common:\n%s\n", sendline); - err_ret ("Strange server"); - } - if (verbose) - { - printf ("Checked\n"); - } - } - } - tvsub (&newtv, &oldtv); - tvmin (&min, &newtv); - tvmax (&max, &newtv); - printf ("Elapsed time: %d.%06d seconds\n", - (int) newtv.tv_sec, (int) newtv.tv_usec); -#ifdef FLUSH_OUTPUT - if (fflush ((FILE *) NULL) != 0) - { - err_sys ("I cannot flush"); - } -#endif - results[i - 1].valid = 1; - results[i - 1].timevalue = newtv; - successes++; - } - if (number > 1) - { + if (number > 1) { #ifdef OPENSSL - if (ssl) - { - /* SSL_clear (sslh); No, we have to free. Bug #130151 */ - SSL_free (sslh); - } + if (ssl) { + /* + * SSL_clear (sslh); No, we have to free. Bug + * #130151 + */ + SSL_free(sslh); + } #endif #ifdef GNUTLS - if (ssl) - { - gnutls_bye (channel.tls, GNUTLS_SHUT_RDWR); - gnutls_deinit (session); - /* gnutls_certificate_free_credentials(xcred); */ - } + if (ssl) { + gnutls_bye(channel.tls, GNUTLS_SHUT_RDWR); + gnutls_deinit(session); + /* + * gnutls_certificate_free_credentials(xcred); + * + */ + } #endif - } - } /* End of main loop */ + } + } /* End of main loop */ - /* Clean */ - if (plugin) - plugin_terminate (); - /* It would be nice to clean here for OpenSSL */ + /* Clean */ + if (plugin) + plugin_terminate(); + /* It would be nice to clean here for OpenSSL */ #ifdef GNUTLS - if (ssl) - { - gnutls_global_deinit (); - } -#endif - printstats (); - if (successes >= 1) - exit (0); - else - exit (1); + if (ssl) { + gnutls_global_deinit(); + } +#endif + printstats(); + if (successes >= 1) + exit(0); + else + exit(1); } void -printstats () +printstats() { - int i; + int i; - /* if ((number > 1) && ((!udp) || (successes > 0))) { */ - if (successes > 1) - { - printf ("---\n"); - if (successes < attempts) - printf ("Warning: %d message(s) lost (%d %%)\n", attempts - successes, - ((attempts - successes) * 100) / attempts); - printf ("Minimum time: %d.%06d seconds (%.0f bytes per sec.)\n", - (int) min.tv_sec, (int) min.tv_usec, - (double) size / tv2double (min)); - printf ("Maximum time: %d.%06d seconds (%.0f bytes per sec.)\n", - (int) max.tv_sec, (int) max.tv_usec, - (double) size / tv2double (max)); - tvavg (&total, successes); - printf ("Average time: %d.%06d seconds (%.0f bytes per sec.)\n", - (int) total.tv_sec, (int) total.tv_usec, - (double) size / tv2double (total)); - /* The number of bytes/second, as printed above, is not really - meaningful: size does not reflect the number of bytes exchanged. - With echo, N = 2*size, with discard, N = size, with http, N = size + (response)... */ - tvstddev (&stddev, successes, total, results); - printf ("Standard deviation: %d.%06d\n", - (int) stddev.tv_sec, (int) stddev.tv_usec); - for (i = 0; i < number; i++) - { - if (results[i].valid) - good_results[j++] = results[i].timevalue; - } - if (successes != j) /* Todo: bug! */ - err_quit ("successes (%d) is different from j (%d)", successes, j); - qsort (good_results, successes, sizeof (struct timeval), tvcmp); - /* - * for (i = 1; i <= number; i++) { printf("---\nTime %d th: - * %d.%06d seconds\n", i, results[i-1].tv_sec, - * results[i-1].tv_usec); } - */ - if ((successes % 2) == 1) - { - /* - * printf("Searching good_results[%d]\n", (successes - * + 1) / 2 - 1); - */ - median = good_results[((successes + 1) / 2 - 1)]; - } - else - { - /* - * printf("Searching good_results[%d] and [%d]\n", - * (successes / 2) - 1, successes / 2); - */ - tvadd (&median, &good_results[(successes / 2) - 1]); - tvadd (&median, &good_results[successes / 2]); - tvavg (&median, 2); + /* if ((number > 1) && ((!udp) || (successes > 0))) { */ + if (successes > 1) { + printf("---\n"); + if (successes < attempts) + printf("Warning: %d message(s) lost (%d %%)\n", attempts - successes, + ((attempts - successes) * 100) / attempts); + printf("Minimum time: %d.%06d seconds (%.0f bytes per sec.)\n", + (int) min.tv_sec, (int) min.tv_usec, + (double) size / tv2double(min)); + printf("Maximum time: %d.%06d seconds (%.0f bytes per sec.)\n", + (int) max.tv_sec, (int) max.tv_usec, + (double) size / tv2double(max)); + tvavg(&total, successes); + printf("Average time: %d.%06d seconds (%.0f bytes per sec.)\n", + (int) total.tv_sec, (int) total.tv_usec, + (double) size / tv2double(total)); + /* + * The number of bytes/second, as printed above, is not + * really meaningful: size does not reflect the number of + * bytes exchanged. With echo, N = 2*size, with discard, N = + * size, with http, N = size + (response)... + */ + tvstddev(&stddev, successes, total, results); + printf("Standard deviation: %d.%06d\n", + (int) stddev.tv_sec, (int) stddev.tv_usec); + for (i = 0; i < number; i++) { + if (results[i].valid) + good_results[j++] = results[i].timevalue; + } + if (successes != j) /* Todo: bug! */ + err_quit("successes (%d) is different from j (%d)", successes, j); + qsort(good_results, successes, sizeof(struct timeval), tvcmp); + /* + * for (i = 1; i <= number; i++) { printf("---\nTime %d th: + * %d.%06d seconds\n", i, results[i-1].tv_sec, + * results[i-1].tv_usec); } + */ + if ((successes % 2) == 1) { + /* + * printf("Searching good_results[%d]\n", (successes + * + 1) / 2 - 1); + */ + median = good_results[((successes + 1) / 2 - 1)]; + } else { + /* + * printf("Searching good_results[%d] and [%d]\n", + * (successes / 2) - 1, successes / 2); + */ + tvadd(&median, &good_results[(successes / 2) - 1]); + tvadd(&median, &good_results[successes / 2]); + tvavg(&median, 2); + } + printf("Median time: %d.%06d seconds (%.0f bytes per sec.)\n", + (int) median.tv_sec, (int) median.tv_usec, + (double) size / tv2double(median)); } - printf ("Median time: %d.%06d seconds (%.0f bytes per sec.)\n", - (int) median.tv_sec, (int) median.tv_usec, - (double) size / tv2double (median)); - } } /* @@ -1566,16 +1424,16 @@ printstats () */ void -to_alarm () +to_alarm() { - /* printf ("DEBUG: timeout handler called\n"); */ - timeout_flag = 1; /* set flag for function above */ + /* printf ("DEBUG: timeout handler called\n"); */ + timeout_flag = 1; /* set flag for function above */ } void -interrupted () +interrupted() { - printf ("Interrupted by user\n"); - printstats (); - exit (1); + printf("Interrupted by user\n"); + printstats(); + exit(1); } diff --git a/SRC/http.c b/SRC/http.c index cf177c1..c5df986 100644 --- a/SRC/http.c +++ b/SRC/http.c @@ -6,129 +6,133 @@ #include "HTParse.h" -char big_recvline[MAXTOREAD]; +char big_recvline[MAXTOREAD]; -char * -make_http_sendline (char *url, char *host, int port, int nocache) +char * +make_http_sendline(char *url, char *host, int port, int nocache) { - short sport = (short) port; - int size = 200; /* Enough? */ - char *sendline = (char *) malloc (size); - char *hostname = (char *) malloc (size); - char *cache_directive = ""; + short sport = (short) port; + int size = 200; /* Enough? */ + char *sendline = (char *) malloc(size); + char *hostname = (char *) malloc(size); + char *cache_directive = ""; #ifdef HTTP10 - if (nocache) - cache_directive = "Pragma: no-cache\r\n"; /* RFC 1945, "Hypertext - Transfer Protocol -- - HTTP/1.0" */ - sprintf (sendline, - "GET %s HTTP/1.0\r\nUser-Agent: Echoping/%s\r\n%s\r\n", - url, VERSION, cache_directive); + if (nocache) + cache_directive = "Pragma: no-cache\r\n"; /* RFC 1945, "Hypertext + * Transfer Protocol -- + * HTTP/1.0" */ + sprintf(sendline, + "GET %s HTTP/1.0\r\nUser-Agent: Echoping/%s\r\n%s\r\n", + url, VERSION, cache_directive); #else - if (nocache) - { - if (nocache == 1) - cache_directive = "Cache-control: max-age=0\r\n"; /* Simply force a - recheck with the - server */ - else - cache_directive = "Cache-control: no-cache\r\n"; /* RFC 2616 - "Hypertext - Transfer - Protocol -- - HTTP/1.1" */ - } - strcpy (hostname, HTParse (url, "", PARSE_HOST)); - if (!strcmp (hostname, "")) - sprintf (hostname, "%s:%d", host, sport); - sprintf (sendline, - "GET %s HTTP/1.1\r\nUser-Agent: Echoping/%s\r\nHost: %s\r\nConnection: close\r\n%s\r\n", - url, VERSION, hostname, cache_directive); - free (hostname); + if (nocache) { + if (nocache == 1) + cache_directive = "Cache-control: max-age=0\r\n"; /* Simply force a + * recheck with the + * server */ + else + cache_directive = "Cache-control: no-cache\r\n"; /* RFC 2616 "Hypertext + * Transfer Protocol -- + * HTTP/1.1" */ + } + strcpy(hostname, HTParse(url, "", PARSE_HOST)); + if (!strcmp(hostname, "")) + sprintf(hostname, "%s:%d", host, sport); + sprintf(sendline, + "GET %s HTTP/1.1\r\nUser-Agent: Echoping/%s\r\nHost: %s\r\nConnection: close\r\n%s\r\n", + url, VERSION, hostname, cache_directive); + free(hostname); #endif - return sendline; + return sendline; } int -read_from_server (CHANNEL fs, short ssl, boolean accept_redirects) +read_from_server(CHANNEL fs, short ssl, boolean accept_redirects) { - int nr = 0; - int total = 0; - char reply_code; - int first_line = TRUE; - short body = FALSE; + int nr = 0; + int total = 0; + char reply_code; + int first_line = TRUE; + short body = FALSE; #ifdef OPENSSL - int sslcode; + int sslcode; #endif - while (!body && !timeout_flag) - { - if (!ssl) - nr = readline (fs.fs, big_recvline, MAXTOREAD, TRUE); + while (!body && !timeout_flag) { + if (!ssl) + nr = readline(fs.fs, big_recvline, MAXTOREAD, TRUE); #ifdef OPENSSL - else - { - nr = SSL_readline (fs.ssl, big_recvline, MAXTOREAD, TRUE); - if (nr == -1) - { - sslcode = ERR_get_error (); - err_ret ("SSL_readline error: %s", - ERR_error_string (sslcode, NULL)); - } - } + else { + nr = SSL_readline(fs.ssl, big_recvline, MAXTOREAD, TRUE); + if (nr == -1) { + sslcode = ERR_get_error(); + err_ret("SSL_readline error: %s", + ERR_error_string(sslcode, NULL)); + } + } #endif #ifdef GNUTLS - else - { - nr = TLS_readline (fs.tls, big_recvline, MAXTOREAD, TRUE); - if (nr == -1) - { - err_ret ("TLS_readline error: %s", gnutls_strerror (nr)); - } - } + else + { + nr = TLS_readline(fs.tls, big_recvline, MAXTOREAD, TRUE); + if (nr == -1) { + err_ret("TLS_readline error: %s", gnutls_strerror(nr)); + } + } #endif - /* printf ("DEBUG: reading \"%s\"\n (%d chars)\n", big_recvline, nr); */ - /* HTTP replies should be separated by CR-LF. Unfortunately, some - servers send only CR :-( */ - body = ((nr == 2) || (nr == 1)); /* Empty line CR-LF seen */ - if ((nr < 1) && (timeout_flag)) /* Probably a timeout */ - return -1; - if (nr < 1) - /* SourceForge bug #109385 */ - /* err_sys ("Error reading HTTP header"); */ - return -1; - /* if ((int) big_recvline[nr-1] == 10) - nr--; */ - if (first_line) - { - reply_code = big_recvline[9]; /* 9 because "HTTP/1.x 200..." */ - if (reply_code != '2' && !(reply_code == '3' && accept_redirects)) - /* Status codes beginning with 3 are not errors - See bug #850674 and RFC 2616, section - 10.3 */ - err_quit ("HTTP error \"%s\"", big_recvline); + /* + * printf ("DEBUG: reading \"%s\"\n (%d chars)\n", + * big_recvline, nr); + */ + /* + * HTTP replies should be separated by CR-LF. Unfortunately, + * some servers send only CR :-( + */ + body = ((nr == 2) || (nr == 1)); /* Empty line CR-LF seen */ + if ((nr < 1) && (timeout_flag)) /* Probably a timeout */ + return -1; + if (nr < 1) + /* SourceForge bug #109385 */ + /* err_sys ("Error reading HTTP header"); */ + return -1; + /* + * if ((int) big_recvline[nr-1] == 10) nr--; + */ + if (first_line) { + reply_code = big_recvline[9]; /* 9 because "HTTP/1.x + * 200..." */ + if (reply_code != '2' && !(reply_code == '3' && accept_redirects)) + /* + * Status codes beginning with 3 are not + * errors See bug #850674 and RFC 2616, + * section 10.3 + */ + err_quit("HTTP error \"%s\"", big_recvline); + } + total = total + nr; + first_line = FALSE; } - total = total + nr; - first_line = FALSE; - } - /* Read the body */ - if (!ssl) - nr = readline (fs.fs, big_recvline, MAXTOREAD, FALSE); + /* Read the body */ + if (!ssl) + nr = readline(fs.fs, big_recvline, MAXTOREAD, FALSE); #ifdef OPENSSL - else - nr = SSL_readline (fs.ssl, big_recvline, MAXTOREAD, FALSE); + else + nr = SSL_readline(fs.ssl, big_recvline, MAXTOREAD, FALSE); #endif #ifdef GNUTLS - else - nr = TLS_readline (fs.tls, big_recvline, MAXTOREAD, FALSE); + else + nr = TLS_readline(fs.tls, big_recvline, MAXTOREAD, FALSE); #endif - /* printf ("DEBUG: reading body \"%s\"\n (%d chars)\n", big_recvline, nr); */ - if ((nr < 2) && (timeout_flag)) /* Probably a timeout */ - return -1; - if (nr < 2) /* Hmm, if the body is empty, we'll - get a meaningless error message */ - err_sys ("Error reading HTTP body"); - total = total + nr; - return total; /* How to do if we want only the body's size? */ + /* + * printf ("DEBUG: reading body \"%s\"\n (%d chars)\n", big_recvline, + * nr); + */ + if ((nr < 2) && (timeout_flag)) /* Probably a timeout */ + return -1; + if (nr < 2) /* Hmm, if the body is empty, we'll get a + * meaningless error message */ + err_sys("Error reading HTTP body"); + total = total + nr; + return total; /* How to do if we want only the body's size? */ } -#endif /* HTTP */ +#endif /* HTTP */