aboutsummaryrefslogtreecommitdiff
path: root/netserver.c
diff options
context:
space:
mode:
Diffstat (limited to 'netserver.c')
-rw-r--r--netserver.c1022
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);
-}