diff options
Diffstat (limited to 'netserver.c')
-rw-r--r-- | netserver.c | 1022 |
1 files changed, 0 insertions, 1022 deletions
diff --git a/netserver.c b/netserver.c deleted file mode 100644 index fd8ea1b..0000000 --- a/netserver.c +++ /dev/null @@ -1,1022 +0,0 @@ -/* - - Copyright (C) 1993-2007 Hewlett-Packard Company - ALL RIGHTS RESERVED. - - The enclosed software and documentation includes copyrighted works - of Hewlett-Packard Co. For as long as you comply with the following - limitations, you are hereby authorized to (i) use, reproduce, and - modify the software and documentation, and to (ii) distribute the - software and documentation, including modifications, for - non-commercial purposes only. - - 1. The enclosed software and documentation is made available at no - charge in order to advance the general development of - high-performance networking products. - - 2. You may not delete any copyright notices contained in the - software or documentation. All hard copies, and copies in - source code or object code form, of the software or - documentation (including modifications) must contain at least - one of the copyright notices. - - 3. The enclosed software and documentation has not been subjected - to testing and quality control and is not a Hewlett-Packard Co. - product. At a future time, Hewlett-Packard Co. may or may not - offer a version of the software and documentation as a product. - - 4. THE SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS". - HEWLETT-PACKARD COMPANY DOES NOT WARRANT THAT THE USE, - REPRODUCTION, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR - DOCUMENTATION WILL NOT INFRINGE A THIRD PARTY'S INTELLECTUAL - PROPERTY RIGHTS. HP DOES NOT WARRANT THAT THE SOFTWARE OR - DOCUMENTATION IS ERROR FREE. HP DISCLAIMS ALL WARRANTIES, - EXPRESS AND IMPLIED, WITH REGARD TO THE SOFTWARE AND THE - DOCUMENTATION. HP SPECIFICALLY DISCLAIMS ALL WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - - 5. HEWLETT-PACKARD COMPANY WILL NOT IN ANY EVENT BE LIABLE FOR ANY - DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES - (INCLUDING LOST PROFITS) RELATED TO ANY USE, REPRODUCTION, - MODIFICATION, OR DISTRIBUTION OF THE SOFTWARE OR DOCUMENTATION. - -*/ - -#include "netperf_version.h" - -char netserver_id[]="\ -@(#)netserver.c (c) Copyright 1993-2007 Hewlett-Packard Co. Version 2.4.3"; - - /***********************************************************************/ - /* */ - /* netserver.c */ - /* */ - /* This is the server side code for the netperf test package. It */ - /* will operate either stand-alone, or as a child of inetd. In this */ - /* way, we insure that it can be installed on systems with or without */ - /* root permissions (editing inetd.conf). Essentially, this code is */ - /* the analog to the netsh.c code. */ - /* */ - /***********************************************************************/ - - -/************************************************************************/ -/* */ -/* Global include files */ -/* */ -/************************************************************************/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#if HAVE_STRING_H -# if !STDC_HEADERS && HAVE_MEMORY_H -# include <memory.h> -# endif -# include <string.h> -#endif -#if HAVE_STRINGS_H -# include <strings.h> -#endif -#if HAVE_LIMITS_H -# include <limits.h> -#endif -#include <sys/types.h> -#include <stdio.h> -#ifndef WIN32 -#include <errno.h> -#include <signal.h> -#endif -#if !defined(WIN32) && !defined(__VMS) -#include <sys/ipc.h> -#endif /* !defined(WIN32) && !defined(__VMS) */ -#include <fcntl.h> -#ifdef WIN32 -#include <time.h> -#include <winsock2.h> -#define netperf_socklen_t socklen_t -/* we need to find some other way to decide to include ws2 */ -/* if you are trying to compile on Windows 2000 or NT 4 you will */ -/* probably have to define DONT_IPV6 */ -#ifndef DONT_IPV6 -#include <ws2tcpip.h> -#endif /* DONT_IPV6 */ -#include <windows.h> -#define sleep(x) Sleep((x)*1000) -#else -#ifndef MPE -#include <sys/time.h> -#endif /* MPE */ -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <netinet/in.h> -#include <netdb.h> -#include <unistd.h> -#ifndef DONT_WAIT -#include <sys/wait.h> -#endif /* DONT_WAIT */ -#endif /* WIN32 */ -#include <stdlib.h> -#ifdef __VMS -#include <tcpip$inetdef.h> -#include <unixio.h> -#endif /* __VMS */ -#include "netlib.h" -#include "nettest_bsd.h" - -#ifdef WANT_UNIX -#include "nettest_unix.h" -#endif /* WANT_UNIX */ - -#ifdef WANT_DLPI -#include "nettest_dlpi.h" -#endif /* WANT_DLPI */ - -#ifdef WANT_SCTP -#include "nettest_sctp.h" -#endif - -#include "netsh.h" - -#ifndef DEBUG_LOG_FILE -#ifndef WIN32 -#define DEBUG_LOG_FILE "/tmp/netperf.debug" -#else -#define DEBUG_LOG_FILE "c:\\temp\\netperf.debug" -#endif /* WIN32 */ -#endif /* DEBUG_LOG_FILE */ - - /* some global variables */ - -FILE *afp; -char listen_port[10]; -extern char *optarg; -extern int optind, opterr; - -#ifndef WIN32 -#define SERVER_ARGS "dL:n:p:v:V46" -#else -#define SERVER_ARGS "dL:n:p:v:V46I:i:" -#endif - -/* perhaps one day we will use this as part of only opening a debug - log file if debug is set, of course we have to be wary of the base - use of "where" and so probably always need "where" pointing - "somewhere" or other. */ -void -open_debug_file() -{ -#ifndef WIN32 -#ifndef PATH_MAX -#define PATH_MAX MAX_PATH -#endif - char FileName[PATH_MAX]; /* for opening the debug log file */ - strcpy(FileName, DEBUG_LOG_FILE); - - if (where != NULL) fflush(where); - - snprintf(&FileName[strlen(FileName)], sizeof(FileName) - strlen(FileName), "_%d", getpid()); - if ((where = fopen(FileName, "w")) == NULL) { - perror("netserver: debug file"); - exit(1); - } - - chmod(FileName,0644); -#endif - -} - /* This routine implements the "main event loop" of the netperf */ - /* server code. Code above it will have set-up the control connection */ - /* so it can just merrily go about its business, which is to */ - /* "schedule" performance tests on the server. */ - -void -process_requests() -{ - - float temp_rate; - - if (debug) open_debug_file(); - - - while (1) { - recv_request(); - - switch (netperf_request.content.request_type) { - - case DEBUG_ON: - netperf_response.content.response_type = DEBUG_OK; - /* dump_request already present in recv_request; redundant? */ - if (!debug) { - debug++; - open_debug_file(); - dump_request(); - } - send_response(); - break; - - case DEBUG_OFF: - if (debug) - debug--; - netperf_response.content.response_type = DEBUG_OK; - send_response(); - /* +SAF why??? */ - if (!debug) - { - fclose(where); -#if !defined(WIN32) && !defined(MPE) && !defined(__VMS) - /* For Unix: reopen the debug write file descriptor to "/dev/null" */ - /* and redirect stdout to it. */ - fflush (stdout); - where = fopen ("/dev/null", "w"); - if (where == NULL) - { - perror ("netserver: reopening debug fp for writing: /dev/null"); - exit (1); - } - if (close (STDOUT_FILENO) == -1) - { - perror ("netserver: closing stdout file descriptor"); - exit (1); - } - if (dup (fileno (where)) == -1) - { - perror ("netserver: duplicate /dev/null write file descr. to stdout"); - exit (1); - } -#endif /* !WIN32 !MPE !__VMS */ - } - break; - - case CPU_CALIBRATE: - netperf_response.content.response_type = CPU_CALIBRATE; - temp_rate = calibrate_local_cpu(0.0); - bcopy((char *)&temp_rate, - (char *)netperf_response.content.test_specific_data, - sizeof(temp_rate)); - bcopy((char *)&lib_num_loc_cpus, - (char *)netperf_response.content.test_specific_data + sizeof(temp_rate), - sizeof(lib_num_loc_cpus)); - if (debug) { - fprintf(where,"netserver: sending CPU information:"); - fprintf(where,"rate is %g num cpu %d\n",temp_rate,lib_num_loc_cpus); - fflush(where); - } - - /* we need the cpu_start, cpu_stop in the looper case to kill the */ - /* child proceses raj 7/95 */ - -#ifdef USE_LOOPER - cpu_start(1); - cpu_stop(1,&temp_rate); -#endif /* USE_LOOPER */ - - send_response(); - break; - - case DO_TCP_STREAM: - recv_tcp_stream(); - break; - - case DO_TCP_MAERTS: - recv_tcp_maerts(); - break; - - case DO_TCP_RR: - recv_tcp_rr(); - break; - - case DO_TCP_CRR: - recv_tcp_conn_rr(); - break; - - case DO_TCP_CC: - recv_tcp_cc(); - break; - -#ifdef DO_1644 - case DO_TCP_TRR: - recv_tcp_tran_rr(); - break; -#endif /* DO_1644 */ - -#ifdef DO_NBRR - case DO_TCP_NBRR: - recv_tcp_nbrr(); - break; -#endif /* DO_NBRR */ - - case DO_UDP_STREAM: - recv_udp_stream(); - break; - - case DO_UDP_RR: - recv_udp_rr(); - break; - -#ifdef WANT_DLPI - - case DO_DLPI_CO_RR: - recv_dlpi_co_rr(); - break; - - case DO_DLPI_CL_RR: - recv_dlpi_cl_rr(); - break; - - case DO_DLPI_CO_STREAM: - recv_dlpi_co_stream(); - break; - - case DO_DLPI_CL_STREAM: - recv_dlpi_cl_stream(); - break; - -#endif /* WANT_DLPI */ - -#ifdef WANT_UNIX - - case DO_STREAM_STREAM: - recv_stream_stream(); - break; - - case DO_STREAM_RR: - recv_stream_rr(); - break; - - case DO_DG_STREAM: - recv_dg_stream(); - break; - - case DO_DG_RR: - recv_dg_rr(); - break; - -#endif /* WANT_UNIX */ - -#ifdef WANT_XTI - case DO_XTI_TCP_STREAM: - recv_xti_tcp_stream(); - break; - - case DO_XTI_TCP_RR: - recv_xti_tcp_rr(); - break; - - case DO_XTI_UDP_STREAM: - recv_xti_udp_stream(); - break; - - case DO_XTI_UDP_RR: - recv_xti_udp_rr(); - break; - -#endif /* WANT_XTI */ - -#ifdef WANT_SCTP - case DO_SCTP_STREAM: - recv_sctp_stream(); - break; - - case DO_SCTP_STREAM_MANY: - recv_sctp_stream_1toMany(); - break; - - case DO_SCTP_RR: - recv_sctp_rr(); - break; - - case DO_SCTP_RR_MANY: - recv_sctp_rr_1toMany(); - break; -#endif - -#ifdef WANT_SDP - case DO_SDP_STREAM: - recv_sdp_stream(); - break; - - case DO_SDP_MAERTS: - recv_sdp_maerts(); - break; - - case DO_SDP_RR: - recv_sdp_rr(); - break; -#endif - - default: - fprintf(where,"unknown test number %d\n", - netperf_request.content.request_type); - fflush(where); - netperf_response.content.serv_errno=998; - send_response(); - break; - - } - } -} - -/* - set_up_server() - - set-up the server listen socket. we only call this routine if the - user has specified a port number on the command line or we believe we - are not a child of inetd or its platform-specific equivalent */ - -/*KC*/ - -void -set_up_server(char hostname[], char port[], int af) -{ - - struct addrinfo hints; - struct addrinfo *local_res; - struct addrinfo *local_res_temp; - - struct sockaddr_storage peeraddr; - netperf_socklen_t peeraddr_len = sizeof(peeraddr); - - SOCKET server_control; - int on=1; - int count; - int error; - int not_listening; - -#if !defined(WIN32) && !defined(MPE) && !defined(__VMS) - FILE *rd_null_fp; /* Used to redirect from "/dev/null". */ - FILE *wr_null_fp; /* Used to redirect to "/dev/null". */ -#endif /* !WIN32 !MPE !__VMS */ - - if (debug) { - fprintf(stderr, - "set_up_server called with host '%s' port '%s' remfam %d\n", - hostname, - port, - af); - fflush(stderr); - } - - memset(&hints,0,sizeof(hints)); - hints.ai_family = af; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_flags = AI_PASSIVE; - - count = 0; - do { - error = getaddrinfo((char *)hostname, - (char *)port, - &hints, - &local_res); - count += 1; - if (error == EAI_AGAIN) { - if (debug) { - fprintf(stderr,"Sleeping on getaddrinfo EAI_AGAIN\n"); - fflush(stderr); - } - sleep(1); - } - } while ((error == EAI_AGAIN) && (count <= 5)); - - if (error) { - fprintf(stderr, - "set_up_server: could not resolve remote '%s' port '%s' af %d", - hostname, - port, - af); - fprintf(stderr,"\n\tgetaddrinfo returned %d %s\n", - error, - gai_strerror(error)); - exit(-1); - } - - if (debug) { - dump_addrinfo(stderr, local_res, hostname, port, af); - } - - not_listening = 1; - local_res_temp = local_res; - - while((local_res_temp != NULL) && (not_listening)) { - - fprintf(stderr, - "Starting netserver at port %s\n", - port); - - server_control = socket(local_res_temp->ai_family,SOCK_STREAM,0); - - if (server_control == INVALID_SOCKET) { - perror("set_up_server could not allocate a socket"); - exit(-1); - } - - /* happiness and joy, keep going */ - if (setsockopt(server_control, - SOL_SOCKET, - SO_REUSEADDR, - (char *)&on , - sizeof(on)) == SOCKET_ERROR) { - if (debug) { - perror("warning: set_up_server could not set SO_REUSEADDR"); - } - } - /* still happy and joyful */ - - if ((bind (server_control, - local_res_temp->ai_addr, - local_res_temp->ai_addrlen) != SOCKET_ERROR) && - (listen (server_control,5) != SOCKET_ERROR)) { - not_listening = 0; - break; - } - else { - /* we consider a bind() or listen() failure a transient and try - the next address */ - if (debug) { - perror("warning: set_up_server failed a bind or listen call\n"); - } - local_res_temp = local_res_temp->ai_next; - continue; - } - } - - if (not_listening) { - fprintf(stderr, - "set_up_server could not establish a listen endpoint for %s port %s with family %s\n", - host_name, - port, - inet_ftos(af)); - fflush(stderr); - exit(-1); - } - else { - printf("Starting netserver at hostname %s port %s and family %s\n", - hostname, - port, - inet_ftos(af)); - } - - /* - setpgrp(); - */ - -#if !defined(WIN32) && !defined(MPE) && !defined(__VMS) - /* Flush the standard I/O file descriptors before forking. */ - fflush (stdin); - fflush (stdout); - fflush (stderr); - switch (fork()) - { - case -1: - perror("netperf server error"); - exit(1); - - case 0: - /* Redirect stdin from "/dev/null". */ - rd_null_fp = fopen ("/dev/null", "r"); - if (rd_null_fp == NULL) - { - perror ("netserver: opening for reading: /dev/null"); - exit (1); - } - if (close (STDIN_FILENO) == -1) - { - perror ("netserver: closing stdin file descriptor"); - exit (1); - } - if (dup (fileno (rd_null_fp)) == -1) - { - perror ("netserver: duplicate /dev/null read file descr. to stdin"); - exit (1); - } - - /* Redirect stdout to the debug write file descriptor. */ - if (close (STDOUT_FILENO) == -1) - { - perror ("netserver: closing stdout file descriptor"); - exit (1); - } - if (dup (fileno (where)) == -1) - { - perror ("netserver: duplicate the debug write file descr. to stdout"); - exit (1); - } - - /* Redirect stderr to "/dev/null". */ - wr_null_fp = fopen ("/dev/null", "w"); - if (wr_null_fp == NULL) - { - perror ("netserver: opening for writing: /dev/null"); - exit (1); - } - if (close (STDERR_FILENO) == -1) - { - perror ("netserver: closing stderr file descriptor"); - exit (1); - } - if (dup (fileno (wr_null_fp)) == -1) - { - perror ("netserver: dupicate /dev/null write file descr. to stderr"); - exit (1); - } - -#ifndef NO_SETSID - setsid(); -#else - setpgrp(); -#endif /* NO_SETSID */ - - /* some OS's have SIGCLD defined as SIGCHLD */ -#ifndef SIGCLD -#define SIGCLD SIGCHLD -#endif /* SIGCLD */ - - signal(SIGCLD, SIG_IGN); - -#endif /* !WIN32 !MPE !__VMS */ - - for (;;) - { - if ((server_sock=accept(server_control, - (struct sockaddr *)&peeraddr, - &peeraddr_len)) == INVALID_SOCKET) - { - printf("server_control: accept failed errno %d\n",errno); - exit(1); - } -#if defined(MPE) || defined(__VMS) - /* - * Since we cannot fork this process , we cant fire any threads - * as they all share the same global data . So we better allow - * one request at at time - */ - process_requests() ; -#elif WIN32 - { - BOOL b; - char cmdline[80]; - PROCESS_INFORMATION pi; - STARTUPINFO si; - int i; - - memset(&si, 0 , sizeof(STARTUPINFO)); - si.cb = sizeof(STARTUPINFO); - - /* Pass the server_sock as stdin for the new process. */ - /* Hopefully this will continue to be created with the OBJ_INHERIT attribute. */ - si.hStdInput = (HANDLE)server_sock; - si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); - si.hStdError = GetStdHandle(STD_ERROR_HANDLE); - si.dwFlags = STARTF_USESTDHANDLES; - - /* Build cmdline for child process */ - strcpy(cmdline, program); - if (verbosity > 1) { - snprintf(&cmdline[strlen(cmdline)], sizeof(cmdline) - strlen(cmdline), " -v %d", verbosity); - } - for (i=0; i < debug; i++) { - snprintf(&cmdline[strlen(cmdline)], sizeof(cmdline) - strlen(cmdline), " -d"); - } - snprintf(&cmdline[strlen(cmdline)], sizeof(cmdline) - strlen(cmdline), " -I %x", (int)(UINT_PTR)server_sock); - snprintf(&cmdline[strlen(cmdline)], sizeof(cmdline) - strlen(cmdline), " -i %x", (int)(UINT_PTR)server_control); - snprintf(&cmdline[strlen(cmdline)], sizeof(cmdline) - strlen(cmdline), " -i %x", (int)(UINT_PTR)where); - - b = CreateProcess(NULL, /* Application Name */ - cmdline, - NULL, /* Process security attributes */ - NULL, /* Thread security attributes */ - TRUE, /* Inherit handles */ - 0, /* Creation flags PROCESS_QUERY_INFORMATION, */ - NULL, /* Enviornment */ - NULL, /* Current directory */ - &si, /* StartupInfo */ - &pi); - if (!b) - { - perror("CreateProcessfailure: "); - exit(1); - } - - /* We don't need the thread or process handles any more; let them */ - /* go away on their own timeframe. */ - - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); - - /* And close the server_sock since the child will own it. */ - - close(server_sock); - } -#else - signal(SIGCLD, SIG_IGN); - - switch (fork()) - { - case -1: - /* something went wrong */ - exit(1); - case 0: - /* we are the child process */ - close(server_control); - process_requests(); - exit(0); - break; - default: - /* we are the parent process */ - close(server_sock); - /* we should try to "reap" some of our children. on some */ - /* systems they are being left as defunct processes. we */ - /* will call waitpid, looking for any child process, */ - /* with the WNOHANG feature. when waitpid return a zero, */ - /* we have reaped all the children there are to reap at */ - /* the moment, so it is time to move on. raj 12/94 */ -#ifndef DONT_WAIT -#ifdef NO_SETSID - /* Only call "waitpid()" if "setsid()" is not used. */ - while(waitpid(-1, NULL, WNOHANG) > 0) { } -#endif /* NO_SETSID */ -#endif /* DONT_WAIT */ - break; - } -#endif /* !WIN32 !MPE !__VMS */ - } /*for*/ -#if !defined(WIN32) && !defined(MPE) && !defined(__VMS) - break; /*case 0*/ - - default: - exit (0); - - } -#endif /* !WIN32 !MPE !__VMS */ -} - -#ifdef WIN32 - - /* With Win2003, WinNT's POSIX subsystem is gone and hence so is */ - /* fork. */ - - /* But hopefully the kernel support will continue to exist for some */ - /* time. */ - - /* We are not counting on the child address space copy_on_write */ - /* support, since it isn't exposed except through the NT native APIs */ - /* (which is not public). */ - - /* We will try to use the InheritHandles flag in CreateProcess. It */ - /* is in the public API, though it is documented as "must be FALSE". */ - - /* So where we would have forked, we will now create a new process. */ - /* I have added a set of command line switches to specify a list of */ - /* handles that the child should close since they shouldn't have */ - /* been inherited ("-i#"), and a single switch to specify the handle */ - /* for the server_sock ("I#"). */ - - /* A better alternative would be to re-write NetPerf to be */ - /* multi-threaded; i.e., move all of the various NetPerf global */ - /* variables in to thread specific structures. But this is a bigger */ - /* effort than I want to tackle at this time. (And I doubt that the */ - /* HP-UX author sees value in this effort). */ - -#endif - -int _cdecl -main(int argc, char *argv[]) -{ - - int c; - int not_inetd = 0; -#ifdef WIN32 - BOOL child = FALSE; -#endif - char arg1[BUFSIZ], arg2[BUFSIZ]; -#ifndef PATH_MAX -#define PATH_MAX MAX_PATH -#endif - char FileName[PATH_MAX]; /* for opening the debug log file */ - - struct sockaddr name; - netperf_socklen_t namelen = sizeof(name); - - -#ifdef WIN32 - WSADATA wsa_data ; - - /* Initialize the winsock lib ( version 2.2 ) */ - if ( WSAStartup(MAKEWORD(2,2), &wsa_data) == SOCKET_ERROR ){ - printf("WSAStartup() failed : %d\n", GetLastError()) ; - return 1 ; - } -#endif /* WIN32 */ - - /* Save away the program name */ - program = (char *)malloc(strlen(argv[0]) + 1); - if (program == NULL) { - printf("malloc(%zu) failed!\n", strlen(argv[0]) + 1); - return 1 ; - } - strcpy(program, argv[0]); - - netlib_init(); - - /* Scan the command line to see if we are supposed to set-up our own */ - /* listen socket instead of relying on inetd. */ - - /* first set a copy of initial values */ - strncpy(local_host_name,"0.0.0.0",sizeof(local_host_name)); - local_address_family = AF_UNSPEC; - strncpy(listen_port,TEST_PORT,sizeof(listen_port)); - - while ((c = getopt(argc, argv, SERVER_ARGS)) != EOF) { - switch (c) { - case '?': - case 'h': - print_netserver_usage(); - exit(1); - case 'd': - /* we want to set the debug file name sometime */ - debug++; - break; - case 'L': - not_inetd = 1; - break_args_explicit(optarg,arg1,arg2); - if (arg1[0]) { - strncpy(local_host_name,arg1,sizeof(local_host_name)); - } - if (arg2[0]) { - local_address_family = parse_address_family(arg2); - /* if only the address family was set, we may need to set the - local_host_name accordingly. since our defaults are IPv4 - this should only be necessary if we have IPv6 support raj - 2005-02-07 */ -#if defined (AF_INET6) - if (!arg1[0]) { - strncpy(local_host_name,"::0",sizeof(local_host_name)); - } -#endif - } - break; - case 'n': - shell_num_cpus = atoi(optarg); - if (shell_num_cpus > MAXCPUS) { - fprintf(stderr, - "netserver: This version can only support %d CPUs. Please", - MAXCPUS); - fprintf(stderr, - " increase MAXCPUS in netlib.h and recompile.\n"); - fflush(stderr); - exit(1); - } - break; - case 'p': - /* we want to open a listen socket at a */ - /* specified port number */ - strncpy(listen_port,optarg,sizeof(listen_port)); - not_inetd = 1; - break; - case '4': - local_address_family = AF_INET; - break; - case '6': -#if defined(AF_INET6) - local_address_family = AF_INET6; - strncpy(local_host_name,"::0",sizeof(local_host_name)); -#else - local_address_family = AF_UNSPEC; -#endif - break; - case 'v': - /* say how much to say */ - verbosity = atoi(optarg); - break; - case 'V': - printf("Netperf version %s\n",NETPERF_VERSION); - exit(0); - break; -#ifdef WIN32 -/*+*+SAF */ - case 'I': - child = TRUE; - /* This is the handle we expect to inherit. */ - /*+*+SAF server_sock = (HANDLE)atoi(optarg); */ - break; - case 'i': - /* This is a handle we should NOT inherit. */ - /*+*+SAF CloseHandle((HANDLE)atoi(optarg)); */ - break; -#endif - - } - } - - /* +*+SAF I need a better way to find inherited handles I should close! */ - /* +*+SAF Use DuplicateHandle to force inheritable attribute (or reset it)? */ - -/* unlink(DEBUG_LOG_FILE); */ - - strcpy(FileName, DEBUG_LOG_FILE); - -#ifndef WIN32 - snprintf(&FileName[strlen(FileName)], sizeof(FileName) - strlen(FileName), "_%d", getpid()); - if ((where = fopen(FileName, "w")) == NULL) { - perror("netserver: debug file"); - exit(1); - } -#else - { - - if (child) { - snprintf(&FileName[strlen(FileName)], sizeof(FileName) - strlen(FileName), "_%x", getpid()); - } - - /* Hopefully, by closing stdout & stderr, the subsequent - fopen calls will get mapped to the correct std handles. */ - fclose(stdout); - - if ((where = fopen(FileName, "w")) == NULL) { - perror("netserver: fopen of debug file as new stdout failed!"); - exit(1); - } - - fclose(stderr); - - if ((where = fopen(FileName, "w")) == NULL) { - fprintf(stdout, "fopen of debug file as new stderr failed!\n"); - exit(1); - } - } -#endif - -#ifndef WIN32 - chmod(DEBUG_LOG_FILE,0644); -#endif - -#if WIN32 - if (child) { - server_sock = (SOCKET)GetStdHandle(STD_INPUT_HANDLE); - } -#endif - - /* if we are not a child of an inetd or the like, then we should - open a socket and hang listens off of it. otherwise, we should go - straight into processing requests. the do_listen() routine will sit - in an infinite loop accepting connections and forking child - processes. the child processes will call process_requests */ - - /* If fd 0 is not a socket then assume we're not being called */ - /* from inetd and start server socket on the default port. */ - /* this enhancement comes from vwelch@ncsa.uiuc.edu (Von Welch) */ - if (not_inetd) { - /* the user specified a port number on the command line */ - set_up_server(local_host_name,listen_port,local_address_family); - } -#ifdef WIN32 - /* OK, with Win2003 WinNT's POSIX subsystem is gone, and hence so is */ - /* fork. But hopefully the kernel support will continue to exist */ - /* for some time. We are not counting on the address space */ - /* copy_on_write support, since it isn't exposed except through the */ - /* NT native APIs (which are not public). We will try to use the */ - /* InheritHandles flag in CreateProcess though since this is public */ - /* and is used for more than just POSIX so hopefully it won't go */ - /* away. */ - else if (TRUE) { - if (child) { - process_requests(); - } else { - strncpy(listen_port,TEST_PORT,sizeof(listen_port)); - set_up_server(local_host_name,listen_port,local_address_family); - } - } -#endif -#if !defined(__VMS) - else if (getsockname(0, &name, &namelen) == SOCKET_ERROR) { - /* we may not be a child of inetd */ - if (errno == ENOTSOCK) { - strncpy(listen_port,TEST_PORT,sizeof(listen_port)); - set_up_server(local_host_name,listen_port,local_address_family); - } - } -#endif /* !defined(__VMS) */ - else { - /* we are probably a child of inetd, or are being invoked via the - VMS auxilliarly server mechanism */ -#if !defined(__VMS) - server_sock = 0; -#else - if ( (server_sock = socket(TCPIP$C_AUXS, SOCK_STREAM, 0)) == INVALID_SOCKET ) - { - perror("Failed to grab aux server socket" ); - exit(1); - } - -#endif /* !defined(__VMS) */ - process_requests(); - } -#ifdef WIN32 - /* Cleanup the winsock lib */ - WSACleanup(); -#endif - - return(0); -} |