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 */