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