Home | History | Annotate | Download | only in netperf
      1 #ifndef lint
      2 char	nettest_id[]="\
      3 @(#)nettest_bsd.c (c) Copyright 1993-2004 Hewlett-Packard Co. Version 2.4.3";
      4 #endif /* lint */
      5 
      6 
      7 /****************************************************************/
      8 /*								*/
      9 /*	nettest_bsd.c						*/
     10 /*								*/
     11 /*      the BSD sockets parsing routine...                      */
     12 /*       ...with the addition of Windows NT, this is now also   */
     13 /*          a Winsock test... sigh :)                           */
     14 /*                                                              */
     15 /*      scan_sockets_args()                                     */
     16 /*                                                              */
     17 /*	the actual test routines...				*/
     18 /*								*/
     19 /*	send_tcp_stream()	perform a tcp stream test	*/
     20 /*	recv_tcp_stream()					*/
     21 /*      send_tcp_maerts()       perform a tcp stream test       */
     22 /*      recv_tcp_maerts()       in the other direction          */
     23 /*	send_tcp_rr()		perform a tcp request/response	*/
     24 /*	recv_tcp_rr()						*/
     25 /*      send_tcp_conn_rr()      an RR test including connect    */
     26 /*      recv_tcp_conn_rr()                                      */
     27 /*      send_tcp_cc()           a connect/disconnect test with  */
     28 /*      recv_tcp_cc()           no RR                           */
     29 /*	send_udp_stream()	perform a udp stream test	*/
     30 /*	recv_udp_stream()					*/
     31 /*	send_udp_rr()		perform a udp request/response	*/
     32 /*	recv_udp_rr()						*/
     33 /*	loc_cpu_rate()		determine the local cpu maxrate */
     34 /*	rem_cpu_rate()		find the remote cpu maxrate	*/
     35 /*								*/
     36 /****************************************************************/
     37 
     38 #ifdef HAVE_CONFIG_H
     39 #include <config.h>
     40 #endif
     41 
     42 #include <stdio.h>
     43 #if HAVE_SYS_TYPES_H
     44 # include <sys/types.h>
     45 #endif
     46 #if HAVE_SYS_STAT_H
     47 # include <sys/stat.h>
     48 #endif
     49 #if STDC_HEADERS
     50 # include <stdlib.h>
     51 # include <stddef.h>
     52 #else
     53 # if HAVE_STDLIB_H
     54 #  include <stdlib.h>
     55 # endif
     56 #endif
     57 #if HAVE_STRING_H
     58 # if !STDC_HEADERS && HAVE_MEMORY_H
     59 #  include <memory.h>
     60 # endif
     61 # include <string.h>
     62 #endif
     63 #if HAVE_STRINGS_H
     64 # include <strings.h>
     65 #endif
     66 #if HAVE_INTTYPES_H
     67 # include <inttypes.h>
     68 #else
     69 # if HAVE_STDINT_H
     70 #  include <stdint.h>
     71 # endif
     72 #endif
     73 #if HAVE_UNISTD_H
     74 # include <unistd.h>
     75 #endif
     76 
     77 #include <fcntl.h>
     78 #ifndef WIN32
     79 #include <errno.h>
     80 #include <signal.h>
     81 #endif
     82 
     83 #if TIME_WITH_SYS_TIME
     84 # include <sys/time.h>
     85 # include <time.h>
     86 #else
     87 # if HAVE_SYS_TIME_H
     88 #  include <sys/time.h>
     89 # else
     90 #  include <time.h>
     91 # endif
     92 #endif
     93 
     94 #ifdef NOSTDLIBH
     95 #include <malloc.h>
     96 #endif /* NOSTDLIBH */
     97 
     98 #ifndef WIN32
     99 #if !defined(__VMS)
    100 #include <sys/ipc.h>
    101 #endif /* !defined(__VMS) */
    102 #include <sys/socket.h>
    103 #include <netinet/in.h>
    104 #include <netinet/tcp.h>
    105 #include <arpa/inet.h>
    106 #include <netdb.h>
    107 #else /* WIN32 */
    108 #include <process.h>
    109 #define netperf_socklen_t socklen_t
    110 #include <winsock2.h>
    111 
    112 /* while it is unlikely that anyone running Windows 2000 or NT 4 is
    113    going to be trying to compile this, if they are they will want to
    114    define DONT_IPV6 in the sources file */
    115 #ifndef DONT_IPV6
    116 #include <ws2tcpip.h>
    117 #endif
    118 #include <windows.h>
    119 
    120 #define sleep(x) Sleep((x)*1000)
    121 
    122 #define __func__ __FUNCTION__
    123 #endif /* WIN32 */
    124 
    125 /* We don't want to use bare constants in the shutdown() call.  In the
    126    extremely unlikely event that SHUT_WR isn't defined, we will define
    127    it to the value we used to be passing to shutdown() anyway.  raj
    128    2007-02-08 */
    129 #if !defined(SHUT_WR)
    130 #define SHUT_WR 1
    131 #endif
    132 
    133 #if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO)
    134 # include "missing/getaddrinfo.h"
    135 #endif
    136 
    137 #include "netlib.h"
    138 #include "netsh.h"
    139 #include "nettest_bsd.h"
    140 
    141 #if defined(WANT_HISTOGRAM) || defined(WANT_DEMO)
    142 #include "hist.h"
    143 #endif /* WANT_HISTOGRAM */
    144 
    145 /* make first_burst_size unconditional so we can use it easily enough
    146    when calculating transaction latency for the TCP_RR test. raj
    147    2007-06-08 */
    148 int first_burst_size=0;
    149 
    150 #if defined(HAVE_SENDFILE) && (defined(__linux) || defined(__sun__))
    151 #include <sys/sendfile.h>
    152 #endif /* HAVE_SENDFILE && (__linux || __sun__) */
    153 
    154 
    155 
    157 /* these variables are specific to the BSD sockets tests, but can
    158  * be used elsewhere if needed.  They are externed through nettest_bsd.h
    159  */
    160 
    161 int
    162   rss_size_req = -1,	/* requested remote socket send buffer size */
    163   rsr_size_req = -1,	/* requested remote socket recv buffer size */
    164   rss_size,		/* remote socket send buffer size	*/
    165   rsr_size,		/* remote socket recv buffer size	*/
    166   lss_size_req = -1,	/* requested local socket send buffer size */
    167   lsr_size_req = -1,	/* requested local socket recv buffer size */
    168   lss_size,		/* local  socket send buffer size 	*/
    169   lsr_size,		/* local  socket recv buffer size 	*/
    170   req_size = 1,		/* request size                   	*/
    171   rsp_size = 1,		/* response size			*/
    172   send_size,		/* how big are individual sends		*/
    173   recv_size;		/* how big are individual receives	*/
    174 
    175 static  int confidence_iteration;
    176 static  char  local_cpu_method;
    177 static  char  remote_cpu_method;
    178 
    179 /* these will control the width of port numbers we try to use in the */
    180 /* TCP_CRR and/or TCP_TRR tests. raj 3/95 */
    181 static int client_port_min = 5000;
    182 static int client_port_max = 65535;
    183 
    184  /* different options for the sockets				*/
    185 
    186 int
    187   loc_nodelay,		/* don't/do use NODELAY	locally		*/
    188   rem_nodelay,		/* don't/do use NODELAY remotely	*/
    189 #ifdef TCP_CORK
    190   loc_tcpcork=0,        /* don't/do use TCP_CORK locally        */
    191   rem_tcpcork=0,        /* don't/do use TCP_CORK remotely       */
    192 #endif /* TCP_CORK */
    193   loc_sndavoid,		/* avoid send copies locally		*/
    194   loc_rcvavoid,		/* avoid recv copies locally		*/
    195   rem_sndavoid,		/* avoid send copies remotely		*/
    196   rem_rcvavoid, 	/* avoid recv_copies remotely		*/
    197   local_connected = 0,  /* local socket type, connected/non-connected */
    198   remote_connected = 0; /* remote socket type, connected/non-connected */
    199 
    200 #ifdef WANT_HISTOGRAM
    201 #ifdef HAVE_GETHRTIME
    202 static hrtime_t time_one;
    203 static hrtime_t time_two;
    204 #elif HAVE_GET_HRT
    205 #include "hrt.h"
    206 static hrt_t time_one;
    207 static hrt_t time_two;
    208 #elif defined(WIN32)
    209 static LARGE_INTEGER time_one;
    210 static LARGE_INTEGER time_two;
    211 #else
    212 static struct timeval time_one;
    213 static struct timeval time_two;
    214 #endif /* HAVE_GETHRTIME */
    215 static HIST time_hist;
    216 #endif /* WANT_HISTOGRAM */
    217 
    218 #ifdef WANT_INTERVALS
    219 int interval_count;
    220 #ifndef WANT_SPIN
    221 sigset_t signal_set;
    222 #define INTERVALS_INIT() \
    223     if (interval_burst) { \
    224       /* zero means that we never pause, so we never should need the \
    225          interval timer. we used to use it for demo mode, but we deal \
    226 	 with that with a variant on watching the clock rather than \
    227 	 waiting for a timer. raj 2006-02-06 */ \
    228       start_itimer(interval_wate); \
    229     } \
    230     interval_count = interval_burst; \
    231     /* get the signal set for the call to sigsuspend */ \
    232     if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) { \
    233       fprintf(where, \
    234 	      "%s: unable to get sigmask errno %d\n", \
    235 	      __func__, \
    236 	      errno); \
    237       fflush(where); \
    238       exit(1); \
    239     }
    240 
    241 #define INTERVALS_WAIT() \
    242       /* in this case, the interval count is the count-down couter \
    243 	 to decide to sleep for a little bit */ \
    244       if ((interval_burst) && (--interval_count == 0)) { \
    245 	/* call sigsuspend and wait for the interval timer to get us \
    246 	   out */ \
    247 	if (debug > 1) { \
    248 	  fprintf(where,"about to suspend\n"); \
    249 	  fflush(where); \
    250 	} \
    251 	if (sigsuspend(&signal_set) == EFAULT) { \
    252 	  fprintf(where, \
    253 		  "%s: fault with sigsuspend.\n", \
    254                   __func__); \
    255 	  fflush(where); \
    256 	  exit(1); \
    257 	} \
    258 	interval_count = interval_burst; \
    259       }
    260 #else
    261 /* first out timestamp */
    262 #ifdef HAVE_GETHRTIME
    263 static hrtime_t intvl_one;
    264 static hrtime_t intvl_two;
    265 static hrtime_t *intvl_one_ptr = &intvl_one;
    266 static hrtime_t *intvl_two_ptr = &intvl_two;
    267 static hrtime_t *temp_intvl_ptr = &intvl_one;
    268 #elif defined(WIN32)
    269 static LARGE_INTEGER intvl_one;
    270 static LARGE_INTEGER intvl_two;
    271 static LARGE_INTEGER *intvl_one_ptr = &intvl_one;
    272 static LARGE_INTEGER *intvl_two_ptr = &intvl_two;
    273 static LARGE_INTEGER *temp_intvl_ptr = &intvl_one;
    274 #else
    275 static struct timeval intvl_one;
    276 static struct timeval intvl_two;
    277 static struct timeval *intvl_one_ptr = &intvl_one;
    278 static struct timeval *intvl_two_ptr = &intvl_two;
    279 static struct timeval *temp_intvl_ptr = &intvl_one;
    280 #endif
    281 
    282 #define INTERVALS_INIT() \
    283       if (interval_burst) { \
    284 	HIST_timestamp(intvl_one_ptr); \
    285       } \
    286       interval_count = interval_burst; \
    287 
    288 #define INTERVALS_WAIT() \
    289       /* in this case, the interval count is the count-down couter \
    290 	 to decide to sleep for a little bit */ \
    291       if ((interval_burst) && (--interval_count == 0)) { \
    292 	/* call sigsuspend and wait for the interval timer to get us \
    293 	   out */ \
    294 	if (debug > 1) { \
    295 	  fprintf(where,"about to spin suspend\n"); \
    296 	  fflush(where); \
    297 	} \
    298         HIST_timestamp(intvl_two_ptr); \
    299         while(delta_micro(intvl_one_ptr,intvl_two_ptr) < interval_usecs) { \
    300 	  HIST_timestamp(intvl_two_ptr); \
    301 	} \
    302 	temp_intvl_ptr = intvl_one_ptr; \
    303 	intvl_one_ptr = intvl_two_ptr; \
    304 	intvl_two_ptr = temp_intvl_ptr; \
    305 	interval_count = interval_burst; \
    306       }
    307 #endif
    308 #endif
    309 
    310 #ifdef WANT_DEMO
    311 #ifdef HAVE_GETHRTIME
    312 static hrtime_t demo_one;
    313 static hrtime_t demo_two;
    314 static hrtime_t *demo_one_ptr = &demo_one;
    315 static hrtime_t *demo_two_ptr = &demo_two;
    316 static hrtime_t *temp_demo_ptr = &demo_one;
    317 #elif defined(WIN32)
    318 static LARGE_INTEGER demo_one;
    319 static LARGE_INTEGER demo_two;
    320 static LARGE_INTEGER *demo_one_ptr = &demo_one;
    321 static LARGE_INTEGER *demo_two_ptr = &demo_two;
    322 static LARGE_INTEGER *temp_demo_ptr = &demo_one;
    323 #else
    324 static struct timeval demo_one;
    325 static struct timeval demo_two;
    326 static struct timeval *demo_one_ptr = &demo_one;
    327 static struct timeval *demo_two_ptr = &demo_two;
    328 static struct timeval *temp_demo_ptr = &demo_one;
    329 #endif
    330 
    331 /* for a _STREAM test, "a" should be lss_size and "b" should be
    332    rsr_size. for a _MAERTS test, "a" should be lsr_size and "b" should
    333    be rss_size. raj 2005-04-06 */
    334 #define DEMO_STREAM_SETUP(a,b) \
    335     if ((demo_mode) && (demo_units == 0)) { \
    336       /* take our default value of demo_units to be the larger of \
    337 	 twice the remote's SO_RCVBUF or twice our SO_SNDBUF */ \
    338       if (a > b) { \
    339 	demo_units = 2*a; \
    340       } \
    341       else { \
    342 	demo_units = 2*b; \
    343       } \
    344     }
    345 
    346 #define DEMO_STREAM_INTERVAL(units) \
    347       if (demo_mode) { \
    348 	double actual_interval; \
    349 	units_this_tick += units; \
    350 	if (units_this_tick >= demo_units) { \
    351 	  /* time to possibly update demo_units and maybe output an \
    352 	     interim result */ \
    353 	  HIST_timestamp(demo_two_ptr); \
    354 	  actual_interval = delta_micro(demo_one_ptr,demo_two_ptr); \
    355 	  /* we always want to fine-tune demo_units here whether we \
    356 	     emit an interim result or not.  if we are short, this \
    357 	     will lengthen demo_units.  if we are long, this will \
    358 	     shorten it */ \
    359 	  demo_units = demo_units * (demo_interval / actual_interval); \
    360 	  if (actual_interval >= demo_interval) { \
    361 	    /* time to emit an interim result */ \
    362 	    fprintf(where, \
    363 		    "Interim result: %7.2f %s/s over %.2f seconds\n", \
    364 		    calc_thruput_interval(units_this_tick, \
    365 					  actual_interval/1000000.0), \
    366 		    format_units(), \
    367 		    actual_interval/1000000.0); \
    368             fflush(where); \
    369 	    units_this_tick = 0.0; \
    370 	    /* now get a new starting timestamp.  we could be clever \
    371 	       and swap pointers - the math we do probably does not \
    372 	       take all that long, but for now this will suffice */ \
    373 	    temp_demo_ptr = demo_one_ptr; \
    374 	    demo_one_ptr = demo_two_ptr; \
    375 	    demo_two_ptr = temp_demo_ptr; \
    376 	  } \
    377 	} \
    378       }
    379 
    380 #define DEMO_RR_SETUP(a) \
    381     if ((demo_mode) && (demo_units == 0)) { \
    382       /* take whatever we are given */ \
    383 	demo_units = a; \
    384     }
    385 
    386 #define DEMO_RR_INTERVAL(units) \
    387       if (demo_mode) { \
    388 	double actual_interval; \
    389 	units_this_tick += units; \
    390 	if (units_this_tick >= demo_units) { \
    391 	  /* time to possibly update demo_units and maybe output an \
    392 	     interim result */ \
    393 	  HIST_timestamp(demo_two_ptr); \
    394 	  actual_interval = delta_micro(demo_one_ptr,demo_two_ptr); \
    395 	  /* we always want to fine-tune demo_units here whether we \
    396 	     emit an interim result or not.  if we are short, this \
    397 	     will lengthen demo_units.  if we are long, this will \
    398 	     shorten it */ \
    399 	  demo_units = demo_units * (demo_interval / actual_interval); \
    400 	  if (actual_interval >= demo_interval) { \
    401 	    /* time to emit an interim result */ \
    402 	    fprintf(where, \
    403 		    "Interim result: %.2f %s/s over %.2f seconds\n", \
    404                     units_this_tick / (actual_interval/1000000.0), \
    405 		    "Trans", \
    406 		    actual_interval/1000000.0); \
    407 	    units_this_tick = 0.0; \
    408 	    /* now get a new starting timestamp.  we could be clever \
    409 	       and swap pointers - the math we do probably does not \
    410 	       take all that long, but for now this will suffice */ \
    411 	    temp_demo_ptr = demo_one_ptr; \
    412 	    demo_one_ptr = demo_two_ptr; \
    413 	    demo_two_ptr = temp_demo_ptr; \
    414 	  } \
    415 	} \
    416       }
    417 #endif
    418 
    419 char sockets_usage[] = "\n\
    420 Usage: netperf [global options] -- [test options] \n\
    421 \n\
    422 TCP/UDP BSD Sockets Test Options:\n\
    423     -b number         Send number requests at start of _RR tests\n\
    424     -C                Set TCP_CORK when available\n\
    425     -D [L][,R]        Set TCP_NODELAY locally and/or remotely (TCP_*)\n\
    426     -h                Display this text\n\
    427     -H name,fam       Use name (or IP) and family as target of data connection\n\
    428     -L name,fam       Use name (or IP) and family as source of data connection\n\
    429     -m bytes          Set the send size (TCP_STREAM, UDP_STREAM)\n\
    430     -M bytes          Set the recv size (TCP_STREAM, UDP_STREAM)\n\
    431     -n                Use the connected socket for UDP locally\n\
    432     -N                Use the connected socket for UDP remotely\n\
    433     -p min[,max]      Set the min/max port numbers for TCP_CRR, TCP_TRR\n\
    434     -P local[,remote] Set the local/remote port for the data socket\n\
    435     -r req,[rsp]      Set request/response sizes (TCP_RR, UDP_RR)\n\
    436     -s send[,recv]    Set local socket send/recv buffer sizes\n\
    437     -S send[,recv]    Set remote socket send/recv buffer sizes\n\
    438     -4                Use AF_INET (eg IPv4) on both ends of the data conn\n\
    439     -6                Use AF_INET6 (eg IPv6) on both ends of the data conn\n\
    440 \n\
    441 For those options taking two parms, at least one must be specified;\n\
    442 specifying one value without a comma will set both parms to that\n\
    443 value, specifying a value with a leading comma will set just the second\n\
    444 parm, a value with a trailing comma will set just the first. To set\n\
    445 each parm to unique values, specify both and separate them with a\n\
    446 comma.\n";
    447 
    448 
    449 
    451 /* these routines convert between the AF address space and the NF
    452    address space since the numeric values of AF_mumble are not the
    453    same across the platforms. raj 2005-02-08 */
    454 
    455 int
    456 nf_to_af(int nf) {
    457   switch(nf) {
    458   case NF_INET:
    459     return AF_INET;
    460     break;
    461   case NF_UNSPEC:
    462     return AF_UNSPEC;
    463     break;
    464   case NF_INET6:
    465 #if defined(AF_INET6)
    466     return AF_INET6;
    467 #else
    468     return AF_UNSPEC;
    469 #endif
    470     break;
    471   default:
    472     return AF_UNSPEC;
    473     break;
    474   }
    475 }
    476 
    477 int
    478 af_to_nf(int af) {
    479 
    480   switch(af) {
    481   case AF_INET:
    482     return NF_INET;
    483     break;
    484   case AF_UNSPEC:
    485     return NF_UNSPEC;
    486     break;
    487 #if defined(AF_INET6)
    488   case AF_INET6:
    489     return NF_INET6;
    490     break;
    491 #endif
    492   default:
    493     return NF_UNSPEC;
    494     break;
    495   }
    496 }
    497 
    498 
    499  /* This routine is intended to retrieve interesting aspects of tcp */
    501  /* for the data connection. at first, it attempts to retrieve the */
    502  /* maximum segment size. later, it might be modified to retrieve */
    503  /* other information, but it must be information that can be */
    504  /* retrieved quickly as it is called during the timing of the test. */
    505  /* for that reason, a second routine may be created that can be */
    506  /* called outside of the timing loop */
    507 static
    508 void
    509 get_tcp_info(SOCKET socket, int *mss)
    510 {
    511 
    512 #ifdef TCP_MAXSEG
    513   netperf_socklen_t sock_opt_len;
    514 
    515   sock_opt_len = sizeof(netperf_socklen_t);
    516   if (getsockopt(socket,
    517 		 getprotobyname("tcp")->p_proto,
    518 		 TCP_MAXSEG,
    519 		 (char *)mss,
    520 		 &sock_opt_len) == SOCKET_ERROR) {
    521     fprintf(where,
    522 	    "netperf: get_tcp_info: getsockopt TCP_MAXSEG: errno %d\n",
    523 	    errno);
    524     fflush(where);
    525     *mss = -1;
    526   }
    527 #else
    528   *mss = -1;
    529 #endif /* TCP_MAXSEG */
    530 }
    531 
    532 
    534 /* return a pointer to a completed addrinfo chain - prefer
    535    data_address to controlhost and utilize the specified address
    536    family */
    537 
    538 struct addrinfo *
    539 complete_addrinfo(char *controlhost, char *data_address, char *port, int family, int type, int protocol, int flags)
    540 {
    541   struct addrinfo hints;
    542   struct addrinfo *res;
    543   struct addrinfo *temp_res;
    544 
    545 #define CHANGED_SOCK_TYPE  0x1
    546 #define CHANGED_PROTOCOL   0x2
    547 #define CHANGED_SCTP       0x4
    548   int    change_info = 0;
    549   static int change_warning_displayed = 0;
    550 
    551   int count = 0;
    552   int error = 0;
    553 
    554   char *hostname;
    555 
    556   /* take data-address over controlhost */
    557   if (data_address)
    558     hostname = data_address;
    559   else
    560     hostname = controlhost;
    561 
    562   if (debug) {
    563     fprintf(where,
    564 	    "complete_addrinfo using hostname %s port %s family %s type %s prot %s flags 0x%x\n",
    565 	    hostname,
    566 	    port,
    567 	    inet_ftos(family),
    568 	    inet_ttos(type),
    569 	    inet_ptos(protocol),
    570 	    flags);
    571     fflush(where);
    572   }
    573 
    574   memset(&hints, 0, sizeof(hints));
    575   hints.ai_family = family;
    576   hints.ai_socktype = type;
    577   hints.ai_protocol = protocol;
    578   hints.ai_flags = flags|AI_CANONNAME;
    579 
    580   count = 0;
    581   do {
    582     error = getaddrinfo((char *)hostname,
    583                         (char *)port,
    584                         &hints,
    585                         &res);
    586     count += 1;
    587     if (error == EAI_AGAIN) {
    588       if (debug) {
    589         fprintf(where,"Sleeping on getaddrinfo EAI_AGAIN\n");
    590         fflush(where);
    591       }
    592       sleep(1);
    593     }
    594     /* while you see this kludge first, it is actually the second, the
    595        first being the one for Solaris below. The need for this kludge
    596        came after implementing the Solaris broken getaddrinfo kludge -
    597        now we see a kludge in Linux getaddrinfo where if it is given
    598        SOCK_STREAM and IPPROTO_SCTP it barfs with a -7
    599        EAI_SOCKTYPE. so, we check if the error was EAI_SOCKTYPE and if
    600        we were asking for IPPROTO_SCTP and if so, kludge, again... raj
    601        2008-10-13 */
    602 #ifdef WANT_SCTP
    603     if (EAI_SOCKTYPE == error
    604 #ifdef EAI_BADHINTS
    605         || EAI_BADHINTS == error
    606 #endif
    607         ) {
    608       /* we ass-u-me this is the Linux getaddrinfo bug, clear the
    609 	 hints.ai_protocol field, and set some state "remembering"
    610 	 that we did this so the code for the Solaris kludge can do
    611 	 the fix-up for us.  also flip error over to EAI_AGAIN and
    612 	 make sure we don't "count" this time around the loop. */
    613       hints.ai_protocol = 0;
    614       error = EAI_AGAIN;
    615       count -= 1;
    616       change_info |= CHANGED_SCTP;
    617     }
    618 #endif
    619   } while ((error == EAI_AGAIN) && (count <= 5));
    620 
    621   if (error) {
    622     fprintf(where,
    623 	    "complete_addrinfo: could not resolve '%s' port '%s' af %d",
    624 	    hostname,
    625 	    port,
    626 	    family);
    627     fprintf(where,
    628 	    "\n\tgetaddrinfo returned %d %s\n",
    629 	    error,
    630 	    gai_strerror(error));
    631     fflush(where);
    632     exit(-1);
    633   }
    634 
    635   /* there exists at least one platform - Solaris 10 - that does not
    636      seem to completely honor the ai_protocol and/or ai_socktype one
    637      sets in the hints parm to the getaddrinfo call.  so, we need to
    638      walk the list of entries returned and if either of those do not
    639      match what we asked for, we need to go ahead and set them
    640      "correctly" this is based in part on some earlier SCTP-only code
    641      from previous revisions.  raj 2006-10-09 */
    642 
    643   temp_res = res;
    644 
    645   while (temp_res) {
    646 
    647     if ((type)  &&
    648 	(temp_res->ai_socktype != type)) {
    649       change_info |= CHANGED_SOCK_TYPE;
    650       if (debug) {
    651 	fprintf(where,
    652 		"WARNING! Changed bogus getaddrinfo socket type %d to %d\n",
    653 		temp_res->ai_socktype,
    654 		type);
    655 	fflush(where);
    656       }
    657       temp_res->ai_socktype = type;
    658     }
    659 
    660     if ((protocol) &&
    661 	(temp_res->ai_protocol != protocol)) {
    662       change_info |= CHANGED_PROTOCOL;
    663       if (debug) {
    664 	fprintf(where,
    665 		"WARNING! Changed bogus getaddrinfo protocol %d to %d\n",
    666 		temp_res->ai_protocol,
    667 		protocol);
    668 	fflush(where);
    669       }
    670       temp_res->ai_protocol = protocol;
    671     }
    672     temp_res = temp_res->ai_next;
    673   }
    674 
    675   if ((change_info & CHANGED_SOCK_TYPE) &&
    676       !(change_warning_displayed & CHANGED_SOCK_TYPE)) {
    677     change_warning_displayed |= CHANGED_SOCK_TYPE;
    678     fprintf(where,
    679 	    "WARNING! getaddrinfo returned a socket type which did not\n");
    680     fprintf(where,
    681 	    "match the requested type.  Please contact your vendor for\n");
    682     fprintf(where,
    683 	    "a fix to this bug in getaddrinfo()\n");
    684     fflush(where);
    685   }
    686 
    687   /* if we dropped the protocol hint, it would be for a protocol that
    688      getaddrinfo() wasn't supporting yet, not for the bug that it took
    689      our hint and still returned zero. raj 2006-10-16 */
    690   if ((change_info & CHANGED_PROTOCOL) &&
    691       !(change_warning_displayed & CHANGED_PROTOCOL) &&
    692       (hints.ai_protocol != 0)) {
    693     change_warning_displayed |= CHANGED_PROTOCOL;
    694     fprintf(where,
    695 	    "WARNING! getaddrinfo returned a protocol other than the\n");
    696     fprintf(where,
    697 	    "requested protocol.  Please contact your vendor for\n");
    698     fprintf(where,
    699 	    "a fix to this bug in getaddrinfo()\n");
    700     fflush(where);
    701   }
    702 
    703   if ((change_info & CHANGED_SCTP) &&
    704       !(change_warning_displayed & CHANGED_SCTP)) {
    705     change_warning_displayed |= CHANGED_SCTP;
    706     fprintf(where,
    707 	    "WARNING! getaddrinfo on this platform does not accept IPPROTO_SCTP!\n");
    708     fprintf(where,
    709 	    "Please contact your vendor for a fix to this bug in getaddrinfo().\n");
    710     fflush(where);
    711   }
    712 
    713 
    714   if (debug) {
    715     dump_addrinfo(where, res, hostname, port, family);
    716   }
    717 
    718   return(res);
    719 }
    720 
    721 void
    722 complete_addrinfos(struct addrinfo **remote,struct addrinfo **local, char remote_host[], int type, int protocol, int flags) {
    723 
    724   *remote = complete_addrinfo(remote_host,
    725 			      remote_data_address,
    726 			      remote_data_port,
    727 			      remote_data_family,
    728 			      type,
    729 			      protocol,
    730 			      flags);
    731 
    732   /* OK, if the user has not specified a local data endpoint address
    733      (test-specific -L), pick the local data endpoint address based on
    734      the remote data family info (test-specific -H or -4 or -6
    735      option).  if the user has not specified remote data addressing
    736      info (test-specific -H, -4 -6) pick something based on the local
    737      control connection address (ie the global -L option). */
    738 
    739   if (NULL == local_data_address) {
    740     local_data_address = malloc(HOSTNAMESIZE);
    741     if (NULL == remote_data_address) {
    742       if (debug) {
    743 	fprintf(where,
    744 		"local_data_address not set, using local_host_name of '%s'\n",
    745 		local_host_name);
    746 	fflush(where);
    747       }
    748       strcpy(local_data_address,local_host_name);
    749     }
    750     else {
    751       if (debug) {
    752 	fprintf(where,
    753 		"local_data_address not set, using address family info\n");
    754 	fflush(where);
    755       }
    756       /* by default, use 0.0.0.0 - assume IPv4 */
    757       strcpy(local_data_address,"0.0.0.0");
    758 #if defined(AF_INET6)
    759       if ((AF_INET6 == local_data_family) ||
    760 	  ((AF_UNSPEC == local_data_family) &&
    761 	   (AF_INET6 == remote_data_family)) ||
    762 	  ((AF_UNSPEC == local_data_family) &&
    763 	   (AF_INET6 == (*remote)->ai_family))) {
    764 	strcpy(local_data_address,"::0");
    765       }
    766 #endif
    767     }
    768   }
    769 
    770   *local = complete_addrinfo("what to put here?",
    771 			     local_data_address,
    772 			     local_data_port,
    773 			     local_data_family,
    774 			     type,
    775 			     protocol,
    776 			     flags|AI_PASSIVE);
    777 
    778 }
    779 
    780 void
    781 set_hostname_and_port(char *hostname, char *portstr, int family, int port)
    782 {
    783   strcpy(hostname,"0.0.0.0");
    784 #if defined AF_INET6
    785   if (AF_INET6 == family) {
    786     strcpy(hostname,"::0");
    787   }
    788 #endif
    789 
    790   sprintf(portstr, "%u", port);
    791 
    792 }
    793 
    794 static unsigned short
    795 get_port_number(struct addrinfo *res)
    796 {
    797  switch(res->ai_family) {
    798   case AF_INET: {
    799     struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr;
    800     return(ntohs(foo->sin_port));
    801     break;
    802   }
    803 #if defined(AF_INET6)
    804   case AF_INET6: {
    805     struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr;
    806     return(ntohs(foo->sin6_port));
    807     break;
    808   }
    809 #endif
    810   default:
    811     fprintf(where,
    812 	    "Unexpected Address Family of %u\n",res->ai_family);
    813     fflush(where);
    814     exit(-1);
    815   }
    816 }
    817 
    818 /* this routine will set the port number of the sockaddr in the
    819    addrinfo to the specified value, based on the address family */
    820 void
    821 set_port_number(struct addrinfo *res, unsigned short port)
    822 {
    823   switch(res->ai_family) {
    824   case AF_INET: {
    825     struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr;
    826     foo->sin_port = htons(port);
    827     break;
    828   }
    829 #if defined(AF_INET6)
    830   case AF_INET6: {
    831     struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr;
    832     foo->sin6_port = htons(port);
    833     break;
    834   }
    835 #endif
    836   default:
    837     fprintf(where,
    838 	    "Unexpected Address Family of %u\n",res->ai_family);
    839     fflush(where);
    840     exit(-1);
    841   }
    842 }
    843 
    844 
    845 
    847  /* This routine will create a data (listen) socket with the
    848   apropriate options set and return it to the caller. this replaces
    849   all the duplicate code in each of the test routines and should help
    850   make things a little easier to understand. since this routine can be
    851   called by either the netperf or netserver programs, all output
    852   should be directed towards "where." family is generally AF_INET and
    853   type will be either SOCK_STREAM or SOCK_DGRAM.  This routine will
    854   also be used by the "SCTP" tests, hence the slightly strange-looking
    855   SCTP stuff in the classic bsd sockets test file... vlad/raj
    856   2005-03-15 */
    857 
    858 SOCKET
    859 create_data_socket(struct addrinfo *res)
    860 {
    861 
    862   SOCKET temp_socket;
    863   int one;
    864   int    on  = 1;
    865 
    866 
    867   /*set up the data socket                        */
    868   temp_socket = socket(res->ai_family,
    869 		       res->ai_socktype,
    870 		       res->ai_protocol);
    871 
    872   if (temp_socket == INVALID_SOCKET){
    873     fprintf(where,
    874 	    "netperf: create_data_socket: socket: errno %d fam %s type %s prot %s errmsg %s\n",
    875 	    errno,
    876 	    inet_ftos(res->ai_family),
    877 	    inet_ttos(res->ai_socktype),
    878 	    inet_ptos(res->ai_protocol),
    879 	    strerror(errno));
    880     fflush(where);
    881     exit(1);
    882   }
    883 
    884   if (debug) {
    885     fprintf(where,"create_data_socket: socket %d obtained...\n",temp_socket);
    886     fflush(where);
    887   }
    888 
    889   /* Modify the local socket size. The reason we alter the send buffer
    890    size here rather than when the connection is made is to take care
    891    of decreases in buffer size. Decreasing the window size after
    892    connection establishment is a TCP no-no. Also, by setting the
    893    buffer (window) size before the connection is established, we can
    894    control the TCP MSS (segment size). The MSS is never (well, should
    895    never be) more that 1/2 the minimum receive buffer size at each
    896    half of the connection.  This is why we are altering the receive
    897    buffer size on the sending size of a unidirectional transfer. If
    898    the user has not requested that the socket buffers be altered, we
    899    will try to find-out what their values are. If we cannot touch the
    900    socket buffer in any way, we will set the values to -1 to indicate
    901    that.  */
    902 
    903   /* all the oogy nitty gritty stuff moved from here into the routine
    904      being called below, per patches from davidm to workaround the bug
    905      in Linux getsockopt().  raj 2004-06-15 */
    906   set_sock_buffer (temp_socket, SEND_BUFFER, lss_size_req, &lss_size);
    907   set_sock_buffer (temp_socket, RECV_BUFFER, lsr_size_req, &lsr_size);
    908 
    909   /* now, we may wish to enable the copy avoidance features on the */
    910   /* local system. of course, this may not be possible... */
    911 
    912 #ifdef SO_RCV_COPYAVOID
    913   if (loc_rcvavoid) {
    914     if (setsockopt(temp_socket,
    915 		   SOL_SOCKET,
    916 		   SO_RCV_COPYAVOID,
    917 		   (const char *)&loc_rcvavoid,
    918 		   sizeof(int)) == SOCKET_ERROR) {
    919       fprintf(where,
    920 	      "netperf: create_data_socket: Could not enable receive copy avoidance");
    921       fflush(where);
    922       loc_rcvavoid = 0;
    923     }
    924   }
    925 #else
    926   /* it wasn't compiled in... */
    927   loc_rcvavoid = 0;
    928 #endif /* SO_RCV_COPYAVOID */
    929 
    930 #ifdef SO_SND_COPYAVOID
    931   if (loc_sndavoid) {
    932     if (setsockopt(temp_socket,
    933 		   SOL_SOCKET,
    934 		   SO_SND_COPYAVOID,
    935 		   (const char *)&loc_sndavoid,
    936 		   sizeof(int)) == SOCKET_ERROR) {
    937       fprintf(where,
    938 	      "netperf: create_data_socket: Could not enable send copy avoidance");
    939       fflush(where);
    940       loc_sndavoid = 0;
    941     }
    942   }
    943 #else
    944   /* it was not compiled in... */
    945   loc_sndavoid = 0;
    946 #endif
    947 
    948   /* Now, we will see about setting the TCP_NODELAY flag on the local */
    949   /* socket. We will only do this for those systems that actually */
    950   /* support the option. If it fails, note the fact, but keep going. */
    951   /* If the user tries to enable TCP_NODELAY on a UDP socket, this */
    952   /* will cause an error to be displayed */
    953 
    954   /* well..... long ago and far away that would have happened, in
    955      particular because we would always use IPPROTO_TCP here.
    956      however, now we are using res->ai_protocol, which will be
    957      IPPROT_UDP, and while HP-UX, and I suspect no-one else on the
    958      planet has a UDP_mumble option that overlaps with TCP_NODELAY,
    959      sure as knuth made little green programs, linux has a UDP_CORK
    960      option that is defined as a value of 1, which is the same a
    961      TCP_NODELAY under Linux.  So, when asking for -D and
    962      "TCP_NODELAY" under Linux, we are actually setting UDP_CORK
    963      instead of getting an error like every other OS on the
    964      planet. joy and rupture. this stops a UDP_RR test cold sooo we
    965      have to make sure that res->ai_protocol actually makes sense for
    966      a _NODELAY setsockopt() or a UDP_RR test on Linux where someone
    967      mistakenly sets -D will hang.  raj 2005-04-21 */
    968 
    969 #if defined(TCP_NODELAY) || defined(SCTP_NODELAY)
    970   if ((loc_nodelay) && (res->ai_protocol != IPPROTO_UDP)) {
    971 
    972     /* strictly speaking, since the if defined above is an OR, we
    973        should probably check against TCP_NODELAY being defined here.
    974        however, the likelihood of SCTP_NODELAY being defined and
    975        TCP_NODELAY _NOT_ being defined is, probably :), epsilon.  raj
    976        2005-03-15 */
    977 
    978     int option = TCP_NODELAY;
    979 
    980     /* I suspect that WANT_SCTP would suffice here since that is the
    981        only time we would have called getaddrinfo with a hints asking
    982        for SCTP, but just in case there is an SCTP implementation out
    983        there _without_ SCTP_NODELAY... raj 2005-03-15 */
    984 
    985 #if defined(WANT_SCTP) && defined(SCTP_NODELAY)
    986     if (IPPROTO_SCTP == res->ai_protocol) {
    987       option = SCTP_NODELAY;
    988     }
    989 #endif
    990 
    991     one = 1;
    992     if(setsockopt(temp_socket,
    993 		  res->ai_protocol,
    994 		  option,
    995 		  (char *)&one,
    996 		  sizeof(one)) == SOCKET_ERROR) {
    997       fprintf(where,
    998 	      "netperf: create_data_socket: nodelay: errno %d\n",
    999 	      errno);
   1000       fflush(where);
   1001     }
   1002 
   1003     if (debug > 1) {
   1004       fprintf(where,
   1005 	      "netperf: create_data_socket: [TCP|SCTP]_NODELAY requested...\n");
   1006       fflush(where);
   1007     }
   1008   }
   1009 #else /* TCP_NODELAY */
   1010 
   1011   loc_nodelay = 0;
   1012 
   1013 #endif /* TCP_NODELAY */
   1014 
   1015 #if defined(TCP_CORK)
   1016 
   1017     if (loc_tcpcork != 0) {
   1018       /* the user wishes for us to set TCP_CORK on the socket */
   1019       int one = 1;
   1020       if (setsockopt(temp_socket,
   1021 		     getprotobyname("tcp")->p_proto,
   1022 		     TCP_CORK,
   1023 		     (char *)&one,
   1024 		     sizeof(one)) == SOCKET_ERROR) {
   1025 	perror("netperf: sendfile_tcp_stream: tcp_cork");
   1026 	exit(1);
   1027       }
   1028       if (debug) {
   1029 	fprintf(where,"sendfile_tcp_stream: tcp_cork...\n");
   1030       }
   1031     }
   1032 
   1033 #endif /* TCP_CORK */
   1034 
   1035   /* since some of the UDP tests do not do anything to cause an
   1036      implicit bind() call, we need to be rather explicit about our
   1037      bind() call here. even if the address and/or the port are zero
   1038      (INADDR_ANY etc). raj 2004-07-20 */
   1039 
   1040   if (setsockopt(temp_socket,
   1041 		 SOL_SOCKET,
   1042 		 SO_REUSEADDR,
   1043 		 (const char *)&on,
   1044 		 sizeof(on)) < 0) {
   1045     fprintf(where,
   1046 	    "netperf: create_data_socket: SO_REUSEADDR failed %d\n",
   1047 	    errno);
   1048     fflush(where);
   1049   }
   1050 
   1051   if (bind(temp_socket,
   1052 	   res->ai_addr,
   1053 	   res->ai_addrlen) < 0) {
   1054     if (debug) {
   1055       fprintf(where,
   1056 	      "netperf: create_data_socket: data socket bind failed errno %d\n",
   1057 	      errno);
   1058       fprintf(where," port: %d\n",get_port_number(res));
   1059       fflush(where);
   1060     }
   1061   }
   1062 
   1063 
   1064   return(temp_socket);
   1065 
   1066 }
   1067 
   1068 #ifdef KLUDGE_SOCKET_OPTIONS
   1069 
   1070 
   1071  /* This routine is for those BROKEN systems which do not correctly */
   1073  /* pass socket attributes through calls such as accept(). It should */
   1074  /* only be called for those broken systems. I *really* don't want to */
   1075  /* have this, but even broken systems must be measured. raj 11/95 */
   1076 void
   1077 kludge_socket_options(int temp_socket)
   1078 {
   1079 
   1080   set_sock_buffer(temp_socket, SEND_BUFFER, lss_size_req, &lss_size);
   1081   set_sock_buffer(temp_socket, RECV_BUFFER, lsr_size_req, &lsr_size);
   1082 
   1083   /* now, we may wish to enable the copy avoidance features on the */
   1084   /* local system. of course, this may not be possible... */
   1085   /* those calls were only valid for HP-UX, and I know that HP-UX is */
   1086   /* written correctly, and so we do not need to include those calls */
   1087   /* in this kludgy routine. raj 11/95 */
   1088 
   1089 
   1090   /* Now, we will see about setting the TCP_NODELAY flag on the local */
   1091   /* socket. We will only do this for those systems that actually */
   1092   /* support the option. If it fails, note the fact, but keep going. */
   1093   /* If the user tries to enable TCP_NODELAY on a UDP socket, this */
   1094   /* will cause an error to be displayed */
   1095 
   1096 #ifdef TCP_NODELAY
   1097   if (loc_nodelay) {
   1098     one = 1;
   1099     if(setsockopt(temp_socket,
   1100 		  getprotobyname("tcp")->p_proto,
   1101 		  TCP_NODELAY,
   1102 		  (char *)&one,
   1103 		  sizeof(one)) == SOCKET_ERROR) {
   1104       fprintf(where,"netperf: kludge_socket_options: nodelay: errno %d\n",
   1105 	      errno);
   1106       fflush(where);
   1107     }
   1108 
   1109     if (debug > 1) {
   1110       fprintf(where,
   1111 	      "netperf: kludge_socket_options: TCP_NODELAY requested...\n");
   1112       fflush(where);
   1113     }
   1114   }
   1115 #else /* TCP_NODELAY */
   1116 
   1117   loc_nodelay = 0;
   1118 
   1119 #endif /* TCP_NODELAY */
   1120 
   1121   }
   1122 
   1123 #endif /* KLUDGE_SOCKET_OPTIONS */
   1124 
   1125 
   1127 static void *
   1128 get_address_address(struct addrinfo *info)
   1129 {
   1130   struct sockaddr_in *sin;
   1131 #if defined(AF_INET6)
   1132   struct sockaddr_in6 *sin6;
   1133 #endif
   1134 
   1135   switch(info->ai_family) {
   1136   case AF_INET:
   1137     sin = (struct sockaddr_in *)info->ai_addr;
   1138     return(&(sin->sin_addr));
   1139     break;
   1140 #if defined(AF_INET6)
   1141   case AF_INET6:
   1142     sin6 = (struct sockaddr_in6 *)info->ai_addr;
   1143     return(&(sin6->sin6_addr));
   1144     break;
   1145 #endif
   1146   default:
   1147     fprintf(stderr,"we never expected to get here in get_address_address\n");
   1148     fflush(stderr);
   1149     exit(-1);
   1150   }
   1151 }
   1152 
   1153 #if defined(WIN32)
   1154 /* +*+ Why isn't this in the winsock headers yet? */
   1155 const char *
   1156 inet_ntop(int af, const void *src, char *dst, size_t size);
   1157 #endif
   1158 
   1159 /* This routine is a generic test header printer for the topmost header */
   1160 void
   1161 print_top_test_header(char test_name[], struct addrinfo *source, struct addrinfo *destination)
   1162 {
   1163 
   1164 #if defined(AF_INET6)
   1165   char address_buf[INET6_ADDRSTRLEN];
   1166 #else
   1167   char address_buf[16]; /* magic constant */
   1168 #endif
   1169 
   1170   /* we want to have some additional, interesting information in */
   1171   /* the headers. we know some of it here, but not all, so we will */
   1172   /* only print the test title here and will print the results */
   1173   /* titles after the test is finished */
   1174   fprintf(where, "%s", test_name);
   1175   address_buf[0] = '\0';
   1176   inet_ntop(source->ai_family,get_address_address(source),address_buf,sizeof(address_buf));
   1177   fprintf(where,
   1178 	  " from %s (%s) port %u %s",
   1179 	  source->ai_canonname,
   1180 	  address_buf,
   1181 	  get_port_number(source),
   1182 	  inet_ftos(source->ai_family));
   1183   address_buf[0] = '\0';
   1184   inet_ntop(destination->ai_family,get_address_address(destination),address_buf,sizeof(address_buf));
   1185   fprintf(where,
   1186 	  " to %s (%s) port %u %s",
   1187 	  destination->ai_canonname,
   1188 	  address_buf,
   1189 	  get_port_number(destination),
   1190 	  inet_ftos(destination->ai_family));
   1191 
   1192   if (iteration_max > 1) {
   1193     fprintf(where,
   1194 	    " : +/-%3.1f%% @ %2d%% conf. %s",
   1195 	    interval/0.02,
   1196 	    confidence_level,
   1197 	    result_confidence_only ? " on result only" : "");
   1198   }
   1199   if ((loc_nodelay > 0) || (rem_nodelay > 0)) {
   1200     fprintf(where," : nodelay");
   1201   }
   1202   if ((loc_sndavoid > 0) ||
   1203       (loc_rcvavoid > 0) ||
   1204       (rem_sndavoid > 0) ||
   1205       (rem_rcvavoid > 0)) {
   1206     fprintf(where," : copy avoidance");
   1207   }
   1208 
   1209   if (no_control) {
   1210     fprintf(where," : no control");
   1211   }
   1212 
   1213 #ifdef WANT_HISTOGRAM
   1214   fprintf(where," : histogram");
   1215 #endif /* WANT_HISTOGRAM */
   1216 
   1217 #ifdef WANT_INTERVALS
   1218 #ifndef WANT_SPIN
   1219   fprintf(where," : interval");
   1220 #else
   1221   fprintf(where," : spin interval");
   1222 #endif
   1223 #endif /* WANT_INTERVALS */
   1224 
   1225 #ifdef DIRTY
   1226   fprintf(where," : dirty data");
   1227 #endif /* DIRTY */
   1228 #ifdef WANT_DEMO
   1229   fprintf(where," : demo");
   1230 #endif
   1231 #ifdef WANT_FIRST_BURST
   1232   /* a little hokey perhaps, but we really only want this to be
   1233      emitted for tests where it actually is used, which means a
   1234      "REQUEST/RESPONSE" test. raj 2005-11-10 */
   1235   if (strstr(test_name,"REQUEST/RESPONSE")) {
   1236     fprintf(where," : first burst %d",first_burst_size);
   1237   }
   1238 #endif
   1239   if (cpu_binding_requested) {
   1240     fprintf(where," : cpu bind");
   1241   }
   1242   fprintf(where,"\n");
   1243 
   1244 }
   1245 
   1246 
   1247 /* This routine implements the TCP unidirectional data transfer test */
   1248 /* (a.k.a. stream) for the sockets interface. It receives its */
   1249 /* parameters via global variables from the shell and writes its */
   1250 /* output to the standard output. */
   1251 
   1252 
   1253 void
   1254 send_tcp_stream(char remote_host[])
   1255 {
   1256 
   1257   char *tput_title = "\
   1258 Recv   Send    Send                          \n\
   1259 Socket Socket  Message  Elapsed              \n\
   1260 Size   Size    Size     Time     Throughput  \n\
   1261 bytes  bytes   bytes    secs.    %s/sec  \n\n";
   1262 
   1263   char *tput_fmt_0 =
   1264     "%7.2f %s\n";
   1265 
   1266   char *tput_fmt_1 =
   1267     "%6d %6d %6d    %-6.2f   %7.2f   %s\n";
   1268 
   1269   char *cpu_title = "\
   1270 Recv   Send    Send                          Utilization       Service Demand\n\
   1271 Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
   1272 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
   1273 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
   1274 
   1275   char *cpu_fmt_0 =
   1276     "%6.3f %c %s\n";
   1277 
   1278   char *cpu_fmt_1 =
   1279     "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f %s\n";
   1280 
   1281   char *ksink_fmt = "\n\
   1282 Alignment      Offset         %-8.8s %-8.8s    Sends   %-8.8s Recvs\n\
   1283 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
   1284 Send   Recv    Send   Recv             Send (avg)          Recv (avg)\n\
   1285 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
   1286 
   1287   char *ksink_fmt2 = "\n\
   1288 Maximum\n\
   1289 Segment\n\
   1290 Size (bytes)\n\
   1291 %6d\n";
   1292 
   1293 
   1294   float			elapsed_time;
   1295 
   1296   /* what we want is to have a buffer space that is at least one */
   1297   /* send-size greater than our send window. this will insure that we */
   1298   /* are never trying to re-use a buffer that may still be in the hands */
   1299   /* of the transport. This buffer will be malloc'd after we have found */
   1300   /* the size of the local senc socket buffer. We will want to deal */
   1301   /* with alignment and offset concerns as well. */
   1302 
   1303   struct ring_elt *send_ring;
   1304 
   1305   int len;
   1306   unsigned int nummessages = 0;
   1307   SOCKET send_socket;
   1308   int bytes_remaining;
   1309   int tcp_mss = -1;  /* possibly uninitialized on printf far below */
   1310 
   1311   /* with links like fddi, one can send > 32 bits worth of bytes */
   1312   /* during a test... ;-) at some point, this should probably become a */
   1313   /* 64bit integral type, but those are not entirely common yet */
   1314 
   1315   unsigned long long local_bytes_sent = 0;
   1316   double	bytes_sent = 0.0;
   1317 
   1318   float	local_cpu_utilization;
   1319   float	local_service_demand;
   1320   float	remote_cpu_utilization;
   1321   float	remote_service_demand;
   1322 
   1323   double	thruput;
   1324 
   1325   struct addrinfo *remote_res;
   1326   struct addrinfo *local_res;
   1327 
   1328   struct	tcp_stream_request_struct	*tcp_stream_request;
   1329   struct	tcp_stream_response_struct	*tcp_stream_response;
   1330   struct	tcp_stream_results_struct	*tcp_stream_result;
   1331 
   1332   tcp_stream_request  =
   1333     (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
   1334   tcp_stream_response =
   1335     (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
   1336   tcp_stream_result   =
   1337     (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
   1338 
   1339 #ifdef WANT_HISTOGRAM
   1340   if (verbosity > 1) {
   1341     time_hist = HIST_new();
   1342   }
   1343 #endif /* WANT_HISTOGRAM */
   1344   /* since we are now disconnected from the code that established the */
   1345   /* control socket, and since we want to be able to use different */
   1346   /* protocols and such, we are passed the name of the remote host and */
   1347   /* must turn that into the test specific addressing information. */
   1348 
   1349   /* complete_addrinfos will either succede or exit the process */
   1350   complete_addrinfos(&remote_res,
   1351 		     &local_res,
   1352 		     remote_host,
   1353 		     SOCK_STREAM,
   1354 		     IPPROTO_TCP,
   1355 		     0);
   1356 
   1357   if ( print_headers ) {
   1358     print_top_test_header("TCP STREAM TEST",local_res,remote_res);
   1359   }
   1360 
   1361   send_ring = NULL;
   1362   confidence_iteration = 1;
   1363   init_stat();
   1364 
   1365   /* we have a great-big while loop which controls the number of times */
   1366   /* we run a particular test. this is for the calculation of a */
   1367   /* confidence interval (I really should have stayed awake during */
   1368   /* probstats :). If the user did not request confidence measurement */
   1369   /* (no confidence is the default) then we will only go though the */
   1370   /* loop once. the confidence stuff originates from the folks at IBM */
   1371 
   1372   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   1373 	 (confidence_iteration <= iteration_min)) {
   1374 
   1375     /* initialize a few counters. we have to remember that we might be */
   1376     /* going through the loop more than once. */
   1377 
   1378     nummessages    =	0;
   1379     bytes_sent     =	0.0;
   1380     times_up       = 	0;
   1381 
   1382     /*set up the data socket                        */
   1383     send_socket = create_data_socket(local_res);
   1384 
   1385     if (send_socket == INVALID_SOCKET){
   1386       perror("netperf: send_tcp_stream: tcp stream data socket");
   1387       exit(1);
   1388     }
   1389 
   1390     if (debug) {
   1391       fprintf(where,"send_tcp_stream: send_socket obtained...\n");
   1392     }
   1393 
   1394     /* at this point, we have either retrieved the socket buffer sizes, */
   1395     /* or have tried to set them, so now, we may want to set the send */
   1396     /* size based on that (because the user either did not use a -m */
   1397     /* option, or used one with an argument of 0). If the socket buffer */
   1398     /* size is not available, we will set the send size to 4KB - no */
   1399     /* particular reason, just arbitrary... */
   1400     if (send_size == 0) {
   1401       if (lss_size > 0) {
   1402 	send_size = lss_size;
   1403       }
   1404       else {
   1405 	send_size = 4096;
   1406       }
   1407     }
   1408 
   1409     /* set-up the data buffer ring with the requested alignment and offset. */
   1410     /* note also that we have allocated a quantity */
   1411     /* of memory that is at least one send-size greater than our socket */
   1412     /* buffer size. We want to be sure that there are at least two */
   1413     /* buffers allocated - this can be a bit of a problem when the */
   1414     /* send_size is bigger than the socket size, so we must check... the */
   1415     /* user may have wanted to explicitly set the "width" of our send */
   1416     /* buffers, we should respect that wish... */
   1417     if (send_width == 0) {
   1418       send_width = (lss_size/send_size) + 1;
   1419       if (send_width == 1) send_width++;
   1420     }
   1421 
   1422     if (send_ring == NULL) {
   1423       /* only allocate the send ring once. this is a networking test, */
   1424       /* not a memory allocation test. this way, we do not need a */
   1425       /* deallocate_buffer_ring() routine, and I don't feel like */
   1426       /* writing one anyway :) raj 11/94 */
   1427       send_ring = allocate_buffer_ring(send_width,
   1428 				       send_size,
   1429 				       local_send_align,
   1430 				       local_send_offset);
   1431     }
   1432 
   1433     /* If the user has requested cpu utilization measurements, we must */
   1434     /* calibrate the cpu(s). We will perform this task within the tests */
   1435     /* themselves. If the user has specified the cpu rate, then */
   1436     /* calibrate_local_cpu will return rather quickly as it will have */
   1437     /* nothing to do. If local_cpu_rate is zero, then we will go through */
   1438     /* all the "normal" calibration stuff and return the rate back. */
   1439 
   1440     if (local_cpu_usage) {
   1441       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   1442     }
   1443 
   1444     if (!no_control) {
   1445       /* Tell the remote end to do a listen. The server alters the
   1446 	 socket paramters on the other side at this point, hence the
   1447 	 reason for all the values being passed in the setup
   1448 	 message. If the user did not specify any of the parameters,
   1449 	 they will be passed as 0, which will indicate to the remote
   1450 	 that no changes beyond the system's default should be
   1451 	 used. Alignment is the exception, it will default to 1, which
   1452 	 will be no alignment alterations. */
   1453 
   1454       netperf_request.content.request_type =	DO_TCP_STREAM;
   1455       tcp_stream_request->send_buf_size	=	rss_size_req;
   1456       tcp_stream_request->recv_buf_size	=	rsr_size_req;
   1457       tcp_stream_request->receive_size	=	recv_size;
   1458       tcp_stream_request->no_delay	=	rem_nodelay;
   1459       tcp_stream_request->recv_alignment	=	remote_recv_align;
   1460       tcp_stream_request->recv_offset	=	remote_recv_offset;
   1461       tcp_stream_request->measure_cpu	=	remote_cpu_usage;
   1462       tcp_stream_request->cpu_rate	=	remote_cpu_rate;
   1463       if (test_time) {
   1464 	tcp_stream_request->test_length	=	test_time;
   1465       }
   1466       else {
   1467 	tcp_stream_request->test_length	=	test_bytes;
   1468       }
   1469       tcp_stream_request->so_rcvavoid	=	rem_rcvavoid;
   1470       tcp_stream_request->so_sndavoid	=	rem_sndavoid;
   1471 #ifdef DIRTY
   1472       tcp_stream_request->dirty_count     =       rem_dirty_count;
   1473       tcp_stream_request->clean_count     =       rem_clean_count;
   1474 #endif /* DIRTY */
   1475       tcp_stream_request->port            =    atoi(remote_data_port);
   1476       tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
   1477       if (debug > 1) {
   1478 	fprintf(where,
   1479 		"netperf: send_tcp_stream: requesting TCP stream test\n");
   1480       }
   1481 
   1482       send_request();
   1483 
   1484       /* The response from the remote will contain all of the relevant
   1485          socket parameters for this test type. We will put them back
   1486          into the variables here so they can be displayed if desired.
   1487          The remote will have calibrated CPU if necessary, and will
   1488          have done all the needed set-up we will have calibrated the
   1489          cpu locally before sending the request, and will grab the
   1490          counter value right after the connect returns. The remote
   1491          will grab the counter right after the accept call. This saves
   1492          the hassle of extra messages being sent for the TCP
   1493          tests.  */
   1494 
   1495       recv_response();
   1496 
   1497       if (!netperf_response.content.serv_errno) {
   1498 	if (debug)
   1499 	  fprintf(where,"remote listen done.\n");
   1500 	rsr_size	      =	tcp_stream_response->recv_buf_size;
   1501 	rss_size	      =	tcp_stream_response->send_buf_size;
   1502 	rem_nodelay     =	tcp_stream_response->no_delay;
   1503 	remote_cpu_usage=	tcp_stream_response->measure_cpu;
   1504 	remote_cpu_rate = tcp_stream_response->cpu_rate;
   1505 
   1506 	/* we have to make sure that the server port number is in
   1507 	   network order */
   1508 	set_port_number(remote_res,
   1509 			(short)tcp_stream_response->data_port_number);
   1510 
   1511 	rem_rcvavoid	= tcp_stream_response->so_rcvavoid;
   1512 	rem_sndavoid	= tcp_stream_response->so_sndavoid;
   1513       }
   1514       else {
   1515 	Set_errno(netperf_response.content.serv_errno);
   1516 	fprintf(where,
   1517 		"netperf: remote error %d",
   1518 		netperf_response.content.serv_errno);
   1519 	perror("");
   1520 	fflush(where);
   1521 
   1522 	exit(1);
   1523       }
   1524     }
   1525 
   1526 #ifdef WANT_DEMO
   1527     DEMO_STREAM_SETUP(lss_size,rsr_size)
   1528 #endif
   1529 
   1530     /*Connect up to the remote port on the data socket  */
   1531     if (connect(send_socket,
   1532 		remote_res->ai_addr,
   1533 		remote_res->ai_addrlen) == INVALID_SOCKET){
   1534       perror("netperf: send_tcp_stream: data socket connect failed");
   1535       exit(1);
   1536     }
   1537 
   1538     /* Data Socket set-up is finished. If there were problems, either */
   1539     /* the connect would have failed, or the previous response would */
   1540     /* have indicated a problem. I failed to see the value of the */
   1541     /* extra  message after the accept on the remote. If it failed, */
   1542     /* we'll see it here. If it didn't, we might as well start pumping */
   1543     /* data. */
   1544 
   1545     /* Set-up the test end conditions. For a stream test, they can be */
   1546     /* either time or byte-count based. */
   1547 
   1548     if (test_time) {
   1549       /* The user wanted to end the test after a period of time. */
   1550       times_up = 0;
   1551       bytes_remaining = 0;
   1552       /* in previous revisions, we had the same code repeated throught */
   1553       /* all the test suites. this was unnecessary, and meant more */
   1554       /* work for me when I wanted to switch to POSIX signals, so I */
   1555       /* have abstracted this out into a routine in netlib.c. if you */
   1556       /* are experiencing signal problems, you might want to look */
   1557       /* there. raj 11/94 */
   1558       start_timer(test_time);
   1559     }
   1560     else {
   1561       /* The tester wanted to send a number of bytes. */
   1562       bytes_remaining = test_bytes;
   1563       times_up = 1;
   1564     }
   1565 
   1566     /* The cpu_start routine will grab the current time and possibly */
   1567     /* value of the idle counter for later use in measuring cpu */
   1568     /* utilization and/or service demand and thruput. */
   1569 
   1570     cpu_start(local_cpu_usage);
   1571 
   1572     /* we only start the interval timer if we are using the
   1573        timer-timed intervals rather than the sit and spin ones. raj
   1574        2006-02-06 */
   1575 #if defined(WANT_INTERVALS)
   1576     INTERVALS_INIT();
   1577 #endif /* WANT_INTERVALS */
   1578 
   1579     /* before we start, initialize a few variables */
   1580 
   1581 #ifdef WANT_DEMO
   1582       if (demo_mode) {
   1583 	HIST_timestamp(demo_one_ptr);
   1584       }
   1585 #endif
   1586 
   1587 
   1588     /* We use an "OR" to control test execution. When the test is */
   1589     /* controlled by time, the byte count check will always return false. */
   1590     /* When the test is controlled by byte count, the time test will */
   1591     /* always return false. When the test is finished, the whole */
   1592     /* expression will go false and we will stop sending data. */
   1593 
   1594     while ((!times_up) || (bytes_remaining > 0)) {
   1595 
   1596 #ifdef DIRTY
   1597       access_buffer(send_ring->buffer_ptr,
   1598 		    send_size,
   1599 		    loc_dirty_count,
   1600 		    loc_clean_count);
   1601 #endif /* DIRTY */
   1602 
   1603 #ifdef WANT_HISTOGRAM
   1604       if (verbosity > 1) {
   1605 	/* timestamp just before we go into send and then again just
   1606 	 after we come out raj 8/94 */
   1607 	/* but lets only do this if there is going to be a histogram
   1608 	   displayed */
   1609 	HIST_timestamp(&time_one);
   1610       }
   1611 #endif /* WANT_HISTOGRAM */
   1612 
   1613       if((len=send(send_socket,
   1614 		   send_ring->buffer_ptr,
   1615 		   send_size,
   1616 		   0)) != send_size) {
   1617       if ((len >=0) || SOCKET_EINTR(len)) {
   1618 	    /* the test was interrupted, must be the end of test */
   1619 	    break;
   1620 	  }
   1621 	perror("netperf: data send error");
   1622 	printf("len was %d\n",len);
   1623 	exit(1);
   1624       }
   1625 
   1626       local_bytes_sent += send_size;
   1627 
   1628 #ifdef WANT_HISTOGRAM
   1629       if (verbosity > 1) {
   1630 	/* timestamp the exit from the send call and update the histogram */
   1631 	HIST_timestamp(&time_two);
   1632 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   1633       }
   1634 #endif /* WANT_HISTOGRAM */
   1635 
   1636 #ifdef WANT_DEMO
   1637       DEMO_STREAM_INTERVAL(send_size)
   1638 #endif
   1639 
   1640 #if defined(WANT_INTERVALS)
   1641       INTERVALS_WAIT();
   1642 #endif /* WANT_INTERVALS */
   1643 
   1644       /* now we want to move our pointer to the next position in the */
   1645       /* data buffer...we may also want to wrap back to the "beginning" */
   1646       /* of the bufferspace, so we will mod the number of messages sent */
   1647       /* by the send width, and use that to calculate the offset to add */
   1648       /* to the base pointer. */
   1649       nummessages++;
   1650       send_ring = send_ring->next;
   1651       if (bytes_remaining) {
   1652 	bytes_remaining -= send_size;
   1653       }
   1654     }
   1655 
   1656     /* The test is over. Flush the buffers to the remote end. We do a */
   1657     /* graceful release to insure that all data has been taken by the */
   1658     /* remote. */
   1659 
   1660     /* but first, if the verbosity is greater than 1, find-out what */
   1661     /* the TCP maximum segment_size was (if possible) */
   1662     if (verbosity > 1) {
   1663       tcp_mss = -1;
   1664       get_tcp_info(send_socket,&tcp_mss);
   1665     }
   1666 
   1667     if (shutdown(send_socket,SHUT_WR) == SOCKET_ERROR) {
   1668       perror("netperf: cannot shutdown tcp stream socket");
   1669       exit(1);
   1670     }
   1671 
   1672     /* hang a recv() off the socket to block until the remote has */
   1673     /* brought all the data up into the application. it will do a */
   1674     /* shutdown to cause a FIN to be sent our way. We will assume that */
   1675     /* any exit from the recv() call is good... raj 4/93 */
   1676 
   1677     recv(send_socket, send_ring->buffer_ptr, send_size, 0);
   1678 
   1679     /* this call will always give us the elapsed time for the test, and */
   1680     /* will also store-away the necessaries for cpu utilization */
   1681 
   1682     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
   1683 						/* measured and how */
   1684 						/* long did we really */
   1685 						/* run? */
   1686 
   1687     /* we are finished with the socket, so close it to prevent hitting */
   1688     /* the limit on maximum open files. */
   1689 
   1690     close(send_socket);
   1691 
   1692     if (!no_control) {
   1693       /* Get the statistics from the remote end. The remote will have
   1694 	 calculated service demand and all those interesting
   1695 	 things. If it wasn't supposed to care, it will return obvious
   1696 	 values. */
   1697 
   1698       recv_response();
   1699       if (!netperf_response.content.serv_errno) {
   1700 	if (debug)
   1701 	  fprintf(where,"remote results obtained\n");
   1702       }
   1703       else {
   1704 	Set_errno(netperf_response.content.serv_errno);
   1705 	fprintf(where,
   1706 		"netperf: remote error %d",
   1707 		netperf_response.content.serv_errno);
   1708 	perror("");
   1709 	fflush(where);
   1710 
   1711 	exit(1);
   1712       }
   1713 
   1714       /* We now calculate what our thruput was for the test. In the
   1715 	 future, we may want to include a calculation of the thruput
   1716 	 measured by the remote, but it should be the case that for a
   1717 	 TCP stream test, that the two numbers should be *very*
   1718 	 close... We calculate bytes_sent regardless of the way the
   1719 	 test length was controlled.  If it was time, we needed to,
   1720 	 and if it was by bytes, the user may have specified a number
   1721 	 of bytes that wasn't a multiple of the send_size, so we
   1722 	 really didn't send what he asked for ;-) */
   1723 
   1724       bytes_sent	= ntohd(tcp_stream_result->bytes_received);
   1725     }
   1726     else {
   1727       bytes_sent = (double)local_bytes_sent;
   1728     }
   1729 
   1730     thruput	= calc_thruput(bytes_sent);
   1731 
   1732     if (local_cpu_usage || remote_cpu_usage) {
   1733       /* We must now do a little math for service demand and cpu */
   1734       /* utilization for the system(s) */
   1735       /* Of course, some of the information might be bogus because */
   1736       /* there was no idle counter in the kernel(s). We need to make */
   1737       /* a note of this for the user's benefit...*/
   1738       if (local_cpu_usage) {
   1739 
   1740 	local_cpu_utilization	= calc_cpu_util(0.0);
   1741 	local_service_demand	= calc_service_demand(bytes_sent,
   1742 						      0.0,
   1743 						      0.0,
   1744 						      0);
   1745       }
   1746       else {
   1747 	local_cpu_utilization	= (float) -1.0;
   1748 	local_service_demand	= (float) -1.0;
   1749       }
   1750 
   1751       if (remote_cpu_usage) {
   1752 
   1753 	remote_cpu_utilization	= tcp_stream_result->cpu_util;
   1754 	remote_service_demand	= calc_service_demand(bytes_sent,
   1755 						      0.0,
   1756 						      remote_cpu_utilization,
   1757 						      tcp_stream_result->num_cpus);
   1758       }
   1759       else {
   1760 	remote_cpu_utilization = (float) -1.0;
   1761 	remote_service_demand  = (float) -1.0;
   1762       }
   1763     }
   1764     else {
   1765       /* we were not measuring cpu, for the confidence stuff, we */
   1766       /* should make it -1.0 */
   1767       local_cpu_utilization	= (float) -1.0;
   1768       local_service_demand	= (float) -1.0;
   1769       remote_cpu_utilization = (float) -1.0;
   1770       remote_service_demand  = (float) -1.0;
   1771     }
   1772 
   1773     /* at this point, we want to calculate the confidence information. */
   1774     /* if debugging is on, calculate_confidence will print-out the */
   1775     /* parameters we pass it */
   1776 
   1777     calculate_confidence(confidence_iteration,
   1778 			 elapsed_time,
   1779 			 thruput,
   1780 			 local_cpu_utilization,
   1781 			 remote_cpu_utilization,
   1782 			 local_service_demand,
   1783 			 remote_service_demand);
   1784 
   1785 
   1786     confidence_iteration++;
   1787   }
   1788 
   1789   /* at this point, we have finished making all the runs that we */
   1790   /* will be making. so, we should extract what the calcuated values */
   1791   /* are for all the confidence stuff. we could make the values */
   1792   /* global, but that seemed a little messy, and it did not seem worth */
   1793   /* all the mucking with header files. so, we create a routine much */
   1794   /* like calcualte_confidence, which just returns the mean values. */
   1795   /* raj 11/94 */
   1796 
   1797   retrieve_confident_values(&elapsed_time,
   1798 			    &thruput,
   1799 			    &local_cpu_utilization,
   1800 			    &remote_cpu_utilization,
   1801 			    &local_service_demand,
   1802 			    &remote_service_demand);
   1803 
   1804   /* We are now ready to print all the information. If the user */
   1805   /* has specified zero-level verbosity, we will just print the */
   1806   /* local service demand, or the remote service demand. If the */
   1807   /* user has requested verbosity level 1, he will get the basic */
   1808   /* "streamperf" numbers. If the user has specified a verbosity */
   1809   /* of greater than 1, we will display a veritable plethora of */
   1810   /* background information from outside of this block as it it */
   1811   /* not cpu_measurement specific...  */
   1812 
   1813   if (confidence < 0) {
   1814     /* we did not hit confidence, but were we asked to look for it? */
   1815     if (iteration_max > 1) {
   1816       display_confidence();
   1817     }
   1818   }
   1819 
   1820   if (local_cpu_usage || remote_cpu_usage) {
   1821     local_cpu_method = format_cpu_method(cpu_method);
   1822     remote_cpu_method = format_cpu_method(tcp_stream_result->cpu_method);
   1823 
   1824     switch (verbosity) {
   1825     case 0:
   1826       if (local_cpu_usage) {
   1827 	fprintf(where,
   1828 		cpu_fmt_0,
   1829 		local_service_demand,
   1830 		local_cpu_method,
   1831 		((print_headers) ||
   1832 		 (result_brand == NULL)) ? "" : result_brand);
   1833       }
   1834       else {
   1835 	fprintf(where,
   1836 		cpu_fmt_0,
   1837 		remote_service_demand,
   1838 		remote_cpu_method,
   1839 		((print_headers) ||
   1840 		 (result_brand == NULL)) ? "" : result_brand);
   1841       }
   1842       break;
   1843     case 1:
   1844     case 2:
   1845       if (print_headers) {
   1846 		fprintf(where,
   1847 		cpu_title,
   1848 		format_units(),
   1849 		local_cpu_method,
   1850 		remote_cpu_method);
   1851       }
   1852 
   1853       fprintf(where,
   1854 	      cpu_fmt_1,		/* the format string */
   1855 	      rsr_size,		        /* remote recvbuf size */
   1856 	      lss_size,		        /* local sendbuf size */
   1857 	      send_size,		/* how large were the sends */
   1858 	      elapsed_time,		/* how long was the test */
   1859 	      thruput, 		        /* what was the xfer rate */
   1860 	      local_cpu_utilization,	/* local cpu */
   1861 	      remote_cpu_utilization,	/* remote cpu */
   1862 	      local_service_demand,	/* local service demand */
   1863 	      remote_service_demand,	/* remote service demand */
   1864 	      ((print_headers) ||
   1865 	       (result_brand == NULL)) ? "" : result_brand);
   1866       break;
   1867     }
   1868   }
   1869   else {
   1870     /* The tester did not wish to measure service demand. */
   1871 
   1872     switch (verbosity) {
   1873     case 0:
   1874       fprintf(where,
   1875 	      tput_fmt_0,
   1876 	      thruput,
   1877 	      ((print_headers) ||
   1878 	       (result_brand == NULL)) ? "" : result_brand);
   1879       break;
   1880     case 1:
   1881     case 2:
   1882       if (print_headers) {
   1883 		fprintf(where,tput_title,format_units());
   1884       }
   1885       fprintf(where,
   1886 	      tput_fmt_1,		/* the format string */
   1887 	      rsr_size, 		/* remote recvbuf size */
   1888 	      lss_size, 		/* local sendbuf size */
   1889 	      send_size,		/* how large were the sends */
   1890 	      elapsed_time, 		/* how long did it take */
   1891 	      thruput,                  /* how fast did it go */
   1892 	      ((print_headers) ||
   1893 	       (result_brand == NULL)) ? "" : result_brand);
   1894       break;
   1895     }
   1896   }
   1897 
   1898   /* it would be a good thing to include information about some of the */
   1899   /* other parameters that may have been set for this test, but at the */
   1900   /* moment, I do not wish to figure-out all the  formatting, so I will */
   1901   /* just put this comment here to help remind me that it is something */
   1902   /* that should be done at a later time. */
   1903 
   1904   if (verbosity > 1) {
   1905     /* The user wanted to know it all, so we will give it to him. */
   1906     /* This information will include as much as we can find about */
   1907     /* TCP statistics, the alignments of the sends and receives */
   1908     /* and all that sort of rot... */
   1909 
   1910     /* this stuff needs to be worked-out in the presence of confidence */
   1911     /* intervals and multiple iterations of the test... raj 11/94 */
   1912 
   1913     fprintf(where,
   1914 	    ksink_fmt,
   1915 	    "Bytes",
   1916 	    "Bytes",
   1917 	    "Bytes",
   1918 	    local_send_align,
   1919 	    remote_recv_align,
   1920 	    local_send_offset,
   1921 	    remote_recv_offset,
   1922 	    bytes_sent,
   1923 	    bytes_sent / (double)nummessages,
   1924 	    nummessages,
   1925 	    bytes_sent / (double)tcp_stream_result->recv_calls,
   1926 	    tcp_stream_result->recv_calls);
   1927     fprintf(where,
   1928 	    ksink_fmt2,
   1929 	    tcp_mss);
   1930     fflush(where);
   1931 #ifdef WANT_HISTOGRAM
   1932     fprintf(where,"\n\nHistogram of time spent in send() call.\n");
   1933     fflush(where);
   1934     HIST_report(time_hist);
   1935 #endif /* WANT_HISTOGRAM */
   1936   }
   1937 
   1938 }
   1939 
   1940 
   1941 
   1943 /* This routine implements the netperf-side TCP unidirectional data
   1944    transfer test (a.k.a. stream) for the sockets interface where the
   1945    data flow is from the netserver to the netperf.  It receives its
   1946    parameters via global variables from the shell and writes its
   1947    output to the standard output. */
   1948 
   1949 
   1950 void
   1951 send_tcp_maerts(char remote_host[])
   1952 {
   1953 
   1954   char *tput_title = "\
   1955 Recv   Send    Send                          \n\
   1956 Socket Socket  Message  Elapsed              \n\
   1957 Size   Size    Size     Time     Throughput  \n\
   1958 bytes  bytes   bytes    secs.    %s/sec  \n\n";
   1959 
   1960   char *tput_fmt_0 =
   1961     "%7.2f %s\n";
   1962 
   1963   char *tput_fmt_1 =
   1964     "%6d %6d %6d    %-6.2f   %7.2f    %s \n";
   1965 
   1966   char *cpu_title = "\
   1967 Recv   Send    Send                          Utilization       Service Demand\n\
   1968 Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
   1969 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
   1970 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
   1971 
   1972   char *cpu_fmt_0 =
   1973     "%6.3f %c %s\n";
   1974 
   1975   char *cpu_fmt_1 =
   1976     "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f %s\n";
   1977 
   1978   char *ksink_fmt = "\n\
   1979 Alignment      Offset         %-8.8s %-8.8s    Recvs   %-8.8s Sends\n\
   1980 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
   1981 Recv   Send    Recv   Send             Recv (avg)          Send (avg)\n\
   1982 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
   1983 
   1984   char *ksink_fmt2 = "\n\
   1985 Maximum\n\
   1986 Segment\n\
   1987 Size (bytes)\n\
   1988 %6d\n";
   1989 
   1990 
   1991   float			elapsed_time;
   1992 
   1993   /* what we want is to have a buffer space that is at least one */
   1994   /* recv-size greater than our recv window. this will insure that we */
   1995   /* are never trying to re-use a buffer that may still be in the hands */
   1996   /* of the transport. This buffer will be malloc'd after we have found */
   1997   /* the size of the local senc socket buffer. We will want to deal */
   1998   /* with alignment and offset concerns as well. */
   1999 
   2000   struct ring_elt *recv_ring;
   2001 
   2002   int len;
   2003   unsigned int nummessages = 0;
   2004   SOCKET recv_socket;
   2005   int bytes_remaining;
   2006   int tcp_mss = -1;  /* possibly uninitialized on printf far below */
   2007 
   2008   /* with links like fddi, one can recv > 32 bits worth of bytes */
   2009   /* during a test... ;-) at some point, this should probably become a */
   2010   /* 64bit integral type, but those are not entirely common yet */
   2011   double	bytes_sent = 0.0;
   2012   unsigned long long local_bytes_recvd = 0;
   2013 
   2014   float	local_cpu_utilization;
   2015   float	local_service_demand;
   2016   float	remote_cpu_utilization;
   2017   float	remote_service_demand;
   2018 
   2019   double	thruput;
   2020 
   2021   struct addrinfo *remote_res;
   2022   struct addrinfo *local_res;
   2023 
   2024   struct	tcp_maerts_request_struct	*tcp_maerts_request;
   2025   struct	tcp_maerts_response_struct	*tcp_maerts_response;
   2026   struct	tcp_maerts_results_struct	*tcp_maerts_result;
   2027 
   2028   tcp_maerts_request  =
   2029     (struct tcp_maerts_request_struct *)netperf_request.content.test_specific_data;
   2030   tcp_maerts_response =
   2031     (struct tcp_maerts_response_struct *)netperf_response.content.test_specific_data;
   2032   tcp_maerts_result   =
   2033     (struct tcp_maerts_results_struct *)netperf_response.content.test_specific_data;
   2034 
   2035 #ifdef WANT_HISTOGRAM
   2036   if (verbosity > 1) {
   2037     time_hist = HIST_new();
   2038   }
   2039 #endif /* WANT_HISTOGRAM */
   2040   /* since we are now disconnected from the code that established the */
   2041   /* control socket, and since we want to be able to use different */
   2042   /* protocols and such, we are passed the name of the remote host and */
   2043   /* must turn that into the test specific addressing information. */
   2044 
   2045   complete_addrinfos(&remote_res,
   2046 		     &local_res,
   2047 		     remote_host,
   2048 		     SOCK_STREAM,
   2049 		     IPPROTO_TCP,
   2050 		     0);
   2051 
   2052   if ( print_headers ) {
   2053     print_top_test_header("TCP MAERTS TEST",local_res,remote_res);
   2054   }
   2055 
   2056   recv_ring = NULL;
   2057   confidence_iteration = 1;
   2058   init_stat();
   2059 
   2060   /* we have a great-big while loop which controls the number of times */
   2061   /* we run a particular test. this is for the calculation of a */
   2062   /* confidence interval (I really should have stayed awake during */
   2063   /* probstats :). If the user did not request confidence measurement */
   2064   /* (no confidence is the default) then we will only go though the */
   2065   /* loop once. the confidence stuff originates from the folks at IBM */
   2066 
   2067   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   2068 	 (confidence_iteration <= iteration_min)) {
   2069 
   2070     /* initialize a few counters. we have to remember that we might be */
   2071     /* going through the loop more than once. */
   2072 
   2073     nummessages    =	0;
   2074     bytes_sent     =	0.0;
   2075     times_up       = 	0;
   2076 
   2077     /*set up the data socket                        */
   2078     recv_socket = create_data_socket(local_res);
   2079 
   2080     if (recv_socket == INVALID_SOCKET){
   2081       perror("netperf: send_tcp_maerts: tcp stream data socket");
   2082       exit(1);
   2083     }
   2084 
   2085     if (debug) {
   2086       fprintf(where,"send_tcp_maerts: recv_socket obtained...\n");
   2087     }
   2088 
   2089     /* at this point, we have either retrieved the socket buffer sizes, */
   2090     /* or have tried to set them, so now, we may want to set the recv */
   2091     /* size based on that (because the user either did not use a -m */
   2092     /* option, or used one with an argument of 0). If the socket buffer */
   2093     /* size is not available, we will set the recv size to 4KB - no */
   2094     /* particular reason, just arbitrary... */
   2095     if (recv_size == 0) {
   2096       if (lsr_size > 0) {
   2097 	recv_size = lsr_size;
   2098       }
   2099       else {
   2100 	recv_size = 4096;
   2101       }
   2102     }
   2103 
   2104     /* set-up the data buffer ring with the requested alignment and offset. */
   2105     /* note also that we have allocated a quantity */
   2106     /* of memory that is at least one recv-size greater than our socket */
   2107     /* buffer size. We want to be sure that there are at least two */
   2108     /* buffers allocated - this can be a bit of a problem when the */
   2109     /* recv_size is bigger than the socket size, so we must check... the */
   2110     /* user may have wanted to explicitly set the "width" of our recv */
   2111     /* buffers, we should respect that wish... */
   2112     if (recv_width == 0) {
   2113       recv_width = (lsr_size/recv_size) + 1;
   2114       if (recv_width == 1) recv_width++;
   2115     }
   2116 
   2117     if (recv_ring == NULL) {
   2118       /* only allocate the recv ring once. this is a networking test, */
   2119       /* not a memory allocation test. this way, we do not need a */
   2120       /* deallocate_buffer_ring() routine, and I don't feel like */
   2121       /* writing one anyway :) raj 11/94 */
   2122       recv_ring = allocate_buffer_ring(recv_width,
   2123 				       recv_size,
   2124 				       local_recv_align,
   2125 				       local_recv_offset);
   2126     }
   2127 
   2128     /* If the user has requested cpu utilization measurements, we must */
   2129     /* calibrate the cpu(s). We will perform this task within the tests */
   2130     /* themselves. If the user has specified the cpu rate, then */
   2131     /* calibrate_local_cpu will return rather quickly as it will have */
   2132     /* nothing to do. If local_cpu_rate is zero, then we will go through */
   2133     /* all the "normal" calibration stuff and return the rate back. */
   2134 
   2135     if (local_cpu_usage) {
   2136       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   2137     }
   2138 
   2139     if (!no_control) {
   2140       /* Tell the remote end to do a listen. The server alters the
   2141 	 socket paramters on the other side at this point, hence the
   2142 	 reason for all the values being passed in the setup
   2143 	 message. If the user did not specify any of the parameters,
   2144 	 they will be passed as 0, which will indicate to the remote
   2145 	 that no changes beyond the system's default should be
   2146 	 used. Alignment is the exception, it will default to 1, which
   2147 	 will be no alignment alterations. */
   2148 
   2149       netperf_request.content.request_type	=	DO_TCP_MAERTS;
   2150       tcp_maerts_request->send_buf_size	=	rss_size_req;
   2151       tcp_maerts_request->recv_buf_size	=	rsr_size_req;
   2152       tcp_maerts_request->send_size	=	send_size;
   2153       tcp_maerts_request->no_delay	=	rem_nodelay;
   2154       tcp_maerts_request->send_alignment	=	remote_send_align;
   2155       tcp_maerts_request->send_offset	=	remote_send_offset;
   2156       tcp_maerts_request->measure_cpu	=	remote_cpu_usage;
   2157       tcp_maerts_request->cpu_rate	=	remote_cpu_rate;
   2158       if (test_time) {
   2159 	tcp_maerts_request->test_length	=	test_time;
   2160       }
   2161       else {
   2162 	tcp_maerts_request->test_length	=	test_bytes;
   2163       }
   2164       tcp_maerts_request->so_rcvavoid	=	rem_rcvavoid;
   2165       tcp_maerts_request->so_sndavoid	=	rem_sndavoid;
   2166 #ifdef DIRTY
   2167       tcp_maerts_request->dirty_count       =       rem_dirty_count;
   2168       tcp_maerts_request->clean_count       =       rem_clean_count;
   2169 #endif /* DIRTY */
   2170       tcp_maerts_request->port            = atoi(remote_data_port);
   2171       tcp_maerts_request->ipfamily        = af_to_nf(remote_res->ai_family);
   2172       if (debug > 1) {
   2173 	fprintf(where,
   2174 		"netperf: send_tcp_maerts: requesting TCP maerts test\n");
   2175       }
   2176 
   2177       send_request();
   2178 
   2179       /* The response from the remote will contain all of the relevant
   2180 	 socket parameters for this test type. We will put them back
   2181 	 into the variables here so they can be displayed if desired.
   2182 	 The remote will have calibrated CPU if necessary, and will
   2183 	 have done all the needed set-up we will have calibrated the
   2184 	 cpu locally before sending the request, and will grab the
   2185 	 counter value right after the connect returns. The remote
   2186 	 will grab the counter right after the accept call. This saves
   2187 	 the hassle of extra messages being sent for the TCP
   2188 	 tests.  */
   2189 
   2190       recv_response();
   2191 
   2192       if (!netperf_response.content.serv_errno) {
   2193 	if (debug)
   2194 	  fprintf(where,"remote listen done.\n");
   2195 	rsr_size	=	tcp_maerts_response->recv_buf_size;
   2196 	rss_size	=	tcp_maerts_response->send_buf_size;
   2197 	rem_nodelay     =	tcp_maerts_response->no_delay;
   2198 	remote_cpu_usage=	tcp_maerts_response->measure_cpu;
   2199 	remote_cpu_rate = tcp_maerts_response->cpu_rate;
   2200 	send_size       = tcp_maerts_response->send_size;
   2201 
   2202 	/* we have to make sure that the server port number is in
   2203 	 network order */
   2204       set_port_number(remote_res,
   2205 		      (short)tcp_maerts_response->data_port_number);
   2206       rem_rcvavoid	= tcp_maerts_response->so_rcvavoid;
   2207       rem_sndavoid	= tcp_maerts_response->so_sndavoid;
   2208       }
   2209       else {
   2210 	Set_errno(netperf_response.content.serv_errno);
   2211 	fprintf(where,
   2212 		"netperf: remote error %d",
   2213 		netperf_response.content.serv_errno);
   2214 	perror("");
   2215 	fflush(where);
   2216 
   2217 	exit(1);
   2218       }
   2219     }
   2220 
   2221 #ifdef WANT_DEMO
   2222     DEMO_STREAM_SETUP(lsr_size,rss_size)
   2223 #endif
   2224 
   2225     /*Connect up to the remote port on the data socket  */
   2226     if (connect(recv_socket,
   2227 		remote_res->ai_addr,
   2228 		remote_res->ai_addrlen) == INVALID_SOCKET){
   2229       perror("netperf: send_tcp_maerts: data socket connect failed");
   2230       exit(1);
   2231     }
   2232 
   2233     /* Data Socket set-up is finished. If there were problems, either */
   2234     /* the connect would have failed, or the previous response would */
   2235     /* have indicated a problem. I failed to see the value of the */
   2236     /* extra  message after the accept on the remote. If it failed, */
   2237     /* we'll see it here. If it didn't, we might as well start pumping */
   2238     /* data. */
   2239 
   2240     /* Set-up the test end conditions. For a maerts test, they can be */
   2241     /* either time or byte-count based. */
   2242 
   2243     if (test_time) {
   2244       /* The user wanted to end the test after a period of time. */
   2245       times_up = 0;
   2246       bytes_remaining = 0;
   2247       /* in previous revisions, we had the same code repeated throught */
   2248       /* all the test suites. this was unnecessary, and meant more */
   2249       /* work for me when I wanted to switch to POSIX signals, so I */
   2250       /* have abstracted this out into a routine in netlib.c. if you */
   2251       /* are experiencing signal problems, you might want to look */
   2252       /* there. raj 11/94 */
   2253       if (!no_control) {
   2254 	/* this is a netperf to netserver test, netserver will close
   2255 	   to tell us the test is over, so use PAD_TIME to avoid
   2256 	   causing the netserver fits. */
   2257 	start_timer(test_time + PAD_TIME);
   2258       }
   2259       else {
   2260 	/* this is a netperf to data source test, no PAD_TIME */
   2261 	start_timer(test_time);
   2262       }
   2263     }
   2264     else {
   2265       /* The tester wanted to recv a number of bytes. we don't do that
   2266 	 in a TCP_MAERTS test. sorry. raj 2002-06-21 */
   2267       printf("netperf: send_tcp_maerts: test must be timed\n");
   2268       exit(1);
   2269     }
   2270 
   2271     /* The cpu_start routine will grab the current time and possibly */
   2272     /* value of the idle counter for later use in measuring cpu */
   2273     /* utilization and/or service demand and thruput. */
   2274 
   2275     cpu_start(local_cpu_usage);
   2276 
   2277 #ifdef WANT_INTERVALS
   2278     INTERVALS_INIT();
   2279 #endif /* WANT_INTERVALS */
   2280 
   2281     /* before we start, initialize a few variables */
   2282 
   2283 #ifdef WANT_DEMO
   2284     if (demo_mode) {
   2285       HIST_timestamp(demo_one_ptr);
   2286     }
   2287 #endif
   2288 
   2289     /* the test will continue until we either get a zero-byte recv()
   2290        on the socket or our failsafe timer expires. most of the time
   2291        we trust that we get a zero-byte recieve from the socket. raj
   2292        2002-06-21 */
   2293 
   2294 #ifdef WANT_HISTOGRAM
   2295     if (verbosity > 1) {
   2296       /* timestamp just before we go into recv and then again just
   2297 	 after we come out raj 8/94 */
   2298       /* but only if we are actually going to display a histogram. raj
   2299 	 2006-02-07 */
   2300       HIST_timestamp(&time_one);
   2301     }
   2302 #endif /* WANT_HISTOGRAM */
   2303 
   2304     while ((!times_up) && (len=recv(recv_socket,
   2305 				    recv_ring->buffer_ptr,
   2306 				    recv_size,
   2307 				    0)) > 0 ) {
   2308 
   2309 #ifdef WANT_HISTOGRAM
   2310       if (verbosity > 1) {
   2311 	/* timestamp the exit from the recv call and update the histogram */
   2312 	HIST_timestamp(&time_two);
   2313 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   2314       }
   2315 #endif /* WANT_HISTOGRAM */
   2316 
   2317 #ifdef DIRTY
   2318       access_buffer(recv_ring->buffer_ptr,
   2319 		    recv_size,
   2320 		    loc_dirty_count,
   2321 		    loc_clean_count);
   2322 #endif /* DIRTY */
   2323 
   2324 #ifdef WANT_DEMO
   2325       DEMO_STREAM_INTERVAL(len);
   2326 #endif
   2327 
   2328 #ifdef WANT_INTERVALS
   2329       INTERVALS_WAIT();
   2330 #endif /* WANT_INTERVALS */
   2331 
   2332       /* now we want to move our pointer to the next position in the */
   2333       /* data buffer...we may also want to wrap back to the "beginning" */
   2334       /* of the bufferspace, so we will mod the number of messages sent */
   2335       /* by the recv width, and use that to calculate the offset to add */
   2336       /* to the base pointer. */
   2337       nummessages++;
   2338       recv_ring = recv_ring->next;
   2339       if (bytes_remaining) {
   2340 	bytes_remaining -= len;
   2341       }
   2342 
   2343       local_bytes_recvd += len;
   2344 
   2345 #ifdef WANT_HISTOGRAM
   2346       if (verbosity > 1) {
   2347 	/* make sure we timestamp just before we go into recv  */
   2348 	/* raj 2004-06-15 */
   2349 	HIST_timestamp(&time_one);
   2350       }
   2351 #endif /* WANT_HISTOGRAM */
   2352 
   2353     }
   2354 
   2355     /* an EINTR is to be expected when this is a no_control test */
   2356     if (((len < 0) || SOCKET_EINTR(len)) && (!no_control)) {
   2357       perror("send_tcp_maerts: data recv error");
   2358       printf("len was %d\n",len);
   2359       exit(1);
   2360     }
   2361 
   2362     /* if we get here, it must mean we had a recv return of 0 before
   2363        the watchdog timer expired, or the watchdog timer expired and
   2364        this was a no_control test */
   2365 
   2366     /* The test is over. Flush the buffers to the remote end. We do a
   2367        graceful release to tell the  remote we have all the data. */
   2368 
   2369     /* but first, if the verbosity is greater than 1, find-out what */
   2370     /* the TCP maximum segment_size was (if possible) */
   2371     if (verbosity > 1) {
   2372       tcp_mss = -1;
   2373       get_tcp_info(recv_socket,&tcp_mss);
   2374     }
   2375 
   2376     if (shutdown(recv_socket,SHUT_WR) == SOCKET_ERROR) {
   2377       perror("netperf: cannot shutdown tcp maerts socket");
   2378       exit(1);
   2379     }
   2380 
   2381     stop_timer();
   2382 
   2383     /* this call will always give us the local elapsed time for the
   2384        test, and will also store-away the necessaries for cpu
   2385        utilization */
   2386 
   2387     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
   2388 						/* measured and how */
   2389 						/* long did we really */
   2390 						/* run? */
   2391 
   2392     /* we are finished with the socket, so close it to prevent hitting */
   2393     /* the limit on maximum open files. */
   2394 
   2395     close(recv_socket);
   2396 
   2397     if (!no_control) {
   2398       /* Get the statistics from the remote end. The remote will have
   2399          calculated service demand and all those interesting
   2400          things. If it wasn't supposed to care, it will return obvious
   2401          values. */
   2402 
   2403       recv_response();
   2404       if (!netperf_response.content.serv_errno) {
   2405 	if (debug)
   2406 	  fprintf(where,"remote results obtained\n");
   2407       }
   2408       else {
   2409 	Set_errno(netperf_response.content.serv_errno);
   2410 	fprintf(where,
   2411 		"netperf: remote error %d",
   2412 		netperf_response.content.serv_errno);
   2413 	perror("");
   2414 	fflush(where);
   2415 
   2416 	exit(1);
   2417       }
   2418 
   2419       /* We now calculate what our thruput was for the test. In the
   2420 	 future, we may want to include a calculation of the thruput
   2421 	 measured by the remote, but it should be the case that for a
   2422 	 TCP maerts test, that the two numbers should be *very*
   2423 	 close... We calculate bytes_sent regardless of the way the
   2424 	 test length was controlled.  If it was time, we needed to,
   2425 	 and if it was by bytes, the user may have specified a number
   2426 	 of bytes that wasn't a multiple of the recv_size, so we
   2427 	 really didn't recv what he asked for ;-) */
   2428 
   2429       bytes_sent	= ntohd(tcp_maerts_result->bytes_sent);
   2430     }
   2431     else {
   2432       bytes_sent = (double)local_bytes_recvd;
   2433     }
   2434 
   2435 
   2436     thruput	= calc_thruput(bytes_sent);
   2437 
   2438     if (local_cpu_usage || remote_cpu_usage) {
   2439       /* We must now do a little math for service demand and cpu */
   2440       /* utilization for the system(s) */
   2441       /* Of course, some of the information might be bogus because */
   2442       /* there was no idle counter in the kernel(s). We need to make */
   2443       /* a note of this for the user's benefit...*/
   2444       if (local_cpu_usage) {
   2445 
   2446 	local_cpu_utilization	= calc_cpu_util(0.0);
   2447 	local_service_demand	= calc_service_demand(bytes_sent,
   2448 						      0.0,
   2449 						      0.0,
   2450 						      0);
   2451       }
   2452       else {
   2453 	local_cpu_utilization	= (float) -1.0;
   2454 	local_service_demand	= (float) -1.0;
   2455       }
   2456 
   2457       if (remote_cpu_usage) {
   2458 
   2459 	remote_cpu_utilization	= tcp_maerts_result->cpu_util;
   2460 	remote_service_demand	= calc_service_demand(bytes_sent,
   2461 						      0.0,
   2462 						      remote_cpu_utilization,
   2463 						      tcp_maerts_result->num_cpus);
   2464       }
   2465       else {
   2466 	remote_cpu_utilization = (float) -1.0;
   2467 	remote_service_demand  = (float) -1.0;
   2468       }
   2469     }
   2470     else {
   2471       /* we were not measuring cpu, for the confidence stuff, we */
   2472       /* should make it -1.0 */
   2473       local_cpu_utilization	= (float) -1.0;
   2474       local_service_demand	= (float) -1.0;
   2475       remote_cpu_utilization = (float) -1.0;
   2476       remote_service_demand  = (float) -1.0;
   2477     }
   2478 
   2479     /* at this point, we want to calculate the confidence information. */
   2480     /* if debugging is on, calculate_confidence will print-out the */
   2481     /* parameters we pass it */
   2482 
   2483     calculate_confidence(confidence_iteration,
   2484 			 elapsed_time,
   2485 			 thruput,
   2486 			 local_cpu_utilization,
   2487 			 remote_cpu_utilization,
   2488 			 local_service_demand,
   2489 			 remote_service_demand);
   2490 
   2491 
   2492     confidence_iteration++;
   2493   }
   2494 
   2495   /* at this point, we have finished making all the runs that we */
   2496   /* will be making. so, we should extract what the calcuated values */
   2497   /* are for all the confidence stuff. we could make the values */
   2498   /* global, but that seemed a little messy, and it did not seem worth */
   2499   /* all the mucking with header files. so, we create a routine much */
   2500   /* like calcualte_confidence, which just returns the mean values. */
   2501   /* raj 11/94 */
   2502 
   2503   retrieve_confident_values(&elapsed_time,
   2504 			    &thruput,
   2505 			    &local_cpu_utilization,
   2506 			    &remote_cpu_utilization,
   2507 			    &local_service_demand,
   2508 			    &remote_service_demand);
   2509 
   2510   /* We are now ready to print all the information. If the user */
   2511   /* has specified zero-level verbosity, we will just print the */
   2512   /* local service demand, or the remote service demand. If the */
   2513   /* user has requested verbosity level 1, he will get the basic */
   2514   /* "streamperf" numbers. If the user has specified a verbosity */
   2515   /* of greater than 1, we will display a veritable plethora of */
   2516   /* background information from outside of this block as it it */
   2517   /* not cpu_measurement specific...  */
   2518 
   2519   if (confidence < 0) {
   2520     /* we did not hit confidence, but were we asked to look for it? */
   2521     if (iteration_max > 1) {
   2522       display_confidence();
   2523     }
   2524   }
   2525 
   2526   if (local_cpu_usage || remote_cpu_usage) {
   2527     local_cpu_method = format_cpu_method(cpu_method);
   2528     remote_cpu_method = format_cpu_method(tcp_maerts_result->cpu_method);
   2529 
   2530     switch (verbosity) {
   2531     case 0:
   2532       if (local_cpu_usage) {
   2533 	fprintf(where,
   2534 		cpu_fmt_0,
   2535 		local_service_demand,
   2536 		local_cpu_method,
   2537 		((print_headers) ||
   2538 		 (result_brand == NULL)) ? "" : result_brand);
   2539       }
   2540       else {
   2541 	fprintf(where,
   2542 		cpu_fmt_0,
   2543 		remote_service_demand,
   2544 		remote_cpu_method,
   2545 		((print_headers) ||
   2546 		 (result_brand == NULL)) ? "" : result_brand);
   2547       }
   2548       break;
   2549     case 1:
   2550     case 2:
   2551       if (print_headers) {
   2552 	fprintf(where,
   2553 		cpu_title,
   2554 		format_units(),
   2555 		local_cpu_method,
   2556 		remote_cpu_method);
   2557       }
   2558 
   2559       fprintf(where,
   2560 	      cpu_fmt_1,		/* the format string */
   2561 	      rsr_size,		        /* remote recvbuf size */
   2562 	      lss_size,		        /* local sendbuf size */
   2563 	      send_size,		/* how large were the recvs */
   2564 	      elapsed_time,		/* how long was the test */
   2565 	      thruput, 		        /* what was the xfer rate */
   2566 	      local_cpu_utilization,	/* local cpu */
   2567 	      remote_cpu_utilization,	/* remote cpu */
   2568 	      local_service_demand,	/* local service demand */
   2569 	      remote_service_demand,	/* remote service demand */
   2570 	      ((print_headers) ||
   2571 	       (result_brand == NULL)) ? "" : result_brand);
   2572       break;
   2573     }
   2574   }
   2575   else {
   2576     /* The tester did not wish to measure service demand. */
   2577 
   2578     switch (verbosity) {
   2579     case 0:
   2580       fprintf(where,
   2581 	      tput_fmt_0,
   2582 	      thruput,
   2583 	      ((print_headers) ||
   2584 	       (result_brand == NULL)) ? "" : result_brand);
   2585       break;
   2586     case 1:
   2587     case 2:
   2588       if (print_headers) {
   2589 	fprintf(where,tput_title,format_units());
   2590       }
   2591       fprintf(where,
   2592 	      tput_fmt_1,		/* the format string */
   2593 	      lsr_size, 		/* local recvbuf size */
   2594 	      rss_size, 		/* remot sendbuf size */
   2595 	      send_size,		/* how large were the recvs */
   2596 	      elapsed_time, 		/* how long did it take */
   2597 	      thruput,                  /* how fast did it go */
   2598 	      ((print_headers) ||
   2599 	       (result_brand == NULL)) ? "" : result_brand);
   2600       break;
   2601     }
   2602   }
   2603 
   2604   /* it would be a good thing to include information about some of the */
   2605   /* other parameters that may have been set for this test, but at the */
   2606   /* moment, I do not wish to figure-out all the  formatting, so I will */
   2607   /* just put this comment here to help remind me that it is something */
   2608   /* that should be done at a later time. */
   2609 
   2610   if (verbosity > 1) {
   2611     /* The user wanted to know it all, so we will give it to him. */
   2612     /* This information will include as much as we can find about */
   2613     /* TCP statistics, the alignments of the sends and receives */
   2614     /* and all that sort of rot... */
   2615 
   2616     /* this stuff needs to be worked-out in the presence of confidence */
   2617     /* intervals and multiple iterations of the test... raj 11/94 */
   2618 
   2619     fprintf(where,
   2620 	    ksink_fmt,
   2621 	    "Bytes",
   2622 	    "Bytes",
   2623 	    "Bytes",
   2624 	    local_recv_align,
   2625 	    remote_recv_align,
   2626 	    local_recv_offset,
   2627 	    remote_recv_offset,
   2628 	    bytes_sent,
   2629 	    bytes_sent / (double)nummessages,
   2630 	    nummessages,
   2631 	    bytes_sent / (double)tcp_maerts_result->send_calls,
   2632 	    tcp_maerts_result->send_calls);
   2633     fprintf(where,
   2634 	    ksink_fmt2,
   2635 	    tcp_mss);
   2636     fflush(where);
   2637 #ifdef WANT_HISTOGRAM
   2638     fprintf(where,"\n\nHistogram of time spent in recv() call.\n");
   2639     fflush(where);
   2640     HIST_report(time_hist);
   2641 #endif /* WANT_HISTOGRAM */
   2642   }
   2643 
   2644 }
   2645 
   2646 
   2647 
   2649 #ifdef HAVE_ICSC_EXS
   2650 
   2651 #include <sys/exs.h>
   2652 
   2653 
   2654 /* This routine implements the TCP unidirectional data transfer test */
   2655 /* (a.k.a. stream) for the sockets interface. It receives its */
   2656 /* parameters via global variables from the shell and writes its */
   2657 /* output to the standard output. */
   2658 
   2659 void
   2660 send_exs_tcp_stream(char remote_host[])
   2661 {
   2662 
   2663     char *tput_title = "\
   2664 Recv   Send    Send                          \n\
   2665 Socket Socket  Message  Elapsed              \n\
   2666 Size   Size    Size     Time     Throughput  \n\
   2667 bytes  bytes   bytes    secs.    %s/sec  \n\n";
   2668 
   2669     char *tput_fmt_0 =
   2670         "%7.2f\n";
   2671 
   2672     char *tput_fmt_1 =
   2673         "%6d %6d %6d    %-6.2f   %7.2f   \n";
   2674 
   2675     char *cpu_title = "\
   2676 Recv   Send    Send                          Utilization       Service Demand\n\
   2677 Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
   2678 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
   2679 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
   2680 
   2681     char *cpu_fmt_0 =
   2682         "%6.3f %c\n";
   2683 
   2684     char *cpu_fmt_1 =
   2685         "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f\n";
   2686 
   2687     char *ksink_fmt = "\n\
   2688 Alignment      Offset         %-8.8s %-8.8s    Sends   %-8.8s Recvs\n\
   2689 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
   2690 Send   Recv    Send   Recv             Send (avg)          Recv (avg)\n\
   2691 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
   2692 
   2693     char *ksink_fmt2 = "\n\
   2694 Maximum\n\
   2695 Segment\n\
   2696 Size (bytes)\n\
   2697 %6d\n";
   2698 
   2699 
   2700     float         elapsed_time;
   2701 
   2702     /* what we want is to have a buffer space that is at least one */
   2703     /* send-size greater than our send window. this will insure that we */
   2704     /* are never trying to re-use a buffer that may still be in the hands */
   2705     /* of the transport. This buffer will be malloc'd after we have found */
   2706     /* the size of the local senc socket buffer. We will want to deal */
   2707     /* with alignment and offset concerns as well. */
   2708 
   2709     struct ring_elt *send_ring;
   2710 
   2711     int len;
   2712     unsigned int nummessages = 0;
   2713     SOCKET send_socket;
   2714     int bytes_remaining;
   2715     int tcp_mss = -1;  /* possibly uninitialized on printf far below */
   2716 
   2717     exs_mhandle_t exs_mhandle;
   2718     exs_qhandle_t exs_qhandle;
   2719 #define NETPERF_EXS_PENDING  16
   2720     int exs_aio_pending;
   2721     int exs_aio_eagain;
   2722     int exs_aio_dequeued;
   2723     int exs_aio_dequeuecnt;
   2724     int exs_evtcnt;
   2725 #define NETPERF_EXS_QSIZE    128
   2726     exs_event_t exs_evtvec[NETPERF_EXS_QSIZE];
   2727 
   2728     /* with links like fddi, one can send > 32 bits worth of bytes */
   2729     /* during a test... ;-) at some point, this should probably become a */
   2730     /* 64bit integral type, but those are not entirely common yet */
   2731 
   2732     double   bytes_sent = 0.0;
   2733 
   2734     float   local_cpu_utilization;
   2735     float   local_service_demand;
   2736     float   remote_cpu_utilization;
   2737     float   remote_service_demand;
   2738 
   2739     double   thruput;
   2740 
   2741     struct addrinfo *remote_res;
   2742     struct addrinfo *local_res;
   2743 
   2744     struct   tcp_stream_request_struct   *tcp_stream_request;
   2745     struct   tcp_stream_response_struct   *tcp_stream_response;
   2746     struct   tcp_stream_results_struct   *tcp_stream_result;
   2747 
   2748     tcp_stream_request  =
   2749         (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
   2750     tcp_stream_response =
   2751         (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
   2752     tcp_stream_result   =
   2753         (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
   2754 
   2755 #if 0 /* def WANT_HISTOGRAM */
   2756     time_hist = HIST_new();
   2757 #endif /* WANT_HISTOGRAM */
   2758     /* since we are now disconnected from the code that established the */
   2759     /* control socket, and since we want to be able to use different */
   2760     /* protocols and such, we are passed the name of the remote host and */
   2761     /* must turn that into the test specific addressing information. */
   2762 
   2763     /* complete_addrinfos will either succede or exit the process */
   2764     complete_addrinfos(&remote_res,
   2765                        &local_res,
   2766                        remote_host,
   2767                        SOCK_STREAM,
   2768                        IPPROTO_TCP,
   2769                        0);
   2770 
   2771     if ( print_headers ) {
   2772         print_top_test_header("EXS TCP STREAM TEST",local_res,remote_res);
   2773     }
   2774 
   2775     send_ring = NULL;
   2776     confidence_iteration = 1;
   2777     init_stat();
   2778 
   2779     /* initialize EXS API and create event queue */
   2780     if (exs_init (EXS_VERSION) == -1) {
   2781         perror ("netperf: send_exs_tcp_stream: exs_init failed");
   2782         exit (1);
   2783     }
   2784 
   2785     if ((exs_qhandle = exs_qcreate (NETPERF_EXS_QSIZE)) == EXS_QHANDLE_INVALID) {
   2786         perror ("netperf: send_exs_tcp_stream: exs_qcreate failed");
   2787         exit (1);
   2788     }
   2789     if (debug) {
   2790         fprintf (where, "send_exs_tcp_stream: qhandle=%d\n", exs_qhandle);
   2791     }
   2792 
   2793     /* we have a great-big while loop which controls the number of times */
   2794     /* we run a particular test. this is for the calculation of a */
   2795     /* confidence interval (I really should have stayed awake during */
   2796     /* probstats :). If the user did not request confidence measurement */
   2797     /* (no confidence is the default) then we will only go though the */
   2798     /* loop once. the confidence stuff originates from the folks at IBM */
   2799 
   2800     while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   2801            (confidence_iteration <= iteration_min)) {
   2802 
   2803         /* initialize a few counters. we have to remember that we might be */
   2804         /* going through the loop more than once. */
   2805 
   2806         nummessages    =   0;
   2807         bytes_sent     =   0.0;
   2808         times_up       =    0;
   2809 
   2810         /*set up the data socket                        */
   2811         send_socket = create_data_socket(local_res);
   2812 
   2813         if (send_socket == INVALID_SOCKET){
   2814             perror("netperf: send_tcp_stream: tcp stream data socket");
   2815             exit(1);
   2816         }
   2817 
   2818         if (debug) {
   2819             fprintf(where,"send_tcp_stream: send_socket obtained...\n");
   2820         }
   2821 
   2822         /* at this point, we have either retrieved the socket buffer sizes, */
   2823         /* or have tried to set them, so now, we may want to set the send */
   2824         /* size based on that (because the user either did not use a -m */
   2825         /* option, or used one with an argument of 0). If the socket buffer */
   2826         /* size is not available, we will set the send size to 4KB - no */
   2827         /* particular reason, just arbitrary... */
   2828         if (send_size == 0) {
   2829             if (lss_size > 0) {
   2830                 send_size = lss_size;
   2831             }
   2832             else {
   2833                 send_size = 4096;
   2834             }
   2835         }
   2836 
   2837         /* set-up the data buffer ring with the requested alignment and offset. */
   2838         /* note also that we have allocated a quantity */
   2839         /* of memory that is at least one send-size greater than our socket */
   2840         /* buffer size. We want to be sure that there are at least two */
   2841         /* buffers allocated - this can be a bit of a problem when the */
   2842         /* send_size is bigger than the socket size, so we must check... the */
   2843         /* user may have wanted to explicitly set the "width" of our send */
   2844         /* buffers, we should respect that wish... */
   2845         if (send_width == 0) {
   2846             send_width = (lss_size/send_size) + 1;
   2847             if (send_width == 1) send_width++;
   2848         }
   2849 
   2850         if (send_ring == NULL) {
   2851             /* only allocate the send ring once. this is a networking test, */
   2852             /* not a memory allocation test. this way, we do not need a */
   2853             /* deallocate_buffer_ring() routine, and I don't feel like */
   2854             /* writing one anyway :) raj 11/94 */
   2855             send_ring = allocate_exs_buffer_ring(send_width,
   2856                                                  send_size,
   2857                                                  local_send_align,
   2858                                                  local_send_offset,
   2859                                                  &exs_mhandle);
   2860         }
   2861 
   2862         /* If the user has requested cpu utilization measurements, we must */
   2863         /* calibrate the cpu(s). We will perform this task within the tests */
   2864         /* themselves. If the user has specified the cpu rate, then */
   2865         /* calibrate_local_cpu will return rather quickly as it will have */
   2866         /* nothing to do. If local_cpu_rate is zero, then we will go through */
   2867         /* all the "normal" calibration stuff and return the rate back. */
   2868 
   2869         if (local_cpu_usage) {
   2870             local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   2871         }
   2872 
   2873         /* Tell the remote end to do a listen. The server alters the socket */
   2874         /* paramters on the other side at this point, hence the reason for */
   2875         /* all the values being passed in the setup message. If the user did */
   2876         /* not specify any of the parameters, they will be passed as 0, which */
   2877         /* will indicate to the remote that no changes beyond the system's */
   2878         /* default should be used. Alignment is the exception, it will */
   2879         /* default to 1, which will be no alignment alterations. */
   2880 
   2881         netperf_request.content.request_type =   DO_TCP_STREAM;
   2882         tcp_stream_request->send_buf_size   =   rss_size_req;
   2883         tcp_stream_request->recv_buf_size   =   rsr_size_req;
   2884         tcp_stream_request->receive_size   =   recv_size;
   2885         tcp_stream_request->no_delay   =   rem_nodelay;
   2886         tcp_stream_request->recv_alignment   =   remote_recv_align;
   2887         tcp_stream_request->recv_offset   =   remote_recv_offset;
   2888         tcp_stream_request->measure_cpu   =   remote_cpu_usage;
   2889         tcp_stream_request->cpu_rate   =   remote_cpu_rate;
   2890         if (test_time) {
   2891             tcp_stream_request->test_length   =   test_time;
   2892         }
   2893         else {
   2894             tcp_stream_request->test_length   =   test_bytes;
   2895         }
   2896         tcp_stream_request->so_rcvavoid   =   rem_rcvavoid;
   2897         tcp_stream_request->so_sndavoid   =   rem_sndavoid;
   2898 #ifdef DIRTY
   2899         tcp_stream_request->dirty_count     =       rem_dirty_count;
   2900         tcp_stream_request->clean_count     =       rem_clean_count;
   2901 #endif /* DIRTY */
   2902         tcp_stream_request->port            =    atoi(remote_data_port);
   2903         tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
   2904         if (debug > 1) {
   2905             fprintf(where,
   2906                     "netperf: send_tcp_stream: requesting TCP stream test\n");
   2907         }
   2908 
   2909         send_request();
   2910 
   2911         /* The response from the remote will contain all of the relevant    */
   2912         /* socket parameters for this test type. We will put them back into */
   2913         /* the variables here so they can be displayed if desired.  The   */
   2914         /* remote will have calibrated CPU if necessary, and will have done   */
   2915         /* all the needed set-up we will have calibrated the cpu locally   */
   2916         /* before sending the request, and will grab the counter value right*/
   2917         /* after the connect returns. The remote will grab the counter right*/
   2918         /* after the accept call. This saves the hassle of extra messages   */
   2919         /* being sent for the TCP tests.               */
   2920 
   2921         recv_response();
   2922 
   2923         if (!netperf_response.content.serv_errno) {
   2924             if (debug)
   2925                 fprintf(where,"remote listen done.\n");
   2926             rsr_size         =   tcp_stream_response->recv_buf_size;
   2927             rss_size         =   tcp_stream_response->send_buf_size;
   2928             rem_nodelay     =   tcp_stream_response->no_delay;
   2929             remote_cpu_usage=   tcp_stream_response->measure_cpu;
   2930             remote_cpu_rate = tcp_stream_response->cpu_rate;
   2931 
   2932             /* we have to make sure that the server port number is in */
   2933             /* network order */
   2934             set_port_number(remote_res,(short)tcp_stream_response->data_port_number);
   2935 
   2936             rem_rcvavoid   = tcp_stream_response->so_rcvavoid;
   2937             rem_sndavoid   = tcp_stream_response->so_sndavoid;
   2938         }
   2939         else {
   2940             Set_errno(netperf_response.content.serv_errno);
   2941             fprintf(where,
   2942                     "netperf: remote error %d",
   2943                     netperf_response.content.serv_errno);
   2944             perror("");
   2945             fflush(where);
   2946 
   2947             exit(1);
   2948         }
   2949 
   2950 #if 0 /* def WANT_DEMO */
   2951         DEMO_STREAM_SETUP(lss_size,rsr_size)
   2952 #endif
   2953 
   2954             /*Connect up to the remote port on the data socket  */
   2955             if (connect(send_socket,
   2956                         remote_res->ai_addr,
   2957                         remote_res->ai_addrlen) == INVALID_SOCKET){
   2958                 perror("netperf: send_tcp_stream: data socket connect failed");
   2959                 exit(1);
   2960             }
   2961 
   2962         /* Data Socket set-up is finished. If there were problems, either */
   2963         /* the connect would have failed, or the previous response would */
   2964         /* have indicated a problem. I failed to see the value of the */
   2965         /* extra  message after the accept on the remote. If it failed, */
   2966         /* we'll see it here. If it didn't, we might as well start pumping */
   2967         /* data. */
   2968 
   2969         /* Set-up the test end conditions. For a stream test, they can be */
   2970         /* either time or byte-count based. */
   2971 
   2972         if (test_time) {
   2973             /* The user wanted to end the test after a period of time. */
   2974             times_up = 0;
   2975             bytes_remaining = 0;
   2976             /* in previous revisions, we had the same code repeated throught */
   2977             /* all the test suites. this was unnecessary, and meant more */
   2978             /* work for me when I wanted to switch to POSIX signals, so I */
   2979             /* have abstracted this out into a routine in netlib.c. if you */
   2980             /* are experiencing signal problems, you might want to look */
   2981             /* there. raj 11/94 */
   2982             start_timer(test_time);
   2983         }
   2984         else {
   2985             /* The tester wanted to send a number of bytes. */
   2986             bytes_remaining = test_bytes;
   2987             times_up = 1;
   2988         }
   2989 
   2990         /* The cpu_start routine will grab the current time and possibly */
   2991         /* value of the idle counter for later use in measuring cpu */
   2992         /* utilization and/or service demand and thruput. */
   2993 
   2994         cpu_start(local_cpu_usage);
   2995 
   2996 #if 0 /* def WANT_INTERVALS */
   2997 	INTERVALS_INIT();
   2998 #endif /* WANT_INTERVALS */
   2999 
   3000         /* before we start, initialize a few variables */
   3001 
   3002 #if 0 /* def WANT_DEMO */
   3003         if (demo_mode) {
   3004             HIST_timestamp(demo_one_ptr);
   3005         }
   3006 #endif
   3007 
   3008 
   3009         /* We use an "OR" to control test execution. When the test is */
   3010         /* controlled by time, the byte count check will always return false. */
   3011         /* When the test is controlled by byte count, the time test will */
   3012         /* always return false. When the test is finished, the whole */
   3013         /* expression will go false and we will stop sending data. */
   3014 
   3015         exs_aio_pending = 0;
   3016         exs_aio_eagain = 0;
   3017         exs_aio_dequeuecnt = 0;
   3018 
   3019         while ((!times_up) || (bytes_remaining > 0)) {
   3020 
   3021 #ifdef DIRTY
   3022 	  access_buffer(send_ring->buffer_ptr,
   3023 			send_size,
   3024 			loc_dirty_count,
   3025 			loc_clean_count);
   3026 #endif /* DIRTY */
   3027 
   3028 #if 0 /* def WANT_HISTOGRAM */
   3029             /* timestamp just before we go into send and then again just after */
   3030             /* we come out raj 8/94 */
   3031             HIST_timestamp(&time_one);
   3032 #endif /* WANT_HISTOGRAM */
   3033 
   3034 
   3035             /* post up to NETPERF_EXS_PENDING I/Os  */
   3036             while ((exs_aio_pending < NETPERF_EXS_PENDING) &&
   3037                    (exs_send (send_socket, send_ring->buffer_ptr, send_size,
   3038                               0, exs_qhandle, (exs_ahandle_t)-1, exs_mhandle) == 0)) {
   3039                 exs_aio_pending++;
   3040 
   3041                 /* now we want to move our pointer to the next
   3042 		   position in the data buffer...we may also want to
   3043 		   wrap back to the "beginning" of the bufferspace, so
   3044 		   we will mod the number of messages sent by the send
   3045 		   width, and use that to calculate the offset to add
   3046 		   to the base pointer. */
   3047 
   3048                 nummessages++;
   3049                 send_ring = send_ring->next;
   3050                 if (bytes_remaining) {
   3051                     bytes_remaining -= send_size;
   3052                 }
   3053             }
   3054 
   3055             /* check exs_send result */
   3056             if (exs_aio_pending < NETPERF_EXS_PENDING) {
   3057                /* standard flow control case */
   3058                 if (errno == EAGAIN)
   3059                     exs_aio_eagain++;
   3060                 /* case of times_up */
   3061                 else if (errno == EINTR)
   3062                     break;
   3063                 /* strange, let's stop */
   3064                 else {
   3065                     perror ("netperf: exs_send error");
   3066                     exit (1);
   3067                 }
   3068             }
   3069 
   3070             /* dequeue events with "threshold" on 1/2 posted */
   3071             exs_aio_dequeued =
   3072                 exs_qdequeue (exs_qhandle, exs_evtvec,
   3073                               -(exs_aio_pending>>1), NULL);
   3074             exs_aio_dequeuecnt++;
   3075 
   3076             /* check exs_dequeue result */
   3077             if (exs_aio_dequeued < 0) {
   3078                 /* case of times_up */
   3079                 if (errno == EINTR)
   3080                     break;
   3081                 /* strange, let's stop */
   3082                 else {
   3083                     perror ("netperf: exs_send error");
   3084                     exit (1);
   3085                 }
   3086             }
   3087             /* update number of pending I/Os */
   3088             else {
   3089                 exs_aio_pending -= exs_aio_dequeued;
   3090             }
   3091 
   3092 
   3093 #if 0 /* def WANT_HISTOGRAM */
   3094             /* timestamp the exit from the send call and update the histogram */
   3095             HIST_timestamp(&time_two);
   3096             HIST_add(time_hist,delta_micro(&time_one,&time_two));
   3097 #endif /* WANT_HISTOGRAM */
   3098 
   3099 #if 0 /* def WANT_DEMO */
   3100             DEMO_STREAM_INTERVAL(send_size);
   3101 #endif
   3102 
   3103 #if 0 /* def WANT_INTERVALS */
   3104 	    INTERVALS_WAIT();
   3105 #endif /* WANT_INTERVALS */
   3106 
   3107         }
   3108 
   3109         /* Collect the last completion events */
   3110         exs_aio_dequeued =
   3111             exs_qdequeue (exs_qhandle, exs_evtvec, -exs_aio_pending, NULL);
   3112         exs_aio_dequeuecnt++;
   3113         /* check exs_dequeue result and update number of pending I/Os */
   3114         if (exs_aio_dequeued < 0) {
   3115             perror ("netperf: exs_send error");
   3116             exit (1);
   3117         }
   3118         exs_aio_pending -= exs_aio_dequeued;
   3119 
   3120         /* Display some async I/O debug info */
   3121         if (debug) {
   3122             fprintf (where, "send_exs_tcp_stream: "
   3123                      "aio sent=%d eagain=%d dequeue=%d pending=%d\n",
   3124                      nummessages, exs_aio_eagain, exs_aio_dequeuecnt, exs_aio_pending);
   3125         }
   3126 
   3127         /* The test is over. Flush the buffers to the remote end. We do a */
   3128         /* graceful release to insure that all data has been taken by the */
   3129         /* remote. */
   3130 
   3131         /* but first, if the verbosity is greater than 1, find-out what */
   3132         /* the TCP maximum segment_size was (if possible) */
   3133         if (verbosity > 1) {
   3134             tcp_mss = -1;
   3135             get_tcp_info(send_socket,&tcp_mss);
   3136         }
   3137 
   3138         if (shutdown(send_socket,SHUT_WR) == SOCKET_ERROR) {
   3139             perror("netperf: cannot shutdown tcp stream socket");
   3140             exit(1);
   3141         }
   3142 
   3143         /* hang a recv() off the socket to block until the remote has */
   3144         /* brought all the data up into the application. it will do a */
   3145         /* shutdown to cause a FIN to be sent our way. We will assume that */
   3146         /* any exit from the recv() call is good... raj 4/93 */
   3147 
   3148         recv(send_socket, send_ring->buffer_ptr, send_size, 0);
   3149 
   3150         /* this call will always give us the elapsed time for the test, and */
   3151         /* will also store-away the necessaries for cpu utilization */
   3152 
   3153         cpu_stop(local_cpu_usage,&elapsed_time);   /* was cpu being */
   3154         /* measured and how */
   3155         /* long did we really */
   3156         /* run? */
   3157 
   3158         /* we are finished with the socket, so close it to prevent hitting */
   3159         /* the limit on maximum open files. */
   3160 
   3161         close(send_socket);
   3162 
   3163         /* Get the statistics from the remote end. The remote will have */
   3164         /* calculated service demand and all those interesting things. If it */
   3165         /* wasn't supposed to care, it will return obvious values. */
   3166 
   3167         recv_response();
   3168         if (!netperf_response.content.serv_errno) {
   3169             if (debug)
   3170                 fprintf(where,"remote results obtained\n");
   3171         }
   3172         else {
   3173             Set_errno(netperf_response.content.serv_errno);
   3174             fprintf(where,
   3175                     "netperf: remote error %d",
   3176                     netperf_response.content.serv_errno);
   3177             perror("");
   3178             fflush(where);
   3179 
   3180             exit(1);
   3181         }
   3182 
   3183         /* We now calculate what our thruput was for the test. In the future, */
   3184         /* we may want to include a calculation of the thruput measured by */
   3185         /* the remote, but it should be the case that for a TCP stream test, */
   3186         /* that the two numbers should be *very* close... We calculate */
   3187         /* bytes_sent regardless of the way the test length was controlled. */
   3188         /* If it was time, we needed to, and if it was by bytes, the user may */
   3189         /* have specified a number of bytes that wasn't a multiple of the */
   3190         /* send_size, so we really didn't send what he asked for ;-) */
   3191 
   3192         bytes_sent   = ntohd(tcp_stream_result->bytes_received);
   3193 
   3194         thruput   = calc_thruput(bytes_sent);
   3195 
   3196         if (local_cpu_usage || remote_cpu_usage) {
   3197             /* We must now do a little math for service demand and cpu */
   3198             /* utilization for the system(s) */
   3199             /* Of course, some of the information might be bogus because */
   3200             /* there was no idle counter in the kernel(s). We need to make */
   3201             /* a note of this for the user's benefit...*/
   3202             if (local_cpu_usage) {
   3203 
   3204                 local_cpu_utilization   = calc_cpu_util(0.0);
   3205                 local_service_demand   = calc_service_demand(bytes_sent,
   3206                                                              0.0,
   3207                                                              0.0,
   3208                                                              0);
   3209             }
   3210             else {
   3211                 local_cpu_utilization   = (float) -1.0;
   3212                 local_service_demand   = (float) -1.0;
   3213             }
   3214 
   3215             if (remote_cpu_usage) {
   3216 
   3217                 remote_cpu_utilization   = tcp_stream_result->cpu_util;
   3218                 remote_service_demand   = calc_service_demand(bytes_sent,
   3219                                                               0.0,
   3220                                                               remote_cpu_utilization,
   3221                                                               tcp_stream_result->num_cpus);
   3222             }
   3223             else {
   3224                 remote_cpu_utilization = (float) -1.0;
   3225                 remote_service_demand  = (float) -1.0;
   3226             }
   3227         }
   3228         else {
   3229             /* we were not measuring cpu, for the confidence stuff, we */
   3230             /* should make it -1.0 */
   3231             local_cpu_utilization   = (float) -1.0;
   3232             local_service_demand   = (float) -1.0;
   3233             remote_cpu_utilization = (float) -1.0;
   3234             remote_service_demand  = (float) -1.0;
   3235         }
   3236 
   3237         /* at this point, we want to calculate the confidence information. */
   3238         /* if debugging is on, calculate_confidence will print-out the */
   3239         /* parameters we pass it */
   3240 
   3241         calculate_confidence(confidence_iteration,
   3242                              elapsed_time,
   3243                              thruput,
   3244                              local_cpu_utilization,
   3245                              remote_cpu_utilization,
   3246                              local_service_demand,
   3247                              remote_service_demand);
   3248 
   3249 
   3250         confidence_iteration++;
   3251     }
   3252 
   3253     /* at this point, we have finished making all the runs that we */
   3254     /* will be making. so, we should extract what the calcuated values */
   3255     /* are for all the confidence stuff. we could make the values */
   3256     /* global, but that seemed a little messy, and it did not seem worth */
   3257     /* all the mucking with header files. so, we create a routine much */
   3258     /* like calcualte_confidence, which just returns the mean values. */
   3259     /* raj 11/94 */
   3260 
   3261     retrieve_confident_values(&elapsed_time,
   3262                               &thruput,
   3263                               &local_cpu_utilization,
   3264                               &remote_cpu_utilization,
   3265                               &local_service_demand,
   3266                               &remote_service_demand);
   3267 
   3268     /* We are now ready to print all the information. If the user */
   3269     /* has specified zero-level verbosity, we will just print the */
   3270     /* local service demand, or the remote service demand. If the */
   3271     /* user has requested verbosity level 1, he will get the basic */
   3272     /* "streamperf" numbers. If the user has specified a verbosity */
   3273     /* of greater than 1, we will display a veritable plethora of */
   3274     /* background information from outside of this block as it it */
   3275     /* not cpu_measurement specific...  */
   3276 
   3277     if (confidence < 0) {
   3278         /* we did not hit confidence, but were we asked to look for it? */
   3279         if (iteration_max > 1) {
   3280             display_confidence();
   3281         }
   3282     }
   3283 
   3284     if (local_cpu_usage || remote_cpu_usage) {
   3285         local_cpu_method = format_cpu_method(cpu_method);
   3286         remote_cpu_method = format_cpu_method(tcp_stream_result->cpu_method);
   3287 
   3288         switch (verbosity) {
   3289             case 0:
   3290                 if (local_cpu_usage) {
   3291                     fprintf(where,
   3292                             cpu_fmt_0,
   3293                             local_service_demand,
   3294                             local_cpu_method);
   3295                 }
   3296                 else {
   3297                     fprintf(where,
   3298                             cpu_fmt_0,
   3299                             remote_service_demand,
   3300                             remote_cpu_method);
   3301                 }
   3302                 break;
   3303             case 1:
   3304             case 2:
   3305                 if (print_headers) {
   3306                     fprintf(where,
   3307                             cpu_title,
   3308                             format_units(),
   3309                             local_cpu_method,
   3310                             remote_cpu_method);
   3311                 }
   3312 
   3313                 fprintf(where,
   3314                         cpu_fmt_1,      /* the format string */
   3315                         rsr_size,              /* remote recvbuf size */
   3316                         lss_size,              /* local sendbuf size */
   3317                         send_size,      /* how large were the sends */
   3318                         elapsed_time,      /* how long was the test */
   3319                         thruput,               /* what was the xfer rate */
   3320                         local_cpu_utilization,   /* local cpu */
   3321                         remote_cpu_utilization,   /* remote cpu */
   3322                         local_service_demand,   /* local service demand */
   3323                         remote_service_demand);   /* remote service demand */
   3324                 break;
   3325         }
   3326     }
   3327     else {
   3328         /* The tester did not wish to measure service demand. */
   3329 
   3330         switch (verbosity) {
   3331             case 0:
   3332                 fprintf(where,
   3333                         tput_fmt_0,
   3334                         thruput);
   3335                 break;
   3336             case 1:
   3337             case 2:
   3338                 if (print_headers) {
   3339                     fprintf(where,tput_title,format_units());
   3340                 }
   3341                 fprintf(where,
   3342                         tput_fmt_1,      /* the format string */
   3343                         rsr_size,       /* remote recvbuf size */
   3344                         lss_size,       /* local sendbuf size */
   3345                         send_size,      /* how large were the sends */
   3346                         elapsed_time,       /* how long did it take */
   3347                         thruput);/* how fast did it go */
   3348                 break;
   3349         }
   3350     }
   3351 
   3352     /* it would be a good thing to include information about some of the */
   3353     /* other parameters that may have been set for this test, but at the */
   3354     /* moment, I do not wish to figure-out all the  formatting, so I will */
   3355     /* just put this comment here to help remind me that it is something */
   3356     /* that should be done at a later time. */
   3357 
   3358     if (verbosity > 1) {
   3359         /* The user wanted to know it all, so we will give it to him. */
   3360         /* This information will include as much as we can find about */
   3361         /* TCP statistics, the alignments of the sends and receives */
   3362         /* and all that sort of rot... */
   3363 
   3364         /* this stuff needs to be worked-out in the presence of confidence */
   3365         /* intervals and multiple iterations of the test... raj 11/94 */
   3366 
   3367         fprintf(where,
   3368                 ksink_fmt,
   3369                 "Bytes",
   3370                 "Bytes",
   3371                 "Bytes",
   3372                 local_send_align,
   3373                 remote_recv_align,
   3374                 local_send_offset,
   3375                 remote_recv_offset,
   3376                 bytes_sent,
   3377                 bytes_sent / (double)nummessages,
   3378                 nummessages,
   3379                 bytes_sent / (double)tcp_stream_result->recv_calls,
   3380                 tcp_stream_result->recv_calls);
   3381         fprintf(where,
   3382                 ksink_fmt2,
   3383                 tcp_mss);
   3384         fflush(where);
   3385 #if 0 /* def WANT_HISTOGRAM */
   3386         fprintf(where,"\n\nHistogram of time spent in send() call.\n");
   3387         fflush(where);
   3388         HIST_report(time_hist);
   3389 #endif /* WANT_HISTOGRAM */
   3390     }
   3391 
   3392 }
   3393 
   3394 #endif /* HAVE_ICSC_EXS */
   3395 
   3396 
   3397 
   3399 #if defined(HAVE_SENDFILE)
   3400 
   3401 #if defined(QUICK_SENDPATH)
   3402 
   3403 /*
   3404  * a temporary stub for the sendpath() system call
   3405  * which is defined & implemented in the kernel
   3406  * but which has no libc stub.
   3407  */
   3408 #include <sys/types.h>
   3409 #include <sys/scall_define.h>
   3410 #include <sys/uio.h>
   3411 
   3412 ssize_t
   3413 sendpath(int s, char *path, off_t offset, size_t nbytes,
   3414 	 const struct iovec *hdtrl, int flags)
   3415   {
   3416     return syscall(SYS_sendpath, s, path, offset, nbytes, hdtrl, flags);
   3417   }
   3418 #endif /* QUICK_SENDPATH */
   3419 
   3420 /* This routine implements the TCP unidirectional data transfer test
   3421    (a.k.a. stream) for the sockets interface using the sendfile()
   3422    system call - TCP_SENDFILE.  It receives its  parameters via global
   3423    variables from the shell and writes its  output to the standard
   3424    output. Basically,  this is the same test as the send_tcp_stream()
   3425    logic and we even tell the remote to do a TCP_STREAM test since for
   3426    all it knows, nothig is different. */
   3427 
   3428 void
   3429 sendfile_tcp_stream(remote_host)
   3430      char	remote_host[];
   3431 {
   3432 
   3433   char *tput_title = "\
   3434 Recv   Send    Send                          \n\
   3435 Socket Socket  Message  Elapsed              \n\
   3436 Size   Size    Size     Time     Throughput  \n\
   3437 bytes  bytes   bytes    secs.    %s/sec  \n\n";
   3438 
   3439   char *tput_fmt_0 =
   3440     "%7.2f\n";
   3441 
   3442   char *tput_fmt_1 =
   3443     "%6d %6d %6d    %-6.2f   %7.2f   \n";
   3444 
   3445   char *cpu_title = "\
   3446 Recv   Send    Send                          Utilization       Service Demand\n\
   3447 Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
   3448 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
   3449 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
   3450 
   3451   char *cpu_fmt_0 =
   3452     "%6.3f %c\n";
   3453   char *cpu_fmt_1 =
   3454     "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f\n";
   3455 
   3456   char *ksink_fmt = "\n\
   3457 Alignment      Offset         %-8.8s %-8.8s    Sends   %-8.8s Recvs\n\
   3458 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
   3459 Send   Recv    Send   Recv             Send (avg)          Recv (avg)\n\
   3460 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
   3461 
   3462 char *ksink_fmt2 = "\n\
   3463 Maximum\n\
   3464 Segment\n\
   3465 Size (bytes)\n\
   3466 %6d\n";
   3467 
   3468   float			elapsed_time;
   3469 
   3470   /* what we want is to have a buffer space that is at least one */
   3471   /* send-size greater than our send window. this will insure that we */
   3472   /* are never trying to re-use a buffer that may still be in the hands */
   3473   /* of the transport. This buffer will be malloc'd after we have found */
   3474   /* the size of the local senc socket buffer. We will want to deal */
   3475   /* with alignment and offset concerns as well. */
   3476 
   3477   struct sendfile_ring_elt *send_ring;
   3478 
   3479   int len;
   3480   unsigned int nummessages = 0;
   3481   SOCKET send_socket;
   3482   int bytes_remaining;
   3483   int tcp_mss = -1;  /* possibly uninitialized on printf far below */
   3484 
   3485   /* with links like fddi, one can send > 32 bits worth of bytes */
   3486   /* during a test... ;-) at some point, this should probably become a */
   3487   /* 64bit integral type, but those are not entirely common yet */
   3488   double	bytes_sent = 0.0;
   3489 
   3490   float	local_cpu_utilization;
   3491   float	local_service_demand;
   3492   float	remote_cpu_utilization;
   3493   float	remote_service_demand;
   3494 
   3495   double	thruput;
   3496 
   3497   struct  addrinfo *remote_res;
   3498   struct  addrinfo *local_res;
   3499   struct	sockaddr_in	server;
   3500 
   3501 #if defined(__linux) || defined(__sun__)
   3502   off_t     scratch_offset;   /* the linux sendfile() call will update
   3503 				 the offset variable, which is
   3504 				 something we do _not_ want to happen
   3505 				 to the value in the send_ring! so, we
   3506 				 have to use a scratch variable. */
   3507 #endif /* __linux  || defined(__sun__) */
   3508 #if defined (USE_OSX)
   3509    off_t    scratch_len;  /* Darwin 9.x need a value-result parameter  */
   3510 #endif
   3511 #if defined (__sun__)
   3512    size_t  scratch_len;	/* the sun sendfilev() needs a place to
   3513 			   tell us how many bytes were written,
   3514 			   even though it also returns the value */
   3515    sendfilevec_t sv;
   3516 #endif /* __sun__ */
   3517 
   3518   struct	tcp_stream_request_struct	*tcp_stream_request;
   3519   struct	tcp_stream_response_struct	*tcp_stream_response;
   3520   struct	tcp_stream_results_struct	*tcp_stream_result;
   3521 
   3522   tcp_stream_request  =
   3523     (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
   3524   tcp_stream_response =
   3525     (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
   3526   tcp_stream_result   =
   3527     (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
   3528 
   3529 #ifdef WANT_HISTOGRAM
   3530   if (verbosity > 1) {
   3531     time_hist = HIST_new();
   3532   }
   3533 #endif /* WANT_HISTOGRAM */
   3534 
   3535   /* since we are now disconnected from the code that established the */
   3536   /* control socket, and since we want to be able to use different */
   3537   /* protocols and such, we are passed the name of the remote host and */
   3538   /* must turn that into the test specific addressing information. */
   3539 
   3540   bzero((char *)&server,
   3541 	sizeof(server));
   3542 
   3543   complete_addrinfos(&remote_res,
   3544 		     &local_res,
   3545 		     remote_host,
   3546 		     SOCK_STREAM,
   3547 		     IPPROTO_TCP,
   3548 		     0);
   3549 
   3550   if ( print_headers ) {
   3551     /* we want to have some additional, interesting information in */
   3552     /* the headers. we know some of it here, but not all, so we will */
   3553     /* only print the test title here and will print the results */
   3554     /* titles after the test is finished */
   3555 #ifdef QUICK_SENDPATH
   3556     print_top_test_header("TCP SENDPATH TEST",local_res,remote_res);
   3557 #else
   3558     print_top_test_header("TCP SENDFILE TEST",local_res,remote_res);
   3559 #endif /* QUICK_SENDPATH */
   3560   }
   3561   send_ring = NULL;
   3562   confidence_iteration = 1;
   3563   init_stat();
   3564 
   3565   /* we have a great-big while loop which controls the number of times */
   3566   /* we run a particular test. this is for the calculation of a */
   3567   /* confidence interval (I really should have stayed awake during */
   3568   /* probstats :). If the user did not request confidence measurement */
   3569   /* (no confidence is the default) then we will only go though the */
   3570   /* loop once. the confidence stuff originates from the folks at IBM */
   3571 
   3572   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   3573 	 (confidence_iteration <= iteration_min)) {
   3574 
   3575     /* initialize a few counters. we have to remember that we might be */
   3576     /* going through the loop more than once. */
   3577 
   3578     nummessages    =	0;
   3579     bytes_sent     =	0.0;
   3580     times_up       = 	0;
   3581 
   3582     /* set up the data socket */
   3583     send_socket = create_data_socket(local_res);
   3584 
   3585     if (send_socket == INVALID_SOCKET){
   3586       perror("netperf: sendfile_tcp_stream: tcp stream data socket");
   3587       exit(1);
   3588     }
   3589 
   3590     if (debug) {
   3591       fprintf(where,"sendfile_tcp_stream: send_socket obtained...\n");
   3592     }
   3593 
   3594 #if defined(TCP_CORK)
   3595     /* should this even be here?!? */
   3596     if (loc_tcpcork != 0) {
   3597       /* the user wishes for us to set TCP_CORK on the socket */
   3598       int one = 1;
   3599       if (setsockopt(send_socket,
   3600 		     getprotobyname("tcp")->p_proto,
   3601 		     TCP_CORK,
   3602 		     (char *)&one,
   3603 		     sizeof(one)) == SOCKET_ERROR) {
   3604 	perror("netperf: sendfile_tcp_stream: tcp_cork");
   3605 	exit(1);
   3606       }
   3607       if (debug) {
   3608 	fprintf(where,"sendfile_tcp_stream: tcp_cork...\n");
   3609       }
   3610     }
   3611 
   3612 #endif /* TCP_CORK */
   3613 
   3614     /* at this point, we have either retrieved the socket buffer sizes, */
   3615     /* or have tried to set them, so now, we may want to set the send */
   3616     /* size based on that (because the user either did not use a -m */
   3617     /* option, or used one with an argument of 0). If the socket buffer */
   3618     /* size is not available, we will set the send size to 4KB - no */
   3619     /* particular reason, just arbitrary... */
   3620 
   3621     /*check for file size/ min file size here?  create file here/ back out???*/
   3622 
   3623     if (send_size == 0) {
   3624       if (lss_size > 0) {
   3625 	send_size = lss_size;
   3626       }
   3627       else {
   3628 	send_size = 4096;
   3629       }
   3630     }
   3631 
   3632     /* set-up the data buffer ring with the requested alignment and
   3633        offset. note also that we have allocated a quantity  of memory
   3634        that is at least one send-size greater than our socket  buffer
   3635        size. We want to be sure that there are at least two  buffers
   3636        allocated - this can be a bit of a problem when the  send_size
   3637        is bigger than the socket size, so we must check... the  user
   3638        may have wanted to explicitly set the "width" of our send
   3639        buffers, we should respect that wish... */
   3640 
   3641     /*sendring -> an offset index that will shift the starting point of the*/
   3642     /*section of the file sent throughout the file*/
   3643 
   3644     if (send_width == 0) {
   3645       send_width = (lss_size/send_size) + 1;
   3646       if (send_width == 1) send_width++;
   3647     }
   3648 
   3649     if (send_ring == NULL) {
   3650 
   3651       /* only allocate the send ring once. this is a networking test,
   3652 	 not a memory allocation test. this way, we do not need a
   3653 	 deallocate_buffer_ring() routine, and I don't feel like
   3654 	 writing one anyway :) raj 11/94 */
   3655 
   3656       send_ring = alloc_sendfile_buf_ring(send_width,
   3657 					  send_size,
   3658 					  local_send_align,
   3659 					  local_send_offset);
   3660     }
   3661 
   3662     /* If the user has requested cpu utilization measurements, we must
   3663        calibrate the cpu(s). We will perform this task within the
   3664        tests  themselves. If the user has specified the cpu rate, then
   3665        calibrate_local_cpu will return rather quickly as it will have
   3666        nothing to do. If local_cpu_rate is zero, then we will go
   3667        through  all the "normal" calibration stuff and return the rate
   3668        back. */
   3669 
   3670     if (local_cpu_usage) {
   3671       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   3672     }
   3673 
   3674     /* Tell the remote end to do a listen. The server alters the
   3675        socket  paramters on the other side at this point, hence the
   3676        reason for  all the values being passed in the setup
   3677        message. If the user did  not specify any of the parameters,
   3678        they will be passed as 0, which  will indicate to the remote
   3679        that no changes beyond the system's  default should be
   3680        used. Alignment is the exception, it will  default to 1, which
   3681        will be no alignment alterations. */
   3682 
   3683     netperf_request.content.request_type =	DO_TCP_STREAM;
   3684     tcp_stream_request->send_buf_size	=	rss_size_req;
   3685     tcp_stream_request->recv_buf_size	=	rsr_size_req;
   3686     tcp_stream_request->receive_size	=	recv_size;
   3687     tcp_stream_request->no_delay	=	rem_nodelay;
   3688     tcp_stream_request->recv_alignment	=	remote_recv_align;
   3689     tcp_stream_request->recv_offset	=	remote_recv_offset;
   3690     tcp_stream_request->measure_cpu	=	remote_cpu_usage;
   3691     tcp_stream_request->cpu_rate	=	remote_cpu_rate;
   3692 
   3693     if (test_time) {
   3694       tcp_stream_request->test_length	=	test_time;
   3695     }
   3696     else {
   3697       tcp_stream_request->test_length	=	test_bytes;
   3698     }
   3699 
   3700     tcp_stream_request->so_rcvavoid	=	rem_rcvavoid;
   3701     tcp_stream_request->so_sndavoid	=	rem_sndavoid;
   3702 
   3703 #ifdef DIRTY
   3704     tcp_stream_request->dirty_count       =       rem_dirty_count;
   3705     tcp_stream_request->clean_count       =       rem_clean_count;
   3706 #endif /* DIRTY */
   3707     tcp_stream_request->port     = atoi(remote_data_port);
   3708     tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
   3709 
   3710     if (debug > 1) {
   3711       fprintf(where,
   3712 	      "netperf: send_tcp_stream: requesting TCP stream test\n");
   3713     }
   3714 
   3715     send_request();
   3716 
   3717     /* The response from the remote will contain all of the relevant
   3718        socket parameters for this test type. We will put them back
   3719        into the variables here so they can be displayed if desired.
   3720        The remote will have calibrated CPU if necessary, and will have
   3721        done all the needed set-up we will have calibrated the cpu
   3722        locally before sending the request, and will grab the counter
   3723        value right after the connect returns. The remote will grab the
   3724        counter right after the accept call. This saves the hassle of
   3725        extra messages being sent for the TCP tests.  */
   3726 
   3727     recv_response();
   3728 
   3729     if (!netperf_response.content.serv_errno) {
   3730       if (debug)
   3731 	fprintf(where,"remote listen done.\n");
   3732       rsr_size	      =	tcp_stream_response->recv_buf_size;
   3733       rss_size	      =	tcp_stream_response->send_buf_size;
   3734       rem_nodelay     =	tcp_stream_response->no_delay;
   3735       remote_cpu_usage=	tcp_stream_response->measure_cpu;
   3736       remote_cpu_rate = tcp_stream_response->cpu_rate;
   3737 
   3738       /* we have to make sure that the server port number is in */
   3739       /* network order */
   3740       set_port_number(remote_res,(short)tcp_stream_response->data_port_number);
   3741       rem_rcvavoid	= tcp_stream_response->so_rcvavoid;
   3742       rem_sndavoid	= tcp_stream_response->so_sndavoid;
   3743     }
   3744     else {
   3745       Set_errno(netperf_response.content.serv_errno);
   3746       fprintf(where,
   3747 	      "netperf: remote error %d",
   3748 	      netperf_response.content.serv_errno);
   3749       perror("");
   3750       fflush(where);
   3751 
   3752       exit(1);
   3753     }
   3754 
   3755 #ifdef WANT_DEMO
   3756     DEMO_STREAM_SETUP(lss_size,rsr_size)
   3757 #endif
   3758 
   3759     /*Connect up to the remote port on the data socket  */
   3760     if (connect(send_socket,
   3761 		remote_res->ai_addr,
   3762 		remote_res->ai_addrlen) == INVALID_SOCKET){
   3763       perror("netperf: send_tcp_stream: data socket connect failed");
   3764       printf(" port: %d\n",ntohs(server.sin_port));
   3765       exit(1);
   3766     }
   3767 
   3768     /* Data Socket set-up is finished. If there were problems, either
   3769        the connect would have failed, or the previous response would
   3770        have indicated a problem. I failed to see the value of the
   3771        extra message after the accept on the remote. If it failed,
   3772        we'll see it here. If it didn't, we might as well start pumping
   3773        data. */
   3774 
   3775     /* Set-up the test end conditions. For a stream test, they can be */
   3776     /* either time or byte-count based. */
   3777 
   3778     if (test_time) {
   3779       /* The user wanted to end the test after a period of time. */
   3780       times_up = 0;
   3781       bytes_remaining = 0;
   3782 
   3783       /* in previous revisions, we had the same code repeated throught
   3784          all the test suites. this was unnecessary, and meant more
   3785          work for me when I wanted to switch to POSIX signals, so I
   3786          have abstracted this out into a routine in netlib.c. if you
   3787          are experiencing signal problems, you might want to look
   3788          there. raj 11/94 */
   3789 
   3790       start_timer(test_time);
   3791     }
   3792     else {
   3793       /* The tester wanted to send a number of bytes. */
   3794       bytes_remaining = test_bytes;
   3795       times_up = 1;
   3796     }
   3797 
   3798     /* The cpu_start routine will grab the current time and possibly */
   3799     /* value of the idle counter for later use in measuring cpu */
   3800     /* utilization and/or service demand and thruput. */
   3801 
   3802     cpu_start(local_cpu_usage);
   3803 
   3804 #ifdef WANT_INTERVALS
   3805     INTERVALS_INIT();
   3806 #endif /* WANT_INTERVALS */
   3807 
   3808 
   3809     /* before we start, initialize a few variables */
   3810 
   3811 #ifdef WANT_DEMO
   3812     if (demo_mode) {
   3813       HIST_timestamp(demo_one_ptr);
   3814     }
   3815 #endif
   3816 
   3817     /* We use an "OR" to control test execution. When the test is
   3818        controlled by time, the byte count check will always return
   3819        false. When the test is controlled by byte count, the time test
   3820        will always return false. When the test is finished, the whole
   3821        expression will go false and we will stop sending data. */
   3822 
   3823     while ((!times_up) || (bytes_remaining > 0)) {
   3824 
   3825       /* the sendfile_tcp_stream test does not support making the buffers
   3826 	 dirty. 08/2000 */
   3827 
   3828 #ifdef WANT_HISTOGRAM
   3829       if (verbosity > 1) {
   3830 	/* timestamp just before we go into sendfile() and then again
   3831          just after we come out raj 08/2000 */
   3832 	/* but only if we are actually going to display a histogram */
   3833 	HIST_timestamp(&time_one);
   3834       }
   3835 #endif /* WANT_HISTOGRAM */
   3836 
   3837       /* you can look at netlib.h for a description of the fields we
   3838 	 are passing to sendfile(). 08/2000 */
   3839 #ifdef QUICK_SENDPATH
   3840       if ((len=sendpath(send_socket,
   3841 			fill_file,
   3842 			send_ring->offset,
   3843 			send_ring->length,
   3844 			send_ring->hdtrl,
   3845 			send_ring->flags)) != send_size)
   3846 #elif defined(__linux)
   3847 	scratch_offset = send_ring->offset;
   3848       if ((len=sendfile(send_socket,
   3849 			send_ring->fildes,
   3850 			&scratch_offset,   /* modified after the call! */
   3851 			send_ring->length)) != send_size)
   3852 #elif defined (__sun__)
   3853       /* We must call with SFV_NOWAIT and a large file size (>= 16MB) to
   3854 	 get zero-copy, as well as compiling with  -D_LARGEFILE_SOURCE
   3855 	  -D_FILE_OFFSET_BITS=64 */
   3856       sv.sfv_fd = send_ring->fildes;
   3857       sv.sfv_flag = SFV_NOWAIT;
   3858       sv.sfv_off = send_ring->offset;
   3859       sv.sfv_len =  send_ring->length;
   3860       if ((len = sendfilev(send_socket, &sv, 1, &scratch_len)) != send_size)
   3861 #elif defined(__FreeBSD__)
   3862 	/* so close to HP-UX and yet so far away... :) */
   3863 	if ((sendfile(send_ring->fildes,
   3864 		      send_socket,
   3865 		      send_ring->offset,
   3866 		      send_ring->length,
   3867 		      NULL,
   3868 		      (off_t *)&len,
   3869 		      send_ring->flags) != 0) ||
   3870 	    (len != send_size))
   3871 #elif defined(USE_OSX)
   3872     scratch_len = send_ring->length;
   3873     if ((sendfile(send_ring->fildes,
   3874               send_socket,
   3875               send_ring->offset,
   3876               (off_t *)&scratch_len,
   3877               NULL,
   3878               send_ring->flags) != 0) ||
   3879         (scratch_len != send_size))
   3880 #else /* original sendile HP-UX */
   3881 	  if ((len=sendfile(send_socket,
   3882 			    send_ring->fildes,
   3883 			    send_ring->offset,
   3884 			    send_ring->length,
   3885 			    send_ring->hdtrl,
   3886 			    send_ring->flags)) != send_size)
   3887 #endif /* QUICK_SENDPATH */
   3888 	    {
   3889 	      /* the test was interrupted, must be the end of test. the
   3890 		 send_tcp_stream code has some WIN32 ifdefs that we do not
   3891 		 need here. */
   3892 	      if ((len >=0) || SOCKET_EINTR(len)) {
   3893 		break;
   3894 	      }
   3895 	      perror("netperf: data send error: sendfile");
   3896 	      fprintf(stderr,
   3897 		      "len was %d send_size was %d\n",
   3898 		      len,
   3899 		      send_size);
   3900 	      fflush(stderr);
   3901 	      exit(1);
   3902 	    }
   3903 
   3904       /*	offset += len;*/
   3905 
   3906 #ifdef WANT_HISTOGRAM
   3907       if (verbosity > 1) {
   3908 	/* timestamp the exit from the send call and update the
   3909 	   histogram */
   3910 
   3911 	HIST_timestamp(&time_two);
   3912 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   3913       }
   3914 #endif /* WANT_HISTOGRAM */
   3915 
   3916 #ifdef WANT_DEMO
   3917       DEMO_STREAM_INTERVAL(send_size);
   3918 #endif
   3919 
   3920 #ifdef WANT_INTERVALS
   3921       INTERVALS_WAIT();
   3922 #endif /* WANT_INTERVALS */
   3923 
   3924       /* now we want to move our pointer to the next position in the */
   3925       /* data buffer...we may also want to wrap back to the "beginning" */
   3926       /* of the bufferspace, so we will mod the number of messages sent */
   3927       /* by the send width, and use that to calculate the offset to add */
   3928       /* to the base pointer. */
   3929 
   3930       nummessages++;
   3931       send_ring = send_ring->next;
   3932       if (bytes_remaining) {
   3933 	bytes_remaining -= send_size;
   3934       }
   3935     }
   3936 
   3937     /* The test is over. Flush the buffers to the remote end. We do a
   3938        graceful release to insure that all data has been taken by the
   3939        remote. */
   3940 
   3941     /* but first, if the verbosity is greater than 1, find-out what */
   3942     /* the TCP maximum segment_size was (if possible) */
   3943     if (verbosity > 1) {
   3944       tcp_mss = -1;
   3945       get_tcp_info(send_socket,&tcp_mss);
   3946     }
   3947 
   3948     if (shutdown(send_socket,SHUT_WR) == SOCKET_ERROR) {
   3949       perror("netperf: cannot shutdown tcp stream socket");
   3950       exit(1);
   3951     }
   3952 
   3953     /* hang a recv() off the socket to block until the remote has */
   3954     /* brought all the data up into the application. it will do a */
   3955     /* shutdown to cause a FIN to be sent our way. We will assume that */
   3956     /* any exit from the recv() call is good... raj 4/93 */
   3957 
   3958     /* since we are using sendfile() instead of send, we have no
   3959        scratch buffer from the send_ring to use for the
   3960        receive. however, since we "know" that the recv should be
   3961        returning zero bytes (not that we are making the checks we
   3962        should) we can pass the address of the flags field. raj 08/2000
   3963     */
   3964 
   3965     recv(send_socket,
   3966 	 &(send_ring->flags),
   3967 	 sizeof(send_ring->flags),
   3968 	 0);
   3969 
   3970     /* this call will always give us the elapsed time for the test, and */
   3971     /* will also store-away the necessaries for cpu utilization */
   3972 
   3973     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
   3974 						/* measured and how */
   3975 						/* long did we really */
   3976 						/* run? */
   3977 
   3978     /* we are finished with the socket, so close it to prevent hitting */
   3979     /* the limit on maximum open files. */
   3980 
   3981     close(send_socket);
   3982 
   3983     /* Get the statistics from the remote end. The remote will have */
   3984     /* calculated service demand and all those interesting things. If it */
   3985     /* wasn't supposed to care, it will return obvious values. */
   3986 
   3987     recv_response();
   3988 
   3989     if (!netperf_response.content.serv_errno) {
   3990       if (debug)
   3991 	fprintf(where,"remote results obtained\n");
   3992     }
   3993 
   3994     else {
   3995       Set_errno(netperf_response.content.serv_errno);
   3996       fprintf(where,
   3997 	      "netperf: remote error %d",
   3998 	      netperf_response.content.serv_errno);
   3999       perror("");
   4000       fflush(where);
   4001 
   4002       exit(1);
   4003     }
   4004 
   4005     /* We now calculate what our thruput was for the test. In the future, */
   4006     /* we may want to include a calculation of the thruput measured by */
   4007     /* the remote, but it should be the case that for a TCP stream test, */
   4008     /* that the two numbers should be *very* close... We calculate */
   4009     /* bytes_sent regardless of the way the test length was controlled. */
   4010     /* If it was time, we needed to, and if it was by bytes, the user may */
   4011     /* have specified a number of bytes that wasn't a multiple of the */
   4012     /* send_size, so we really didn't send what he asked for ;-) */
   4013 
   4014     bytes_sent	= ntohd(tcp_stream_result->bytes_received);
   4015 
   4016     thruput	= calc_thruput(bytes_sent);
   4017 
   4018     if (local_cpu_usage || remote_cpu_usage) {
   4019 
   4020       /* We must now do a little math for service demand and cpu */
   4021       /* utilization for the system(s) */
   4022       /* Of course, some of the information might be bogus because */
   4023       /* there was no idle counter in the kernel(s). We need to make */
   4024       /* a note of this for the user's benefit...*/
   4025       if (local_cpu_usage) {
   4026 
   4027 	local_cpu_utilization	= calc_cpu_util(0.0);
   4028 	local_service_demand	= calc_service_demand(bytes_sent,
   4029 						      0.0,
   4030 						      0.0,
   4031 						      0);
   4032       }
   4033       else {
   4034 	local_cpu_utilization	= (float) -1.0;
   4035 	local_service_demand	= (float) -1.0;
   4036       }
   4037 
   4038       if (remote_cpu_usage) {
   4039 
   4040 	remote_cpu_utilization	= tcp_stream_result->cpu_util;
   4041 	remote_service_demand	= calc_service_demand(bytes_sent,
   4042 						      0.0,
   4043 						      remote_cpu_utilization,
   4044 						      tcp_stream_result->num_cpus);
   4045       }
   4046       else {
   4047 	remote_cpu_utilization = (float) -1.0;
   4048 	remote_service_demand  = (float) -1.0;
   4049       }
   4050     }
   4051     else {
   4052       /* we were not measuring cpu, for the confidence stuff, we */
   4053       /* should make it -1.0 */
   4054       local_cpu_utilization	= (float) -1.0;
   4055       local_service_demand	= (float) -1.0;
   4056       remote_cpu_utilization = (float) -1.0;
   4057       remote_service_demand  = (float) -1.0;
   4058     }
   4059 
   4060     /* at this point, we want to calculate the confidence information. */
   4061     /* if debugging is on, calculate_confidence will print-out the */
   4062     /* parameters we pass it */
   4063 
   4064     calculate_confidence(confidence_iteration,
   4065 			 elapsed_time,
   4066 			 thruput,
   4067 			 local_cpu_utilization,
   4068 			 remote_cpu_utilization,
   4069 			 local_service_demand,
   4070 			 remote_service_demand);
   4071 
   4072     confidence_iteration++;
   4073   }
   4074 
   4075   /* at this point, we have finished making all the runs that we */
   4076   /* will be making. so, we should extract what the calcuated values */
   4077   /* are for all the confidence stuff. we could make the values */
   4078   /* global, but that seemed a little messy, and it did not seem worth */
   4079   /* all the mucking with header files. so, we create a routine much */
   4080   /* like calcualte_confidence, which just returns the mean values. */
   4081   /* raj 11/94 */
   4082 
   4083   retrieve_confident_values(&elapsed_time,
   4084 			    &thruput,
   4085 			    &local_cpu_utilization,
   4086 			    &remote_cpu_utilization,
   4087 			    &local_service_demand,
   4088 			    &remote_service_demand);
   4089 
   4090   /* We are now ready to print all the information. If the user */
   4091   /* has specified zero-level verbosity, we will just print the */
   4092   /* local service demand, or the remote service demand. If the */
   4093   /* user has requested verbosity level 1, he will get the basic */
   4094   /* "streamperf" numbers. If the user has specified a verbosity */
   4095   /* of greater than 1, we will display a veritable plethora of */
   4096   /* background information from outside of this block as it it */
   4097   /* not cpu_measurement specific...  */
   4098 
   4099   if (confidence < 0) {
   4100     /* we did not hit confidence, but were we asked to look for it? */
   4101     if (iteration_max > 1) {
   4102       display_confidence();
   4103     }
   4104   }
   4105 
   4106   if (local_cpu_usage || remote_cpu_usage) {
   4107     local_cpu_method = format_cpu_method(cpu_method);
   4108     remote_cpu_method = format_cpu_method(tcp_stream_result->cpu_method);
   4109 
   4110     switch (verbosity) {
   4111     case 0:
   4112 
   4113     if (local_cpu_usage) {
   4114 	fprintf(where,
   4115 		cpu_fmt_0,
   4116 		local_service_demand,
   4117 		local_cpu_method);
   4118       }
   4119 
   4120       else {
   4121 	fprintf(where,
   4122 		cpu_fmt_0,
   4123 		remote_service_demand,
   4124 		remote_cpu_method);
   4125       }
   4126 
   4127       break;
   4128 
   4129     case 1:
   4130     case 2:
   4131       if (print_headers) {
   4132 	fprintf(where,
   4133 		cpu_title,
   4134 		format_units(),
   4135 		local_cpu_method,
   4136 		remote_cpu_method);
   4137       }
   4138 
   4139       fprintf(where,
   4140 	      cpu_fmt_1,		/* the format string */
   4141 	      rsr_size,		        /* remote recvbuf size */
   4142 	      lss_size,		        /* local sendbuf size */
   4143 	      send_size,		/* how large were the sends */
   4144 	      elapsed_time,		/* how long was the test */
   4145 	      thruput, 		        /* what was the xfer rate */
   4146 	      local_cpu_utilization,	/* local cpu */
   4147 	      remote_cpu_utilization,	/* remote cpu */
   4148 	      local_service_demand,	/* local service demand */
   4149 	      remote_service_demand);	/* remote service demand */
   4150       break;
   4151     }
   4152 
   4153   }
   4154 
   4155   else {
   4156     /* The tester did not wish to measure service demand. */
   4157 
   4158     switch (verbosity) {
   4159 
   4160     case 0:
   4161 
   4162       fprintf(where,
   4163 	      tput_fmt_0,
   4164 	      thruput);
   4165       break;
   4166 
   4167     case 1:
   4168     case 2:
   4169 
   4170       if (print_headers) {
   4171 	fprintf(where,tput_title,format_units());
   4172       }
   4173 
   4174       fprintf(where,
   4175 	      tput_fmt_1,		/* the format string */
   4176 	      rsr_size, 		/* remote recvbuf size */
   4177 	      lss_size, 		/* local sendbuf size */
   4178 	      send_size,		/* how large were the sends */
   4179 	      elapsed_time, 		/* how long did it take */
   4180 	      thruput);/* how fast did it go */
   4181       break;
   4182     }
   4183   }
   4184 
   4185   /* it would be a good thing to include information about some of the */
   4186   /* other parameters that may have been set for this test, but at the */
   4187   /* moment, I do not wish to figure-out all the  formatting, so I will */
   4188   /* just put this comment here to help remind me that it is something */
   4189   /* that should be done at a later time. */
   4190 
   4191     if (verbosity > 1) {
   4192 
   4193     /* The user wanted to know it all, so we will give it to him. */
   4194     /* This information will include as much as we can find about */
   4195     /* TCP statistics, the alignments of the sends and receives */
   4196     /* and all that sort of rot... */
   4197 
   4198     /* this stuff needs to be worked-out in the presence of confidence */
   4199     /* intervals and multiple iterations of the test... raj 11/94 */
   4200 
   4201     fprintf(where,
   4202 	    ksink_fmt,
   4203 	    "Bytes",
   4204 	    "Bytes",
   4205 	    "Bytes",
   4206 	    local_send_align,
   4207 	    remote_recv_align,
   4208 	    local_send_offset,
   4209 	    remote_recv_offset,
   4210 	    bytes_sent,
   4211 	    bytes_sent / (double)nummessages,
   4212 	    nummessages,
   4213 	    bytes_sent / (double)tcp_stream_result->recv_calls,
   4214 	    tcp_stream_result->recv_calls);
   4215 
   4216     fprintf(where,
   4217 	    ksink_fmt2,
   4218 	    tcp_mss);
   4219 
   4220     fflush(where);
   4221 
   4222 #ifdef WANT_HISTOGRAM
   4223 
   4224     fprintf(where,"\n\nHistogram of time spent in send() call.\n");
   4225     fflush(where);
   4226     HIST_report(time_hist);
   4227 #endif /* WANT_HISTOGRAM */
   4228   }
   4229 }
   4230 
   4231 #endif /* HAVE_SENDFILE */
   4232 
   4233 /* This is the server-side routine for the tcp stream test. It is */
   4234 /* implemented as one routine. I could break things-out somewhat, but */
   4235 /* didn't feel it was necessary. */
   4236 
   4237 void
   4238 recv_tcp_stream()
   4239 {
   4240 
   4241   struct sockaddr_storage myaddr_in, peeraddr_in;
   4242   SOCKET s_listen,s_data;
   4243   netperf_socklen_t addrlen;
   4244   int	len;
   4245   unsigned int	receive_calls;
   4246   float	elapsed_time;
   4247   double   bytes_received;
   4248 
   4249   struct ring_elt *recv_ring;
   4250 
   4251   struct addrinfo *local_res;
   4252   char local_name[BUFSIZ];
   4253   char port_buffer[PORTBUFSIZE];
   4254 
   4255 #ifdef DO_SELECT
   4256   fd_set readfds;
   4257   struct timeval timeout;
   4258 #endif /* DO_SELECT */
   4259 
   4260   struct	tcp_stream_request_struct	*tcp_stream_request;
   4261   struct	tcp_stream_response_struct	*tcp_stream_response;
   4262   struct	tcp_stream_results_struct	*tcp_stream_results;
   4263 
   4264 #ifdef DO_SELECT
   4265   FD_ZERO(&readfds);
   4266   timeout.tv_sec = 1;
   4267   timeout.tv_usec = 0;
   4268 #endif /* DO_SELECT */
   4269 
   4270   tcp_stream_request	=
   4271     (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
   4272   tcp_stream_response	=
   4273     (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
   4274   tcp_stream_results	=
   4275     (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
   4276 
   4277   if (debug) {
   4278     fprintf(where,"netserver: recv_tcp_stream: entered...\n");
   4279     fflush(where);
   4280   }
   4281 
   4282   /* We want to set-up the listen socket with all the desired */
   4283   /* parameters and then let the initiator know that all is ready. If */
   4284   /* socket size defaults are to be used, then the initiator will have */
   4285   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   4286   /* send-back what they are. If that information cannot be determined, */
   4287   /* then we send-back -1's for the sizes. If things go wrong for any */
   4288   /* reason, we will drop back ten yards and punt. */
   4289 
   4290   /* If anything goes wrong, we want the remote to know about it. It */
   4291   /* would be best if the error that the remote reports to the user is */
   4292   /* the actual error we encountered, rather than some bogus unexpected */
   4293   /* response type message. */
   4294 
   4295   if (debug) {
   4296     fprintf(where,"recv_tcp_stream: setting the response type...\n");
   4297     fflush(where);
   4298   }
   4299 
   4300   netperf_response.content.response_type = TCP_STREAM_RESPONSE;
   4301 
   4302   if (debug) {
   4303     fprintf(where,"recv_tcp_stream: the response type is set...\n");
   4304     fflush(where);
   4305   }
   4306 
   4307   /* We now alter the message_ptr variable to be at the desired */
   4308   /* alignment with the desired offset. */
   4309 
   4310   if (debug) {
   4311     fprintf(where,"recv_tcp_stream: requested alignment of %d\n",
   4312 	    tcp_stream_request->recv_alignment);
   4313     fflush(where);
   4314   }
   4315 
   4316   /* create_data_socket expects to find some things in the global */
   4317   /* variables, so set the globals based on the values in the request. */
   4318   /* once the socket has been created, we will set the response values */
   4319   /* based on the updated value of those globals. raj 7/94 */
   4320   lss_size_req = tcp_stream_request->send_buf_size;
   4321   lsr_size_req = tcp_stream_request->recv_buf_size;
   4322   loc_nodelay  = tcp_stream_request->no_delay;
   4323   loc_rcvavoid = tcp_stream_request->so_rcvavoid;
   4324   loc_sndavoid = tcp_stream_request->so_sndavoid;
   4325 
   4326   set_hostname_and_port(local_name,
   4327 			port_buffer,
   4328 			nf_to_af(tcp_stream_request->ipfamily),
   4329 			tcp_stream_request->port);
   4330 
   4331   local_res = complete_addrinfo(local_name,
   4332 				local_name,
   4333 				port_buffer,
   4334 				nf_to_af(tcp_stream_request->ipfamily),
   4335 				SOCK_STREAM,
   4336 				IPPROTO_TCP,
   4337 				0);
   4338 
   4339   s_listen = create_data_socket(local_res);
   4340 
   4341   if (s_listen == INVALID_SOCKET) {
   4342     netperf_response.content.serv_errno = errno;
   4343     send_response();
   4344     exit(1);
   4345   }
   4346 
   4347 #ifdef WIN32
   4348   /* The test timer can fire during operations on the listening socket,
   4349      so to make the start_timer below work we have to move
   4350      it to close s_listen while we are blocked on accept. */
   4351   win_kludge_socket2 = s_listen;
   4352 #endif
   4353 
   4354   /* what sort of sizes did we end-up with? */
   4355   if (tcp_stream_request->receive_size == 0) {
   4356     if (lsr_size > 0) {
   4357       recv_size = lsr_size;
   4358     }
   4359     else {
   4360       recv_size = 4096;
   4361     }
   4362   }
   4363   else {
   4364     recv_size = tcp_stream_request->receive_size;
   4365   }
   4366 
   4367   /* we want to set-up our recv_ring in a manner analagous to what we */
   4368   /* do on the sending side. this is more for the sake of symmetry */
   4369   /* than for the needs of say copy avoidance, but it might also be */
   4370   /* more realistic - this way one could conceivably go with a */
   4371   /* double-buffering scheme when taking the data an putting it into */
   4372   /* the filesystem or something like that. raj 7/94 */
   4373 
   4374   if (recv_width == 0) {
   4375     recv_width = (lsr_size/recv_size) + 1;
   4376     if (recv_width == 1) recv_width++;
   4377   }
   4378 
   4379   recv_ring = allocate_buffer_ring(recv_width,
   4380 				   recv_size,
   4381 				   tcp_stream_request->recv_alignment,
   4382 				   tcp_stream_request->recv_offset);
   4383 
   4384   if (debug) {
   4385     fprintf(where,"recv_tcp_stream: receive alignment and offset set...\n");
   4386     fflush(where);
   4387   }
   4388 
   4389   /* Now, let's set-up the socket to listen for connections */
   4390   if (listen(s_listen, 5) == SOCKET_ERROR) {
   4391     netperf_response.content.serv_errno = errno;
   4392     close(s_listen);
   4393     send_response();
   4394 
   4395     exit(1);
   4396   }
   4397 
   4398 
   4399   /* now get the port number assigned by the system  */
   4400   addrlen = sizeof(myaddr_in);
   4401   if (getsockname(s_listen,
   4402 		  (struct sockaddr *)&myaddr_in,
   4403 		  &addrlen) == SOCKET_ERROR){
   4404     netperf_response.content.serv_errno = errno;
   4405     close(s_listen);
   4406     send_response();
   4407 
   4408     exit(1);
   4409   }
   4410 
   4411   /* Now myaddr_in contains the port and the internet address this is */
   4412   /* returned to the sender also implicitly telling the sender that the */
   4413   /* socket buffer sizing has been done. */
   4414 
   4415   tcp_stream_response->data_port_number =
   4416     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
   4417   netperf_response.content.serv_errno   = 0;
   4418 
   4419   /* But wait, there's more. If the initiator wanted cpu measurements, */
   4420   /* then we must call the calibrate routine, which will return the max */
   4421   /* rate back to the initiator. If the CPU was not to be measured, or */
   4422   /* something went wrong with the calibration, we will return a -1 to */
   4423   /* the initiator. */
   4424 
   4425   tcp_stream_response->cpu_rate = (float)0.0; 	/* assume no cpu */
   4426   if (tcp_stream_request->measure_cpu) {
   4427     tcp_stream_response->measure_cpu = 1;
   4428     tcp_stream_response->cpu_rate =
   4429       calibrate_local_cpu(tcp_stream_request->cpu_rate);
   4430   }
   4431   else {
   4432     tcp_stream_response->measure_cpu = 0;
   4433   }
   4434 
   4435   /* before we send the response back to the initiator, pull some of */
   4436   /* the socket parms from the globals */
   4437   tcp_stream_response->send_buf_size = lss_size;
   4438   tcp_stream_response->recv_buf_size = lsr_size;
   4439   tcp_stream_response->no_delay = loc_nodelay;
   4440   tcp_stream_response->so_rcvavoid = loc_rcvavoid;
   4441   tcp_stream_response->so_sndavoid = loc_sndavoid;
   4442   tcp_stream_response->receive_size = recv_size;
   4443 
   4444   send_response();
   4445 
   4446   addrlen = sizeof(peeraddr_in);
   4447 
   4448   if ((s_data=accept(s_listen,
   4449 		     (struct sockaddr *)&peeraddr_in,
   4450 		     &addrlen)) == INVALID_SOCKET) {
   4451     /* Let's just punt. The remote will be given some information */
   4452     close(s_listen);
   4453     exit(1);
   4454   }
   4455 
   4456 #ifdef KLUDGE_SOCKET_OPTIONS
   4457   /* this is for those systems which *INCORRECTLY* fail to pass */
   4458   /* attributes across an accept() call. Including this goes against */
   4459   /* my better judgement :( raj 11/95 */
   4460 
   4461   kludge_socket_options(s_data);
   4462 
   4463 #endif /* KLUDGE_SOCKET_OPTIONS */
   4464 
   4465   /* Now it's time to start receiving data on the connection. We will */
   4466   /* first grab the apropriate counters and then start grabbing. */
   4467 
   4468   cpu_start(tcp_stream_request->measure_cpu);
   4469 
   4470   /* The loop will exit when the sender does a shutdown, which will */
   4471   /* return a length of zero   */
   4472 
   4473   /* there used to be an #ifdef DIRTY call to access_buffer() here,
   4474      but we have switched from accessing the buffer before the recv()
   4475      call to accessing the buffer after the recv() call.  The
   4476      accessing before was, IIRC, related to having dirty data when
   4477      doing page-flipping copy avoidance. */
   4478 
   4479   bytes_received = 0;
   4480   receive_calls  = 0;
   4481 
   4482   while ((len = recv(s_data, recv_ring->buffer_ptr, recv_size, 0)) != 0) {
   4483     if (len == SOCKET_ERROR )
   4484 	{
   4485       netperf_response.content.serv_errno = errno;
   4486       send_response();
   4487       exit(1);
   4488     }
   4489     bytes_received += len;
   4490     receive_calls++;
   4491 
   4492 #ifdef DIRTY
   4493     /* we access the buffer after the recv() call now, rather than before */
   4494     access_buffer(recv_ring->buffer_ptr,
   4495 		  recv_size,
   4496 		  tcp_stream_request->dirty_count,
   4497 		  tcp_stream_request->clean_count);
   4498 #endif /* DIRTY */
   4499 
   4500 
   4501     /* move to the next buffer in the recv_ring */
   4502     recv_ring = recv_ring->next;
   4503 
   4504 #ifdef PAUSE
   4505     sleep(1);
   4506 #endif /* PAUSE */
   4507 
   4508 #ifdef DO_SELECT
   4509 	FD_SET(s_data,&readfds);
   4510 	select(s_data+1,&readfds,NULL,NULL,&timeout);
   4511 #endif /* DO_SELECT */
   4512 
   4513   }
   4514 
   4515   /* perform a shutdown to signal the sender that */
   4516   /* we have received all the data sent. raj 4/93 */
   4517 
   4518   if (shutdown(s_data,SHUT_WR) == SOCKET_ERROR) {
   4519       netperf_response.content.serv_errno = errno;
   4520       send_response();
   4521       exit(1);
   4522     }
   4523 
   4524   cpu_stop(tcp_stream_request->measure_cpu,&elapsed_time);
   4525 
   4526   /* send the results to the sender			*/
   4527 
   4528   if (debug) {
   4529     fprintf(where,
   4530 	    "recv_tcp_stream: got %g bytes\n",
   4531 	    bytes_received);
   4532     fprintf(where,
   4533 	    "recv_tcp_stream: got %d recvs\n",
   4534 	    receive_calls);
   4535     fflush(where);
   4536   }
   4537 
   4538   tcp_stream_results->bytes_received	= htond(bytes_received);
   4539   tcp_stream_results->elapsed_time	= elapsed_time;
   4540   tcp_stream_results->recv_calls	= receive_calls;
   4541 
   4542   tcp_stream_results->cpu_method = cpu_method;
   4543   tcp_stream_results->num_cpus   = lib_num_loc_cpus;
   4544 
   4545   if (tcp_stream_request->measure_cpu) {
   4546     tcp_stream_results->cpu_util	= calc_cpu_util(0.0);
   4547   };
   4548 
   4549   if (debug) {
   4550     fprintf(where,
   4551 	    "recv_tcp_stream: test complete, sending results.\n");
   4552     fprintf(where,
   4553 	    "                 bytes_received %g receive_calls %d\n",
   4554 	    bytes_received,
   4555 	    receive_calls);
   4556     fprintf(where,
   4557 	    "                 len %d\n",
   4558 	    len);
   4559     fflush(where);
   4560   }
   4561 
   4562   send_response();
   4563 
   4564   /* we are now done with the sockets */
   4565   close(s_data);
   4566   close(s_listen);
   4567 
   4568   }
   4569 
   4570 /* This is the server-side routine for the tcp maerts test. It is
   4572    implemented as one routine. I could break things-out somewhat, but
   4573    didn't feel it was necessary. */
   4574 
   4575 void
   4576 recv_tcp_maerts()
   4577 {
   4578 
   4579   struct sockaddr_storage myaddr_in, peeraddr_in;
   4580   struct addrinfo *local_res;
   4581   char  local_name[BUFSIZ];
   4582   char  port_buffer[PORTBUFSIZE];
   4583 
   4584   SOCKET	s_listen,s_data;
   4585   netperf_socklen_t 	addrlen;
   4586   int	len;
   4587   unsigned int	send_calls;
   4588   float	elapsed_time;
   4589   double   bytes_sent = 0.0 ;
   4590 
   4591   struct ring_elt *send_ring;
   4592 
   4593   struct	tcp_maerts_request_struct	*tcp_maerts_request;
   4594   struct	tcp_maerts_response_struct	*tcp_maerts_response;
   4595   struct	tcp_maerts_results_struct	*tcp_maerts_results;
   4596 
   4597   tcp_maerts_request	=
   4598     (struct tcp_maerts_request_struct *)netperf_request.content.test_specific_data;
   4599   tcp_maerts_response	=
   4600     (struct tcp_maerts_response_struct *)netperf_response.content.test_specific_data;
   4601   tcp_maerts_results	=
   4602     (struct tcp_maerts_results_struct *)netperf_response.content.test_specific_data;
   4603 
   4604   if (debug) {
   4605     fprintf(where,"netserver: recv_tcp_maerts: entered...\n");
   4606     fflush(where);
   4607   }
   4608 
   4609   /* We want to set-up the listen socket with all the desired
   4610      parameters and then let the initiator know that all is ready. If
   4611      socket size defaults are to be used, then the initiator will have
   4612      sent us 0's. If the socket sizes cannot be changed, then we will
   4613      send-back what they are. If that information cannot be
   4614      determined, then we send-back -1's for the sizes. If things go
   4615      wrong for any reason, we will drop back ten yards and punt. */
   4616 
   4617   /* If anything goes wrong, we want the remote to know about it. It
   4618      would be best if the error that the remote reports to the user is
   4619      the actual error we encountered, rather than some bogus
   4620      unexpected response type message. */
   4621 
   4622   if (debug) {
   4623     fprintf(where,"recv_tcp_maerts: setting the response type...\n");
   4624     fflush(where);
   4625   }
   4626 
   4627   netperf_response.content.response_type = TCP_MAERTS_RESPONSE;
   4628 
   4629   if (debug) {
   4630     fprintf(where,"recv_tcp_maerts: the response type is set...\n");
   4631     fflush(where);
   4632   }
   4633 
   4634   /* We now alter the message_ptr variable to be at the desired */
   4635   /* alignment with the desired offset. */
   4636 
   4637   if (debug) {
   4638     fprintf(where,"recv_tcp_maerts: requested alignment of %d\n",
   4639 	    tcp_maerts_request->send_alignment);
   4640     fflush(where);
   4641   }
   4642 
   4643   /* Grab a socket to listen on, and then listen on it. */
   4644 
   4645   if (debug) {
   4646     fprintf(where,"recv_tcp_maerts: grabbing a socket...\n");
   4647     fflush(where);
   4648   }
   4649 
   4650   /* create_data_socket expects to find some things in the global */
   4651   /* variables, so set the globals based on the values in the request. */
   4652   /* once the socket has been created, we will set the response values */
   4653   /* based on the updated value of those globals. raj 7/94 */
   4654   lss_size_req = tcp_maerts_request->send_buf_size;
   4655   lsr_size_req = tcp_maerts_request->recv_buf_size;
   4656   loc_nodelay = tcp_maerts_request->no_delay;
   4657   loc_rcvavoid = tcp_maerts_request->so_rcvavoid;
   4658   loc_sndavoid = tcp_maerts_request->so_sndavoid;
   4659 
   4660   set_hostname_and_port(local_name,
   4661 			port_buffer,
   4662 			nf_to_af(tcp_maerts_request->ipfamily),
   4663 			tcp_maerts_request->port);
   4664 
   4665   local_res = complete_addrinfo(local_name,
   4666 				local_name,
   4667 				port_buffer,
   4668 				nf_to_af(tcp_maerts_request->ipfamily),
   4669 				SOCK_STREAM,
   4670 				IPPROTO_TCP,
   4671 				0);
   4672 
   4673   s_listen = create_data_socket(local_res);
   4674 
   4675   if (s_listen == INVALID_SOCKET) {
   4676     netperf_response.content.serv_errno = errno;
   4677     send_response();
   4678     exit(1);
   4679   }
   4680 
   4681 #ifdef WIN32
   4682   /* The test timer can fire during operations on the listening socket,
   4683      so to make the start_timer below work we have to move
   4684      it to close s_listen while we are blocked on accept. */
   4685   win_kludge_socket2 = s_listen;
   4686 #endif
   4687 
   4688 
   4689   /* what sort of sizes did we end-up with? */
   4690   if (tcp_maerts_request->send_size == 0) {
   4691     if (lss_size > 0) {
   4692       send_size = lss_size;
   4693     }
   4694     else {
   4695       send_size = 4096;
   4696     }
   4697   }
   4698   else {
   4699     send_size = tcp_maerts_request->send_size;
   4700   }
   4701 
   4702   /* we want to set-up our recv_ring in a manner analagous to what we */
   4703   /* do on the recving side. this is more for the sake of symmetry */
   4704   /* than for the needs of say copy avoidance, but it might also be */
   4705   /* more realistic - this way one could conceivably go with a */
   4706   /* double-buffering scheme when taking the data an putting it into */
   4707   /* the filesystem or something like that. raj 7/94 */
   4708 
   4709   if (send_width == 0) {
   4710     send_width = (lsr_size/send_size) + 1;
   4711     if (send_width == 1) send_width++;
   4712   }
   4713 
   4714   send_ring = allocate_buffer_ring(send_width,
   4715 				   send_size,
   4716 				   tcp_maerts_request->send_alignment,
   4717 				   tcp_maerts_request->send_offset);
   4718 
   4719   if (debug) {
   4720     fprintf(where,"recv_tcp_maerts: receive alignment and offset set...\n");
   4721     fflush(where);
   4722   }
   4723 
   4724   /* Now, let's set-up the socket to listen for connections */
   4725   if (listen(s_listen, 5) == SOCKET_ERROR) {
   4726     netperf_response.content.serv_errno = errno;
   4727     close(s_listen);
   4728     send_response();
   4729 
   4730     exit(1);
   4731   }
   4732 
   4733 
   4734   /* now get the port number assigned by the system  */
   4735   addrlen = sizeof(myaddr_in);
   4736   if (getsockname(s_listen,
   4737 		  (struct sockaddr *)&myaddr_in,
   4738 		  &addrlen) == SOCKET_ERROR){
   4739     netperf_response.content.serv_errno = errno;
   4740     close(s_listen);
   4741     send_response();
   4742 
   4743     exit(1);
   4744   }
   4745 
   4746   /* Now myaddr_in contains the port and the internet address this is */
   4747   /* returned to the sender also implicitly telling the sender that the */
   4748   /* socket buffer sizing has been done. */
   4749 
   4750   tcp_maerts_response->data_port_number =
   4751     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
   4752   netperf_response.content.serv_errno   = 0;
   4753 
   4754   /* But wait, there's more. If the initiator wanted cpu measurements, */
   4755   /* then we must call the calibrate routine, which will return the max */
   4756   /* rate back to the initiator. If the CPU was not to be measured, or */
   4757   /* something went wrong with the calibration, we will return a -1 to */
   4758   /* the initiator. */
   4759 
   4760   tcp_maerts_response->cpu_rate = (float)0.0; 	/* assume no cpu */
   4761   if (tcp_maerts_request->measure_cpu) {
   4762     tcp_maerts_response->measure_cpu = 1;
   4763     tcp_maerts_response->cpu_rate =
   4764       calibrate_local_cpu(tcp_maerts_request->cpu_rate);
   4765   }
   4766   else {
   4767     tcp_maerts_response->measure_cpu = 0;
   4768   }
   4769 
   4770   /* before we send the response back to the initiator, pull some of */
   4771   /* the socket parms from the globals */
   4772   tcp_maerts_response->send_buf_size = lss_size;
   4773   tcp_maerts_response->recv_buf_size = lsr_size;
   4774   tcp_maerts_response->no_delay = loc_nodelay;
   4775   tcp_maerts_response->so_rcvavoid = loc_rcvavoid;
   4776   tcp_maerts_response->so_sndavoid = loc_sndavoid;
   4777   tcp_maerts_response->send_size = send_size;
   4778 
   4779   send_response();
   4780 
   4781   addrlen = sizeof(peeraddr_in);
   4782 
   4783   /* we will start the timer before the accept() to be somewhat
   4784      analagous to the starting of the timer before the connect() call
   4785      in the TCP_STREAM test. raj 2002-06-21 */
   4786 
   4787   start_timer(tcp_maerts_request->test_length);
   4788 
   4789   /* Now it's time to start receiving data on the connection. We will
   4790      first grab the apropriate counters and then start grabbing. */
   4791 
   4792   cpu_start(tcp_maerts_request->measure_cpu);
   4793 
   4794 
   4795   if ((s_data=accept(s_listen,
   4796 		     (struct sockaddr *)&peeraddr_in,
   4797 		     &addrlen)) == INVALID_SOCKET) {
   4798     /* Let's just punt. The remote will be given some information */
   4799     close(s_listen);
   4800     exit(1);
   4801   }
   4802 
   4803 #ifdef KLUDGE_SOCKET_OPTIONS
   4804 
   4805   /* this is for those systems which *INCORRECTLY* fail to pass
   4806      attributes across an accept() call. Including this goes against
   4807      my better judgement :( raj 11/95 */
   4808 
   4809   kludge_socket_options(s_data);
   4810 
   4811 #endif /* KLUDGE_SOCKET_OPTIONS */
   4812 
   4813   /* The loop will exit when the sender does a shutdown, which will */
   4814   /* return a length of zero   */
   4815 
   4816   bytes_sent = 0.0;
   4817   send_calls  = 0;
   4818 
   4819   len = 0;   /* nt-lint; len is not initialized (printf far below) if
   4820 		times_up initially true.*/
   4821   times_up = 0; /* must remember to initialize this little beauty */
   4822   while (!times_up) {
   4823 
   4824 #ifdef DIRTY
   4825     /* we want to dirty some number of consecutive integers in the buffer */
   4826     /* we are about to send. we may also want to bring some number of */
   4827     /* them cleanly into the cache. The clean ones will follow any dirty */
   4828     /* ones into the cache. */
   4829 
   4830   access_buffer(send_ring->buffer_ptr,
   4831 		send_size,
   4832 		tcp_maerts_request->dirty_count,
   4833 		tcp_maerts_request->clean_count);
   4834 
   4835 #endif /* DIRTY */
   4836 
   4837     if((len=send(s_data,
   4838 		 send_ring->buffer_ptr,
   4839 		 send_size,
   4840 		 0)) != send_size) {
   4841 		if ((len >=0) || SOCKET_EINTR(len)) {
   4842 	      /* the test was interrupted, must be the end of test */
   4843 	      break;
   4844 		}
   4845       netperf_response.content.serv_errno = errno;
   4846       send_response();
   4847       exit(1);
   4848     }
   4849 
   4850     bytes_sent += len;
   4851     send_calls++;
   4852 
   4853     /* more to the next buffer in the send_ring */
   4854     send_ring = send_ring->next;
   4855 
   4856   }
   4857 
   4858   /* perform a shutdown to signal the sender that */
   4859   /* we have received all the data sent. raj 4/93 */
   4860 
   4861   if (shutdown(s_data,SHUT_WR) == SOCKET_ERROR) {
   4862       netperf_response.content.serv_errno = errno;
   4863       send_response();
   4864       exit(1);
   4865     }
   4866 
   4867   /* hang a recv() off the socket to block until the remote has
   4868      brought all the data up into the application. it will do a
   4869      shutdown to cause a FIN to be sent our way. We will assume that
   4870      any exit from the recv() call is good... raj 4/93 */
   4871 
   4872   recv(s_data, send_ring->buffer_ptr, send_size, 0);
   4873 
   4874 
   4875   cpu_stop(tcp_maerts_request->measure_cpu,&elapsed_time);
   4876 
   4877   /* send the results to the sender			*/
   4878 
   4879   if (debug) {
   4880     fprintf(where,
   4881 	    "recv_tcp_maerts: got %g bytes\n",
   4882 	    bytes_sent);
   4883     fprintf(where,
   4884 	    "recv_tcp_maerts: got %d sends\n",
   4885 	    send_calls);
   4886     fflush(where);
   4887   }
   4888 
   4889   tcp_maerts_results->bytes_sent	= htond(bytes_sent);
   4890   tcp_maerts_results->elapsed_time	= elapsed_time;
   4891   tcp_maerts_results->send_calls	= send_calls;
   4892 
   4893   if (tcp_maerts_request->measure_cpu) {
   4894     tcp_maerts_results->cpu_util	= calc_cpu_util(0.0);
   4895   };
   4896 
   4897   if (debug) {
   4898     fprintf(where,
   4899 	    "recv_tcp_maerts: test complete, sending results.\n");
   4900     fprintf(where,
   4901 	    "                 bytes_sent %g send_calls %d\n",
   4902 	    bytes_sent,
   4903 	    send_calls);
   4904     fprintf(where,
   4905 	    "                 len %d\n",
   4906 	    len);
   4907     fflush(where);
   4908   }
   4909 
   4910   tcp_maerts_results->cpu_method = cpu_method;
   4911   tcp_maerts_results->num_cpus   = lib_num_loc_cpus;
   4912   send_response();
   4913 
   4914   /* we are now done with the sockets */
   4915   close(s_data);
   4916   close(s_listen);
   4917 
   4918   }
   4919 
   4920 
   4922  /* this routine implements the sending (netperf) side of the TCP_RR */
   4923  /* test. */
   4924 
   4925 void
   4926 send_tcp_rr(char remote_host[])
   4927 {
   4928 
   4929   char *tput_title = "\
   4930 Local /Remote\n\
   4931 Socket Size   Request  Resp.   Elapsed  Trans.\n\
   4932 Send   Recv   Size     Size    Time     Rate         \n\
   4933 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
   4934 
   4935   char *tput_title_band = "\
   4936 Local /Remote\n\
   4937 Socket Size   Request  Resp.   Elapsed  \n\
   4938 Send   Recv   Size     Size    Time     Throughput \n\
   4939 bytes  Bytes  bytes    bytes   secs.    %s/sec   \n\n";
   4940 
   4941   char *tput_fmt_0 =
   4942     "%7.2f %s\n";
   4943 
   4944   char *tput_fmt_1_line_1 = "\
   4945 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   %s\n";
   4946   char *tput_fmt_1_line_2 = "\
   4947 %-6d %-6d\n";
   4948 
   4949   char *cpu_title = "\
   4950 Local /Remote\n\
   4951 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
   4952 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
   4953 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
   4954 
   4955   char *cpu_title_tput = "\
   4956 Local /Remote\n\
   4957 Socket Size   Request Resp.  Elapsed Tput     CPU    CPU    S.dem   S.dem\n\
   4958 Send   Recv   Size    Size   Time    %-8.8s local  remote local   remote\n\
   4959 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
   4960 
   4961   char *cpu_fmt_0 =
   4962     "%6.3f %c %s\n";
   4963 
   4964   char *cpu_fmt_1_line_1 = "\
   4965 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f  %-6.2f %-6.2f %-6.3f  %-6.3f %s\n";
   4966 
   4967   char *cpu_fmt_1_line_2 = "\
   4968 %-6d %-6d\n";
   4969 
   4970   char *ksink_fmt = "\
   4971 Alignment      Offset         RoundTrip  Trans    Throughput\n\
   4972 Local  Remote  Local  Remote  Latency    Rate     %-8.8s/s\n\
   4973 Send   Recv    Send   Recv    usec/Tran  per sec  Outbound   Inbound\n\
   4974 %5d  %5d   %5d  %5d   %-6.3f   %-6.3f %-6.3f    %-6.3f\n";
   4975 
   4976 
   4977   int			timed_out = 0;
   4978   float			elapsed_time;
   4979 
   4980   int	len;
   4981   char	*temp_message_ptr;
   4982   int	nummessages;
   4983   SOCKET	send_socket;
   4984   int	trans_remaining;
   4985   double	bytes_xferd;
   4986 
   4987   struct ring_elt *send_ring;
   4988   struct ring_elt *recv_ring;
   4989 
   4990   int	rsp_bytes_left;
   4991   int	rsp_bytes_recvd;
   4992 
   4993   float	local_cpu_utilization;
   4994   float	local_service_demand;
   4995   float	remote_cpu_utilization;
   4996   float	remote_service_demand;
   4997   double	thruput;
   4998 
   4999   struct addrinfo *local_res;
   5000   struct addrinfo *remote_res;
   5001 
   5002   struct	tcp_rr_request_struct	*tcp_rr_request;
   5003   struct	tcp_rr_response_struct	*tcp_rr_response;
   5004   struct	tcp_rr_results_struct	*tcp_rr_result;
   5005 
   5006 #ifdef WANT_FIRST_BURST
   5007 #define REQUEST_CWND_INITIAL 2
   5008   /* "in the beginning..." the WANT_FIRST_BURST stuff was like both
   5009      Unix and the state of New Jersey - both were simple an unspoiled.
   5010      then it was realized that some stacks are quite picky about
   5011      initial congestion windows and a non-trivial initial burst of
   5012      requests would not be individual segments even with TCP_NODELAY
   5013      set. so, we have to start tracking a poor-man's congestion window
   5014      up here in window space because we want to try to make something
   5015      happen that frankly, we cannot guarantee with the specification
   5016      of TCP.  ain't that grand?-)  raj 2006-01-30 */
   5017   int requests_outstanding = 0;
   5018   int request_cwnd = REQUEST_CWND_INITIAL;  /* we ass-u-me that having
   5019 					       three requests
   5020 					       outstanding at the
   5021 					       beginning of the test
   5022 					       is ok with TCP stacks
   5023 					       of interest. the first
   5024 					       two will come from our
   5025 					       first_burst loop, and
   5026 					       the third from our
   5027 					       regularly scheduled
   5028 					       send */
   5029 #endif
   5030 
   5031   tcp_rr_request =
   5032     (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data;
   5033   tcp_rr_response=
   5034     (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data;
   5035   tcp_rr_result	=
   5036     (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data;
   5037 
   5038 #ifdef WANT_HISTOGRAM
   5039   if (verbosity > 1) {
   5040     time_hist = HIST_new();
   5041   }
   5042 #endif /* WANT_HISTOGRAM */
   5043 
   5044   /* since we are now disconnected from the code that established the */
   5045   /* control socket, and since we want to be able to use different */
   5046   /* protocols and such, we are passed the name of the remote host and */
   5047   /* must turn that into the test specific addressing information. */
   5048 
   5049   complete_addrinfos(&remote_res,
   5050 		     &local_res,
   5051 		     remote_host,
   5052 		     SOCK_STREAM,
   5053 		     IPPROTO_TCP,
   5054 		     0);
   5055 
   5056   if ( print_headers ) {
   5057     print_top_test_header("TCP REQUEST/RESPONSE TEST",local_res,remote_res);
   5058   }
   5059 
   5060   /* initialize a few counters */
   5061 
   5062   send_ring = NULL;
   5063   recv_ring = NULL;
   5064   confidence_iteration = 1;
   5065   init_stat();
   5066 
   5067   /* we have a great-big while loop which controls the number of times */
   5068   /* we run a particular test. this is for the calculation of a */
   5069   /* confidence interval (I really should have stayed awake during */
   5070   /* probstats :). If the user did not request confidence measurement */
   5071   /* (no confidence is the default) then we will only go though the */
   5072   /* loop once. the confidence stuff originates from the folks at IBM */
   5073 
   5074   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   5075 	 (confidence_iteration <= iteration_min)) {
   5076 
   5077     /* initialize a few counters. we have to remember that we might be */
   5078     /* going through the loop more than once. */
   5079 
   5080     nummessages     = 0;
   5081     bytes_xferd     = 0.0;
   5082     times_up        = 0;
   5083     timed_out       = 0;
   5084     trans_remaining = 0;
   5085 
   5086 #ifdef WANT_FIRST_BURST
   5087     /* we have to remember to reset the number of transactions
   5088        outstanding and the "congestion window for each new
   5089        iteration. raj 2006-01-31 */
   5090     requests_outstanding = 0;
   5091     request_cwnd = REQUEST_CWND_INITIAL;
   5092 #endif
   5093 
   5094 
   5095     /* set-up the data buffers with the requested alignment and offset. */
   5096     /* since this is a request/response test, default the send_width and */
   5097     /* recv_width to 1 and not two raj 7/94 */
   5098 
   5099     if (send_width == 0) send_width = 1;
   5100     if (recv_width == 0) recv_width = 1;
   5101 
   5102     if (send_ring == NULL) {
   5103       send_ring = allocate_buffer_ring(send_width,
   5104 				       req_size,
   5105 				       local_send_align,
   5106 				       local_send_offset);
   5107     }
   5108 
   5109     if (recv_ring == NULL) {
   5110       recv_ring = allocate_buffer_ring(recv_width,
   5111 				       rsp_size,
   5112 				       local_recv_align,
   5113 				       local_recv_offset);
   5114     }
   5115 
   5116     /*set up the data socket                        */
   5117     send_socket = create_data_socket(local_res);
   5118 
   5119     if (send_socket == INVALID_SOCKET){
   5120       perror("netperf: send_tcp_rr: tcp stream data socket");
   5121       exit(1);
   5122     }
   5123 
   5124     if (debug) {
   5125       fprintf(where,"send_tcp_rr: send_socket obtained...\n");
   5126     }
   5127 
   5128     /* If the user has requested cpu utilization measurements, we must */
   5129     /* calibrate the cpu(s). We will perform this task within the tests */
   5130     /* themselves. If the user has specified the cpu rate, then */
   5131     /* calibrate_local_cpu will return rather quickly as it will have */
   5132     /* nothing to do. If local_cpu_rate is zero, then we will go through */
   5133     /* all the "normal" calibration stuff and return the rate back.*/
   5134 
   5135     if (local_cpu_usage) {
   5136       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   5137     }
   5138 
   5139     if (!no_control) {
   5140       /* Tell the remote end to do a listen. The server alters the
   5141 	 socket paramters on the other side at this point, hence the
   5142 	 reason for all the values being passed in the setup
   5143 	 message. If the user did not specify any of the parameters,
   5144 	 they will be passed as 0, which will indicate to the remote
   5145 	 that no changes beyond the system's default should be
   5146 	 used. Alignment is the exception, it will default to 8, which
   5147 	 will be no alignment alterations. */
   5148 
   5149       netperf_request.content.request_type	=	DO_TCP_RR;
   5150       tcp_rr_request->recv_buf_size	=	rsr_size_req;
   5151       tcp_rr_request->send_buf_size	=	rss_size_req;
   5152       tcp_rr_request->recv_alignment    =	remote_recv_align;
   5153       tcp_rr_request->recv_offset	=	remote_recv_offset;
   5154       tcp_rr_request->send_alignment    =	remote_send_align;
   5155       tcp_rr_request->send_offset	=	remote_send_offset;
   5156       tcp_rr_request->request_size	=	req_size;
   5157       tcp_rr_request->response_size	=	rsp_size;
   5158       tcp_rr_request->no_delay	        =	rem_nodelay;
   5159       tcp_rr_request->measure_cpu	=	remote_cpu_usage;
   5160       tcp_rr_request->cpu_rate	        =	remote_cpu_rate;
   5161       tcp_rr_request->so_rcvavoid	=	rem_rcvavoid;
   5162       tcp_rr_request->so_sndavoid	=	rem_sndavoid;
   5163       if (test_time) {
   5164 	tcp_rr_request->test_length	=	test_time;
   5165       }
   5166       else {
   5167 	tcp_rr_request->test_length	=	test_trans * -1;
   5168       }
   5169       tcp_rr_request->port              =      atoi(remote_data_port);
   5170       tcp_rr_request->ipfamily = af_to_nf(remote_res->ai_family);
   5171 
   5172       if (debug > 1) {
   5173 	fprintf(where,"netperf: send_tcp_rr: requesting TCP rr test\n");
   5174       }
   5175 
   5176       send_request();
   5177 
   5178       /* The response from the remote will contain all of the relevant
   5179 	 socket parameters for this test type. We will put them back
   5180 	 into the variables here so they can be displayed if desired.
   5181 	 The remote will have calibrated CPU if necessary, and will
   5182 	 have done all the needed set-up we will have calibrated the
   5183 	 cpu locally before sending the request, and will grab the
   5184 	 counter value right after the connect returns. The remote
   5185 	 will grab the counter right after the accept call. This saves
   5186 	 the hassle of extra messages being sent for the TCP
   5187 	 tests.  */
   5188 
   5189       recv_response();
   5190 
   5191       if (!netperf_response.content.serv_errno) {
   5192 	if (debug)
   5193 	  fprintf(where,"remote listen done.\n");
   5194 	rsr_size          = tcp_rr_response->recv_buf_size;
   5195 	rss_size          = tcp_rr_response->send_buf_size;
   5196 	rem_nodelay       = tcp_rr_response->no_delay;
   5197 	remote_cpu_usage  = tcp_rr_response->measure_cpu;
   5198 	remote_cpu_rate   = tcp_rr_response->cpu_rate;
   5199 	/* make sure that port numbers are in network order */
   5200 	set_port_number(remote_res,(short)tcp_rr_response->data_port_number);
   5201       }
   5202       else {
   5203 	Set_errno(netperf_response.content.serv_errno);
   5204 	fprintf(where,
   5205 		"netperf: remote error %d",
   5206 		netperf_response.content.serv_errno);
   5207 	perror("");
   5208 	fflush(where);
   5209 
   5210 	exit(1);
   5211       }
   5212     }
   5213 
   5214 #ifdef WANT_DEMO
   5215     DEMO_RR_SETUP(1000)
   5216 #endif
   5217 
   5218     /*Connect up to the remote port on the data socket  */
   5219     if (connect(send_socket,
   5220 		remote_res->ai_addr,
   5221 		remote_res->ai_addrlen) == INVALID_SOCKET){
   5222       perror("netperf: data socket connect failed");
   5223 
   5224       exit(1);
   5225     }
   5226 
   5227     /* Data Socket set-up is finished. If there were problems, either the */
   5228     /* connect would have failed, or the previous response would have */
   5229     /* indicated a problem. I failed to see the value of the extra */
   5230     /* message after the accept on the remote. If it failed, we'll see it */
   5231     /* here. If it didn't, we might as well start pumping data. */
   5232 
   5233     /* Set-up the test end conditions. For a request/response test, they */
   5234     /* can be either time or transaction based. */
   5235 
   5236     if (test_time) {
   5237       /* The user wanted to end the test after a period of time. */
   5238       times_up = 0;
   5239       trans_remaining = 0;
   5240       start_timer(test_time);
   5241     }
   5242     else {
   5243       /* The tester wanted to send a number of bytes. */
   5244       trans_remaining = test_bytes;
   5245       times_up = 1;
   5246     }
   5247 
   5248     /* The cpu_start routine will grab the current time and possibly */
   5249     /* value of the idle counter for later use in measuring cpu */
   5250     /* utilization and/or service demand and thruput. */
   5251 
   5252     cpu_start(local_cpu_usage);
   5253 
   5254 #ifdef WANT_INTERVALS
   5255     INTERVALS_INIT();
   5256 #endif /* WANT_INTERVALS */
   5257 
   5258     /* We use an "OR" to control test execution. When the test is */
   5259     /* controlled by time, the byte count check will always return false. */
   5260     /* When the test is controlled by byte count, the time test will */
   5261     /* always return false. When the test is finished, the whole */
   5262     /* expression will go false and we will stop sending data. I think I */
   5263     /* just arbitrarily decrement trans_remaining for the timed test, but */
   5264     /* will not do that just yet... One other question is whether or not */
   5265     /* the send buffer and the receive buffer should be the same buffer. */
   5266 
   5267 #ifdef WANT_DEMO
   5268       if (demo_mode) {
   5269 	HIST_timestamp(demo_one_ptr);
   5270       }
   5271 #endif
   5272 
   5273     while ((!times_up) || (trans_remaining > 0)) {
   5274       /* send the request. we assume that if we use a blocking socket, */
   5275       /* the request will be sent at one shot. */
   5276 
   5277 #ifdef WANT_FIRST_BURST
   5278       /* we can inject no more than request_cwnd, which will grow with
   5279 	 time, and no more than first_burst_size.  we don't use <= to
   5280 	 account for the "regularly scheduled" send call.  of course
   5281 	 that makes it more a "max_outstanding_ than a
   5282 	 "first_burst_size" but for now we won't fix the names. also,
   5283 	 I suspect the extra check against < first_burst_size is
   5284 	 redundant since later I expect to make sure that request_cwnd
   5285 	 can never get larger than first_burst_size, but just at the
   5286 	 moment I'm feeling like a belt and suspenders kind of
   5287 	 programmer. raj 2006-01-30 */
   5288       while ((first_burst_size > 0) &&
   5289 	     (requests_outstanding < request_cwnd) &&
   5290 	     (requests_outstanding < first_burst_size)) {
   5291 	if (debug) {
   5292 	  fprintf(where,
   5293 		  "injecting, req_outstndng %d req_cwnd %d burst %d\n",
   5294 		  requests_outstanding,
   5295 		  request_cwnd,
   5296 		  first_burst_size);
   5297 	}
   5298 	if ((len = send(send_socket,
   5299 			send_ring->buffer_ptr,
   5300 			req_size,
   5301 			0)) != req_size) {
   5302 	  /* we should never hit the end of the test in the first burst */
   5303 	  perror("send_tcp_rr: initial burst data send error");
   5304 	  exit(-1);
   5305 	}
   5306 	requests_outstanding += 1;
   5307       }
   5308 
   5309 #endif /* WANT_FIRST_BURST */
   5310 
   5311 #ifdef WANT_HISTOGRAM
   5312       if (verbosity > 1) {
   5313 	/* timestamp just before our call to send, and then again just
   5314 	   after the receive raj 8/94 */
   5315 	/* but only if we are actually going to display one. raj
   5316 	   2007-02-07 */
   5317 
   5318 	HIST_timestamp(&time_one);
   5319       }
   5320 #endif /* WANT_HISTOGRAM */
   5321 
   5322       if ((len = send(send_socket,
   5323 		      send_ring->buffer_ptr,
   5324 		      req_size,
   5325 		      0)) != req_size) {
   5326 	if (SOCKET_EINTR(len) || (errno == 0)) {
   5327 	  /* we hit the end of a */
   5328 	  /* timed test. */
   5329 	  timed_out = 1;
   5330 	  break;
   5331 	}
   5332 	perror("send_tcp_rr: data send error");
   5333 	exit(1);
   5334       }
   5335       send_ring = send_ring->next;
   5336 
   5337 #ifdef WANT_FIRST_BURST
   5338       requests_outstanding += 1;
   5339 #endif
   5340 
   5341       /* receive the response */
   5342       rsp_bytes_left = rsp_size;
   5343       temp_message_ptr  = recv_ring->buffer_ptr;
   5344       while(rsp_bytes_left > 0) {
   5345 	if((rsp_bytes_recvd=recv(send_socket,
   5346 				 temp_message_ptr,
   5347 				 rsp_bytes_left,
   5348 				 0)) == SOCKET_ERROR) {
   5349 		if ( SOCKET_EINTR(rsp_bytes_recvd) ) {
   5350 		    /* We hit the end of a timed test. */
   5351 			timed_out = 1;
   5352 			break;
   5353 		}
   5354 	  perror("send_tcp_rr: data recv error");
   5355 	  exit(1);
   5356 	}
   5357 	rsp_bytes_left -= rsp_bytes_recvd;
   5358 	temp_message_ptr  += rsp_bytes_recvd;
   5359       }
   5360       recv_ring = recv_ring->next;
   5361 
   5362 #ifdef WANT_FIRST_BURST
   5363       /* so, since we've gotten a response back, update the
   5364 	 bookkeeping accordingly.  there is one less request
   5365 	 outstanding and we can put one more out there than before. */
   5366       requests_outstanding -= 1;
   5367       if (request_cwnd < first_burst_size) {
   5368 	request_cwnd += 1;
   5369 	if (debug) {
   5370 	  fprintf(where,
   5371 		  "incr req_cwnd to %d first_burst %d reqs_outstndng %d\n",
   5372 		  request_cwnd,
   5373 		  first_burst_size,
   5374 		  requests_outstanding);
   5375 	}
   5376       }
   5377 #endif
   5378       if (timed_out) {
   5379 	/* we may have been in a nested while loop - we need */
   5380 	/* another call to break. */
   5381 	break;
   5382       }
   5383 
   5384 #ifdef WANT_HISTOGRAM
   5385       if (verbosity > 1) {
   5386 	HIST_timestamp(&time_two);
   5387 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   5388       }
   5389 #endif /* WANT_HISTOGRAM */
   5390 
   5391 #ifdef WANT_DEMO
   5392       DEMO_RR_INTERVAL(1);
   5393 #endif
   5394 
   5395 #ifdef WANT_INTERVALS
   5396       INTERVALS_WAIT();
   5397 #endif /* WANT_INTERVALS */
   5398 
   5399       nummessages++;
   5400       if (trans_remaining) {
   5401 	trans_remaining--;
   5402       }
   5403 
   5404       if (debug > 3) {
   5405 	if ((nummessages % 100) == 0) {
   5406 	  fprintf(where,
   5407 		  "Transaction %d completed\n",
   5408 		  nummessages);
   5409 	  fflush(where);
   5410 	}
   5411       }
   5412     }
   5413 
   5414     /* At this point we used to call shutdown on the data socket to be
   5415        sure all the data was delivered, but this was not germane in a
   5416        request/response test, and it was causing the tests to "hang"
   5417        when they were being controlled by time. So, I have replaced
   5418        this shutdown call with a call to close that can be found later
   5419        in the procedure. */
   5420 
   5421     /* this call will always give us the elapsed time for the test,
   5422        and will also store-away the necessaries for cpu utilization */
   5423 
   5424     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
   5425 						/* measured? how long */
   5426 						/* did we really run? */
   5427 
   5428     if (!no_control) {
   5429       /* Get the statistics from the remote end. The remote will have
   5430 	 calculated CPU utilization. If it wasn't supposed to care, it
   5431 	 will return obvious values. */
   5432 
   5433       recv_response();
   5434       if (!netperf_response.content.serv_errno) {
   5435 	if (debug)
   5436 	  fprintf(where,"remote results obtained\n");
   5437       }
   5438       else {
   5439 	Set_errno(netperf_response.content.serv_errno);
   5440 	fprintf(where,"netperf: remote error %d",
   5441 		netperf_response.content.serv_errno);
   5442 	perror("");
   5443 	fflush(where);
   5444 	exit(1);
   5445       }
   5446     }
   5447 
   5448     /* We now calculate what our "throughput" was for the test. */
   5449 
   5450     bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
   5451     thruput	= nummessages/elapsed_time;
   5452 
   5453     if (local_cpu_usage || remote_cpu_usage) {
   5454       /* We must now do a little math for service demand and cpu
   5455        utilization for the system(s) Of course, some of the
   5456        information might be bogus because there was no idle counter in
   5457        the kernel(s). We need to make a note of this for the user's
   5458        benefit... */
   5459       if (local_cpu_usage) {
   5460 	local_cpu_utilization = calc_cpu_util(0.0);
   5461  	/* since calc_service demand is doing ms/Kunit we will
   5462 	   multiply the number of transaction by 1024 to get "good"
   5463 	   numbers */
   5464 	local_service_demand  = calc_service_demand((double) nummessages*1024,
   5465 						    0.0,
   5466 						    0.0,
   5467 						    0);
   5468       }
   5469       else {
   5470 	local_cpu_utilization	= (float) -1.0;
   5471 	local_service_demand	= (float) -1.0;
   5472       }
   5473 
   5474       if (remote_cpu_usage) {
   5475 	remote_cpu_utilization = tcp_rr_result->cpu_util;
   5476 	/* since calc_service demand is doing ms/Kunit we will
   5477 	   multiply the number of transaction by 1024 to get "good"
   5478 	   numbers */
   5479 	remote_service_demand = calc_service_demand((double) nummessages*1024,
   5480 						    0.0,
   5481 						    remote_cpu_utilization,
   5482 						    tcp_rr_result->num_cpus);
   5483       }
   5484       else {
   5485 	remote_cpu_utilization = (float) -1.0;
   5486 	remote_service_demand  = (float) -1.0;
   5487       }
   5488 
   5489     }
   5490     else {
   5491       /* we were not measuring cpu, for the confidence stuff, we */
   5492       /* should make it -1.0 */
   5493       local_cpu_utilization	= (float) -1.0;
   5494       local_service_demand	= (float) -1.0;
   5495       remote_cpu_utilization = (float) -1.0;
   5496       remote_service_demand  = (float) -1.0;
   5497     }
   5498 
   5499     /* at this point, we want to calculate the confidence information.
   5500        if debugging is on, calculate_confidence will print-out the
   5501        parameters we pass it */
   5502 
   5503     calculate_confidence(confidence_iteration,
   5504 			 elapsed_time,
   5505 			 thruput,
   5506 			 local_cpu_utilization,
   5507 			 remote_cpu_utilization,
   5508 			 local_service_demand,
   5509 			 remote_service_demand);
   5510 
   5511 
   5512     confidence_iteration++;
   5513 
   5514     /* we are now done with the socket, so close it */
   5515     close(send_socket);
   5516 
   5517   }
   5518 
   5519   retrieve_confident_values(&elapsed_time,
   5520 			    &thruput,
   5521 			    &local_cpu_utilization,
   5522 			    &remote_cpu_utilization,
   5523 			    &local_service_demand,
   5524 			    &remote_service_demand);
   5525 
   5526   /* We are now ready to print all the information. If the user has
   5527      specified zero-level verbosity, we will just print the local
   5528      service demand, or the remote service demand. If the user has
   5529      requested verbosity level 1, he will get the basic "streamperf"
   5530      numbers. If the user has specified a verbosity of greater than 1,
   5531      we will display a veritable plethora of background information
   5532      from outside of this block as it it not cpu_measurement
   5533      specific...  */
   5534 
   5535   if (confidence < 0) {
   5536     /* we did not hit confidence, but were we asked to look for it? */
   5537     if (iteration_max > 1) {
   5538       display_confidence();
   5539     }
   5540   }
   5541 
   5542   if (local_cpu_usage || remote_cpu_usage) {
   5543     local_cpu_method = format_cpu_method(cpu_method);
   5544     remote_cpu_method = format_cpu_method(tcp_rr_result->cpu_method);
   5545 
   5546     switch (verbosity) {
   5547     case 0:
   5548       if (local_cpu_usage) {
   5549 	fprintf(where,
   5550 		cpu_fmt_0,
   5551 		local_service_demand,
   5552 		local_cpu_method,
   5553 		((print_headers) ||
   5554 		 (result_brand == NULL)) ? "" : result_brand);
   5555       }
   5556       else {
   5557 	fprintf(where,
   5558 		cpu_fmt_0,
   5559 		remote_service_demand,
   5560 		remote_cpu_method,
   5561 		((print_headers) ||
   5562 		 (result_brand == NULL)) ? "" : result_brand);
   5563       }
   5564       break;
   5565     case 1:
   5566     case 2:
   5567       if (print_headers) {
   5568 	if ('x' == libfmt) {
   5569 	  fprintf(where,
   5570 		  cpu_title,
   5571 		  local_cpu_method,
   5572 		  remote_cpu_method);
   5573 	}
   5574 	else {
   5575 	  fprintf(where,
   5576 		  cpu_title_tput,
   5577 		  format_units(),
   5578 		  local_cpu_method,
   5579 		  remote_cpu_method);
   5580 	}
   5581       }
   5582 
   5583       fprintf(where,
   5584 	      cpu_fmt_1_line_1,		/* the format string */
   5585 	      lss_size,		/* local sendbuf size */
   5586 	      lsr_size,
   5587 	      req_size,		/* how large were the requests */
   5588 	      rsp_size,		/* guess */
   5589 	      elapsed_time,		/* how long was the test */
   5590 	      ('x' == libfmt) ? thruput :
   5591 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
   5592 					 1.0),
   5593 	      local_cpu_utilization,	/* local cpu */
   5594 	      remote_cpu_utilization,	/* remote cpu */
   5595 	      local_service_demand,	/* local service demand */
   5596 	      remote_service_demand,	/* remote service demand */
   5597 	      ((print_headers) ||
   5598 	       (result_brand == NULL)) ? "" : result_brand);
   5599       fprintf(where,
   5600 	      cpu_fmt_1_line_2,
   5601 	      rss_size,
   5602 	      rsr_size);
   5603       break;
   5604     }
   5605   }
   5606   else {
   5607     /* The tester did not wish to measure service demand. */
   5608 
   5609     switch (verbosity) {
   5610     case 0:
   5611       fprintf(where,
   5612 	      tput_fmt_0,
   5613 	      ('x' == libfmt) ? thruput :
   5614 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
   5615 					 1.0),
   5616 	      ((print_headers) ||
   5617 	       (result_brand == NULL)) ? "" : result_brand);
   5618       break;
   5619     case 1:
   5620     case 2:
   5621       if (print_headers) {
   5622 	fprintf(where,
   5623 		('x' == libfmt) ? tput_title : tput_title_band,
   5624 		format_units());
   5625       }
   5626 
   5627       fprintf(where,
   5628 	      tput_fmt_1_line_1,	/* the format string */
   5629 	      lss_size,
   5630 	      lsr_size,
   5631 	      req_size,		/* how large were the requests */
   5632 	      rsp_size,		/* how large were the responses */
   5633 	      elapsed_time, 		/* how long did it take */
   5634 	      /* are we trans or do we need to convert to bytes then
   5635 		 bits? at this point, thruput is in our "confident"
   5636 		 transactions per second. we can convert to a
   5637 		 bidirectional bitrate by multiplying that by the sum
   5638 		 of the req_size and rsp_size.  we pass that to
   5639 		 calc_thruput_interval_omni with an elapsed time of
   5640 		 1.0 s to get it converted to [kmg]bits/s or
   5641 		 [KMG]Bytes/s */
   5642 	      ('x' == libfmt) ?  thruput :
   5643 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
   5644 					 1.0),
   5645 	      ((print_headers) ||
   5646 	       (result_brand == NULL)) ? "" : result_brand);
   5647       fprintf(where,
   5648 	      tput_fmt_1_line_2,
   5649 	      rss_size, 		/* remote recvbuf size */
   5650 	      rsr_size);
   5651 
   5652       break;
   5653     }
   5654   }
   5655 
   5656   /* it would be a good thing to include information about some of the */
   5657   /* other parameters that may have been set for this test, but at the */
   5658   /* moment, I do not wish to figure-out all the  formatting, so I will */
   5659   /* just put this comment here to help remind me that it is something */
   5660   /* that should be done at a later time. */
   5661 
   5662   /* how to handle the verbose information in the presence of */
   5663   /* confidence intervals is yet to be determined... raj 11/94 */
   5664   if (verbosity > 1) {
   5665     /* The user wanted to know it all, so we will give it to him. */
   5666     /* This information will include as much as we can find about */
   5667     /* TCP statistics, the alignments of the sends and receives */
   5668     /* and all that sort of rot... */
   5669 
   5670     /* normally, you might think that if we were messing about with
   5671        the value of libfmt we would need to put it back again, but
   5672        since this is basically the last thing we are going to do with
   5673        it, it does not matter.  so there :) raj 2007-06-08 */
   5674     /* if the user was asking for transactions, then we report
   5675        megabits per sedcond for the unidirectional throughput,
   5676        otherwise we use the desired units. */
   5677     if ('x' == libfmt) {
   5678       libfmt = 'm';
   5679     }
   5680 
   5681     fprintf(where,
   5682 	    ksink_fmt,
   5683 	    format_units(),
   5684 	    local_send_align,
   5685 	    remote_recv_offset,
   5686 	    local_send_offset,
   5687 	    remote_recv_offset,
   5688 	    /* if the user has enable burst mode, we have to remember
   5689 	       to account for that in the number of transactions
   5690 	       outstanding at any one time. otherwise we will
   5691 	       underreport the latency of individual
   5692 	       transactions. learned from saf by raj 2007-06-08  */
   5693 	    (((double)1.0/thruput)*(double)1000000.0) *
   5694 	    (double) (1+first_burst_size),
   5695 	    thruput,
   5696 	    calc_thruput_interval_omni(thruput * (double)req_size,1.0),
   5697 	    calc_thruput_interval_omni(thruput * (double)rsp_size,1.0));
   5698 
   5699 #ifdef WANT_HISTOGRAM
   5700     fprintf(where,"\nHistogram of request/response times\n");
   5701     fflush(where);
   5702     HIST_report(time_hist);
   5703 #endif /* WANT_HISTOGRAM */
   5704 
   5705   }
   5706 
   5707 }
   5708 
   5709 void
   5711 send_udp_stream(char remote_host[])
   5712 {
   5713   /**********************************************************************/
   5714   /*									*/
   5715   /*               	UDP Unidirectional Send Test                    */
   5716   /*									*/
   5717   /**********************************************************************/
   5718 
   5719 #define UDP_LENGTH_MAX 0XFFFF - 28
   5720 
   5721   char *tput_title = "\
   5722 Socket  Message  Elapsed      Messages                \n\
   5723 Size    Size     Time         Okay Errors   Throughput\n\
   5724 bytes   bytes    secs            #      #   %s/sec\n\n";
   5725 
   5726   char *tput_fmt_0 =
   5727     "%7.2f\n";
   5728 
   5729   char *tput_fmt_1 = "\
   5730 %6d  %6d   %-7.2f   %7d %6d    %7.2f\n\
   5731 %6d           %-7.2f   %7d           %7.2f\n\n";
   5732 
   5733 
   5734   char *cpu_title = "\
   5735 Socket  Message  Elapsed      Messages                   CPU      Service\n\
   5736 Size    Size     Time         Okay Errors   Throughput   Util     Demand\n\
   5737 bytes   bytes    secs            #      #   %s/sec %% %c%c     us/KB\n\n";
   5738 
   5739   char *cpu_fmt_0 =
   5740     "%6.2f %c\n";
   5741 
   5742   char *cpu_fmt_1 = "\
   5743 %6d  %6d   %-7.2f   %7d %6d    %7.1f     %-6.2f   %-6.3f\n\
   5744 %6d           %-7.2f   %7d           %7.1f     %-6.2f   %-6.3f\n\n";
   5745 
   5746   unsigned int	messages_recvd;
   5747   unsigned int 	messages_sent;
   5748   unsigned int	failed_sends;
   5749 
   5750   float	elapsed_time,
   5751         local_cpu_utilization,
   5752         remote_cpu_utilization;
   5753 
   5754   float	 local_service_demand, remote_service_demand;
   5755   double local_thruput, remote_thruput;
   5756   double bytes_sent;
   5757   double bytes_recvd;
   5758 
   5759 
   5760   int	len;
   5761   struct ring_elt *send_ring;
   5762   SOCKET 	data_socket;
   5763 
   5764   unsigned int sum_messages_sent;
   5765   unsigned int sum_messages_recvd;
   5766   unsigned int sum_failed_sends;
   5767   double sum_local_thruput;
   5768 
   5769   struct addrinfo *local_res;
   5770   struct addrinfo *remote_res;
   5771 
   5772   struct	udp_stream_request_struct	*udp_stream_request;
   5773   struct	udp_stream_response_struct	*udp_stream_response;
   5774   struct	udp_stream_results_struct	*udp_stream_results;
   5775 
   5776   udp_stream_request	=
   5777     (struct udp_stream_request_struct *)netperf_request.content.test_specific_data;
   5778   udp_stream_response	=
   5779     (struct udp_stream_response_struct *)netperf_response.content.test_specific_data;
   5780   udp_stream_results	=
   5781     (struct udp_stream_results_struct *)netperf_response.content.test_specific_data;
   5782 
   5783 #ifdef WANT_HISTOGRAM
   5784   if (verbosity > 1) {
   5785     time_hist = HIST_new();
   5786   }
   5787 #endif /* WANT_HISTOGRAM */
   5788 
   5789   /* since we are now disconnected from the code that established the */
   5790   /* control socket, and since we want to be able to use different */
   5791   /* protocols and such, we are passed the name of the remote host and */
   5792   /* must turn that into the test specific addressing information. */
   5793 
   5794   complete_addrinfos(&remote_res,
   5795 		     &local_res,
   5796 		     remote_host,
   5797 		     SOCK_DGRAM,
   5798 		     IPPROTO_UDP,
   5799 		     0);
   5800 
   5801   if ( print_headers ) {
   5802     print_top_test_header("UDP UNIDIRECTIONAL SEND TEST",local_res,remote_res);
   5803   }
   5804 
   5805   send_ring            = NULL;
   5806   confidence_iteration = 1;
   5807   init_stat();
   5808   sum_messages_sent    = 0;
   5809   sum_messages_recvd   = 0;
   5810   sum_failed_sends     = 0;
   5811   sum_local_thruput    = 0.0;
   5812 
   5813   /* we have a great-big while loop which controls the number of times */
   5814   /* we run a particular test. this is for the calculation of a */
   5815   /* confidence interval (I really should have stayed awake during */
   5816   /* probstats :). If the user did not request confidence measurement */
   5817   /* (no confidence is the default) then we will only go though the */
   5818   /* loop once. the confidence stuff originates from the folks at IBM */
   5819 
   5820   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   5821 	 (confidence_iteration <= iteration_min)) {
   5822 
   5823     /* initialize a few counters. we have to remember that we might be */
   5824     /* going through the loop more than once. */
   5825     messages_sent  = 0;
   5826     messages_recvd = 0;
   5827     failed_sends   = 0;
   5828     times_up       = 0;
   5829 
   5830     /*set up the data socket			*/
   5831     data_socket = create_data_socket(local_res);
   5832 
   5833     if (data_socket == INVALID_SOCKET){
   5834       perror("udp_send: data socket");
   5835       exit(1);
   5836     }
   5837 
   5838     /* now, we want to see if we need to set the send_size */
   5839     if (send_size == 0) {
   5840       if (lss_size > 0) {
   5841 	send_size = (lss_size < UDP_LENGTH_MAX ? lss_size : UDP_LENGTH_MAX);
   5842       }
   5843       else {
   5844 	send_size = 4096;
   5845       }
   5846     }
   5847 
   5848 
   5849     /* set-up the data buffer with the requested alignment and offset, */
   5850     /* most of the numbers here are just a hack to pick something nice */
   5851     /* and big in an attempt to never try to send a buffer a second time */
   5852     /* before it leaves the node...unless the user set the width */
   5853     /* explicitly. */
   5854     if (send_width == 0) send_width = 32;
   5855 
   5856     if (send_ring == NULL ) {
   5857       send_ring = allocate_buffer_ring(send_width,
   5858 				       send_size,
   5859 				       local_send_align,
   5860 				       local_send_offset);
   5861     }
   5862 
   5863 
   5864     /* if the user supplied a cpu rate, this call will complete rather */
   5865     /* quickly, otherwise, the cpu rate will be retured to us for */
   5866     /* possible display. The Library will keep it's own copy of this data */
   5867     /* for use elsewhere. We will only display it. (Does that make it */
   5868     /* "opaque" to us?) */
   5869 
   5870     if (local_cpu_usage)
   5871       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   5872 
   5873     if (!no_control) {
   5874       /* Tell the remote end to set up the data connection. The server
   5875          sends back the port number and alters the socket parameters
   5876          there.  Of course this is a datagram service so no connection
   5877          is actually set up, the server just sets up the socket and
   5878          binds it. */
   5879 
   5880       netperf_request.content.request_type      = DO_UDP_STREAM;
   5881       udp_stream_request->recv_buf_size  = rsr_size_req;
   5882       udp_stream_request->message_size   = send_size;
   5883       udp_stream_request->recv_connected = remote_connected;
   5884       udp_stream_request->recv_alignment = remote_recv_align;
   5885       udp_stream_request->recv_offset    = remote_recv_offset;
   5886       udp_stream_request->measure_cpu    = remote_cpu_usage;
   5887       udp_stream_request->cpu_rate       = remote_cpu_rate;
   5888       udp_stream_request->test_length    = test_time;
   5889       udp_stream_request->so_rcvavoid    = rem_rcvavoid;
   5890       udp_stream_request->so_sndavoid    = rem_sndavoid;
   5891       udp_stream_request->port           = atoi(remote_data_port);
   5892       udp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
   5893 
   5894       send_request();
   5895 
   5896       recv_response();
   5897 
   5898       if (!netperf_response.content.serv_errno) {
   5899 	if (debug)
   5900 	  fprintf(where,"send_udp_stream: remote data connection done.\n");
   5901       }
   5902       else {
   5903 	Set_errno(netperf_response.content.serv_errno);
   5904 	perror("send_udp_stream: error on remote");
   5905 	exit(1);
   5906       }
   5907 
   5908       /* Place the port number returned by the remote into the sockaddr */
   5909       /* structure so our sends can be sent to the correct place. Also get */
   5910       /* some of the returned socket buffer information for user display. */
   5911 
   5912       /* make sure that port numbers are in the proper order */
   5913       set_port_number(remote_res,(short)udp_stream_response->data_port_number);
   5914 
   5915       rsr_size        = udp_stream_response->recv_buf_size;
   5916       rss_size        = udp_stream_response->send_buf_size;
   5917       remote_cpu_rate = udp_stream_response->cpu_rate;
   5918     }
   5919 
   5920 #ifdef WANT_DEMO
   5921     DEMO_STREAM_SETUP(lss_size,rsr_size)
   5922 #endif
   5923 
   5924     /* We "connect" up to the remote post to allow is to use the send */
   5925     /* call instead of the sendto call. Presumeably, this is a little */
   5926     /* simpler, and a little more efficient. I think that it also means */
   5927     /* that we can be informed of certain things, but am not sure */
   5928     /* yet...also, this is the way I would expect a client to behave */
   5929     /* when talking to a server */
   5930     if (local_connected) {
   5931        if (connect(data_socket,
   5932       		   remote_res->ai_addr,
   5933 		   remote_res->ai_addrlen) == INVALID_SOCKET){
   5934           perror("send_udp_stream: data socket connect failed");
   5935           exit(1);
   5936        } else if (debug) {
   5937           fprintf(where,"send_udp_stream: connected data socket.\n");
   5938           fflush(where);
   5939        }
   5940     }
   5941 
   5942     /* set up the timer to call us after test_time. one of these days, */
   5943     /* it might be nice to figure-out a nice reliable way to have the */
   5944     /* test controlled by a byte count as well, but since UDP is not */
   5945     /* reliable, that could prove difficult. so, in the meantime, we */
   5946     /* only allow a UDP_STREAM test to be a timed test. */
   5947 
   5948     if (test_time) {
   5949       times_up = 0;
   5950       start_timer(test_time);
   5951     }
   5952     else {
   5953       fprintf(where,"Sorry, UDP_STREAM tests must be timed.\n");
   5954       fflush(where);
   5955     }
   5956 
   5957     /* Get the start count for the idle counter and the start time */
   5958 
   5959     cpu_start(local_cpu_usage);
   5960 
   5961 #ifdef WANT_INTERVALS
   5962     INTERVALS_INIT();
   5963 #endif /* WANT_INTERVALS */
   5964 
   5965 #ifdef WANT_DEMO
   5966     if (demo_mode) {
   5967       HIST_timestamp(demo_one_ptr);
   5968     }
   5969 #endif
   5970 
   5971     /* Send datagrams like there was no tomorrow. at somepoint it might */
   5972     /* be nice to set this up so that a quantity of bytes could be sent, */
   5973     /* but we still need some sort of end of test trigger on the receive */
   5974     /* side. that could be a select with a one second timeout, but then */
   5975     /* if there is a test where none of the data arrives for awile and */
   5976     /* then starts again, we would end the test too soon. something to */
   5977     /* think about... */
   5978     while (!times_up) {
   5979 
   5980 #ifdef DIRTY
   5981       /* we want to dirty some number of consecutive integers in the buffer */
   5982       /* we are about to send. we may also want to bring some number of */
   5983       /* them cleanly into the cache. The clean ones will follow any dirty */
   5984       /* ones into the cache. */
   5985 
   5986       access_buffer(send_ring->buffer_ptr,
   5987 		    send_size,
   5988 		    loc_dirty_count,
   5989 		    loc_clean_count);
   5990 #endif /* DIRTY */
   5991 
   5992 #ifdef WANT_HISTOGRAM
   5993       if (verbosity > 1) {
   5994 	HIST_timestamp(&time_one);
   5995       }
   5996 #endif /* WANT_HISTOGRAM */
   5997 
   5998       if (local_connected) {
   5999          len = send(data_socket,
   6000 	  	    send_ring->buffer_ptr,
   6001 		    send_size,
   6002 		    0);
   6003       } else {
   6004          len = sendto(data_socket,
   6005 		      send_ring->buffer_ptr,
   6006 		      send_size,
   6007 		      0,
   6008 		      remote_res->ai_addr,
   6009 		      remote_res->ai_addrlen);
   6010       }
   6011 
   6012       if (len != send_size) {
   6013 	if ((len >= 0) ||
   6014 	    SOCKET_EINTR(len))
   6015 	  break;
   6016 	if (errno == ENOBUFS) {
   6017 	  failed_sends++;
   6018 	  continue;
   6019 	}
   6020 	perror("udp_send: data send error");
   6021 	exit(1);
   6022       }
   6023       messages_sent++;
   6024 
   6025       /* now we want to move our pointer to the next position in the */
   6026       /* data buffer... */
   6027 
   6028       send_ring = send_ring->next;
   6029 
   6030 
   6031 #ifdef WANT_HISTOGRAM
   6032       if (verbosity > 1) {
   6033 	/* get the second timestamp */
   6034 	HIST_timestamp(&time_two);
   6035 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   6036       }
   6037 #endif /* WANT_HISTOGRAM */
   6038 
   6039 #ifdef WANT_DEMO
   6040       DEMO_STREAM_INTERVAL(send_size)
   6041 #endif
   6042 
   6043 #ifdef WANT_INTERVALS
   6044       INTERVALS_WAIT();
   6045 #endif /* WANT_INTERVALS */
   6046 
   6047     }
   6048 
   6049     /* This is a timed test, so the remote will be returning to us after */
   6050     /* a time. We should not need to send any "strange" messages to tell */
   6051     /* the remote that the test is completed, unless we decide to add a */
   6052     /* number of messages to the test. */
   6053 
   6054     /* the test is over, so get stats and stuff */
   6055     cpu_stop(local_cpu_usage,
   6056 	     &elapsed_time);
   6057 
   6058     if (!no_control) {
   6059       /* Get the statistics from the remote end	*/
   6060       recv_response();
   6061       if (!netperf_response.content.serv_errno) {
   6062 	if (debug)
   6063 	  fprintf(where,"send_udp_stream: remote results obtained\n");
   6064       }
   6065       else {
   6066 	Set_errno(netperf_response.content.serv_errno);
   6067 	perror("send_udp_stream: error on remote");
   6068 	exit(1);
   6069       }
   6070       messages_recvd = udp_stream_results->messages_recvd;
   6071       bytes_recvd    = (double) send_size * (double) messages_recvd;
   6072     }
   6073     else {
   6074       /* since there was no control connection, we've no idea what was
   6075 	 actually received. raj 2007-02-08 */
   6076       messages_recvd = -1;
   6077       bytes_recvd = -1.0;
   6078     }
   6079 
   6080     bytes_sent    = (double) send_size * (double) messages_sent;
   6081     local_thruput = calc_thruput(bytes_sent);
   6082 
   6083 
   6084     /* we asume that the remote ran for as long as we did */
   6085 
   6086     remote_thruput = calc_thruput(bytes_recvd);
   6087 
   6088     /* print the results for this socket and message size */
   6089 
   6090     if (local_cpu_usage || remote_cpu_usage) {
   6091       /* We must now do a little math for service demand and cpu */
   6092       /* utilization for the system(s) We pass zeros for the local */
   6093       /* cpu utilization and elapsed time to tell the routine to use */
   6094       /* the libraries own values for those. */
   6095       if (local_cpu_usage) {
   6096 	local_cpu_utilization	= calc_cpu_util(0.0);
   6097 	/* shouldn't this really be based on bytes_recvd, since that is */
   6098 	/* the effective throughput of the test? I think that it should, */
   6099 	/* so will make the change raj 11/94 */
   6100 	local_service_demand	= calc_service_demand(bytes_recvd,
   6101 						      0.0,
   6102 						      0.0,
   6103 						      0);
   6104       }
   6105       else {
   6106 	local_cpu_utilization	= (float) -1.0;
   6107 	local_service_demand	= (float) -1.0;
   6108       }
   6109 
   6110       /* The local calculations could use variables being kept by */
   6111       /* the local netlib routines. The remote calcuations need to */
   6112       /* have a few things passed to them. */
   6113       if (remote_cpu_usage) {
   6114 	remote_cpu_utilization	= udp_stream_results->cpu_util;
   6115 	remote_service_demand	= calc_service_demand(bytes_recvd,
   6116 						      0.0,
   6117 						      remote_cpu_utilization,
   6118 						      udp_stream_results->num_cpus);
   6119       }
   6120       else {
   6121 	remote_cpu_utilization	= (float) -1.0;
   6122 	remote_service_demand	= (float) -1.0;
   6123       }
   6124     }
   6125     else {
   6126       /* we were not measuring cpu, for the confidence stuff, we */
   6127       /* should make it -1.0 */
   6128       local_cpu_utilization  = (float) -1.0;
   6129       local_service_demand   = (float) -1.0;
   6130       remote_cpu_utilization = (float) -1.0;
   6131       remote_service_demand  = (float) -1.0;
   6132     }
   6133 
   6134     /* at this point, we want to calculate the confidence information. */
   6135     /* if debugging is on, calculate_confidence will print-out the */
   6136     /* parameters we pass it */
   6137 
   6138     calculate_confidence(confidence_iteration,
   6139 			 elapsed_time,
   6140 			 remote_thruput,
   6141 			 local_cpu_utilization,
   6142 			 remote_cpu_utilization,
   6143 			 local_service_demand,
   6144 			 remote_service_demand);
   6145 
   6146     /* since the routine calculate_confidence is rather generic, and */
   6147     /* we have a few other parms of interest, we will do a little work */
   6148     /* here to caclulate their average. */
   6149     sum_messages_sent  += messages_sent;
   6150     sum_messages_recvd += messages_recvd;
   6151     sum_failed_sends   += failed_sends;
   6152     sum_local_thruput  += local_thruput;
   6153 
   6154     confidence_iteration++;
   6155 
   6156     /* this datapoint is done, so we don't need the socket any longer */
   6157     close(data_socket);
   6158 
   6159   }
   6160 
   6161   /* we should reach this point once the test is finished */
   6162 
   6163   retrieve_confident_values(&elapsed_time,
   6164 			    &remote_thruput,
   6165 			    &local_cpu_utilization,
   6166 			    &remote_cpu_utilization,
   6167 			    &local_service_demand,
   6168 			    &remote_service_demand);
   6169 
   6170   /* some of the interesting values aren't covered by the generic */
   6171   /* confidence routine */
   6172   messages_sent    = sum_messages_sent / (confidence_iteration -1);
   6173   messages_recvd   = sum_messages_recvd / (confidence_iteration -1);
   6174   failed_sends     = sum_failed_sends / (confidence_iteration -1);
   6175   local_thruput    = sum_local_thruput / (confidence_iteration -1);
   6176 
   6177   /* We are now ready to print all the information. If the user */
   6178   /* has specified zero-level verbosity, we will just print the */
   6179   /* local service demand, or the remote service demand. If the */
   6180   /* user has requested verbosity level 1, he will get the basic */
   6181   /* "streamperf" numbers. If the user has specified a verbosity */
   6182   /* of greater than 1, we will display a veritable plethora of */
   6183   /* background information from outside of this block as it it */
   6184   /* not cpu_measurement specific...  */
   6185 
   6186 
   6187   if (confidence < 0) {
   6188     /* we did not hit confidence, but were we asked to look for it? */
   6189     if (iteration_max > 1) {
   6190       display_confidence();
   6191     }
   6192   }
   6193 
   6194   if (local_cpu_usage || remote_cpu_usage) {
   6195     local_cpu_method = format_cpu_method(cpu_method);
   6196     remote_cpu_method = format_cpu_method(udp_stream_results->cpu_method);
   6197 
   6198     switch (verbosity) {
   6199     case 0:
   6200       if (local_cpu_usage) {
   6201 	fprintf(where,
   6202 		cpu_fmt_0,
   6203 		local_service_demand,
   6204 		local_cpu_method);
   6205       }
   6206       else {
   6207 	fprintf(where,
   6208 		cpu_fmt_0,
   6209 		remote_service_demand,
   6210 		local_cpu_method);
   6211       }
   6212       break;
   6213     case 1:
   6214     case 2:
   6215       if (print_headers) {
   6216 	fprintf(where,
   6217 		cpu_title,
   6218 		format_units(),
   6219 		local_cpu_method,
   6220 		remote_cpu_method);
   6221       }
   6222 
   6223       fprintf(where,
   6224 	      cpu_fmt_1,		/* the format string */
   6225 	      lss_size,		        /* local sendbuf size */
   6226 	      send_size,		/* how large were the sends */
   6227 	      elapsed_time,		/* how long was the test */
   6228 	      messages_sent,
   6229 	      failed_sends,
   6230 	      local_thruput, 		/* what was the xfer rate */
   6231 	      local_cpu_utilization,	/* local cpu */
   6232 	      local_service_demand,	/* local service demand */
   6233 	      rsr_size,
   6234 	      elapsed_time,
   6235 	      messages_recvd,
   6236 	      remote_thruput,
   6237 	      remote_cpu_utilization,	/* remote cpu */
   6238 	      remote_service_demand);	/* remote service demand */
   6239       break;
   6240     }
   6241   }
   6242   else {
   6243     /* The tester did not wish to measure service demand. */
   6244     switch (verbosity) {
   6245     case 0:
   6246       fprintf(where,
   6247 	      tput_fmt_0,
   6248 	      local_thruput);
   6249       break;
   6250     case 1:
   6251     case 2:
   6252       if (print_headers) {
   6253 	fprintf(where,tput_title,format_units());
   6254       }
   6255       fprintf(where,
   6256 	      tput_fmt_1,		/* the format string */
   6257 	      lss_size, 		/* local sendbuf size */
   6258 	      send_size,		/* how large were the sends */
   6259 	      elapsed_time, 		/* how long did it take */
   6260 	      messages_sent,
   6261 	      failed_sends,
   6262 	      local_thruput,
   6263 	      rsr_size, 		/* remote recvbuf size */
   6264 	      elapsed_time,
   6265 	      messages_recvd,
   6266 	      remote_thruput);
   6267       break;
   6268     }
   6269   }
   6270 
   6271   fflush(where);
   6272 #ifdef WANT_HISTOGRAM
   6273   if (verbosity > 1) {
   6274     fprintf(where,"\nHistogram of time spent in send() call\n");
   6275     fflush(where);
   6276     HIST_report(time_hist);
   6277   }
   6278 #endif /* WANT_HISTOGRAM */
   6279 
   6280 }
   6281 
   6282 
   6284  /* this routine implements the receive side (netserver) of the */
   6285  /* UDP_STREAM performance test. */
   6286 
   6287 void
   6288 recv_udp_stream()
   6289 {
   6290   struct ring_elt *recv_ring;
   6291   struct addrinfo *local_res;
   6292   char local_name[BUFSIZ];
   6293   char port_buffer[PORTBUFSIZE];
   6294 
   6295   struct sockaddr_storage myaddr_in;
   6296   SOCKET	s_data;
   6297   netperf_socklen_t 	addrlen;
   6298   struct sockaddr_storage remote_addr;
   6299   netperf_socklen_t remote_addrlen;
   6300 
   6301   int	len = 0;
   6302   unsigned int	bytes_received = 0;
   6303   float	elapsed_time;
   6304 
   6305   int	message_size;
   6306   unsigned int	messages_recvd = 0;
   6307 
   6308   struct	udp_stream_request_struct	*udp_stream_request;
   6309   struct	udp_stream_response_struct	*udp_stream_response;
   6310   struct	udp_stream_results_struct	*udp_stream_results;
   6311 
   6312   udp_stream_request  =
   6313     (struct udp_stream_request_struct *)netperf_request.content.test_specific_data;
   6314   udp_stream_response =
   6315     (struct udp_stream_response_struct *)netperf_response.content.test_specific_data;
   6316   udp_stream_results  =
   6317     (struct udp_stream_results_struct *)netperf_response.content.test_specific_data;
   6318 
   6319   if (debug) {
   6320     fprintf(where,"netserver: recv_udp_stream: entered...\n");
   6321     fflush(where);
   6322   }
   6323 
   6324   /* We want to set-up the listen socket with all the desired */
   6325   /* parameters and then let the initiator know that all is ready. If */
   6326   /* socket size defaults are to be used, then the initiator will have */
   6327   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   6328   /* send-back what they are. If that information cannot be determined, */
   6329   /* then we send-back -1's for the sizes. If things go wrong for any */
   6330   /* reason, we will drop back ten yards and punt. */
   6331 
   6332   /* If anything goes wrong, we want the remote to know about it. It */
   6333   /* would be best if the error that the remote reports to the user is */
   6334   /* the actual error we encountered, rather than some bogus unexpected */
   6335   /* response type message. */
   6336 
   6337   if (debug > 1) {
   6338     fprintf(where,"recv_udp_stream: setting the response type...\n");
   6339     fflush(where);
   6340   }
   6341 
   6342   netperf_response.content.response_type = UDP_STREAM_RESPONSE;
   6343 
   6344   if (debug > 2) {
   6345     fprintf(where,"recv_udp_stream: the response type is set...\n");
   6346     fflush(where);
   6347   }
   6348 
   6349   /* We now alter the message_ptr variable to be at the desired */
   6350   /* alignment with the desired offset. */
   6351 
   6352   if (debug > 1) {
   6353     fprintf(where,"recv_udp_stream: requested alignment of %d\n",
   6354 	    udp_stream_request->recv_alignment);
   6355     fflush(where);
   6356   }
   6357 
   6358   if (recv_width == 0) recv_width = 1;
   6359 
   6360   recv_ring = allocate_buffer_ring(recv_width,
   6361 				   udp_stream_request->message_size,
   6362 				   udp_stream_request->recv_alignment,
   6363 				   udp_stream_request->recv_offset);
   6364 
   6365   if (debug > 1) {
   6366     fprintf(where,"recv_udp_stream: receive alignment and offset set...\n");
   6367     fflush(where);
   6368   }
   6369 
   6370   /* Grab a socket to listen on, and then listen on it. */
   6371 
   6372   if (debug > 1) {
   6373     fprintf(where,"recv_udp_stream: grabbing a socket...\n");
   6374     fflush(where);
   6375   }
   6376 
   6377   /* create_data_socket expects to find some things in the global */
   6378   /* variables, so set the globals based on the values in the request. */
   6379   /* once the socket has been created, we will set the response values */
   6380   /* based on the updated value of those globals. raj 7/94 */
   6381   lsr_size_req = udp_stream_request->recv_buf_size;
   6382   loc_rcvavoid = udp_stream_request->so_rcvavoid;
   6383   loc_sndavoid = udp_stream_request->so_sndavoid;
   6384   local_connected = udp_stream_request->recv_connected;
   6385 
   6386   set_hostname_and_port(local_name,
   6387 			port_buffer,
   6388 			nf_to_af(udp_stream_request->ipfamily),
   6389 			udp_stream_request->port);
   6390 
   6391   local_res = complete_addrinfo(local_name,
   6392 				local_name,
   6393 				port_buffer,
   6394 				nf_to_af(udp_stream_request->ipfamily),
   6395 				SOCK_DGRAM,
   6396 				IPPROTO_UDP,
   6397 				0);
   6398 
   6399   s_data = create_data_socket(local_res);
   6400 
   6401   if (s_data == INVALID_SOCKET) {
   6402     netperf_response.content.serv_errno = errno;
   6403     send_response();
   6404     exit(1);
   6405   }
   6406 
   6407   udp_stream_response->test_length = udp_stream_request->test_length;
   6408 
   6409   /* now get the port number assigned by the system  */
   6410   addrlen = sizeof(myaddr_in);
   6411   if (getsockname(s_data,
   6412 		  (struct sockaddr *)&myaddr_in,
   6413 		  &addrlen) == SOCKET_ERROR){
   6414     netperf_response.content.serv_errno = errno;
   6415     close(s_data);
   6416     send_response();
   6417 
   6418     exit(1);
   6419   }
   6420 
   6421   /* Now myaddr_in contains the port and the internet address this is */
   6422   /* returned to the sender also implicitly telling the sender that the */
   6423   /* socket buffer sizing has been done. */
   6424 
   6425   udp_stream_response->data_port_number =
   6426     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
   6427   netperf_response.content.serv_errno   = 0;
   6428 
   6429   /* But wait, there's more. If the initiator wanted cpu measurements, */
   6430   /* then we must call the calibrate routine, which will return the max */
   6431   /* rate back to the initiator. If the CPU was not to be measured, or */
   6432   /* something went wrong with the calibration, we will return a -1 to */
   6433   /* the initiator. */
   6434 
   6435   udp_stream_response->cpu_rate    = (float)0.0; /* assume no cpu */
   6436   udp_stream_response->measure_cpu = 0;
   6437   if (udp_stream_request->measure_cpu) {
   6438     /* We will pass the rate into the calibration routine. If the */
   6439     /* user did not specify one, it will be 0.0, and we will do a */
   6440     /* "real" calibration. Otherwise, all it will really do is */
   6441     /* store it away... */
   6442     udp_stream_response->measure_cpu = 1;
   6443     udp_stream_response->cpu_rate =
   6444       calibrate_local_cpu(udp_stream_request->cpu_rate);
   6445   }
   6446 
   6447   message_size	= udp_stream_request->message_size;
   6448   test_time	= udp_stream_request->test_length;
   6449 
   6450   /* before we send the response back to the initiator, pull some of */
   6451   /* the socket parms from the globals */
   6452   udp_stream_response->send_buf_size = lss_size;
   6453   udp_stream_response->recv_buf_size = lsr_size;
   6454   udp_stream_response->so_rcvavoid = loc_rcvavoid;
   6455   udp_stream_response->so_sndavoid = loc_sndavoid;
   6456 
   6457   send_response();
   6458 
   6459   /* Now it's time to start receiving data on the connection. We will */
   6460   /* first grab the apropriate counters and then start grabbing. */
   6461 
   6462   cpu_start(udp_stream_request->measure_cpu);
   6463 
   6464 #ifdef WIN32
   6465   /* this is used so the timer thread can close the socket out from */
   6466   /* under us, which to date is the easiest/cleanest/least */
   6467   /* Windows-specific way I can find to force the winsock calls to */
   6468   /* return WSAEINTR with the test is over. anything that will run on */
   6469   /* 95 and NT and is closer to what netperf expects from Unix signals */
   6470   /* and such would be appreciated raj 1/96 */
   6471   win_kludge_socket = s_data;
   6472 #endif /* WIN32 */
   6473 
   6474   /* The loop will exit when the timer pops, or if we happen to recv a */
   6475   /* message of less than send_size bytes... */
   6476 
   6477   times_up = 0;
   6478 
   6479   start_timer(test_time + PAD_TIME);
   6480 
   6481   if (debug) {
   6482     fprintf(where,"recv_udp_stream: about to enter inner sanctum.\n");
   6483     fflush(where);
   6484   }
   6485 
   6486   /* We "connect" up to the remote post to allow us to use the recv */
   6487   /* call instead of the recvfrom call. Presumeably, this is a little */
   6488   /* simpler, and a little more efficient. */
   6489 
   6490   if (local_connected) {
   6491 
   6492     /* Receive the first message using recvfrom to find the remote address */
   6493     remote_addrlen = sizeof(remote_addr);
   6494     len = recvfrom(s_data, recv_ring->buffer_ptr,
   6495                    message_size, 0,
   6496                    (struct sockaddr*)&remote_addr, &remote_addrlen);
   6497     if (len != message_size) {
   6498       if ((len == SOCKET_ERROR) && !SOCKET_EINTR(len)) {
   6499             netperf_response.content.serv_errno = errno;
   6500             send_response();
   6501             exit(1);
   6502       }
   6503     }
   6504     messages_recvd++;
   6505     recv_ring = recv_ring->next;
   6506 
   6507 
   6508     /* Now connect with the remote socket address */
   6509     if (connect(s_data,
   6510                 (struct sockaddr*)&remote_addr,
   6511                 remote_addrlen )== INVALID_SOCKET) {
   6512         netperf_response.content.serv_errno = errno;
   6513         close(s_data);
   6514         send_response();
   6515         exit(1);
   6516     }
   6517 
   6518     if (debug) {
   6519         fprintf(where,"recv_udp_stream: connected data socket\n");
   6520         fflush(where);
   6521      }
   6522   }
   6523 
   6524   while (!times_up) {
   6525     if(local_connected) {
   6526        len = recv(s_data,
   6527                   recv_ring->buffer_ptr,
   6528                   message_size,
   6529                   0);
   6530     } else {
   6531        len = recvfrom(s_data,
   6532                       recv_ring->buffer_ptr,
   6533     	              message_size,
   6534 		      0,0,0);
   6535     }
   6536 
   6537     if (len != message_size) {
   6538       if ((len == SOCKET_ERROR) && !SOCKET_EINTR(len)) {
   6539             netperf_response.content.serv_errno = errno;
   6540 	    send_response();
   6541 	    exit(1);
   6542       }
   6543       break;
   6544     }
   6545     messages_recvd++;
   6546     recv_ring = recv_ring->next;
   6547   }
   6548 
   6549   if (debug) {
   6550     fprintf(where,"recv_udp_stream: got %d messages.\n",messages_recvd);
   6551     fflush(where);
   6552   }
   6553 
   6554 
   6555   /* The loop now exits due timer or < send_size bytes received. in */
   6556   /* reality, we only really support a timed UDP_STREAM test. raj */
   6557   /* 12/95 */
   6558 
   6559   cpu_stop(udp_stream_request->measure_cpu,&elapsed_time);
   6560 
   6561   if (times_up) {
   6562     /* we ended on a timer, subtract the PAD_TIME */
   6563     elapsed_time -= (float)PAD_TIME;
   6564   }
   6565   else {
   6566     stop_timer();
   6567   }
   6568 
   6569   if (debug) {
   6570     fprintf(where,"recv_udp_stream: test ended in %f seconds.\n",elapsed_time);
   6571     fflush(where);
   6572   }
   6573 
   6574 
   6575   /* We will count the "off" message that got us out of the loop */
   6576   bytes_received = (messages_recvd * message_size) + len;
   6577 
   6578   /* send the results to the sender			*/
   6579 
   6580   if (debug) {
   6581     fprintf(where,
   6582 	    "recv_udp_stream: got %d bytes\n",
   6583 	    bytes_received);
   6584     fflush(where);
   6585   }
   6586 
   6587   netperf_response.content.response_type	= UDP_STREAM_RESULTS;
   6588   udp_stream_results->bytes_received	= htonl(bytes_received);
   6589   udp_stream_results->messages_recvd	= messages_recvd;
   6590   udp_stream_results->elapsed_time	= elapsed_time;
   6591   udp_stream_results->cpu_method        = cpu_method;
   6592   udp_stream_results->num_cpus          = lib_num_loc_cpus;
   6593   if (udp_stream_request->measure_cpu) {
   6594     udp_stream_results->cpu_util	= calc_cpu_util(elapsed_time);
   6595   }
   6596   else {
   6597     udp_stream_results->cpu_util	= (float) -1.0;
   6598   }
   6599 
   6600   if (debug > 1) {
   6601     fprintf(where,
   6602 	    "recv_udp_stream: test complete, sending results.\n");
   6603     fflush(where);
   6604   }
   6605 
   6606   send_response();
   6607 
   6608   close(s_data);
   6609 
   6610 }
   6611 
   6612 void
   6614 send_udp_rr(char remote_host[])
   6615 {
   6616 
   6617   char *tput_title = "\
   6618 Local /Remote\n\
   6619 Socket Size   Request  Resp.   Elapsed  Trans.\n\
   6620 Send   Recv   Size     Size    Time     Rate         \n\
   6621 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
   6622 
   6623   char *tput_fmt_0 =
   6624     "%7.2f\n";
   6625 
   6626   char *tput_fmt_1_line_1 = "\
   6627 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
   6628   char *tput_fmt_1_line_2 = "\
   6629 %-6d %-6d\n";
   6630 
   6631   char *cpu_title = "\
   6632 Local /Remote\n\
   6633 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
   6634 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
   6635 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
   6636 
   6637   char *cpu_fmt_0 =
   6638     "%6.3f %c\n";
   6639 
   6640   char *cpu_fmt_1_line_1 = "\
   6641 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f\n";
   6642 
   6643   char *cpu_fmt_1_line_2 = "\
   6644 %-6d %-6d\n";
   6645 
   6646   float			elapsed_time;
   6647 
   6648   struct ring_elt *send_ring;
   6649   struct ring_elt *recv_ring;
   6650 
   6651   int	len;
   6652   int	nummessages;
   6653   SOCKET	send_socket;
   6654   int	trans_remaining;
   6655   int	bytes_xferd;
   6656 
   6657   int	rsp_bytes_recvd;
   6658 
   6659   float	local_cpu_utilization;
   6660   float	local_service_demand;
   6661   float	remote_cpu_utilization;
   6662   float	remote_service_demand;
   6663   double	thruput;
   6664 
   6665   struct addrinfo *local_res;
   6666   struct addrinfo *remote_res;
   6667 
   6668   struct	udp_rr_request_struct	*udp_rr_request;
   6669   struct	udp_rr_response_struct	*udp_rr_response;
   6670   struct	udp_rr_results_struct	*udp_rr_result;
   6671 
   6672   udp_rr_request  =
   6673     (struct udp_rr_request_struct *)netperf_request.content.test_specific_data;
   6674   udp_rr_response =
   6675     (struct udp_rr_response_struct *)netperf_response.content.test_specific_data;
   6676   udp_rr_result	 =
   6677     (struct udp_rr_results_struct *)netperf_response.content.test_specific_data;
   6678 
   6679 #ifdef WANT_HISTOGRAM
   6680   if (verbosity > 1) {
   6681     time_hist = HIST_new();
   6682   }
   6683 #endif
   6684 
   6685   /* since we are now disconnected from the code that established the */
   6686   /* control socket, and since we want to be able to use different */
   6687   /* protocols and such, we are passed the name of the remote host and */
   6688   /* must turn that into the test specific addressing information. */
   6689 
   6690   complete_addrinfos(&remote_res,
   6691 		     &local_res,
   6692 		     remote_host,
   6693 		     SOCK_DGRAM,
   6694 		     IPPROTO_UDP,
   6695 		     0);
   6696 
   6697   if ( print_headers ) {
   6698     print_top_test_header("UDP REQUEST/RESPONSE TEST",local_res,remote_res);
   6699   }
   6700 
   6701   /* initialize a few counters */
   6702 
   6703   send_ring     = NULL;
   6704   recv_ring     = NULL;
   6705   nummessages	= 0;
   6706   bytes_xferd	= 0;
   6707   times_up 	= 0;
   6708   confidence_iteration = 1;
   6709   init_stat();
   6710 
   6711   /* we have a great-big while loop which controls the number of times */
   6712   /* we run a particular test. this is for the calculation of a */
   6713   /* confidence interval (I really should have stayed awake during */
   6714   /* probstats :). If the user did not request confidence measurement */
   6715   /* (no confidence is the default) then we will only go though the */
   6716   /* loop once. the confidence stuff originates from the folks at IBM */
   6717 
   6718   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   6719 	 (confidence_iteration <= iteration_min)) {
   6720 
   6721     nummessages     = 0;
   6722     bytes_xferd     = 0;
   6723     times_up        = 0;
   6724     trans_remaining = 0;
   6725 
   6726     /* set-up the data buffers with the requested alignment and offset */
   6727 
   6728     if (send_width == 0) send_width = 1;
   6729     if (recv_width == 0) recv_width = 1;
   6730 
   6731     if (send_ring == NULL) {
   6732       send_ring = allocate_buffer_ring(send_width,
   6733 				       req_size,
   6734 				       local_send_align,
   6735 				       local_send_offset);
   6736     }
   6737 
   6738     if (recv_ring == NULL) {
   6739       recv_ring = allocate_buffer_ring(recv_width,
   6740 				       rsp_size,
   6741 				       local_recv_align,
   6742 				       local_recv_offset);
   6743     }
   6744 
   6745     /*set up the data socket                        */
   6746     send_socket = create_data_socket(local_res);
   6747 
   6748     if (send_socket == INVALID_SOCKET){
   6749       perror("netperf: send_udp_rr: udp rr data socket");
   6750       exit(1);
   6751     }
   6752 
   6753     if (debug) {
   6754       fprintf(where,"send_udp_rr: send_socket obtained...\n");
   6755     }
   6756 
   6757     /* If the user has requested cpu utilization measurements, we must */
   6758     /* calibrate the cpu(s). We will perform this task within the tests */
   6759     /* themselves. If the user has specified the cpu rate, then */
   6760     /* calibrate_local_cpu will return rather quickly as it will have */
   6761     /* nothing to do. If local_cpu_rate is zero, then we will go through */
   6762     /* all the "normal" calibration stuff and return the rate back. If */
   6763     /* there is no idle counter in the kernel idle loop, the */
   6764     /* local_cpu_rate will be set to -1. */
   6765 
   6766     if (local_cpu_usage) {
   6767       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   6768     }
   6769 
   6770     if (!no_control) {
   6771       /* Tell the remote end to do a listen. The server alters the
   6772 	 socket paramters on the other side at this point, hence the
   6773 	 reason for all the values being passed in the setup
   6774 	 message. If the user did not specify any of the parameters,
   6775 	 they will be passed as 0, which will indicate to the remote
   6776 	 that no changes beyond the system's default should be
   6777 	 used. Alignment is the exception, it will default to 8, which
   6778 	 will be no alignment alterations. */
   6779 
   6780       netperf_request.content.request_type	= DO_UDP_RR;
   6781       udp_rr_request->recv_buf_size	= rsr_size_req;
   6782       udp_rr_request->send_buf_size	= rss_size_req;
   6783       udp_rr_request->recv_alignment      = remote_recv_align;
   6784       udp_rr_request->recv_offset	        = remote_recv_offset;
   6785       udp_rr_request->send_alignment      = remote_send_align;
   6786       udp_rr_request->send_offset	        = remote_send_offset;
   6787       udp_rr_request->request_size	= req_size;
   6788       udp_rr_request->response_size	= rsp_size;
   6789       udp_rr_request->measure_cpu	        = remote_cpu_usage;
   6790       udp_rr_request->cpu_rate	        = remote_cpu_rate;
   6791       udp_rr_request->so_rcvavoid	        = rem_rcvavoid;
   6792       udp_rr_request->so_sndavoid	        = rem_sndavoid;
   6793       if (test_time) {
   6794 	udp_rr_request->test_length	= test_time;
   6795       }
   6796       else {
   6797 	udp_rr_request->test_length	= test_trans * -1;
   6798       }
   6799       udp_rr_request->port                = atoi(remote_data_port);
   6800       udp_rr_request->ipfamily = af_to_nf(remote_res->ai_family);
   6801 
   6802       if (debug > 1) {
   6803 	fprintf(where,"netperf: send_udp_rr: requesting UDP r/r test\n");
   6804       }
   6805 
   6806       send_request();
   6807 
   6808       /* The response from the remote will contain all of the relevant
   6809 	 socket parameters for this test type. We will put them back
   6810 	 into the variables here so they can be displayed if desired.
   6811 	 The remote will have calibrated CPU if necessary, and will
   6812 	 have done all the needed set-up we will have calibrated the
   6813 	 cpu locally before sending the request, and will grab the
   6814 	 counter value right after the connect returns. The remote
   6815 	 will grab the counter right after the accept call. This saves
   6816 	 the hassle of extra messages being sent for the UDP
   6817 	 tests.  */
   6818 
   6819       recv_response();
   6820 
   6821       if (!netperf_response.content.serv_errno) {
   6822 	if (debug)
   6823 	  fprintf(where,"remote listen done.\n");
   6824 	rsr_size	       =	udp_rr_response->recv_buf_size;
   6825 	rss_size	       =	udp_rr_response->send_buf_size;
   6826 	remote_cpu_usage =	udp_rr_response->measure_cpu;
   6827 	remote_cpu_rate  = 	udp_rr_response->cpu_rate;
   6828 	/* port numbers in proper order */
   6829 	set_port_number(remote_res,(short)udp_rr_response->data_port_number);
   6830       }
   6831       else {
   6832 	Set_errno(netperf_response.content.serv_errno);
   6833 	fprintf(where,
   6834 		"netperf: remote error %d",
   6835 		netperf_response.content.serv_errno);
   6836 	perror("");
   6837 	fflush(where);
   6838 	exit(1);
   6839       }
   6840     }
   6841 
   6842 #ifdef WANT_DEMO
   6843     DEMO_RR_SETUP(100)
   6844 #endif
   6845 
   6846     /* Connect up to the remote port on the data socket. This will set */
   6847     /* the default destination address on this socket. With UDP, this */
   6848     /* does make a performance difference as we may not have to do as */
   6849     /* many routing lookups, however, I expect that a client would */
   6850     /* behave this way. raj 1/94 */
   6851 
   6852     if ( connect(send_socket,
   6853 		 remote_res->ai_addr,
   6854 		 remote_res->ai_addrlen) == INVALID_SOCKET ) {
   6855       perror("netperf: data socket connect failed");
   6856       exit(1);
   6857     }
   6858 
   6859     /* Data Socket set-up is finished. If there were problems, either the */
   6860     /* connect would have failed, or the previous response would have */
   6861     /* indicated a problem. I failed to see the value of the extra */
   6862     /* message after the accept on the remote. If it failed, we'll see it */
   6863     /* here. If it didn't, we might as well start pumping data. */
   6864 
   6865     /* Set-up the test end conditions. For a request/response test, they */
   6866     /* can be either time or transaction based. */
   6867 
   6868     if (test_time) {
   6869       /* The user wanted to end the test after a period of time. */
   6870       times_up = 0;
   6871       trans_remaining = 0;
   6872       start_timer(test_time);
   6873     }
   6874     else {
   6875       /* The tester wanted to send a number of bytes. */
   6876       trans_remaining = test_bytes;
   6877       times_up = 1;
   6878     }
   6879 
   6880     /* The cpu_start routine will grab the current time and possibly */
   6881     /* value of the idle counter for later use in measuring cpu */
   6882     /* utilization and/or service demand and thruput. */
   6883 
   6884     cpu_start(local_cpu_usage);
   6885 
   6886 #ifdef WANT_DEMO
   6887     if (demo_mode) {
   6888       HIST_timestamp(demo_one_ptr);
   6889     }
   6890 #endif
   6891 
   6892 #ifdef WANT_INTERVALS
   6893     INTERVALS_INIT();
   6894 #endif /* WANT_INTERVALS */
   6895 
   6896     /* We use an "OR" to control test execution. When the test is */
   6897     /* controlled by time, the byte count check will always return */
   6898     /* false. When the test is controlled by byte count, the time test */
   6899     /* will always return false. When the test is finished, the whole */
   6900     /* expression will go false and we will stop sending data. I think */
   6901     /* I just arbitrarily decrement trans_remaining for the timed */
   6902     /* test, but will not do that just yet... One other question is */
   6903     /* whether or not the send buffer and the receive buffer should be */
   6904     /* the same buffer. */
   6905 
   6906 #ifdef WANT_FIRST_BURST
   6907     {
   6908       int i;
   6909       for (i = 0; i < first_burst_size; i++) {
   6910 	if((len=send(send_socket,
   6911 		     send_ring->buffer_ptr,
   6912 		     req_size,
   6913 		     0)) != req_size) {
   6914 	  /* we should never hit the end of the test in the first burst */
   6915 	  perror("send_udp_rr: initial burst data send error");
   6916 	  exit(-1);
   6917 	}
   6918       }
   6919     }
   6920 #endif /* WANT_FIRST_BURST */
   6921 
   6922     while ((!times_up) || (trans_remaining > 0)) {
   6923       /* send the request */
   6924 #ifdef WANT_HISTOGRAM
   6925       if (verbosity > 1) {
   6926 	HIST_timestamp(&time_one);
   6927       }
   6928 #endif
   6929       if((len=send(send_socket,
   6930 		   send_ring->buffer_ptr,
   6931 		   req_size,
   6932 		   0)) != req_size) {
   6933         if (SOCKET_EINTR(len)) {
   6934 	      /* We likely hit */
   6935 	      /* test-end time. */
   6936 	      break;
   6937 		}
   6938 	    perror("send_udp_rr: data send error");
   6939 	    exit(1);
   6940 	  }
   6941       send_ring = send_ring->next;
   6942 
   6943       /* receive the response. with UDP we will get it all, or nothing */
   6944 
   6945       if((rsp_bytes_recvd=recv(send_socket,
   6946 			       recv_ring->buffer_ptr,
   6947 			       rsp_size,
   6948 			       0)) != rsp_size) {
   6949 	    if (SOCKET_EINTR(rsp_bytes_recvd))
   6950 		{
   6951     	  /* Again, we have likely hit test-end time */
   6952 	      break;
   6953 		}
   6954 	    perror("send_udp_rr: data recv error");
   6955 	    exit(1);
   6956       }
   6957       recv_ring = recv_ring->next;
   6958 
   6959 #ifdef WANT_HISTOGRAM
   6960       if (verbosity > 1) {
   6961 	HIST_timestamp(&time_two);
   6962 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   6963       }
   6964 
   6965 #endif
   6966 
   6967       /* at this point, we may wish to sleep for some period of */
   6968       /* time, so we see how long that last transaction just took, */
   6969       /* and sleep for the difference of that and the interval. We */
   6970       /* will not sleep if the time would be less than a */
   6971       /* millisecond.  */
   6972 
   6973 #ifdef WANT_DEMO
   6974       DEMO_RR_INTERVAL(1);
   6975 #endif
   6976 
   6977 #ifdef WANT_INTERVALS
   6978       INTERVALS_WAIT();
   6979 #endif /* WANT_INTERVALS */
   6980 
   6981       nummessages++;
   6982       if (trans_remaining) {
   6983 	trans_remaining--;
   6984       }
   6985 
   6986       if (debug > 3) {
   6987 	if ((nummessages % 100) == 0) {
   6988 	  fprintf(where,"Transaction %d completed\n",nummessages);
   6989 	  fflush(where);
   6990 	}
   6991       }
   6992 
   6993     }
   6994 
   6995     /* for some strange reason, I used to call shutdown on the UDP */
   6996     /* data socket here. I'm not sure why, because it would not have */
   6997     /* any effect... raj 11/94 */
   6998 
   6999     /* this call will always give us the elapsed time for the test, and */
   7000     /* will also store-away the necessaries for cpu utilization */
   7001 
   7002     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
   7003 						/* measured? how long */
   7004 						/* did we really run? */
   7005 
   7006     if (!no_control) {
   7007       /* Get the statistics from the remote end. The remote will have
   7008 	 calculated service demand and all those interesting
   7009 	 things. If it wasn't supposed to care, it will return obvious
   7010 	 values. */
   7011 
   7012       recv_response();
   7013       if (!netperf_response.content.serv_errno) {
   7014 	if (debug)
   7015 	  fprintf(where,"remote results obtained\n");
   7016       }
   7017       else {
   7018 	Set_errno(netperf_response.content.serv_errno);
   7019 	fprintf(where,
   7020 		"netperf: remote error %d",
   7021 		netperf_response.content.serv_errno);
   7022 	perror("");
   7023 	fflush(where);
   7024 	exit(1);
   7025       }
   7026     }
   7027 
   7028     /* We now calculate what our thruput was for the test. In the */
   7029     /* future, we may want to include a calculation of the thruput */
   7030     /* measured by the remote, but it should be the case that for a */
   7031     /* UDP rr test, that the two numbers should be *very* close... */
   7032     /* We calculate bytes_sent regardless of the way the test length */
   7033     /* was controlled.  */
   7034 
   7035     bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
   7036     thruput	= nummessages / elapsed_time;
   7037 
   7038     if (local_cpu_usage || remote_cpu_usage) {
   7039 
   7040       /* We must now do a little math for service demand and cpu */
   7041       /* utilization for the system(s) Of course, some of the */
   7042       /* information might be bogus because there was no idle counter */
   7043       /* in the kernel(s). We need to make a note of this for the */
   7044       /* user's benefit by placing a code for the metod used in the */
   7045       /* test banner */
   7046 
   7047       if (local_cpu_usage) {
   7048 	local_cpu_utilization = calc_cpu_util(0.0);
   7049 
   7050 	/* since calc_service demand is doing ms/Kunit we will */
   7051 	/* multiply the number of transaction by 1024 to get */
   7052 	/* "good" numbers */
   7053 
   7054 	local_service_demand  = calc_service_demand((double) nummessages*1024,
   7055 						    0.0,
   7056 						    0.0,
   7057 						    0);
   7058       }
   7059       else {
   7060 	local_cpu_utilization	= (float) -1.0;
   7061 	local_service_demand	= (float) -1.0;
   7062       }
   7063 
   7064       if (remote_cpu_usage) {
   7065 	remote_cpu_utilization = udp_rr_result->cpu_util;
   7066 
   7067 	/* since calc_service demand is doing ms/Kunit we will */
   7068 	/* multiply the number of transaction by 1024 to get */
   7069 	/* "good" numbers */
   7070 
   7071 	remote_service_demand  = calc_service_demand((double) nummessages*1024,
   7072 						     0.0,
   7073 						     remote_cpu_utilization,
   7074 						     udp_rr_result->num_cpus);
   7075       }
   7076       else {
   7077 	remote_cpu_utilization = (float) -1.0;
   7078 	remote_service_demand  = (float) -1.0;
   7079       }
   7080     }
   7081     else {
   7082       /* we were not measuring cpu, for the confidence stuff, we */
   7083       /* should make it -1.0 */
   7084       local_cpu_utilization	= (float) -1.0;
   7085       local_service_demand	= (float) -1.0;
   7086       remote_cpu_utilization = (float) -1.0;
   7087       remote_service_demand  = (float) -1.0;
   7088     }
   7089 
   7090     /* at this point, we want to calculate the confidence information. */
   7091     /* if debugging is on, calculate_confidence will print-out the */
   7092     /* parameters we pass it */
   7093 
   7094     calculate_confidence(confidence_iteration,
   7095 			 elapsed_time,
   7096 			 thruput,
   7097 			 local_cpu_utilization,
   7098 			 remote_cpu_utilization,
   7099 			 local_service_demand,
   7100 			 remote_service_demand);
   7101 
   7102 
   7103     confidence_iteration++;
   7104 
   7105     /* we are done with the socket */
   7106     close(send_socket);
   7107   }
   7108 
   7109   /* at this point, we have made all the iterations we are going to */
   7110   /* make. */
   7111   retrieve_confident_values(&elapsed_time,
   7112 			    &thruput,
   7113 			    &local_cpu_utilization,
   7114 			    &remote_cpu_utilization,
   7115 			    &local_service_demand,
   7116 			    &remote_service_demand);
   7117 
   7118   /* We are now ready to print all the information. If the user */
   7119   /* has specified zero-level verbosity, we will just print the */
   7120   /* local service demand, or the remote service demand. If the */
   7121   /* user has requested verbosity level 1, he will get the basic */
   7122   /* "streamperf" numbers. If the user has specified a verbosity */
   7123   /* of greater than 1, we will display a veritable plethora of */
   7124   /* background information from outside of this block as it it */
   7125   /* not cpu_measurement specific...  */
   7126 
   7127   if (confidence < 0) {
   7128     /* we did not hit confidence, but were we asked to look for it? */
   7129     if (iteration_max > 1) {
   7130       display_confidence();
   7131     }
   7132   }
   7133 
   7134   if (local_cpu_usage || remote_cpu_usage) {
   7135     local_cpu_method = format_cpu_method(cpu_method);
   7136     remote_cpu_method = format_cpu_method(udp_rr_result->cpu_method);
   7137 
   7138     switch (verbosity) {
   7139     case 0:
   7140       if (local_cpu_usage) {
   7141 	fprintf(where,
   7142 		cpu_fmt_0,
   7143 		local_service_demand,
   7144 		local_cpu_method);
   7145       }
   7146       else {
   7147 	fprintf(where,
   7148 		cpu_fmt_0,
   7149 		remote_service_demand,
   7150 		remote_cpu_method);
   7151       }
   7152       break;
   7153     case 1:
   7154     case 2:
   7155       if (print_headers) {
   7156 	fprintf(where,
   7157 		cpu_title,
   7158 		local_cpu_method,
   7159 		remote_cpu_method);
   7160       }
   7161 
   7162       fprintf(where,
   7163 	      cpu_fmt_1_line_1,		/* the format string */
   7164 	      lss_size,		/* local sendbuf size */
   7165 	      lsr_size,
   7166 	      req_size,		/* how large were the requests */
   7167 	      rsp_size,		/* guess */
   7168 	      elapsed_time,		/* how long was the test */
   7169 	      nummessages/elapsed_time,
   7170 	      local_cpu_utilization,	/* local cpu */
   7171 	      remote_cpu_utilization,	/* remote cpu */
   7172 	      local_service_demand,	/* local service demand */
   7173 	      remote_service_demand);	/* remote service demand */
   7174       fprintf(where,
   7175 	      cpu_fmt_1_line_2,
   7176 	      rss_size,
   7177 	      rsr_size);
   7178       break;
   7179     }
   7180   }
   7181   else {
   7182     /* The tester did not wish to measure service demand. */
   7183     switch (verbosity) {
   7184     case 0:
   7185       fprintf(where,
   7186 	      tput_fmt_0,
   7187 	      nummessages/elapsed_time);
   7188       break;
   7189     case 1:
   7190     case 2:
   7191       if (print_headers) {
   7192 	fprintf(where,tput_title,format_units());
   7193       }
   7194 
   7195       fprintf(where,
   7196 	      tput_fmt_1_line_1,	/* the format string */
   7197 	      lss_size,
   7198 	      lsr_size,
   7199 	      req_size,		/* how large were the requests */
   7200 	      rsp_size,		/* how large were the responses */
   7201 	      elapsed_time, 		/* how long did it take */
   7202 	      nummessages/elapsed_time);
   7203       fprintf(where,
   7204 	      tput_fmt_1_line_2,
   7205 	      rss_size, 		/* remote recvbuf size */
   7206 	      rsr_size);
   7207 
   7208       break;
   7209     }
   7210   }
   7211   fflush(where);
   7212 
   7213   /* it would be a good thing to include information about some of the */
   7214   /* other parameters that may have been set for this test, but at the */
   7215   /* moment, I do not wish to figure-out all the  formatting, so I will */
   7216   /* just put this comment here to help remind me that it is something */
   7217   /* that should be done at a later time. */
   7218 
   7219   /* how to handle the verbose information in the presence of */
   7220   /* confidence intervals is yet to be determined... raj 11/94 */
   7221 
   7222   if (verbosity > 1) {
   7223     /* The user wanted to know it all, so we will give it to him. */
   7224     /* This information will include as much as we can find about */
   7225     /* UDP statistics, the alignments of the sends and receives */
   7226     /* and all that sort of rot... */
   7227 
   7228 #ifdef WANT_HISTOGRAM
   7229     fprintf(where,"\nHistogram of request/reponse times.\n");
   7230     fflush(where);
   7231     HIST_report(time_hist);
   7232 #endif /* WANT_HISTOGRAM */
   7233   }
   7234 }
   7235 
   7236  /* this routine implements the receive side (netserver) of a UDP_RR */
   7238  /* test. */
   7239 void
   7240 recv_udp_rr()
   7241 {
   7242 
   7243   struct ring_elt *recv_ring;
   7244   struct ring_elt *send_ring;
   7245 
   7246   struct addrinfo *local_res;
   7247   char local_name[BUFSIZ];
   7248   char port_buffer[PORTBUFSIZE];
   7249 
   7250   struct sockaddr_storage        myaddr_in;
   7251   struct sockaddr_storage    peeraddr;
   7252   SOCKET	s_data;
   7253   netperf_socklen_t 	addrlen;
   7254   int	trans_received;
   7255   int	trans_remaining;
   7256   int   request_bytes_recvd;
   7257   int   response_bytes_sent;
   7258   float	elapsed_time;
   7259 
   7260   struct	udp_rr_request_struct	*udp_rr_request;
   7261   struct	udp_rr_response_struct	*udp_rr_response;
   7262   struct	udp_rr_results_struct	*udp_rr_results;
   7263 
   7264   udp_rr_request  =
   7265     (struct udp_rr_request_struct *)netperf_request.content.test_specific_data;
   7266   udp_rr_response =
   7267     (struct udp_rr_response_struct *)netperf_response.content.test_specific_data;
   7268   udp_rr_results  =
   7269     (struct udp_rr_results_struct *)netperf_response.content.test_specific_data;
   7270 
   7271   if (debug) {
   7272     fprintf(where,"netserver: recv_udp_rr: entered...\n");
   7273     fflush(where);
   7274   }
   7275 
   7276   /* We want to set-up the listen socket with all the desired */
   7277   /* parameters and then let the initiator know that all is ready. If */
   7278   /* socket size defaults are to be used, then the initiator will have */
   7279   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   7280   /* send-back what they are. If that information cannot be determined, */
   7281   /* then we send-back -1's for the sizes. If things go wrong for any */
   7282   /* reason, we will drop back ten yards and punt. */
   7283 
   7284   /* If anything goes wrong, we want the remote to know about it. It */
   7285   /* would be best if the error that the remote reports to the user is */
   7286   /* the actual error we encountered, rather than some bogus unexpected */
   7287   /* response type message. */
   7288 
   7289   if (debug) {
   7290     fprintf(where,"recv_udp_rr: setting the response type...\n");
   7291     fflush(where);
   7292   }
   7293 
   7294   netperf_response.content.response_type = UDP_RR_RESPONSE;
   7295 
   7296   if (debug) {
   7297     fprintf(where,"recv_udp_rr: the response type is set...\n");
   7298     fflush(where);
   7299   }
   7300 
   7301   /* We now alter the message_ptr variables to be at the desired */
   7302   /* alignments with the desired offsets. */
   7303 
   7304   if (debug) {
   7305     fprintf(where,"recv_udp_rr: requested recv alignment of %d offset %d\n",
   7306 	    udp_rr_request->recv_alignment,
   7307 	    udp_rr_request->recv_offset);
   7308     fprintf(where,"recv_udp_rr: requested send alignment of %d offset %d\n",
   7309 	    udp_rr_request->send_alignment,
   7310 	    udp_rr_request->send_offset);
   7311     fflush(where);
   7312   }
   7313 
   7314   if (send_width == 0) send_width = 1;
   7315   if (recv_width == 0) recv_width = 1;
   7316 
   7317   recv_ring = allocate_buffer_ring(recv_width,
   7318 				   udp_rr_request->request_size,
   7319 				   udp_rr_request->recv_alignment,
   7320 				   udp_rr_request->recv_offset);
   7321 
   7322   send_ring = allocate_buffer_ring(send_width,
   7323 				   udp_rr_request->response_size,
   7324 				   udp_rr_request->send_alignment,
   7325 				   udp_rr_request->send_offset);
   7326 
   7327   if (debug) {
   7328     fprintf(where,"recv_udp_rr: receive alignment and offset set...\n");
   7329     fflush(where);
   7330   }
   7331 
   7332   /* Grab a socket to listen on, and then listen on it. */
   7333 
   7334   if (debug) {
   7335     fprintf(where,"recv_udp_rr: grabbing a socket...\n");
   7336     fflush(where);
   7337   }
   7338 
   7339 
   7340   /* create_data_socket expects to find some things in the global */
   7341   /* variables, so set the globals based on the values in the request. */
   7342   /* once the socket has been created, we will set the response values */
   7343   /* based on the updated value of those globals. raj 7/94 */
   7344   lss_size_req = udp_rr_request->send_buf_size;
   7345   lsr_size_req = udp_rr_request->recv_buf_size;
   7346   loc_rcvavoid = udp_rr_request->so_rcvavoid;
   7347   loc_sndavoid = udp_rr_request->so_sndavoid;
   7348 
   7349   set_hostname_and_port(local_name,
   7350 			port_buffer,
   7351 			nf_to_af(udp_rr_request->ipfamily),
   7352 			udp_rr_request->port);
   7353 
   7354   local_res = complete_addrinfo(local_name,
   7355 				local_name,
   7356 				port_buffer,
   7357 				nf_to_af(udp_rr_request->ipfamily),
   7358 				SOCK_DGRAM,
   7359 				IPPROTO_UDP,
   7360 				0);
   7361 
   7362   s_data = create_data_socket(local_res);
   7363 
   7364   if (s_data == INVALID_SOCKET) {
   7365     netperf_response.content.serv_errno = errno;
   7366     send_response();
   7367 
   7368     exit(1);
   7369   }
   7370 
   7371   /* now get the port number assigned by the system  */
   7372   addrlen = sizeof(myaddr_in);
   7373   if (getsockname(s_data,
   7374 		  (struct sockaddr *)&myaddr_in,
   7375 		  &addrlen) == SOCKET_ERROR){
   7376     netperf_response.content.serv_errno = errno;
   7377     close(s_data);
   7378     send_response();
   7379 
   7380     exit(1);
   7381   }
   7382 
   7383   /* Now myaddr_in contains the port and the internet address this is */
   7384   /* returned to the sender also implicitly telling the sender that the */
   7385   /* socket buffer sizing has been done. */
   7386 
   7387   udp_rr_response->data_port_number =
   7388     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
   7389   netperf_response.content.serv_errno   = 0;
   7390 
   7391   if (debug) {
   7392     fprintf(where,
   7393 	    "recv port number %d\n",
   7394 	    ((struct sockaddr_in *)&myaddr_in)->sin_port);
   7395     fflush(where);
   7396   }
   7397 
   7398   /* But wait, there's more. If the initiator wanted cpu measurements, */
   7399   /* then we must call the calibrate routine, which will return the max */
   7400   /* rate back to the initiator. If the CPU was not to be measured, or */
   7401   /* something went wrong with the calibration, we will return a 0.0 to */
   7402   /* the initiator. */
   7403 
   7404   udp_rr_response->cpu_rate    = (float)0.0; 	/* assume no cpu */
   7405   udp_rr_response->measure_cpu = 0;
   7406   if (udp_rr_request->measure_cpu) {
   7407     udp_rr_response->measure_cpu = 1;
   7408     udp_rr_response->cpu_rate = calibrate_local_cpu(udp_rr_request->cpu_rate);
   7409   }
   7410 
   7411   /* before we send the response back to the initiator, pull some of */
   7412   /* the socket parms from the globals */
   7413   udp_rr_response->send_buf_size = lss_size;
   7414   udp_rr_response->recv_buf_size = lsr_size;
   7415   udp_rr_response->so_rcvavoid   = loc_rcvavoid;
   7416   udp_rr_response->so_sndavoid   = loc_sndavoid;
   7417 
   7418   send_response();
   7419 
   7420 
   7421   /* Now it's time to start receiving data on the connection. We will */
   7422   /* first grab the apropriate counters and then start grabbing. */
   7423 
   7424   cpu_start(udp_rr_request->measure_cpu);
   7425 
   7426 #ifdef WIN32
   7427   /* this is used so the timer thread can close the socket out from */
   7428   /* under us, which to date is the easiest/cleanest/least */
   7429   /* Windows-specific way I can find to force the winsock calls to */
   7430   /* return WSAEINTR with the test is over. anything that will run on */
   7431   /* 95 and NT and is closer to what netperf expects from Unix signals */
   7432   /* and such would be appreciated raj 1/96 */
   7433   win_kludge_socket = s_data;
   7434 #endif /* WIN32 */
   7435 
   7436   if (udp_rr_request->test_length > 0) {
   7437     times_up = 0;
   7438     trans_remaining = 0;
   7439     start_timer(udp_rr_request->test_length + PAD_TIME);
   7440   }
   7441   else {
   7442     times_up = 1;
   7443     trans_remaining = udp_rr_request->test_length * -1;
   7444   }
   7445 
   7446   addrlen = sizeof(peeraddr);
   7447   bzero((char *)&peeraddr, addrlen);
   7448 
   7449   trans_received = 0;
   7450 
   7451   while ((!times_up) || (trans_remaining > 0)) {
   7452 
   7453     /* receive the request from the other side */
   7454     if ((request_bytes_recvd = recvfrom(s_data,
   7455 		 recv_ring->buffer_ptr,
   7456 		 udp_rr_request->request_size,
   7457 		 0,
   7458 		 (struct sockaddr *)&peeraddr,
   7459 		 &addrlen)) != udp_rr_request->request_size) {
   7460 	  if ( SOCKET_EINTR(request_bytes_recvd) )
   7461 	  {
   7462 	    /* we must have hit the end of test time. */
   7463 	    break;
   7464       }
   7465       netperf_response.content.serv_errno = errno;
   7466       send_response();
   7467       exit(1);
   7468     }
   7469     recv_ring = recv_ring->next;
   7470 
   7471     /* Now, send the response to the remote */
   7472     if ((response_bytes_sent = sendto(s_data,
   7473 				      send_ring->buffer_ptr,
   7474 				      udp_rr_request->response_size,
   7475 				      0,
   7476 				      (struct sockaddr *)&peeraddr,
   7477 				      addrlen)) !=
   7478 	udp_rr_request->response_size) {
   7479       if ( SOCKET_EINTR(response_bytes_sent) )
   7480 	  {
   7481 	    /* we have hit end of test time. */
   7482 	    break;
   7483       }
   7484       netperf_response.content.serv_errno = errno;
   7485       send_response();
   7486       exit(1);
   7487     }
   7488     send_ring = send_ring->next;
   7489 
   7490     trans_received++;
   7491     if (trans_remaining) {
   7492       trans_remaining--;
   7493     }
   7494 
   7495     if (debug) {
   7496       fprintf(where,
   7497 	      "recv_udp_rr: Transaction %d complete.\n",
   7498 	      trans_received);
   7499       fflush(where);
   7500     }
   7501 
   7502   }
   7503 
   7504 
   7505   /* The loop now exits due to timeout or transaction count being */
   7506   /* reached */
   7507 
   7508   cpu_stop(udp_rr_request->measure_cpu,&elapsed_time);
   7509 
   7510   if (times_up) {
   7511     /* we ended the test by time, which was at least 2 seconds */
   7512     /* longer than we wanted to run. so, we want to subtract */
   7513     /* PAD_TIME from the elapsed_time. */
   7514     elapsed_time -= PAD_TIME;
   7515   }
   7516   /* send the results to the sender			*/
   7517 
   7518   if (debug) {
   7519     fprintf(where,
   7520 	    "recv_udp_rr: got %d transactions\n",
   7521 	    trans_received);
   7522     fflush(where);
   7523   }
   7524 
   7525   udp_rr_results->bytes_received = (trans_received *
   7526 				    (udp_rr_request->request_size +
   7527 				     udp_rr_request->response_size));
   7528   udp_rr_results->trans_received = trans_received;
   7529   udp_rr_results->elapsed_time	 = elapsed_time;
   7530   udp_rr_results->cpu_method     = cpu_method;
   7531   udp_rr_results->num_cpus       = lib_num_loc_cpus;
   7532   if (udp_rr_request->measure_cpu) {
   7533     udp_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
   7534   }
   7535 
   7536   if (debug) {
   7537     fprintf(where,
   7538 	    "recv_udp_rr: test complete, sending results.\n");
   7539     fflush(where);
   7540   }
   7541 
   7542   send_response();
   7543 
   7544   /* we are done with the socket now */
   7545   close(s_data);
   7546 
   7547       }
   7548 
   7549 
   7550  /* this routine implements the receive (netserver) side of a TCP_RR */
   7552  /* test */
   7553 void
   7554 recv_tcp_rr()
   7555 {
   7556 
   7557   struct ring_elt *send_ring;
   7558   struct ring_elt *recv_ring;
   7559 
   7560   struct addrinfo *local_res;
   7561   char local_name[BUFSIZ];
   7562   char port_buffer[PORTBUFSIZE];
   7563 
   7564   struct	sockaddr_storage        myaddr_in,
   7565   peeraddr_in;
   7566   SOCKET	s_listen,s_data;
   7567   netperf_socklen_t 	addrlen;
   7568   char	*temp_message_ptr;
   7569   int	trans_received;
   7570   int	trans_remaining;
   7571   int	bytes_sent;
   7572   int	request_bytes_recvd;
   7573   int	request_bytes_remaining;
   7574   int	timed_out = 0;
   7575   int   sock_closed = 0;
   7576   float	elapsed_time;
   7577 
   7578   struct	tcp_rr_request_struct	*tcp_rr_request;
   7579   struct	tcp_rr_response_struct	*tcp_rr_response;
   7580   struct	tcp_rr_results_struct	*tcp_rr_results;
   7581 
   7582   tcp_rr_request =
   7583     (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data;
   7584   tcp_rr_response =
   7585     (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data;
   7586   tcp_rr_results =
   7587     (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data;
   7588 
   7589   if (debug) {
   7590     fprintf(where,"netserver: recv_tcp_rr: entered...\n");
   7591     fflush(where);
   7592   }
   7593 
   7594   /* We want to set-up the listen socket with all the desired */
   7595   /* parameters and then let the initiator know that all is ready. If */
   7596   /* socket size defaults are to be used, then the initiator will have */
   7597   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   7598   /* send-back what they are. If that information cannot be determined, */
   7599   /* then we send-back -1's for the sizes. If things go wrong for any */
   7600   /* reason, we will drop back ten yards and punt. */
   7601 
   7602   /* If anything goes wrong, we want the remote to know about it. It */
   7603   /* would be best if the error that the remote reports to the user is */
   7604   /* the actual error we encountered, rather than some bogus unexpected */
   7605   /* response type message. */
   7606 
   7607   if (debug) {
   7608     fprintf(where,"recv_tcp_rr: setting the response type...\n");
   7609     fflush(where);
   7610   }
   7611 
   7612   netperf_response.content.response_type = TCP_RR_RESPONSE;
   7613 
   7614   if (debug) {
   7615     fprintf(where,"recv_tcp_rr: the response type is set...\n");
   7616     fflush(where);
   7617   }
   7618 
   7619   /* allocate the recv and send rings with the requested alignments */
   7620   /* and offsets. raj 7/94 */
   7621   if (debug) {
   7622     fprintf(where,"recv_tcp_rr: requested recv alignment of %d offset %d\n",
   7623 	    tcp_rr_request->recv_alignment,
   7624 	    tcp_rr_request->recv_offset);
   7625     fprintf(where,"recv_tcp_rr: requested send alignment of %d offset %d\n",
   7626 	    tcp_rr_request->send_alignment,
   7627 	    tcp_rr_request->send_offset);
   7628     fflush(where);
   7629   }
   7630 
   7631   /* at some point, these need to come to us from the remote system */
   7632   if (send_width == 0) send_width = 1;
   7633   if (recv_width == 0) recv_width = 1;
   7634 
   7635   send_ring = allocate_buffer_ring(send_width,
   7636 				   tcp_rr_request->response_size,
   7637 				   tcp_rr_request->send_alignment,
   7638 				   tcp_rr_request->send_offset);
   7639 
   7640   recv_ring = allocate_buffer_ring(recv_width,
   7641 				   tcp_rr_request->request_size,
   7642 				   tcp_rr_request->recv_alignment,
   7643 				   tcp_rr_request->recv_offset);
   7644 
   7645 
   7646   /* Grab a socket to listen on, and then listen on it. */
   7647 
   7648   if (debug) {
   7649     fprintf(where,"recv_tcp_rr: grabbing a socket...\n");
   7650     fflush(where);
   7651   }
   7652 
   7653   /* create_data_socket expects to find some things in the global */
   7654   /* variables, so set the globals based on the values in the request. */
   7655   /* once the socket has been created, we will set the response values */
   7656   /* based on the updated value of those globals. raj 7/94 */
   7657   lss_size_req = tcp_rr_request->send_buf_size;
   7658   lsr_size_req = tcp_rr_request->recv_buf_size;
   7659   loc_nodelay = tcp_rr_request->no_delay;
   7660   loc_rcvavoid = tcp_rr_request->so_rcvavoid;
   7661   loc_sndavoid = tcp_rr_request->so_sndavoid;
   7662 
   7663   set_hostname_and_port(local_name,
   7664 			port_buffer,
   7665 			nf_to_af(tcp_rr_request->ipfamily),
   7666 			tcp_rr_request->port);
   7667 
   7668   local_res = complete_addrinfo(local_name,
   7669 				local_name,
   7670 				port_buffer,
   7671 				nf_to_af(tcp_rr_request->ipfamily),
   7672 				SOCK_STREAM,
   7673 				IPPROTO_TCP,
   7674 				0);
   7675 
   7676   s_listen = create_data_socket(local_res);
   7677 
   7678   if (s_listen == INVALID_SOCKET) {
   7679     netperf_response.content.serv_errno = errno;
   7680     send_response();
   7681 
   7682     exit(1);
   7683   }
   7684 
   7685 
   7686 #ifdef WIN32
   7687   /* The test timer can fire during operations on the listening socket,
   7688      so to make the start_timer below work we have to move
   7689      it to close s_listen while we are blocked on accept. */
   7690   win_kludge_socket2 = s_listen;
   7691 #endif
   7692 
   7693 
   7694   /* Now, let's set-up the socket to listen for connections */
   7695   if (listen(s_listen, 5) == SOCKET_ERROR) {
   7696     netperf_response.content.serv_errno = errno;
   7697     close(s_listen);
   7698     send_response();
   7699 
   7700     exit(1);
   7701   }
   7702 
   7703 
   7704   /* now get the port number assigned by the system  */
   7705   addrlen = sizeof(myaddr_in);
   7706   if (getsockname(s_listen,
   7707 		  (struct sockaddr *)&myaddr_in,
   7708 		  &addrlen) == SOCKET_ERROR) {
   7709     netperf_response.content.serv_errno = errno;
   7710     close(s_listen);
   7711     send_response();
   7712 
   7713     exit(1);
   7714   }
   7715 
   7716   /* Now myaddr_in contains the port and the internet address this is */
   7717   /* returned to the sender also implicitly telling the sender that the */
   7718   /* socket buffer sizing has been done. */
   7719 
   7720   tcp_rr_response->data_port_number =
   7721     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
   7722   netperf_response.content.serv_errno   = 0;
   7723 
   7724   /* But wait, there's more. If the initiator wanted cpu measurements, */
   7725   /* then we must call the calibrate routine, which will return the max */
   7726   /* rate back to the initiator. If the CPU was not to be measured, or */
   7727   /* something went wrong with the calibration, we will return a 0.0 to */
   7728   /* the initiator. */
   7729 
   7730   tcp_rr_response->cpu_rate = (float)0.0; 	/* assume no cpu */
   7731   tcp_rr_response->measure_cpu = 0;
   7732 
   7733   if (tcp_rr_request->measure_cpu) {
   7734     tcp_rr_response->measure_cpu = 1;
   7735     tcp_rr_response->cpu_rate = calibrate_local_cpu(tcp_rr_request->cpu_rate);
   7736   }
   7737 
   7738 
   7739   /* before we send the response back to the initiator, pull some of */
   7740   /* the socket parms from the globals */
   7741   tcp_rr_response->send_buf_size = lss_size;
   7742   tcp_rr_response->recv_buf_size = lsr_size;
   7743   tcp_rr_response->no_delay = loc_nodelay;
   7744   tcp_rr_response->so_rcvavoid = loc_rcvavoid;
   7745   tcp_rr_response->so_sndavoid = loc_sndavoid;
   7746   tcp_rr_response->test_length = tcp_rr_request->test_length;
   7747   send_response();
   7748 
   7749   addrlen = sizeof(peeraddr_in);
   7750 
   7751   if ((s_data = accept(s_listen,
   7752 		       (struct sockaddr *)&peeraddr_in,
   7753 		       &addrlen)) == INVALID_SOCKET) {
   7754     /* Let's just punt. The remote will be given some information */
   7755     close(s_listen);
   7756 
   7757     exit(1);
   7758   }
   7759 
   7760 #ifdef KLUDGE_SOCKET_OPTIONS
   7761   /* this is for those systems which *INCORRECTLY* fail to pass */
   7762   /* attributes across an accept() call. Including this goes against */
   7763   /* my better judgement :( raj 11/95 */
   7764 
   7765   kludge_socket_options(s_data);
   7766 
   7767 #endif /* KLUDGE_SOCKET_OPTIONS */
   7768 
   7769 #ifdef WIN32
   7770   /* this is used so the timer thread can close the socket out from */
   7771   /* under us, which to date is the easiest/cleanest/least */
   7772   /* Windows-specific way I can find to force the winsock calls to */
   7773   /* return WSAEINTR with the test is over. anything that will run on */
   7774   /* 95 and NT and is closer to what netperf expects from Unix signals */
   7775   /* and such would be appreciated raj 1/96 */
   7776   win_kludge_socket = s_data;
   7777 #endif /* WIN32 */
   7778 
   7779   if (debug) {
   7780     fprintf(where,"recv_tcp_rr: accept completes on the data connection.\n");
   7781     fflush(where);
   7782   }
   7783 
   7784   /* Now it's time to start receiving data on the connection. We will */
   7785   /* first grab the apropriate counters and then start grabbing. */
   7786 
   7787   cpu_start(tcp_rr_request->measure_cpu);
   7788 
   7789   /* The loop will exit when we hit the end of the test time, or when */
   7790   /* we have exchanged the requested number of transactions. */
   7791 
   7792   if (tcp_rr_request->test_length > 0) {
   7793     times_up = 0;
   7794     trans_remaining = 0;
   7795     start_timer(tcp_rr_request->test_length + PAD_TIME);
   7796   }
   7797   else {
   7798     times_up = 1;
   7799     trans_remaining = tcp_rr_request->test_length * -1;
   7800   }
   7801 
   7802   trans_received = 0;
   7803 
   7804   while ((!times_up) || (trans_remaining > 0)) {
   7805     temp_message_ptr = recv_ring->buffer_ptr;
   7806     request_bytes_remaining	= tcp_rr_request->request_size;
   7807     while(request_bytes_remaining > 0) {
   7808       if((request_bytes_recvd=recv(s_data,
   7809 				   temp_message_ptr,
   7810 				   request_bytes_remaining,
   7811 				   0)) == SOCKET_ERROR) {
   7812 	if (SOCKET_EINTR(request_bytes_recvd))
   7813 	{
   7814 	  timed_out = 1;
   7815 	  break;
   7816 	}
   7817 
   7818 	netperf_response.content.serv_errno = errno;
   7819 	send_response();
   7820 	exit(1);
   7821       }
   7822       else if( request_bytes_recvd == 0 ) {
   7823 	if (debug) {
   7824 	  fprintf(where,"zero is my hero\n");
   7825 	  fflush(where);
   7826 	}
   7827 	sock_closed = 1;
   7828 	break;
   7829       }
   7830       else {
   7831 	request_bytes_remaining -= request_bytes_recvd;
   7832 	temp_message_ptr  += request_bytes_recvd;
   7833       }
   7834     }
   7835 
   7836     recv_ring = recv_ring->next;
   7837 
   7838     if ((timed_out) || (sock_closed)) {
   7839       /* we hit the end of the test based on time - or the socket
   7840 	 closed on us along the way.  bail out of here now... */
   7841       if (debug) {
   7842 	fprintf(where,"yo5\n");
   7843 	fflush(where);
   7844       }
   7845       break;
   7846     }
   7847 
   7848     /* Now, send the response to the remote */
   7849     if((bytes_sent=send(s_data,
   7850 			send_ring->buffer_ptr,
   7851 			tcp_rr_request->response_size,
   7852 			0)) == SOCKET_ERROR) {
   7853       if (SOCKET_EINTR(bytes_sent)) {
   7854 	/* the test timer has popped */
   7855 	timed_out = 1;
   7856 	fprintf(where,"yo6\n");
   7857 	fflush(where);
   7858 	break;
   7859       }
   7860       netperf_response.content.serv_errno = 992;
   7861       send_response();
   7862       exit(1);
   7863     }
   7864 
   7865     send_ring = send_ring->next;
   7866 
   7867     trans_received++;
   7868     if (trans_remaining) {
   7869       trans_remaining--;
   7870     }
   7871   }
   7872 
   7873 
   7874   /* The loop now exits due to timeout or transaction count being */
   7875   /* reached */
   7876 
   7877   cpu_stop(tcp_rr_request->measure_cpu,&elapsed_time);
   7878 
   7879   stop_timer();
   7880 
   7881   if (timed_out) {
   7882     /* we ended the test by time, which was at least 2 seconds */
   7883     /* longer than we wanted to run. so, we want to subtract */
   7884     /* PAD_TIME from the elapsed_time. */
   7885     elapsed_time -= PAD_TIME;
   7886   }
   7887 
   7888   /* send the results to the sender			*/
   7889 
   7890   if (debug) {
   7891     fprintf(where,
   7892 	    "recv_tcp_rr: got %d transactions\n",
   7893 	    trans_received);
   7894     fflush(where);
   7895   }
   7896 
   7897   tcp_rr_results->bytes_received = (trans_received *
   7898 				    (tcp_rr_request->request_size +
   7899 				     tcp_rr_request->response_size));
   7900   tcp_rr_results->trans_received = trans_received;
   7901   tcp_rr_results->elapsed_time   = elapsed_time;
   7902   tcp_rr_results->cpu_method     = cpu_method;
   7903   tcp_rr_results->num_cpus       = lib_num_loc_cpus;
   7904   if (tcp_rr_request->measure_cpu) {
   7905     tcp_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
   7906   }
   7907 
   7908   if (debug) {
   7909     fprintf(where,
   7910 	    "recv_tcp_rr: test complete, sending results.\n");
   7911     fflush(where);
   7912   }
   7913 
   7914   /* we are now done with the sockets */
   7915   close(s_data);
   7916   close(s_listen);
   7917 
   7918   send_response();
   7919 
   7920 }
   7921 
   7922 
   7923 void
   7925 loc_cpu_rate()
   7926 {
   7927 #if defined(USE_LOOPER)
   7928   float dummy;
   7929 #endif
   7930 
   7931   /* a rather simple little test - it merely calibrates the local cpu */
   7932   /* and prints the results. There are no headers to allow someone to */
   7933   /* find a rate and use it in other tests automagically by setting a */
   7934   /* variable equal to the output of this test. We ignore any rates */
   7935   /* that may have been specified. In fact, we ignore all of the */
   7936   /* command line args! */
   7937 
   7938   fprintf(where,
   7939 	  "%g",
   7940 	  calibrate_local_cpu(0.0));
   7941 
   7942   if (verbosity > 1)
   7943     fprintf(where,
   7944 	    "\nThere %s %d local %s\n",
   7945 	    (lib_num_loc_cpus > 1) ? "are" : "is",
   7946 	    lib_num_loc_cpus,
   7947 	    (lib_num_loc_cpus > 1) ? "cpus" : "cpu");
   7948 
   7949   /* we need the cpu_start, cpu_stop in the looper case to kill the */
   7950   /* child proceses raj 4/95 */
   7951 
   7952 #ifdef USE_LOOPER
   7953   cpu_start(1);
   7954   cpu_stop(1,&dummy);
   7955 #endif /* USE_LOOPER */
   7956 
   7957 }
   7958 
   7959 void
   7960 rem_cpu_rate()
   7961 {
   7962   /* this test is much like the local variant, except that it works for */
   7963   /* the remote system, so in this case, we do pay attention to the */
   7964   /* value of the '-H' command line argument. */
   7965 
   7966   fprintf(where,
   7967 	  "%g",
   7968 	  calibrate_remote_cpu());
   7969 
   7970   if (verbosity > 1)
   7971     fprintf(where,
   7972 	    "\nThere %s %d remote %s\n",
   7973 	    (lib_num_rem_cpus > 1) ? "are" : "is",
   7974 	    lib_num_rem_cpus,
   7975 	    (lib_num_rem_cpus > 1) ? "cpus" : "cpu");
   7976 
   7977 }
   7978 
   7979 
   7981  /* this test is intended to test the performance of establishing a
   7982     connection, exchanging a request/response pair, and repeating. it
   7983     is expected that this would be a good starting-point for
   7984     comparision of T/TCP with classic TCP for transactional workloads.
   7985     it will also look (can look) much like the communication pattern
   7986     of http for www access. */
   7987 
   7988 void
   7989 send_tcp_conn_rr(char remote_host[])
   7990 {
   7991 
   7992   char *tput_title = "\
   7993 Local /Remote\n\
   7994 Socket Size   Request  Resp.   Elapsed  Trans.\n\
   7995 Send   Recv   Size     Size    Time     Rate         \n\
   7996 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
   7997 
   7998   char *tput_fmt_0 =
   7999     "%7.2f\n";
   8000 
   8001   char *tput_fmt_1_line_1 = "\
   8002 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
   8003   char *tput_fmt_1_line_2 = "\
   8004 %-6d %-6d\n";
   8005 
   8006   char *cpu_title = "\
   8007 Local /Remote\n\
   8008 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
   8009 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
   8010 bytes  bytes  bytes   bytes  secs.   per sec  %%      %%      us/Tr   us/Tr\n\n";
   8011 
   8012   char *cpu_fmt_0 =
   8013     "%6.3f\n";
   8014 
   8015   char *cpu_fmt_1_line_1 = "\
   8016 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f\n";
   8017 
   8018   char *cpu_fmt_1_line_2 = "\
   8019 %-6d %-6d\n";
   8020 
   8021   char *ksink_fmt = "\n\
   8022 Alignment      Offset\n\
   8023 Local  Remote  Local  Remote\n\
   8024 Send   Recv    Send   Recv\n\
   8025 %5d  %5d   %5d  %5d\n";
   8026 
   8027 
   8028   int			timed_out = 0;
   8029   float			elapsed_time;
   8030 
   8031   int	len;
   8032   struct ring_elt *send_ring;
   8033   struct ring_elt *recv_ring;
   8034   char	*temp_message_ptr;
   8035   int	nummessages;
   8036   SOCKET	send_socket;
   8037   int	trans_remaining;
   8038   double	bytes_xferd;
   8039   int	rsp_bytes_left;
   8040   int	rsp_bytes_recvd;
   8041 
   8042   float	local_cpu_utilization;
   8043   float	local_service_demand;
   8044   float	remote_cpu_utilization;
   8045   float	remote_service_demand;
   8046   double	thruput;
   8047 
   8048   struct addrinfo *local_res;
   8049   struct addrinfo *remote_res;
   8050 
   8051   int                           myport;
   8052   int                           ret;
   8053 
   8054   struct	tcp_conn_rr_request_struct	*tcp_conn_rr_request;
   8055   struct	tcp_conn_rr_response_struct	*tcp_conn_rr_response;
   8056   struct	tcp_conn_rr_results_struct	*tcp_conn_rr_result;
   8057 
   8058   tcp_conn_rr_request =
   8059     (struct tcp_conn_rr_request_struct *)netperf_request.content.test_specific_data;
   8060   tcp_conn_rr_response =
   8061     (struct tcp_conn_rr_response_struct *)netperf_response.content.test_specific_data;
   8062   tcp_conn_rr_result =
   8063     (struct tcp_conn_rr_results_struct *)netperf_response.content.test_specific_data;
   8064 
   8065 
   8066 #ifdef WANT_HISTOGRAM
   8067   if (verbosity > 1) {
   8068     time_hist = HIST_new();
   8069   }
   8070 #endif /* WANT_HISTOGRAM */
   8071 
   8072   /* since we are now disconnected from the code that established the */
   8073   /* control socket, and since we want to be able to use different */
   8074   /* protocols and such, we are passed the name of the remote host and */
   8075   /* must turn that into the test specific addressing information. */
   8076 
   8077   complete_addrinfos(&remote_res,
   8078 		     &local_res,
   8079 		     remote_host,
   8080 		     SOCK_STREAM,
   8081 		     IPPROTO_TCP,
   8082 		     0);
   8083 
   8084   if ( print_headers ) {
   8085     print_top_test_header("TCP Connect/Request/Response TEST",local_res,remote_res);
   8086   }
   8087 
   8088   /* initialize a few counters */
   8089 
   8090   nummessages	=	0;
   8091   bytes_xferd	=	0.0;
   8092   times_up 	= 	0;
   8093 
   8094   /* set-up the data buffers with the requested alignment and offset */
   8095   if (send_width == 0) send_width = 1;
   8096   if (recv_width == 0) recv_width = 1;
   8097 
   8098   send_ring = allocate_buffer_ring(send_width,
   8099 				   req_size,
   8100 				   local_send_align,
   8101 				   local_send_offset);
   8102 
   8103   recv_ring = allocate_buffer_ring(recv_width,
   8104 				   rsp_size,
   8105 				   local_recv_align,
   8106 				   local_recv_offset);
   8107 
   8108 
   8109   if (debug) {
   8110     fprintf(where,"send_tcp_conn_rr: send_socket obtained...\n");
   8111   }
   8112 
   8113   /* If the user has requested cpu utilization measurements, we must */
   8114   /* calibrate the cpu(s). We will perform this task within the tests */
   8115   /* themselves. If the user has specified the cpu rate, then */
   8116   /* calibrate_local_cpu will return rather quickly as it will have */
   8117   /* nothing to do. If local_cpu_rate is zero, then we will go through */
   8118   /* all the "normal" calibration stuff and return the rate back.*/
   8119 
   8120   if (local_cpu_usage) {
   8121     local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   8122   }
   8123 
   8124   if (!no_control) {
   8125 
   8126     /* Tell the remote end to do a listen. The server alters the
   8127        socket paramters on the other side at this point, hence the
   8128        reason for all the values being passed in the setup message. If
   8129        the user did not specify any of the parameters, they will be
   8130        passed as 0, which will indicate to the remote that no changes
   8131        beyond the system's default should be used. Alignment is the
   8132        exception, it will default to 8, which will be no alignment
   8133        alterations. */
   8134 
   8135     netperf_request.content.request_type =	DO_TCP_CRR;
   8136     tcp_conn_rr_request->recv_buf_size	=	rsr_size_req;
   8137     tcp_conn_rr_request->send_buf_size	=	rss_size_req;
   8138     tcp_conn_rr_request->recv_alignment	=	remote_recv_align;
   8139     tcp_conn_rr_request->recv_offset	=	remote_recv_offset;
   8140     tcp_conn_rr_request->send_alignment	=	remote_send_align;
   8141     tcp_conn_rr_request->send_offset	=	remote_send_offset;
   8142     tcp_conn_rr_request->request_size	=	req_size;
   8143     tcp_conn_rr_request->response_size	=	rsp_size;
   8144     tcp_conn_rr_request->no_delay	=	rem_nodelay;
   8145     tcp_conn_rr_request->measure_cpu	=	remote_cpu_usage;
   8146     tcp_conn_rr_request->cpu_rate	=	remote_cpu_rate;
   8147     tcp_conn_rr_request->so_rcvavoid	=	rem_rcvavoid;
   8148     tcp_conn_rr_request->so_sndavoid	=	rem_sndavoid;
   8149     if (test_time) {
   8150       tcp_conn_rr_request->test_length	=	test_time;
   8151     }
   8152     else {
   8153       tcp_conn_rr_request->test_length	=	test_trans * -1;
   8154     }
   8155     tcp_conn_rr_request->port           = atoi(remote_data_port);
   8156     tcp_conn_rr_request->ipfamily       = af_to_nf(remote_res->ai_family);
   8157 
   8158     if (debug > 1) {
   8159       fprintf(where,"netperf: send_tcp_conn_rr: requesting TCP crr test\n");
   8160     }
   8161 
   8162     send_request();
   8163 
   8164     /* The response from the remote will contain all of the relevant
   8165        socket parameters for this test type. We will put them back
   8166        into the variables here so they can be displayed if desired.
   8167        The remote will have calibrated CPU if necessary, and will have
   8168        done all the needed set-up we will have calibrated the cpu
   8169        locally before sending the request, and will grab the counter
   8170        value right after the connect returns. The remote will grab the
   8171        counter right after the accept call. This saves the hassle of
   8172        extra messages being sent for the TCP tests.  */
   8173 
   8174     recv_response();
   8175 
   8176     if (!netperf_response.content.serv_errno) {
   8177       rsr_size	       =	tcp_conn_rr_response->recv_buf_size;
   8178       rss_size	       =	tcp_conn_rr_response->send_buf_size;
   8179       rem_nodelay      =	tcp_conn_rr_response->no_delay;
   8180       remote_cpu_usage =	tcp_conn_rr_response->measure_cpu;
   8181       remote_cpu_rate  = 	tcp_conn_rr_response->cpu_rate;
   8182       /* make sure that port numbers are in network order */
   8183       set_port_number(remote_res,
   8184 		      (unsigned short)tcp_conn_rr_response->data_port_number);
   8185 
   8186       if (debug) {
   8187 	fprintf(where,"remote listen done.\n");
   8188 	fprintf(where,"remote port is %u\n",get_port_number(remote_res));
   8189 	fflush(where);
   8190       }
   8191     }
   8192     else {
   8193       Set_errno(netperf_response.content.serv_errno);
   8194       fprintf(where,
   8195 	      "netperf: remote error %d",
   8196 	      netperf_response.content.serv_errno);
   8197       perror("");
   8198       fflush(where);
   8199       exit(1);
   8200     }
   8201   }
   8202 #ifdef WANT_DEMO
   8203   DEMO_RR_SETUP(100)
   8204 #endif
   8205 
   8206   /* pick a nice random spot between client_port_min and */
   8207   /* client_port_max for our initial port number */
   8208   srand(getpid());
   8209   if (client_port_max - client_port_min) {
   8210     myport = client_port_min +
   8211       (rand() % (client_port_max - client_port_min));
   8212   }
   8213   else {
   8214     myport = client_port_min;
   8215   }
   8216   /* there will be a ++ before the first call to bind, so subtract one */
   8217   myport--;
   8218   /* Set-up the test end conditions. For a request/response test, they */
   8219   /* can be either time or transaction based. */
   8220 
   8221   if (test_time) {
   8222     /* The user wanted to end the test after a period of time. */
   8223     times_up = 0;
   8224     trans_remaining = 0;
   8225     start_timer(test_time);
   8226   }
   8227   else {
   8228     /* The tester wanted to send a number of bytes. */
   8229     trans_remaining = test_bytes;
   8230     times_up = 1;
   8231   }
   8232 
   8233   /* The cpu_start routine will grab the current time and possibly */
   8234   /* value of the idle counter for later use in measuring cpu */
   8235   /* utilization and/or service demand and thruput. */
   8236 
   8237 
   8238   cpu_start(local_cpu_usage);
   8239 
   8240 #ifdef WANT_DEMO
   8241       if (demo_mode) {
   8242 	HIST_timestamp(demo_one_ptr);
   8243       }
   8244 #endif
   8245 
   8246   /* We use an "OR" to control test execution. When the test is */
   8247   /* controlled by time, the byte count check will always return false. */
   8248   /* When the test is controlled by byte count, the time test will */
   8249   /* always return false. When the test is finished, the whole */
   8250   /* expression will go false and we will stop sending data. I think I */
   8251   /* just arbitrarily decrement trans_remaining for the timed test, but */
   8252   /* will not do that just yet... One other question is whether or not */
   8253   /* the send buffer and the receive buffer should be the same buffer. */
   8254 
   8255   while ((!times_up) || (trans_remaining > 0)) {
   8256 
   8257 #ifdef WANT_HISTOGRAM
   8258     if (verbosity > 1) {
   8259       /* timestamp just before our call to create the socket, and then */
   8260       /* again just after the receive raj 3/95 */
   8261       HIST_timestamp(&time_one);
   8262     }
   8263 #endif /* WANT_HISTOGRAM */
   8264 
   8265 newport:
   8266     /* pick a new port number */
   8267     myport++;
   8268 
   8269     /* wrap the port number when we get to client_port_max. NOTE, some */
   8270     /* broken TCP's might treat the port number as a signed 16 bit */
   8271     /* quantity.  we aren't interested in testing such broken */
   8272     /* implementations :) so we won't make sure that it is below 32767 */
   8273     /* raj 8/94  */
   8274     if (myport >= client_port_max) {
   8275       myport = client_port_min;
   8276     }
   8277 
   8278     /* we do not want to use the port number that the server is */
   8279     /* sitting at - this would cause us to fail in a loopback test. we */
   8280     /* could just rely on the failure of the bind to get us past this, */
   8281     /* but I'm guessing that in this one case at least, it is much */
   8282     /* faster, given that we *know* that port number is already in use */
   8283     /* (or rather would be in a loopback test) */
   8284 
   8285     if (myport == get_port_number(remote_res)) myport++;
   8286 
   8287     if (debug) {
   8288       if ((nummessages % 100) == 0) {
   8289 	printf("port %d\n",myport);
   8290       }
   8291     }
   8292 
   8293     /* set up the data socket */
   8294     set_port_number(local_res, (unsigned short)myport);
   8295     send_socket = create_data_socket(local_res);
   8296 
   8297     if (send_socket == INVALID_SOCKET) {
   8298       perror("netperf: send_tcp_conn_rr: tcp stream data socket");
   8299       exit(1);
   8300     }
   8301 
   8302 
   8303     /* we used to call bind here, but that is now taken-care-of by the
   8304        create_data_socket routine. */
   8305 
   8306     /* Connect up to the remote port on the data socket  */
   8307     if ((ret = connect(send_socket,
   8308 		       remote_res->ai_addr,
   8309 		       remote_res->ai_addrlen)) == INVALID_SOCKET){
   8310       if (SOCKET_EINTR(ret))
   8311 	  {
   8312 	    /* we hit the end of a */
   8313 	    /* timed test. */
   8314 	    timed_out = 1;
   8315 	    break;
   8316       }
   8317       if ((SOCKET_EADDRINUSE(ret)) || SOCKET_EADDRNOTAVAIL(ret)) {
   8318 	/* likely something our explicit bind() would have caught in
   8319            the past, so go get another port, via create_data_socket.
   8320            yes, this is a bit more overhead than before, but the
   8321            condition should be rather rare.  raj 2005-02-08 */
   8322 	close(send_socket);
   8323 	goto newport;
   8324       }
   8325       perror("netperf: data socket connect failed");
   8326       printf("\tattempted to connect on socket %d to port %d",
   8327 	     send_socket,
   8328 	     get_port_number(remote_res));
   8329       printf(" from port %d \n",get_port_number(local_res));
   8330       exit(1);
   8331     }
   8332 
   8333 
   8334     /* send the request */
   8335     if((len=send(send_socket,
   8336 		 send_ring->buffer_ptr,
   8337 		 req_size,
   8338 		 0)) != req_size) {
   8339       if (SOCKET_EINTR(len))
   8340 	  {
   8341 	    /* we hit the end of a */
   8342 	    /* timed test. */
   8343 	    timed_out = 1;
   8344 	    break;
   8345       }
   8346       perror("send_tcp_conn_rr: data send error");
   8347       exit(1);
   8348     }
   8349     send_ring = send_ring->next;
   8350 
   8351     /* receive the response */
   8352     rsp_bytes_left = rsp_size;
   8353     temp_message_ptr  = recv_ring->buffer_ptr;
   8354 
   8355 
   8356     do {
   8357       rsp_bytes_recvd = recv(send_socket,
   8358 			     temp_message_ptr,
   8359 			     rsp_bytes_left,
   8360 			     0);
   8361       if (rsp_bytes_recvd > 0) {
   8362 	rsp_bytes_left -= rsp_bytes_recvd;
   8363 	temp_message_ptr += rsp_bytes_recvd;
   8364       }
   8365       else {
   8366 	break;
   8367       }
   8368     } while (rsp_bytes_left);
   8369 
   8370 
   8371     /* OK, we are out of the loop - now what? */
   8372     if (rsp_bytes_recvd < 0) {
   8373       /* did the timer hit, or was there an error? */
   8374       if (SOCKET_EINTR(rsp_bytes_recvd))
   8375 	  {
   8376 	    /* We hit the end of a timed test. */
   8377 	    timed_out = 1;
   8378 	    break;
   8379 	  }
   8380 	  perror("send_tcp_conn_rr: data recv error");
   8381 	  exit(1);
   8382     }
   8383 
   8384     /* if this is a no_control test, we initiate connection close,
   8385        otherwise the remote netserver does it to remain just like
   8386        previous behaviour. raj 2007-27-08 */
   8387     if (!no_control) {
   8388       shutdown(send_socket,SHUT_WR);
   8389     }
   8390 
   8391     /* we are expecting to get either a return of zero indicating
   8392        connection close, or an error.  */
   8393     rsp_bytes_recvd = recv(send_socket,
   8394 			   temp_message_ptr,
   8395 			   1,
   8396 			   0);
   8397 
   8398     /* our exit from the while loop should generally be when */
   8399     /* tmp_bytes_recvd is equal to zero, which implies the connection */
   8400     /* has been closed by the server side. By waiting until we get the */
   8401     /* zero return we can avoid race conditions that stick us with the */
   8402     /* TIME_WAIT connection and not the server. raj 8/96 */
   8403 
   8404     if (rsp_bytes_recvd == 0) {
   8405       /* connection close, call close. we assume that the requisite */
   8406       /* number of bytes have been received */
   8407       recv_ring = recv_ring->next;
   8408 
   8409 #ifdef WANT_HISTOGRAM
   8410       if (verbosity > 1) {
   8411 	HIST_timestamp(&time_two);
   8412 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   8413       }
   8414 #endif /* WANT_HISTOGRAM */
   8415 
   8416 #ifdef WANT_DEMO
   8417       DEMO_RR_INTERVAL(1)
   8418 #endif
   8419 
   8420       nummessages++;
   8421       if (trans_remaining) {
   8422 	trans_remaining--;
   8423       }
   8424 
   8425       if (debug > 3) {
   8426 	fprintf(where,
   8427 		"Transaction %d completed on local port %d\n",
   8428 		nummessages,
   8429 		get_port_number(local_res));
   8430 	fflush(where);
   8431       }
   8432 
   8433       close(send_socket);
   8434 
   8435     }
   8436     else {
   8437       /* it was less than zero - an error occured */
   8438       if (SOCKET_EINTR(rsp_bytes_recvd))
   8439 	  {
   8440 	    /* We hit the end of a timed test. */
   8441 	    timed_out = 1;
   8442 	    break;
   8443 	  }
   8444 	  perror("send_tcp_conn_rr: data recv error");
   8445 	  exit(1);
   8446     }
   8447 
   8448   }
   8449 
   8450 
   8451   /* this call will always give us the elapsed time for the test, and */
   8452   /* will also store-away the necessaries for cpu utilization */
   8453 
   8454   cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being measured? */
   8455   /* how long did we really run? */
   8456 
   8457   if (!no_control) {
   8458     /* Get the statistics from the remote end. The remote will have
   8459        calculated service demand and all those interesting things. If
   8460        it wasn't supposed to care, it will return obvious values. */
   8461 
   8462     recv_response();
   8463     if (!netperf_response.content.serv_errno) {
   8464       if (debug)
   8465 	fprintf(where,"remote results obtained\n");
   8466     }
   8467     else {
   8468       Set_errno(netperf_response.content.serv_errno);
   8469       fprintf(where,
   8470 	      "netperf: remote error %d",
   8471 	      netperf_response.content.serv_errno);
   8472       perror("");
   8473       fflush(where);
   8474 
   8475       exit(1);
   8476     }
   8477   }
   8478 
   8479   /* We now calculate what our thruput was for the test. In the future, */
   8480   /* we may want to include a calculation of the thruput measured by */
   8481   /* the remote, but it should be the case that for a TCP stream test, */
   8482   /* that the two numbers should be *very* close... We calculate */
   8483   /* bytes_sent regardless of the way the test length was controlled. */
   8484   /* If it was time, we needed to, and if it was by bytes, the user may */
   8485   /* have specified a number of bytes that wasn't a multiple of the */
   8486   /* send_size, so we really didn't send what he asked for ;-) We use */
   8487   /* Kbytes/s as the units of thruput for a TCP stream test, where K = */
   8488   /* 1024. A future enhancement *might* be to choose from a couple of */
   8489   /* unit selections. */
   8490 
   8491   bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
   8492   thruput	= calc_thruput(bytes_xferd);
   8493 
   8494   if (local_cpu_usage || remote_cpu_usage) {
   8495     /* We must now do a little math for service demand and cpu */
   8496     /* utilization for the system(s) */
   8497     /* Of course, some of the information might be bogus because */
   8498     /* there was no idle counter in the kernel(s). We need to make */
   8499     /* a note of this for the user's benefit...*/
   8500     if (local_cpu_usage) {
   8501       if (local_cpu_rate == 0.0) {
   8502 	fprintf(where,
   8503 		"WARNING WARNING WARNING  WARNING WARNING WARNING  WARNING!\n");
   8504 	fprintf(where,
   8505 		"Local CPU usage numbers based on process information only!\n");
   8506 	fflush(where);
   8507       }
   8508       local_cpu_utilization = calc_cpu_util(0.0);
   8509       /* since calc_service demand is doing ms/Kunit we will */
   8510       /* multiply the number of transaction by 1024 to get */
   8511       /* "good" numbers */
   8512       local_service_demand  = calc_service_demand((double) nummessages*1024,
   8513 						  0.0,
   8514 						  0.0,
   8515 						  0);
   8516     }
   8517     else {
   8518       local_cpu_utilization	= (float) -1.0;
   8519       local_service_demand	= (float) -1.0;
   8520     }
   8521 
   8522     if (remote_cpu_usage) {
   8523       if (remote_cpu_rate == 0.0) {
   8524 	fprintf(where,
   8525 		"DANGER  DANGER  DANGER    DANGER  DANGER  DANGER    DANGER!\n");
   8526 	fprintf(where,
   8527 		"Remote CPU usage numbers based on process information only!\n");
   8528 	fflush(where);
   8529       }
   8530       remote_cpu_utilization = tcp_conn_rr_result->cpu_util;
   8531       /* since calc_service demand is doing ms/Kunit we will */
   8532       /* multiply the number of transaction by 1024 to get */
   8533       /* "good" numbers */
   8534       remote_service_demand = calc_service_demand((double) nummessages*1024,
   8535 						  0.0,
   8536 						  remote_cpu_utilization,
   8537 						  tcp_conn_rr_result->num_cpus);
   8538     }
   8539     else {
   8540       remote_cpu_utilization = (float) -1.0;
   8541       remote_service_demand  = (float) -1.0;
   8542     }
   8543 
   8544     /* We are now ready to print all the information. If the user */
   8545     /* has specified zero-level verbosity, we will just print the */
   8546     /* local service demand, or the remote service demand. If the */
   8547     /* user has requested verbosity level 1, he will get the basic */
   8548     /* "streamperf" numbers. If the user has specified a verbosity */
   8549     /* of greater than 1, we will display a veritable plethora of */
   8550     /* background information from outside of this block as it it */
   8551     /* not cpu_measurement specific...  */
   8552 
   8553     switch (verbosity) {
   8554     case 0:
   8555       if (local_cpu_usage) {
   8556 	fprintf(where,
   8557 		cpu_fmt_0,
   8558 		local_service_demand);
   8559       }
   8560       else {
   8561 	fprintf(where,
   8562 		cpu_fmt_0,
   8563 		remote_service_demand);
   8564       }
   8565       break;
   8566     case 1:
   8567     case 2:
   8568 
   8569       if (print_headers) {
   8570 	fprintf(where,
   8571 		cpu_title,
   8572 		local_cpu_method,
   8573 		remote_cpu_method);
   8574       }
   8575 
   8576       fprintf(where,
   8577 	      cpu_fmt_1_line_1,		/* the format string */
   8578 	      lss_size,		/* local sendbuf size */
   8579 	      lsr_size,
   8580 	      req_size,		/* how large were the requests */
   8581 	      rsp_size,		/* guess */
   8582 	      elapsed_time,		/* how long was the test */
   8583 	      nummessages/elapsed_time,
   8584 	      local_cpu_utilization,	/* local cpu */
   8585 	      remote_cpu_utilization,	/* remote cpu */
   8586 	      local_service_demand,	/* local service demand */
   8587 	      remote_service_demand);	/* remote service demand */
   8588       fprintf(where,
   8589 	      cpu_fmt_1_line_2,
   8590 	      rss_size,
   8591 	      rsr_size);
   8592       break;
   8593     }
   8594   }
   8595   else {
   8596     /* The tester did not wish to measure service demand. */
   8597     switch (verbosity) {
   8598     case 0:
   8599       fprintf(where,
   8600 	      tput_fmt_0,
   8601 	      nummessages/elapsed_time);
   8602       break;
   8603     case 1:
   8604     case 2:
   8605       if (print_headers) {
   8606 	fprintf(where,tput_title,format_units());
   8607       }
   8608 
   8609       fprintf(where,
   8610 	      tput_fmt_1_line_1,	/* the format string */
   8611 	      lss_size,
   8612 	      lsr_size,
   8613 	      req_size,		/* how large were the requests */
   8614 	      rsp_size,		/* how large were the responses */
   8615 	      elapsed_time, 		/* how long did it take */
   8616 	      nummessages/elapsed_time);
   8617       fprintf(where,
   8618 	      tput_fmt_1_line_2,
   8619 	      rss_size, 		/* remote recvbuf size */
   8620 	      rsr_size);
   8621 
   8622       break;
   8623     }
   8624   }
   8625 
   8626   /* it would be a good thing to include information about some of the */
   8627   /* other parameters that may have been set for this test, but at the */
   8628   /* moment, I do not wish to figure-out all the  formatting, so I will */
   8629   /* just put this comment here to help remind me that it is something */
   8630   /* that should be done at a later time. */
   8631 
   8632   if (verbosity > 1) {
   8633     /* The user wanted to know it all, so we will give it to him. */
   8634     /* This information will include as much as we can find about */
   8635     /* TCP statistics, the alignments of the sends and receives */
   8636     /* and all that sort of rot... */
   8637 
   8638     fprintf(where,
   8639 	    ksink_fmt,
   8640 	    local_send_align,
   8641 	    remote_recv_offset,
   8642 	    local_send_offset,
   8643 	    remote_recv_offset);
   8644 
   8645 #ifdef WANT_HISTOGRAM
   8646     fprintf(where,"\nHistogram of request/response times\n");
   8647     fflush(where);
   8648     HIST_report(time_hist);
   8649 #endif /* WANT_HISTOGRAM */
   8650 
   8651   }
   8652 
   8653 }
   8654 
   8655 
   8656 void
   8658 recv_tcp_conn_rr()
   8659 {
   8660 
   8661   char  *message;
   8662   struct addrinfo *local_res;
   8663   char local_name[BUFSIZ];
   8664   char port_buffer[PORTBUFSIZE];
   8665 
   8666   struct	sockaddr_storage        myaddr_in, peeraddr_in;
   8667   SOCKET	s_listen,s_data;
   8668   netperf_socklen_t 	addrlen;
   8669   char	*recv_message_ptr;
   8670   char	*send_message_ptr;
   8671   char	*temp_message_ptr;
   8672   int	trans_received;
   8673   int	trans_remaining;
   8674   int	bytes_sent;
   8675   int	request_bytes_recvd;
   8676   int	request_bytes_remaining;
   8677   int	timed_out = 0;
   8678   float	elapsed_time;
   8679 
   8680   struct	tcp_conn_rr_request_struct	*tcp_conn_rr_request;
   8681   struct	tcp_conn_rr_response_struct	*tcp_conn_rr_response;
   8682   struct	tcp_conn_rr_results_struct	*tcp_conn_rr_results;
   8683 
   8684   tcp_conn_rr_request =
   8685     (struct tcp_conn_rr_request_struct *)netperf_request.content.test_specific_data;
   8686   tcp_conn_rr_response =
   8687     (struct tcp_conn_rr_response_struct *)netperf_response.content.test_specific_data;
   8688   tcp_conn_rr_results =
   8689     (struct tcp_conn_rr_results_struct *)netperf_response.content.test_specific_data;
   8690 
   8691   if (debug) {
   8692     fprintf(where,"netserver: recv_tcp_conn_rr: entered...\n");
   8693     fflush(where);
   8694   }
   8695 
   8696   /* We want to set-up the listen socket with all the desired */
   8697   /* parameters and then let the initiator know that all is ready. If */
   8698   /* socket size defaults are to be used, then the initiator will have */
   8699   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   8700   /* send-back what they are. If that information cannot be determined, */
   8701   /* then we send-back -1's for the sizes. If things go wrong for any */
   8702   /* reason, we will drop back ten yards and punt. */
   8703 
   8704   /* If anything goes wrong, we want the remote to know about it. It */
   8705   /* would be best if the error that the remote reports to the user is */
   8706   /* the actual error we encountered, rather than some bogus unexpected */
   8707   /* response type message. */
   8708 
   8709   if (debug) {
   8710     fprintf(where,"recv_tcp_conn_rr: setting the response type...\n");
   8711     fflush(where);
   8712   }
   8713 
   8714   netperf_response.content.response_type = TCP_CRR_RESPONSE;
   8715 
   8716   if (debug) {
   8717     fprintf(where,"recv_tcp_conn_rr: the response type is set...\n");
   8718     fflush(where);
   8719   }
   8720 
   8721   /* set-up the data buffer with the requested alignment and offset */
   8722   message = (char *)malloc(DATABUFFERLEN);
   8723   if (message == NULL) {
   8724     printf("malloc(%d) failed!\n", DATABUFFERLEN);
   8725     exit(1);
   8726   }
   8727 
   8728   /* We now alter the message_ptr variables to be at the desired */
   8729   /* alignments with the desired offsets. */
   8730 
   8731   if (debug) {
   8732     fprintf(where,
   8733 	    "recv_tcp_conn_rr: requested recv alignment of %d offset %d\n",
   8734 	    tcp_conn_rr_request->recv_alignment,
   8735 	    tcp_conn_rr_request->recv_offset);
   8736     fprintf(where,
   8737 	    "recv_tcp_conn_rr: requested send alignment of %d offset %d\n",
   8738 	    tcp_conn_rr_request->send_alignment,
   8739 	    tcp_conn_rr_request->send_offset);
   8740     fflush(where);
   8741   }
   8742 
   8743   recv_message_ptr = ALIGN_BUFFER(message, tcp_conn_rr_request->recv_alignment, tcp_conn_rr_request->recv_offset);
   8744 
   8745   send_message_ptr = ALIGN_BUFFER(message, tcp_conn_rr_request->send_alignment, tcp_conn_rr_request->send_offset);
   8746 
   8747   if (debug) {
   8748     fprintf(where,"recv_tcp_conn_rr: receive alignment and offset set...\n");
   8749     fflush(where);
   8750   }
   8751 
   8752   /* Grab a socket to listen on, and then listen on it. */
   8753 
   8754   if (debug) {
   8755     fprintf(where,"recv_tcp_conn_rr: grabbing a socket...\n");
   8756     fflush(where);
   8757   }
   8758 
   8759   /* create_data_socket expects to find some things in the global */
   8760   /* variables, so set the globals based on the values in the request. */
   8761   /* once the socket has been created, we will set the response values */
   8762   /* based on the updated value of those globals. raj 7/94 */
   8763   lss_size_req = tcp_conn_rr_request->send_buf_size;
   8764   lsr_size_req = tcp_conn_rr_request->recv_buf_size;
   8765   loc_nodelay = tcp_conn_rr_request->no_delay;
   8766   loc_rcvavoid = tcp_conn_rr_request->so_rcvavoid;
   8767   loc_sndavoid = tcp_conn_rr_request->so_sndavoid;
   8768 
   8769   set_hostname_and_port(local_name,
   8770 			port_buffer,
   8771 			nf_to_af(tcp_conn_rr_request->ipfamily),
   8772 			tcp_conn_rr_request->port);
   8773 
   8774   local_res = complete_addrinfo(local_name,
   8775 				local_name,
   8776 				port_buffer,
   8777 				nf_to_af(tcp_conn_rr_request->ipfamily),
   8778 				SOCK_STREAM,
   8779 				IPPROTO_TCP,
   8780 				0);
   8781 
   8782   s_listen = create_data_socket(local_res);
   8783 
   8784   if (s_listen == INVALID_SOCKET) {
   8785     netperf_response.content.serv_errno = errno;
   8786     send_response();
   8787     if (debug) {
   8788       fprintf(where,"could not create data socket\n");
   8789       fflush(where);
   8790     }
   8791     exit(1);
   8792   }
   8793 
   8794 #ifdef WIN32
   8795     /* The test timer can fire during operations on the listening socket,
   8796        so to make the start_timer below work we have to move
   8797        it to close s_listen while we are blocked on accept. */
   8798     win_kludge_socket2 = s_listen;
   8799 #endif
   8800 
   8801 
   8802   /* Now, let's set-up the socket to listen for connections */
   8803   if (listen(s_listen, 5) == SOCKET_ERROR) {
   8804     netperf_response.content.serv_errno = errno;
   8805     close(s_listen);
   8806     send_response();
   8807     if (debug) {
   8808       fprintf(where,"could not listen\n");
   8809       fflush(where);
   8810     }
   8811     exit(1);
   8812   }
   8813 
   8814   /* now get the port number assigned by the system  */
   8815   addrlen = sizeof(myaddr_in);
   8816   if (getsockname(s_listen,
   8817 		  (struct sockaddr *)&myaddr_in,
   8818 		  &addrlen) == SOCKET_ERROR){
   8819     netperf_response.content.serv_errno = errno;
   8820     close(s_listen);
   8821     send_response();
   8822     if (debug) {
   8823       fprintf(where,"could not getsockname\n");
   8824       fflush(where);
   8825     }
   8826     exit(1);
   8827   }
   8828 
   8829   /* Now myaddr_in contains the port and the internet address this is */
   8830   /* returned to the sender also implicitly telling the sender that the */
   8831   /* socket buffer sizing has been done. */
   8832 
   8833   tcp_conn_rr_response->data_port_number =
   8834     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
   8835   if (debug) {
   8836     fprintf(where,"telling the remote to call me at %d\n",
   8837 	    tcp_conn_rr_response->data_port_number);
   8838     fflush(where);
   8839   }
   8840   netperf_response.content.serv_errno   = 0;
   8841 
   8842   /* But wait, there's more. If the initiator wanted cpu measurements, */
   8843   /* then we must call the calibrate routine, which will return the max */
   8844   /* rate back to the initiator. If the CPU was not to be measured, or */
   8845   /* something went wrong with the calibration, we will return a 0.0 to */
   8846   /* the initiator. */
   8847 
   8848   tcp_conn_rr_response->cpu_rate = (float)0.0; 	/* assume no cpu */
   8849   if (tcp_conn_rr_request->measure_cpu) {
   8850     tcp_conn_rr_response->measure_cpu = 1;
   8851     tcp_conn_rr_response->cpu_rate =
   8852       calibrate_local_cpu(tcp_conn_rr_request->cpu_rate);
   8853   }
   8854 
   8855 
   8856 
   8857   /* before we send the response back to the initiator, pull some of */
   8858   /* the socket parms from the globals */
   8859   tcp_conn_rr_response->send_buf_size = lss_size;
   8860   tcp_conn_rr_response->recv_buf_size = lsr_size;
   8861   tcp_conn_rr_response->no_delay = loc_nodelay;
   8862   tcp_conn_rr_response->so_rcvavoid = loc_rcvavoid;
   8863   tcp_conn_rr_response->so_sndavoid = loc_sndavoid;
   8864 
   8865   send_response();
   8866 
   8867   addrlen = sizeof(peeraddr_in);
   8868 
   8869   /* Now it's time to start receiving data on the connection. We will */
   8870   /* first grab the apropriate counters and then start grabbing. */
   8871 
   8872   cpu_start(tcp_conn_rr_request->measure_cpu);
   8873 
   8874   /* The loop will exit when the sender does a shutdown, which will */
   8875   /* return a length of zero   */
   8876 
   8877   if (tcp_conn_rr_request->test_length > 0) {
   8878     times_up = 0;
   8879     trans_remaining = 0;
   8880     start_timer(tcp_conn_rr_request->test_length + PAD_TIME);
   8881   }
   8882   else {
   8883     times_up = 1;
   8884     trans_remaining = tcp_conn_rr_request->test_length * -1;
   8885   }
   8886 
   8887   trans_received = 0;
   8888 
   8889   while ((!times_up) || (trans_remaining > 0)) {
   8890 
   8891     /* accept a connection from the remote */
   8892 #ifdef WIN32
   8893     /* The test timer will probably fire during this accept,
   8894        so to make the start_timer above work we have to move
   8895        it to close s_listen while we are blocked on accept. */
   8896     win_kludge_socket = s_listen;
   8897 #endif
   8898     if ((s_data=accept(s_listen,
   8899 		       (struct sockaddr *)&peeraddr_in,
   8900 		       &addrlen)) == INVALID_SOCKET) {
   8901       if (errno == EINTR) {
   8902 	/* the timer popped */
   8903 	timed_out = 1;
   8904 	break;
   8905       }
   8906       fprintf(where,"recv_tcp_conn_rr: accept: errno = %d\n",errno);
   8907       fflush(where);
   8908       close(s_listen);
   8909 
   8910       exit(1);
   8911     }
   8912 
   8913     if (debug) {
   8914       fprintf(where,"recv_tcp_conn_rr: accepted data connection.\n");
   8915       fflush(where);
   8916     }
   8917 
   8918 #ifdef WIN32
   8919   /* this is used so the timer thread can close the socket out from */
   8920   /* under us, which to date is the easiest/cleanest/least */
   8921   /* Windows-specific way I can find to force the winsock calls to */
   8922   /* return WSAEINTR with the test is over. anything that will run on */
   8923   /* 95 and NT and is closer to what netperf expects from Unix signals */
   8924   /* and such would be appreciated raj 1/96 */
   8925   win_kludge_socket = s_data;
   8926 #endif /* WIN32 */
   8927 
   8928 #ifdef KLUDGE_SOCKET_OPTIONS
   8929     /* this is for those systems which *INCORRECTLY* fail to pass */
   8930     /* attributes across an accept() call. Including this goes against */
   8931     /* my better judgement :( raj 11/95 */
   8932 
   8933     kludge_socket_options(s_data);
   8934 
   8935 #endif /* KLUDGE_SOCKET_OPTIONS */
   8936 
   8937     temp_message_ptr	= recv_message_ptr;
   8938     request_bytes_remaining	= tcp_conn_rr_request->request_size;
   8939 
   8940     /* receive the request from the other side */
   8941     while (!times_up && (request_bytes_remaining > 0)) {
   8942       if((request_bytes_recvd=recv(s_data,
   8943 				   temp_message_ptr,
   8944 				   request_bytes_remaining,
   8945 				   0)) == SOCKET_ERROR) {
   8946 	if (SOCKET_EINTR(request_bytes_recvd))
   8947 	{
   8948 	  /* the timer popped */
   8949 	  timed_out = 1;
   8950 	  break;
   8951 	}
   8952 	netperf_response.content.serv_errno = errno;
   8953 	send_response();
   8954 	exit(1);
   8955       }
   8956       else {
   8957 	request_bytes_remaining -= request_bytes_recvd;
   8958 	temp_message_ptr  += request_bytes_recvd;
   8959       }
   8960     }
   8961 
   8962     if (timed_out) {
   8963       /* we hit the end of the test based on time - lets */
   8964       /* bail out of here now... */
   8965       fprintf(where,"yo5\n");
   8966       fflush(where);
   8967       break;
   8968     }
   8969 
   8970     /* Now, send the response to the remote */
   8971     if((bytes_sent=send(s_data,
   8972 			send_message_ptr,
   8973 			tcp_conn_rr_request->response_size,
   8974 			0)) == SOCKET_ERROR) {
   8975       if (errno == EINTR) {
   8976 	/* the test timer has popped */
   8977 	timed_out = 1;
   8978 	fprintf(where,"yo6\n");
   8979 	fflush(where);
   8980 	break;
   8981       }
   8982       netperf_response.content.serv_errno = 99;
   8983       send_response();
   8984       exit(1);
   8985     }
   8986 
   8987     trans_received++;
   8988     if (trans_remaining) {
   8989       trans_remaining--;
   8990     }
   8991 
   8992     if (debug) {
   8993       fprintf(where,
   8994 	      "recv_tcp_conn_rr: Transaction %d complete\n",
   8995 	      trans_received);
   8996       fflush(where);
   8997     }
   8998 
   8999     /* close the connection. the server will likely do a graceful */
   9000     /* close of the connection, insuring that all data has arrived at */
   9001     /* the client. for this it will call shutdown(), and then recv() and */
   9002     /* then close(). I'm reasonably confident that this is the */
   9003     /* appropriate sequence of calls - I would like to hear of */
   9004     /* examples in web servers to the contrary. raj 10/95*/
   9005 #ifdef TCP_CRR_SHUTDOWN
   9006     shutdown(s_data,SHUT_WR);
   9007     recv(s_data,
   9008 	 recv_message_ptr,
   9009 	 1,
   9010 	 0);
   9011     close(s_data);
   9012 #else
   9013     close(s_data);
   9014 #endif /* TCP_CRR_SHUTDOWN */
   9015 
   9016   }
   9017 
   9018 
   9019   /* The loop now exits due to timeout or transaction count being */
   9020   /* reached */
   9021 
   9022   cpu_stop(tcp_conn_rr_request->measure_cpu,&elapsed_time);
   9023 
   9024   if (timed_out) {
   9025     /* we ended the test by time, which was at least 2 seconds */
   9026     /* longer than we wanted to run. so, we want to subtract */
   9027     /* PAD_TIME from the elapsed_time. */
   9028     elapsed_time -= PAD_TIME;
   9029   }
   9030   /* send the results to the sender			*/
   9031 
   9032   if (debug) {
   9033     fprintf(where,
   9034 	    "recv_tcp_conn_rr: got %d transactions\n",
   9035 	    trans_received);
   9036     fflush(where);
   9037   }
   9038 
   9039   tcp_conn_rr_results->bytes_received	= (trans_received *
   9040 					   (tcp_conn_rr_request->request_size +
   9041 					    tcp_conn_rr_request->response_size));
   9042   tcp_conn_rr_results->trans_received	= trans_received;
   9043   tcp_conn_rr_results->elapsed_time	= elapsed_time;
   9044   if (tcp_conn_rr_request->measure_cpu) {
   9045     tcp_conn_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
   9046   }
   9047 
   9048   if (debug) {
   9049     fprintf(where,
   9050 	    "recv_tcp_conn_rr: test complete, sending results.\n");
   9051     fflush(where);
   9052   }
   9053 
   9054   send_response();
   9055 
   9056 }
   9057 
   9058 
   9060 #ifdef DO_1644
   9061 
   9062  /* this test is intended to test the performance of establishing a */
   9063  /* connection, exchanging a request/response pair, and repeating. it */
   9064  /* is expected that this would be a good starting-point for */
   9065  /* comparision of T/TCP with classic TCP for transactional workloads. */
   9066  /* it will also look (can look) much like the communication pattern */
   9067  /* of http for www access. */
   9068 
   9069 int
   9070 send_tcp_tran_rr(char remote_host[])
   9071 {
   9072 
   9073   char *tput_title = "\
   9074 Local /Remote\n\
   9075 Socket Size   Request  Resp.   Elapsed  Trans.\n\
   9076 Send   Recv   Size     Size    Time     Rate         \n\
   9077 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
   9078 
   9079   char *tput_fmt_0 =
   9080     "%7.2f\n";
   9081 
   9082   char *tput_fmt_1_line_1 = "\
   9083 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
   9084   char *tput_fmt_1_line_2 = "\
   9085 %-6d %-6d\n";
   9086 
   9087   char *cpu_title = "\
   9088 Local /Remote\n\
   9089 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
   9090 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
   9091 bytes  bytes  bytes   bytes  secs.   per sec  %%      %%      us/Tr   us/Tr\n\n";
   9092 
   9093   char *cpu_fmt_0 =
   9094     "%6.3f\n";
   9095 
   9096   char *cpu_fmt_1_line_1 = "\
   9097 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f\n";
   9098 
   9099   char *cpu_fmt_1_line_2 = "\
   9100 %-6d %-6d\n";
   9101 
   9102   char *ksink_fmt = "\n\
   9103 Alignment      Offset\n\
   9104 Local  Remote  Local  Remote\n\
   9105 Send   Recv    Send   Recv\n\
   9106 %5d  %5d   %5d  %5d\n";
   9107 
   9108 
   9109   int 			one = 1;
   9110   int			timed_out = 0;
   9111   float			elapsed_time;
   9112 
   9113   int	len;
   9114   struct ring_elt *send_ring;
   9115   struct ring_elt *recv_ring;
   9116   char	*temp_message_ptr;
   9117   int	nummessages;
   9118   SOCKET	send_socket;
   9119   int	trans_remaining;
   9120   double	bytes_xferd;
   9121   int	sock_opt_len = sizeof(int);
   9122   int	rsp_bytes_left;
   9123   int	rsp_bytes_recvd;
   9124 
   9125   float	local_cpu_utilization;
   9126   float	local_service_demand;
   9127   float	remote_cpu_utilization;
   9128   float	remote_service_demand;
   9129   double	thruput;
   9130 
   9131   struct	hostent	        *hp;
   9132   struct	sockaddr_in	server;
   9133   struct        sockaddr_in     *myaddr;
   9134   unsigned      int             addr;
   9135   int                           myport;
   9136 
   9137   struct	tcp_tran_rr_request_struct	*tcp_tran_rr_request;
   9138   struct	tcp_tran_rr_response_struct	*tcp_tran_rr_response;
   9139   struct	tcp_tran_rr_results_struct	*tcp_tran_rr_result;
   9140 
   9141   tcp_tran_rr_request =
   9142     (struct tcp_tran_rr_request_struct *)netperf_request.content.test_specific_data;
   9143   tcp_tran_rr_response =
   9144     (struct tcp_tran_rr_response_struct *)netperf_response.content.test_specific_data;
   9145   tcp_tran_rr_result =
   9146     (struct tcp_tran_rr_results_struct *)netperf_response.content.test_specific_data;
   9147 
   9148 
   9149 #ifdef WANT_HISTOGRAM
   9150   if (verbosity > 1) {
   9151     time_hist = HIST_new();
   9152   }
   9153 #endif /* WANT_HISTOGRAM */
   9154 
   9155   /* since we are now disconnected from the code that established the */
   9156   /* control socket, and since we want to be able to use different */
   9157   /* protocols and such, we are passed the name of the remote host and */
   9158   /* must turn that into the test specific addressing information. */
   9159 
   9160   myaddr = (struct sockaddr_storage *)malloc(sizeof(struct sockaddr_storage));
   9161   if (myaddr == NULL) {
   9162     printf("malloc(%d) failed!\n", sizeof(struct sockaddr_storage));
   9163     exit(1);
   9164   }
   9165 
   9166   bzero((char *)&server,
   9167 	sizeof(server));
   9168   bzero((char *)myaddr,
   9169 	sizeof(struct sockaddr_storage));
   9170   myaddr->sin_family = AF_INET;
   9171 
   9172   complete_addrinfos(&remote_res,
   9173 		     &local_res,
   9174 		     remote_host,
   9175 		     SOCK_STREAM,
   9176 		     IPPROTO_TCP,
   9177 		     0);
   9178 
   9179   if ( print_headers ) {
   9180     print_top_test_header("TCP Transactional/Request/Response TEST",local_res,remote_res);
   9181   }
   9182 
   9183   /* initialize a few counters */
   9184 
   9185   nummessages	=	0;
   9186   bytes_xferd	=	0.0;
   9187   times_up 	= 	0;
   9188 
   9189   /* set-up the data buffers with the requested alignment and offset */
   9190   if (send_width == 0) send_width = 1;
   9191   if (recv_width == 0) recv_width = 1;
   9192 
   9193   send_ring = allocate_buffer_ring(send_width,
   9194 				   req_size,
   9195 				   local_send_align,
   9196 				   local_send_offset);
   9197 
   9198   recv_ring = allocate_buffer_ring(recv_width,
   9199 				   rsp_size,
   9200 				   local_recv_align,
   9201 				   local_recv_offset);
   9202 
   9203 
   9204   if (debug) {
   9205     fprintf(where,"send_tcp_tran_rr: send_socket obtained...\n");
   9206   }
   9207 
   9208   /* If the user has requested cpu utilization measurements, we must */
   9209   /* calibrate the cpu(s). We will perform this task within the tests */
   9210   /* themselves. If the user has specified the cpu rate, then */
   9211   /* calibrate_local_cpu will return rather quickly as it will have */
   9212   /* nothing to do. If local_cpu_rate is zero, then we will go through */
   9213   /* all the "normal" calibration stuff and return the rate back.*/
   9214 
   9215   if (local_cpu_usage) {
   9216     local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   9217   }
   9218 
   9219   /* Tell the remote end to do a listen. The server alters the socket */
   9220   /* paramters on the other side at this point, hence the reason for */
   9221   /* all the values being passed in the setup message. If the user did */
   9222   /* not specify any of the parameters, they will be passed as 0, which */
   9223   /* will indicate to the remote that no changes beyond the system's */
   9224   /* default should be used. Alignment is the exception, it will */
   9225   /* default to 8, which will be no alignment alterations. */
   9226 
   9227   netperf_request.content.request_type	        =	DO_TCP_TRR;
   9228   tcp_tran_rr_request->recv_buf_size	=	rsr_size_req;
   9229   tcp_tran_rr_request->send_buf_size	=	rss_size_req;
   9230   tcp_tran_rr_request->recv_alignment	=	remote_recv_align;
   9231   tcp_tran_rr_request->recv_offset	=	remote_recv_offset;
   9232   tcp_tran_rr_request->send_alignment	=	remote_send_align;
   9233   tcp_tran_rr_request->send_offset	=	remote_send_offset;
   9234   tcp_tran_rr_request->request_size	=	req_size;
   9235   tcp_tran_rr_request->response_size	=	rsp_size;
   9236   tcp_tran_rr_request->no_delay	        =	rem_nodelay;
   9237   tcp_tran_rr_request->measure_cpu	=	remote_cpu_usage;
   9238   tcp_tran_rr_request->cpu_rate	        =	remote_cpu_rate;
   9239   tcp_tran_rr_request->so_rcvavoid	=	rem_rcvavoid;
   9240   tcp_tran_rr_request->so_sndavoid	=	rem_sndavoid;
   9241   if (test_time) {
   9242     tcp_tran_rr_request->test_length	=	test_time;
   9243   }
   9244   else {
   9245     tcp_tran_rr_request->test_length	=	test_trans * -1;
   9246   }
   9247   tcp_tran_rr_request->port             =       atoi(remote_data_port);
   9248   tcp_tran_rr_request->ipfamily        =       af_to_nf(remote_res->ai_family);
   9249 
   9250   if (debug > 1) {
   9251     fprintf(where,"netperf: send_tcp_tran_rr: requesting TCP_TRR test\n");
   9252   }
   9253 
   9254   send_request();
   9255 
   9256   /* The response from the remote will contain all of the relevant 	*/
   9257   /* socket parameters for this test type. We will put them back into 	*/
   9258   /* the variables here so they can be displayed if desired.  The	*/
   9259   /* remote will have calibrated CPU if necessary, and will have done	*/
   9260   /* all the needed set-up we will have calibrated the cpu locally	*/
   9261   /* before sending the request, and will grab the counter value right	*/
   9262   /* after the connect returns. The remote will grab the counter right	*/
   9263   /* after the accept call. This saves the hassle of extra messages	*/
   9264   /* being sent for the TCP tests.					*/
   9265 
   9266   recv_response();
   9267 
   9268   if (!netperf_response.content.serv_errno) {
   9269     rsr_size	=	tcp_tran_rr_response->recv_buf_size;
   9270     rss_size	=	tcp_tran_rr_response->send_buf_size;
   9271     rem_nodelay	=	tcp_tran_rr_response->no_delay;
   9272     remote_cpu_usage=	tcp_tran_rr_response->measure_cpu;
   9273     remote_cpu_rate = 	tcp_tran_rr_response->cpu_rate;
   9274     /* make sure that port numbers are in network order */
   9275     server.sin_port	=	tcp_tran_rr_response->data_port_number;
   9276     server.sin_port =	htons(server.sin_port);
   9277     if (debug) {
   9278       fprintf(where,"remote listen done.\n");
   9279       fprintf(where,"remote port is %d\n",ntohs(server.sin_port));
   9280       fflush(where);
   9281     }
   9282   }
   9283   else {
   9284     Set_errno(netperf_response.content.serv_errno);
   9285     fprintf(where,
   9286 	    "netperf: remote error %d",
   9287 	    netperf_response.content.serv_errno);
   9288     perror("");
   9289     fflush(where);
   9290     exit(1);
   9291   }
   9292 
   9293   /* pick a nice random spot between client_port_min and */
   9294   /* client_port_max for our initial port number. if they are the */
   9295   /* same, then just set to _min */
   9296   if (client_port_max - client_port_min) {
   9297     srand(getpid());
   9298     myport = client_port_min +
   9299       (rand() % (client_port_max - client_port_min));
   9300   }
   9301   else {
   9302     myport = client_port_min;
   9303   }
   9304 
   9305   /* there will be a ++ before the first call to bind, so subtract one */
   9306   myport--;
   9307   myaddr->sin_port = htons((unsigned short)myport);
   9308 
   9309   /* Set-up the test end conditions. For a request/response test, they */
   9310   /* can be either time or transaction based. */
   9311 
   9312   if (test_time) {
   9313     /* The user wanted to end the test after a period of time. */
   9314     times_up = 0;
   9315     trans_remaining = 0;
   9316     start_timer(test_time);
   9317   }
   9318   else {
   9319     /* The tester wanted to send a number of bytes. */
   9320     trans_remaining = test_bytes;
   9321     times_up = 1;
   9322   }
   9323 
   9324   /* The cpu_start routine will grab the current time and possibly */
   9325   /* value of the idle counter for later use in measuring cpu */
   9326   /* utilization and/or service demand and thruput. */
   9327 
   9328   cpu_start(local_cpu_usage);
   9329 
   9330   /* We use an "OR" to control test execution. When the test is */
   9331   /* controlled by time, the byte count check will always return false. */
   9332   /* When the test is controlled by byte count, the time test will */
   9333   /* always return false. When the test is finished, the whole */
   9334   /* expression will go false and we will stop sending data. I think I */
   9335   /* just arbitrarily decrement trans_remaining for the timed test, but */
   9336   /* will not do that just yet... One other question is whether or not */
   9337   /* the send buffer and the receive buffer should be the same buffer. */
   9338 
   9339   while ((!times_up) || (trans_remaining > 0)) {
   9340 
   9341 #ifdef WANT_HISTOGRAM
   9342     if (verbosity > 1) {
   9343       /* timestamp just before our call to create the socket, and then */
   9344       /* again just after the receive raj 3/95 */
   9345       HIST_timestamp(&time_one);
   9346     }
   9347 #endif /* WANT_HISTOGRAM */
   9348 
   9349     /* set up the data socket - is this really necessary or can I just */
   9350     /* re-use the same socket and move this cal out of the while loop. */
   9351     /* it does introcudea *boatload* of system calls. I guess that it */
   9352     /* all depends on "reality of programming." keeping it this way is */
   9353     /* a bit more conservative I imagine - raj 3/95 */
   9354     send_socket = create_data_socket(local_res);
   9355 
   9356     if (send_socket == INVALID_SOCKET) {
   9357       perror("netperf: send_tcp_tran_rr: tcp stream data socket");
   9358       exit(1);
   9359     }
   9360 
   9361     /* we set SO_REUSEADDR on the premis that no unreserved port */
   9362     /* number on the local system is going to be already connected to */
   9363     /* the remote netserver's port number. One thing that I might */
   9364     /* try later is to have the remote actually allocate a couple of */
   9365     /* port numbers and cycle through those as well. depends on if we */
   9366     /* can get through all the unreserved port numbers in less than */
   9367     /* the length of the TIME_WAIT state raj 8/94 */
   9368     one = 1;
   9369     if(setsockopt(send_socket, SOL_SOCKET, SO_REUSEADDR,
   9370 		  (char *)&one, sock_opt_len) == SOCKET_ERROR) {
   9371       perror("netperf: send_tcp_tran_rr: so_reuseaddr");
   9372       exit(1);
   9373     }
   9374 
   9375 newport:
   9376     /* pick a new port number */
   9377     myport = ntohs(myaddr->sin_port);
   9378     myport++;
   9379 
   9380     /* we do not want to use the port number that the server is */
   9381     /* sitting at - this would cause us to fail in a loopback test. we */
   9382     /* could just rely on the failure of the bind to get us past this, */
   9383     /* but I'm guessing that in this one case at least, it is much */
   9384     /* faster, given that we *know* that port number is already in use */
   9385     /* (or rather would be in a loopback test) */
   9386 
   9387     if (myport == ntohs(server.sin_port)) myport++;
   9388 
   9389     /* wrap the port number when we get to 65535. NOTE, some broken */
   9390     /* TCP's might treat the port number as a signed 16 bit quantity. */
   9391     /* we aren't interested in testing such broken implementations :) */
   9392     /* raj 8/94  */
   9393     if (myport >= client_port_max) {
   9394       myport = client_port_min;
   9395     }
   9396     myaddr->sin_port = htons((unsigned short)myport);
   9397 
   9398     if (debug) {
   9399       if ((nummessages % 100) == 0) {
   9400 	printf("port %d\n",myport);
   9401       }
   9402     }
   9403 
   9404     /* we want to bind our socket to a particular port number. */
   9405     if (bind(send_socket,
   9406 	     (struct sockaddr *)myaddr,
   9407 	     sizeof(struct sockaddr_storage)) == SOCKET_ERROR) {
   9408       /* if the bind failed, someone else must have that port number */
   9409       /* - perhaps in the listen state. since we can't use it, skip to */
   9410       /* the next port number. we may have to do this again later, but */
   9411       /* that's just too bad :) */
   9412       if (debug > 1) {
   9413 	fprintf(where,
   9414 		"send_tcp_tran_rr: tried to bind to port %d errno %d\n",
   9415 		ntohs(myaddr->sin_port),
   9416 		errno);
   9417 	fflush(where);
   9418       }
   9419 	/* yes, goto's are supposed to be evil, but they do have their */
   9420 	/* uses from time to time. the real world doesn't always have */
   9421 	/* to code to ge tthe A in CS 101 :) raj 3/95 */
   9422 	goto newport;
   9423     }
   9424 
   9425     /* Connect up to the remote port on the data socket. Since this is */
   9426     /* a test for RFC_1644-style transactional TCP, we can use the */
   9427     /* sendto() call instead of calling connect and then send() */
   9428 
   9429     /* send the request */
   9430     if((len=sendto(send_socket,
   9431 		   send_ring->buffer_ptr,
   9432 		   req_size,
   9433 		   MSG_EOF,
   9434 		   (struct sockaddr *)&server,
   9435 		   sizeof(server))) != req_size) {
   9436       if (SOCKET_EINTR(len))
   9437 	  {
   9438 	    /* we hit the end of a */
   9439 	    /* timed test. */
   9440 	    timed_out = 1;
   9441 	    break;
   9442       }
   9443       perror("send_tcp_tran_rr: data send error");
   9444       exit(1);
   9445     }
   9446     send_ring = send_ring->next;
   9447 
   9448     /* receive the response */
   9449     rsp_bytes_left = rsp_size;
   9450     temp_message_ptr  = recv_ring->buffer_ptr;
   9451     while(rsp_bytes_left > 0) {
   9452       if((rsp_bytes_recvd=recv(send_socket,
   9453 			       temp_message_ptr,
   9454 			       rsp_bytes_left,
   9455 			       0)) == SOCKET_ERROR) {
   9456 	    if (SOCKET_EINTR(rsp_bytes_recvd))
   9457 		{
   9458 	      /* We hit the end of a timed test. */
   9459 	      timed_out = 1;
   9460 	      break;
   9461 		}
   9462 	    perror("send_tcp_tran_rr: data recv error");
   9463 	    exit(1);
   9464       }
   9465       rsp_bytes_left -= rsp_bytes_recvd;
   9466       temp_message_ptr  += rsp_bytes_recvd;
   9467     }
   9468     recv_ring = recv_ring->next;
   9469 
   9470     if (timed_out) {
   9471       /* we may have been in a nested while loop - we need */
   9472       /* another call to break. */
   9473       break;
   9474     }
   9475 
   9476     close(send_socket);
   9477 
   9478 #ifdef WANT_HISTOGRAM
   9479     if (verbosity > 1) {
   9480       HIST_timestamp(&time_two);
   9481       HIST_add(time_hist,delta_micro(&time_one,&time_two));
   9482     }
   9483 #endif /* WANT_HISTOGRAM */
   9484 
   9485     nummessages++;
   9486     if (trans_remaining) {
   9487       trans_remaining--;
   9488     }
   9489 
   9490     if (debug > 3) {
   9491       fprintf(where,
   9492 	      "Transaction %d completed on local port %d\n",
   9493 	      nummessages,
   9494 	      ntohs(myaddr->sin_port));
   9495       fflush(where);
   9496     }
   9497 
   9498 
   9499   }
   9500 
   9501   /* this call will always give us the elapsed time for the test, and */
   9502   /* will also store-away the necessaries for cpu utilization */
   9503 
   9504   cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being measured? */
   9505   /* how long did we really run? */
   9506 
   9507   /* Get the statistics from the remote end. The remote will have */
   9508   /* calculated service demand and all those interesting things. If it */
   9509   /* wasn't supposed to care, it will return obvious values. */
   9510 
   9511   recv_response();
   9512   if (!netperf_response.content.serv_errno) {
   9513     if (debug)
   9514       fprintf(where,"remote results obtained\n");
   9515   }
   9516   else {
   9517     Set_errno(netperf_response.content.serv_errno);
   9518     fprintf(where,
   9519 	    "netperf: remote error %d",
   9520 	    netperf_response.content.serv_errno);
   9521     perror("");
   9522     fflush(where);
   9523     exit(1);
   9524   }
   9525 
   9526   /* We now calculate what our thruput was for the test. In the future, */
   9527   /* we may want to include a calculation of the thruput measured by */
   9528   /* the remote, but it should be the case that for a TCP stream test, */
   9529   /* that the two numbers should be *very* close... We calculate */
   9530   /* bytes_sent regardless of the way the test length was controlled. */
   9531   /* If it was time, we needed to, and if it was by bytes, the user may */
   9532   /* have specified a number of bytes that wasn't a multiple of the */
   9533   /* send_size, so we really didn't send what he asked for ;-) We use */
   9534   /* Kbytes/s as the units of thruput for a TCP stream test, where K = */
   9535   /* 1024. A future enhancement *might* be to choose from a couple of */
   9536   /* unit selections. */
   9537 
   9538   bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
   9539   thruput	= calc_thruput(bytes_xferd);
   9540 
   9541   if (local_cpu_usage || remote_cpu_usage) {
   9542     /* We must now do a little math for service demand and cpu */
   9543     /* utilization for the system(s) */
   9544     /* Of course, some of the information might be bogus because */
   9545     /* there was no idle counter in the kernel(s). We need to make */
   9546     /* a note of this for the user's benefit...*/
   9547     if (local_cpu_usage) {
   9548       if (local_cpu_rate == 0.0) {
   9549 	fprintf(where,"WARNING WARNING WARNING  WARNING WARNING WARNING  WARNING!\n");
   9550 	fprintf(where,"Local CPU usage numbers based on process information only!\n");
   9551 	fflush(where);
   9552       }
   9553       local_cpu_utilization = calc_cpu_util(0.0);
   9554       /* since calc_service demand is doing ms/Kunit we will */
   9555       /* multiply the number of transaction by 1024 to get */
   9556       /* "good" numbers */
   9557       local_service_demand  = calc_service_demand((double) nummessages*1024,
   9558 						  0.0,
   9559 						  0.0,
   9560 						  0);
   9561     }
   9562     else {
   9563       local_cpu_utilization	= (float) -1.0;
   9564       local_service_demand	= (float) -1.0;
   9565     }
   9566 
   9567     if (remote_cpu_usage) {
   9568       if (remote_cpu_rate == 0.0) {
   9569 	fprintf(where,"DANGER  DANGER  DANGER    DANGER  DANGER  DANGER    DANGER!\n");
   9570 	fprintf(where,"Remote CPU usage numbers based on process information only!\n");
   9571 	fflush(where);
   9572       }
   9573       remote_cpu_utilization = tcp_tran_rr_result->cpu_util;
   9574       /* since calc_service demand is doing ms/Kunit we will */
   9575       /* multiply the number of transaction by 1024 to get */
   9576       /* "good" numbers */
   9577       remote_service_demand = calc_service_demand((double) nummessages*1024,
   9578 						  0.0,
   9579 						  remote_cpu_utilization,
   9580 						  tcp_tran_rr_result->num_cpus);
   9581     }
   9582     else {
   9583       remote_cpu_utilization = (float) -1.0;
   9584       remote_service_demand  = (float) -1.0;
   9585     }
   9586 
   9587     /* We are now ready to print all the information. If the user */
   9588     /* has specified zero-level verbosity, we will just print the */
   9589     /* local service demand, or the remote service demand. If the */
   9590     /* user has requested verbosity level 1, he will get the basic */
   9591     /* "streamperf" numbers. If the user has specified a verbosity */
   9592     /* of greater than 1, we will display a veritable plethora of */
   9593     /* background information from outside of this block as it it */
   9594     /* not cpu_measurement specific...  */
   9595 
   9596     switch (verbosity) {
   9597     case 0:
   9598       if (local_cpu_usage) {
   9599 	fprintf(where,
   9600 		cpu_fmt_0,
   9601 		local_service_demand);
   9602       }
   9603       else {
   9604 	fprintf(where,
   9605 		cpu_fmt_0,
   9606 		remote_service_demand);
   9607       }
   9608       break;
   9609     case 1:
   9610     case 2:
   9611 
   9612       if (print_headers) {
   9613 	fprintf(where,
   9614 		cpu_title,
   9615 		local_cpu_method,
   9616 		remote_cpu_method);
   9617       }
   9618 
   9619       fprintf(where,
   9620 	      cpu_fmt_1_line_1,		/* the format string */
   9621 	      lss_size,		/* local sendbuf size */
   9622 	      lsr_size,
   9623 	      req_size,		/* how large were the requests */
   9624 	      rsp_size,		/* guess */
   9625 	      elapsed_time,		/* how long was the test */
   9626 	      nummessages/elapsed_time,
   9627 	      local_cpu_utilization,	/* local cpu */
   9628 	      remote_cpu_utilization,	/* remote cpu */
   9629 	      local_service_demand,	/* local service demand */
   9630 	      remote_service_demand);	/* remote service demand */
   9631       fprintf(where,
   9632 	      cpu_fmt_1_line_2,
   9633 	      rss_size,
   9634 	      rsr_size);
   9635       break;
   9636     }
   9637   }
   9638   else {
   9639     /* The tester did not wish to measure service demand. */
   9640     switch (verbosity) {
   9641     case 0:
   9642       fprintf(where,
   9643 	      tput_fmt_0,
   9644 	      nummessages/elapsed_time);
   9645       break;
   9646     case 1:
   9647     case 2:
   9648       if (print_headers) {
   9649 	fprintf(where,tput_title,format_units());
   9650       }
   9651 
   9652       fprintf(where,
   9653 	      tput_fmt_1_line_1,	/* the format string */
   9654 	      lss_size,
   9655 	      lsr_size,
   9656 	      req_size,		/* how large were the requests */
   9657 	      rsp_size,		/* how large were the responses */
   9658 	      elapsed_time, 		/* how long did it take */
   9659 	      nummessages/elapsed_time);
   9660       fprintf(where,
   9661 	      tput_fmt_1_line_2,
   9662 	      rss_size, 		/* remote recvbuf size */
   9663 	      rsr_size);
   9664 
   9665       break;
   9666     }
   9667   }
   9668 
   9669   /* it would be a good thing to include information about some of the */
   9670   /* other parameters that may have been set for this test, but at the */
   9671   /* moment, I do not wish to figure-out all the  formatting, so I will */
   9672   /* just put this comment here to help remind me that it is something */
   9673   /* that should be done at a later time. */
   9674 
   9675   if (verbosity > 1) {
   9676     /* The user wanted to know it all, so we will give it to him. */
   9677     /* This information will include as much as we can find about */
   9678     /* TCP statistics, the alignments of the sends and receives */
   9679     /* and all that sort of rot... */
   9680 
   9681     fprintf(where,
   9682 	    ksink_fmt,
   9683 	    local_send_align,
   9684 	    remote_recv_offset,
   9685 	    local_send_offset,
   9686 	    remote_recv_offset);
   9687 
   9688 #ifdef WANT_HISTOGRAM
   9689     fprintf(where,"\nHistogram of request/response times\n");
   9690     fflush(where);
   9691     HIST_report(time_hist);
   9692 #endif /* WANT_HISTOGRAM */
   9693 
   9694   }
   9695 
   9696 }
   9697 
   9698 
   9699 int
   9701 recv_tcp_tran_rr()
   9702 {
   9703 
   9704   char  *message;
   9705   struct	sockaddr_in        myaddr_in,
   9706   peeraddr_in;
   9707   SOCKET	s_listen,s_data;
   9708   netperf_socklen_t 	addrlen;
   9709   int   NoPush = 1;
   9710 
   9711   char	*recv_message_ptr;
   9712   char	*send_message_ptr;
   9713   char	*temp_message_ptr;
   9714   int	trans_received;
   9715   int	trans_remaining;
   9716   int	bytes_sent;
   9717   int	request_bytes_recvd;
   9718   int	request_bytes_remaining;
   9719   int	timed_out = 0;
   9720   float	elapsed_time;
   9721 
   9722   struct	tcp_tran_rr_request_struct	*tcp_tran_rr_request;
   9723   struct	tcp_tran_rr_response_struct	*tcp_tran_rr_response;
   9724   struct	tcp_tran_rr_results_struct	*tcp_tran_rr_results;
   9725 
   9726   tcp_tran_rr_request =
   9727     (struct tcp_tran_rr_request_struct *)netperf_request.content.test_specific_data;
   9728   tcp_tran_rr_response =
   9729     (struct tcp_tran_rr_response_struct *)netperf_response.content.test_specific_data;
   9730   tcp_tran_rr_results =
   9731     (struct tcp_tran_rr_results_struct *)netperf_response.content.test_specific_data;
   9732 
   9733   if (debug) {
   9734     fprintf(where,"netserver: recv_tcp_tran_rr: entered...\n");
   9735     fflush(where);
   9736   }
   9737 
   9738   /* We want to set-up the listen socket with all the desired */
   9739   /* parameters and then let the initiator know that all is ready. If */
   9740   /* socket size defaults are to be used, then the initiator will have */
   9741   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   9742   /* send-back what they are. If that information cannot be determined, */
   9743   /* then we send-back -1's for the sizes. If things go wrong for any */
   9744   /* reason, we will drop back ten yards and punt. */
   9745 
   9746   /* If anything goes wrong, we want the remote to know about it. It */
   9747   /* would be best if the error that the remote reports to the user is */
   9748   /* the actual error we encountered, rather than some bogus unexpected */
   9749   /* response type message. */
   9750 
   9751   if (debug) {
   9752     fprintf(where,"recv_tcp_tran_rr: setting the response type...\n");
   9753     fflush(where);
   9754   }
   9755 
   9756   netperf_response.content.response_type = TCP_TRR_RESPONSE;
   9757 
   9758   if (debug) {
   9759     fprintf(where,"recv_tcp_tran_rr: the response type is set...\n");
   9760     fflush(where);
   9761   }
   9762 
   9763   /* set-up the data buffer with the requested alignment and offset */
   9764   message = (char *)malloc(DATABUFFERLEN);
   9765   if (message == NULL) {
   9766     printf("malloc(%d) failed!\n", DATABUFFERLEN);
   9767     exit(1);
   9768   }
   9769 
   9770   /* We now alter the message_ptr variables to be at the desired */
   9771   /* alignments with the desired offsets. */
   9772 
   9773   if (debug) {
   9774     fprintf(where,
   9775 	    "recv_tcp_tran_rr: requested recv alignment of %d offset %d\n",
   9776 	    tcp_tran_rr_request->recv_alignment,
   9777 	    tcp_tran_rr_request->recv_offset);
   9778     fprintf(where,
   9779 	    "recv_tcp_tran_rr: requested send alignment of %d offset %d\n",
   9780 	    tcp_tran_rr_request->send_alignment,
   9781 	    tcp_tran_rr_request->send_offset);
   9782     fflush(where);
   9783   }
   9784 
   9785   recv_message_ptr = ALIGN_BUFFER(message, tcp_tran_rr_request->recv_alignment, tcp_tran_rr_request->recv_offset);
   9786 
   9787   send_message_ptr = ALIGN_BUFFER(message, tcp_tran_rr_request->send_alignment, tcp_tran_rr_request->send_offset);
   9788 
   9789   if (debug) {
   9790     fprintf(where,"recv_tcp_tran_rr: receive alignment and offset set...\n");
   9791     fflush(where);
   9792   }
   9793 
   9794   /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */
   9795   /* can put in OUR values !-) At some point, we may want to nail this */
   9796   /* socket to a particular network-level address, but for now, */
   9797   /* INADDR_ANY should be just fine. */
   9798 
   9799   bzero((char *)&myaddr_in,
   9800 	sizeof(myaddr_in));
   9801   myaddr_in.sin_family      = AF_INET;
   9802   myaddr_in.sin_addr.s_addr = INADDR_ANY;
   9803   myaddr_in.sin_port        = htons((unsigned short)tcp_tran_rr_request->port);
   9804 
   9805   /* Grab a socket to listen on, and then listen on it. */
   9806 
   9807   if (debug) {
   9808     fprintf(where,"recv_tcp_tran_rr: grabbing a socket...\n");
   9809     fflush(where);
   9810   }
   9811 
   9812   /* create_data_socket expects to find some things in the global */
   9813   /* variables, so set the globals based on the values in the request. */
   9814   /* once the socket has been created, we will set the response values */
   9815   /* based on the updated value of those globals. raj 7/94 */
   9816   lss_size_req = tcp_tran_rr_request->send_buf_size;
   9817   lsr_size_req = tcp_tran_rr_request->recv_buf_size;
   9818   loc_nodelay = tcp_tran_rr_request->no_delay;
   9819   loc_rcvavoid = tcp_tran_rr_request->so_rcvavoid;
   9820   loc_sndavoid = tcp_tran_rr_request->so_sndavoid;
   9821 
   9822   set_hostname_and_port(local_name,
   9823 			port_buffer,
   9824 			nf_to_af(tcp_tran_rr_request->ipfamily),
   9825 			tcp_tran_rr_request->port);
   9826 
   9827   local_res = complete_addrinfo(local_name,
   9828 				local_name,
   9829 				port_buffer,
   9830 				nf_to_af(tcp_tran_rr_request->ipfamily),
   9831 				SOCK_STREAM,
   9832 				IPPROTO_TCP,
   9833 				0);
   9834 
   9835   s_listen = create_data_socket(local_res);
   9836 
   9837   if (s_listen == INVALID_SOCKET) {
   9838     netperf_response.content.serv_errno = errno;
   9839     send_response();
   9840     if (debug) {
   9841       fprintf(where,"could not create data socket\n");
   9842       fflush(where);
   9843     }
   9844     exit(1);
   9845   }
   9846 
   9847 #ifdef WIN32
   9848   /* The test timer can fire during operations on the listening socket,
   9849      so to make the start_timer below work we have to move
   9850      it to close s_listen while we are blocked on accept. */
   9851   win_kludge_socket2 = s_listen;
   9852 #endif
   9853 
   9854 
   9855   /* Let's get an address assigned to this socket so we can tell the */
   9856   /* initiator how to reach the data socket. There may be a desire to */
   9857   /* nail this socket to a specific IP address in a multi-homed, */
   9858   /* multi-connection situation, but for now, we'll ignore the issue */
   9859   /* and concentrate on single connection testing. */
   9860 
   9861   if (bind(s_listen,
   9862 	   (struct sockaddr *)&myaddr_in,
   9863 	   sizeof(myaddr_in)) == SOCKET_ERROR) {
   9864     netperf_response.content.serv_errno = errno;
   9865     close(s_listen);
   9866     send_response();
   9867     if (debug) {
   9868       fprintf(where,"could not bind\n");
   9869       fflush(where);
   9870     }
   9871     exit(1);
   9872   }
   9873 
   9874   /* we want to disable the implicit PUSH on all sends. at some point, */
   9875   /* this might want to be a parm to the test raj 3/95 */
   9876   if (setsockopt(s_listen,
   9877 		 IPPROTO_TCP,
   9878 		 TCP_NOPUSH,
   9879 		 (const char *)&NoPush,
   9880 		 sizeof(int)) == SOCKET_ERROR) {
   9881     fprintf(where,
   9882 	    "recv_tcp_tran_rr: could not set TCP_NOPUSH errno %d\n",
   9883 	    errno);
   9884     fflush(where);
   9885     netperf_response.content.serv_errno = errno;
   9886     close(s_listen);
   9887     send_response();
   9888   }
   9889 
   9890   /* Now, let's set-up the socket to listen for connections */
   9891   if (listen(s_listen, 5) == SOCKET_ERROR) {
   9892     netperf_response.content.serv_errno = errno;
   9893     close(s_listen);
   9894     send_response();
   9895     if (debug) {
   9896       fprintf(where,"could not listen\n");
   9897       fflush(where);
   9898     }
   9899     exit(1);
   9900   }
   9901 
   9902   /* now get the port number assigned by the system  */
   9903   addrlen = sizeof(myaddr_in);
   9904   if (getsockname(s_listen,
   9905 		  (struct sockaddr *)&myaddr_in,
   9906 		  &addrlen) == SOCKET_ERROR){
   9907     netperf_response.content.serv_errno = errno;
   9908     close(s_listen);
   9909     send_response();
   9910     if (debug) {
   9911       fprintf(where,"could not geetsockname\n");
   9912       fflush(where);
   9913     }
   9914     exit(1);
   9915   }
   9916 
   9917   /* Now myaddr_in contains the port and the internet address this is */
   9918   /* returned to the sender also implicitly telling the sender that the */
   9919   /* socket buffer sizing has been done. */
   9920 
   9921   tcp_tran_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port);
   9922   if (debug) {
   9923     fprintf(where,"telling the remote to call me at %d\n",
   9924 	    tcp_tran_rr_response->data_port_number);
   9925     fflush(where);
   9926   }
   9927   netperf_response.content.serv_errno   = 0;
   9928 
   9929   /* But wait, there's more. If the initiator wanted cpu measurements, */
   9930   /* then we must call the calibrate routine, which will return the max */
   9931   /* rate back to the initiator. If the CPU was not to be measured, or */
   9932   /* something went wrong with the calibration, we will return a 0.0 to */
   9933   /* the initiator. */
   9934 
   9935   tcp_tran_rr_response->cpu_rate = 0.0; 	/* assume no cpu */
   9936   if (tcp_tran_rr_request->measure_cpu) {
   9937     tcp_tran_rr_response->measure_cpu = 1;
   9938     tcp_tran_rr_response->cpu_rate =
   9939       calibrate_local_cpu(tcp_tran_rr_request->cpu_rate);
   9940   }
   9941 
   9942 
   9943 
   9944   /* before we send the response back to the initiator, pull some of */
   9945   /* the socket parms from the globals */
   9946   tcp_tran_rr_response->send_buf_size = lss_size;
   9947   tcp_tran_rr_response->recv_buf_size = lsr_size;
   9948   tcp_tran_rr_response->no_delay = loc_nodelay;
   9949   tcp_tran_rr_response->so_rcvavoid = loc_rcvavoid;
   9950   tcp_tran_rr_response->so_sndavoid = loc_sndavoid;
   9951 
   9952   send_response();
   9953 
   9954   addrlen = sizeof(peeraddr_in);
   9955 
   9956   /* Now it's time to start receiving data on the connection. We will */
   9957   /* first grab the apropriate counters and then start grabbing. */
   9958 
   9959   cpu_start(tcp_tran_rr_request->measure_cpu);
   9960 
   9961   /* The loop will exit when the sender does a shutdown, which will */
   9962   /* return a length of zero   */
   9963 
   9964   if (tcp_tran_rr_request->test_length > 0) {
   9965     times_up = 0;
   9966     trans_remaining = 0;
   9967     start_timer(tcp_tran_rr_request->test_length + PAD_TIME);
   9968   }
   9969   else {
   9970     times_up = 1;
   9971     trans_remaining = tcp_tran_rr_request->test_length * -1;
   9972   }
   9973 
   9974   trans_received = 0;
   9975 
   9976   while ((!times_up) || (trans_remaining > 0)) {
   9977 
   9978     /* accept a connection from the remote */
   9979     if ((s_data=accept(s_listen,
   9980 		       (struct sockaddr *)&peeraddr_in,
   9981 		       &addrlen)) == INVALID_SOCKET) {
   9982       if (errno == EINTR) {
   9983 	/* the timer popped */
   9984 	timed_out = 1;
   9985 	break;
   9986       }
   9987       fprintf(where,"recv_tcp_tran_rr: accept: errno = %d\n",errno);
   9988       fflush(where);
   9989       close(s_listen);
   9990 
   9991       exit(1);
   9992     }
   9993 
   9994     if (debug) {
   9995       fprintf(where,"recv_tcp_tran_rr: accepted data connection.\n");
   9996       fflush(where);
   9997     }
   9998 
   9999 #ifdef WIN32
   10000   /* this is used so the timer thread can close the socket out from */
   10001   /* under us, which to date is the easiest/cleanest/least */
   10002   /* Windows-specific way I can find to force the winsock calls to */
   10003   /* return WSAEINTR with the test is over. anything that will run on */
   10004   /* 95 and NT and is closer to what netperf expects from Unix signals */
   10005   /* and such would be appreciated raj 1/96 */
   10006   win_kludge_socket = s_data;
   10007 #endif /* WIN32 */
   10008 
   10009 #ifdef KLUDGE_SOCKET_OPTIONS
   10010   /* this is for those systems which *INCORRECTLY* fail to pass */
   10011   /* attributes across an accept() call. Including this goes against */
   10012   /* my better judgement :( raj 11/95 */
   10013 
   10014   kludge_socket_options(s_data);
   10015 
   10016 #endif /* KLUDGE_SOCKET_OPTIONS */
   10017 
   10018     temp_message_ptr	= recv_message_ptr;
   10019     request_bytes_remaining	= tcp_tran_rr_request->request_size;
   10020 
   10021     /* receive the request from the other side. we can just receive */
   10022     /* until we get zero bytes, but that would be a slight structure */
   10023     /* change in the code, with minimal perfomance effects. If */
   10024     /* however, I has variable-length messages, I would want to do */
   10025     /* this to avoid needing "double reads" - one for the message */
   10026     /* length, and one for the rest of the message raj 3/95 */
   10027     while(request_bytes_remaining > 0) {
   10028       if((request_bytes_recvd=recv(s_data,
   10029 				   temp_message_ptr,
   10030 				   request_bytes_remaining,
   10031 				   0)) == SOCKET_ERROR) {
   10032 	    if ( SOCKET_EINTR(request_bytes_recvd) )
   10033 		{
   10034 	      /* the timer popped */
   10035 	      timed_out = 1;
   10036 	      break;
   10037 		}
   10038 	    netperf_response.content.serv_errno = errno;
   10039 	    send_response();
   10040 	    exit(1);
   10041       }
   10042       else {
   10043 	request_bytes_remaining -= request_bytes_recvd;
   10044 	temp_message_ptr  += request_bytes_recvd;
   10045       }
   10046     }
   10047 
   10048     if (timed_out) {
   10049       /* we hit the end of the test based on time - lets */
   10050       /* bail out of here now... */
   10051       fprintf(where,"yo5\n");
   10052       fflush(where);
   10053       break;
   10054     }
   10055 
   10056     /* Now, send the response to the remote we can use sendto here to */
   10057     /* help remind people that this is an rfc 1644 style of test */
   10058     if((bytes_sent=sendto(s_data,
   10059 			  send_message_ptr,
   10060 			  tcp_tran_rr_request->response_size,
   10061 			  MSG_EOF,
   10062 			  (struct sockaddr *)&peeraddr_in,
   10063 			  sizeof(struct sockaddr_storage))) == SOCKET_ERROR) {
   10064       if (SOCKET_EINTR(bytes_sent)) {
   10065 	/* the test timer has popped */
   10066 	timed_out = 1;
   10067 	fprintf(where,"yo6\n");
   10068 	fflush(where);
   10069 	break;
   10070       }
   10071       netperf_response.content.serv_errno = 99;
   10072       send_response();
   10073       exit(1);
   10074     }
   10075 
   10076     trans_received++;
   10077     if (trans_remaining) {
   10078       trans_remaining--;
   10079     }
   10080 
   10081     if (debug) {
   10082       fprintf(where,
   10083 	      "recv_tcp_tran_rr: Transaction %d complete\n",
   10084 	      trans_received);
   10085       fflush(where);
   10086     }
   10087 
   10088     /* close the connection. since we have disable PUSH on sends, the */
   10089     /* FIN should be tacked-onto our last send instead of being */
   10090     /* standalone */
   10091     close(s_data);
   10092 
   10093   }
   10094 
   10095 
   10096   /* The loop now exits due to timeout or transaction count being */
   10097   /* reached */
   10098 
   10099   cpu_stop(tcp_tran_rr_request->measure_cpu,&elapsed_time);
   10100 
   10101   if (timed_out) {
   10102     /* we ended the test by time, which was at least 2 seconds */
   10103     /* longer than we wanted to run. so, we want to subtract */
   10104     /* PAD_TIME from the elapsed_time. */
   10105     elapsed_time -= PAD_TIME;
   10106   }
   10107   /* send the results to the sender			*/
   10108 
   10109   if (debug) {
   10110     fprintf(where,
   10111 	    "recv_tcp_tran_rr: got %d transactions\n",
   10112 	    trans_received);
   10113     fflush(where);
   10114   }
   10115 
   10116   tcp_tran_rr_results->bytes_received	= (trans_received *
   10117 					   (tcp_tran_rr_request->request_size +
   10118 					    tcp_tran_rr_request->response_size));
   10119   tcp_tran_rr_results->trans_received	= trans_received;
   10120   tcp_tran_rr_results->elapsed_time	= elapsed_time;
   10121   if (tcp_tran_rr_request->measure_cpu) {
   10122     tcp_tran_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
   10123   }
   10124 
   10125   if (debug) {
   10126     fprintf(where,
   10127 	    "recv_tcp_tran_rr: test complete, sending results.\n");
   10128     fflush(where);
   10129   }
   10130 
   10131   send_response();
   10132 
   10133 }
   10134 #endif /* DO_1644 */
   10135 
   10136 #ifdef DO_NBRR
   10138  /* this routine implements the sending (netperf) side of the TCP_RR */
   10139  /* test using POSIX-style non-blocking sockets. */
   10140 
   10141 void
   10142 send_tcp_nbrr(char remote_host[])
   10143 {
   10144 
   10145   char *tput_title = "\
   10146 Local /Remote\n\
   10147 Socket Size   Request  Resp.   Elapsed  Trans.\n\
   10148 Send   Recv   Size     Size    Time     Rate         \n\
   10149 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
   10150 
   10151   char *tput_fmt_0 =
   10152     "%7.2f\n";
   10153 
   10154   char *tput_fmt_1_line_1 = "\
   10155 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
   10156   char *tput_fmt_1_line_2 = "\
   10157 %-6d %-6d\n";
   10158 
   10159   char *cpu_title = "\
   10160 Local /Remote\n\
   10161 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
   10162 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
   10163 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
   10164 
   10165   char *cpu_fmt_0 =
   10166     "%6.3f %c\n";
   10167 
   10168   char *cpu_fmt_1_line_1 = "\
   10169 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f  %-6.2f %-6.2f %-6.3f  %-6.3f\n";
   10170 
   10171   char *cpu_fmt_1_line_2 = "\
   10172 %-6d %-6d\n";
   10173 
   10174   char *ksink_fmt = "\
   10175 Alignment      Offset\n\
   10176 Local  Remote  Local  Remote\n\
   10177 Send   Recv    Send   Recv\n\
   10178 %5d  %5d   %5d  %5d\n";
   10179 
   10180 
   10181   int			timed_out = 0;
   10182   float			elapsed_time;
   10183 
   10184   int	len;
   10185   char	*temp_message_ptr;
   10186   int	nummessages;
   10187   SOCKET	send_socket;
   10188   int	trans_remaining;
   10189   double	bytes_xferd;
   10190 
   10191   struct ring_elt *send_ring;
   10192   struct ring_elt *recv_ring;
   10193 
   10194   int	rsp_bytes_left;
   10195   int	rsp_bytes_recvd;
   10196 
   10197   float	local_cpu_utilization;
   10198   float	local_service_demand;
   10199   float	remote_cpu_utilization;
   10200   float	remote_service_demand;
   10201   double	thruput;
   10202 
   10203   struct	hostent	        *hp;
   10204   struct	sockaddr_storage	server;
   10205   unsigned      int             addr;
   10206 
   10207   struct	tcp_rr_request_struct	*tcp_rr_request;
   10208   struct	tcp_rr_response_struct	*tcp_rr_response;
   10209   struct	tcp_rr_results_struct	*tcp_rr_result;
   10210 
   10211   struct addrinfo *remote_res;
   10212   struct addrinfo *local_res;
   10213 
   10214   tcp_rr_request =
   10215     (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data;
   10216   tcp_rr_response=
   10217     (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data;
   10218   tcp_rr_result	=
   10219     (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data;
   10220 
   10221 #ifdef WANT_HISTOGRAM
   10222   if (verbosity > 1) {
   10223     time_hist = HIST_new();
   10224   }
   10225 #endif /* WANT_HISTOGRAM */
   10226 
   10227   /* since we are now disconnected from the code that established the */
   10228   /* control socket, and since we want to be able to use different */
   10229   /* protocols and such, we are passed the name of the remote host and */
   10230   /* must turn that into the test specific addressing information. */
   10231 
   10232   bzero((char *)&server,
   10233 	sizeof(server));
   10234 
   10235   complete_addrinfos(&remote_res,
   10236 		     &local_res,
   10237 		     remote_host,
   10238 		     SOCK_STREAM,
   10239 		     IPPROTO_TCP,
   10240 		     0);
   10241 
   10242   if ( print_headers ) {
   10243     print_top_test_header("TCP Non-Blocking REQUEST/RESPONSE TEST",local_res,remote_res);
   10244   }
   10245 
   10246   /* initialize a few counters */
   10247 
   10248   send_ring = NULL;
   10249   recv_ring = NULL;
   10250   confidence_iteration = 1;
   10251   init_stat();
   10252 
   10253   /* we have a great-big while loop which controls the number of times */
   10254   /* we run a particular test. this is for the calculation of a */
   10255   /* confidence interval (I really should have stayed awake during */
   10256   /* probstats :). If the user did not request confidence measurement */
   10257   /* (no confidence is the default) then we will only go though the */
   10258   /* loop once. the confidence stuff originates from the folks at IBM */
   10259 
   10260   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   10261 	 (confidence_iteration <= iteration_min)) {
   10262 
   10263     /* initialize a few counters. we have to remember that we might be */
   10264     /* going through the loop more than once. */
   10265 
   10266     nummessages     = 0;
   10267     bytes_xferd     = 0.0;
   10268     times_up        = 0;
   10269     timed_out       = 0;
   10270     trans_remaining = 0;
   10271 
   10272     /* set-up the data buffers with the requested alignment and offset. */
   10273     /* since this is a request/response test, default the send_width and */
   10274     /* recv_width to 1 and not two raj 7/94 */
   10275 
   10276     if (send_width == 0) send_width = 1;
   10277     if (recv_width == 0) recv_width = 1;
   10278 
   10279     if (send_ring == NULL) {
   10280       send_ring = allocate_buffer_ring(send_width,
   10281 				       req_size,
   10282 				       local_send_align,
   10283 				       local_send_offset);
   10284     }
   10285 
   10286     if (recv_ring == NULL) {
   10287       recv_ring = allocate_buffer_ring(recv_width,
   10288 				       rsp_size,
   10289 				       local_recv_align,
   10290 				       local_recv_offset);
   10291     }
   10292 
   10293     /*set up the data socket                        */
   10294     send_socket = create_data_socket(local_res);
   10295 
   10296     if (send_socket == INVALID_SOCKET){
   10297       perror("netperf: send_tcp_nbrr: tcp stream data socket");
   10298       exit(1);
   10299     }
   10300 
   10301     if (debug) {
   10302       fprintf(where,"send_tcp_nbrr: send_socket obtained...\n");
   10303     }
   10304 
   10305     /* If the user has requested cpu utilization measurements, we must */
   10306     /* calibrate the cpu(s). We will perform this task within the tests */
   10307     /* themselves. If the user has specified the cpu rate, then */
   10308     /* calibrate_local_cpu will return rather quickly as it will have */
   10309     /* nothing to do. If local_cpu_rate is zero, then we will go through */
   10310     /* all the "normal" calibration stuff and return the rate back.*/
   10311 
   10312     if (local_cpu_usage) {
   10313       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   10314     }
   10315 
   10316     /* Tell the remote end to do a listen. The server alters the socket */
   10317     /* paramters on the other side at this point, hence the reason for */
   10318     /* all the values being passed in the setup message. If the user did */
   10319     /* not specify any of the parameters, they will be passed as 0, which */
   10320     /* will indicate to the remote that no changes beyond the system's */
   10321     /* default should be used. Alignment is the exception, it will */
   10322     /* default to 8, which will be no alignment alterations. */
   10323 
   10324     netperf_request.content.request_type	=	DO_TCP_NBRR;
   10325     tcp_rr_request->recv_buf_size	=	rsr_size_req;
   10326     tcp_rr_request->send_buf_size	=	rss_size_req;
   10327     tcp_rr_request->recv_alignment      =	remote_recv_align;
   10328     tcp_rr_request->recv_offset	        =	remote_recv_offset;
   10329     tcp_rr_request->send_alignment      =	remote_send_align;
   10330     tcp_rr_request->send_offset	        =	remote_send_offset;
   10331     tcp_rr_request->request_size	=	req_size;
   10332     tcp_rr_request->response_size	=	rsp_size;
   10333     tcp_rr_request->no_delay	        =	rem_nodelay;
   10334     tcp_rr_request->measure_cpu	        =	remote_cpu_usage;
   10335     tcp_rr_request->cpu_rate	        =	remote_cpu_rate;
   10336     tcp_rr_request->so_rcvavoid	        =	rem_rcvavoid;
   10337     tcp_rr_request->so_sndavoid	        =	rem_sndavoid;
   10338     if (test_time) {
   10339       tcp_rr_request->test_length	=	test_time;
   10340     }
   10341     else {
   10342       tcp_rr_request->test_length	=	test_trans * -1;
   10343     }
   10344 
   10345     if (debug > 1) {
   10346       fprintf(where,"netperf: send_tcp_nbrr: requesting TCP rr test\n");
   10347     }
   10348 
   10349     send_request();
   10350 
   10351     /* The response from the remote will contain all of the relevant 	*/
   10352     /* socket parameters for this test type. We will put them back into */
   10353     /* the variables here so they can be displayed if desired.  The	*/
   10354     /* remote will have calibrated CPU if necessary, and will have done	*/
   10355     /* all the needed set-up we will have calibrated the cpu locally	*/
   10356     /* before sending the request, and will grab the counter value right*/
   10357     /* after the connect returns. The remote will grab the counter right*/
   10358     /* after the accept call. This saves the hassle of extra messages	*/
   10359     /* being sent for the TCP tests.					*/
   10360 
   10361     recv_response();
   10362 
   10363     if (!netperf_response.content.serv_errno) {
   10364       if (debug)
   10365 	fprintf(where,"remote listen done.\n");
   10366       rsr_size          = tcp_rr_response->recv_buf_size;
   10367       rss_size          = tcp_rr_response->send_buf_size;
   10368       rem_nodelay       = tcp_rr_response->no_delay;
   10369       remote_cpu_usage  = tcp_rr_response->measure_cpu;
   10370       remote_cpu_rate   = tcp_rr_response->cpu_rate;
   10371       /* make sure that port numbers are in network order */
   10372       server.sin_port   = (unsigned short)tcp_rr_response->data_port_number;
   10373       server.sin_port   = htons(server.sin_port);
   10374     }
   10375     else {
   10376       Set_errno(netperf_response.content.serv_errno);
   10377       fprintf(where,
   10378 	      "netperf: remote error %d",
   10379 	      netperf_response.content.serv_errno);
   10380       perror("");
   10381       fflush(where);
   10382       exit(1);
   10383     }
   10384 
   10385     /*Connect up to the remote port on the data socket  */
   10386     if (connect(send_socket,
   10387 		remote_res->ai_addr,
   10388 		remote_res->ai_addrlen) == INVALID_SOCKET){
   10389       perror("netperf: data socket connect failed");
   10390 
   10391       exit(1);
   10392     }
   10393 
   10394     /* now that we are connected, mark the socket as non-blocking */
   10395     if (!set_nonblock(send_socket)) {
   10396       perror("netperf: set_nonblock");
   10397       exit(1);
   10398     }
   10399 
   10400     /* Data Socket set-up is finished. If there were problems, either the */
   10401     /* connect would have failed, or the previous response would have */
   10402     /* indicated a problem. I failed to see the value of the extra */
   10403     /* message after the accept on the remote. If it failed, we'll see it */
   10404     /* here. If it didn't, we might as well start pumping data. */
   10405 
   10406     /* Set-up the test end conditions. For a request/response test, they */
   10407     /* can be either time or transaction based. */
   10408 
   10409     if (test_time) {
   10410       /* The user wanted to end the test after a period of time. */
   10411       times_up = 0;
   10412       trans_remaining = 0;
   10413       start_timer(test_time);
   10414     }
   10415     else {
   10416       /* The tester wanted to send a number of bytes. */
   10417       trans_remaining = test_bytes;
   10418       times_up = 1;
   10419     }
   10420 
   10421     /* The cpu_start routine will grab the current time and possibly */
   10422     /* value of the idle counter for later use in measuring cpu */
   10423     /* utilization and/or service demand and thruput. */
   10424 
   10425     cpu_start(local_cpu_usage);
   10426 
   10427 #ifdef WANT_INTERVALS
   10428     INTERVALS_INIT();
   10429 #endif /* WANT_INTERVALS */
   10430 
   10431     /* We use an "OR" to control test execution. When the test is */
   10432     /* controlled by time, the byte count check will always return false. */
   10433     /* When the test is controlled by byte count, the time test will */
   10434     /* always return false. When the test is finished, the whole */
   10435     /* expression will go false and we will stop sending data. I think I */
   10436     /* just arbitrarily decrement trans_remaining for the timed test, but */
   10437     /* will not do that just yet... One other question is whether or not */
   10438     /* the send buffer and the receive buffer should be the same buffer. */
   10439 
   10440     while ((!times_up) || (trans_remaining > 0)) {
   10441       /* send the request. we assume that if we use a blocking socket, */
   10442       /* the request will be sent at one shot. */
   10443 
   10444 #ifdef WANT_HISTOGRAM
   10445       if (verbosity > 1) {
   10446 	/* timestamp just before our call to send, and then again just */
   10447 	/* after the receive raj 8/94 */
   10448 	HIST_timestamp(&time_one);
   10449       }
   10450 #endif /* WANT_HISTOGRAM */
   10451 
   10452       /* even though this is a non-blocking socket, we will assume for */
   10453       /* the time being that we will be able to send an entire request */
   10454       /* without getting an EAGAIN */
   10455       if((len=send(send_socket,
   10456 		   send_ring->buffer_ptr,
   10457 		   req_size,
   10458 		   0)) != req_size) {
   10459 	if (SOCKET_EINTR(len)) {
   10460 	  /* we hit the end of a */
   10461 	  /* timed test. */
   10462 	  timed_out = 1;
   10463 	  break;
   10464 	}
   10465 	perror("send_tcp_nbrr: data send error");
   10466 	exit(1);
   10467       }
   10468       send_ring = send_ring->next;
   10469 
   10470       /* receive the response. since we are using non-blocking I/O, we */
   10471       /* will "spin" on the recvs */
   10472       rsp_bytes_left = rsp_size;
   10473       temp_message_ptr  = recv_ring->buffer_ptr;
   10474       while(rsp_bytes_left > 0) {
   10475 	if((rsp_bytes_recvd=recv(send_socket,
   10476 				 temp_message_ptr,
   10477 				 rsp_bytes_left,
   10478 				 0)) == SOCKET_ERROR) {
   10479 	  if (SOCKET_EINTR(rsp_bytes_recvd))
   10480 	  {
   10481 	    /* We hit the end of a timed test. */
   10482 	    timed_out = 1;
   10483 	    break;
   10484 	  }
   10485 #ifndef WIN32  // But what does WinNT indicate in this situation...
   10486 	  else if (errno == EAGAIN) {
   10487 	    Set_errno(0);
   10488 	    continue;
   10489 	  }
   10490 #endif
   10491 	  else {
   10492 	    perror("send_tcp_nbrr: data recv error");
   10493 	    exit(1);
   10494 	  }
   10495 	}
   10496 	rsp_bytes_left -= rsp_bytes_recvd;
   10497 	temp_message_ptr  += rsp_bytes_recvd;
   10498       }
   10499       recv_ring = recv_ring->next;
   10500 
   10501       if (timed_out) {
   10502 	/* we may have been in a nested while loop - we need */
   10503 	/* another call to break. */
   10504 	break;
   10505       }
   10506 
   10507 #ifdef WANT_HISTOGRAM
   10508       if (verbosity > 1) {
   10509 	HIST_timestamp(&time_two);
   10510 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   10511       }
   10512 #endif /* WANT_HISTOGRAM */
   10513 #ifdef WANT_INTERVALS
   10514       INTERVALS_WAIT();
   10515 #endif /* WANT_INTERVALS */
   10516 
   10517       nummessages++;
   10518       if (trans_remaining) {
   10519 	trans_remaining--;
   10520       }
   10521 
   10522       if (debug > 3) {
   10523 	if ((nummessages % 100) == 0) {
   10524 	  fprintf(where,
   10525 		  "Transaction %d completed\n",
   10526 		  nummessages);
   10527 	  fflush(where);
   10528 	}
   10529       }
   10530     }
   10531 
   10532     /* At this point we used to call shutdown on the data socket to be */
   10533     /* sure all the data was delivered, but this was not germane in a */
   10534     /* request/response test, and it was causing the tests to "hang" when */
   10535     /* they were being controlled by time. So, I have replaced this */
   10536     /* shutdown call with a call to close that can be found later in the */
   10537     /* procedure. */
   10538 
   10539     /* this call will always give us the elapsed time for the test, and */
   10540     /* will also store-away the necessaries for cpu utilization */
   10541 
   10542     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
   10543 						/* measured? how long */
   10544 						/* did we really run? */
   10545 
   10546     /* Get the statistics from the remote end. The remote will have */
   10547     /* calculated service demand and all those interesting things. If it */
   10548     /* wasn't supposed to care, it will return obvious values. */
   10549 
   10550     recv_response();
   10551     if (!netperf_response.content.serv_errno) {
   10552       if (debug)
   10553 	fprintf(where,"remote results obtained\n");
   10554     }
   10555     else {
   10556       Set_errno(netperf_response.content.serv_errno);
   10557       fprintf(where,
   10558 	      "netperf: remote error %d",
   10559 	      netperf_response.content.serv_errno);
   10560       perror("");
   10561       fflush(where);
   10562 
   10563       exit(1);
   10564     }
   10565 
   10566     /* We now calculate what our thruput was for the test. */
   10567 
   10568     bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
   10569     thruput	= nummessages/elapsed_time;
   10570 
   10571     if (local_cpu_usage || remote_cpu_usage) {
   10572       /* We must now do a little math for service demand and cpu */
   10573       /* utilization for the system(s) */
   10574       /* Of course, some of the information might be bogus because */
   10575       /* there was no idle counter in the kernel(s). We need to make */
   10576       /* a note of this for the user's benefit...*/
   10577       if (local_cpu_usage) {
   10578 	local_cpu_utilization = calc_cpu_util(0.0);
   10579 	/* since calc_service demand is doing ms/Kunit we will */
   10580 	/* multiply the number of transaction by 1024 to get */
   10581 	/* "good" numbers */
   10582 	local_service_demand  = calc_service_demand((double) nummessages*1024,
   10583 						    0.0,
   10584 						    0.0,
   10585 						    0);
   10586       }
   10587       else {
   10588 	local_cpu_utilization	= (float) -1.0;
   10589 	local_service_demand	= (float) -1.0;
   10590       }
   10591 
   10592       if (remote_cpu_usage) {
   10593 	remote_cpu_utilization = tcp_rr_result->cpu_util;
   10594 	/* since calc_service demand is doing ms/Kunit we will */
   10595 	/* multiply the number of transaction by 1024 to get */
   10596 	/* "good" numbers */
   10597 	remote_service_demand = calc_service_demand((double) nummessages*1024,
   10598 						    0.0,
   10599 						    remote_cpu_utilization,
   10600 						    tcp_rr_result->num_cpus);
   10601       }
   10602       else {
   10603 	remote_cpu_utilization = (float) -1.0;
   10604 	remote_service_demand  = (float) -1.0;
   10605       }
   10606 
   10607     }
   10608     else {
   10609       /* we were not measuring cpu, for the confidence stuff, we */
   10610       /* should make it -1.0 */
   10611       local_cpu_utilization	= (float) -1.0;
   10612       local_service_demand	= (float) -1.0;
   10613       remote_cpu_utilization = (float) -1.0;
   10614       remote_service_demand  = (float) -1.0;
   10615     }
   10616 
   10617     /* at this point, we want to calculate the confidence information. */
   10618     /* if debugging is on, calculate_confidence will print-out the */
   10619     /* parameters we pass it */
   10620 
   10621     calculate_confidence(confidence_iteration,
   10622 			 elapsed_time,
   10623 			 thruput,
   10624 			 local_cpu_utilization,
   10625 			 remote_cpu_utilization,
   10626 			 local_service_demand,
   10627 			 remote_service_demand);
   10628 
   10629 
   10630     confidence_iteration++;
   10631 
   10632     /* we are now done with the socket, so close it */
   10633     close(send_socket);
   10634 
   10635   }
   10636 
   10637   retrieve_confident_values(&elapsed_time,
   10638 			    &thruput,
   10639 			    &local_cpu_utilization,
   10640 			    &remote_cpu_utilization,
   10641 			    &local_service_demand,
   10642 			    &remote_service_demand);
   10643 
   10644   /* We are now ready to print all the information. If the user */
   10645   /* has specified zero-level verbosity, we will just print the */
   10646   /* local service demand, or the remote service demand. If the */
   10647   /* user has requested verbosity level 1, he will get the basic */
   10648   /* "streamperf" numbers. If the user has specified a verbosity */
   10649   /* of greater than 1, we will display a veritable plethora of */
   10650   /* background information from outside of this block as it it */
   10651   /* not cpu_measurement specific...  */
   10652 
   10653   if (confidence < 0) {
   10654     /* we did not hit confidence, but were we asked to look for it? */
   10655     if (iteration_max > 1) {
   10656       display_confidence();
   10657     }
   10658   }
   10659 
   10660   if (local_cpu_usage || remote_cpu_usage) {
   10661     local_cpu_method = format_cpu_method(cpu_method);
   10662     remote_cpu_method = format_cpu_method(tcp_rr_result->cpu_method);
   10663 
   10664     switch (verbosity) {
   10665     case 0:
   10666       if (local_cpu_usage) {
   10667 	fprintf(where,
   10668 		cpu_fmt_0,
   10669 		local_service_demand,
   10670 		local_cpu_method);
   10671       }
   10672       else {
   10673 	fprintf(where,
   10674 		cpu_fmt_0,
   10675 		remote_service_demand,
   10676 		remote_cpu_method);
   10677       }
   10678       break;
   10679     case 1:
   10680     case 2:
   10681       if (print_headers) {
   10682 	fprintf(where,
   10683 		cpu_title,
   10684 		local_cpu_method,
   10685 		remote_cpu_method);
   10686       }
   10687 
   10688       fprintf(where,
   10689 	      cpu_fmt_1_line_1,		/* the format string */
   10690 	      lss_size,		/* local sendbuf size */
   10691 	      lsr_size,
   10692 	      req_size,		/* how large were the requests */
   10693 	      rsp_size,		/* guess */
   10694 	      elapsed_time,		/* how long was the test */
   10695 	      thruput,
   10696 	      local_cpu_utilization,	/* local cpu */
   10697 	      remote_cpu_utilization,	/* remote cpu */
   10698 	      local_service_demand,	/* local service demand */
   10699 	      remote_service_demand);	/* remote service demand */
   10700       fprintf(where,
   10701 	      cpu_fmt_1_line_2,
   10702 	      rss_size,
   10703 	      rsr_size);
   10704       break;
   10705     }
   10706   }
   10707   else {
   10708     /* The tester did not wish to measure service demand. */
   10709 
   10710     switch (verbosity) {
   10711     case 0:
   10712       fprintf(where,
   10713 	      tput_fmt_0,
   10714 	      thruput);
   10715       break;
   10716     case 1:
   10717     case 2:
   10718       if (print_headers) {
   10719 	fprintf(where,tput_title,format_units());
   10720       }
   10721 
   10722       fprintf(where,
   10723 	      tput_fmt_1_line_1,	/* the format string */
   10724 	      lss_size,
   10725 	      lsr_size,
   10726 	      req_size,		/* how large were the requests */
   10727 	      rsp_size,		/* how large were the responses */
   10728 	      elapsed_time, 		/* how long did it take */
   10729 	      thruput);
   10730       fprintf(where,
   10731 	      tput_fmt_1_line_2,
   10732 	      rss_size, 		/* remote recvbuf size */
   10733 	      rsr_size);
   10734 
   10735       break;
   10736     }
   10737   }
   10738 
   10739   /* it would be a good thing to include information about some of the */
   10740   /* other parameters that may have been set for this test, but at the */
   10741   /* moment, I do not wish to figure-out all the  formatting, so I will */
   10742   /* just put this comment here to help remind me that it is something */
   10743   /* that should be done at a later time. */
   10744 
   10745   /* how to handle the verbose information in the presence of */
   10746   /* confidence intervals is yet to be determined... raj 11/94 */
   10747   if (verbosity > 1) {
   10748     /* The user wanted to know it all, so we will give it to him. */
   10749     /* This information will include as much as we can find about */
   10750     /* TCP statistics, the alignments of the sends and receives */
   10751     /* and all that sort of rot... */
   10752 
   10753     fprintf(where,
   10754 	    ksink_fmt,
   10755 	    local_send_align,
   10756 	    remote_recv_offset,
   10757 	    local_send_offset,
   10758 	    remote_recv_offset);
   10759 
   10760 #ifdef WANT_HISTOGRAM
   10761     fprintf(where,"\nHistogram of request/response times\n");
   10762     fflush(where);
   10763     HIST_report(time_hist);
   10764 #endif /* WANT_HISTOGRAM */
   10765 
   10766   }
   10767 
   10768 }
   10769 
   10770  /* this routine implements the receive (netserver) side of a TCP_RR */
   10772  /* test */
   10773 void
   10774 recv_tcp_nbrr()
   10775 {
   10776 
   10777   struct ring_elt *send_ring;
   10778   struct ring_elt *recv_ring;
   10779 
   10780   struct	sockaddr_in        myaddr_in,
   10781   peeraddr_in;
   10782   SOCKET	s_listen,s_data;
   10783   netperf_socklen_t 	addrlen;
   10784   char	*temp_message_ptr;
   10785   int	trans_received;
   10786   int	trans_remaining;
   10787   int	bytes_sent;
   10788   int	request_bytes_recvd;
   10789   int	request_bytes_remaining;
   10790   int	timed_out = 0;
   10791   float	elapsed_time;
   10792 
   10793   struct addrinfo *local_res;
   10794   char local_name[BUFSIZ];
   10795   char port_buffer[PORTBUFSIZE];
   10796 
   10797   struct	tcp_rr_request_struct	*tcp_rr_request;
   10798   struct	tcp_rr_response_struct	*tcp_rr_response;
   10799   struct	tcp_rr_results_struct	*tcp_rr_results;
   10800 
   10801   tcp_rr_request =
   10802     (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data;
   10803   tcp_rr_response =
   10804     (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data;
   10805   tcp_rr_results =
   10806     (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data;
   10807 
   10808   if (debug) {
   10809     fprintf(where,"netserver: recv_tcp_nbrr: entered...\n");
   10810     fflush(where);
   10811   }
   10812 
   10813   /* We want to set-up the listen socket with all the desired */
   10814   /* parameters and then let the initiator know that all is ready. If */
   10815   /* socket size defaults are to be used, then the initiator will have */
   10816   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   10817   /* send-back what they are. If that information cannot be determined, */
   10818   /* then we send-back -1's for the sizes. If things go wrong for any */
   10819   /* reason, we will drop back ten yards and punt. */
   10820 
   10821   /* If anything goes wrong, we want the remote to know about it. It */
   10822   /* would be best if the error that the remote reports to the user is */
   10823   /* the actual error we encountered, rather than some bogus unexpected */
   10824   /* response type message. */
   10825 
   10826   if (debug) {
   10827     fprintf(where,"recv_tcp_nbrr: setting the response type...\n");
   10828     fflush(where);
   10829   }
   10830 
   10831   netperf_response.content.response_type = TCP_RR_RESPONSE;
   10832 
   10833   if (debug) {
   10834     fprintf(where,"recv_tcp_nbrr: the response type is set...\n");
   10835     fflush(where);
   10836   }
   10837 
   10838   /* allocate the recv and send rings with the requested alignments */
   10839   /* and offsets. raj 7/94 */
   10840   if (debug) {
   10841     fprintf(where,"recv_tcp_nbrr: requested recv alignment of %d offset %d\n",
   10842 	    tcp_rr_request->recv_alignment,
   10843 	    tcp_rr_request->recv_offset);
   10844     fprintf(where,"recv_tcp_nbrr: requested send alignment of %d offset %d\n",
   10845 	    tcp_rr_request->send_alignment,
   10846 	    tcp_rr_request->send_offset);
   10847     fflush(where);
   10848   }
   10849 
   10850   /* at some point, these need to come to us from the remote system */
   10851   if (send_width == 0) send_width = 1;
   10852   if (recv_width == 0) recv_width = 1;
   10853 
   10854   send_ring = allocate_buffer_ring(send_width,
   10855 				   tcp_rr_request->response_size,
   10856 				   tcp_rr_request->send_alignment,
   10857 				   tcp_rr_request->send_offset);
   10858 
   10859   recv_ring = allocate_buffer_ring(recv_width,
   10860 				   tcp_rr_request->request_size,
   10861 				   tcp_rr_request->recv_alignment,
   10862 				   tcp_rr_request->recv_offset);
   10863 
   10864 
   10865   /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */
   10866   /* can put in OUR values !-) At some point, we may want to nail this */
   10867   /* socket to a particular network-level address, but for now, */
   10868   /* INADDR_ANY should be just fine. */
   10869 
   10870   bzero((char *)&myaddr_in,
   10871 	sizeof(myaddr_in));
   10872   myaddr_in.sin_family      = AF_INET;
   10873   myaddr_in.sin_addr.s_addr = INADDR_ANY;
   10874   myaddr_in.sin_port        = htons((unsigned short)tcp_rr_request->port);
   10875 
   10876   /* Grab a socket to listen on, and then listen on it. */
   10877 
   10878   if (debug) {
   10879     fprintf(where,"recv_tcp_nbrr: grabbing a socket...\n");
   10880     fflush(where);
   10881   }
   10882 
   10883   /* create_data_socket expects to find some things in the global */
   10884   /* variables, so set the globals based on the values in the request. */
   10885   /* once the socket has been created, we will set the response values */
   10886   /* based on the updated value of those globals. raj 7/94 */
   10887   lss_size_req = tcp_rr_request->send_buf_size;
   10888   lsr_size_req = tcp_rr_request->recv_buf_size;
   10889   loc_nodelay = tcp_rr_request->no_delay;
   10890   loc_rcvavoid = tcp_rr_request->so_rcvavoid;
   10891   loc_sndavoid = tcp_rr_request->so_sndavoid;
   10892 
   10893   set_hostname_and_port(local_name,
   10894 			port_buffer,
   10895 			nf_to_af(tcp_rr_request->ipfamily),
   10896 			tcp_rr_request->port);
   10897 
   10898   local_res = complete_addrinfo(local_name,
   10899 				local_name,
   10900 				port_buffer,
   10901 				nf_to_af(tcp_rr_request->ipfamily),
   10902 				SOCK_STREAM,
   10903 				IPPROTO_TCP,
   10904 				0);
   10905 
   10906   s_listen = create_data_socket(local_res);
   10907 
   10908   if (s_listen == INVALID_SOCKET) {
   10909     netperf_response.content.serv_errno = errno;
   10910     send_response();
   10911 
   10912     exit(1);
   10913   }
   10914 
   10915   /* Let's get an address assigned to this socket so we can tell the */
   10916   /* initiator how to reach the data socket. There may be a desire to */
   10917   /* nail this socket to a specific IP address in a multi-homed, */
   10918   /* multi-connection situation, but for now, we'll ignore the issue */
   10919   /* and concentrate on single connection testing. */
   10920 
   10921   if (bind(s_listen,
   10922 	   (struct sockaddr *)&myaddr_in,
   10923 	   sizeof(myaddr_in)) == SOCKET_ERROR) {
   10924     netperf_response.content.serv_errno = errno;
   10925     close(s_listen);
   10926     send_response();
   10927 
   10928     exit(1);
   10929   }
   10930 
   10931   /* Now, let's set-up the socket to listen for connections */
   10932   if (listen(s_listen, 5) == SOCKET_ERROR) {
   10933     netperf_response.content.serv_errno = errno;
   10934     close(s_listen);
   10935     send_response();
   10936 
   10937     exit(1);
   10938   }
   10939 
   10940 
   10941   /* now get the port number assigned by the system  */
   10942   addrlen = sizeof(myaddr_in);
   10943   if (getsockname(s_listen,
   10944 		  (struct sockaddr *)&myaddr_in, &addrlen) == SOCKET_ERROR){
   10945     netperf_response.content.serv_errno = errno;
   10946     close(s_listen);
   10947     send_response();
   10948 
   10949     exit(1);
   10950   }
   10951 
   10952   /* Now myaddr_in contains the port and the internet address this is */
   10953   /* returned to the sender also implicitly telling the sender that the */
   10954   /* socket buffer sizing has been done. */
   10955 
   10956   tcp_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port);
   10957   netperf_response.content.serv_errno   = 0;
   10958 
   10959   /* But wait, there's more. If the initiator wanted cpu measurements, */
   10960   /* then we must call the calibrate routine, which will return the max */
   10961   /* rate back to the initiator. If the CPU was not to be measured, or */
   10962   /* something went wrong with the calibration, we will return a 0.0 to */
   10963   /* the initiator. */
   10964 
   10965   tcp_rr_response->cpu_rate = 0.0; 	/* assume no cpu */
   10966   tcp_rr_response->measure_cpu = 0;
   10967 
   10968   if (tcp_rr_request->measure_cpu) {
   10969     tcp_rr_response->measure_cpu = 1;
   10970     tcp_rr_response->cpu_rate = calibrate_local_cpu(tcp_rr_request->cpu_rate);
   10971   }
   10972 
   10973 
   10974   /* before we send the response back to the initiator, pull some of */
   10975   /* the socket parms from the globals */
   10976   tcp_rr_response->send_buf_size = lss_size;
   10977   tcp_rr_response->recv_buf_size = lsr_size;
   10978   tcp_rr_response->no_delay = loc_nodelay;
   10979   tcp_rr_response->so_rcvavoid = loc_rcvavoid;
   10980   tcp_rr_response->so_sndavoid = loc_sndavoid;
   10981   tcp_rr_response->test_length = tcp_rr_request->test_length;
   10982   send_response();
   10983 
   10984   addrlen = sizeof(peeraddr_in);
   10985 
   10986   if ((s_data = accept(s_listen,
   10987 		       (struct sockaddr *)&peeraddr_in,
   10988 		       &addrlen)) == INVALID_SOCKET) {
   10989     /* Let's just punt. The remote will be given some information */
   10990     close(s_listen);
   10991     exit(1);
   10992   }
   10993 
   10994   if (debug) {
   10995     fprintf(where,"recv_tcp_nbrr: accept completes on the data connection.\n");
   10996     fflush(where);
   10997   }
   10998 
   10999 #ifdef KLUDGE_SOCKET_OPTIONS
   11000   /* this is for those systems which *INCORRECTLY* fail to pass */
   11001   /* attributes across an accept() call. Including this goes against */
   11002   /* my better judgement :( raj 11/95 */
   11003 
   11004   kludge_socket_options(s_data);
   11005 
   11006 #endif /* KLUDGE_SOCKET_OPTIONS */
   11007 
   11008   /* now that we are connected, mark the socket as non-blocking */
   11009   if (!set_nonblock(s_data)) {
   11010     close(s_data);
   11011     exit(1);
   11012   }
   11013 
   11014 
   11015   /* Now it's time to start receiving data on the connection. We will */
   11016   /* first grab the apropriate counters and then start grabbing. */
   11017 
   11018   cpu_start(tcp_rr_request->measure_cpu);
   11019 
   11020 #ifdef WIN32
   11021   /* this is used so the timer thread can close the socket out from */
   11022   /* under us, which to date is the easiest/cleanest/least */
   11023   /* Windows-specific way I can find to force the winsock calls to */
   11024   /* return WSAEINTR with the test is over. anything that will run on */
   11025   /* 95 and NT and is closer to what netperf expects from Unix signals */
   11026   /* and such would be appreciated raj 1/96 */
   11027   win_kludge_socket = s_data;
   11028 #endif /* WIN32 */
   11029 
   11030   /* The loop will exit when the sender does a shutdown, which will */
   11031   /* return a length of zero   */
   11032 
   11033   if (tcp_rr_request->test_length > 0) {
   11034     times_up = 0;
   11035     trans_remaining = 0;
   11036     start_timer(tcp_rr_request->test_length + PAD_TIME);
   11037   }
   11038   else {
   11039     times_up = 1;
   11040     trans_remaining = tcp_rr_request->test_length * -1;
   11041   }
   11042 
   11043   trans_received = 0;
   11044 
   11045   while ((!times_up) || (trans_remaining > 0)) {
   11046     temp_message_ptr = recv_ring->buffer_ptr;
   11047     request_bytes_remaining	= tcp_rr_request->request_size;
   11048     while(request_bytes_remaining > 0) {
   11049       if((request_bytes_recvd=recv(s_data,
   11050 				   temp_message_ptr,
   11051 				   request_bytes_remaining,
   11052 				   0)) == SOCKET_ERROR) {
   11053 	    if ( SOCKET_EINTR(request_bytes_recvd))
   11054 		{
   11055 	      /* the timer popped */
   11056 	      timed_out = 1;
   11057 	      break;
   11058 		}
   11059 #ifndef WIN32  // But what does WinNT indicate in this situation...
   11060 	    else if (errno == EAGAIN) {
   11061 	      Set_errno(0);
   11062 	      if (times_up) {
   11063 	        timed_out = 1;
   11064 	        break;
   11065 		  }
   11066 	      continue;
   11067 		}
   11068 #endif
   11069 	    else {
   11070 	      netperf_response.content.serv_errno = errno;
   11071 	      send_response();
   11072 	      exit(1);
   11073 		}
   11074       }
   11075       else {
   11076 	request_bytes_remaining -= request_bytes_recvd;
   11077 	temp_message_ptr  += request_bytes_recvd;
   11078       }
   11079     }
   11080 
   11081     recv_ring = recv_ring->next;
   11082 
   11083     if (timed_out) {
   11084       /* we hit the end of the test based on time - lets */
   11085       /* bail out of here now... */
   11086       fprintf(where,"yo5\n");
   11087       fflush(where);
   11088       break;
   11089     }
   11090 
   11091     /* Now, send the response to the remote */
   11092     if((bytes_sent=send(s_data,
   11093 			send_ring->buffer_ptr,
   11094 			tcp_rr_request->response_size,
   11095 			0)) == SOCKET_ERROR) {
   11096       if (SOCKET_EINTR(bytes_sent)) {
   11097 	/* the test timer has popped */
   11098 	timed_out = 1;
   11099 	fprintf(where,"yo6\n");
   11100 	fflush(where);
   11101 	break;
   11102       }
   11103       netperf_response.content.serv_errno = 992;
   11104       send_response();
   11105       exit(1);
   11106     }
   11107 
   11108     send_ring = send_ring->next;
   11109 
   11110     trans_received++;
   11111     if (trans_remaining) {
   11112       trans_remaining--;
   11113     }
   11114   }
   11115 
   11116 
   11117   /* The loop now exits due to timeout or transaction count being */
   11118   /* reached */
   11119 
   11120   cpu_stop(tcp_rr_request->measure_cpu,&elapsed_time);
   11121 
   11122   stop_timer();
   11123 
   11124   if (timed_out) {
   11125     /* we ended the test by time, which was at least 2 seconds */
   11126     /* longer than we wanted to run. so, we want to subtract */
   11127     /* PAD_TIME from the elapsed_time. */
   11128     elapsed_time -= PAD_TIME;
   11129   }
   11130 
   11131   /* send the results to the sender			*/
   11132 
   11133   if (debug) {
   11134     fprintf(where,
   11135 	    "recv_tcp_nbrr: got %d transactions\n",
   11136 	    trans_received);
   11137     fflush(where);
   11138   }
   11139 
   11140   tcp_rr_results->bytes_received = (trans_received *
   11141 				    (tcp_rr_request->request_size +
   11142 				     tcp_rr_request->response_size));
   11143   tcp_rr_results->trans_received = trans_received;
   11144   tcp_rr_results->elapsed_time   = elapsed_time;
   11145   tcp_rr_results->cpu_method     = cpu_method;
   11146   tcp_rr_results->num_cpus       = lib_num_loc_cpus;
   11147   if (tcp_rr_request->measure_cpu) {
   11148     tcp_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
   11149   }
   11150 
   11151   if (debug) {
   11152     fprintf(where,
   11153 	    "recv_tcp_nbrr: test complete, sending results.\n");
   11154     fflush(where);
   11155   }
   11156 
   11157   /* we are done with the socket, free it */
   11158   close(s_data);
   11159 
   11160   send_response();
   11161 
   11162 }
   11163 
   11164 #endif /* DO_NBRR */
   11165 
   11166 
   11168  /* this test is intended to test the performance of establishing a */
   11169  /* connection, and then closing it again. this test is of somewhat */
   11170  /* arcane interest since no packets are exchanged between the */
   11171  /* user-space processes, but it will show the raw overhead of */
   11172  /* establishing a TCP connection. that service demand could then be */
   11173  /* compared with the sum of the service demands of a TCP_CRR and */
   11174  /* TCP_RR test - presumeably, they would all relate */
   11175 
   11176 void
   11177 send_tcp_cc(char remote_host[])
   11178 {
   11179 
   11180   char *tput_title = "\
   11181 Local /Remote\n\
   11182 Socket Size   Request  Resp.   Elapsed  Trans.\n\
   11183 Send   Recv   Size     Size    Time     Rate         \n\
   11184 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
   11185 
   11186   char *tput_fmt_0 =
   11187     "%7.2f\n";
   11188 
   11189   char *tput_fmt_1_line_1 = "\
   11190 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
   11191   char *tput_fmt_1_line_2 = "\
   11192 %-6d %-6d\n";
   11193 
   11194   char *cpu_title = "\
   11195 Local /Remote\n\
   11196 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
   11197 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
   11198 bytes  bytes  bytes   bytes  secs.   per sec  %%      %%      us/Tr   us/Tr\n\n";
   11199 
   11200   char *cpu_fmt_0 =
   11201     "%6.3f\n";
   11202 
   11203   char *cpu_fmt_1_line_1 = "\
   11204 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f\n";
   11205 
   11206   char *cpu_fmt_1_line_2 = "\
   11207 %-6d %-6d\n";
   11208 
   11209   char *ksink_fmt = "\n\
   11210 Alignment      Offset\n\
   11211 Local  Remote  Local  Remote\n\
   11212 Send   Recv    Send   Recv\n\
   11213 %5d  %5d   %5d  %5d\n";
   11214 
   11215 
   11216   int			timed_out = 0;
   11217   float			elapsed_time;
   11218 
   11219   char	temp_message_ptr[1];
   11220   int	nummessages;
   11221   SOCKET	send_socket;
   11222   int	trans_remaining;
   11223   double	bytes_xferd;
   11224   int	rsp_bytes_left = 1;
   11225   int	rsp_bytes_recvd;
   11226 
   11227   float	local_cpu_utilization;
   11228   float	local_service_demand;
   11229   float	remote_cpu_utilization;
   11230   float	remote_service_demand;
   11231   double	thruput;
   11232 
   11233   struct addrinfo *local_res;
   11234   struct addrinfo *remote_res;
   11235 
   11236   int                           myport;
   11237   int                           ret;
   11238 
   11239   struct	tcp_cc_request_struct	*tcp_cc_request;
   11240   struct	tcp_cc_response_struct	*tcp_cc_response;
   11241   struct	tcp_cc_results_struct	*tcp_cc_result;
   11242 
   11243   tcp_cc_request =
   11244     (struct tcp_cc_request_struct *)netperf_request.content.test_specific_data;
   11245   tcp_cc_response =
   11246     (struct tcp_cc_response_struct *)netperf_response.content.test_specific_data;
   11247   tcp_cc_result =
   11248     (struct tcp_cc_results_struct *)netperf_response.content.test_specific_data;
   11249 
   11250 
   11251 #ifdef WANT_HISTOGRAM
   11252   if (verbosity > 1) {
   11253     time_hist = HIST_new();
   11254   }
   11255 #endif /* WANT_HISTOGRAM */
   11256 
   11257   /* since we are now disconnected from the code that established the */
   11258   /* control socket, and since we want to be able to use different */
   11259   /* protocols and such, we are passed the name of the remote host and */
   11260   /* must turn that into the test specific addressing information. */
   11261 
   11262   complete_addrinfos(&remote_res,
   11263 		     &local_res,
   11264 		     remote_host,
   11265 		     SOCK_STREAM,
   11266 		     IPPROTO_TCP,
   11267 		     0);
   11268 
   11269   if ( print_headers ) {
   11270     print_top_test_header("TCP Connect/Close TEST",local_res,remote_res);
   11271   }
   11272 
   11273   /* initialize a few counters */
   11274 
   11275   nummessages	=	0;
   11276   bytes_xferd	=	0.0;
   11277   times_up 	= 	0;
   11278 
   11279   /* since there are no data buffers in this test, we need no send or */
   11280   /* recv rings */
   11281 
   11282   if (debug) {
   11283     fprintf(where,"send_tcp_cc: send_socket obtained...\n");
   11284   }
   11285 
   11286   /* If the user has requested cpu utilization measurements, we must */
   11287   /* calibrate the cpu(s). We will perform this task within the tests */
   11288   /* themselves. If the user has specified the cpu rate, then */
   11289   /* calibrate_local_cpu will return rather quickly as it will have */
   11290   /* nothing to do. If local_cpu_rate is zero, then we will go through */
   11291   /* all the "normal" calibration stuff and return the rate back.*/
   11292 
   11293   if (local_cpu_usage) {
   11294     local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   11295   }
   11296 
   11297   /* Tell the remote end to do a listen. The server alters the socket */
   11298   /* paramters on the other side at this point, hence the reason for */
   11299   /* all the values being passed in the setup message. If the user did */
   11300   /* not specify any of the parameters, they will be passed as 0, which */
   11301   /* will indicate to the remote that no changes beyond the system's */
   11302   /* default should be used. Alignment is the exception, it will */
   11303   /* default to 8, which will be no alignment alterations. */
   11304 
   11305   netperf_request.content.request_type	=	DO_TCP_CC;
   11306   tcp_cc_request->recv_buf_size	        =	rsr_size_req;
   11307   tcp_cc_request->send_buf_size	        =	rss_size_req;
   11308   tcp_cc_request->recv_alignment	=	remote_recv_align;
   11309   tcp_cc_request->recv_offset	        =	remote_recv_offset;
   11310   tcp_cc_request->send_alignment	=	remote_send_align;
   11311   tcp_cc_request->send_offset	        =	remote_send_offset;
   11312   tcp_cc_request->request_size	        =	req_size;
   11313   tcp_cc_request->response_size	        =	rsp_size;
   11314   tcp_cc_request->no_delay	        =	rem_nodelay;
   11315   tcp_cc_request->measure_cpu	        =	remote_cpu_usage;
   11316   tcp_cc_request->cpu_rate	        =	remote_cpu_rate;
   11317   tcp_cc_request->so_rcvavoid	=	rem_rcvavoid;
   11318   tcp_cc_request->so_sndavoid	=	rem_sndavoid;
   11319   if (test_time) {
   11320     tcp_cc_request->test_length	=	test_time;
   11321   }
   11322   else {
   11323     tcp_cc_request->test_length	=	test_trans * -1;
   11324   }
   11325   tcp_cc_request->port          = atoi(remote_data_port);
   11326   tcp_cc_request->ipfamily  = af_to_nf(remote_res->ai_family);
   11327 
   11328   if (debug > 1) {
   11329     fprintf(where,"netperf: send_tcp_cc: requesting TCP crr test\n");
   11330   }
   11331 
   11332   send_request();
   11333 
   11334   /* The response from the remote will contain all of the relevant 	*/
   11335   /* socket parameters for this test type. We will put them back into 	*/
   11336   /* the variables here so they can be displayed if desired.  The	*/
   11337   /* remote will have calibrated CPU if necessary, and will have done	*/
   11338   /* all the needed set-up we will have calibrated the cpu locally	*/
   11339   /* before sending the request, and will grab the counter value right	*/
   11340   /* after the connect returns. The remote will grab the counter right	*/
   11341   /* after the accept call. This saves the hassle of extra messages	*/
   11342   /* being sent for the TCP tests.					*/
   11343 
   11344   recv_response();
   11345 
   11346   if (!netperf_response.content.serv_errno) {
   11347     rsr_size	=	tcp_cc_response->recv_buf_size;
   11348     rss_size	=	tcp_cc_response->send_buf_size;
   11349     rem_nodelay	=	tcp_cc_response->no_delay;
   11350     remote_cpu_usage=	tcp_cc_response->measure_cpu;
   11351     remote_cpu_rate = 	tcp_cc_response->cpu_rate;
   11352     /* make sure that port numbers are in network order */
   11353     set_port_number(remote_res,(unsigned short)tcp_cc_response->data_port_number);
   11354 
   11355     if (debug) {
   11356       fprintf(where,"remote listen done.\n");
   11357       fprintf(where,"remote port is %d\n",get_port_number(remote_res));
   11358       fflush(where);
   11359     }
   11360   }
   11361   else {
   11362     Set_errno(netperf_response.content.serv_errno);
   11363     fprintf(where,
   11364 	    "netperf: remote error %d",
   11365 	    netperf_response.content.serv_errno);
   11366     perror("");
   11367     fflush(where);
   11368     exit(1);
   11369   }
   11370 
   11371 #ifdef WANT_DEMO
   11372   DEMO_RR_SETUP(100)
   11373 #endif
   11374 
   11375   /* pick a nice random spot between client_port_min and */
   11376   /* client_port_max for our initial port number */
   11377   srand(getpid());
   11378   if (client_port_max - client_port_min) {
   11379     myport = client_port_min +
   11380       (rand() % (client_port_max - client_port_min));
   11381   }
   11382   else {
   11383     myport = client_port_min;
   11384   }
   11385   /* there will be a ++ before the first call to bind, so subtract one */
   11386   myport--;
   11387 
   11388   /* Set-up the test end conditions. For a request/response test, they */
   11389   /* can be either time or transaction based. */
   11390 
   11391   if (test_time) {
   11392     /* The user wanted to end the test after a period of time. */
   11393     times_up = 0;
   11394     trans_remaining = 0;
   11395     start_timer(test_time);
   11396   }
   11397   else {
   11398     /* The tester wanted to send a number of bytes. */
   11399     trans_remaining = test_bytes;
   11400     times_up = 1;
   11401   }
   11402 
   11403   /* The cpu_start routine will grab the current time and possibly */
   11404   /* value of the idle counter for later use in measuring cpu */
   11405   /* utilization and/or service demand and thruput. */
   11406 
   11407   cpu_start(local_cpu_usage);
   11408 
   11409 #ifdef WANT_DEMO
   11410   if (demo_mode) {
   11411     HIST_timestamp(demo_one_ptr);
   11412   }
   11413 #endif
   11414 
   11415   /* We use an "OR" to control test execution. When the test is */
   11416   /* controlled by time, the byte count check will always return false. */
   11417   /* When the test is controlled by byte count, the time test will */
   11418   /* always return false. When the test is finished, the whole */
   11419   /* expression will go false and we will stop sending data. I think I */
   11420   /* just arbitrarily decrement trans_remaining for the timed test, but */
   11421   /* will not do that just yet... One other question is whether or not */
   11422   /* the send buffer and the receive buffer should be the same buffer. */
   11423 
   11424   while ((!times_up) || (trans_remaining > 0)) {
   11425 
   11426 #ifdef WANT_HISTOGRAM
   11427     if (verbosity > 1) {
   11428       /* timestamp just before our call to create the socket, and then */
   11429       /* again just after the receive raj 3/95 */
   11430       HIST_timestamp(&time_one);
   11431     }
   11432 #endif /* WANT_HISTOGRAM */
   11433 
   11434     /* set up the data socket */
   11435     /* newport: is this label really required any longer? */
   11436     /* pick a new port number */
   11437     myport++;
   11438 
   11439     /* wrap the port number when we get to client_port_max. NOTE, some */
   11440     /* broken TCP's might treat the port number as a signed 16 bit */
   11441     /* quantity.  we aren't interested in testing such broken */
   11442     /* implementations :) so we won't make sure that it is below 32767 */
   11443     /* raj 8/94  */
   11444     if (myport >= client_port_max) {
   11445       myport = client_port_min;
   11446     }
   11447 
   11448     /* we do not want to use the port number that the server is */
   11449     /* sitting at - this would cause us to fail in a loopback test. we */
   11450     /* could just rely on the failure of the bind to get us past this, */
   11451     /* but I'm guessing that in this one case at least, it is much */
   11452     /* faster, given that we *know* that port number is already in use */
   11453     /* (or rather would be in a loopback test) */
   11454 
   11455     if (myport == get_port_number(remote_res)) myport++;
   11456 
   11457     if (debug) {
   11458       if ((nummessages % 100) == 0) {
   11459 	printf("port %d\n",myport);
   11460       }
   11461     }
   11462     set_port_number(local_res, (unsigned short)myport);
   11463     send_socket = create_data_socket(local_res);
   11464 
   11465     if (send_socket == INVALID_SOCKET) {
   11466       perror("netperf: send_tcp_cc: tcp stream data socket");
   11467       exit(1);
   11468     }
   11469 
   11470     /* we used to have a call to bind() here, but that is being
   11471        taken care of by create_data_socket(). raj 2005-02-08 */
   11472 
   11473     /* Connect up to the remote port on the data socket  */
   11474     if ((ret = connect(send_socket,
   11475 		       remote_res->ai_addr,
   11476 		       remote_res->ai_addrlen)) == INVALID_SOCKET){
   11477       if (SOCKET_EINTR(ret))
   11478 	  {
   11479 	    /* we hit the end of a */
   11480 	    /* timed test. */
   11481 	    timed_out = 1;
   11482 	    break;
   11483       }
   11484       perror("netperf: data socket connect failed");
   11485       printf("\tattempted to connect on socket %d to port %d",
   11486 	     send_socket,
   11487 	     get_port_number(remote_res));
   11488       printf(" from port %u \n",get_port_number(local_res));
   11489       exit(1);
   11490     }
   11491 
   11492     /* we hang in a recv() to get the remote's close indication */
   11493 
   11494     rsp_bytes_recvd=recv(send_socket,
   11495 			 temp_message_ptr,
   11496 			 rsp_bytes_left,
   11497 			 0);
   11498 
   11499 
   11500     if (rsp_bytes_recvd == 0) {
   11501       /* connection close, call close. we assume that the requisite */
   11502       /* number of bytes have been received */
   11503 
   11504 #ifdef WANT_HISTOGRAM
   11505       if (verbosity > 1) {
   11506 	HIST_timestamp(&time_two);
   11507 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   11508       }
   11509 #endif /* WANT_HISTOGRAM */
   11510 
   11511 #ifdef WANT_DEMO
   11512       DEMO_RR_INTERVAL(1)
   11513 #endif
   11514 
   11515       nummessages++;
   11516       if (trans_remaining) {
   11517 	trans_remaining--;
   11518       }
   11519 
   11520       if (debug > 3) {
   11521 	fprintf(where,
   11522 		"Transaction %d completed on local port %u\n",
   11523 		nummessages,
   11524 		get_port_number(local_res));
   11525 	fflush(where);
   11526       }
   11527 
   11528       close(send_socket);
   11529 
   11530     }
   11531     else {
   11532       /* it was less than zero - an error occured */
   11533       if (SOCKET_EINTR(rsp_bytes_recvd))
   11534 	  {
   11535 	    /* We hit the end of a timed test. */
   11536 	    timed_out = 1;
   11537 	    break;
   11538 	  }
   11539 	  perror("send_tcp_cc: data recv error");
   11540 	  exit(1);
   11541     }
   11542 
   11543   }
   11544 
   11545 
   11546   /* this call will always give us the elapsed time for the test, and */
   11547   /* will also store-away the necessaries for cpu utilization */
   11548 
   11549   cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being measured? */
   11550   /* how long did we really run? */
   11551 
   11552   /* Get the statistics from the remote end. The remote will have */
   11553   /* calculated service demand and all those interesting things. If it */
   11554   /* wasn't supposed to care, it will return obvious values. */
   11555 
   11556   recv_response();
   11557   if (!netperf_response.content.serv_errno) {
   11558     if (debug)
   11559       fprintf(where,"remote results obtained\n");
   11560   }
   11561   else {
   11562     Set_errno(netperf_response.content.serv_errno);
   11563     fprintf(where,
   11564 	    "netperf: remote error %d",
   11565 	     netperf_response.content.serv_errno);
   11566     perror("");
   11567     fflush(where);
   11568 
   11569     exit(1);
   11570   }
   11571 
   11572   /* We now calculate what our thruput was for the test. In the future, */
   11573   /* we may want to include a calculation of the thruput measured by */
   11574   /* the remote, but it should be the case that for a TCP stream test, */
   11575   /* that the two numbers should be *very* close... We calculate */
   11576   /* bytes_sent regardless of the way the test length was controlled. */
   11577   /* If it was time, we needed to, and if it was by bytes, the user may */
   11578   /* have specified a number of bytes that wasn't a multiple of the */
   11579   /* send_size, so we really didn't send what he asked for ;-) We use */
   11580   /* Kbytes/s as the units of thruput for a TCP stream test, where K = */
   11581   /* 1024. A future enhancement *might* be to choose from a couple of */
   11582   /* unit selections. */
   11583 
   11584   bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
   11585   thruput	= calc_thruput(bytes_xferd);
   11586 
   11587   if (local_cpu_usage || remote_cpu_usage) {
   11588     /* We must now do a little math for service demand and cpu */
   11589     /* utilization for the system(s) */
   11590     /* Of course, some of the information might be bogus because */
   11591     /* there was no idle counter in the kernel(s). We need to make */
   11592     /* a note of this for the user's benefit...*/
   11593     if (local_cpu_usage) {
   11594       if (local_cpu_rate == 0.0) {
   11595 	fprintf(where,"WARNING WARNING WARNING  WARNING WARNING WARNING  WARNING!\n");
   11596 	fprintf(where,"Local CPU usage numbers based on process information only!\n");
   11597 	fflush(where);
   11598       }
   11599       local_cpu_utilization = calc_cpu_util(0.0);
   11600       /* since calc_service demand is doing ms/Kunit we will */
   11601       /* multiply the number of transaction by 1024 to get */
   11602       /* "good" numbers */
   11603       local_service_demand  = calc_service_demand((double) nummessages*1024,
   11604 						  0.0,
   11605 						  0.0,
   11606 						  0);
   11607     }
   11608     else {
   11609       local_cpu_utilization	= (float) -1.0;
   11610       local_service_demand	= (float) -1.0;
   11611     }
   11612 
   11613     if (remote_cpu_usage) {
   11614       if (remote_cpu_rate == 0.0) {
   11615 	fprintf(where,"DANGER  DANGER  DANGER    DANGER  DANGER  DANGER    DANGER!\n");
   11616 	fprintf(where,"Remote CPU usage numbers based on process information only!\n");
   11617 	fflush(where);
   11618       }
   11619       remote_cpu_utilization = tcp_cc_result->cpu_util;
   11620       /* since calc_service demand is doing ms/Kunit we will */
   11621       /* multiply the number of transaction by 1024 to get */
   11622       /* "good" numbers */
   11623       remote_service_demand = calc_service_demand((double) nummessages*1024,
   11624 						  0.0,
   11625 						  remote_cpu_utilization,
   11626 						  tcp_cc_result->num_cpus);
   11627     }
   11628     else {
   11629       remote_cpu_utilization = (float) -1.0;
   11630       remote_service_demand  = (float) -1.0;
   11631     }
   11632 
   11633     /* We are now ready to print all the information. If the user */
   11634     /* has specified zero-level verbosity, we will just print the */
   11635     /* local service demand, or the remote service demand. If the */
   11636     /* user has requested verbosity level 1, he will get the basic */
   11637     /* "streamperf" numbers. If the user has specified a verbosity */
   11638     /* of greater than 1, we will display a veritable plethora of */
   11639     /* background information from outside of this block as it it */
   11640     /* not cpu_measurement specific...  */
   11641 
   11642     switch (verbosity) {
   11643     case 0:
   11644       if (local_cpu_usage) {
   11645 	fprintf(where,
   11646 		cpu_fmt_0,
   11647 		local_service_demand);
   11648       }
   11649       else {
   11650 	fprintf(where,
   11651 		cpu_fmt_0,
   11652 		remote_service_demand);
   11653       }
   11654       break;
   11655     case 1:
   11656     case 2:
   11657 
   11658       if (print_headers) {
   11659 	fprintf(where,
   11660 		cpu_title,
   11661 		local_cpu_method,
   11662 		remote_cpu_method);
   11663       }
   11664 
   11665       fprintf(where,
   11666 	      cpu_fmt_1_line_1,		/* the format string */
   11667 	      lss_size,		/* local sendbuf size */
   11668 	      lsr_size,
   11669 	      req_size,		/* how large were the requests */
   11670 	      rsp_size,		/* guess */
   11671 	      elapsed_time,		/* how long was the test */
   11672 	      nummessages/elapsed_time,
   11673 	      local_cpu_utilization,	/* local cpu */
   11674 	      remote_cpu_utilization,	/* remote cpu */
   11675 	      local_service_demand,	/* local service demand */
   11676 	      remote_service_demand);	/* remote service demand */
   11677       fprintf(where,
   11678 	      cpu_fmt_1_line_2,
   11679 	      rss_size,
   11680 	      rsr_size);
   11681       break;
   11682     }
   11683   }
   11684   else {
   11685     /* The tester did not wish to measure service demand. */
   11686     switch (verbosity) {
   11687     case 0:
   11688       fprintf(where,
   11689 	      tput_fmt_0,
   11690 	      nummessages/elapsed_time);
   11691       break;
   11692     case 1:
   11693     case 2:
   11694       if (print_headers) {
   11695 	fprintf(where,tput_title,format_units());
   11696       }
   11697 
   11698       fprintf(where,
   11699 	      tput_fmt_1_line_1,	/* the format string */
   11700 	      lss_size,
   11701 	      lsr_size,
   11702 	      req_size,		/* how large were the requests */
   11703 	      rsp_size,		/* how large were the responses */
   11704 	      elapsed_time, 		/* how long did it take */
   11705 	      nummessages/elapsed_time);
   11706       fprintf(where,
   11707 	      tput_fmt_1_line_2,
   11708 	      rss_size, 		/* remote recvbuf size */
   11709 	      rsr_size);
   11710 
   11711       break;
   11712     }
   11713   }
   11714 
   11715   /* it would be a good thing to include information about some of the */
   11716   /* other parameters that may have been set for this test, but at the */
   11717   /* moment, I do not wish to figure-out all the  formatting, so I will */
   11718   /* just put this comment here to help remind me that it is something */
   11719   /* that should be done at a later time. */
   11720 
   11721   if (verbosity > 1) {
   11722     /* The user wanted to know it all, so we will give it to him. */
   11723     /* This information will include as much as we can find about */
   11724     /* TCP statistics, the alignments of the sends and receives */
   11725     /* and all that sort of rot... */
   11726 
   11727     fprintf(where,
   11728 	    ksink_fmt,
   11729 	    local_send_align,
   11730 	    remote_recv_offset,
   11731 	    local_send_offset,
   11732 	    remote_recv_offset);
   11733 
   11734 #ifdef WANT_HISTOGRAM
   11735     fprintf(where,"\nHistogram of request/response times\n");
   11736     fflush(where);
   11737     HIST_report(time_hist);
   11738 #endif /* WANT_HISTOGRAM */
   11739 
   11740   }
   11741 
   11742 }
   11743 
   11744 
   11745 void
   11747 recv_tcp_cc()
   11748 {
   11749 
   11750   char  *message;
   11751 
   11752   struct addrinfo *local_res;
   11753   char local_name[BUFSIZ];
   11754   char port_buffer[PORTBUFSIZE];
   11755 
   11756   struct	sockaddr_storage        myaddr_in,  peeraddr_in;
   11757   SOCKET	s_listen,s_data;
   11758   netperf_socklen_t 	addrlen;
   11759   char	*recv_message_ptr;
   11760   char	*send_message_ptr;
   11761   int	trans_received;
   11762   int	trans_remaining;
   11763   int	timed_out = 0;
   11764   float	elapsed_time;
   11765 
   11766   struct	tcp_cc_request_struct	*tcp_cc_request;
   11767   struct	tcp_cc_response_struct	*tcp_cc_response;
   11768   struct	tcp_cc_results_struct	*tcp_cc_results;
   11769 
   11770   tcp_cc_request =
   11771     (struct tcp_cc_request_struct *)netperf_request.content.test_specific_data;
   11772   tcp_cc_response =
   11773     (struct tcp_cc_response_struct *)netperf_response.content.test_specific_data;
   11774   tcp_cc_results =
   11775     (struct tcp_cc_results_struct *)netperf_response.content.test_specific_data;
   11776 
   11777   if (debug) {
   11778     fprintf(where,"netserver: recv_tcp_cc: entered...\n");
   11779     fflush(where);
   11780   }
   11781 
   11782   /* We want to set-up the listen socket with all the desired */
   11783   /* parameters and then let the initiator know that all is ready. If */
   11784   /* socket size defaults are to be used, then the initiator will have */
   11785   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   11786   /* send-back what they are. If that information cannot be determined, */
   11787   /* then we send-back -1's for the sizes. If things go wrong for any */
   11788   /* reason, we will drop back ten yards and punt. */
   11789 
   11790   /* If anything goes wrong, we want the remote to know about it. It */
   11791   /* would be best if the error that the remote reports to the user is */
   11792   /* the actual error we encountered, rather than some bogus unexpected */
   11793   /* response type message. */
   11794 
   11795   if (debug) {
   11796     fprintf(where,"recv_tcp_cc: setting the response type...\n");
   11797     fflush(where);
   11798   }
   11799 
   11800   netperf_response.content.response_type = TCP_CC_RESPONSE;
   11801 
   11802   if (debug) {
   11803     fprintf(where,"recv_tcp_cc: the response type is set...\n");
   11804     fflush(where);
   11805   }
   11806 
   11807   /* set-up the data buffer with the requested alignment and offset */
   11808   message = (char *)malloc(DATABUFFERLEN);
   11809   if (message == NULL) {
   11810     printf("malloc(%d) failed!\n", DATABUFFERLEN);
   11811     exit(1);
   11812   }
   11813 
   11814   /* We now alter the message_ptr variables to be at the desired */
   11815   /* alignments with the desired offsets. */
   11816 
   11817   if (debug) {
   11818     fprintf(where,
   11819 	    "recv_tcp_cc: requested recv alignment of %d offset %d\n",
   11820 	    tcp_cc_request->recv_alignment,
   11821 	    tcp_cc_request->recv_offset);
   11822     fprintf(where,
   11823 	    "recv_tcp_cc: requested send alignment of %d offset %d\n",
   11824 	    tcp_cc_request->send_alignment,
   11825 	    tcp_cc_request->send_offset);
   11826     fflush(where);
   11827   }
   11828 
   11829   recv_message_ptr = ALIGN_BUFFER(message, tcp_cc_request->recv_alignment, tcp_cc_request->recv_offset);
   11830 
   11831   send_message_ptr = ALIGN_BUFFER(message, tcp_cc_request->send_alignment, tcp_cc_request->send_offset);
   11832 
   11833   if (debug) {
   11834     fprintf(where,"recv_tcp_cc: receive alignment and offset set...\n");
   11835     fflush(where);
   11836   }
   11837 
   11838   /* Grab a socket to listen on, and then listen on it. */
   11839 
   11840   if (debug) {
   11841     fprintf(where,"recv_tcp_cc: grabbing a socket...\n");
   11842     fflush(where);
   11843   }
   11844 
   11845   /* create_data_socket expects to find some things in the global */
   11846   /* variables, so set the globals based on the values in the request. */
   11847   /* once the socket has been created, we will set the response values */
   11848   /* based on the updated value of those globals. raj 7/94 */
   11849   lss_size_req = tcp_cc_request->send_buf_size;
   11850   lsr_size_req = tcp_cc_request->recv_buf_size;
   11851   loc_nodelay = tcp_cc_request->no_delay;
   11852   loc_rcvavoid = tcp_cc_request->so_rcvavoid;
   11853   loc_sndavoid = tcp_cc_request->so_sndavoid;
   11854 
   11855   set_hostname_and_port(local_name,
   11856 			port_buffer,
   11857 			nf_to_af(tcp_cc_request->ipfamily),
   11858 			tcp_cc_request->port);
   11859 
   11860   local_res = complete_addrinfo(local_name,
   11861 				local_name,
   11862 				port_buffer,
   11863 				nf_to_af(tcp_cc_request->ipfamily),
   11864 				SOCK_STREAM,
   11865 				IPPROTO_TCP,
   11866 				0);
   11867 
   11868   s_listen = create_data_socket(local_res);
   11869 
   11870   if (s_listen == INVALID_SOCKET) {
   11871     netperf_response.content.serv_errno = errno;
   11872     send_response();
   11873     if (debug) {
   11874       fprintf(where,"could not create data socket\n");
   11875       fflush(where);
   11876     }
   11877     exit(1);
   11878   }
   11879 
   11880 #ifdef WIN32
   11881   /* The test timer can fire during operations on the listening socket,
   11882      so to make the start_timer below work we have to move
   11883      it to close s_listen while we are blocked on accept. */
   11884   win_kludge_socket2 = s_listen;
   11885 #endif
   11886 
   11887 
   11888   /* Now, let's set-up the socket to listen for connections */
   11889   if (listen(s_listen, 5) == SOCKET_ERROR) {
   11890     netperf_response.content.serv_errno = errno;
   11891     close(s_listen);
   11892     send_response();
   11893     if (debug) {
   11894       fprintf(where,"could not listen\n");
   11895       fflush(where);
   11896     }
   11897     exit(1);
   11898   }
   11899 
   11900   /* now get the port number assigned by the system  */
   11901   addrlen = sizeof(myaddr_in);
   11902   if (getsockname(s_listen,
   11903 		  (struct sockaddr *)&myaddr_in,
   11904 		  &addrlen) == SOCKET_ERROR){
   11905     netperf_response.content.serv_errno = errno;
   11906     close(s_listen);
   11907     send_response();
   11908     if (debug) {
   11909       fprintf(where,"could not geetsockname\n");
   11910       fflush(where);
   11911     }
   11912     exit(1);
   11913   }
   11914 
   11915   /* Now myaddr_in contains the port and the internet address this is */
   11916   /* returned to the sender also implicitly telling the sender that the */
   11917   /* socket buffer sizing has been done. */
   11918 
   11919   tcp_cc_response->data_port_number =
   11920     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
   11921   if (debug) {
   11922     fprintf(where,"telling the remote to call me at %d\n",
   11923 	    tcp_cc_response->data_port_number);
   11924     fflush(where);
   11925   }
   11926   netperf_response.content.serv_errno   = 0;
   11927 
   11928   /* But wait, there's more. If the initiator wanted cpu measurements, */
   11929   /* then we must call the calibrate routine, which will return the max */
   11930   /* rate back to the initiator. If the CPU was not to be measured, or */
   11931   /* something went wrong with the calibration, we will return a 0.0 to */
   11932   /* the initiator. */
   11933 
   11934   tcp_cc_response->cpu_rate = (float)0.0; 	/* assume no cpu */
   11935   if (tcp_cc_request->measure_cpu) {
   11936     tcp_cc_response->measure_cpu = 1;
   11937     tcp_cc_response->cpu_rate =
   11938       calibrate_local_cpu(tcp_cc_request->cpu_rate);
   11939   }
   11940 
   11941 
   11942 
   11943   /* before we send the response back to the initiator, pull some of */
   11944   /* the socket parms from the globals */
   11945   tcp_cc_response->send_buf_size = lss_size;
   11946   tcp_cc_response->recv_buf_size = lsr_size;
   11947   tcp_cc_response->no_delay = loc_nodelay;
   11948   tcp_cc_response->so_rcvavoid = loc_rcvavoid;
   11949   tcp_cc_response->so_sndavoid = loc_sndavoid;
   11950 
   11951   send_response();
   11952 
   11953   addrlen = sizeof(peeraddr_in);
   11954 
   11955   /* Now it's time to start receiving data on the connection. We will */
   11956   /* first grab the apropriate counters and then start grabbing. */
   11957 
   11958   cpu_start(tcp_cc_request->measure_cpu);
   11959 
   11960   /* The loop will exit when the sender does a shutdown, which will */
   11961   /* return a length of zero   */
   11962 
   11963   if (tcp_cc_request->test_length > 0) {
   11964     times_up = 0;
   11965     trans_remaining = 0;
   11966     start_timer(tcp_cc_request->test_length + PAD_TIME);
   11967   }
   11968   else {
   11969     times_up = 1;
   11970     trans_remaining = tcp_cc_request->test_length * -1;
   11971   }
   11972 
   11973   trans_received = 0;
   11974 
   11975   while ((!times_up) || (trans_remaining > 0)) {
   11976 #ifdef WIN32
   11977     /* The test timer will probably fire during this accept,
   11978        so to make the start_timer above work we have to move
   11979        it to close s_listen while we are blocked on accept. */
   11980     win_kludge_socket = s_listen;
   11981 #endif
   11982     /* accept a connection from the remote */
   11983     if ((s_data=accept(s_listen,
   11984 		       (struct sockaddr *)&peeraddr_in,
   11985 		       &addrlen)) == INVALID_SOCKET) {
   11986       if (errno == EINTR) {
   11987 	/* the timer popped */
   11988 	timed_out = 1;
   11989 	break;
   11990       }
   11991       fprintf(where,"recv_tcp_cc: accept: errno = %d\n",errno);
   11992       fflush(where);
   11993       close(s_listen);
   11994 
   11995       exit(1);
   11996     }
   11997 
   11998 #ifdef KLUDGE_SOCKET_OPTIONS
   11999     /* this is for those systems which *INCORRECTLY* fail to pass */
   12000     /* attributes across an accept() call. Including this goes against */
   12001     /* my better judgement :( raj 11/95 */
   12002 
   12003     kludge_socket_options(s_data);
   12004 
   12005 #endif /* KLUDGE_SOCKET_OPTIONS */
   12006 
   12007 #ifdef WIN32
   12008   /* this is used so the timer thread can close the socket out from */
   12009   /* under us, which to date is the easiest/cleanest/least */
   12010   /* Windows-specific way I can find to force the winsock calls to */
   12011   /* return WSAEINTR with the test is over. anything that will run on */
   12012   /* 95 and NT and is closer to what netperf expects from Unix signals */
   12013   /* and such would be appreciated raj 1/96 */
   12014   win_kludge_socket = s_data;
   12015 #endif /* WIN32 */
   12016 
   12017     if (debug) {
   12018       fprintf(where,"recv_tcp_cc: accepted data connection.\n");
   12019       fflush(where);
   12020     }
   12021 
   12022 
   12023     /* close the connection. the server will likely do a graceful */
   12024     /* close of the connection, insuring that all data has arrived at */
   12025     /* the client. for this it will call shutdown(), and then recv() and */
   12026     /* then close(). I'm reasonably confident that this is the */
   12027     /* appropriate sequence of calls - I would like to hear of */
   12028     /* examples in web servers to the contrary. raj 10/95*/
   12029     close(s_data);
   12030 
   12031     trans_received++;
   12032     if (trans_remaining) {
   12033       trans_remaining--;
   12034     }
   12035 
   12036     if (debug) {
   12037       fprintf(where,
   12038 	      "recv_tcp_cc: Transaction %d complete\n",
   12039 	      trans_received);
   12040       fflush(where);
   12041     }
   12042 
   12043   }
   12044 
   12045 
   12046   /* The loop now exits due to timeout or transaction count being */
   12047   /* reached */
   12048 
   12049   cpu_stop(tcp_cc_request->measure_cpu,&elapsed_time);
   12050 
   12051   if (timed_out) {
   12052     /* we ended the test by time, which was at least 2 seconds */
   12053     /* longer than we wanted to run. so, we want to subtract */
   12054     /* PAD_TIME from the elapsed_time. */
   12055     elapsed_time -= PAD_TIME;
   12056   }
   12057   /* send the results to the sender			*/
   12058 
   12059   if (debug) {
   12060     fprintf(where,
   12061 	    "recv_tcp_cc: got %d transactions\n",
   12062 	    trans_received);
   12063     fflush(where);
   12064   }
   12065 
   12066   tcp_cc_results->bytes_received	= (trans_received *
   12067 					   (tcp_cc_request->request_size +
   12068 					    tcp_cc_request->response_size));
   12069   tcp_cc_results->trans_received	= trans_received;
   12070   tcp_cc_results->elapsed_time	= elapsed_time;
   12071   if (tcp_cc_request->measure_cpu) {
   12072     tcp_cc_results->cpu_util	= calc_cpu_util(elapsed_time);
   12073   }
   12074 
   12075   if (debug) {
   12076     fprintf(where,
   12077 	    "recv_tcp_cc: test complete, sending results.\n");
   12078     fflush(where);
   12079   }
   12080 
   12081   send_response();
   12082 
   12083 }
   12084 
   12085 void
   12087 print_sockets_usage()
   12088 {
   12089 
   12090   fwrite(sockets_usage, sizeof(char), strlen(sockets_usage), stdout);
   12091   exit(1);
   12092 
   12093 }
   12094 
   12095 void
   12096 scan_sockets_args(int argc, char *argv[])
   12097 
   12098 {
   12099 
   12100 #define SOCKETS_ARGS "b:CDnNhH:L:m:M:p:P:r:s:S:T:Vw:W:z46"
   12101 
   12102   extern char	*optarg;	  /* pointer to option string	*/
   12103 
   12104   int		c;
   12105 
   12106   char
   12107     arg1[BUFSIZ],  /* argument holders		*/
   12108     arg2[BUFSIZ];
   12109 
   12110   if (debug) {
   12111     int i;
   12112     printf("%s called with the following argument vector\n",
   12113 	   __func__);
   12114     for (i = 0; i< argc; i++) {
   12115       printf("%s ",argv[i]);
   12116     }
   12117     printf("\n");
   12118   }
   12119 
   12120   strncpy(local_data_port,"0",sizeof(local_data_port));
   12121   strncpy(remote_data_port,"0",sizeof(remote_data_port));
   12122 
   12123   /* Go through all the command line arguments and break them */
   12124   /* out. For those options that take two parms, specifying only */
   12125   /* the first will set both to that value. Specifying only the */
   12126   /* second will leave the first untouched. To change only the */
   12127   /* first, use the form "first," (see the routine break_args.. */
   12128 
   12129   while ((c= getopt(argc, argv, SOCKETS_ARGS)) != EOF) {
   12130     switch (c) {
   12131     case '?':
   12132     case '4':
   12133       remote_data_family = AF_INET;
   12134       local_data_family = AF_INET;
   12135       break;
   12136     case '6':
   12137 #if defined(AF_INET6)
   12138       remote_data_family = AF_INET6;
   12139       local_data_family = AF_INET6;
   12140 #else
   12141       fprintf(stderr,
   12142 	      "This netperf was not compiled on an IPv6 capable host!\n");
   12143       fflush(stderr);
   12144       exit(-1);
   12145 #endif
   12146       break;
   12147     case 'h':
   12148       print_sockets_usage();
   12149       exit(1);
   12150     case 'b':
   12151 #ifdef WANT_FIRST_BURST
   12152       first_burst_size = atoi(optarg);
   12153 #else /* WANT_FIRST_BURST */
   12154       printf("Initial request burst functionality not compiled-in!\n");
   12155 #endif /* WANT_FIRST_BURST */
   12156       break;
   12157     case 'C':
   12158 #ifdef TCP_CORK
   12159       /* set TCP_CORK */
   12160       loc_tcpcork = 1;
   12161       rem_tcpcork = 1; /* however, at first, we ony have cork affect loc */
   12162 #else
   12163       printf("WARNING: TCP_CORK not available on this platform!\n");
   12164 #endif /* TCP_CORK */
   12165       break;
   12166     case 'D':
   12167       /* set the TCP nodelay flag */
   12168       loc_nodelay = 1;
   12169       rem_nodelay = 1;
   12170       break;
   12171     case 'H':
   12172       break_args_explicit(optarg,arg1,arg2);
   12173       if (arg1[0]) {
   12174 	/* make sure we leave room for the NULL termination boys and
   12175 	   girls. raj 2005-02-82 */
   12176 	remote_data_address = malloc(strlen(arg1)+1);
   12177 	strncpy(remote_data_address,arg1,strlen(arg1));
   12178       }
   12179       if (arg2[0])
   12180 	remote_data_family = parse_address_family(arg2);
   12181       break;
   12182     case 'L':
   12183       break_args_explicit(optarg,arg1,arg2);
   12184       if (arg1[0]) {
   12185 	/* make sure we leave room for the NULL termination boys and
   12186 	   girls. raj 2005-02-82 */
   12187 	local_data_address = malloc(strlen(arg1)+1);
   12188 	strncpy(local_data_address,arg1,strlen(arg1));
   12189       }
   12190       if (arg2[0])
   12191 	local_data_family = parse_address_family(arg2);
   12192       break;
   12193     case 's':
   12194       /* set local socket sizes */
   12195       break_args(optarg,arg1,arg2);
   12196       if (arg1[0])
   12197 	lss_size_req = convert(arg1);
   12198       if (arg2[0])
   12199 	lsr_size_req = convert(arg2);
   12200       break;
   12201     case 'S':
   12202       /* set remote socket sizes */
   12203       break_args(optarg,arg1,arg2);
   12204       if (arg1[0])
   12205 	rss_size_req = convert(arg1);
   12206       if (arg2[0])
   12207 	rsr_size_req = convert(arg2);
   12208       break;
   12209     case 'r':
   12210       /* set the request/response sizes */
   12211       break_args(optarg,arg1,arg2);
   12212       if (arg1[0])
   12213 	req_size = convert(arg1);
   12214       if (arg2[0])
   12215 	rsp_size = convert(arg2);
   12216       break;
   12217     case 'm':
   12218       /* set the send size */
   12219       send_size = convert(optarg);
   12220       break;
   12221     case 'M':
   12222       /* set the recv size */
   12223       recv_size = convert(optarg);
   12224       break;
   12225     case 'n':
   12226       /* set the local socket type*/
   12227       local_connected = 1;
   12228       break;
   12229     case 'N':
   12230       /* set the remote socket type*/
   12231       remote_connected = 1;
   12232       break;
   12233     case 'p':
   12234       /* set the min and max port numbers for the TCP_CRR and TCP_TRR */
   12235       /* tests. */
   12236       break_args(optarg,arg1,arg2);
   12237       if (arg1[0])
   12238 	client_port_min = atoi(arg1);
   12239       if (arg2[0])
   12240 	client_port_max = atoi(arg2);
   12241       break;
   12242     case 'P':
   12243       /* set the local and remote data port numbers for the tests to
   12244 	 allow them to run through those blankety blank end-to-end
   12245 	 breaking firewalls. raj 2004-06-15 */
   12246       break_args(optarg,arg1,arg2);
   12247       if (arg1[0])
   12248 	strncpy(local_data_port,arg1,sizeof(local_data_port));
   12249       if (arg2[0])
   12250 	strncpy(remote_data_port,arg2,sizeof(remote_data_port));
   12251       break;
   12252     case 't':
   12253       /* set the test name */
   12254       strcpy(test_name,optarg);
   12255       break;
   12256     case 'W':
   12257       /* set the "width" of the user space data */
   12258       /* buffer. This will be the number of */
   12259       /* send_size buffers malloc'd in the */
   12260       /* *_STREAM test. It may be enhanced to set */
   12261       /* both send and receive "widths" but for now */
   12262       /* it is just the sending *_STREAM. */
   12263       send_width = convert(optarg);
   12264       break;
   12265     case 'V' :
   12266       /* we want to do copy avoidance and will set */
   12267       /* it for everything, everywhere, if we really */
   12268       /* can. of course, we don't know anything */
   12269       /* about the remote... */
   12270 #ifdef SO_SND_COPYAVOID
   12271       loc_sndavoid = 1;
   12272 #else
   12273       loc_sndavoid = 0;
   12274       printf("Local send copy avoidance not available.\n");
   12275 #endif
   12276 #ifdef SO_RCV_COPYAVOID
   12277       loc_rcvavoid = 1;
   12278 #else
   12279       loc_rcvavoid = 0;
   12280       printf("Local recv copy avoidance not available.\n");
   12281 #endif
   12282       rem_sndavoid = 1;
   12283       rem_rcvavoid = 1;
   12284       break;
   12285     };
   12286   }
   12287 
   12288 #if defined(WANT_FIRST_BURST)
   12289 #if defined(WANT_HISTOGRAM)
   12290   /* if WANT_FIRST_BURST and WANT_HISTOGRAM are defined and the user
   12291      indeed wants a non-zero first burst size, and we would emit a
   12292      histogram, then we should emit a warning that the two are not
   12293      compatible. raj 2006-01-31 */
   12294   if ((first_burst_size > 0) && (verbosity >= 2)) {
   12295     fprintf(stderr,
   12296 	    "WARNING! Histograms and first bursts are incompatible!\n");
   12297     fflush(stderr);
   12298   }
   12299 #endif
   12300 #endif
   12301 
   12302   /* we do not want to make remote_data_address non-NULL because if
   12303      the user has not specified a remote adata address, we want to
   12304      take it from the hostname in the -H global option. raj
   12305      2005-02-08 */
   12306 
   12307   /* so, if there is to be no control connection, we want to have some
   12308      different settings for a few things */
   12309 
   12310   if (no_control) {
   12311 
   12312     if (strcmp(remote_data_port,"0") == 0) {
   12313       /* we need to select either the discard port, echo port or
   12314 	 chargen port dedepending on the test name. raj 2007-02-08 */
   12315       if (strstr(test_name,"STREAM") ||
   12316 	  strstr(test_name,"SENDFILE")) {
   12317 	strncpy(remote_data_port,"discard",sizeof(remote_data_port));
   12318       }
   12319       else if (strstr(test_name,"RR")) {
   12320 	strncpy(remote_data_port,"echo",sizeof(remote_data_port));
   12321       }
   12322       else if (strstr(test_name,"MAERTS")) {
   12323 	strncpy(remote_data_port,"chargen",sizeof(remote_data_port));
   12324       }
   12325       else {
   12326 	printf("No default port known for the %s test, please set one yourself\n",test_name);
   12327 	exit(-1);
   12328       }
   12329     }
   12330     remote_data_port[sizeof(remote_data_port) - 1] = '\0';
   12331 
   12332     /* I go back and forth on whether these should become -1 or if
   12333        they should become 0 for a no_control test. what do you think?
   12334        raj 2006-02-08 */
   12335 
   12336     rem_rcvavoid = -1;
   12337     rem_sndavoid = -1;
   12338     rss_size_req = -1;
   12339     rsr_size_req = -1;
   12340     rem_nodelay = -1;
   12341 
   12342     if (strstr(test_name,"STREAM") ||
   12343 	strstr(test_name,"SENDFILE")) {
   12344       recv_size = -1;
   12345     }
   12346     else if (strstr(test_name,"RR")) {
   12347       /* I am however _certain_ that for a no control RR test the
   12348 	 response size must equal the request size since 99 times out
   12349 	 of ten we will be speaking to the echo service somewhere */
   12350       rsp_size = req_size;
   12351     }
   12352     else if (strstr(test_name,"MAERTS")) {
   12353       send_size = -1;
   12354     }
   12355     else {
   12356       printf("No default port known for the %s test, please set one yourself\n",test_name);
   12357       exit(-1);
   12358     }
   12359   }
   12360 }
   12361