Home | History | Annotate | Download | only in src
      1 #ifndef lint
      2 char	nettest_id[]="\
      3 @(#)nettest_bsd.c (c) Copyright 1993-2012 Hewlett-Packard Co. Version 2.6.0";
      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_tcp_mss()          just report the mss             */
     30 /*	send_udp_stream()	perform a udp stream test	*/
     31 /*	recv_udp_stream()					*/
     32 /*	send_udp_rr()		perform a udp request/response	*/
     33 /*	recv_udp_rr()						*/
     34 /*	loc_cpu_rate()		determine the local cpu maxrate */
     35 /*	rem_cpu_rate()		find the remote cpu maxrate	*/
     36 /*								*/
     37 /****************************************************************/
     38 
     39 #ifdef HAVE_CONFIG_H
     40 #include <config.h>
     41 #endif
     42 
     43 #include <stdio.h>
     44 #if HAVE_SYS_TYPES_H
     45 # include <sys/types.h>
     46 #endif
     47 #if HAVE_SYS_STAT_H
     48 # include <sys/stat.h>
     49 #endif
     50 #if STDC_HEADERS
     51 # include <stdlib.h>
     52 # include <stddef.h>
     53 #else
     54 # if HAVE_STDLIB_H
     55 #  include <stdlib.h>
     56 # endif
     57 #endif
     58 #if HAVE_STRING_H
     59 # if !STDC_HEADERS && HAVE_MEMORY_H
     60 #  include <memory.h>
     61 # endif
     62 # include <string.h>
     63 #endif
     64 #if HAVE_STRINGS_H
     65 # include <strings.h>
     66 #endif
     67 #if HAVE_INTTYPES_H
     68 # include <inttypes.h>
     69 #else
     70 # if HAVE_STDINT_H
     71 #  include <stdint.h>
     72 # endif
     73 #endif
     74 #if HAVE_UNISTD_H
     75 # include <unistd.h>
     76 #endif
     77 
     78 #include <fcntl.h>
     79 #ifndef WIN32
     80 #include <errno.h>
     81 #include <signal.h>
     82 #endif
     83 
     84 #if TIME_WITH_SYS_TIME
     85 # include <sys/time.h>
     86 # include <time.h>
     87 #else
     88 # if HAVE_SYS_TIME_H
     89 #  include <sys/time.h>
     90 # else
     91 #  include <time.h>
     92 # endif
     93 #endif
     94 
     95 #ifdef NOSTDLIBH
     96 #include <malloc.h>
     97 #endif /* NOSTDLIBH */
     98 
     99 
    100 #ifndef WIN32
    101 #if !defined(__VMS)
    102 #include <sys/ipc.h>
    103 #endif /* !__VMS */
    104 #include <sys/socket.h>
    105 #include <netinet/in.h>
    106 #include <netinet/tcp.h>
    107 
    108 #ifdef HAVE_NETINET_SCTP_H
    109 #include <netinet/sctp.h>
    110 #endif
    111 
    112 #include <arpa/inet.h>
    113 #include <netdb.h>
    114 #else /* WIN32 */
    115 #include <process.h>
    116 #define netperf_socklen_t socklen_t
    117 #include <winsock2.h>
    118 #include "missing\stdint.h"
    119 /* while it is unlikely that anyone running Windows 2000 or NT 4 is
    120    going to be trying to compile this, if they are they will want to
    121    define DONT_IPV6 in the sources file */
    122 #ifndef DONT_IPV6
    123 #include <ws2tcpip.h>
    124 #endif
    125 #include <windows.h>
    126 
    127 #define sleep(x) Sleep((x)*1000)
    128 
    129 #define __func__ __FUNCTION__
    130 #endif /* WIN32 */
    131 
    132 /* We don't want to use bare constants in the shutdown() call.  In the
    133    extremely unlikely event that SHUT_WR isn't defined, we will define
    134    it to the value we used to be passing to shutdown() anyway.  raj
    135    2007-02-08 */
    136 #if !defined(SHUT_WR)
    137 #define SHUT_WR 1
    138 #endif
    139 
    140 #if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO)
    141 # include "missing/getaddrinfo.h"
    142 #endif
    143 
    144 #include "netlib.h"
    145 #include "netsh.h"
    146 #include "nettest_bsd.h"
    147 
    148 #if defined(WANT_HISTOGRAM) || defined(WANT_DEMO)
    149 #include "hist.h"
    150 #endif /* WANT_HISTOGRAM */
    151 
    152 
    153 /* make first_burst_size unconditional so we can use it easily enough
    154    when calculating transaction latency for the TCP_RR test. raj
    155    2007-06-08 however, change its default value so one can tell in
    156    "omni" output whether or not WANT_BURST was enabled. raj
    157    2008-01-28 */
    158 #if defined(WANT_FIRST_BURST)
    159 int first_burst_size=0;
    160 #else
    161 int first_burst_size=-1;
    162 #endif
    163 
    164 #if defined(HAVE_SENDFILE) && (defined(__linux) || defined(__sun))
    165 #include <sys/sendfile.h>
    166 #endif /* HAVE_SENDFILE && (__linux || __sun) */
    167 
    168 
    169 
    171 /* these variables are specific to the BSD sockets tests, but can
    172  * be used elsewhere if needed.  They are externed through nettest_bsd.h
    173  */
    174 
    175 int
    176   socket_type,          /* used initially by the "omni" tests */
    177   rss_size_req = -1,	/* requested remote socket send buffer size */
    178   rsr_size_req = -1,	/* requested remote socket recv buffer size */
    179   rss_size,		/* initial remote socket send buffer size */
    180   rsr_size,		/* initial remote socket recv buffer size */
    181   rss_size_end = -1,    /* final  remote socket send buffer size */
    182   rsr_size_end = -1,    /* final  remote socket recv buffer size */
    183   lss_size_req = -1,	/* requested local socket send buffer size */
    184   lsr_size_req = -1,	/* requested local socket recv buffer size */
    185   lss_size,		/* local  socket send buffer size 	*/
    186   lsr_size,		/* local  socket recv buffer size 	*/
    187   lss_size_end = -1,    /* final local  socket send buffer size */
    188   lsr_size_end = -1,    /* final local  socket recv buffer size */
    189   req_size = 1,		/* request size                   	*/
    190   rsp_size = 1,		/* response size			*/
    191   send_size,		/* how big are individual sends		*/
    192   recv_size,		/* how big are individual receives	*/
    193   transport_mss_req = -1; /* what maximum segment size is wanted */
    194 
    195 static  int confidence_iteration;
    196 static  char  local_cpu_method;
    197 static  char  remote_cpu_method;
    198 
    199 /* these will control the width of port numbers we try to use in the */
    200 /* TCP_CRR and/or TCP_TRR tests. raj 3/95 */
    201 static int client_port_min = 5000;
    202 static int client_port_max = 65535;
    203 
    204  /* different options for the sockets				*/
    205 
    206 int
    207   loc_nodelay,		/* don't/do use NODELAY	locally		*/
    208   rem_nodelay,		/* don't/do use NODELAY remotely	*/
    209 #ifdef TCP_CORK
    210   loc_tcpcork=0,        /* don't/do use TCP_CORK locally        */
    211   rem_tcpcork=0,        /* don't/do use TCP_CORK remotely       */
    212 #else
    213   loc_tcpcork=-1,
    214   rem_tcpcork=-1,
    215 #endif /* TCP_CORK */
    216   loc_sndavoid,		/* avoid send copies locally		*/
    217   loc_rcvavoid,		/* avoid recv copies locally		*/
    218   rem_sndavoid,		/* avoid send copies remotely		*/
    219   rem_rcvavoid, 	/* avoid recv_copies remotely		*/
    220   local_connected = 0,  /* local socket type, connected/non-connected */
    221   remote_connected = 0, /* remote socket type, connected/non-connected */
    222   routing_allowed = 1;    /* set/clear SO_DONTROUTE on data socket */
    223 
    224 int multicast_ttl = -1; /* should we set the multicast TTL to a value? */
    225 
    226 int want_keepalive = 0;
    227 
    228 #ifdef WANT_HISTOGRAM
    229 #ifdef HAVE_GETHRTIME
    230 static hrtime_t time_one;
    231 static hrtime_t time_two;
    232 #elif HAVE_GET_HRT
    233 #include "hrt.h"
    234 static hrt_t time_one;
    235 static hrt_t time_two;
    236 #elif defined(WIN32)
    237 static LARGE_INTEGER time_one;
    238 static LARGE_INTEGER time_two;
    239 #else
    240 static struct timeval time_one;
    241 static struct timeval time_two;
    242 #endif /* HAVE_GETHRTIME */
    243 static HIST time_hist;
    244 #endif /* WANT_HISTOGRAM */
    245 
    246 #ifdef WANT_INTERVALS
    247 int interval_count;
    248 #ifndef WANT_SPIN
    249 #ifdef WIN32
    250 #define INTERVALS_INIT() \
    251     if (interval_burst) { \
    252       /* zero means that we never pause, so we never should need the \
    253          interval timer. we used to use it for demo mode, but we deal \
    254 	 with that with a variant on watching the clock rather than \
    255 	 waiting for a timer. raj 2006-02-06 */ \
    256       start_itimer(interval_wate); \
    257     } \
    258     interval_count = interval_burst;
    259 #else
    260 sigset_t signal_set;
    261 #define INTERVALS_INIT() \
    262     if (interval_burst) { \
    263       /* zero means that we never pause, so we never should need the \
    264          interval timer. we used to use it for demo mode, but we deal \
    265 	 with that with a variant on watching the clock rather than \
    266 	 waiting for a timer. raj 2006-02-06 */ \
    267       start_itimer(interval_wate); \
    268     } \
    269     interval_count = interval_burst; \
    270     /* get the signal set for the call to sigsuspend */ \
    271     if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) { \
    272       fprintf(where, \
    273 	      "%s: unable to get sigmask errno %d\n", \
    274 	      __func__, \
    275 	      errno); \
    276       fflush(where); \
    277       exit(1); \
    278     }
    279 #endif /* WIN32 */
    280 
    281 #ifdef WIN32
    282 #define INTERVALS_WAIT() \
    283       /* in this case, the interval count is the count-down counter \
    284 	 to decide to sleep for a little bit */ \
    285       if ((interval_burst) && (--interval_count == 0)) { \
    286 	/* call WaitForSingleObject and wait for the interval timer to get us \
    287 	   out */ \
    288 	if (debug > 1) { \
    289 	  fprintf(where,"about to suspend\n"); \
    290 	  fflush(where); \
    291 	} \
    292     if (WaitForSingleObject(WinTimer, INFINITE) != WAIT_OBJECT_0) { \
    293         fprintf(where, "WaitForSingleObject failed (%d)\n", GetLastError()); \
    294 	  fflush(where); \
    295 	  exit(1); \
    296 	} \
    297 	interval_count = interval_burst; \
    298       }
    299 #else
    300 #define INTERVALS_WAIT() \
    301       /* in this case, the interval count is the count-down couter \
    302 	 to decide to sleep for a little bit */ \
    303       if ((interval_burst) && (--interval_count == 0)) { \
    304 	/* call sigsuspend and wait for the interval timer to get us \
    305 	   out */ \
    306 	if (debug > 1) { \
    307 	  fprintf(where,"about to suspend\n"); \
    308 	  fflush(where); \
    309 	} \
    310 	if (sigsuspend(&signal_set) == EFAULT) { \
    311 	  fprintf(where, \
    312 		  "%s: fault with sigsuspend.\n", \
    313                   __func__); \
    314 	  fflush(where); \
    315 	  exit(1); \
    316 	} \
    317 	interval_count = interval_burst; \
    318       }
    319 #endif /* WIN32 */
    320 #else
    321 /* first out timestamp */
    322 #ifdef HAVE_GETHRTIME
    323 static hrtime_t intvl_one;
    324 static hrtime_t intvl_two;
    325 static hrtime_t *intvl_one_ptr = &intvl_one;
    326 static hrtime_t *intvl_two_ptr = &intvl_two;
    327 static hrtime_t *temp_intvl_ptr = &intvl_one;
    328 #elif defined(WIN32)
    329 static LARGE_INTEGER intvl_one;
    330 static LARGE_INTEGER intvl_two;
    331 static LARGE_INTEGER *intvl_one_ptr = &intvl_one;
    332 static LARGE_INTEGER *intvl_two_ptr = &intvl_two;
    333 static LARGE_INTEGER *temp_intvl_ptr = &intvl_one;
    334 #else
    335 static struct timeval intvl_one;
    336 static struct timeval intvl_two;
    337 static struct timeval *intvl_one_ptr = &intvl_one;
    338 static struct timeval *intvl_two_ptr = &intvl_two;
    339 static struct timeval *temp_intvl_ptr = &intvl_one;
    340 #endif
    341 
    342 #define INTERVALS_INIT() \
    343       if (interval_burst) { \
    344 	HIST_timestamp(intvl_one_ptr); \
    345       } \
    346       interval_count = interval_burst; \
    347 
    348 #define INTERVALS_WAIT() \
    349       /* in this case, the interval count is the count-down couter \
    350 	 to decide to sleep for a little bit */ \
    351       if ((interval_burst) && (--interval_count == 0)) { \
    352 	/* call sigsuspend and wait for the interval timer to get us \
    353 	   out */ \
    354 	if (debug > 1) { \
    355 	  fprintf(where,"about to spin suspend\n"); \
    356 	  fflush(where); \
    357 	} \
    358         HIST_timestamp(intvl_two_ptr); \
    359         while(delta_micro(intvl_one_ptr,intvl_two_ptr) < interval_usecs) { \
    360 	  HIST_timestamp(intvl_two_ptr); \
    361 	} \
    362 	temp_intvl_ptr = intvl_one_ptr; \
    363 	intvl_one_ptr = intvl_two_ptr; \
    364 	intvl_two_ptr = temp_intvl_ptr; \
    365 	interval_count = interval_burst; \
    366       }
    367 #endif
    368 #endif
    369 
    370 
    371 char sockets_usage[] = "\n\
    372 Usage: netperf [global options] -- [test options] \n\
    373 \n\
    374 TCP/UDP BSD Sockets Test Options:\n\
    375     -b number         Send number requests at start of _RR tests\n\
    376     -C                Set TCP_CORK when available\n\
    377     -D [L][,R]        Set TCP_NODELAY locally and/or remotely (TCP_*)\n\
    378     -h                Display this text\n\
    379     -H name,fam       Use name (or IP) and family as target of data connection\n\
    380     -L name,fam       Use name (or IP) and family as source of data connection\n\
    381     -m bytes          Set the send size (TCP_STREAM, UDP_STREAM)\n\
    382     -M bytes          Set the recv size (TCP_STREAM, UDP_STREAM)\n\
    383     -n                Use the connected socket for UDP locally\n\
    384     -N                Use the connected socket for UDP remotely\n\
    385     -p min[,max]      Set the min/max port numbers for TCP_CRR, TCP_TRR\n\
    386     -P local[,remote] Set the local/remote port for the data socket\n\
    387     -r req,[rsp]      Set request/response sizes (TCP_RR, UDP_RR)\n\
    388     -s send[,recv]    Set local socket send/recv buffer sizes\n\
    389     -S send[,recv]    Set remote socket send/recv buffer sizes\n\
    390     -4                Use AF_INET (eg IPv4) on both ends of the data conn\n\
    391     -6                Use AF_INET6 (eg IPv6) on both ends of the data conn\n\
    392 \n\
    393 For those options taking two parms, at least one must be specified;\n\
    394 specifying one value without a comma will set both parms to that\n\
    395 value, specifying a value with a leading comma will set just the second\n\
    396 parm, a value with a trailing comma will set just the first. To set\n\
    397 each parm to unique values, specify both and separate them with a\n\
    398 comma.\n";
    399 
    400 
    401 
    403 /* these routines convert between the AF address space and the NF
    404    address space since the numeric values of AF_mumble are not the
    405    same across the platforms. raj 2005-02-08 */
    406 
    407 int
    408 nf_to_af(int nf) {
    409   switch(nf) {
    410   case NF_INET:
    411     return AF_INET;
    412   case NF_UNSPEC:
    413     return AF_UNSPEC;
    414   case NF_INET6:
    415 #if defined(AF_INET6)
    416     return AF_INET6;
    417 #else
    418     return AF_UNSPEC;
    419 #endif
    420   case NF_RDS:
    421 #if defined(AF_RDS)
    422     return AF_RDS;
    423 #else
    424     return AF_UNSPEC;
    425 #endif
    426   default:
    427     return AF_UNSPEC;
    428   }
    429 }
    430 
    431 int
    432 af_to_nf(int af) {
    433 
    434   switch(af) {
    435   case AF_INET:
    436     return NF_INET;
    437   case AF_UNSPEC:
    438     return NF_UNSPEC;
    439 #if defined(AF_INET6)
    440   case AF_INET6:
    441     return NF_INET6;
    442 #endif
    443 #if defined(AF_RDS)
    444   case AF_RDS:
    445     return NF_RDS;
    446 #endif
    447   default:
    448     return NF_UNSPEC;
    449   }
    450 }
    451 
    452 
    453 /* these routines will convert between the hosts' socket types and
    455    those netperf uses.  we need this because different platforms can
    456    have different values for SOCK_STREAM, SOCK_DGRAM and the
    457    like... */
    458 
    459 int
    460 nst_to_hst(int nst) {
    461   switch(nst) {
    462 #ifdef SOCK_STREAM
    463   case NST_STREAM:
    464     return SOCK_STREAM;
    465     break;  /* ok, this may not be necessary :) */
    466 #endif
    467 #ifdef SOCK_DGRAM
    468   case NST_DGRAM:
    469     return SOCK_DGRAM;
    470     break;
    471 #endif
    472 #ifdef SOCK_DCCP
    473   case NST_DCCP:
    474     return SOCK_DCCP;
    475     break;
    476 #endif
    477 #ifdef SOCK_SEQPACKET
    478   case NST_SEQPACKET:
    479     return NST_SEQPACKET;
    480 #endif
    481   default:
    482     return -1;
    483   }
    484 }
    485 
    486 int
    487 hst_to_nst(int hst) {
    488 
    489   switch(hst) {
    490 #ifdef SOCK_STREAM
    491   case SOCK_STREAM:
    492     return NST_STREAM;
    493     break;
    494 #endif
    495 #ifdef SOCK_DGRAM
    496   case SOCK_DGRAM:
    497     return NST_DGRAM;
    498     break;
    499 #endif
    500 #ifdef SOCK_DCCP
    501   case SOCK_DCCP:
    502     return NST_DCCP;
    503     break;
    504 #endif
    505 #ifdef SOCK_SEQPACKET
    506   case SOCK_SEQPACKET:
    507     return NST_SEQPACKET;
    508 #endif
    509   default:
    510     return NST_UNKN;
    511   }
    512 }
    513 char *
    514 hst_to_str(int hst) {
    515 
    516   switch(hst) {
    517 #ifdef SOCK_STREAM
    518   case SOCK_STREAM:
    519     return "Stream";
    520     break;
    521 #endif
    522 #ifdef SOCK_DGRAM
    523   case SOCK_DGRAM:
    524     return "Datagram";
    525     break;
    526 #endif
    527 #ifdef SOCK_DCCP
    528   case SOCK_DCCP:
    529     return "DCCP";
    530     break;
    531 #endif
    532 #ifdef SOCK_SEQPACKET
    533   case SOCK_SEQPACKET:
    534     return "Seqpacket";
    535 #endif
    536   default:
    537     return "Unknown";
    538   }
    539 }
    540 
    541 char *
    542 protocol_to_str(int protocol) {
    543   switch(protocol) {
    544     /* ass-u-me that everyone has IPPROTO_TCP and IPPROTO_UDP */
    545   case IPPROTO_TCP:
    546     return "TCP";
    547   case IPPROTO_UDP:
    548     return "UDP";
    549     /* but do not assume that everyone has the others */
    550 #ifdef IPPROTO_UDPLITE
    551   case IPPROTO_UDPLITE:
    552     return "UDPLite";
    553 #endif
    554 #ifdef IPPROTO_SCTP
    555   case IPPROTO_SCTP:
    556     return "SCTP";
    557 #endif
    558 #ifdef IPPROTO_DCCP
    559   case IPPROTO_DCCP:
    560     return "DCCP";
    561 #endif
    562 #ifdef IPPROTO_SDP
    563   case IPPROTO_SDP:
    564     return "SDP";
    565 #endif
    566 #ifdef IPPROTO_IP
    567   case IPPROTO_IP:
    568     return "IP Default";
    569 #endif
    570   default:
    571     return "Unknown Protocol";
    572   }
    573 }
    574 
    575 
    576  /* This routine is intended to retrieve interesting aspects of tcp */
    578  /* for the data connection. at first, it attempts to retrieve the */
    579  /* maximum segment size. later, it might be modified to retrieve */
    580  /* other information, but it must be information that can be */
    581  /* retrieved quickly as it is called during the timing of the test. */
    582  /* for that reason, a second routine may be created that can be */
    583  /* called outside of the timing loop */
    584 static
    585 void
    586 get_tcp_info(SOCKET socket, int *mss)
    587 {
    588 
    589 #ifdef TCP_MAXSEG
    590   netperf_socklen_t sock_opt_len;
    591 
    592   sock_opt_len = sizeof(int);
    593   if (getsockopt(socket,
    594 		 getprotobyname("tcp")->p_proto,
    595 		 TCP_MAXSEG,
    596 		 (char *)mss,
    597 		 &sock_opt_len) == SOCKET_ERROR) {
    598     fprintf(where,
    599 	    "netperf: get_tcp_info: getsockopt TCP_MAXSEG: errno %d\n",
    600 	    errno);
    601     fflush(where);
    602     *mss = -1;
    603   }
    604 #else
    605   *mss = -1;
    606 #endif /* TCP_MAXSEG */
    607 }
    608 
    609 static
    610 void
    611 set_tcp_mss(SOCKET socket, int mss) {
    612 #ifdef TCP_MAXSEG
    613   netperf_socklen_t sock_opt_len;
    614 
    615   sock_opt_len = sizeof(int);
    616   if ((setsockopt(socket,
    617 		  getprotobyname("tcp")->p_proto,
    618 		  TCP_MAXSEG,
    619 		  (const char *)&mss,
    620 		  sock_opt_len) == SOCKET_ERROR) && (debug)) {
    621     fprintf(where,
    622 	    "netperf: %s: setsockopt TCP_MAXSEG: %s (errno %d)\n",
    623 	    __FUNCTION__,
    624 	    strerror(errno),
    625 	    errno);
    626     fflush(where);
    627   }
    628 #else
    629   if (debug) {
    630     fprintf(where,
    631 	    "netperf: %s platform does not know how to set TCP segment size\n",
    632 	    __FUNCTION__);
    633     fflush(where);
    634   }
    635 
    636 #endif /* TCP_MAXSEG */
    637 }
    638 
    639 
    640 
    642 /* return a pointer to a completed addrinfo chain - prefer
    643    data_address to controlhost and utilize the specified address
    644    family */
    645 
    646 struct addrinfo *
    647 complete_addrinfo(char *controlhost, char *data_address, char *port, int family, int type, int protocol, int flags)
    648 {
    649   struct addrinfo hints;
    650   struct addrinfo *res;
    651   struct addrinfo *temp_res;
    652 
    653 #define CHANGED_SOCK_TYPE  0x1
    654 #define CHANGED_PROTOCOL   0x2
    655 #define CHANGED_SCTP       0x4
    656 #define CHANGED_DCCP       0x8
    657 #define CHANGED_DCCP_SOCK  0x10
    658 
    659   int    change_info = 0;
    660   static int change_warning_displayed = 0;
    661 
    662   int count = 0;
    663   int error = 0;
    664 
    665   char *hostname;
    666 
    667   /* take data-address over controlhost */
    668   if (data_address)
    669     hostname = data_address;
    670   else
    671     hostname = controlhost;
    672 
    673   if (debug) {
    674     fprintf(where,
    675 	    "complete_addrinfo using hostname %s port %s family %s type %s prot %s flags 0x%x\n",
    676 	    hostname,
    677 	    port,
    678 	    inet_ftos(family),
    679 	    inet_ttos(type),
    680 	    inet_ptos(protocol),
    681 	    flags);
    682     fflush(where);
    683   }
    684 
    685   memset(&hints, 0, sizeof(hints));
    686   hints.ai_family = family;
    687   hints.ai_socktype = type;
    688   hints.ai_protocol = protocol;
    689   hints.ai_flags = flags|AI_CANONNAME|AI_ADDRCONFIG;
    690 
    691   count = 0;
    692   do {
    693     error = getaddrinfo((char *)hostname,
    694                         (char *)port,
    695                         &hints,
    696                         &res);
    697     count += 1;
    698     if (error == EAI_AGAIN) {
    699       if (debug) {
    700         fprintf(where,"Sleeping on getaddrinfo EAI_AGAIN\n");
    701         fflush(where);
    702       }
    703       sleep(1);
    704     }
    705     /* while you see this kludge first, it is actually the second, the
    706        first being the one for Solaris below. The need for this kludge
    707        came after implementing the Solaris broken getaddrinfo kludge -
    708        now we see a kludge in Linux getaddrinfo where if it is given
    709        SOCK_STREAM and IPPROTO_SCTP it barfs with a -7
    710        EAI_SOCKTYPE. so, we check if the error was EAI_SOCKTYPE and if
    711        we were asking for IPPROTO_SCTP and if so, kludge, again... raj
    712        200?-10-13 and of course, requiring the kludge for SCTP, it is
    713        no surprise that linux needs a kludge for DCCP...actually not
    714        only does it need the ai_protocol kludge, it needs an
    715        ai_socktype kludge too... sigh raj 2008-02-01 */
    716 #if defined(IPPROTO_SCTP) || defined (IPPROTO_DCCP)
    717     if (EAI_SOCKTYPE == error
    718 #ifdef EAI_BADHINTS
    719         || EAI_BADHINTS == error
    720 #endif
    721         ) {
    722       /* we ass-u-me this is the Linux getaddrinfo bug, clear the
    723 	 hints.ai_protocol field, and set some state "remembering"
    724 	 that we did this so the code for the Solaris kludge can do
    725 	 the fix-up for us.  also flip error over to EAI_AGAIN and
    726 	 make sure we don't "count" this time around the loop. */
    727 #if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
    728       /* only tweak on this one the second time around, after we've
    729 	 kludged the ai_protocol field */
    730       if ((hints.ai_socktype == SOCK_DCCP) &&
    731 	  (hints.ai_protocol == 0)) {
    732 	change_info |= CHANGED_DCCP_SOCK;
    733 	hints.ai_socktype = 0;
    734 	/* we need to give it some sort of IPPROTO or it gets unhappy,
    735 	   so for now, pick one from deep within the colon and use
    736 	   IPPROTO_TCP */
    737 	hints.ai_protocol = IPPROTO_TCP;
    738       }
    739 
    740       if (hints.ai_protocol == IPPROTO_DCCP) {
    741 	change_info |= CHANGED_DCCP;
    742 	hints.ai_protocol = 0;
    743       }
    744 
    745 #endif
    746 #if defined(IPPROTO_SCTP)
    747       if (hints.ai_protocol == IPPROTO_SCTP) {
    748 	change_info |= CHANGED_SCTP;
    749 	hints.ai_protocol = 0;
    750       }
    751 #endif
    752 
    753       error = EAI_AGAIN;
    754       count -= 1;
    755     }
    756 #endif
    757   } while ((error == EAI_AGAIN) && (count <= 5));
    758 
    759   if (error) {
    760     fprintf(where,
    761 	    "complete_addrinfo: could not resolve '%s' port '%s' af %d"
    762 	    "\n\tgetaddrinfo returned %d %s\n",
    763 	    hostname,
    764 	    port,
    765 	    family,
    766 	    error,
    767 	    gai_strerror(error));
    768     fflush(where);
    769     exit(-1);
    770   }
    771 
    772   /* there exists at least one platform - Solaris 10 - that does not
    773      seem to completely honor the ai_protocol and/or ai_socktype one
    774      sets in the hints parm to the getaddrinfo call.  so, we need to
    775      walk the list of entries returned and if either of those do not
    776      match what we asked for, we need to go ahead and set them
    777      "correctly" this is based in part on some earlier SCTP-only code
    778      from previous revisions.  raj 2006-10-09 */
    779 
    780   temp_res = res;
    781 
    782   while (temp_res) {
    783 
    784     if ((type)  &&
    785 	(temp_res->ai_socktype != type)) {
    786       change_info |= CHANGED_SOCK_TYPE;
    787       if (debug) {
    788 	fprintf(where,
    789 		"WARNING! Changed bogus getaddrinfo socket type %d to %d\n",
    790 		temp_res->ai_socktype,
    791 		type);
    792 	fflush(where);
    793       }
    794       temp_res->ai_socktype = type;
    795     }
    796 
    797     if ((protocol) &&
    798 	(temp_res->ai_protocol != protocol)) {
    799       change_info |= CHANGED_PROTOCOL;
    800       if (debug) {
    801 	fprintf(where,
    802 		"WARNING! Changed bogus getaddrinfo protocol %d to %d\n",
    803 		temp_res->ai_protocol,
    804 		protocol);
    805 	fflush(where);
    806       }
    807       temp_res->ai_protocol = protocol;
    808     }
    809     temp_res = temp_res->ai_next;
    810   }
    811 
    812   if ((change_info & CHANGED_SOCK_TYPE) &&
    813       !(change_warning_displayed & CHANGED_SOCK_TYPE)) {
    814     change_warning_displayed |= CHANGED_SOCK_TYPE;
    815     fprintf(where,
    816 	    "WARNING! getaddrinfo returned a socket type which did not\n"
    817 	    "match the requested type.  Please contact your vendor for\n"
    818 	    "a fix to this bug in getaddrinfo()\n");
    819     fflush(where);
    820   }
    821 
    822   /* if we dropped the protocol hint, it would be for a protocol that
    823      getaddrinfo() wasn't supporting yet, not for the bug that it took
    824      our hint and still returned zero. raj 2006-10-16 */
    825   /* as there is now an open bug against (Open)Solaris (id 6847733) on
    826      this behaviour we will only emit this warning if debug is set
    827      under Solaris and will continue to emit it under any circumstance
    828      on other platforms should it arise. raj 2009-06-03 */
    829   /* since it has now been two years since that bug was filed, it
    830      should be resolved by now, so the "out" given to Sun should no
    831      longer be necessary.  either folks are running with the fix or
    832      they need to get the fix. raj 2011-07-06 */
    833   if ((change_info & CHANGED_PROTOCOL) &&
    834       !(change_warning_displayed & CHANGED_PROTOCOL) &&
    835       (hints.ai_protocol != 0)) {
    836     change_warning_displayed |= CHANGED_PROTOCOL;
    837     fprintf(where,
    838 	    "WARNING! getaddrinfo returned a protocol other than the\n"
    839 	    "requested protocol.  Please contact your vendor for\n"
    840 	    "a fix to this bug in getaddrinfo()\n");
    841     fflush(where);
    842   }
    843 
    844   if ((change_info & CHANGED_SCTP) &&
    845       !(change_warning_displayed & CHANGED_SCTP)) {
    846     change_warning_displayed |= CHANGED_SCTP;
    847     fprintf(where,
    848 	    "WARNING! getaddrinfo on this platform does not accept IPPROTO_SCTP!\n"
    849 	    "Please contact your vendor for a fix to this bug in getaddrinfo().\n");
    850     fflush(where);
    851   }
    852 
    853   if ((change_info & CHANGED_DCCP) &&
    854       !(change_warning_displayed & CHANGED_DCCP)) {
    855     change_warning_displayed |= CHANGED_DCCP;
    856     fprintf(where,
    857 	    "WARNING! getaddrinfo on this platform does not accept IPPROTO_DCCP!\n"
    858 	    "Please contact your vendor for a fix to this bug in getaddrinfo().\n");
    859     fflush(where);
    860   }
    861 
    862 
    863   if (debug) {
    864     dump_addrinfo(where, res, hostname, port, family);
    865   }
    866 
    867   return(res);
    868 }
    869 
    870 void
    871 complete_addrinfos(struct addrinfo **remote,struct addrinfo **local, char remote_host[], int type, int protocol, int flags) {
    872 
    873   if (remote_data_family == AF_UNSPEC) {
    874     remote_data_family = control_family;
    875   }
    876 
    877   *remote = complete_addrinfo(remote_host,
    878 			      remote_data_address,
    879 			      remote_data_port,
    880 			      remote_data_family,
    881 			      type,
    882 			      protocol,
    883 			      flags);
    884 
    885   /* OK, if the user has not specified a local data endpoint address
    886      (test-specific -L), pick the local data endpoint address based on
    887      the remote data family info (test-specific -H or -4 or -6
    888      option).  if the user has not specified remote data addressing
    889      info (test-specific -H, -4 -6) pick something based on the local
    890      control connection address (ie the global -L option). */
    891 
    892   if (NULL == local_data_address) {
    893     local_data_address = malloc(HOSTNAMESIZE);
    894     if (NULL == remote_data_address) {
    895       if (debug) {
    896 	fprintf(where,
    897 		"local_data_address not set, using local_host_name of '%s'\n",
    898 		local_host_name);
    899 	fflush(where);
    900       }
    901       strcpy(local_data_address,local_host_name);
    902     }
    903     else {
    904       if (debug) {
    905 	fprintf(where,
    906 		"local_data_address not set, using address family info\n");
    907 	fflush(where);
    908       }
    909       /* by default, use 0.0.0.0 - assume IPv4 */
    910       strcpy(local_data_address,"0.0.0.0");
    911 #if defined(AF_INET6)
    912       if ((AF_INET6 == local_data_family) ||
    913 	  ((AF_UNSPEC == local_data_family) &&
    914 	   (AF_INET6 == remote_data_family)) ||
    915 	  ((AF_UNSPEC == local_data_family) &&
    916 	   (AF_INET6 == (*remote)->ai_family))) {
    917 	strcpy(local_data_address,"::0");
    918       }
    919 #endif
    920     }
    921   }
    922 
    923   *local = complete_addrinfo("what to put here?",
    924 			     local_data_address,
    925 			     local_data_port,
    926 			     local_data_family,
    927 			     type,
    928 			     protocol,
    929 			     flags|AI_PASSIVE);
    930 
    931   /* OK, at this point, if remote_data_address is NULL, we know that
    932      we used the value of remote_host (the control connection) for the
    933      remote, which means we can/should set remote_data_address to
    934      remote_host so the "omni" output routines can use that global
    935      variable. at least i think I can get away with that :) I'm sure
    936      that at some point I'll find-out that I need to allocate
    937      something for it rather than mess with the pointers, but that can
    938      wait.  famous last words of raj 2008-01-25 */
    939   if (remote_data_address == NULL)
    940     remote_data_address = remote_host;
    941 }
    942 
    943 void
    944 set_hostname_and_port(char *hostname, char *portstr, int family, int port)
    945 {
    946   strcpy(hostname,"0.0.0.0");
    947 #if defined AF_INET6
    948   if (AF_INET6 == family) {
    949     strcpy(hostname,"::0");
    950   }
    951 #endif
    952 
    953   sprintf(portstr, "%u", port);
    954 
    955 }
    956 
    957 static unsigned short
    958 get_port_number(struct addrinfo *res)
    959 {
    960  switch(res->ai_family) {
    961   case AF_INET: {
    962     struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr;
    963     return(ntohs(foo->sin_port));
    964     break;
    965   }
    966 #if defined(AF_INET6)
    967   case AF_INET6: {
    968     struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr;
    969     return(ntohs(foo->sin6_port));
    970     break;
    971   }
    972 #endif
    973   default:
    974     fprintf(where,
    975 	    "Given Unexpected Address Family of %u\n",res->ai_family);
    976     fflush(where);
    977     exit(-1);
    978   }
    979 }
    980 
    981 static void
    982 extract_inet_address_and_port(struct addrinfo *res, void *addr, int len, int *port)
    983 {
    984  switch(res->ai_family) {
    985   case AF_INET: {
    986     struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr;
    987     *port = foo->sin_port;
    988     memcpy(addr,&(foo->sin_addr),min(len,sizeof(foo->sin_addr)));
    989     break;
    990   }
    991 #if defined(AF_INET6)
    992   case AF_INET6: {
    993     struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr;
    994     *port = foo->sin6_port;
    995     memcpy(addr,&(foo->sin6_addr),min(len,sizeof(foo->sin6_addr)));
    996     break;
    997   }
    998 #endif
    999   default:
   1000     *port = 0xDEADBEEF;
   1001     strncpy(addr,"UNKN FAMILY",len);
   1002   }
   1003 }
   1004 
   1005 /* this routine will set the port number of the sockaddr in the
   1006    addrinfo to the specified value, based on the address family */
   1007 void
   1008 set_port_number(struct addrinfo *res, unsigned short port)
   1009 {
   1010   switch(res->ai_family) {
   1011   case AF_INET:
   1012 #if defined(AF_RDS)
   1013   case AF_RDS:
   1014 #endif
   1015     {
   1016       struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr;
   1017       foo->sin_port = htons(port);
   1018       break;
   1019     }
   1020 #if defined(AF_INET6)
   1021   case AF_INET6: {
   1022     struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr;
   1023     foo->sin6_port = htons(port);
   1024     break;
   1025   }
   1026 #endif
   1027   default:
   1028     fprintf(where,
   1029 	    "set_port_number Unexpected Address Family of %u\n",res->ai_family);
   1030     fflush(where);
   1031     exit(-1);
   1032   }
   1033 }
   1034 
   1035 /* stuff the address family, port number and address into a
   1036    sockaddr. for now, we will go ahead and zero-out the sockaddr
   1037    first */
   1038 void
   1039 set_sockaddr_family_addr_port(struct sockaddr_storage *sockaddr, int family, void *addr, int port) {
   1040 
   1041   memset(sockaddr,0,sizeof(struct sockaddr_storage));
   1042 
   1043   switch (family) {
   1044 #if defined(AF_RDS)
   1045   case AF_RDS:
   1046 #endif
   1047   case AF_INET: {
   1048     struct sockaddr_in *foo = (struct sockaddr_in *)sockaddr;
   1049     foo->sin_port = htons((unsigned short) port);
   1050     foo->sin_family = (unsigned short) family;
   1051     memcpy(&(foo->sin_addr),addr,sizeof(foo->sin_addr));
   1052     *(int *)addr = htonl(*(int *)addr);
   1053     break;
   1054   }
   1055 #if defined(AF_INET6)
   1056   case AF_INET6: {
   1057     struct sockaddr_in6 *foo = (struct sockaddr_in6 *)sockaddr;
   1058     foo->sin6_port = htons((unsigned short) port);
   1059     foo->sin6_family = (unsigned short) family;
   1060     memcpy(&(foo->sin6_addr),addr,sizeof(foo->sin6_addr));
   1061     break;
   1062   }
   1063 #endif
   1064   default:
   1065     fprintf(where,
   1066 	    "set_sockaddr_family_addr_port Unexpected Address Family of %u\n",family);
   1067     fflush(where);
   1068     exit(-1);
   1069   }
   1070 }
   1071 
   1072 /* pull the port and address out of the sockaddr in host format */
   1073 int
   1074 get_sockaddr_family_addr_port(struct sockaddr_storage *sockaddr, int family, void *addr, int *port)
   1075 {
   1076   struct sockaddr_in *sin = (struct sockaddr_in *)sockaddr;
   1077 
   1078   int ret = 0;
   1079   if (sin->sin_family != family) {
   1080     fprintf(where,
   1081 	    "get_sockaddr_family_addr_port family mismatch %d vs %d\n",
   1082 	    sin->sin_family,
   1083 	    family);
   1084     fflush(where);
   1085     return -1;
   1086   }
   1087 
   1088   switch(family) {
   1089 #if defined(AF_RDS)
   1090   case AF_RDS:
   1091 #endif
   1092   case  AF_INET: {
   1093     *port = ntohs(sin->sin_port);
   1094     memcpy(addr,&(sin->sin_addr),sizeof(sin->sin_addr));
   1095     if (*(int *)addr == INADDR_ANY) ret = 1;
   1096     *(int *)addr = ntohl(*(int *)addr);
   1097     break;
   1098   }
   1099 #ifdef AF_INET6
   1100   case AF_INET6: {
   1101     int i;
   1102     struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sockaddr;
   1103     *port = ntohs(sin6->sin6_port);
   1104     ret = 1;
   1105     for (i=0; i < sizeof(struct in6_addr); i++)
   1106       if (sin6->sin6_addr.s6_addr[i] != 0) ret=0;
   1107     memcpy(addr,&(sin6->sin6_addr), sizeof(sin6->sin6_addr));
   1108     break;
   1109   }
   1110 #endif
   1111   default:
   1112     fprintf(where,
   1113 	    "get_sockaddr_family_addr_port: Unexpected Address Family of %u\n",family);
   1114     fflush(where);
   1115     exit(-1);
   1116   }
   1117   return ret;
   1118 }
   1119 
   1120 
   1121 int
   1123 set_socket_tos(SOCKET sock, int family, int socket_tos) {
   1124 
   1125   int my_tos = -3;
   1126   netperf_socklen_t sock_opt_len;
   1127 
   1128   switch (family) {
   1129 #if defined(IP_TOS)
   1130   case AF_INET:
   1131     /* should I mask-away anything above the byte? */
   1132     my_tos = socket_tos;
   1133     if (setsockopt(sock,
   1134 		   IPPROTO_IP,
   1135 		   IP_TOS,
   1136 		   (const char *)&my_tos,sizeof(my_tos)) == SOCKET_ERROR) {
   1137       fprintf(where,
   1138 	      "%s ip_tos failed with %s (errno %d)\n",
   1139 	      __FUNCTION__,
   1140 	      strerror(errno),
   1141 	      errno);
   1142       fflush(where);
   1143       my_tos = -2;
   1144     }
   1145     else {
   1146       sock_opt_len = sizeof(my_tos);
   1147       getsockopt(sock,
   1148 		 IPPROTO_IP,
   1149 		 IP_TOS,
   1150 		 (char *)&my_tos,
   1151 		 &sock_opt_len);
   1152     }
   1153     break;
   1154 #endif
   1155 #if defined(IPV6_TCLASS)
   1156   case AF_INET6:
   1157     /* should I mask-away anything above the byte? */
   1158     my_tos = socket_tos;
   1159     if (setsockopt(sock,
   1160 		   IPPROTO_IPV6,
   1161 		   IPV6_TCLASS,
   1162 		   (const char *)&my_tos,sizeof(my_tos)) == SOCKET_ERROR) {
   1163       fprintf(where,
   1164 	      "%s ip_tos failed with %s (errno %d)\n",
   1165 	      __FUNCTION__,
   1166 	      strerror(errno),
   1167 	      errno);
   1168       fflush(where);
   1169       my_tos = -2;
   1170     }
   1171     else {
   1172       sock_opt_len = sizeof(my_tos);
   1173       getsockopt(sock,
   1174 		 IPPROTO_IPV6,
   1175 		 IPV6_TCLASS,
   1176 		 (char *)&my_tos,
   1177 		 &sock_opt_len);
   1178     }
   1179     break;
   1180 #endif
   1181   }
   1182   return my_tos;
   1183 }
   1184 
   1185 
   1187  /* This routine will create a data (listen) socket with the
   1188   apropriate options set and return it to the caller. this replaces
   1189   all the duplicate code in each of the test routines and should help
   1190   make things a little easier to understand. since this routine can be
   1191   called by either the netperf or netserver programs, all output
   1192   should be directed towards "where." family is generally AF_INET and
   1193   type will be either SOCK_STREAM or SOCK_DGRAM.  This routine will
   1194   also be used by the "SCTP" tests, hence the slightly strange-looking
   1195   SCTP stuff in the classic bsd sockets test file... vlad/raj
   1196   2005-03-15 */
   1197 
   1198 SOCKET
   1199 create_data_socket(struct addrinfo *res)
   1200 {
   1201 
   1202   SOCKET temp_socket;
   1203   int one = 1;
   1204   int on  = 1;
   1205   netperf_socklen_t sock_opt_len;
   1206 
   1207   /*set up the data socket                        */
   1208   temp_socket = socket(res->ai_family,
   1209 		       res->ai_socktype,
   1210 		       res->ai_protocol);
   1211 
   1212   if (temp_socket == INVALID_SOCKET){
   1213     fprintf(where,
   1214 	    "netperf: create_data_socket: socket: errno %d fam %s type %s prot %s errmsg %s\n",
   1215 	    errno,
   1216 	    inet_ftos(res->ai_family),
   1217 	    inet_ttos(res->ai_socktype),
   1218 	    inet_ptos(res->ai_protocol),
   1219 	    strerror(errno));
   1220     fflush(where);
   1221     exit(1);
   1222   }
   1223 
   1224   if (debug) {
   1225     fprintf(where,"create_data_socket: socket %d obtained...\n",temp_socket);
   1226     fflush(where);
   1227   }
   1228 
   1229   /* Modify the local socket size. The reason we alter the send buffer
   1230    size here rather than when the connection is made is to take care
   1231    of decreases in buffer size. Decreasing the window size after
   1232    connection establishment is a TCP no-no. Also, by setting the
   1233    buffer (window) size before the connection is established, we can
   1234    control the TCP MSS (segment size). The MSS is never (well, should
   1235    never be) more that 1/2 the minimum receive buffer size at each
   1236    half of the connection.  This is why we are altering the receive
   1237    buffer size on the sending size of a unidirectional transfer. If
   1238    the user has not requested that the socket buffers be altered, we
   1239    will try to find-out what their values are. If we cannot touch the
   1240    socket buffer in any way, we will set the values to -1 to indicate
   1241    that.  */
   1242 
   1243   /* all the oogy nitty gritty stuff moved from here into the routine
   1244      being called below, per patches from davidm to workaround the bug
   1245      in Linux getsockopt().  raj 2004-06-15 */
   1246   set_sock_buffer (temp_socket, SEND_BUFFER, lss_size_req, &lss_size);
   1247   set_sock_buffer (temp_socket, RECV_BUFFER, lsr_size_req, &lsr_size);
   1248 
   1249   /* now, we may wish to enable the copy avoidance features on the */
   1250   /* local system. of course, this may not be possible... */
   1251 
   1252 #ifdef SO_RCV_COPYAVOID
   1253   /* this is ancient vestigial HP-UX code that should probably go away
   1254      one day */
   1255   if (loc_rcvavoid) {
   1256     if (setsockopt(temp_socket,
   1257 		   SOL_SOCKET,
   1258 		   SO_RCV_COPYAVOID,
   1259 		   (const char *)&loc_rcvavoid,
   1260 		   sizeof(int)) == SOCKET_ERROR) {
   1261       fprintf(where,
   1262 	      "netperf: create_data_socket: Could not enable receive copy avoidance");
   1263       fflush(where);
   1264       loc_rcvavoid = 0;
   1265     }
   1266   }
   1267 #endif
   1268 
   1269 #ifdef SO_SND_COPYAVOID
   1270   if (loc_sndavoid) {
   1271     if (setsockopt(temp_socket,
   1272 		   SOL_SOCKET,
   1273 		   SO_SND_COPYAVOID,
   1274 		   (const char *)&loc_sndavoid,
   1275 		   sizeof(int)) == SOCKET_ERROR) {
   1276       fprintf(where,
   1277 	      "netperf: create_data_socket: Could not enable send copy avoidance");
   1278       fflush(where);
   1279       loc_sndavoid = 0;
   1280     }
   1281   }
   1282 #endif
   1283 
   1284   /* Now, we will see about setting the TCP_NODELAY flag on the local */
   1285   /* socket. We will only do this for those systems that actually */
   1286   /* support the option. If it fails, note the fact, but keep going. */
   1287   /* If the user tries to enable TCP_NODELAY on a UDP socket, this */
   1288   /* will cause an error to be displayed */
   1289 
   1290   /* well..... long ago and far away that would have happened, in
   1291      particular because we would always use IPPROTO_TCP here.
   1292      however, now we are using res->ai_protocol, which will be
   1293      IPPROT_UDP, and while HP-UX, and I suspect no-one else on the
   1294      planet has a UDP_mumble option that overlaps with TCP_NODELAY,
   1295      sure as knuth made little green programs, linux has a UDP_CORK
   1296      option that is defined as a value of 1, which is the same a
   1297      TCP_NODELAY under Linux.  So, when asking for -D and
   1298      "TCP_NODELAY" under Linux, we are actually setting UDP_CORK
   1299      instead of getting an error like every other OS on the
   1300      planet. joy and rupture. this stops a UDP_RR test cold sooo we
   1301      have to make sure that res->ai_protocol actually makes sense for
   1302      a _NODELAY setsockopt() or a UDP_RR test on Linux where someone
   1303      mistakenly sets -D will hang.  raj 2005-04-21 */
   1304 
   1305 #if defined(TCP_NODELAY) || defined(SCTP_NODELAY)
   1306   if ((loc_nodelay) && (res->ai_protocol != IPPROTO_UDP)) {
   1307 
   1308     /* strictly speaking, since the if defined above is an OR, we
   1309        should probably check against TCP_NODELAY being defined here.
   1310        however, the likelihood of SCTP_NODELAY being defined and
   1311        TCP_NODELAY _NOT_ being defined is, probably :), epsilon.  raj
   1312        2005-03-15 */
   1313 
   1314     int option = TCP_NODELAY;
   1315 
   1316     /* I suspect that WANT_SCTP would suffice here since that is the
   1317        only time we would have called getaddrinfo with a hints asking
   1318        for SCTP, but just in case there is an SCTP implementation out
   1319        there _without_ SCTP_NODELAY... raj 2005-03-15 */
   1320     /* change this to IPPROTO_SCTP rather than WANT_SCTP to better fit
   1321        with the modus operandi of the new "omni" tests. raj
   1322        2008-02-04 */
   1323 #if defined(IPPROTO_SCTP) && defined(SCTP_NODELAY)
   1324     if (IPPROTO_SCTP == res->ai_protocol) {
   1325       option = SCTP_NODELAY;
   1326     }
   1327 #endif
   1328 
   1329     one = 1;
   1330     if(setsockopt(temp_socket,
   1331 		  res->ai_protocol,
   1332 		  option,
   1333 		  (char *)&one,
   1334 		  sizeof(one)) == SOCKET_ERROR) {
   1335       fprintf(where,
   1336 	      "netperf: create_data_socket: nodelay: errno %d\n",
   1337 	      errno);
   1338       fflush(where);
   1339     }
   1340 
   1341     if (debug > 1) {
   1342       fprintf(where,
   1343 	      "netperf: create_data_socket: [TCP|SCTP]_NODELAY requested...\n");
   1344       fflush(where);
   1345     }
   1346   }
   1347 #else /* TCP_NODELAY */
   1348 
   1349   loc_nodelay = 0;
   1350 
   1351 #endif /* TCP_NODELAY */
   1352 
   1353   if ((transport_mss_req != -1) && (IPPROTO_TCP == res->ai_protocol)) {
   1354     set_tcp_mss(temp_socket,transport_mss_req);
   1355   }
   1356 
   1357 #if defined(TCP_CORK)
   1358 
   1359   if (loc_tcpcork > 0) {
   1360     /* the user wishes for us to set TCP_CORK on the socket */
   1361     if (setsockopt(temp_socket,
   1362 		   getprotobyname("tcp")->p_proto,
   1363 		   TCP_CORK,
   1364 		   (char *)&one,
   1365 		   sizeof(one)) == SOCKET_ERROR) {
   1366       perror("netperf: create_data_socket: tcp_cork");
   1367       exit(1);
   1368     }
   1369     if (debug) {
   1370       fprintf(where,"create_data_socket: tcp_cork...\n");
   1371     }
   1372   }
   1373 
   1374 #endif /* TCP_CORK */
   1375 
   1376   /* well, after Knuth only knows how many years, I have finally
   1377     decided to enable setting SO_KEEPALIVE on the data socket.  99
   1378     times out of 10 this should not be necessary, but that 100th time,
   1379     perhaps when netperf is being (ab)used by functional testers, may
   1380     benefit from it.  And it may help clean-up some lingering
   1381     netservers from time to time.  raj 2011-06-29 */
   1382 
   1383 #if defined(SO_KEEPALIVE)
   1384 
   1385   if (want_keepalive) {
   1386     if (setsockopt(temp_socket,
   1387 		   SOL_SOCKET,
   1388 		   SO_KEEPALIVE,
   1389 		   (const char *)&on,
   1390 		   sizeof(on)) < 0) {
   1391       if (debug) {
   1392 	fprintf(where,
   1393 		"%s: unable to set SO_KEEPALIVE on data socket: %s (errno %d)\n",
   1394 		__FUNCTION__,
   1395 		strerror(errno),
   1396 		errno);
   1397 	fflush(where);
   1398       }
   1399     }
   1400   }
   1401 
   1402 #endif /* SO_KEEPALIVE */
   1403 
   1404   /* since some of the UDP tests do not do anything to cause an
   1405      implicit bind() call, we need to be rather explicit about our
   1406      bind() call here. even if the address and/or the port are zero
   1407      (INADDR_ANY etc). raj 2004-07-20 */
   1408 
   1409   if (setsockopt(temp_socket,
   1410 #ifdef IPPROTO_DCCP
   1411 		 /* it is REALLY SILLY THAT THIS SHOULD BE NEEDED!! I
   1412 		    should be able to use SOL_SOCKET for this just
   1413 		    like TCP and SCTP */
   1414 		 /* IT IS EVEN SILLIER THAT THERE COULD BE SYSTEMS
   1415 		    WITH IPPROTO_DCCP and no SOL_DCCP */
   1416 #ifndef SOL_DCCP
   1417 #define SOL_DCCP SOL_SOCKET
   1418 #define NETPERF_NEED_CLEANUP 1
   1419 #endif
   1420 		 (res->ai_protocol == IPPROTO_DCCP) ? SOL_DCCP : SOL_SOCKET,
   1421 #ifdef NETPERF_NEED_CLEANUP
   1422 #undef SOL_DCCP
   1423 #undef NETPERF_NEED_CLEANUP
   1424 #endif
   1425 
   1426 #else
   1427 		 SOL_SOCKET,
   1428 #endif
   1429 		 SO_REUSEADDR,
   1430 		 (const char *)&on,
   1431 		 sizeof(on)) < 0) {
   1432     fprintf(where,
   1433 	    "netperf: create_data_socket: SO_REUSEADDR failed %d\n",
   1434 	    errno);
   1435     fflush(where);
   1436   }
   1437 
   1438   if (bind(temp_socket,
   1439 	   res->ai_addr,
   1440 	   res->ai_addrlen) < 0) {
   1441     if (debug) {
   1442       fprintf(where,
   1443 	      "netperf: create_data_socket: data socket bind failed: %s (errno %d)\n",
   1444 	      strerror(errno),
   1445 	      errno);
   1446       fprintf(where," port: %d\n",get_port_number(res));
   1447       fflush(where);
   1448     }
   1449   }
   1450 
   1451   /* this one is a slightly grudgingly added backside covering for
   1452      those folks who (ab)use netperf as a functional testing tool, and
   1453      further compound that error by running tests on systems also
   1454      connected to their site networks, and then compound it even
   1455      further compound it by running UDP_STREAM tests over links that
   1456      generate link-down events and so cause the traffic to be sent out
   1457      the default route into their corporate network...  frankly such
   1458      people should not be allowed to run netperf in the first place
   1459      but there we are... raj 20091026 */
   1460 
   1461 #if defined (SO_DONTROUTE)
   1462   if (!routing_allowed) {
   1463     if (setsockopt(temp_socket,
   1464 		   SOL_SOCKET,
   1465 		   SO_DONTROUTE,
   1466 		   (char *)&one,
   1467 		   sizeof(one)) == SOCKET_ERROR) {
   1468       fprintf(where,
   1469 	      "netperf: create_data_socket: so_dontroute: errno %d\n",
   1470 	      errno);
   1471       fflush(where);
   1472     }
   1473   }
   1474 #endif
   1475 
   1476 #if defined(SO_PRIORITY)
   1477   if (local_socket_prio >= 0) {
   1478     if (setsockopt(temp_socket,
   1479                   SOL_SOCKET,
   1480                   SO_PRIORITY,
   1481                   &local_socket_prio,
   1482                   sizeof(int)) == SOCKET_ERROR) {
   1483       fprintf(where,
   1484              "netperf: create_data_socket: so_priority: errno %d\n",
   1485              errno);
   1486       fflush(where);
   1487       local_socket_prio = -2;
   1488     }
   1489     else {
   1490       sock_opt_len = 4;
   1491       getsockopt(temp_socket,
   1492 		 SOL_SOCKET,
   1493 		 SO_PRIORITY,
   1494 		 &local_socket_prio,
   1495 		 &sock_opt_len);
   1496     }
   1497   }
   1498 #else
   1499   local_socket_prio = -3;
   1500 #endif
   1501 
   1502 #if defined (IP_TOS) || defined(IPV6_TCLASS)
   1503   if (local_socket_tos > 0)
   1504     local_socket_tos = set_socket_tos(temp_socket,res->ai_family, local_socket_tos);
   1505 #endif
   1506 
   1507   return temp_socket;
   1508 }
   1509 
   1510 #ifdef KLUDGE_SOCKET_OPTIONS
   1511 
   1512 
   1513  /* This routine is for those BROKEN systems which do not correctly */
   1515  /* pass socket attributes through calls such as accept(). It should */
   1516  /* only be called for those broken systems. I *really* don't want to */
   1517  /* have this, but even broken systems must be measured. raj 11/95 */
   1518 void
   1519 kludge_socket_options(int temp_socket)
   1520 {
   1521 
   1522   set_sock_buffer(temp_socket, SEND_BUFFER, lss_size_req, &lss_size);
   1523   set_sock_buffer(temp_socket, RECV_BUFFER, lsr_size_req, &lsr_size);
   1524 
   1525   /* now, we may wish to enable the copy avoidance features on the */
   1526   /* local system. of course, this may not be possible... */
   1527   /* those calls were only valid for HP-UX, and I know that HP-UX is */
   1528   /* written correctly, and so we do not need to include those calls */
   1529   /* in this kludgy routine. raj 11/95 */
   1530 
   1531 
   1532   /* Now, we will see about setting the TCP_NODELAY flag on the local */
   1533   /* socket. We will only do this for those systems that actually */
   1534   /* support the option. If it fails, note the fact, but keep going. */
   1535   /* If the user tries to enable TCP_NODELAY on a UDP socket, this */
   1536   /* will cause an error to be displayed */
   1537 
   1538 #ifdef TCP_NODELAY
   1539   if (loc_nodelay) {
   1540     one = 1;
   1541     if(setsockopt(temp_socket,
   1542 		  getprotobyname("tcp")->p_proto,
   1543 		  TCP_NODELAY,
   1544 		  (char *)&one,
   1545 		  sizeof(one)) == SOCKET_ERROR) {
   1546       fprintf(where,"netperf: kludge_socket_options: nodelay: errno %d\n",
   1547 	      errno);
   1548       fflush(where);
   1549     }
   1550 
   1551     if (debug > 1) {
   1552       fprintf(where,
   1553 	      "netperf: kludge_socket_options: TCP_NODELAY requested...\n");
   1554       fflush(where);
   1555     }
   1556   }
   1557 #else /* TCP_NODELAY */
   1558 
   1559   loc_nodelay = 0;
   1560 
   1561 #endif /* TCP_NODELAY */
   1562 
   1563   }
   1564 
   1565 #endif /* KLUDGE_SOCKET_OPTIONS */
   1566 
   1567 
   1569 static void *
   1570 get_address_address(struct addrinfo *info)
   1571 {
   1572   struct sockaddr_in *sin;
   1573 #if defined(AF_INET6)
   1574   struct sockaddr_in6 *sin6;
   1575 #endif
   1576 
   1577   switch(info->ai_family) {
   1578   case AF_INET:
   1579     sin = (struct sockaddr_in *)info->ai_addr;
   1580     return(&(sin->sin_addr));
   1581     break;
   1582 #if defined(AF_INET6)
   1583   case AF_INET6:
   1584     sin6 = (struct sockaddr_in6 *)info->ai_addr;
   1585     return(&(sin6->sin6_addr));
   1586     break;
   1587 #endif
   1588   default:
   1589     fprintf(stderr,"we never expected to get here in get_address_address\n");
   1590     fflush(stderr);
   1591     exit(-1);
   1592   }
   1593 }
   1594 
   1595 #if defined(WIN32)
   1596 #if !defined(InetNtop)
   1597 /* +*+ Why isn't this in the winsock headers yet? */
   1598 const char *
   1599 inet_ntop(int af, const void *src, char *dst, size_t size);
   1600 #endif
   1601 #endif
   1602 
   1603 /* This routine is a generic test header printer for the topmost header */
   1604 void
   1605 print_top_test_header(char test_name[], struct addrinfo *source, struct addrinfo *destination)
   1606 {
   1607 
   1608   char *address_buf;
   1609 
   1610 #ifdef AF_INET6
   1611   address_buf = malloc(INET6_ADDRSTRLEN);
   1612 #else
   1613   address_buf = malloc(16); /* magic constant */
   1614 #endif
   1615 
   1616   if (address_buf == NULL) {
   1617     fprintf(where,"Unable to allocate address_buf\n");
   1618     fflush(where);
   1619     exit(1);
   1620   }
   1621 
   1622   /* we want to have some additional, interesting information in the
   1623      headers. we know some of it here, but not all, so we will only
   1624      print the test title here and will print the results titles after
   1625      the test is finished */
   1626   fprintf(where,"%s",test_name);
   1627 
   1628   address_buf[0] = '\0';
   1629   inet_ntop(source->ai_family,get_address_address(source),address_buf,sizeof(address_buf));
   1630   fprintf(where,
   1631 	  " from %s (%s) port %u %s",
   1632 	  source->ai_canonname,
   1633 	  address_buf,
   1634 	  get_port_number(source),
   1635 	  inet_ftos(source->ai_family));
   1636 
   1637   address_buf[0] = '\0';
   1638   inet_ntop(destination->ai_family,get_address_address(destination),address_buf,sizeof(address_buf));
   1639   fprintf(where,
   1640 	  " to %s (%s) port %u %s",
   1641 	  destination->ai_canonname,
   1642 	  address_buf,
   1643 	  get_port_number(destination),
   1644 	  inet_ftos(destination->ai_family));
   1645 
   1646   if (iteration_max > 1) {
   1647     fprintf(where,
   1648 	    " : +/-%.3f%% @ %2d%% conf. %s",
   1649 	    interval/0.02,
   1650 	    confidence_level,
   1651 	    result_confidence_only ? " on result only" : "");
   1652   }
   1653   if ((loc_nodelay > 0) || (rem_nodelay > 0)) {
   1654     fprintf(where," : nodelay");
   1655   }
   1656   if ((loc_sndavoid > 0) ||
   1657       (loc_rcvavoid > 0) ||
   1658       (rem_sndavoid > 0) ||
   1659       (rem_rcvavoid > 0)) {
   1660     fprintf(where," : copy avoidance");
   1661   }
   1662 
   1663   if (no_control) {
   1664     fprintf(where," : no control");
   1665   }
   1666 
   1667 #ifdef WANT_HISTOGRAM
   1668   fprintf(where," : histogram");
   1669 #endif /* WANT_HISTOGRAM */
   1670 
   1671 #ifdef WANT_INTERVALS
   1672 #ifndef WANT_SPIN
   1673   fprintf(where," : interval");
   1674 #else
   1675   fprintf(where," : spin interval");
   1676 #endif
   1677 #endif /* WANT_INTERVALS */
   1678 
   1679 #ifdef DIRTY
   1680   fprintf(where," : dirty data");
   1681 #endif /* DIRTY */
   1682 #ifdef WANT_DEMO
   1683   fprintf(where," : demo");
   1684 #endif
   1685 #ifdef WANT_FIRST_BURST
   1686   /* a little hokey perhaps, but we really only want this to be
   1687      emitted for tests where it actually is used, which means a
   1688      "REQUEST/RESPONSE" test. raj 2005-11-10 */
   1689   if (strstr(test_name,"REQUEST/RESPONSE")) {
   1690     fprintf(where," : first burst %d",first_burst_size);
   1691   }
   1692 #endif
   1693   if (cpu_binding_requested) {
   1694     fprintf(where," : cpu bind");
   1695   }
   1696   fprintf(where,"\n");
   1697 
   1698   free(address_buf);
   1699 }
   1700 
   1701 /* if WANT_MIGRATION is defined, we will use the send_tcp_stream()
   1702    call in src/nettest_omni.c */
   1703 #ifndef WANT_MIGRATION
   1704 
   1705 /* This routine implements the TCP unidirectional data transfer test */
   1706 /* (a.k.a. stream) for the sockets interface. It receives its */
   1707 /* parameters via global variables from the shell and writes its */
   1708 /* output to the standard output. */
   1709 
   1710 void
   1711 send_tcp_stream(char remote_host[])
   1712 {
   1713 
   1714   char *tput_title = "\
   1715 Recv   Send    Send                          \n\
   1716 Socket Socket  Message  Elapsed              \n\
   1717 Size   Size    Size     Time     Throughput  \n\
   1718 bytes  bytes   bytes    secs.    %s/sec  \n\n";
   1719 
   1720   char *tput_fmt_0 =
   1721     "%7.2f %s\n";
   1722 
   1723   char *tput_fmt_1 =
   1724     "%6d %6d %6d    %-6.2f   %7.2f   %s\n";
   1725 
   1726   char *cpu_title = "\
   1727 Recv   Send    Send                          Utilization       Service Demand\n\
   1728 Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
   1729 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
   1730 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
   1731 
   1732   char *cpu_fmt_0 =
   1733     "%6.3f %c %s\n";
   1734 
   1735   char *cpu_fmt_1 =
   1736     "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f %s\n";
   1737 
   1738   char *ksink_fmt = "\n\
   1739 Alignment      Offset         %-8.8s %-8.8s    Sends   %-8.8s Recvs\n\
   1740 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
   1741 Send   Recv    Send   Recv             Send (avg)          Recv (avg)\n\
   1742 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
   1743 
   1744   char *ksink_fmt2 = "\n\
   1745 Maximum\n\
   1746 Segment\n\
   1747 Size (bytes)\n\
   1748 %6d\n";
   1749 
   1750 
   1751   float			elapsed_time;
   1752 
   1753   /* what we want is to have a buffer space that is at least one */
   1754   /* send-size greater than our send window. this will insure that we */
   1755   /* are never trying to re-use a buffer that may still be in the hands */
   1756   /* of the transport. This buffer will be malloc'd after we have found */
   1757   /* the size of the local senc socket buffer. We will want to deal */
   1758   /* with alignment and offset concerns as well. */
   1759 
   1760   struct ring_elt *send_ring;
   1761 
   1762   int len;
   1763   unsigned int nummessages = 0;
   1764   SOCKET send_socket;
   1765   int bytes_remaining;
   1766   int tcp_mss = -1;  /* possibly uninitialized on printf far below */
   1767 
   1768   /* with links like fddi, one can send > 32 bits worth of bytes
   1769      during a test... ;-) at some point, this should probably become a
   1770      64bit integral type, but those are not entirely common
   1771      yet... time passes, and 64 bit types do indeed become common. */
   1772 #if defined(WIN32) && _MSC_VER <= 1200
   1773   __int64 local_bytes_sent = 0;
   1774 #else
   1775   unsigned long long local_bytes_sent = 0;
   1776 #endif
   1777 
   1778   double	bytes_sent = 0.0;
   1779 
   1780   float	local_cpu_utilization;
   1781   float	local_service_demand;
   1782   float	remote_cpu_utilization;
   1783   float	remote_service_demand;
   1784 
   1785   double	thruput;
   1786 
   1787   struct addrinfo *remote_res;
   1788   struct addrinfo *local_res;
   1789 
   1790   struct	tcp_stream_request_struct	*tcp_stream_request;
   1791   struct	tcp_stream_response_struct	*tcp_stream_response;
   1792   struct	tcp_stream_results_struct	*tcp_stream_result;
   1793 
   1794   tcp_stream_request  =
   1795     (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
   1796   tcp_stream_response =
   1797     (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
   1798   tcp_stream_result   =
   1799     (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
   1800 
   1801 #ifdef WANT_HISTOGRAM
   1802   if (verbosity > 1) {
   1803     time_hist = HIST_new();
   1804   }
   1805 #endif /* WANT_HISTOGRAM */
   1806   /* since we are now disconnected from the code that established the */
   1807   /* control socket, and since we want to be able to use different */
   1808   /* protocols and such, we are passed the name of the remote host and */
   1809   /* must turn that into the test specific addressing information. */
   1810 
   1811   /* complete_addrinfos will either succede or exit the process */
   1812   complete_addrinfos(&remote_res,
   1813 		     &local_res,
   1814 		     remote_host,
   1815 		     SOCK_STREAM,
   1816 		     IPPROTO_TCP,
   1817 		     0);
   1818 
   1819   if ( print_headers ) {
   1820     print_top_test_header("TCP STREAM TEST",local_res,remote_res);
   1821   }
   1822 
   1823   send_ring = NULL;
   1824   confidence_iteration = 1;
   1825   init_stat();
   1826 
   1827   /* we have a great-big while loop which controls the number of times */
   1828   /* we run a particular test. this is for the calculation of a */
   1829   /* confidence interval (I really should have stayed awake during */
   1830   /* probstats :). If the user did not request confidence measurement */
   1831   /* (no confidence is the default) then we will only go though the */
   1832   /* loop once. the confidence stuff originates from the folks at IBM */
   1833 
   1834   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   1835 	 (confidence_iteration <= iteration_min)) {
   1836 
   1837     /* initialize a few counters. we have to remember that we might be */
   1838     /* going through the loop more than once. */
   1839 
   1840     nummessages    =	0;
   1841     bytes_sent     =	0.0;
   1842     times_up       = 	0;
   1843 
   1844     /*set up the data socket                        */
   1845     send_socket = create_data_socket(local_res);
   1846 
   1847     if (send_socket == INVALID_SOCKET){
   1848       perror("netperf: send_tcp_stream: tcp stream data socket");
   1849       exit(1);
   1850     }
   1851 
   1852     if (debug) {
   1853       fprintf(where,"send_tcp_stream: send_socket obtained...\n");
   1854     }
   1855 
   1856     /* at this point, we have either retrieved the socket buffer sizes, */
   1857     /* or have tried to set them, so now, we may want to set the send */
   1858     /* size based on that (because the user either did not use a -m */
   1859     /* option, or used one with an argument of 0). If the socket buffer */
   1860     /* size is not available, we will set the send size to 4KB - no */
   1861     /* particular reason, just arbitrary... */
   1862     if (send_size == 0) {
   1863       if (lss_size > 0) {
   1864 	send_size = lss_size;
   1865       }
   1866       else {
   1867 	send_size = 4096;
   1868       }
   1869     }
   1870 
   1871     /* set-up the data buffer ring with the requested alignment and offset. */
   1872     /* note also that we have allocated a quantity */
   1873     /* of memory that is at least one send-size greater than our socket */
   1874     /* buffer size. We want to be sure that there are at least two */
   1875     /* buffers allocated - this can be a bit of a problem when the */
   1876     /* send_size is bigger than the socket size, so we must check... the */
   1877     /* user may have wanted to explicitly set the "width" of our send */
   1878     /* buffers, we should respect that wish... */
   1879     if (send_width == 0) {
   1880       send_width = (lss_size/send_size) + 1;
   1881       if (send_width == 1) send_width++;
   1882     }
   1883 
   1884     if (send_ring == NULL) {
   1885       /* only allocate the send ring once. this is a networking test, */
   1886       /* not a memory allocation test. this way, we do not need a */
   1887       /* deallocate_buffer_ring() routine, and I don't feel like */
   1888       /* writing one anyway :) raj 11/94 */
   1889       send_ring = allocate_buffer_ring(send_width,
   1890 				       send_size,
   1891 				       local_send_align,
   1892 				       local_send_offset);
   1893     }
   1894 
   1895     /* If the user has requested cpu utilization measurements, we must */
   1896     /* calibrate the cpu(s). We will perform this task within the tests */
   1897     /* themselves. If the user has specified the cpu rate, then */
   1898     /* calibrate_local_cpu will return rather quickly as it will have */
   1899     /* nothing to do. If local_cpu_rate is zero, then we will go through */
   1900     /* all the "normal" calibration stuff and return the rate back. */
   1901 
   1902     if (local_cpu_usage) {
   1903       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   1904     }
   1905 
   1906     if (!no_control) {
   1907       /* Tell the remote end to do a listen. The server alters the
   1908 	 socket paramters on the other side at this point, hence the
   1909 	 reason for all the values being passed in the setup
   1910 	 message. If the user did not specify any of the parameters,
   1911 	 they will be passed as 0, which will indicate to the remote
   1912 	 that no changes beyond the system's default should be
   1913 	 used. Alignment is the exception, it will default to 1, which
   1914 	 will be no alignment alterations. */
   1915 
   1916       netperf_request.content.request_type =	DO_TCP_STREAM;
   1917       tcp_stream_request->send_buf_size	=	rss_size_req;
   1918       tcp_stream_request->recv_buf_size	=	rsr_size_req;
   1919       tcp_stream_request->receive_size	=	recv_size;
   1920       tcp_stream_request->no_delay	=	rem_nodelay;
   1921       tcp_stream_request->recv_alignment	=	remote_recv_align;
   1922       tcp_stream_request->recv_offset	=	remote_recv_offset;
   1923       tcp_stream_request->measure_cpu	=	remote_cpu_usage;
   1924       tcp_stream_request->cpu_rate	=	remote_cpu_rate;
   1925       if (test_time) {
   1926 	tcp_stream_request->test_length	=	test_time;
   1927       }
   1928       else {
   1929 	tcp_stream_request->test_length	=	test_bytes;
   1930       }
   1931       tcp_stream_request->so_rcvavoid	=	rem_rcvavoid;
   1932       tcp_stream_request->so_sndavoid	=	rem_sndavoid;
   1933 #ifdef DIRTY
   1934       tcp_stream_request->dirty_count     =       rem_dirty_count;
   1935       tcp_stream_request->clean_count     =       rem_clean_count;
   1936 #endif /* DIRTY */
   1937       tcp_stream_request->port            =    atoi(remote_data_port);
   1938       tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
   1939       if (debug > 1) {
   1940 	fprintf(where,
   1941 		"netperf: send_tcp_stream: requesting TCP stream test\n");
   1942       }
   1943 
   1944       send_request();
   1945 
   1946       /* The response from the remote will contain all of the relevant
   1947          socket parameters for this test type. We will put them back
   1948          into the variables here so they can be displayed if desired.
   1949          The remote will have calibrated CPU if necessary, and will
   1950          have done all the needed set-up we will have calibrated the
   1951          cpu locally before sending the request, and will grab the
   1952          counter value right after the connect returns. The remote
   1953          will grab the counter right after the accept call. This saves
   1954          the hassle of extra messages being sent for the TCP
   1955          tests.  */
   1956 
   1957       recv_response();
   1958 
   1959       if (!netperf_response.content.serv_errno) {
   1960 	if (debug)
   1961 	  fprintf(where,"remote listen done.\n");
   1962 	rsr_size	      =	tcp_stream_response->recv_buf_size;
   1963 	rss_size	      =	tcp_stream_response->send_buf_size;
   1964 	rem_nodelay     =	tcp_stream_response->no_delay;
   1965 	remote_cpu_usage=	tcp_stream_response->measure_cpu;
   1966 	remote_cpu_rate = tcp_stream_response->cpu_rate;
   1967 
   1968 	/* we have to make sure that the server port number is in
   1969 	   network order */
   1970 	set_port_number(remote_res,
   1971 			(short)tcp_stream_response->data_port_number);
   1972 
   1973 	rem_rcvavoid	= tcp_stream_response->so_rcvavoid;
   1974 	rem_sndavoid	= tcp_stream_response->so_sndavoid;
   1975       }
   1976       else {
   1977 	Set_errno(netperf_response.content.serv_errno);
   1978 	fprintf(where,
   1979 		"netperf: remote error %d",
   1980 		netperf_response.content.serv_errno);
   1981 	perror("");
   1982 	fflush(where);
   1983 
   1984 	exit(1);
   1985       }
   1986     }
   1987 
   1988 #ifdef WANT_DEMO
   1989     demo_stream_setup(lss_size,rsr_size);
   1990 #endif
   1991 
   1992     /*Connect up to the remote port on the data socket  */
   1993     if (connect(send_socket,
   1994 		remote_res->ai_addr,
   1995 		remote_res->ai_addrlen) == INVALID_SOCKET){
   1996       perror("netperf: send_tcp_stream: data socket connect failed");
   1997       exit(1);
   1998     }
   1999 
   2000 #ifdef WIN32
   2001   /* this is used so the timer thread can close the socket out from */
   2002   /* under us, which to date is the easiest/cleanest/least */
   2003   /* Windows-specific way I can find to force the winsock calls to */
   2004   /* return WSAEINTR with the test is over. anything that will run on */
   2005   /* 95 and NT and is closer to what netperf expects from Unix signals */
   2006   /* and such would be appreciated raj 1/96 */
   2007   win_kludge_socket = send_socket;
   2008 #endif /* WIN32 */
   2009 
   2010     /* Data Socket set-up is finished. If there were problems, either */
   2011     /* the connect would have failed, or the previous response would */
   2012     /* have indicated a problem. I failed to see the value of the */
   2013     /* extra  message after the accept on the remote. If it failed, */
   2014     /* we'll see it here. If it didn't, we might as well start pumping */
   2015     /* data. */
   2016 
   2017     /* Set-up the test end conditions. For a stream test, they can be */
   2018     /* either time or byte-count based. */
   2019 
   2020     if (test_time) {
   2021       /* The user wanted to end the test after a period of time. */
   2022       times_up = 0;
   2023       bytes_remaining = 0;
   2024       /* in previous revisions, we had the same code repeated throught */
   2025       /* all the test suites. this was unnecessary, and meant more */
   2026       /* work for me when I wanted to switch to POSIX signals, so I */
   2027       /* have abstracted this out into a routine in netlib.c. if you */
   2028       /* are experiencing signal problems, you might want to look */
   2029       /* there. raj 11/94 */
   2030       start_timer(test_time);
   2031     }
   2032     else {
   2033       /* The tester wanted to send a number of bytes. */
   2034       bytes_remaining = test_bytes;
   2035       times_up = 1;
   2036     }
   2037 
   2038     /* The cpu_start routine will grab the current time and possibly */
   2039     /* value of the idle counter for later use in measuring cpu */
   2040     /* utilization and/or service demand and thruput. */
   2041 
   2042     cpu_start(local_cpu_usage);
   2043 
   2044     /* we only start the interval timer if we are using the
   2045        timer-timed intervals rather than the sit and spin ones. raj
   2046        2006-02-06 */
   2047 #if defined(WANT_INTERVALS)
   2048     INTERVALS_INIT();
   2049 #endif /* WANT_INTERVALS */
   2050 
   2051     /* before we start, initialize a few variables */
   2052 
   2053 #ifdef WANT_DEMO
   2054       if (demo_mode) {
   2055 	demo_first_timestamp();
   2056       }
   2057 #endif
   2058 
   2059 
   2060     /* We use an "OR" to control test execution. When the test is */
   2061     /* controlled by time, the byte count check will always return false. */
   2062     /* When the test is controlled by byte count, the time test will */
   2063     /* always return false. When the test is finished, the whole */
   2064     /* expression will go false and we will stop sending data. */
   2065 
   2066     while ((!times_up) || (bytes_remaining > 0)) {
   2067 
   2068 #ifdef DIRTY
   2069       access_buffer(send_ring->buffer_ptr,
   2070 		    send_size,
   2071 		    loc_dirty_count,
   2072 		    loc_clean_count);
   2073 #endif /* DIRTY */
   2074 
   2075 #ifdef WANT_HISTOGRAM
   2076       if (verbosity > 1) {
   2077 	/* timestamp just before we go into send and then again just
   2078 	 after we come out raj 8/94 */
   2079 	/* but lets only do this if there is going to be a histogram
   2080 	   displayed */
   2081 	HIST_timestamp(&time_one);
   2082       }
   2083 #endif /* WANT_HISTOGRAM */
   2084 
   2085       if((len=send(send_socket,
   2086 		   send_ring->buffer_ptr,
   2087 		   send_size,
   2088 		   0)) != send_size) {
   2089       if ((len >=0) || SOCKET_EINTR(len)) {
   2090 	    /* the test was interrupted, must be the end of test */
   2091 	    break;
   2092 	  }
   2093 	perror("netperf: data send error");
   2094 	printf("len was %d\n",len);
   2095 	exit(1);
   2096       }
   2097 
   2098       local_bytes_sent += send_size;
   2099 
   2100 #ifdef WANT_HISTOGRAM
   2101       if (verbosity > 1) {
   2102 	/* timestamp the exit from the send call and update the histogram */
   2103 	HIST_timestamp(&time_two);
   2104 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   2105       }
   2106 #endif /* WANT_HISTOGRAM */
   2107 
   2108 #ifdef WANT_DEMO
   2109       demo_stream_interval(send_size);
   2110 #endif
   2111 
   2112 #if defined(WANT_INTERVALS)
   2113       INTERVALS_WAIT();
   2114 #endif /* WANT_INTERVALS */
   2115 
   2116       /* now we want to move our pointer to the next position in the */
   2117       /* data buffer...we may also want to wrap back to the "beginning" */
   2118       /* of the bufferspace, so we will mod the number of messages sent */
   2119       /* by the send width, and use that to calculate the offset to add */
   2120       /* to the base pointer. */
   2121       nummessages++;
   2122       send_ring = send_ring->next;
   2123       if (bytes_remaining) {
   2124 	bytes_remaining -= send_size;
   2125       }
   2126     }
   2127 
   2128     /* The test is over. Flush the buffers to the remote end. We do a */
   2129     /* graceful release to insure that all data has been taken by the */
   2130     /* remote. */
   2131 
   2132     /* but first, if the verbosity is greater than 1, find-out what */
   2133     /* the TCP maximum segment_size was (if possible) */
   2134     if (verbosity > 1) {
   2135       tcp_mss = -1;
   2136       get_tcp_info(send_socket,&tcp_mss);
   2137     }
   2138 
   2139     if (shutdown(send_socket,SHUT_WR) == SOCKET_ERROR && !times_up) {
   2140       perror("netperf: cannot shutdown tcp stream socket");
   2141       exit(1);
   2142     }
   2143 
   2144     /* hang a recv() off the socket to block until the remote has */
   2145     /* brought all the data up into the application. it will do a */
   2146     /* shutdown to cause a FIN to be sent our way. We will assume that */
   2147     /* any exit from the recv() call is good... raj 4/93 */
   2148 
   2149     recv(send_socket, send_ring->buffer_ptr, send_size, 0);
   2150 
   2151     /* this call will always give us the elapsed time for the test, and */
   2152     /* will also store-away the necessaries for cpu utilization */
   2153 
   2154     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
   2155 						/* measured and how */
   2156 						/* long did we really */
   2157 						/* run? */
   2158 
   2159     /* we are finished with the socket, so close it to prevent hitting */
   2160     /* the limit on maximum open files. */
   2161 
   2162     close(send_socket);
   2163 
   2164 #if defined(WANT_INTERVALS)
   2165 #ifdef WIN32
   2166   stop_itimer();
   2167 #endif
   2168 #endif /* WANT_INTERVALS */
   2169 
   2170     if (!no_control) {
   2171       /* Get the statistics from the remote end. The remote will have
   2172 	 calculated service demand and all those interesting
   2173 	 things. If it wasn't supposed to care, it will return obvious
   2174 	 values. */
   2175 
   2176       recv_response();
   2177       if (!netperf_response.content.serv_errno) {
   2178 	if (debug)
   2179 	  fprintf(where,
   2180 		  "remote reporting results for %.2f seconds\n",
   2181 		  tcp_stream_result->elapsed_time);
   2182       }
   2183       else {
   2184 	Set_errno(netperf_response.content.serv_errno);
   2185 	fprintf(where,
   2186 		"netperf: remote error %d",
   2187 		netperf_response.content.serv_errno);
   2188 	perror("");
   2189 	fflush(where);
   2190 
   2191 	exit(1);
   2192       }
   2193 
   2194       /* We now calculate what our thruput was for the test. In the
   2195 	 future, we may want to include a calculation of the thruput
   2196 	 measured by the remote, but it should be the case that for a
   2197 	 TCP stream test, that the two numbers should be *very*
   2198 	 close... We calculate bytes_sent regardless of the way the
   2199 	 test length was controlled.  If it was time, we needed to,
   2200 	 and if it was by bytes, the user may have specified a number
   2201 	 of bytes that wasn't a multiple of the send_size, so we
   2202 	 really didn't send what he asked for ;-) */
   2203 
   2204       bytes_sent	= ntohd(tcp_stream_result->bytes_received);
   2205     }
   2206     else {
   2207       bytes_sent = (double)local_bytes_sent;
   2208     }
   2209 
   2210     thruput	= calc_thruput(bytes_sent);
   2211 
   2212     if (local_cpu_usage || remote_cpu_usage) {
   2213       /* We must now do a little math for service demand and cpu */
   2214       /* utilization for the system(s) */
   2215       /* Of course, some of the information might be bogus because */
   2216       /* there was no idle counter in the kernel(s). We need to make */
   2217       /* a note of this for the user's benefit...*/
   2218       if (local_cpu_usage) {
   2219 
   2220 	local_cpu_utilization	= calc_cpu_util(0.0);
   2221 	local_service_demand	= calc_service_demand(bytes_sent,
   2222 						      0.0,
   2223 						      0.0,
   2224 						      0);
   2225       }
   2226       else {
   2227 	local_cpu_utilization	= (float) -1.0;
   2228 	local_service_demand	= (float) -1.0;
   2229       }
   2230 
   2231       if (remote_cpu_usage) {
   2232 
   2233 	remote_cpu_utilization	= tcp_stream_result->cpu_util;
   2234 	remote_service_demand	= calc_service_demand(bytes_sent,
   2235 						      0.0,
   2236 						      remote_cpu_utilization,
   2237 						      tcp_stream_result->num_cpus);
   2238       }
   2239       else {
   2240 	remote_cpu_utilization = (float) -1.0;
   2241 	remote_service_demand  = (float) -1.0;
   2242       }
   2243     }
   2244     else {
   2245       /* we were not measuring cpu, for the confidence stuff, we */
   2246       /* should make it -1.0 */
   2247       local_cpu_utilization	= (float) -1.0;
   2248       local_service_demand	= (float) -1.0;
   2249       remote_cpu_utilization = (float) -1.0;
   2250       remote_service_demand  = (float) -1.0;
   2251     }
   2252 
   2253     /* at this point, we want to calculate the confidence information. */
   2254     /* if debugging is on, calculate_confidence will print-out the */
   2255     /* parameters we pass it */
   2256 
   2257     calculate_confidence(confidence_iteration,
   2258 			 elapsed_time,
   2259 			 thruput,
   2260 			 local_cpu_utilization,
   2261 			 remote_cpu_utilization,
   2262 			 local_service_demand,
   2263 			 remote_service_demand);
   2264 
   2265 
   2266     confidence_iteration++;
   2267   }
   2268 
   2269   /* at this point, we have finished making all the runs that we */
   2270   /* will be making. so, we should extract what the calcuated values */
   2271   /* are for all the confidence stuff. we could make the values */
   2272   /* global, but that seemed a little messy, and it did not seem worth */
   2273   /* all the mucking with header files. so, we create a routine much */
   2274   /* like calcualte_confidence, which just returns the mean values. */
   2275   /* raj 11/94 */
   2276 
   2277   retrieve_confident_values(&elapsed_time,
   2278 			    &thruput,
   2279 			    &local_cpu_utilization,
   2280 			    &remote_cpu_utilization,
   2281 			    &local_service_demand,
   2282 			    &remote_service_demand);
   2283 
   2284   /* We are now ready to print all the information. If the user */
   2285   /* has specified zero-level verbosity, we will just print the */
   2286   /* local service demand, or the remote service demand. If the */
   2287   /* user has requested verbosity level 1, he will get the basic */
   2288   /* "streamperf" numbers. If the user has specified a verbosity */
   2289   /* of greater than 1, we will display a veritable plethora of */
   2290   /* background information from outside of this block as it it */
   2291   /* not cpu_measurement specific...  */
   2292 
   2293   if (confidence < 0) {
   2294     /* we did not hit confidence, but were we asked to look for it? */
   2295     if (iteration_max > 1) {
   2296       display_confidence();
   2297     }
   2298   }
   2299 
   2300   if (local_cpu_usage || remote_cpu_usage) {
   2301     local_cpu_method = format_cpu_method(cpu_method);
   2302     remote_cpu_method = format_cpu_method(tcp_stream_result->cpu_method);
   2303 
   2304     switch (verbosity) {
   2305     case 0:
   2306       if (local_cpu_usage) {
   2307 	fprintf(where,
   2308 		cpu_fmt_0,
   2309 		local_service_demand,
   2310 		local_cpu_method,
   2311 		((print_headers) ||
   2312 		 (result_brand == NULL)) ? "" : result_brand);
   2313       }
   2314       else {
   2315 	fprintf(where,
   2316 		cpu_fmt_0,
   2317 		remote_service_demand,
   2318 		remote_cpu_method,
   2319 		((print_headers) ||
   2320 		 (result_brand == NULL)) ? "" : result_brand);
   2321       }
   2322       break;
   2323     case 1:
   2324     case 2:
   2325       if (print_headers) {
   2326 		fprintf(where,
   2327 		cpu_title,
   2328 		format_units(),
   2329 		local_cpu_method,
   2330 		remote_cpu_method);
   2331       }
   2332 
   2333       fprintf(where,
   2334 	      cpu_fmt_1,		/* the format string */
   2335 	      rsr_size,		        /* remote recvbuf size */
   2336 	      lss_size,		        /* local sendbuf size */
   2337 	      send_size,		/* how large were the sends */
   2338 	      elapsed_time,		/* how long was the test */
   2339 	      thruput, 		        /* what was the xfer rate */
   2340 	      local_cpu_utilization,	/* local cpu */
   2341 	      remote_cpu_utilization,	/* remote cpu */
   2342 	      local_service_demand,	/* local service demand */
   2343 	      remote_service_demand,	/* remote service demand */
   2344 	      ((print_headers) ||
   2345 	       (result_brand == NULL)) ? "" : result_brand);
   2346       break;
   2347     }
   2348   }
   2349   else {
   2350     /* The tester did not wish to measure service demand. */
   2351 
   2352     switch (verbosity) {
   2353     case 0:
   2354       fprintf(where,
   2355 	      tput_fmt_0,
   2356 	      thruput,
   2357 	      ((print_headers) ||
   2358 	       (result_brand == NULL)) ? "" : result_brand);
   2359       break;
   2360     case 1:
   2361     case 2:
   2362       if (print_headers) {
   2363 		fprintf(where,tput_title,format_units());
   2364       }
   2365       fprintf(where,
   2366 	      tput_fmt_1,		/* the format string */
   2367 	      rsr_size, 		/* remote recvbuf size */
   2368 	      lss_size, 		/* local sendbuf size */
   2369 	      send_size,		/* how large were the sends */
   2370 	      elapsed_time, 		/* how long did it take */
   2371 	      thruput,                  /* how fast did it go */
   2372 	      ((print_headers) ||
   2373 	       (result_brand == NULL)) ? "" : result_brand);
   2374       break;
   2375     }
   2376   }
   2377 
   2378   /* it would be a good thing to include information about some of the */
   2379   /* other parameters that may have been set for this test, but at the */
   2380   /* moment, I do not wish to figure-out all the  formatting, so I will */
   2381   /* just put this comment here to help remind me that it is something */
   2382   /* that should be done at a later time. */
   2383 
   2384   if (verbosity > 1) {
   2385     /* The user wanted to know it all, so we will give it to him. */
   2386     /* This information will include as much as we can find about */
   2387     /* TCP statistics, the alignments of the sends and receives */
   2388     /* and all that sort of rot... */
   2389 
   2390     /* this stuff needs to be worked-out in the presence of confidence */
   2391     /* intervals and multiple iterations of the test... raj 11/94 */
   2392 
   2393     fprintf(where,
   2394 	    ksink_fmt,
   2395 	    "Bytes",
   2396 	    "Bytes",
   2397 	    "Bytes",
   2398 	    local_send_align,
   2399 	    remote_recv_align,
   2400 	    local_send_offset,
   2401 	    remote_recv_offset,
   2402 	    bytes_sent,
   2403 	    bytes_sent / (double)nummessages,
   2404 	    nummessages,
   2405 	    bytes_sent / (double)tcp_stream_result->recv_calls,
   2406 	    tcp_stream_result->recv_calls);
   2407     fprintf(where,
   2408 	    ksink_fmt2,
   2409 	    tcp_mss);
   2410     fflush(where);
   2411 #ifdef WANT_HISTOGRAM
   2412     fprintf(where,"\n\nHistogram of time spent in send() call.\n");
   2413     fflush(where);
   2414     HIST_report(time_hist);
   2415 #endif /* WANT_HISTOGRAM */
   2416   }
   2417 
   2418 }
   2419 
   2420 
   2421 
   2423 /* This routine implements the netperf-side TCP unidirectional data
   2424    transfer test (a.k.a. stream) for the sockets interface where the
   2425    data flow is from the netserver to the netperf.  It receives its
   2426    parameters via global variables from the shell and writes its
   2427    output to the standard output. */
   2428 
   2429 
   2430 void
   2431 send_tcp_maerts(char remote_host[])
   2432 {
   2433 
   2434   char *tput_title = "\
   2435 Recv   Send    Send                          \n\
   2436 Socket Socket  Message  Elapsed              \n\
   2437 Size   Size    Size     Time     Throughput  \n\
   2438 bytes  bytes   bytes    secs.    %s/sec  \n\n";
   2439 
   2440   char *tput_fmt_0 =
   2441     "%7.2f %s\n";
   2442 
   2443   char *tput_fmt_1 =
   2444     "%6d %6d %6d    %-6.2f   %7.2f   %s\n";
   2445 
   2446   char *cpu_title = "\
   2447 Recv   Send    Send                          Utilization       Service Demand\n\
   2448 Socket Socket  Message  Elapsed              Recv     Send     Recv    Send\n\
   2449 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
   2450 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
   2451 
   2452   char *cpu_fmt_0 =
   2453     "%6.3f %c %s\n";
   2454 
   2455   char *cpu_fmt_1 =
   2456     "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f %s\n";
   2457 
   2458   char *ksink_fmt = "\n\
   2459 Alignment      Offset         %-8.8s %-8.8s    Recvs   %-8.8s Sends\n\
   2460 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
   2461 Recv   Send    Recv   Send             Recv (avg)          Send (avg)\n\
   2462 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
   2463 
   2464   char *ksink_fmt2 = "\n\
   2465 Maximum\n\
   2466 Segment\n\
   2467 Size (bytes)\n\
   2468 %6d\n";
   2469 
   2470 
   2471   float			elapsed_time;
   2472 
   2473   /* what we want is to have a buffer space that is at least one */
   2474   /* recv-size greater than our recv window. this will insure that we */
   2475   /* are never trying to re-use a buffer that may still be in the hands */
   2476   /* of the transport. This buffer will be malloc'd after we have found */
   2477   /* the size of the local senc socket buffer. We will want to deal */
   2478   /* with alignment and offset concerns as well. */
   2479 
   2480   struct ring_elt *recv_ring;
   2481 
   2482   int len;
   2483   unsigned int nummessages = 0;
   2484   SOCKET recv_socket;
   2485   int bytes_remaining;
   2486   int tcp_mss = -1;  /* possibly uninitialized on printf far below */
   2487 
   2488   /* with links like fddi, one can recv > 32 bits worth of bytes
   2489      during a test... ;-) at some point, this should probably become a
   2490      64bit integral type, but those are not entirely common yet.  of
   2491      course, time passes and they do become common.
   2492  */
   2493   double	bytes_sent = 0.0;
   2494 
   2495 #if defined(WIN32) && (_MSC_VER < 1200)
   2496   __int64 local_bytes_recvd = 0;
   2497 #else
   2498   unsigned long long local_bytes_recvd = 0;
   2499 #endif
   2500 
   2501   float	local_cpu_utilization;
   2502   float	local_service_demand;
   2503   float	remote_cpu_utilization;
   2504   float	remote_service_demand;
   2505 
   2506   double	thruput;
   2507 
   2508   struct addrinfo *remote_res;
   2509   struct addrinfo *local_res;
   2510 
   2511   struct	tcp_maerts_request_struct	*tcp_maerts_request;
   2512   struct	tcp_maerts_response_struct	*tcp_maerts_response;
   2513   struct	tcp_maerts_results_struct	*tcp_maerts_result;
   2514 
   2515   tcp_maerts_request  =
   2516     (struct tcp_maerts_request_struct *)netperf_request.content.test_specific_data;
   2517   tcp_maerts_response =
   2518     (struct tcp_maerts_response_struct *)netperf_response.content.test_specific_data;
   2519   tcp_maerts_result   =
   2520     (struct tcp_maerts_results_struct *)netperf_response.content.test_specific_data;
   2521 
   2522 #ifdef WANT_HISTOGRAM
   2523   if (verbosity > 1) {
   2524     time_hist = HIST_new();
   2525   }
   2526 #endif /* WANT_HISTOGRAM */
   2527   /* since we are now disconnected from the code that established the */
   2528   /* control socket, and since we want to be able to use different */
   2529   /* protocols and such, we are passed the name of the remote host and */
   2530   /* must turn that into the test specific addressing information. */
   2531 
   2532   complete_addrinfos(&remote_res,
   2533 		     &local_res,
   2534 		     remote_host,
   2535 		     SOCK_STREAM,
   2536 		     IPPROTO_TCP,
   2537 		     0);
   2538 
   2539   if ( print_headers ) {
   2540     print_top_test_header("TCP MAERTS TEST",local_res,remote_res);
   2541   }
   2542 
   2543   recv_ring = NULL;
   2544   confidence_iteration = 1;
   2545   init_stat();
   2546 
   2547   /* we have a great-big while loop which controls the number of times */
   2548   /* we run a particular test. this is for the calculation of a */
   2549   /* confidence interval (I really should have stayed awake during */
   2550   /* probstats :). If the user did not request confidence measurement */
   2551   /* (no confidence is the default) then we will only go though the */
   2552   /* loop once. the confidence stuff originates from the folks at IBM */
   2553 
   2554   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   2555 	 (confidence_iteration <= iteration_min)) {
   2556 
   2557     /* initialize a few counters. we have to remember that we might be */
   2558     /* going through the loop more than once. */
   2559 
   2560     nummessages    =	0;
   2561     bytes_sent     =	0.0;
   2562     times_up       = 	0;
   2563 
   2564     /*set up the data socket                        */
   2565     recv_socket = create_data_socket(local_res);
   2566 
   2567     if (recv_socket == INVALID_SOCKET){
   2568       perror("netperf: send_tcp_maerts: tcp stream data socket");
   2569       exit(1);
   2570     }
   2571 
   2572     if (debug) {
   2573       fprintf(where,"send_tcp_maerts: recv_socket obtained...\n");
   2574     }
   2575 
   2576     /* at this point, we have either retrieved the socket buffer sizes, */
   2577     /* or have tried to set them, so now, we may want to set the recv */
   2578     /* size based on that (because the user either did not use a -m */
   2579     /* option, or used one with an argument of 0). If the socket buffer */
   2580     /* size is not available, we will set the recv size to 4KB - no */
   2581     /* particular reason, just arbitrary... */
   2582     if (recv_size == 0) {
   2583       if (lsr_size > 0) {
   2584 	recv_size = lsr_size;
   2585       }
   2586       else {
   2587 	recv_size = 4096;
   2588       }
   2589     }
   2590 
   2591     /* set-up the data buffer ring with the requested alignment and offset. */
   2592     /* note also that we have allocated a quantity */
   2593     /* of memory that is at least one recv-size greater than our socket */
   2594     /* buffer size. We want to be sure that there are at least two */
   2595     /* buffers allocated - this can be a bit of a problem when the */
   2596     /* recv_size is bigger than the socket size, so we must check... the */
   2597     /* user may have wanted to explicitly set the "width" of our recv */
   2598     /* buffers, we should respect that wish... */
   2599     if (recv_width == 0) {
   2600       recv_width = (lsr_size/recv_size) + 1;
   2601       if (recv_width == 1) recv_width++;
   2602     }
   2603 
   2604     if (recv_ring == NULL) {
   2605       /* only allocate the recv ring once. this is a networking test, */
   2606       /* not a memory allocation test. this way, we do not need a */
   2607       /* deallocate_buffer_ring() routine, and I don't feel like */
   2608       /* writing one anyway :) raj 11/94 */
   2609       recv_ring = allocate_buffer_ring(recv_width,
   2610 				       recv_size,
   2611 				       local_recv_align,
   2612 				       local_recv_offset);
   2613     }
   2614 
   2615     /* If the user has requested cpu utilization measurements, we must */
   2616     /* calibrate the cpu(s). We will perform this task within the tests */
   2617     /* themselves. If the user has specified the cpu rate, then */
   2618     /* calibrate_local_cpu will return rather quickly as it will have */
   2619     /* nothing to do. If local_cpu_rate is zero, then we will go through */
   2620     /* all the "normal" calibration stuff and return the rate back. */
   2621 
   2622     if (local_cpu_usage) {
   2623       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   2624     }
   2625 
   2626     if (!no_control) {
   2627       /* Tell the remote end to do a listen. The server alters the
   2628 	 socket paramters on the other side at this point, hence the
   2629 	 reason for all the values being passed in the setup
   2630 	 message. If the user did not specify any of the parameters,
   2631 	 they will be passed as 0, which will indicate to the remote
   2632 	 that no changes beyond the system's default should be
   2633 	 used. Alignment is the exception, it will default to 1, which
   2634 	 will be no alignment alterations. */
   2635 
   2636       netperf_request.content.request_type	=	DO_TCP_MAERTS;
   2637       tcp_maerts_request->send_buf_size	=	rss_size_req;
   2638       tcp_maerts_request->recv_buf_size	=	rsr_size_req;
   2639       tcp_maerts_request->send_size	=	send_size;
   2640       tcp_maerts_request->no_delay	=	rem_nodelay;
   2641       tcp_maerts_request->send_alignment	=	remote_send_align;
   2642       tcp_maerts_request->send_offset	=	remote_send_offset;
   2643       tcp_maerts_request->measure_cpu	=	remote_cpu_usage;
   2644       tcp_maerts_request->cpu_rate	=	remote_cpu_rate;
   2645       if (test_time) {
   2646 	tcp_maerts_request->test_length	=	test_time;
   2647       }
   2648       else {
   2649 	tcp_maerts_request->test_length	=	test_bytes;
   2650       }
   2651       tcp_maerts_request->so_rcvavoid	=	rem_rcvavoid;
   2652       tcp_maerts_request->so_sndavoid	=	rem_sndavoid;
   2653 #ifdef DIRTY
   2654       tcp_maerts_request->dirty_count       =       rem_dirty_count;
   2655       tcp_maerts_request->clean_count       =       rem_clean_count;
   2656 #endif /* DIRTY */
   2657       tcp_maerts_request->port            = atoi(remote_data_port);
   2658       tcp_maerts_request->ipfamily        = af_to_nf(remote_res->ai_family);
   2659       if (debug > 1) {
   2660 	fprintf(where,
   2661 		"netperf: send_tcp_maerts: requesting TCP maerts test\n");
   2662       }
   2663 
   2664       send_request();
   2665 
   2666       /* The response from the remote will contain all of the relevant
   2667 	 socket parameters for this test type. We will put them back
   2668 	 into the variables here so they can be displayed if desired.
   2669 	 The remote will have calibrated CPU if necessary, and will
   2670 	 have done all the needed set-up we will have calibrated the
   2671 	 cpu locally before sending the request, and will grab the
   2672 	 counter value right after the connect returns. The remote
   2673 	 will grab the counter right after the accept call. This saves
   2674 	 the hassle of extra messages being sent for the TCP
   2675 	 tests.  */
   2676 
   2677       recv_response();
   2678 
   2679       if (!netperf_response.content.serv_errno) {
   2680 	if (debug)
   2681 	  fprintf(where,"remote listen done.\n");
   2682 	rsr_size	=	tcp_maerts_response->recv_buf_size;
   2683 	rss_size	=	tcp_maerts_response->send_buf_size;
   2684 	rem_nodelay     =	tcp_maerts_response->no_delay;
   2685 	remote_cpu_usage=	tcp_maerts_response->measure_cpu;
   2686 	remote_cpu_rate = tcp_maerts_response->cpu_rate;
   2687 	send_size       = tcp_maerts_response->send_size;
   2688 
   2689 	/* we have to make sure that the server port number is in
   2690 	 network order */
   2691       set_port_number(remote_res,
   2692 		      (short)tcp_maerts_response->data_port_number);
   2693       rem_rcvavoid	= tcp_maerts_response->so_rcvavoid;
   2694       rem_sndavoid	= tcp_maerts_response->so_sndavoid;
   2695       }
   2696       else {
   2697 	Set_errno(netperf_response.content.serv_errno);
   2698 	fprintf(where,
   2699 		"netperf: remote error %d",
   2700 		netperf_response.content.serv_errno);
   2701 	perror("");
   2702 	fflush(where);
   2703 
   2704 	exit(1);
   2705       }
   2706     }
   2707 
   2708 #ifdef WANT_DEMO
   2709     demo_stream_setup(lsr_size,rss_size);
   2710 #endif
   2711 
   2712     /*Connect up to the remote port on the data socket  */
   2713     if (connect(recv_socket,
   2714 		remote_res->ai_addr,
   2715 		remote_res->ai_addrlen) == INVALID_SOCKET){
   2716       perror("netperf: send_tcp_maerts: data socket connect failed");
   2717       exit(1);
   2718     }
   2719 
   2720 #ifdef WIN32
   2721   /* this is used so the timer thread can close the socket out from */
   2722   /* under us, which to date is the easiest/cleanest/least */
   2723   /* Windows-specific way I can find to force the winsock calls to */
   2724   /* return WSAEINTR with the test is over. anything that will run on */
   2725   /* 95 and NT and is closer to what netperf expects from Unix signals */
   2726   /* and such would be appreciated raj 1/96 */
   2727   win_kludge_socket = recv_socket;
   2728 #endif /* WIN32 */
   2729 
   2730     /* Data Socket set-up is finished. If there were problems, either */
   2731     /* the connect would have failed, or the previous response would */
   2732     /* have indicated a problem. I failed to see the value of the */
   2733     /* extra  message after the accept on the remote. If it failed, */
   2734     /* we'll see it here. If it didn't, we might as well start pumping */
   2735     /* data. */
   2736 
   2737     /* Set-up the test end conditions. For a maerts test, they can be */
   2738     /* either time or byte-count based. */
   2739 
   2740     if (test_time) {
   2741       /* The user wanted to end the test after a period of time. */
   2742       times_up = 0;
   2743       bytes_remaining = 0;
   2744       /* in previous revisions, we had the same code repeated throught */
   2745       /* all the test suites. this was unnecessary, and meant more */
   2746       /* work for me when I wanted to switch to POSIX signals, so I */
   2747       /* have abstracted this out into a routine in netlib.c. if you */
   2748       /* are experiencing signal problems, you might want to look */
   2749       /* there. raj 11/94 */
   2750       if (!no_control) {
   2751 	/* this is a netperf to netserver test, netserver will close
   2752 	   to tell us the test is over, so use PAD_TIME to avoid
   2753 	   causing the netserver fits. */
   2754 	start_timer(test_time + PAD_TIME);
   2755       }
   2756       else {
   2757 	/* this is a netperf to data source test, no PAD_TIME */
   2758 	start_timer(test_time);
   2759       }
   2760     }
   2761     else {
   2762       /* The tester wanted to recv a number of bytes. we don't do that
   2763 	 in a TCP_MAERTS test. sorry. raj 2002-06-21 */
   2764       printf("netperf: send_tcp_maerts: test must be timed\n");
   2765       exit(1);
   2766     }
   2767 
   2768     /* The cpu_start routine will grab the current time and possibly */
   2769     /* value of the idle counter for later use in measuring cpu */
   2770     /* utilization and/or service demand and thruput. */
   2771 
   2772     cpu_start(local_cpu_usage);
   2773 
   2774 #ifdef WANT_INTERVALS
   2775     INTERVALS_INIT();
   2776 #endif /* WANT_INTERVALS */
   2777 
   2778     /* before we start, initialize a few variables */
   2779 
   2780 #ifdef WANT_DEMO
   2781     if (demo_mode) {
   2782       demo_first_timestamp();
   2783     }
   2784 #endif
   2785 
   2786     /* the test will continue until we either get a zero-byte recv()
   2787        on the socket or our failsafe timer expires. most of the time
   2788        we trust that we get a zero-byte recieve from the socket. raj
   2789        2002-06-21 */
   2790 
   2791 #ifdef WANT_HISTOGRAM
   2792     if (verbosity > 1) {
   2793       /* timestamp just before we go into recv and then again just
   2794 	 after we come out raj 8/94 */
   2795       /* but only if we are actually going to display a histogram. raj
   2796 	 2006-02-07 */
   2797       HIST_timestamp(&time_one);
   2798     }
   2799 #endif /* WANT_HISTOGRAM */
   2800 
   2801     while ((!times_up) && (len=recv(recv_socket,
   2802 				    recv_ring->buffer_ptr,
   2803 				    recv_size,
   2804 				    0)) > 0 ) {
   2805 
   2806 #ifdef WANT_HISTOGRAM
   2807       if (verbosity > 1) {
   2808 	/* timestamp the exit from the recv call and update the histogram */
   2809 	HIST_timestamp(&time_two);
   2810 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   2811       }
   2812 #endif /* WANT_HISTOGRAM */
   2813 
   2814 #ifdef DIRTY
   2815       access_buffer(recv_ring->buffer_ptr,
   2816 		    recv_size,
   2817 		    loc_dirty_count,
   2818 		    loc_clean_count);
   2819 #endif /* DIRTY */
   2820 
   2821 #ifdef WANT_DEMO
   2822       demo_stream_interval(len);
   2823 #endif
   2824 
   2825 #ifdef WANT_INTERVALS
   2826       INTERVALS_WAIT();
   2827 #endif /* WANT_INTERVALS */
   2828 
   2829       /* now we want to move our pointer to the next position in the */
   2830       /* data buffer...we may also want to wrap back to the "beginning" */
   2831       /* of the bufferspace, so we will mod the number of messages sent */
   2832       /* by the recv width, and use that to calculate the offset to add */
   2833       /* to the base pointer. */
   2834       nummessages++;
   2835       recv_ring = recv_ring->next;
   2836       if (bytes_remaining) {
   2837 	bytes_remaining -= len;
   2838       }
   2839 
   2840       local_bytes_recvd += len;
   2841 
   2842 #ifdef WANT_HISTOGRAM
   2843       if (verbosity > 1) {
   2844 	/* make sure we timestamp just before we go into recv  */
   2845 	/* raj 2004-06-15 */
   2846 	HIST_timestamp(&time_one);
   2847       }
   2848 #endif /* WANT_HISTOGRAM */
   2849 
   2850     }
   2851 
   2852     /* an EINTR is to be expected when this is a no_control test */
   2853     if (((len < 0) || SOCKET_EINTR(len)) && (!no_control)) {
   2854       perror("send_tcp_maerts: data recv error");
   2855       printf("len was %d\n",len);
   2856       exit(1);
   2857     }
   2858 
   2859     /* if we get here, it must mean we had a recv return of 0 before
   2860        the watchdog timer expired, or the watchdog timer expired and
   2861        this was a no_control test */
   2862 
   2863     /* The test is over. Flush the buffers to the remote end. We do a
   2864        graceful release to tell the  remote we have all the data. */
   2865 
   2866     /* but first, if the verbosity is greater than 1, find-out what */
   2867     /* the TCP maximum segment_size was (if possible) */
   2868     if (verbosity > 1) {
   2869       tcp_mss = -1;
   2870       get_tcp_info(recv_socket,&tcp_mss);
   2871     }
   2872 
   2873     if (shutdown(recv_socket,SHUT_WR) == SOCKET_ERROR) {
   2874       perror("netperf: cannot shutdown tcp maerts socket");
   2875       exit(1);
   2876     }
   2877 
   2878     stop_timer();
   2879 
   2880 #if defined(WANT_INTERVALS)
   2881 #ifdef WIN32
   2882     stop_itimer();
   2883 #endif
   2884 #endif /* WANT_INTERVALS */
   2885 
   2886     /* this call will always give us the local elapsed time for the
   2887        test, and will also store-away the necessaries for cpu
   2888        utilization */
   2889 
   2890     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
   2891 						/* measured and how */
   2892 						/* long did we really */
   2893 						/* run? */
   2894 
   2895     /* we are finished with the socket, so close it to prevent hitting */
   2896     /* the limit on maximum open files. */
   2897 
   2898     close(recv_socket);
   2899 
   2900     if (!no_control) {
   2901       /* Get the statistics from the remote end. The remote will have
   2902          calculated service demand and all those interesting
   2903          things. If it wasn't supposed to care, it will return obvious
   2904          values. */
   2905 
   2906       recv_response();
   2907       if (!netperf_response.content.serv_errno) {
   2908 	if (debug)
   2909 	  fprintf(where,"remote results obtained\n");
   2910       }
   2911       else {
   2912 	Set_errno(netperf_response.content.serv_errno);
   2913 	fprintf(where,
   2914 		"netperf: remote error %d",
   2915 		netperf_response.content.serv_errno);
   2916 	perror("");
   2917 	fflush(where);
   2918 
   2919 	exit(1);
   2920       }
   2921 
   2922       /* We now calculate what our thruput was for the test. In the
   2923 	 future, we may want to include a calculation of the thruput
   2924 	 measured by the remote, but it should be the case that for a
   2925 	 TCP maerts test, that the two numbers should be *very*
   2926 	 close... We calculate bytes_sent regardless of the way the
   2927 	 test length was controlled.  If it was time, we needed to,
   2928 	 and if it was by bytes, the user may have specified a number
   2929 	 of bytes that wasn't a multiple of the recv_size, so we
   2930 	 really didn't recv what he asked for ;-) */
   2931 
   2932       bytes_sent	= ntohd(tcp_maerts_result->bytes_sent);
   2933     }
   2934     else {
   2935       bytes_sent = (double)local_bytes_recvd;
   2936     }
   2937 
   2938 
   2939     thruput	= calc_thruput(bytes_sent);
   2940 
   2941     if (local_cpu_usage || remote_cpu_usage) {
   2942       /* We must now do a little math for service demand and cpu */
   2943       /* utilization for the system(s) */
   2944       /* Of course, some of the information might be bogus because */
   2945       /* there was no idle counter in the kernel(s). We need to make */
   2946       /* a note of this for the user's benefit...*/
   2947       if (local_cpu_usage) {
   2948 
   2949 	local_cpu_utilization	= calc_cpu_util(0.0);
   2950 	local_service_demand	= calc_service_demand(bytes_sent,
   2951 						      0.0,
   2952 						      0.0,
   2953 						      0);
   2954       }
   2955       else {
   2956 	local_cpu_utilization	= (float) -1.0;
   2957 	local_service_demand	= (float) -1.0;
   2958       }
   2959 
   2960       if (remote_cpu_usage) {
   2961 
   2962 	remote_cpu_utilization	= tcp_maerts_result->cpu_util;
   2963 	remote_service_demand	= calc_service_demand(bytes_sent,
   2964 						      0.0,
   2965 						      remote_cpu_utilization,
   2966 						      tcp_maerts_result->num_cpus);
   2967       }
   2968       else {
   2969 	remote_cpu_utilization = (float) -1.0;
   2970 	remote_service_demand  = (float) -1.0;
   2971       }
   2972     }
   2973     else {
   2974       /* we were not measuring cpu, for the confidence stuff, we */
   2975       /* should make it -1.0 */
   2976       local_cpu_utilization	= (float) -1.0;
   2977       local_service_demand	= (float) -1.0;
   2978       remote_cpu_utilization = (float) -1.0;
   2979       remote_service_demand  = (float) -1.0;
   2980     }
   2981 
   2982     /* at this point, we want to calculate the confidence information. */
   2983     /* if debugging is on, calculate_confidence will print-out the */
   2984     /* parameters we pass it */
   2985 
   2986     calculate_confidence(confidence_iteration,
   2987 			 elapsed_time,
   2988 			 thruput,
   2989 			 local_cpu_utilization,
   2990 			 remote_cpu_utilization,
   2991 			 local_service_demand,
   2992 			 remote_service_demand);
   2993 
   2994 
   2995     confidence_iteration++;
   2996   }
   2997 
   2998   /* at this point, we have finished making all the runs that we */
   2999   /* will be making. so, we should extract what the calcuated values */
   3000   /* are for all the confidence stuff. we could make the values */
   3001   /* global, but that seemed a little messy, and it did not seem worth */
   3002   /* all the mucking with header files. so, we create a routine much */
   3003   /* like calcualte_confidence, which just returns the mean values. */
   3004   /* raj 11/94 */
   3005 
   3006   retrieve_confident_values(&elapsed_time,
   3007 			    &thruput,
   3008 			    &local_cpu_utilization,
   3009 			    &remote_cpu_utilization,
   3010 			    &local_service_demand,
   3011 			    &remote_service_demand);
   3012 
   3013   /* We are now ready to print all the information. If the user */
   3014   /* has specified zero-level verbosity, we will just print the */
   3015   /* local service demand, or the remote service demand. If the */
   3016   /* user has requested verbosity level 1, he will get the basic */
   3017   /* "streamperf" numbers. If the user has specified a verbosity */
   3018   /* of greater than 1, we will display a veritable plethora of */
   3019   /* background information from outside of this block as it it */
   3020   /* not cpu_measurement specific...  */
   3021 
   3022   if (confidence < 0) {
   3023     /* we did not hit confidence, but were we asked to look for it? */
   3024     if (iteration_max > 1) {
   3025       display_confidence();
   3026     }
   3027   }
   3028 
   3029   if (local_cpu_usage || remote_cpu_usage) {
   3030     local_cpu_method = format_cpu_method(cpu_method);
   3031     remote_cpu_method = format_cpu_method(tcp_maerts_result->cpu_method);
   3032 
   3033     switch (verbosity) {
   3034     case 0:
   3035       if (local_cpu_usage) {
   3036 	fprintf(where,
   3037 		cpu_fmt_0,
   3038 		local_service_demand,
   3039 		local_cpu_method,
   3040 		((print_headers) ||
   3041 		 (result_brand == NULL)) ? "" : result_brand);
   3042       }
   3043       else {
   3044 	fprintf(where,
   3045 		cpu_fmt_0,
   3046 		remote_service_demand,
   3047 		remote_cpu_method,
   3048 		((print_headers) ||
   3049 		 (result_brand == NULL)) ? "" : result_brand);
   3050       }
   3051       break;
   3052     case 1:
   3053     case 2:
   3054       if (print_headers) {
   3055 	fprintf(where,
   3056 		cpu_title,
   3057 		format_units(),
   3058 		local_cpu_method,
   3059 		remote_cpu_method);
   3060       }
   3061 
   3062       fprintf(where,
   3063 	      cpu_fmt_1,		/* the format string */
   3064 	      rsr_size,		        /* remote recvbuf size */
   3065 	      lss_size,		        /* local sendbuf size */
   3066 	      send_size,		/* how large were the recvs */
   3067 	      elapsed_time,		/* how long was the test */
   3068 	      thruput, 		        /* what was the xfer rate */
   3069 	      local_cpu_utilization,	/* local cpu */
   3070 	      remote_cpu_utilization,	/* remote cpu */
   3071 	      local_service_demand,	/* local service demand */
   3072 	      remote_service_demand,	/* remote service demand */
   3073 	      ((print_headers) ||
   3074 	       (result_brand == NULL)) ? "" : result_brand);
   3075       break;
   3076     }
   3077   }
   3078   else {
   3079     /* The tester did not wish to measure service demand. */
   3080 
   3081     switch (verbosity) {
   3082     case 0:
   3083       fprintf(where,
   3084 	      tput_fmt_0,
   3085 	      thruput,
   3086 	      ((print_headers) ||
   3087 	       (result_brand == NULL)) ? "" : result_brand);
   3088       break;
   3089     case 1:
   3090     case 2:
   3091       if (print_headers) {
   3092 	fprintf(where,tput_title,format_units());
   3093       }
   3094       fprintf(where,
   3095 	      tput_fmt_1,		/* the format string */
   3096 	      lsr_size, 		/* local recvbuf size */
   3097 	      rss_size, 		/* remot sendbuf size */
   3098 	      send_size,		/* how large were the recvs */
   3099 	      elapsed_time, 		/* how long did it take */
   3100 	      thruput,                  /* how fast did it go */
   3101 	      ((print_headers) ||
   3102 	       (result_brand == NULL)) ? "" : result_brand);
   3103       break;
   3104     }
   3105   }
   3106 
   3107   /* it would be a good thing to include information about some of the */
   3108   /* other parameters that may have been set for this test, but at the */
   3109   /* moment, I do not wish to figure-out all the  formatting, so I will */
   3110   /* just put this comment here to help remind me that it is something */
   3111   /* that should be done at a later time. */
   3112 
   3113   if (verbosity > 1) {
   3114     /* The user wanted to know it all, so we will give it to him. */
   3115     /* This information will include as much as we can find about */
   3116     /* TCP statistics, the alignments of the sends and receives */
   3117     /* and all that sort of rot... */
   3118 
   3119     /* this stuff needs to be worked-out in the presence of confidence */
   3120     /* intervals and multiple iterations of the test... raj 11/94 */
   3121 
   3122     fprintf(where,
   3123 	    ksink_fmt,
   3124 	    "Bytes",
   3125 	    "Bytes",
   3126 	    "Bytes",
   3127 	    local_recv_align,
   3128 	    remote_recv_align,
   3129 	    local_recv_offset,
   3130 	    remote_recv_offset,
   3131 	    bytes_sent,
   3132 	    bytes_sent / (double)nummessages,
   3133 	    nummessages,
   3134 	    bytes_sent / (double)tcp_maerts_result->send_calls,
   3135 	    tcp_maerts_result->send_calls);
   3136     fprintf(where,
   3137 	    ksink_fmt2,
   3138 	    tcp_mss);
   3139     fflush(where);
   3140 #ifdef WANT_HISTOGRAM
   3141     fprintf(where,"\n\nHistogram of time spent in recv() call.\n");
   3142     fflush(where);
   3143     HIST_report(time_hist);
   3144 #endif /* WANT_HISTOGRAM */
   3145   }
   3146 
   3147 }
   3148 #endif /* WANT_MIGRATION */
   3149 
   3150 
   3152 /* this routine implements the TCP_MSS test.  All it does is pretend
   3153    to be a TCP_STREAM test and report the TCP_MSS for the data
   3154    connection.  No actual data is transferred. raj 2007-11-07
   3155 */
   3156 void
   3157 send_tcp_mss(char remote_host[])
   3158 {
   3159 
   3160   char *mss_title = "\
   3161 Maximum\n\
   3162 Segment\n\
   3163 Size (bytes)\n\n";
   3164 
   3165   char *mss_fmt_0 =
   3166     "%d %s\n";
   3167 
   3168   SOCKET send_socket;
   3169   int tcp_mss = -1;  /* possibly uninitialized on printf far below */
   3170 
   3171   struct addrinfo *remote_res;
   3172   struct addrinfo *local_res;
   3173 
   3174   struct	tcp_stream_request_struct	*tcp_stream_request;
   3175   struct	tcp_stream_response_struct	*tcp_stream_response;
   3176   struct	tcp_stream_results_struct	*tcp_stream_result;
   3177 
   3178   tcp_stream_request  =
   3179     (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
   3180   tcp_stream_response =
   3181     (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
   3182   tcp_stream_result   =
   3183     (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
   3184 
   3185   /* since we are now disconnected from the code that established the */
   3186   /* control socket, and since we want to be able to use different */
   3187   /* protocols and such, we are passed the name of the remote host and */
   3188   /* must turn that into the test specific addressing information. */
   3189 
   3190   /* complete_addrinfos will either succede or exit the process */
   3191   complete_addrinfos(&remote_res,
   3192 		     &local_res,
   3193 		     remote_host,
   3194 		     SOCK_STREAM,
   3195 		     IPPROTO_TCP,
   3196 		     0);
   3197 
   3198   if ( print_headers ) {
   3199     print_top_test_header("TCP MSS TEST",local_res,remote_res);
   3200   }
   3201 
   3202   /*set up the data socket                        */
   3203   send_socket = create_data_socket(local_res);
   3204 
   3205   if (send_socket == INVALID_SOCKET){
   3206     perror("netperf: send_tcp_stream: tcp stream data socket");
   3207     exit(1);
   3208   }
   3209 
   3210   if (debug) {
   3211     fprintf(where,"send_tcp_stream: send_socket obtained...\n");
   3212   }
   3213 
   3214 
   3215   if (!no_control) {
   3216     /* Tell the remote end to do a listen. The server alters the
   3217        socket paramters on the other side at this point, hence the
   3218        reason for all the values being passed in the setup
   3219        message. If the user did not specify any of the parameters,
   3220        they will be passed as 0, which will indicate to the remote
   3221        that no changes beyond the system's default should be
   3222        used. Alignment is the exception, it will default to 1, which
   3223        will be no alignment alterations. */
   3224 
   3225     netperf_request.content.request_type =	DO_TCP_STREAM;
   3226     tcp_stream_request->send_buf_size	=	rss_size_req;
   3227     tcp_stream_request->recv_buf_size	=	rsr_size_req;
   3228     tcp_stream_request->receive_size	=	recv_size;
   3229     tcp_stream_request->no_delay	=	rem_nodelay;
   3230     tcp_stream_request->recv_alignment	=	remote_recv_align;
   3231     tcp_stream_request->recv_offset	=	remote_recv_offset;
   3232     tcp_stream_request->measure_cpu	=	remote_cpu_usage;
   3233     tcp_stream_request->cpu_rate	=	remote_cpu_rate;
   3234     if (test_time) {
   3235       tcp_stream_request->test_length	=	test_time;
   3236     }
   3237     else {
   3238       tcp_stream_request->test_length	=	test_bytes;
   3239     }
   3240     tcp_stream_request->so_rcvavoid	=	rem_rcvavoid;
   3241     tcp_stream_request->so_sndavoid	=	rem_sndavoid;
   3242 #ifdef DIRTY
   3243     tcp_stream_request->dirty_count     =       rem_dirty_count;
   3244     tcp_stream_request->clean_count     =       rem_clean_count;
   3245 #endif /* DIRTY */
   3246     tcp_stream_request->port            =    atoi(remote_data_port);
   3247     tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
   3248     if (debug > 1) {
   3249       fprintf(where,
   3250 	      "netperf: send_tcp_mss: requesting TCP stream test\n");
   3251     }
   3252 
   3253     send_request();
   3254 
   3255     /* The response from the remote will contain all of the relevant
   3256        socket parameters for this test type. We will put them back
   3257        into the variables here so they can be displayed if desired.
   3258        The remote will have calibrated CPU if necessary, and will
   3259        have done all the needed set-up we will have calibrated the
   3260        cpu locally before sending the request, and will grab the
   3261        counter value right after the connect returns. The remote
   3262        will grab the counter right after the accept call. This saves
   3263        the hassle of extra messages being sent for the TCP
   3264        tests.  */
   3265 
   3266     recv_response();
   3267 
   3268     if (!netperf_response.content.serv_errno) {
   3269       if (debug)
   3270 	fprintf(where,"remote listen done.\n");
   3271       rsr_size	      =	tcp_stream_response->recv_buf_size;
   3272       rss_size	      =	tcp_stream_response->send_buf_size;
   3273       rem_nodelay     =	tcp_stream_response->no_delay;
   3274       remote_cpu_usage=	tcp_stream_response->measure_cpu;
   3275       remote_cpu_rate = tcp_stream_response->cpu_rate;
   3276 
   3277       /* we have to make sure that the server port number is in
   3278 	 network order */
   3279       set_port_number(remote_res,
   3280 		      (short)tcp_stream_response->data_port_number);
   3281 
   3282       rem_rcvavoid	= tcp_stream_response->so_rcvavoid;
   3283       rem_sndavoid	= tcp_stream_response->so_sndavoid;
   3284     }
   3285     else {
   3286       Set_errno(netperf_response.content.serv_errno);
   3287       fprintf(where,
   3288 	      "netperf: remote error %d",
   3289 	      netperf_response.content.serv_errno);
   3290       perror("");
   3291       fflush(where);
   3292 
   3293       exit(1);
   3294     }
   3295   }
   3296 
   3297   /*Connect up to the remote port on the data socket  */
   3298   if (connect(send_socket,
   3299 	      remote_res->ai_addr,
   3300 	      remote_res->ai_addrlen) == INVALID_SOCKET){
   3301     perror("netperf: send_tcp_mss: data socket connect failed");
   3302     exit(1);
   3303     }
   3304 
   3305 
   3306   /* find-out what the TCP maximum segment_size was (if possible) */
   3307   tcp_mss = -1;
   3308   get_tcp_info(send_socket,&tcp_mss);
   3309 
   3310   /* just go ahead and close the socket, the remote should figure it
   3311      out */
   3312   close(send_socket);
   3313 
   3314   /* statistics? we don't need no stinking statistics */
   3315 
   3316 
   3317     switch (verbosity) {
   3318     case 0:
   3319       fprintf(where,
   3320 	      mss_fmt_0,
   3321 	      tcp_mss,
   3322 	      ((print_headers) ||
   3323 	       (result_brand == NULL)) ? "" : result_brand);
   3324       break;
   3325     case 1:
   3326     case 2:
   3327       if (print_headers) {
   3328 		fprintf(where,"%s",mss_title);
   3329       }
   3330       fprintf(where,
   3331 	      mss_fmt_0,		/* the format string */
   3332 	      tcp_mss,
   3333 	      ((print_headers) ||
   3334 	       (result_brand == NULL)) ? "" : result_brand);
   3335       break;
   3336     }
   3337 
   3338 
   3339 }
   3340 
   3341 
   3342 
   3344 #ifdef HAVE_ICSC_EXS
   3345 
   3346 #include <sys/exs.h>
   3347 
   3348 
   3349 /* This routine implements the TCP unidirectional data transfer test */
   3350 /* (a.k.a. stream) for the sockets interface. It receives its */
   3351 /* parameters via global variables from the shell and writes its */
   3352 /* output to the standard output. */
   3353 
   3354 void
   3355 send_exs_tcp_stream(char remote_host[])
   3356 {
   3357 
   3358     char *tput_title = "\
   3359 Recv   Send    Send                          \n\
   3360 Socket Socket  Message  Elapsed              \n\
   3361 Size   Size    Size     Time     Throughput  \n\
   3362 bytes  bytes   bytes    secs.    %s/sec  \n\n";
   3363 
   3364     char *tput_fmt_0 =
   3365         "%7.2f\n";
   3366 
   3367     char *tput_fmt_1 =
   3368         "%6d %6d %6d    %-6.2f   %7.2f   \n";
   3369 
   3370     char *cpu_title = "\
   3371 Recv   Send    Send                          Utilization       Service Demand\n\
   3372 Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
   3373 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
   3374 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
   3375 
   3376     char *cpu_fmt_0 =
   3377         "%6.3f %c\n";
   3378 
   3379     char *cpu_fmt_1 =
   3380         "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f\n";
   3381 
   3382     char *ksink_fmt = "\n\
   3383 Alignment      Offset         %-8.8s %-8.8s    Sends   %-8.8s Recvs\n\
   3384 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
   3385 Send   Recv    Send   Recv             Send (avg)          Recv (avg)\n\
   3386 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
   3387 
   3388     char *ksink_fmt2 = "\n\
   3389 Maximum\n\
   3390 Segment\n\
   3391 Size (bytes)\n\
   3392 %6d\n";
   3393 
   3394 
   3395     float         elapsed_time;
   3396 
   3397     /* what we want is to have a buffer space that is at least one */
   3398     /* send-size greater than our send window. this will insure that we */
   3399     /* are never trying to re-use a buffer that may still be in the hands */
   3400     /* of the transport. This buffer will be malloc'd after we have found */
   3401     /* the size of the local senc socket buffer. We will want to deal */
   3402     /* with alignment and offset concerns as well. */
   3403 
   3404     struct ring_elt *send_ring;
   3405 
   3406     int len;
   3407     unsigned int nummessages = 0;
   3408     SOCKET send_socket;
   3409     int bytes_remaining;
   3410     int tcp_mss = -1;  /* possibly uninitialized on printf far below */
   3411 
   3412     exs_mhandle_t exs_mhandle;
   3413     exs_qhandle_t exs_qhandle;
   3414 #define NETPERF_EXS_PENDING  16
   3415     int exs_aio_pending;
   3416     int exs_aio_eagain;
   3417     int exs_aio_dequeued;
   3418     int exs_aio_dequeuecnt;
   3419     int exs_evtcnt;
   3420 #define NETPERF_EXS_QSIZE    128
   3421     exs_event_t exs_evtvec[NETPERF_EXS_QSIZE];
   3422 
   3423     /* with links like fddi, one can send > 32 bits worth of bytes */
   3424     /* during a test... ;-) at some point, this should probably become a */
   3425     /* 64bit integral type, but those are not entirely common yet */
   3426 
   3427     double   bytes_sent = 0.0;
   3428 
   3429     float   local_cpu_utilization;
   3430     float   local_service_demand;
   3431     float   remote_cpu_utilization;
   3432     float   remote_service_demand;
   3433 
   3434     double   thruput;
   3435 
   3436     struct addrinfo *remote_res;
   3437     struct addrinfo *local_res;
   3438 
   3439     struct   tcp_stream_request_struct   *tcp_stream_request;
   3440     struct   tcp_stream_response_struct   *tcp_stream_response;
   3441     struct   tcp_stream_results_struct   *tcp_stream_result;
   3442 
   3443     tcp_stream_request  =
   3444         (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
   3445     tcp_stream_response =
   3446         (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
   3447     tcp_stream_result   =
   3448         (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
   3449 
   3450 #if 0 /* def WANT_HISTOGRAM */
   3451     time_hist = HIST_new();
   3452 #endif /* WANT_HISTOGRAM */
   3453     /* since we are now disconnected from the code that established the */
   3454     /* control socket, and since we want to be able to use different */
   3455     /* protocols and such, we are passed the name of the remote host and */
   3456     /* must turn that into the test specific addressing information. */
   3457 
   3458     /* complete_addrinfos will either succede or exit the process */
   3459     complete_addrinfos(&remote_res,
   3460                        &local_res,
   3461                        remote_host,
   3462                        SOCK_STREAM,
   3463                        IPPROTO_TCP,
   3464                        0);
   3465 
   3466     if ( print_headers ) {
   3467         print_top_test_header("EXS TCP STREAM TEST",local_res,remote_res);
   3468     }
   3469 
   3470     send_ring = NULL;
   3471     confidence_iteration = 1;
   3472     init_stat();
   3473 
   3474     /* initialize EXS API and create event queue */
   3475     if (exs_init (EXS_VERSION) == -1) {
   3476         perror ("netperf: send_exs_tcp_stream: exs_init failed");
   3477         exit (1);
   3478     }
   3479 
   3480     if ((exs_qhandle = exs_qcreate (NETPERF_EXS_QSIZE)) == EXS_QHANDLE_INVALID) {
   3481         perror ("netperf: send_exs_tcp_stream: exs_qcreate failed");
   3482         exit (1);
   3483     }
   3484     if (debug) {
   3485         fprintf (where, "send_exs_tcp_stream: qhandle=%d\n", exs_qhandle);
   3486     }
   3487 
   3488     /* we have a great-big while loop which controls the number of times */
   3489     /* we run a particular test. this is for the calculation of a */
   3490     /* confidence interval (I really should have stayed awake during */
   3491     /* probstats :). If the user did not request confidence measurement */
   3492     /* (no confidence is the default) then we will only go though the */
   3493     /* loop once. the confidence stuff originates from the folks at IBM */
   3494 
   3495     while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   3496            (confidence_iteration <= iteration_min)) {
   3497 
   3498         /* initialize a few counters. we have to remember that we might be */
   3499         /* going through the loop more than once. */
   3500 
   3501         nummessages    =   0;
   3502         bytes_sent     =   0.0;
   3503         times_up       =    0;
   3504 
   3505         /*set up the data socket                        */
   3506         send_socket = create_data_socket(local_res);
   3507 
   3508         if (send_socket == INVALID_SOCKET){
   3509             perror("netperf: send_tcp_stream: tcp stream data socket");
   3510             exit(1);
   3511         }
   3512 
   3513         if (debug) {
   3514             fprintf(where,"send_tcp_stream: send_socket obtained...\n");
   3515         }
   3516 
   3517         /* at this point, we have either retrieved the socket buffer sizes, */
   3518         /* or have tried to set them, so now, we may want to set the send */
   3519         /* size based on that (because the user either did not use a -m */
   3520         /* option, or used one with an argument of 0). If the socket buffer */
   3521         /* size is not available, we will set the send size to 4KB - no */
   3522         /* particular reason, just arbitrary... */
   3523         if (send_size == 0) {
   3524             if (lss_size > 0) {
   3525                 send_size = lss_size;
   3526             }
   3527             else {
   3528                 send_size = 4096;
   3529             }
   3530         }
   3531 
   3532         /* set-up the data buffer ring with the requested alignment and offset. */
   3533         /* note also that we have allocated a quantity */
   3534         /* of memory that is at least one send-size greater than our socket */
   3535         /* buffer size. We want to be sure that there are at least two */
   3536         /* buffers allocated - this can be a bit of a problem when the */
   3537         /* send_size is bigger than the socket size, so we must check... the */
   3538         /* user may have wanted to explicitly set the "width" of our send */
   3539         /* buffers, we should respect that wish... */
   3540         if (send_width == 0) {
   3541             send_width = (lss_size/send_size) + 1;
   3542             if (send_width == 1) send_width++;
   3543         }
   3544 
   3545         if (send_ring == NULL) {
   3546             /* only allocate the send ring once. this is a networking test, */
   3547             /* not a memory allocation test. this way, we do not need a */
   3548             /* deallocate_buffer_ring() routine, and I don't feel like */
   3549             /* writing one anyway :) raj 11/94 */
   3550             send_ring = allocate_exs_buffer_ring(send_width,
   3551                                                  send_size,
   3552                                                  local_send_align,
   3553                                                  local_send_offset,
   3554                                                  &exs_mhandle);
   3555         }
   3556 
   3557         /* If the user has requested cpu utilization measurements, we must */
   3558         /* calibrate the cpu(s). We will perform this task within the tests */
   3559         /* themselves. If the user has specified the cpu rate, then */
   3560         /* calibrate_local_cpu will return rather quickly as it will have */
   3561         /* nothing to do. If local_cpu_rate is zero, then we will go through */
   3562         /* all the "normal" calibration stuff and return the rate back. */
   3563 
   3564         if (local_cpu_usage) {
   3565             local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   3566         }
   3567 
   3568         /* Tell the remote end to do a listen. The server alters the socket */
   3569         /* paramters on the other side at this point, hence the reason for */
   3570         /* all the values being passed in the setup message. If the user did */
   3571         /* not specify any of the parameters, they will be passed as 0, which */
   3572         /* will indicate to the remote that no changes beyond the system's */
   3573         /* default should be used. Alignment is the exception, it will */
   3574         /* default to 1, which will be no alignment alterations. */
   3575 
   3576         netperf_request.content.request_type =   DO_TCP_STREAM;
   3577         tcp_stream_request->send_buf_size   =   rss_size_req;
   3578         tcp_stream_request->recv_buf_size   =   rsr_size_req;
   3579         tcp_stream_request->receive_size   =   recv_size;
   3580         tcp_stream_request->no_delay   =   rem_nodelay;
   3581         tcp_stream_request->recv_alignment   =   remote_recv_align;
   3582         tcp_stream_request->recv_offset   =   remote_recv_offset;
   3583         tcp_stream_request->measure_cpu   =   remote_cpu_usage;
   3584         tcp_stream_request->cpu_rate   =   remote_cpu_rate;
   3585         if (test_time) {
   3586             tcp_stream_request->test_length   =   test_time;
   3587         }
   3588         else {
   3589             tcp_stream_request->test_length   =   test_bytes;
   3590         }
   3591         tcp_stream_request->so_rcvavoid   =   rem_rcvavoid;
   3592         tcp_stream_request->so_sndavoid   =   rem_sndavoid;
   3593 #ifdef DIRTY
   3594         tcp_stream_request->dirty_count     =       rem_dirty_count;
   3595         tcp_stream_request->clean_count     =       rem_clean_count;
   3596 #endif /* DIRTY */
   3597         tcp_stream_request->port            =    atoi(remote_data_port);
   3598         tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
   3599         if (debug > 1) {
   3600             fprintf(where,
   3601                     "netperf: send_tcp_stream: requesting TCP stream test\n");
   3602         }
   3603 
   3604         send_request();
   3605 
   3606         /* The response from the remote will contain all of the relevant    */
   3607         /* socket parameters for this test type. We will put them back into */
   3608         /* the variables here so they can be displayed if desired.  The   */
   3609         /* remote will have calibrated CPU if necessary, and will have done   */
   3610         /* all the needed set-up we will have calibrated the cpu locally   */
   3611         /* before sending the request, and will grab the counter value right*/
   3612         /* after the connect returns. The remote will grab the counter right*/
   3613         /* after the accept call. This saves the hassle of extra messages   */
   3614         /* being sent for the TCP tests.               */
   3615 
   3616         recv_response();
   3617 
   3618         if (!netperf_response.content.serv_errno) {
   3619             if (debug)
   3620                 fprintf(where,"remote listen done.\n");
   3621             rsr_size         =   tcp_stream_response->recv_buf_size;
   3622             rss_size         =   tcp_stream_response->send_buf_size;
   3623             rem_nodelay     =   tcp_stream_response->no_delay;
   3624             remote_cpu_usage=   tcp_stream_response->measure_cpu;
   3625             remote_cpu_rate = tcp_stream_response->cpu_rate;
   3626 
   3627             /* we have to make sure that the server port number is in */
   3628             /* network order */
   3629             set_port_number(remote_res,(short)tcp_stream_response->data_port_number);
   3630 
   3631             rem_rcvavoid   = tcp_stream_response->so_rcvavoid;
   3632             rem_sndavoid   = tcp_stream_response->so_sndavoid;
   3633         }
   3634         else {
   3635             Set_errno(netperf_response.content.serv_errno);
   3636             fprintf(where,
   3637                     "netperf: remote error %d",
   3638                     netperf_response.content.serv_errno);
   3639             perror("");
   3640             fflush(where);
   3641 
   3642             exit(1);
   3643         }
   3644 
   3645 #if 0 /* def WANT_DEMO */
   3646         demo_stream_setup(lss_size,rsr_size);
   3647 #endif
   3648 
   3649             /*Connect up to the remote port on the data socket  */
   3650             if (connect(send_socket,
   3651                         remote_res->ai_addr,
   3652                         remote_res->ai_addrlen) == INVALID_SOCKET){
   3653                 perror("netperf: send_tcp_stream: data socket connect failed");
   3654                 exit(1);
   3655             }
   3656 
   3657 #ifdef WIN32
   3658   /* this is used so the timer thread can close the socket out from */
   3659   /* under us, which to date is the easiest/cleanest/least */
   3660   /* Windows-specific way I can find to force the winsock calls to */
   3661   /* return WSAEINTR with the test is over. anything that will run on */
   3662   /* 95 and NT and is closer to what netperf expects from Unix signals */
   3663   /* and such would be appreciated raj 1/96 */
   3664   win_kludge_socket = send_socket;
   3665 #endif /* WIN32 */
   3666 
   3667         /* Data Socket set-up is finished. If there were problems, either */
   3668         /* the connect would have failed, or the previous response would */
   3669         /* have indicated a problem. I failed to see the value of the */
   3670         /* extra  message after the accept on the remote. If it failed, */
   3671         /* we'll see it here. If it didn't, we might as well start pumping */
   3672         /* data. */
   3673 
   3674         /* Set-up the test end conditions. For a stream test, they can be */
   3675         /* either time or byte-count based. */
   3676 
   3677         if (test_time) {
   3678             /* The user wanted to end the test after a period of time. */
   3679             times_up = 0;
   3680             bytes_remaining = 0;
   3681             /* in previous revisions, we had the same code repeated throught */
   3682             /* all the test suites. this was unnecessary, and meant more */
   3683             /* work for me when I wanted to switch to POSIX signals, so I */
   3684             /* have abstracted this out into a routine in netlib.c. if you */
   3685             /* are experiencing signal problems, you might want to look */
   3686             /* there. raj 11/94 */
   3687             start_timer(test_time);
   3688         }
   3689         else {
   3690             /* The tester wanted to send a number of bytes. */
   3691             bytes_remaining = test_bytes;
   3692             times_up = 1;
   3693         }
   3694 
   3695         /* The cpu_start routine will grab the current time and possibly */
   3696         /* value of the idle counter for later use in measuring cpu */
   3697         /* utilization and/or service demand and thruput. */
   3698 
   3699         cpu_start(local_cpu_usage);
   3700 
   3701 #if 0 /* def WANT_INTERVALS */
   3702 	INTERVALS_INIT();
   3703 #endif /* WANT_INTERVALS */
   3704 
   3705         /* before we start, initialize a few variables */
   3706 
   3707 #if 0 /* def WANT_DEMO */
   3708         if (demo_mode) {
   3709 	  demo_first_timestamp();
   3710         }
   3711 #endif
   3712 
   3713 
   3714         /* We use an "OR" to control test execution. When the test is */
   3715         /* controlled by time, the byte count check will always return false. */
   3716         /* When the test is controlled by byte count, the time test will */
   3717         /* always return false. When the test is finished, the whole */
   3718         /* expression will go false and we will stop sending data. */
   3719 
   3720         exs_aio_pending = 0;
   3721         exs_aio_eagain = 0;
   3722         exs_aio_dequeuecnt = 0;
   3723 
   3724         while ((!times_up) || (bytes_remaining > 0)) {
   3725 
   3726 #ifdef DIRTY
   3727 	  access_buffer(send_ring->buffer_ptr,
   3728 			send_size,
   3729 			loc_dirty_count,
   3730 			loc_clean_count);
   3731 #endif /* DIRTY */
   3732 
   3733 #if 0 /* def WANT_HISTOGRAM */
   3734             /* timestamp just before we go into send and then again just after */
   3735             /* we come out raj 8/94 */
   3736             HIST_timestamp(&time_one);
   3737 #endif /* WANT_HISTOGRAM */
   3738 
   3739 
   3740             /* post up to NETPERF_EXS_PENDING I/Os  */
   3741             while ((exs_aio_pending < NETPERF_EXS_PENDING) &&
   3742                    (exs_send (send_socket, send_ring->buffer_ptr, send_size,
   3743                               0, exs_qhandle, (exs_ahandle_t)-1, exs_mhandle) == 0)) {
   3744                 exs_aio_pending++;
   3745 
   3746                 /* now we want to move our pointer to the next
   3747 		   position in the data buffer...we may also want to
   3748 		   wrap back to the "beginning" of the bufferspace, so
   3749 		   we will mod the number of messages sent by the send
   3750 		   width, and use that to calculate the offset to add
   3751 		   to the base pointer. */
   3752 
   3753                 nummessages++;
   3754                 send_ring = send_ring->next;
   3755                 if (bytes_remaining) {
   3756                     bytes_remaining -= send_size;
   3757                 }
   3758             }
   3759 
   3760             /* check exs_send result */
   3761             if (exs_aio_pending < NETPERF_EXS_PENDING) {
   3762                /* standard flow control case */
   3763                 if (errno == EAGAIN)
   3764                     exs_aio_eagain++;
   3765                 /* case of times_up */
   3766                 else if (errno == EINTR)
   3767                     break;
   3768                 /* strange, let's stop */
   3769                 else {
   3770                     perror ("netperf: exs_send error");
   3771                     exit (1);
   3772                 }
   3773             }
   3774 
   3775             /* dequeue events with "threshold" on 1/2 posted */
   3776             exs_aio_dequeued =
   3777                 exs_qdequeue (exs_qhandle, exs_evtvec,
   3778                               -(exs_aio_pending>>1), NULL);
   3779             exs_aio_dequeuecnt++;
   3780 
   3781             /* check exs_dequeue result */
   3782             if (exs_aio_dequeued < 0) {
   3783                 /* case of times_up */
   3784                 if (errno == EINTR)
   3785                     break;
   3786                 /* strange, let's stop */
   3787                 else {
   3788                     perror ("netperf: exs_send error");
   3789                     exit (1);
   3790                 }
   3791             }
   3792             /* update number of pending I/Os */
   3793             else {
   3794                 exs_aio_pending -= exs_aio_dequeued;
   3795             }
   3796 
   3797 
   3798 #if 0 /* def WANT_HISTOGRAM */
   3799             /* timestamp the exit from the send call and update the histogram */
   3800             HIST_timestamp(&time_two);
   3801             HIST_add(time_hist,delta_micro(&time_one,&time_two));
   3802 #endif /* WANT_HISTOGRAM */
   3803 
   3804 #if 0 /* def WANT_DEMO */
   3805             demo_stream_interval(send_size);
   3806 #endif
   3807 
   3808 #if 0 /* def WANT_INTERVALS */
   3809 	    INTERVALS_WAIT();
   3810 #endif /* WANT_INTERVALS */
   3811 
   3812         }
   3813 
   3814         /* Collect the last completion events */
   3815         exs_aio_dequeued =
   3816             exs_qdequeue (exs_qhandle, exs_evtvec, -exs_aio_pending, NULL);
   3817         exs_aio_dequeuecnt++;
   3818         /* check exs_dequeue result and update number of pending I/Os */
   3819         if (exs_aio_dequeued < 0) {
   3820             perror ("netperf: exs_send error");
   3821             exit (1);
   3822         }
   3823         exs_aio_pending -= exs_aio_dequeued;
   3824 
   3825         /* Display some async I/O debug info */
   3826         if (debug) {
   3827             fprintf (where, "send_exs_tcp_stream: "
   3828                      "aio sent=%d eagain=%d dequeue=%d pending=%d\n",
   3829                      nummessages, exs_aio_eagain, exs_aio_dequeuecnt, exs_aio_pending);
   3830         }
   3831 
   3832         /* The test is over. Flush the buffers to the remote end. We do a */
   3833         /* graceful release to insure that all data has been taken by the */
   3834         /* remote. */
   3835 
   3836         /* but first, if the verbosity is greater than 1, find-out what */
   3837         /* the TCP maximum segment_size was (if possible) */
   3838         if (verbosity > 1) {
   3839             tcp_mss = -1;
   3840             get_tcp_info(send_socket,&tcp_mss);
   3841         }
   3842 
   3843         if (shutdown(send_socket,SHUT_WR) == SOCKET_ERROR) {
   3844             perror("netperf: cannot shutdown tcp stream socket");
   3845             exit(1);
   3846         }
   3847 
   3848         /* hang a recv() off the socket to block until the remote has */
   3849         /* brought all the data up into the application. it will do a */
   3850         /* shutdown to cause a FIN to be sent our way. We will assume that */
   3851         /* any exit from the recv() call is good... raj 4/93 */
   3852 
   3853         recv(send_socket, send_ring->buffer_ptr, send_size, 0);
   3854 
   3855         /* this call will always give us the elapsed time for the test, and */
   3856         /* will also store-away the necessaries for cpu utilization */
   3857 
   3858         cpu_stop(local_cpu_usage,&elapsed_time);   /* was cpu being */
   3859         /* measured and how */
   3860         /* long did we really */
   3861         /* run? */
   3862 
   3863         /* we are finished with the socket, so close it to prevent hitting */
   3864         /* the limit on maximum open files. */
   3865 
   3866         close(send_socket);
   3867 
   3868         /* Get the statistics from the remote end. The remote will have */
   3869         /* calculated service demand and all those interesting things. If it */
   3870         /* wasn't supposed to care, it will return obvious values. */
   3871 
   3872         recv_response();
   3873         if (!netperf_response.content.serv_errno) {
   3874             if (debug)
   3875                 fprintf(where,"remote results obtained\n");
   3876         }
   3877         else {
   3878             Set_errno(netperf_response.content.serv_errno);
   3879             fprintf(where,
   3880                     "netperf: remote error %d",
   3881                     netperf_response.content.serv_errno);
   3882             perror("");
   3883             fflush(where);
   3884 
   3885             exit(1);
   3886         }
   3887 
   3888         /* We now calculate what our thruput was for the test. In the future, */
   3889         /* we may want to include a calculation of the thruput measured by */
   3890         /* the remote, but it should be the case that for a TCP stream test, */
   3891         /* that the two numbers should be *very* close... We calculate */
   3892         /* bytes_sent regardless of the way the test length was controlled. */
   3893         /* If it was time, we needed to, and if it was by bytes, the user may */
   3894         /* have specified a number of bytes that wasn't a multiple of the */
   3895         /* send_size, so we really didn't send what he asked for ;-) */
   3896 
   3897         bytes_sent   = ntohd(tcp_stream_result->bytes_received);
   3898 
   3899         thruput   = calc_thruput(bytes_sent);
   3900 
   3901         if (local_cpu_usage || remote_cpu_usage) {
   3902             /* We must now do a little math for service demand and cpu */
   3903             /* utilization for the system(s) */
   3904             /* Of course, some of the information might be bogus because */
   3905             /* there was no idle counter in the kernel(s). We need to make */
   3906             /* a note of this for the user's benefit...*/
   3907             if (local_cpu_usage) {
   3908 
   3909                 local_cpu_utilization   = calc_cpu_util(0.0);
   3910                 local_service_demand   = calc_service_demand(bytes_sent,
   3911                                                              0.0,
   3912                                                              0.0,
   3913                                                              0);
   3914             }
   3915             else {
   3916                 local_cpu_utilization   = (float) -1.0;
   3917                 local_service_demand   = (float) -1.0;
   3918             }
   3919 
   3920             if (remote_cpu_usage) {
   3921 
   3922                 remote_cpu_utilization   = tcp_stream_result->cpu_util;
   3923                 remote_service_demand   = calc_service_demand(bytes_sent,
   3924                                                               0.0,
   3925                                                               remote_cpu_utilization,
   3926                                                               tcp_stream_result->num_cpus);
   3927             }
   3928             else {
   3929                 remote_cpu_utilization = (float) -1.0;
   3930                 remote_service_demand  = (float) -1.0;
   3931             }
   3932         }
   3933         else {
   3934             /* we were not measuring cpu, for the confidence stuff, we */
   3935             /* should make it -1.0 */
   3936             local_cpu_utilization   = (float) -1.0;
   3937             local_service_demand   = (float) -1.0;
   3938             remote_cpu_utilization = (float) -1.0;
   3939             remote_service_demand  = (float) -1.0;
   3940         }
   3941 
   3942         /* at this point, we want to calculate the confidence information. */
   3943         /* if debugging is on, calculate_confidence will print-out the */
   3944         /* parameters we pass it */
   3945 
   3946         calculate_confidence(confidence_iteration,
   3947                              elapsed_time,
   3948                              thruput,
   3949                              local_cpu_utilization,
   3950                              remote_cpu_utilization,
   3951                              local_service_demand,
   3952                              remote_service_demand);
   3953 
   3954 
   3955         confidence_iteration++;
   3956     }
   3957 
   3958     /* at this point, we have finished making all the runs that we */
   3959     /* will be making. so, we should extract what the calcuated values */
   3960     /* are for all the confidence stuff. we could make the values */
   3961     /* global, but that seemed a little messy, and it did not seem worth */
   3962     /* all the mucking with header files. so, we create a routine much */
   3963     /* like calcualte_confidence, which just returns the mean values. */
   3964     /* raj 11/94 */
   3965 
   3966     retrieve_confident_values(&elapsed_time,
   3967                               &thruput,
   3968                               &local_cpu_utilization,
   3969                               &remote_cpu_utilization,
   3970                               &local_service_demand,
   3971                               &remote_service_demand);
   3972 
   3973     /* We are now ready to print all the information. If the user */
   3974     /* has specified zero-level verbosity, we will just print the */
   3975     /* local service demand, or the remote service demand. If the */
   3976     /* user has requested verbosity level 1, he will get the basic */
   3977     /* "streamperf" numbers. If the user has specified a verbosity */
   3978     /* of greater than 1, we will display a veritable plethora of */
   3979     /* background information from outside of this block as it it */
   3980     /* not cpu_measurement specific...  */
   3981 
   3982     if (confidence < 0) {
   3983         /* we did not hit confidence, but were we asked to look for it? */
   3984         if (iteration_max > 1) {
   3985             display_confidence();
   3986         }
   3987     }
   3988 
   3989     if (local_cpu_usage || remote_cpu_usage) {
   3990         local_cpu_method = format_cpu_method(cpu_method);
   3991         remote_cpu_method = format_cpu_method(tcp_stream_result->cpu_method);
   3992 
   3993         switch (verbosity) {
   3994             case 0:
   3995                 if (local_cpu_usage) {
   3996                     fprintf(where,
   3997                             cpu_fmt_0,
   3998                             local_service_demand,
   3999                             local_cpu_method);
   4000                 }
   4001                 else {
   4002                     fprintf(where,
   4003                             cpu_fmt_0,
   4004                             remote_service_demand,
   4005                             remote_cpu_method);
   4006                 }
   4007                 break;
   4008             case 1:
   4009             case 2:
   4010                 if (print_headers) {
   4011                     fprintf(where,
   4012                             cpu_title,
   4013                             format_units(),
   4014                             local_cpu_method,
   4015                             remote_cpu_method);
   4016                 }
   4017 
   4018                 fprintf(where,
   4019                         cpu_fmt_1,      /* the format string */
   4020                         rsr_size,              /* remote recvbuf size */
   4021                         lss_size,              /* local sendbuf size */
   4022                         send_size,      /* how large were the sends */
   4023                         elapsed_time,      /* how long was the test */
   4024                         thruput,               /* what was the xfer rate */
   4025                         local_cpu_utilization,   /* local cpu */
   4026                         remote_cpu_utilization,   /* remote cpu */
   4027                         local_service_demand,   /* local service demand */
   4028                         remote_service_demand);   /* remote service demand */
   4029                 break;
   4030         }
   4031     }
   4032     else {
   4033         /* The tester did not wish to measure service demand. */
   4034 
   4035         switch (verbosity) {
   4036             case 0:
   4037                 fprintf(where,
   4038                         tput_fmt_0,
   4039                         thruput);
   4040                 break;
   4041             case 1:
   4042             case 2:
   4043                 if (print_headers) {
   4044                     fprintf(where,tput_title,format_units());
   4045                 }
   4046                 fprintf(where,
   4047                         tput_fmt_1,      /* the format string */
   4048                         rsr_size,       /* remote recvbuf size */
   4049                         lss_size,       /* local sendbuf size */
   4050                         send_size,      /* how large were the sends */
   4051                         elapsed_time,       /* how long did it take */
   4052                         thruput);/* how fast did it go */
   4053                 break;
   4054         }
   4055     }
   4056 
   4057     /* it would be a good thing to include information about some of the */
   4058     /* other parameters that may have been set for this test, but at the */
   4059     /* moment, I do not wish to figure-out all the  formatting, so I will */
   4060     /* just put this comment here to help remind me that it is something */
   4061     /* that should be done at a later time. */
   4062 
   4063     if (verbosity > 1) {
   4064         /* The user wanted to know it all, so we will give it to him. */
   4065         /* This information will include as much as we can find about */
   4066         /* TCP statistics, the alignments of the sends and receives */
   4067         /* and all that sort of rot... */
   4068 
   4069         /* this stuff needs to be worked-out in the presence of confidence */
   4070         /* intervals and multiple iterations of the test... raj 11/94 */
   4071 
   4072         fprintf(where,
   4073                 ksink_fmt,
   4074                 "Bytes",
   4075                 "Bytes",
   4076                 "Bytes",
   4077                 local_send_align,
   4078                 remote_recv_align,
   4079                 local_send_offset,
   4080                 remote_recv_offset,
   4081                 bytes_sent,
   4082                 bytes_sent / (double)nummessages,
   4083                 nummessages,
   4084                 bytes_sent / (double)tcp_stream_result->recv_calls,
   4085                 tcp_stream_result->recv_calls);
   4086         fprintf(where,
   4087                 ksink_fmt2,
   4088                 tcp_mss);
   4089         fflush(where);
   4090 #if 0 /* def WANT_HISTOGRAM */
   4091         fprintf(where,"\n\nHistogram of time spent in send() call.\n");
   4092         fflush(where);
   4093         HIST_report(time_hist);
   4094 #endif /* WANT_HISTOGRAM */
   4095     }
   4096 
   4097 }
   4098 
   4099 #endif /* HAVE_ICSC_EXS */
   4100 
   4101 
   4102 
   4104 #if defined(HAVE_SENDFILE)
   4105 
   4106 
   4107 /* This routine implements the TCP unidirectional data transfer test
   4108    (a.k.a. stream) for the sockets interface using the sendfile()
   4109    system call - TCP_SENDFILE.  It receives its  parameters via global
   4110    variables from the shell and writes its  output to the standard
   4111    output. Basically,  this is the same test as the send_tcp_stream()
   4112    logic and we even tell the remote to do a TCP_STREAM test since for
   4113    all it knows, nothig is different. */
   4114 
   4115 void
   4116 sendfile_tcp_stream(remote_host)
   4117      char	remote_host[];
   4118 {
   4119 
   4120   char *tput_title = "\
   4121 Recv   Send    Send                          \n\
   4122 Socket Socket  Message  Elapsed              \n\
   4123 Size   Size    Size     Time     Throughput  \n\
   4124 bytes  bytes   bytes    secs.    %s/sec  \n\n";
   4125 
   4126   char *tput_fmt_0 =
   4127     "%7.2f %s\n";
   4128 
   4129   char *tput_fmt_1 =
   4130     "%6d %6d %6d    %-6.2f   %7.2f   %s\n";
   4131 
   4132   char *cpu_title = "\
   4133 Recv   Send    Send                          Utilization       Service Demand\n\
   4134 Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
   4135 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
   4136 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
   4137 
   4138   char *cpu_fmt_0 =
   4139     "%6.3f %c %s\n";
   4140   char *cpu_fmt_1 =
   4141     "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f %s\n";
   4142 
   4143   char *ksink_fmt = "\n\
   4144 Alignment      Offset         %-8.8s %-8.8s    Sends   %-8.8s Recvs\n\
   4145 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
   4146 Send   Recv    Send   Recv             Send (avg)          Recv (avg)\n\
   4147 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
   4148 
   4149 char *ksink_fmt2 = "\n\
   4150 Maximum\n\
   4151 Segment\n\
   4152 Size (bytes)\n\
   4153 %6d\n";
   4154 
   4155   float			elapsed_time;
   4156 
   4157   /* what we want is to have a buffer space that is at least one */
   4158   /* send-size greater than our send window. this will insure that we */
   4159   /* are never trying to re-use a buffer that may still be in the hands */
   4160   /* of the transport. This buffer will be malloc'd after we have found */
   4161   /* the size of the local senc socket buffer. We will want to deal */
   4162   /* with alignment and offset concerns as well. */
   4163 
   4164   struct ring_elt *send_ring;
   4165 
   4166   int len;
   4167   unsigned int nummessages = 0;
   4168   SOCKET send_socket;
   4169   int bytes_remaining;
   4170   int tcp_mss = -1;  /* possibly uninitialized on printf far below */
   4171 
   4172   /* with links like fddi, one can send > 32 bits worth of bytes */
   4173   /* during a test... ;-) at some point, this should probably become a */
   4174   /* 64bit integral type, but those are not entirely common yet */
   4175   double	bytes_sent = 0.0;
   4176 
   4177   float	local_cpu_utilization;
   4178   float	local_service_demand;
   4179   float	remote_cpu_utilization;
   4180   float	remote_service_demand;
   4181 
   4182   double	thruput;
   4183 
   4184   struct  addrinfo *remote_res;
   4185   struct  addrinfo *local_res;
   4186   struct	sockaddr_in	server;
   4187 
   4188 #if defined(__linux) || defined(__sun)
   4189   off_t     scratch_offset;   /* the linux sendfile() call will update
   4190 				 the offset variable, which is
   4191 				 something we do _not_ want to happen
   4192 				 to the value in the send_ring! so, we
   4193 				 have to use a scratch variable. */
   4194 #endif /* __linux  || defined(__sun) */
   4195 #if defined (USE_OSX)
   4196    off_t    scratch_len;  /* Darwin 9.x need a value-result parameter  */
   4197 #endif
   4198 #if defined (__sun)
   4199    size_t  scratch_len;	/* the sun sendfilev() needs a place to
   4200 			   tell us how many bytes were written,
   4201 			   even though it also returns the value */
   4202    sendfilevec_t sv;
   4203 #endif /* __sun */
   4204 
   4205   struct	tcp_stream_request_struct	*tcp_stream_request;
   4206   struct	tcp_stream_response_struct	*tcp_stream_response;
   4207   struct	tcp_stream_results_struct	*tcp_stream_result;
   4208 
   4209   tcp_stream_request  =
   4210     (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
   4211   tcp_stream_response =
   4212     (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
   4213   tcp_stream_result   =
   4214     (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
   4215 
   4216 #ifdef WANT_HISTOGRAM
   4217   if (verbosity > 1) {
   4218     time_hist = HIST_new();
   4219   }
   4220 #endif /* WANT_HISTOGRAM */
   4221 
   4222   /* since we are now disconnected from the code that established the */
   4223   /* control socket, and since we want to be able to use different */
   4224   /* protocols and such, we are passed the name of the remote host and */
   4225   /* must turn that into the test specific addressing information. */
   4226 
   4227   bzero((char *)&server,
   4228 	sizeof(server));
   4229 
   4230   complete_addrinfos(&remote_res,
   4231 		     &local_res,
   4232 		     remote_host,
   4233 		     SOCK_STREAM,
   4234 		     IPPROTO_TCP,
   4235 		     0);
   4236 
   4237   if ( print_headers ) {
   4238     /* we want to have some additional, interesting information in */
   4239     /* the headers. we know some of it here, but not all, so we will */
   4240     /* only print the test title here and will print the results */
   4241     /* titles after the test is finished */
   4242     print_top_test_header("TCP SENDFILE TEST",local_res,remote_res);
   4243   }
   4244 
   4245   send_ring = NULL;
   4246   confidence_iteration = 1;
   4247   init_stat();
   4248 
   4249   /* we have a great-big while loop which controls the number of times */
   4250   /* we run a particular test. this is for the calculation of a */
   4251   /* confidence interval (I really should have stayed awake during */
   4252   /* probstats :). If the user did not request confidence measurement */
   4253   /* (no confidence is the default) then we will only go though the */
   4254   /* loop once. the confidence stuff originates from the folks at IBM */
   4255 
   4256   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   4257 	 (confidence_iteration <= iteration_min)) {
   4258 
   4259     /* initialize a few counters. we have to remember that we might be */
   4260     /* going through the loop more than once. */
   4261 
   4262     nummessages    =	0;
   4263     bytes_sent     =	0.0;
   4264     times_up       = 	0;
   4265 
   4266     /* set up the data socket */
   4267     send_socket = create_data_socket(local_res);
   4268 
   4269     if (send_socket == INVALID_SOCKET){
   4270       perror("netperf: sendfile_tcp_stream: tcp stream data socket");
   4271       exit(1);
   4272     }
   4273 
   4274     if (debug) {
   4275       fprintf(where,"sendfile_tcp_stream: send_socket obtained...\n");
   4276     }
   4277 
   4278 #if defined(TCP_CORK)
   4279     /* should this even be here?!? */
   4280     if (loc_tcpcork > 0) {
   4281       /* the user wishes for us to set TCP_CORK on the socket */
   4282       int one = 1;
   4283       if (setsockopt(send_socket,
   4284 		     getprotobyname("tcp")->p_proto,
   4285 		     TCP_CORK,
   4286 		     (char *)&one,
   4287 		     sizeof(one)) == SOCKET_ERROR) {
   4288 	perror("netperf: sendfile_tcp_stream: tcp_cork");
   4289 	exit(1);
   4290       }
   4291       if (debug) {
   4292 	fprintf(where,"sendfile_tcp_stream: tcp_cork...\n");
   4293       }
   4294     }
   4295 
   4296 #endif /* TCP_CORK */
   4297 
   4298     /* at this point, we have either retrieved the socket buffer sizes, */
   4299     /* or have tried to set them, so now, we may want to set the send */
   4300     /* size based on that (because the user either did not use a -m */
   4301     /* option, or used one with an argument of 0). If the socket buffer */
   4302     /* size is not available, we will set the send size to 4KB - no */
   4303     /* particular reason, just arbitrary... */
   4304 
   4305     /*check for file size/ min file size here?  create file here/ back out???*/
   4306 
   4307     if (send_size == 0) {
   4308       if (lss_size > 0) {
   4309 	send_size = lss_size;
   4310       }
   4311       else {
   4312 	send_size = 4096;
   4313       }
   4314     }
   4315 
   4316     /* set-up the data buffer ring with the requested alignment and
   4317        offset. note also that we have allocated a quantity  of memory
   4318        that is at least one send-size greater than our socket  buffer
   4319        size. We want to be sure that there are at least two  buffers
   4320        allocated - this can be a bit of a problem when the  send_size
   4321        is bigger than the socket size, so we must check... the  user
   4322        may have wanted to explicitly set the "width" of our send
   4323        buffers, we should respect that wish... */
   4324 
   4325     /*sendring -> an offset index that will shift the starting point of the*/
   4326     /*section of the file sent throughout the file*/
   4327 
   4328     if (send_width == 0) {
   4329       send_width = (lss_size/send_size) + 1;
   4330       if (send_width == 1) send_width++;
   4331     }
   4332 
   4333     if (send_ring == NULL) {
   4334 
   4335       /* only allocate the send ring once. this is a networking test,
   4336 	 not a memory allocation test. this way, we do not need a
   4337 	 deallocate_buffer_ring() routine, and I don't feel like
   4338 	 writing one anyway :) raj 11/94 */
   4339 
   4340       send_ring = alloc_sendfile_buf_ring(send_width,
   4341 					  send_size,
   4342 					  local_send_align,
   4343 					  local_send_offset);
   4344     }
   4345 
   4346     /* If the user has requested cpu utilization measurements, we must
   4347        calibrate the cpu(s). We will perform this task within the
   4348        tests  themselves. If the user has specified the cpu rate, then
   4349        calibrate_local_cpu will return rather quickly as it will have
   4350        nothing to do. If local_cpu_rate is zero, then we will go
   4351        through  all the "normal" calibration stuff and return the rate
   4352        back. */
   4353 
   4354     if (local_cpu_usage) {
   4355       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   4356     }
   4357 
   4358     /* Tell the remote end to do a listen. The server alters the
   4359        socket  paramters on the other side at this point, hence the
   4360        reason for  all the values being passed in the setup
   4361        message. If the user did  not specify any of the parameters,
   4362        they will be passed as 0, which  will indicate to the remote
   4363        that no changes beyond the system's  default should be
   4364        used. Alignment is the exception, it will  default to 1, which
   4365        will be no alignment alterations. */
   4366 
   4367     netperf_request.content.request_type =	DO_TCP_STREAM;
   4368     tcp_stream_request->send_buf_size	=	rss_size_req;
   4369     tcp_stream_request->recv_buf_size	=	rsr_size_req;
   4370     tcp_stream_request->receive_size	=	recv_size;
   4371     tcp_stream_request->no_delay	=	rem_nodelay;
   4372     tcp_stream_request->recv_alignment	=	remote_recv_align;
   4373     tcp_stream_request->recv_offset	=	remote_recv_offset;
   4374     tcp_stream_request->measure_cpu	=	remote_cpu_usage;
   4375     tcp_stream_request->cpu_rate	=	remote_cpu_rate;
   4376 
   4377     if (test_time) {
   4378       tcp_stream_request->test_length	=	test_time;
   4379     }
   4380     else {
   4381       tcp_stream_request->test_length	=	test_bytes;
   4382     }
   4383 
   4384     tcp_stream_request->so_rcvavoid	=	rem_rcvavoid;
   4385     tcp_stream_request->so_sndavoid	=	rem_sndavoid;
   4386 
   4387 #ifdef DIRTY
   4388     tcp_stream_request->dirty_count       =       rem_dirty_count;
   4389     tcp_stream_request->clean_count       =       rem_clean_count;
   4390 #endif /* DIRTY */
   4391     tcp_stream_request->port     = atoi(remote_data_port);
   4392     tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
   4393 
   4394     if (debug > 1) {
   4395       fprintf(where,
   4396 	      "netperf: send_tcp_stream: requesting TCP stream test\n");
   4397     }
   4398 
   4399     send_request();
   4400 
   4401     /* The response from the remote will contain all of the relevant
   4402        socket parameters for this test type. We will put them back
   4403        into the variables here so they can be displayed if desired.
   4404        The remote will have calibrated CPU if necessary, and will have
   4405        done all the needed set-up we will have calibrated the cpu
   4406        locally before sending the request, and will grab the counter
   4407        value right after the connect returns. The remote will grab the
   4408        counter right after the accept call. This saves the hassle of
   4409        extra messages being sent for the TCP tests.  */
   4410 
   4411     recv_response();
   4412 
   4413     if (!netperf_response.content.serv_errno) {
   4414       if (debug)
   4415 	fprintf(where,"remote listen done.\n");
   4416       rsr_size	      =	tcp_stream_response->recv_buf_size;
   4417       rss_size	      =	tcp_stream_response->send_buf_size;
   4418       rem_nodelay     =	tcp_stream_response->no_delay;
   4419       remote_cpu_usage=	tcp_stream_response->measure_cpu;
   4420       remote_cpu_rate = tcp_stream_response->cpu_rate;
   4421 
   4422       /* we have to make sure that the server port number is in */
   4423       /* network order */
   4424       set_port_number(remote_res,(short)tcp_stream_response->data_port_number);
   4425       rem_rcvavoid	= tcp_stream_response->so_rcvavoid;
   4426       rem_sndavoid	= tcp_stream_response->so_sndavoid;
   4427     }
   4428     else {
   4429       Set_errno(netperf_response.content.serv_errno);
   4430       fprintf(where,
   4431 	      "netperf: remote error %d",
   4432 	      netperf_response.content.serv_errno);
   4433       perror("");
   4434       fflush(where);
   4435 
   4436       exit(1);
   4437     }
   4438 
   4439 #ifdef WANT_DEMO
   4440     demo_stream_setup(lss_size,rsr_size);
   4441 #endif
   4442 
   4443     /*Connect up to the remote port on the data socket  */
   4444     if (connect(send_socket,
   4445 		remote_res->ai_addr,
   4446 		remote_res->ai_addrlen) == INVALID_SOCKET){
   4447       perror("netperf: send_tcp_stream: data socket connect failed");
   4448       printf(" port: %d\n",ntohs(server.sin_port));
   4449       exit(1);
   4450     }
   4451 
   4452 #ifdef WIN32
   4453   /* this is used so the timer thread can close the socket out from */
   4454   /* under us, which to date is the easiest/cleanest/least */
   4455   /* Windows-specific way I can find to force the winsock calls to */
   4456   /* return WSAEINTR with the test is over. anything that will run on */
   4457   /* 95 and NT and is closer to what netperf expects from Unix signals */
   4458   /* and such would be appreciated raj 1/96 */
   4459   win_kludge_socket = send_socket;
   4460 #endif /* WIN32 */
   4461 
   4462     /* Data Socket set-up is finished. If there were problems, either
   4463        the connect would have failed, or the previous response would
   4464        have indicated a problem. I failed to see the value of the
   4465        extra message after the accept on the remote. If it failed,
   4466        we'll see it here. If it didn't, we might as well start pumping
   4467        data. */
   4468 
   4469     /* Set-up the test end conditions. For a stream test, they can be */
   4470     /* either time or byte-count based. */
   4471 
   4472     if (test_time) {
   4473       /* The user wanted to end the test after a period of time. */
   4474       times_up = 0;
   4475       bytes_remaining = 0;
   4476 
   4477       /* in previous revisions, we had the same code repeated throught
   4478          all the test suites. this was unnecessary, and meant more
   4479          work for me when I wanted to switch to POSIX signals, so I
   4480          have abstracted this out into a routine in netlib.c. if you
   4481          are experiencing signal problems, you might want to look
   4482          there. raj 11/94 */
   4483 
   4484       start_timer(test_time);
   4485     }
   4486     else {
   4487       /* The tester wanted to send a number of bytes. */
   4488       bytes_remaining = test_bytes;
   4489       times_up = 1;
   4490     }
   4491 
   4492     /* The cpu_start routine will grab the current time and possibly */
   4493     /* value of the idle counter for later use in measuring cpu */
   4494     /* utilization and/or service demand and thruput. */
   4495 
   4496     cpu_start(local_cpu_usage);
   4497 
   4498 #ifdef WANT_INTERVALS
   4499     INTERVALS_INIT();
   4500 #endif /* WANT_INTERVALS */
   4501 
   4502 
   4503     /* before we start, initialize a few variables */
   4504 
   4505 #ifdef WANT_DEMO
   4506     if (demo_mode) {
   4507       demo_first_timestamp();
   4508     }
   4509 #endif
   4510 
   4511     /* We use an "OR" to control test execution. When the test is
   4512        controlled by time, the byte count check will always return
   4513        false. When the test is controlled by byte count, the time test
   4514        will always return false. When the test is finished, the whole
   4515        expression will go false and we will stop sending data. */
   4516 
   4517     while ((!times_up) || (bytes_remaining > 0)) {
   4518 
   4519       /* the sendfile_tcp_stream test does not support making the buffers
   4520 	 dirty. 08/2000 */
   4521 
   4522 #ifdef WANT_HISTOGRAM
   4523       if (verbosity > 1) {
   4524 	/* timestamp just before we go into sendfile() and then again
   4525          just after we come out raj 08/2000 */
   4526 	/* but only if we are actually going to display a histogram */
   4527 	HIST_timestamp(&time_one);
   4528       }
   4529 #endif /* WANT_HISTOGRAM */
   4530 
   4531       /* you can look at netlib.h for a description of the fields we
   4532 	 are passing to sendfile(). 08/2000 */
   4533       if (netperf_sendfile(send_socket, send_ring) != send_size) {
   4534 	/* the test was interrupted, must be the end of test. the
   4535 	   send_tcp_stream code has some WIN32 ifdefs that we do not
   4536 	   need here. */
   4537 	if ((len >=0) || SOCKET_EINTR(len)) {
   4538 	  break;
   4539 	}
   4540 	perror("netperf: data send error: sendfile");
   4541 	fprintf(stderr,
   4542 		"len was %d send_size was %d\n",
   4543 		len,
   4544 		send_size);
   4545 	fflush(stderr);
   4546 	exit(1);
   4547       }
   4548 
   4549 #ifdef WANT_HISTOGRAM
   4550       if (verbosity > 1) {
   4551 	/* timestamp the exit from the send call and update the
   4552 	   histogram */
   4553 
   4554 	HIST_timestamp(&time_two);
   4555 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   4556       }
   4557 #endif /* WANT_HISTOGRAM */
   4558 
   4559 #ifdef WANT_DEMO
   4560       demo_stream_interval(send_size);
   4561 #endif
   4562 
   4563 #ifdef WANT_INTERVALS
   4564       INTERVALS_WAIT();
   4565 #endif /* WANT_INTERVALS */
   4566 
   4567       /* now we want to move our pointer to the next position in the */
   4568       /* data buffer...we may also want to wrap back to the "beginning" */
   4569       /* of the bufferspace, so we will mod the number of messages sent */
   4570       /* by the send width, and use that to calculate the offset to add */
   4571       /* to the base pointer. */
   4572 
   4573       nummessages++;
   4574       send_ring = send_ring->next;
   4575       if (bytes_remaining) {
   4576 	bytes_remaining -= send_size;
   4577       }
   4578     }
   4579 
   4580     /* The test is over. Flush the buffers to the remote end. We do a
   4581        graceful release to insure that all data has been taken by the
   4582        remote. */
   4583 
   4584     /* but first, if the verbosity is greater than 1, find-out what */
   4585     /* the TCP maximum segment_size was (if possible) */
   4586     if (verbosity > 1) {
   4587       tcp_mss = -1;
   4588       get_tcp_info(send_socket,&tcp_mss);
   4589     }
   4590 
   4591     if (shutdown(send_socket,SHUT_WR) == SOCKET_ERROR) {
   4592       perror("netperf: cannot shutdown tcp stream socket");
   4593       exit(1);
   4594     }
   4595 
   4596     /* hang a recv() off the socket to block until the remote has */
   4597     /* brought all the data up into the application. it will do a */
   4598     /* shutdown to cause a FIN to be sent our way. We will assume that */
   4599     /* any exit from the recv() call is good... raj 4/93 */
   4600 
   4601     /* since we are using sendfile() instead of send, we have no
   4602        scratch buffer from the send_ring to use for the
   4603        receive. however, since we "know" that the recv should be
   4604        returning zero bytes (not that we are making the checks we
   4605        should) we can pass the address of the flags field. raj 08/2000
   4606     */
   4607 
   4608     recv(send_socket,
   4609 	 &(send_ring->flags),
   4610 	 sizeof(send_ring->flags),
   4611 	 0);
   4612 
   4613     /* this call will always give us the elapsed time for the test, and */
   4614     /* will also store-away the necessaries for cpu utilization */
   4615 
   4616     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
   4617 						/* measured and how */
   4618 						/* long did we really */
   4619 						/* run? */
   4620 
   4621     /* we are finished with the socket, so close it to prevent hitting */
   4622     /* the limit on maximum open files. */
   4623 
   4624     close(send_socket);
   4625 
   4626  #if defined(WANT_INTERVALS)
   4627 #ifdef WIN32
   4628     stop_itimer();
   4629 #endif
   4630 #endif /* WANT_INTERVALS */
   4631 
   4632    /* Get the statistics from the remote end. The remote will have */
   4633     /* calculated service demand and all those interesting things. If it */
   4634     /* wasn't supposed to care, it will return obvious values. */
   4635 
   4636     recv_response();
   4637 
   4638     if (!netperf_response.content.serv_errno) {
   4639       if (debug)
   4640 	fprintf(where,"remote results obtained\n");
   4641     }
   4642 
   4643     else {
   4644       Set_errno(netperf_response.content.serv_errno);
   4645       fprintf(where,
   4646 	      "netperf: remote error %d",
   4647 	      netperf_response.content.serv_errno);
   4648       perror("");
   4649       fflush(where);
   4650 
   4651       exit(1);
   4652     }
   4653 
   4654     /* We now calculate what our thruput was for the test. In the future, */
   4655     /* we may want to include a calculation of the thruput measured by */
   4656     /* the remote, but it should be the case that for a TCP stream test, */
   4657     /* that the two numbers should be *very* close... We calculate */
   4658     /* bytes_sent regardless of the way the test length was controlled. */
   4659     /* If it was time, we needed to, and if it was by bytes, the user may */
   4660     /* have specified a number of bytes that wasn't a multiple of the */
   4661     /* send_size, so we really didn't send what he asked for ;-) */
   4662 
   4663     bytes_sent	= ntohd(tcp_stream_result->bytes_received);
   4664 
   4665     thruput	= calc_thruput(bytes_sent);
   4666 
   4667     if (local_cpu_usage || remote_cpu_usage) {
   4668 
   4669       /* We must now do a little math for service demand and cpu */
   4670       /* utilization for the system(s) */
   4671       /* Of course, some of the information might be bogus because */
   4672       /* there was no idle counter in the kernel(s). We need to make */
   4673       /* a note of this for the user's benefit...*/
   4674       if (local_cpu_usage) {
   4675 
   4676 	local_cpu_utilization	= calc_cpu_util(0.0);
   4677 	local_service_demand	= calc_service_demand(bytes_sent,
   4678 						      0.0,
   4679 						      0.0,
   4680 						      0);
   4681       }
   4682       else {
   4683 	local_cpu_utilization	= (float) -1.0;
   4684 	local_service_demand	= (float) -1.0;
   4685       }
   4686 
   4687       if (remote_cpu_usage) {
   4688 
   4689 	remote_cpu_utilization	= tcp_stream_result->cpu_util;
   4690 	remote_service_demand	= calc_service_demand(bytes_sent,
   4691 						      0.0,
   4692 						      remote_cpu_utilization,
   4693 						      tcp_stream_result->num_cpus);
   4694       }
   4695       else {
   4696 	remote_cpu_utilization = (float) -1.0;
   4697 	remote_service_demand  = (float) -1.0;
   4698       }
   4699     }
   4700     else {
   4701       /* we were not measuring cpu, for the confidence stuff, we */
   4702       /* should make it -1.0 */
   4703       local_cpu_utilization	= (float) -1.0;
   4704       local_service_demand	= (float) -1.0;
   4705       remote_cpu_utilization = (float) -1.0;
   4706       remote_service_demand  = (float) -1.0;
   4707     }
   4708 
   4709     /* at this point, we want to calculate the confidence information. */
   4710     /* if debugging is on, calculate_confidence will print-out the */
   4711     /* parameters we pass it */
   4712 
   4713     calculate_confidence(confidence_iteration,
   4714 			 elapsed_time,
   4715 			 thruput,
   4716 			 local_cpu_utilization,
   4717 			 remote_cpu_utilization,
   4718 			 local_service_demand,
   4719 			 remote_service_demand);
   4720 
   4721     confidence_iteration++;
   4722   }
   4723 
   4724   /* at this point, we have finished making all the runs that we */
   4725   /* will be making. so, we should extract what the calcuated values */
   4726   /* are for all the confidence stuff. we could make the values */
   4727   /* global, but that seemed a little messy, and it did not seem worth */
   4728   /* all the mucking with header files. so, we create a routine much */
   4729   /* like calcualte_confidence, which just returns the mean values. */
   4730   /* raj 11/94 */
   4731 
   4732   retrieve_confident_values(&elapsed_time,
   4733 			    &thruput,
   4734 			    &local_cpu_utilization,
   4735 			    &remote_cpu_utilization,
   4736 			    &local_service_demand,
   4737 			    &remote_service_demand);
   4738 
   4739   /* We are now ready to print all the information. If the user */
   4740   /* has specified zero-level verbosity, we will just print the */
   4741   /* local service demand, or the remote service demand. If the */
   4742   /* user has requested verbosity level 1, he will get the basic */
   4743   /* "streamperf" numbers. If the user has specified a verbosity */
   4744   /* of greater than 1, we will display a veritable plethora of */
   4745   /* background information from outside of this block as it it */
   4746   /* not cpu_measurement specific...  */
   4747 
   4748   if (confidence < 0) {
   4749     /* we did not hit confidence, but were we asked to look for it? */
   4750     if (iteration_max > 1) {
   4751       display_confidence();
   4752     }
   4753   }
   4754 
   4755   if (local_cpu_usage || remote_cpu_usage) {
   4756     local_cpu_method = format_cpu_method(cpu_method);
   4757     remote_cpu_method = format_cpu_method(tcp_stream_result->cpu_method);
   4758 
   4759     switch (verbosity) {
   4760     case 0:
   4761 
   4762     if (local_cpu_usage) {
   4763 	fprintf(where,
   4764 		cpu_fmt_0,
   4765 		local_service_demand,
   4766 		local_cpu_method,
   4767 		((print_headers) ||
   4768 		 (result_brand == NULL)) ? "" : result_brand);
   4769       }
   4770 
   4771       else {
   4772 	fprintf(where,
   4773 		cpu_fmt_0,
   4774 		remote_service_demand,
   4775 		remote_cpu_method,
   4776 		((print_headers) ||
   4777 		 (result_brand == NULL)) ? "" : result_brand);
   4778       }
   4779 
   4780       break;
   4781 
   4782     case 1:
   4783     case 2:
   4784       if (print_headers) {
   4785 	fprintf(where,
   4786 		cpu_title,
   4787 		format_units(),
   4788 		local_cpu_method,
   4789 		remote_cpu_method);
   4790       }
   4791 
   4792       fprintf(where,
   4793 	      cpu_fmt_1,		/* the format string */
   4794 	      rsr_size,		        /* remote recvbuf size */
   4795 	      lss_size,		        /* local sendbuf size */
   4796 	      send_size,		/* how large were the sends */
   4797 	      elapsed_time,		/* how long was the test */
   4798 	      thruput, 		        /* what was the xfer rate */
   4799 	      local_cpu_utilization,	/* local cpu */
   4800 	      remote_cpu_utilization,	/* remote cpu */
   4801 	      local_service_demand,	/* local service demand */
   4802 	      remote_service_demand,	/* remote service demand */
   4803 	      ((print_headers) ||
   4804 	       (result_brand == NULL)) ? "" : result_brand);
   4805       break;
   4806     }
   4807 
   4808   }
   4809 
   4810   else {
   4811     /* The tester did not wish to measure service demand. */
   4812 
   4813     switch (verbosity) {
   4814 
   4815     case 0:
   4816 
   4817       fprintf(where,
   4818 	      tput_fmt_0,
   4819 	      thruput,
   4820 	      ((print_headers) ||
   4821 	       (result_brand == NULL)) ? "" : result_brand);
   4822       break;
   4823 
   4824     case 1:
   4825     case 2:
   4826 
   4827       if (print_headers) {
   4828 	fprintf(where,tput_title,format_units());
   4829       }
   4830 
   4831       fprintf(where,
   4832 	      tput_fmt_1,		/* the format string */
   4833 	      rsr_size, 		/* remote recvbuf size */
   4834 	      lss_size, 		/* local sendbuf size */
   4835 	      send_size,		/* how large were the sends */
   4836 	      elapsed_time, 		/* how long did it take */
   4837 	      thruput,                  /* how fast did it go */
   4838 	      ((print_headers) ||
   4839 	       (result_brand == NULL)) ? "" : result_brand);
   4840       break;
   4841     }
   4842   }
   4843 
   4844   /* it would be a good thing to include information about some of the */
   4845   /* other parameters that may have been set for this test, but at the */
   4846   /* moment, I do not wish to figure-out all the  formatting, so I will */
   4847   /* just put this comment here to help remind me that it is something */
   4848   /* that should be done at a later time. */
   4849 
   4850     if (verbosity > 1) {
   4851 
   4852     /* The user wanted to know it all, so we will give it to him. */
   4853     /* This information will include as much as we can find about */
   4854     /* TCP statistics, the alignments of the sends and receives */
   4855     /* and all that sort of rot... */
   4856 
   4857     /* this stuff needs to be worked-out in the presence of confidence */
   4858     /* intervals and multiple iterations of the test... raj 11/94 */
   4859 
   4860     fprintf(where,
   4861 	    ksink_fmt,
   4862 	    "Bytes",
   4863 	    "Bytes",
   4864 	    "Bytes",
   4865 	    local_send_align,
   4866 	    remote_recv_align,
   4867 	    local_send_offset,
   4868 	    remote_recv_offset,
   4869 	    bytes_sent,
   4870 	    bytes_sent / (double)nummessages,
   4871 	    nummessages,
   4872 	    bytes_sent / (double)tcp_stream_result->recv_calls,
   4873 	    tcp_stream_result->recv_calls);
   4874 
   4875     fprintf(where,
   4876 	    ksink_fmt2,
   4877 	    tcp_mss);
   4878 
   4879     fflush(where);
   4880 
   4881 #ifdef WANT_HISTOGRAM
   4882 
   4883     fprintf(where,"\n\nHistogram of time spent in send() call.\n");
   4884     fflush(where);
   4885     HIST_report(time_hist);
   4886 #endif /* WANT_HISTOGRAM */
   4887   }
   4888 }
   4889 
   4890 #endif /* HAVE_SENDFILE */
   4891 
   4892 /* This is the server-side routine for the tcp stream test. It is */
   4893 /* implemented as one routine. I could break things-out somewhat, but */
   4894 /* didn't feel it was necessary. */
   4895 
   4896 void
   4897 recv_tcp_stream()
   4898 {
   4899 
   4900   struct sockaddr_storage myaddr_in, peeraddr_in;
   4901   SOCKET s_listen,s_data;
   4902   netperf_socklen_t addrlen;
   4903   int	len;
   4904   unsigned int	receive_calls;
   4905   float	elapsed_time;
   4906   double   bytes_received;
   4907 
   4908   struct ring_elt *recv_ring;
   4909 
   4910   struct addrinfo *local_res;
   4911   char local_name[BUFSIZ];
   4912   char port_buffer[PORTBUFSIZE];
   4913 
   4914 #ifdef DO_SELECT
   4915   fd_set readfds;
   4916   struct timeval timeout;
   4917 #endif /* DO_SELECT */
   4918 
   4919   struct	tcp_stream_request_struct	*tcp_stream_request;
   4920   struct	tcp_stream_response_struct	*tcp_stream_response;
   4921   struct	tcp_stream_results_struct	*tcp_stream_results;
   4922 
   4923 #ifdef DO_SELECT
   4924   FD_ZERO(&readfds);
   4925   timeout.tv_sec = 1;
   4926   timeout.tv_usec = 0;
   4927 #endif /* DO_SELECT */
   4928 
   4929   tcp_stream_request	=
   4930     (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
   4931   tcp_stream_response	=
   4932     (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
   4933   tcp_stream_results	=
   4934     (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
   4935 
   4936   if (debug) {
   4937     fprintf(where,"netserver: recv_tcp_stream: entered...\n");
   4938     fflush(where);
   4939   }
   4940 
   4941   /* We want to set-up the listen socket with all the desired */
   4942   /* parameters and then let the initiator know that all is ready. If */
   4943   /* socket size defaults are to be used, then the initiator will have */
   4944   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   4945   /* send-back what they are. If that information cannot be determined, */
   4946   /* then we send-back -1's for the sizes. If things go wrong for any */
   4947   /* reason, we will drop back ten yards and punt. */
   4948 
   4949   /* If anything goes wrong, we want the remote to know about it. It */
   4950   /* would be best if the error that the remote reports to the user is */
   4951   /* the actual error we encountered, rather than some bogus unexpected */
   4952   /* response type message. */
   4953 
   4954   if (debug) {
   4955     fprintf(where,"recv_tcp_stream: setting the response type...\n");
   4956     fflush(where);
   4957   }
   4958 
   4959   netperf_response.content.response_type = TCP_STREAM_RESPONSE;
   4960 
   4961   if (debug) {
   4962     fprintf(where,"recv_tcp_stream: the response type is set...\n");
   4963     fflush(where);
   4964   }
   4965 
   4966   /* We now alter the message_ptr variable to be at the desired */
   4967   /* alignment with the desired offset. */
   4968 
   4969   if (debug) {
   4970     fprintf(where,"recv_tcp_stream: requested alignment of %d\n",
   4971 	    tcp_stream_request->recv_alignment);
   4972     fflush(where);
   4973   }
   4974 
   4975   /* create_data_socket expects to find some things in the global */
   4976   /* variables, so set the globals based on the values in the request. */
   4977   /* once the socket has been created, we will set the response values */
   4978   /* based on the updated value of those globals. raj 7/94 */
   4979   lss_size_req = tcp_stream_request->send_buf_size;
   4980   lsr_size_req = tcp_stream_request->recv_buf_size;
   4981   loc_nodelay  = tcp_stream_request->no_delay;
   4982   loc_rcvavoid = tcp_stream_request->so_rcvavoid;
   4983   loc_sndavoid = tcp_stream_request->so_sndavoid;
   4984 
   4985   set_hostname_and_port(local_name,
   4986 			port_buffer,
   4987 			nf_to_af(tcp_stream_request->ipfamily),
   4988 			tcp_stream_request->port);
   4989 
   4990   local_res = complete_addrinfo(local_name,
   4991 				local_name,
   4992 				port_buffer,
   4993 				nf_to_af(tcp_stream_request->ipfamily),
   4994 				SOCK_STREAM,
   4995 				IPPROTO_TCP,
   4996 				0);
   4997 
   4998   s_listen = create_data_socket(local_res);
   4999 
   5000   if (s_listen == INVALID_SOCKET) {
   5001     netperf_response.content.serv_errno = errno;
   5002     send_response();
   5003     exit(1);
   5004   }
   5005 
   5006 #ifdef WIN32
   5007   /* The test timer can fire during operations on the listening socket,
   5008      so to make the start_timer below work we have to move
   5009      it to close s_listen while we are blocked on accept. */
   5010   win_kludge_socket2 = s_listen;
   5011 #endif
   5012 
   5013   /* what sort of sizes did we end-up with? */
   5014   if (tcp_stream_request->receive_size == 0) {
   5015     if (lsr_size > 0) {
   5016       recv_size = lsr_size;
   5017     }
   5018     else {
   5019       recv_size = 4096;
   5020     }
   5021   }
   5022   else {
   5023     recv_size = tcp_stream_request->receive_size;
   5024   }
   5025 
   5026   /* we want to set-up our recv_ring in a manner analagous to what we */
   5027   /* do on the sending side. this is more for the sake of symmetry */
   5028   /* than for the needs of say copy avoidance, but it might also be */
   5029   /* more realistic - this way one could conceivably go with a */
   5030   /* double-buffering scheme when taking the data an putting it into */
   5031   /* the filesystem or something like that. raj 7/94 */
   5032 
   5033   if (recv_width == 0) {
   5034     recv_width = (lsr_size/recv_size) + 1;
   5035     if (recv_width == 1) recv_width++;
   5036   }
   5037 
   5038   recv_ring = allocate_buffer_ring(recv_width,
   5039 				   recv_size,
   5040 				   tcp_stream_request->recv_alignment,
   5041 				   tcp_stream_request->recv_offset);
   5042 
   5043   if (debug) {
   5044     fprintf(where,"recv_tcp_stream: receive alignment and offset set...\n");
   5045     fflush(where);
   5046   }
   5047 
   5048   /* Now, let's set-up the socket to listen for connections */
   5049   if (listen(s_listen, 5) == SOCKET_ERROR) {
   5050     netperf_response.content.serv_errno = errno;
   5051     close(s_listen);
   5052     send_response();
   5053 
   5054     exit(1);
   5055   }
   5056 
   5057 
   5058   /* now get the port number assigned by the system  */
   5059   addrlen = sizeof(myaddr_in);
   5060   if (getsockname(s_listen,
   5061 		  (struct sockaddr *)&myaddr_in,
   5062 		  &addrlen) == SOCKET_ERROR){
   5063     netperf_response.content.serv_errno = errno;
   5064     close(s_listen);
   5065     send_response();
   5066 
   5067     exit(1);
   5068   }
   5069 
   5070   /* Now myaddr_in contains the port and the internet address this is */
   5071   /* returned to the sender also implicitly telling the sender that the */
   5072   /* socket buffer sizing has been done. */
   5073 
   5074   tcp_stream_response->data_port_number =
   5075     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
   5076   netperf_response.content.serv_errno   = 0;
   5077 
   5078   /* But wait, there's more. If the initiator wanted cpu measurements, */
   5079   /* then we must call the calibrate routine, which will return the max */
   5080   /* rate back to the initiator. If the CPU was not to be measured, or */
   5081   /* something went wrong with the calibration, we will return a -1 to */
   5082   /* the initiator. */
   5083 
   5084   tcp_stream_response->cpu_rate = (float)0.0; 	/* assume no cpu */
   5085   if (tcp_stream_request->measure_cpu) {
   5086     tcp_stream_response->measure_cpu = 1;
   5087     tcp_stream_response->cpu_rate =
   5088       calibrate_local_cpu(tcp_stream_request->cpu_rate);
   5089   }
   5090   else {
   5091     tcp_stream_response->measure_cpu = 0;
   5092   }
   5093 
   5094   /* before we send the response back to the initiator, pull some of */
   5095   /* the socket parms from the globals */
   5096   tcp_stream_response->send_buf_size = lss_size;
   5097   tcp_stream_response->recv_buf_size = lsr_size;
   5098   tcp_stream_response->no_delay = loc_nodelay;
   5099   tcp_stream_response->so_rcvavoid = loc_rcvavoid;
   5100   tcp_stream_response->so_sndavoid = loc_sndavoid;
   5101   tcp_stream_response->receive_size = recv_size;
   5102 
   5103   send_response();
   5104 
   5105   addrlen = sizeof(peeraddr_in);
   5106 
   5107   if ((s_data=accept(s_listen,
   5108 		     (struct sockaddr *)&peeraddr_in,
   5109 		     &addrlen)) == INVALID_SOCKET) {
   5110     /* Let's just punt. The remote will be given some information */
   5111     close(s_listen);
   5112     exit(1);
   5113   }
   5114 
   5115 #ifdef WIN32
   5116   /* this is used so the timer thread can close the socket out from */
   5117   /* under us, which to date is the easiest/cleanest/least */
   5118   /* Windows-specific way I can find to force the winsock calls to */
   5119   /* return WSAEINTR with the test is over. anything that will run on */
   5120   /* 95 and NT and is closer to what netperf expects from Unix signals */
   5121   /* and such would be appreciated raj 1/96 */
   5122   win_kludge_socket = s_data;
   5123   win_kludge_socket2 = INVALID_SOCKET;
   5124 #endif /* WIN32 */
   5125 
   5126   times_up = 0;
   5127 
   5128   start_timer(tcp_stream_request->test_length + PAD_TIME);
   5129 
   5130 #ifdef KLUDGE_SOCKET_OPTIONS
   5131   /* this is for those systems which *INCORRECTLY* fail to pass */
   5132   /* attributes across an accept() call. Including this goes against */
   5133   /* my better judgement :( raj 11/95 */
   5134 
   5135   kludge_socket_options(s_data);
   5136 
   5137 #endif /* KLUDGE_SOCKET_OPTIONS */
   5138 
   5139   /* Now it's time to start receiving data on the connection. We will */
   5140   /* first grab the apropriate counters and then start grabbing. */
   5141 
   5142   cpu_start(tcp_stream_request->measure_cpu);
   5143 
   5144   /* The loop will exit when the sender does a shutdown, which will */
   5145   /* return a length of zero   */
   5146 
   5147   /* there used to be an #ifdef DIRTY call to access_buffer() here,
   5148      but we have switched from accessing the buffer before the recv()
   5149      call to accessing the buffer after the recv() call.  The
   5150      accessing before was, IIRC, related to having dirty data when
   5151      doing page-flipping copy avoidance. */
   5152 
   5153   bytes_received = 0;
   5154   receive_calls  = 0;
   5155 
   5156   while (!times_up && ((len = recv(s_data, recv_ring->buffer_ptr, recv_size, 0)) != 0)) {
   5157     if (len == SOCKET_ERROR ) {
   5158       if (times_up) {
   5159 	break;
   5160       }
   5161       netperf_response.content.serv_errno = errno;
   5162       send_response();
   5163       exit(1);
   5164     }
   5165     bytes_received += len;
   5166     receive_calls++;
   5167 
   5168 #ifdef DIRTY
   5169     /* we access the buffer after the recv() call now, rather than before */
   5170     access_buffer(recv_ring->buffer_ptr,
   5171 		  recv_size,
   5172 		  tcp_stream_request->dirty_count,
   5173 		  tcp_stream_request->clean_count);
   5174 #endif /* DIRTY */
   5175 
   5176 
   5177     /* move to the next buffer in the recv_ring */
   5178     recv_ring = recv_ring->next;
   5179 
   5180 #ifdef PAUSE
   5181     sleep(1);
   5182 #endif /* PAUSE */
   5183 
   5184 #ifdef DO_SELECT
   5185 	FD_SET(s_data,&readfds);
   5186 	select(s_data+1,&readfds,NULL,NULL,&timeout);
   5187 #endif /* DO_SELECT */
   5188 
   5189   }
   5190 
   5191   /* perform a shutdown to signal the sender that */
   5192   /* we have received all the data sent. raj 4/93 */
   5193 
   5194   if (shutdown(s_data,SHUT_WR) == SOCKET_ERROR && !times_up) {
   5195       netperf_response.content.serv_errno = errno;
   5196       send_response();
   5197       exit(1);
   5198     }
   5199 
   5200   cpu_stop(tcp_stream_request->measure_cpu,&elapsed_time);
   5201 
   5202   /* send the results to the sender			*/
   5203 
   5204   if (debug) {
   5205     fprintf(where,
   5206 	    "recv_tcp_stream: got %g bytes\n",
   5207 	    bytes_received);
   5208     fprintf(where,
   5209 	    "recv_tcp_stream: got %d recvs\n",
   5210 	    receive_calls);
   5211     fflush(where);
   5212   }
   5213 
   5214   tcp_stream_results->bytes_received	= htond(bytes_received);
   5215   tcp_stream_results->elapsed_time	= elapsed_time;
   5216   tcp_stream_results->recv_calls	= receive_calls;
   5217 
   5218   tcp_stream_results->cpu_method = cpu_method;
   5219   tcp_stream_results->num_cpus   = lib_num_loc_cpus;
   5220 
   5221   if (tcp_stream_request->measure_cpu) {
   5222     tcp_stream_results->cpu_util	= calc_cpu_util(0.0);
   5223   };
   5224 
   5225   if (debug) {
   5226     fprintf(where,
   5227 	    "recv_tcp_stream: test complete, sending results.\n");
   5228     fprintf(where,
   5229 	    "                 bytes_received %g receive_calls %d\n",
   5230 	    bytes_received,
   5231 	    receive_calls);
   5232     fprintf(where,
   5233 	    "                 len %d\n",
   5234 	    len);
   5235     fflush(where);
   5236   }
   5237 
   5238   send_response();
   5239 
   5240   /* we are now done with the sockets */
   5241   close(s_data);
   5242   close(s_listen);
   5243 
   5244   }
   5245 
   5246 /* This is the server-side routine for the tcp maerts test. It is
   5248    implemented as one routine. I could break things-out somewhat, but
   5249    didn't feel it was necessary. */
   5250 
   5251 void
   5252 recv_tcp_maerts()
   5253 {
   5254 
   5255   struct sockaddr_storage myaddr_in, peeraddr_in;
   5256   struct addrinfo *local_res;
   5257   char  local_name[BUFSIZ];
   5258   char  port_buffer[PORTBUFSIZE];
   5259 
   5260   SOCKET	s_listen,s_data;
   5261   netperf_socklen_t 	addrlen;
   5262   int	len;
   5263   unsigned int	send_calls;
   5264   float	elapsed_time;
   5265   double   bytes_sent = 0.0 ;
   5266 
   5267   struct ring_elt *send_ring;
   5268 
   5269   struct	tcp_maerts_request_struct	*tcp_maerts_request;
   5270   struct	tcp_maerts_response_struct	*tcp_maerts_response;
   5271   struct	tcp_maerts_results_struct	*tcp_maerts_results;
   5272 
   5273   tcp_maerts_request	=
   5274     (struct tcp_maerts_request_struct *)netperf_request.content.test_specific_data;
   5275   tcp_maerts_response	=
   5276     (struct tcp_maerts_response_struct *)netperf_response.content.test_specific_data;
   5277   tcp_maerts_results	=
   5278     (struct tcp_maerts_results_struct *)netperf_response.content.test_specific_data;
   5279 
   5280   if (debug) {
   5281     fprintf(where,"netserver: recv_tcp_maerts: entered...\n");
   5282     fflush(where);
   5283   }
   5284 
   5285   /* We want to set-up the listen socket with all the desired
   5286      parameters and then let the initiator know that all is ready. If
   5287      socket size defaults are to be used, then the initiator will have
   5288      sent us 0's. If the socket sizes cannot be changed, then we will
   5289      send-back what they are. If that information cannot be
   5290      determined, then we send-back -1's for the sizes. If things go
   5291      wrong for any reason, we will drop back ten yards and punt. */
   5292 
   5293   /* If anything goes wrong, we want the remote to know about it. It
   5294      would be best if the error that the remote reports to the user is
   5295      the actual error we encountered, rather than some bogus
   5296      unexpected response type message. */
   5297 
   5298   if (debug) {
   5299     fprintf(where,"recv_tcp_maerts: setting the response type...\n");
   5300     fflush(where);
   5301   }
   5302 
   5303   netperf_response.content.response_type = TCP_MAERTS_RESPONSE;
   5304 
   5305   if (debug) {
   5306     fprintf(where,"recv_tcp_maerts: the response type is set...\n");
   5307     fflush(where);
   5308   }
   5309 
   5310   /* We now alter the message_ptr variable to be at the desired */
   5311   /* alignment with the desired offset. */
   5312 
   5313   if (debug) {
   5314     fprintf(where,"recv_tcp_maerts: requested alignment of %d\n",
   5315 	    tcp_maerts_request->send_alignment);
   5316     fflush(where);
   5317   }
   5318 
   5319   /* Grab a socket to listen on, and then listen on it. */
   5320 
   5321   if (debug) {
   5322     fprintf(where,"recv_tcp_maerts: grabbing a socket...\n");
   5323     fflush(where);
   5324   }
   5325 
   5326   /* create_data_socket expects to find some things in the global */
   5327   /* variables, so set the globals based on the values in the request. */
   5328   /* once the socket has been created, we will set the response values */
   5329   /* based on the updated value of those globals. raj 7/94 */
   5330   lss_size_req = tcp_maerts_request->send_buf_size;
   5331   lsr_size_req = tcp_maerts_request->recv_buf_size;
   5332   loc_nodelay = tcp_maerts_request->no_delay;
   5333   loc_rcvavoid = tcp_maerts_request->so_rcvavoid;
   5334   loc_sndavoid = tcp_maerts_request->so_sndavoid;
   5335 
   5336   set_hostname_and_port(local_name,
   5337 			port_buffer,
   5338 			nf_to_af(tcp_maerts_request->ipfamily),
   5339 			tcp_maerts_request->port);
   5340 
   5341   local_res = complete_addrinfo(local_name,
   5342 				local_name,
   5343 				port_buffer,
   5344 				nf_to_af(tcp_maerts_request->ipfamily),
   5345 				SOCK_STREAM,
   5346 				IPPROTO_TCP,
   5347 				0);
   5348 
   5349   s_listen = create_data_socket(local_res);
   5350 
   5351   if (s_listen == INVALID_SOCKET) {
   5352     netperf_response.content.serv_errno = errno;
   5353     send_response();
   5354     exit(1);
   5355   }
   5356 
   5357 #ifdef WIN32
   5358   /* The test timer can fire during operations on the listening socket,
   5359      so to make the start_timer below work we have to move
   5360      it to close s_listen while we are blocked on accept. */
   5361   win_kludge_socket2 = s_listen;
   5362 #endif
   5363 
   5364 
   5365   /* what sort of sizes did we end-up with? */
   5366   if (tcp_maerts_request->send_size == 0) {
   5367     if (lss_size > 0) {
   5368       send_size = lss_size;
   5369     }
   5370     else {
   5371       send_size = 4096;
   5372     }
   5373   }
   5374   else {
   5375     send_size = tcp_maerts_request->send_size;
   5376   }
   5377 
   5378   /* we want to set-up our recv_ring in a manner analagous to what we */
   5379   /* do on the recving side. this is more for the sake of symmetry */
   5380   /* than for the needs of say copy avoidance, but it might also be */
   5381   /* more realistic - this way one could conceivably go with a */
   5382   /* double-buffering scheme when taking the data an putting it into */
   5383   /* the filesystem or something like that. raj 7/94 */
   5384 
   5385   if (send_width == 0) {
   5386     send_width = (lsr_size/send_size) + 1;
   5387     if (send_width == 1) send_width++;
   5388   }
   5389 
   5390   send_ring = allocate_buffer_ring(send_width,
   5391 				   send_size,
   5392 				   tcp_maerts_request->send_alignment,
   5393 				   tcp_maerts_request->send_offset);
   5394 
   5395   if (debug) {
   5396     fprintf(where,"recv_tcp_maerts: receive alignment and offset set...\n");
   5397     fflush(where);
   5398   }
   5399 
   5400   /* Now, let's set-up the socket to listen for connections */
   5401   if (listen(s_listen, 5) == SOCKET_ERROR) {
   5402     netperf_response.content.serv_errno = errno;
   5403     close(s_listen);
   5404     send_response();
   5405 
   5406     exit(1);
   5407   }
   5408 
   5409 
   5410   /* now get the port number assigned by the system  */
   5411   addrlen = sizeof(myaddr_in);
   5412   if (getsockname(s_listen,
   5413 		  (struct sockaddr *)&myaddr_in,
   5414 		  &addrlen) == SOCKET_ERROR){
   5415     netperf_response.content.serv_errno = errno;
   5416     close(s_listen);
   5417     send_response();
   5418 
   5419     exit(1);
   5420   }
   5421 
   5422   /* Now myaddr_in contains the port and the internet address this is */
   5423   /* returned to the sender also implicitly telling the sender that the */
   5424   /* socket buffer sizing has been done. */
   5425 
   5426   tcp_maerts_response->data_port_number =
   5427     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
   5428   netperf_response.content.serv_errno   = 0;
   5429 
   5430   /* But wait, there's more. If the initiator wanted cpu measurements, */
   5431   /* then we must call the calibrate routine, which will return the max */
   5432   /* rate back to the initiator. If the CPU was not to be measured, or */
   5433   /* something went wrong with the calibration, we will return a -1 to */
   5434   /* the initiator. */
   5435 
   5436   tcp_maerts_response->cpu_rate = (float)0.0; 	/* assume no cpu */
   5437   if (tcp_maerts_request->measure_cpu) {
   5438     tcp_maerts_response->measure_cpu = 1;
   5439     tcp_maerts_response->cpu_rate =
   5440       calibrate_local_cpu(tcp_maerts_request->cpu_rate);
   5441   }
   5442   else {
   5443     tcp_maerts_response->measure_cpu = 0;
   5444   }
   5445 
   5446   /* before we send the response back to the initiator, pull some of */
   5447   /* the socket parms from the globals */
   5448   tcp_maerts_response->send_buf_size = lss_size;
   5449   tcp_maerts_response->recv_buf_size = lsr_size;
   5450   tcp_maerts_response->no_delay = loc_nodelay;
   5451   tcp_maerts_response->so_rcvavoid = loc_rcvavoid;
   5452   tcp_maerts_response->so_sndavoid = loc_sndavoid;
   5453   tcp_maerts_response->send_size = send_size;
   5454 
   5455   send_response();
   5456 
   5457   addrlen = sizeof(peeraddr_in);
   5458 
   5459   /* we will start the timer before the accept() to be somewhat
   5460      analagous to the starting of the timer before the connect() call
   5461      in the TCP_STREAM test. raj 2002-06-21 */
   5462 
   5463   start_timer(tcp_maerts_request->test_length);
   5464 
   5465   /* Now it's time to start receiving data on the connection. We will
   5466      first grab the apropriate counters and then start grabbing. */
   5467 
   5468   cpu_start(tcp_maerts_request->measure_cpu);
   5469 
   5470 
   5471   if ((s_data=accept(s_listen,
   5472 		     (struct sockaddr *)&peeraddr_in,
   5473 		     &addrlen)) == INVALID_SOCKET) {
   5474     /* Let's just punt. The remote will be given some information */
   5475     close(s_listen);
   5476     exit(1);
   5477   }
   5478 
   5479 #ifdef WIN32
   5480   /* this is used so the timer thread can close the socket out from */
   5481   /* under us, which to date is the easiest/cleanest/least */
   5482   /* Windows-specific way I can find to force the winsock calls to */
   5483   /* return WSAEINTR with the test is over. anything that will run on */
   5484   /* 95 and NT and is closer to what netperf expects from Unix signals */
   5485   /* and such would be appreciated raj 1/96 */
   5486   win_kludge_socket = s_data;
   5487   win_kludge_socket2 = INVALID_SOCKET;
   5488 #endif /* WIN32 */
   5489 
   5490 #ifdef KLUDGE_SOCKET_OPTIONS
   5491 
   5492   /* this is for those systems which *INCORRECTLY* fail to pass
   5493      attributes across an accept() call. Including this goes against
   5494      my better judgement :( raj 11/95 */
   5495 
   5496   kludge_socket_options(s_data);
   5497 
   5498 #endif /* KLUDGE_SOCKET_OPTIONS */
   5499 
   5500   /* The loop will exit when the sender does a shutdown, which will */
   5501   /* return a length of zero   */
   5502 
   5503   bytes_sent = 0.0;
   5504   send_calls  = 0;
   5505 
   5506   len = 0;   /* nt-lint; len is not initialized (printf far below) if
   5507 		times_up initially true.*/
   5508   times_up = 0; /* must remember to initialize this little beauty */
   5509   while (!times_up) {
   5510 
   5511 #ifdef DIRTY
   5512     /* we want to dirty some number of consecutive integers in the buffer */
   5513     /* we are about to send. we may also want to bring some number of */
   5514     /* them cleanly into the cache. The clean ones will follow any dirty */
   5515     /* ones into the cache. */
   5516 
   5517   access_buffer(send_ring->buffer_ptr,
   5518 		send_size,
   5519 		tcp_maerts_request->dirty_count,
   5520 		tcp_maerts_request->clean_count);
   5521 
   5522 #endif /* DIRTY */
   5523 
   5524     if((len=send(s_data,
   5525 		 send_ring->buffer_ptr,
   5526 		 send_size,
   5527 		 0)) != send_size) {
   5528 		if ((len >=0) || SOCKET_EINTR(len)) {
   5529 	      /* the test was interrupted, must be the end of test */
   5530 	      break;
   5531 		}
   5532       netperf_response.content.serv_errno = errno;
   5533       send_response();
   5534       exit(1);
   5535     }
   5536 
   5537     bytes_sent += len;
   5538     send_calls++;
   5539 
   5540     /* more to the next buffer in the send_ring */
   5541     send_ring = send_ring->next;
   5542 
   5543   }
   5544 
   5545   /* perform a shutdown to signal the sender that */
   5546   /* we have received all the data sent. raj 4/93 */
   5547 
   5548   if (shutdown(s_data,SHUT_WR) == SOCKET_ERROR) {
   5549       netperf_response.content.serv_errno = errno;
   5550       send_response();
   5551       exit(1);
   5552     }
   5553 
   5554   /* hang a recv() off the socket to block until the remote has
   5555      brought all the data up into the application. it will do a
   5556      shutdown to cause a FIN to be sent our way. We will assume that
   5557      any exit from the recv() call is good... raj 4/93 */
   5558 
   5559   recv(s_data, send_ring->buffer_ptr, send_size, 0);
   5560 
   5561 
   5562   cpu_stop(tcp_maerts_request->measure_cpu,&elapsed_time);
   5563 
   5564   /* send the results to the sender			*/
   5565 
   5566   if (debug) {
   5567     fprintf(where,
   5568 	    "recv_tcp_maerts: got %g bytes\n",
   5569 	    bytes_sent);
   5570     fprintf(where,
   5571 	    "recv_tcp_maerts: got %d sends\n",
   5572 	    send_calls);
   5573     fflush(where);
   5574   }
   5575 
   5576   tcp_maerts_results->bytes_sent	= htond(bytes_sent);
   5577   tcp_maerts_results->elapsed_time	= elapsed_time;
   5578   tcp_maerts_results->send_calls	= send_calls;
   5579 
   5580   if (tcp_maerts_request->measure_cpu) {
   5581     tcp_maerts_results->cpu_util	= calc_cpu_util(0.0);
   5582   };
   5583 
   5584   if (debug) {
   5585     fprintf(where,
   5586 	    "recv_tcp_maerts: test complete, sending results.\n");
   5587     fprintf(where,
   5588 	    "                 bytes_sent %g send_calls %d\n",
   5589 	    bytes_sent,
   5590 	    send_calls);
   5591     fprintf(where,
   5592 	    "                 len %d\n",
   5593 	    len);
   5594     fflush(where);
   5595   }
   5596 
   5597   tcp_maerts_results->cpu_method = cpu_method;
   5598   tcp_maerts_results->num_cpus   = lib_num_loc_cpus;
   5599   send_response();
   5600 
   5601   /* we are now done with the sockets */
   5602   close(s_data);
   5603   close(s_listen);
   5604 
   5605   }
   5606 
   5607 
   5609  /* this routine implements the sending (netperf) side of the TCP_RR */
   5610  /* test. */
   5611 #ifndef WANT_MIGRATION
   5612 void
   5613 send_tcp_rr(char remote_host[])
   5614 {
   5615 
   5616   char *tput_title = "\
   5617 Local /Remote\n\
   5618 Socket Size   Request  Resp.   Elapsed  Trans.\n\
   5619 Send   Recv   Size     Size    Time     Rate         \n\
   5620 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
   5621 
   5622   char *tput_title_band = "\
   5623 Local /Remote\n\
   5624 Socket Size   Request  Resp.   Elapsed  \n\
   5625 Send   Recv   Size     Size    Time     Throughput \n\
   5626 bytes  Bytes  bytes    bytes   secs.    %s/sec   \n\n";
   5627 
   5628   char *tput_fmt_0 =
   5629     "%7.2f %s\n";
   5630 
   5631   char *tput_fmt_1_line_1 = "\
   5632 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   %s\n";
   5633   char *tput_fmt_1_line_2 = "\
   5634 %-6d %-6d\n";
   5635 
   5636   char *cpu_title = "\
   5637 Local /Remote\n\
   5638 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
   5639 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
   5640 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
   5641 
   5642   char *cpu_title_tput = "\
   5643 Local /Remote\n\
   5644 Socket Size   Request Resp.  Elapsed Tput     CPU    CPU    S.dem   S.dem\n\
   5645 Send   Recv   Size    Size   Time    %-8.8s local  remote local   remote\n\
   5646 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
   5647 
   5648   char *cpu_title_latency = "\
   5649 Local /Remote\n\
   5650 Socket Size   Request Resp.  Elapsed Latency  CPU    CPU    S.dem   S.dem\n\
   5651 Send   Recv   Size    Size   Time    usecs    local  remote local   remote\n\
   5652 bytes  bytes  bytes   bytes  secs.   per tran %% %c    %% %c    us/Tr   us/Tr\n\n";
   5653 
   5654   char *cpu_fmt_0 =
   5655     "%6.3f %c %s\n";
   5656 
   5657   char *cpu_fmt_1_line_1 = "\
   5658 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f  %-6.2f %-6.2f %-6.3f  %-6.3f %s\n";
   5659 
   5660   char *cpu_fmt_1_line_2 = "\
   5661 %-6d %-6d\n";
   5662 
   5663   char *ksink_fmt = "\
   5664 Alignment      Offset         RoundTrip  Trans    Throughput\n\
   5665 Local  Remote  Local  Remote  Latency    Rate     %-8.8s/s\n\
   5666 Send   Recv    Send   Recv    usec/Tran  per sec  Outbound   Inbound\n\
   5667 %5d  %5d   %5d  %5d   %-6.3f   %-6.3f %-6.3f    %-6.3f\n";
   5668 
   5669 
   5670   int			timed_out = 0;
   5671   float			elapsed_time;
   5672 
   5673   int	len;
   5674   char	*temp_message_ptr;
   5675   int	nummessages;
   5676   SOCKET	send_socket;
   5677   int	trans_remaining;
   5678   double	bytes_xferd;
   5679 
   5680   struct ring_elt *send_ring;
   5681   struct ring_elt *recv_ring;
   5682 
   5683   int	rsp_bytes_left;
   5684   int	rsp_bytes_recvd;
   5685 
   5686   float	local_cpu_utilization;
   5687   float	local_service_demand;
   5688   float	remote_cpu_utilization;
   5689   float	remote_service_demand;
   5690   double	thruput;
   5691 
   5692   struct addrinfo *local_res;
   5693   struct addrinfo *remote_res;
   5694 
   5695   struct	tcp_rr_request_struct	*tcp_rr_request;
   5696   struct	tcp_rr_response_struct	*tcp_rr_response;
   5697   struct	tcp_rr_results_struct	*tcp_rr_result;
   5698 
   5699 #ifdef WANT_FIRST_BURST
   5700 #define REQUEST_CWND_INITIAL 2
   5701   /* "in the beginning..." the WANT_FIRST_BURST stuff was like both
   5702      Unix and the state of New Jersey - both were simple an unspoiled.
   5703      then it was realized that some stacks are quite picky about
   5704      initial congestion windows and a non-trivial initial burst of
   5705      requests would not be individual segments even with TCP_NODELAY
   5706      set. so, we have to start tracking a poor-man's congestion window
   5707      up here in window space because we want to try to make something
   5708      happen that frankly, we cannot guarantee with the specification
   5709      of TCP.  ain't that grand?-)  raj 2006-01-30 */
   5710   int requests_outstanding = 0;
   5711   int request_cwnd = REQUEST_CWND_INITIAL;  /* we ass-u-me that having
   5712 					       three requests
   5713 					       outstanding at the
   5714 					       beginning of the test
   5715 					       is ok with TCP stacks
   5716 					       of interest. the first
   5717 					       two will come from our
   5718 					       first_burst loop, and
   5719 					       the third from our
   5720 					       regularly scheduled
   5721 					       send */
   5722 #endif
   5723 
   5724   tcp_rr_request =
   5725     (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data;
   5726   tcp_rr_response=
   5727     (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data;
   5728   tcp_rr_result	=
   5729     (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data;
   5730 
   5731 #ifdef WANT_HISTOGRAM
   5732   if (verbosity > 1) {
   5733     time_hist = HIST_new();
   5734   }
   5735 #endif /* WANT_HISTOGRAM */
   5736 
   5737   /* since we are now disconnected from the code that established the */
   5738   /* control socket, and since we want to be able to use different */
   5739   /* protocols and such, we are passed the name of the remote host and */
   5740   /* must turn that into the test specific addressing information. */
   5741 
   5742   complete_addrinfos(&remote_res,
   5743 		     &local_res,
   5744 		     remote_host,
   5745 		     SOCK_STREAM,
   5746 		     IPPROTO_TCP,
   5747 		     0);
   5748 
   5749   if ( print_headers ) {
   5750     print_top_test_header("TCP REQUEST/RESPONSE TEST",local_res,remote_res);
   5751   }
   5752 
   5753   /* initialize a few counters */
   5754 
   5755   send_ring = NULL;
   5756   recv_ring = NULL;
   5757   confidence_iteration = 1;
   5758   init_stat();
   5759 
   5760   /* we have a great-big while loop which controls the number of times */
   5761   /* we run a particular test. this is for the calculation of a */
   5762   /* confidence interval (I really should have stayed awake during */
   5763   /* probstats :). If the user did not request confidence measurement */
   5764   /* (no confidence is the default) then we will only go though the */
   5765   /* loop once. the confidence stuff originates from the folks at IBM */
   5766 
   5767   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   5768 	 (confidence_iteration <= iteration_min)) {
   5769 
   5770     /* initialize a few counters. we have to remember that we might be */
   5771     /* going through the loop more than once. */
   5772 
   5773     nummessages     = 0;
   5774     bytes_xferd     = 0.0;
   5775     times_up        = 0;
   5776     timed_out       = 0;
   5777     trans_remaining = 0;
   5778 
   5779 #ifdef WANT_FIRST_BURST
   5780     /* we have to remember to reset the number of transactions
   5781        outstanding and the "congestion window for each new
   5782        iteration. raj 2006-01-31 */
   5783     requests_outstanding = 0;
   5784     request_cwnd = REQUEST_CWND_INITIAL;
   5785 #endif
   5786 
   5787 
   5788     /* set-up the data buffers with the requested alignment and offset. */
   5789     /* since this is a request/response test, default the send_width and */
   5790     /* recv_width to 1 and not two raj 7/94 */
   5791 
   5792     if (send_width == 0) send_width = 1;
   5793     if (recv_width == 0) recv_width = 1;
   5794 
   5795     if (send_ring == NULL) {
   5796       send_ring = allocate_buffer_ring(send_width,
   5797 				       req_size,
   5798 				       local_send_align,
   5799 				       local_send_offset);
   5800     }
   5801 
   5802     if (recv_ring == NULL) {
   5803       recv_ring = allocate_buffer_ring(recv_width,
   5804 				       rsp_size,
   5805 				       local_recv_align,
   5806 				       local_recv_offset);
   5807     }
   5808 
   5809     /*set up the data socket                        */
   5810     send_socket = create_data_socket(local_res);
   5811 
   5812     if (send_socket == INVALID_SOCKET){
   5813       perror("netperf: send_tcp_rr: tcp stream data socket");
   5814       exit(1);
   5815     }
   5816 
   5817     if (debug) {
   5818       fprintf(where,"send_tcp_rr: send_socket obtained...\n");
   5819     }
   5820 
   5821     /* If the user has requested cpu utilization measurements, we must */
   5822     /* calibrate the cpu(s). We will perform this task within the tests */
   5823     /* themselves. If the user has specified the cpu rate, then */
   5824     /* calibrate_local_cpu will return rather quickly as it will have */
   5825     /* nothing to do. If local_cpu_rate is zero, then we will go through */
   5826     /* all the "normal" calibration stuff and return the rate back.*/
   5827 
   5828     if (local_cpu_usage) {
   5829       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   5830     }
   5831 
   5832     if (!no_control) {
   5833       /* Tell the remote end to do a listen. The server alters the
   5834 	 socket paramters on the other side at this point, hence the
   5835 	 reason for all the values being passed in the setup
   5836 	 message. If the user did not specify any of the parameters,
   5837 	 they will be passed as 0, which will indicate to the remote
   5838 	 that no changes beyond the system's default should be
   5839 	 used. Alignment is the exception, it will default to 8, which
   5840 	 will be no alignment alterations. */
   5841 
   5842       netperf_request.content.request_type	=	DO_TCP_RR;
   5843       tcp_rr_request->recv_buf_size	=	rsr_size_req;
   5844       tcp_rr_request->send_buf_size	=	rss_size_req;
   5845       tcp_rr_request->recv_alignment    =	remote_recv_align;
   5846       tcp_rr_request->recv_offset	=	remote_recv_offset;
   5847       tcp_rr_request->send_alignment    =	remote_send_align;
   5848       tcp_rr_request->send_offset	=	remote_send_offset;
   5849       tcp_rr_request->request_size	=	req_size;
   5850       tcp_rr_request->response_size	=	rsp_size;
   5851       tcp_rr_request->no_delay	        =	rem_nodelay;
   5852       tcp_rr_request->measure_cpu	=	remote_cpu_usage;
   5853       tcp_rr_request->cpu_rate	        =	remote_cpu_rate;
   5854       tcp_rr_request->so_rcvavoid	=	rem_rcvavoid;
   5855       tcp_rr_request->so_sndavoid	=	rem_sndavoid;
   5856       if (test_time) {
   5857 	tcp_rr_request->test_length	=	test_time;
   5858       }
   5859       else {
   5860 	tcp_rr_request->test_length	=	test_trans * -1;
   5861       }
   5862       tcp_rr_request->port              =      atoi(remote_data_port);
   5863       tcp_rr_request->ipfamily = af_to_nf(remote_res->ai_family);
   5864 
   5865       if (debug > 1) {
   5866 	fprintf(where,"netperf: send_tcp_rr: requesting TCP rr test\n");
   5867       }
   5868 
   5869       send_request();
   5870 
   5871       /* The response from the remote will contain all of the relevant
   5872 	 socket parameters for this test type. We will put them back
   5873 	 into the variables here so they can be displayed if desired.
   5874 	 The remote will have calibrated CPU if necessary, and will
   5875 	 have done all the needed set-up we will have calibrated the
   5876 	 cpu locally before sending the request, and will grab the
   5877 	 counter value right after the connect returns. The remote
   5878 	 will grab the counter right after the accept call. This saves
   5879 	 the hassle of extra messages being sent for the TCP
   5880 	 tests.  */
   5881 
   5882       recv_response();
   5883 
   5884       if (!netperf_response.content.serv_errno) {
   5885 	if (debug)
   5886 	  fprintf(where,"remote listen done.\n");
   5887 	rsr_size          = tcp_rr_response->recv_buf_size;
   5888 	rss_size          = tcp_rr_response->send_buf_size;
   5889 	rem_nodelay       = tcp_rr_response->no_delay;
   5890 	remote_cpu_usage  = tcp_rr_response->measure_cpu;
   5891 	remote_cpu_rate   = tcp_rr_response->cpu_rate;
   5892 	/* make sure that port numbers are in network order */
   5893 	set_port_number(remote_res,(short)tcp_rr_response->data_port_number);
   5894       }
   5895       else {
   5896 	Set_errno(netperf_response.content.serv_errno);
   5897 	fprintf(where,
   5898 		"netperf: remote error %d",
   5899 		netperf_response.content.serv_errno);
   5900 	perror("");
   5901 	fflush(where);
   5902 
   5903 	exit(1);
   5904       }
   5905     }
   5906 
   5907 #ifdef WANT_DEMO
   5908     demo_rr_setup(1000);
   5909 #endif
   5910 
   5911     /*Connect up to the remote port on the data socket  */
   5912     if (connect(send_socket,
   5913 		remote_res->ai_addr,
   5914 		remote_res->ai_addrlen) == INVALID_SOCKET){
   5915       perror("netperf: data socket connect failed");
   5916 
   5917       exit(1);
   5918     }
   5919 
   5920 #ifdef WIN32
   5921     /* this is used so the timer thread can close the socket out from */
   5922     /* under us, which to date is the easiest/cleanest/least */
   5923     /* Windows-specific way I can find to force the winsock calls to */
   5924     /* return WSAEINTR with the test is over. anything that will run on */
   5925     /* 95 and NT and is closer to what netperf expects from Unix signals */
   5926     /* and such would be appreciated raj 1/96 */
   5927     win_kludge_socket = send_socket;
   5928 #endif /* WIN32 */
   5929 
   5930     /* Data Socket set-up is finished. If there were problems, either the */
   5931     /* connect would have failed, or the previous response would have */
   5932     /* indicated a problem. I failed to see the value of the extra */
   5933     /* message after the accept on the remote. If it failed, we'll see it */
   5934     /* here. If it didn't, we might as well start pumping data. */
   5935 
   5936     /* Set-up the test end conditions. For a request/response test, they */
   5937     /* can be either time or transaction based. */
   5938 
   5939     if (test_time) {
   5940       /* The user wanted to end the test after a period of time. */
   5941       times_up = 0;
   5942       trans_remaining = 0;
   5943       start_timer(test_time);
   5944     }
   5945     else {
   5946       /* The tester wanted to send a number of bytes. */
   5947       trans_remaining = test_bytes;
   5948       times_up = 1;
   5949     }
   5950 
   5951     /* The cpu_start routine will grab the current time and possibly */
   5952     /* value of the idle counter for later use in measuring cpu */
   5953     /* utilization and/or service demand and thruput. */
   5954 
   5955     cpu_start(local_cpu_usage);
   5956 
   5957 #ifdef WANT_INTERVALS
   5958     INTERVALS_INIT();
   5959 #endif /* WANT_INTERVALS */
   5960 
   5961     /* We use an "OR" to control test execution. When the test is */
   5962     /* controlled by time, the byte count check will always return false. */
   5963     /* When the test is controlled by byte count, the time test will */
   5964     /* always return false. When the test is finished, the whole */
   5965     /* expression will go false and we will stop sending data. I think I */
   5966     /* just arbitrarily decrement trans_remaining for the timed test, but */
   5967     /* will not do that just yet... One other question is whether or not */
   5968     /* the send buffer and the receive buffer should be the same buffer. */
   5969 
   5970 #ifdef WANT_DEMO
   5971       if (demo_mode) {
   5972 	demo_first_timestamp();
   5973       }
   5974 #endif
   5975 
   5976     while ((!times_up) || (trans_remaining > 0)) {
   5977       /* send the request. we assume that if we use a blocking socket, */
   5978       /* the request will be sent at one shot. */
   5979 
   5980 #ifdef WANT_FIRST_BURST
   5981       /* we can inject no more than request_cwnd, which will grow with
   5982 	 time, and no more than first_burst_size.  we don't use <= to
   5983 	 account for the "regularly scheduled" send call.  of course
   5984 	 that makes it more a "max_outstanding_ than a
   5985 	 "first_burst_size" but for now we won't fix the names. also,
   5986 	 I suspect the extra check against < first_burst_size is
   5987 	 redundant since later I expect to make sure that request_cwnd
   5988 	 can never get larger than first_burst_size, but just at the
   5989 	 moment I'm feeling like a belt and suspenders kind of
   5990 	 programmer. raj 2006-01-30 */
   5991       while ((first_burst_size > 0) &&
   5992 	     (requests_outstanding < request_cwnd) &&
   5993 	     (requests_outstanding < first_burst_size)) {
   5994 	if (debug) {
   5995 	  fprintf(where,
   5996 		  "injecting, req_outstndng %d req_cwnd %d burst %d\n",
   5997 		  requests_outstanding,
   5998 		  request_cwnd,
   5999 		  first_burst_size);
   6000 	}
   6001 	if ((len = send(send_socket,
   6002 			send_ring->buffer_ptr,
   6003 			req_size,
   6004 			0)) != req_size) {
   6005 	  /* we should never hit the end of the test in the first burst */
   6006 	  perror("send_tcp_rr: initial burst data send error");
   6007 	  exit(-1);
   6008 	}
   6009 	requests_outstanding += 1;
   6010       }
   6011 
   6012 #endif /* WANT_FIRST_BURST */
   6013 
   6014 #ifdef WANT_HISTOGRAM
   6015       if (verbosity > 1) {
   6016 	/* timestamp just before our call to send, and then again just
   6017 	   after the receive raj 8/94 */
   6018 	/* but only if we are actually going to display one. raj
   6019 	   2007-02-07 */
   6020 
   6021 	HIST_timestamp(&time_one);
   6022       }
   6023 #endif /* WANT_HISTOGRAM */
   6024 
   6025       if ((len = send(send_socket,
   6026 		      send_ring->buffer_ptr,
   6027 		      req_size,
   6028 		      0)) != req_size) {
   6029 	if (SOCKET_EINTR(len) || (errno == 0)) {
   6030 	  /* we hit the end of a */
   6031 	  /* timed test. */
   6032 	  timed_out = 1;
   6033 	  break;
   6034 	}
   6035 	perror("send_tcp_rr: data send error");
   6036 	exit(1);
   6037       }
   6038       send_ring = send_ring->next;
   6039 
   6040 #ifdef WANT_FIRST_BURST
   6041       requests_outstanding += 1;
   6042 #endif
   6043 
   6044       /* receive the response */
   6045       rsp_bytes_left = rsp_size;
   6046       temp_message_ptr  = recv_ring->buffer_ptr;
   6047       while(rsp_bytes_left > 0) {
   6048 	if((rsp_bytes_recvd=recv(send_socket,
   6049 				 temp_message_ptr,
   6050 				 rsp_bytes_left,
   6051 				 0)) == SOCKET_ERROR || rsp_bytes_recvd == 0) {
   6052 		if ( SOCKET_EINTR(rsp_bytes_recvd) ) {
   6053 		    /* We hit the end of a timed test. */
   6054 			timed_out = 1;
   6055 			break;
   6056 		}
   6057 	  perror("send_tcp_rr: data recv error");
   6058 	  exit(1);
   6059 	}
   6060 	rsp_bytes_left -= rsp_bytes_recvd;
   6061 	temp_message_ptr  += rsp_bytes_recvd;
   6062       }
   6063       recv_ring = recv_ring->next;
   6064 
   6065 #ifdef WANT_FIRST_BURST
   6066       /* so, since we've gotten a response back, update the
   6067 	 bookkeeping accordingly.  there is one less request
   6068 	 outstanding and we can put one more out there than before. */
   6069       requests_outstanding -= 1;
   6070       if (request_cwnd < first_burst_size) {
   6071 	request_cwnd += 1;
   6072 	if (debug) {
   6073 	  fprintf(where,
   6074 		  "incr req_cwnd to %d first_burst %d reqs_outstndng %d\n",
   6075 		  request_cwnd,
   6076 		  first_burst_size,
   6077 		  requests_outstanding);
   6078 	}
   6079       }
   6080 #endif
   6081       if (timed_out) {
   6082 	/* we may have been in a nested while loop - we need */
   6083 	/* another call to break. */
   6084 	break;
   6085       }
   6086 
   6087 #ifdef WANT_HISTOGRAM
   6088       if (verbosity > 1) {
   6089 	HIST_timestamp(&time_two);
   6090 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   6091       }
   6092 #endif /* WANT_HISTOGRAM */
   6093 
   6094 #ifdef WANT_DEMO
   6095       demo_rr_interval(1);
   6096 #endif
   6097 
   6098 #ifdef WANT_INTERVALS
   6099       INTERVALS_WAIT();
   6100 #endif /* WANT_INTERVALS */
   6101 
   6102       nummessages++;
   6103       if (trans_remaining) {
   6104 	trans_remaining--;
   6105       }
   6106 
   6107       if (debug > 3) {
   6108 	if ((nummessages % 100) == 0) {
   6109 	  fprintf(where,
   6110 		  "Transaction %d completed\n",
   6111 		  nummessages);
   6112 	  fflush(where);
   6113 	}
   6114       }
   6115     }
   6116 
   6117     /* At this point we used to call shutdown on the data socket to be
   6118        sure all the data was delivered, but this was not germane in a
   6119        request/response test, and it was causing the tests to "hang"
   6120        when they were being controlled by time. So, I have replaced
   6121        this shutdown call with a call to close that can be found later
   6122        in the procedure. */
   6123 
   6124     /* this call will always give us the elapsed time for the test,
   6125        and will also store-away the necessaries for cpu utilization */
   6126 
   6127     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
   6128 						/* measured? how long */
   6129 						/* did we really run? */
   6130 
   6131 #if defined(WANT_INTERVALS)
   6132 #ifdef WIN32
   6133     stop_itimer();
   6134 #endif
   6135 #endif /* WANT_INTERVALS */
   6136 
   6137     if (!no_control) {
   6138       /* Get the statistics from the remote end. The remote will have
   6139 	 calculated CPU utilization. If it wasn't supposed to care, it
   6140 	 will return obvious values. */
   6141 
   6142       recv_response();
   6143       if (!netperf_response.content.serv_errno) {
   6144 	if (debug)
   6145 	  fprintf(where,"remote results obtained\n");
   6146       }
   6147       else {
   6148 	Set_errno(netperf_response.content.serv_errno);
   6149 	fprintf(where,"netperf: remote error %d",
   6150 		netperf_response.content.serv_errno);
   6151 	perror("");
   6152 	fflush(where);
   6153 	exit(1);
   6154       }
   6155     }
   6156 
   6157     /* We now calculate what our "throughput" was for the test. */
   6158 
   6159     bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
   6160     thruput	= nummessages/elapsed_time;
   6161 
   6162     if (local_cpu_usage || remote_cpu_usage) {
   6163       /* We must now do a little math for service demand and cpu
   6164        utilization for the system(s) Of course, some of the
   6165        information might be bogus because there was no idle counter in
   6166        the kernel(s). We need to make a note of this for the user's
   6167        benefit... */
   6168       if (local_cpu_usage) {
   6169 	local_cpu_utilization = calc_cpu_util(0.0);
   6170  	/* since calc_service demand is doing ms/Kunit we will
   6171 	   multiply the number of transaction by 1024 to get "good"
   6172 	   numbers */
   6173 	local_service_demand  = calc_service_demand((double) nummessages*1024,
   6174 						    0.0,
   6175 						    0.0,
   6176 						    0);
   6177       }
   6178       else {
   6179 	local_cpu_utilization	= (float) -1.0;
   6180 	local_service_demand	= (float) -1.0;
   6181       }
   6182 
   6183       if (remote_cpu_usage) {
   6184 	remote_cpu_utilization = tcp_rr_result->cpu_util;
   6185 	/* since calc_service demand is doing ms/Kunit we will
   6186 	   multiply the number of transaction by 1024 to get "good"
   6187 	   numbers */
   6188 	remote_service_demand = calc_service_demand((double) nummessages*1024,
   6189 						    0.0,
   6190 						    remote_cpu_utilization,
   6191 						    tcp_rr_result->num_cpus);
   6192       }
   6193       else {
   6194 	remote_cpu_utilization = (float) -1.0;
   6195 	remote_service_demand  = (float) -1.0;
   6196       }
   6197 
   6198     }
   6199     else {
   6200       /* we were not measuring cpu, for the confidence stuff, we */
   6201       /* should make it -1.0 */
   6202       local_cpu_utilization	= (float) -1.0;
   6203       local_service_demand	= (float) -1.0;
   6204       remote_cpu_utilization = (float) -1.0;
   6205       remote_service_demand  = (float) -1.0;
   6206     }
   6207 
   6208     /* at this point, we want to calculate the confidence information.
   6209        if debugging is on, calculate_confidence will print-out the
   6210        parameters we pass it */
   6211 
   6212     calculate_confidence(confidence_iteration,
   6213 			 elapsed_time,
   6214 			 thruput,
   6215 			 local_cpu_utilization,
   6216 			 remote_cpu_utilization,
   6217 			 local_service_demand,
   6218 			 remote_service_demand);
   6219 
   6220 
   6221     confidence_iteration++;
   6222 
   6223     /* we are now done with the socket, so close it */
   6224     close(send_socket);
   6225 
   6226   }
   6227 
   6228   retrieve_confident_values(&elapsed_time,
   6229 			    &thruput,
   6230 			    &local_cpu_utilization,
   6231 			    &remote_cpu_utilization,
   6232 			    &local_service_demand,
   6233 			    &remote_service_demand);
   6234 
   6235   /* We are now ready to print all the information. If the user has
   6236      specified zero-level verbosity, we will just print the local
   6237      service demand, or the remote service demand. If the user has
   6238      requested verbosity level 1, he will get the basic "streamperf"
   6239      numbers. If the user has specified a verbosity of greater than 1,
   6240      we will display a veritable plethora of background information
   6241      from outside of this block as it it not cpu_measurement
   6242      specific...  */
   6243 
   6244   if (confidence < 0) {
   6245     /* we did not hit confidence, but were we asked to look for it? */
   6246     if (iteration_max > 1) {
   6247       display_confidence();
   6248     }
   6249   }
   6250 
   6251   if (local_cpu_usage || remote_cpu_usage) {
   6252     local_cpu_method = format_cpu_method(cpu_method);
   6253     remote_cpu_method = format_cpu_method(tcp_rr_result->cpu_method);
   6254 
   6255     switch (verbosity) {
   6256     case 0:
   6257       if (local_cpu_usage) {
   6258 	fprintf(where,
   6259 		cpu_fmt_0,
   6260 		local_service_demand,
   6261 		local_cpu_method,
   6262 		((print_headers) ||
   6263 		 (result_brand == NULL)) ? "" : result_brand);
   6264       }
   6265       else {
   6266 	fprintf(where,
   6267 		cpu_fmt_0,
   6268 		remote_service_demand,
   6269 		remote_cpu_method,
   6270 		((print_headers) ||
   6271 		 (result_brand == NULL)) ? "" : result_brand);
   6272       }
   6273       break;
   6274     case 1:
   6275     case 2:
   6276       if (print_headers) {
   6277 	if ('x' == libfmt) {
   6278 	  fprintf(where,
   6279 		  cpu_title,
   6280 		  local_cpu_method,
   6281 		  remote_cpu_method);
   6282 	}
   6283 	else {
   6284 	  fprintf(where,
   6285 		  cpu_title_tput,
   6286 		  format_units(),
   6287 		  local_cpu_method,
   6288 		  remote_cpu_method);
   6289 	}
   6290       }
   6291 
   6292       fprintf(where,
   6293 	      cpu_fmt_1_line_1,		/* the format string */
   6294 	      lss_size,		/* local sendbuf size */
   6295 	      lsr_size,
   6296 	      req_size,		/* how large were the requests */
   6297 	      rsp_size,		/* guess */
   6298 	      elapsed_time,		/* how long was the test */
   6299 	      ('x' == libfmt) ? thruput :
   6300 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
   6301 					 1.0),
   6302 	      local_cpu_utilization,	/* local cpu */
   6303 	      remote_cpu_utilization,	/* remote cpu */
   6304 	      local_service_demand,	/* local service demand */
   6305 	      remote_service_demand,	/* remote service demand */
   6306 	      ((print_headers) ||
   6307 	       (result_brand == NULL)) ? "" : result_brand);
   6308       fprintf(where,
   6309 	      cpu_fmt_1_line_2,
   6310 	      rss_size,
   6311 	      rsr_size);
   6312       break;
   6313     }
   6314   }
   6315   else {
   6316     /* The tester did not wish to measure service demand. */
   6317 
   6318     switch (verbosity) {
   6319     case 0:
   6320       fprintf(where,
   6321 	      tput_fmt_0,
   6322 	      ('x' == libfmt) ? thruput :
   6323 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
   6324 					 1.0),
   6325 	      ((print_headers) ||
   6326 	       (result_brand == NULL)) ? "" : result_brand);
   6327       break;
   6328     case 1:
   6329     case 2:
   6330       if (print_headers) {
   6331 	fprintf(where,
   6332 		('x' == libfmt) ? tput_title : tput_title_band,
   6333 		format_units());
   6334       }
   6335 
   6336       fprintf(where,
   6337 	      tput_fmt_1_line_1,	/* the format string */
   6338 	      lss_size,
   6339 	      lsr_size,
   6340 	      req_size,		/* how large were the requests */
   6341 	      rsp_size,		/* how large were the responses */
   6342 	      elapsed_time, 		/* how long did it take */
   6343 	      /* are we trans or do we need to convert to bytes then
   6344 		 bits? at this point, thruput is in our "confident"
   6345 		 transactions per second. we can convert to a
   6346 		 bidirectional bitrate by multiplying that by the sum
   6347 		 of the req_size and rsp_size.  we pass that to
   6348 		 calc_thruput_interval_omni with an elapsed time of
   6349 		 1.0 s to get it converted to [kmg]bits/s or
   6350 		 [KMG]Bytes/s */
   6351 	      ('x' == libfmt) ?  thruput :
   6352 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
   6353 					 1.0),
   6354 	      ((print_headers) ||
   6355 	       (result_brand == NULL)) ? "" : result_brand);
   6356       fprintf(where,
   6357 	      tput_fmt_1_line_2,
   6358 	      rss_size, 		/* remote recvbuf size */
   6359 	      rsr_size);
   6360 
   6361       break;
   6362     }
   6363   }
   6364 
   6365   /* it would be a good thing to include information about some of the */
   6366   /* other parameters that may have been set for this test, but at the */
   6367   /* moment, I do not wish to figure-out all the  formatting, so I will */
   6368   /* just put this comment here to help remind me that it is something */
   6369   /* that should be done at a later time. */
   6370 
   6371   /* how to handle the verbose information in the presence of */
   6372   /* confidence intervals is yet to be determined... raj 11/94 */
   6373   if (verbosity > 1) {
   6374     /* The user wanted to know it all, so we will give it to him. */
   6375     /* This information will include as much as we can find about */
   6376     /* TCP statistics, the alignments of the sends and receives */
   6377     /* and all that sort of rot... */
   6378 
   6379     /* normally, you might think that if we were messing about with
   6380        the value of libfmt we would need to put it back again, but
   6381        since this is basically the last thing we are going to do with
   6382        it, it does not matter.  so there :) raj 2007-06-08 */
   6383     /* if the user was asking for transactions, then we report
   6384        megabits per second for the unidirectional throughput,
   6385        otherwise we use the desired units. */
   6386     if ('x' == libfmt) {
   6387       libfmt = 'm';
   6388     }
   6389 
   6390     fprintf(where,
   6391 	    ksink_fmt,
   6392 	    format_units(),
   6393 	    local_send_align,
   6394 	    remote_recv_offset,
   6395 	    local_send_offset,
   6396 	    remote_recv_offset,
   6397 	    /* if the user has enable burst mode, we have to remember
   6398 	       to account for that in the number of transactions
   6399 	       outstanding at any one time. otherwise we will
   6400 	       underreport the latency of individual
   6401 	       transactions. learned from saf by raj 2007-06-08  */
   6402 	    (((double)1.0/thruput)*(double)1000000.0) *
   6403 	    (double) (1 + ((first_burst_size > 0) ? first_burst_size : 0)),
   6404 	    thruput,
   6405 	    calc_thruput_interval_omni(thruput * (double)req_size,1.0),
   6406 	    calc_thruput_interval_omni(thruput * (double)rsp_size,1.0));
   6407 
   6408 #ifdef WANT_HISTOGRAM
   6409     fprintf(where,"\nHistogram of request/response times\n");
   6410     fflush(where);
   6411     HIST_report(time_hist);
   6412 #endif /* WANT_HISTOGRAM */
   6413 
   6414   }
   6415 
   6416 }
   6417 #endif /* WANT_MIGRATION */
   6418 
   6419 #if defined(__linux)
   6421 /*
   6422  * Linux has this odd behavior where if the socket buffers are larger than
   6423  * a device's txqueuelen, the kernel will silently drop transmits which would
   6424  * not fit into the tx queue, and not  pass an ENOBUFS error back to the
   6425  * application.  As a result, a UDP stream test can report absurd transmit
   6426  * bandwidths (like 20Gb/s on a 1GbE NIC).  This behavior can be avoided if
   6427  * you  request extended error reporting on the socket.  This is done by
   6428  * setting the IP_RECVERR socket option at the IP level.
   6429  */
   6430 static void
   6431 enable_enobufs(int s)
   6432 {
   6433   struct protoent *pr;
   6434   int on = 1;
   6435 
   6436   if ((pr = getprotobyname("ip")) == NULL) {
   6437     fprintf(where, "enable_enobufs failed: getprotobyname\n");
   6438     fflush(where);
   6439     return;
   6440   }
   6441   if (setsockopt(s, pr->p_proto, IP_RECVERR, (char *)&on, sizeof(on)) < 0) {
   6442     fprintf(where, "enable_enobufs failed: setsockopt\n");
   6443     fflush(where);
   6444     return;
   6445   }
   6446 }
   6447 #endif
   6448 
   6449 #ifndef WANT_MIGRATION
   6450 void
   6451 send_udp_stream(char remote_host[])
   6452 {
   6453   /**********************************************************************/
   6454   /*									*/
   6455   /*               	UDP Unidirectional Send Test                    */
   6456   /*									*/
   6457   /**********************************************************************/
   6458 
   6459 #define UDP_LENGTH_MAX 0XFFFF - 28
   6460 
   6461   char *tput_title = "\
   6462 Socket  Message  Elapsed      Messages                \n\
   6463 Size    Size     Time         Okay Errors   Throughput\n\
   6464 bytes   bytes    secs            #      #   %s/sec\n\n";
   6465 
   6466   char *tput_fmt_0 =
   6467     "%7.2f\n";
   6468 
   6469   char *tput_fmt_1 = "\
   6470 %6d  %6d   %-7.2f   %7d %6d    %7.2f\n\
   6471 %6d           %-7.2f   %7d           %7.2f\n\n";
   6472 
   6473 
   6474   char *cpu_title = "\
   6475 Socket  Message  Elapsed      Messages                   CPU      Service\n\
   6476 Size    Size     Time         Okay Errors   Throughput   Util     Demand\n\
   6477 bytes   bytes    secs            #      #   %s/sec %% %c%c     us/KB\n\n";
   6478 
   6479   char *cpu_fmt_0 =
   6480     "%6.2f %c\n";
   6481 
   6482   char *cpu_fmt_1 = "\
   6483 %6d  %6d   %-7.2f   %7d %6d    %7.1f     %-6.2f   %-6.3f\n\
   6484 %6d           %-7.2f   %7d           %7.1f     %-6.2f   %-6.3f\n\n";
   6485 
   6486   unsigned int	messages_recvd;
   6487   unsigned int 	messages_sent;
   6488   unsigned int	failed_sends;
   6489 
   6490   float	elapsed_time,
   6491         local_cpu_utilization,
   6492         remote_cpu_utilization;
   6493 
   6494   float	 local_service_demand, remote_service_demand;
   6495   double local_thruput, remote_thruput;
   6496   double bytes_sent;
   6497   double bytes_recvd;
   6498 
   6499 
   6500   int	len;
   6501   struct ring_elt *send_ring;
   6502   SOCKET 	data_socket;
   6503 
   6504   unsigned int sum_messages_sent;
   6505   unsigned int sum_messages_recvd;
   6506   unsigned int sum_failed_sends;
   6507   double sum_local_thruput;
   6508 
   6509   struct addrinfo *local_res;
   6510   struct addrinfo *remote_res;
   6511 
   6512   struct	udp_stream_request_struct	*udp_stream_request;
   6513   struct	udp_stream_response_struct	*udp_stream_response;
   6514   struct	udp_stream_results_struct	*udp_stream_results;
   6515 
   6516   udp_stream_request	=
   6517     (struct udp_stream_request_struct *)netperf_request.content.test_specific_data;
   6518   udp_stream_response	=
   6519     (struct udp_stream_response_struct *)netperf_response.content.test_specific_data;
   6520   udp_stream_results	=
   6521     (struct udp_stream_results_struct *)netperf_response.content.test_specific_data;
   6522 
   6523 #ifdef WANT_HISTOGRAM
   6524   if (verbosity > 1) {
   6525     time_hist = HIST_new();
   6526   }
   6527 #endif /* WANT_HISTOGRAM */
   6528 
   6529   /* since we are now disconnected from the code that established the */
   6530   /* control socket, and since we want to be able to use different */
   6531   /* protocols and such, we are passed the name of the remote host and */
   6532   /* must turn that into the test specific addressing information. */
   6533 
   6534   complete_addrinfos(&remote_res,
   6535 		     &local_res,
   6536 		     remote_host,
   6537 		     SOCK_DGRAM,
   6538 		     IPPROTO_UDP,
   6539 		     0);
   6540 
   6541   if ( print_headers ) {
   6542     print_top_test_header("UDP UNIDIRECTIONAL SEND TEST",local_res,remote_res);
   6543   }
   6544 
   6545   send_ring            = NULL;
   6546   confidence_iteration = 1;
   6547   init_stat();
   6548   sum_messages_sent    = 0;
   6549   sum_messages_recvd   = 0;
   6550   sum_failed_sends     = 0;
   6551   sum_local_thruput    = 0.0;
   6552 
   6553   /* we have a great-big while loop which controls the number of times */
   6554   /* we run a particular test. this is for the calculation of a */
   6555   /* confidence interval (I really should have stayed awake during */
   6556   /* probstats :). If the user did not request confidence measurement */
   6557   /* (no confidence is the default) then we will only go though the */
   6558   /* loop once. the confidence stuff originates from the folks at IBM */
   6559 
   6560   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   6561 	 (confidence_iteration <= iteration_min)) {
   6562 
   6563     /* initialize a few counters. we have to remember that we might be */
   6564     /* going through the loop more than once. */
   6565     messages_sent  = 0;
   6566     messages_recvd = 0;
   6567     failed_sends   = 0;
   6568     times_up       = 0;
   6569 
   6570     /*set up the data socket			*/
   6571     data_socket = create_data_socket(local_res);
   6572 
   6573     if (data_socket == INVALID_SOCKET){
   6574       perror("udp_send: data socket");
   6575       exit(1);
   6576     }
   6577 
   6578     /* now, we want to see if we need to set the send_size */
   6579     if (send_size == 0) {
   6580       if (lss_size > 0) {
   6581 	send_size = (lss_size < UDP_LENGTH_MAX ? lss_size : UDP_LENGTH_MAX);
   6582       }
   6583       else {
   6584 	send_size = 4096;
   6585       }
   6586     }
   6587 
   6588 
   6589     /* set-up the data buffer with the requested alignment and offset, */
   6590     /* most of the numbers here are just a hack to pick something nice */
   6591     /* and big in an attempt to never try to send a buffer a second time */
   6592     /* before it leaves the node...unless the user set the width */
   6593     /* explicitly. */
   6594     if (send_width == 0) send_width = 32;
   6595 
   6596     if (send_ring == NULL ) {
   6597       send_ring = allocate_buffer_ring(send_width,
   6598 				       send_size,
   6599 				       local_send_align,
   6600 				       local_send_offset);
   6601     }
   6602 
   6603 
   6604     /* if the user supplied a cpu rate, this call will complete rather */
   6605     /* quickly, otherwise, the cpu rate will be retured to us for */
   6606     /* possible display. The Library will keep it's own copy of this data */
   6607     /* for use elsewhere. We will only display it. (Does that make it */
   6608     /* "opaque" to us?) */
   6609 
   6610     if (local_cpu_usage)
   6611       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   6612 
   6613     if (!no_control) {
   6614       /* Tell the remote end to set up the data connection. The server
   6615          sends back the port number and alters the socket parameters
   6616          there.  Of course this is a datagram service so no connection
   6617          is actually set up, the server just sets up the socket and
   6618          binds it. */
   6619 
   6620       netperf_request.content.request_type      = DO_UDP_STREAM;
   6621       udp_stream_request->recv_buf_size  = rsr_size_req;
   6622       udp_stream_request->message_size   = send_size;
   6623       udp_stream_request->recv_connected = remote_connected;
   6624       udp_stream_request->recv_alignment = remote_recv_align;
   6625       udp_stream_request->recv_offset    = remote_recv_offset;
   6626       udp_stream_request->measure_cpu    = remote_cpu_usage;
   6627       udp_stream_request->cpu_rate       = remote_cpu_rate;
   6628       udp_stream_request->test_length    = test_time;
   6629       udp_stream_request->so_rcvavoid    = rem_rcvavoid;
   6630       udp_stream_request->so_sndavoid    = rem_sndavoid;
   6631       udp_stream_request->port           = atoi(remote_data_port);
   6632       udp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
   6633 
   6634       send_request();
   6635 
   6636       recv_response();
   6637 
   6638       if (!netperf_response.content.serv_errno) {
   6639 	if (debug)
   6640 	  fprintf(where,"send_udp_stream: remote data connection done.\n");
   6641       }
   6642       else {
   6643 	Set_errno(netperf_response.content.serv_errno);
   6644 	perror("send_udp_stream: error on remote");
   6645 	exit(1);
   6646       }
   6647 
   6648       /* Place the port number returned by the remote into the sockaddr */
   6649       /* structure so our sends can be sent to the correct place. Also get */
   6650       /* some of the returned socket buffer information for user display. */
   6651 
   6652       /* make sure that port numbers are in the proper order */
   6653       set_port_number(remote_res,(short)udp_stream_response->data_port_number);
   6654 
   6655       rsr_size        = udp_stream_response->recv_buf_size;
   6656       rss_size        = udp_stream_response->send_buf_size;
   6657       remote_cpu_rate = udp_stream_response->cpu_rate;
   6658     }
   6659 
   6660 #ifdef WANT_DEMO
   6661     demo_stream_setup(lss_size,rsr_size);
   6662 #endif
   6663 
   6664     /* We "connect" up to the remote post to allow is to use the send */
   6665     /* call instead of the sendto call. Presumeably, this is a little */
   6666     /* simpler, and a little more efficient. I think that it also means */
   6667     /* that we can be informed of certain things, but am not sure */
   6668     /* yet...also, this is the way I would expect a client to behave */
   6669     /* when talking to a server */
   6670     if (local_connected) {
   6671        if (connect(data_socket,
   6672       		   remote_res->ai_addr,
   6673 		   remote_res->ai_addrlen) == INVALID_SOCKET){
   6674           perror("send_udp_stream: data socket connect failed");
   6675           exit(1);
   6676        } else if (debug) {
   6677           fprintf(where,"send_udp_stream: connected data socket.\n");
   6678           fflush(where);
   6679        }
   6680     }
   6681 
   6682 #if defined (__linux)
   6683   enable_enobufs(data_socket);
   6684 #endif
   6685 
   6686 #ifdef WIN32
   6687   /* this is used so the timer thread can close the socket out from */
   6688   /* under us, which to date is the easiest/cleanest/least */
   6689   /* Windows-specific way I can find to force the winsock calls to */
   6690   /* return WSAEINTR with the test is over. anything that will run on */
   6691   /* 95 and NT and is closer to what netperf expects from Unix signals */
   6692   /* and such would be appreciated raj 1/96 */
   6693     win_kludge_socket = data_socket;
   6694 #endif /* WIN32 */
   6695 
   6696     /* set up the timer to call us after test_time. one of these days, */
   6697     /* it might be nice to figure-out a nice reliable way to have the */
   6698     /* test controlled by a byte count as well, but since UDP is not */
   6699     /* reliable, that could prove difficult. so, in the meantime, we */
   6700     /* only allow a UDP_STREAM test to be a timed test. */
   6701 
   6702     if (test_time) {
   6703       times_up = 0;
   6704       start_timer(test_time);
   6705     }
   6706     else {
   6707       fprintf(where,"Sorry, UDP_STREAM tests must be timed.\n");
   6708       fflush(where);
   6709     }
   6710 
   6711     /* Get the start count for the idle counter and the start time */
   6712 
   6713     cpu_start(local_cpu_usage);
   6714 
   6715 #ifdef WANT_INTERVALS
   6716     INTERVALS_INIT();
   6717 #endif /* WANT_INTERVALS */
   6718 
   6719 #ifdef WANT_DEMO
   6720     if (demo_mode) {
   6721       demo_first_timestamp();
   6722     }
   6723 #endif
   6724 
   6725     /* Send datagrams like there was no tomorrow. at somepoint it might */
   6726     /* be nice to set this up so that a quantity of bytes could be sent, */
   6727     /* but we still need some sort of end of test trigger on the receive */
   6728     /* side. that could be a select with a one second timeout, but then */
   6729     /* if there is a test where none of the data arrives for awile and */
   6730     /* then starts again, we would end the test too soon. something to */
   6731     /* think about... */
   6732     while (!times_up) {
   6733 
   6734 #ifdef DIRTY
   6735       /* we want to dirty some number of consecutive integers in the buffer */
   6736       /* we are about to send. we may also want to bring some number of */
   6737       /* them cleanly into the cache. The clean ones will follow any dirty */
   6738       /* ones into the cache. */
   6739 
   6740       access_buffer(send_ring->buffer_ptr,
   6741 		    send_size,
   6742 		    loc_dirty_count,
   6743 		    loc_clean_count);
   6744 #endif /* DIRTY */
   6745 
   6746 #ifdef WANT_HISTOGRAM
   6747       if (verbosity > 1) {
   6748 	HIST_timestamp(&time_one);
   6749       }
   6750 #endif /* WANT_HISTOGRAM */
   6751 
   6752       if (local_connected) {
   6753          len = send(data_socket,
   6754 	  	    send_ring->buffer_ptr,
   6755 		    send_size,
   6756 		    0);
   6757       } else {
   6758          len = sendto(data_socket,
   6759 		      send_ring->buffer_ptr,
   6760 		      send_size,
   6761 		      0,
   6762 		      remote_res->ai_addr,
   6763 		      remote_res->ai_addrlen);
   6764       }
   6765 
   6766       if (len != send_size) {
   6767 	if ((len >= 0) ||
   6768 	    SOCKET_EINTR(len))
   6769 	  break;
   6770 	if (errno == ENOBUFS) {
   6771 	  failed_sends++;
   6772 	  continue;
   6773 	}
   6774 	perror("udp_send: data send error");
   6775 	exit(1);
   6776       }
   6777       messages_sent++;
   6778 
   6779       /* now we want to move our pointer to the next position in the */
   6780       /* data buffer... */
   6781 
   6782       send_ring = send_ring->next;
   6783 
   6784 
   6785 #ifdef WANT_HISTOGRAM
   6786       if (verbosity > 1) {
   6787 	/* get the second timestamp */
   6788 	HIST_timestamp(&time_two);
   6789 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   6790       }
   6791 #endif /* WANT_HISTOGRAM */
   6792 
   6793 #ifdef WANT_DEMO
   6794       demo_stream_interval(send_size);
   6795 #endif
   6796 
   6797 #ifdef WANT_INTERVALS
   6798       INTERVALS_WAIT();
   6799 #endif /* WANT_INTERVALS */
   6800 
   6801     }
   6802 
   6803     /* This is a timed test, so the remote will be returning to us after */
   6804     /* a time. We should not need to send any "strange" messages to tell */
   6805     /* the remote that the test is completed, unless we decide to add a */
   6806     /* number of messages to the test. */
   6807 
   6808     /* the test is over, so get stats and stuff */
   6809     cpu_stop(local_cpu_usage,
   6810 	     &elapsed_time);
   6811 
   6812 #if defined(WANT_INTERVALS)
   6813 #ifdef WIN32
   6814     stop_itimer();
   6815 #endif
   6816 #endif /* WANT_INTERVALS */
   6817 
   6818     if (!no_control) {
   6819       /* Get the statistics from the remote end	*/
   6820       recv_response();
   6821       if (!netperf_response.content.serv_errno) {
   6822 	if (debug)
   6823 	  fprintf(where,"send_udp_stream: remote results obtained\n");
   6824       }
   6825       else {
   6826 	Set_errno(netperf_response.content.serv_errno);
   6827 	perror("send_udp_stream: error on remote");
   6828 	exit(1);
   6829       }
   6830       messages_recvd = udp_stream_results->messages_recvd;
   6831       bytes_recvd    = (double) send_size * (double) messages_recvd;
   6832     }
   6833     else {
   6834       /* since there was no control connection, we've no idea what was
   6835 	 actually received. raj 2007-02-08 */
   6836       messages_recvd = -1;
   6837       bytes_recvd = -1.0;
   6838     }
   6839 
   6840     bytes_sent    = (double) send_size * (double) messages_sent;
   6841     local_thruput = calc_thruput(bytes_sent);
   6842 
   6843 
   6844     /* we asume that the remote ran for as long as we did */
   6845 
   6846     remote_thruput = calc_thruput(bytes_recvd);
   6847 
   6848     /* print the results for this socket and message size */
   6849 
   6850     if (local_cpu_usage || remote_cpu_usage) {
   6851       /* We must now do a little math for service demand and cpu */
   6852       /* utilization for the system(s) We pass zeros for the local */
   6853       /* cpu utilization and elapsed time to tell the routine to use */
   6854       /* the libraries own values for those. */
   6855       if (local_cpu_usage) {
   6856 	local_cpu_utilization	= calc_cpu_util(0.0);
   6857 	/* shouldn't this really be based on bytes_recvd, since that is */
   6858 	/* the effective throughput of the test? I think that it should, */
   6859 	/* so will make the change raj 11/94 */
   6860 	local_service_demand	= calc_service_demand(bytes_recvd,
   6861 						      0.0,
   6862 						      0.0,
   6863 						      0);
   6864       }
   6865       else {
   6866 	local_cpu_utilization	= (float) -1.0;
   6867 	local_service_demand	= (float) -1.0;
   6868       }
   6869 
   6870       /* The local calculations could use variables being kept by */
   6871       /* the local netlib routines. The remote calcuations need to */
   6872       /* have a few things passed to them. */
   6873       if (remote_cpu_usage) {
   6874 	remote_cpu_utilization	= udp_stream_results->cpu_util;
   6875 	remote_service_demand	= calc_service_demand(bytes_recvd,
   6876 						      0.0,
   6877 						      remote_cpu_utilization,
   6878 						      udp_stream_results->num_cpus);
   6879       }
   6880       else {
   6881 	remote_cpu_utilization	= (float) -1.0;
   6882 	remote_service_demand	= (float) -1.0;
   6883       }
   6884     }
   6885     else {
   6886       /* we were not measuring cpu, for the confidence stuff, we */
   6887       /* should make it -1.0 */
   6888       local_cpu_utilization  = (float) -1.0;
   6889       local_service_demand   = (float) -1.0;
   6890       remote_cpu_utilization = (float) -1.0;
   6891       remote_service_demand  = (float) -1.0;
   6892     }
   6893 
   6894     /* at this point, we want to calculate the confidence information. */
   6895     /* if debugging is on, calculate_confidence will print-out the */
   6896     /* parameters we pass it */
   6897 
   6898     calculate_confidence(confidence_iteration,
   6899 			 elapsed_time,
   6900 			 remote_thruput,
   6901 			 local_cpu_utilization,
   6902 			 remote_cpu_utilization,
   6903 			 local_service_demand,
   6904 			 remote_service_demand);
   6905 
   6906     /* since the routine calculate_confidence is rather generic, and */
   6907     /* we have a few other parms of interest, we will do a little work */
   6908     /* here to caclulate their average. */
   6909     sum_messages_sent  += messages_sent;
   6910     sum_messages_recvd += messages_recvd;
   6911     sum_failed_sends   += failed_sends;
   6912     sum_local_thruput  += local_thruput;
   6913 
   6914     confidence_iteration++;
   6915 
   6916     /* this datapoint is done, so we don't need the socket any longer */
   6917     close(data_socket);
   6918 
   6919   }
   6920 
   6921   /* we should reach this point once the test is finished */
   6922 
   6923   retrieve_confident_values(&elapsed_time,
   6924 			    &remote_thruput,
   6925 			    &local_cpu_utilization,
   6926 			    &remote_cpu_utilization,
   6927 			    &local_service_demand,
   6928 			    &remote_service_demand);
   6929 
   6930   /* some of the interesting values aren't covered by the generic */
   6931   /* confidence routine */
   6932   messages_sent    = sum_messages_sent / (confidence_iteration -1);
   6933   messages_recvd   = sum_messages_recvd / (confidence_iteration -1);
   6934   failed_sends     = sum_failed_sends / (confidence_iteration -1);
   6935   local_thruput    = sum_local_thruput / (confidence_iteration -1);
   6936 
   6937   /* We are now ready to print all the information. If the user */
   6938   /* has specified zero-level verbosity, we will just print the */
   6939   /* local service demand, or the remote service demand. If the */
   6940   /* user has requested verbosity level 1, he will get the basic */
   6941   /* "streamperf" numbers. If the user has specified a verbosity */
   6942   /* of greater than 1, we will display a veritable plethora of */
   6943   /* background information from outside of this block as it it */
   6944   /* not cpu_measurement specific...  */
   6945 
   6946 
   6947   if (confidence < 0) {
   6948     /* we did not hit confidence, but were we asked to look for it? */
   6949     if (iteration_max > 1) {
   6950       display_confidence();
   6951     }
   6952   }
   6953 
   6954   if (local_cpu_usage || remote_cpu_usage) {
   6955     local_cpu_method = format_cpu_method(cpu_method);
   6956     remote_cpu_method = format_cpu_method(udp_stream_results->cpu_method);
   6957 
   6958     switch (verbosity) {
   6959     case 0:
   6960       if (local_cpu_usage) {
   6961 	fprintf(where,
   6962 		cpu_fmt_0,
   6963 		local_service_demand,
   6964 		local_cpu_method);
   6965       }
   6966       else {
   6967 	fprintf(where,
   6968 		cpu_fmt_0,
   6969 		remote_service_demand,
   6970 		local_cpu_method);
   6971       }
   6972       break;
   6973     case 1:
   6974     case 2:
   6975       if (print_headers) {
   6976 	fprintf(where,
   6977 		cpu_title,
   6978 		format_units(),
   6979 		local_cpu_method,
   6980 		remote_cpu_method);
   6981       }
   6982 
   6983       fprintf(where,
   6984 	      cpu_fmt_1,		/* the format string */
   6985 	      lss_size,		        /* local sendbuf size */
   6986 	      send_size,		/* how large were the sends */
   6987 	      elapsed_time,		/* how long was the test */
   6988 	      messages_sent,
   6989 	      failed_sends,
   6990 	      local_thruput, 		/* what was the xfer rate */
   6991 	      local_cpu_utilization,	/* local cpu */
   6992 	      local_service_demand,	/* local service demand */
   6993 	      rsr_size,
   6994 	      elapsed_time,
   6995 	      messages_recvd,
   6996 	      remote_thruput,
   6997 	      remote_cpu_utilization,	/* remote cpu */
   6998 	      remote_service_demand);	/* remote service demand */
   6999       break;
   7000     }
   7001   }
   7002   else {
   7003     /* The tester did not wish to measure service demand. */
   7004     switch (verbosity) {
   7005     case 0:
   7006       fprintf(where,
   7007 	      tput_fmt_0,
   7008 	      local_thruput);
   7009       break;
   7010     case 1:
   7011     case 2:
   7012       if (print_headers) {
   7013 	fprintf(where,tput_title,format_units());
   7014       }
   7015       fprintf(where,
   7016 	      tput_fmt_1,		/* the format string */
   7017 	      lss_size, 		/* local sendbuf size */
   7018 	      send_size,		/* how large were the sends */
   7019 	      elapsed_time, 		/* how long did it take */
   7020 	      messages_sent,
   7021 	      failed_sends,
   7022 	      local_thruput,
   7023 	      rsr_size, 		/* remote recvbuf size */
   7024 	      elapsed_time,
   7025 	      messages_recvd,
   7026 	      remote_thruput);
   7027       break;
   7028     }
   7029   }
   7030 
   7031   fflush(where);
   7032 #ifdef WANT_HISTOGRAM
   7033   if (verbosity > 1) {
   7034     fprintf(where,"\nHistogram of time spent in send() call\n");
   7035     fflush(where);
   7036     HIST_report(time_hist);
   7037   }
   7038 #endif /* WANT_HISTOGRAM */
   7039 
   7040 }
   7041 #endif /* WANT_MIGRATION */
   7042 
   7043 
   7045  /* this routine implements the receive side (netserver) of the */
   7046  /* UDP_STREAM performance test. */
   7047 
   7048 void
   7049 recv_udp_stream()
   7050 {
   7051   struct ring_elt *recv_ring;
   7052   struct addrinfo *local_res;
   7053   char local_name[BUFSIZ];
   7054   char port_buffer[PORTBUFSIZE];
   7055 
   7056   struct sockaddr_storage myaddr_in;
   7057   SOCKET	s_data;
   7058   netperf_socklen_t 	addrlen;
   7059   struct sockaddr_storage remote_addr;
   7060   netperf_socklen_t remote_addrlen;
   7061 
   7062   int	len = 0;
   7063   unsigned int	bytes_received = 0;
   7064   float	elapsed_time;
   7065 
   7066   int	message_size;
   7067   unsigned int	messages_recvd = 0;
   7068 
   7069   struct	udp_stream_request_struct	*udp_stream_request;
   7070   struct	udp_stream_response_struct	*udp_stream_response;
   7071   struct	udp_stream_results_struct	*udp_stream_results;
   7072 
   7073   udp_stream_request  =
   7074     (struct udp_stream_request_struct *)netperf_request.content.test_specific_data;
   7075   udp_stream_response =
   7076     (struct udp_stream_response_struct *)netperf_response.content.test_specific_data;
   7077   udp_stream_results  =
   7078     (struct udp_stream_results_struct *)netperf_response.content.test_specific_data;
   7079 
   7080   if (debug) {
   7081     fprintf(where,"netserver: recv_udp_stream: entered...\n");
   7082     fflush(where);
   7083   }
   7084 
   7085   /* We want to set-up the listen socket with all the desired */
   7086   /* parameters and then let the initiator know that all is ready. If */
   7087   /* socket size defaults are to be used, then the initiator will have */
   7088   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   7089   /* send-back what they are. If that information cannot be determined, */
   7090   /* then we send-back -1's for the sizes. If things go wrong for any */
   7091   /* reason, we will drop back ten yards and punt. */
   7092 
   7093   /* If anything goes wrong, we want the remote to know about it. It */
   7094   /* would be best if the error that the remote reports to the user is */
   7095   /* the actual error we encountered, rather than some bogus unexpected */
   7096   /* response type message. */
   7097 
   7098   if (debug > 1) {
   7099     fprintf(where,"recv_udp_stream: setting the response type...\n");
   7100     fflush(where);
   7101   }
   7102 
   7103   netperf_response.content.response_type = UDP_STREAM_RESPONSE;
   7104 
   7105   if (debug > 2) {
   7106     fprintf(where,"recv_udp_stream: the response type is set...\n");
   7107     fflush(where);
   7108   }
   7109 
   7110   /* We now alter the message_ptr variable to be at the desired */
   7111   /* alignment with the desired offset. */
   7112 
   7113   if (debug > 1) {
   7114     fprintf(where,"recv_udp_stream: requested alignment of %d\n",
   7115 	    udp_stream_request->recv_alignment);
   7116     fflush(where);
   7117   }
   7118 
   7119   if (recv_width == 0) recv_width = 1;
   7120 
   7121   recv_ring = allocate_buffer_ring(recv_width,
   7122 				   udp_stream_request->message_size,
   7123 				   udp_stream_request->recv_alignment,
   7124 				   udp_stream_request->recv_offset);
   7125 
   7126   if (debug > 1) {
   7127     fprintf(where,"recv_udp_stream: receive alignment and offset set...\n");
   7128     fflush(where);
   7129   }
   7130 
   7131   /* Grab a socket to listen on, and then listen on it. */
   7132 
   7133   if (debug > 1) {
   7134     fprintf(where,"recv_udp_stream: grabbing a socket...\n");
   7135     fflush(where);
   7136   }
   7137 
   7138   /* create_data_socket expects to find some things in the global */
   7139   /* variables, so set the globals based on the values in the request. */
   7140   /* once the socket has been created, we will set the response values */
   7141   /* based on the updated value of those globals. raj 7/94 */
   7142   lsr_size_req = udp_stream_request->recv_buf_size;
   7143   loc_rcvavoid = udp_stream_request->so_rcvavoid;
   7144   loc_sndavoid = udp_stream_request->so_sndavoid;
   7145   local_connected = udp_stream_request->recv_connected;
   7146 
   7147   set_hostname_and_port(local_name,
   7148 			port_buffer,
   7149 			nf_to_af(udp_stream_request->ipfamily),
   7150 			udp_stream_request->port);
   7151 
   7152   local_res = complete_addrinfo(local_name,
   7153 				local_name,
   7154 				port_buffer,
   7155 				nf_to_af(udp_stream_request->ipfamily),
   7156 				SOCK_DGRAM,
   7157 				IPPROTO_UDP,
   7158 				0);
   7159 
   7160   s_data = create_data_socket(local_res);
   7161 
   7162   if (s_data == INVALID_SOCKET) {
   7163     netperf_response.content.serv_errno = errno;
   7164     send_response();
   7165     exit(1);
   7166   }
   7167 
   7168   udp_stream_response->test_length = udp_stream_request->test_length;
   7169 
   7170   /* now get the port number assigned by the system  */
   7171   addrlen = sizeof(myaddr_in);
   7172   if (getsockname(s_data,
   7173 		  (struct sockaddr *)&myaddr_in,
   7174 		  &addrlen) == SOCKET_ERROR){
   7175     netperf_response.content.serv_errno = errno;
   7176     close(s_data);
   7177     send_response();
   7178 
   7179     exit(1);
   7180   }
   7181 
   7182   /* Now myaddr_in contains the port and the internet address this is */
   7183   /* returned to the sender also implicitly telling the sender that the */
   7184   /* socket buffer sizing has been done. */
   7185 
   7186   udp_stream_response->data_port_number =
   7187     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
   7188   netperf_response.content.serv_errno   = 0;
   7189 
   7190   /* But wait, there's more. If the initiator wanted cpu measurements, */
   7191   /* then we must call the calibrate routine, which will return the max */
   7192   /* rate back to the initiator. If the CPU was not to be measured, or */
   7193   /* something went wrong with the calibration, we will return a -1 to */
   7194   /* the initiator. */
   7195 
   7196   udp_stream_response->cpu_rate    = (float)0.0; /* assume no cpu */
   7197   udp_stream_response->measure_cpu = 0;
   7198   if (udp_stream_request->measure_cpu) {
   7199     /* We will pass the rate into the calibration routine. If the */
   7200     /* user did not specify one, it will be 0.0, and we will do a */
   7201     /* "real" calibration. Otherwise, all it will really do is */
   7202     /* store it away... */
   7203     udp_stream_response->measure_cpu = 1;
   7204     udp_stream_response->cpu_rate =
   7205       calibrate_local_cpu(udp_stream_request->cpu_rate);
   7206   }
   7207 
   7208   message_size	= udp_stream_request->message_size;
   7209   test_time	= udp_stream_request->test_length;
   7210 
   7211   /* before we send the response back to the initiator, pull some of */
   7212   /* the socket parms from the globals */
   7213   udp_stream_response->send_buf_size = lss_size;
   7214   udp_stream_response->recv_buf_size = lsr_size;
   7215   udp_stream_response->so_rcvavoid = loc_rcvavoid;
   7216   udp_stream_response->so_sndavoid = loc_sndavoid;
   7217 
   7218   send_response();
   7219 
   7220   /* Now it's time to start receiving data on the connection. We will */
   7221   /* first grab the apropriate counters and then start grabbing. */
   7222 
   7223   cpu_start(udp_stream_request->measure_cpu);
   7224 
   7225 #ifdef WIN32
   7226   /* this is used so the timer thread can close the socket out from */
   7227   /* under us, which to date is the easiest/cleanest/least */
   7228   /* Windows-specific way I can find to force the winsock calls to */
   7229   /* return WSAEINTR with the test is over. anything that will run on */
   7230   /* 95 and NT and is closer to what netperf expects from Unix signals */
   7231   /* and such would be appreciated raj 1/96 */
   7232   win_kludge_socket = s_data;
   7233 #endif /* WIN32 */
   7234 
   7235   /* The loop will exit when the timer pops, or if we happen to recv a */
   7236   /* message of less than send_size bytes... */
   7237 
   7238   times_up = 0;
   7239 
   7240   start_timer(test_time + PAD_TIME);
   7241 
   7242   if (debug) {
   7243     fprintf(where,"recv_udp_stream: about to enter inner sanctum.\n");
   7244     fflush(where);
   7245   }
   7246 
   7247   /* We "connect" up to the remote post to allow us to use the recv */
   7248   /* call instead of the recvfrom call. Presumeably, this is a little */
   7249   /* simpler, and a little more efficient. */
   7250 
   7251   if (local_connected) {
   7252 
   7253     /* Receive the first message using recvfrom to find the remote address */
   7254     remote_addrlen = sizeof(remote_addr);
   7255     len = recvfrom(s_data, recv_ring->buffer_ptr,
   7256                    message_size, 0,
   7257                    (struct sockaddr*)&remote_addr, &remote_addrlen);
   7258     if (len != message_size) {
   7259       if ((len == SOCKET_ERROR) && !SOCKET_EINTR(len)) {
   7260             netperf_response.content.serv_errno = errno;
   7261             send_response();
   7262             exit(1);
   7263       }
   7264     }
   7265     messages_recvd++;
   7266     recv_ring = recv_ring->next;
   7267 
   7268 
   7269     /* Now connect with the remote socket address */
   7270     if (connect(s_data,
   7271                 (struct sockaddr*)&remote_addr,
   7272                 remote_addrlen )== INVALID_SOCKET) {
   7273         netperf_response.content.serv_errno = errno;
   7274         close(s_data);
   7275         send_response();
   7276         exit(1);
   7277     }
   7278 
   7279     if (debug) {
   7280         fprintf(where,"recv_udp_stream: connected data socket\n");
   7281         fflush(where);
   7282      }
   7283   }
   7284 
   7285   while (!times_up) {
   7286     if(local_connected) {
   7287        len = recv(s_data,
   7288                   recv_ring->buffer_ptr,
   7289                   message_size,
   7290                   0);
   7291     } else {
   7292        len = recvfrom(s_data,
   7293                       recv_ring->buffer_ptr,
   7294     	              message_size,
   7295 		      0,0,0);
   7296     }
   7297 
   7298     if (len != message_size) {
   7299       if ((len == SOCKET_ERROR) && !SOCKET_EINTR(len)) {
   7300             netperf_response.content.serv_errno = errno;
   7301 	    send_response();
   7302 	    exit(1);
   7303       }
   7304       break;
   7305     }
   7306     messages_recvd++;
   7307     recv_ring = recv_ring->next;
   7308   }
   7309 
   7310   if (debug) {
   7311     fprintf(where,"recv_udp_stream: got %d messages.\n",messages_recvd);
   7312     fflush(where);
   7313   }
   7314 
   7315 
   7316   /* The loop now exits due timer or < send_size bytes received. in */
   7317   /* reality, we only really support a timed UDP_STREAM test. raj */
   7318   /* 12/95 */
   7319 
   7320   cpu_stop(udp_stream_request->measure_cpu,&elapsed_time);
   7321 
   7322   if (times_up) {
   7323     /* we ended on a timer, subtract the PAD_TIME */
   7324     elapsed_time -= (float)PAD_TIME;
   7325   }
   7326   else {
   7327     stop_timer();
   7328   }
   7329 
   7330   if (debug) {
   7331     fprintf(where,"recv_udp_stream: test ended in %f seconds.\n",elapsed_time);
   7332     fflush(where);
   7333   }
   7334 
   7335 
   7336   /* We will count the "off" message that got us out of the loop */
   7337   bytes_received = (messages_recvd * message_size) + len;
   7338 
   7339   /* send the results to the sender			*/
   7340 
   7341   if (debug) {
   7342     fprintf(where,
   7343 	    "recv_udp_stream: got %d bytes\n",
   7344 	    bytes_received);
   7345     fflush(where);
   7346   }
   7347 
   7348   netperf_response.content.response_type	= UDP_STREAM_RESULTS;
   7349   udp_stream_results->bytes_received	= bytes_received;
   7350   udp_stream_results->messages_recvd	= messages_recvd;
   7351   udp_stream_results->elapsed_time	= elapsed_time;
   7352   udp_stream_results->cpu_method        = cpu_method;
   7353   udp_stream_results->num_cpus          = lib_num_loc_cpus;
   7354   if (udp_stream_request->measure_cpu) {
   7355     udp_stream_results->cpu_util	= calc_cpu_util(elapsed_time);
   7356   }
   7357   else {
   7358     udp_stream_results->cpu_util	= (float) -1.0;
   7359   }
   7360 
   7361   if (debug > 1) {
   7362     fprintf(where,
   7363 	    "recv_udp_stream: test complete, sending results.\n");
   7364     fflush(where);
   7365   }
   7366 
   7367   send_response();
   7368 
   7369   close(s_data);
   7370 
   7371 }
   7372 
   7373 #ifndef WANT_MIGRATION
   7375 void
   7376 send_udp_rr(char remote_host[])
   7377 {
   7378 
   7379   char *tput_title = "\
   7380 Local /Remote\n\
   7381 Socket Size   Request  Resp.   Elapsed  Trans.\n\
   7382 Send   Recv   Size     Size    Time     Rate         \n\
   7383 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
   7384 
   7385   char *tput_title_band = "\
   7386 Local /Remote\n\
   7387 Socket Size   Request  Resp.   Elapsed  \n\
   7388 Send   Recv   Size     Size    Time     Throughput \n\
   7389 bytes  Bytes  bytes    bytes   secs.    %s/sec   \n\n";
   7390 
   7391   char *tput_fmt_0 =
   7392     "%7.2f %s\n";
   7393 
   7394   char *tput_fmt_1_line_1 = "\
   7395 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   %s\n";
   7396 
   7397   char *tput_fmt_1_line_2 = "\
   7398 %-6d %-6d\n";
   7399 
   7400   char *cpu_title = "\
   7401 Local /Remote\n\
   7402 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
   7403 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
   7404 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
   7405 
   7406   char *cpu_title_tput = "\
   7407 Local /Remote\n\
   7408 Socket Size   Request Resp.  Elapsed Tput     CPU    CPU    S.dem   S.dem\n\
   7409 Send   Recv   Size    Size   Time    %-8.8s local  remote local   remote\n\
   7410 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
   7411 
   7412   char *cpu_fmt_0 =
   7413     "%6.3f %c %s\n";
   7414 
   7415   char *cpu_fmt_1_line_1 = "\
   7416 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f %s\n";
   7417 
   7418   char *cpu_fmt_1_line_2 = "\
   7419 %-6d %-6d\n";
   7420 
   7421   float			elapsed_time;
   7422 
   7423   struct ring_elt *send_ring;
   7424   struct ring_elt *recv_ring;
   7425 
   7426   int	len;
   7427   int	nummessages;
   7428   SOCKET	send_socket;
   7429   int	trans_remaining;
   7430   int	bytes_xferd;
   7431 
   7432   int	rsp_bytes_recvd;
   7433 
   7434   float	local_cpu_utilization;
   7435   float	local_service_demand;
   7436   float	remote_cpu_utilization;
   7437   float	remote_service_demand;
   7438   double	thruput;
   7439 
   7440   struct addrinfo *local_res;
   7441   struct addrinfo *remote_res;
   7442 
   7443   struct	udp_rr_request_struct	*udp_rr_request;
   7444   struct	udp_rr_response_struct	*udp_rr_response;
   7445   struct	udp_rr_results_struct	*udp_rr_result;
   7446 
   7447   udp_rr_request  =
   7448     (struct udp_rr_request_struct *)netperf_request.content.test_specific_data;
   7449   udp_rr_response =
   7450     (struct udp_rr_response_struct *)netperf_response.content.test_specific_data;
   7451   udp_rr_result	 =
   7452     (struct udp_rr_results_struct *)netperf_response.content.test_specific_data;
   7453 
   7454 #ifdef WANT_HISTOGRAM
   7455   if (verbosity > 1) {
   7456     time_hist = HIST_new();
   7457   }
   7458 #endif
   7459 
   7460   /* since we are now disconnected from the code that established the */
   7461   /* control socket, and since we want to be able to use different */
   7462   /* protocols and such, we are passed the name of the remote host and */
   7463   /* must turn that into the test specific addressing information. */
   7464 
   7465   complete_addrinfos(&remote_res,
   7466 		     &local_res,
   7467 		     remote_host,
   7468 		     SOCK_DGRAM,
   7469 		     IPPROTO_UDP,
   7470 		     0);
   7471 
   7472   if ( print_headers ) {
   7473     print_top_test_header("UDP REQUEST/RESPONSE TEST",local_res,remote_res);
   7474   }
   7475 
   7476   /* initialize a few counters */
   7477 
   7478   send_ring     = NULL;
   7479   recv_ring     = NULL;
   7480   nummessages	= 0;
   7481   bytes_xferd	= 0;
   7482   times_up 	= 0;
   7483   confidence_iteration = 1;
   7484   init_stat();
   7485 
   7486   /* we have a great-big while loop which controls the number of times */
   7487   /* we run a particular test. this is for the calculation of a */
   7488   /* confidence interval (I really should have stayed awake during */
   7489   /* probstats :). If the user did not request confidence measurement */
   7490   /* (no confidence is the default) then we will only go though the */
   7491   /* loop once. the confidence stuff originates from the folks at IBM */
   7492 
   7493   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   7494 	 (confidence_iteration <= iteration_min)) {
   7495 
   7496     nummessages     = 0;
   7497     bytes_xferd     = 0;
   7498     times_up        = 0;
   7499     trans_remaining = 0;
   7500 
   7501     /* set-up the data buffers with the requested alignment and offset */
   7502 
   7503     if (send_width == 0) send_width = 1;
   7504     if (recv_width == 0) recv_width = 1;
   7505 
   7506     if (send_ring == NULL) {
   7507       send_ring = allocate_buffer_ring(send_width,
   7508 				       req_size,
   7509 				       local_send_align,
   7510 				       local_send_offset);
   7511     }
   7512 
   7513     if (recv_ring == NULL) {
   7514       recv_ring = allocate_buffer_ring(recv_width,
   7515 				       rsp_size,
   7516 				       local_recv_align,
   7517 				       local_recv_offset);
   7518     }
   7519 
   7520     /*set up the data socket                        */
   7521     send_socket = create_data_socket(local_res);
   7522 
   7523     if (send_socket == INVALID_SOCKET){
   7524       perror("netperf: send_udp_rr: udp rr data socket");
   7525       exit(1);
   7526     }
   7527 
   7528     if (debug) {
   7529       fprintf(where,"send_udp_rr: send_socket obtained...\n");
   7530     }
   7531 
   7532     /* If the user has requested cpu utilization measurements, we must */
   7533     /* calibrate the cpu(s). We will perform this task within the tests */
   7534     /* themselves. If the user has specified the cpu rate, then */
   7535     /* calibrate_local_cpu will return rather quickly as it will have */
   7536     /* nothing to do. If local_cpu_rate is zero, then we will go through */
   7537     /* all the "normal" calibration stuff and return the rate back. If */
   7538     /* there is no idle counter in the kernel idle loop, the */
   7539     /* local_cpu_rate will be set to -1. */
   7540 
   7541     if (local_cpu_usage) {
   7542       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   7543     }
   7544 
   7545     if (!no_control) {
   7546       /* Tell the remote end to do a listen. The server alters the
   7547 	 socket paramters on the other side at this point, hence the
   7548 	 reason for all the values being passed in the setup
   7549 	 message. If the user did not specify any of the parameters,
   7550 	 they will be passed as 0, which will indicate to the remote
   7551 	 that no changes beyond the system's default should be
   7552 	 used. Alignment is the exception, it will default to 8, which
   7553 	 will be no alignment alterations. */
   7554 
   7555       netperf_request.content.request_type	= DO_UDP_RR;
   7556       udp_rr_request->recv_buf_size	= rsr_size_req;
   7557       udp_rr_request->send_buf_size	= rss_size_req;
   7558       udp_rr_request->recv_alignment      = remote_recv_align;
   7559       udp_rr_request->recv_offset	        = remote_recv_offset;
   7560       udp_rr_request->send_alignment      = remote_send_align;
   7561       udp_rr_request->send_offset	        = remote_send_offset;
   7562       udp_rr_request->request_size	= req_size;
   7563       udp_rr_request->response_size	= rsp_size;
   7564       udp_rr_request->measure_cpu	        = remote_cpu_usage;
   7565       udp_rr_request->cpu_rate	        = remote_cpu_rate;
   7566       udp_rr_request->so_rcvavoid	        = rem_rcvavoid;
   7567       udp_rr_request->so_sndavoid	        = rem_sndavoid;
   7568       if (test_time) {
   7569 	udp_rr_request->test_length	= test_time;
   7570       }
   7571       else {
   7572 	udp_rr_request->test_length	= test_trans * -1;
   7573       }
   7574       udp_rr_request->port                = atoi(remote_data_port);
   7575       udp_rr_request->ipfamily = af_to_nf(remote_res->ai_family);
   7576 
   7577       if (debug > 1) {
   7578 	fprintf(where,"netperf: send_udp_rr: requesting UDP r/r test\n");
   7579       }
   7580 
   7581       send_request();
   7582 
   7583       /* The response from the remote will contain all of the relevant
   7584 	 socket parameters for this test type. We will put them back
   7585 	 into the variables here so they can be displayed if desired.
   7586 	 The remote will have calibrated CPU if necessary, and will
   7587 	 have done all the needed set-up we will have calibrated the
   7588 	 cpu locally before sending the request, and will grab the
   7589 	 counter value right after the connect returns. The remote
   7590 	 will grab the counter right after the accept call. This saves
   7591 	 the hassle of extra messages being sent for the UDP
   7592 	 tests.  */
   7593 
   7594       recv_response();
   7595 
   7596       if (!netperf_response.content.serv_errno) {
   7597 	if (debug)
   7598 	  fprintf(where,"remote listen done.\n");
   7599 	rsr_size	       =	udp_rr_response->recv_buf_size;
   7600 	rss_size	       =	udp_rr_response->send_buf_size;
   7601 	remote_cpu_usage =	udp_rr_response->measure_cpu;
   7602 	remote_cpu_rate  = 	udp_rr_response->cpu_rate;
   7603 	/* port numbers in proper order */
   7604 	set_port_number(remote_res,(short)udp_rr_response->data_port_number);
   7605       }
   7606       else {
   7607 	Set_errno(netperf_response.content.serv_errno);
   7608 	fprintf(where,
   7609 		"netperf: remote error %d",
   7610 		netperf_response.content.serv_errno);
   7611 	perror("");
   7612 	fflush(where);
   7613 	exit(1);
   7614       }
   7615     }
   7616 
   7617 #ifdef WANT_DEMO
   7618     demo_rr_setup(100);
   7619 #endif
   7620 
   7621     /* Connect up to the remote port on the data socket. This will set */
   7622     /* the default destination address on this socket. With UDP, this */
   7623     /* does make a performance difference as we may not have to do as */
   7624     /* many routing lookups, however, I expect that a client would */
   7625     /* behave this way. raj 1/94 */
   7626 
   7627     if ( connect(send_socket,
   7628 		 remote_res->ai_addr,
   7629 		 remote_res->ai_addrlen) == INVALID_SOCKET ) {
   7630       perror("netperf: data socket connect failed");
   7631       exit(1);
   7632     }
   7633 
   7634 #ifdef WIN32
   7635   /* this is used so the timer thread can close the socket out from */
   7636   /* under us, which to date is the easiest/cleanest/least */
   7637   /* Windows-specific way I can find to force the winsock calls to */
   7638   /* return WSAEINTR with the test is over. anything that will run on */
   7639   /* 95 and NT and is closer to what netperf expects from Unix signals */
   7640   /* and such would be appreciated raj 1/96 */
   7641   win_kludge_socket = send_socket;
   7642 #endif /* WIN32 */
   7643 
   7644     /* Data Socket set-up is finished. If there were problems, either the */
   7645     /* connect would have failed, or the previous response would have */
   7646     /* indicated a problem. I failed to see the value of the extra */
   7647     /* message after the accept on the remote. If it failed, we'll see it */
   7648     /* here. If it didn't, we might as well start pumping data. */
   7649 
   7650     /* Set-up the test end conditions. For a request/response test, they */
   7651     /* can be either time or transaction based. */
   7652 
   7653     if (test_time) {
   7654       /* The user wanted to end the test after a period of time. */
   7655       times_up = 0;
   7656       trans_remaining = 0;
   7657       start_timer(test_time);
   7658     }
   7659     else {
   7660       /* The tester wanted to send a number of bytes. */
   7661       trans_remaining = test_bytes;
   7662       times_up = 1;
   7663     }
   7664 
   7665     /* The cpu_start routine will grab the current time and possibly */
   7666     /* value of the idle counter for later use in measuring cpu */
   7667     /* utilization and/or service demand and thruput. */
   7668 
   7669     cpu_start(local_cpu_usage);
   7670 
   7671 #ifdef WANT_DEMO
   7672     if (demo_mode) {
   7673       demo_first_timestamp();
   7674     }
   7675 #endif
   7676 
   7677 #ifdef WANT_INTERVALS
   7678     INTERVALS_INIT();
   7679 #endif /* WANT_INTERVALS */
   7680 
   7681     /* We use an "OR" to control test execution. When the test is */
   7682     /* controlled by time, the byte count check will always return */
   7683     /* false. When the test is controlled by byte count, the time test */
   7684     /* will always return false. When the test is finished, the whole */
   7685     /* expression will go false and we will stop sending data. I think */
   7686     /* I just arbitrarily decrement trans_remaining for the timed */
   7687     /* test, but will not do that just yet... One other question is */
   7688     /* whether or not the send buffer and the receive buffer should be */
   7689     /* the same buffer. */
   7690 
   7691 #ifdef WANT_FIRST_BURST
   7692     {
   7693       int i;
   7694       for (i = 0; i < first_burst_size; i++) {
   7695 	if((len=send(send_socket,
   7696 		     send_ring->buffer_ptr,
   7697 		     req_size,
   7698 		     0)) != req_size) {
   7699 	  /* we should never hit the end of the test in the first burst */
   7700 	  perror("send_udp_rr: initial burst data send error");
   7701 	  exit(-1);
   7702 	}
   7703       }
   7704     }
   7705 #endif /* WANT_FIRST_BURST */
   7706 
   7707     while ((!times_up) || (trans_remaining > 0)) {
   7708       /* send the request */
   7709 #ifdef WANT_HISTOGRAM
   7710       if (verbosity > 1) {
   7711 	HIST_timestamp(&time_one);
   7712       }
   7713 #endif
   7714       if((len=send(send_socket,
   7715 		   send_ring->buffer_ptr,
   7716 		   req_size,
   7717 		   0)) != req_size) {
   7718         if (SOCKET_EINTR(len)) {
   7719 	      /* We likely hit */
   7720 	      /* test-end time. */
   7721 	      break;
   7722 		}
   7723 	    perror("send_udp_rr: data send error");
   7724 	    exit(1);
   7725 	  }
   7726       send_ring = send_ring->next;
   7727 
   7728       /* receive the response. with UDP we will get it all, or nothing */
   7729 
   7730       if((rsp_bytes_recvd=recv(send_socket,
   7731 			       recv_ring->buffer_ptr,
   7732 			       rsp_size,
   7733 			       0)) != rsp_size) {
   7734 	    if (SOCKET_EINTR(rsp_bytes_recvd))
   7735 		{
   7736     	  /* Again, we have likely hit test-end time */
   7737 	      break;
   7738 		}
   7739 	    perror("send_udp_rr: data recv error");
   7740 	    exit(1);
   7741       }
   7742       recv_ring = recv_ring->next;
   7743 
   7744 #ifdef WANT_HISTOGRAM
   7745       if (verbosity > 1) {
   7746 	HIST_timestamp(&time_two);
   7747 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   7748       }
   7749 
   7750 #endif
   7751 
   7752       /* at this point, we may wish to sleep for some period of */
   7753       /* time, so we see how long that last transaction just took, */
   7754       /* and sleep for the difference of that and the interval. We */
   7755       /* will not sleep if the time would be less than a */
   7756       /* millisecond.  */
   7757 
   7758 #ifdef WANT_DEMO
   7759       demo_rr_interval(1);
   7760 #endif
   7761 
   7762 #ifdef WANT_INTERVALS
   7763       INTERVALS_WAIT();
   7764 #endif /* WANT_INTERVALS */
   7765 
   7766       nummessages++;
   7767       if (trans_remaining) {
   7768 	trans_remaining--;
   7769       }
   7770 
   7771       if (debug > 3) {
   7772 	if ((nummessages % 100) == 0) {
   7773 	  fprintf(where,"Transaction %d completed\n",nummessages);
   7774 	  fflush(where);
   7775 	}
   7776       }
   7777 
   7778     }
   7779 
   7780     /* for some strange reason, I used to call shutdown on the UDP */
   7781     /* data socket here. I'm not sure why, because it would not have */
   7782     /* any effect... raj 11/94 */
   7783 
   7784     /* this call will always give us the elapsed time for the test, and */
   7785     /* will also store-away the necessaries for cpu utilization */
   7786 
   7787     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
   7788 						/* measured? how long */
   7789 						/* did we really run? */
   7790 
   7791 #if defined(WANT_INTERVALS)
   7792 #ifdef WIN32
   7793     stop_itimer();
   7794 #endif
   7795 #endif /* WANT_INTERVALS */
   7796 
   7797     if (!no_control) {
   7798       /* Get the statistics from the remote end. The remote will have
   7799 	 calculated service demand and all those interesting
   7800 	 things. If it wasn't supposed to care, it will return obvious
   7801 	 values. */
   7802 
   7803       recv_response();
   7804       if (!netperf_response.content.serv_errno) {
   7805 	if (debug)
   7806 	  fprintf(where,"remote results obtained\n");
   7807       }
   7808       else {
   7809 	Set_errno(netperf_response.content.serv_errno);
   7810 	fprintf(where,
   7811 		"netperf: remote error %d",
   7812 		netperf_response.content.serv_errno);
   7813 	perror("");
   7814 	fflush(where);
   7815 	exit(1);
   7816       }
   7817     }
   7818 
   7819     /* We now calculate what our thruput was for the test. In the */
   7820     /* future, we may want to include a calculation of the thruput */
   7821     /* measured by the remote, but it should be the case that for a */
   7822     /* UDP rr test, that the two numbers should be *very* close... */
   7823     /* We calculate bytes_sent regardless of the way the test length */
   7824     /* was controlled.  */
   7825 
   7826     bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
   7827     thruput	= nummessages / elapsed_time;
   7828 
   7829     if (local_cpu_usage || remote_cpu_usage) {
   7830 
   7831       /* We must now do a little math for service demand and cpu */
   7832       /* utilization for the system(s) Of course, some of the */
   7833       /* information might be bogus because there was no idle counter */
   7834       /* in the kernel(s). We need to make a note of this for the */
   7835       /* user's benefit by placing a code for the metod used in the */
   7836       /* test banner */
   7837 
   7838       if (local_cpu_usage) {
   7839 	local_cpu_utilization = calc_cpu_util(0.0);
   7840 
   7841 	/* since calc_service demand is doing ms/Kunit we will */
   7842 	/* multiply the number of transaction by 1024 to get */
   7843 	/* "good" numbers */
   7844 
   7845 	local_service_demand  = calc_service_demand((double) nummessages*1024,
   7846 						    0.0,
   7847 						    0.0,
   7848 						    0);
   7849       }
   7850       else {
   7851 	local_cpu_utilization	= (float) -1.0;
   7852 	local_service_demand	= (float) -1.0;
   7853       }
   7854 
   7855       if (remote_cpu_usage) {
   7856 	remote_cpu_utilization = udp_rr_result->cpu_util;
   7857 
   7858 	/* since calc_service demand is doing ms/Kunit we will */
   7859 	/* multiply the number of transaction by 1024 to get */
   7860 	/* "good" numbers */
   7861 
   7862 	remote_service_demand  = calc_service_demand((double) nummessages*1024,
   7863 						     0.0,
   7864 						     remote_cpu_utilization,
   7865 						     udp_rr_result->num_cpus);
   7866       }
   7867       else {
   7868 	remote_cpu_utilization = (float) -1.0;
   7869 	remote_service_demand  = (float) -1.0;
   7870       }
   7871     }
   7872     else {
   7873       /* we were not measuring cpu, for the confidence stuff, we */
   7874       /* should make it -1.0 */
   7875       local_cpu_utilization	= (float) -1.0;
   7876       local_service_demand	= (float) -1.0;
   7877       remote_cpu_utilization = (float) -1.0;
   7878       remote_service_demand  = (float) -1.0;
   7879     }
   7880 
   7881     /* at this point, we want to calculate the confidence information. */
   7882     /* if debugging is on, calculate_confidence will print-out the */
   7883     /* parameters we pass it */
   7884 
   7885     calculate_confidence(confidence_iteration,
   7886 			 elapsed_time,
   7887 			 thruput,
   7888 			 local_cpu_utilization,
   7889 			 remote_cpu_utilization,
   7890 			 local_service_demand,
   7891 			 remote_service_demand);
   7892 
   7893 
   7894     confidence_iteration++;
   7895 
   7896     /* we are done with the socket */
   7897     close(send_socket);
   7898   }
   7899 
   7900   /* at this point, we have made all the iterations we are going to */
   7901   /* make. */
   7902   retrieve_confident_values(&elapsed_time,
   7903 			    &thruput,
   7904 			    &local_cpu_utilization,
   7905 			    &remote_cpu_utilization,
   7906 			    &local_service_demand,
   7907 			    &remote_service_demand);
   7908 
   7909   /* We are now ready to print all the information. If the user */
   7910   /* has specified zero-level verbosity, we will just print the */
   7911   /* local service demand, or the remote service demand. If the */
   7912   /* user has requested verbosity level 1, he will get the basic */
   7913   /* "streamperf" numbers. If the user has specified a verbosity */
   7914   /* of greater than 1, we will display a veritable plethora of */
   7915   /* background information from outside of this block as it it */
   7916   /* not cpu_measurement specific...  */
   7917 
   7918   if (confidence < 0) {
   7919     /* we did not hit confidence, but were we asked to look for it? */
   7920     if (iteration_max > 1) {
   7921       display_confidence();
   7922     }
   7923   }
   7924 
   7925   if (local_cpu_usage || remote_cpu_usage) {
   7926     local_cpu_method = format_cpu_method(cpu_method);
   7927     remote_cpu_method = format_cpu_method(udp_rr_result->cpu_method);
   7928 
   7929     switch (verbosity) {
   7930     case 0:
   7931       if (local_cpu_usage) {
   7932 	fprintf(where,
   7933 		cpu_fmt_0,
   7934 		local_service_demand,
   7935 		local_cpu_method,
   7936                 ((print_headers) ||
   7937                  (result_brand == NULL)) ? "" : result_brand);
   7938 
   7939       }
   7940       else {
   7941 	fprintf(where,
   7942 		cpu_fmt_0,
   7943 		remote_service_demand,
   7944 		remote_cpu_method,
   7945                 ((print_headers) ||
   7946                  (result_brand == NULL)) ? "" : result_brand);
   7947 
   7948       }
   7949       break;
   7950     case 1:
   7951     case 2:
   7952       if (print_headers) {
   7953         if ('x' == libfmt) {
   7954           fprintf(where,
   7955                   cpu_title,
   7956                   local_cpu_method,
   7957                   remote_cpu_method);
   7958         }
   7959         else {
   7960           fprintf(where,
   7961                   cpu_title_tput,
   7962                   format_units(),
   7963                   local_cpu_method,
   7964                   remote_cpu_method);
   7965         }
   7966       }
   7967 
   7968       fprintf(where,
   7969 	      cpu_fmt_1_line_1,		/* the format string */
   7970 	      lss_size,		/* local sendbuf size */
   7971 	      lsr_size,
   7972 	      req_size,		/* how large were the requests */
   7973 	      rsp_size,		/* guess */
   7974 	      elapsed_time,		/* how long was the test */
   7975 	      ('x' == libfmt) ? thruput :
   7976 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
   7977 									 1.0),
   7978 	      local_cpu_utilization,	/* local cpu */
   7979 	      remote_cpu_utilization,	/* remote cpu */
   7980 	      local_service_demand,	/* local service demand */
   7981 	      remote_service_demand,	/* remote service demand */
   7982 	      ((print_headers) ||
   7983 	       (result_brand == NULL)) ? "" : result_brand);
   7984       fprintf(where,
   7985 	      cpu_fmt_1_line_2,
   7986 	      rss_size,
   7987 	      rsr_size);
   7988       break;
   7989     }
   7990   }
   7991   else {
   7992     /* The tester did not wish to measure service demand. */
   7993     switch (verbosity) {
   7994     case 0:
   7995       fprintf(where,
   7996 	      tput_fmt_0,
   7997 	      ('x' == libfmt) ? thruput :
   7998 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
   7999 					 1.0),
   8000 	      ((print_headers) ||
   8001 	       (result_brand == NULL)) ? "" : result_brand);
   8002       break;
   8003     case 1:
   8004     case 2:
   8005       if (print_headers) {
   8006 	fprintf(where,
   8007 		('x' == libfmt) ? tput_title : tput_title_band,
   8008 		format_units());
   8009       }
   8010 
   8011       fprintf(where,
   8012 	      tput_fmt_1_line_1,	/* the format string */
   8013 	      lss_size,
   8014 	      lsr_size,
   8015 	      req_size,		/* how large were the requests */
   8016 	      rsp_size,		/* how large were the responses */
   8017 	      elapsed_time, 		/* how long did it take */
   8018 	      ('x' == libfmt) ?  thruput :
   8019 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
   8020 					 1.0),
   8021 	      ((print_headers) ||
   8022 	       (result_brand == NULL)) ? "" : result_brand);
   8023       fprintf(where,
   8024 	      tput_fmt_1_line_2,
   8025 	      rss_size, 		/* remote recvbuf size */
   8026 	      rsr_size);
   8027 
   8028       break;
   8029     }
   8030   }
   8031   fflush(where);
   8032 
   8033   /* it would be a good thing to include information about some of the */
   8034   /* other parameters that may have been set for this test, but at the */
   8035   /* moment, I do not wish to figure-out all the  formatting, so I will */
   8036   /* just put this comment here to help remind me that it is something */
   8037   /* that should be done at a later time. */
   8038 
   8039   /* how to handle the verbose information in the presence of */
   8040   /* confidence intervals is yet to be determined... raj 11/94 */
   8041 
   8042   if (verbosity > 1) {
   8043     /* The user wanted to know it all, so we will give it to him. */
   8044     /* This information will include as much as we can find about */
   8045     /* UDP statistics, the alignments of the sends and receives */
   8046     /* and all that sort of rot... */
   8047 
   8048 #ifdef WANT_HISTOGRAM
   8049     fprintf(where,"\nHistogram of request/reponse times.\n");
   8050     fflush(where);
   8051     HIST_report(time_hist);
   8052 #endif /* WANT_HISTOGRAM */
   8053   }
   8054 }
   8055 #endif /* WANT_MIGRATION */
   8056 
   8057  /* this routine implements the receive side (netserver) of a UDP_RR */
   8059  /* test. */
   8060 void
   8061 recv_udp_rr()
   8062 {
   8063 
   8064   struct ring_elt *recv_ring;
   8065   struct ring_elt *send_ring;
   8066 
   8067   struct addrinfo *local_res;
   8068   char local_name[BUFSIZ];
   8069   char port_buffer[PORTBUFSIZE];
   8070 
   8071   struct sockaddr_storage        myaddr_in;
   8072   struct sockaddr_storage    peeraddr;
   8073   SOCKET	s_data;
   8074   netperf_socklen_t 	addrlen;
   8075   int	trans_received;
   8076   int	trans_remaining;
   8077   int   request_bytes_recvd;
   8078   int   response_bytes_sent;
   8079   float	elapsed_time;
   8080 
   8081   struct	udp_rr_request_struct	*udp_rr_request;
   8082   struct	udp_rr_response_struct	*udp_rr_response;
   8083   struct	udp_rr_results_struct	*udp_rr_results;
   8084 
   8085   udp_rr_request  =
   8086     (struct udp_rr_request_struct *)netperf_request.content.test_specific_data;
   8087   udp_rr_response =
   8088     (struct udp_rr_response_struct *)netperf_response.content.test_specific_data;
   8089   udp_rr_results  =
   8090     (struct udp_rr_results_struct *)netperf_response.content.test_specific_data;
   8091 
   8092   if (debug) {
   8093     fprintf(where,"netserver: recv_udp_rr: entered...\n");
   8094     fflush(where);
   8095   }
   8096 
   8097   /* We want to set-up the listen socket with all the desired */
   8098   /* parameters and then let the initiator know that all is ready. If */
   8099   /* socket size defaults are to be used, then the initiator will have */
   8100   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   8101   /* send-back what they are. If that information cannot be determined, */
   8102   /* then we send-back -1's for the sizes. If things go wrong for any */
   8103   /* reason, we will drop back ten yards and punt. */
   8104 
   8105   /* If anything goes wrong, we want the remote to know about it. It */
   8106   /* would be best if the error that the remote reports to the user is */
   8107   /* the actual error we encountered, rather than some bogus unexpected */
   8108   /* response type message. */
   8109 
   8110   if (debug) {
   8111     fprintf(where,"recv_udp_rr: setting the response type...\n");
   8112     fflush(where);
   8113   }
   8114 
   8115   netperf_response.content.response_type = UDP_RR_RESPONSE;
   8116 
   8117   if (debug) {
   8118     fprintf(where,"recv_udp_rr: the response type is set...\n");
   8119     fflush(where);
   8120   }
   8121 
   8122   /* We now alter the message_ptr variables to be at the desired */
   8123   /* alignments with the desired offsets. */
   8124 
   8125   if (debug) {
   8126     fprintf(where,"recv_udp_rr: requested recv alignment of %d offset %d\n",
   8127 	    udp_rr_request->recv_alignment,
   8128 	    udp_rr_request->recv_offset);
   8129     fprintf(where,"recv_udp_rr: requested send alignment of %d offset %d\n",
   8130 	    udp_rr_request->send_alignment,
   8131 	    udp_rr_request->send_offset);
   8132     fflush(where);
   8133   }
   8134 
   8135   if (send_width == 0) send_width = 1;
   8136   if (recv_width == 0) recv_width = 1;
   8137 
   8138   recv_ring = allocate_buffer_ring(recv_width,
   8139 				   udp_rr_request->request_size,
   8140 				   udp_rr_request->recv_alignment,
   8141 				   udp_rr_request->recv_offset);
   8142 
   8143   send_ring = allocate_buffer_ring(send_width,
   8144 				   udp_rr_request->response_size,
   8145 				   udp_rr_request->send_alignment,
   8146 				   udp_rr_request->send_offset);
   8147 
   8148   if (debug) {
   8149     fprintf(where,"recv_udp_rr: receive alignment and offset set...\n");
   8150     fflush(where);
   8151   }
   8152 
   8153   /* Grab a socket to listen on, and then listen on it. */
   8154 
   8155   if (debug) {
   8156     fprintf(where,"recv_udp_rr: grabbing a socket...\n");
   8157     fflush(where);
   8158   }
   8159 
   8160 
   8161   /* create_data_socket expects to find some things in the global */
   8162   /* variables, so set the globals based on the values in the request. */
   8163   /* once the socket has been created, we will set the response values */
   8164   /* based on the updated value of those globals. raj 7/94 */
   8165   lss_size_req = udp_rr_request->send_buf_size;
   8166   lsr_size_req = udp_rr_request->recv_buf_size;
   8167   loc_rcvavoid = udp_rr_request->so_rcvavoid;
   8168   loc_sndavoid = udp_rr_request->so_sndavoid;
   8169 
   8170   set_hostname_and_port(local_name,
   8171 			port_buffer,
   8172 			nf_to_af(udp_rr_request->ipfamily),
   8173 			udp_rr_request->port);
   8174 
   8175   local_res = complete_addrinfo(local_name,
   8176 				local_name,
   8177 				port_buffer,
   8178 				nf_to_af(udp_rr_request->ipfamily),
   8179 				SOCK_DGRAM,
   8180 				IPPROTO_UDP,
   8181 				0);
   8182 
   8183   s_data = create_data_socket(local_res);
   8184 
   8185   if (s_data == INVALID_SOCKET) {
   8186     netperf_response.content.serv_errno = errno;
   8187     send_response();
   8188 
   8189     exit(1);
   8190   }
   8191 
   8192   /* now get the port number assigned by the system  */
   8193   addrlen = sizeof(myaddr_in);
   8194   if (getsockname(s_data,
   8195 		  (struct sockaddr *)&myaddr_in,
   8196 		  &addrlen) == SOCKET_ERROR){
   8197     netperf_response.content.serv_errno = errno;
   8198     close(s_data);
   8199     send_response();
   8200 
   8201     exit(1);
   8202   }
   8203 
   8204   /* Now myaddr_in contains the port and the internet address this is */
   8205   /* returned to the sender also implicitly telling the sender that the */
   8206   /* socket buffer sizing has been done. */
   8207 
   8208   udp_rr_response->data_port_number =
   8209     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
   8210   netperf_response.content.serv_errno   = 0;
   8211 
   8212   if (debug) {
   8213     fprintf(where,
   8214 	    "recv port number %d\n",
   8215 	    ((struct sockaddr_in *)&myaddr_in)->sin_port);
   8216     fflush(where);
   8217   }
   8218 
   8219   /* But wait, there's more. If the initiator wanted cpu measurements, */
   8220   /* then we must call the calibrate routine, which will return the max */
   8221   /* rate back to the initiator. If the CPU was not to be measured, or */
   8222   /* something went wrong with the calibration, we will return a 0.0 to */
   8223   /* the initiator. */
   8224 
   8225   udp_rr_response->cpu_rate    = (float)0.0; 	/* assume no cpu */
   8226   udp_rr_response->measure_cpu = 0;
   8227   if (udp_rr_request->measure_cpu) {
   8228     udp_rr_response->measure_cpu = 1;
   8229     udp_rr_response->cpu_rate = calibrate_local_cpu(udp_rr_request->cpu_rate);
   8230   }
   8231 
   8232   /* before we send the response back to the initiator, pull some of */
   8233   /* the socket parms from the globals */
   8234   udp_rr_response->send_buf_size = lss_size;
   8235   udp_rr_response->recv_buf_size = lsr_size;
   8236   udp_rr_response->so_rcvavoid   = loc_rcvavoid;
   8237   udp_rr_response->so_sndavoid   = loc_sndavoid;
   8238 
   8239   send_response();
   8240 
   8241 
   8242   /* Now it's time to start receiving data on the connection. We will */
   8243   /* first grab the apropriate counters and then start grabbing. */
   8244 
   8245   cpu_start(udp_rr_request->measure_cpu);
   8246 
   8247 #ifdef WIN32
   8248   /* this is used so the timer thread can close the socket out from */
   8249   /* under us, which to date is the easiest/cleanest/least */
   8250   /* Windows-specific way I can find to force the winsock calls to */
   8251   /* return WSAEINTR with the test is over. anything that will run on */
   8252   /* 95 and NT and is closer to what netperf expects from Unix signals */
   8253   /* and such would be appreciated raj 1/96 */
   8254   win_kludge_socket = s_data;
   8255 #endif /* WIN32 */
   8256 
   8257   if (udp_rr_request->test_length > 0) {
   8258     times_up = 0;
   8259     trans_remaining = 0;
   8260     start_timer(udp_rr_request->test_length + PAD_TIME);
   8261   }
   8262   else {
   8263     times_up = 1;
   8264     trans_remaining = udp_rr_request->test_length * -1;
   8265   }
   8266 
   8267   addrlen = sizeof(peeraddr);
   8268   bzero((char *)&peeraddr, addrlen);
   8269 
   8270   trans_received = 0;
   8271 
   8272   while ((!times_up) || (trans_remaining > 0)) {
   8273 
   8274     /* receive the request from the other side */
   8275     if ((request_bytes_recvd = recvfrom(s_data,
   8276 		 recv_ring->buffer_ptr,
   8277 		 udp_rr_request->request_size,
   8278 		 0,
   8279 		 (struct sockaddr *)&peeraddr,
   8280 		 &addrlen)) != udp_rr_request->request_size) {
   8281 	  if ( SOCKET_EINTR(request_bytes_recvd) )
   8282 	  {
   8283 	    /* we must have hit the end of test time. */
   8284 	    break;
   8285       }
   8286       netperf_response.content.serv_errno = errno;
   8287       send_response();
   8288       exit(1);
   8289     }
   8290     recv_ring = recv_ring->next;
   8291 
   8292     /* Now, send the response to the remote */
   8293     if ((response_bytes_sent = sendto(s_data,
   8294 				      send_ring->buffer_ptr,
   8295 				      udp_rr_request->response_size,
   8296 				      0,
   8297 				      (struct sockaddr *)&peeraddr,
   8298 				      addrlen)) !=
   8299 	udp_rr_request->response_size) {
   8300       if ( SOCKET_EINTR(response_bytes_sent) )
   8301 	  {
   8302 	    /* we have hit end of test time. */
   8303 	    break;
   8304       }
   8305       netperf_response.content.serv_errno = errno;
   8306       send_response();
   8307       exit(1);
   8308     }
   8309     send_ring = send_ring->next;
   8310 
   8311     trans_received++;
   8312     if (trans_remaining) {
   8313       trans_remaining--;
   8314     }
   8315 
   8316     if (debug) {
   8317       fprintf(where,
   8318 	      "recv_udp_rr: Transaction %d complete.\n",
   8319 	      trans_received);
   8320       fflush(where);
   8321     }
   8322 
   8323   }
   8324 
   8325 
   8326   /* The loop now exits due to timeout or transaction count being */
   8327   /* reached */
   8328 
   8329   cpu_stop(udp_rr_request->measure_cpu,&elapsed_time);
   8330 
   8331   if (times_up) {
   8332     /* we ended the test by time, which was at least 2 seconds */
   8333     /* longer than we wanted to run. so, we want to subtract */
   8334     /* PAD_TIME from the elapsed_time. */
   8335     elapsed_time -= PAD_TIME;
   8336   }
   8337   /* send the results to the sender			*/
   8338 
   8339   if (debug) {
   8340     fprintf(where,
   8341 	    "recv_udp_rr: got %d transactions\n",
   8342 	    trans_received);
   8343     fflush(where);
   8344   }
   8345 
   8346   udp_rr_results->bytes_received = (trans_received *
   8347 				    (udp_rr_request->request_size +
   8348 				     udp_rr_request->response_size));
   8349   udp_rr_results->trans_received = trans_received;
   8350   udp_rr_results->elapsed_time	 = elapsed_time;
   8351   udp_rr_results->cpu_method     = cpu_method;
   8352   udp_rr_results->num_cpus       = lib_num_loc_cpus;
   8353   if (udp_rr_request->measure_cpu) {
   8354     udp_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
   8355   }
   8356 
   8357   if (debug) {
   8358     fprintf(where,
   8359 	    "recv_udp_rr: test complete, sending results.\n");
   8360     fflush(where);
   8361   }
   8362 
   8363   send_response();
   8364 
   8365   /* we are done with the socket now */
   8366   close(s_data);
   8367 
   8368       }
   8369 
   8370 
   8371  /* this routine implements the receive (netserver) side of a TCP_RR */
   8373  /* test */
   8374 void
   8375 recv_tcp_rr()
   8376 {
   8377 
   8378   struct ring_elt *send_ring;
   8379   struct ring_elt *recv_ring;
   8380 
   8381   struct addrinfo *local_res;
   8382   char local_name[BUFSIZ];
   8383   char port_buffer[PORTBUFSIZE];
   8384 
   8385   struct	sockaddr_storage        myaddr_in,
   8386   peeraddr_in;
   8387   SOCKET	s_listen,s_data;
   8388   netperf_socklen_t 	addrlen;
   8389   char	*temp_message_ptr;
   8390   int	trans_received;
   8391   int	trans_remaining;
   8392   int	bytes_sent;
   8393   int	request_bytes_recvd;
   8394   int	request_bytes_remaining;
   8395   int	timed_out = 0;
   8396   int   sock_closed = 0;
   8397   float	elapsed_time;
   8398 
   8399   struct	tcp_rr_request_struct	*tcp_rr_request;
   8400   struct	tcp_rr_response_struct	*tcp_rr_response;
   8401   struct	tcp_rr_results_struct	*tcp_rr_results;
   8402 
   8403   tcp_rr_request =
   8404     (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data;
   8405   tcp_rr_response =
   8406     (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data;
   8407   tcp_rr_results =
   8408     (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data;
   8409 
   8410   if (debug) {
   8411     fprintf(where,"netserver: recv_tcp_rr: entered...\n");
   8412     fflush(where);
   8413   }
   8414 
   8415   /* We want to set-up the listen socket with all the desired */
   8416   /* parameters and then let the initiator know that all is ready. If */
   8417   /* socket size defaults are to be used, then the initiator will have */
   8418   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   8419   /* send-back what they are. If that information cannot be determined, */
   8420   /* then we send-back -1's for the sizes. If things go wrong for any */
   8421   /* reason, we will drop back ten yards and punt. */
   8422 
   8423   /* If anything goes wrong, we want the remote to know about it. It */
   8424   /* would be best if the error that the remote reports to the user is */
   8425   /* the actual error we encountered, rather than some bogus unexpected */
   8426   /* response type message. */
   8427 
   8428   if (debug) {
   8429     fprintf(where,"recv_tcp_rr: setting the response type...\n");
   8430     fflush(where);
   8431   }
   8432 
   8433   netperf_response.content.response_type = TCP_RR_RESPONSE;
   8434 
   8435   if (debug) {
   8436     fprintf(where,"recv_tcp_rr: the response type is set...\n");
   8437     fflush(where);
   8438   }
   8439 
   8440   /* allocate the recv and send rings with the requested alignments */
   8441   /* and offsets. raj 7/94 */
   8442   if (debug) {
   8443     fprintf(where,"recv_tcp_rr: requested recv alignment of %d offset %d\n",
   8444 	    tcp_rr_request->recv_alignment,
   8445 	    tcp_rr_request->recv_offset);
   8446     fprintf(where,"recv_tcp_rr: requested send alignment of %d offset %d\n",
   8447 	    tcp_rr_request->send_alignment,
   8448 	    tcp_rr_request->send_offset);
   8449     fflush(where);
   8450   }
   8451 
   8452   /* at some point, these need to come to us from the remote system */
   8453   if (send_width == 0) send_width = 1;
   8454   if (recv_width == 0) recv_width = 1;
   8455 
   8456   send_ring = allocate_buffer_ring(send_width,
   8457 				   tcp_rr_request->response_size,
   8458 				   tcp_rr_request->send_alignment,
   8459 				   tcp_rr_request->send_offset);
   8460 
   8461   recv_ring = allocate_buffer_ring(recv_width,
   8462 				   tcp_rr_request->request_size,
   8463 				   tcp_rr_request->recv_alignment,
   8464 				   tcp_rr_request->recv_offset);
   8465 
   8466 
   8467   /* Grab a socket to listen on, and then listen on it. */
   8468 
   8469   if (debug) {
   8470     fprintf(where,"recv_tcp_rr: grabbing a socket...\n");
   8471     fflush(where);
   8472   }
   8473 
   8474   /* create_data_socket expects to find some things in the global */
   8475   /* variables, so set the globals based on the values in the request. */
   8476   /* once the socket has been created, we will set the response values */
   8477   /* based on the updated value of those globals. raj 7/94 */
   8478   lss_size_req = tcp_rr_request->send_buf_size;
   8479   lsr_size_req = tcp_rr_request->recv_buf_size;
   8480   loc_nodelay = tcp_rr_request->no_delay;
   8481   loc_rcvavoid = tcp_rr_request->so_rcvavoid;
   8482   loc_sndavoid = tcp_rr_request->so_sndavoid;
   8483 
   8484   set_hostname_and_port(local_name,
   8485 			port_buffer,
   8486 			nf_to_af(tcp_rr_request->ipfamily),
   8487 			tcp_rr_request->port);
   8488 
   8489   local_res = complete_addrinfo(local_name,
   8490 				local_name,
   8491 				port_buffer,
   8492 				nf_to_af(tcp_rr_request->ipfamily),
   8493 				SOCK_STREAM,
   8494 				IPPROTO_TCP,
   8495 				0);
   8496 
   8497   s_listen = create_data_socket(local_res);
   8498 
   8499   if (s_listen == INVALID_SOCKET) {
   8500     netperf_response.content.serv_errno = errno;
   8501     send_response();
   8502 
   8503     exit(1);
   8504   }
   8505 
   8506 
   8507 #ifdef WIN32
   8508   /* The test timer can fire during operations on the listening socket,
   8509      so to make the start_timer below work we have to move
   8510      it to close s_listen while we are blocked on accept. */
   8511   win_kludge_socket2 = s_listen;
   8512 #endif
   8513 
   8514 
   8515   /* Now, let's set-up the socket to listen for connections */
   8516   if (listen(s_listen, 5) == SOCKET_ERROR) {
   8517     netperf_response.content.serv_errno = errno;
   8518     close(s_listen);
   8519     send_response();
   8520 
   8521     exit(1);
   8522   }
   8523 
   8524 
   8525   /* now get the port number assigned by the system  */
   8526   addrlen = sizeof(myaddr_in);
   8527   if (getsockname(s_listen,
   8528 		  (struct sockaddr *)&myaddr_in,
   8529 		  &addrlen) == SOCKET_ERROR) {
   8530     netperf_response.content.serv_errno = errno;
   8531     close(s_listen);
   8532     send_response();
   8533 
   8534     exit(1);
   8535   }
   8536 
   8537   /* Now myaddr_in contains the port and the internet address this is */
   8538   /* returned to the sender also implicitly telling the sender that the */
   8539   /* socket buffer sizing has been done. */
   8540 
   8541   tcp_rr_response->data_port_number =
   8542     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
   8543   netperf_response.content.serv_errno   = 0;
   8544 
   8545   /* But wait, there's more. If the initiator wanted cpu measurements, */
   8546   /* then we must call the calibrate routine, which will return the max */
   8547   /* rate back to the initiator. If the CPU was not to be measured, or */
   8548   /* something went wrong with the calibration, we will return a 0.0 to */
   8549   /* the initiator. */
   8550 
   8551   tcp_rr_response->cpu_rate = (float)0.0; 	/* assume no cpu */
   8552   tcp_rr_response->measure_cpu = 0;
   8553 
   8554   if (tcp_rr_request->measure_cpu) {
   8555     tcp_rr_response->measure_cpu = 1;
   8556     tcp_rr_response->cpu_rate = calibrate_local_cpu(tcp_rr_request->cpu_rate);
   8557   }
   8558 
   8559 
   8560   /* before we send the response back to the initiator, pull some of */
   8561   /* the socket parms from the globals */
   8562   tcp_rr_response->send_buf_size = lss_size;
   8563   tcp_rr_response->recv_buf_size = lsr_size;
   8564   tcp_rr_response->no_delay = loc_nodelay;
   8565   tcp_rr_response->so_rcvavoid = loc_rcvavoid;
   8566   tcp_rr_response->so_sndavoid = loc_sndavoid;
   8567   tcp_rr_response->test_length = tcp_rr_request->test_length;
   8568   send_response();
   8569 
   8570   addrlen = sizeof(peeraddr_in);
   8571 
   8572   if ((s_data = accept(s_listen,
   8573 		       (struct sockaddr *)&peeraddr_in,
   8574 		       &addrlen)) == INVALID_SOCKET) {
   8575     /* Let's just punt. The remote will be given some information */
   8576     close(s_listen);
   8577 
   8578     exit(1);
   8579   }
   8580 
   8581 #ifdef KLUDGE_SOCKET_OPTIONS
   8582   /* this is for those systems which *INCORRECTLY* fail to pass */
   8583   /* attributes across an accept() call. Including this goes against */
   8584   /* my better judgement :( raj 11/95 */
   8585 
   8586   kludge_socket_options(s_data);
   8587 
   8588 #endif /* KLUDGE_SOCKET_OPTIONS */
   8589 
   8590 #ifdef WIN32
   8591   /* this is used so the timer thread can close the socket out from */
   8592   /* under us, which to date is the easiest/cleanest/least */
   8593   /* Windows-specific way I can find to force the winsock calls to */
   8594   /* return WSAEINTR with the test is over. anything that will run on */
   8595   /* 95 and NT and is closer to what netperf expects from Unix signals */
   8596   /* and such would be appreciated raj 1/96 */
   8597   win_kludge_socket = s_data;
   8598   win_kludge_socket2 = INVALID_SOCKET;
   8599 #endif /* WIN32 */
   8600 
   8601   if (debug) {
   8602     fprintf(where,"recv_tcp_rr: accept completes on the data connection.\n");
   8603     fflush(where);
   8604   }
   8605 
   8606   /* Now it's time to start receiving data on the connection. We will */
   8607   /* first grab the apropriate counters and then start grabbing. */
   8608 
   8609   cpu_start(tcp_rr_request->measure_cpu);
   8610 
   8611   /* The loop will exit when we hit the end of the test time, or when */
   8612   /* we have exchanged the requested number of transactions. */
   8613 
   8614   if (tcp_rr_request->test_length > 0) {
   8615     times_up = 0;
   8616     trans_remaining = 0;
   8617     start_timer(tcp_rr_request->test_length + PAD_TIME);
   8618   }
   8619   else {
   8620     times_up = 1;
   8621     trans_remaining = tcp_rr_request->test_length * -1;
   8622   }
   8623 
   8624   trans_received = 0;
   8625 
   8626   while ((!times_up) || (trans_remaining > 0)) {
   8627     temp_message_ptr = recv_ring->buffer_ptr;
   8628     request_bytes_remaining	= tcp_rr_request->request_size;
   8629     while(request_bytes_remaining > 0) {
   8630       if((request_bytes_recvd=recv(s_data,
   8631 				   temp_message_ptr,
   8632 				   request_bytes_remaining,
   8633 				   0)) == SOCKET_ERROR) {
   8634 	if (SOCKET_EINTR(request_bytes_recvd))
   8635 	{
   8636 	  timed_out = 1;
   8637 	  break;
   8638 	}
   8639 
   8640 	netperf_response.content.serv_errno = errno;
   8641 	send_response();
   8642 	exit(1);
   8643       }
   8644       else if( request_bytes_recvd == 0 ) {
   8645 	if (debug) {
   8646 	  fprintf(where,"zero is my hero\n");
   8647 	  fflush(where);
   8648 	}
   8649 	sock_closed = 1;
   8650 	break;
   8651       }
   8652       else {
   8653 	request_bytes_remaining -= request_bytes_recvd;
   8654 	temp_message_ptr  += request_bytes_recvd;
   8655       }
   8656     }
   8657 
   8658     recv_ring = recv_ring->next;
   8659 
   8660     if ((timed_out) || (sock_closed)) {
   8661       /* we hit the end of the test based on time - or the socket
   8662 	 closed on us along the way.  bail out of here now... */
   8663       if (debug) {
   8664 	fprintf(where,"yo5\n");
   8665 	fflush(where);
   8666       }
   8667       break;
   8668     }
   8669 
   8670     /* Now, send the response to the remote */
   8671     if((bytes_sent=send(s_data,
   8672 			send_ring->buffer_ptr,
   8673 			tcp_rr_request->response_size,
   8674 			0)) == SOCKET_ERROR) {
   8675       if (SOCKET_EINTR(bytes_sent)) {
   8676 	/* the test timer has popped */
   8677 	timed_out = 1;
   8678 	fprintf(where,"yo6\n");
   8679 	fflush(where);
   8680 	break;
   8681       }
   8682       netperf_response.content.serv_errno = 992;
   8683       send_response();
   8684       exit(1);
   8685     }
   8686 
   8687     send_ring = send_ring->next;
   8688 
   8689     trans_received++;
   8690     if (trans_remaining) {
   8691       trans_remaining--;
   8692     }
   8693   }
   8694 
   8695 
   8696   /* The loop now exits due to timeout or transaction count being */
   8697   /* reached */
   8698 
   8699   cpu_stop(tcp_rr_request->measure_cpu,&elapsed_time);
   8700 
   8701   stop_timer();
   8702 
   8703   if (timed_out) {
   8704     /* we ended the test by time, which was at least 2 seconds */
   8705     /* longer than we wanted to run. so, we want to subtract */
   8706     /* PAD_TIME from the elapsed_time. */
   8707     elapsed_time -= PAD_TIME;
   8708   }
   8709 
   8710   /* send the results to the sender			*/
   8711 
   8712   if (debug) {
   8713     fprintf(where,
   8714 	    "recv_tcp_rr: got %d transactions\n",
   8715 	    trans_received);
   8716     fflush(where);
   8717   }
   8718 
   8719   tcp_rr_results->bytes_received = (trans_received *
   8720 				    (tcp_rr_request->request_size +
   8721 				     tcp_rr_request->response_size));
   8722   tcp_rr_results->trans_received = trans_received;
   8723   tcp_rr_results->elapsed_time   = elapsed_time;
   8724   tcp_rr_results->cpu_method     = cpu_method;
   8725   tcp_rr_results->num_cpus       = lib_num_loc_cpus;
   8726   if (tcp_rr_request->measure_cpu) {
   8727     tcp_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
   8728   }
   8729 
   8730   if (debug) {
   8731     fprintf(where,
   8732 	    "recv_tcp_rr: test complete, sending results.\n");
   8733     fflush(where);
   8734   }
   8735 
   8736   /* we are now done with the sockets */
   8737   close(s_data);
   8738   close(s_listen);
   8739 
   8740   send_response();
   8741 
   8742 }
   8743 
   8744 
   8745 void
   8747 loc_cpu_rate()
   8748 {
   8749 #if defined(USE_LOOPER)
   8750   float dummy;
   8751 #endif
   8752 
   8753   /* a rather simple little test - it merely calibrates the local cpu */
   8754   /* and prints the results. There are no headers to allow someone to */
   8755   /* find a rate and use it in other tests automagically by setting a */
   8756   /* variable equal to the output of this test. We ignore any rates */
   8757   /* that may have been specified. In fact, we ignore all of the */
   8758   /* command line args! */
   8759 
   8760   fprintf(where,
   8761 	  "%g",
   8762 	  calibrate_local_cpu(0.0));
   8763 
   8764   if (verbosity > 1)
   8765     fprintf(where,
   8766 	    "\nThere %s %d local %s\n",
   8767 	    (lib_num_loc_cpus > 1) ? "are" : "is",
   8768 	    lib_num_loc_cpus,
   8769 	    (lib_num_loc_cpus > 1) ? "cpus" : "cpu");
   8770 
   8771   /* we need the cpu_start, cpu_stop in the looper case to kill the */
   8772   /* child proceses raj 4/95 */
   8773 
   8774 #ifdef USE_LOOPER
   8775   cpu_start(1);
   8776   cpu_stop(1,&dummy);
   8777 #endif /* USE_LOOPER */
   8778 
   8779 }
   8780 
   8781 void
   8782 rem_cpu_rate()
   8783 {
   8784   /* this test is much like the local variant, except that it works for */
   8785   /* the remote system, so in this case, we do pay attention to the */
   8786   /* value of the '-H' command line argument. */
   8787 
   8788   fprintf(where,
   8789 	  "%g",
   8790 	  calibrate_remote_cpu());
   8791 
   8792   if (verbosity > 1)
   8793     fprintf(where,
   8794 	    "\nThere %s %d remote %s\n",
   8795 	    (lib_num_rem_cpus > 1) ? "are" : "is",
   8796 	    lib_num_rem_cpus,
   8797 	    (lib_num_rem_cpus > 1) ? "cpus" : "cpu");
   8798 
   8799 }
   8800 
   8801 
   8802 #ifndef WANT_MIGRATION
   8804  /* this test is intended to test the performance of establishing a
   8805     connection, exchanging a request/response pair, and repeating. it
   8806     is expected that this would be a good starting-point for
   8807     comparision of T/TCP with classic TCP for transactional workloads.
   8808     it will also look (can look) much like the communication pattern
   8809     of http for www access. */
   8810 
   8811 void
   8812 send_tcp_conn_rr(char remote_host[])
   8813 {
   8814 
   8815   char *tput_title = "\
   8816 Local /Remote\n\
   8817 Socket Size   Request  Resp.   Elapsed  Trans.\n\
   8818 Send   Recv   Size     Size    Time     Rate         \n\
   8819 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
   8820 
   8821   char *tput_fmt_0 =
   8822     "%7.2f\n";
   8823 
   8824   char *tput_fmt_1_line_1 = "\
   8825 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
   8826   char *tput_fmt_1_line_2 = "\
   8827 %-6d %-6d\n";
   8828 
   8829   char *cpu_title = "\
   8830 Local /Remote\n\
   8831 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
   8832 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
   8833 bytes  bytes  bytes   bytes  secs.   per sec  %%      %%      us/Tr   us/Tr\n\n";
   8834 
   8835   char *cpu_fmt_0 =
   8836     "%6.3f\n";
   8837 
   8838   char *cpu_fmt_1_line_1 = "\
   8839 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f\n";
   8840 
   8841   char *cpu_fmt_1_line_2 = "\
   8842 %-6d %-6d\n";
   8843 
   8844   char *ksink_fmt = "\n\
   8845 Alignment      Offset\n\
   8846 Local  Remote  Local  Remote\n\
   8847 Send   Recv    Send   Recv\n\
   8848 %5d  %5d   %5d  %5d\n";
   8849 
   8850 
   8851   int			timed_out = 0;
   8852   float			elapsed_time;
   8853 
   8854   int	len;
   8855   struct ring_elt *send_ring;
   8856   struct ring_elt *recv_ring;
   8857   char	*temp_message_ptr;
   8858   int	nummessages;
   8859   SOCKET	send_socket;
   8860   int	trans_remaining;
   8861   double	bytes_xferd;
   8862   int	rsp_bytes_left;
   8863   int	rsp_bytes_recvd;
   8864 
   8865   float	local_cpu_utilization;
   8866   float	local_service_demand;
   8867   float	remote_cpu_utilization;
   8868   float	remote_service_demand;
   8869   double	thruput;
   8870 
   8871   struct addrinfo *local_res;
   8872   struct addrinfo *remote_res;
   8873 
   8874   int                           myport;
   8875   int                           ret;
   8876 
   8877   struct	tcp_conn_rr_request_struct	*tcp_conn_rr_request;
   8878   struct	tcp_conn_rr_response_struct	*tcp_conn_rr_response;
   8879   struct	tcp_conn_rr_results_struct	*tcp_conn_rr_result;
   8880 
   8881   tcp_conn_rr_request =
   8882     (struct tcp_conn_rr_request_struct *)netperf_request.content.test_specific_data;
   8883   tcp_conn_rr_response =
   8884     (struct tcp_conn_rr_response_struct *)netperf_response.content.test_specific_data;
   8885   tcp_conn_rr_result =
   8886     (struct tcp_conn_rr_results_struct *)netperf_response.content.test_specific_data;
   8887 
   8888 
   8889 #ifdef WANT_HISTOGRAM
   8890   if (verbosity > 1) {
   8891     time_hist = HIST_new();
   8892   }
   8893 #endif /* WANT_HISTOGRAM */
   8894 
   8895   /* since we are now disconnected from the code that established the */
   8896   /* control socket, and since we want to be able to use different */
   8897   /* protocols and such, we are passed the name of the remote host and */
   8898   /* must turn that into the test specific addressing information. */
   8899 
   8900   complete_addrinfos(&remote_res,
   8901 		     &local_res,
   8902 		     remote_host,
   8903 		     SOCK_STREAM,
   8904 		     IPPROTO_TCP,
   8905 		     0);
   8906 
   8907   if ( print_headers ) {
   8908     print_top_test_header("TCP Connect/Request/Response TEST",local_res,remote_res);
   8909   }
   8910 
   8911   /* initialize a few counters */
   8912 
   8913   nummessages	=	0;
   8914   bytes_xferd	=	0.0;
   8915   times_up 	= 	0;
   8916 
   8917   /* set-up the data buffers with the requested alignment and offset */
   8918   if (send_width == 0) send_width = 1;
   8919   if (recv_width == 0) recv_width = 1;
   8920 
   8921   send_ring = allocate_buffer_ring(send_width,
   8922 				   req_size,
   8923 				   local_send_align,
   8924 				   local_send_offset);
   8925 
   8926   recv_ring = allocate_buffer_ring(recv_width,
   8927 				   rsp_size,
   8928 				   local_recv_align,
   8929 				   local_recv_offset);
   8930 
   8931 
   8932   if (debug) {
   8933     fprintf(where,"send_tcp_conn_rr: send_socket obtained...\n");
   8934   }
   8935 
   8936   /* If the user has requested cpu utilization measurements, we must */
   8937   /* calibrate the cpu(s). We will perform this task within the tests */
   8938   /* themselves. If the user has specified the cpu rate, then */
   8939   /* calibrate_local_cpu will return rather quickly as it will have */
   8940   /* nothing to do. If local_cpu_rate is zero, then we will go through */
   8941   /* all the "normal" calibration stuff and return the rate back.*/
   8942 
   8943   if (local_cpu_usage) {
   8944     local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   8945   }
   8946 
   8947   if (!no_control) {
   8948 
   8949     /* Tell the remote end to do a listen. The server alters the
   8950        socket paramters on the other side at this point, hence the
   8951        reason for all the values being passed in the setup message. If
   8952        the user did not specify any of the parameters, they will be
   8953        passed as 0, which will indicate to the remote that no changes
   8954        beyond the system's default should be used. Alignment is the
   8955        exception, it will default to 8, which will be no alignment
   8956        alterations. */
   8957 
   8958     netperf_request.content.request_type =	DO_TCP_CRR;
   8959     tcp_conn_rr_request->recv_buf_size	=	rsr_size_req;
   8960     tcp_conn_rr_request->send_buf_size	=	rss_size_req;
   8961     tcp_conn_rr_request->recv_alignment	=	remote_recv_align;
   8962     tcp_conn_rr_request->recv_offset	=	remote_recv_offset;
   8963     tcp_conn_rr_request->send_alignment	=	remote_send_align;
   8964     tcp_conn_rr_request->send_offset	=	remote_send_offset;
   8965     tcp_conn_rr_request->request_size	=	req_size;
   8966     tcp_conn_rr_request->response_size	=	rsp_size;
   8967     tcp_conn_rr_request->no_delay	=	rem_nodelay;
   8968     tcp_conn_rr_request->measure_cpu	=	remote_cpu_usage;
   8969     tcp_conn_rr_request->cpu_rate	=	remote_cpu_rate;
   8970     tcp_conn_rr_request->so_rcvavoid	=	rem_rcvavoid;
   8971     tcp_conn_rr_request->so_sndavoid	=	rem_sndavoid;
   8972     if (test_time) {
   8973       tcp_conn_rr_request->test_length	=	test_time;
   8974     }
   8975     else {
   8976       tcp_conn_rr_request->test_length	=	test_trans * -1;
   8977     }
   8978     tcp_conn_rr_request->port           = atoi(remote_data_port);
   8979     tcp_conn_rr_request->ipfamily       = af_to_nf(remote_res->ai_family);
   8980 
   8981     if (debug > 1) {
   8982       fprintf(where,"netperf: send_tcp_conn_rr: requesting TCP crr test\n");
   8983     }
   8984 
   8985     send_request();
   8986 
   8987     /* The response from the remote will contain all of the relevant
   8988        socket parameters for this test type. We will put them back
   8989        into the variables here so they can be displayed if desired.
   8990        The remote will have calibrated CPU if necessary, and will have
   8991        done all the needed set-up we will have calibrated the cpu
   8992        locally before sending the request, and will grab the counter
   8993        value right after the connect returns. The remote will grab the
   8994        counter right after the accept call. This saves the hassle of
   8995        extra messages being sent for the TCP tests.  */
   8996 
   8997     recv_response();
   8998 
   8999     if (!netperf_response.content.serv_errno) {
   9000       rsr_size	       =	tcp_conn_rr_response->recv_buf_size;
   9001       rss_size	       =	tcp_conn_rr_response->send_buf_size;
   9002       rem_nodelay      =	tcp_conn_rr_response->no_delay;
   9003       remote_cpu_usage =	tcp_conn_rr_response->measure_cpu;
   9004       remote_cpu_rate  = 	tcp_conn_rr_response->cpu_rate;
   9005       /* make sure that port numbers are in network order */
   9006       set_port_number(remote_res,
   9007 		      (unsigned short)tcp_conn_rr_response->data_port_number);
   9008 
   9009       if (debug) {
   9010 	fprintf(where,"remote listen done.\n");
   9011 	fprintf(where,"remote port is %u\n",get_port_number(remote_res));
   9012 	fflush(where);
   9013       }
   9014     }
   9015     else {
   9016       Set_errno(netperf_response.content.serv_errno);
   9017       fprintf(where,
   9018 	      "netperf: remote error %d",
   9019 	      netperf_response.content.serv_errno);
   9020       perror("");
   9021       fflush(where);
   9022       exit(1);
   9023     }
   9024   }
   9025 #ifdef WANT_DEMO
   9026   demo_rr_setup(100);
   9027 #endif
   9028 
   9029   /* pick a nice random spot between client_port_min and */
   9030   /* client_port_max for our initial port number */
   9031   srand(getpid());
   9032   if (client_port_max - client_port_min) {
   9033     myport = client_port_min +
   9034       (rand() % (client_port_max - client_port_min));
   9035   }
   9036   else {
   9037     myport = client_port_min;
   9038   }
   9039   /* there will be a ++ before the first call to bind, so subtract one */
   9040   myport--;
   9041   /* Set-up the test end conditions. For a request/response test, they */
   9042   /* can be either time or transaction based. */
   9043 
   9044   if (test_time) {
   9045     /* The user wanted to end the test after a period of time. */
   9046     times_up = 0;
   9047     trans_remaining = 0;
   9048     start_timer(test_time);
   9049   }
   9050   else {
   9051     /* The tester wanted to send a number of bytes. */
   9052     trans_remaining = test_bytes;
   9053     times_up = 1;
   9054   }
   9055 
   9056   /* The cpu_start routine will grab the current time and possibly */
   9057   /* value of the idle counter for later use in measuring cpu */
   9058   /* utilization and/or service demand and thruput. */
   9059 
   9060 
   9061   cpu_start(local_cpu_usage);
   9062 
   9063 #ifdef WANT_DEMO
   9064       if (demo_mode) {
   9065 	demo_first_timestamp();
   9066       }
   9067 #endif
   9068 
   9069   /* We use an "OR" to control test execution. When the test is */
   9070   /* controlled by time, the byte count check will always return false. */
   9071   /* When the test is controlled by byte count, the time test will */
   9072   /* always return false. When the test is finished, the whole */
   9073   /* expression will go false and we will stop sending data. I think I */
   9074   /* just arbitrarily decrement trans_remaining for the timed test, but */
   9075   /* will not do that just yet... One other question is whether or not */
   9076   /* the send buffer and the receive buffer should be the same buffer. */
   9077 
   9078   while ((!times_up) || (trans_remaining > 0)) {
   9079 
   9080 #ifdef WANT_HISTOGRAM
   9081     if (verbosity > 1) {
   9082       /* timestamp just before our call to create the socket, and then */
   9083       /* again just after the receive raj 3/95 */
   9084       HIST_timestamp(&time_one);
   9085     }
   9086 #endif /* WANT_HISTOGRAM */
   9087 
   9088 newport:
   9089     /* pick a new port number */
   9090     myport++;
   9091 
   9092     /* wrap the port number when we get to client_port_max. NOTE, some */
   9093     /* broken TCP's might treat the port number as a signed 16 bit */
   9094     /* quantity.  we aren't interested in testing such broken */
   9095     /* implementations :) so we won't make sure that it is below 32767 */
   9096     /* raj 8/94  */
   9097     if (myport >= client_port_max) {
   9098       myport = client_port_min;
   9099     }
   9100 
   9101     /* we do not want to use the port number that the server is */
   9102     /* sitting at - this would cause us to fail in a loopback test. we */
   9103     /* could just rely on the failure of the bind to get us past this, */
   9104     /* but I'm guessing that in this one case at least, it is much */
   9105     /* faster, given that we *know* that port number is already in use */
   9106     /* (or rather would be in a loopback test) */
   9107 
   9108     if (myport == get_port_number(remote_res)) myport++;
   9109 
   9110     if (debug) {
   9111       if ((nummessages % 100) == 0) {
   9112 	printf("port %d\n",myport);
   9113       }
   9114     }
   9115 
   9116     /* set up the data socket */
   9117     set_port_number(local_res, (unsigned short)myport);
   9118     send_socket = create_data_socket(local_res);
   9119 
   9120     if (send_socket == INVALID_SOCKET) {
   9121       perror("netperf: send_tcp_conn_rr: tcp stream data socket");
   9122       exit(1);
   9123     }
   9124 
   9125 
   9126     /* we used to call bind here, but that is now taken-care-of by the
   9127        create_data_socket routine. */
   9128 
   9129     /* Connect up to the remote port on the data socket  */
   9130     if ((ret = connect(send_socket,
   9131 		       remote_res->ai_addr,
   9132 		       remote_res->ai_addrlen)) == INVALID_SOCKET){
   9133       if (SOCKET_EINTR(ret))
   9134 	  {
   9135 	    /* we hit the end of a */
   9136 	    /* timed test. */
   9137 	    timed_out = 1;
   9138 	    break;
   9139       }
   9140       if ((SOCKET_EADDRINUSE(ret)) || SOCKET_EADDRNOTAVAIL(ret)) {
   9141 	/* likely something our explicit bind() would have caught in
   9142            the past, so go get another port, via create_data_socket.
   9143            yes, this is a bit more overhead than before, but the
   9144            condition should be rather rare.  raj 2005-02-08 */
   9145 	close(send_socket);
   9146 	goto newport;
   9147       }
   9148       perror("netperf: data socket connect failed");
   9149       printf("\tattempted to connect on socket %d to port %d",
   9150 	     send_socket,
   9151 	     get_port_number(remote_res));
   9152       printf(" from port %d \n",get_port_number(local_res));
   9153       exit(1);
   9154     }
   9155 
   9156 
   9157     /* send the request */
   9158     if((len=send(send_socket,
   9159 		 send_ring->buffer_ptr,
   9160 		 req_size,
   9161 		 0)) != req_size) {
   9162       if (SOCKET_EINTR(len))
   9163 	  {
   9164 	    /* we hit the end of a */
   9165 	    /* timed test. */
   9166 	    timed_out = 1;
   9167 	    break;
   9168       }
   9169       perror("send_tcp_conn_rr: data send error");
   9170       exit(1);
   9171     }
   9172     send_ring = send_ring->next;
   9173 
   9174     /* receive the response */
   9175     rsp_bytes_left = rsp_size;
   9176     temp_message_ptr  = recv_ring->buffer_ptr;
   9177 
   9178 
   9179     do {
   9180       rsp_bytes_recvd = recv(send_socket,
   9181 			     temp_message_ptr,
   9182 			     rsp_bytes_left,
   9183 			     0);
   9184       if (rsp_bytes_recvd > 0) {
   9185 	rsp_bytes_left -= rsp_bytes_recvd;
   9186 	temp_message_ptr += rsp_bytes_recvd;
   9187       }
   9188       else {
   9189 	break;
   9190       }
   9191     } while (rsp_bytes_left);
   9192 
   9193 
   9194     /* OK, we are out of the loop - now what? */
   9195     if (rsp_bytes_recvd < 0) {
   9196       /* did the timer hit, or was there an error? */
   9197       if (SOCKET_EINTR(rsp_bytes_recvd))
   9198 	  {
   9199 	    /* We hit the end of a timed test. */
   9200 	    timed_out = 1;
   9201 	    break;
   9202 	  }
   9203 	  perror("send_tcp_conn_rr: data recv error");
   9204 	  exit(1);
   9205     }
   9206 
   9207     /* if this is a no_control test, we initiate connection close,
   9208        otherwise the remote netserver does it to remain just like
   9209        previous behaviour. raj 2007-27-08 */
   9210     if (!no_control) {
   9211       shutdown(send_socket,SHUT_WR);
   9212     }
   9213 
   9214     /* we are expecting to get either a return of zero indicating
   9215        connection close, or an error.  */
   9216     rsp_bytes_recvd = recv(send_socket,
   9217 			   temp_message_ptr,
   9218 			   1,
   9219 			   0);
   9220 
   9221     /* our exit from the while loop should generally be when */
   9222     /* tmp_bytes_recvd is equal to zero, which implies the connection */
   9223     /* has been closed by the server side. By waiting until we get the */
   9224     /* zero return we can avoid race conditions that stick us with the */
   9225     /* TIME_WAIT connection and not the server. raj 8/96 */
   9226 
   9227 #ifdef VMWARE_UW
   9228     /* why this should be for VMware I'm not sure, but it was given as
   9229        part of the patches, so we include it here, but put it under an
   9230        ifdef VMWARE_UW. raj 2008-07-25 */
   9231     if (sp_bytes_recvd < 0 && errno == ECONNRESET) {
   9232       rsp_bytes_recvd = 0;
   9233     }
   9234 #endif /* VMWARE_UW */
   9235 
   9236     if (rsp_bytes_recvd == 0) {
   9237       /* connection close, call close. we assume that the requisite */
   9238       /* number of bytes have been received */
   9239       recv_ring = recv_ring->next;
   9240 
   9241 #ifdef WANT_HISTOGRAM
   9242       if (verbosity > 1) {
   9243 	HIST_timestamp(&time_two);
   9244 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   9245       }
   9246 #endif /* WANT_HISTOGRAM */
   9247 
   9248 #ifdef WANT_DEMO
   9249       demo_rr_interval(1);
   9250 #endif
   9251 
   9252       nummessages++;
   9253       if (trans_remaining) {
   9254 	trans_remaining--;
   9255       }
   9256 
   9257       if (debug > 3) {
   9258 	fprintf(where,
   9259 		"Transaction %d completed on local port %d\n",
   9260 		nummessages,
   9261 		get_port_number(local_res));
   9262 	fflush(where);
   9263       }
   9264 
   9265       close(send_socket);
   9266 
   9267     }
   9268     else {
   9269       /* it was less than zero - an error occured */
   9270       if (SOCKET_EINTR(rsp_bytes_recvd))
   9271 	  {
   9272 	    /* We hit the end of a timed test. */
   9273 	    timed_out = 1;
   9274 	    break;
   9275 	  }
   9276 	  perror("send_tcp_conn_rr: data recv error");
   9277 	  exit(1);
   9278     }
   9279 
   9280   }
   9281 
   9282 
   9283   /* this call will always give us the elapsed time for the test, and */
   9284   /* will also store-away the necessaries for cpu utilization */
   9285 
   9286   cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being measured? */
   9287   /* how long did we really run? */
   9288 
   9289   if (!no_control) {
   9290     /* Get the statistics from the remote end. The remote will have
   9291        calculated service demand and all those interesting things. If
   9292        it wasn't supposed to care, it will return obvious values. */
   9293 
   9294     recv_response();
   9295     if (!netperf_response.content.serv_errno) {
   9296       if (debug)
   9297 	fprintf(where,"remote results obtained\n");
   9298     }
   9299     else {
   9300       Set_errno(netperf_response.content.serv_errno);
   9301       fprintf(where,
   9302 	      "netperf: remote error %d",
   9303 	      netperf_response.content.serv_errno);
   9304       perror("");
   9305       fflush(where);
   9306 
   9307       exit(1);
   9308     }
   9309   }
   9310 
   9311   /* We now calculate what our thruput was for the test. In the future, */
   9312   /* we may want to include a calculation of the thruput measured by */
   9313   /* the remote, but it should be the case that for a TCP stream test, */
   9314   /* that the two numbers should be *very* close... We calculate */
   9315   /* bytes_sent regardless of the way the test length was controlled. */
   9316   /* If it was time, we needed to, and if it was by bytes, the user may */
   9317   /* have specified a number of bytes that wasn't a multiple of the */
   9318   /* send_size, so we really didn't send what he asked for ;-) We use */
   9319   /* Kbytes/s as the units of thruput for a TCP stream test, where K = */
   9320   /* 1024. A future enhancement *might* be to choose from a couple of */
   9321   /* unit selections. */
   9322 
   9323   bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
   9324   thruput	= calc_thruput(bytes_xferd);
   9325 
   9326   if (local_cpu_usage || remote_cpu_usage) {
   9327     /* We must now do a little math for service demand and cpu */
   9328     /* utilization for the system(s) */
   9329     /* Of course, some of the information might be bogus because */
   9330     /* there was no idle counter in the kernel(s). We need to make */
   9331     /* a note of this for the user's benefit...*/
   9332     if (local_cpu_usage) {
   9333       if (local_cpu_rate == 0.0) {
   9334 	fprintf(where,
   9335 		"WARNING WARNING WARNING  WARNING WARNING WARNING  WARNING!\n");
   9336 	fprintf(where,
   9337 		"Local CPU usage numbers based on process information only!\n");
   9338 	fflush(where);
   9339       }
   9340       local_cpu_utilization = calc_cpu_util(0.0);
   9341       /* since calc_service demand is doing ms/Kunit we will */
   9342       /* multiply the number of transaction by 1024 to get */
   9343       /* "good" numbers */
   9344       local_service_demand  = calc_service_demand((double) nummessages*1024,
   9345 						  0.0,
   9346 						  0.0,
   9347 						  0);
   9348     }
   9349     else {
   9350       local_cpu_utilization	= (float) -1.0;
   9351       local_service_demand	= (float) -1.0;
   9352     }
   9353 
   9354     if (remote_cpu_usage) {
   9355       if (remote_cpu_rate == 0.0) {
   9356 	fprintf(where,
   9357 		"DANGER  DANGER  DANGER    DANGER  DANGER  DANGER    DANGER!\n");
   9358 	fprintf(where,
   9359 		"Remote CPU usage numbers based on process information only!\n");
   9360 	fflush(where);
   9361       }
   9362       remote_cpu_utilization = tcp_conn_rr_result->cpu_util;
   9363       /* since calc_service demand is doing ms/Kunit we will */
   9364       /* multiply the number of transaction by 1024 to get */
   9365       /* "good" numbers */
   9366       remote_service_demand = calc_service_demand((double) nummessages*1024,
   9367 						  0.0,
   9368 						  remote_cpu_utilization,
   9369 						  tcp_conn_rr_result->num_cpus);
   9370     }
   9371     else {
   9372       remote_cpu_utilization = (float) -1.0;
   9373       remote_service_demand  = (float) -1.0;
   9374     }
   9375 
   9376     /* We are now ready to print all the information. If the user */
   9377     /* has specified zero-level verbosity, we will just print the */
   9378     /* local service demand, or the remote service demand. If the */
   9379     /* user has requested verbosity level 1, he will get the basic */
   9380     /* "streamperf" numbers. If the user has specified a verbosity */
   9381     /* of greater than 1, we will display a veritable plethora of */
   9382     /* background information from outside of this block as it it */
   9383     /* not cpu_measurement specific...  */
   9384 
   9385     switch (verbosity) {
   9386     case 0:
   9387       if (local_cpu_usage) {
   9388 	fprintf(where,
   9389 		cpu_fmt_0,
   9390 		local_service_demand);
   9391       }
   9392       else {
   9393 	fprintf(where,
   9394 		cpu_fmt_0,
   9395 		remote_service_demand);
   9396       }
   9397       break;
   9398     case 1:
   9399     case 2:
   9400 
   9401       if (print_headers) {
   9402 	fprintf(where,
   9403 		cpu_title,
   9404 		local_cpu_method,
   9405 		remote_cpu_method);
   9406       }
   9407 
   9408       fprintf(where,
   9409 	      cpu_fmt_1_line_1,		/* the format string */
   9410 	      lss_size,		/* local sendbuf size */
   9411 	      lsr_size,
   9412 	      req_size,		/* how large were the requests */
   9413 	      rsp_size,		/* guess */
   9414 	      elapsed_time,		/* how long was the test */
   9415 	      nummessages/elapsed_time,
   9416 	      local_cpu_utilization,	/* local cpu */
   9417 	      remote_cpu_utilization,	/* remote cpu */
   9418 	      local_service_demand,	/* local service demand */
   9419 	      remote_service_demand);	/* remote service demand */
   9420       fprintf(where,
   9421 	      cpu_fmt_1_line_2,
   9422 	      rss_size,
   9423 	      rsr_size);
   9424       break;
   9425     }
   9426   }
   9427   else {
   9428     /* The tester did not wish to measure service demand. */
   9429     switch (verbosity) {
   9430     case 0:
   9431       fprintf(where,
   9432 	      tput_fmt_0,
   9433 	      nummessages/elapsed_time);
   9434       break;
   9435     case 1:
   9436     case 2:
   9437       if (print_headers) {
   9438 	fprintf(where,tput_title,format_units());
   9439       }
   9440 
   9441       fprintf(where,
   9442 	      tput_fmt_1_line_1,	/* the format string */
   9443 	      lss_size,
   9444 	      lsr_size,
   9445 	      req_size,		/* how large were the requests */
   9446 	      rsp_size,		/* how large were the responses */
   9447 	      elapsed_time, 		/* how long did it take */
   9448 	      nummessages/elapsed_time);
   9449       fprintf(where,
   9450 	      tput_fmt_1_line_2,
   9451 	      rss_size, 		/* remote recvbuf size */
   9452 	      rsr_size);
   9453 
   9454       break;
   9455     }
   9456   }
   9457 
   9458   /* it would be a good thing to include information about some of the */
   9459   /* other parameters that may have been set for this test, but at the */
   9460   /* moment, I do not wish to figure-out all the  formatting, so I will */
   9461   /* just put this comment here to help remind me that it is something */
   9462   /* that should be done at a later time. */
   9463 
   9464   if (verbosity > 1) {
   9465     /* The user wanted to know it all, so we will give it to him. */
   9466     /* This information will include as much as we can find about */
   9467     /* TCP statistics, the alignments of the sends and receives */
   9468     /* and all that sort of rot... */
   9469 
   9470     fprintf(where,
   9471 	    ksink_fmt,
   9472 	    local_send_align,
   9473 	    remote_recv_offset,
   9474 	    local_send_offset,
   9475 	    remote_recv_offset);
   9476 
   9477 #ifdef WANT_HISTOGRAM
   9478     fprintf(where,"\nHistogram of request/response times\n");
   9479     fflush(where);
   9480     HIST_report(time_hist);
   9481 #endif /* WANT_HISTOGRAM */
   9482 
   9483   }
   9484 
   9485 }
   9486 #endif /* WANT_MIGRATION */
   9487 
   9488 void
   9490 recv_tcp_conn_rr()
   9491 {
   9492 
   9493   char  *message;
   9494   struct addrinfo *local_res;
   9495   char local_name[BUFSIZ];
   9496   char port_buffer[PORTBUFSIZE];
   9497 
   9498   struct	sockaddr_storage        myaddr_in, peeraddr_in;
   9499   SOCKET	s_listen,s_data;
   9500   netperf_socklen_t 	addrlen;
   9501   char	*recv_message_ptr;
   9502   char	*send_message_ptr;
   9503   char	*temp_message_ptr;
   9504   int	trans_received;
   9505   int	trans_remaining;
   9506   int	bytes_sent;
   9507   int	request_bytes_recvd;
   9508   int	request_bytes_remaining;
   9509   int	timed_out = 0;
   9510   float	elapsed_time;
   9511 
   9512   struct	tcp_conn_rr_request_struct	*tcp_conn_rr_request;
   9513   struct	tcp_conn_rr_response_struct	*tcp_conn_rr_response;
   9514   struct	tcp_conn_rr_results_struct	*tcp_conn_rr_results;
   9515 
   9516   tcp_conn_rr_request =
   9517     (struct tcp_conn_rr_request_struct *)netperf_request.content.test_specific_data;
   9518   tcp_conn_rr_response =
   9519     (struct tcp_conn_rr_response_struct *)netperf_response.content.test_specific_data;
   9520   tcp_conn_rr_results =
   9521     (struct tcp_conn_rr_results_struct *)netperf_response.content.test_specific_data;
   9522 
   9523   if (debug) {
   9524     fprintf(where,"netserver: recv_tcp_conn_rr: entered...\n");
   9525     fflush(where);
   9526   }
   9527 
   9528   /* We want to set-up the listen socket with all the desired */
   9529   /* parameters and then let the initiator know that all is ready. If */
   9530   /* socket size defaults are to be used, then the initiator will have */
   9531   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   9532   /* send-back what they are. If that information cannot be determined, */
   9533   /* then we send-back -1's for the sizes. If things go wrong for any */
   9534   /* reason, we will drop back ten yards and punt. */
   9535 
   9536   /* If anything goes wrong, we want the remote to know about it. It */
   9537   /* would be best if the error that the remote reports to the user is */
   9538   /* the actual error we encountered, rather than some bogus unexpected */
   9539   /* response type message. */
   9540 
   9541   if (debug) {
   9542     fprintf(where,"recv_tcp_conn_rr: setting the response type...\n");
   9543     fflush(where);
   9544   }
   9545 
   9546   netperf_response.content.response_type = TCP_CRR_RESPONSE;
   9547 
   9548   if (debug) {
   9549     fprintf(where,"recv_tcp_conn_rr: the response type is set...\n");
   9550     fflush(where);
   9551   }
   9552 
   9553   /* set-up the data buffer with the requested alignment and offset */
   9554   message = (char *)malloc(DATABUFFERLEN);
   9555   if (message == NULL) {
   9556     printf("malloc(%d) failed!\n", DATABUFFERLEN);
   9557     exit(1);
   9558   }
   9559 
   9560   /* We now alter the message_ptr variables to be at the desired */
   9561   /* alignments with the desired offsets. */
   9562 
   9563   if (debug) {
   9564     fprintf(where,
   9565 	    "recv_tcp_conn_rr: requested recv alignment of %d offset %d\n",
   9566 	    tcp_conn_rr_request->recv_alignment,
   9567 	    tcp_conn_rr_request->recv_offset);
   9568     fprintf(where,
   9569 	    "recv_tcp_conn_rr: requested send alignment of %d offset %d\n",
   9570 	    tcp_conn_rr_request->send_alignment,
   9571 	    tcp_conn_rr_request->send_offset);
   9572     fflush(where);
   9573   }
   9574 
   9575   recv_message_ptr = ALIGN_BUFFER(message, tcp_conn_rr_request->recv_alignment, tcp_conn_rr_request->recv_offset);
   9576 
   9577   send_message_ptr = ALIGN_BUFFER(message, tcp_conn_rr_request->send_alignment, tcp_conn_rr_request->send_offset);
   9578 
   9579   if (debug) {
   9580     fprintf(where,"recv_tcp_conn_rr: receive alignment and offset set...\n");
   9581     fflush(where);
   9582   }
   9583 
   9584   /* Grab a socket to listen on, and then listen on it. */
   9585 
   9586   if (debug) {
   9587     fprintf(where,"recv_tcp_conn_rr: grabbing a socket...\n");
   9588     fflush(where);
   9589   }
   9590 
   9591   /* create_data_socket expects to find some things in the global */
   9592   /* variables, so set the globals based on the values in the request. */
   9593   /* once the socket has been created, we will set the response values */
   9594   /* based on the updated value of those globals. raj 7/94 */
   9595   lss_size_req = tcp_conn_rr_request->send_buf_size;
   9596   lsr_size_req = tcp_conn_rr_request->recv_buf_size;
   9597   loc_nodelay = tcp_conn_rr_request->no_delay;
   9598   loc_rcvavoid = tcp_conn_rr_request->so_rcvavoid;
   9599   loc_sndavoid = tcp_conn_rr_request->so_sndavoid;
   9600 
   9601   set_hostname_and_port(local_name,
   9602 			port_buffer,
   9603 			nf_to_af(tcp_conn_rr_request->ipfamily),
   9604 			tcp_conn_rr_request->port);
   9605 
   9606   local_res = complete_addrinfo(local_name,
   9607 				local_name,
   9608 				port_buffer,
   9609 				nf_to_af(tcp_conn_rr_request->ipfamily),
   9610 				SOCK_STREAM,
   9611 				IPPROTO_TCP,
   9612 				0);
   9613 
   9614   s_listen = create_data_socket(local_res);
   9615 
   9616   if (s_listen == INVALID_SOCKET) {
   9617     netperf_response.content.serv_errno = errno;
   9618     send_response();
   9619     if (debug) {
   9620       fprintf(where,"could not create data socket\n");
   9621       fflush(where);
   9622     }
   9623     exit(1);
   9624   }
   9625 
   9626 #ifdef WIN32
   9627     /* The test timer can fire during operations on the listening socket,
   9628        so to make the start_timer below work we have to move
   9629        it to close s_listen while we are blocked on accept. */
   9630     win_kludge_socket2 = s_listen;
   9631 #endif
   9632 
   9633 
   9634   /* Now, let's set-up the socket to listen for connections */
   9635   if (listen(s_listen, 128) == SOCKET_ERROR) {
   9636     netperf_response.content.serv_errno = errno;
   9637     close(s_listen);
   9638     send_response();
   9639     if (debug) {
   9640       fprintf(where,"could not listen\n");
   9641       fflush(where);
   9642     }
   9643     exit(1);
   9644   }
   9645 
   9646   /* now get the port number assigned by the system  */
   9647   addrlen = sizeof(myaddr_in);
   9648   if (getsockname(s_listen,
   9649 		  (struct sockaddr *)&myaddr_in,
   9650 		  &addrlen) == SOCKET_ERROR){
   9651     netperf_response.content.serv_errno = errno;
   9652     close(s_listen);
   9653     send_response();
   9654     if (debug) {
   9655       fprintf(where,"could not getsockname\n");
   9656       fflush(where);
   9657     }
   9658     exit(1);
   9659   }
   9660 
   9661   /* Now myaddr_in contains the port and the internet address this is */
   9662   /* returned to the sender also implicitly telling the sender that the */
   9663   /* socket buffer sizing has been done. */
   9664 
   9665   tcp_conn_rr_response->data_port_number =
   9666     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
   9667   if (debug) {
   9668     fprintf(where,"telling the remote to call me at %d\n",
   9669 	    tcp_conn_rr_response->data_port_number);
   9670     fflush(where);
   9671   }
   9672   netperf_response.content.serv_errno   = 0;
   9673 
   9674   /* But wait, there's more. If the initiator wanted cpu measurements, */
   9675   /* then we must call the calibrate routine, which will return the max */
   9676   /* rate back to the initiator. If the CPU was not to be measured, or */
   9677   /* something went wrong with the calibration, we will return a 0.0 to */
   9678   /* the initiator. */
   9679 
   9680   tcp_conn_rr_response->cpu_rate = (float)0.0; 	/* assume no cpu */
   9681   if (tcp_conn_rr_request->measure_cpu) {
   9682     tcp_conn_rr_response->measure_cpu = 1;
   9683     tcp_conn_rr_response->cpu_rate =
   9684       calibrate_local_cpu(tcp_conn_rr_request->cpu_rate);
   9685   }
   9686 
   9687 
   9688 
   9689   /* before we send the response back to the initiator, pull some of */
   9690   /* the socket parms from the globals */
   9691   tcp_conn_rr_response->send_buf_size = lss_size;
   9692   tcp_conn_rr_response->recv_buf_size = lsr_size;
   9693   tcp_conn_rr_response->no_delay = loc_nodelay;
   9694   tcp_conn_rr_response->so_rcvavoid = loc_rcvavoid;
   9695   tcp_conn_rr_response->so_sndavoid = loc_sndavoid;
   9696 
   9697   send_response();
   9698 
   9699   addrlen = sizeof(peeraddr_in);
   9700 
   9701   /* Now it's time to start receiving data on the connection. We will */
   9702   /* first grab the apropriate counters and then start grabbing. */
   9703 
   9704   cpu_start(tcp_conn_rr_request->measure_cpu);
   9705 
   9706   /* The loop will exit when the sender does a shutdown, which will */
   9707   /* return a length of zero   */
   9708 
   9709   if (tcp_conn_rr_request->test_length > 0) {
   9710     times_up = 0;
   9711     trans_remaining = 0;
   9712     start_timer(tcp_conn_rr_request->test_length + PAD_TIME);
   9713   }
   9714   else {
   9715     times_up = 1;
   9716     trans_remaining = tcp_conn_rr_request->test_length * -1;
   9717   }
   9718 
   9719   trans_received = 0;
   9720 
   9721   while ((!times_up) || (trans_remaining > 0)) {
   9722 
   9723     /* accept a connection from the remote */
   9724 #ifdef WIN32
   9725     /* The test timer will probably fire during this accept,
   9726        so to make the start_timer above work we have to move
   9727        it to close s_listen while we are blocked on accept. */
   9728     win_kludge_socket = s_listen;
   9729 #endif
   9730     if ((s_data=accept(s_listen,
   9731 		       (struct sockaddr *)&peeraddr_in,
   9732 		       &addrlen)) == INVALID_SOCKET) {
   9733       if (errno == EINTR) {
   9734 	/* the timer popped */
   9735 	timed_out = 1;
   9736 	break;
   9737       }
   9738       fprintf(where,"recv_tcp_conn_rr: accept: errno = %d\n",errno);
   9739       fflush(where);
   9740       close(s_listen);
   9741 
   9742       exit(1);
   9743     }
   9744 
   9745     if (debug) {
   9746       fprintf(where,"recv_tcp_conn_rr: accepted data connection.\n");
   9747       fflush(where);
   9748     }
   9749 
   9750 #ifdef WIN32
   9751   /* this is used so the timer thread can close the socket out from */
   9752   /* under us, which to date is the easiest/cleanest/least */
   9753   /* Windows-specific way I can find to force the winsock calls to */
   9754   /* return WSAEINTR with the test is over. anything that will run on */
   9755   /* 95 and NT and is closer to what netperf expects from Unix signals */
   9756   /* and such would be appreciated raj 1/96 */
   9757   win_kludge_socket = s_data;
   9758 #endif /* WIN32 */
   9759 
   9760 #ifdef KLUDGE_SOCKET_OPTIONS
   9761     /* this is for those systems which *INCORRECTLY* fail to pass */
   9762     /* attributes across an accept() call. Including this goes against */
   9763     /* my better judgement :( raj 11/95 */
   9764 
   9765     kludge_socket_options(s_data);
   9766 
   9767 #endif /* KLUDGE_SOCKET_OPTIONS */
   9768 
   9769     temp_message_ptr	= recv_message_ptr;
   9770     request_bytes_remaining	= tcp_conn_rr_request->request_size;
   9771 
   9772     /* receive the request from the other side */
   9773     while (!times_up && (request_bytes_remaining > 0)) {
   9774       if((request_bytes_recvd=recv(s_data,
   9775 				   temp_message_ptr,
   9776 				   request_bytes_remaining,
   9777 				   0)) == SOCKET_ERROR) {
   9778 	if (SOCKET_EINTR(request_bytes_recvd))
   9779 	{
   9780 	  /* the timer popped */
   9781 	  timed_out = 1;
   9782 	  break;
   9783 	}
   9784 	netperf_response.content.serv_errno = errno;
   9785 	send_response();
   9786 	exit(1);
   9787       }
   9788       else if (request_bytes_recvd > 0) {
   9789 	request_bytes_remaining -= request_bytes_recvd;
   9790 	temp_message_ptr  += request_bytes_recvd;
   9791       }
   9792       else {
   9793       	/* for some reason the remote closed the connection on
   9794 	 * us and that is unexpected so we should just close the
   9795 	 * socket and move-on. for that we will use an evil goto
   9796 	 * neener neener raj 20090622 */
   9797     	goto bail;
   9798       }
   9799     }
   9800 
   9801     if (timed_out) {
   9802       /* we hit the end of the test based on time - lets */
   9803       /* bail out of here now... */
   9804       fprintf(where,"yo5\n");
   9805       fflush(where);
   9806       break;
   9807     }
   9808 
   9809     /* Now, send the response to the remote */
   9810     if((bytes_sent=send(s_data,
   9811 			send_message_ptr,
   9812 			tcp_conn_rr_request->response_size,
   9813 			0)) == SOCKET_ERROR) {
   9814       if (errno == EINTR) {
   9815 	/* the test timer has popped */
   9816 	timed_out = 1;
   9817 	fprintf(where,"yo6\n");
   9818 	fflush(where);
   9819 	break;
   9820       }
   9821       netperf_response.content.serv_errno = 99;
   9822       send_response();
   9823       exit(1);
   9824     }
   9825 
   9826     trans_received++;
   9827     if (trans_remaining) {
   9828       trans_remaining--;
   9829     }
   9830 
   9831     if (debug) {
   9832       fprintf(where,
   9833 	      "recv_tcp_conn_rr: Transaction %d complete\n",
   9834 	      trans_received);
   9835       fflush(where);
   9836     }
   9837 
   9838     /* close the connection. the server will likely do a graceful */
   9839     /* close of the connection, insuring that all data has arrived at */
   9840     /* the client. for this it will call shutdown(), and then recv() and */
   9841     /* then close(). I'm reasonably confident that this is the */
   9842     /* appropriate sequence of calls - I would like to hear of */
   9843     /* examples in web servers to the contrary. raj 10/95*/
   9844 #ifdef TCP_CRR_SHUTDOWN
   9845     shutdown(s_data,SHUT_WR);
   9846     recv(s_data,
   9847 	 recv_message_ptr,
   9848 	 1,
   9849 	 0);
   9850 bail:
   9851     close(s_data);
   9852 #else
   9853 bail:
   9854     close(s_data);
   9855 #endif /* TCP_CRR_SHUTDOWN */
   9856 
   9857   }
   9858 
   9859 
   9860   /* The loop now exits due to timeout or transaction count being */
   9861   /* reached */
   9862 
   9863   cpu_stop(tcp_conn_rr_request->measure_cpu,&elapsed_time);
   9864 
   9865   if (timed_out) {
   9866     /* we ended the test by time, which was at least 2 seconds */
   9867     /* longer than we wanted to run. so, we want to subtract */
   9868     /* PAD_TIME from the elapsed_time. */
   9869     elapsed_time -= PAD_TIME;
   9870   }
   9871   /* send the results to the sender			*/
   9872 
   9873   if (debug) {
   9874     fprintf(where,
   9875 	    "recv_tcp_conn_rr: got %d transactions\n",
   9876 	    trans_received);
   9877     fflush(where);
   9878   }
   9879 
   9880   tcp_conn_rr_results->bytes_received	= (trans_received *
   9881 					   (tcp_conn_rr_request->request_size +
   9882 					    tcp_conn_rr_request->response_size));
   9883   tcp_conn_rr_results->trans_received	= trans_received;
   9884   tcp_conn_rr_results->elapsed_time	= elapsed_time;
   9885   if (tcp_conn_rr_request->measure_cpu) {
   9886     tcp_conn_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
   9887   }
   9888 
   9889   if (debug) {
   9890     fprintf(where,
   9891 	    "recv_tcp_conn_rr: test complete, sending results.\n");
   9892     fflush(where);
   9893   }
   9894 
   9895   send_response();
   9896 
   9897 }
   9898 
   9899 
   9901 #ifdef DO_1644
   9902 
   9903  /* this test is intended to test the performance of establishing a */
   9904  /* connection, exchanging a request/response pair, and repeating. it */
   9905  /* is expected that this would be a good starting-point for */
   9906  /* comparision of T/TCP with classic TCP for transactional workloads. */
   9907  /* it will also look (can look) much like the communication pattern */
   9908  /* of http for www access. */
   9909 
   9910 int
   9911 send_tcp_tran_rr(char remote_host[])
   9912 {
   9913 
   9914   char *tput_title = "\
   9915 Local /Remote\n\
   9916 Socket Size   Request  Resp.   Elapsed  Trans.\n\
   9917 Send   Recv   Size     Size    Time     Rate         \n\
   9918 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
   9919 
   9920   char *tput_fmt_0 =
   9921     "%7.2f\n";
   9922 
   9923   char *tput_fmt_1_line_1 = "\
   9924 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
   9925   char *tput_fmt_1_line_2 = "\
   9926 %-6d %-6d\n";
   9927 
   9928   char *cpu_title = "\
   9929 Local /Remote\n\
   9930 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
   9931 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
   9932 bytes  bytes  bytes   bytes  secs.   per sec  %%      %%      us/Tr   us/Tr\n\n";
   9933 
   9934   char *cpu_fmt_0 =
   9935     "%6.3f\n";
   9936 
   9937   char *cpu_fmt_1_line_1 = "\
   9938 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f\n";
   9939 
   9940   char *cpu_fmt_1_line_2 = "\
   9941 %-6d %-6d\n";
   9942 
   9943   char *ksink_fmt = "\n\
   9944 Alignment      Offset\n\
   9945 Local  Remote  Local  Remote\n\
   9946 Send   Recv    Send   Recv\n\
   9947 %5d  %5d   %5d  %5d\n";
   9948 
   9949 
   9950   int 			one = 1;
   9951   int			timed_out = 0;
   9952   float			elapsed_time;
   9953 
   9954   int	len;
   9955   struct ring_elt *send_ring;
   9956   struct ring_elt *recv_ring;
   9957   char	*temp_message_ptr;
   9958   int	nummessages;
   9959   SOCKET	send_socket;
   9960   int	trans_remaining;
   9961   double	bytes_xferd;
   9962   int	sock_opt_len = sizeof(int);
   9963   int	rsp_bytes_left;
   9964   int	rsp_bytes_recvd;
   9965 
   9966   float	local_cpu_utilization;
   9967   float	local_service_demand;
   9968   float	remote_cpu_utilization;
   9969   float	remote_service_demand;
   9970   double	thruput;
   9971 
   9972   struct	hostent	        *hp;
   9973   struct	sockaddr_in	server;
   9974   struct        sockaddr_in     *myaddr;
   9975   unsigned      int             addr;
   9976   int                           myport;
   9977 
   9978   struct	tcp_tran_rr_request_struct	*tcp_tran_rr_request;
   9979   struct	tcp_tran_rr_response_struct	*tcp_tran_rr_response;
   9980   struct	tcp_tran_rr_results_struct	*tcp_tran_rr_result;
   9981 
   9982   tcp_tran_rr_request =
   9983     (struct tcp_tran_rr_request_struct *)netperf_request.content.test_specific_data;
   9984   tcp_tran_rr_response =
   9985     (struct tcp_tran_rr_response_struct *)netperf_response.content.test_specific_data;
   9986   tcp_tran_rr_result =
   9987     (struct tcp_tran_rr_results_struct *)netperf_response.content.test_specific_data;
   9988 
   9989 
   9990 #ifdef WANT_HISTOGRAM
   9991   if (verbosity > 1) {
   9992     time_hist = HIST_new();
   9993   }
   9994 #endif /* WANT_HISTOGRAM */
   9995 
   9996   /* since we are now disconnected from the code that established the */
   9997   /* control socket, and since we want to be able to use different */
   9998   /* protocols and such, we are passed the name of the remote host and */
   9999   /* must turn that into the test specific addressing information. */
   10000 
   10001   myaddr = (struct sockaddr_storage *)malloc(sizeof(struct sockaddr_storage));
   10002   if (myaddr == NULL) {
   10003     printf("malloc(%d) failed!\n", sizeof(struct sockaddr_storage));
   10004     exit(1);
   10005   }
   10006 
   10007   bzero((char *)&server,
   10008 	sizeof(server));
   10009   bzero((char *)myaddr,
   10010 	sizeof(struct sockaddr_storage));
   10011   myaddr->sin_family = AF_INET;
   10012 
   10013   complete_addrinfos(&remote_res,
   10014 		     &local_res,
   10015 		     remote_host,
   10016 		     SOCK_STREAM,
   10017 		     IPPROTO_TCP,
   10018 		     0);
   10019 
   10020   if ( print_headers ) {
   10021     print_top_test_header("TCP Transactional/Request/Response TEST",local_res,remote_res);
   10022   }
   10023 
   10024   /* initialize a few counters */
   10025 
   10026   nummessages	=	0;
   10027   bytes_xferd	=	0.0;
   10028   times_up 	= 	0;
   10029 
   10030   /* set-up the data buffers with the requested alignment and offset */
   10031   if (send_width == 0) send_width = 1;
   10032   if (recv_width == 0) recv_width = 1;
   10033 
   10034   send_ring = allocate_buffer_ring(send_width,
   10035 				   req_size,
   10036 				   local_send_align,
   10037 				   local_send_offset);
   10038 
   10039   recv_ring = allocate_buffer_ring(recv_width,
   10040 				   rsp_size,
   10041 				   local_recv_align,
   10042 				   local_recv_offset);
   10043 
   10044 
   10045   if (debug) {
   10046     fprintf(where,"send_tcp_tran_rr: send_socket obtained...\n");
   10047   }
   10048 
   10049   /* If the user has requested cpu utilization measurements, we must */
   10050   /* calibrate the cpu(s). We will perform this task within the tests */
   10051   /* themselves. If the user has specified the cpu rate, then */
   10052   /* calibrate_local_cpu will return rather quickly as it will have */
   10053   /* nothing to do. If local_cpu_rate is zero, then we will go through */
   10054   /* all the "normal" calibration stuff and return the rate back.*/
   10055 
   10056   if (local_cpu_usage) {
   10057     local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   10058   }
   10059 
   10060   /* Tell the remote end to do a listen. The server alters the socket */
   10061   /* paramters on the other side at this point, hence the reason for */
   10062   /* all the values being passed in the setup message. If the user did */
   10063   /* not specify any of the parameters, they will be passed as 0, which */
   10064   /* will indicate to the remote that no changes beyond the system's */
   10065   /* default should be used. Alignment is the exception, it will */
   10066   /* default to 8, which will be no alignment alterations. */
   10067 
   10068   netperf_request.content.request_type	        =	DO_TCP_TRR;
   10069   tcp_tran_rr_request->recv_buf_size	=	rsr_size_req;
   10070   tcp_tran_rr_request->send_buf_size	=	rss_size_req;
   10071   tcp_tran_rr_request->recv_alignment	=	remote_recv_align;
   10072   tcp_tran_rr_request->recv_offset	=	remote_recv_offset;
   10073   tcp_tran_rr_request->send_alignment	=	remote_send_align;
   10074   tcp_tran_rr_request->send_offset	=	remote_send_offset;
   10075   tcp_tran_rr_request->request_size	=	req_size;
   10076   tcp_tran_rr_request->response_size	=	rsp_size;
   10077   tcp_tran_rr_request->no_delay	        =	rem_nodelay;
   10078   tcp_tran_rr_request->measure_cpu	=	remote_cpu_usage;
   10079   tcp_tran_rr_request->cpu_rate	        =	remote_cpu_rate;
   10080   tcp_tran_rr_request->so_rcvavoid	=	rem_rcvavoid;
   10081   tcp_tran_rr_request->so_sndavoid	=	rem_sndavoid;
   10082   if (test_time) {
   10083     tcp_tran_rr_request->test_length	=	test_time;
   10084   }
   10085   else {
   10086     tcp_tran_rr_request->test_length	=	test_trans * -1;
   10087   }
   10088   tcp_tran_rr_request->port             =       atoi(remote_data_port);
   10089   tcp_tran_rr_request->ipfamily        =       af_to_nf(remote_res->ai_family);
   10090 
   10091   if (debug > 1) {
   10092     fprintf(where,"netperf: send_tcp_tran_rr: requesting TCP_TRR test\n");
   10093   }
   10094 
   10095   send_request();
   10096 
   10097   /* The response from the remote will contain all of the relevant 	*/
   10098   /* socket parameters for this test type. We will put them back into 	*/
   10099   /* the variables here so they can be displayed if desired.  The	*/
   10100   /* remote will have calibrated CPU if necessary, and will have done	*/
   10101   /* all the needed set-up we will have calibrated the cpu locally	*/
   10102   /* before sending the request, and will grab the counter value right	*/
   10103   /* after the connect returns. The remote will grab the counter right	*/
   10104   /* after the accept call. This saves the hassle of extra messages	*/
   10105   /* being sent for the TCP tests.					*/
   10106 
   10107   recv_response();
   10108 
   10109   if (!netperf_response.content.serv_errno) {
   10110     rsr_size	=	tcp_tran_rr_response->recv_buf_size;
   10111     rss_size	=	tcp_tran_rr_response->send_buf_size;
   10112     rem_nodelay	=	tcp_tran_rr_response->no_delay;
   10113     remote_cpu_usage=	tcp_tran_rr_response->measure_cpu;
   10114     remote_cpu_rate = 	tcp_tran_rr_response->cpu_rate;
   10115     /* make sure that port numbers are in network order */
   10116     server.sin_port	=	tcp_tran_rr_response->data_port_number;
   10117     server.sin_port =	htons(server.sin_port);
   10118     if (debug) {
   10119       fprintf(where,"remote listen done.\n");
   10120       fprintf(where,"remote port is %d\n",ntohs(server.sin_port));
   10121       fflush(where);
   10122     }
   10123   }
   10124   else {
   10125     Set_errno(netperf_response.content.serv_errno);
   10126     fprintf(where,
   10127 	    "netperf: remote error %d",
   10128 	    netperf_response.content.serv_errno);
   10129     perror("");
   10130     fflush(where);
   10131     exit(1);
   10132   }
   10133 
   10134   /* pick a nice random spot between client_port_min and */
   10135   /* client_port_max for our initial port number. if they are the */
   10136   /* same, then just set to _min */
   10137   if (client_port_max - client_port_min) {
   10138     srand(getpid());
   10139     myport = client_port_min +
   10140       (rand() % (client_port_max - client_port_min));
   10141   }
   10142   else {
   10143     myport = client_port_min;
   10144   }
   10145 
   10146   /* there will be a ++ before the first call to bind, so subtract one */
   10147   myport--;
   10148   myaddr->sin_port = htons((unsigned short)myport);
   10149 
   10150   /* Set-up the test end conditions. For a request/response test, they */
   10151   /* can be either time or transaction based. */
   10152 
   10153   if (test_time) {
   10154     /* The user wanted to end the test after a period of time. */
   10155     times_up = 0;
   10156     trans_remaining = 0;
   10157     start_timer(test_time);
   10158   }
   10159   else {
   10160     /* The tester wanted to send a number of bytes. */
   10161     trans_remaining = test_bytes;
   10162     times_up = 1;
   10163   }
   10164 
   10165   /* The cpu_start routine will grab the current time and possibly */
   10166   /* value of the idle counter for later use in measuring cpu */
   10167   /* utilization and/or service demand and thruput. */
   10168 
   10169   cpu_start(local_cpu_usage);
   10170 
   10171   /* We use an "OR" to control test execution. When the test is */
   10172   /* controlled by time, the byte count check will always return false. */
   10173   /* When the test is controlled by byte count, the time test will */
   10174   /* always return false. When the test is finished, the whole */
   10175   /* expression will go false and we will stop sending data. I think I */
   10176   /* just arbitrarily decrement trans_remaining for the timed test, but */
   10177   /* will not do that just yet... One other question is whether or not */
   10178   /* the send buffer and the receive buffer should be the same buffer. */
   10179 
   10180   while ((!times_up) || (trans_remaining > 0)) {
   10181 
   10182 #ifdef WANT_HISTOGRAM
   10183     if (verbosity > 1) {
   10184       /* timestamp just before our call to create the socket, and then */
   10185       /* again just after the receive raj 3/95 */
   10186       HIST_timestamp(&time_one);
   10187     }
   10188 #endif /* WANT_HISTOGRAM */
   10189 
   10190     /* set up the data socket - is this really necessary or can I just */
   10191     /* re-use the same socket and move this cal out of the while loop. */
   10192     /* it does introcudea *boatload* of system calls. I guess that it */
   10193     /* all depends on "reality of programming." keeping it this way is */
   10194     /* a bit more conservative I imagine - raj 3/95 */
   10195     send_socket = create_data_socket(local_res);
   10196 
   10197     if (send_socket == INVALID_SOCKET) {
   10198       perror("netperf: send_tcp_tran_rr: tcp stream data socket");
   10199       exit(1);
   10200     }
   10201 
   10202     /* we set SO_REUSEADDR on the premis that no unreserved port */
   10203     /* number on the local system is going to be already connected to */
   10204     /* the remote netserver's port number. One thing that I might */
   10205     /* try later is to have the remote actually allocate a couple of */
   10206     /* port numbers and cycle through those as well. depends on if we */
   10207     /* can get through all the unreserved port numbers in less than */
   10208     /* the length of the TIME_WAIT state raj 8/94 */
   10209     one = 1;
   10210     if(setsockopt(send_socket, SOL_SOCKET, SO_REUSEADDR,
   10211 		  (char *)&one, sock_opt_len) == SOCKET_ERROR) {
   10212       perror("netperf: send_tcp_tran_rr: so_reuseaddr");
   10213       exit(1);
   10214     }
   10215 
   10216 newport:
   10217     /* pick a new port number */
   10218     myport = ntohs(myaddr->sin_port);
   10219     myport++;
   10220 
   10221     /* we do not want to use the port number that the server is */
   10222     /* sitting at - this would cause us to fail in a loopback test. we */
   10223     /* could just rely on the failure of the bind to get us past this, */
   10224     /* but I'm guessing that in this one case at least, it is much */
   10225     /* faster, given that we *know* that port number is already in use */
   10226     /* (or rather would be in a loopback test) */
   10227 
   10228     if (myport == ntohs(server.sin_port)) myport++;
   10229 
   10230     /* wrap the port number when we get to 65535. NOTE, some broken */
   10231     /* TCP's might treat the port number as a signed 16 bit quantity. */
   10232     /* we aren't interested in testing such broken implementations :) */
   10233     /* raj 8/94  */
   10234     if (myport >= client_port_max) {
   10235       myport = client_port_min;
   10236     }
   10237     myaddr->sin_port = htons((unsigned short)myport);
   10238 
   10239     if (debug) {
   10240       if ((nummessages % 100) == 0) {
   10241 	printf("port %d\n",myport);
   10242       }
   10243     }
   10244 
   10245     /* we want to bind our socket to a particular port number. */
   10246     if (bind(send_socket,
   10247 	     (struct sockaddr *)myaddr,
   10248 	     sizeof(struct sockaddr_storage)) == SOCKET_ERROR) {
   10249       /* if the bind failed, someone else must have that port number */
   10250       /* - perhaps in the listen state. since we can't use it, skip to */
   10251       /* the next port number. we may have to do this again later, but */
   10252       /* that's just too bad :) */
   10253       if (debug > 1) {
   10254 	fprintf(where,
   10255 		"send_tcp_tran_rr: tried to bind to port %d errno %d\n",
   10256 		ntohs(myaddr->sin_port),
   10257 		errno);
   10258 	fflush(where);
   10259       }
   10260 	/* yes, goto's are supposed to be evil, but they do have their */
   10261 	/* uses from time to time. the real world doesn't always have */
   10262 	/* to code to ge tthe A in CS 101 :) raj 3/95 */
   10263 	goto newport;
   10264     }
   10265 
   10266     /* Connect up to the remote port on the data socket. Since this is */
   10267     /* a test for RFC_1644-style transactional TCP, we can use the */
   10268     /* sendto() call instead of calling connect and then send() */
   10269 
   10270     /* send the request */
   10271     if((len=sendto(send_socket,
   10272 		   send_ring->buffer_ptr,
   10273 		   req_size,
   10274 		   MSG_EOF,
   10275 		   (struct sockaddr *)&server,
   10276 		   sizeof(server))) != req_size) {
   10277       if (SOCKET_EINTR(len))
   10278 	  {
   10279 	    /* we hit the end of a */
   10280 	    /* timed test. */
   10281 	    timed_out = 1;
   10282 	    break;
   10283       }
   10284       perror("send_tcp_tran_rr: data send error");
   10285       exit(1);
   10286     }
   10287     send_ring = send_ring->next;
   10288 
   10289     /* receive the response */
   10290     rsp_bytes_left = rsp_size;
   10291     temp_message_ptr  = recv_ring->buffer_ptr;
   10292     while(rsp_bytes_left > 0) {
   10293       if((rsp_bytes_recvd=recv(send_socket,
   10294 			       temp_message_ptr,
   10295 			       rsp_bytes_left,
   10296 			       0)) == SOCKET_ERROR) {
   10297 	    if (SOCKET_EINTR(rsp_bytes_recvd))
   10298 		{
   10299 	      /* We hit the end of a timed test. */
   10300 	      timed_out = 1;
   10301 	      break;
   10302 		}
   10303 	    perror("send_tcp_tran_rr: data recv error");
   10304 	    exit(1);
   10305       }
   10306       rsp_bytes_left -= rsp_bytes_recvd;
   10307       temp_message_ptr  += rsp_bytes_recvd;
   10308     }
   10309     recv_ring = recv_ring->next;
   10310 
   10311     if (timed_out) {
   10312       /* we may have been in a nested while loop - we need */
   10313       /* another call to break. */
   10314       break;
   10315     }
   10316 
   10317     close(send_socket);
   10318 
   10319 #ifdef WANT_HISTOGRAM
   10320     if (verbosity > 1) {
   10321       HIST_timestamp(&time_two);
   10322       HIST_add(time_hist,delta_micro(&time_one,&time_two));
   10323     }
   10324 #endif /* WANT_HISTOGRAM */
   10325 
   10326     nummessages++;
   10327     if (trans_remaining) {
   10328       trans_remaining--;
   10329     }
   10330 
   10331     if (debug > 3) {
   10332       fprintf(where,
   10333 	      "Transaction %d completed on local port %d\n",
   10334 	      nummessages,
   10335 	      ntohs(myaddr->sin_port));
   10336       fflush(where);
   10337     }
   10338 
   10339 
   10340   }
   10341 
   10342   /* this call will always give us the elapsed time for the test, and */
   10343   /* will also store-away the necessaries for cpu utilization */
   10344 
   10345   cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being measured? */
   10346   /* how long did we really run? */
   10347 
   10348   /* Get the statistics from the remote end. The remote will have */
   10349   /* calculated service demand and all those interesting things. If it */
   10350   /* wasn't supposed to care, it will return obvious values. */
   10351 
   10352   recv_response();
   10353   if (!netperf_response.content.serv_errno) {
   10354     if (debug)
   10355       fprintf(where,"remote results obtained\n");
   10356   }
   10357   else {
   10358     Set_errno(netperf_response.content.serv_errno);
   10359     fprintf(where,
   10360 	    "netperf: remote error %d",
   10361 	    netperf_response.content.serv_errno);
   10362     perror("");
   10363     fflush(where);
   10364     exit(1);
   10365   }
   10366 
   10367   /* We now calculate what our thruput was for the test. In the future, */
   10368   /* we may want to include a calculation of the thruput measured by */
   10369   /* the remote, but it should be the case that for a TCP stream test, */
   10370   /* that the two numbers should be *very* close... We calculate */
   10371   /* bytes_sent regardless of the way the test length was controlled. */
   10372   /* If it was time, we needed to, and if it was by bytes, the user may */
   10373   /* have specified a number of bytes that wasn't a multiple of the */
   10374   /* send_size, so we really didn't send what he asked for ;-) We use */
   10375   /* Kbytes/s as the units of thruput for a TCP stream test, where K = */
   10376   /* 1024. A future enhancement *might* be to choose from a couple of */
   10377   /* unit selections. */
   10378 
   10379   bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
   10380   thruput	= calc_thruput(bytes_xferd);
   10381 
   10382   if (local_cpu_usage || remote_cpu_usage) {
   10383     /* We must now do a little math for service demand and cpu */
   10384     /* utilization for the system(s) */
   10385     /* Of course, some of the information might be bogus because */
   10386     /* there was no idle counter in the kernel(s). We need to make */
   10387     /* a note of this for the user's benefit...*/
   10388     if (local_cpu_usage) {
   10389       if (local_cpu_rate == 0.0) {
   10390 	fprintf(where,"WARNING WARNING WARNING  WARNING WARNING WARNING  WARNING!\n");
   10391 	fprintf(where,"Local CPU usage numbers based on process information only!\n");
   10392 	fflush(where);
   10393       }
   10394       local_cpu_utilization = calc_cpu_util(0.0);
   10395       /* since calc_service demand is doing ms/Kunit we will */
   10396       /* multiply the number of transaction by 1024 to get */
   10397       /* "good" numbers */
   10398       local_service_demand  = calc_service_demand((double) nummessages*1024,
   10399 						  0.0,
   10400 						  0.0,
   10401 						  0);
   10402     }
   10403     else {
   10404       local_cpu_utilization	= (float) -1.0;
   10405       local_service_demand	= (float) -1.0;
   10406     }
   10407 
   10408     if (remote_cpu_usage) {
   10409       if (remote_cpu_rate == 0.0) {
   10410 	fprintf(where,"DANGER  DANGER  DANGER    DANGER  DANGER  DANGER    DANGER!\n");
   10411 	fprintf(where,"Remote CPU usage numbers based on process information only!\n");
   10412 	fflush(where);
   10413       }
   10414       remote_cpu_utilization = tcp_tran_rr_result->cpu_util;
   10415       /* since calc_service demand is doing ms/Kunit we will */
   10416       /* multiply the number of transaction by 1024 to get */
   10417       /* "good" numbers */
   10418       remote_service_demand = calc_service_demand((double) nummessages*1024,
   10419 						  0.0,
   10420 						  remote_cpu_utilization,
   10421 						  tcp_tran_rr_result->num_cpus);
   10422     }
   10423     else {
   10424       remote_cpu_utilization = (float) -1.0;
   10425       remote_service_demand  = (float) -1.0;
   10426     }
   10427 
   10428     /* We are now ready to print all the information. If the user */
   10429     /* has specified zero-level verbosity, we will just print the */
   10430     /* local service demand, or the remote service demand. If the */
   10431     /* user has requested verbosity level 1, he will get the basic */
   10432     /* "streamperf" numbers. If the user has specified a verbosity */
   10433     /* of greater than 1, we will display a veritable plethora of */
   10434     /* background information from outside of this block as it it */
   10435     /* not cpu_measurement specific...  */
   10436 
   10437     switch (verbosity) {
   10438     case 0:
   10439       if (local_cpu_usage) {
   10440 	fprintf(where,
   10441 		cpu_fmt_0,
   10442 		local_service_demand);
   10443       }
   10444       else {
   10445 	fprintf(where,
   10446 		cpu_fmt_0,
   10447 		remote_service_demand);
   10448       }
   10449       break;
   10450     case 1:
   10451     case 2:
   10452 
   10453       if (print_headers) {
   10454 	fprintf(where,
   10455 		cpu_title,
   10456 		local_cpu_method,
   10457 		remote_cpu_method);
   10458       }
   10459 
   10460       fprintf(where,
   10461 	      cpu_fmt_1_line_1,		/* the format string */
   10462 	      lss_size,		/* local sendbuf size */
   10463 	      lsr_size,
   10464 	      req_size,		/* how large were the requests */
   10465 	      rsp_size,		/* guess */
   10466 	      elapsed_time,		/* how long was the test */
   10467 	      nummessages/elapsed_time,
   10468 	      local_cpu_utilization,	/* local cpu */
   10469 	      remote_cpu_utilization,	/* remote cpu */
   10470 	      local_service_demand,	/* local service demand */
   10471 	      remote_service_demand);	/* remote service demand */
   10472       fprintf(where,
   10473 	      cpu_fmt_1_line_2,
   10474 	      rss_size,
   10475 	      rsr_size);
   10476       break;
   10477     }
   10478   }
   10479   else {
   10480     /* The tester did not wish to measure service demand. */
   10481     switch (verbosity) {
   10482     case 0:
   10483       fprintf(where,
   10484 	      tput_fmt_0,
   10485 	      nummessages/elapsed_time);
   10486       break;
   10487     case 1:
   10488     case 2:
   10489       if (print_headers) {
   10490 	fprintf(where,tput_title,format_units());
   10491       }
   10492 
   10493       fprintf(where,
   10494 	      tput_fmt_1_line_1,	/* the format string */
   10495 	      lss_size,
   10496 	      lsr_size,
   10497 	      req_size,		/* how large were the requests */
   10498 	      rsp_size,		/* how large were the responses */
   10499 	      elapsed_time, 		/* how long did it take */
   10500 	      nummessages/elapsed_time);
   10501       fprintf(where,
   10502 	      tput_fmt_1_line_2,
   10503 	      rss_size, 		/* remote recvbuf size */
   10504 	      rsr_size);
   10505 
   10506       break;
   10507     }
   10508   }
   10509 
   10510   /* it would be a good thing to include information about some of the */
   10511   /* other parameters that may have been set for this test, but at the */
   10512   /* moment, I do not wish to figure-out all the  formatting, so I will */
   10513   /* just put this comment here to help remind me that it is something */
   10514   /* that should be done at a later time. */
   10515 
   10516   if (verbosity > 1) {
   10517     /* The user wanted to know it all, so we will give it to him. */
   10518     /* This information will include as much as we can find about */
   10519     /* TCP statistics, the alignments of the sends and receives */
   10520     /* and all that sort of rot... */
   10521 
   10522     fprintf(where,
   10523 	    ksink_fmt,
   10524 	    local_send_align,
   10525 	    remote_recv_offset,
   10526 	    local_send_offset,
   10527 	    remote_recv_offset);
   10528 
   10529 #ifdef WANT_HISTOGRAM
   10530     fprintf(where,"\nHistogram of request/response times\n");
   10531     fflush(where);
   10532     HIST_report(time_hist);
   10533 #endif /* WANT_HISTOGRAM */
   10534 
   10535   }
   10536 
   10537 }
   10538 
   10539 
   10540 int
   10542 recv_tcp_tran_rr()
   10543 {
   10544 
   10545   char  *message;
   10546   struct	sockaddr_in        myaddr_in,
   10547   peeraddr_in;
   10548   SOCKET	s_listen,s_data;
   10549   netperf_socklen_t 	addrlen;
   10550   int   NoPush = 1;
   10551 
   10552   char	*recv_message_ptr;
   10553   char	*send_message_ptr;
   10554   char	*temp_message_ptr;
   10555   int	trans_received;
   10556   int	trans_remaining;
   10557   int	bytes_sent;
   10558   int	request_bytes_recvd;
   10559   int	request_bytes_remaining;
   10560   int	timed_out = 0;
   10561   float	elapsed_time;
   10562 
   10563   struct	tcp_tran_rr_request_struct	*tcp_tran_rr_request;
   10564   struct	tcp_tran_rr_response_struct	*tcp_tran_rr_response;
   10565   struct	tcp_tran_rr_results_struct	*tcp_tran_rr_results;
   10566 
   10567   tcp_tran_rr_request =
   10568     (struct tcp_tran_rr_request_struct *)netperf_request.content.test_specific_data;
   10569   tcp_tran_rr_response =
   10570     (struct tcp_tran_rr_response_struct *)netperf_response.content.test_specific_data;
   10571   tcp_tran_rr_results =
   10572     (struct tcp_tran_rr_results_struct *)netperf_response.content.test_specific_data;
   10573 
   10574   if (debug) {
   10575     fprintf(where,"netserver: recv_tcp_tran_rr: entered...\n");
   10576     fflush(where);
   10577   }
   10578 
   10579   /* We want to set-up the listen socket with all the desired */
   10580   /* parameters and then let the initiator know that all is ready. If */
   10581   /* socket size defaults are to be used, then the initiator will have */
   10582   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   10583   /* send-back what they are. If that information cannot be determined, */
   10584   /* then we send-back -1's for the sizes. If things go wrong for any */
   10585   /* reason, we will drop back ten yards and punt. */
   10586 
   10587   /* If anything goes wrong, we want the remote to know about it. It */
   10588   /* would be best if the error that the remote reports to the user is */
   10589   /* the actual error we encountered, rather than some bogus unexpected */
   10590   /* response type message. */
   10591 
   10592   if (debug) {
   10593     fprintf(where,"recv_tcp_tran_rr: setting the response type...\n");
   10594     fflush(where);
   10595   }
   10596 
   10597   netperf_response.content.response_type = TCP_TRR_RESPONSE;
   10598 
   10599   if (debug) {
   10600     fprintf(where,"recv_tcp_tran_rr: the response type is set...\n");
   10601     fflush(where);
   10602   }
   10603 
   10604   /* set-up the data buffer with the requested alignment and offset */
   10605   message = (char *)malloc(DATABUFFERLEN);
   10606   if (message == NULL) {
   10607     printf("malloc(%d) failed!\n", DATABUFFERLEN);
   10608     exit(1);
   10609   }
   10610 
   10611   /* We now alter the message_ptr variables to be at the desired */
   10612   /* alignments with the desired offsets. */
   10613 
   10614   if (debug) {
   10615     fprintf(where,
   10616 	    "recv_tcp_tran_rr: requested recv alignment of %d offset %d\n",
   10617 	    tcp_tran_rr_request->recv_alignment,
   10618 	    tcp_tran_rr_request->recv_offset);
   10619     fprintf(where,
   10620 	    "recv_tcp_tran_rr: requested send alignment of %d offset %d\n",
   10621 	    tcp_tran_rr_request->send_alignment,
   10622 	    tcp_tran_rr_request->send_offset);
   10623     fflush(where);
   10624   }
   10625 
   10626   recv_message_ptr = ALIGN_BUFFER(message, tcp_tran_rr_request->recv_alignment, tcp_tran_rr_request->recv_offset);
   10627 
   10628   send_message_ptr = ALIGN_BUFFER(message, tcp_tran_rr_request->send_alignment, tcp_tran_rr_request->send_offset);
   10629 
   10630   if (debug) {
   10631     fprintf(where,"recv_tcp_tran_rr: receive alignment and offset set...\n");
   10632     fflush(where);
   10633   }
   10634 
   10635   /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */
   10636   /* can put in OUR values !-) At some point, we may want to nail this */
   10637   /* socket to a particular network-level address, but for now, */
   10638   /* INADDR_ANY should be just fine. */
   10639 
   10640   bzero((char *)&myaddr_in,
   10641 	sizeof(myaddr_in));
   10642   myaddr_in.sin_family      = AF_INET;
   10643   myaddr_in.sin_addr.s_addr = INADDR_ANY;
   10644   myaddr_in.sin_port        = htons((unsigned short)tcp_tran_rr_request->port);
   10645 
   10646   /* Grab a socket to listen on, and then listen on it. */
   10647 
   10648   if (debug) {
   10649     fprintf(where,"recv_tcp_tran_rr: grabbing a socket...\n");
   10650     fflush(where);
   10651   }
   10652 
   10653   /* create_data_socket expects to find some things in the global */
   10654   /* variables, so set the globals based on the values in the request. */
   10655   /* once the socket has been created, we will set the response values */
   10656   /* based on the updated value of those globals. raj 7/94 */
   10657   lss_size_req = tcp_tran_rr_request->send_buf_size;
   10658   lsr_size_req = tcp_tran_rr_request->recv_buf_size;
   10659   loc_nodelay = tcp_tran_rr_request->no_delay;
   10660   loc_rcvavoid = tcp_tran_rr_request->so_rcvavoid;
   10661   loc_sndavoid = tcp_tran_rr_request->so_sndavoid;
   10662 
   10663   set_hostname_and_port(local_name,
   10664 			port_buffer,
   10665 			nf_to_af(tcp_tran_rr_request->ipfamily),
   10666 			tcp_tran_rr_request->port);
   10667 
   10668   local_res = complete_addrinfo(local_name,
   10669 				local_name,
   10670 				port_buffer,
   10671 				nf_to_af(tcp_tran_rr_request->ipfamily),
   10672 				SOCK_STREAM,
   10673 				IPPROTO_TCP,
   10674 				0);
   10675 
   10676   s_listen = create_data_socket(local_res);
   10677 
   10678   if (s_listen == INVALID_SOCKET) {
   10679     netperf_response.content.serv_errno = errno;
   10680     send_response();
   10681     if (debug) {
   10682       fprintf(where,"could not create data socket\n");
   10683       fflush(where);
   10684     }
   10685     exit(1);
   10686   }
   10687 
   10688 #ifdef WIN32
   10689   /* The test timer can fire during operations on the listening socket,
   10690      so to make the start_timer below work we have to move
   10691      it to close s_listen while we are blocked on accept. */
   10692   win_kludge_socket2 = s_listen;
   10693 #endif
   10694 
   10695 
   10696   /* Let's get an address assigned to this socket so we can tell the */
   10697   /* initiator how to reach the data socket. There may be a desire to */
   10698   /* nail this socket to a specific IP address in a multi-homed, */
   10699   /* multi-connection situation, but for now, we'll ignore the issue */
   10700   /* and concentrate on single connection testing. */
   10701 
   10702   if (bind(s_listen,
   10703 	   (struct sockaddr *)&myaddr_in,
   10704 	   sizeof(myaddr_in)) == SOCKET_ERROR) {
   10705     netperf_response.content.serv_errno = errno;
   10706     close(s_listen);
   10707     send_response();
   10708     if (debug) {
   10709       fprintf(where,"could not bind\n");
   10710       fflush(where);
   10711     }
   10712     exit(1);
   10713   }
   10714 
   10715   /* we want to disable the implicit PUSH on all sends. at some point, */
   10716   /* this might want to be a parm to the test raj 3/95 */
   10717   if (setsockopt(s_listen,
   10718 		 IPPROTO_TCP,
   10719 		 TCP_NOPUSH,
   10720 		 (const char *)&NoPush,
   10721 		 sizeof(int)) == SOCKET_ERROR) {
   10722     fprintf(where,
   10723 	    "recv_tcp_tran_rr: could not set TCP_NOPUSH errno %d\n",
   10724 	    errno);
   10725     fflush(where);
   10726     netperf_response.content.serv_errno = errno;
   10727     close(s_listen);
   10728     send_response();
   10729   }
   10730 
   10731   /* Now, let's set-up the socket to listen for connections */
   10732   if (listen(s_listen, 5) == SOCKET_ERROR) {
   10733     netperf_response.content.serv_errno = errno;
   10734     close(s_listen);
   10735     send_response();
   10736     if (debug) {
   10737       fprintf(where,"could not listen\n");
   10738       fflush(where);
   10739     }
   10740     exit(1);
   10741   }
   10742 
   10743   /* now get the port number assigned by the system  */
   10744   addrlen = sizeof(myaddr_in);
   10745   if (getsockname(s_listen,
   10746 		  (struct sockaddr *)&myaddr_in,
   10747 		  &addrlen) == SOCKET_ERROR){
   10748     netperf_response.content.serv_errno = errno;
   10749     close(s_listen);
   10750     send_response();
   10751     if (debug) {
   10752       fprintf(where,"could not geetsockname\n");
   10753       fflush(where);
   10754     }
   10755     exit(1);
   10756   }
   10757 
   10758   /* Now myaddr_in contains the port and the internet address this is */
   10759   /* returned to the sender also implicitly telling the sender that the */
   10760   /* socket buffer sizing has been done. */
   10761 
   10762   tcp_tran_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port);
   10763   if (debug) {
   10764     fprintf(where,"telling the remote to call me at %d\n",
   10765 	    tcp_tran_rr_response->data_port_number);
   10766     fflush(where);
   10767   }
   10768   netperf_response.content.serv_errno   = 0;
   10769 
   10770   /* But wait, there's more. If the initiator wanted cpu measurements, */
   10771   /* then we must call the calibrate routine, which will return the max */
   10772   /* rate back to the initiator. If the CPU was not to be measured, or */
   10773   /* something went wrong with the calibration, we will return a 0.0 to */
   10774   /* the initiator. */
   10775 
   10776   tcp_tran_rr_response->cpu_rate = 0.0; 	/* assume no cpu */
   10777   if (tcp_tran_rr_request->measure_cpu) {
   10778     tcp_tran_rr_response->measure_cpu = 1;
   10779     tcp_tran_rr_response->cpu_rate =
   10780       calibrate_local_cpu(tcp_tran_rr_request->cpu_rate);
   10781   }
   10782 
   10783 
   10784 
   10785   /* before we send the response back to the initiator, pull some of */
   10786   /* the socket parms from the globals */
   10787   tcp_tran_rr_response->send_buf_size = lss_size;
   10788   tcp_tran_rr_response->recv_buf_size = lsr_size;
   10789   tcp_tran_rr_response->no_delay = loc_nodelay;
   10790   tcp_tran_rr_response->so_rcvavoid = loc_rcvavoid;
   10791   tcp_tran_rr_response->so_sndavoid = loc_sndavoid;
   10792 
   10793   send_response();
   10794 
   10795   addrlen = sizeof(peeraddr_in);
   10796 
   10797   /* Now it's time to start receiving data on the connection. We will */
   10798   /* first grab the apropriate counters and then start grabbing. */
   10799 
   10800   cpu_start(tcp_tran_rr_request->measure_cpu);
   10801 
   10802   /* The loop will exit when the sender does a shutdown, which will */
   10803   /* return a length of zero   */
   10804 
   10805   if (tcp_tran_rr_request->test_length > 0) {
   10806     times_up = 0;
   10807     trans_remaining = 0;
   10808     start_timer(tcp_tran_rr_request->test_length + PAD_TIME);
   10809   }
   10810   else {
   10811     times_up = 1;
   10812     trans_remaining = tcp_tran_rr_request->test_length * -1;
   10813   }
   10814 
   10815   trans_received = 0;
   10816 
   10817   while ((!times_up) || (trans_remaining > 0)) {
   10818 
   10819     /* accept a connection from the remote */
   10820     if ((s_data=accept(s_listen,
   10821 		       (struct sockaddr *)&peeraddr_in,
   10822 		       &addrlen)) == INVALID_SOCKET) {
   10823       if (errno == EINTR) {
   10824 	/* the timer popped */
   10825 	timed_out = 1;
   10826 	break;
   10827       }
   10828       fprintf(where,"recv_tcp_tran_rr: accept: errno = %d\n",errno);
   10829       fflush(where);
   10830       close(s_listen);
   10831 
   10832       exit(1);
   10833     }
   10834 
   10835     if (debug) {
   10836       fprintf(where,"recv_tcp_tran_rr: accepted data connection.\n");
   10837       fflush(where);
   10838     }
   10839 
   10840 #ifdef WIN32
   10841   /* this is used so the timer thread can close the socket out from */
   10842   /* under us, which to date is the easiest/cleanest/least */
   10843   /* Windows-specific way I can find to force the winsock calls to */
   10844   /* return WSAEINTR with the test is over. anything that will run on */
   10845   /* 95 and NT and is closer to what netperf expects from Unix signals */
   10846   /* and such would be appreciated raj 1/96 */
   10847   win_kludge_socket = s_data;
   10848 #endif /* WIN32 */
   10849 
   10850 #ifdef KLUDGE_SOCKET_OPTIONS
   10851   /* this is for those systems which *INCORRECTLY* fail to pass */
   10852   /* attributes across an accept() call. Including this goes against */
   10853   /* my better judgement :( raj 11/95 */
   10854 
   10855   kludge_socket_options(s_data);
   10856 
   10857 #endif /* KLUDGE_SOCKET_OPTIONS */
   10858 
   10859     temp_message_ptr	= recv_message_ptr;
   10860     request_bytes_remaining	= tcp_tran_rr_request->request_size;
   10861 
   10862     /* receive the request from the other side. we can just receive */
   10863     /* until we get zero bytes, but that would be a slight structure */
   10864     /* change in the code, with minimal perfomance effects. If */
   10865     /* however, I has variable-length messages, I would want to do */
   10866     /* this to avoid needing "double reads" - one for the message */
   10867     /* length, and one for the rest of the message raj 3/95 */
   10868     while(request_bytes_remaining > 0) {
   10869       if((request_bytes_recvd=recv(s_data,
   10870 				   temp_message_ptr,
   10871 				   request_bytes_remaining,
   10872 				   0)) == SOCKET_ERROR) {
   10873 	    if ( SOCKET_EINTR(request_bytes_recvd) )
   10874 		{
   10875 	      /* the timer popped */
   10876 	      timed_out = 1;
   10877 	      break;
   10878 		}
   10879 	    netperf_response.content.serv_errno = errno;
   10880 	    send_response();
   10881 	    exit(1);
   10882       }
   10883       else {
   10884 	request_bytes_remaining -= request_bytes_recvd;
   10885 	temp_message_ptr  += request_bytes_recvd;
   10886       }
   10887     }
   10888 
   10889     if (timed_out) {
   10890       /* we hit the end of the test based on time - lets */
   10891       /* bail out of here now... */
   10892       fprintf(where,"yo5\n");
   10893       fflush(where);
   10894       break;
   10895     }
   10896 
   10897     /* Now, send the response to the remote we can use sendto here to */
   10898     /* help remind people that this is an rfc 1644 style of test */
   10899     if((bytes_sent=sendto(s_data,
   10900 			  send_message_ptr,
   10901 			  tcp_tran_rr_request->response_size,
   10902 			  MSG_EOF,
   10903 			  (struct sockaddr *)&peeraddr_in,
   10904 			  sizeof(struct sockaddr_storage))) == SOCKET_ERROR) {
   10905       if (SOCKET_EINTR(bytes_sent)) {
   10906 	/* the test timer has popped */
   10907 	timed_out = 1;
   10908 	fprintf(where,"yo6\n");
   10909 	fflush(where);
   10910 	break;
   10911       }
   10912       netperf_response.content.serv_errno = 99;
   10913       send_response();
   10914       exit(1);
   10915     }
   10916 
   10917     trans_received++;
   10918     if (trans_remaining) {
   10919       trans_remaining--;
   10920     }
   10921 
   10922     if (debug) {
   10923       fprintf(where,
   10924 	      "recv_tcp_tran_rr: Transaction %d complete\n",
   10925 	      trans_received);
   10926       fflush(where);
   10927     }
   10928 
   10929     /* close the connection. since we have disable PUSH on sends, the */
   10930     /* FIN should be tacked-onto our last send instead of being */
   10931     /* standalone */
   10932     close(s_data);
   10933 
   10934   }
   10935 
   10936 
   10937   /* The loop now exits due to timeout or transaction count being */
   10938   /* reached */
   10939 
   10940   cpu_stop(tcp_tran_rr_request->measure_cpu,&elapsed_time);
   10941 
   10942   if (timed_out) {
   10943     /* we ended the test by time, which was at least 2 seconds */
   10944     /* longer than we wanted to run. so, we want to subtract */
   10945     /* PAD_TIME from the elapsed_time. */
   10946     elapsed_time -= PAD_TIME;
   10947   }
   10948   /* send the results to the sender			*/
   10949 
   10950   if (debug) {
   10951     fprintf(where,
   10952 	    "recv_tcp_tran_rr: got %d transactions\n",
   10953 	    trans_received);
   10954     fflush(where);
   10955   }
   10956 
   10957   tcp_tran_rr_results->bytes_received	= (trans_received *
   10958 					   (tcp_tran_rr_request->request_size +
   10959 					    tcp_tran_rr_request->response_size));
   10960   tcp_tran_rr_results->trans_received	= trans_received;
   10961   tcp_tran_rr_results->elapsed_time	= elapsed_time;
   10962   if (tcp_tran_rr_request->measure_cpu) {
   10963     tcp_tran_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
   10964   }
   10965 
   10966   if (debug) {
   10967     fprintf(where,
   10968 	    "recv_tcp_tran_rr: test complete, sending results.\n");
   10969     fflush(where);
   10970   }
   10971 
   10972   send_response();
   10973 
   10974 }
   10975 #endif /* DO_1644 */
   10976 
   10977 #ifdef DO_NBRR
   10979  /* this routine implements the sending (netperf) side of the TCP_RR */
   10980  /* test using POSIX-style non-blocking sockets. */
   10981 
   10982 void
   10983 send_tcp_nbrr(char remote_host[])
   10984 {
   10985 
   10986   char *tput_title = "\
   10987 Local /Remote\n\
   10988 Socket Size   Request  Resp.   Elapsed  Trans.\n\
   10989 Send   Recv   Size     Size    Time     Rate         \n\
   10990 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
   10991 
   10992   char *tput_fmt_0 =
   10993     "%7.2f\n";
   10994 
   10995   char *tput_fmt_1_line_1 = "\
   10996 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
   10997   char *tput_fmt_1_line_2 = "\
   10998 %-6d %-6d\n";
   10999 
   11000   char *cpu_title = "\
   11001 Local /Remote\n\
   11002 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
   11003 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
   11004 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
   11005 
   11006   char *cpu_fmt_0 =
   11007     "%6.3f %c\n";
   11008 
   11009   char *cpu_fmt_1_line_1 = "\
   11010 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f  %-6.2f %-6.2f %-6.3f  %-6.3f\n";
   11011 
   11012   char *cpu_fmt_1_line_2 = "\
   11013 %-6d %-6d\n";
   11014 
   11015   char *ksink_fmt = "\
   11016 Alignment      Offset\n\
   11017 Local  Remote  Local  Remote\n\
   11018 Send   Recv    Send   Recv\n\
   11019 %5d  %5d   %5d  %5d\n";
   11020 
   11021 
   11022   int			timed_out = 0;
   11023   float			elapsed_time;
   11024 
   11025   int	len;
   11026   char	*temp_message_ptr;
   11027   int	nummessages;
   11028   SOCKET	send_socket;
   11029   int	trans_remaining;
   11030   double	bytes_xferd;
   11031 
   11032   struct ring_elt *send_ring;
   11033   struct ring_elt *recv_ring;
   11034 
   11035   int	rsp_bytes_left;
   11036   int	rsp_bytes_recvd;
   11037 
   11038   float	local_cpu_utilization;
   11039   float	local_service_demand;
   11040   float	remote_cpu_utilization;
   11041   float	remote_service_demand;
   11042   double	thruput;
   11043 
   11044   struct	hostent	        *hp;
   11045   struct	sockaddr_storage	server;
   11046   unsigned      int             addr;
   11047 
   11048   struct	tcp_rr_request_struct	*tcp_rr_request;
   11049   struct	tcp_rr_response_struct	*tcp_rr_response;
   11050   struct	tcp_rr_results_struct	*tcp_rr_result;
   11051 
   11052   struct addrinfo *remote_res;
   11053   struct addrinfo *local_res;
   11054 
   11055   tcp_rr_request =
   11056     (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data;
   11057   tcp_rr_response=
   11058     (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data;
   11059   tcp_rr_result	=
   11060     (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data;
   11061 
   11062 #ifdef WANT_HISTOGRAM
   11063   if (verbosity > 1) {
   11064     time_hist = HIST_new();
   11065   }
   11066 #endif /* WANT_HISTOGRAM */
   11067 
   11068   /* since we are now disconnected from the code that established the */
   11069   /* control socket, and since we want to be able to use different */
   11070   /* protocols and such, we are passed the name of the remote host and */
   11071   /* must turn that into the test specific addressing information. */
   11072 
   11073   bzero((char *)&server,
   11074 	sizeof(server));
   11075 
   11076   complete_addrinfos(&remote_res,
   11077 		     &local_res,
   11078 		     remote_host,
   11079 		     SOCK_STREAM,
   11080 		     IPPROTO_TCP,
   11081 		     0);
   11082 
   11083   if ( print_headers ) {
   11084     print_top_test_header("TCP Non-Blocking REQUEST/RESPONSE TEST",local_res,remote_res);
   11085   }
   11086 
   11087   /* initialize a few counters */
   11088 
   11089   send_ring = NULL;
   11090   recv_ring = NULL;
   11091   confidence_iteration = 1;
   11092   init_stat();
   11093 
   11094   /* we have a great-big while loop which controls the number of times */
   11095   /* we run a particular test. this is for the calculation of a */
   11096   /* confidence interval (I really should have stayed awake during */
   11097   /* probstats :). If the user did not request confidence measurement */
   11098   /* (no confidence is the default) then we will only go though the */
   11099   /* loop once. the confidence stuff originates from the folks at IBM */
   11100 
   11101   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   11102 	 (confidence_iteration <= iteration_min)) {
   11103 
   11104     /* initialize a few counters. we have to remember that we might be */
   11105     /* going through the loop more than once. */
   11106 
   11107     nummessages     = 0;
   11108     bytes_xferd     = 0.0;
   11109     times_up        = 0;
   11110     timed_out       = 0;
   11111     trans_remaining = 0;
   11112 
   11113     /* set-up the data buffers with the requested alignment and offset. */
   11114     /* since this is a request/response test, default the send_width and */
   11115     /* recv_width to 1 and not two raj 7/94 */
   11116 
   11117     if (send_width == 0) send_width = 1;
   11118     if (recv_width == 0) recv_width = 1;
   11119 
   11120     if (send_ring == NULL) {
   11121       send_ring = allocate_buffer_ring(send_width,
   11122 				       req_size,
   11123 				       local_send_align,
   11124 				       local_send_offset);
   11125     }
   11126 
   11127     if (recv_ring == NULL) {
   11128       recv_ring = allocate_buffer_ring(recv_width,
   11129 				       rsp_size,
   11130 				       local_recv_align,
   11131 				       local_recv_offset);
   11132     }
   11133 
   11134     /*set up the data socket                        */
   11135     send_socket = create_data_socket(local_res);
   11136 
   11137     if (send_socket == INVALID_SOCKET){
   11138       perror("netperf: send_tcp_nbrr: tcp stream data socket");
   11139       exit(1);
   11140     }
   11141 
   11142     if (debug) {
   11143       fprintf(where,"send_tcp_nbrr: send_socket obtained...\n");
   11144     }
   11145 
   11146     /* If the user has requested cpu utilization measurements, we must */
   11147     /* calibrate the cpu(s). We will perform this task within the tests */
   11148     /* themselves. If the user has specified the cpu rate, then */
   11149     /* calibrate_local_cpu will return rather quickly as it will have */
   11150     /* nothing to do. If local_cpu_rate is zero, then we will go through */
   11151     /* all the "normal" calibration stuff and return the rate back.*/
   11152 
   11153     if (local_cpu_usage) {
   11154       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   11155     }
   11156 
   11157     /* Tell the remote end to do a listen. The server alters the socket */
   11158     /* paramters on the other side at this point, hence the reason for */
   11159     /* all the values being passed in the setup message. If the user did */
   11160     /* not specify any of the parameters, they will be passed as 0, which */
   11161     /* will indicate to the remote that no changes beyond the system's */
   11162     /* default should be used. Alignment is the exception, it will */
   11163     /* default to 8, which will be no alignment alterations. */
   11164 
   11165     netperf_request.content.request_type	=	DO_TCP_NBRR;
   11166     tcp_rr_request->recv_buf_size	=	rsr_size_req;
   11167     tcp_rr_request->send_buf_size	=	rss_size_req;
   11168     tcp_rr_request->recv_alignment      =	remote_recv_align;
   11169     tcp_rr_request->recv_offset	        =	remote_recv_offset;
   11170     tcp_rr_request->send_alignment      =	remote_send_align;
   11171     tcp_rr_request->send_offset	        =	remote_send_offset;
   11172     tcp_rr_request->request_size	=	req_size;
   11173     tcp_rr_request->response_size	=	rsp_size;
   11174     tcp_rr_request->no_delay	        =	rem_nodelay;
   11175     tcp_rr_request->measure_cpu	        =	remote_cpu_usage;
   11176     tcp_rr_request->cpu_rate	        =	remote_cpu_rate;
   11177     tcp_rr_request->so_rcvavoid	        =	rem_rcvavoid;
   11178     tcp_rr_request->so_sndavoid	        =	rem_sndavoid;
   11179     if (test_time) {
   11180       tcp_rr_request->test_length	=	test_time;
   11181     }
   11182     else {
   11183       tcp_rr_request->test_length	=	test_trans * -1;
   11184     }
   11185 
   11186     if (debug > 1) {
   11187       fprintf(where,"netperf: send_tcp_nbrr: requesting TCP rr test\n");
   11188     }
   11189 
   11190     send_request();
   11191 
   11192     /* The response from the remote will contain all of the relevant 	*/
   11193     /* socket parameters for this test type. We will put them back into */
   11194     /* the variables here so they can be displayed if desired.  The	*/
   11195     /* remote will have calibrated CPU if necessary, and will have done	*/
   11196     /* all the needed set-up we will have calibrated the cpu locally	*/
   11197     /* before sending the request, and will grab the counter value right*/
   11198     /* after the connect returns. The remote will grab the counter right*/
   11199     /* after the accept call. This saves the hassle of extra messages	*/
   11200     /* being sent for the TCP tests.					*/
   11201 
   11202     recv_response();
   11203 
   11204     if (!netperf_response.content.serv_errno) {
   11205       if (debug)
   11206 	fprintf(where,"remote listen done.\n");
   11207       rsr_size          = tcp_rr_response->recv_buf_size;
   11208       rss_size          = tcp_rr_response->send_buf_size;
   11209       rem_nodelay       = tcp_rr_response->no_delay;
   11210       remote_cpu_usage  = tcp_rr_response->measure_cpu;
   11211       remote_cpu_rate   = tcp_rr_response->cpu_rate;
   11212       /* make sure that port numbers are in network order */
   11213       server.sin_port   = (unsigned short)tcp_rr_response->data_port_number;
   11214       server.sin_port   = htons(server.sin_port);
   11215     }
   11216     else {
   11217       Set_errno(netperf_response.content.serv_errno);
   11218       fprintf(where,
   11219 	      "netperf: remote error %d",
   11220 	      netperf_response.content.serv_errno);
   11221       perror("");
   11222       fflush(where);
   11223       exit(1);
   11224     }
   11225 
   11226     /*Connect up to the remote port on the data socket  */
   11227     if (connect(send_socket,
   11228 		remote_res->ai_addr,
   11229 		remote_res->ai_addrlen) == INVALID_SOCKET){
   11230       perror("netperf: data socket connect failed");
   11231 
   11232       exit(1);
   11233     }
   11234 
   11235     /* now that we are connected, mark the socket as non-blocking */
   11236     if (!set_nonblock(send_socket)) {
   11237       perror("netperf: set_nonblock");
   11238       exit(1);
   11239     }
   11240 
   11241 #ifdef WIN32
   11242   /* this is used so the timer thread can close the socket out from */
   11243   /* under us, which to date is the easiest/cleanest/least */
   11244   /* Windows-specific way I can find to force the winsock calls to */
   11245   /* return WSAEINTR with the test is over. anything that will run on */
   11246   /* 95 and NT and is closer to what netperf expects from Unix signals */
   11247   /* and such would be appreciated raj 1/96 */
   11248   win_kludge_socket = send_socket;
   11249 #endif /* WIN32 */
   11250 
   11251     /* Data Socket set-up is finished. If there were problems, either the */
   11252     /* connect would have failed, or the previous response would have */
   11253     /* indicated a problem. I failed to see the value of the extra */
   11254     /* message after the accept on the remote. If it failed, we'll see it */
   11255     /* here. If it didn't, we might as well start pumping data. */
   11256 
   11257     /* Set-up the test end conditions. For a request/response test, they */
   11258     /* can be either time or transaction based. */
   11259 
   11260     if (test_time) {
   11261       /* The user wanted to end the test after a period of time. */
   11262       times_up = 0;
   11263       trans_remaining = 0;
   11264       start_timer(test_time);
   11265     }
   11266     else {
   11267       /* The tester wanted to send a number of bytes. */
   11268       trans_remaining = test_bytes;
   11269       times_up = 1;
   11270     }
   11271 
   11272     /* The cpu_start routine will grab the current time and possibly */
   11273     /* value of the idle counter for later use in measuring cpu */
   11274     /* utilization and/or service demand and thruput. */
   11275 
   11276     cpu_start(local_cpu_usage);
   11277 
   11278 #ifdef WANT_INTERVALS
   11279     INTERVALS_INIT();
   11280 #endif /* WANT_INTERVALS */
   11281 
   11282     /* We use an "OR" to control test execution. When the test is */
   11283     /* controlled by time, the byte count check will always return false. */
   11284     /* When the test is controlled by byte count, the time test will */
   11285     /* always return false. When the test is finished, the whole */
   11286     /* expression will go false and we will stop sending data. I think I */
   11287     /* just arbitrarily decrement trans_remaining for the timed test, but */
   11288     /* will not do that just yet... One other question is whether or not */
   11289     /* the send buffer and the receive buffer should be the same buffer. */
   11290 
   11291     while ((!times_up) || (trans_remaining > 0)) {
   11292       /* send the request. we assume that if we use a blocking socket, */
   11293       /* the request will be sent at one shot. */
   11294 
   11295 #ifdef WANT_HISTOGRAM
   11296       if (verbosity > 1) {
   11297 	/* timestamp just before our call to send, and then again just */
   11298 	/* after the receive raj 8/94 */
   11299 	HIST_timestamp(&time_one);
   11300       }
   11301 #endif /* WANT_HISTOGRAM */
   11302 
   11303       /* even though this is a non-blocking socket, we will assume for */
   11304       /* the time being that we will be able to send an entire request */
   11305       /* without getting an EAGAIN */
   11306       if((len=send(send_socket,
   11307 		   send_ring->buffer_ptr,
   11308 		   req_size,
   11309 		   0)) != req_size) {
   11310 	if (SOCKET_EINTR(len)) {
   11311 	  /* we hit the end of a */
   11312 	  /* timed test. */
   11313 	  timed_out = 1;
   11314 	  break;
   11315 	}
   11316 	perror("send_tcp_nbrr: data send error");
   11317 	exit(1);
   11318       }
   11319       send_ring = send_ring->next;
   11320 
   11321       /* receive the response. since we are using non-blocking I/O, we */
   11322       /* will "spin" on the recvs */
   11323       rsp_bytes_left = rsp_size;
   11324       temp_message_ptr  = recv_ring->buffer_ptr;
   11325       while(rsp_bytes_left > 0) {
   11326 	if((rsp_bytes_recvd=recv(send_socket,
   11327 				 temp_message_ptr,
   11328 				 rsp_bytes_left,
   11329 				 0)) == SOCKET_ERROR) {
   11330 	  if (SOCKET_EINTR(rsp_bytes_recvd))
   11331 	  {
   11332 	    /* We hit the end of a timed test. */
   11333 	    timed_out = 1;
   11334 	    break;
   11335 	  }
   11336 #ifndef WIN32  // But what does WinNT indicate in this situation...
   11337 	  else if (errno == EAGAIN) {
   11338 	    Set_errno(0);
   11339 	    continue;
   11340 	  }
   11341 #endif
   11342 	  else {
   11343 	    perror("send_tcp_nbrr: data recv error");
   11344 	    exit(1);
   11345 	  }
   11346 	}
   11347 	rsp_bytes_left -= rsp_bytes_recvd;
   11348 	temp_message_ptr  += rsp_bytes_recvd;
   11349       }
   11350       recv_ring = recv_ring->next;
   11351 
   11352       if (timed_out) {
   11353 	/* we may have been in a nested while loop - we need */
   11354 	/* another call to break. */
   11355 	break;
   11356       }
   11357 
   11358 #ifdef WANT_HISTOGRAM
   11359       if (verbosity > 1) {
   11360 	HIST_timestamp(&time_two);
   11361 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   11362       }
   11363 #endif /* WANT_HISTOGRAM */
   11364 #ifdef WANT_INTERVALS
   11365       INTERVALS_WAIT();
   11366 #endif /* WANT_INTERVALS */
   11367 
   11368       nummessages++;
   11369       if (trans_remaining) {
   11370 	trans_remaining--;
   11371       }
   11372 
   11373       if (debug > 3) {
   11374 	if ((nummessages % 100) == 0) {
   11375 	  fprintf(where,
   11376 		  "Transaction %d completed\n",
   11377 		  nummessages);
   11378 	  fflush(where);
   11379 	}
   11380       }
   11381     }
   11382 
   11383     /* At this point we used to call shutdown on the data socket to be */
   11384     /* sure all the data was delivered, but this was not germane in a */
   11385     /* request/response test, and it was causing the tests to "hang" when */
   11386     /* they were being controlled by time. So, I have replaced this */
   11387     /* shutdown call with a call to close that can be found later in the */
   11388     /* procedure. */
   11389 
   11390     /* this call will always give us the elapsed time for the test, and */
   11391     /* will also store-away the necessaries for cpu utilization */
   11392 
   11393     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
   11394 						/* measured? how long */
   11395 						/* did we really run? */
   11396 
   11397     /* Get the statistics from the remote end. The remote will have */
   11398     /* calculated service demand and all those interesting things. If it */
   11399     /* wasn't supposed to care, it will return obvious values. */
   11400 
   11401 #if defined(WANT_INTERVALS)
   11402 #ifdef WIN32
   11403     stop_itimer();
   11404 #endif
   11405 #endif /* WANT_INTERVALS */
   11406 
   11407     recv_response();
   11408     if (!netperf_response.content.serv_errno) {
   11409       if (debug)
   11410 	fprintf(where,"remote results obtained\n");
   11411     }
   11412     else {
   11413       Set_errno(netperf_response.content.serv_errno);
   11414       fprintf(where,
   11415 	      "netperf: remote error %d",
   11416 	      netperf_response.content.serv_errno);
   11417       perror("");
   11418       fflush(where);
   11419 
   11420       exit(1);
   11421     }
   11422 
   11423     /* We now calculate what our thruput was for the test. */
   11424 
   11425     bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
   11426     thruput	= nummessages/elapsed_time;
   11427 
   11428     if (local_cpu_usage || remote_cpu_usage) {
   11429       /* We must now do a little math for service demand and cpu */
   11430       /* utilization for the system(s) */
   11431       /* Of course, some of the information might be bogus because */
   11432       /* there was no idle counter in the kernel(s). We need to make */
   11433       /* a note of this for the user's benefit...*/
   11434       if (local_cpu_usage) {
   11435 	local_cpu_utilization = calc_cpu_util(0.0);
   11436 	/* since calc_service demand is doing ms/Kunit we will */
   11437 	/* multiply the number of transaction by 1024 to get */
   11438 	/* "good" numbers */
   11439 	local_service_demand  = calc_service_demand((double) nummessages*1024,
   11440 						    0.0,
   11441 						    0.0,
   11442 						    0);
   11443       }
   11444       else {
   11445 	local_cpu_utilization	= (float) -1.0;
   11446 	local_service_demand	= (float) -1.0;
   11447       }
   11448 
   11449       if (remote_cpu_usage) {
   11450 	remote_cpu_utilization = tcp_rr_result->cpu_util;
   11451 	/* since calc_service demand is doing ms/Kunit we will */
   11452 	/* multiply the number of transaction by 1024 to get */
   11453 	/* "good" numbers */
   11454 	remote_service_demand = calc_service_demand((double) nummessages*1024,
   11455 						    0.0,
   11456 						    remote_cpu_utilization,
   11457 						    tcp_rr_result->num_cpus);
   11458       }
   11459       else {
   11460 	remote_cpu_utilization = (float) -1.0;
   11461 	remote_service_demand  = (float) -1.0;
   11462       }
   11463 
   11464     }
   11465     else {
   11466       /* we were not measuring cpu, for the confidence stuff, we */
   11467       /* should make it -1.0 */
   11468       local_cpu_utilization	= (float) -1.0;
   11469       local_service_demand	= (float) -1.0;
   11470       remote_cpu_utilization = (float) -1.0;
   11471       remote_service_demand  = (float) -1.0;
   11472     }
   11473 
   11474     /* at this point, we want to calculate the confidence information. */
   11475     /* if debugging is on, calculate_confidence will print-out the */
   11476     /* parameters we pass it */
   11477 
   11478     calculate_confidence(confidence_iteration,
   11479 			 elapsed_time,
   11480 			 thruput,
   11481 			 local_cpu_utilization,
   11482 			 remote_cpu_utilization,
   11483 			 local_service_demand,
   11484 			 remote_service_demand);
   11485 
   11486 
   11487     confidence_iteration++;
   11488 
   11489     /* we are now done with the socket, so close it */
   11490     close(send_socket);
   11491 
   11492   }
   11493 
   11494   retrieve_confident_values(&elapsed_time,
   11495 			    &thruput,
   11496 			    &local_cpu_utilization,
   11497 			    &remote_cpu_utilization,
   11498 			    &local_service_demand,
   11499 			    &remote_service_demand);
   11500 
   11501   /* We are now ready to print all the information. If the user */
   11502   /* has specified zero-level verbosity, we will just print the */
   11503   /* local service demand, or the remote service demand. If the */
   11504   /* user has requested verbosity level 1, he will get the basic */
   11505   /* "streamperf" numbers. If the user has specified a verbosity */
   11506   /* of greater than 1, we will display a veritable plethora of */
   11507   /* background information from outside of this block as it it */
   11508   /* not cpu_measurement specific...  */
   11509 
   11510   if (confidence < 0) {
   11511     /* we did not hit confidence, but were we asked to look for it? */
   11512     if (iteration_max > 1) {
   11513       display_confidence();
   11514     }
   11515   }
   11516 
   11517   if (local_cpu_usage || remote_cpu_usage) {
   11518     local_cpu_method = format_cpu_method(cpu_method);
   11519     remote_cpu_method = format_cpu_method(tcp_rr_result->cpu_method);
   11520 
   11521     switch (verbosity) {
   11522     case 0:
   11523       if (local_cpu_usage) {
   11524 	fprintf(where,
   11525 		cpu_fmt_0,
   11526 		local_service_demand,
   11527 		local_cpu_method);
   11528       }
   11529       else {
   11530 	fprintf(where,
   11531 		cpu_fmt_0,
   11532 		remote_service_demand,
   11533 		remote_cpu_method);
   11534       }
   11535       break;
   11536     case 1:
   11537     case 2:
   11538       if (print_headers) {
   11539 	fprintf(where,
   11540 		cpu_title,
   11541 		local_cpu_method,
   11542 		remote_cpu_method);
   11543       }
   11544 
   11545       fprintf(where,
   11546 	      cpu_fmt_1_line_1,		/* the format string */
   11547 	      lss_size,		/* local sendbuf size */
   11548 	      lsr_size,
   11549 	      req_size,		/* how large were the requests */
   11550 	      rsp_size,		/* guess */
   11551 	      elapsed_time,		/* how long was the test */
   11552 	      thruput,
   11553 	      local_cpu_utilization,	/* local cpu */
   11554 	      remote_cpu_utilization,	/* remote cpu */
   11555 	      local_service_demand,	/* local service demand */
   11556 	      remote_service_demand);	/* remote service demand */
   11557       fprintf(where,
   11558 	      cpu_fmt_1_line_2,
   11559 	      rss_size,
   11560 	      rsr_size);
   11561       break;
   11562     }
   11563   }
   11564   else {
   11565     /* The tester did not wish to measure service demand. */
   11566 
   11567     switch (verbosity) {
   11568     case 0:
   11569       fprintf(where,
   11570 	      tput_fmt_0,
   11571 	      thruput);
   11572       break;
   11573     case 1:
   11574     case 2:
   11575       if (print_headers) {
   11576 	fprintf(where,tput_title,format_units());
   11577       }
   11578 
   11579       fprintf(where,
   11580 	      tput_fmt_1_line_1,	/* the format string */
   11581 	      lss_size,
   11582 	      lsr_size,
   11583 	      req_size,		/* how large were the requests */
   11584 	      rsp_size,		/* how large were the responses */
   11585 	      elapsed_time, 		/* how long did it take */
   11586 	      thruput);
   11587       fprintf(where,
   11588 	      tput_fmt_1_line_2,
   11589 	      rss_size, 		/* remote recvbuf size */
   11590 	      rsr_size);
   11591 
   11592       break;
   11593     }
   11594   }
   11595 
   11596   /* it would be a good thing to include information about some of the */
   11597   /* other parameters that may have been set for this test, but at the */
   11598   /* moment, I do not wish to figure-out all the  formatting, so I will */
   11599   /* just put this comment here to help remind me that it is something */
   11600   /* that should be done at a later time. */
   11601 
   11602   /* how to handle the verbose information in the presence of */
   11603   /* confidence intervals is yet to be determined... raj 11/94 */
   11604   if (verbosity > 1) {
   11605     /* The user wanted to know it all, so we will give it to him. */
   11606     /* This information will include as much as we can find about */
   11607     /* TCP statistics, the alignments of the sends and receives */
   11608     /* and all that sort of rot... */
   11609 
   11610     fprintf(where,
   11611 	    ksink_fmt,
   11612 	    local_send_align,
   11613 	    remote_recv_offset,
   11614 	    local_send_offset,
   11615 	    remote_recv_offset);
   11616 
   11617 #ifdef WANT_HISTOGRAM
   11618     fprintf(where,"\nHistogram of request/response times\n");
   11619     fflush(where);
   11620     HIST_report(time_hist);
   11621 #endif /* WANT_HISTOGRAM */
   11622 
   11623   }
   11624 
   11625 }
   11626 
   11627  /* this routine implements the receive (netserver) side of a TCP_RR */
   11629  /* test */
   11630 void
   11631 recv_tcp_nbrr()
   11632 {
   11633 
   11634   struct ring_elt *send_ring;
   11635   struct ring_elt *recv_ring;
   11636 
   11637   struct	sockaddr_in        myaddr_in,
   11638   peeraddr_in;
   11639   SOCKET	s_listen,s_data;
   11640   netperf_socklen_t 	addrlen;
   11641   char	*temp_message_ptr;
   11642   int	trans_received;
   11643   int	trans_remaining;
   11644   int	bytes_sent;
   11645   int	request_bytes_recvd;
   11646   int	request_bytes_remaining;
   11647   int	timed_out = 0;
   11648   float	elapsed_time;
   11649 
   11650   struct addrinfo *local_res;
   11651   char local_name[BUFSIZ];
   11652   char port_buffer[PORTBUFSIZE];
   11653 
   11654   struct	tcp_rr_request_struct	*tcp_rr_request;
   11655   struct	tcp_rr_response_struct	*tcp_rr_response;
   11656   struct	tcp_rr_results_struct	*tcp_rr_results;
   11657 
   11658   tcp_rr_request =
   11659     (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data;
   11660   tcp_rr_response =
   11661     (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data;
   11662   tcp_rr_results =
   11663     (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data;
   11664 
   11665   if (debug) {
   11666     fprintf(where,"netserver: recv_tcp_nbrr: entered...\n");
   11667     fflush(where);
   11668   }
   11669 
   11670   /* We want to set-up the listen socket with all the desired */
   11671   /* parameters and then let the initiator know that all is ready. If */
   11672   /* socket size defaults are to be used, then the initiator will have */
   11673   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   11674   /* send-back what they are. If that information cannot be determined, */
   11675   /* then we send-back -1's for the sizes. If things go wrong for any */
   11676   /* reason, we will drop back ten yards and punt. */
   11677 
   11678   /* If anything goes wrong, we want the remote to know about it. It */
   11679   /* would be best if the error that the remote reports to the user is */
   11680   /* the actual error we encountered, rather than some bogus unexpected */
   11681   /* response type message. */
   11682 
   11683   if (debug) {
   11684     fprintf(where,"recv_tcp_nbrr: setting the response type...\n");
   11685     fflush(where);
   11686   }
   11687 
   11688   netperf_response.content.response_type = TCP_RR_RESPONSE;
   11689 
   11690   if (debug) {
   11691     fprintf(where,"recv_tcp_nbrr: the response type is set...\n");
   11692     fflush(where);
   11693   }
   11694 
   11695   /* allocate the recv and send rings with the requested alignments */
   11696   /* and offsets. raj 7/94 */
   11697   if (debug) {
   11698     fprintf(where,"recv_tcp_nbrr: requested recv alignment of %d offset %d\n",
   11699 	    tcp_rr_request->recv_alignment,
   11700 	    tcp_rr_request->recv_offset);
   11701     fprintf(where,"recv_tcp_nbrr: requested send alignment of %d offset %d\n",
   11702 	    tcp_rr_request->send_alignment,
   11703 	    tcp_rr_request->send_offset);
   11704     fflush(where);
   11705   }
   11706 
   11707   /* at some point, these need to come to us from the remote system */
   11708   if (send_width == 0) send_width = 1;
   11709   if (recv_width == 0) recv_width = 1;
   11710 
   11711   send_ring = allocate_buffer_ring(send_width,
   11712 				   tcp_rr_request->response_size,
   11713 				   tcp_rr_request->send_alignment,
   11714 				   tcp_rr_request->send_offset);
   11715 
   11716   recv_ring = allocate_buffer_ring(recv_width,
   11717 				   tcp_rr_request->request_size,
   11718 				   tcp_rr_request->recv_alignment,
   11719 				   tcp_rr_request->recv_offset);
   11720 
   11721 
   11722   /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */
   11723   /* can put in OUR values !-) At some point, we may want to nail this */
   11724   /* socket to a particular network-level address, but for now, */
   11725   /* INADDR_ANY should be just fine. */
   11726 
   11727   bzero((char *)&myaddr_in,
   11728 	sizeof(myaddr_in));
   11729   myaddr_in.sin_family      = AF_INET;
   11730   myaddr_in.sin_addr.s_addr = INADDR_ANY;
   11731   myaddr_in.sin_port        = htons((unsigned short)tcp_rr_request->port);
   11732 
   11733   /* Grab a socket to listen on, and then listen on it. */
   11734 
   11735   if (debug) {
   11736     fprintf(where,"recv_tcp_nbrr: grabbing a socket...\n");
   11737     fflush(where);
   11738   }
   11739 
   11740   /* create_data_socket expects to find some things in the global */
   11741   /* variables, so set the globals based on the values in the request. */
   11742   /* once the socket has been created, we will set the response values */
   11743   /* based on the updated value of those globals. raj 7/94 */
   11744   lss_size_req = tcp_rr_request->send_buf_size;
   11745   lsr_size_req = tcp_rr_request->recv_buf_size;
   11746   loc_nodelay = tcp_rr_request->no_delay;
   11747   loc_rcvavoid = tcp_rr_request->so_rcvavoid;
   11748   loc_sndavoid = tcp_rr_request->so_sndavoid;
   11749 
   11750   set_hostname_and_port(local_name,
   11751 			port_buffer,
   11752 			nf_to_af(tcp_rr_request->ipfamily),
   11753 			tcp_rr_request->port);
   11754 
   11755   local_res = complete_addrinfo(local_name,
   11756 				local_name,
   11757 				port_buffer,
   11758 				nf_to_af(tcp_rr_request->ipfamily),
   11759 				SOCK_STREAM,
   11760 				IPPROTO_TCP,
   11761 				0);
   11762 
   11763   s_listen = create_data_socket(local_res);
   11764 
   11765   if (s_listen == INVALID_SOCKET) {
   11766     netperf_response.content.serv_errno = errno;
   11767     send_response();
   11768 
   11769     exit(1);
   11770   }
   11771 
   11772   /* Let's get an address assigned to this socket so we can tell the */
   11773   /* initiator how to reach the data socket. There may be a desire to */
   11774   /* nail this socket to a specific IP address in a multi-homed, */
   11775   /* multi-connection situation, but for now, we'll ignore the issue */
   11776   /* and concentrate on single connection testing. */
   11777 
   11778   if (bind(s_listen,
   11779 	   (struct sockaddr *)&myaddr_in,
   11780 	   sizeof(myaddr_in)) == SOCKET_ERROR) {
   11781     netperf_response.content.serv_errno = errno;
   11782     close(s_listen);
   11783     send_response();
   11784 
   11785     exit(1);
   11786   }
   11787 
   11788   /* Now, let's set-up the socket to listen for connections */
   11789   if (listen(s_listen, 5) == SOCKET_ERROR) {
   11790     netperf_response.content.serv_errno = errno;
   11791     close(s_listen);
   11792     send_response();
   11793 
   11794     exit(1);
   11795   }
   11796 
   11797 
   11798   /* now get the port number assigned by the system  */
   11799   addrlen = sizeof(myaddr_in);
   11800   if (getsockname(s_listen,
   11801 		  (struct sockaddr *)&myaddr_in, &addrlen) == SOCKET_ERROR){
   11802     netperf_response.content.serv_errno = errno;
   11803     close(s_listen);
   11804     send_response();
   11805 
   11806     exit(1);
   11807   }
   11808 
   11809   /* Now myaddr_in contains the port and the internet address this is */
   11810   /* returned to the sender also implicitly telling the sender that the */
   11811   /* socket buffer sizing has been done. */
   11812 
   11813   tcp_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port);
   11814   netperf_response.content.serv_errno   = 0;
   11815 
   11816   /* But wait, there's more. If the initiator wanted cpu measurements, */
   11817   /* then we must call the calibrate routine, which will return the max */
   11818   /* rate back to the initiator. If the CPU was not to be measured, or */
   11819   /* something went wrong with the calibration, we will return a 0.0 to */
   11820   /* the initiator. */
   11821 
   11822   tcp_rr_response->cpu_rate = 0.0; 	/* assume no cpu */
   11823   tcp_rr_response->measure_cpu = 0;
   11824 
   11825   if (tcp_rr_request->measure_cpu) {
   11826     tcp_rr_response->measure_cpu = 1;
   11827     tcp_rr_response->cpu_rate = calibrate_local_cpu(tcp_rr_request->cpu_rate);
   11828   }
   11829 
   11830 
   11831   /* before we send the response back to the initiator, pull some of */
   11832   /* the socket parms from the globals */
   11833   tcp_rr_response->send_buf_size = lss_size;
   11834   tcp_rr_response->recv_buf_size = lsr_size;
   11835   tcp_rr_response->no_delay = loc_nodelay;
   11836   tcp_rr_response->so_rcvavoid = loc_rcvavoid;
   11837   tcp_rr_response->so_sndavoid = loc_sndavoid;
   11838   tcp_rr_response->test_length = tcp_rr_request->test_length;
   11839   send_response();
   11840 
   11841   addrlen = sizeof(peeraddr_in);
   11842 
   11843   if ((s_data = accept(s_listen,
   11844 		       (struct sockaddr *)&peeraddr_in,
   11845 		       &addrlen)) == INVALID_SOCKET) {
   11846     /* Let's just punt. The remote will be given some information */
   11847     close(s_listen);
   11848     exit(1);
   11849   }
   11850 
   11851   if (debug) {
   11852     fprintf(where,"recv_tcp_nbrr: accept completes on the data connection.\n");
   11853     fflush(where);
   11854   }
   11855 
   11856 #ifdef KLUDGE_SOCKET_OPTIONS
   11857   /* this is for those systems which *INCORRECTLY* fail to pass */
   11858   /* attributes across an accept() call. Including this goes against */
   11859   /* my better judgement :( raj 11/95 */
   11860 
   11861   kludge_socket_options(s_data);
   11862 
   11863 #endif /* KLUDGE_SOCKET_OPTIONS */
   11864 
   11865   /* now that we are connected, mark the socket as non-blocking */
   11866   if (!set_nonblock(s_data)) {
   11867     close(s_data);
   11868     exit(1);
   11869   }
   11870 
   11871 
   11872   /* Now it's time to start receiving data on the connection. We will */
   11873   /* first grab the apropriate counters and then start grabbing. */
   11874 
   11875   cpu_start(tcp_rr_request->measure_cpu);
   11876 
   11877 #ifdef WIN32
   11878   /* this is used so the timer thread can close the socket out from */
   11879   /* under us, which to date is the easiest/cleanest/least */
   11880   /* Windows-specific way I can find to force the winsock calls to */
   11881   /* return WSAEINTR with the test is over. anything that will run on */
   11882   /* 95 and NT and is closer to what netperf expects from Unix signals */
   11883   /* and such would be appreciated raj 1/96 */
   11884   win_kludge_socket = s_data;
   11885 #endif /* WIN32 */
   11886 
   11887   /* The loop will exit when the sender does a shutdown, which will */
   11888   /* return a length of zero   */
   11889 
   11890   if (tcp_rr_request->test_length > 0) {
   11891     times_up = 0;
   11892     trans_remaining = 0;
   11893     start_timer(tcp_rr_request->test_length + PAD_TIME);
   11894   }
   11895   else {
   11896     times_up = 1;
   11897     trans_remaining = tcp_rr_request->test_length * -1;
   11898   }
   11899 
   11900   trans_received = 0;
   11901 
   11902   while ((!times_up) || (trans_remaining > 0)) {
   11903     temp_message_ptr = recv_ring->buffer_ptr;
   11904     request_bytes_remaining	= tcp_rr_request->request_size;
   11905     while(request_bytes_remaining > 0) {
   11906       if((request_bytes_recvd=recv(s_data,
   11907 				   temp_message_ptr,
   11908 				   request_bytes_remaining,
   11909 				   0)) == SOCKET_ERROR) {
   11910 	    if ( SOCKET_EINTR(request_bytes_recvd))
   11911 		{
   11912 	      /* the timer popped */
   11913 	      timed_out = 1;
   11914 	      break;
   11915 		}
   11916 #ifndef WIN32  // But what does WinNT indicate in this situation...
   11917 	    else if (errno == EAGAIN) {
   11918 	      Set_errno(0);
   11919 	      if (times_up) {
   11920 	        timed_out = 1;
   11921 	        break;
   11922 		  }
   11923 	      continue;
   11924 		}
   11925 #endif
   11926 	    else {
   11927 	      netperf_response.content.serv_errno = errno;
   11928 	      send_response();
   11929 	      exit(1);
   11930 		}
   11931       }
   11932       else {
   11933 	request_bytes_remaining -= request_bytes_recvd;
   11934 	temp_message_ptr  += request_bytes_recvd;
   11935       }
   11936     }
   11937 
   11938     recv_ring = recv_ring->next;
   11939 
   11940     if (timed_out) {
   11941       /* we hit the end of the test based on time - lets */
   11942       /* bail out of here now... */
   11943       fprintf(where,"yo5\n");
   11944       fflush(where);
   11945       break;
   11946     }
   11947 
   11948     /* Now, send the response to the remote */
   11949     if((bytes_sent=send(s_data,
   11950 			send_ring->buffer_ptr,
   11951 			tcp_rr_request->response_size,
   11952 			0)) == SOCKET_ERROR) {
   11953       if (SOCKET_EINTR(bytes_sent)) {
   11954 	/* the test timer has popped */
   11955 	timed_out = 1;
   11956 	fprintf(where,"yo6\n");
   11957 	fflush(where);
   11958 	break;
   11959       }
   11960       netperf_response.content.serv_errno = 992;
   11961       send_response();
   11962       exit(1);
   11963     }
   11964 
   11965     send_ring = send_ring->next;
   11966 
   11967     trans_received++;
   11968     if (trans_remaining) {
   11969       trans_remaining--;
   11970     }
   11971   }
   11972 
   11973 
   11974   /* The loop now exits due to timeout or transaction count being */
   11975   /* reached */
   11976 
   11977   cpu_stop(tcp_rr_request->measure_cpu,&elapsed_time);
   11978 
   11979   stop_timer();
   11980 
   11981   if (timed_out) {
   11982     /* we ended the test by time, which was at least 2 seconds */
   11983     /* longer than we wanted to run. so, we want to subtract */
   11984     /* PAD_TIME from the elapsed_time. */
   11985     elapsed_time -= PAD_TIME;
   11986   }
   11987 
   11988   /* send the results to the sender			*/
   11989 
   11990   if (debug) {
   11991     fprintf(where,
   11992 	    "recv_tcp_nbrr: got %d transactions\n",
   11993 	    trans_received);
   11994     fflush(where);
   11995   }
   11996 
   11997   tcp_rr_results->bytes_received = (trans_received *
   11998 				    (tcp_rr_request->request_size +
   11999 				     tcp_rr_request->response_size));
   12000   tcp_rr_results->trans_received = trans_received;
   12001   tcp_rr_results->elapsed_time   = elapsed_time;
   12002   tcp_rr_results->cpu_method     = cpu_method;
   12003   tcp_rr_results->num_cpus       = lib_num_loc_cpus;
   12004   if (tcp_rr_request->measure_cpu) {
   12005     tcp_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
   12006   }
   12007 
   12008   if (debug) {
   12009     fprintf(where,
   12010 	    "recv_tcp_nbrr: test complete, sending results.\n");
   12011     fflush(where);
   12012   }
   12013 
   12014   /* we are done with the socket, free it */
   12015   close(s_data);
   12016 
   12017   send_response();
   12018 
   12019 }
   12020 
   12021 #endif /* DO_NBRR */
   12022 
   12023 
   12025  /* this test is intended to test the performance of establishing a */
   12026  /* connection, and then closing it again. this test is of somewhat */
   12027  /* arcane interest since no packets are exchanged between the */
   12028  /* user-space processes, but it will show the raw overhead of */
   12029  /* establishing a TCP connection. that service demand could then be */
   12030  /* compared with the sum of the service demands of a TCP_CRR and */
   12031  /* TCP_RR test - presumeably, they would all relate */
   12032 
   12033 void
   12034 send_tcp_cc(char remote_host[])
   12035 {
   12036 
   12037   char *tput_title = "\
   12038 Local /Remote\n\
   12039 Socket Size   Request  Resp.   Elapsed  Trans.\n\
   12040 Send   Recv   Size     Size    Time     Rate         \n\
   12041 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
   12042 
   12043   char *tput_fmt_0 =
   12044     "%7.2f\n";
   12045 
   12046   char *tput_fmt_1_line_1 = "\
   12047 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
   12048   char *tput_fmt_1_line_2 = "\
   12049 %-6d %-6d\n";
   12050 
   12051   char *cpu_title = "\
   12052 Local /Remote\n\
   12053 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
   12054 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
   12055 bytes  bytes  bytes   bytes  secs.   per sec  %%      %%      us/Tr   us/Tr\n\n";
   12056 
   12057   char *cpu_fmt_0 =
   12058     "%6.3f\n";
   12059 
   12060   char *cpu_fmt_1_line_1 = "\
   12061 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f\n";
   12062 
   12063   char *cpu_fmt_1_line_2 = "\
   12064 %-6d %-6d\n";
   12065 
   12066   char *ksink_fmt = "\n\
   12067 Alignment      Offset\n\
   12068 Local  Remote  Local  Remote\n\
   12069 Send   Recv    Send   Recv\n\
   12070 %5d  %5d   %5d  %5d\n";
   12071 
   12072 
   12073   int			timed_out = 0;
   12074   float			elapsed_time;
   12075 
   12076   char	temp_message_ptr[1];
   12077   int	nummessages;
   12078   SOCKET	send_socket;
   12079   int	trans_remaining;
   12080   double	bytes_xferd;
   12081   int	rsp_bytes_left = 1;
   12082   int	rsp_bytes_recvd;
   12083 
   12084   float	local_cpu_utilization;
   12085   float	local_service_demand;
   12086   float	remote_cpu_utilization;
   12087   float	remote_service_demand;
   12088   double	thruput;
   12089 
   12090   struct addrinfo *local_res;
   12091   struct addrinfo *remote_res;
   12092 
   12093   int                           myport;
   12094   int                           ret;
   12095 
   12096   struct	tcp_cc_request_struct	*tcp_cc_request;
   12097   struct	tcp_cc_response_struct	*tcp_cc_response;
   12098   struct	tcp_cc_results_struct	*tcp_cc_result;
   12099 
   12100   tcp_cc_request =
   12101     (struct tcp_cc_request_struct *)netperf_request.content.test_specific_data;
   12102   tcp_cc_response =
   12103     (struct tcp_cc_response_struct *)netperf_response.content.test_specific_data;
   12104   tcp_cc_result =
   12105     (struct tcp_cc_results_struct *)netperf_response.content.test_specific_data;
   12106 
   12107 
   12108 #ifdef WANT_HISTOGRAM
   12109   if (verbosity > 1) {
   12110     time_hist = HIST_new();
   12111   }
   12112 #endif /* WANT_HISTOGRAM */
   12113 
   12114   /* since we are now disconnected from the code that established the */
   12115   /* control socket, and since we want to be able to use different */
   12116   /* protocols and such, we are passed the name of the remote host and */
   12117   /* must turn that into the test specific addressing information. */
   12118 
   12119   complete_addrinfos(&remote_res,
   12120 		     &local_res,
   12121 		     remote_host,
   12122 		     SOCK_STREAM,
   12123 		     IPPROTO_TCP,
   12124 		     0);
   12125 
   12126   if ( print_headers ) {
   12127     print_top_test_header("TCP Connect/Close TEST",local_res,remote_res);
   12128   }
   12129 
   12130   /* initialize a few counters */
   12131 
   12132   nummessages	=	0;
   12133   bytes_xferd	=	0.0;
   12134   times_up 	= 	0;
   12135 
   12136   /* since there are no data buffers in this test, we need no send or */
   12137   /* recv rings */
   12138 
   12139   if (debug) {
   12140     fprintf(where,"send_tcp_cc: send_socket obtained...\n");
   12141   }
   12142 
   12143   /* If the user has requested cpu utilization measurements, we must */
   12144   /* calibrate the cpu(s). We will perform this task within the tests */
   12145   /* themselves. If the user has specified the cpu rate, then */
   12146   /* calibrate_local_cpu will return rather quickly as it will have */
   12147   /* nothing to do. If local_cpu_rate is zero, then we will go through */
   12148   /* all the "normal" calibration stuff and return the rate back.*/
   12149 
   12150   if (local_cpu_usage) {
   12151     local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   12152   }
   12153 
   12154   /* Tell the remote end to do a listen. The server alters the socket */
   12155   /* paramters on the other side at this point, hence the reason for */
   12156   /* all the values being passed in the setup message. If the user did */
   12157   /* not specify any of the parameters, they will be passed as 0, which */
   12158   /* will indicate to the remote that no changes beyond the system's */
   12159   /* default should be used. Alignment is the exception, it will */
   12160   /* default to 8, which will be no alignment alterations. */
   12161 
   12162   netperf_request.content.request_type	=	DO_TCP_CC;
   12163   tcp_cc_request->recv_buf_size	        =	rsr_size_req;
   12164   tcp_cc_request->send_buf_size	        =	rss_size_req;
   12165   tcp_cc_request->recv_alignment	=	remote_recv_align;
   12166   tcp_cc_request->recv_offset	        =	remote_recv_offset;
   12167   tcp_cc_request->send_alignment	=	remote_send_align;
   12168   tcp_cc_request->send_offset	        =	remote_send_offset;
   12169   tcp_cc_request->request_size	        =	req_size;
   12170   tcp_cc_request->response_size	        =	rsp_size;
   12171   tcp_cc_request->no_delay	        =	rem_nodelay;
   12172   tcp_cc_request->measure_cpu	        =	remote_cpu_usage;
   12173   tcp_cc_request->cpu_rate	        =	remote_cpu_rate;
   12174   tcp_cc_request->so_rcvavoid	=	rem_rcvavoid;
   12175   tcp_cc_request->so_sndavoid	=	rem_sndavoid;
   12176   if (test_time) {
   12177     tcp_cc_request->test_length	=	test_time;
   12178   }
   12179   else {
   12180     tcp_cc_request->test_length	=	test_trans * -1;
   12181   }
   12182   tcp_cc_request->port          = atoi(remote_data_port);
   12183   tcp_cc_request->ipfamily  = af_to_nf(remote_res->ai_family);
   12184 
   12185   if (debug > 1) {
   12186     fprintf(where,"netperf: send_tcp_cc: requesting TCP crr test\n");
   12187   }
   12188 
   12189   send_request();
   12190 
   12191   /* The response from the remote will contain all of the relevant 	*/
   12192   /* socket parameters for this test type. We will put them back into 	*/
   12193   /* the variables here so they can be displayed if desired.  The	*/
   12194   /* remote will have calibrated CPU if necessary, and will have done	*/
   12195   /* all the needed set-up we will have calibrated the cpu locally	*/
   12196   /* before sending the request, and will grab the counter value right	*/
   12197   /* after the connect returns. The remote will grab the counter right	*/
   12198   /* after the accept call. This saves the hassle of extra messages	*/
   12199   /* being sent for the TCP tests.					*/
   12200 
   12201   recv_response();
   12202 
   12203   if (!netperf_response.content.serv_errno) {
   12204     rsr_size	=	tcp_cc_response->recv_buf_size;
   12205     rss_size	=	tcp_cc_response->send_buf_size;
   12206     rem_nodelay	=	tcp_cc_response->no_delay;
   12207     remote_cpu_usage=	tcp_cc_response->measure_cpu;
   12208     remote_cpu_rate = 	tcp_cc_response->cpu_rate;
   12209     /* make sure that port numbers are in network order */
   12210     set_port_number(remote_res,(unsigned short)tcp_cc_response->data_port_number);
   12211 
   12212     if (debug) {
   12213       fprintf(where,"remote listen done.\n");
   12214       fprintf(where,"remote port is %d\n",get_port_number(remote_res));
   12215       fflush(where);
   12216     }
   12217   }
   12218   else {
   12219     Set_errno(netperf_response.content.serv_errno);
   12220     fprintf(where,
   12221 	    "netperf: remote error %d",
   12222 	    netperf_response.content.serv_errno);
   12223     perror("");
   12224     fflush(where);
   12225     exit(1);
   12226   }
   12227 
   12228 #ifdef WANT_DEMO
   12229   demo_rr_setup(100);
   12230 #endif
   12231 
   12232   /* pick a nice random spot between client_port_min and */
   12233   /* client_port_max for our initial port number */
   12234   srand(getpid());
   12235   if (client_port_max - client_port_min) {
   12236     myport = client_port_min +
   12237       (rand() % (client_port_max - client_port_min));
   12238   }
   12239   else {
   12240     myport = client_port_min;
   12241   }
   12242   /* there will be a ++ before the first call to bind, so subtract one */
   12243   myport--;
   12244 
   12245   /* Set-up the test end conditions. For a request/response test, they */
   12246   /* can be either time or transaction based. */
   12247 
   12248   if (test_time) {
   12249     /* The user wanted to end the test after a period of time. */
   12250     times_up = 0;
   12251     trans_remaining = 0;
   12252     start_timer(test_time);
   12253   }
   12254   else {
   12255     /* The tester wanted to send a number of bytes. */
   12256     trans_remaining = test_bytes;
   12257     times_up = 1;
   12258   }
   12259 
   12260   /* The cpu_start routine will grab the current time and possibly */
   12261   /* value of the idle counter for later use in measuring cpu */
   12262   /* utilization and/or service demand and thruput. */
   12263 
   12264   cpu_start(local_cpu_usage);
   12265 
   12266 #ifdef WANT_DEMO
   12267   if (demo_mode) {
   12268     demo_first_timestamp();
   12269   }
   12270 #endif
   12271 
   12272   /* We use an "OR" to control test execution. When the test is */
   12273   /* controlled by time, the byte count check will always return false. */
   12274   /* When the test is controlled by byte count, the time test will */
   12275   /* always return false. When the test is finished, the whole */
   12276   /* expression will go false and we will stop sending data. I think I */
   12277   /* just arbitrarily decrement trans_remaining for the timed test, but */
   12278   /* will not do that just yet... One other question is whether or not */
   12279   /* the send buffer and the receive buffer should be the same buffer. */
   12280 
   12281   while ((!times_up) || (trans_remaining > 0)) {
   12282 
   12283 #ifdef WANT_HISTOGRAM
   12284     if (verbosity > 1) {
   12285       /* timestamp just before our call to create the socket, and then */
   12286       /* again just after the receive raj 3/95 */
   12287       HIST_timestamp(&time_one);
   12288     }
   12289 #endif /* WANT_HISTOGRAM */
   12290 
   12291     /* set up the data socket */
   12292     /* newport: is this label really required any longer? */
   12293     /* pick a new port number */
   12294     myport++;
   12295 
   12296     /* wrap the port number when we get to client_port_max. NOTE, some */
   12297     /* broken TCP's might treat the port number as a signed 16 bit */
   12298     /* quantity.  we aren't interested in testing such broken */
   12299     /* implementations :) so we won't make sure that it is below 32767 */
   12300     /* raj 8/94  */
   12301     if (myport >= client_port_max) {
   12302       myport = client_port_min;
   12303     }
   12304 
   12305     /* we do not want to use the port number that the server is */
   12306     /* sitting at - this would cause us to fail in a loopback test. we */
   12307     /* could just rely on the failure of the bind to get us past this, */
   12308     /* but I'm guessing that in this one case at least, it is much */
   12309     /* faster, given that we *know* that port number is already in use */
   12310     /* (or rather would be in a loopback test) */
   12311 
   12312     if (myport == get_port_number(remote_res)) myport++;
   12313 
   12314     if (debug) {
   12315       if ((nummessages % 100) == 0) {
   12316 	printf("port %d\n",myport);
   12317       }
   12318     }
   12319     set_port_number(local_res, (unsigned short)myport);
   12320     send_socket = create_data_socket(local_res);
   12321 
   12322     if (send_socket == INVALID_SOCKET) {
   12323       perror("netperf: send_tcp_cc: tcp stream data socket");
   12324       exit(1);
   12325     }
   12326 
   12327 #ifdef WIN32
   12328     /* this is used so the timer thread can close the socket out from */
   12329     /* under us, which to date is the easiest/cleanest/least */
   12330     /* Windows-specific way I can find to force the winsock calls to */
   12331     /* return WSAEINTR with the test is over. anything that will run on */
   12332     /* 95 and NT and is closer to what netperf expects from Unix signals */
   12333     /* and such would be appreciated raj 1/96 */
   12334     win_kludge_socket = send_socket;
   12335 #endif /* WIN32 */
   12336 
   12337     /* we used to have a call to bind() here, but that is being
   12338        taken care of by create_data_socket(). raj 2005-02-08 */
   12339 
   12340     /* Connect up to the remote port on the data socket  */
   12341     if ((ret = connect(send_socket,
   12342 		       remote_res->ai_addr,
   12343 		       remote_res->ai_addrlen)) == INVALID_SOCKET){
   12344       if (SOCKET_EINTR(ret))
   12345 	  {
   12346 	    /* we hit the end of a */
   12347 	    /* timed test. */
   12348 	    timed_out = 1;
   12349 	    break;
   12350       }
   12351       perror("netperf: data socket connect failed");
   12352       printf("\tattempted to connect on socket %d to port %d",
   12353 	     send_socket,
   12354 	     get_port_number(remote_res));
   12355       printf(" from port %u \n",get_port_number(local_res));
   12356       exit(1);
   12357     }
   12358 
   12359     /* we hang in a recv() to get the remote's close indication */
   12360 
   12361     rsp_bytes_recvd=recv(send_socket,
   12362 			 temp_message_ptr,
   12363 			 rsp_bytes_left,
   12364 			 0);
   12365 
   12366 
   12367     if (rsp_bytes_recvd == 0) {
   12368       /* connection close, call close. we assume that the requisite */
   12369       /* number of bytes have been received */
   12370 
   12371 #ifdef WANT_HISTOGRAM
   12372       if (verbosity > 1) {
   12373 	HIST_timestamp(&time_two);
   12374 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   12375       }
   12376 #endif /* WANT_HISTOGRAM */
   12377 
   12378 #ifdef WANT_DEMO
   12379       demo_rr_interval(1);
   12380 #endif
   12381 
   12382       nummessages++;
   12383       if (trans_remaining) {
   12384 	trans_remaining--;
   12385       }
   12386 
   12387       if (debug > 3) {
   12388 	fprintf(where,
   12389 		"Transaction %d completed on local port %u\n",
   12390 		nummessages,
   12391 		get_port_number(local_res));
   12392 	fflush(where);
   12393       }
   12394 
   12395       close(send_socket);
   12396 
   12397     }
   12398     else {
   12399       /* it was less than zero - an error occured */
   12400       if (SOCKET_EINTR(rsp_bytes_recvd))
   12401 	  {
   12402 	    /* We hit the end of a timed test. */
   12403 	    timed_out = 1;
   12404 	    break;
   12405 	  }
   12406 	  perror("send_tcp_cc: data recv error");
   12407 	  exit(1);
   12408     }
   12409 
   12410   }
   12411 
   12412 
   12413   /* this call will always give us the elapsed time for the test, and */
   12414   /* will also store-away the necessaries for cpu utilization */
   12415 
   12416   cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being measured? */
   12417   /* how long did we really run? */
   12418 
   12419   /* Get the statistics from the remote end. The remote will have */
   12420   /* calculated service demand and all those interesting things. If it */
   12421   /* wasn't supposed to care, it will return obvious values. */
   12422 
   12423   recv_response();
   12424   if (!netperf_response.content.serv_errno) {
   12425     if (debug)
   12426       fprintf(where,"remote results obtained\n");
   12427   }
   12428   else {
   12429     Set_errno(netperf_response.content.serv_errno);
   12430     fprintf(where,
   12431 	    "netperf: remote error %d",
   12432 	     netperf_response.content.serv_errno);
   12433     perror("");
   12434     fflush(where);
   12435 
   12436     exit(1);
   12437   }
   12438 
   12439   /* We now calculate what our thruput was for the test. In the future, */
   12440   /* we may want to include a calculation of the thruput measured by */
   12441   /* the remote, but it should be the case that for a TCP stream test, */
   12442   /* that the two numbers should be *very* close... We calculate */
   12443   /* bytes_sent regardless of the way the test length was controlled. */
   12444   /* If it was time, we needed to, and if it was by bytes, the user may */
   12445   /* have specified a number of bytes that wasn't a multiple of the */
   12446   /* send_size, so we really didn't send what he asked for ;-) We use */
   12447   /* Kbytes/s as the units of thruput for a TCP stream test, where K = */
   12448   /* 1024. A future enhancement *might* be to choose from a couple of */
   12449   /* unit selections. */
   12450 
   12451   bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
   12452   thruput	= calc_thruput(bytes_xferd);
   12453 
   12454   if (local_cpu_usage || remote_cpu_usage) {
   12455     /* We must now do a little math for service demand and cpu */
   12456     /* utilization for the system(s) */
   12457     /* Of course, some of the information might be bogus because */
   12458     /* there was no idle counter in the kernel(s). We need to make */
   12459     /* a note of this for the user's benefit...*/
   12460     if (local_cpu_usage) {
   12461       if (local_cpu_rate == 0.0) {
   12462 	fprintf(where,"WARNING WARNING WARNING  WARNING WARNING WARNING  WARNING!\n");
   12463 	fprintf(where,"Local CPU usage numbers based on process information only!\n");
   12464 	fflush(where);
   12465       }
   12466       local_cpu_utilization = calc_cpu_util(0.0);
   12467       /* since calc_service demand is doing ms/Kunit we will */
   12468       /* multiply the number of transaction by 1024 to get */
   12469       /* "good" numbers */
   12470       local_service_demand  = calc_service_demand((double) nummessages*1024,
   12471 						  0.0,
   12472 						  0.0,
   12473 						  0);
   12474     }
   12475     else {
   12476       local_cpu_utilization	= (float) -1.0;
   12477       local_service_demand	= (float) -1.0;
   12478     }
   12479 
   12480     if (remote_cpu_usage) {
   12481       if (remote_cpu_rate == 0.0) {
   12482 	fprintf(where,"DANGER  DANGER  DANGER    DANGER  DANGER  DANGER    DANGER!\n");
   12483 	fprintf(where,"Remote CPU usage numbers based on process information only!\n");
   12484 	fflush(where);
   12485       }
   12486       remote_cpu_utilization = tcp_cc_result->cpu_util;
   12487       /* since calc_service demand is doing ms/Kunit we will */
   12488       /* multiply the number of transaction by 1024 to get */
   12489       /* "good" numbers */
   12490       remote_service_demand = calc_service_demand((double) nummessages*1024,
   12491 						  0.0,
   12492 						  remote_cpu_utilization,
   12493 						  tcp_cc_result->num_cpus);
   12494     }
   12495     else {
   12496       remote_cpu_utilization = (float) -1.0;
   12497       remote_service_demand  = (float) -1.0;
   12498     }
   12499 
   12500     /* We are now ready to print all the information. If the user */
   12501     /* has specified zero-level verbosity, we will just print the */
   12502     /* local service demand, or the remote service demand. If the */
   12503     /* user has requested verbosity level 1, he will get the basic */
   12504     /* "streamperf" numbers. If the user has specified a verbosity */
   12505     /* of greater than 1, we will display a veritable plethora of */
   12506     /* background information from outside of this block as it it */
   12507     /* not cpu_measurement specific...  */
   12508 
   12509     switch (verbosity) {
   12510     case 0:
   12511       if (local_cpu_usage) {
   12512 	fprintf(where,
   12513 		cpu_fmt_0,
   12514 		local_service_demand);
   12515       }
   12516       else {
   12517 	fprintf(where,
   12518 		cpu_fmt_0,
   12519 		remote_service_demand);
   12520       }
   12521       break;
   12522     case 1:
   12523     case 2:
   12524 
   12525       if (print_headers) {
   12526 	fprintf(where,
   12527 		cpu_title,
   12528 		local_cpu_method,
   12529 		remote_cpu_method);
   12530       }
   12531 
   12532       fprintf(where,
   12533 	      cpu_fmt_1_line_1,		/* the format string */
   12534 	      lss_size,		/* local sendbuf size */
   12535 	      lsr_size,
   12536 	      req_size,		/* how large were the requests */
   12537 	      rsp_size,		/* guess */
   12538 	      elapsed_time,		/* how long was the test */
   12539 	      nummessages/elapsed_time,
   12540 	      local_cpu_utilization,	/* local cpu */
   12541 	      remote_cpu_utilization,	/* remote cpu */
   12542 	      local_service_demand,	/* local service demand */
   12543 	      remote_service_demand);	/* remote service demand */
   12544       fprintf(where,
   12545 	      cpu_fmt_1_line_2,
   12546 	      rss_size,
   12547 	      rsr_size);
   12548       break;
   12549     }
   12550   }
   12551   else {
   12552     /* The tester did not wish to measure service demand. */
   12553     switch (verbosity) {
   12554     case 0:
   12555       fprintf(where,
   12556 	      tput_fmt_0,
   12557 	      nummessages/elapsed_time);
   12558       break;
   12559     case 1:
   12560     case 2:
   12561       if (print_headers) {
   12562 	fprintf(where,tput_title,format_units());
   12563       }
   12564 
   12565       fprintf(where,
   12566 	      tput_fmt_1_line_1,	/* the format string */
   12567 	      lss_size,
   12568 	      lsr_size,
   12569 	      req_size,		/* how large were the requests */
   12570 	      rsp_size,		/* how large were the responses */
   12571 	      elapsed_time, 		/* how long did it take */
   12572 	      nummessages/elapsed_time);
   12573       fprintf(where,
   12574 	      tput_fmt_1_line_2,
   12575 	      rss_size, 		/* remote recvbuf size */
   12576 	      rsr_size);
   12577 
   12578       break;
   12579     }
   12580   }
   12581 
   12582   /* it would be a good thing to include information about some of the */
   12583   /* other parameters that may have been set for this test, but at the */
   12584   /* moment, I do not wish to figure-out all the  formatting, so I will */
   12585   /* just put this comment here to help remind me that it is something */
   12586   /* that should be done at a later time. */
   12587 
   12588   if (verbosity > 1) {
   12589     /* The user wanted to know it all, so we will give it to him. */
   12590     /* This information will include as much as we can find about */
   12591     /* TCP statistics, the alignments of the sends and receives */
   12592     /* and all that sort of rot... */
   12593 
   12594     fprintf(where,
   12595 	    ksink_fmt,
   12596 	    local_send_align,
   12597 	    remote_recv_offset,
   12598 	    local_send_offset,
   12599 	    remote_recv_offset);
   12600 
   12601 #ifdef WANT_HISTOGRAM
   12602     fprintf(where,"\nHistogram of request/response times\n");
   12603     fflush(where);
   12604     HIST_report(time_hist);
   12605 #endif /* WANT_HISTOGRAM */
   12606 
   12607   }
   12608 
   12609 }
   12610 
   12611 
   12612 void
   12614 recv_tcp_cc()
   12615 {
   12616 
   12617   char  *message;
   12618 
   12619   struct addrinfo *local_res;
   12620   char local_name[BUFSIZ];
   12621   char port_buffer[PORTBUFSIZE];
   12622 
   12623   struct	sockaddr_storage        myaddr_in,  peeraddr_in;
   12624   SOCKET	s_listen,s_data;
   12625   netperf_socklen_t 	addrlen;
   12626   char	*recv_message_ptr;
   12627   char	*send_message_ptr;
   12628   int	trans_received;
   12629   int	trans_remaining;
   12630   int	timed_out = 0;
   12631   float	elapsed_time;
   12632 
   12633   struct	tcp_cc_request_struct	*tcp_cc_request;
   12634   struct	tcp_cc_response_struct	*tcp_cc_response;
   12635   struct	tcp_cc_results_struct	*tcp_cc_results;
   12636 
   12637   tcp_cc_request =
   12638     (struct tcp_cc_request_struct *)netperf_request.content.test_specific_data;
   12639   tcp_cc_response =
   12640     (struct tcp_cc_response_struct *)netperf_response.content.test_specific_data;
   12641   tcp_cc_results =
   12642     (struct tcp_cc_results_struct *)netperf_response.content.test_specific_data;
   12643 
   12644   if (debug) {
   12645     fprintf(where,"netserver: recv_tcp_cc: entered...\n");
   12646     fflush(where);
   12647   }
   12648 
   12649   /* We want to set-up the listen socket with all the desired */
   12650   /* parameters and then let the initiator know that all is ready. If */
   12651   /* socket size defaults are to be used, then the initiator will have */
   12652   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   12653   /* send-back what they are. If that information cannot be determined, */
   12654   /* then we send-back -1's for the sizes. If things go wrong for any */
   12655   /* reason, we will drop back ten yards and punt. */
   12656 
   12657   /* If anything goes wrong, we want the remote to know about it. It */
   12658   /* would be best if the error that the remote reports to the user is */
   12659   /* the actual error we encountered, rather than some bogus unexpected */
   12660   /* response type message. */
   12661 
   12662   if (debug) {
   12663     fprintf(where,"recv_tcp_cc: setting the response type...\n");
   12664     fflush(where);
   12665   }
   12666 
   12667   netperf_response.content.response_type = TCP_CC_RESPONSE;
   12668 
   12669   if (debug) {
   12670     fprintf(where,"recv_tcp_cc: the response type is set...\n");
   12671     fflush(where);
   12672   }
   12673 
   12674   /* set-up the data buffer with the requested alignment and offset */
   12675   message = (char *)malloc(DATABUFFERLEN);
   12676   if (message == NULL) {
   12677     printf("malloc(%d) failed!\n", DATABUFFERLEN);
   12678     exit(1);
   12679   }
   12680 
   12681   /* We now alter the message_ptr variables to be at the desired */
   12682   /* alignments with the desired offsets. */
   12683 
   12684   if (debug) {
   12685     fprintf(where,
   12686 	    "recv_tcp_cc: requested recv alignment of %d offset %d\n",
   12687 	    tcp_cc_request->recv_alignment,
   12688 	    tcp_cc_request->recv_offset);
   12689     fprintf(where,
   12690 	    "recv_tcp_cc: requested send alignment of %d offset %d\n",
   12691 	    tcp_cc_request->send_alignment,
   12692 	    tcp_cc_request->send_offset);
   12693     fflush(where);
   12694   }
   12695 
   12696   recv_message_ptr = ALIGN_BUFFER(message, tcp_cc_request->recv_alignment, tcp_cc_request->recv_offset);
   12697 
   12698   send_message_ptr = ALIGN_BUFFER(message, tcp_cc_request->send_alignment, tcp_cc_request->send_offset);
   12699 
   12700   if (debug) {
   12701     fprintf(where,"recv_tcp_cc: receive alignment and offset set...\n");
   12702     fflush(where);
   12703   }
   12704 
   12705   /* Grab a socket to listen on, and then listen on it. */
   12706 
   12707   if (debug) {
   12708     fprintf(where,"recv_tcp_cc: grabbing a socket...\n");
   12709     fflush(where);
   12710   }
   12711 
   12712   /* create_data_socket expects to find some things in the global */
   12713   /* variables, so set the globals based on the values in the request. */
   12714   /* once the socket has been created, we will set the response values */
   12715   /* based on the updated value of those globals. raj 7/94 */
   12716   lss_size_req = tcp_cc_request->send_buf_size;
   12717   lsr_size_req = tcp_cc_request->recv_buf_size;
   12718   loc_nodelay = tcp_cc_request->no_delay;
   12719   loc_rcvavoid = tcp_cc_request->so_rcvavoid;
   12720   loc_sndavoid = tcp_cc_request->so_sndavoid;
   12721 
   12722   set_hostname_and_port(local_name,
   12723 			port_buffer,
   12724 			nf_to_af(tcp_cc_request->ipfamily),
   12725 			tcp_cc_request->port);
   12726 
   12727   local_res = complete_addrinfo(local_name,
   12728 				local_name,
   12729 				port_buffer,
   12730 				nf_to_af(tcp_cc_request->ipfamily),
   12731 				SOCK_STREAM,
   12732 				IPPROTO_TCP,
   12733 				0);
   12734 
   12735   s_listen = create_data_socket(local_res);
   12736 
   12737   if (s_listen == INVALID_SOCKET) {
   12738     netperf_response.content.serv_errno = errno;
   12739     send_response();
   12740     if (debug) {
   12741       fprintf(where,"could not create data socket\n");
   12742       fflush(where);
   12743     }
   12744     exit(1);
   12745   }
   12746 
   12747 #ifdef WIN32
   12748   /* The test timer can fire during operations on the listening socket,
   12749      so to make the start_timer below work we have to move
   12750      it to close s_listen while we are blocked on accept. */
   12751   win_kludge_socket2 = s_listen;
   12752 #endif
   12753 
   12754 
   12755   /* Now, let's set-up the socket to listen for connections */
   12756   if (listen(s_listen, 5) == SOCKET_ERROR) {
   12757     netperf_response.content.serv_errno = errno;
   12758     close(s_listen);
   12759     send_response();
   12760     if (debug) {
   12761       fprintf(where,"could not listen\n");
   12762       fflush(where);
   12763     }
   12764     exit(1);
   12765   }
   12766 
   12767   /* now get the port number assigned by the system  */
   12768   addrlen = sizeof(myaddr_in);
   12769   if (getsockname(s_listen,
   12770 		  (struct sockaddr *)&myaddr_in,
   12771 		  &addrlen) == SOCKET_ERROR){
   12772     netperf_response.content.serv_errno = errno;
   12773     close(s_listen);
   12774     send_response();
   12775     if (debug) {
   12776       fprintf(where,"could not geetsockname\n");
   12777       fflush(where);
   12778     }
   12779     exit(1);
   12780   }
   12781 
   12782   /* Now myaddr_in contains the port and the internet address this is */
   12783   /* returned to the sender also implicitly telling the sender that the */
   12784   /* socket buffer sizing has been done. */
   12785 
   12786   tcp_cc_response->data_port_number =
   12787     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
   12788   if (debug) {
   12789     fprintf(where,"telling the remote to call me at %d\n",
   12790 	    tcp_cc_response->data_port_number);
   12791     fflush(where);
   12792   }
   12793   netperf_response.content.serv_errno   = 0;
   12794 
   12795   /* But wait, there's more. If the initiator wanted cpu measurements, */
   12796   /* then we must call the calibrate routine, which will return the max */
   12797   /* rate back to the initiator. If the CPU was not to be measured, or */
   12798   /* something went wrong with the calibration, we will return a 0.0 to */
   12799   /* the initiator. */
   12800 
   12801   tcp_cc_response->cpu_rate = (float)0.0; 	/* assume no cpu */
   12802   if (tcp_cc_request->measure_cpu) {
   12803     tcp_cc_response->measure_cpu = 1;
   12804     tcp_cc_response->cpu_rate =
   12805       calibrate_local_cpu(tcp_cc_request->cpu_rate);
   12806   }
   12807 
   12808 
   12809 
   12810   /* before we send the response back to the initiator, pull some of */
   12811   /* the socket parms from the globals */
   12812   tcp_cc_response->send_buf_size = lss_size;
   12813   tcp_cc_response->recv_buf_size = lsr_size;
   12814   tcp_cc_response->no_delay = loc_nodelay;
   12815   tcp_cc_response->so_rcvavoid = loc_rcvavoid;
   12816   tcp_cc_response->so_sndavoid = loc_sndavoid;
   12817 
   12818   send_response();
   12819 
   12820   addrlen = sizeof(peeraddr_in);
   12821 
   12822   /* Now it's time to start receiving data on the connection. We will */
   12823   /* first grab the apropriate counters and then start grabbing. */
   12824 
   12825   cpu_start(tcp_cc_request->measure_cpu);
   12826 
   12827   /* The loop will exit when the sender does a shutdown, which will */
   12828   /* return a length of zero   */
   12829 
   12830   if (tcp_cc_request->test_length > 0) {
   12831     times_up = 0;
   12832     trans_remaining = 0;
   12833     start_timer(tcp_cc_request->test_length + PAD_TIME);
   12834   }
   12835   else {
   12836     times_up = 1;
   12837     trans_remaining = tcp_cc_request->test_length * -1;
   12838   }
   12839 
   12840   trans_received = 0;
   12841 
   12842   while ((!times_up) || (trans_remaining > 0)) {
   12843 #ifdef WIN32
   12844     /* The test timer will probably fire during this accept,
   12845        so to make the start_timer above work we have to move
   12846        it to close s_listen while we are blocked on accept. */
   12847     win_kludge_socket = s_listen;
   12848 #endif
   12849     /* accept a connection from the remote */
   12850     if ((s_data=accept(s_listen,
   12851 		       (struct sockaddr *)&peeraddr_in,
   12852 		       &addrlen)) == INVALID_SOCKET) {
   12853       if (errno == EINTR) {
   12854 	/* the timer popped */
   12855 	timed_out = 1;
   12856 	break;
   12857       }
   12858       fprintf(where,"recv_tcp_cc: accept: errno = %d\n",errno);
   12859       fflush(where);
   12860       close(s_listen);
   12861 
   12862       exit(1);
   12863     }
   12864 
   12865 #ifdef KLUDGE_SOCKET_OPTIONS
   12866     /* this is for those systems which *INCORRECTLY* fail to pass */
   12867     /* attributes across an accept() call. Including this goes against */
   12868     /* my better judgement :( raj 11/95 */
   12869 
   12870     kludge_socket_options(s_data);
   12871 
   12872 #endif /* KLUDGE_SOCKET_OPTIONS */
   12873 
   12874 #ifdef WIN32
   12875   /* this is used so the timer thread can close the socket out from */
   12876   /* under us, which to date is the easiest/cleanest/least */
   12877   /* Windows-specific way I can find to force the winsock calls to */
   12878   /* return WSAEINTR with the test is over. anything that will run on */
   12879   /* 95 and NT and is closer to what netperf expects from Unix signals */
   12880   /* and such would be appreciated raj 1/96 */
   12881   win_kludge_socket = s_data;
   12882 #endif /* WIN32 */
   12883 
   12884     if (debug) {
   12885       fprintf(where,"recv_tcp_cc: accepted data connection.\n");
   12886       fflush(where);
   12887     }
   12888 
   12889 
   12890     /* close the connection. the server will likely do a graceful */
   12891     /* close of the connection, insuring that all data has arrived at */
   12892     /* the client. for this it will call shutdown(), and then recv() and */
   12893     /* then close(). I'm reasonably confident that this is the */
   12894     /* appropriate sequence of calls - I would like to hear of */
   12895     /* examples in web servers to the contrary. raj 10/95*/
   12896     close(s_data);
   12897 
   12898     trans_received++;
   12899     if (trans_remaining) {
   12900       trans_remaining--;
   12901     }
   12902 
   12903     if (debug) {
   12904       fprintf(where,
   12905 	      "recv_tcp_cc: Transaction %d complete\n",
   12906 	      trans_received);
   12907       fflush(where);
   12908     }
   12909 
   12910   }
   12911 
   12912 
   12913   /* The loop now exits due to timeout or transaction count being */
   12914   /* reached */
   12915 
   12916   cpu_stop(tcp_cc_request->measure_cpu,&elapsed_time);
   12917 
   12918   if (timed_out) {
   12919     /* we ended the test by time, which was at least 2 seconds */
   12920     /* longer than we wanted to run. so, we want to subtract */
   12921     /* PAD_TIME from the elapsed_time. */
   12922     elapsed_time -= PAD_TIME;
   12923   }
   12924   /* send the results to the sender			*/
   12925 
   12926   if (debug) {
   12927     fprintf(where,
   12928 	    "recv_tcp_cc: got %d transactions\n",
   12929 	    trans_received);
   12930     fflush(where);
   12931   }
   12932 
   12933   tcp_cc_results->bytes_received = (trans_received *
   12934 				    (tcp_cc_request->request_size +
   12935 				     tcp_cc_request->response_size));
   12936   tcp_cc_results->trans_received = trans_received;
   12937   tcp_cc_results->elapsed_time	 = elapsed_time;
   12938   tcp_cc_results->num_cpus       = lib_num_loc_cpus;
   12939   if (tcp_cc_request->measure_cpu) {
   12940     tcp_cc_results->cpu_util	= calc_cpu_util(elapsed_time);
   12941   }
   12942 
   12943   if (debug) {
   12944     fprintf(where,
   12945 	    "recv_tcp_cc: test complete, sending results.\n");
   12946     fflush(where);
   12947   }
   12948 
   12949   send_response();
   12950 
   12951 }
   12952 
   12953 void
   12955 print_sockets_usage()
   12956 {
   12957 
   12958   fwrite(sockets_usage, sizeof(char), strlen(sockets_usage), stdout);
   12959   exit(1);
   12960 
   12961 }
   12962 
   12963 void
   12964 scan_sockets_args(int argc, char *argv[])
   12965 
   12966 {
   12967 
   12968 #define SOCKETS_ARGS "b:CDnNhH:L:m:M:p:P:r:R:s:S:T:Vw:W:z46"
   12969 
   12970   extern char	*optarg;	  /* pointer to option string	*/
   12971 
   12972   int		c;
   12973 
   12974   char
   12975     arg1[BUFSIZ],  /* argument holders		*/
   12976     arg2[BUFSIZ];
   12977 
   12978   if (debug) {
   12979     int i;
   12980     printf("%s called with the following argument vector\n",
   12981 #if _MSC_VER <= 1200
   12982 	   "scan_sockets_args");
   12983 #else
   12984 	   __func__);
   12985 #endif
   12986     for (i = 0; i< argc; i++) {
   12987       printf("%s ",argv[i]);
   12988     }
   12989     printf("\n");
   12990   }
   12991 
   12992   strncpy(local_data_port,"0",sizeof(local_data_port));
   12993   strncpy(remote_data_port,"0",sizeof(remote_data_port));
   12994 
   12995   /* by default, only a UDP_STREAM test disallows routing, to cover
   12996      the backsides of incompetent testers who have bogus setups */
   12997   if (strcasecmp(test_name,"UDP_STREAM") == 0) {
   12998     routing_allowed = 0;
   12999   }
   13000 
   13001   /* Go through all the command line arguments and break them */
   13002   /* out. For those options that take two parms, specifying only */
   13003   /* the first will set both to that value. Specifying only the */
   13004   /* second will leave the first untouched. To change only the */
   13005   /* first, use the form "first," (see the routine break_args.. */
   13006 
   13007   while ((c= getopt(argc, argv, SOCKETS_ARGS)) != EOF) {
   13008     switch (c) {
   13009     case '?':
   13010     case '4':
   13011       remote_data_family = AF_INET;
   13012       local_data_family = AF_INET;
   13013       break;
   13014     case '6':
   13015 #if defined(AF_INET6)
   13016       remote_data_family = AF_INET6;
   13017       local_data_family = AF_INET6;
   13018 #else
   13019       fprintf(stderr,
   13020 	      "This netperf was not compiled on an IPv6 capable host!\n");
   13021       fflush(stderr);
   13022       exit(-1);
   13023 #endif
   13024       break;
   13025     case 'h':
   13026       print_sockets_usage();
   13027       exit(1);
   13028     case 'b':
   13029 #ifdef WANT_FIRST_BURST
   13030       first_burst_size = atoi(optarg);
   13031 #else /* WANT_FIRST_BURST */
   13032       printf("Initial request burst functionality not compiled-in!\n");
   13033 #endif /* WANT_FIRST_BURST */
   13034       break;
   13035     case 'C':
   13036 #ifdef TCP_CORK
   13037       /* set TCP_CORK */
   13038       loc_tcpcork = 1;
   13039       rem_tcpcork = 1; /* however, at first, we ony have cork affect loc */
   13040 #else
   13041       printf("WARNING: TCP_CORK not available on this platform!\n");
   13042 #endif /* TCP_CORK */
   13043       break;
   13044     case 'D':
   13045       /* set the TCP nodelay flag */
   13046       loc_nodelay = 1;
   13047       rem_nodelay = 1;
   13048       break;
   13049     case 'H':
   13050       break_args_explicit(optarg,arg1,arg2);
   13051       if (arg1[0]) {
   13052 	/* make sure we leave room for the NULL termination boys and
   13053 	   girls. raj 2005-02-82 */
   13054 	remote_data_address = malloc(strlen(arg1)+1);
   13055 	strncpy(remote_data_address,arg1,strlen(arg1));
   13056       }
   13057       if (arg2[0])
   13058 	remote_data_family = parse_address_family(arg2);
   13059       break;
   13060     case 'L':
   13061       break_args_explicit(optarg,arg1,arg2);
   13062       if (arg1[0]) {
   13063 	/* make sure we leave room for the NULL termination boys and
   13064 	   girls. raj 2005-02-82 */
   13065 	local_data_address = malloc(strlen(arg1)+1);
   13066 	strncpy(local_data_address,arg1,strlen(arg1));
   13067       }
   13068       if (arg2[0])
   13069 	local_data_family = parse_address_family(arg2);
   13070       break;
   13071     case 's':
   13072       /* set local socket sizes */
   13073       break_args(optarg,arg1,arg2);
   13074       if (arg1[0])
   13075 	lss_size_req = convert(arg1);
   13076       if (arg2[0])
   13077 	lsr_size_req = convert(arg2);
   13078       break;
   13079     case 'S':
   13080       /* set remote socket sizes */
   13081       break_args(optarg,arg1,arg2);
   13082       if (arg1[0])
   13083 	rss_size_req = convert(arg1);
   13084       if (arg2[0])
   13085 	rsr_size_req = convert(arg2);
   13086       break;
   13087     case 'r':
   13088       /* set the request/response sizes */
   13089       break_args(optarg,arg1,arg2);
   13090       if (arg1[0])
   13091 	req_size = convert(arg1);
   13092       if (arg2[0])
   13093 	rsp_size = convert(arg2);
   13094       break;
   13095     case 'R':
   13096       /* enable/disable routing on the data connection*/
   13097       routing_allowed = atoi(optarg);
   13098       break;
   13099     case 'm':
   13100       /* set the send size */
   13101       send_size = convert(optarg);
   13102       break;
   13103     case 'M':
   13104       /* set the recv size */
   13105       recv_size = convert(optarg);
   13106       break;
   13107     case 'n':
   13108       /* set the local socket type*/
   13109       local_connected = 1;
   13110       break;
   13111     case 'N':
   13112       /* set the remote socket type*/
   13113       remote_connected = 1;
   13114       break;
   13115     case 'p':
   13116       /* set the min and max port numbers for the TCP_CRR and TCP_TRR */
   13117       /* tests. */
   13118       break_args(optarg,arg1,arg2);
   13119       if (arg1[0])
   13120 	client_port_min = atoi(arg1);
   13121       if (arg2[0])
   13122 	client_port_max = atoi(arg2);
   13123       break;
   13124     case 'P':
   13125       /* set the local and remote data port numbers for the tests to
   13126 	 allow them to run through those blankety blank end-to-end
   13127 	 breaking firewalls. raj 2004-06-15 */
   13128       break_args(optarg,arg1,arg2);
   13129       if (arg1[0])
   13130 	strncpy(local_data_port,arg1,sizeof(local_data_port));
   13131       if (arg2[0])
   13132 	strncpy(remote_data_port,arg2,sizeof(remote_data_port));
   13133       break;
   13134     case 't':
   13135       /* set the test name */
   13136       strcpy(test_name,optarg);
   13137       break;
   13138     case 'W':
   13139       /* set the "width" of the user space data */
   13140       /* buffer. This will be the number of */
   13141       /* send_size buffers malloc'd in the */
   13142       /* *_STREAM test. It may be enhanced to set */
   13143       /* both send and receive "widths" but for now */
   13144       /* it is just the sending *_STREAM. */
   13145       send_width = convert(optarg);
   13146       break;
   13147     case 'V' :
   13148       /* we want to do copy avoidance and will set */
   13149       /* it for everything, everywhere, if we really */
   13150       /* can. of course, we don't know anything */
   13151       /* about the remote... */
   13152 #ifdef SO_SND_COPYAVOID
   13153       loc_sndavoid = 1;
   13154 #else
   13155       loc_sndavoid = 0;
   13156       printf("Local send copy avoidance not available.\n");
   13157 #endif
   13158 #ifdef SO_RCV_COPYAVOID
   13159       loc_rcvavoid = 1;
   13160 #else
   13161       loc_rcvavoid = 0;
   13162       printf("Local recv copy avoidance not available.\n");
   13163 #endif
   13164       rem_sndavoid = 1;
   13165       rem_rcvavoid = 1;
   13166       break;
   13167     };
   13168   }
   13169 
   13170 #if defined(WANT_FIRST_BURST)
   13171 #if defined(WANT_HISTOGRAM)
   13172   /* if WANT_FIRST_BURST and WANT_HISTOGRAM are defined and the user
   13173      indeed wants a non-zero first burst size, and we would emit a
   13174      histogram, then we should emit a warning that the two are not
   13175      compatible. raj 2006-01-31 */
   13176   if ((first_burst_size > 0) && (verbosity >= 2)) {
   13177     fprintf(stderr,
   13178 	    "WARNING! Histograms and first bursts are incompatible!\n");
   13179     fflush(stderr);
   13180   }
   13181 #endif
   13182 #endif
   13183 
   13184   /* we do not want to make remote_data_address non-NULL because if
   13185      the user has not specified a remote adata address, we want to
   13186      take it from the hostname in the -H global option. raj
   13187      2005-02-08 */
   13188 
   13189   /* so, if there is to be no control connection, we want to have some
   13190      different settings for a few things */
   13191 
   13192   if (no_control) {
   13193 
   13194     if (strcmp(remote_data_port,"0") == 0) {
   13195       /* we need to select either the discard port, echo port or
   13196 	 chargen port dedepending on the test name. raj 2007-02-08 */
   13197       if (strstr(test_name,"STREAM") ||
   13198 	  strstr(test_name,"SENDFILE")) {
   13199 	strncpy(remote_data_port,"discard",sizeof(remote_data_port));
   13200       }
   13201       else if (strstr(test_name,"RR")) {
   13202 	strncpy(remote_data_port,"echo",sizeof(remote_data_port));
   13203       }
   13204       else if (strstr(test_name,"MAERTS")) {
   13205 	strncpy(remote_data_port,"chargen",sizeof(remote_data_port));
   13206       }
   13207       else {
   13208 	printf("No default port known for the %s test, please set one yourself\n",test_name);
   13209 	exit(-1);
   13210       }
   13211     }
   13212     remote_data_port[sizeof(remote_data_port) - 1] = '\0';
   13213 
   13214     /* I go back and forth on whether these should become -1 or if
   13215        they should become 0 for a no_control test. what do you think?
   13216        raj 2006-02-08 */
   13217 
   13218     rem_rcvavoid = -1;
   13219     rem_sndavoid = -1;
   13220     rss_size_req = -1;
   13221     rsr_size_req = -1;
   13222     rem_nodelay = -1;
   13223 
   13224     if (strstr(test_name,"STREAM") ||
   13225 	strstr(test_name,"SENDFILE")) {
   13226       recv_size = -1;
   13227     }
   13228     else if (strstr(test_name,"MAERTS")) {
   13229       send_size = -1;
   13230     }
   13231   }
   13232 }
   13233