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