1 #ifndef lint
2 char	nettest_id[]="\
3 @(#)nettest_bsd.c (c) Copyright 1993-2012 Hewlett-Packard Co. Version 2.6.0";
4 #endif /* lint */
5 
6 
7 /****************************************************************/
8 /*								*/
9 /*	nettest_bsd.c						*/
10 /*								*/
11 /*      the BSD sockets parsing routine...                      */
12 /*       ...with the addition of Windows NT, this is now also   */
13 /*          a Winsock test... sigh :)                           */
14 /*                                                              */
15 /*      scan_sockets_args()                                     */
16 /*                                                              */
17 /*	the actual test routines...				*/
18 /*								*/
19 /*	send_tcp_stream()	perform a tcp stream test	*/
20 /*	recv_tcp_stream()					*/
21 /*      send_tcp_maerts()       perform a tcp stream test       */
22 /*      recv_tcp_maerts()       in the other direction          */
23 /*	send_tcp_rr()		perform a tcp request/response	*/
24 /*	recv_tcp_rr()						*/
25 /*      send_tcp_conn_rr()      an RR test including connect    */
26 /*      recv_tcp_conn_rr()                                      */
27 /*      send_tcp_cc()           a connect/disconnect test with  */
28 /*      recv_tcp_cc()           no RR                           */
29 /*      send_tcp_mss()          just report the mss             */
30 /*	send_udp_stream()	perform a udp stream test	*/
31 /*	recv_udp_stream()					*/
32 /*	send_udp_rr()		perform a udp request/response	*/
33 /*	recv_udp_rr()						*/
34 /*	loc_cpu_rate()		determine the local cpu maxrate */
35 /*	rem_cpu_rate()		find the remote cpu maxrate	*/
36 /*								*/
37 /****************************************************************/
38 
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 #endif
42 
43 #include <stdio.h>
44 #if HAVE_SYS_TYPES_H
45 # include <sys/types.h>
46 #endif
47 #if HAVE_SYS_STAT_H
48 # include <sys/stat.h>
49 #endif
50 #if STDC_HEADERS
51 # include <stdlib.h>
52 # include <stddef.h>
53 #else
54 # if HAVE_STDLIB_H
55 #  include <stdlib.h>
56 # endif
57 #endif
58 #if HAVE_STRING_H
59 # if !STDC_HEADERS && HAVE_MEMORY_H
60 #  include <memory.h>
61 # endif
62 # include <string.h>
63 #endif
64 #if HAVE_STRINGS_H
65 # include <strings.h>
66 #endif
67 #if HAVE_INTTYPES_H
68 # include <inttypes.h>
69 #else
70 # if HAVE_STDINT_H
71 #  include <stdint.h>
72 # endif
73 #endif
74 #if HAVE_UNISTD_H
75 # include <unistd.h>
76 #endif
77 #if HAVE_AIO
78 # include <assert.h> // XXX
79 # include <aio.h>
80 #endif
81 
82 #include <fcntl.h>
83 #ifndef WIN32
84 #include <errno.h>
85 #include <signal.h>
86 #endif
87 
88 #if TIME_WITH_SYS_TIME
89 # include <sys/time.h>
90 # include <time.h>
91 #else
92 # if HAVE_SYS_TIME_H
93 #  include <sys/time.h>
94 # else
95 #  include <time.h>
96 # endif
97 #endif
98 
99 #ifdef NOSTDLIBH
100 #include <malloc.h>
101 #endif /* NOSTDLIBH */
102 
103 
104 #ifndef WIN32
105 #if !defined(__VMS)
106 #if defined(HAVE_SYS_IPC_H)
107 #include <sys/ipc.h>
108 #endif
109 #endif /* !__VMS */
110 #include <sys/socket.h>
111 #include <netinet/in.h>
112 #include <netinet/tcp.h>
113 
114 #ifdef HAVE_NETINET_SCTP_H
115 #include <netinet/sctp.h>
116 #endif
117 
118 #include <arpa/inet.h>
119 #include <netdb.h>
120 #else /* WIN32 */
121 #include <process.h>
122 #define netperf_socklen_t socklen_t
123 #include <winsock2.h>
124 #include "missing\stdint.h"
125 /* while it is unlikely that anyone running Windows 2000 or NT 4 is
126    going to be trying to compile this, if they are they will want to
127    define DONT_IPV6 in the sources file */
128 #ifndef DONT_IPV6
129 #include <ws2tcpip.h>
130 #endif
131 
132 #define WIN32_LEAN_AND_MEAN 1
133 #include <windows.h>
134 
135 #define sleep(x) Sleep((x)*1000)
136 
137 #define __func__ __FUNCTION__
138 #endif /* WIN32 */
139 
140 /* We don't want to use bare constants in the shutdown() call.  In the
141    extremely unlikely event that SHUT_WR isn't defined, we will define
142    it to the value we used to be passing to shutdown() anyway.  raj
143    2007-02-08 */
144 #if !defined(SHUT_WR)
145 #define SHUT_WR 1
146 #endif
147 
148 #if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO)
149 # include "missing/getaddrinfo.h"
150 #endif
151 
152 #include "netlib.h"
153 #include "netsh.h"
154 #include "nettest_bsd.h"
155 
156 #if defined(WANT_HISTOGRAM) || defined(WANT_DEMO)
157 #include "hist.h"
158 #endif /* WANT_HISTOGRAM */
159 
160 
161 /* make first_burst_size unconditional so we can use it easily enough
162    when calculating transaction latency for the TCP_RR test. raj
163    2007-06-08 however, change its default value so one can tell in
164    "omni" output whether or not WANT_BURST was enabled. raj
165    2008-01-28 */
166 #if defined(WANT_FIRST_BURST)
167 int first_burst_size=0;
168 #else
169 int first_burst_size=-1;
170 #endif
171 
172 #if defined(HAVE_SENDFILE) && (defined(__linux) || defined(__sun))
173 #include <sys/sendfile.h>
174 #endif /* HAVE_SENDFILE && (__linux || __sun) */
175 
176 
177 
178 /* these variables are specific to the BSD sockets tests, but can
179  * be used elsewhere if needed.  They are externed through nettest_bsd.h
180  */
181 
182 int
183   socket_type,          /* used initially by the "omni" tests */
184   rss_size_req = -1,	/* requested remote socket send buffer size */
185   rsr_size_req = -1,	/* requested remote socket recv buffer size */
186   rss_size,		/* initial remote socket send buffer size */
187   rsr_size,		/* initial remote socket recv buffer size */
188   rss_size_end = -1,    /* final  remote socket send buffer size */
189   rsr_size_end = -1,    /* final  remote socket recv buffer size */
190   lss_size_req = -1,	/* requested local socket send buffer size */
191   lsr_size_req = -1,	/* requested local socket recv buffer size */
192   lss_size,		/* local  socket send buffer size 	*/
193   lsr_size,		/* local  socket recv buffer size 	*/
194   lss_size_end = -1,    /* final local  socket send buffer size */
195   lsr_size_end = -1,    /* final local  socket recv buffer size */
196   req_size = 1,		/* request size                   	*/
197   rsp_size = 1,		/* response size			*/
198   send_size,		/* how big are individual sends		*/
199   recv_size,		/* how big are individual receives	*/
200   transport_mss_req = -1; /* what maximum segment size is wanted */
201 
202 static  int confidence_iteration;
203 static  char  local_cpu_method;
204 static  char  remote_cpu_method;
205 
206 /* these will control the width of port numbers we try to use in the */
207 /* TCP_CRR and/or TCP_TRR tests. raj 3/95 */
208 static int client_port_min = 5000;
209 static int client_port_max = 65535;
210 
211  /* different options for the sockets				*/
212 
213 int
214   loc_nodelay,		/* don't/do use NODELAY	locally		*/
215   rem_nodelay,		/* don't/do use NODELAY remotely	*/
216 #ifdef TCP_CORK
217   loc_tcpcork=0,        /* don't/do use TCP_CORK locally        */
218   rem_tcpcork=0,        /* don't/do use TCP_CORK remotely       */
219 #else
220   loc_tcpcork=-1,
221   rem_tcpcork=-1,
222 #endif /* TCP_CORK */
223 #if HAVE_AIO
224   loc_rcvaio,           /* don't/do use aio_read() locally      */
225   rem_rcvaio,           /* don't/do use aio_read() remotely     */
226   loc_sndaio,           /* don't/do use aio_write() locally     */
227   rem_sndaio,           /* don't/do use aio_write() remotely    */
228 #else
229   loc_rcvaio=-1,
230   rem_rcvaio=-1,
231   loc_sndaio=-1,
232   rem_sndaio=-1,
233 #endif
234   loc_sndavoid,		/* avoid send copies locally		*/
235   loc_rcvavoid,		/* avoid recv copies locally		*/
236   rem_sndavoid,		/* avoid send copies remotely		*/
237   rem_rcvavoid, 	/* avoid recv_copies remotely		*/
238   local_connected = 0,  /* local socket type, connected/non-connected */
239   remote_connected = 0, /* remote socket type, connected/non-connected */
240   routing_allowed = 1,  /* set/clear SO_DONTROUTE on data socket */
241   pacing_rate = 0;      /* set a socket pacing rate? */
242 
243 int multicast_ttl = -1; /* should we set the multicast TTL to a value? */
244 
245 int want_keepalive = 0;
246 
247 #ifdef WANT_HISTOGRAM
248 #ifdef HAVE_GETHRTIME
249 static hrtime_t time_one;
250 static hrtime_t time_two;
251 #elif HAVE_GET_HRT
252 #include "hrt.h"
253 static hrt_t time_one;
254 static hrt_t time_two;
255 #elif defined(WIN32)
256 static LARGE_INTEGER time_one;
257 static LARGE_INTEGER time_two;
258 #else
259 static struct timeval time_one;
260 static struct timeval time_two;
261 #endif /* HAVE_GETHRTIME */
262 static HIST time_hist;
263 #endif /* WANT_HISTOGRAM */
264 
265 #ifdef WANT_INTERVALS
266 int interval_count;
267 #ifndef WANT_SPIN
268 #ifdef WIN32
269 #define INTERVALS_INIT() \
270     if (interval_burst) { \
271       /* zero means that we never pause, so we never should need the \
272          interval timer. we used to use it for demo mode, but we deal \
273 	 with that with a variant on watching the clock rather than \
274 	 waiting for a timer. raj 2006-02-06 */ \
275       start_itimer(interval_wate); \
276     } \
277     interval_count = interval_burst;
278 #else
279 sigset_t signal_set;
280 #define INTERVALS_INIT() \
281     if (interval_burst) { \
282       /* zero means that we never pause, so we never should need the \
283          interval timer. we used to use it for demo mode, but we deal \
284 	 with that with a variant on watching the clock rather than \
285 	 waiting for a timer. raj 2006-02-06 */ \
286       start_itimer(interval_wate); \
287     } \
288     interval_count = interval_burst; \
289     /* get the signal set for the call to sigsuspend */ \
290     if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) { \
291       fprintf(where, \
292 	      "%s: unable to get sigmask errno %d\n", \
293 	      __func__, \
294 	      errno); \
295       fflush(where); \
296       exit(1); \
297     }
298 #endif /* WIN32 */
299 
300 #ifdef WIN32
301 #define INTERVALS_WAIT() \
302       /* in this case, the interval count is the count-down counter \
303 	 to decide to sleep for a little bit */ \
304       if ((interval_burst) && (--interval_count == 0)) { \
305 	/* call WaitForSingleObject and wait for the interval timer to get us \
306 	   out */ \
307 	if (debug > 1) { \
308 	  fprintf(where,"about to suspend\n"); \
309 	  fflush(where); \
310 	} \
311     if (WaitForSingleObject(WinTimer, INFINITE) != WAIT_OBJECT_0) { \
312         fprintf(where, "WaitForSingleObject failed (%d)\n", GetLastError()); \
313 	  fflush(where); \
314 	  exit(1); \
315 	} \
316 	interval_count = interval_burst; \
317       }
318 #else
319 #define INTERVALS_WAIT() \
320       /* in this case, the interval count is the count-down couter \
321 	 to decide to sleep for a little bit */ \
322       if ((interval_burst) && (--interval_count == 0)) { \
323 	/* call sigsuspend and wait for the interval timer to get us \
324 	   out */ \
325 	if (debug > 1) { \
326 	  fprintf(where,"about to suspend\n"); \
327 	  fflush(where); \
328 	} \
329 	if (sigsuspend(&signal_set) == EFAULT) { \
330 	  fprintf(where, \
331 		  "%s: fault with sigsuspend.\n", \
332                   __func__); \
333 	  fflush(where); \
334 	  exit(1); \
335 	} \
336 	interval_count = interval_burst; \
337       }
338 #endif /* WIN32 */
339 #else
340 /* first out timestamp */
341 #ifdef HAVE_GETHRTIME
342 static hrtime_t intvl_one;
343 static hrtime_t intvl_two;
344 static hrtime_t *intvl_one_ptr = &intvl_one;
345 static hrtime_t *intvl_two_ptr = &intvl_two;
346 static hrtime_t *temp_intvl_ptr = &intvl_one;
347 #elif defined(WIN32)
348 static LARGE_INTEGER intvl_one;
349 static LARGE_INTEGER intvl_two;
350 static LARGE_INTEGER *intvl_one_ptr = &intvl_one;
351 static LARGE_INTEGER *intvl_two_ptr = &intvl_two;
352 static LARGE_INTEGER *temp_intvl_ptr = &intvl_one;
353 #else
354 static struct timeval intvl_one;
355 static struct timeval intvl_two;
356 static struct timeval *intvl_one_ptr = &intvl_one;
357 static struct timeval *intvl_two_ptr = &intvl_two;
358 static struct timeval *temp_intvl_ptr = &intvl_one;
359 #endif
360 
361 #define INTERVALS_INIT() \
362       if (interval_burst) { \
363 	HIST_timestamp(intvl_one_ptr); \
364       } \
365       interval_count = interval_burst; \
366 
367 #define INTERVALS_WAIT() \
368       /* in this case, the interval count is the count-down couter \
369 	 to decide to sleep for a little bit */ \
370       if ((interval_burst) && (--interval_count == 0)) { \
371 	/* call sigsuspend and wait for the interval timer to get us \
372 	   out */ \
373 	if (debug > 1) { \
374 	  fprintf(where,"about to spin suspend\n"); \
375 	  fflush(where); \
376 	} \
377         HIST_timestamp(intvl_two_ptr); \
378         while(delta_micro(intvl_one_ptr,intvl_two_ptr) < interval_usecs) { \
379 	  HIST_timestamp(intvl_two_ptr); \
380 	} \
381 	temp_intvl_ptr = intvl_one_ptr; \
382 	intvl_one_ptr = intvl_two_ptr; \
383 	intvl_two_ptr = temp_intvl_ptr; \
384 	interval_count = interval_burst; \
385       }
386 #endif
387 #endif
388 
389 
390 char sockets_usage[] = "\n\
391 Usage: netperf [global options] -- [test options] \n\
392 \n\
393 TCP/UDP BSD Sockets Test Options:\n\
394     -a                Use aio_write(2)\n\
395     -A                Use aio_read(2)\n\
396     -b number         Send number requests at start of _RR tests\n\
397     -C                Set TCP_CORK when available\n\
398     -D [L][,R]        Set TCP_NODELAY locally and/or remotely (TCP_*)\n\
399     -h                Display this text\n\
400     -H name,fam       Use name (or IP) and family as target of data connection\n\
401     -L name,fam       Use name (or IP) and family as source of data connection\n\
402     -m bytes          Set the send size (TCP_STREAM, UDP_STREAM)\n\
403     -M bytes          Set the recv size (TCP_STREAM, UDP_STREAM)\n\
404     -n                Use the connected socket for UDP locally\n\
405     -N                Use the connected socket for UDP remotely\n\
406     -p min[,max]      Set the min/max port numbers for TCP_CRR, TCP_TRR\n\
407     -P local[,remote] Set the local/remote port for the data socket\n\
408     -r req,[rsp]      Set request/response sizes (TCP_RR, UDP_RR)\n\
409     -s send[,recv]    Set local socket send/recv buffer sizes\n\
410     -S send[,recv]    Set remote socket send/recv buffer sizes\n\
411     -4                Use AF_INET (eg IPv4) on both ends of the data conn\n\
412     -6                Use AF_INET6 (eg IPv6) on both ends of the data conn\n\
413 \n\
414 For those options taking two parms, at least one must be specified;\n\
415 specifying one value without a comma will set both parms to that\n\
416 value, specifying a value with a leading comma will set just the second\n\
417 parm, a value with a trailing comma will set just the first. To set\n\
418 each parm to unique values, specify both and separate them with a\n\
419 comma.\n";
420 
421 
422 
423 /* these routines convert between the AF address space and the NF
424    address space since the numeric values of AF_mumble are not the
425    same across the platforms. raj 2005-02-08 */
426 
427 int
nf_to_af(int nf)428 nf_to_af(int nf) {
429   switch(nf) {
430   case NF_INET:
431     return AF_INET;
432   case NF_UNSPEC:
433     return AF_UNSPEC;
434   case NF_INET6:
435 #if defined(AF_INET6)
436     return AF_INET6;
437 #else
438     return AF_UNSPEC;
439 #endif
440   case NF_RDS:
441 #if defined(AF_RDS)
442     return AF_RDS;
443 #else
444     return AF_UNSPEC;
445 #endif
446   default:
447     return AF_UNSPEC;
448   }
449 }
450 
451 int
af_to_nf(int af)452 af_to_nf(int af) {
453 
454   switch(af) {
455   case AF_INET:
456     return NF_INET;
457   case AF_UNSPEC:
458     return NF_UNSPEC;
459 #if defined(AF_INET6)
460   case AF_INET6:
461     return NF_INET6;
462 #endif
463 #if defined(AF_RDS)
464   case AF_RDS:
465     return NF_RDS;
466 #endif
467   default:
468     return NF_UNSPEC;
469   }
470 }
471 
472 
473 /* these routines will convert between the hosts' socket types and
474    those netperf uses.  we need this because different platforms can
475    have different values for SOCK_STREAM, SOCK_DGRAM and the
476    like... */
477 
478 int
nst_to_hst(int nst)479 nst_to_hst(int nst) {
480   switch(nst) {
481 #ifdef SOCK_STREAM
482   case NST_STREAM:
483     return SOCK_STREAM;
484     break;  /* ok, this may not be necessary :) */
485 #endif
486 #ifdef SOCK_DGRAM
487   case NST_DGRAM:
488     return SOCK_DGRAM;
489     break;
490 #endif
491 #ifdef SOCK_DCCP
492   case NST_DCCP:
493     return SOCK_DCCP;
494     break;
495 #endif
496 #ifdef SOCK_SEQPACKET
497   case NST_SEQPACKET:
498     return NST_SEQPACKET;
499 #endif
500   default:
501     return -1;
502   }
503 }
504 
505 int
hst_to_nst(int hst)506 hst_to_nst(int hst) {
507 
508   switch(hst) {
509 #ifdef SOCK_STREAM
510   case SOCK_STREAM:
511     return NST_STREAM;
512     break;
513 #endif
514 #ifdef SOCK_DGRAM
515   case SOCK_DGRAM:
516     return NST_DGRAM;
517     break;
518 #endif
519 #ifdef SOCK_DCCP
520   case SOCK_DCCP:
521     return NST_DCCP;
522     break;
523 #endif
524 #ifdef SOCK_SEQPACKET
525   case SOCK_SEQPACKET:
526     return NST_SEQPACKET;
527 #endif
528   default:
529     return NST_UNKN;
530   }
531 }
532 char *
hst_to_str(int hst)533 hst_to_str(int hst) {
534 
535   switch(hst) {
536 #ifdef SOCK_STREAM
537   case SOCK_STREAM:
538     return "Stream";
539     break;
540 #endif
541 #ifdef SOCK_DGRAM
542   case SOCK_DGRAM:
543     return "Datagram";
544     break;
545 #endif
546 #ifdef SOCK_DCCP
547   case SOCK_DCCP:
548     return "DCCP";
549     break;
550 #endif
551 #ifdef SOCK_SEQPACKET
552   case SOCK_SEQPACKET:
553     return "Seqpacket";
554 #endif
555   default:
556     return "Unknown";
557   }
558 }
559 
560 char *
protocol_to_str(int protocol)561 protocol_to_str(int protocol) {
562   switch(protocol) {
563     /* ass-u-me that everyone has IPPROTO_TCP and IPPROTO_UDP */
564   case IPPROTO_TCP:
565     return "TCP";
566   case IPPROTO_UDP:
567     return "UDP";
568     /* but do not assume that everyone has the others */
569 #ifdef IPPROTO_UDPLITE
570   case IPPROTO_UDPLITE:
571     return "UDPLite";
572 #endif
573 #ifdef IPPROTO_SCTP
574   case IPPROTO_SCTP:
575     return "SCTP";
576 #endif
577 #ifdef IPPROTO_DCCP
578   case IPPROTO_DCCP:
579     return "DCCP";
580 #endif
581 #ifdef IPPROTO_SDP
582   case IPPROTO_SDP:
583     return "SDP";
584 #endif
585 #ifdef IPPROTO_IP
586   case IPPROTO_IP:
587     return "IP Default";
588 #endif
589   default:
590     return "Unknown Protocol";
591   }
592 }
593 
594 
595  /* This routine is intended to retrieve interesting aspects of tcp */
596  /* for the data connection. at first, it attempts to retrieve the */
597  /* maximum segment size. later, it might be modified to retrieve */
598  /* other information, but it must be information that can be */
599  /* retrieved quickly as it is called during the timing of the test. */
600  /* for that reason, a second routine may be created that can be */
601  /* called outside of the timing loop */
602 static
603 void
get_tcp_info(SOCKET socket,int * mss)604 get_tcp_info(SOCKET socket, int *mss)
605 {
606 
607 #ifdef TCP_MAXSEG
608   netperf_socklen_t sock_opt_len;
609 
610   sock_opt_len = sizeof(int);
611   if (getsockopt(socket,
612 		 getprotobyname("tcp")->p_proto,
613 		 TCP_MAXSEG,
614 		 (char *)mss,
615 		 &sock_opt_len) == SOCKET_ERROR) {
616     fprintf(where,
617 	    "netperf: get_tcp_info: getsockopt TCP_MAXSEG: errno %d\n",
618 	    errno);
619     fflush(where);
620     *mss = -1;
621   }
622 #else
623   *mss = -1;
624 #endif /* TCP_MAXSEG */
625 }
626 
627 static
628 void
set_tcp_mss(SOCKET socket,int mss)629 set_tcp_mss(SOCKET socket, int mss) {
630 #ifdef TCP_MAXSEG
631   netperf_socklen_t sock_opt_len;
632 
633   sock_opt_len = sizeof(int);
634   if ((setsockopt(socket,
635 		  getprotobyname("tcp")->p_proto,
636 		  TCP_MAXSEG,
637 		  (const char *)&mss,
638 		  sock_opt_len) == SOCKET_ERROR) && (debug)) {
639     fprintf(where,
640 	    "netperf: %s: setsockopt TCP_MAXSEG: %s (errno %d)\n",
641 	    __FUNCTION__,
642 	    strerror(errno),
643 	    errno);
644     fflush(where);
645   }
646 #else
647   if (debug) {
648     fprintf(where,
649 	    "netperf: %s platform does not know how to set TCP segment size\n",
650 	    __FUNCTION__);
651     fflush(where);
652   }
653 
654 #endif /* TCP_MAXSEG */
655 }
656 
657 
658 
659 /* return a pointer to a completed addrinfo chain - prefer
660    data_address to controlhost and utilize the specified address
661    family */
662 
663 struct addrinfo *
complete_addrinfo(char * controlhost,char * data_address,char * port,int family,int type,int protocol,int flags)664 complete_addrinfo(char *controlhost, char *data_address, char *port, int family, int type, int protocol, int flags)
665 {
666   struct addrinfo hints;
667   struct addrinfo *res;
668   struct addrinfo *temp_res;
669 
670 #define CHANGED_SOCK_TYPE  0x1
671 #define CHANGED_PROTOCOL   0x2
672 #define CHANGED_SCTP       0x4
673 #define CHANGED_DCCP       0x8
674 #define CHANGED_DCCP_SOCK  0x10
675 
676   int    change_info = 0;
677   static int change_warning_displayed = 0;
678 
679   int count = 0;
680   int error = 0;
681 
682   char *hostname;
683 
684   /* take data-address over controlhost */
685   if (data_address)
686     hostname = data_address;
687   else
688     hostname = controlhost;
689 
690   if (debug) {
691     fprintf(where,
692 	    "complete_addrinfo using hostname %s port %s family %s type %s prot %s flags 0x%x\n",
693 	    hostname,
694 	    port,
695 	    inet_ftos(family),
696 	    inet_ttos(type),
697 	    inet_ptos(protocol),
698 	    flags);
699     fflush(where);
700   }
701 
702   memset(&hints, 0, sizeof(hints));
703   hints.ai_family = family;
704   hints.ai_socktype = type;
705   hints.ai_protocol = protocol;
706   hints.ai_flags = flags|AI_CANONNAME|AI_ADDRCONFIG;
707 
708   count = 0;
709   do {
710     error = getaddrinfo((char *)hostname,
711                         (char *)port,
712                         &hints,
713                         &res);
714     count += 1;
715     if (error == EAI_AGAIN) {
716       if (debug) {
717         fprintf(where,"Sleeping on getaddrinfo EAI_AGAIN\n");
718         fflush(where);
719       }
720       sleep(1);
721     }
722     /* while you see this kludge first, it is actually the second, the
723        first being the one for Solaris below. The need for this kludge
724        came after implementing the Solaris broken getaddrinfo kludge -
725        now we see a kludge in Linux getaddrinfo where if it is given
726        SOCK_STREAM and IPPROTO_SCTP it barfs with a -7
727        EAI_SOCKTYPE. so, we check if the error was EAI_SOCKTYPE and if
728        we were asking for IPPROTO_SCTP and if so, kludge, again... raj
729        200?-10-13 and of course, requiring the kludge for SCTP, it is
730        no surprise that linux needs a kludge for DCCP...actually not
731        only does it need the ai_protocol kludge, it needs an
732        ai_socktype kludge too... sigh raj 2008-02-01 */
733 #if defined(IPPROTO_SCTP) || defined (IPPROTO_DCCP)
734     if (EAI_SOCKTYPE == error
735 #ifdef EAI_BADHINTS
736         || EAI_BADHINTS == error
737 #endif
738         ) {
739       /* we ass-u-me this is the Linux getaddrinfo bug, clear the
740 	 hints.ai_protocol field, and set some state "remembering"
741 	 that we did this so the code for the Solaris kludge can do
742 	 the fix-up for us.  also flip error over to EAI_AGAIN and
743 	 make sure we don't "count" this time around the loop. */
744 #if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
745       /* only tweak on this one the second time around, after we've
746 	 kludged the ai_protocol field */
747       if ((hints.ai_socktype == SOCK_DCCP) &&
748 	  (hints.ai_protocol == 0)) {
749 	change_info |= CHANGED_DCCP_SOCK;
750 	hints.ai_socktype = 0;
751 	/* we need to give it some sort of IPPROTO or it gets unhappy,
752 	   so for now, pick one from deep within the colon and use
753 	   IPPROTO_TCP */
754 	hints.ai_protocol = IPPROTO_TCP;
755       }
756 
757       if (hints.ai_protocol == IPPROTO_DCCP) {
758 	change_info |= CHANGED_DCCP;
759 	hints.ai_protocol = 0;
760       }
761 
762 #endif
763 #if defined(IPPROTO_SCTP)
764       if (hints.ai_protocol == IPPROTO_SCTP) {
765 	change_info |= CHANGED_SCTP;
766 	hints.ai_protocol = 0;
767       }
768 #endif
769 
770       error = EAI_AGAIN;
771       count -= 1;
772     }
773 #endif
774   } while ((error == EAI_AGAIN) && (count <= 5));
775 
776   if (error) {
777     fprintf(where,
778 	    "complete_addrinfo: could not resolve '%s' port '%s' af %d"
779 	    "\n\tgetaddrinfo returned %d %s\n",
780 	    hostname,
781 	    port,
782 	    family,
783 	    error,
784 	    gai_strerror(error));
785     fflush(where);
786     exit(-1);
787   }
788 
789   /* there exists at least one platform - Solaris 10 - that does not
790      seem to completely honor the ai_protocol and/or ai_socktype one
791      sets in the hints parm to the getaddrinfo call.  so, we need to
792      walk the list of entries returned and if either of those do not
793      match what we asked for, we need to go ahead and set them
794      "correctly" this is based in part on some earlier SCTP-only code
795      from previous revisions.  raj 2006-10-09 */
796 
797   temp_res = res;
798 
799   while (temp_res) {
800 
801     if ((type)  &&
802 	(temp_res->ai_socktype != type)) {
803       change_info |= CHANGED_SOCK_TYPE;
804       if (debug) {
805 	fprintf(where,
806 		"WARNING! Changed bogus getaddrinfo socket type %d to %d\n",
807 		temp_res->ai_socktype,
808 		type);
809 	fflush(where);
810       }
811       temp_res->ai_socktype = type;
812     }
813 
814     if ((protocol) &&
815 	(temp_res->ai_protocol != protocol)) {
816       change_info |= CHANGED_PROTOCOL;
817       if (debug) {
818 	fprintf(where,
819 		"WARNING! Changed bogus getaddrinfo protocol %d to %d\n",
820 		temp_res->ai_protocol,
821 		protocol);
822 	fflush(where);
823       }
824       temp_res->ai_protocol = protocol;
825     }
826     temp_res = temp_res->ai_next;
827   }
828 
829   if ((change_info & CHANGED_SOCK_TYPE) &&
830       !(change_warning_displayed & CHANGED_SOCK_TYPE)) {
831     change_warning_displayed |= CHANGED_SOCK_TYPE;
832     fprintf(where,
833 	    "WARNING! getaddrinfo returned a socket type which did not\n"
834 	    "match the requested type.  Please contact your vendor for\n"
835 	    "a fix to this bug in getaddrinfo()\n");
836     fflush(where);
837   }
838 
839   /* if we dropped the protocol hint, it would be for a protocol that
840      getaddrinfo() wasn't supporting yet, not for the bug that it took
841      our hint and still returned zero. raj 2006-10-16 */
842   /* as there is now an open bug against (Open)Solaris (id 6847733) on
843      this behaviour we will only emit this warning if debug is set
844      under Solaris and will continue to emit it under any circumstance
845      on other platforms should it arise. raj 2009-06-03 */
846   /* since it has now been two years since that bug was filed, it
847      should be resolved by now, so the "out" given to Sun should no
848      longer be necessary.  either folks are running with the fix or
849      they need to get the fix. raj 2011-07-06 */
850   if ((change_info & CHANGED_PROTOCOL) &&
851       !(change_warning_displayed & CHANGED_PROTOCOL) &&
852       (hints.ai_protocol != 0)) {
853     change_warning_displayed |= CHANGED_PROTOCOL;
854     fprintf(where,
855 	    "WARNING! getaddrinfo returned a protocol other than the\n"
856 	    "requested protocol.  Please contact your vendor for\n"
857 	    "a fix to this bug in getaddrinfo()\n");
858     fflush(where);
859   }
860 
861   if ((change_info & CHANGED_SCTP) &&
862       !(change_warning_displayed & CHANGED_SCTP)) {
863     change_warning_displayed |= CHANGED_SCTP;
864     fprintf(where,
865 	    "WARNING! getaddrinfo on this platform does not accept IPPROTO_SCTP!\n"
866 	    "Please contact your vendor for a fix to this bug in getaddrinfo().\n");
867     fflush(where);
868   }
869 
870   if ((change_info & CHANGED_DCCP) &&
871       !(change_warning_displayed & CHANGED_DCCP)) {
872     change_warning_displayed |= CHANGED_DCCP;
873     fprintf(where,
874 	    "WARNING! getaddrinfo on this platform does not accept IPPROTO_DCCP!\n"
875 	    "Please contact your vendor for a fix to this bug in getaddrinfo().\n");
876     fflush(where);
877   }
878 
879 
880   if (debug) {
881     dump_addrinfo(where, res, hostname, port, family);
882   }
883 
884   return(res);
885 }
886 
887 void
complete_addrinfos(struct addrinfo ** remote,struct addrinfo ** local,char remote_host[],int type,int protocol,int flags)888 complete_addrinfos(struct addrinfo **remote,struct addrinfo **local, char remote_host[], int type, int protocol, int flags) {
889 
890   if (remote_data_family == AF_UNSPEC) {
891     remote_data_family = control_family;
892   }
893 
894   *remote = complete_addrinfo(remote_host,
895 			      remote_data_address,
896 			      remote_data_port,
897 			      remote_data_family,
898 			      type,
899 			      protocol,
900 			      flags);
901 
902   /* OK, if the user has not specified a local data endpoint address
903      (test-specific -L), pick the local data endpoint address based on
904      the remote data family info (test-specific -H or -4 or -6
905      option).  if the user has not specified remote data addressing
906      info (test-specific -H, -4 -6) pick something based on the local
907      control connection address (ie the global -L option). */
908 
909   if (NULL == local_data_address) {
910     local_data_address = malloc(HOSTNAMESIZE);
911     if (NULL == remote_data_address) {
912       if (debug) {
913 	fprintf(where,
914 		"local_data_address not set, using local_host_name of '%s'\n",
915 		local_host_name);
916 	fflush(where);
917       }
918       strcpy(local_data_address,local_host_name);
919     }
920     else {
921       if (debug) {
922 	fprintf(where,
923 		"local_data_address not set, using address family info\n");
924 	fflush(where);
925       }
926       /* by default, use 0.0.0.0 - assume IPv4 */
927       strcpy(local_data_address,"0.0.0.0");
928 #if defined(AF_INET6)
929       if ((AF_INET6 == local_data_family) ||
930 	  ((AF_UNSPEC == local_data_family) &&
931 	   (AF_INET6 == remote_data_family)) ||
932 	  ((AF_UNSPEC == local_data_family) &&
933 	   (AF_INET6 == (*remote)->ai_family))) {
934 	strcpy(local_data_address,"::0");
935       }
936 #endif
937     }
938   }
939 
940   *local = complete_addrinfo("what to put here?",
941 			     local_data_address,
942 			     local_data_port,
943 			     local_data_family,
944 			     type,
945 			     protocol,
946 			     flags|AI_PASSIVE);
947 
948   /* OK, at this point, if remote_data_address is NULL, we know that
949      we used the value of remote_host (the control connection) for the
950      remote, which means we can/should set remote_data_address to
951      remote_host so the "omni" output routines can use that global
952      variable. at least i think I can get away with that :) I'm sure
953      that at some point I'll find-out that I need to allocate
954      something for it rather than mess with the pointers, but that can
955      wait.  famous last words of raj 2008-01-25 */
956   if (remote_data_address == NULL)
957     remote_data_address = remote_host;
958 }
959 
960 void
set_hostname_and_port(char * hostname,char * portstr,int family,int port)961 set_hostname_and_port(char *hostname, char *portstr, int family, int port)
962 {
963   strcpy(hostname,"0.0.0.0");
964 #if defined AF_INET6
965   if (AF_INET6 == family) {
966     strcpy(hostname,"::0");
967   }
968 #endif
969 
970   sprintf(portstr, "%u", port);
971 
972 }
973 
974 static unsigned short
get_port_number(struct addrinfo * res)975 get_port_number(struct addrinfo *res)
976 {
977  switch(res->ai_family) {
978   case AF_INET: {
979     struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr;
980     return(ntohs(foo->sin_port));
981     break;
982   }
983 #if defined(AF_INET6)
984   case AF_INET6: {
985     struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr;
986     return(ntohs(foo->sin6_port));
987     break;
988   }
989 #endif
990   default:
991     fprintf(where,
992 	    "Given Unexpected Address Family of %u\n",res->ai_family);
993     fflush(where);
994     exit(-1);
995   }
996 }
997 
998 static void
extract_inet_address_and_port(struct addrinfo * res,void * addr,int len,int * port)999 extract_inet_address_and_port(struct addrinfo *res, void *addr, int len, int *port)
1000 {
1001  switch(res->ai_family) {
1002   case AF_INET: {
1003     struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr;
1004     *port = foo->sin_port;
1005     memcpy(addr,&(foo->sin_addr),min(len,sizeof(foo->sin_addr)));
1006     break;
1007   }
1008 #if defined(AF_INET6)
1009   case AF_INET6: {
1010     struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr;
1011     *port = foo->sin6_port;
1012     memcpy(addr,&(foo->sin6_addr),min(len,sizeof(foo->sin6_addr)));
1013     break;
1014   }
1015 #endif
1016   default:
1017     *port = 0xDEADBEEF;
1018     strncpy(addr,"UNKN FAMILY",len);
1019   }
1020 }
1021 
1022 /* this routine will set the port number of the sockaddr in the
1023    addrinfo to the specified value, based on the address family */
1024 void
set_port_number(struct addrinfo * res,unsigned short port)1025 set_port_number(struct addrinfo *res, unsigned short port)
1026 {
1027   switch(res->ai_family) {
1028   case AF_INET:
1029 #if defined(AF_RDS)
1030   case AF_RDS:
1031 #endif
1032     {
1033       struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr;
1034       foo->sin_port = htons(port);
1035       break;
1036     }
1037 #if defined(AF_INET6)
1038   case AF_INET6: {
1039     struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr;
1040     foo->sin6_port = htons(port);
1041     break;
1042   }
1043 #endif
1044   default:
1045     fprintf(where,
1046 	    "set_port_number Unexpected Address Family of %u\n",res->ai_family);
1047     fflush(where);
1048     exit(-1);
1049   }
1050 }
1051 
1052 /* stuff the address family, port number and address into a
1053    sockaddr. for now, we will go ahead and zero-out the sockaddr
1054    first */
1055 void
set_sockaddr_family_addr_port(struct sockaddr_storage * sockaddr,int family,void * addr,int port)1056 set_sockaddr_family_addr_port(struct sockaddr_storage *sockaddr, int family, void *addr, int port) {
1057 
1058   memset(sockaddr,0,sizeof(struct sockaddr_storage));
1059 
1060   switch (family) {
1061 #if defined(AF_RDS)
1062   case AF_RDS:
1063 #endif
1064   case AF_INET: {
1065     struct sockaddr_in *foo = (struct sockaddr_in *)sockaddr;
1066     foo->sin_port = htons((unsigned short) port);
1067     foo->sin_family = (unsigned short) family;
1068     memcpy(&(foo->sin_addr),addr,sizeof(foo->sin_addr));
1069     *(int *)addr = htonl(*(int *)addr);
1070     break;
1071   }
1072 #if defined(AF_INET6)
1073   case AF_INET6: {
1074     struct sockaddr_in6 *foo = (struct sockaddr_in6 *)sockaddr;
1075     foo->sin6_port = htons((unsigned short) port);
1076     foo->sin6_family = (unsigned short) family;
1077     memcpy(&(foo->sin6_addr),addr,sizeof(foo->sin6_addr));
1078     break;
1079   }
1080 #endif
1081   default:
1082     fprintf(where,
1083 	    "set_sockaddr_family_addr_port Unexpected Address Family of %u\n",family);
1084     fflush(where);
1085     exit(-1);
1086   }
1087 }
1088 
1089 /* pull the port and address out of the sockaddr in host format */
1090 int
get_sockaddr_family_addr_port(struct sockaddr_storage * sockaddr,int family,void * addr,int * port)1091 get_sockaddr_family_addr_port(struct sockaddr_storage *sockaddr, int family, void *addr, int *port)
1092 {
1093   struct sockaddr_in *sin = (struct sockaddr_in *)sockaddr;
1094 
1095   int ret = 0;
1096   if (sin->sin_family != family) {
1097     fprintf(where,
1098 	    "get_sockaddr_family_addr_port family mismatch %d vs %d\n",
1099 	    sin->sin_family,
1100 	    family);
1101     fflush(where);
1102     return -1;
1103   }
1104 
1105   switch(family) {
1106 #if defined(AF_RDS)
1107   case AF_RDS:
1108 #endif
1109   case  AF_INET: {
1110     *port = ntohs(sin->sin_port);
1111     memcpy(addr,&(sin->sin_addr),sizeof(sin->sin_addr));
1112     if (*(int *)addr == INADDR_ANY) ret = 1;
1113     *(int *)addr = ntohl(*(int *)addr);
1114     break;
1115   }
1116 #ifdef AF_INET6
1117   case AF_INET6: {
1118     int i;
1119     struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sockaddr;
1120     *port = ntohs(sin6->sin6_port);
1121     ret = 1;
1122     for (i=0; i < sizeof(struct in6_addr); i++)
1123       if (sin6->sin6_addr.s6_addr[i] != 0) ret=0;
1124     memcpy(addr,&(sin6->sin6_addr), sizeof(sin6->sin6_addr));
1125     break;
1126   }
1127 #endif
1128   default:
1129     fprintf(where,
1130 	    "get_sockaddr_family_addr_port: Unexpected Address Family of %u\n",family);
1131     fflush(where);
1132     exit(-1);
1133   }
1134   return ret;
1135 }
1136 
1137 
1138 int
set_socket_tos(SOCKET sock,int family,int socket_tos)1139 set_socket_tos(SOCKET sock, int family, int socket_tos) {
1140 
1141   int my_tos = -3;
1142   netperf_socklen_t sock_opt_len;
1143 
1144   switch (family) {
1145 #if defined(IP_TOS)
1146   case AF_INET:
1147     /* should I mask-away anything above the byte? */
1148     my_tos = socket_tos;
1149     if (setsockopt(sock,
1150 		   IPPROTO_IP,
1151 		   IP_TOS,
1152 		   (const char *)&my_tos,sizeof(my_tos)) == SOCKET_ERROR) {
1153       fprintf(where,
1154 	      "%s ip_tos failed with %s (errno %d)\n",
1155 	      __FUNCTION__,
1156 	      strerror(errno),
1157 	      errno);
1158       fflush(where);
1159       my_tos = -2;
1160     }
1161     else {
1162       sock_opt_len = sizeof(my_tos);
1163       getsockopt(sock,
1164 		 IPPROTO_IP,
1165 		 IP_TOS,
1166 		 (char *)&my_tos,
1167 		 &sock_opt_len);
1168     }
1169     break;
1170 #endif
1171 #if defined(IPV6_TCLASS)
1172   case AF_INET6:
1173     /* should I mask-away anything above the byte? */
1174     my_tos = socket_tos;
1175     if (setsockopt(sock,
1176 		   IPPROTO_IPV6,
1177 		   IPV6_TCLASS,
1178 		   (const char *)&my_tos,sizeof(my_tos)) == SOCKET_ERROR) {
1179       fprintf(where,
1180 	      "%s ip_tos failed with %s (errno %d)\n",
1181 	      __FUNCTION__,
1182 	      strerror(errno),
1183 	      errno);
1184       fflush(where);
1185       my_tos = -2;
1186     }
1187     else {
1188       sock_opt_len = sizeof(my_tos);
1189       getsockopt(sock,
1190 		 IPPROTO_IPV6,
1191 		 IPV6_TCLASS,
1192 		 (char *)&my_tos,
1193 		 &sock_opt_len);
1194     }
1195     break;
1196 #endif
1197   }
1198   return my_tos;
1199 }
1200 
1201 
1202  /* This routine will create a data (listen) socket with the
1203   apropriate options set and return it to the caller. this replaces
1204   all the duplicate code in each of the test routines and should help
1205   make things a little easier to understand. since this routine can be
1206   called by either the netperf or netserver programs, all output
1207   should be directed towards "where." family is generally AF_INET and
1208   type will be either SOCK_STREAM or SOCK_DGRAM.  This routine will
1209   also be used by the "SCTP" tests, hence the slightly strange-looking
1210   SCTP stuff in the classic bsd sockets test file... vlad/raj
1211   2005-03-15 */
1212 
1213 SOCKET
create_data_socket(struct addrinfo * res)1214 create_data_socket(struct addrinfo *res)
1215 {
1216 
1217   SOCKET temp_socket;
1218   int one = 1;
1219   int on  = 1;
1220   netperf_socklen_t sock_opt_len;
1221 
1222   /*set up the data socket                        */
1223   temp_socket = socket(res->ai_family,
1224 		       res->ai_socktype,
1225 		       res->ai_protocol);
1226 
1227   if (temp_socket == INVALID_SOCKET){
1228     fprintf(where,
1229 	    "netperf: create_data_socket: socket: errno %d fam %s type %s prot %s errmsg %s\n",
1230 	    errno,
1231 	    inet_ftos(res->ai_family),
1232 	    inet_ttos(res->ai_socktype),
1233 	    inet_ptos(res->ai_protocol),
1234 	    strerror(errno));
1235     fflush(where);
1236     exit(1);
1237   }
1238 
1239   if (debug) {
1240     fprintf(where,"create_data_socket: socket %d obtained...\n",temp_socket);
1241     fflush(where);
1242   }
1243 
1244   /* Modify the local socket size. The reason we alter the send buffer
1245    size here rather than when the connection is made is to take care
1246    of decreases in buffer size. Decreasing the window size after
1247    connection establishment is a TCP no-no. Also, by setting the
1248    buffer (window) size before the connection is established, we can
1249    control the TCP MSS (segment size). The MSS is never (well, should
1250    never be) more that 1/2 the minimum receive buffer size at each
1251    half of the connection.  This is why we are altering the receive
1252    buffer size on the sending size of a unidirectional transfer. If
1253    the user has not requested that the socket buffers be altered, we
1254    will try to find-out what their values are. If we cannot touch the
1255    socket buffer in any way, we will set the values to -1 to indicate
1256    that.  */
1257 
1258   /* all the oogy nitty gritty stuff moved from here into the routine
1259      being called below, per patches from davidm to workaround the bug
1260      in Linux getsockopt().  raj 2004-06-15 */
1261   set_sock_buffer (temp_socket, SEND_BUFFER, lss_size_req, &lss_size);
1262   set_sock_buffer (temp_socket, RECV_BUFFER, lsr_size_req, &lsr_size);
1263 
1264   /* now, we may wish to enable the copy avoidance features on the */
1265   /* local system. of course, this may not be possible... */
1266 
1267 #ifdef SO_RCV_COPYAVOID
1268   /* this is ancient vestigial HP-UX code that should probably go away
1269      one day */
1270   if (loc_rcvavoid) {
1271     if (setsockopt(temp_socket,
1272 		   SOL_SOCKET,
1273 		   SO_RCV_COPYAVOID,
1274 		   (const char *)&loc_rcvavoid,
1275 		   sizeof(int)) == SOCKET_ERROR) {
1276       fprintf(where,
1277 	      "netperf: create_data_socket: Could not enable receive copy avoidance");
1278       fflush(where);
1279       loc_rcvavoid = 0;
1280     }
1281   }
1282 #endif
1283 
1284 #ifdef SO_SND_COPYAVOID
1285   if (loc_sndavoid) {
1286     if (setsockopt(temp_socket,
1287 		   SOL_SOCKET,
1288 		   SO_SND_COPYAVOID,
1289 		   (const char *)&loc_sndavoid,
1290 		   sizeof(int)) == SOCKET_ERROR) {
1291       fprintf(where,
1292 	      "netperf: create_data_socket: Could not enable send copy avoidance");
1293       fflush(where);
1294       loc_sndavoid = 0;
1295     }
1296   }
1297 #endif
1298 
1299   /* Now, we will see about setting the TCP_NODELAY flag on the local */
1300   /* socket. We will only do this for those systems that actually */
1301   /* support the option. If it fails, note the fact, but keep going. */
1302   /* If the user tries to enable TCP_NODELAY on a UDP socket, this */
1303   /* will cause an error to be displayed */
1304 
1305   /* well..... long ago and far away that would have happened, in
1306      particular because we would always use IPPROTO_TCP here.
1307      however, now we are using res->ai_protocol, which will be
1308      IPPROT_UDP, and while HP-UX, and I suspect no-one else on the
1309      planet has a UDP_mumble option that overlaps with TCP_NODELAY,
1310      sure as knuth made little green programs, linux has a UDP_CORK
1311      option that is defined as a value of 1, which is the same a
1312      TCP_NODELAY under Linux.  So, when asking for -D and
1313      "TCP_NODELAY" under Linux, we are actually setting UDP_CORK
1314      instead of getting an error like every other OS on the
1315      planet. joy and rupture. this stops a UDP_RR test cold sooo we
1316      have to make sure that res->ai_protocol actually makes sense for
1317      a _NODELAY setsockopt() or a UDP_RR test on Linux where someone
1318      mistakenly sets -D will hang.  raj 2005-04-21 */
1319 
1320 #if defined(TCP_NODELAY) || defined(SCTP_NODELAY)
1321   if ((loc_nodelay) && (res->ai_protocol != IPPROTO_UDP)) {
1322 
1323     /* strictly speaking, since the if defined above is an OR, we
1324        should probably check against TCP_NODELAY being defined here.
1325        however, the likelihood of SCTP_NODELAY being defined and
1326        TCP_NODELAY _NOT_ being defined is, probably :), epsilon.  raj
1327        2005-03-15 */
1328 
1329     int option = TCP_NODELAY;
1330 
1331     /* I suspect that WANT_SCTP would suffice here since that is the
1332        only time we would have called getaddrinfo with a hints asking
1333        for SCTP, but just in case there is an SCTP implementation out
1334        there _without_ SCTP_NODELAY... raj 2005-03-15 */
1335     /* change this to IPPROTO_SCTP rather than WANT_SCTP to better fit
1336        with the modus operandi of the new "omni" tests. raj
1337        2008-02-04 */
1338 #if defined(IPPROTO_SCTP) && defined(SCTP_NODELAY)
1339     if (IPPROTO_SCTP == res->ai_protocol) {
1340       option = SCTP_NODELAY;
1341     }
1342 #endif
1343 
1344     one = 1;
1345     if(setsockopt(temp_socket,
1346 		  res->ai_protocol,
1347 		  option,
1348 		  (char *)&one,
1349 		  sizeof(one)) == SOCKET_ERROR) {
1350       fprintf(where,
1351 	      "netperf: create_data_socket: nodelay: errno %d\n",
1352 	      errno);
1353       fflush(where);
1354     }
1355 
1356     if (debug > 1) {
1357       fprintf(where,
1358 	      "netperf: create_data_socket: [TCP|SCTP]_NODELAY requested...\n");
1359       fflush(where);
1360     }
1361   }
1362 #else /* TCP_NODELAY */
1363 
1364   loc_nodelay = 0;
1365 
1366 #endif /* TCP_NODELAY */
1367 
1368   if ((transport_mss_req != -1) && (IPPROTO_TCP == res->ai_protocol)) {
1369     set_tcp_mss(temp_socket,transport_mss_req);
1370   }
1371 
1372 #if defined(TCP_CORK)
1373 
1374   if (loc_tcpcork > 0) {
1375     /* the user wishes for us to set TCP_CORK on the socket */
1376     if (setsockopt(temp_socket,
1377 		   getprotobyname("tcp")->p_proto,
1378 		   TCP_CORK,
1379 		   (char *)&one,
1380 		   sizeof(one)) == SOCKET_ERROR) {
1381       perror("netperf: create_data_socket: tcp_cork");
1382       exit(1);
1383     }
1384     if (debug) {
1385       fprintf(where,"create_data_socket: tcp_cork...\n");
1386     }
1387   }
1388 
1389 #endif /* TCP_CORK */
1390 
1391   /* well, after Knuth only knows how many years, I have finally
1392     decided to enable setting SO_KEEPALIVE on the data socket.  99
1393     times out of 10 this should not be necessary, but that 100th time,
1394     perhaps when netperf is being (ab)used by functional testers, may
1395     benefit from it.  And it may help clean-up some lingering
1396     netservers from time to time.  raj 2011-06-29 */
1397 
1398 #if defined(SO_KEEPALIVE)
1399 
1400   if (want_keepalive) {
1401     if (setsockopt(temp_socket,
1402 		   SOL_SOCKET,
1403 		   SO_KEEPALIVE,
1404 		   (const char *)&on,
1405 		   sizeof(on)) < 0) {
1406       if (debug) {
1407 	fprintf(where,
1408 		"%s: unable to set SO_KEEPALIVE on data socket: %s (errno %d)\n",
1409 		__FUNCTION__,
1410 		strerror(errno),
1411 		errno);
1412 	fflush(where);
1413       }
1414     }
1415   }
1416 
1417 #endif /* SO_KEEPALIVE */
1418 
1419   /* since some of the UDP tests do not do anything to cause an
1420      implicit bind() call, we need to be rather explicit about our
1421      bind() call here. even if the address and/or the port are zero
1422      (INADDR_ANY etc). raj 2004-07-20 */
1423 
1424   if (setsockopt(temp_socket,
1425 #ifdef IPPROTO_DCCP
1426 		 /* it is REALLY SILLY THAT THIS SHOULD BE NEEDED!! I
1427 		    should be able to use SOL_SOCKET for this just
1428 		    like TCP and SCTP */
1429 		 /* IT IS EVEN SILLIER THAT THERE COULD BE SYSTEMS
1430 		    WITH IPPROTO_DCCP and no SOL_DCCP */
1431 #ifndef SOL_DCCP
1432 #define SOL_DCCP SOL_SOCKET
1433 #define NETPERF_NEED_CLEANUP 1
1434 #endif
1435 		 (res->ai_protocol == IPPROTO_DCCP) ? SOL_DCCP : SOL_SOCKET,
1436 #ifdef NETPERF_NEED_CLEANUP
1437 #undef SOL_DCCP
1438 #undef NETPERF_NEED_CLEANUP
1439 #endif
1440 
1441 #else
1442 		 SOL_SOCKET,
1443 #endif
1444 		 SO_REUSEADDR,
1445 		 (const char *)&on,
1446 		 sizeof(on)) < 0) {
1447     fprintf(where,
1448 	    "netperf: create_data_socket: SO_REUSEADDR failed %d\n",
1449 	    errno);
1450     fflush(where);
1451   }
1452 
1453   /* bind only if we must */
1454   if ((get_port_number(res) != 0) ||
1455       (res->ai_protocol == IPPROTO_UDP)) {
1456     if (bind(temp_socket,
1457 	     res->ai_addr,
1458 	     res->ai_addrlen) < 0) {
1459       if (debug) {
1460 	fprintf(where,
1461 		"netperf: create_data_socket: data socket bind failed: %s (errno %d)\n",
1462 		strerror(errno),
1463 		errno);
1464 	fprintf(where," port: %d\n",get_port_number(res));
1465 	fflush(where);
1466       }
1467     }
1468   }
1469   /* this one is a slightly grudgingly added backside covering for
1470      those folks who (ab)use netperf as a functional testing tool, and
1471      further compound that error by running tests on systems also
1472      connected to their site networks, and then compound it even
1473      further compound it by running UDP_STREAM tests over links that
1474      generate link-down events and so cause the traffic to be sent out
1475      the default route into their corporate network...  frankly such
1476      people should not be allowed to run netperf in the first place
1477      but there we are... raj 20091026 */
1478 
1479 #if defined (SO_DONTROUTE)
1480   if (!routing_allowed) {
1481     if (setsockopt(temp_socket,
1482 		   SOL_SOCKET,
1483 		   SO_DONTROUTE,
1484 		   (char *)&one,
1485 		   sizeof(one)) == SOCKET_ERROR) {
1486       fprintf(where,
1487 	      "netperf: create_data_socket: so_dontroute: errno %d\n",
1488 	      errno);
1489       fflush(where);
1490     }
1491   }
1492 #endif
1493 
1494 #if defined(SO_PRIORITY)
1495   if (local_socket_prio >= 0) {
1496     if (setsockopt(temp_socket,
1497                   SOL_SOCKET,
1498                   SO_PRIORITY,
1499                   &local_socket_prio,
1500                   sizeof(int)) == SOCKET_ERROR) {
1501       fprintf(where,
1502              "netperf: create_data_socket: so_priority: errno %d\n",
1503              errno);
1504       fflush(where);
1505       local_socket_prio = -2;
1506     }
1507     else {
1508       sock_opt_len = 4;
1509       getsockopt(temp_socket,
1510 		 SOL_SOCKET,
1511 		 SO_PRIORITY,
1512 		 &local_socket_prio,
1513 		 &sock_opt_len);
1514     }
1515   }
1516 #else
1517   local_socket_prio = -3;
1518 #endif
1519 
1520 #if defined (IP_TOS) || defined(IPV6_TCLASS)
1521   if (local_socket_tos > 0)
1522     local_socket_tos = set_socket_tos(temp_socket,res->ai_family, local_socket_tos);
1523 #endif
1524 
1525   /* some platforms can be told to set a rate on a socket */
1526 #ifndef SO_MAX_PACING_RATE
1527 #define SO_MAX_PACING_RATE 47
1528 #endif
1529 
1530   if (pacing_rate > 0) {
1531     if (setsockopt(temp_socket, SOL_SOCKET, SO_MAX_PACING_RATE,
1532 		   &pacing_rate,
1533 		   sizeof(pacing_rate)) < 0) {
1534       fprintf(where, "netperf: setsockopt: SO_MAX_PACING_RATE: errno %d\n",
1535 	      errno);
1536     }
1537   }
1538 
1539   return temp_socket;
1540 }
1541 
1542 #ifdef KLUDGE_SOCKET_OPTIONS
1543 
1544 
1545  /* This routine is for those BROKEN systems which do not correctly */
1546  /* pass socket attributes through calls such as accept(). It should */
1547  /* only be called for those broken systems. I *really* don't want to */
1548  /* have this, but even broken systems must be measured. raj 11/95 */
1549 void
kludge_socket_options(int temp_socket)1550 kludge_socket_options(int temp_socket)
1551 {
1552 
1553   set_sock_buffer(temp_socket, SEND_BUFFER, lss_size_req, &lss_size);
1554   set_sock_buffer(temp_socket, RECV_BUFFER, lsr_size_req, &lsr_size);
1555 
1556   /* now, we may wish to enable the copy avoidance features on the */
1557   /* local system. of course, this may not be possible... */
1558   /* those calls were only valid for HP-UX, and I know that HP-UX is */
1559   /* written correctly, and so we do not need to include those calls */
1560   /* in this kludgy routine. raj 11/95 */
1561 
1562 
1563   /* Now, we will see about setting the TCP_NODELAY flag on the local */
1564   /* socket. We will only do this for those systems that actually */
1565   /* support the option. If it fails, note the fact, but keep going. */
1566   /* If the user tries to enable TCP_NODELAY on a UDP socket, this */
1567   /* will cause an error to be displayed */
1568 
1569 #ifdef TCP_NODELAY
1570   if (loc_nodelay) {
1571     one = 1;
1572     if(setsockopt(temp_socket,
1573 		  getprotobyname("tcp")->p_proto,
1574 		  TCP_NODELAY,
1575 		  (char *)&one,
1576 		  sizeof(one)) == SOCKET_ERROR) {
1577       fprintf(where,"netperf: kludge_socket_options: nodelay: errno %d\n",
1578 	      errno);
1579       fflush(where);
1580     }
1581 
1582     if (debug > 1) {
1583       fprintf(where,
1584 	      "netperf: kludge_socket_options: TCP_NODELAY requested...\n");
1585       fflush(where);
1586     }
1587   }
1588 #else /* TCP_NODELAY */
1589 
1590   loc_nodelay = 0;
1591 
1592 #endif /* TCP_NODELAY */
1593 
1594   }
1595 
1596 #endif /* KLUDGE_SOCKET_OPTIONS */
1597 
1598 
1599 static void *
get_address_address(struct addrinfo * info)1600 get_address_address(struct addrinfo *info)
1601 {
1602   struct sockaddr_in *sin;
1603 #if defined(AF_INET6)
1604   struct sockaddr_in6 *sin6;
1605 #endif
1606 
1607   switch(info->ai_family) {
1608   case AF_INET:
1609     sin = (struct sockaddr_in *)info->ai_addr;
1610     return(&(sin->sin_addr));
1611     break;
1612 #if defined(AF_INET6)
1613   case AF_INET6:
1614     sin6 = (struct sockaddr_in6 *)info->ai_addr;
1615     return(&(sin6->sin6_addr));
1616     break;
1617 #endif
1618   default:
1619     fprintf(stderr,"we never expected to get here in get_address_address\n");
1620     fflush(stderr);
1621     exit(-1);
1622   }
1623 }
1624 
1625 #if defined(WIN32)
1626 #if !defined(InetNtop)
1627 /* +*+ Why isn't this in the winsock headers yet? */
1628 const char *
1629 inet_ntop(int af, const void *src, char *dst, size_t size);
1630 #endif
1631 #endif
1632 
1633 /* This routine is a generic test header printer for the topmost header */
1634 void
print_top_test_header(char test_name[],struct addrinfo * source,struct addrinfo * destination)1635 print_top_test_header(char test_name[], struct addrinfo *source, struct addrinfo *destination)
1636 {
1637 
1638   char *address_buf;
1639 
1640 #ifdef AF_INET6
1641   address_buf = malloc(INET6_ADDRSTRLEN);
1642 #else
1643   address_buf = malloc(16); /* magic constant */
1644 #endif
1645 
1646   if (address_buf == NULL) {
1647     fprintf(where,"Unable to allocate address_buf\n");
1648     fflush(where);
1649     exit(1);
1650   }
1651 
1652   /* we want to have some additional, interesting information in the
1653      headers. we know some of it here, but not all, so we will only
1654      print the test title here and will print the results titles after
1655      the test is finished */
1656   fprintf(where,"%s",test_name);
1657 
1658   address_buf[0] = '\0';
1659   inet_ntop(source->ai_family,get_address_address(source),address_buf,sizeof(address_buf));
1660   fprintf(where,
1661 	  " from %s (%s) port %u %s",
1662 	  source->ai_canonname,
1663 	  address_buf,
1664 	  get_port_number(source),
1665 	  inet_ftos(source->ai_family));
1666 
1667   address_buf[0] = '\0';
1668   inet_ntop(destination->ai_family,get_address_address(destination),address_buf,sizeof(address_buf));
1669   fprintf(where,
1670 	  " to %s (%s) port %u %s",
1671 	  destination->ai_canonname,
1672 	  address_buf,
1673 	  get_port_number(destination),
1674 	  inet_ftos(destination->ai_family));
1675 
1676   if (iteration_max > 1) {
1677     fprintf(where,
1678 	    " : +/-%.3f%% @ %2d%% conf. %s",
1679 	    interval/0.02,
1680 	    confidence_level,
1681 	    result_confidence_only ? " on result only" : "");
1682   }
1683   if ((loc_nodelay > 0) || (rem_nodelay > 0)) {
1684     fprintf(where," : nodelay");
1685   }
1686   if ((loc_sndavoid > 0) ||
1687       (loc_rcvavoid > 0) ||
1688       (rem_sndavoid > 0) ||
1689       (rem_rcvavoid > 0)) {
1690     fprintf(where," : copy avoidance");
1691   }
1692 
1693   if (no_control) {
1694     fprintf(where," : no control");
1695   }
1696 
1697 #ifdef WANT_HISTOGRAM
1698   fprintf(where," : histogram");
1699 #endif /* WANT_HISTOGRAM */
1700 
1701 #ifdef WANT_INTERVALS
1702 #ifndef WANT_SPIN
1703   fprintf(where," : interval");
1704 #else
1705   fprintf(where," : spin interval");
1706 #endif
1707 #endif /* WANT_INTERVALS */
1708 
1709 #ifdef DIRTY
1710   fprintf(where," : dirty data");
1711 #endif /* DIRTY */
1712 #ifdef WANT_DEMO
1713   fprintf(where," : demo");
1714 #endif
1715 #ifdef WANT_FIRST_BURST
1716   /* a little hokey perhaps, but we really only want this to be
1717      emitted for tests where it actually is used, which means a
1718      "REQUEST/RESPONSE" test. raj 2005-11-10 */
1719   if (strstr(test_name,"REQUEST/RESPONSE")) {
1720     fprintf(where," : first burst %d",first_burst_size);
1721   }
1722 #endif
1723   if (cpu_binding_requested) {
1724     fprintf(where," : cpu bind");
1725   }
1726   fprintf(where,"\n");
1727 
1728   free(address_buf);
1729 }
1730 
1731 /* if WANT_MIGRATION is defined, we will use the send_tcp_stream()
1732    call in src/nettest_omni.c */
1733 #ifndef WANT_MIGRATION
1734 
1735 /* This routine implements the TCP unidirectional data transfer test */
1736 /* (a.k.a. stream) for the sockets interface. It receives its */
1737 /* parameters via global variables from the shell and writes its */
1738 /* output to the standard output. */
1739 
1740 void
send_tcp_stream(char remote_host[])1741 send_tcp_stream(char remote_host[])
1742 {
1743 
1744   char *tput_title = "\
1745 Recv   Send    Send                          \n\
1746 Socket Socket  Message  Elapsed              \n\
1747 Size   Size    Size     Time     Throughput  \n\
1748 bytes  bytes   bytes    secs.    %s/sec  \n\n";
1749 
1750   char *tput_fmt_0 =
1751     "%7.2f %s\n";
1752 
1753   char *tput_fmt_1 =
1754     "%6d %6d %6d    %-6.2f   %7.2f   %s\n";
1755 
1756   char *cpu_title = "\
1757 Recv   Send    Send                          Utilization       Service Demand\n\
1758 Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
1759 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
1760 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
1761 
1762   char *cpu_fmt_0 =
1763     "%6.3f %c %s\n";
1764 
1765   char *cpu_fmt_1 =
1766     "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f %s\n";
1767 
1768   char *ksink_fmt = "\n\
1769 Alignment      Offset         %-8.8s %-8.8s    Sends   %-8.8s Recvs\n\
1770 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
1771 Send   Recv    Send   Recv             Send (avg)          Recv (avg)\n\
1772 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
1773 
1774   char *ksink_fmt2 = "\n\
1775 Maximum\n\
1776 Segment\n\
1777 Size (bytes)\n\
1778 %6d\n";
1779 
1780 
1781   float			elapsed_time;
1782 
1783   /* what we want is to have a buffer space that is at least one */
1784   /* send-size greater than our send window. this will insure that we */
1785   /* are never trying to re-use a buffer that may still be in the hands */
1786   /* of the transport. This buffer will be malloc'd after we have found */
1787   /* the size of the local senc socket buffer. We will want to deal */
1788   /* with alignment and offset concerns as well. */
1789 
1790   struct ring_elt *send_ring;
1791 
1792   int len;
1793   unsigned int nummessages = 0;
1794   SOCKET send_socket;
1795   int bytes_remaining;
1796   int tcp_mss = -1;  /* possibly uninitialized on printf far below */
1797 
1798   /* with links like fddi, one can send > 32 bits worth of bytes
1799      during a test... ;-) at some point, this should probably become a
1800      64bit integral type, but those are not entirely common
1801      yet... time passes, and 64 bit types do indeed become common. */
1802 #if defined(WIN32) && _MSC_VER <= 1200
1803   __int64 local_bytes_sent = 0;
1804 #else
1805   unsigned long long local_bytes_sent = 0;
1806 #endif
1807 
1808   double	bytes_sent = 0.0;
1809 
1810   float	local_cpu_utilization;
1811   float	local_service_demand;
1812   float	remote_cpu_utilization;
1813   float	remote_service_demand;
1814 
1815   double	thruput;
1816 
1817   struct addrinfo *remote_res;
1818   struct addrinfo *local_res;
1819 
1820   struct	tcp_stream_request_struct	*tcp_stream_request;
1821   struct	tcp_stream_response_struct	*tcp_stream_response;
1822   struct	tcp_stream_results_struct	*tcp_stream_result;
1823 
1824   tcp_stream_request  =
1825     (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
1826   tcp_stream_response =
1827     (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
1828   tcp_stream_result   =
1829     (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
1830 
1831 #ifdef WANT_HISTOGRAM
1832   if (verbosity > 1) {
1833     time_hist = HIST_new();
1834   }
1835 #endif /* WANT_HISTOGRAM */
1836   /* since we are now disconnected from the code that established the */
1837   /* control socket, and since we want to be able to use different */
1838   /* protocols and such, we are passed the name of the remote host and */
1839   /* must turn that into the test specific addressing information. */
1840 
1841   /* complete_addrinfos will either succede or exit the process */
1842   complete_addrinfos(&remote_res,
1843 		     &local_res,
1844 		     remote_host,
1845 		     SOCK_STREAM,
1846 		     IPPROTO_TCP,
1847 		     0);
1848 
1849   if ( print_headers ) {
1850     print_top_test_header("TCP STREAM TEST",local_res,remote_res);
1851   }
1852 
1853   send_ring = NULL;
1854   confidence_iteration = 1;
1855   init_stat();
1856 
1857   /* we have a great-big while loop which controls the number of times */
1858   /* we run a particular test. this is for the calculation of a */
1859   /* confidence interval (I really should have stayed awake during */
1860   /* probstats :). If the user did not request confidence measurement */
1861   /* (no confidence is the default) then we will only go though the */
1862   /* loop once. the confidence stuff originates from the folks at IBM */
1863 
1864   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
1865 	 (confidence_iteration <= iteration_min)) {
1866 
1867     /* initialize a few counters. we have to remember that we might be */
1868     /* going through the loop more than once. */
1869 
1870     nummessages    =	0;
1871     bytes_sent     =	0.0;
1872     times_up       = 	0;
1873 
1874     /*set up the data socket                        */
1875     send_socket = create_data_socket(local_res);
1876 
1877     if (send_socket == INVALID_SOCKET){
1878       perror("netperf: send_tcp_stream: tcp stream data socket");
1879       exit(1);
1880     }
1881 
1882     if (debug) {
1883       fprintf(where,"send_tcp_stream: send_socket obtained...\n");
1884     }
1885 
1886     /* at this point, we have either retrieved the socket buffer sizes, */
1887     /* or have tried to set them, so now, we may want to set the send */
1888     /* size based on that (because the user either did not use a -m */
1889     /* option, or used one with an argument of 0). If the socket buffer */
1890     /* size is not available, we will set the send size to 4KB - no */
1891     /* particular reason, just arbitrary... */
1892     if (send_size == 0) {
1893       if (lss_size > 0) {
1894 	send_size = lss_size;
1895       }
1896       else {
1897 	send_size = 4096;
1898       }
1899     }
1900 
1901     /* set-up the data buffer ring with the requested alignment and offset. */
1902     /* note also that we have allocated a quantity */
1903     /* of memory that is at least one send-size greater than our socket */
1904     /* buffer size. We want to be sure that there are at least two */
1905     /* buffers allocated - this can be a bit of a problem when the */
1906     /* send_size is bigger than the socket size, so we must check... the */
1907     /* user may have wanted to explicitly set the "width" of our send */
1908     /* buffers, we should respect that wish... */
1909     if (send_width == 0) {
1910       send_width = (lss_size/send_size) + 1;
1911       if (send_width == 1) send_width++;
1912     }
1913 
1914     if (send_ring == NULL) {
1915       /* only allocate the send ring once. this is a networking test, */
1916       /* not a memory allocation test. this way, we do not need a */
1917       /* deallocate_buffer_ring() routine, and I don't feel like */
1918       /* writing one anyway :) raj 11/94 */
1919       send_ring = allocate_buffer_ring(send_width,
1920 				       send_size,
1921 				       local_send_align,
1922 				       local_send_offset);
1923     }
1924 
1925     /* If the user has requested cpu utilization measurements, we must */
1926     /* calibrate the cpu(s). We will perform this task within the tests */
1927     /* themselves. If the user has specified the cpu rate, then */
1928     /* calibrate_local_cpu will return rather quickly as it will have */
1929     /* nothing to do. If local_cpu_rate is zero, then we will go through */
1930     /* all the "normal" calibration stuff and return the rate back. */
1931 
1932     if (local_cpu_usage) {
1933       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
1934     }
1935 
1936     if (!no_control) {
1937       /* Tell the remote end to do a listen. The server alters the
1938 	 socket paramters on the other side at this point, hence the
1939 	 reason for all the values being passed in the setup
1940 	 message. If the user did not specify any of the parameters,
1941 	 they will be passed as 0, which will indicate to the remote
1942 	 that no changes beyond the system's default should be
1943 	 used. Alignment is the exception, it will default to 1, which
1944 	 will be no alignment alterations. */
1945 
1946       netperf_request.content.request_type =	DO_TCP_STREAM;
1947       tcp_stream_request->send_buf_size	=	rss_size_req;
1948       tcp_stream_request->recv_buf_size	=	rsr_size_req;
1949       tcp_stream_request->receive_size	=	recv_size;
1950       tcp_stream_request->no_delay	=	rem_nodelay;
1951       tcp_stream_request->recv_alignment	=	remote_recv_align;
1952       tcp_stream_request->recv_offset	=	remote_recv_offset;
1953       tcp_stream_request->measure_cpu	=	remote_cpu_usage;
1954       tcp_stream_request->cpu_rate	=	remote_cpu_rate;
1955       if (test_time) {
1956 	tcp_stream_request->test_length	=	test_time;
1957       }
1958       else {
1959 	tcp_stream_request->test_length	=	test_bytes;
1960       }
1961       tcp_stream_request->so_rcvavoid	=	rem_rcvavoid;
1962       tcp_stream_request->so_sndavoid	=	rem_sndavoid;
1963 #ifdef DIRTY
1964       tcp_stream_request->dirty_count     =       rem_dirty_count;
1965       tcp_stream_request->clean_count     =       rem_clean_count;
1966 #endif /* DIRTY */
1967       tcp_stream_request->port            =    atoi(remote_data_port);
1968       tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
1969       tcp_stream_request->recv_aio      =       rem_rcvaio;
1970       if (debug > 1) {
1971 	fprintf(where,
1972 		"netperf: send_tcp_stream: requesting TCP stream test\n");
1973       }
1974 
1975       send_request();
1976 
1977       /* The response from the remote will contain all of the relevant
1978          socket parameters for this test type. We will put them back
1979          into the variables here so they can be displayed if desired.
1980          The remote will have calibrated CPU if necessary, and will
1981          have done all the needed set-up we will have calibrated the
1982          cpu locally before sending the request, and will grab the
1983          counter value right after the connect returns. The remote
1984          will grab the counter right after the accept call. This saves
1985          the hassle of extra messages being sent for the TCP
1986          tests.  */
1987 
1988       recv_response();
1989 
1990       if (!netperf_response.content.serv_errno) {
1991 	if (debug)
1992 	  fprintf(where,"remote listen done.\n");
1993 	rsr_size	      =	tcp_stream_response->recv_buf_size;
1994 	rss_size	      =	tcp_stream_response->send_buf_size;
1995 	rem_nodelay     =	tcp_stream_response->no_delay;
1996 	remote_cpu_usage=	tcp_stream_response->measure_cpu;
1997 	remote_cpu_rate = tcp_stream_response->cpu_rate;
1998 
1999 	/* we have to make sure that the server port number is in
2000 	   network order */
2001 	set_port_number(remote_res,
2002 			(short)tcp_stream_response->data_port_number);
2003 
2004 	rem_rcvavoid	= tcp_stream_response->so_rcvavoid;
2005 	rem_sndavoid	= tcp_stream_response->so_sndavoid;
2006       }
2007       else {
2008 	Set_errno(netperf_response.content.serv_errno);
2009 	fprintf(where,
2010 		"netperf: remote error %d",
2011 		netperf_response.content.serv_errno);
2012 	perror("");
2013 	fflush(where);
2014 
2015 	exit(1);
2016       }
2017     }
2018 
2019 #ifdef WANT_DEMO
2020     demo_stream_setup(lss_size,rsr_size);
2021 #endif
2022 
2023     /*Connect up to the remote port on the data socket  */
2024     if (connect(send_socket,
2025 		remote_res->ai_addr,
2026 		remote_res->ai_addrlen) == INVALID_SOCKET){
2027       perror("netperf: send_tcp_stream: data socket connect failed");
2028       exit(1);
2029     }
2030 
2031 #ifdef WIN32
2032   /* this is used so the timer thread can close the socket out from */
2033   /* under us, which to date is the easiest/cleanest/least */
2034   /* Windows-specific way I can find to force the winsock calls to */
2035   /* return WSAEINTR with the test is over. anything that will run on */
2036   /* 95 and NT and is closer to what netperf expects from Unix signals */
2037   /* and such would be appreciated raj 1/96 */
2038   win_kludge_socket = send_socket;
2039 #endif /* WIN32 */
2040 
2041     /* Data Socket set-up is finished. If there were problems, either */
2042     /* the connect would have failed, or the previous response would */
2043     /* have indicated a problem. I failed to see the value of the */
2044     /* extra  message after the accept on the remote. If it failed, */
2045     /* we'll see it here. If it didn't, we might as well start pumping */
2046     /* data. */
2047 
2048     /* Set-up the test end conditions. For a stream test, they can be */
2049     /* either time or byte-count based. */
2050 
2051     if (test_time) {
2052       /* The user wanted to end the test after a period of time. */
2053       times_up = 0;
2054       bytes_remaining = 0;
2055       /* in previous revisions, we had the same code repeated throught */
2056       /* all the test suites. this was unnecessary, and meant more */
2057       /* work for me when I wanted to switch to POSIX signals, so I */
2058       /* have abstracted this out into a routine in netlib.c. if you */
2059       /* are experiencing signal problems, you might want to look */
2060       /* there. raj 11/94 */
2061       start_timer(test_time);
2062     }
2063     else {
2064       /* The tester wanted to send a number of bytes. */
2065       bytes_remaining = test_bytes;
2066       times_up = 1;
2067     }
2068 
2069     /* The cpu_start routine will grab the current time and possibly */
2070     /* value of the idle counter for later use in measuring cpu */
2071     /* utilization and/or service demand and thruput. */
2072 
2073     cpu_start(local_cpu_usage);
2074 
2075     /* we only start the interval timer if we are using the
2076        timer-timed intervals rather than the sit and spin ones. raj
2077        2006-02-06 */
2078 #if defined(WANT_INTERVALS)
2079     INTERVALS_INIT();
2080 #endif /* WANT_INTERVALS */
2081 
2082     /* before we start, initialize a few variables */
2083 
2084 #ifdef WANT_DEMO
2085       if (demo_mode) {
2086 	demo_first_timestamp();
2087       }
2088 #endif
2089 
2090 
2091     /* We use an "OR" to control test execution. When the test is */
2092     /* controlled by time, the byte count check will always return false. */
2093     /* When the test is controlled by byte count, the time test will */
2094     /* always return false. When the test is finished, the whole */
2095     /* expression will go false and we will stop sending data. */
2096 
2097     while ((!times_up) || (bytes_remaining > 0)) {
2098 
2099 #if HAVE_AIO
2100       /* When using aio, wait for the previous write for this buffer to
2101 	 complete. */
2102       if (loc_sndaio > 0 && send_ring->completion_ptr != NULL) {
2103 	const struct aiocb *iocblist[1];
2104 	struct aiocb *iocb;
2105 	int error;
2106 
2107 	iocb = send_ring->completion_ptr;
2108 	iocblist[0] = iocb;
2109 	if (aio_suspend(iocblist, 1, NULL) == -1) {
2110 	  if (errno == EINTR) {
2111 	    /* the test was interrupted, must be the end of test */
2112 	    break;
2113 	  }
2114 	  perror("netperf: data send error");
2115 	  exit(1);
2116 	}
2117 
2118 	error = aio_error(iocb);
2119 	if (error == 0)
2120 	  len = aio_return(iocb);
2121 	else {
2122 	  len = SOCKET_ERROR;
2123 	  errno = error;
2124 	}
2125       }
2126 #endif
2127 
2128 #ifdef DIRTY
2129       access_buffer(send_ring->buffer_ptr,
2130 		    send_size,
2131 		    loc_dirty_count,
2132 		    loc_clean_count);
2133 #endif /* DIRTY */
2134 
2135 #ifdef WANT_HISTOGRAM
2136       if (verbosity > 1) {
2137 	/* timestamp just before we go into send and then again just
2138 	 after we come out raj 8/94 */
2139 	/* but lets only do this if there is going to be a histogram
2140 	   displayed */
2141 	HIST_timestamp(&time_one);
2142       }
2143 #endif /* WANT_HISTOGRAM */
2144 
2145 #if HAVE_AIO
2146       if (loc_sndaio > 0) {
2147 	struct aiocb *iocb, *old;
2148 
2149 	old = iocb = send_ring->completion_ptr;
2150 	if (iocb == NULL) {
2151 	  iocb = calloc(1, sizeof(*iocb));
2152 	  send_ring->completion_ptr = iocb;
2153 	} else
2154 	  memset(iocb, 0, sizeof(*iocb));
2155 	iocb->aio_nbytes = send_size;
2156 	iocb->aio_fildes = send_socket;
2157 	iocb->aio_buf = send_ring->buffer_ptr;
2158 	if (aio_write(iocb) == -1) {
2159 	  if (errno == EINTR) {
2160 	    /* the test was interrupted, must be the end of test */
2161 	    /* clear the completion pointer to avoid trying to cancel it */
2162 	    send_ring->completion_ptr = NULL;
2163 	    send_ring = send_ring->next;
2164 	    break;
2165 	  }
2166 	  perror("netperf: data send error");
2167 	  exit(1);
2168 	}
2169 	if (old == NULL)
2170 	  /* No previous write was completed. */
2171 	  goto next_buffer;
2172       } else
2173 #endif
2174 	len = send(send_socket,
2175 		   send_ring->buffer_ptr,
2176 		   send_size,
2177 		   0);
2178 
2179       if(len != send_size) {
2180       if ((len >=0) || SOCKET_EINTR(len)) {
2181 	    /* the test was interrupted, must be the end of test */
2182 	    break;
2183 	  }
2184 	perror("netperf: data send error");
2185 	printf("len was %d\n",len);
2186 	exit(1);
2187       }
2188 
2189       local_bytes_sent += send_size;
2190 
2191 #if HAVE_AIO
2192     next_buffer:
2193 #endif
2194 
2195 #ifdef WANT_HISTOGRAM
2196       if (verbosity > 1) {
2197 	/* timestamp the exit from the send call and update the histogram */
2198 	HIST_timestamp(&time_two);
2199 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
2200       }
2201 #endif /* WANT_HISTOGRAM */
2202 
2203 #ifdef WANT_DEMO
2204       demo_stream_interval(send_size);
2205 #endif
2206 
2207 #if defined(WANT_INTERVALS)
2208       INTERVALS_WAIT();
2209 #endif /* WANT_INTERVALS */
2210 
2211       /* now we want to move our pointer to the next position in the */
2212       /* data buffer...we may also want to wrap back to the "beginning" */
2213       /* of the bufferspace, so we will mod the number of messages sent */
2214       /* by the send width, and use that to calculate the offset to add */
2215       /* to the base pointer. */
2216       nummessages++;
2217       send_ring = send_ring->next;
2218       if (bytes_remaining) {
2219 	bytes_remaining -= send_size;
2220       }
2221     }
2222 
2223     /* The test is over. Flush the buffers to the remote end. We do a */
2224     /* graceful release to insure that all data has been taken by the */
2225     /* remote. */
2226 
2227 #if HAVE_AIO
2228     if (loc_sndaio > 0) {
2229       const struct aiocb *iocblist[1];
2230       struct ring_elt *send_ring2;
2231       struct aiocb *iocb;
2232       int error;
2233 
2234       send_ring2 = send_ring;
2235       while (send_ring2->completion_ptr != NULL) {
2236 	if (aio_cancel(send_socket, send_ring2->completion_ptr) == -1) {
2237 	  perror("netperf: data send error");
2238 	  exit(1);
2239 	}
2240 	send_ring2 = send_ring2->next;
2241 	if (send_ring2 == send_ring)
2242 	  break;
2243       }
2244 
2245       while (send_ring->completion_ptr != NULL) {
2246 	iocb = send_ring->completion_ptr;
2247 	iocblist[0] = iocb;
2248 	if (aio_suspend(iocblist, 1, NULL) == -1) {
2249 	  perror("netperf: data send error");
2250 	  exit(1);
2251 	}
2252 
2253 	error = aio_error(iocb);
2254 	if (error == 0)
2255 	  local_bytes_sent += aio_return(iocb);
2256 	else if (error != ECANCELED) {
2257 	  errno = error;
2258 	  perror("netperf: data send error");
2259 	  exit(1);
2260 	}
2261 	send_ring->completion_ptr = NULL;
2262 	send_ring = send_ring->next;
2263 	free(iocb);
2264       }
2265     }
2266 #endif
2267 
2268     /* but first, if the verbosity is greater than 1, find-out what */
2269     /* the TCP maximum segment_size was (if possible) */
2270     if (verbosity > 1) {
2271       tcp_mss = -1;
2272       get_tcp_info(send_socket,&tcp_mss);
2273     }
2274 
2275     if (shutdown(send_socket,SHUT_WR) == SOCKET_ERROR && !times_up) {
2276       perror("netperf: cannot shutdown tcp stream socket");
2277       exit(1);
2278     }
2279 
2280     /* hang a recv() off the socket to block until the remote has */
2281     /* brought all the data up into the application. it will do a */
2282     /* shutdown to cause a FIN to be sent our way. We will assume that */
2283     /* any exit from the recv() call is good... raj 4/93 */
2284 
2285     recv(send_socket, send_ring->buffer_ptr, send_size, 0);
2286 
2287     /* this call will always give us the elapsed time for the test, and */
2288     /* will also store-away the necessaries for cpu utilization */
2289 
2290     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
2291 						/* measured and how */
2292 						/* long did we really */
2293 						/* run? */
2294 
2295     /* we are finished with the socket, so close it to prevent hitting */
2296     /* the limit on maximum open files. */
2297 
2298     close(send_socket);
2299 
2300 #if defined(WANT_INTERVALS)
2301 #ifdef WIN32
2302   stop_itimer();
2303 #endif
2304 #endif /* WANT_INTERVALS */
2305 
2306     if (!no_control) {
2307       /* Get the statistics from the remote end. The remote will have
2308 	 calculated service demand and all those interesting
2309 	 things. If it wasn't supposed to care, it will return obvious
2310 	 values. */
2311 
2312       recv_response();
2313       if (!netperf_response.content.serv_errno) {
2314 	if (debug)
2315 	  fprintf(where,
2316 		  "remote reporting results for %.2f seconds\n",
2317 		  tcp_stream_result->elapsed_time);
2318       }
2319       else {
2320 	Set_errno(netperf_response.content.serv_errno);
2321 	fprintf(where,
2322 		"netperf: remote error %d",
2323 		netperf_response.content.serv_errno);
2324 	perror("");
2325 	fflush(where);
2326 
2327 	exit(1);
2328       }
2329 
2330       /* We now calculate what our thruput was for the test. In the
2331 	 future, we may want to include a calculation of the thruput
2332 	 measured by the remote, but it should be the case that for a
2333 	 TCP stream test, that the two numbers should be *very*
2334 	 close... We calculate bytes_sent regardless of the way the
2335 	 test length was controlled.  If it was time, we needed to,
2336 	 and if it was by bytes, the user may have specified a number
2337 	 of bytes that wasn't a multiple of the send_size, so we
2338 	 really didn't send what he asked for ;-) */
2339 
2340       bytes_sent	= ntohd(tcp_stream_result->bytes_received);
2341     }
2342     else {
2343       bytes_sent = (double)local_bytes_sent;
2344     }
2345 
2346     thruput	= calc_thruput(bytes_sent);
2347 
2348     if (local_cpu_usage || remote_cpu_usage) {
2349       /* We must now do a little math for service demand and cpu */
2350       /* utilization for the system(s) */
2351       /* Of course, some of the information might be bogus because */
2352       /* there was no idle counter in the kernel(s). We need to make */
2353       /* a note of this for the user's benefit...*/
2354       if (local_cpu_usage) {
2355 
2356 	local_cpu_utilization	= calc_cpu_util(0.0);
2357 	local_service_demand	= calc_service_demand(bytes_sent,
2358 						      0.0,
2359 						      0.0,
2360 						      0);
2361       }
2362       else {
2363 	local_cpu_utilization	= (float) -1.0;
2364 	local_service_demand	= (float) -1.0;
2365       }
2366 
2367       if (remote_cpu_usage) {
2368 
2369 	remote_cpu_utilization	= tcp_stream_result->cpu_util;
2370 	remote_service_demand	= calc_service_demand(bytes_sent,
2371 						      0.0,
2372 						      remote_cpu_utilization,
2373 						      tcp_stream_result->num_cpus);
2374       }
2375       else {
2376 	remote_cpu_utilization = (float) -1.0;
2377 	remote_service_demand  = (float) -1.0;
2378       }
2379     }
2380     else {
2381       /* we were not measuring cpu, for the confidence stuff, we */
2382       /* should make it -1.0 */
2383       local_cpu_utilization	= (float) -1.0;
2384       local_service_demand	= (float) -1.0;
2385       remote_cpu_utilization = (float) -1.0;
2386       remote_service_demand  = (float) -1.0;
2387     }
2388 
2389     /* at this point, we want to calculate the confidence information. */
2390     /* if debugging is on, calculate_confidence will print-out the */
2391     /* parameters we pass it */
2392 
2393     calculate_confidence(confidence_iteration,
2394 			 elapsed_time,
2395 			 thruput,
2396 			 local_cpu_utilization,
2397 			 remote_cpu_utilization,
2398 			 local_service_demand,
2399 			 remote_service_demand);
2400 
2401 
2402     confidence_iteration++;
2403   }
2404 
2405   /* at this point, we have finished making all the runs that we */
2406   /* will be making. so, we should extract what the calcuated values */
2407   /* are for all the confidence stuff. we could make the values */
2408   /* global, but that seemed a little messy, and it did not seem worth */
2409   /* all the mucking with header files. so, we create a routine much */
2410   /* like calcualte_confidence, which just returns the mean values. */
2411   /* raj 11/94 */
2412 
2413   retrieve_confident_values(&elapsed_time,
2414 			    &thruput,
2415 			    &local_cpu_utilization,
2416 			    &remote_cpu_utilization,
2417 			    &local_service_demand,
2418 			    &remote_service_demand);
2419 
2420   /* We are now ready to print all the information. If the user */
2421   /* has specified zero-level verbosity, we will just print the */
2422   /* local service demand, or the remote service demand. If the */
2423   /* user has requested verbosity level 1, he will get the basic */
2424   /* "streamperf" numbers. If the user has specified a verbosity */
2425   /* of greater than 1, we will display a veritable plethora of */
2426   /* background information from outside of this block as it it */
2427   /* not cpu_measurement specific...  */
2428 
2429   if (confidence < 0) {
2430     /* we did not hit confidence, but were we asked to look for it? */
2431     if (iteration_max > 1) {
2432       display_confidence();
2433     }
2434   }
2435 
2436   if (local_cpu_usage || remote_cpu_usage) {
2437     local_cpu_method = format_cpu_method(cpu_method);
2438     remote_cpu_method = format_cpu_method(tcp_stream_result->cpu_method);
2439 
2440     switch (verbosity) {
2441     case 0:
2442       if (local_cpu_usage) {
2443 	fprintf(where,
2444 		cpu_fmt_0,
2445 		local_service_demand,
2446 		local_cpu_method,
2447 		((print_headers) ||
2448 		 (result_brand == NULL)) ? "" : result_brand);
2449       }
2450       else {
2451 	fprintf(where,
2452 		cpu_fmt_0,
2453 		remote_service_demand,
2454 		remote_cpu_method,
2455 		((print_headers) ||
2456 		 (result_brand == NULL)) ? "" : result_brand);
2457       }
2458       break;
2459     case 1:
2460     case 2:
2461       if (print_headers) {
2462 		fprintf(where,
2463 		cpu_title,
2464 		format_units(),
2465 		local_cpu_method,
2466 		remote_cpu_method);
2467       }
2468 
2469       fprintf(where,
2470 	      cpu_fmt_1,		/* the format string */
2471 	      rsr_size,		        /* remote recvbuf size */
2472 	      lss_size,		        /* local sendbuf size */
2473 	      send_size,		/* how large were the sends */
2474 	      elapsed_time,		/* how long was the test */
2475 	      thruput, 		        /* what was the xfer rate */
2476 	      local_cpu_utilization,	/* local cpu */
2477 	      remote_cpu_utilization,	/* remote cpu */
2478 	      local_service_demand,	/* local service demand */
2479 	      remote_service_demand,	/* remote service demand */
2480 	      ((print_headers) ||
2481 	       (result_brand == NULL)) ? "" : result_brand);
2482       break;
2483     }
2484   }
2485   else {
2486     /* The tester did not wish to measure service demand. */
2487 
2488     switch (verbosity) {
2489     case 0:
2490       fprintf(where,
2491 	      tput_fmt_0,
2492 	      thruput,
2493 	      ((print_headers) ||
2494 	       (result_brand == NULL)) ? "" : result_brand);
2495       break;
2496     case 1:
2497     case 2:
2498       if (print_headers) {
2499 		fprintf(where,tput_title,format_units());
2500       }
2501       fprintf(where,
2502 	      tput_fmt_1,		/* the format string */
2503 	      rsr_size, 		/* remote recvbuf size */
2504 	      lss_size, 		/* local sendbuf size */
2505 	      send_size,		/* how large were the sends */
2506 	      elapsed_time, 		/* how long did it take */
2507 	      thruput,                  /* how fast did it go */
2508 	      ((print_headers) ||
2509 	       (result_brand == NULL)) ? "" : result_brand);
2510       break;
2511     }
2512   }
2513 
2514   /* it would be a good thing to include information about some of the */
2515   /* other parameters that may have been set for this test, but at the */
2516   /* moment, I do not wish to figure-out all the  formatting, so I will */
2517   /* just put this comment here to help remind me that it is something */
2518   /* that should be done at a later time. */
2519 
2520   if (verbosity > 1) {
2521     /* The user wanted to know it all, so we will give it to him. */
2522     /* This information will include as much as we can find about */
2523     /* TCP statistics, the alignments of the sends and receives */
2524     /* and all that sort of rot... */
2525 
2526     /* this stuff needs to be worked-out in the presence of confidence */
2527     /* intervals and multiple iterations of the test... raj 11/94 */
2528 
2529     fprintf(where,
2530 	    ksink_fmt,
2531 	    "Bytes",
2532 	    "Bytes",
2533 	    "Bytes",
2534 	    local_send_align,
2535 	    remote_recv_align,
2536 	    local_send_offset,
2537 	    remote_recv_offset,
2538 	    bytes_sent,
2539 	    bytes_sent / (double)nummessages,
2540 	    nummessages,
2541 	    bytes_sent / (double)tcp_stream_result->recv_calls,
2542 	    tcp_stream_result->recv_calls);
2543     fprintf(where,
2544 	    ksink_fmt2,
2545 	    tcp_mss);
2546     fflush(where);
2547 #ifdef WANT_HISTOGRAM
2548     fprintf(where,"\n\nHistogram of time spent in send() call.\n");
2549     fflush(where);
2550     HIST_report(time_hist);
2551 #endif /* WANT_HISTOGRAM */
2552   }
2553 
2554 }
2555 
2556 
2557 
2558 /* This routine implements the netperf-side TCP unidirectional data
2559    transfer test (a.k.a. stream) for the sockets interface where the
2560    data flow is from the netserver to the netperf.  It receives its
2561    parameters via global variables from the shell and writes its
2562    output to the standard output. */
2563 
2564 
2565 void
send_tcp_maerts(char remote_host[])2566 send_tcp_maerts(char remote_host[])
2567 {
2568 
2569   char *tput_title = "\
2570 Recv   Send    Send                          \n\
2571 Socket Socket  Message  Elapsed              \n\
2572 Size   Size    Size     Time     Throughput  \n\
2573 bytes  bytes   bytes    secs.    %s/sec  \n\n";
2574 
2575   char *tput_fmt_0 =
2576     "%7.2f %s\n";
2577 
2578   char *tput_fmt_1 =
2579     "%6d %6d %6d    %-6.2f   %7.2f   %s\n";
2580 
2581   char *cpu_title = "\
2582 Recv   Send    Send                          Utilization       Service Demand\n\
2583 Socket Socket  Message  Elapsed              Recv     Send     Recv    Send\n\
2584 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
2585 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
2586 
2587   char *cpu_fmt_0 =
2588     "%6.3f %c %s\n";
2589 
2590   char *cpu_fmt_1 =
2591     "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f %s\n";
2592 
2593   char *ksink_fmt = "\n\
2594 Alignment      Offset         %-8.8s %-8.8s    Recvs   %-8.8s Sends\n\
2595 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
2596 Recv   Send    Recv   Send             Recv (avg)          Send (avg)\n\
2597 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
2598 
2599   char *ksink_fmt2 = "\n\
2600 Maximum\n\
2601 Segment\n\
2602 Size (bytes)\n\
2603 %6d\n";
2604 
2605 
2606   float			elapsed_time;
2607 
2608   /* what we want is to have a buffer space that is at least one */
2609   /* recv-size greater than our recv window. this will insure that we */
2610   /* are never trying to re-use a buffer that may still be in the hands */
2611   /* of the transport. This buffer will be malloc'd after we have found */
2612   /* the size of the local senc socket buffer. We will want to deal */
2613   /* with alignment and offset concerns as well. */
2614 
2615   struct ring_elt *recv_ring;
2616 
2617   int len;
2618   unsigned int nummessages = 0;
2619   SOCKET recv_socket;
2620   int bytes_remaining;
2621   int tcp_mss = -1;  /* possibly uninitialized on printf far below */
2622 
2623   /* with links like fddi, one can recv > 32 bits worth of bytes
2624      during a test... ;-) at some point, this should probably become a
2625      64bit integral type, but those are not entirely common yet.  of
2626      course, time passes and they do become common.
2627  */
2628   double	bytes_sent = 0.0;
2629 
2630 #if defined(WIN32) && (_MSC_VER < 1200)
2631   __int64 local_bytes_recvd = 0;
2632 #else
2633   unsigned long long local_bytes_recvd = 0;
2634 #endif
2635 
2636   float	local_cpu_utilization;
2637   float	local_service_demand;
2638   float	remote_cpu_utilization;
2639   float	remote_service_demand;
2640 
2641   double	thruput;
2642 
2643   struct addrinfo *remote_res;
2644   struct addrinfo *local_res;
2645 
2646   struct	tcp_maerts_request_struct	*tcp_maerts_request;
2647   struct	tcp_maerts_response_struct	*tcp_maerts_response;
2648   struct	tcp_maerts_results_struct	*tcp_maerts_result;
2649 
2650   tcp_maerts_request  =
2651     (struct tcp_maerts_request_struct *)netperf_request.content.test_specific_data;
2652   tcp_maerts_response =
2653     (struct tcp_maerts_response_struct *)netperf_response.content.test_specific_data;
2654   tcp_maerts_result   =
2655     (struct tcp_maerts_results_struct *)netperf_response.content.test_specific_data;
2656 
2657 #ifdef WANT_HISTOGRAM
2658   if (verbosity > 1) {
2659     time_hist = HIST_new();
2660   }
2661 #endif /* WANT_HISTOGRAM */
2662   /* since we are now disconnected from the code that established the */
2663   /* control socket, and since we want to be able to use different */
2664   /* protocols and such, we are passed the name of the remote host and */
2665   /* must turn that into the test specific addressing information. */
2666 
2667   complete_addrinfos(&remote_res,
2668 		     &local_res,
2669 		     remote_host,
2670 		     SOCK_STREAM,
2671 		     IPPROTO_TCP,
2672 		     0);
2673 
2674   if ( print_headers ) {
2675     print_top_test_header("TCP MAERTS TEST",local_res,remote_res);
2676   }
2677 
2678   recv_ring = NULL;
2679   confidence_iteration = 1;
2680   init_stat();
2681 
2682   /* we have a great-big while loop which controls the number of times */
2683   /* we run a particular test. this is for the calculation of a */
2684   /* confidence interval (I really should have stayed awake during */
2685   /* probstats :). If the user did not request confidence measurement */
2686   /* (no confidence is the default) then we will only go though the */
2687   /* loop once. the confidence stuff originates from the folks at IBM */
2688 
2689   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
2690 	 (confidence_iteration <= iteration_min)) {
2691 
2692     /* initialize a few counters. we have to remember that we might be */
2693     /* going through the loop more than once. */
2694 
2695     nummessages    =	0;
2696     bytes_sent     =	0.0;
2697     times_up       = 	0;
2698 
2699     /*set up the data socket                        */
2700     recv_socket = create_data_socket(local_res);
2701 
2702     if (recv_socket == INVALID_SOCKET){
2703       perror("netperf: send_tcp_maerts: tcp stream data socket");
2704       exit(1);
2705     }
2706 
2707     if (debug) {
2708       fprintf(where,"send_tcp_maerts: recv_socket obtained...\n");
2709     }
2710 
2711     /* at this point, we have either retrieved the socket buffer sizes, */
2712     /* or have tried to set them, so now, we may want to set the recv */
2713     /* size based on that (because the user either did not use a -m */
2714     /* option, or used one with an argument of 0). If the socket buffer */
2715     /* size is not available, we will set the recv size to 4KB - no */
2716     /* particular reason, just arbitrary... */
2717     if (recv_size == 0) {
2718       if (lsr_size > 0) {
2719 	recv_size = lsr_size;
2720       }
2721       else {
2722 	recv_size = 4096;
2723       }
2724     }
2725 
2726     /* set-up the data buffer ring with the requested alignment and offset. */
2727     /* note also that we have allocated a quantity */
2728     /* of memory that is at least one recv-size greater than our socket */
2729     /* buffer size. We want to be sure that there are at least two */
2730     /* buffers allocated - this can be a bit of a problem when the */
2731     /* recv_size is bigger than the socket size, so we must check... the */
2732     /* user may have wanted to explicitly set the "width" of our recv */
2733     /* buffers, we should respect that wish... */
2734     if (recv_width == 0) {
2735       recv_width = (lsr_size/recv_size) + 1;
2736       if (recv_width == 1) recv_width++;
2737     }
2738 
2739     if (recv_ring == NULL) {
2740       /* only allocate the recv ring once. this is a networking test, */
2741       /* not a memory allocation test. this way, we do not need a */
2742       /* deallocate_buffer_ring() routine, and I don't feel like */
2743       /* writing one anyway :) raj 11/94 */
2744       recv_ring = allocate_buffer_ring(recv_width,
2745 				       recv_size,
2746 				       local_recv_align,
2747 				       local_recv_offset);
2748     }
2749 
2750     /* If the user has requested cpu utilization measurements, we must */
2751     /* calibrate the cpu(s). We will perform this task within the tests */
2752     /* themselves. If the user has specified the cpu rate, then */
2753     /* calibrate_local_cpu will return rather quickly as it will have */
2754     /* nothing to do. If local_cpu_rate is zero, then we will go through */
2755     /* all the "normal" calibration stuff and return the rate back. */
2756 
2757     if (local_cpu_usage) {
2758       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
2759     }
2760 
2761     if (!no_control) {
2762       /* Tell the remote end to do a listen. The server alters the
2763 	 socket paramters on the other side at this point, hence the
2764 	 reason for all the values being passed in the setup
2765 	 message. If the user did not specify any of the parameters,
2766 	 they will be passed as 0, which will indicate to the remote
2767 	 that no changes beyond the system's default should be
2768 	 used. Alignment is the exception, it will default to 1, which
2769 	 will be no alignment alterations. */
2770 
2771       netperf_request.content.request_type	=	DO_TCP_MAERTS;
2772       tcp_maerts_request->send_buf_size	=	rss_size_req;
2773       tcp_maerts_request->recv_buf_size	=	rsr_size_req;
2774       tcp_maerts_request->send_size	=	send_size;
2775       tcp_maerts_request->no_delay	=	rem_nodelay;
2776       tcp_maerts_request->send_alignment	=	remote_send_align;
2777       tcp_maerts_request->send_offset	=	remote_send_offset;
2778       tcp_maerts_request->measure_cpu	=	remote_cpu_usage;
2779       tcp_maerts_request->cpu_rate	=	remote_cpu_rate;
2780       if (test_time) {
2781 	tcp_maerts_request->test_length	=	test_time;
2782       }
2783       else {
2784 	tcp_maerts_request->test_length	=	test_bytes;
2785       }
2786       tcp_maerts_request->so_rcvavoid	=	rem_rcvavoid;
2787       tcp_maerts_request->so_sndavoid	=	rem_sndavoid;
2788 #ifdef DIRTY
2789       tcp_maerts_request->dirty_count       =       rem_dirty_count;
2790       tcp_maerts_request->clean_count       =       rem_clean_count;
2791 #endif /* DIRTY */
2792       tcp_maerts_request->port            = atoi(remote_data_port);
2793       tcp_maerts_request->ipfamily        = af_to_nf(remote_res->ai_family);
2794       if (debug > 1) {
2795 	fprintf(where,
2796 		"netperf: send_tcp_maerts: requesting TCP maerts test\n");
2797       }
2798 
2799       send_request();
2800 
2801       /* The response from the remote will contain all of the relevant
2802 	 socket parameters for this test type. We will put them back
2803 	 into the variables here so they can be displayed if desired.
2804 	 The remote will have calibrated CPU if necessary, and will
2805 	 have done all the needed set-up we will have calibrated the
2806 	 cpu locally before sending the request, and will grab the
2807 	 counter value right after the connect returns. The remote
2808 	 will grab the counter right after the accept call. This saves
2809 	 the hassle of extra messages being sent for the TCP
2810 	 tests.  */
2811 
2812       recv_response();
2813 
2814       if (!netperf_response.content.serv_errno) {
2815 	if (debug)
2816 	  fprintf(where,"remote listen done.\n");
2817 	rsr_size	=	tcp_maerts_response->recv_buf_size;
2818 	rss_size	=	tcp_maerts_response->send_buf_size;
2819 	rem_nodelay     =	tcp_maerts_response->no_delay;
2820 	remote_cpu_usage=	tcp_maerts_response->measure_cpu;
2821 	remote_cpu_rate = tcp_maerts_response->cpu_rate;
2822 	send_size       = tcp_maerts_response->send_size;
2823 
2824 	/* we have to make sure that the server port number is in
2825 	 network order */
2826       set_port_number(remote_res,
2827 		      (short)tcp_maerts_response->data_port_number);
2828       rem_rcvavoid	= tcp_maerts_response->so_rcvavoid;
2829       rem_sndavoid	= tcp_maerts_response->so_sndavoid;
2830       }
2831       else {
2832 	Set_errno(netperf_response.content.serv_errno);
2833 	fprintf(where,
2834 		"netperf: remote error %d",
2835 		netperf_response.content.serv_errno);
2836 	perror("");
2837 	fflush(where);
2838 
2839 	exit(1);
2840       }
2841     }
2842 
2843 #ifdef WANT_DEMO
2844     demo_stream_setup(lsr_size,rss_size);
2845 #endif
2846 
2847     /*Connect up to the remote port on the data socket  */
2848     if (connect(recv_socket,
2849 		remote_res->ai_addr,
2850 		remote_res->ai_addrlen) == INVALID_SOCKET){
2851       perror("netperf: send_tcp_maerts: data socket connect failed");
2852       exit(1);
2853     }
2854 
2855 #ifdef WIN32
2856   /* this is used so the timer thread can close the socket out from */
2857   /* under us, which to date is the easiest/cleanest/least */
2858   /* Windows-specific way I can find to force the winsock calls to */
2859   /* return WSAEINTR with the test is over. anything that will run on */
2860   /* 95 and NT and is closer to what netperf expects from Unix signals */
2861   /* and such would be appreciated raj 1/96 */
2862   win_kludge_socket = recv_socket;
2863 #endif /* WIN32 */
2864 
2865     /* Data Socket set-up is finished. If there were problems, either */
2866     /* the connect would have failed, or the previous response would */
2867     /* have indicated a problem. I failed to see the value of the */
2868     /* extra  message after the accept on the remote. If it failed, */
2869     /* we'll see it here. If it didn't, we might as well start pumping */
2870     /* data. */
2871 
2872     /* Set-up the test end conditions. For a maerts test, they can be */
2873     /* either time or byte-count based. */
2874 
2875     if (test_time) {
2876       /* The user wanted to end the test after a period of time. */
2877       times_up = 0;
2878       bytes_remaining = 0;
2879       /* in previous revisions, we had the same code repeated throught */
2880       /* all the test suites. this was unnecessary, and meant more */
2881       /* work for me when I wanted to switch to POSIX signals, so I */
2882       /* have abstracted this out into a routine in netlib.c. if you */
2883       /* are experiencing signal problems, you might want to look */
2884       /* there. raj 11/94 */
2885       if (!no_control) {
2886 	/* this is a netperf to netserver test, netserver will close
2887 	   to tell us the test is over, so use PAD_TIME to avoid
2888 	   causing the netserver fits. */
2889 	start_timer(test_time + PAD_TIME);
2890       }
2891       else {
2892 	/* this is a netperf to data source test, no PAD_TIME */
2893 	start_timer(test_time);
2894       }
2895     }
2896     else {
2897       /* The tester wanted to recv a number of bytes. we don't do that
2898 	 in a TCP_MAERTS test. sorry. raj 2002-06-21 */
2899       printf("netperf: send_tcp_maerts: test must be timed\n");
2900       exit(1);
2901     }
2902 
2903     /* The cpu_start routine will grab the current time and possibly */
2904     /* value of the idle counter for later use in measuring cpu */
2905     /* utilization and/or service demand and thruput. */
2906 
2907     cpu_start(local_cpu_usage);
2908 
2909 #ifdef WANT_INTERVALS
2910     INTERVALS_INIT();
2911 #endif /* WANT_INTERVALS */
2912 
2913     /* before we start, initialize a few variables */
2914 
2915 #ifdef WANT_DEMO
2916     if (demo_mode) {
2917       demo_first_timestamp();
2918     }
2919 #endif
2920 
2921     /* the test will continue until we either get a zero-byte recv()
2922        on the socket or our failsafe timer expires. most of the time
2923        we trust that we get a zero-byte recieve from the socket. raj
2924        2002-06-21 */
2925 
2926 #ifdef WANT_HISTOGRAM
2927     if (verbosity > 1) {
2928       /* timestamp just before we go into recv and then again just
2929 	 after we come out raj 8/94 */
2930       /* but only if we are actually going to display a histogram. raj
2931 	 2006-02-07 */
2932       HIST_timestamp(&time_one);
2933     }
2934 #endif /* WANT_HISTOGRAM */
2935 
2936     while ((!times_up) && (len=recv(recv_socket,
2937 				    recv_ring->buffer_ptr,
2938 				    recv_size,
2939 				    0)) > 0 ) {
2940 
2941 #ifdef WANT_HISTOGRAM
2942       if (verbosity > 1) {
2943 	/* timestamp the exit from the recv call and update the histogram */
2944 	HIST_timestamp(&time_two);
2945 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
2946       }
2947 #endif /* WANT_HISTOGRAM */
2948 
2949 #ifdef DIRTY
2950       access_buffer(recv_ring->buffer_ptr,
2951 		    recv_size,
2952 		    loc_dirty_count,
2953 		    loc_clean_count);
2954 #endif /* DIRTY */
2955 
2956 #ifdef WANT_DEMO
2957       demo_stream_interval(len);
2958 #endif
2959 
2960 #ifdef WANT_INTERVALS
2961       INTERVALS_WAIT();
2962 #endif /* WANT_INTERVALS */
2963 
2964       /* now we want to move our pointer to the next position in the */
2965       /* data buffer...we may also want to wrap back to the "beginning" */
2966       /* of the bufferspace, so we will mod the number of messages sent */
2967       /* by the recv width, and use that to calculate the offset to add */
2968       /* to the base pointer. */
2969       nummessages++;
2970       recv_ring = recv_ring->next;
2971       if (bytes_remaining) {
2972 	bytes_remaining -= len;
2973       }
2974 
2975       local_bytes_recvd += len;
2976 
2977 #ifdef WANT_HISTOGRAM
2978       if (verbosity > 1) {
2979 	/* make sure we timestamp just before we go into recv  */
2980 	/* raj 2004-06-15 */
2981 	HIST_timestamp(&time_one);
2982       }
2983 #endif /* WANT_HISTOGRAM */
2984 
2985     }
2986 
2987     /* an EINTR is to be expected when this is a no_control test */
2988     if (((len < 0) || SOCKET_EINTR(len)) && (!no_control)) {
2989       perror("send_tcp_maerts: data recv error");
2990       printf("len was %d\n",len);
2991       exit(1);
2992     }
2993 
2994     /* if we get here, it must mean we had a recv return of 0 before
2995        the watchdog timer expired, or the watchdog timer expired and
2996        this was a no_control test */
2997 
2998     /* The test is over. Flush the buffers to the remote end. We do a
2999        graceful release to tell the  remote we have all the data. */
3000 
3001     /* but first, if the verbosity is greater than 1, find-out what */
3002     /* the TCP maximum segment_size was (if possible) */
3003     if (verbosity > 1) {
3004       tcp_mss = -1;
3005       get_tcp_info(recv_socket,&tcp_mss);
3006     }
3007 
3008     if (shutdown(recv_socket,SHUT_WR) == SOCKET_ERROR) {
3009       perror("netperf: cannot shutdown tcp maerts socket");
3010       exit(1);
3011     }
3012 
3013     stop_timer();
3014 
3015 #if defined(WANT_INTERVALS)
3016 #ifdef WIN32
3017     stop_itimer();
3018 #endif
3019 #endif /* WANT_INTERVALS */
3020 
3021     /* this call will always give us the local elapsed time for the
3022        test, and will also store-away the necessaries for cpu
3023        utilization */
3024 
3025     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
3026 						/* measured and how */
3027 						/* long did we really */
3028 						/* run? */
3029 
3030     /* we are finished with the socket, so close it to prevent hitting */
3031     /* the limit on maximum open files. */
3032 
3033     close(recv_socket);
3034 
3035     if (!no_control) {
3036       /* Get the statistics from the remote end. The remote will have
3037          calculated service demand and all those interesting
3038          things. If it wasn't supposed to care, it will return obvious
3039          values. */
3040 
3041       recv_response();
3042       if (!netperf_response.content.serv_errno) {
3043 	if (debug)
3044 	  fprintf(where,"remote results obtained\n");
3045       }
3046       else {
3047 	Set_errno(netperf_response.content.serv_errno);
3048 	fprintf(where,
3049 		"netperf: remote error %d",
3050 		netperf_response.content.serv_errno);
3051 	perror("");
3052 	fflush(where);
3053 
3054 	exit(1);
3055       }
3056 
3057       /* We now calculate what our thruput was for the test. In the
3058 	 future, we may want to include a calculation of the thruput
3059 	 measured by the remote, but it should be the case that for a
3060 	 TCP maerts test, that the two numbers should be *very*
3061 	 close... We calculate bytes_sent regardless of the way the
3062 	 test length was controlled.  If it was time, we needed to,
3063 	 and if it was by bytes, the user may have specified a number
3064 	 of bytes that wasn't a multiple of the recv_size, so we
3065 	 really didn't recv what he asked for ;-) */
3066 
3067       bytes_sent	= ntohd(tcp_maerts_result->bytes_sent);
3068     }
3069     else {
3070       bytes_sent = (double)local_bytes_recvd;
3071     }
3072 
3073 
3074     thruput	= calc_thruput(bytes_sent);
3075 
3076     if (local_cpu_usage || remote_cpu_usage) {
3077       /* We must now do a little math for service demand and cpu */
3078       /* utilization for the system(s) */
3079       /* Of course, some of the information might be bogus because */
3080       /* there was no idle counter in the kernel(s). We need to make */
3081       /* a note of this for the user's benefit...*/
3082       if (local_cpu_usage) {
3083 
3084 	local_cpu_utilization	= calc_cpu_util(0.0);
3085 	local_service_demand	= calc_service_demand(bytes_sent,
3086 						      0.0,
3087 						      0.0,
3088 						      0);
3089       }
3090       else {
3091 	local_cpu_utilization	= (float) -1.0;
3092 	local_service_demand	= (float) -1.0;
3093       }
3094 
3095       if (remote_cpu_usage) {
3096 
3097 	remote_cpu_utilization	= tcp_maerts_result->cpu_util;
3098 	remote_service_demand	= calc_service_demand(bytes_sent,
3099 						      0.0,
3100 						      remote_cpu_utilization,
3101 						      tcp_maerts_result->num_cpus);
3102       }
3103       else {
3104 	remote_cpu_utilization = (float) -1.0;
3105 	remote_service_demand  = (float) -1.0;
3106       }
3107     }
3108     else {
3109       /* we were not measuring cpu, for the confidence stuff, we */
3110       /* should make it -1.0 */
3111       local_cpu_utilization	= (float) -1.0;
3112       local_service_demand	= (float) -1.0;
3113       remote_cpu_utilization = (float) -1.0;
3114       remote_service_demand  = (float) -1.0;
3115     }
3116 
3117     /* at this point, we want to calculate the confidence information. */
3118     /* if debugging is on, calculate_confidence will print-out the */
3119     /* parameters we pass it */
3120 
3121     calculate_confidence(confidence_iteration,
3122 			 elapsed_time,
3123 			 thruput,
3124 			 local_cpu_utilization,
3125 			 remote_cpu_utilization,
3126 			 local_service_demand,
3127 			 remote_service_demand);
3128 
3129 
3130     confidence_iteration++;
3131   }
3132 
3133   /* at this point, we have finished making all the runs that we */
3134   /* will be making. so, we should extract what the calcuated values */
3135   /* are for all the confidence stuff. we could make the values */
3136   /* global, but that seemed a little messy, and it did not seem worth */
3137   /* all the mucking with header files. so, we create a routine much */
3138   /* like calcualte_confidence, which just returns the mean values. */
3139   /* raj 11/94 */
3140 
3141   retrieve_confident_values(&elapsed_time,
3142 			    &thruput,
3143 			    &local_cpu_utilization,
3144 			    &remote_cpu_utilization,
3145 			    &local_service_demand,
3146 			    &remote_service_demand);
3147 
3148   /* We are now ready to print all the information. If the user */
3149   /* has specified zero-level verbosity, we will just print the */
3150   /* local service demand, or the remote service demand. If the */
3151   /* user has requested verbosity level 1, he will get the basic */
3152   /* "streamperf" numbers. If the user has specified a verbosity */
3153   /* of greater than 1, we will display a veritable plethora of */
3154   /* background information from outside of this block as it it */
3155   /* not cpu_measurement specific...  */
3156 
3157   if (confidence < 0) {
3158     /* we did not hit confidence, but were we asked to look for it? */
3159     if (iteration_max > 1) {
3160       display_confidence();
3161     }
3162   }
3163 
3164   if (local_cpu_usage || remote_cpu_usage) {
3165     local_cpu_method = format_cpu_method(cpu_method);
3166     remote_cpu_method = format_cpu_method(tcp_maerts_result->cpu_method);
3167 
3168     switch (verbosity) {
3169     case 0:
3170       if (local_cpu_usage) {
3171 	fprintf(where,
3172 		cpu_fmt_0,
3173 		local_service_demand,
3174 		local_cpu_method,
3175 		((print_headers) ||
3176 		 (result_brand == NULL)) ? "" : result_brand);
3177       }
3178       else {
3179 	fprintf(where,
3180 		cpu_fmt_0,
3181 		remote_service_demand,
3182 		remote_cpu_method,
3183 		((print_headers) ||
3184 		 (result_brand == NULL)) ? "" : result_brand);
3185       }
3186       break;
3187     case 1:
3188     case 2:
3189       if (print_headers) {
3190 	fprintf(where,
3191 		cpu_title,
3192 		format_units(),
3193 		local_cpu_method,
3194 		remote_cpu_method);
3195       }
3196 
3197       fprintf(where,
3198 	      cpu_fmt_1,		/* the format string */
3199 	      rsr_size,		        /* remote recvbuf size */
3200 	      lss_size,		        /* local sendbuf size */
3201 	      send_size,		/* how large were the recvs */
3202 	      elapsed_time,		/* how long was the test */
3203 	      thruput, 		        /* what was the xfer rate */
3204 	      local_cpu_utilization,	/* local cpu */
3205 	      remote_cpu_utilization,	/* remote cpu */
3206 	      local_service_demand,	/* local service demand */
3207 	      remote_service_demand,	/* remote service demand */
3208 	      ((print_headers) ||
3209 	       (result_brand == NULL)) ? "" : result_brand);
3210       break;
3211     }
3212   }
3213   else {
3214     /* The tester did not wish to measure service demand. */
3215 
3216     switch (verbosity) {
3217     case 0:
3218       fprintf(where,
3219 	      tput_fmt_0,
3220 	      thruput,
3221 	      ((print_headers) ||
3222 	       (result_brand == NULL)) ? "" : result_brand);
3223       break;
3224     case 1:
3225     case 2:
3226       if (print_headers) {
3227 	fprintf(where,tput_title,format_units());
3228       }
3229       fprintf(where,
3230 	      tput_fmt_1,		/* the format string */
3231 	      lsr_size, 		/* local recvbuf size */
3232 	      rss_size, 		/* remot sendbuf size */
3233 	      send_size,		/* how large were the recvs */
3234 	      elapsed_time, 		/* how long did it take */
3235 	      thruput,                  /* how fast did it go */
3236 	      ((print_headers) ||
3237 	       (result_brand == NULL)) ? "" : result_brand);
3238       break;
3239     }
3240   }
3241 
3242   /* it would be a good thing to include information about some of the */
3243   /* other parameters that may have been set for this test, but at the */
3244   /* moment, I do not wish to figure-out all the  formatting, so I will */
3245   /* just put this comment here to help remind me that it is something */
3246   /* that should be done at a later time. */
3247 
3248   if (verbosity > 1) {
3249     /* The user wanted to know it all, so we will give it to him. */
3250     /* This information will include as much as we can find about */
3251     /* TCP statistics, the alignments of the sends and receives */
3252     /* and all that sort of rot... */
3253 
3254     /* this stuff needs to be worked-out in the presence of confidence */
3255     /* intervals and multiple iterations of the test... raj 11/94 */
3256 
3257     fprintf(where,
3258 	    ksink_fmt,
3259 	    "Bytes",
3260 	    "Bytes",
3261 	    "Bytes",
3262 	    local_recv_align,
3263 	    remote_recv_align,
3264 	    local_recv_offset,
3265 	    remote_recv_offset,
3266 	    bytes_sent,
3267 	    bytes_sent / (double)nummessages,
3268 	    nummessages,
3269 	    bytes_sent / (double)tcp_maerts_result->send_calls,
3270 	    tcp_maerts_result->send_calls);
3271     fprintf(where,
3272 	    ksink_fmt2,
3273 	    tcp_mss);
3274     fflush(where);
3275 #ifdef WANT_HISTOGRAM
3276     fprintf(where,"\n\nHistogram of time spent in recv() call.\n");
3277     fflush(where);
3278     HIST_report(time_hist);
3279 #endif /* WANT_HISTOGRAM */
3280   }
3281 
3282 }
3283 #endif /* WANT_MIGRATION */
3284 
3285 
3286 /* this routine implements the TCP_MSS test.  All it does is pretend
3287    to be a TCP_STREAM test and report the TCP_MSS for the data
3288    connection.  No actual data is transferred. raj 2007-11-07
3289 */
3290 void
send_tcp_mss(char remote_host[])3291 send_tcp_mss(char remote_host[])
3292 {
3293 
3294   char *mss_title = "\
3295 Maximum\n\
3296 Segment\n\
3297 Size (bytes)\n\n";
3298 
3299   char *mss_fmt_0 =
3300     "%d %s\n";
3301 
3302   SOCKET send_socket;
3303   int tcp_mss = -1;  /* possibly uninitialized on printf far below */
3304 
3305   struct addrinfo *remote_res;
3306   struct addrinfo *local_res;
3307 
3308   struct	tcp_stream_request_struct	*tcp_stream_request;
3309   struct	tcp_stream_response_struct	*tcp_stream_response;
3310   struct	tcp_stream_results_struct	*tcp_stream_result;
3311 
3312   tcp_stream_request  =
3313     (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
3314   tcp_stream_response =
3315     (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
3316   tcp_stream_result   =
3317     (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
3318 
3319   /* since we are now disconnected from the code that established the */
3320   /* control socket, and since we want to be able to use different */
3321   /* protocols and such, we are passed the name of the remote host and */
3322   /* must turn that into the test specific addressing information. */
3323 
3324   /* complete_addrinfos will either succede or exit the process */
3325   complete_addrinfos(&remote_res,
3326 		     &local_res,
3327 		     remote_host,
3328 		     SOCK_STREAM,
3329 		     IPPROTO_TCP,
3330 		     0);
3331 
3332   if ( print_headers ) {
3333     print_top_test_header("TCP MSS TEST",local_res,remote_res);
3334   }
3335 
3336   /*set up the data socket                        */
3337   send_socket = create_data_socket(local_res);
3338 
3339   if (send_socket == INVALID_SOCKET){
3340     perror("netperf: send_tcp_stream: tcp stream data socket");
3341     exit(1);
3342   }
3343 
3344   if (debug) {
3345     fprintf(where,"send_tcp_stream: send_socket obtained...\n");
3346   }
3347 
3348 
3349   if (!no_control) {
3350     /* Tell the remote end to do a listen. The server alters the
3351        socket paramters on the other side at this point, hence the
3352        reason for all the values being passed in the setup
3353        message. If the user did not specify any of the parameters,
3354        they will be passed as 0, which will indicate to the remote
3355        that no changes beyond the system's default should be
3356        used. Alignment is the exception, it will default to 1, which
3357        will be no alignment alterations. */
3358 
3359     netperf_request.content.request_type =	DO_TCP_STREAM;
3360     tcp_stream_request->send_buf_size	=	rss_size_req;
3361     tcp_stream_request->recv_buf_size	=	rsr_size_req;
3362     tcp_stream_request->receive_size	=	recv_size;
3363     tcp_stream_request->no_delay	=	rem_nodelay;
3364     tcp_stream_request->recv_alignment	=	remote_recv_align;
3365     tcp_stream_request->recv_offset	=	remote_recv_offset;
3366     tcp_stream_request->measure_cpu	=	remote_cpu_usage;
3367     tcp_stream_request->cpu_rate	=	remote_cpu_rate;
3368     if (test_time) {
3369       tcp_stream_request->test_length	=	test_time;
3370     }
3371     else {
3372       tcp_stream_request->test_length	=	test_bytes;
3373     }
3374     tcp_stream_request->so_rcvavoid	=	rem_rcvavoid;
3375     tcp_stream_request->so_sndavoid	=	rem_sndavoid;
3376 #ifdef DIRTY
3377     tcp_stream_request->dirty_count     =       rem_dirty_count;
3378     tcp_stream_request->clean_count     =       rem_clean_count;
3379 #endif /* DIRTY */
3380     tcp_stream_request->port            =    atoi(remote_data_port);
3381     tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
3382     tcp_stream_request->recv_aio        =       rem_rcvaio;
3383     if (debug > 1) {
3384       fprintf(where,
3385 	      "netperf: send_tcp_mss: requesting TCP stream test\n");
3386     }
3387 
3388     send_request();
3389 
3390     /* The response from the remote will contain all of the relevant
3391        socket parameters for this test type. We will put them back
3392        into the variables here so they can be displayed if desired.
3393        The remote will have calibrated CPU if necessary, and will
3394        have done all the needed set-up we will have calibrated the
3395        cpu locally before sending the request, and will grab the
3396        counter value right after the connect returns. The remote
3397        will grab the counter right after the accept call. This saves
3398        the hassle of extra messages being sent for the TCP
3399        tests.  */
3400 
3401     recv_response();
3402 
3403     if (!netperf_response.content.serv_errno) {
3404       if (debug)
3405 	fprintf(where,"remote listen done.\n");
3406       rsr_size	      =	tcp_stream_response->recv_buf_size;
3407       rss_size	      =	tcp_stream_response->send_buf_size;
3408       rem_nodelay     =	tcp_stream_response->no_delay;
3409       remote_cpu_usage=	tcp_stream_response->measure_cpu;
3410       remote_cpu_rate = tcp_stream_response->cpu_rate;
3411 
3412       /* we have to make sure that the server port number is in
3413 	 network order */
3414       set_port_number(remote_res,
3415 		      (short)tcp_stream_response->data_port_number);
3416 
3417       rem_rcvavoid	= tcp_stream_response->so_rcvavoid;
3418       rem_sndavoid	= tcp_stream_response->so_sndavoid;
3419     }
3420     else {
3421       Set_errno(netperf_response.content.serv_errno);
3422       fprintf(where,
3423 	      "netperf: remote error %d",
3424 	      netperf_response.content.serv_errno);
3425       perror("");
3426       fflush(where);
3427 
3428       exit(1);
3429     }
3430   }
3431 
3432   /*Connect up to the remote port on the data socket  */
3433   if (connect(send_socket,
3434 	      remote_res->ai_addr,
3435 	      remote_res->ai_addrlen) == INVALID_SOCKET){
3436     perror("netperf: send_tcp_mss: data socket connect failed");
3437     exit(1);
3438     }
3439 
3440 
3441   /* find-out what the TCP maximum segment_size was (if possible) */
3442   tcp_mss = -1;
3443   get_tcp_info(send_socket,&tcp_mss);
3444 
3445   /* just go ahead and close the socket, the remote should figure it
3446      out */
3447   close(send_socket);
3448 
3449   /* statistics? we don't need no stinking statistics */
3450 
3451 
3452     switch (verbosity) {
3453     case 0:
3454       fprintf(where,
3455 	      mss_fmt_0,
3456 	      tcp_mss,
3457 	      ((print_headers) ||
3458 	       (result_brand == NULL)) ? "" : result_brand);
3459       break;
3460     case 1:
3461     case 2:
3462       if (print_headers) {
3463 		fprintf(where,"%s",mss_title);
3464       }
3465       fprintf(where,
3466 	      mss_fmt_0,		/* the format string */
3467 	      tcp_mss,
3468 	      ((print_headers) ||
3469 	       (result_brand == NULL)) ? "" : result_brand);
3470       break;
3471     }
3472 
3473 
3474 }
3475 
3476 
3477 
3478 #ifdef HAVE_ICSC_EXS
3479 
3480 #include <sys/exs.h>
3481 
3482 
3483 /* This routine implements the TCP unidirectional data transfer test */
3484 /* (a.k.a. stream) for the sockets interface. It receives its */
3485 /* parameters via global variables from the shell and writes its */
3486 /* output to the standard output. */
3487 
3488 void
send_exs_tcp_stream(char remote_host[])3489 send_exs_tcp_stream(char remote_host[])
3490 {
3491 
3492     char *tput_title = "\
3493 Recv   Send    Send                          \n\
3494 Socket Socket  Message  Elapsed              \n\
3495 Size   Size    Size     Time     Throughput  \n\
3496 bytes  bytes   bytes    secs.    %s/sec  \n\n";
3497 
3498     char *tput_fmt_0 =
3499         "%7.2f\n";
3500 
3501     char *tput_fmt_1 =
3502         "%6d %6d %6d    %-6.2f   %7.2f   \n";
3503 
3504     char *cpu_title = "\
3505 Recv   Send    Send                          Utilization       Service Demand\n\
3506 Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
3507 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
3508 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
3509 
3510     char *cpu_fmt_0 =
3511         "%6.3f %c\n";
3512 
3513     char *cpu_fmt_1 =
3514         "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f\n";
3515 
3516     char *ksink_fmt = "\n\
3517 Alignment      Offset         %-8.8s %-8.8s    Sends   %-8.8s Recvs\n\
3518 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
3519 Send   Recv    Send   Recv             Send (avg)          Recv (avg)\n\
3520 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
3521 
3522     char *ksink_fmt2 = "\n\
3523 Maximum\n\
3524 Segment\n\
3525 Size (bytes)\n\
3526 %6d\n";
3527 
3528 
3529     float         elapsed_time;
3530 
3531     /* what we want is to have a buffer space that is at least one */
3532     /* send-size greater than our send window. this will insure that we */
3533     /* are never trying to re-use a buffer that may still be in the hands */
3534     /* of the transport. This buffer will be malloc'd after we have found */
3535     /* the size of the local senc socket buffer. We will want to deal */
3536     /* with alignment and offset concerns as well. */
3537 
3538     struct ring_elt *send_ring;
3539 
3540     int len;
3541     unsigned int nummessages = 0;
3542     SOCKET send_socket;
3543     int bytes_remaining;
3544     int tcp_mss = -1;  /* possibly uninitialized on printf far below */
3545 
3546     exs_mhandle_t exs_mhandle;
3547     exs_qhandle_t exs_qhandle;
3548 #define NETPERF_EXS_PENDING  16
3549     int exs_aio_pending;
3550     int exs_aio_eagain;
3551     int exs_aio_dequeued;
3552     int exs_aio_dequeuecnt;
3553     int exs_evtcnt;
3554 #define NETPERF_EXS_QSIZE    128
3555     exs_event_t exs_evtvec[NETPERF_EXS_QSIZE];
3556 
3557     /* with links like fddi, one can send > 32 bits worth of bytes */
3558     /* during a test... ;-) at some point, this should probably become a */
3559     /* 64bit integral type, but those are not entirely common yet */
3560 
3561     double   bytes_sent = 0.0;
3562 
3563     float   local_cpu_utilization;
3564     float   local_service_demand;
3565     float   remote_cpu_utilization;
3566     float   remote_service_demand;
3567 
3568     double   thruput;
3569 
3570     struct addrinfo *remote_res;
3571     struct addrinfo *local_res;
3572 
3573     struct   tcp_stream_request_struct   *tcp_stream_request;
3574     struct   tcp_stream_response_struct   *tcp_stream_response;
3575     struct   tcp_stream_results_struct   *tcp_stream_result;
3576 
3577     tcp_stream_request  =
3578         (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
3579     tcp_stream_response =
3580         (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
3581     tcp_stream_result   =
3582         (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
3583 
3584 #if 0 /* def WANT_HISTOGRAM */
3585     time_hist = HIST_new();
3586 #endif /* WANT_HISTOGRAM */
3587     /* since we are now disconnected from the code that established the */
3588     /* control socket, and since we want to be able to use different */
3589     /* protocols and such, we are passed the name of the remote host and */
3590     /* must turn that into the test specific addressing information. */
3591 
3592     /* complete_addrinfos will either succede or exit the process */
3593     complete_addrinfos(&remote_res,
3594                        &local_res,
3595                        remote_host,
3596                        SOCK_STREAM,
3597                        IPPROTO_TCP,
3598                        0);
3599 
3600     if ( print_headers ) {
3601         print_top_test_header("EXS TCP STREAM TEST",local_res,remote_res);
3602     }
3603 
3604     send_ring = NULL;
3605     confidence_iteration = 1;
3606     init_stat();
3607 
3608     /* initialize EXS API and create event queue */
3609     if (exs_init (EXS_VERSION) == -1) {
3610         perror ("netperf: send_exs_tcp_stream: exs_init failed");
3611         exit (1);
3612     }
3613 
3614     if ((exs_qhandle = exs_qcreate (NETPERF_EXS_QSIZE)) == EXS_QHANDLE_INVALID) {
3615         perror ("netperf: send_exs_tcp_stream: exs_qcreate failed");
3616         exit (1);
3617     }
3618     if (debug) {
3619         fprintf (where, "send_exs_tcp_stream: qhandle=%d\n", exs_qhandle);
3620     }
3621 
3622     /* we have a great-big while loop which controls the number of times */
3623     /* we run a particular test. this is for the calculation of a */
3624     /* confidence interval (I really should have stayed awake during */
3625     /* probstats :). If the user did not request confidence measurement */
3626     /* (no confidence is the default) then we will only go though the */
3627     /* loop once. the confidence stuff originates from the folks at IBM */
3628 
3629     while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
3630            (confidence_iteration <= iteration_min)) {
3631 
3632         /* initialize a few counters. we have to remember that we might be */
3633         /* going through the loop more than once. */
3634 
3635         nummessages    =   0;
3636         bytes_sent     =   0.0;
3637         times_up       =    0;
3638 
3639         /*set up the data socket                        */
3640         send_socket = create_data_socket(local_res);
3641 
3642         if (send_socket == INVALID_SOCKET){
3643             perror("netperf: send_tcp_stream: tcp stream data socket");
3644             exit(1);
3645         }
3646 
3647         if (debug) {
3648             fprintf(where,"send_tcp_stream: send_socket obtained...\n");
3649         }
3650 
3651         /* at this point, we have either retrieved the socket buffer sizes, */
3652         /* or have tried to set them, so now, we may want to set the send */
3653         /* size based on that (because the user either did not use a -m */
3654         /* option, or used one with an argument of 0). If the socket buffer */
3655         /* size is not available, we will set the send size to 4KB - no */
3656         /* particular reason, just arbitrary... */
3657         if (send_size == 0) {
3658             if (lss_size > 0) {
3659                 send_size = lss_size;
3660             }
3661             else {
3662                 send_size = 4096;
3663             }
3664         }
3665 
3666         /* set-up the data buffer ring with the requested alignment and offset. */
3667         /* note also that we have allocated a quantity */
3668         /* of memory that is at least one send-size greater than our socket */
3669         /* buffer size. We want to be sure that there are at least two */
3670         /* buffers allocated - this can be a bit of a problem when the */
3671         /* send_size is bigger than the socket size, so we must check... the */
3672         /* user may have wanted to explicitly set the "width" of our send */
3673         /* buffers, we should respect that wish... */
3674         if (send_width == 0) {
3675             send_width = (lss_size/send_size) + 1;
3676             if (send_width == 1) send_width++;
3677         }
3678 
3679         if (send_ring == NULL) {
3680             /* only allocate the send ring once. this is a networking test, */
3681             /* not a memory allocation test. this way, we do not need a */
3682             /* deallocate_buffer_ring() routine, and I don't feel like */
3683             /* writing one anyway :) raj 11/94 */
3684             send_ring = allocate_exs_buffer_ring(send_width,
3685                                                  send_size,
3686                                                  local_send_align,
3687                                                  local_send_offset,
3688                                                  &exs_mhandle);
3689         }
3690 
3691         /* If the user has requested cpu utilization measurements, we must */
3692         /* calibrate the cpu(s). We will perform this task within the tests */
3693         /* themselves. If the user has specified the cpu rate, then */
3694         /* calibrate_local_cpu will return rather quickly as it will have */
3695         /* nothing to do. If local_cpu_rate is zero, then we will go through */
3696         /* all the "normal" calibration stuff and return the rate back. */
3697 
3698         if (local_cpu_usage) {
3699             local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
3700         }
3701 
3702         /* Tell the remote end to do a listen. The server alters the socket */
3703         /* paramters on the other side at this point, hence the reason for */
3704         /* all the values being passed in the setup message. If the user did */
3705         /* not specify any of the parameters, they will be passed as 0, which */
3706         /* will indicate to the remote that no changes beyond the system's */
3707         /* default should be used. Alignment is the exception, it will */
3708         /* default to 1, which will be no alignment alterations. */
3709 
3710         netperf_request.content.request_type =   DO_TCP_STREAM;
3711         tcp_stream_request->send_buf_size   =   rss_size_req;
3712         tcp_stream_request->recv_buf_size   =   rsr_size_req;
3713         tcp_stream_request->receive_size   =   recv_size;
3714         tcp_stream_request->no_delay   =   rem_nodelay;
3715         tcp_stream_request->recv_alignment   =   remote_recv_align;
3716         tcp_stream_request->recv_offset   =   remote_recv_offset;
3717         tcp_stream_request->measure_cpu   =   remote_cpu_usage;
3718         tcp_stream_request->cpu_rate   =   remote_cpu_rate;
3719         if (test_time) {
3720             tcp_stream_request->test_length   =   test_time;
3721         }
3722         else {
3723             tcp_stream_request->test_length   =   test_bytes;
3724         }
3725         tcp_stream_request->so_rcvavoid   =   rem_rcvavoid;
3726         tcp_stream_request->so_sndavoid   =   rem_sndavoid;
3727 #ifdef DIRTY
3728         tcp_stream_request->dirty_count     =       rem_dirty_count;
3729         tcp_stream_request->clean_count     =       rem_clean_count;
3730 #endif /* DIRTY */
3731         tcp_stream_request->port            =    atoi(remote_data_port);
3732         tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
3733 	tcp_stream_request->recv_aio      =       rem_rcvaio;
3734         if (debug > 1) {
3735             fprintf(where,
3736                     "netperf: send_tcp_stream: requesting TCP stream test\n");
3737         }
3738 
3739         send_request();
3740 
3741         /* The response from the remote will contain all of the relevant    */
3742         /* socket parameters for this test type. We will put them back into */
3743         /* the variables here so they can be displayed if desired.  The   */
3744         /* remote will have calibrated CPU if necessary, and will have done   */
3745         /* all the needed set-up we will have calibrated the cpu locally   */
3746         /* before sending the request, and will grab the counter value right*/
3747         /* after the connect returns. The remote will grab the counter right*/
3748         /* after the accept call. This saves the hassle of extra messages   */
3749         /* being sent for the TCP tests.               */
3750 
3751         recv_response();
3752 
3753         if (!netperf_response.content.serv_errno) {
3754             if (debug)
3755                 fprintf(where,"remote listen done.\n");
3756             rsr_size         =   tcp_stream_response->recv_buf_size;
3757             rss_size         =   tcp_stream_response->send_buf_size;
3758             rem_nodelay     =   tcp_stream_response->no_delay;
3759             remote_cpu_usage=   tcp_stream_response->measure_cpu;
3760             remote_cpu_rate = tcp_stream_response->cpu_rate;
3761 
3762             /* we have to make sure that the server port number is in */
3763             /* network order */
3764             set_port_number(remote_res,(short)tcp_stream_response->data_port_number);
3765 
3766             rem_rcvavoid   = tcp_stream_response->so_rcvavoid;
3767             rem_sndavoid   = tcp_stream_response->so_sndavoid;
3768         }
3769         else {
3770             Set_errno(netperf_response.content.serv_errno);
3771             fprintf(where,
3772                     "netperf: remote error %d",
3773                     netperf_response.content.serv_errno);
3774             perror("");
3775             fflush(where);
3776 
3777             exit(1);
3778         }
3779 
3780 #if 0 /* def WANT_DEMO */
3781         demo_stream_setup(lss_size,rsr_size);
3782 #endif
3783 
3784             /*Connect up to the remote port on the data socket  */
3785             if (connect(send_socket,
3786                         remote_res->ai_addr,
3787                         remote_res->ai_addrlen) == INVALID_SOCKET){
3788                 perror("netperf: send_tcp_stream: data socket connect failed");
3789                 exit(1);
3790             }
3791 
3792 #ifdef WIN32
3793   /* this is used so the timer thread can close the socket out from */
3794   /* under us, which to date is the easiest/cleanest/least */
3795   /* Windows-specific way I can find to force the winsock calls to */
3796   /* return WSAEINTR with the test is over. anything that will run on */
3797   /* 95 and NT and is closer to what netperf expects from Unix signals */
3798   /* and such would be appreciated raj 1/96 */
3799   win_kludge_socket = send_socket;
3800 #endif /* WIN32 */
3801 
3802         /* Data Socket set-up is finished. If there were problems, either */
3803         /* the connect would have failed, or the previous response would */
3804         /* have indicated a problem. I failed to see the value of the */
3805         /* extra  message after the accept on the remote. If it failed, */
3806         /* we'll see it here. If it didn't, we might as well start pumping */
3807         /* data. */
3808 
3809         /* Set-up the test end conditions. For a stream test, they can be */
3810         /* either time or byte-count based. */
3811 
3812         if (test_time) {
3813             /* The user wanted to end the test after a period of time. */
3814             times_up = 0;
3815             bytes_remaining = 0;
3816             /* in previous revisions, we had the same code repeated throught */
3817             /* all the test suites. this was unnecessary, and meant more */
3818             /* work for me when I wanted to switch to POSIX signals, so I */
3819             /* have abstracted this out into a routine in netlib.c. if you */
3820             /* are experiencing signal problems, you might want to look */
3821             /* there. raj 11/94 */
3822             start_timer(test_time);
3823         }
3824         else {
3825             /* The tester wanted to send a number of bytes. */
3826             bytes_remaining = test_bytes;
3827             times_up = 1;
3828         }
3829 
3830         /* The cpu_start routine will grab the current time and possibly */
3831         /* value of the idle counter for later use in measuring cpu */
3832         /* utilization and/or service demand and thruput. */
3833 
3834         cpu_start(local_cpu_usage);
3835 
3836 #if 0 /* def WANT_INTERVALS */
3837 	INTERVALS_INIT();
3838 #endif /* WANT_INTERVALS */
3839 
3840         /* before we start, initialize a few variables */
3841 
3842 #if 0 /* def WANT_DEMO */
3843         if (demo_mode) {
3844 	  demo_first_timestamp();
3845         }
3846 #endif
3847 
3848 
3849         /* We use an "OR" to control test execution. When the test is */
3850         /* controlled by time, the byte count check will always return false. */
3851         /* When the test is controlled by byte count, the time test will */
3852         /* always return false. When the test is finished, the whole */
3853         /* expression will go false and we will stop sending data. */
3854 
3855         exs_aio_pending = 0;
3856         exs_aio_eagain = 0;
3857         exs_aio_dequeuecnt = 0;
3858 
3859         while ((!times_up) || (bytes_remaining > 0)) {
3860 
3861 #ifdef DIRTY
3862 	  access_buffer(send_ring->buffer_ptr,
3863 			send_size,
3864 			loc_dirty_count,
3865 			loc_clean_count);
3866 #endif /* DIRTY */
3867 
3868 #if 0 /* def WANT_HISTOGRAM */
3869             /* timestamp just before we go into send and then again just after */
3870             /* we come out raj 8/94 */
3871             HIST_timestamp(&time_one);
3872 #endif /* WANT_HISTOGRAM */
3873 
3874 
3875             /* post up to NETPERF_EXS_PENDING I/Os  */
3876             while ((exs_aio_pending < NETPERF_EXS_PENDING) &&
3877                    (exs_send (send_socket, send_ring->buffer_ptr, send_size,
3878                               0, exs_qhandle, (exs_ahandle_t)-1, exs_mhandle) == 0)) {
3879                 exs_aio_pending++;
3880 
3881                 /* now we want to move our pointer to the next
3882 		   position in the data buffer...we may also want to
3883 		   wrap back to the "beginning" of the bufferspace, so
3884 		   we will mod the number of messages sent by the send
3885 		   width, and use that to calculate the offset to add
3886 		   to the base pointer. */
3887 
3888                 nummessages++;
3889                 send_ring = send_ring->next;
3890                 if (bytes_remaining) {
3891                     bytes_remaining -= send_size;
3892                 }
3893             }
3894 
3895             /* check exs_send result */
3896             if (exs_aio_pending < NETPERF_EXS_PENDING) {
3897                /* standard flow control case */
3898                 if (errno == EAGAIN)
3899                     exs_aio_eagain++;
3900                 /* case of times_up */
3901                 else if (errno == EINTR)
3902                     break;
3903                 /* strange, let's stop */
3904                 else {
3905                     perror ("netperf: exs_send error");
3906                     exit (1);
3907                 }
3908             }
3909 
3910             /* dequeue events with "threshold" on 1/2 posted */
3911             exs_aio_dequeued =
3912                 exs_qdequeue (exs_qhandle, exs_evtvec,
3913                               -(exs_aio_pending>>1), NULL);
3914             exs_aio_dequeuecnt++;
3915 
3916             /* check exs_dequeue result */
3917             if (exs_aio_dequeued < 0) {
3918                 /* case of times_up */
3919                 if (errno == EINTR)
3920                     break;
3921                 /* strange, let's stop */
3922                 else {
3923                     perror ("netperf: exs_send error");
3924                     exit (1);
3925                 }
3926             }
3927             /* update number of pending I/Os */
3928             else {
3929                 exs_aio_pending -= exs_aio_dequeued;
3930             }
3931 
3932 
3933 #if 0 /* def WANT_HISTOGRAM */
3934             /* timestamp the exit from the send call and update the histogram */
3935             HIST_timestamp(&time_two);
3936             HIST_add(time_hist,delta_micro(&time_one,&time_two));
3937 #endif /* WANT_HISTOGRAM */
3938 
3939 #if 0 /* def WANT_DEMO */
3940             demo_stream_interval(send_size);
3941 #endif
3942 
3943 #if 0 /* def WANT_INTERVALS */
3944 	    INTERVALS_WAIT();
3945 #endif /* WANT_INTERVALS */
3946 
3947         }
3948 
3949         /* Collect the last completion events */
3950         exs_aio_dequeued =
3951             exs_qdequeue (exs_qhandle, exs_evtvec, -exs_aio_pending, NULL);
3952         exs_aio_dequeuecnt++;
3953         /* check exs_dequeue result and update number of pending I/Os */
3954         if (exs_aio_dequeued < 0) {
3955             perror ("netperf: exs_send error");
3956             exit (1);
3957         }
3958         exs_aio_pending -= exs_aio_dequeued;
3959 
3960         /* Display some async I/O debug info */
3961         if (debug) {
3962             fprintf (where, "send_exs_tcp_stream: "
3963                      "aio sent=%d eagain=%d dequeue=%d pending=%d\n",
3964                      nummessages, exs_aio_eagain, exs_aio_dequeuecnt, exs_aio_pending);
3965         }
3966 
3967         /* The test is over. Flush the buffers to the remote end. We do a */
3968         /* graceful release to insure that all data has been taken by the */
3969         /* remote. */
3970 
3971         /* but first, if the verbosity is greater than 1, find-out what */
3972         /* the TCP maximum segment_size was (if possible) */
3973         if (verbosity > 1) {
3974             tcp_mss = -1;
3975             get_tcp_info(send_socket,&tcp_mss);
3976         }
3977 
3978         if (shutdown(send_socket,SHUT_WR) == SOCKET_ERROR) {
3979             perror("netperf: cannot shutdown tcp stream socket");
3980             exit(1);
3981         }
3982 
3983         /* hang a recv() off the socket to block until the remote has */
3984         /* brought all the data up into the application. it will do a */
3985         /* shutdown to cause a FIN to be sent our way. We will assume that */
3986         /* any exit from the recv() call is good... raj 4/93 */
3987 
3988         recv(send_socket, send_ring->buffer_ptr, send_size, 0);
3989 
3990         /* this call will always give us the elapsed time for the test, and */
3991         /* will also store-away the necessaries for cpu utilization */
3992 
3993         cpu_stop(local_cpu_usage,&elapsed_time);   /* was cpu being */
3994         /* measured and how */
3995         /* long did we really */
3996         /* run? */
3997 
3998         /* we are finished with the socket, so close it to prevent hitting */
3999         /* the limit on maximum open files. */
4000 
4001         close(send_socket);
4002 
4003         /* Get the statistics from the remote end. The remote will have */
4004         /* calculated service demand and all those interesting things. If it */
4005         /* wasn't supposed to care, it will return obvious values. */
4006 
4007         recv_response();
4008         if (!netperf_response.content.serv_errno) {
4009             if (debug)
4010                 fprintf(where,"remote results obtained\n");
4011         }
4012         else {
4013             Set_errno(netperf_response.content.serv_errno);
4014             fprintf(where,
4015                     "netperf: remote error %d",
4016                     netperf_response.content.serv_errno);
4017             perror("");
4018             fflush(where);
4019 
4020             exit(1);
4021         }
4022 
4023         /* We now calculate what our thruput was for the test. In the future, */
4024         /* we may want to include a calculation of the thruput measured by */
4025         /* the remote, but it should be the case that for a TCP stream test, */
4026         /* that the two numbers should be *very* close... We calculate */
4027         /* bytes_sent regardless of the way the test length was controlled. */
4028         /* If it was time, we needed to, and if it was by bytes, the user may */
4029         /* have specified a number of bytes that wasn't a multiple of the */
4030         /* send_size, so we really didn't send what he asked for ;-) */
4031 
4032         bytes_sent   = ntohd(tcp_stream_result->bytes_received);
4033 
4034         thruput   = calc_thruput(bytes_sent);
4035 
4036         if (local_cpu_usage || remote_cpu_usage) {
4037             /* We must now do a little math for service demand and cpu */
4038             /* utilization for the system(s) */
4039             /* Of course, some of the information might be bogus because */
4040             /* there was no idle counter in the kernel(s). We need to make */
4041             /* a note of this for the user's benefit...*/
4042             if (local_cpu_usage) {
4043 
4044                 local_cpu_utilization   = calc_cpu_util(0.0);
4045                 local_service_demand   = calc_service_demand(bytes_sent,
4046                                                              0.0,
4047                                                              0.0,
4048                                                              0);
4049             }
4050             else {
4051                 local_cpu_utilization   = (float) -1.0;
4052                 local_service_demand   = (float) -1.0;
4053             }
4054 
4055             if (remote_cpu_usage) {
4056 
4057                 remote_cpu_utilization   = tcp_stream_result->cpu_util;
4058                 remote_service_demand   = calc_service_demand(bytes_sent,
4059                                                               0.0,
4060                                                               remote_cpu_utilization,
4061                                                               tcp_stream_result->num_cpus);
4062             }
4063             else {
4064                 remote_cpu_utilization = (float) -1.0;
4065                 remote_service_demand  = (float) -1.0;
4066             }
4067         }
4068         else {
4069             /* we were not measuring cpu, for the confidence stuff, we */
4070             /* should make it -1.0 */
4071             local_cpu_utilization   = (float) -1.0;
4072             local_service_demand   = (float) -1.0;
4073             remote_cpu_utilization = (float) -1.0;
4074             remote_service_demand  = (float) -1.0;
4075         }
4076 
4077         /* at this point, we want to calculate the confidence information. */
4078         /* if debugging is on, calculate_confidence will print-out the */
4079         /* parameters we pass it */
4080 
4081         calculate_confidence(confidence_iteration,
4082                              elapsed_time,
4083                              thruput,
4084                              local_cpu_utilization,
4085                              remote_cpu_utilization,
4086                              local_service_demand,
4087                              remote_service_demand);
4088 
4089 
4090         confidence_iteration++;
4091     }
4092 
4093     /* at this point, we have finished making all the runs that we */
4094     /* will be making. so, we should extract what the calcuated values */
4095     /* are for all the confidence stuff. we could make the values */
4096     /* global, but that seemed a little messy, and it did not seem worth */
4097     /* all the mucking with header files. so, we create a routine much */
4098     /* like calcualte_confidence, which just returns the mean values. */
4099     /* raj 11/94 */
4100 
4101     retrieve_confident_values(&elapsed_time,
4102                               &thruput,
4103                               &local_cpu_utilization,
4104                               &remote_cpu_utilization,
4105                               &local_service_demand,
4106                               &remote_service_demand);
4107 
4108     /* We are now ready to print all the information. If the user */
4109     /* has specified zero-level verbosity, we will just print the */
4110     /* local service demand, or the remote service demand. If the */
4111     /* user has requested verbosity level 1, he will get the basic */
4112     /* "streamperf" numbers. If the user has specified a verbosity */
4113     /* of greater than 1, we will display a veritable plethora of */
4114     /* background information from outside of this block as it it */
4115     /* not cpu_measurement specific...  */
4116 
4117     if (confidence < 0) {
4118         /* we did not hit confidence, but were we asked to look for it? */
4119         if (iteration_max > 1) {
4120             display_confidence();
4121         }
4122     }
4123 
4124     if (local_cpu_usage || remote_cpu_usage) {
4125         local_cpu_method = format_cpu_method(cpu_method);
4126         remote_cpu_method = format_cpu_method(tcp_stream_result->cpu_method);
4127 
4128         switch (verbosity) {
4129             case 0:
4130                 if (local_cpu_usage) {
4131                     fprintf(where,
4132                             cpu_fmt_0,
4133                             local_service_demand,
4134                             local_cpu_method);
4135                 }
4136                 else {
4137                     fprintf(where,
4138                             cpu_fmt_0,
4139                             remote_service_demand,
4140                             remote_cpu_method);
4141                 }
4142                 break;
4143             case 1:
4144             case 2:
4145                 if (print_headers) {
4146                     fprintf(where,
4147                             cpu_title,
4148                             format_units(),
4149                             local_cpu_method,
4150                             remote_cpu_method);
4151                 }
4152 
4153                 fprintf(where,
4154                         cpu_fmt_1,      /* the format string */
4155                         rsr_size,              /* remote recvbuf size */
4156                         lss_size,              /* local sendbuf size */
4157                         send_size,      /* how large were the sends */
4158                         elapsed_time,      /* how long was the test */
4159                         thruput,               /* what was the xfer rate */
4160                         local_cpu_utilization,   /* local cpu */
4161                         remote_cpu_utilization,   /* remote cpu */
4162                         local_service_demand,   /* local service demand */
4163                         remote_service_demand);   /* remote service demand */
4164                 break;
4165         }
4166     }
4167     else {
4168         /* The tester did not wish to measure service demand. */
4169 
4170         switch (verbosity) {
4171             case 0:
4172                 fprintf(where,
4173                         tput_fmt_0,
4174                         thruput);
4175                 break;
4176             case 1:
4177             case 2:
4178                 if (print_headers) {
4179                     fprintf(where,tput_title,format_units());
4180                 }
4181                 fprintf(where,
4182                         tput_fmt_1,      /* the format string */
4183                         rsr_size,       /* remote recvbuf size */
4184                         lss_size,       /* local sendbuf size */
4185                         send_size,      /* how large were the sends */
4186                         elapsed_time,       /* how long did it take */
4187                         thruput);/* how fast did it go */
4188                 break;
4189         }
4190     }
4191 
4192     /* it would be a good thing to include information about some of the */
4193     /* other parameters that may have been set for this test, but at the */
4194     /* moment, I do not wish to figure-out all the  formatting, so I will */
4195     /* just put this comment here to help remind me that it is something */
4196     /* that should be done at a later time. */
4197 
4198     if (verbosity > 1) {
4199         /* The user wanted to know it all, so we will give it to him. */
4200         /* This information will include as much as we can find about */
4201         /* TCP statistics, the alignments of the sends and receives */
4202         /* and all that sort of rot... */
4203 
4204         /* this stuff needs to be worked-out in the presence of confidence */
4205         /* intervals and multiple iterations of the test... raj 11/94 */
4206 
4207         fprintf(where,
4208                 ksink_fmt,
4209                 "Bytes",
4210                 "Bytes",
4211                 "Bytes",
4212                 local_send_align,
4213                 remote_recv_align,
4214                 local_send_offset,
4215                 remote_recv_offset,
4216                 bytes_sent,
4217                 bytes_sent / (double)nummessages,
4218                 nummessages,
4219                 bytes_sent / (double)tcp_stream_result->recv_calls,
4220                 tcp_stream_result->recv_calls);
4221         fprintf(where,
4222                 ksink_fmt2,
4223                 tcp_mss);
4224         fflush(where);
4225 #if 0 /* def WANT_HISTOGRAM */
4226         fprintf(where,"\n\nHistogram of time spent in send() call.\n");
4227         fflush(where);
4228         HIST_report(time_hist);
4229 #endif /* WANT_HISTOGRAM */
4230     }
4231 
4232 }
4233 
4234 #endif /* HAVE_ICSC_EXS */
4235 
4236 
4237 
4238 #if defined(HAVE_SENDFILE)
4239 
4240 
4241 /* This routine implements the TCP unidirectional data transfer test
4242    (a.k.a. stream) for the sockets interface using the sendfile()
4243    system call - TCP_SENDFILE.  It receives its  parameters via global
4244    variables from the shell and writes its  output to the standard
4245    output. Basically,  this is the same test as the send_tcp_stream()
4246    logic and we even tell the remote to do a TCP_STREAM test since for
4247    all it knows, nothig is different. */
4248 
4249 void
sendfile_tcp_stream(remote_host)4250 sendfile_tcp_stream(remote_host)
4251      char	remote_host[];
4252 {
4253 
4254   char *tput_title = "\
4255 Recv   Send    Send                          \n\
4256 Socket Socket  Message  Elapsed              \n\
4257 Size   Size    Size     Time     Throughput  \n\
4258 bytes  bytes   bytes    secs.    %s/sec  \n\n";
4259 
4260   char *tput_fmt_0 =
4261     "%7.2f %s\n";
4262 
4263   char *tput_fmt_1 =
4264     "%6d %6d %6d    %-6.2f   %7.2f   %s\n";
4265 
4266   char *cpu_title = "\
4267 Recv   Send    Send                          Utilization       Service Demand\n\
4268 Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
4269 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
4270 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
4271 
4272   char *cpu_fmt_0 =
4273     "%6.3f %c %s\n";
4274   char *cpu_fmt_1 =
4275     "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f %s\n";
4276 
4277   char *ksink_fmt = "\n\
4278 Alignment      Offset         %-8.8s %-8.8s    Sends   %-8.8s Recvs\n\
4279 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
4280 Send   Recv    Send   Recv             Send (avg)          Recv (avg)\n\
4281 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
4282 
4283 char *ksink_fmt2 = "\n\
4284 Maximum\n\
4285 Segment\n\
4286 Size (bytes)\n\
4287 %6d\n";
4288 
4289   float			elapsed_time;
4290 
4291   /* what we want is to have a buffer space that is at least one */
4292   /* send-size greater than our send window. this will insure that we */
4293   /* are never trying to re-use a buffer that may still be in the hands */
4294   /* of the transport. This buffer will be malloc'd after we have found */
4295   /* the size of the local senc socket buffer. We will want to deal */
4296   /* with alignment and offset concerns as well. */
4297 
4298   struct ring_elt *send_ring;
4299 
4300   int len;
4301   unsigned int nummessages = 0;
4302   SOCKET send_socket;
4303   int bytes_remaining;
4304   int tcp_mss = -1;  /* possibly uninitialized on printf far below */
4305 
4306   /* with links like fddi, one can send > 32 bits worth of bytes */
4307   /* during a test... ;-) at some point, this should probably become a */
4308   /* 64bit integral type, but those are not entirely common yet */
4309   double	bytes_sent = 0.0;
4310 
4311   float	local_cpu_utilization;
4312   float	local_service_demand;
4313   float	remote_cpu_utilization;
4314   float	remote_service_demand;
4315 
4316   double	thruput;
4317 
4318   struct  addrinfo *remote_res;
4319   struct  addrinfo *local_res;
4320   struct	sockaddr_in	server;
4321 
4322 #if defined(__linux) || defined(__sun)
4323   off_t     scratch_offset;   /* the linux sendfile() call will update
4324 				 the offset variable, which is
4325 				 something we do _not_ want to happen
4326 				 to the value in the send_ring! so, we
4327 				 have to use a scratch variable. */
4328 #endif /* __linux  || defined(__sun) */
4329 #if defined (USE_OSX)
4330    off_t    scratch_len;  /* Darwin 9.x need a value-result parameter  */
4331 #endif
4332 #if defined (__sun)
4333    size_t  scratch_len;	/* the sun sendfilev() needs a place to
4334 			   tell us how many bytes were written,
4335 			   even though it also returns the value */
4336    sendfilevec_t sv;
4337 #endif /* __sun */
4338 
4339   struct	tcp_stream_request_struct	*tcp_stream_request;
4340   struct	tcp_stream_response_struct	*tcp_stream_response;
4341   struct	tcp_stream_results_struct	*tcp_stream_result;
4342 
4343   tcp_stream_request  =
4344     (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
4345   tcp_stream_response =
4346     (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
4347   tcp_stream_result   =
4348     (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
4349 
4350 #ifdef WANT_HISTOGRAM
4351   if (verbosity > 1) {
4352     time_hist = HIST_new();
4353   }
4354 #endif /* WANT_HISTOGRAM */
4355 
4356   /* since we are now disconnected from the code that established the */
4357   /* control socket, and since we want to be able to use different */
4358   /* protocols and such, we are passed the name of the remote host and */
4359   /* must turn that into the test specific addressing information. */
4360 
4361   bzero((char *)&server,
4362 	sizeof(server));
4363 
4364   complete_addrinfos(&remote_res,
4365 		     &local_res,
4366 		     remote_host,
4367 		     SOCK_STREAM,
4368 		     IPPROTO_TCP,
4369 		     0);
4370 
4371   if ( print_headers ) {
4372     /* we want to have some additional, interesting information in */
4373     /* the headers. we know some of it here, but not all, so we will */
4374     /* only print the test title here and will print the results */
4375     /* titles after the test is finished */
4376     print_top_test_header("TCP SENDFILE TEST",local_res,remote_res);
4377   }
4378 
4379   send_ring = NULL;
4380   confidence_iteration = 1;
4381   init_stat();
4382 
4383   /* we have a great-big while loop which controls the number of times */
4384   /* we run a particular test. this is for the calculation of a */
4385   /* confidence interval (I really should have stayed awake during */
4386   /* probstats :). If the user did not request confidence measurement */
4387   /* (no confidence is the default) then we will only go though the */
4388   /* loop once. the confidence stuff originates from the folks at IBM */
4389 
4390   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
4391 	 (confidence_iteration <= iteration_min)) {
4392 
4393     /* initialize a few counters. we have to remember that we might be */
4394     /* going through the loop more than once. */
4395 
4396     nummessages    =	0;
4397     bytes_sent     =	0.0;
4398     times_up       = 	0;
4399 
4400     /* set up the data socket */
4401     send_socket = create_data_socket(local_res);
4402 
4403     if (send_socket == INVALID_SOCKET){
4404       perror("netperf: sendfile_tcp_stream: tcp stream data socket");
4405       exit(1);
4406     }
4407 
4408     if (debug) {
4409       fprintf(where,"sendfile_tcp_stream: send_socket obtained...\n");
4410     }
4411 
4412 #if defined(TCP_CORK)
4413     /* should this even be here?!? */
4414     if (loc_tcpcork > 0) {
4415       /* the user wishes for us to set TCP_CORK on the socket */
4416       int one = 1;
4417       if (setsockopt(send_socket,
4418 		     getprotobyname("tcp")->p_proto,
4419 		     TCP_CORK,
4420 		     (char *)&one,
4421 		     sizeof(one)) == SOCKET_ERROR) {
4422 	perror("netperf: sendfile_tcp_stream: tcp_cork");
4423 	exit(1);
4424       }
4425       if (debug) {
4426 	fprintf(where,"sendfile_tcp_stream: tcp_cork...\n");
4427       }
4428     }
4429 
4430 #endif /* TCP_CORK */
4431 
4432     /* at this point, we have either retrieved the socket buffer sizes, */
4433     /* or have tried to set them, so now, we may want to set the send */
4434     /* size based on that (because the user either did not use a -m */
4435     /* option, or used one with an argument of 0). If the socket buffer */
4436     /* size is not available, we will set the send size to 4KB - no */
4437     /* particular reason, just arbitrary... */
4438 
4439     /*check for file size/ min file size here?  create file here/ back out???*/
4440 
4441     if (send_size == 0) {
4442       if (lss_size > 0) {
4443 	send_size = lss_size;
4444       }
4445       else {
4446 	send_size = 4096;
4447       }
4448     }
4449 
4450     /* set-up the data buffer ring with the requested alignment and
4451        offset. note also that we have allocated a quantity  of memory
4452        that is at least one send-size greater than our socket  buffer
4453        size. We want to be sure that there are at least two  buffers
4454        allocated - this can be a bit of a problem when the  send_size
4455        is bigger than the socket size, so we must check... the  user
4456        may have wanted to explicitly set the "width" of our send
4457        buffers, we should respect that wish... */
4458 
4459     /*sendring -> an offset index that will shift the starting point of the*/
4460     /*section of the file sent throughout the file*/
4461 
4462     if (send_width == 0) {
4463       send_width = (lss_size/send_size) + 1;
4464       if (send_width == 1) send_width++;
4465     }
4466 
4467     if (send_ring == NULL) {
4468 
4469       /* only allocate the send ring once. this is a networking test,
4470 	 not a memory allocation test. this way, we do not need a
4471 	 deallocate_buffer_ring() routine, and I don't feel like
4472 	 writing one anyway :) raj 11/94 */
4473 
4474       send_ring = alloc_sendfile_buf_ring(send_width,
4475 					  send_size,
4476 					  local_send_align,
4477 					  local_send_offset);
4478     }
4479 
4480     /* If the user has requested cpu utilization measurements, we must
4481        calibrate the cpu(s). We will perform this task within the
4482        tests  themselves. If the user has specified the cpu rate, then
4483        calibrate_local_cpu will return rather quickly as it will have
4484        nothing to do. If local_cpu_rate is zero, then we will go
4485        through  all the "normal" calibration stuff and return the rate
4486        back. */
4487 
4488     if (local_cpu_usage) {
4489       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
4490     }
4491 
4492     /* Tell the remote end to do a listen. The server alters the
4493        socket  paramters on the other side at this point, hence the
4494        reason for  all the values being passed in the setup
4495        message. If the user did  not specify any of the parameters,
4496        they will be passed as 0, which  will indicate to the remote
4497        that no changes beyond the system's  default should be
4498        used. Alignment is the exception, it will  default to 1, which
4499        will be no alignment alterations. */
4500 
4501     netperf_request.content.request_type =	DO_TCP_STREAM;
4502     tcp_stream_request->send_buf_size	=	rss_size_req;
4503     tcp_stream_request->recv_buf_size	=	rsr_size_req;
4504     tcp_stream_request->receive_size	=	recv_size;
4505     tcp_stream_request->no_delay	=	rem_nodelay;
4506     tcp_stream_request->recv_alignment	=	remote_recv_align;
4507     tcp_stream_request->recv_offset	=	remote_recv_offset;
4508     tcp_stream_request->measure_cpu	=	remote_cpu_usage;
4509     tcp_stream_request->cpu_rate	=	remote_cpu_rate;
4510 
4511     if (test_time) {
4512       tcp_stream_request->test_length	=	test_time;
4513     }
4514     else {
4515       tcp_stream_request->test_length	=	test_bytes;
4516     }
4517 
4518     tcp_stream_request->so_rcvavoid	=	rem_rcvavoid;
4519     tcp_stream_request->so_sndavoid	=	rem_sndavoid;
4520 
4521 #ifdef DIRTY
4522     tcp_stream_request->dirty_count       =       rem_dirty_count;
4523     tcp_stream_request->clean_count       =       rem_clean_count;
4524 #endif /* DIRTY */
4525     tcp_stream_request->port     = atoi(remote_data_port);
4526     tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
4527     tcp_stream_request->recv_aio        =       rem_rcvaio;
4528 
4529     if (debug > 1) {
4530       fprintf(where,
4531 	      "netperf: send_tcp_stream: requesting TCP stream test\n");
4532     }
4533 
4534     send_request();
4535 
4536     /* The response from the remote will contain all of the relevant
4537        socket parameters for this test type. We will put them back
4538        into the variables here so they can be displayed if desired.
4539        The remote will have calibrated CPU if necessary, and will have
4540        done all the needed set-up we will have calibrated the cpu
4541        locally before sending the request, and will grab the counter
4542        value right after the connect returns. The remote will grab the
4543        counter right after the accept call. This saves the hassle of
4544        extra messages being sent for the TCP tests.  */
4545 
4546     recv_response();
4547 
4548     if (!netperf_response.content.serv_errno) {
4549       if (debug)
4550 	fprintf(where,"remote listen done.\n");
4551       rsr_size	      =	tcp_stream_response->recv_buf_size;
4552       rss_size	      =	tcp_stream_response->send_buf_size;
4553       rem_nodelay     =	tcp_stream_response->no_delay;
4554       remote_cpu_usage=	tcp_stream_response->measure_cpu;
4555       remote_cpu_rate = tcp_stream_response->cpu_rate;
4556 
4557       /* we have to make sure that the server port number is in */
4558       /* network order */
4559       set_port_number(remote_res,(short)tcp_stream_response->data_port_number);
4560       rem_rcvavoid	= tcp_stream_response->so_rcvavoid;
4561       rem_sndavoid	= tcp_stream_response->so_sndavoid;
4562     }
4563     else {
4564       Set_errno(netperf_response.content.serv_errno);
4565       fprintf(where,
4566 	      "netperf: remote error %d",
4567 	      netperf_response.content.serv_errno);
4568       perror("");
4569       fflush(where);
4570 
4571       exit(1);
4572     }
4573 
4574 #ifdef WANT_DEMO
4575     demo_stream_setup(lss_size,rsr_size);
4576 #endif
4577 
4578     /*Connect up to the remote port on the data socket  */
4579     if (connect(send_socket,
4580 		remote_res->ai_addr,
4581 		remote_res->ai_addrlen) == INVALID_SOCKET){
4582       perror("netperf: send_tcp_stream: data socket connect failed");
4583       printf(" port: %d\n",ntohs(server.sin_port));
4584       exit(1);
4585     }
4586 
4587 #ifdef WIN32
4588   /* this is used so the timer thread can close the socket out from */
4589   /* under us, which to date is the easiest/cleanest/least */
4590   /* Windows-specific way I can find to force the winsock calls to */
4591   /* return WSAEINTR with the test is over. anything that will run on */
4592   /* 95 and NT and is closer to what netperf expects from Unix signals */
4593   /* and such would be appreciated raj 1/96 */
4594   win_kludge_socket = send_socket;
4595 #endif /* WIN32 */
4596 
4597     /* Data Socket set-up is finished. If there were problems, either
4598        the connect would have failed, or the previous response would
4599        have indicated a problem. I failed to see the value of the
4600        extra message after the accept on the remote. If it failed,
4601        we'll see it here. If it didn't, we might as well start pumping
4602        data. */
4603 
4604     /* Set-up the test end conditions. For a stream test, they can be */
4605     /* either time or byte-count based. */
4606 
4607     if (test_time) {
4608       /* The user wanted to end the test after a period of time. */
4609       times_up = 0;
4610       bytes_remaining = 0;
4611 
4612       /* in previous revisions, we had the same code repeated throught
4613          all the test suites. this was unnecessary, and meant more
4614          work for me when I wanted to switch to POSIX signals, so I
4615          have abstracted this out into a routine in netlib.c. if you
4616          are experiencing signal problems, you might want to look
4617          there. raj 11/94 */
4618 
4619       start_timer(test_time);
4620     }
4621     else {
4622       /* The tester wanted to send a number of bytes. */
4623       bytes_remaining = test_bytes;
4624       times_up = 1;
4625     }
4626 
4627     /* The cpu_start routine will grab the current time and possibly */
4628     /* value of the idle counter for later use in measuring cpu */
4629     /* utilization and/or service demand and thruput. */
4630 
4631     cpu_start(local_cpu_usage);
4632 
4633 #ifdef WANT_INTERVALS
4634     INTERVALS_INIT();
4635 #endif /* WANT_INTERVALS */
4636 
4637 
4638     /* before we start, initialize a few variables */
4639 
4640 #ifdef WANT_DEMO
4641     if (demo_mode) {
4642       demo_first_timestamp();
4643     }
4644 #endif
4645 
4646     /* We use an "OR" to control test execution. When the test is
4647        controlled by time, the byte count check will always return
4648        false. When the test is controlled by byte count, the time test
4649        will always return false. When the test is finished, the whole
4650        expression will go false and we will stop sending data. */
4651 
4652     while ((!times_up) || (bytes_remaining > 0)) {
4653 
4654       /* the sendfile_tcp_stream test does not support making the buffers
4655 	 dirty. 08/2000 */
4656 
4657 #ifdef WANT_HISTOGRAM
4658       if (verbosity > 1) {
4659 	/* timestamp just before we go into sendfile() and then again
4660          just after we come out raj 08/2000 */
4661 	/* but only if we are actually going to display a histogram */
4662 	HIST_timestamp(&time_one);
4663       }
4664 #endif /* WANT_HISTOGRAM */
4665 
4666       /* you can look at netlib.h for a description of the fields we
4667 	 are passing to sendfile(). 08/2000 */
4668       if (netperf_sendfile(send_socket, send_ring) != send_size) {
4669 	/* the test was interrupted, must be the end of test. the
4670 	   send_tcp_stream code has some WIN32 ifdefs that we do not
4671 	   need here. */
4672 	if ((len >=0) || SOCKET_EINTR(len)) {
4673 	  break;
4674 	}
4675 	perror("netperf: data send error: sendfile");
4676 	fprintf(stderr,
4677 		"len was %d send_size was %d\n",
4678 		len,
4679 		send_size);
4680 	fflush(stderr);
4681 	exit(1);
4682       }
4683 
4684 #ifdef WANT_HISTOGRAM
4685       if (verbosity > 1) {
4686 	/* timestamp the exit from the send call and update the
4687 	   histogram */
4688 
4689 	HIST_timestamp(&time_two);
4690 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
4691       }
4692 #endif /* WANT_HISTOGRAM */
4693 
4694 #ifdef WANT_DEMO
4695       demo_stream_interval(send_size);
4696 #endif
4697 
4698 #ifdef WANT_INTERVALS
4699       INTERVALS_WAIT();
4700 #endif /* WANT_INTERVALS */
4701 
4702       /* now we want to move our pointer to the next position in the */
4703       /* data buffer...we may also want to wrap back to the "beginning" */
4704       /* of the bufferspace, so we will mod the number of messages sent */
4705       /* by the send width, and use that to calculate the offset to add */
4706       /* to the base pointer. */
4707 
4708       nummessages++;
4709       send_ring = send_ring->next;
4710       if (bytes_remaining) {
4711 	bytes_remaining -= send_size;
4712       }
4713     }
4714 
4715     /* The test is over. Flush the buffers to the remote end. We do a
4716        graceful release to insure that all data has been taken by the
4717        remote. */
4718 
4719     /* but first, if the verbosity is greater than 1, find-out what */
4720     /* the TCP maximum segment_size was (if possible) */
4721     if (verbosity > 1) {
4722       tcp_mss = -1;
4723       get_tcp_info(send_socket,&tcp_mss);
4724     }
4725 
4726     if (shutdown(send_socket,SHUT_WR) == SOCKET_ERROR) {
4727       perror("netperf: cannot shutdown tcp stream socket");
4728       exit(1);
4729     }
4730 
4731     /* hang a recv() off the socket to block until the remote has */
4732     /* brought all the data up into the application. it will do a */
4733     /* shutdown to cause a FIN to be sent our way. We will assume that */
4734     /* any exit from the recv() call is good... raj 4/93 */
4735 
4736     /* since we are using sendfile() instead of send, we have no
4737        scratch buffer from the send_ring to use for the
4738        receive. however, since we "know" that the recv should be
4739        returning zero bytes (not that we are making the checks we
4740        should) we can pass the address of the flags field. raj 08/2000
4741     */
4742 
4743     recv(send_socket,
4744 	 &(send_ring->flags),
4745 	 sizeof(send_ring->flags),
4746 	 0);
4747 
4748     /* this call will always give us the elapsed time for the test, and */
4749     /* will also store-away the necessaries for cpu utilization */
4750 
4751     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
4752 						/* measured and how */
4753 						/* long did we really */
4754 						/* run? */
4755 
4756     /* we are finished with the socket, so close it to prevent hitting */
4757     /* the limit on maximum open files. */
4758 
4759     close(send_socket);
4760 
4761  #if defined(WANT_INTERVALS)
4762 #ifdef WIN32
4763     stop_itimer();
4764 #endif
4765 #endif /* WANT_INTERVALS */
4766 
4767    /* Get the statistics from the remote end. The remote will have */
4768     /* calculated service demand and all those interesting things. If it */
4769     /* wasn't supposed to care, it will return obvious values. */
4770 
4771     recv_response();
4772 
4773     if (!netperf_response.content.serv_errno) {
4774       if (debug)
4775 	fprintf(where,"remote results obtained\n");
4776     }
4777 
4778     else {
4779       Set_errno(netperf_response.content.serv_errno);
4780       fprintf(where,
4781 	      "netperf: remote error %d",
4782 	      netperf_response.content.serv_errno);
4783       perror("");
4784       fflush(where);
4785 
4786       exit(1);
4787     }
4788 
4789     /* We now calculate what our thruput was for the test. In the future, */
4790     /* we may want to include a calculation of the thruput measured by */
4791     /* the remote, but it should be the case that for a TCP stream test, */
4792     /* that the two numbers should be *very* close... We calculate */
4793     /* bytes_sent regardless of the way the test length was controlled. */
4794     /* If it was time, we needed to, and if it was by bytes, the user may */
4795     /* have specified a number of bytes that wasn't a multiple of the */
4796     /* send_size, so we really didn't send what he asked for ;-) */
4797 
4798     bytes_sent	= ntohd(tcp_stream_result->bytes_received);
4799 
4800     thruput	= calc_thruput(bytes_sent);
4801 
4802     if (local_cpu_usage || remote_cpu_usage) {
4803 
4804       /* We must now do a little math for service demand and cpu */
4805       /* utilization for the system(s) */
4806       /* Of course, some of the information might be bogus because */
4807       /* there was no idle counter in the kernel(s). We need to make */
4808       /* a note of this for the user's benefit...*/
4809       if (local_cpu_usage) {
4810 
4811 	local_cpu_utilization	= calc_cpu_util(0.0);
4812 	local_service_demand	= calc_service_demand(bytes_sent,
4813 						      0.0,
4814 						      0.0,
4815 						      0);
4816       }
4817       else {
4818 	local_cpu_utilization	= (float) -1.0;
4819 	local_service_demand	= (float) -1.0;
4820       }
4821 
4822       if (remote_cpu_usage) {
4823 
4824 	remote_cpu_utilization	= tcp_stream_result->cpu_util;
4825 	remote_service_demand	= calc_service_demand(bytes_sent,
4826 						      0.0,
4827 						      remote_cpu_utilization,
4828 						      tcp_stream_result->num_cpus);
4829       }
4830       else {
4831 	remote_cpu_utilization = (float) -1.0;
4832 	remote_service_demand  = (float) -1.0;
4833       }
4834     }
4835     else {
4836       /* we were not measuring cpu, for the confidence stuff, we */
4837       /* should make it -1.0 */
4838       local_cpu_utilization	= (float) -1.0;
4839       local_service_demand	= (float) -1.0;
4840       remote_cpu_utilization = (float) -1.0;
4841       remote_service_demand  = (float) -1.0;
4842     }
4843 
4844     /* at this point, we want to calculate the confidence information. */
4845     /* if debugging is on, calculate_confidence will print-out the */
4846     /* parameters we pass it */
4847 
4848     calculate_confidence(confidence_iteration,
4849 			 elapsed_time,
4850 			 thruput,
4851 			 local_cpu_utilization,
4852 			 remote_cpu_utilization,
4853 			 local_service_demand,
4854 			 remote_service_demand);
4855 
4856     confidence_iteration++;
4857   }
4858 
4859   /* at this point, we have finished making all the runs that we */
4860   /* will be making. so, we should extract what the calcuated values */
4861   /* are for all the confidence stuff. we could make the values */
4862   /* global, but that seemed a little messy, and it did not seem worth */
4863   /* all the mucking with header files. so, we create a routine much */
4864   /* like calcualte_confidence, which just returns the mean values. */
4865   /* raj 11/94 */
4866 
4867   retrieve_confident_values(&elapsed_time,
4868 			    &thruput,
4869 			    &local_cpu_utilization,
4870 			    &remote_cpu_utilization,
4871 			    &local_service_demand,
4872 			    &remote_service_demand);
4873 
4874   /* We are now ready to print all the information. If the user */
4875   /* has specified zero-level verbosity, we will just print the */
4876   /* local service demand, or the remote service demand. If the */
4877   /* user has requested verbosity level 1, he will get the basic */
4878   /* "streamperf" numbers. If the user has specified a verbosity */
4879   /* of greater than 1, we will display a veritable plethora of */
4880   /* background information from outside of this block as it it */
4881   /* not cpu_measurement specific...  */
4882 
4883   if (confidence < 0) {
4884     /* we did not hit confidence, but were we asked to look for it? */
4885     if (iteration_max > 1) {
4886       display_confidence();
4887     }
4888   }
4889 
4890   if (local_cpu_usage || remote_cpu_usage) {
4891     local_cpu_method = format_cpu_method(cpu_method);
4892     remote_cpu_method = format_cpu_method(tcp_stream_result->cpu_method);
4893 
4894     switch (verbosity) {
4895     case 0:
4896 
4897     if (local_cpu_usage) {
4898 	fprintf(where,
4899 		cpu_fmt_0,
4900 		local_service_demand,
4901 		local_cpu_method,
4902 		((print_headers) ||
4903 		 (result_brand == NULL)) ? "" : result_brand);
4904       }
4905 
4906       else {
4907 	fprintf(where,
4908 		cpu_fmt_0,
4909 		remote_service_demand,
4910 		remote_cpu_method,
4911 		((print_headers) ||
4912 		 (result_brand == NULL)) ? "" : result_brand);
4913       }
4914 
4915       break;
4916 
4917     case 1:
4918     case 2:
4919       if (print_headers) {
4920 	fprintf(where,
4921 		cpu_title,
4922 		format_units(),
4923 		local_cpu_method,
4924 		remote_cpu_method);
4925       }
4926 
4927       fprintf(where,
4928 	      cpu_fmt_1,		/* the format string */
4929 	      rsr_size,		        /* remote recvbuf size */
4930 	      lss_size,		        /* local sendbuf size */
4931 	      send_size,		/* how large were the sends */
4932 	      elapsed_time,		/* how long was the test */
4933 	      thruput, 		        /* what was the xfer rate */
4934 	      local_cpu_utilization,	/* local cpu */
4935 	      remote_cpu_utilization,	/* remote cpu */
4936 	      local_service_demand,	/* local service demand */
4937 	      remote_service_demand,	/* remote service demand */
4938 	      ((print_headers) ||
4939 	       (result_brand == NULL)) ? "" : result_brand);
4940       break;
4941     }
4942 
4943   }
4944 
4945   else {
4946     /* The tester did not wish to measure service demand. */
4947 
4948     switch (verbosity) {
4949 
4950     case 0:
4951 
4952       fprintf(where,
4953 	      tput_fmt_0,
4954 	      thruput,
4955 	      ((print_headers) ||
4956 	       (result_brand == NULL)) ? "" : result_brand);
4957       break;
4958 
4959     case 1:
4960     case 2:
4961 
4962       if (print_headers) {
4963 	fprintf(where,tput_title,format_units());
4964       }
4965 
4966       fprintf(where,
4967 	      tput_fmt_1,		/* the format string */
4968 	      rsr_size, 		/* remote recvbuf size */
4969 	      lss_size, 		/* local sendbuf size */
4970 	      send_size,		/* how large were the sends */
4971 	      elapsed_time, 		/* how long did it take */
4972 	      thruput,                  /* how fast did it go */
4973 	      ((print_headers) ||
4974 	       (result_brand == NULL)) ? "" : result_brand);
4975       break;
4976     }
4977   }
4978 
4979   /* it would be a good thing to include information about some of the */
4980   /* other parameters that may have been set for this test, but at the */
4981   /* moment, I do not wish to figure-out all the  formatting, so I will */
4982   /* just put this comment here to help remind me that it is something */
4983   /* that should be done at a later time. */
4984 
4985     if (verbosity > 1) {
4986 
4987     /* The user wanted to know it all, so we will give it to him. */
4988     /* This information will include as much as we can find about */
4989     /* TCP statistics, the alignments of the sends and receives */
4990     /* and all that sort of rot... */
4991 
4992     /* this stuff needs to be worked-out in the presence of confidence */
4993     /* intervals and multiple iterations of the test... raj 11/94 */
4994 
4995     fprintf(where,
4996 	    ksink_fmt,
4997 	    "Bytes",
4998 	    "Bytes",
4999 	    "Bytes",
5000 	    local_send_align,
5001 	    remote_recv_align,
5002 	    local_send_offset,
5003 	    remote_recv_offset,
5004 	    bytes_sent,
5005 	    bytes_sent / (double)nummessages,
5006 	    nummessages,
5007 	    bytes_sent / (double)tcp_stream_result->recv_calls,
5008 	    tcp_stream_result->recv_calls);
5009 
5010     fprintf(where,
5011 	    ksink_fmt2,
5012 	    tcp_mss);
5013 
5014     fflush(where);
5015 
5016 #ifdef WANT_HISTOGRAM
5017 
5018     fprintf(where,"\n\nHistogram of time spent in send() call.\n");
5019     fflush(where);
5020     HIST_report(time_hist);
5021 #endif /* WANT_HISTOGRAM */
5022   }
5023 }
5024 
5025 #endif /* HAVE_SENDFILE */
5026 
5027 /* This is the server-side routine for the tcp stream test. It is */
5028 /* implemented as one routine. I could break things-out somewhat, but */
5029 /* didn't feel it was necessary. */
5030 
5031 void
recv_tcp_stream()5032 recv_tcp_stream()
5033 {
5034 
5035   struct sockaddr_storage myaddr_in, peeraddr_in;
5036   SOCKET s_listen,s_data;
5037   netperf_socklen_t addrlen;
5038   int	len;
5039   unsigned int	receive_calls;
5040   float	elapsed_time;
5041   double   bytes_received;
5042 
5043   struct ring_elt *recv_ring;
5044 
5045   struct addrinfo *local_res;
5046   char local_name[BUFSIZ];
5047   char port_buffer[PORTBUFSIZE];
5048 
5049 #ifdef DO_SELECT
5050   fd_set readfds;
5051   struct timeval timeout;
5052 #endif /* DO_SELECT */
5053 
5054   struct	tcp_stream_request_struct	*tcp_stream_request;
5055   struct	tcp_stream_response_struct	*tcp_stream_response;
5056   struct	tcp_stream_results_struct	*tcp_stream_results;
5057 
5058 #ifdef DO_SELECT
5059   FD_ZERO(&readfds);
5060   timeout.tv_sec = 1;
5061   timeout.tv_usec = 0;
5062 #endif /* DO_SELECT */
5063 
5064   tcp_stream_request	=
5065     (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
5066   tcp_stream_response	=
5067     (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
5068   tcp_stream_results	=
5069     (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
5070 
5071   if (debug) {
5072     fprintf(where,"netserver: recv_tcp_stream: entered...\n");
5073     fflush(where);
5074   }
5075 
5076   /* We want to set-up the listen socket with all the desired */
5077   /* parameters and then let the initiator know that all is ready. If */
5078   /* socket size defaults are to be used, then the initiator will have */
5079   /* sent us 0's. If the socket sizes cannot be changed, then we will */
5080   /* send-back what they are. If that information cannot be determined, */
5081   /* then we send-back -1's for the sizes. If things go wrong for any */
5082   /* reason, we will drop back ten yards and punt. */
5083 
5084   /* If anything goes wrong, we want the remote to know about it. It */
5085   /* would be best if the error that the remote reports to the user is */
5086   /* the actual error we encountered, rather than some bogus unexpected */
5087   /* response type message. */
5088 
5089   if (debug) {
5090     fprintf(where,"recv_tcp_stream: setting the response type...\n");
5091     fflush(where);
5092   }
5093 
5094   netperf_response.content.response_type = TCP_STREAM_RESPONSE;
5095 
5096   if (debug) {
5097     fprintf(where,"recv_tcp_stream: the response type is set...\n");
5098     fflush(where);
5099   }
5100 
5101   /* We now alter the message_ptr variable to be at the desired */
5102   /* alignment with the desired offset. */
5103 
5104   if (debug) {
5105     fprintf(where,"recv_tcp_stream: requested alignment of %d\n",
5106 	    tcp_stream_request->recv_alignment);
5107     fflush(where);
5108   }
5109 
5110   /* create_data_socket expects to find some things in the global */
5111   /* variables, so set the globals based on the values in the request. */
5112   /* once the socket has been created, we will set the response values */
5113   /* based on the updated value of those globals. raj 7/94 */
5114   lss_size_req = tcp_stream_request->send_buf_size;
5115   lsr_size_req = tcp_stream_request->recv_buf_size;
5116   loc_nodelay  = tcp_stream_request->no_delay;
5117   loc_rcvavoid = tcp_stream_request->so_rcvavoid;
5118   loc_sndavoid = tcp_stream_request->so_sndavoid;
5119   loc_rcvaio   = tcp_stream_request->recv_aio;
5120 
5121   set_hostname_and_port(local_name,
5122 			port_buffer,
5123 			nf_to_af(tcp_stream_request->ipfamily),
5124 			tcp_stream_request->port);
5125 
5126   local_res = complete_addrinfo(local_name,
5127 				local_name,
5128 				port_buffer,
5129 				nf_to_af(tcp_stream_request->ipfamily),
5130 				SOCK_STREAM,
5131 				IPPROTO_TCP,
5132 				0);
5133 
5134   s_listen = create_data_socket(local_res);
5135 
5136   if (s_listen == INVALID_SOCKET) {
5137     netperf_response.content.serv_errno = errno;
5138     send_response();
5139     exit(1);
5140   }
5141 
5142 #ifdef WIN32
5143   /* The test timer can fire during operations on the listening socket,
5144      so to make the start_timer below work we have to move
5145      it to close s_listen while we are blocked on accept. */
5146   win_kludge_socket2 = s_listen;
5147 #endif
5148 
5149   /* what sort of sizes did we end-up with? */
5150   if (tcp_stream_request->receive_size == 0) {
5151     if (lsr_size > 0) {
5152       recv_size = lsr_size;
5153     }
5154     else {
5155       recv_size = 4096;
5156     }
5157   }
5158   else {
5159     recv_size = tcp_stream_request->receive_size;
5160   }
5161 
5162   /* we want to set-up our recv_ring in a manner analagous to what we */
5163   /* do on the sending side. this is more for the sake of symmetry */
5164   /* than for the needs of say copy avoidance, but it might also be */
5165   /* more realistic - this way one could conceivably go with a */
5166   /* double-buffering scheme when taking the data an putting it into */
5167   /* the filesystem or something like that. raj 7/94 */
5168 
5169   if (recv_width == 0) {
5170     recv_width = (lsr_size/recv_size) + 1;
5171     if (recv_width == 1) recv_width++;
5172   }
5173 
5174   recv_ring = allocate_buffer_ring(recv_width,
5175 				   recv_size,
5176 				   tcp_stream_request->recv_alignment,
5177 				   tcp_stream_request->recv_offset);
5178 
5179   if (debug) {
5180     fprintf(where,"recv_tcp_stream: receive alignment and offset set...\n");
5181     fflush(where);
5182   }
5183 
5184   /* Now, let's set-up the socket to listen for connections */
5185   if (listen(s_listen, 5) == SOCKET_ERROR) {
5186     netperf_response.content.serv_errno = errno;
5187     close(s_listen);
5188     send_response();
5189 
5190     exit(1);
5191   }
5192 
5193 
5194   /* now get the port number assigned by the system  */
5195   addrlen = sizeof(myaddr_in);
5196   if (getsockname(s_listen,
5197 		  (struct sockaddr *)&myaddr_in,
5198 		  &addrlen) == SOCKET_ERROR){
5199     netperf_response.content.serv_errno = errno;
5200     close(s_listen);
5201     send_response();
5202 
5203     exit(1);
5204   }
5205 
5206   /* Now myaddr_in contains the port and the internet address this is */
5207   /* returned to the sender also implicitly telling the sender that the */
5208   /* socket buffer sizing has been done. */
5209 
5210   tcp_stream_response->data_port_number =
5211     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
5212   netperf_response.content.serv_errno   = 0;
5213 
5214   /* But wait, there's more. If the initiator wanted cpu measurements, */
5215   /* then we must call the calibrate routine, which will return the max */
5216   /* rate back to the initiator. If the CPU was not to be measured, or */
5217   /* something went wrong with the calibration, we will return a -1 to */
5218   /* the initiator. */
5219 
5220   tcp_stream_response->cpu_rate = (float)0.0; 	/* assume no cpu */
5221   if (tcp_stream_request->measure_cpu) {
5222     tcp_stream_response->measure_cpu = 1;
5223     tcp_stream_response->cpu_rate =
5224       calibrate_local_cpu(tcp_stream_request->cpu_rate);
5225   }
5226   else {
5227     tcp_stream_response->measure_cpu = 0;
5228   }
5229 
5230   /* before we send the response back to the initiator, pull some of */
5231   /* the socket parms from the globals */
5232   tcp_stream_response->send_buf_size = lss_size;
5233   tcp_stream_response->recv_buf_size = lsr_size;
5234   tcp_stream_response->no_delay = loc_nodelay;
5235   tcp_stream_response->so_rcvavoid = loc_rcvavoid;
5236   tcp_stream_response->so_sndavoid = loc_sndavoid;
5237   tcp_stream_response->receive_size = recv_size;
5238 
5239   send_response();
5240 
5241   addrlen = sizeof(peeraddr_in);
5242 
5243   if ((s_data=accept(s_listen,
5244 		     (struct sockaddr *)&peeraddr_in,
5245 		     &addrlen)) == INVALID_SOCKET) {
5246     /* Let's just punt. The remote will be given some information */
5247     close(s_listen);
5248     exit(1);
5249   }
5250 
5251 #ifdef WIN32
5252   /* this is used so the timer thread can close the socket out from */
5253   /* under us, which to date is the easiest/cleanest/least */
5254   /* Windows-specific way I can find to force the winsock calls to */
5255   /* return WSAEINTR with the test is over. anything that will run on */
5256   /* 95 and NT and is closer to what netperf expects from Unix signals */
5257   /* and such would be appreciated raj 1/96 */
5258   win_kludge_socket = s_data;
5259   win_kludge_socket2 = INVALID_SOCKET;
5260 #endif /* WIN32 */
5261 
5262   times_up = 0;
5263 
5264   start_timer(tcp_stream_request->test_length + PAD_TIME);
5265 
5266 #ifdef KLUDGE_SOCKET_OPTIONS
5267   /* this is for those systems which *INCORRECTLY* fail to pass */
5268   /* attributes across an accept() call. Including this goes against */
5269   /* my better judgement :( raj 11/95 */
5270 
5271   kludge_socket_options(s_data);
5272 
5273 #endif /* KLUDGE_SOCKET_OPTIONS */
5274 
5275   /* Now it's time to start receiving data on the connection. We will */
5276   /* first grab the apropriate counters and then start grabbing. */
5277 
5278   cpu_start(tcp_stream_request->measure_cpu);
5279 
5280   /* The loop will exit when the sender does a shutdown, which will */
5281   /* return a length of zero   */
5282 
5283   /* there used to be an #ifdef DIRTY call to access_buffer() here,
5284      but we have switched from accessing the buffer before the recv()
5285      call to accessing the buffer after the recv() call.  The
5286      accessing before was, IIRC, related to having dirty data when
5287      doing page-flipping copy avoidance. */
5288 
5289   bytes_received = 0;
5290   receive_calls  = 0;
5291 
5292 #if HAVE_AIO
5293   if (loc_rcvaio > 0) {
5294     struct aiocb *iocb;
5295     unsigned int i;
5296 
5297     for (i = 0; i < recv_width; i++) {
5298       assert(recv_ring->completion_ptr == NULL);
5299       iocb = calloc(1, sizeof(*iocb));
5300       iocb->aio_nbytes = recv_size;
5301       iocb->aio_fildes = s_data;
5302       iocb->aio_buf = recv_ring->buffer_ptr;
5303       recv_ring->completion_ptr = iocb;
5304       recv_ring = recv_ring->next;
5305       if (aio_read(iocb) != 0) {
5306         netperf_response.content.serv_errno = errno;
5307         send_response();
5308         exit(1);
5309       }
5310     }
5311     assert(recv_ring->completion_ptr != NULL);
5312   }
5313 #endif
5314 
5315   while (!times_up) {
5316 #if HAVE_AIO
5317     if (loc_rcvaio > 0) {
5318       const struct aiocb *iocblist[1];
5319       struct aiocb *iocb;
5320       int error;
5321 
5322       /*
5323        * POSIX doesn't define which order jobs of the same priority
5324        * are completed in on all systems.  This hopes for FIFO.
5325        */
5326       iocb = recv_ring->completion_ptr;
5327       iocblist[0] = iocb;
5328       if (aio_suspend(iocblist, 1, NULL) == -1) {
5329         len = SOCKET_ERROR;
5330       } else {
5331         error = aio_error(iocb);
5332         if (error == 0) {
5333           len = aio_return(iocb);
5334         } else {
5335           errno = error;
5336           len = SOCKET_ERROR;
5337         }
5338       }
5339     } else
5340 #endif
5341     {
5342       len = recv(s_data, recv_ring->buffer_ptr, recv_size, 0);
5343     }
5344     if (len == 0)
5345       break;
5346     if (len == SOCKET_ERROR ) {
5347       if (times_up) {
5348 	break;
5349       }
5350       netperf_response.content.serv_errno = errno;
5351       send_response();
5352       exit(1);
5353     }
5354     bytes_received += len;
5355     receive_calls++;
5356 
5357 #ifdef DIRTY
5358     /* we access the buffer after the recv() call now, rather than before */
5359     access_buffer(recv_ring->buffer_ptr,
5360 		  recv_size,
5361 		  tcp_stream_request->dirty_count,
5362 		  tcp_stream_request->clean_count);
5363 #endif /* DIRTY */
5364 
5365 #if HAVE_AIO
5366     if (loc_rcvaio > 0) {
5367       struct aiocb *iocb;
5368 
5369       iocb = recv_ring->completion_ptr;
5370       memset(iocb, 0, sizeof(*iocb));
5371       iocb->aio_nbytes = recv_size;
5372       iocb->aio_fildes = s_data;
5373       iocb->aio_buf = recv_ring->buffer_ptr;
5374       if (aio_read(iocb) != 0) {
5375         netperf_response.content.serv_errno = errno;
5376         send_response();
5377         exit(1);
5378       }
5379     }
5380 #endif
5381 
5382     /* move to the next buffer in the recv_ring */
5383     recv_ring = recv_ring->next;
5384 
5385 #ifdef PAUSE
5386     sleep(1);
5387 #endif /* PAUSE */
5388 
5389 #ifdef DO_SELECT
5390 	FD_SET(s_data,&readfds);
5391 	select(s_data+1,&readfds,NULL,NULL,&timeout);
5392 #endif /* DO_SELECT */
5393 
5394   }
5395 
5396   /* perform a shutdown to signal the sender that */
5397   /* we have received all the data sent. raj 4/93 */
5398 
5399   if (shutdown(s_data,SHUT_WR) == SOCKET_ERROR && !times_up) {
5400       netperf_response.content.serv_errno = errno;
5401       send_response();
5402       exit(1);
5403     }
5404 
5405   cpu_stop(tcp_stream_request->measure_cpu,&elapsed_time);
5406 
5407   /* send the results to the sender			*/
5408 
5409   if (debug) {
5410     fprintf(where,
5411 	    "recv_tcp_stream: got %g bytes\n",
5412 	    bytes_received);
5413     fprintf(where,
5414 	    "recv_tcp_stream: got %d recvs\n",
5415 	    receive_calls);
5416     fflush(where);
5417   }
5418 
5419   tcp_stream_results->bytes_received	= htond(bytes_received);
5420   tcp_stream_results->elapsed_time	= elapsed_time;
5421   tcp_stream_results->recv_calls	= receive_calls;
5422 
5423   tcp_stream_results->cpu_method = cpu_method;
5424   tcp_stream_results->num_cpus   = lib_num_loc_cpus;
5425 
5426   if (tcp_stream_request->measure_cpu) {
5427     tcp_stream_results->cpu_util	= calc_cpu_util(0.0);
5428   };
5429 
5430   if (debug) {
5431     fprintf(where,
5432 	    "recv_tcp_stream: test complete, sending results.\n");
5433     fprintf(where,
5434 	    "                 bytes_received %g receive_calls %d\n",
5435 	    bytes_received,
5436 	    receive_calls);
5437     fprintf(where,
5438 	    "                 len %d\n",
5439 	    len);
5440     fflush(where);
5441   }
5442 
5443   send_response();
5444 
5445   /* we are now done with the sockets */
5446   close(s_data);
5447   close(s_listen);
5448 
5449   }
5450 
5451 /* This is the server-side routine for the tcp maerts test. It is
5452    implemented as one routine. I could break things-out somewhat, but
5453    didn't feel it was necessary. */
5454 
5455 void
recv_tcp_maerts()5456 recv_tcp_maerts()
5457 {
5458 
5459   struct sockaddr_storage myaddr_in, peeraddr_in;
5460   struct addrinfo *local_res;
5461   char  local_name[BUFSIZ];
5462   char  port_buffer[PORTBUFSIZE];
5463 
5464   SOCKET	s_listen,s_data;
5465   netperf_socklen_t 	addrlen;
5466   int	len;
5467   unsigned int	send_calls;
5468   float	elapsed_time;
5469   double   bytes_sent = 0.0 ;
5470 
5471   struct ring_elt *send_ring;
5472 
5473   struct	tcp_maerts_request_struct	*tcp_maerts_request;
5474   struct	tcp_maerts_response_struct	*tcp_maerts_response;
5475   struct	tcp_maerts_results_struct	*tcp_maerts_results;
5476 
5477   tcp_maerts_request	=
5478     (struct tcp_maerts_request_struct *)netperf_request.content.test_specific_data;
5479   tcp_maerts_response	=
5480     (struct tcp_maerts_response_struct *)netperf_response.content.test_specific_data;
5481   tcp_maerts_results	=
5482     (struct tcp_maerts_results_struct *)netperf_response.content.test_specific_data;
5483 
5484   if (debug) {
5485     fprintf(where,"netserver: recv_tcp_maerts: entered...\n");
5486     fflush(where);
5487   }
5488 
5489   /* We want to set-up the listen socket with all the desired
5490      parameters and then let the initiator know that all is ready. If
5491      socket size defaults are to be used, then the initiator will have
5492      sent us 0's. If the socket sizes cannot be changed, then we will
5493      send-back what they are. If that information cannot be
5494      determined, then we send-back -1's for the sizes. If things go
5495      wrong for any reason, we will drop back ten yards and punt. */
5496 
5497   /* If anything goes wrong, we want the remote to know about it. It
5498      would be best if the error that the remote reports to the user is
5499      the actual error we encountered, rather than some bogus
5500      unexpected response type message. */
5501 
5502   if (debug) {
5503     fprintf(where,"recv_tcp_maerts: setting the response type...\n");
5504     fflush(where);
5505   }
5506 
5507   netperf_response.content.response_type = TCP_MAERTS_RESPONSE;
5508 
5509   if (debug) {
5510     fprintf(where,"recv_tcp_maerts: the response type is set...\n");
5511     fflush(where);
5512   }
5513 
5514   /* We now alter the message_ptr variable to be at the desired */
5515   /* alignment with the desired offset. */
5516 
5517   if (debug) {
5518     fprintf(where,"recv_tcp_maerts: requested alignment of %d\n",
5519 	    tcp_maerts_request->send_alignment);
5520     fflush(where);
5521   }
5522 
5523   /* Grab a socket to listen on, and then listen on it. */
5524 
5525   if (debug) {
5526     fprintf(where,"recv_tcp_maerts: grabbing a socket...\n");
5527     fflush(where);
5528   }
5529 
5530   /* create_data_socket expects to find some things in the global */
5531   /* variables, so set the globals based on the values in the request. */
5532   /* once the socket has been created, we will set the response values */
5533   /* based on the updated value of those globals. raj 7/94 */
5534   lss_size_req = tcp_maerts_request->send_buf_size;
5535   lsr_size_req = tcp_maerts_request->recv_buf_size;
5536   loc_nodelay = tcp_maerts_request->no_delay;
5537   loc_rcvavoid = tcp_maerts_request->so_rcvavoid;
5538   loc_sndavoid = tcp_maerts_request->so_sndavoid;
5539 
5540   set_hostname_and_port(local_name,
5541 			port_buffer,
5542 			nf_to_af(tcp_maerts_request->ipfamily),
5543 			tcp_maerts_request->port);
5544 
5545   local_res = complete_addrinfo(local_name,
5546 				local_name,
5547 				port_buffer,
5548 				nf_to_af(tcp_maerts_request->ipfamily),
5549 				SOCK_STREAM,
5550 				IPPROTO_TCP,
5551 				0);
5552 
5553   s_listen = create_data_socket(local_res);
5554 
5555   if (s_listen == INVALID_SOCKET) {
5556     netperf_response.content.serv_errno = errno;
5557     send_response();
5558     exit(1);
5559   }
5560 
5561 #ifdef WIN32
5562   /* The test timer can fire during operations on the listening socket,
5563      so to make the start_timer below work we have to move
5564      it to close s_listen while we are blocked on accept. */
5565   win_kludge_socket2 = s_listen;
5566 #endif
5567 
5568 
5569   /* what sort of sizes did we end-up with? */
5570   if (tcp_maerts_request->send_size == 0) {
5571     if (lss_size > 0) {
5572       send_size = lss_size;
5573     }
5574     else {
5575       send_size = 4096;
5576     }
5577   }
5578   else {
5579     send_size = tcp_maerts_request->send_size;
5580   }
5581 
5582   /* we want to set-up our recv_ring in a manner analagous to what we */
5583   /* do on the recving side. this is more for the sake of symmetry */
5584   /* than for the needs of say copy avoidance, but it might also be */
5585   /* more realistic - this way one could conceivably go with a */
5586   /* double-buffering scheme when taking the data an putting it into */
5587   /* the filesystem or something like that. raj 7/94 */
5588 
5589   if (send_width == 0) {
5590     send_width = (lsr_size/send_size) + 1;
5591     if (send_width == 1) send_width++;
5592   }
5593 
5594   send_ring = allocate_buffer_ring(send_width,
5595 				   send_size,
5596 				   tcp_maerts_request->send_alignment,
5597 				   tcp_maerts_request->send_offset);
5598 
5599   if (debug) {
5600     fprintf(where,"recv_tcp_maerts: receive alignment and offset set...\n");
5601     fflush(where);
5602   }
5603 
5604   /* Now, let's set-up the socket to listen for connections */
5605   if (listen(s_listen, 5) == SOCKET_ERROR) {
5606     netperf_response.content.serv_errno = errno;
5607     close(s_listen);
5608     send_response();
5609 
5610     exit(1);
5611   }
5612 
5613 
5614   /* now get the port number assigned by the system  */
5615   addrlen = sizeof(myaddr_in);
5616   if (getsockname(s_listen,
5617 		  (struct sockaddr *)&myaddr_in,
5618 		  &addrlen) == SOCKET_ERROR){
5619     netperf_response.content.serv_errno = errno;
5620     close(s_listen);
5621     send_response();
5622 
5623     exit(1);
5624   }
5625 
5626   /* Now myaddr_in contains the port and the internet address this is */
5627   /* returned to the sender also implicitly telling the sender that the */
5628   /* socket buffer sizing has been done. */
5629 
5630   tcp_maerts_response->data_port_number =
5631     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
5632   netperf_response.content.serv_errno   = 0;
5633 
5634   /* But wait, there's more. If the initiator wanted cpu measurements, */
5635   /* then we must call the calibrate routine, which will return the max */
5636   /* rate back to the initiator. If the CPU was not to be measured, or */
5637   /* something went wrong with the calibration, we will return a -1 to */
5638   /* the initiator. */
5639 
5640   tcp_maerts_response->cpu_rate = (float)0.0; 	/* assume no cpu */
5641   if (tcp_maerts_request->measure_cpu) {
5642     tcp_maerts_response->measure_cpu = 1;
5643     tcp_maerts_response->cpu_rate =
5644       calibrate_local_cpu(tcp_maerts_request->cpu_rate);
5645   }
5646   else {
5647     tcp_maerts_response->measure_cpu = 0;
5648   }
5649 
5650   /* before we send the response back to the initiator, pull some of */
5651   /* the socket parms from the globals */
5652   tcp_maerts_response->send_buf_size = lss_size;
5653   tcp_maerts_response->recv_buf_size = lsr_size;
5654   tcp_maerts_response->no_delay = loc_nodelay;
5655   tcp_maerts_response->so_rcvavoid = loc_rcvavoid;
5656   tcp_maerts_response->so_sndavoid = loc_sndavoid;
5657   tcp_maerts_response->send_size = send_size;
5658 
5659   send_response();
5660 
5661   addrlen = sizeof(peeraddr_in);
5662 
5663   /* we will start the timer before the accept() to be somewhat
5664      analagous to the starting of the timer before the connect() call
5665      in the TCP_STREAM test. raj 2002-06-21 */
5666 
5667   start_timer(tcp_maerts_request->test_length);
5668 
5669   /* Now it's time to start receiving data on the connection. We will
5670      first grab the apropriate counters and then start grabbing. */
5671 
5672   cpu_start(tcp_maerts_request->measure_cpu);
5673 
5674 
5675   if ((s_data=accept(s_listen,
5676 		     (struct sockaddr *)&peeraddr_in,
5677 		     &addrlen)) == INVALID_SOCKET) {
5678     /* Let's just punt. The remote will be given some information */
5679     close(s_listen);
5680     exit(1);
5681   }
5682 
5683 #ifdef WIN32
5684   /* this is used so the timer thread can close the socket out from */
5685   /* under us, which to date is the easiest/cleanest/least */
5686   /* Windows-specific way I can find to force the winsock calls to */
5687   /* return WSAEINTR with the test is over. anything that will run on */
5688   /* 95 and NT and is closer to what netperf expects from Unix signals */
5689   /* and such would be appreciated raj 1/96 */
5690   win_kludge_socket = s_data;
5691   win_kludge_socket2 = INVALID_SOCKET;
5692 #endif /* WIN32 */
5693 
5694 #ifdef KLUDGE_SOCKET_OPTIONS
5695 
5696   /* this is for those systems which *INCORRECTLY* fail to pass
5697      attributes across an accept() call. Including this goes against
5698      my better judgement :( raj 11/95 */
5699 
5700   kludge_socket_options(s_data);
5701 
5702 #endif /* KLUDGE_SOCKET_OPTIONS */
5703 
5704   /* The loop will exit when the sender does a shutdown, which will */
5705   /* return a length of zero   */
5706 
5707   bytes_sent = 0.0;
5708   send_calls  = 0;
5709 
5710   len = 0;   /* nt-lint; len is not initialized (printf far below) if
5711 		times_up initially true.*/
5712   times_up = 0; /* must remember to initialize this little beauty */
5713   while (!times_up) {
5714 
5715 #ifdef DIRTY
5716     /* we want to dirty some number of consecutive integers in the buffer */
5717     /* we are about to send. we may also want to bring some number of */
5718     /* them cleanly into the cache. The clean ones will follow any dirty */
5719     /* ones into the cache. */
5720 
5721   access_buffer(send_ring->buffer_ptr,
5722 		send_size,
5723 		tcp_maerts_request->dirty_count,
5724 		tcp_maerts_request->clean_count);
5725 
5726 #endif /* DIRTY */
5727 
5728     if((len=send(s_data,
5729 		 send_ring->buffer_ptr,
5730 		 send_size,
5731 		 0)) != send_size) {
5732 		if ((len >=0) || SOCKET_EINTR(len)) {
5733 	      /* the test was interrupted, must be the end of test */
5734 	      break;
5735 		}
5736       netperf_response.content.serv_errno = errno;
5737       send_response();
5738       exit(1);
5739     }
5740 
5741     bytes_sent += len;
5742     send_calls++;
5743 
5744     /* more to the next buffer in the send_ring */
5745     send_ring = send_ring->next;
5746 
5747   }
5748 
5749   /* perform a shutdown to signal the sender that */
5750   /* we have received all the data sent. raj 4/93 */
5751 
5752   if (shutdown(s_data,SHUT_WR) == SOCKET_ERROR) {
5753       netperf_response.content.serv_errno = errno;
5754       send_response();
5755       exit(1);
5756     }
5757 
5758   /* hang a recv() off the socket to block until the remote has
5759      brought all the data up into the application. it will do a
5760      shutdown to cause a FIN to be sent our way. We will assume that
5761      any exit from the recv() call is good... raj 4/93 */
5762 
5763   recv(s_data, send_ring->buffer_ptr, send_size, 0);
5764 
5765 
5766   cpu_stop(tcp_maerts_request->measure_cpu,&elapsed_time);
5767 
5768   /* send the results to the sender			*/
5769 
5770   if (debug) {
5771     fprintf(where,
5772 	    "recv_tcp_maerts: got %g bytes\n",
5773 	    bytes_sent);
5774     fprintf(where,
5775 	    "recv_tcp_maerts: got %d sends\n",
5776 	    send_calls);
5777     fflush(where);
5778   }
5779 
5780   tcp_maerts_results->bytes_sent	= htond(bytes_sent);
5781   tcp_maerts_results->elapsed_time	= elapsed_time;
5782   tcp_maerts_results->send_calls	= send_calls;
5783 
5784   if (tcp_maerts_request->measure_cpu) {
5785     tcp_maerts_results->cpu_util	= calc_cpu_util(0.0);
5786   };
5787 
5788   if (debug) {
5789     fprintf(where,
5790 	    "recv_tcp_maerts: test complete, sending results.\n");
5791     fprintf(where,
5792 	    "                 bytes_sent %g send_calls %d\n",
5793 	    bytes_sent,
5794 	    send_calls);
5795     fprintf(where,
5796 	    "                 len %d\n",
5797 	    len);
5798     fflush(where);
5799   }
5800 
5801   tcp_maerts_results->cpu_method = cpu_method;
5802   tcp_maerts_results->num_cpus   = lib_num_loc_cpus;
5803   send_response();
5804 
5805   /* we are now done with the sockets */
5806   close(s_data);
5807   close(s_listen);
5808 
5809   }
5810 
5811 
5812  /* this routine implements the sending (netperf) side of the TCP_RR */
5813  /* test. */
5814 #ifndef WANT_MIGRATION
5815 void
send_tcp_rr(char remote_host[])5816 send_tcp_rr(char remote_host[])
5817 {
5818 
5819   char *tput_title = "\
5820 Local /Remote\n\
5821 Socket Size   Request  Resp.   Elapsed  Trans.\n\
5822 Send   Recv   Size     Size    Time     Rate         \n\
5823 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
5824 
5825   char *tput_title_band = "\
5826 Local /Remote\n\
5827 Socket Size   Request  Resp.   Elapsed  \n\
5828 Send   Recv   Size     Size    Time     Throughput \n\
5829 bytes  Bytes  bytes    bytes   secs.    %s/sec   \n\n";
5830 
5831   char *tput_fmt_0 =
5832     "%7.2f %s\n";
5833 
5834   char *tput_fmt_1_line_1 = "\
5835 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   %s\n";
5836   char *tput_fmt_1_line_2 = "\
5837 %-6d %-6d\n";
5838 
5839   char *cpu_title = "\
5840 Local /Remote\n\
5841 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
5842 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
5843 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
5844 
5845   char *cpu_title_tput = "\
5846 Local /Remote\n\
5847 Socket Size   Request Resp.  Elapsed Tput     CPU    CPU    S.dem   S.dem\n\
5848 Send   Recv   Size    Size   Time    %-8.8s local  remote local   remote\n\
5849 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
5850 
5851   char *cpu_title_latency = "\
5852 Local /Remote\n\
5853 Socket Size   Request Resp.  Elapsed Latency  CPU    CPU    S.dem   S.dem\n\
5854 Send   Recv   Size    Size   Time    usecs    local  remote local   remote\n\
5855 bytes  bytes  bytes   bytes  secs.   per tran %% %c    %% %c    us/Tr   us/Tr\n\n";
5856 
5857   char *cpu_fmt_0 =
5858     "%6.3f %c %s\n";
5859 
5860   char *cpu_fmt_1_line_1 = "\
5861 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f  %-6.2f %-6.2f %-6.3f  %-6.3f %s\n";
5862 
5863   char *cpu_fmt_1_line_2 = "\
5864 %-6d %-6d\n";
5865 
5866   char *ksink_fmt = "\
5867 Alignment      Offset         RoundTrip  Trans    Throughput\n\
5868 Local  Remote  Local  Remote  Latency    Rate     %-8.8s/s\n\
5869 Send   Recv    Send   Recv    usec/Tran  per sec  Outbound   Inbound\n\
5870 %5d  %5d   %5d  %5d   %-6.3f   %-6.3f %-6.3f    %-6.3f\n";
5871 
5872 
5873   int			timed_out = 0;
5874   float			elapsed_time;
5875 
5876   int	len;
5877   char	*temp_message_ptr;
5878   int	nummessages;
5879   SOCKET	send_socket;
5880   int	trans_remaining;
5881   double	bytes_xferd;
5882 
5883   struct ring_elt *send_ring;
5884   struct ring_elt *recv_ring;
5885 
5886   int	rsp_bytes_left;
5887   int	rsp_bytes_recvd;
5888 
5889   float	local_cpu_utilization;
5890   float	local_service_demand;
5891   float	remote_cpu_utilization;
5892   float	remote_service_demand;
5893   double	thruput;
5894 
5895   struct addrinfo *local_res;
5896   struct addrinfo *remote_res;
5897 
5898   struct	tcp_rr_request_struct	*tcp_rr_request;
5899   struct	tcp_rr_response_struct	*tcp_rr_response;
5900   struct	tcp_rr_results_struct	*tcp_rr_result;
5901 
5902 #ifdef WANT_FIRST_BURST
5903 #define REQUEST_CWND_INITIAL 2
5904   /* "in the beginning..." the WANT_FIRST_BURST stuff was like both
5905      Unix and the state of New Jersey - both were simple an unspoiled.
5906      then it was realized that some stacks are quite picky about
5907      initial congestion windows and a non-trivial initial burst of
5908      requests would not be individual segments even with TCP_NODELAY
5909      set. so, we have to start tracking a poor-man's congestion window
5910      up here in window space because we want to try to make something
5911      happen that frankly, we cannot guarantee with the specification
5912      of TCP.  ain't that grand?-)  raj 2006-01-30 */
5913   int requests_outstanding = 0;
5914   int request_cwnd = REQUEST_CWND_INITIAL;  /* we ass-u-me that having
5915 					       three requests
5916 					       outstanding at the
5917 					       beginning of the test
5918 					       is ok with TCP stacks
5919 					       of interest. the first
5920 					       two will come from our
5921 					       first_burst loop, and
5922 					       the third from our
5923 					       regularly scheduled
5924 					       send */
5925 #endif
5926 
5927   tcp_rr_request =
5928     (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data;
5929   tcp_rr_response=
5930     (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data;
5931   tcp_rr_result	=
5932     (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data;
5933 
5934 #ifdef WANT_HISTOGRAM
5935   if (verbosity > 1) {
5936     time_hist = HIST_new();
5937   }
5938 #endif /* WANT_HISTOGRAM */
5939 
5940   /* since we are now disconnected from the code that established the */
5941   /* control socket, and since we want to be able to use different */
5942   /* protocols and such, we are passed the name of the remote host and */
5943   /* must turn that into the test specific addressing information. */
5944 
5945   complete_addrinfos(&remote_res,
5946 		     &local_res,
5947 		     remote_host,
5948 		     SOCK_STREAM,
5949 		     IPPROTO_TCP,
5950 		     0);
5951 
5952   if ( print_headers ) {
5953     print_top_test_header("TCP REQUEST/RESPONSE TEST",local_res,remote_res);
5954   }
5955 
5956   /* initialize a few counters */
5957 
5958   send_ring = NULL;
5959   recv_ring = NULL;
5960   confidence_iteration = 1;
5961   init_stat();
5962 
5963   /* we have a great-big while loop which controls the number of times */
5964   /* we run a particular test. this is for the calculation of a */
5965   /* confidence interval (I really should have stayed awake during */
5966   /* probstats :). If the user did not request confidence measurement */
5967   /* (no confidence is the default) then we will only go though the */
5968   /* loop once. the confidence stuff originates from the folks at IBM */
5969 
5970   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
5971 	 (confidence_iteration <= iteration_min)) {
5972 
5973     /* initialize a few counters. we have to remember that we might be */
5974     /* going through the loop more than once. */
5975 
5976     nummessages     = 0;
5977     bytes_xferd     = 0.0;
5978     times_up        = 0;
5979     timed_out       = 0;
5980     trans_remaining = 0;
5981 
5982 #ifdef WANT_FIRST_BURST
5983     /* we have to remember to reset the number of transactions
5984        outstanding and the "congestion window for each new
5985        iteration. raj 2006-01-31 */
5986     requests_outstanding = 0;
5987     request_cwnd = REQUEST_CWND_INITIAL;
5988 #endif
5989 
5990 
5991     /* set-up the data buffers with the requested alignment and offset. */
5992     /* since this is a request/response test, default the send_width and */
5993     /* recv_width to 1 and not two raj 7/94 */
5994 
5995     if (send_width == 0) send_width = 1;
5996     if (recv_width == 0) recv_width = 1;
5997 
5998     if (send_ring == NULL) {
5999       send_ring = allocate_buffer_ring(send_width,
6000 				       req_size,
6001 				       local_send_align,
6002 				       local_send_offset);
6003     }
6004 
6005     if (recv_ring == NULL) {
6006       recv_ring = allocate_buffer_ring(recv_width,
6007 				       rsp_size,
6008 				       local_recv_align,
6009 				       local_recv_offset);
6010     }
6011 
6012     /*set up the data socket                        */
6013     send_socket = create_data_socket(local_res);
6014 
6015     if (send_socket == INVALID_SOCKET){
6016       perror("netperf: send_tcp_rr: tcp stream data socket");
6017       exit(1);
6018     }
6019 
6020     if (debug) {
6021       fprintf(where,"send_tcp_rr: send_socket obtained...\n");
6022     }
6023 
6024     /* If the user has requested cpu utilization measurements, we must */
6025     /* calibrate the cpu(s). We will perform this task within the tests */
6026     /* themselves. If the user has specified the cpu rate, then */
6027     /* calibrate_local_cpu will return rather quickly as it will have */
6028     /* nothing to do. If local_cpu_rate is zero, then we will go through */
6029     /* all the "normal" calibration stuff and return the rate back.*/
6030 
6031     if (local_cpu_usage) {
6032       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
6033     }
6034 
6035     if (!no_control) {
6036       /* Tell the remote end to do a listen. The server alters the
6037 	 socket paramters on the other side at this point, hence the
6038 	 reason for all the values being passed in the setup
6039 	 message. If the user did not specify any of the parameters,
6040 	 they will be passed as 0, which will indicate to the remote
6041 	 that no changes beyond the system's default should be
6042 	 used. Alignment is the exception, it will default to 8, which
6043 	 will be no alignment alterations. */
6044 
6045       netperf_request.content.request_type	=	DO_TCP_RR;
6046       tcp_rr_request->recv_buf_size	=	rsr_size_req;
6047       tcp_rr_request->send_buf_size	=	rss_size_req;
6048       tcp_rr_request->recv_alignment    =	remote_recv_align;
6049       tcp_rr_request->recv_offset	=	remote_recv_offset;
6050       tcp_rr_request->send_alignment    =	remote_send_align;
6051       tcp_rr_request->send_offset	=	remote_send_offset;
6052       tcp_rr_request->request_size	=	req_size;
6053       tcp_rr_request->response_size	=	rsp_size;
6054       tcp_rr_request->no_delay	        =	rem_nodelay;
6055       tcp_rr_request->measure_cpu	=	remote_cpu_usage;
6056       tcp_rr_request->cpu_rate	        =	remote_cpu_rate;
6057       tcp_rr_request->so_rcvavoid	=	rem_rcvavoid;
6058       tcp_rr_request->so_sndavoid	=	rem_sndavoid;
6059       if (test_time) {
6060 	tcp_rr_request->test_length	=	test_time;
6061       }
6062       else {
6063 	tcp_rr_request->test_length	=	test_trans * -1;
6064       }
6065       tcp_rr_request->port              =      atoi(remote_data_port);
6066       tcp_rr_request->ipfamily = af_to_nf(remote_res->ai_family);
6067 
6068       if (debug > 1) {
6069 	fprintf(where,"netperf: send_tcp_rr: requesting TCP rr test\n");
6070       }
6071 
6072       send_request();
6073 
6074       /* The response from the remote will contain all of the relevant
6075 	 socket parameters for this test type. We will put them back
6076 	 into the variables here so they can be displayed if desired.
6077 	 The remote will have calibrated CPU if necessary, and will
6078 	 have done all the needed set-up we will have calibrated the
6079 	 cpu locally before sending the request, and will grab the
6080 	 counter value right after the connect returns. The remote
6081 	 will grab the counter right after the accept call. This saves
6082 	 the hassle of extra messages being sent for the TCP
6083 	 tests.  */
6084 
6085       recv_response();
6086 
6087       if (!netperf_response.content.serv_errno) {
6088 	if (debug)
6089 	  fprintf(where,"remote listen done.\n");
6090 	rsr_size          = tcp_rr_response->recv_buf_size;
6091 	rss_size          = tcp_rr_response->send_buf_size;
6092 	rem_nodelay       = tcp_rr_response->no_delay;
6093 	remote_cpu_usage  = tcp_rr_response->measure_cpu;
6094 	remote_cpu_rate   = tcp_rr_response->cpu_rate;
6095 	/* make sure that port numbers are in network order */
6096 	set_port_number(remote_res,(short)tcp_rr_response->data_port_number);
6097       }
6098       else {
6099 	Set_errno(netperf_response.content.serv_errno);
6100 	fprintf(where,
6101 		"netperf: remote error %d",
6102 		netperf_response.content.serv_errno);
6103 	perror("");
6104 	fflush(where);
6105 
6106 	exit(1);
6107       }
6108     }
6109 
6110 #ifdef WANT_DEMO
6111     demo_rr_setup(1000);
6112 #endif
6113 
6114     /*Connect up to the remote port on the data socket  */
6115     if (connect(send_socket,
6116 		remote_res->ai_addr,
6117 		remote_res->ai_addrlen) == INVALID_SOCKET){
6118       perror("netperf: data socket connect failed");
6119 
6120       exit(1);
6121     }
6122 
6123 #ifdef WIN32
6124     /* this is used so the timer thread can close the socket out from */
6125     /* under us, which to date is the easiest/cleanest/least */
6126     /* Windows-specific way I can find to force the winsock calls to */
6127     /* return WSAEINTR with the test is over. anything that will run on */
6128     /* 95 and NT and is closer to what netperf expects from Unix signals */
6129     /* and such would be appreciated raj 1/96 */
6130     win_kludge_socket = send_socket;
6131 #endif /* WIN32 */
6132 
6133     /* Data Socket set-up is finished. If there were problems, either the */
6134     /* connect would have failed, or the previous response would have */
6135     /* indicated a problem. I failed to see the value of the extra */
6136     /* message after the accept on the remote. If it failed, we'll see it */
6137     /* here. If it didn't, we might as well start pumping data. */
6138 
6139     /* Set-up the test end conditions. For a request/response test, they */
6140     /* can be either time or transaction based. */
6141 
6142     if (test_time) {
6143       /* The user wanted to end the test after a period of time. */
6144       times_up = 0;
6145       trans_remaining = 0;
6146       start_timer(test_time);
6147     }
6148     else {
6149       /* The tester wanted to send a number of bytes. */
6150       trans_remaining = test_bytes;
6151       times_up = 1;
6152     }
6153 
6154     /* The cpu_start routine will grab the current time and possibly */
6155     /* value of the idle counter for later use in measuring cpu */
6156     /* utilization and/or service demand and thruput. */
6157 
6158     cpu_start(local_cpu_usage);
6159 
6160 #ifdef WANT_INTERVALS
6161     INTERVALS_INIT();
6162 #endif /* WANT_INTERVALS */
6163 
6164     /* We use an "OR" to control test execution. When the test is */
6165     /* controlled by time, the byte count check will always return false. */
6166     /* When the test is controlled by byte count, the time test will */
6167     /* always return false. When the test is finished, the whole */
6168     /* expression will go false and we will stop sending data. I think I */
6169     /* just arbitrarily decrement trans_remaining for the timed test, but */
6170     /* will not do that just yet... One other question is whether or not */
6171     /* the send buffer and the receive buffer should be the same buffer. */
6172 
6173 #ifdef WANT_DEMO
6174       if (demo_mode) {
6175 	demo_first_timestamp();
6176       }
6177 #endif
6178 
6179     while ((!times_up) || (trans_remaining > 0)) {
6180       /* send the request. we assume that if we use a blocking socket, */
6181       /* the request will be sent at one shot. */
6182 
6183 #ifdef WANT_FIRST_BURST
6184       /* we can inject no more than request_cwnd, which will grow with
6185 	 time, and no more than first_burst_size.  we don't use <= to
6186 	 account for the "regularly scheduled" send call.  of course
6187 	 that makes it more a "max_outstanding_ than a
6188 	 "first_burst_size" but for now we won't fix the names. also,
6189 	 I suspect the extra check against < first_burst_size is
6190 	 redundant since later I expect to make sure that request_cwnd
6191 	 can never get larger than first_burst_size, but just at the
6192 	 moment I'm feeling like a belt and suspenders kind of
6193 	 programmer. raj 2006-01-30 */
6194       while ((first_burst_size > 0) &&
6195 	     (requests_outstanding < request_cwnd) &&
6196 	     (requests_outstanding < first_burst_size)) {
6197 	if (debug) {
6198 	  fprintf(where,
6199 		  "injecting, req_outstndng %d req_cwnd %d burst %d\n",
6200 		  requests_outstanding,
6201 		  request_cwnd,
6202 		  first_burst_size);
6203 	}
6204 	if ((len = send(send_socket,
6205 			send_ring->buffer_ptr,
6206 			req_size,
6207 			0)) != req_size) {
6208 	  /* we should never hit the end of the test in the first burst */
6209 	  perror("send_tcp_rr: initial burst data send error");
6210 	  exit(-1);
6211 	}
6212 	requests_outstanding += 1;
6213       }
6214 
6215 #endif /* WANT_FIRST_BURST */
6216 
6217 #ifdef WANT_HISTOGRAM
6218       if (verbosity > 1) {
6219 	/* timestamp just before our call to send, and then again just
6220 	   after the receive raj 8/94 */
6221 	/* but only if we are actually going to display one. raj
6222 	   2007-02-07 */
6223 
6224 	HIST_timestamp(&time_one);
6225       }
6226 #endif /* WANT_HISTOGRAM */
6227 
6228       if ((len = send(send_socket,
6229 		      send_ring->buffer_ptr,
6230 		      req_size,
6231 		      0)) != req_size) {
6232 	if (SOCKET_EINTR(len) || (errno == 0)) {
6233 	  /* we hit the end of a */
6234 	  /* timed test. */
6235 	  timed_out = 1;
6236 	  break;
6237 	}
6238 	perror("send_tcp_rr: data send error");
6239 	exit(1);
6240       }
6241       send_ring = send_ring->next;
6242 
6243 #ifdef WANT_FIRST_BURST
6244       requests_outstanding += 1;
6245 #endif
6246 
6247       /* receive the response */
6248       rsp_bytes_left = rsp_size;
6249       temp_message_ptr  = recv_ring->buffer_ptr;
6250       while(rsp_bytes_left > 0) {
6251 	if((rsp_bytes_recvd=recv(send_socket,
6252 				 temp_message_ptr,
6253 				 rsp_bytes_left,
6254 				 0)) == SOCKET_ERROR || rsp_bytes_recvd == 0) {
6255 		if ( SOCKET_EINTR(rsp_bytes_recvd) ) {
6256 		    /* We hit the end of a timed test. */
6257 			timed_out = 1;
6258 			break;
6259 		}
6260 	  perror("send_tcp_rr: data recv error");
6261 	  exit(1);
6262 	}
6263 	rsp_bytes_left -= rsp_bytes_recvd;
6264 	temp_message_ptr  += rsp_bytes_recvd;
6265       }
6266       recv_ring = recv_ring->next;
6267 
6268 #ifdef WANT_FIRST_BURST
6269       /* so, since we've gotten a response back, update the
6270 	 bookkeeping accordingly.  there is one less request
6271 	 outstanding and we can put one more out there than before. */
6272       requests_outstanding -= 1;
6273       if (request_cwnd < first_burst_size) {
6274 	request_cwnd += 1;
6275 	if (debug) {
6276 	  fprintf(where,
6277 		  "incr req_cwnd to %d first_burst %d reqs_outstndng %d\n",
6278 		  request_cwnd,
6279 		  first_burst_size,
6280 		  requests_outstanding);
6281 	}
6282       }
6283 #endif
6284       if (timed_out) {
6285 	/* we may have been in a nested while loop - we need */
6286 	/* another call to break. */
6287 	break;
6288       }
6289 
6290 #ifdef WANT_HISTOGRAM
6291       if (verbosity > 1) {
6292 	HIST_timestamp(&time_two);
6293 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
6294       }
6295 #endif /* WANT_HISTOGRAM */
6296 
6297 #ifdef WANT_DEMO
6298       demo_rr_interval(1);
6299 #endif
6300 
6301 #ifdef WANT_INTERVALS
6302       INTERVALS_WAIT();
6303 #endif /* WANT_INTERVALS */
6304 
6305       nummessages++;
6306       if (trans_remaining) {
6307 	trans_remaining--;
6308       }
6309 
6310       if (debug > 3) {
6311 	if ((nummessages % 100) == 0) {
6312 	  fprintf(where,
6313 		  "Transaction %d completed\n",
6314 		  nummessages);
6315 	  fflush(where);
6316 	}
6317       }
6318     }
6319 
6320     /* At this point we used to call shutdown on the data socket to be
6321        sure all the data was delivered, but this was not germane in a
6322        request/response test, and it was causing the tests to "hang"
6323        when they were being controlled by time. So, I have replaced
6324        this shutdown call with a call to close that can be found later
6325        in the procedure. */
6326 
6327     /* this call will always give us the elapsed time for the test,
6328        and will also store-away the necessaries for cpu utilization */
6329 
6330     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
6331 						/* measured? how long */
6332 						/* did we really run? */
6333 
6334 #if defined(WANT_INTERVALS)
6335 #ifdef WIN32
6336     stop_itimer();
6337 #endif
6338 #endif /* WANT_INTERVALS */
6339 
6340     if (!no_control) {
6341       /* Get the statistics from the remote end. The remote will have
6342 	 calculated CPU utilization. If it wasn't supposed to care, it
6343 	 will return obvious values. */
6344 
6345       recv_response();
6346       if (!netperf_response.content.serv_errno) {
6347 	if (debug)
6348 	  fprintf(where,"remote results obtained\n");
6349       }
6350       else {
6351 	Set_errno(netperf_response.content.serv_errno);
6352 	fprintf(where,"netperf: remote error %d",
6353 		netperf_response.content.serv_errno);
6354 	perror("");
6355 	fflush(where);
6356 	exit(1);
6357       }
6358     }
6359 
6360     /* We now calculate what our "throughput" was for the test. */
6361 
6362     bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
6363     thruput	= nummessages/elapsed_time;
6364 
6365     if (local_cpu_usage || remote_cpu_usage) {
6366       /* We must now do a little math for service demand and cpu
6367        utilization for the system(s) Of course, some of the
6368        information might be bogus because there was no idle counter in
6369        the kernel(s). We need to make a note of this for the user's
6370        benefit... */
6371       if (local_cpu_usage) {
6372 	local_cpu_utilization = calc_cpu_util(0.0);
6373  	/* since calc_service demand is doing ms/Kunit we will
6374 	   multiply the number of transaction by 1024 to get "good"
6375 	   numbers */
6376 	local_service_demand  = calc_service_demand((double) nummessages*1024,
6377 						    0.0,
6378 						    0.0,
6379 						    0);
6380       }
6381       else {
6382 	local_cpu_utilization	= (float) -1.0;
6383 	local_service_demand	= (float) -1.0;
6384       }
6385 
6386       if (remote_cpu_usage) {
6387 	remote_cpu_utilization = tcp_rr_result->cpu_util;
6388 	/* since calc_service demand is doing ms/Kunit we will
6389 	   multiply the number of transaction by 1024 to get "good"
6390 	   numbers */
6391 	remote_service_demand = calc_service_demand((double) nummessages*1024,
6392 						    0.0,
6393 						    remote_cpu_utilization,
6394 						    tcp_rr_result->num_cpus);
6395       }
6396       else {
6397 	remote_cpu_utilization = (float) -1.0;
6398 	remote_service_demand  = (float) -1.0;
6399       }
6400 
6401     }
6402     else {
6403       /* we were not measuring cpu, for the confidence stuff, we */
6404       /* should make it -1.0 */
6405       local_cpu_utilization	= (float) -1.0;
6406       local_service_demand	= (float) -1.0;
6407       remote_cpu_utilization = (float) -1.0;
6408       remote_service_demand  = (float) -1.0;
6409     }
6410 
6411     /* at this point, we want to calculate the confidence information.
6412        if debugging is on, calculate_confidence will print-out the
6413        parameters we pass it */
6414 
6415     calculate_confidence(confidence_iteration,
6416 			 elapsed_time,
6417 			 thruput,
6418 			 local_cpu_utilization,
6419 			 remote_cpu_utilization,
6420 			 local_service_demand,
6421 			 remote_service_demand);
6422 
6423 
6424     confidence_iteration++;
6425 
6426     /* we are now done with the socket, so close it */
6427     close(send_socket);
6428 
6429   }
6430 
6431   retrieve_confident_values(&elapsed_time,
6432 			    &thruput,
6433 			    &local_cpu_utilization,
6434 			    &remote_cpu_utilization,
6435 			    &local_service_demand,
6436 			    &remote_service_demand);
6437 
6438   /* We are now ready to print all the information. If the user has
6439      specified zero-level verbosity, we will just print the local
6440      service demand, or the remote service demand. If the user has
6441      requested verbosity level 1, he will get the basic "streamperf"
6442      numbers. If the user has specified a verbosity of greater than 1,
6443      we will display a veritable plethora of background information
6444      from outside of this block as it it not cpu_measurement
6445      specific...  */
6446 
6447   if (confidence < 0) {
6448     /* we did not hit confidence, but were we asked to look for it? */
6449     if (iteration_max > 1) {
6450       display_confidence();
6451     }
6452   }
6453 
6454   if (local_cpu_usage || remote_cpu_usage) {
6455     local_cpu_method = format_cpu_method(cpu_method);
6456     remote_cpu_method = format_cpu_method(tcp_rr_result->cpu_method);
6457 
6458     switch (verbosity) {
6459     case 0:
6460       if (local_cpu_usage) {
6461 	fprintf(where,
6462 		cpu_fmt_0,
6463 		local_service_demand,
6464 		local_cpu_method,
6465 		((print_headers) ||
6466 		 (result_brand == NULL)) ? "" : result_brand);
6467       }
6468       else {
6469 	fprintf(where,
6470 		cpu_fmt_0,
6471 		remote_service_demand,
6472 		remote_cpu_method,
6473 		((print_headers) ||
6474 		 (result_brand == NULL)) ? "" : result_brand);
6475       }
6476       break;
6477     case 1:
6478     case 2:
6479       if (print_headers) {
6480 	if ('x' == libfmt) {
6481 	  fprintf(where,
6482 		  cpu_title,
6483 		  local_cpu_method,
6484 		  remote_cpu_method);
6485 	}
6486 	else {
6487 	  fprintf(where,
6488 		  cpu_title_tput,
6489 		  format_units(),
6490 		  local_cpu_method,
6491 		  remote_cpu_method);
6492 	}
6493       }
6494 
6495       fprintf(where,
6496 	      cpu_fmt_1_line_1,		/* the format string */
6497 	      lss_size,		/* local sendbuf size */
6498 	      lsr_size,
6499 	      req_size,		/* how large were the requests */
6500 	      rsp_size,		/* guess */
6501 	      elapsed_time,		/* how long was the test */
6502 	      ('x' == libfmt) ? thruput :
6503 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
6504 					 1.0),
6505 	      local_cpu_utilization,	/* local cpu */
6506 	      remote_cpu_utilization,	/* remote cpu */
6507 	      local_service_demand,	/* local service demand */
6508 	      remote_service_demand,	/* remote service demand */
6509 	      ((print_headers) ||
6510 	       (result_brand == NULL)) ? "" : result_brand);
6511       fprintf(where,
6512 	      cpu_fmt_1_line_2,
6513 	      rss_size,
6514 	      rsr_size);
6515       break;
6516     }
6517   }
6518   else {
6519     /* The tester did not wish to measure service demand. */
6520 
6521     switch (verbosity) {
6522     case 0:
6523       fprintf(where,
6524 	      tput_fmt_0,
6525 	      ('x' == libfmt) ? thruput :
6526 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
6527 					 1.0),
6528 	      ((print_headers) ||
6529 	       (result_brand == NULL)) ? "" : result_brand);
6530       break;
6531     case 1:
6532     case 2:
6533       if (print_headers) {
6534 	fprintf(where,
6535 		('x' == libfmt) ? tput_title : tput_title_band,
6536 		format_units());
6537       }
6538 
6539       fprintf(where,
6540 	      tput_fmt_1_line_1,	/* the format string */
6541 	      lss_size,
6542 	      lsr_size,
6543 	      req_size,		/* how large were the requests */
6544 	      rsp_size,		/* how large were the responses */
6545 	      elapsed_time, 		/* how long did it take */
6546 	      /* are we trans or do we need to convert to bytes then
6547 		 bits? at this point, thruput is in our "confident"
6548 		 transactions per second. we can convert to a
6549 		 bidirectional bitrate by multiplying that by the sum
6550 		 of the req_size and rsp_size.  we pass that to
6551 		 calc_thruput_interval_omni with an elapsed time of
6552 		 1.0 s to get it converted to [kmg]bits/s or
6553 		 [KMG]Bytes/s */
6554 	      ('x' == libfmt) ?  thruput :
6555 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
6556 					 1.0),
6557 	      ((print_headers) ||
6558 	       (result_brand == NULL)) ? "" : result_brand);
6559       fprintf(where,
6560 	      tput_fmt_1_line_2,
6561 	      rss_size, 		/* remote recvbuf size */
6562 	      rsr_size);
6563 
6564       break;
6565     }
6566   }
6567 
6568   /* it would be a good thing to include information about some of the */
6569   /* other parameters that may have been set for this test, but at the */
6570   /* moment, I do not wish to figure-out all the  formatting, so I will */
6571   /* just put this comment here to help remind me that it is something */
6572   /* that should be done at a later time. */
6573 
6574   /* how to handle the verbose information in the presence of */
6575   /* confidence intervals is yet to be determined... raj 11/94 */
6576   if (verbosity > 1) {
6577     /* The user wanted to know it all, so we will give it to him. */
6578     /* This information will include as much as we can find about */
6579     /* TCP statistics, the alignments of the sends and receives */
6580     /* and all that sort of rot... */
6581 
6582     /* normally, you might think that if we were messing about with
6583        the value of libfmt we would need to put it back again, but
6584        since this is basically the last thing we are going to do with
6585        it, it does not matter.  so there :) raj 2007-06-08 */
6586     /* if the user was asking for transactions, then we report
6587        megabits per second for the unidirectional throughput,
6588        otherwise we use the desired units. */
6589     if ('x' == libfmt) {
6590       libfmt = 'm';
6591     }
6592 
6593     fprintf(where,
6594 	    ksink_fmt,
6595 	    format_units(),
6596 	    local_send_align,
6597 	    remote_recv_offset,
6598 	    local_send_offset,
6599 	    remote_recv_offset,
6600 	    /* if the user has enable burst mode, we have to remember
6601 	       to account for that in the number of transactions
6602 	       outstanding at any one time. otherwise we will
6603 	       underreport the latency of individual
6604 	       transactions. learned from saf by raj 2007-06-08  */
6605 	    (((double)1.0/thruput)*(double)1000000.0) *
6606 	    (double) (1 + ((first_burst_size > 0) ? first_burst_size : 0)),
6607 	    thruput,
6608 	    calc_thruput_interval_omni(thruput * (double)req_size,1.0),
6609 	    calc_thruput_interval_omni(thruput * (double)rsp_size,1.0));
6610 
6611 #ifdef WANT_HISTOGRAM
6612     fprintf(where,"\nHistogram of request/response times\n");
6613     fflush(where);
6614     HIST_report(time_hist);
6615 #endif /* WANT_HISTOGRAM */
6616 
6617   }
6618 
6619 }
6620 #endif /* WANT_MIGRATION */
6621 
6622 #if defined(__linux)
6623 /*
6624  * Linux has this odd behavior where if the socket buffers are larger than
6625  * a device's txqueuelen, the kernel will silently drop transmits which would
6626  * not fit into the tx queue, and not  pass an ENOBUFS error back to the
6627  * application.  As a result, a UDP stream test can report absurd transmit
6628  * bandwidths (like 20Gb/s on a 1GbE NIC).  This behavior can be avoided if
6629  * you  request extended error reporting on the socket.  This is done by
6630  * setting the IP_RECVERR socket option at the IP level.
6631  */
6632 static void
enable_enobufs(int s)6633 enable_enobufs(int s)
6634 {
6635   int on = 1;
6636 
6637   /* Per Brian Ginsbach, the likes of SLES12 do not have "ip" listed
6638      in /etc/protocols and others may have an incorrect value.  At his
6639      suggestion, we'll just go with IPPROTO_IP.  And while I am here,
6640      perhaps we should be trying IPPROTO_IPV6 if that fails */
6641   if (setsockopt(s, IPPROTO_IP, IP_RECVERR, (char *)&on, sizeof(on)) < 0) {
6642     if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVERR, (char *)&on, sizeof(on)) < 0) {
6643       fprintf(where, "%s failed: setsockopt (errno %d)\n",__FUNCTION__,errno);
6644       fflush(where);
6645       return;
6646     }
6647   }
6648 }
6649 #endif
6650 
6651 #ifndef WANT_MIGRATION
6652 void
send_udp_stream(char remote_host[])6653 send_udp_stream(char remote_host[])
6654 {
6655   /**********************************************************************/
6656   /*									*/
6657   /*               	UDP Unidirectional Send Test                    */
6658   /*									*/
6659   /**********************************************************************/
6660 
6661 #define UDP_LENGTH_MAX 0XFFFF - 28
6662 
6663   char *tput_title = "\
6664 Socket  Message  Elapsed      Messages                \n\
6665 Size    Size     Time         Okay Errors   Throughput\n\
6666 bytes   bytes    secs            #      #   %s/sec\n\n";
6667 
6668   char *tput_fmt_0 =
6669     "%7.2f\n";
6670 
6671   char *tput_fmt_1 = "\
6672 %6d  %6d   %-7.2f   %7d %6d    %7.2f\n\
6673 %6d           %-7.2f   %7d           %7.2f\n\n";
6674 
6675 
6676   char *cpu_title = "\
6677 Socket  Message  Elapsed      Messages                   CPU      Service\n\
6678 Size    Size     Time         Okay Errors   Throughput   Util     Demand\n\
6679 bytes   bytes    secs            #      #   %s/sec %% %c%c     us/KB\n\n";
6680 
6681   char *cpu_fmt_0 =
6682     "%6.2f %c\n";
6683 
6684   char *cpu_fmt_1 = "\
6685 %6d  %6d   %-7.2f   %7d %6d    %7.1f     %-6.2f   %-6.3f\n\
6686 %6d           %-7.2f   %7d           %7.1f     %-6.2f   %-6.3f\n\n";
6687 
6688   unsigned int	messages_recvd;
6689   unsigned int 	messages_sent;
6690   unsigned int	failed_sends;
6691 
6692   float	elapsed_time,
6693         local_cpu_utilization,
6694         remote_cpu_utilization;
6695 
6696   float	 local_service_demand, remote_service_demand;
6697   double local_thruput, remote_thruput;
6698   double bytes_sent;
6699   double bytes_recvd;
6700 
6701 
6702   int	len;
6703   struct ring_elt *send_ring;
6704   SOCKET 	data_socket;
6705 
6706   unsigned int sum_messages_sent;
6707   unsigned int sum_messages_recvd;
6708   unsigned int sum_failed_sends;
6709   double sum_local_thruput;
6710 
6711   struct addrinfo *local_res;
6712   struct addrinfo *remote_res;
6713 
6714   struct	udp_stream_request_struct	*udp_stream_request;
6715   struct	udp_stream_response_struct	*udp_stream_response;
6716   struct	udp_stream_results_struct	*udp_stream_results;
6717 
6718   udp_stream_request	=
6719     (struct udp_stream_request_struct *)netperf_request.content.test_specific_data;
6720   udp_stream_response	=
6721     (struct udp_stream_response_struct *)netperf_response.content.test_specific_data;
6722   udp_stream_results	=
6723     (struct udp_stream_results_struct *)netperf_response.content.test_specific_data;
6724 
6725 #ifdef WANT_HISTOGRAM
6726   if (verbosity > 1) {
6727     time_hist = HIST_new();
6728   }
6729 #endif /* WANT_HISTOGRAM */
6730 
6731   /* since we are now disconnected from the code that established the */
6732   /* control socket, and since we want to be able to use different */
6733   /* protocols and such, we are passed the name of the remote host and */
6734   /* must turn that into the test specific addressing information. */
6735 
6736   complete_addrinfos(&remote_res,
6737 		     &local_res,
6738 		     remote_host,
6739 		     SOCK_DGRAM,
6740 		     IPPROTO_UDP,
6741 		     0);
6742 
6743   if ( print_headers ) {
6744     print_top_test_header("UDP UNIDIRECTIONAL SEND TEST",local_res,remote_res);
6745   }
6746 
6747   send_ring            = NULL;
6748   confidence_iteration = 1;
6749   init_stat();
6750   sum_messages_sent    = 0;
6751   sum_messages_recvd   = 0;
6752   sum_failed_sends     = 0;
6753   sum_local_thruput    = 0.0;
6754 
6755   /* we have a great-big while loop which controls the number of times */
6756   /* we run a particular test. this is for the calculation of a */
6757   /* confidence interval (I really should have stayed awake during */
6758   /* probstats :). If the user did not request confidence measurement */
6759   /* (no confidence is the default) then we will only go though the */
6760   /* loop once. the confidence stuff originates from the folks at IBM */
6761 
6762   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
6763 	 (confidence_iteration <= iteration_min)) {
6764 
6765     /* initialize a few counters. we have to remember that we might be */
6766     /* going through the loop more than once. */
6767     messages_sent  = 0;
6768     messages_recvd = 0;
6769     failed_sends   = 0;
6770     times_up       = 0;
6771 
6772     /*set up the data socket			*/
6773     data_socket = create_data_socket(local_res);
6774 
6775     if (data_socket == INVALID_SOCKET){
6776       perror("udp_send: data socket");
6777       exit(1);
6778     }
6779 
6780     /* now, we want to see if we need to set the send_size */
6781     if (send_size == 0) {
6782       if (lss_size > 0) {
6783 	send_size = (lss_size < UDP_LENGTH_MAX ? lss_size : UDP_LENGTH_MAX);
6784       }
6785       else {
6786 	send_size = 4096;
6787       }
6788     }
6789 
6790 
6791     /* set-up the data buffer with the requested alignment and offset, */
6792     /* most of the numbers here are just a hack to pick something nice */
6793     /* and big in an attempt to never try to send a buffer a second time */
6794     /* before it leaves the node...unless the user set the width */
6795     /* explicitly. */
6796     if (send_width == 0) send_width = 32;
6797 
6798     if (send_ring == NULL ) {
6799       send_ring = allocate_buffer_ring(send_width,
6800 				       send_size,
6801 				       local_send_align,
6802 				       local_send_offset);
6803     }
6804 
6805 
6806     /* if the user supplied a cpu rate, this call will complete rather */
6807     /* quickly, otherwise, the cpu rate will be retured to us for */
6808     /* possible display. The Library will keep it's own copy of this data */
6809     /* for use elsewhere. We will only display it. (Does that make it */
6810     /* "opaque" to us?) */
6811 
6812     if (local_cpu_usage)
6813       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
6814 
6815     if (!no_control) {
6816       /* Tell the remote end to set up the data connection. The server
6817          sends back the port number and alters the socket parameters
6818          there.  Of course this is a datagram service so no connection
6819          is actually set up, the server just sets up the socket and
6820          binds it. */
6821 
6822       netperf_request.content.request_type      = DO_UDP_STREAM;
6823       udp_stream_request->recv_buf_size  = rsr_size_req;
6824       udp_stream_request->message_size   = send_size;
6825       udp_stream_request->recv_connected = remote_connected;
6826       udp_stream_request->recv_alignment = remote_recv_align;
6827       udp_stream_request->recv_offset    = remote_recv_offset;
6828       udp_stream_request->measure_cpu    = remote_cpu_usage;
6829       udp_stream_request->cpu_rate       = remote_cpu_rate;
6830       udp_stream_request->test_length    = test_time;
6831       udp_stream_request->so_rcvavoid    = rem_rcvavoid;
6832       udp_stream_request->so_sndavoid    = rem_sndavoid;
6833       udp_stream_request->port           = atoi(remote_data_port);
6834       udp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
6835 
6836       send_request();
6837 
6838       recv_response();
6839 
6840       if (!netperf_response.content.serv_errno) {
6841 	if (debug)
6842 	  fprintf(where,"send_udp_stream: remote data connection done.\n");
6843       }
6844       else {
6845 	Set_errno(netperf_response.content.serv_errno);
6846 	perror("send_udp_stream: error on remote");
6847 	exit(1);
6848       }
6849 
6850       /* Place the port number returned by the remote into the sockaddr */
6851       /* structure so our sends can be sent to the correct place. Also get */
6852       /* some of the returned socket buffer information for user display. */
6853 
6854       /* make sure that port numbers are in the proper order */
6855       set_port_number(remote_res,(short)udp_stream_response->data_port_number);
6856 
6857       rsr_size        = udp_stream_response->recv_buf_size;
6858       rss_size        = udp_stream_response->send_buf_size;
6859       remote_cpu_rate = udp_stream_response->cpu_rate;
6860     }
6861 
6862 #ifdef WANT_DEMO
6863     demo_stream_setup(lss_size,rsr_size);
6864 #endif
6865 
6866     /* We "connect" up to the remote post to allow is to use the send */
6867     /* call instead of the sendto call. Presumeably, this is a little */
6868     /* simpler, and a little more efficient. I think that it also means */
6869     /* that we can be informed of certain things, but am not sure */
6870     /* yet...also, this is the way I would expect a client to behave */
6871     /* when talking to a server */
6872     if (local_connected) {
6873        if (connect(data_socket,
6874       		   remote_res->ai_addr,
6875 		   remote_res->ai_addrlen) == INVALID_SOCKET){
6876           perror("send_udp_stream: data socket connect failed");
6877           exit(1);
6878        } else if (debug) {
6879           fprintf(where,"send_udp_stream: connected data socket.\n");
6880           fflush(where);
6881        }
6882     }
6883 
6884 #if defined (__linux)
6885   enable_enobufs(data_socket);
6886 #endif
6887 
6888 #ifdef WIN32
6889   /* this is used so the timer thread can close the socket out from */
6890   /* under us, which to date is the easiest/cleanest/least */
6891   /* Windows-specific way I can find to force the winsock calls to */
6892   /* return WSAEINTR with the test is over. anything that will run on */
6893   /* 95 and NT and is closer to what netperf expects from Unix signals */
6894   /* and such would be appreciated raj 1/96 */
6895     win_kludge_socket = data_socket;
6896 #endif /* WIN32 */
6897 
6898     /* set up the timer to call us after test_time. one of these days, */
6899     /* it might be nice to figure-out a nice reliable way to have the */
6900     /* test controlled by a byte count as well, but since UDP is not */
6901     /* reliable, that could prove difficult. so, in the meantime, we */
6902     /* only allow a UDP_STREAM test to be a timed test. */
6903 
6904     if (test_time) {
6905       times_up = 0;
6906       start_timer(test_time);
6907     }
6908     else {
6909       fprintf(where,"Sorry, UDP_STREAM tests must be timed.\n");
6910       fflush(where);
6911     }
6912 
6913     /* Get the start count for the idle counter and the start time */
6914 
6915     cpu_start(local_cpu_usage);
6916 
6917 #ifdef WANT_INTERVALS
6918     INTERVALS_INIT();
6919 #endif /* WANT_INTERVALS */
6920 
6921 #ifdef WANT_DEMO
6922     if (demo_mode) {
6923       demo_first_timestamp();
6924     }
6925 #endif
6926 
6927     /* Send datagrams like there was no tomorrow. at somepoint it might */
6928     /* be nice to set this up so that a quantity of bytes could be sent, */
6929     /* but we still need some sort of end of test trigger on the receive */
6930     /* side. that could be a select with a one second timeout, but then */
6931     /* if there is a test where none of the data arrives for awile and */
6932     /* then starts again, we would end the test too soon. something to */
6933     /* think about... */
6934     while (!times_up) {
6935 
6936 #ifdef DIRTY
6937       /* we want to dirty some number of consecutive integers in the buffer */
6938       /* we are about to send. we may also want to bring some number of */
6939       /* them cleanly into the cache. The clean ones will follow any dirty */
6940       /* ones into the cache. */
6941 
6942       access_buffer(send_ring->buffer_ptr,
6943 		    send_size,
6944 		    loc_dirty_count,
6945 		    loc_clean_count);
6946 #endif /* DIRTY */
6947 
6948 #ifdef WANT_HISTOGRAM
6949       if (verbosity > 1) {
6950 	HIST_timestamp(&time_one);
6951       }
6952 #endif /* WANT_HISTOGRAM */
6953 
6954       if (local_connected) {
6955          len = send(data_socket,
6956 	  	    send_ring->buffer_ptr,
6957 		    send_size,
6958 		    0);
6959       } else {
6960          len = sendto(data_socket,
6961 		      send_ring->buffer_ptr,
6962 		      send_size,
6963 		      0,
6964 		      remote_res->ai_addr,
6965 		      remote_res->ai_addrlen);
6966       }
6967 
6968       if (len != send_size) {
6969 	if ((len >= 0) ||
6970 	    SOCKET_EINTR(len))
6971 	  break;
6972 	if (errno == ENOBUFS) {
6973 	  failed_sends++;
6974 	  continue;
6975 	}
6976 	perror("udp_send: data send error");
6977 	exit(1);
6978       }
6979       messages_sent++;
6980 
6981       /* now we want to move our pointer to the next position in the */
6982       /* data buffer... */
6983 
6984       send_ring = send_ring->next;
6985 
6986 
6987 #ifdef WANT_HISTOGRAM
6988       if (verbosity > 1) {
6989 	/* get the second timestamp */
6990 	HIST_timestamp(&time_two);
6991 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
6992       }
6993 #endif /* WANT_HISTOGRAM */
6994 
6995 #ifdef WANT_DEMO
6996       demo_stream_interval(send_size);
6997 #endif
6998 
6999 #ifdef WANT_INTERVALS
7000       INTERVALS_WAIT();
7001 #endif /* WANT_INTERVALS */
7002 
7003     }
7004 
7005     /* This is a timed test, so the remote will be returning to us after */
7006     /* a time. We should not need to send any "strange" messages to tell */
7007     /* the remote that the test is completed, unless we decide to add a */
7008     /* number of messages to the test. */
7009 
7010     /* the test is over, so get stats and stuff */
7011     cpu_stop(local_cpu_usage,
7012 	     &elapsed_time);
7013 
7014 #if defined(WANT_INTERVALS)
7015 #ifdef WIN32
7016     stop_itimer();
7017 #endif
7018 #endif /* WANT_INTERVALS */
7019 
7020     if (!no_control) {
7021       /* Get the statistics from the remote end	*/
7022       recv_response();
7023       if (!netperf_response.content.serv_errno) {
7024 	if (debug)
7025 	  fprintf(where,"send_udp_stream: remote results obtained\n");
7026       }
7027       else {
7028 	Set_errno(netperf_response.content.serv_errno);
7029 	perror("send_udp_stream: error on remote");
7030 	exit(1);
7031       }
7032       messages_recvd = udp_stream_results->messages_recvd;
7033       bytes_recvd    = (double) send_size * (double) messages_recvd;
7034     }
7035     else {
7036       /* since there was no control connection, we've no idea what was
7037 	 actually received. raj 2007-02-08 */
7038       messages_recvd = -1;
7039       bytes_recvd = -1.0;
7040     }
7041 
7042     bytes_sent    = (double) send_size * (double) messages_sent;
7043     local_thruput = calc_thruput(bytes_sent);
7044 
7045 
7046     /* we asume that the remote ran for as long as we did */
7047 
7048     remote_thruput = calc_thruput(bytes_recvd);
7049 
7050     /* print the results for this socket and message size */
7051 
7052     if (local_cpu_usage || remote_cpu_usage) {
7053       /* We must now do a little math for service demand and cpu */
7054       /* utilization for the system(s) We pass zeros for the local */
7055       /* cpu utilization and elapsed time to tell the routine to use */
7056       /* the libraries own values for those. */
7057       if (local_cpu_usage) {
7058 	local_cpu_utilization	= calc_cpu_util(0.0);
7059 	/* shouldn't this really be based on bytes_recvd, since that is */
7060 	/* the effective throughput of the test? I think that it should, */
7061 	/* so will make the change raj 11/94 */
7062 	local_service_demand	= calc_service_demand(bytes_recvd,
7063 						      0.0,
7064 						      0.0,
7065 						      0);
7066       }
7067       else {
7068 	local_cpu_utilization	= (float) -1.0;
7069 	local_service_demand	= (float) -1.0;
7070       }
7071 
7072       /* The local calculations could use variables being kept by */
7073       /* the local netlib routines. The remote calcuations need to */
7074       /* have a few things passed to them. */
7075       if (remote_cpu_usage) {
7076 	remote_cpu_utilization	= udp_stream_results->cpu_util;
7077 	remote_service_demand	= calc_service_demand(bytes_recvd,
7078 						      0.0,
7079 						      remote_cpu_utilization,
7080 						      udp_stream_results->num_cpus);
7081       }
7082       else {
7083 	remote_cpu_utilization	= (float) -1.0;
7084 	remote_service_demand	= (float) -1.0;
7085       }
7086     }
7087     else {
7088       /* we were not measuring cpu, for the confidence stuff, we */
7089       /* should make it -1.0 */
7090       local_cpu_utilization  = (float) -1.0;
7091       local_service_demand   = (float) -1.0;
7092       remote_cpu_utilization = (float) -1.0;
7093       remote_service_demand  = (float) -1.0;
7094     }
7095 
7096     /* at this point, we want to calculate the confidence information. */
7097     /* if debugging is on, calculate_confidence will print-out the */
7098     /* parameters we pass it */
7099 
7100     calculate_confidence(confidence_iteration,
7101 			 elapsed_time,
7102 			 remote_thruput,
7103 			 local_cpu_utilization,
7104 			 remote_cpu_utilization,
7105 			 local_service_demand,
7106 			 remote_service_demand);
7107 
7108     /* since the routine calculate_confidence is rather generic, and */
7109     /* we have a few other parms of interest, we will do a little work */
7110     /* here to caclulate their average. */
7111     sum_messages_sent  += messages_sent;
7112     sum_messages_recvd += messages_recvd;
7113     sum_failed_sends   += failed_sends;
7114     sum_local_thruput  += local_thruput;
7115 
7116     confidence_iteration++;
7117 
7118     /* this datapoint is done, so we don't need the socket any longer */
7119     close(data_socket);
7120 
7121   }
7122 
7123   /* we should reach this point once the test is finished */
7124 
7125   retrieve_confident_values(&elapsed_time,
7126 			    &remote_thruput,
7127 			    &local_cpu_utilization,
7128 			    &remote_cpu_utilization,
7129 			    &local_service_demand,
7130 			    &remote_service_demand);
7131 
7132   /* some of the interesting values aren't covered by the generic */
7133   /* confidence routine */
7134   messages_sent    = sum_messages_sent / (confidence_iteration -1);
7135   messages_recvd   = sum_messages_recvd / (confidence_iteration -1);
7136   failed_sends     = sum_failed_sends / (confidence_iteration -1);
7137   local_thruput    = sum_local_thruput / (confidence_iteration -1);
7138 
7139   /* We are now ready to print all the information. If the user */
7140   /* has specified zero-level verbosity, we will just print the */
7141   /* local service demand, or the remote service demand. If the */
7142   /* user has requested verbosity level 1, he will get the basic */
7143   /* "streamperf" numbers. If the user has specified a verbosity */
7144   /* of greater than 1, we will display a veritable plethora of */
7145   /* background information from outside of this block as it it */
7146   /* not cpu_measurement specific...  */
7147 
7148 
7149   if (confidence < 0) {
7150     /* we did not hit confidence, but were we asked to look for it? */
7151     if (iteration_max > 1) {
7152       display_confidence();
7153     }
7154   }
7155 
7156   if (local_cpu_usage || remote_cpu_usage) {
7157     local_cpu_method = format_cpu_method(cpu_method);
7158     remote_cpu_method = format_cpu_method(udp_stream_results->cpu_method);
7159 
7160     switch (verbosity) {
7161     case 0:
7162       if (local_cpu_usage) {
7163 	fprintf(where,
7164 		cpu_fmt_0,
7165 		local_service_demand,
7166 		local_cpu_method);
7167       }
7168       else {
7169 	fprintf(where,
7170 		cpu_fmt_0,
7171 		remote_service_demand,
7172 		local_cpu_method);
7173       }
7174       break;
7175     case 1:
7176     case 2:
7177       if (print_headers) {
7178 	fprintf(where,
7179 		cpu_title,
7180 		format_units(),
7181 		local_cpu_method,
7182 		remote_cpu_method);
7183       }
7184 
7185       fprintf(where,
7186 	      cpu_fmt_1,		/* the format string */
7187 	      lss_size,		        /* local sendbuf size */
7188 	      send_size,		/* how large were the sends */
7189 	      elapsed_time,		/* how long was the test */
7190 	      messages_sent,
7191 	      failed_sends,
7192 	      local_thruput, 		/* what was the xfer rate */
7193 	      local_cpu_utilization,	/* local cpu */
7194 	      local_service_demand,	/* local service demand */
7195 	      rsr_size,
7196 	      elapsed_time,
7197 	      messages_recvd,
7198 	      remote_thruput,
7199 	      remote_cpu_utilization,	/* remote cpu */
7200 	      remote_service_demand);	/* remote service demand */
7201       break;
7202     }
7203   }
7204   else {
7205     /* The tester did not wish to measure service demand. */
7206     switch (verbosity) {
7207     case 0:
7208       fprintf(where,
7209 	      tput_fmt_0,
7210 	      local_thruput);
7211       break;
7212     case 1:
7213     case 2:
7214       if (print_headers) {
7215 	fprintf(where,tput_title,format_units());
7216       }
7217       fprintf(where,
7218 	      tput_fmt_1,		/* the format string */
7219 	      lss_size, 		/* local sendbuf size */
7220 	      send_size,		/* how large were the sends */
7221 	      elapsed_time, 		/* how long did it take */
7222 	      messages_sent,
7223 	      failed_sends,
7224 	      local_thruput,
7225 	      rsr_size, 		/* remote recvbuf size */
7226 	      elapsed_time,
7227 	      messages_recvd,
7228 	      remote_thruput);
7229       break;
7230     }
7231   }
7232 
7233   fflush(where);
7234 #ifdef WANT_HISTOGRAM
7235   if (verbosity > 1) {
7236     fprintf(where,"\nHistogram of time spent in send() call\n");
7237     fflush(where);
7238     HIST_report(time_hist);
7239   }
7240 #endif /* WANT_HISTOGRAM */
7241 
7242 }
7243 #endif /* WANT_MIGRATION */
7244 
7245 
7246  /* this routine implements the receive side (netserver) of the */
7247  /* UDP_STREAM performance test. */
7248 
7249 void
recv_udp_stream()7250 recv_udp_stream()
7251 {
7252   struct ring_elt *recv_ring;
7253   struct addrinfo *local_res;
7254   char local_name[BUFSIZ];
7255   char port_buffer[PORTBUFSIZE];
7256 
7257   struct sockaddr_storage myaddr_in;
7258   SOCKET	s_data;
7259   netperf_socklen_t 	addrlen;
7260   struct sockaddr_storage remote_addr;
7261   netperf_socklen_t remote_addrlen;
7262 
7263   int	len = 0;
7264   unsigned int	bytes_received = 0;
7265   float	elapsed_time;
7266 
7267   int	message_size;
7268   unsigned int	messages_recvd = 0;
7269 
7270   struct	udp_stream_request_struct	*udp_stream_request;
7271   struct	udp_stream_response_struct	*udp_stream_response;
7272   struct	udp_stream_results_struct	*udp_stream_results;
7273 
7274   udp_stream_request  =
7275     (struct udp_stream_request_struct *)netperf_request.content.test_specific_data;
7276   udp_stream_response =
7277     (struct udp_stream_response_struct *)netperf_response.content.test_specific_data;
7278   udp_stream_results  =
7279     (struct udp_stream_results_struct *)netperf_response.content.test_specific_data;
7280 
7281   if (debug) {
7282     fprintf(where,"netserver: recv_udp_stream: entered...\n");
7283     fflush(where);
7284   }
7285 
7286   /* We want to set-up the listen socket with all the desired */
7287   /* parameters and then let the initiator know that all is ready. If */
7288   /* socket size defaults are to be used, then the initiator will have */
7289   /* sent us 0's. If the socket sizes cannot be changed, then we will */
7290   /* send-back what they are. If that information cannot be determined, */
7291   /* then we send-back -1's for the sizes. If things go wrong for any */
7292   /* reason, we will drop back ten yards and punt. */
7293 
7294   /* If anything goes wrong, we want the remote to know about it. It */
7295   /* would be best if the error that the remote reports to the user is */
7296   /* the actual error we encountered, rather than some bogus unexpected */
7297   /* response type message. */
7298 
7299   if (debug > 1) {
7300     fprintf(where,"recv_udp_stream: setting the response type...\n");
7301     fflush(where);
7302   }
7303 
7304   netperf_response.content.response_type = UDP_STREAM_RESPONSE;
7305 
7306   if (debug > 2) {
7307     fprintf(where,"recv_udp_stream: the response type is set...\n");
7308     fflush(where);
7309   }
7310 
7311   /* We now alter the message_ptr variable to be at the desired */
7312   /* alignment with the desired offset. */
7313 
7314   if (debug > 1) {
7315     fprintf(where,"recv_udp_stream: requested alignment of %d\n",
7316 	    udp_stream_request->recv_alignment);
7317     fflush(where);
7318   }
7319 
7320   if (recv_width == 0) recv_width = 1;
7321 
7322   recv_ring = allocate_buffer_ring(recv_width,
7323 				   udp_stream_request->message_size,
7324 				   udp_stream_request->recv_alignment,
7325 				   udp_stream_request->recv_offset);
7326 
7327   if (debug > 1) {
7328     fprintf(where,"recv_udp_stream: receive alignment and offset set...\n");
7329     fflush(where);
7330   }
7331 
7332   /* Grab a socket to listen on, and then listen on it. */
7333 
7334   if (debug > 1) {
7335     fprintf(where,"recv_udp_stream: grabbing a socket...\n");
7336     fflush(where);
7337   }
7338 
7339   /* create_data_socket expects to find some things in the global */
7340   /* variables, so set the globals based on the values in the request. */
7341   /* once the socket has been created, we will set the response values */
7342   /* based on the updated value of those globals. raj 7/94 */
7343   lsr_size_req = udp_stream_request->recv_buf_size;
7344   loc_rcvavoid = udp_stream_request->so_rcvavoid;
7345   loc_sndavoid = udp_stream_request->so_sndavoid;
7346   local_connected = udp_stream_request->recv_connected;
7347 
7348   set_hostname_and_port(local_name,
7349 			port_buffer,
7350 			nf_to_af(udp_stream_request->ipfamily),
7351 			udp_stream_request->port);
7352 
7353   local_res = complete_addrinfo(local_name,
7354 				local_name,
7355 				port_buffer,
7356 				nf_to_af(udp_stream_request->ipfamily),
7357 				SOCK_DGRAM,
7358 				IPPROTO_UDP,
7359 				0);
7360 
7361   s_data = create_data_socket(local_res);
7362 
7363   if (s_data == INVALID_SOCKET) {
7364     netperf_response.content.serv_errno = errno;
7365     send_response();
7366     exit(1);
7367   }
7368 
7369   udp_stream_response->test_length = udp_stream_request->test_length;
7370 
7371   /* now get the port number assigned by the system  */
7372   addrlen = sizeof(myaddr_in);
7373   if (getsockname(s_data,
7374 		  (struct sockaddr *)&myaddr_in,
7375 		  &addrlen) == SOCKET_ERROR){
7376     netperf_response.content.serv_errno = errno;
7377     close(s_data);
7378     send_response();
7379 
7380     exit(1);
7381   }
7382 
7383   /* Now myaddr_in contains the port and the internet address this is */
7384   /* returned to the sender also implicitly telling the sender that the */
7385   /* socket buffer sizing has been done. */
7386 
7387   udp_stream_response->data_port_number =
7388     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
7389   netperf_response.content.serv_errno   = 0;
7390 
7391   /* But wait, there's more. If the initiator wanted cpu measurements, */
7392   /* then we must call the calibrate routine, which will return the max */
7393   /* rate back to the initiator. If the CPU was not to be measured, or */
7394   /* something went wrong with the calibration, we will return a -1 to */
7395   /* the initiator. */
7396 
7397   udp_stream_response->cpu_rate    = (float)0.0; /* assume no cpu */
7398   udp_stream_response->measure_cpu = 0;
7399   if (udp_stream_request->measure_cpu) {
7400     /* We will pass the rate into the calibration routine. If the */
7401     /* user did not specify one, it will be 0.0, and we will do a */
7402     /* "real" calibration. Otherwise, all it will really do is */
7403     /* store it away... */
7404     udp_stream_response->measure_cpu = 1;
7405     udp_stream_response->cpu_rate =
7406       calibrate_local_cpu(udp_stream_request->cpu_rate);
7407   }
7408 
7409   message_size	= udp_stream_request->message_size;
7410   test_time	= udp_stream_request->test_length;
7411 
7412   /* before we send the response back to the initiator, pull some of */
7413   /* the socket parms from the globals */
7414   udp_stream_response->send_buf_size = lss_size;
7415   udp_stream_response->recv_buf_size = lsr_size;
7416   udp_stream_response->so_rcvavoid = loc_rcvavoid;
7417   udp_stream_response->so_sndavoid = loc_sndavoid;
7418 
7419   send_response();
7420 
7421   /* Now it's time to start receiving data on the connection. We will */
7422   /* first grab the apropriate counters and then start grabbing. */
7423 
7424   cpu_start(udp_stream_request->measure_cpu);
7425 
7426 #ifdef WIN32
7427   /* this is used so the timer thread can close the socket out from */
7428   /* under us, which to date is the easiest/cleanest/least */
7429   /* Windows-specific way I can find to force the winsock calls to */
7430   /* return WSAEINTR with the test is over. anything that will run on */
7431   /* 95 and NT and is closer to what netperf expects from Unix signals */
7432   /* and such would be appreciated raj 1/96 */
7433   win_kludge_socket = s_data;
7434 #endif /* WIN32 */
7435 
7436   /* The loop will exit when the timer pops, or if we happen to recv a */
7437   /* message of less than send_size bytes... */
7438 
7439   times_up = 0;
7440 
7441   start_timer(test_time + PAD_TIME);
7442 
7443   if (debug) {
7444     fprintf(where,"recv_udp_stream: about to enter inner sanctum.\n");
7445     fflush(where);
7446   }
7447 
7448   /* We "connect" up to the remote post to allow us to use the recv */
7449   /* call instead of the recvfrom call. Presumeably, this is a little */
7450   /* simpler, and a little more efficient. */
7451 
7452   if (local_connected) {
7453 
7454     /* Receive the first message using recvfrom to find the remote address */
7455     remote_addrlen = sizeof(remote_addr);
7456     len = recvfrom(s_data, recv_ring->buffer_ptr,
7457                    message_size, 0,
7458                    (struct sockaddr*)&remote_addr, &remote_addrlen);
7459     if (len != message_size) {
7460       if ((len == SOCKET_ERROR) && !SOCKET_EINTR(len)) {
7461             netperf_response.content.serv_errno = errno;
7462             send_response();
7463             exit(1);
7464       }
7465     }
7466     messages_recvd++;
7467     recv_ring = recv_ring->next;
7468 
7469 
7470     /* Now connect with the remote socket address */
7471     if (connect(s_data,
7472                 (struct sockaddr*)&remote_addr,
7473                 remote_addrlen )== INVALID_SOCKET) {
7474         netperf_response.content.serv_errno = errno;
7475         close(s_data);
7476         send_response();
7477         exit(1);
7478     }
7479 
7480     if (debug) {
7481         fprintf(where,"recv_udp_stream: connected data socket\n");
7482         fflush(where);
7483      }
7484   }
7485 
7486   while (!times_up) {
7487     if(local_connected) {
7488        len = recv(s_data,
7489                   recv_ring->buffer_ptr,
7490                   message_size,
7491                   0);
7492     } else {
7493        len = recvfrom(s_data,
7494                       recv_ring->buffer_ptr,
7495     	              message_size,
7496 		      0,0,0);
7497     }
7498 
7499     if (len != message_size) {
7500       if ((len == SOCKET_ERROR) && !SOCKET_EINTR(len)) {
7501             netperf_response.content.serv_errno = errno;
7502 	    send_response();
7503 	    exit(1);
7504       }
7505       break;
7506     }
7507     messages_recvd++;
7508     recv_ring = recv_ring->next;
7509   }
7510 
7511   if (debug) {
7512     fprintf(where,"recv_udp_stream: got %d messages.\n",messages_recvd);
7513     fflush(where);
7514   }
7515 
7516 
7517   /* The loop now exits due timer or < send_size bytes received. in */
7518   /* reality, we only really support a timed UDP_STREAM test. raj */
7519   /* 12/95 */
7520 
7521   cpu_stop(udp_stream_request->measure_cpu,&elapsed_time);
7522 
7523   if (times_up) {
7524     /* we ended on a timer, subtract the PAD_TIME */
7525     elapsed_time -= (float)PAD_TIME;
7526   }
7527   else {
7528     stop_timer();
7529   }
7530 
7531   if (debug) {
7532     fprintf(where,"recv_udp_stream: test ended in %f seconds.\n",elapsed_time);
7533     fflush(where);
7534   }
7535 
7536 
7537   /* We will count the "off" message that got us out of the loop */
7538   bytes_received = (messages_recvd * message_size) + len;
7539 
7540   /* send the results to the sender			*/
7541 
7542   if (debug) {
7543     fprintf(where,
7544 	    "recv_udp_stream: got %d bytes\n",
7545 	    bytes_received);
7546     fflush(where);
7547   }
7548 
7549   netperf_response.content.response_type	= UDP_STREAM_RESULTS;
7550   udp_stream_results->bytes_received	= bytes_received;
7551   udp_stream_results->messages_recvd	= messages_recvd;
7552   udp_stream_results->elapsed_time	= elapsed_time;
7553   udp_stream_results->cpu_method        = cpu_method;
7554   udp_stream_results->num_cpus          = lib_num_loc_cpus;
7555   if (udp_stream_request->measure_cpu) {
7556     udp_stream_results->cpu_util	= calc_cpu_util(elapsed_time);
7557   }
7558   else {
7559     udp_stream_results->cpu_util	= (float) -1.0;
7560   }
7561 
7562   if (debug > 1) {
7563     fprintf(where,
7564 	    "recv_udp_stream: test complete, sending results.\n");
7565     fflush(where);
7566   }
7567 
7568   send_response();
7569 
7570   close(s_data);
7571 
7572 }
7573 
7574 #ifndef WANT_MIGRATION
7575 void
send_udp_rr(char remote_host[])7576 send_udp_rr(char remote_host[])
7577 {
7578 
7579   char *tput_title = "\
7580 Local /Remote\n\
7581 Socket Size   Request  Resp.   Elapsed  Trans.\n\
7582 Send   Recv   Size     Size    Time     Rate         \n\
7583 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
7584 
7585   char *tput_title_band = "\
7586 Local /Remote\n\
7587 Socket Size   Request  Resp.   Elapsed  \n\
7588 Send   Recv   Size     Size    Time     Throughput \n\
7589 bytes  Bytes  bytes    bytes   secs.    %s/sec   \n\n";
7590 
7591   char *tput_fmt_0 =
7592     "%7.2f %s\n";
7593 
7594   char *tput_fmt_1_line_1 = "\
7595 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   %s\n";
7596 
7597   char *tput_fmt_1_line_2 = "\
7598 %-6d %-6d\n";
7599 
7600   char *cpu_title = "\
7601 Local /Remote\n\
7602 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
7603 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
7604 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
7605 
7606   char *cpu_title_tput = "\
7607 Local /Remote\n\
7608 Socket Size   Request Resp.  Elapsed Tput     CPU    CPU    S.dem   S.dem\n\
7609 Send   Recv   Size    Size   Time    %-8.8s local  remote local   remote\n\
7610 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
7611 
7612   char *cpu_fmt_0 =
7613     "%6.3f %c %s\n";
7614 
7615   char *cpu_fmt_1_line_1 = "\
7616 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f %s\n";
7617 
7618   char *cpu_fmt_1_line_2 = "\
7619 %-6d %-6d\n";
7620 
7621   float			elapsed_time;
7622 
7623   struct ring_elt *send_ring;
7624   struct ring_elt *recv_ring;
7625 
7626   int	len;
7627   int	nummessages;
7628   SOCKET	send_socket;
7629   int	trans_remaining;
7630   int	bytes_xferd;
7631 
7632   int	rsp_bytes_recvd;
7633 
7634   float	local_cpu_utilization;
7635   float	local_service_demand;
7636   float	remote_cpu_utilization;
7637   float	remote_service_demand;
7638   double	thruput;
7639 
7640   struct addrinfo *local_res;
7641   struct addrinfo *remote_res;
7642 
7643   struct	udp_rr_request_struct	*udp_rr_request;
7644   struct	udp_rr_response_struct	*udp_rr_response;
7645   struct	udp_rr_results_struct	*udp_rr_result;
7646 
7647   udp_rr_request  =
7648     (struct udp_rr_request_struct *)netperf_request.content.test_specific_data;
7649   udp_rr_response =
7650     (struct udp_rr_response_struct *)netperf_response.content.test_specific_data;
7651   udp_rr_result	 =
7652     (struct udp_rr_results_struct *)netperf_response.content.test_specific_data;
7653 
7654 #ifdef WANT_HISTOGRAM
7655   if (verbosity > 1) {
7656     time_hist = HIST_new();
7657   }
7658 #endif
7659 
7660   /* since we are now disconnected from the code that established the */
7661   /* control socket, and since we want to be able to use different */
7662   /* protocols and such, we are passed the name of the remote host and */
7663   /* must turn that into the test specific addressing information. */
7664 
7665   complete_addrinfos(&remote_res,
7666 		     &local_res,
7667 		     remote_host,
7668 		     SOCK_DGRAM,
7669 		     IPPROTO_UDP,
7670 		     0);
7671 
7672   if ( print_headers ) {
7673     print_top_test_header("UDP REQUEST/RESPONSE TEST",local_res,remote_res);
7674   }
7675 
7676   /* initialize a few counters */
7677 
7678   send_ring     = NULL;
7679   recv_ring     = NULL;
7680   nummessages	= 0;
7681   bytes_xferd	= 0;
7682   times_up 	= 0;
7683   confidence_iteration = 1;
7684   init_stat();
7685 
7686   /* we have a great-big while loop which controls the number of times */
7687   /* we run a particular test. this is for the calculation of a */
7688   /* confidence interval (I really should have stayed awake during */
7689   /* probstats :). If the user did not request confidence measurement */
7690   /* (no confidence is the default) then we will only go though the */
7691   /* loop once. the confidence stuff originates from the folks at IBM */
7692 
7693   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
7694 	 (confidence_iteration <= iteration_min)) {
7695 
7696     nummessages     = 0;
7697     bytes_xferd     = 0;
7698     times_up        = 0;
7699     trans_remaining = 0;
7700 
7701     /* set-up the data buffers with the requested alignment and offset */
7702 
7703     if (send_width == 0) send_width = 1;
7704     if (recv_width == 0) recv_width = 1;
7705 
7706     if (send_ring == NULL) {
7707       send_ring = allocate_buffer_ring(send_width,
7708 				       req_size,
7709 				       local_send_align,
7710 				       local_send_offset);
7711     }
7712 
7713     if (recv_ring == NULL) {
7714       recv_ring = allocate_buffer_ring(recv_width,
7715 				       rsp_size,
7716 				       local_recv_align,
7717 				       local_recv_offset);
7718     }
7719 
7720     /*set up the data socket                        */
7721     send_socket = create_data_socket(local_res);
7722 
7723     if (send_socket == INVALID_SOCKET){
7724       perror("netperf: send_udp_rr: udp rr data socket");
7725       exit(1);
7726     }
7727 
7728     if (debug) {
7729       fprintf(where,"send_udp_rr: send_socket obtained...\n");
7730     }
7731 
7732     /* If the user has requested cpu utilization measurements, we must */
7733     /* calibrate the cpu(s). We will perform this task within the tests */
7734     /* themselves. If the user has specified the cpu rate, then */
7735     /* calibrate_local_cpu will return rather quickly as it will have */
7736     /* nothing to do. If local_cpu_rate is zero, then we will go through */
7737     /* all the "normal" calibration stuff and return the rate back. If */
7738     /* there is no idle counter in the kernel idle loop, the */
7739     /* local_cpu_rate will be set to -1. */
7740 
7741     if (local_cpu_usage) {
7742       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
7743     }
7744 
7745     if (!no_control) {
7746       /* Tell the remote end to do a listen. The server alters the
7747 	 socket paramters on the other side at this point, hence the
7748 	 reason for all the values being passed in the setup
7749 	 message. If the user did not specify any of the parameters,
7750 	 they will be passed as 0, which will indicate to the remote
7751 	 that no changes beyond the system's default should be
7752 	 used. Alignment is the exception, it will default to 8, which
7753 	 will be no alignment alterations. */
7754 
7755       netperf_request.content.request_type	= DO_UDP_RR;
7756       udp_rr_request->recv_buf_size	= rsr_size_req;
7757       udp_rr_request->send_buf_size	= rss_size_req;
7758       udp_rr_request->recv_alignment      = remote_recv_align;
7759       udp_rr_request->recv_offset	        = remote_recv_offset;
7760       udp_rr_request->send_alignment      = remote_send_align;
7761       udp_rr_request->send_offset	        = remote_send_offset;
7762       udp_rr_request->request_size	= req_size;
7763       udp_rr_request->response_size	= rsp_size;
7764       udp_rr_request->measure_cpu	        = remote_cpu_usage;
7765       udp_rr_request->cpu_rate	        = remote_cpu_rate;
7766       udp_rr_request->so_rcvavoid	        = rem_rcvavoid;
7767       udp_rr_request->so_sndavoid	        = rem_sndavoid;
7768       if (test_time) {
7769 	udp_rr_request->test_length	= test_time;
7770       }
7771       else {
7772 	udp_rr_request->test_length	= test_trans * -1;
7773       }
7774       udp_rr_request->port                = atoi(remote_data_port);
7775       udp_rr_request->ipfamily = af_to_nf(remote_res->ai_family);
7776 
7777       if (debug > 1) {
7778 	fprintf(where,"netperf: send_udp_rr: requesting UDP r/r test\n");
7779       }
7780 
7781       send_request();
7782 
7783       /* The response from the remote will contain all of the relevant
7784 	 socket parameters for this test type. We will put them back
7785 	 into the variables here so they can be displayed if desired.
7786 	 The remote will have calibrated CPU if necessary, and will
7787 	 have done all the needed set-up we will have calibrated the
7788 	 cpu locally before sending the request, and will grab the
7789 	 counter value right after the connect returns. The remote
7790 	 will grab the counter right after the accept call. This saves
7791 	 the hassle of extra messages being sent for the UDP
7792 	 tests.  */
7793 
7794       recv_response();
7795 
7796       if (!netperf_response.content.serv_errno) {
7797 	if (debug)
7798 	  fprintf(where,"remote listen done.\n");
7799 	rsr_size	       =	udp_rr_response->recv_buf_size;
7800 	rss_size	       =	udp_rr_response->send_buf_size;
7801 	remote_cpu_usage =	udp_rr_response->measure_cpu;
7802 	remote_cpu_rate  = 	udp_rr_response->cpu_rate;
7803 	/* port numbers in proper order */
7804 	set_port_number(remote_res,(short)udp_rr_response->data_port_number);
7805       }
7806       else {
7807 	Set_errno(netperf_response.content.serv_errno);
7808 	fprintf(where,
7809 		"netperf: remote error %d",
7810 		netperf_response.content.serv_errno);
7811 	perror("");
7812 	fflush(where);
7813 	exit(1);
7814       }
7815     }
7816 
7817 #ifdef WANT_DEMO
7818     demo_rr_setup(100);
7819 #endif
7820 
7821     /* Connect up to the remote port on the data socket. This will set */
7822     /* the default destination address on this socket. With UDP, this */
7823     /* does make a performance difference as we may not have to do as */
7824     /* many routing lookups, however, I expect that a client would */
7825     /* behave this way. raj 1/94 */
7826 
7827     if ( connect(send_socket,
7828 		 remote_res->ai_addr,
7829 		 remote_res->ai_addrlen) == INVALID_SOCKET ) {
7830       perror("netperf: data socket connect failed");
7831       exit(1);
7832     }
7833 
7834 #ifdef WIN32
7835   /* this is used so the timer thread can close the socket out from */
7836   /* under us, which to date is the easiest/cleanest/least */
7837   /* Windows-specific way I can find to force the winsock calls to */
7838   /* return WSAEINTR with the test is over. anything that will run on */
7839   /* 95 and NT and is closer to what netperf expects from Unix signals */
7840   /* and such would be appreciated raj 1/96 */
7841   win_kludge_socket = send_socket;
7842 #endif /* WIN32 */
7843 
7844     /* Data Socket set-up is finished. If there were problems, either the */
7845     /* connect would have failed, or the previous response would have */
7846     /* indicated a problem. I failed to see the value of the extra */
7847     /* message after the accept on the remote. If it failed, we'll see it */
7848     /* here. If it didn't, we might as well start pumping data. */
7849 
7850     /* Set-up the test end conditions. For a request/response test, they */
7851     /* can be either time or transaction based. */
7852 
7853     if (test_time) {
7854       /* The user wanted to end the test after a period of time. */
7855       times_up = 0;
7856       trans_remaining = 0;
7857       start_timer(test_time);
7858     }
7859     else {
7860       /* The tester wanted to send a number of bytes. */
7861       trans_remaining = test_bytes;
7862       times_up = 1;
7863     }
7864 
7865     /* The cpu_start routine will grab the current time and possibly */
7866     /* value of the idle counter for later use in measuring cpu */
7867     /* utilization and/or service demand and thruput. */
7868 
7869     cpu_start(local_cpu_usage);
7870 
7871 #ifdef WANT_DEMO
7872     if (demo_mode) {
7873       demo_first_timestamp();
7874     }
7875 #endif
7876 
7877 #ifdef WANT_INTERVALS
7878     INTERVALS_INIT();
7879 #endif /* WANT_INTERVALS */
7880 
7881     /* We use an "OR" to control test execution. When the test is */
7882     /* controlled by time, the byte count check will always return */
7883     /* false. When the test is controlled by byte count, the time test */
7884     /* will always return false. When the test is finished, the whole */
7885     /* expression will go false and we will stop sending data. I think */
7886     /* I just arbitrarily decrement trans_remaining for the timed */
7887     /* test, but will not do that just yet... One other question is */
7888     /* whether or not the send buffer and the receive buffer should be */
7889     /* the same buffer. */
7890 
7891 #ifdef WANT_FIRST_BURST
7892     {
7893       int i;
7894       for (i = 0; i < first_burst_size; i++) {
7895 	if((len=send(send_socket,
7896 		     send_ring->buffer_ptr,
7897 		     req_size,
7898 		     0)) != req_size) {
7899 	  /* we should never hit the end of the test in the first burst */
7900 	  perror("send_udp_rr: initial burst data send error");
7901 	  exit(-1);
7902 	}
7903       }
7904     }
7905 #endif /* WANT_FIRST_BURST */
7906 
7907     while ((!times_up) || (trans_remaining > 0)) {
7908       /* send the request */
7909 #ifdef WANT_HISTOGRAM
7910       if (verbosity > 1) {
7911 	HIST_timestamp(&time_one);
7912       }
7913 #endif
7914       if((len=send(send_socket,
7915 		   send_ring->buffer_ptr,
7916 		   req_size,
7917 		   0)) != req_size) {
7918         if (SOCKET_EINTR(len)) {
7919 	      /* We likely hit */
7920 	      /* test-end time. */
7921 	      break;
7922 		}
7923 	    perror("send_udp_rr: data send error");
7924 	    exit(1);
7925 	  }
7926       send_ring = send_ring->next;
7927 
7928       /* receive the response. with UDP we will get it all, or nothing */
7929 
7930       if((rsp_bytes_recvd=recv(send_socket,
7931 			       recv_ring->buffer_ptr,
7932 			       rsp_size,
7933 			       0)) != rsp_size) {
7934 	    if (SOCKET_EINTR(rsp_bytes_recvd))
7935 		{
7936     	  /* Again, we have likely hit test-end time */
7937 	      break;
7938 		}
7939 	    perror("send_udp_rr: data recv error");
7940 	    exit(1);
7941       }
7942       recv_ring = recv_ring->next;
7943 
7944 #ifdef WANT_HISTOGRAM
7945       if (verbosity > 1) {
7946 	HIST_timestamp(&time_two);
7947 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
7948       }
7949 
7950 #endif
7951 
7952       /* at this point, we may wish to sleep for some period of */
7953       /* time, so we see how long that last transaction just took, */
7954       /* and sleep for the difference of that and the interval. We */
7955       /* will not sleep if the time would be less than a */
7956       /* millisecond.  */
7957 
7958 #ifdef WANT_DEMO
7959       demo_rr_interval(1);
7960 #endif
7961 
7962 #ifdef WANT_INTERVALS
7963       INTERVALS_WAIT();
7964 #endif /* WANT_INTERVALS */
7965 
7966       nummessages++;
7967       if (trans_remaining) {
7968 	trans_remaining--;
7969       }
7970 
7971       if (debug > 3) {
7972 	if ((nummessages % 100) == 0) {
7973 	  fprintf(where,"Transaction %d completed\n",nummessages);
7974 	  fflush(where);
7975 	}
7976       }
7977 
7978     }
7979 
7980     /* for some strange reason, I used to call shutdown on the UDP */
7981     /* data socket here. I'm not sure why, because it would not have */
7982     /* any effect... raj 11/94 */
7983 
7984     /* this call will always give us the elapsed time for the test, and */
7985     /* will also store-away the necessaries for cpu utilization */
7986 
7987     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
7988 						/* measured? how long */
7989 						/* did we really run? */
7990 
7991 #if defined(WANT_INTERVALS)
7992 #ifdef WIN32
7993     stop_itimer();
7994 #endif
7995 #endif /* WANT_INTERVALS */
7996 
7997     if (!no_control) {
7998       /* Get the statistics from the remote end. The remote will have
7999 	 calculated service demand and all those interesting
8000 	 things. If it wasn't supposed to care, it will return obvious
8001 	 values. */
8002 
8003       recv_response();
8004       if (!netperf_response.content.serv_errno) {
8005 	if (debug)
8006 	  fprintf(where,"remote results obtained\n");
8007       }
8008       else {
8009 	Set_errno(netperf_response.content.serv_errno);
8010 	fprintf(where,
8011 		"netperf: remote error %d",
8012 		netperf_response.content.serv_errno);
8013 	perror("");
8014 	fflush(where);
8015 	exit(1);
8016       }
8017     }
8018 
8019     /* We now calculate what our thruput was for the test. In the */
8020     /* future, we may want to include a calculation of the thruput */
8021     /* measured by the remote, but it should be the case that for a */
8022     /* UDP rr test, that the two numbers should be *very* close... */
8023     /* We calculate bytes_sent regardless of the way the test length */
8024     /* was controlled.  */
8025 
8026     bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
8027     thruput	= nummessages / elapsed_time;
8028 
8029     if (local_cpu_usage || remote_cpu_usage) {
8030 
8031       /* We must now do a little math for service demand and cpu */
8032       /* utilization for the system(s) Of course, some of the */
8033       /* information might be bogus because there was no idle counter */
8034       /* in the kernel(s). We need to make a note of this for the */
8035       /* user's benefit by placing a code for the metod used in the */
8036       /* test banner */
8037 
8038       if (local_cpu_usage) {
8039 	local_cpu_utilization = calc_cpu_util(0.0);
8040 
8041 	/* since calc_service demand is doing ms/Kunit we will */
8042 	/* multiply the number of transaction by 1024 to get */
8043 	/* "good" numbers */
8044 
8045 	local_service_demand  = calc_service_demand((double) nummessages*1024,
8046 						    0.0,
8047 						    0.0,
8048 						    0);
8049       }
8050       else {
8051 	local_cpu_utilization	= (float) -1.0;
8052 	local_service_demand	= (float) -1.0;
8053       }
8054 
8055       if (remote_cpu_usage) {
8056 	remote_cpu_utilization = udp_rr_result->cpu_util;
8057 
8058 	/* since calc_service demand is doing ms/Kunit we will */
8059 	/* multiply the number of transaction by 1024 to get */
8060 	/* "good" numbers */
8061 
8062 	remote_service_demand  = calc_service_demand((double) nummessages*1024,
8063 						     0.0,
8064 						     remote_cpu_utilization,
8065 						     udp_rr_result->num_cpus);
8066       }
8067       else {
8068 	remote_cpu_utilization = (float) -1.0;
8069 	remote_service_demand  = (float) -1.0;
8070       }
8071     }
8072     else {
8073       /* we were not measuring cpu, for the confidence stuff, we */
8074       /* should make it -1.0 */
8075       local_cpu_utilization	= (float) -1.0;
8076       local_service_demand	= (float) -1.0;
8077       remote_cpu_utilization = (float) -1.0;
8078       remote_service_demand  = (float) -1.0;
8079     }
8080 
8081     /* at this point, we want to calculate the confidence information. */
8082     /* if debugging is on, calculate_confidence will print-out the */
8083     /* parameters we pass it */
8084 
8085     calculate_confidence(confidence_iteration,
8086 			 elapsed_time,
8087 			 thruput,
8088 			 local_cpu_utilization,
8089 			 remote_cpu_utilization,
8090 			 local_service_demand,
8091 			 remote_service_demand);
8092 
8093 
8094     confidence_iteration++;
8095 
8096     /* we are done with the socket */
8097     close(send_socket);
8098   }
8099 
8100   /* at this point, we have made all the iterations we are going to */
8101   /* make. */
8102   retrieve_confident_values(&elapsed_time,
8103 			    &thruput,
8104 			    &local_cpu_utilization,
8105 			    &remote_cpu_utilization,
8106 			    &local_service_demand,
8107 			    &remote_service_demand);
8108 
8109   /* We are now ready to print all the information. If the user */
8110   /* has specified zero-level verbosity, we will just print the */
8111   /* local service demand, or the remote service demand. If the */
8112   /* user has requested verbosity level 1, he will get the basic */
8113   /* "streamperf" numbers. If the user has specified a verbosity */
8114   /* of greater than 1, we will display a veritable plethora of */
8115   /* background information from outside of this block as it it */
8116   /* not cpu_measurement specific...  */
8117 
8118   if (confidence < 0) {
8119     /* we did not hit confidence, but were we asked to look for it? */
8120     if (iteration_max > 1) {
8121       display_confidence();
8122     }
8123   }
8124 
8125   if (local_cpu_usage || remote_cpu_usage) {
8126     local_cpu_method = format_cpu_method(cpu_method);
8127     remote_cpu_method = format_cpu_method(udp_rr_result->cpu_method);
8128 
8129     switch (verbosity) {
8130     case 0:
8131       if (local_cpu_usage) {
8132 	fprintf(where,
8133 		cpu_fmt_0,
8134 		local_service_demand,
8135 		local_cpu_method,
8136                 ((print_headers) ||
8137                  (result_brand == NULL)) ? "" : result_brand);
8138 
8139       }
8140       else {
8141 	fprintf(where,
8142 		cpu_fmt_0,
8143 		remote_service_demand,
8144 		remote_cpu_method,
8145                 ((print_headers) ||
8146                  (result_brand == NULL)) ? "" : result_brand);
8147 
8148       }
8149       break;
8150     case 1:
8151     case 2:
8152       if (print_headers) {
8153         if ('x' == libfmt) {
8154           fprintf(where,
8155                   cpu_title,
8156                   local_cpu_method,
8157                   remote_cpu_method);
8158         }
8159         else {
8160           fprintf(where,
8161                   cpu_title_tput,
8162                   format_units(),
8163                   local_cpu_method,
8164                   remote_cpu_method);
8165         }
8166       }
8167 
8168       fprintf(where,
8169 	      cpu_fmt_1_line_1,		/* the format string */
8170 	      lss_size,		/* local sendbuf size */
8171 	      lsr_size,
8172 	      req_size,		/* how large were the requests */
8173 	      rsp_size,		/* guess */
8174 	      elapsed_time,		/* how long was the test */
8175 	      ('x' == libfmt) ? thruput :
8176 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
8177 									 1.0),
8178 	      local_cpu_utilization,	/* local cpu */
8179 	      remote_cpu_utilization,	/* remote cpu */
8180 	      local_service_demand,	/* local service demand */
8181 	      remote_service_demand,	/* remote service demand */
8182 	      ((print_headers) ||
8183 	       (result_brand == NULL)) ? "" : result_brand);
8184       fprintf(where,
8185 	      cpu_fmt_1_line_2,
8186 	      rss_size,
8187 	      rsr_size);
8188       break;
8189     }
8190   }
8191   else {
8192     /* The tester did not wish to measure service demand. */
8193     switch (verbosity) {
8194     case 0:
8195       fprintf(where,
8196 	      tput_fmt_0,
8197 	      ('x' == libfmt) ? thruput :
8198 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
8199 					 1.0),
8200 	      ((print_headers) ||
8201 	       (result_brand == NULL)) ? "" : result_brand);
8202       break;
8203     case 1:
8204     case 2:
8205       if (print_headers) {
8206 	fprintf(where,
8207 		('x' == libfmt) ? tput_title : tput_title_band,
8208 		format_units());
8209       }
8210 
8211       fprintf(where,
8212 	      tput_fmt_1_line_1,	/* the format string */
8213 	      lss_size,
8214 	      lsr_size,
8215 	      req_size,		/* how large were the requests */
8216 	      rsp_size,		/* how large were the responses */
8217 	      elapsed_time, 		/* how long did it take */
8218 	      ('x' == libfmt) ?  thruput :
8219 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
8220 					 1.0),
8221 	      ((print_headers) ||
8222 	       (result_brand == NULL)) ? "" : result_brand);
8223       fprintf(where,
8224 	      tput_fmt_1_line_2,
8225 	      rss_size, 		/* remote recvbuf size */
8226 	      rsr_size);
8227 
8228       break;
8229     }
8230   }
8231   fflush(where);
8232 
8233   /* it would be a good thing to include information about some of the */
8234   /* other parameters that may have been set for this test, but at the */
8235   /* moment, I do not wish to figure-out all the  formatting, so I will */
8236   /* just put this comment here to help remind me that it is something */
8237   /* that should be done at a later time. */
8238 
8239   /* how to handle the verbose information in the presence of */
8240   /* confidence intervals is yet to be determined... raj 11/94 */
8241 
8242   if (verbosity > 1) {
8243     /* The user wanted to know it all, so we will give it to him. */
8244     /* This information will include as much as we can find about */
8245     /* UDP statistics, the alignments of the sends and receives */
8246     /* and all that sort of rot... */
8247 
8248 #ifdef WANT_HISTOGRAM
8249     fprintf(where,"\nHistogram of request/reponse times.\n");
8250     fflush(where);
8251     HIST_report(time_hist);
8252 #endif /* WANT_HISTOGRAM */
8253   }
8254 }
8255 #endif /* WANT_MIGRATION */
8256 
8257  /* this routine implements the receive side (netserver) of a UDP_RR */
8258  /* test. */
8259 void
recv_udp_rr()8260 recv_udp_rr()
8261 {
8262 
8263   struct ring_elt *recv_ring;
8264   struct ring_elt *send_ring;
8265 
8266   struct addrinfo *local_res;
8267   char local_name[BUFSIZ];
8268   char port_buffer[PORTBUFSIZE];
8269 
8270   struct sockaddr_storage        myaddr_in;
8271   struct sockaddr_storage    peeraddr;
8272   SOCKET	s_data;
8273   netperf_socklen_t 	addrlen;
8274   int	trans_received;
8275   int	trans_remaining;
8276   int   request_bytes_recvd;
8277   int   response_bytes_sent;
8278   float	elapsed_time;
8279 
8280   struct	udp_rr_request_struct	*udp_rr_request;
8281   struct	udp_rr_response_struct	*udp_rr_response;
8282   struct	udp_rr_results_struct	*udp_rr_results;
8283 
8284   udp_rr_request  =
8285     (struct udp_rr_request_struct *)netperf_request.content.test_specific_data;
8286   udp_rr_response =
8287     (struct udp_rr_response_struct *)netperf_response.content.test_specific_data;
8288   udp_rr_results  =
8289     (struct udp_rr_results_struct *)netperf_response.content.test_specific_data;
8290 
8291   if (debug) {
8292     fprintf(where,"netserver: recv_udp_rr: entered...\n");
8293     fflush(where);
8294   }
8295 
8296   /* We want to set-up the listen socket with all the desired */
8297   /* parameters and then let the initiator know that all is ready. If */
8298   /* socket size defaults are to be used, then the initiator will have */
8299   /* sent us 0's. If the socket sizes cannot be changed, then we will */
8300   /* send-back what they are. If that information cannot be determined, */
8301   /* then we send-back -1's for the sizes. If things go wrong for any */
8302   /* reason, we will drop back ten yards and punt. */
8303 
8304   /* If anything goes wrong, we want the remote to know about it. It */
8305   /* would be best if the error that the remote reports to the user is */
8306   /* the actual error we encountered, rather than some bogus unexpected */
8307   /* response type message. */
8308 
8309   if (debug) {
8310     fprintf(where,"recv_udp_rr: setting the response type...\n");
8311     fflush(where);
8312   }
8313 
8314   netperf_response.content.response_type = UDP_RR_RESPONSE;
8315 
8316   if (debug) {
8317     fprintf(where,"recv_udp_rr: the response type is set...\n");
8318     fflush(where);
8319   }
8320 
8321   /* We now alter the message_ptr variables to be at the desired */
8322   /* alignments with the desired offsets. */
8323 
8324   if (debug) {
8325     fprintf(where,"recv_udp_rr: requested recv alignment of %d offset %d\n",
8326 	    udp_rr_request->recv_alignment,
8327 	    udp_rr_request->recv_offset);
8328     fprintf(where,"recv_udp_rr: requested send alignment of %d offset %d\n",
8329 	    udp_rr_request->send_alignment,
8330 	    udp_rr_request->send_offset);
8331     fflush(where);
8332   }
8333 
8334   if (send_width == 0) send_width = 1;
8335   if (recv_width == 0) recv_width = 1;
8336 
8337   recv_ring = allocate_buffer_ring(recv_width,
8338 				   udp_rr_request->request_size,
8339 				   udp_rr_request->recv_alignment,
8340 				   udp_rr_request->recv_offset);
8341 
8342   send_ring = allocate_buffer_ring(send_width,
8343 				   udp_rr_request->response_size,
8344 				   udp_rr_request->send_alignment,
8345 				   udp_rr_request->send_offset);
8346 
8347   if (debug) {
8348     fprintf(where,"recv_udp_rr: receive alignment and offset set...\n");
8349     fflush(where);
8350   }
8351 
8352   /* Grab a socket to listen on, and then listen on it. */
8353 
8354   if (debug) {
8355     fprintf(where,"recv_udp_rr: grabbing a socket...\n");
8356     fflush(where);
8357   }
8358 
8359 
8360   /* create_data_socket expects to find some things in the global */
8361   /* variables, so set the globals based on the values in the request. */
8362   /* once the socket has been created, we will set the response values */
8363   /* based on the updated value of those globals. raj 7/94 */
8364   lss_size_req = udp_rr_request->send_buf_size;
8365   lsr_size_req = udp_rr_request->recv_buf_size;
8366   loc_rcvavoid = udp_rr_request->so_rcvavoid;
8367   loc_sndavoid = udp_rr_request->so_sndavoid;
8368 
8369   set_hostname_and_port(local_name,
8370 			port_buffer,
8371 			nf_to_af(udp_rr_request->ipfamily),
8372 			udp_rr_request->port);
8373 
8374   local_res = complete_addrinfo(local_name,
8375 				local_name,
8376 				port_buffer,
8377 				nf_to_af(udp_rr_request->ipfamily),
8378 				SOCK_DGRAM,
8379 				IPPROTO_UDP,
8380 				0);
8381 
8382   s_data = create_data_socket(local_res);
8383 
8384   if (s_data == INVALID_SOCKET) {
8385     netperf_response.content.serv_errno = errno;
8386     send_response();
8387 
8388     exit(1);
8389   }
8390 
8391   /* now get the port number assigned by the system  */
8392   addrlen = sizeof(myaddr_in);
8393   if (getsockname(s_data,
8394 		  (struct sockaddr *)&myaddr_in,
8395 		  &addrlen) == SOCKET_ERROR){
8396     netperf_response.content.serv_errno = errno;
8397     close(s_data);
8398     send_response();
8399 
8400     exit(1);
8401   }
8402 
8403   /* Now myaddr_in contains the port and the internet address this is */
8404   /* returned to the sender also implicitly telling the sender that the */
8405   /* socket buffer sizing has been done. */
8406 
8407   udp_rr_response->data_port_number =
8408     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
8409   netperf_response.content.serv_errno   = 0;
8410 
8411   if (debug) {
8412     fprintf(where,
8413 	    "recv port number %d\n",
8414 	    ((struct sockaddr_in *)&myaddr_in)->sin_port);
8415     fflush(where);
8416   }
8417 
8418   /* But wait, there's more. If the initiator wanted cpu measurements, */
8419   /* then we must call the calibrate routine, which will return the max */
8420   /* rate back to the initiator. If the CPU was not to be measured, or */
8421   /* something went wrong with the calibration, we will return a 0.0 to */
8422   /* the initiator. */
8423 
8424   udp_rr_response->cpu_rate    = (float)0.0; 	/* assume no cpu */
8425   udp_rr_response->measure_cpu = 0;
8426   if (udp_rr_request->measure_cpu) {
8427     udp_rr_response->measure_cpu = 1;
8428     udp_rr_response->cpu_rate = calibrate_local_cpu(udp_rr_request->cpu_rate);
8429   }
8430 
8431   /* before we send the response back to the initiator, pull some of */
8432   /* the socket parms from the globals */
8433   udp_rr_response->send_buf_size = lss_size;
8434   udp_rr_response->recv_buf_size = lsr_size;
8435   udp_rr_response->so_rcvavoid   = loc_rcvavoid;
8436   udp_rr_response->so_sndavoid   = loc_sndavoid;
8437 
8438   send_response();
8439 
8440 
8441   /* Now it's time to start receiving data on the connection. We will */
8442   /* first grab the apropriate counters and then start grabbing. */
8443 
8444   cpu_start(udp_rr_request->measure_cpu);
8445 
8446 #ifdef WIN32
8447   /* this is used so the timer thread can close the socket out from */
8448   /* under us, which to date is the easiest/cleanest/least */
8449   /* Windows-specific way I can find to force the winsock calls to */
8450   /* return WSAEINTR with the test is over. anything that will run on */
8451   /* 95 and NT and is closer to what netperf expects from Unix signals */
8452   /* and such would be appreciated raj 1/96 */
8453   win_kludge_socket = s_data;
8454 #endif /* WIN32 */
8455 
8456   if (udp_rr_request->test_length > 0) {
8457     times_up = 0;
8458     trans_remaining = 0;
8459     start_timer(udp_rr_request->test_length + PAD_TIME);
8460   }
8461   else {
8462     times_up = 1;
8463     trans_remaining = udp_rr_request->test_length * -1;
8464   }
8465 
8466   addrlen = sizeof(peeraddr);
8467   bzero((char *)&peeraddr, addrlen);
8468 
8469   trans_received = 0;
8470 
8471   while ((!times_up) || (trans_remaining > 0)) {
8472 
8473     /* receive the request from the other side */
8474     if ((request_bytes_recvd = recvfrom(s_data,
8475 		 recv_ring->buffer_ptr,
8476 		 udp_rr_request->request_size,
8477 		 0,
8478 		 (struct sockaddr *)&peeraddr,
8479 		 &addrlen)) != udp_rr_request->request_size) {
8480 	  if ( SOCKET_EINTR(request_bytes_recvd) )
8481 	  {
8482 	    /* we must have hit the end of test time. */
8483 	    break;
8484       }
8485       netperf_response.content.serv_errno = errno;
8486       send_response();
8487       exit(1);
8488     }
8489     recv_ring = recv_ring->next;
8490 
8491     /* Now, send the response to the remote */
8492     if ((response_bytes_sent = sendto(s_data,
8493 				      send_ring->buffer_ptr,
8494 				      udp_rr_request->response_size,
8495 				      0,
8496 				      (struct sockaddr *)&peeraddr,
8497 				      addrlen)) !=
8498 	udp_rr_request->response_size) {
8499       if ( SOCKET_EINTR(response_bytes_sent) )
8500 	  {
8501 	    /* we have hit end of test time. */
8502 	    break;
8503       }
8504       netperf_response.content.serv_errno = errno;
8505       send_response();
8506       exit(1);
8507     }
8508     send_ring = send_ring->next;
8509 
8510     trans_received++;
8511     if (trans_remaining) {
8512       trans_remaining--;
8513     }
8514 
8515     if (debug) {
8516       fprintf(where,
8517 	      "recv_udp_rr: Transaction %d complete.\n",
8518 	      trans_received);
8519       fflush(where);
8520     }
8521 
8522   }
8523 
8524 
8525   /* The loop now exits due to timeout or transaction count being */
8526   /* reached */
8527 
8528   cpu_stop(udp_rr_request->measure_cpu,&elapsed_time);
8529 
8530   if (times_up) {
8531     /* we ended the test by time, which was at least 2 seconds */
8532     /* longer than we wanted to run. so, we want to subtract */
8533     /* PAD_TIME from the elapsed_time. */
8534     elapsed_time -= PAD_TIME;
8535   }
8536   /* send the results to the sender			*/
8537 
8538   if (debug) {
8539     fprintf(where,
8540 	    "recv_udp_rr: got %d transactions\n",
8541 	    trans_received);
8542     fflush(where);
8543   }
8544 
8545   udp_rr_results->bytes_received = (trans_received *
8546 				    (udp_rr_request->request_size +
8547 				     udp_rr_request->response_size));
8548   udp_rr_results->trans_received = trans_received;
8549   udp_rr_results->elapsed_time	 = elapsed_time;
8550   udp_rr_results->cpu_method     = cpu_method;
8551   udp_rr_results->num_cpus       = lib_num_loc_cpus;
8552   if (udp_rr_request->measure_cpu) {
8553     udp_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
8554   }
8555 
8556   if (debug) {
8557     fprintf(where,
8558 	    "recv_udp_rr: test complete, sending results.\n");
8559     fflush(where);
8560   }
8561 
8562   send_response();
8563 
8564   /* we are done with the socket now */
8565   close(s_data);
8566 
8567       }
8568 
8569 
8570  /* this routine implements the receive (netserver) side of a TCP_RR */
8571  /* test */
8572 void
recv_tcp_rr()8573 recv_tcp_rr()
8574 {
8575 
8576   struct ring_elt *send_ring;
8577   struct ring_elt *recv_ring;
8578 
8579   struct addrinfo *local_res;
8580   char local_name[BUFSIZ];
8581   char port_buffer[PORTBUFSIZE];
8582 
8583   struct	sockaddr_storage        myaddr_in,
8584   peeraddr_in;
8585   SOCKET	s_listen,s_data;
8586   netperf_socklen_t 	addrlen;
8587   char	*temp_message_ptr;
8588   int	trans_received;
8589   int	trans_remaining;
8590   int	bytes_sent;
8591   int	request_bytes_recvd;
8592   int	request_bytes_remaining;
8593   int	timed_out = 0;
8594   int   sock_closed = 0;
8595   float	elapsed_time;
8596 
8597   struct	tcp_rr_request_struct	*tcp_rr_request;
8598   struct	tcp_rr_response_struct	*tcp_rr_response;
8599   struct	tcp_rr_results_struct	*tcp_rr_results;
8600 
8601   tcp_rr_request =
8602     (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data;
8603   tcp_rr_response =
8604     (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data;
8605   tcp_rr_results =
8606     (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data;
8607 
8608   if (debug) {
8609     fprintf(where,"netserver: recv_tcp_rr: entered...\n");
8610     fflush(where);
8611   }
8612 
8613   /* We want to set-up the listen socket with all the desired */
8614   /* parameters and then let the initiator know that all is ready. If */
8615   /* socket size defaults are to be used, then the initiator will have */
8616   /* sent us 0's. If the socket sizes cannot be changed, then we will */
8617   /* send-back what they are. If that information cannot be determined, */
8618   /* then we send-back -1's for the sizes. If things go wrong for any */
8619   /* reason, we will drop back ten yards and punt. */
8620 
8621   /* If anything goes wrong, we want the remote to know about it. It */
8622   /* would be best if the error that the remote reports to the user is */
8623   /* the actual error we encountered, rather than some bogus unexpected */
8624   /* response type message. */
8625 
8626   if (debug) {
8627     fprintf(where,"recv_tcp_rr: setting the response type...\n");
8628     fflush(where);
8629   }
8630 
8631   netperf_response.content.response_type = TCP_RR_RESPONSE;
8632 
8633   if (debug) {
8634     fprintf(where,"recv_tcp_rr: the response type is set...\n");
8635     fflush(where);
8636   }
8637 
8638   /* allocate the recv and send rings with the requested alignments */
8639   /* and offsets. raj 7/94 */
8640   if (debug) {
8641     fprintf(where,"recv_tcp_rr: requested recv alignment of %d offset %d\n",
8642 	    tcp_rr_request->recv_alignment,
8643 	    tcp_rr_request->recv_offset);
8644     fprintf(where,"recv_tcp_rr: requested send alignment of %d offset %d\n",
8645 	    tcp_rr_request->send_alignment,
8646 	    tcp_rr_request->send_offset);
8647     fflush(where);
8648   }
8649 
8650   /* at some point, these need to come to us from the remote system */
8651   if (send_width == 0) send_width = 1;
8652   if (recv_width == 0) recv_width = 1;
8653 
8654   send_ring = allocate_buffer_ring(send_width,
8655 				   tcp_rr_request->response_size,
8656 				   tcp_rr_request->send_alignment,
8657 				   tcp_rr_request->send_offset);
8658 
8659   recv_ring = allocate_buffer_ring(recv_width,
8660 				   tcp_rr_request->request_size,
8661 				   tcp_rr_request->recv_alignment,
8662 				   tcp_rr_request->recv_offset);
8663 
8664 
8665   /* Grab a socket to listen on, and then listen on it. */
8666 
8667   if (debug) {
8668     fprintf(where,"recv_tcp_rr: grabbing a socket...\n");
8669     fflush(where);
8670   }
8671 
8672   /* create_data_socket expects to find some things in the global */
8673   /* variables, so set the globals based on the values in the request. */
8674   /* once the socket has been created, we will set the response values */
8675   /* based on the updated value of those globals. raj 7/94 */
8676   lss_size_req = tcp_rr_request->send_buf_size;
8677   lsr_size_req = tcp_rr_request->recv_buf_size;
8678   loc_nodelay = tcp_rr_request->no_delay;
8679   loc_rcvavoid = tcp_rr_request->so_rcvavoid;
8680   loc_sndavoid = tcp_rr_request->so_sndavoid;
8681 
8682   set_hostname_and_port(local_name,
8683 			port_buffer,
8684 			nf_to_af(tcp_rr_request->ipfamily),
8685 			tcp_rr_request->port);
8686 
8687   local_res = complete_addrinfo(local_name,
8688 				local_name,
8689 				port_buffer,
8690 				nf_to_af(tcp_rr_request->ipfamily),
8691 				SOCK_STREAM,
8692 				IPPROTO_TCP,
8693 				0);
8694 
8695   s_listen = create_data_socket(local_res);
8696 
8697   if (s_listen == INVALID_SOCKET) {
8698     netperf_response.content.serv_errno = errno;
8699     send_response();
8700 
8701     exit(1);
8702   }
8703 
8704 
8705 #ifdef WIN32
8706   /* The test timer can fire during operations on the listening socket,
8707      so to make the start_timer below work we have to move
8708      it to close s_listen while we are blocked on accept. */
8709   win_kludge_socket2 = s_listen;
8710 #endif
8711 
8712 
8713   /* Now, let's set-up the socket to listen for connections */
8714   if (listen(s_listen, 5) == SOCKET_ERROR) {
8715     netperf_response.content.serv_errno = errno;
8716     close(s_listen);
8717     send_response();
8718 
8719     exit(1);
8720   }
8721 
8722 
8723   /* now get the port number assigned by the system  */
8724   addrlen = sizeof(myaddr_in);
8725   if (getsockname(s_listen,
8726 		  (struct sockaddr *)&myaddr_in,
8727 		  &addrlen) == SOCKET_ERROR) {
8728     netperf_response.content.serv_errno = errno;
8729     close(s_listen);
8730     send_response();
8731 
8732     exit(1);
8733   }
8734 
8735   /* Now myaddr_in contains the port and the internet address this is */
8736   /* returned to the sender also implicitly telling the sender that the */
8737   /* socket buffer sizing has been done. */
8738 
8739   tcp_rr_response->data_port_number =
8740     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
8741   netperf_response.content.serv_errno   = 0;
8742 
8743   /* But wait, there's more. If the initiator wanted cpu measurements, */
8744   /* then we must call the calibrate routine, which will return the max */
8745   /* rate back to the initiator. If the CPU was not to be measured, or */
8746   /* something went wrong with the calibration, we will return a 0.0 to */
8747   /* the initiator. */
8748 
8749   tcp_rr_response->cpu_rate = (float)0.0; 	/* assume no cpu */
8750   tcp_rr_response->measure_cpu = 0;
8751 
8752   if (tcp_rr_request->measure_cpu) {
8753     tcp_rr_response->measure_cpu = 1;
8754     tcp_rr_response->cpu_rate = calibrate_local_cpu(tcp_rr_request->cpu_rate);
8755   }
8756 
8757 
8758   /* before we send the response back to the initiator, pull some of */
8759   /* the socket parms from the globals */
8760   tcp_rr_response->send_buf_size = lss_size;
8761   tcp_rr_response->recv_buf_size = lsr_size;
8762   tcp_rr_response->no_delay = loc_nodelay;
8763   tcp_rr_response->so_rcvavoid = loc_rcvavoid;
8764   tcp_rr_response->so_sndavoid = loc_sndavoid;
8765   tcp_rr_response->test_length = tcp_rr_request->test_length;
8766   send_response();
8767 
8768   addrlen = sizeof(peeraddr_in);
8769 
8770   if ((s_data = accept(s_listen,
8771 		       (struct sockaddr *)&peeraddr_in,
8772 		       &addrlen)) == INVALID_SOCKET) {
8773     /* Let's just punt. The remote will be given some information */
8774     close(s_listen);
8775 
8776     exit(1);
8777   }
8778 
8779 #ifdef KLUDGE_SOCKET_OPTIONS
8780   /* this is for those systems which *INCORRECTLY* fail to pass */
8781   /* attributes across an accept() call. Including this goes against */
8782   /* my better judgement :( raj 11/95 */
8783 
8784   kludge_socket_options(s_data);
8785 
8786 #endif /* KLUDGE_SOCKET_OPTIONS */
8787 
8788 #ifdef WIN32
8789   /* this is used so the timer thread can close the socket out from */
8790   /* under us, which to date is the easiest/cleanest/least */
8791   /* Windows-specific way I can find to force the winsock calls to */
8792   /* return WSAEINTR with the test is over. anything that will run on */
8793   /* 95 and NT and is closer to what netperf expects from Unix signals */
8794   /* and such would be appreciated raj 1/96 */
8795   win_kludge_socket = s_data;
8796   win_kludge_socket2 = INVALID_SOCKET;
8797 #endif /* WIN32 */
8798 
8799   if (debug) {
8800     fprintf(where,"recv_tcp_rr: accept completes on the data connection.\n");
8801     fflush(where);
8802   }
8803 
8804   /* Now it's time to start receiving data on the connection. We will */
8805   /* first grab the apropriate counters and then start grabbing. */
8806 
8807   cpu_start(tcp_rr_request->measure_cpu);
8808 
8809   /* The loop will exit when we hit the end of the test time, or when */
8810   /* we have exchanged the requested number of transactions. */
8811 
8812   if (tcp_rr_request->test_length > 0) {
8813     times_up = 0;
8814     trans_remaining = 0;
8815     start_timer(tcp_rr_request->test_length + PAD_TIME);
8816   }
8817   else {
8818     times_up = 1;
8819     trans_remaining = tcp_rr_request->test_length * -1;
8820   }
8821 
8822   trans_received = 0;
8823 
8824   while ((!times_up) || (trans_remaining > 0)) {
8825     temp_message_ptr = recv_ring->buffer_ptr;
8826     request_bytes_remaining	= tcp_rr_request->request_size;
8827     while(request_bytes_remaining > 0) {
8828       if((request_bytes_recvd=recv(s_data,
8829 				   temp_message_ptr,
8830 				   request_bytes_remaining,
8831 				   0)) == SOCKET_ERROR) {
8832 	if (SOCKET_EINTR(request_bytes_recvd))
8833 	{
8834 	  timed_out = 1;
8835 	  break;
8836 	}
8837 
8838 	netperf_response.content.serv_errno = errno;
8839 	send_response();
8840 	exit(1);
8841       }
8842       else if( request_bytes_recvd == 0 ) {
8843 	if (debug) {
8844 	  fprintf(where,"zero is my hero\n");
8845 	  fflush(where);
8846 	}
8847 	sock_closed = 1;
8848 	break;
8849       }
8850       else {
8851 	request_bytes_remaining -= request_bytes_recvd;
8852 	temp_message_ptr  += request_bytes_recvd;
8853       }
8854     }
8855 
8856     recv_ring = recv_ring->next;
8857 
8858     if ((timed_out) || (sock_closed)) {
8859       /* we hit the end of the test based on time - or the socket
8860 	 closed on us along the way.  bail out of here now... */
8861       if (debug) {
8862 	fprintf(where,"yo5\n");
8863 	fflush(where);
8864       }
8865       break;
8866     }
8867 
8868     /* Now, send the response to the remote */
8869     if((bytes_sent=send(s_data,
8870 			send_ring->buffer_ptr,
8871 			tcp_rr_request->response_size,
8872 			0)) == SOCKET_ERROR) {
8873       if (SOCKET_EINTR(bytes_sent)) {
8874 	/* the test timer has popped */
8875 	timed_out = 1;
8876 	fprintf(where,"yo6\n");
8877 	fflush(where);
8878 	break;
8879       }
8880       netperf_response.content.serv_errno = 992;
8881       send_response();
8882       exit(1);
8883     }
8884 
8885     send_ring = send_ring->next;
8886 
8887     trans_received++;
8888     if (trans_remaining) {
8889       trans_remaining--;
8890     }
8891   }
8892 
8893 
8894   /* The loop now exits due to timeout or transaction count being */
8895   /* reached */
8896 
8897   cpu_stop(tcp_rr_request->measure_cpu,&elapsed_time);
8898 
8899   stop_timer();
8900 
8901   if (timed_out) {
8902     /* we ended the test by time, which was at least 2 seconds */
8903     /* longer than we wanted to run. so, we want to subtract */
8904     /* PAD_TIME from the elapsed_time. */
8905     elapsed_time -= PAD_TIME;
8906   }
8907 
8908   /* send the results to the sender			*/
8909 
8910   if (debug) {
8911     fprintf(where,
8912 	    "recv_tcp_rr: got %d transactions\n",
8913 	    trans_received);
8914     fflush(where);
8915   }
8916 
8917   tcp_rr_results->bytes_received = (trans_received *
8918 				    (tcp_rr_request->request_size +
8919 				     tcp_rr_request->response_size));
8920   tcp_rr_results->trans_received = trans_received;
8921   tcp_rr_results->elapsed_time   = elapsed_time;
8922   tcp_rr_results->cpu_method     = cpu_method;
8923   tcp_rr_results->num_cpus       = lib_num_loc_cpus;
8924   if (tcp_rr_request->measure_cpu) {
8925     tcp_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
8926   }
8927 
8928   if (debug) {
8929     fprintf(where,
8930 	    "recv_tcp_rr: test complete, sending results.\n");
8931     fflush(where);
8932   }
8933 
8934   /* we are now done with the sockets */
8935   close(s_data);
8936   close(s_listen);
8937 
8938   send_response();
8939 
8940 }
8941 
8942 
8943 void
loc_cpu_rate()8944 loc_cpu_rate()
8945 {
8946 #if defined(USE_LOOPER)
8947   float dummy;
8948 #endif
8949 
8950   /* a rather simple little test - it merely calibrates the local cpu */
8951   /* and prints the results. There are no headers to allow someone to */
8952   /* find a rate and use it in other tests automagically by setting a */
8953   /* variable equal to the output of this test. We ignore any rates */
8954   /* that may have been specified. In fact, we ignore all of the */
8955   /* command line args! */
8956 
8957   fprintf(where,
8958 	  "%g",
8959 	  calibrate_local_cpu(0.0));
8960 
8961   if (verbosity > 1)
8962     fprintf(where,
8963 	    "\nThere %s %d local %s\n",
8964 	    (lib_num_loc_cpus > 1) ? "are" : "is",
8965 	    lib_num_loc_cpus,
8966 	    (lib_num_loc_cpus > 1) ? "cpus" : "cpu");
8967 
8968   /* we need the cpu_start, cpu_stop in the looper case to kill the */
8969   /* child proceses raj 4/95 */
8970 
8971 #ifdef USE_LOOPER
8972   cpu_start(1);
8973   cpu_stop(1,&dummy);
8974 #endif /* USE_LOOPER */
8975 
8976 }
8977 
8978 void
rem_cpu_rate()8979 rem_cpu_rate()
8980 {
8981   /* this test is much like the local variant, except that it works for */
8982   /* the remote system, so in this case, we do pay attention to the */
8983   /* value of the '-H' command line argument. */
8984 
8985   fprintf(where,
8986 	  "%g",
8987 	  calibrate_remote_cpu());
8988 
8989   if (verbosity > 1)
8990     fprintf(where,
8991 	    "\nThere %s %d remote %s\n",
8992 	    (lib_num_rem_cpus > 1) ? "are" : "is",
8993 	    lib_num_rem_cpus,
8994 	    (lib_num_rem_cpus > 1) ? "cpus" : "cpu");
8995 
8996 }
8997 
8998 
8999 #ifndef WANT_MIGRATION
9000  /* this test is intended to test the performance of establishing a
9001     connection, exchanging a request/response pair, and repeating. it
9002     is expected that this would be a good starting-point for
9003     comparision of T/TCP with classic TCP for transactional workloads.
9004     it will also look (can look) much like the communication pattern
9005     of http for www access. */
9006 
9007 void
send_tcp_conn_rr(char remote_host[])9008 send_tcp_conn_rr(char remote_host[])
9009 {
9010 
9011   char *tput_title = "\
9012 Local /Remote\n\
9013 Socket Size   Request  Resp.   Elapsed  Trans.\n\
9014 Send   Recv   Size     Size    Time     Rate         \n\
9015 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
9016 
9017   char *tput_fmt_0 =
9018     "%7.2f\n";
9019 
9020   char *tput_fmt_1_line_1 = "\
9021 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
9022   char *tput_fmt_1_line_2 = "\
9023 %-6d %-6d\n";
9024 
9025   char *cpu_title = "\
9026 Local /Remote\n\
9027 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
9028 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
9029 bytes  bytes  bytes   bytes  secs.   per sec  %%      %%      us/Tr   us/Tr\n\n";
9030 
9031   char *cpu_fmt_0 =
9032     "%6.3f\n";
9033 
9034   char *cpu_fmt_1_line_1 = "\
9035 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f\n";
9036 
9037   char *cpu_fmt_1_line_2 = "\
9038 %-6d %-6d\n";
9039 
9040   char *ksink_fmt = "\n\
9041 Alignment      Offset\n\
9042 Local  Remote  Local  Remote\n\
9043 Send   Recv    Send   Recv\n\
9044 %5d  %5d   %5d  %5d\n";
9045 
9046 
9047   int			timed_out = 0;
9048   float			elapsed_time;
9049 
9050   int	len;
9051   struct ring_elt *send_ring;
9052   struct ring_elt *recv_ring;
9053   char	*temp_message_ptr;
9054   int	nummessages;
9055   SOCKET	send_socket;
9056   int	trans_remaining;
9057   double	bytes_xferd;
9058   int	rsp_bytes_left;
9059   int	rsp_bytes_recvd;
9060 
9061   float	local_cpu_utilization;
9062   float	local_service_demand;
9063   float	remote_cpu_utilization;
9064   float	remote_service_demand;
9065   double	thruput;
9066 
9067   struct addrinfo *local_res;
9068   struct addrinfo *remote_res;
9069 
9070   int                           myport;
9071   int                           ret;
9072 
9073   struct	tcp_conn_rr_request_struct	*tcp_conn_rr_request;
9074   struct	tcp_conn_rr_response_struct	*tcp_conn_rr_response;
9075   struct	tcp_conn_rr_results_struct	*tcp_conn_rr_result;
9076 
9077   tcp_conn_rr_request =
9078     (struct tcp_conn_rr_request_struct *)netperf_request.content.test_specific_data;
9079   tcp_conn_rr_response =
9080     (struct tcp_conn_rr_response_struct *)netperf_response.content.test_specific_data;
9081   tcp_conn_rr_result =
9082     (struct tcp_conn_rr_results_struct *)netperf_response.content.test_specific_data;
9083 
9084 
9085 #ifdef WANT_HISTOGRAM
9086   if (verbosity > 1) {
9087     time_hist = HIST_new();
9088   }
9089 #endif /* WANT_HISTOGRAM */
9090 
9091   /* since we are now disconnected from the code that established the */
9092   /* control socket, and since we want to be able to use different */
9093   /* protocols and such, we are passed the name of the remote host and */
9094   /* must turn that into the test specific addressing information. */
9095 
9096   complete_addrinfos(&remote_res,
9097 		     &local_res,
9098 		     remote_host,
9099 		     SOCK_STREAM,
9100 		     IPPROTO_TCP,
9101 		     0);
9102 
9103   if ( print_headers ) {
9104     print_top_test_header("TCP Connect/Request/Response TEST",local_res,remote_res);
9105   }
9106 
9107   /* initialize a few counters */
9108 
9109   nummessages	=	0;
9110   bytes_xferd	=	0.0;
9111   times_up 	= 	0;
9112 
9113   /* set-up the data buffers with the requested alignment and offset */
9114   if (send_width == 0) send_width = 1;
9115   if (recv_width == 0) recv_width = 1;
9116 
9117   send_ring = allocate_buffer_ring(send_width,
9118 				   req_size,
9119 				   local_send_align,
9120 				   local_send_offset);
9121 
9122   recv_ring = allocate_buffer_ring(recv_width,
9123 				   rsp_size,
9124 				   local_recv_align,
9125 				   local_recv_offset);
9126 
9127 
9128   if (debug) {
9129     fprintf(where,"send_tcp_conn_rr: send_socket obtained...\n");
9130   }
9131 
9132   /* If the user has requested cpu utilization measurements, we must */
9133   /* calibrate the cpu(s). We will perform this task within the tests */
9134   /* themselves. If the user has specified the cpu rate, then */
9135   /* calibrate_local_cpu will return rather quickly as it will have */
9136   /* nothing to do. If local_cpu_rate is zero, then we will go through */
9137   /* all the "normal" calibration stuff and return the rate back.*/
9138 
9139   if (local_cpu_usage) {
9140     local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
9141   }
9142 
9143   if (!no_control) {
9144 
9145     /* Tell the remote end to do a listen. The server alters the
9146        socket paramters on the other side at this point, hence the
9147        reason for all the values being passed in the setup message. If
9148        the user did not specify any of the parameters, they will be
9149        passed as 0, which will indicate to the remote that no changes
9150        beyond the system's default should be used. Alignment is the
9151        exception, it will default to 8, which will be no alignment
9152        alterations. */
9153 
9154     netperf_request.content.request_type =	DO_TCP_CRR;
9155     tcp_conn_rr_request->recv_buf_size	=	rsr_size_req;
9156     tcp_conn_rr_request->send_buf_size	=	rss_size_req;
9157     tcp_conn_rr_request->recv_alignment	=	remote_recv_align;
9158     tcp_conn_rr_request->recv_offset	=	remote_recv_offset;
9159     tcp_conn_rr_request->send_alignment	=	remote_send_align;
9160     tcp_conn_rr_request->send_offset	=	remote_send_offset;
9161     tcp_conn_rr_request->request_size	=	req_size;
9162     tcp_conn_rr_request->response_size	=	rsp_size;
9163     tcp_conn_rr_request->no_delay	=	rem_nodelay;
9164     tcp_conn_rr_request->measure_cpu	=	remote_cpu_usage;
9165     tcp_conn_rr_request->cpu_rate	=	remote_cpu_rate;
9166     tcp_conn_rr_request->so_rcvavoid	=	rem_rcvavoid;
9167     tcp_conn_rr_request->so_sndavoid	=	rem_sndavoid;
9168     if (test_time) {
9169       tcp_conn_rr_request->test_length	=	test_time;
9170     }
9171     else {
9172       tcp_conn_rr_request->test_length	=	test_trans * -1;
9173     }
9174     tcp_conn_rr_request->port           = atoi(remote_data_port);
9175     tcp_conn_rr_request->ipfamily       = af_to_nf(remote_res->ai_family);
9176 
9177     if (debug > 1) {
9178       fprintf(where,"netperf: send_tcp_conn_rr: requesting TCP crr test\n");
9179     }
9180 
9181     send_request();
9182 
9183     /* The response from the remote will contain all of the relevant
9184        socket parameters for this test type. We will put them back
9185        into the variables here so they can be displayed if desired.
9186        The remote will have calibrated CPU if necessary, and will have
9187        done all the needed set-up we will have calibrated the cpu
9188        locally before sending the request, and will grab the counter
9189        value right after the connect returns. The remote will grab the
9190        counter right after the accept call. This saves the hassle of
9191        extra messages being sent for the TCP tests.  */
9192 
9193     recv_response();
9194 
9195     if (!netperf_response.content.serv_errno) {
9196       rsr_size	       =	tcp_conn_rr_response->recv_buf_size;
9197       rss_size	       =	tcp_conn_rr_response->send_buf_size;
9198       rem_nodelay      =	tcp_conn_rr_response->no_delay;
9199       remote_cpu_usage =	tcp_conn_rr_response->measure_cpu;
9200       remote_cpu_rate  = 	tcp_conn_rr_response->cpu_rate;
9201       /* make sure that port numbers are in network order */
9202       set_port_number(remote_res,
9203 		      (unsigned short)tcp_conn_rr_response->data_port_number);
9204 
9205       if (debug) {
9206 	fprintf(where,"remote listen done.\n");
9207 	fprintf(where,"remote port is %u\n",get_port_number(remote_res));
9208 	fflush(where);
9209       }
9210     }
9211     else {
9212       Set_errno(netperf_response.content.serv_errno);
9213       fprintf(where,
9214 	      "netperf: remote error %d",
9215 	      netperf_response.content.serv_errno);
9216       perror("");
9217       fflush(where);
9218       exit(1);
9219     }
9220   }
9221 #ifdef WANT_DEMO
9222   demo_rr_setup(100);
9223 #endif
9224 
9225   /* pick a nice random spot between client_port_min and */
9226   /* client_port_max for our initial port number */
9227   srand(getpid());
9228   if (client_port_max - client_port_min) {
9229     myport = client_port_min +
9230       (rand() % (client_port_max - client_port_min));
9231   }
9232   else {
9233     myport = client_port_min;
9234   }
9235   /* there will be a ++ before the first call to bind, so subtract one */
9236   myport--;
9237   /* Set-up the test end conditions. For a request/response test, they */
9238   /* can be either time or transaction based. */
9239 
9240   if (test_time) {
9241     /* The user wanted to end the test after a period of time. */
9242     times_up = 0;
9243     trans_remaining = 0;
9244     start_timer(test_time);
9245   }
9246   else {
9247     /* The tester wanted to send a number of bytes. */
9248     trans_remaining = test_bytes;
9249     times_up = 1;
9250   }
9251 
9252   /* The cpu_start routine will grab the current time and possibly */
9253   /* value of the idle counter for later use in measuring cpu */
9254   /* utilization and/or service demand and thruput. */
9255 
9256 
9257   cpu_start(local_cpu_usage);
9258 
9259 #ifdef WANT_DEMO
9260       if (demo_mode) {
9261 	demo_first_timestamp();
9262       }
9263 #endif
9264 
9265   /* We use an "OR" to control test execution. When the test is */
9266   /* controlled by time, the byte count check will always return false. */
9267   /* When the test is controlled by byte count, the time test will */
9268   /* always return false. When the test is finished, the whole */
9269   /* expression will go false and we will stop sending data. I think I */
9270   /* just arbitrarily decrement trans_remaining for the timed test, but */
9271   /* will not do that just yet... One other question is whether or not */
9272   /* the send buffer and the receive buffer should be the same buffer. */
9273 
9274   while ((!times_up) || (trans_remaining > 0)) {
9275 
9276 #ifdef WANT_HISTOGRAM
9277     if (verbosity > 1) {
9278       /* timestamp just before our call to create the socket, and then */
9279       /* again just after the receive raj 3/95 */
9280       HIST_timestamp(&time_one);
9281     }
9282 #endif /* WANT_HISTOGRAM */
9283 
9284 newport:
9285     /* pick a new port number */
9286     myport++;
9287 
9288     /* wrap the port number when we get to client_port_max. NOTE, some */
9289     /* broken TCP's might treat the port number as a signed 16 bit */
9290     /* quantity.  we aren't interested in testing such broken */
9291     /* implementations :) so we won't make sure that it is below 32767 */
9292     /* raj 8/94  */
9293     if (myport >= client_port_max) {
9294       myport = client_port_min;
9295     }
9296 
9297     /* we do not want to use the port number that the server is */
9298     /* sitting at - this would cause us to fail in a loopback test. we */
9299     /* could just rely on the failure of the bind to get us past this, */
9300     /* but I'm guessing that in this one case at least, it is much */
9301     /* faster, given that we *know* that port number is already in use */
9302     /* (or rather would be in a loopback test) */
9303 
9304     if (myport == get_port_number(remote_res)) myport++;
9305 
9306     if (debug) {
9307       if ((nummessages % 100) == 0) {
9308 	printf("port %d\n",myport);
9309       }
9310     }
9311 
9312     /* set up the data socket */
9313     set_port_number(local_res, (unsigned short)myport);
9314     send_socket = create_data_socket(local_res);
9315 
9316     if (send_socket == INVALID_SOCKET) {
9317       perror("netperf: send_tcp_conn_rr: tcp stream data socket");
9318       exit(1);
9319     }
9320 
9321 
9322     /* we used to call bind here, but that is now taken-care-of by the
9323        create_data_socket routine. */
9324 
9325     /* Connect up to the remote port on the data socket  */
9326     if ((ret = connect(send_socket,
9327 		       remote_res->ai_addr,
9328 		       remote_res->ai_addrlen)) == INVALID_SOCKET){
9329       if (SOCKET_EINTR(ret))
9330 	  {
9331 	    /* we hit the end of a */
9332 	    /* timed test. */
9333 	    timed_out = 1;
9334 	    break;
9335       }
9336       if ((SOCKET_EADDRINUSE(ret)) || SOCKET_EADDRNOTAVAIL(ret)) {
9337 	/* likely something our explicit bind() would have caught in
9338            the past, so go get another port, via create_data_socket.
9339            yes, this is a bit more overhead than before, but the
9340            condition should be rather rare.  raj 2005-02-08 */
9341 	close(send_socket);
9342 	goto newport;
9343       }
9344       perror("netperf: data socket connect failed");
9345       printf("\tattempted to connect on socket %d to port %d",
9346 	     send_socket,
9347 	     get_port_number(remote_res));
9348       printf(" from port %d \n",get_port_number(local_res));
9349       exit(1);
9350     }
9351 
9352 
9353     /* send the request */
9354     if((len=send(send_socket,
9355 		 send_ring->buffer_ptr,
9356 		 req_size,
9357 		 0)) != req_size) {
9358       if (SOCKET_EINTR(len))
9359 	  {
9360 	    /* we hit the end of a */
9361 	    /* timed test. */
9362 	    timed_out = 1;
9363 	    break;
9364       }
9365       perror("send_tcp_conn_rr: data send error");
9366       exit(1);
9367     }
9368     send_ring = send_ring->next;
9369 
9370     /* receive the response */
9371     rsp_bytes_left = rsp_size;
9372     temp_message_ptr  = recv_ring->buffer_ptr;
9373 
9374 
9375     do {
9376       rsp_bytes_recvd = recv(send_socket,
9377 			     temp_message_ptr,
9378 			     rsp_bytes_left,
9379 			     0);
9380       if (rsp_bytes_recvd > 0) {
9381 	rsp_bytes_left -= rsp_bytes_recvd;
9382 	temp_message_ptr += rsp_bytes_recvd;
9383       }
9384       else {
9385 	break;
9386       }
9387     } while (rsp_bytes_left);
9388 
9389 
9390     /* OK, we are out of the loop - now what? */
9391     if (rsp_bytes_recvd < 0) {
9392       /* did the timer hit, or was there an error? */
9393       if (SOCKET_EINTR(rsp_bytes_recvd))
9394 	  {
9395 	    /* We hit the end of a timed test. */
9396 	    timed_out = 1;
9397 	    break;
9398 	  }
9399 	  perror("send_tcp_conn_rr: data recv error");
9400 	  exit(1);
9401     }
9402 
9403     /* if this is a no_control test, we initiate connection close,
9404        otherwise the remote netserver does it to remain just like
9405        previous behaviour. raj 2007-27-08 */
9406     if (!no_control) {
9407       shutdown(send_socket,SHUT_WR);
9408     }
9409 
9410     /* we are expecting to get either a return of zero indicating
9411        connection close, or an error.  */
9412     rsp_bytes_recvd = recv(send_socket,
9413 			   temp_message_ptr,
9414 			   1,
9415 			   0);
9416 
9417     /* our exit from the while loop should generally be when */
9418     /* tmp_bytes_recvd is equal to zero, which implies the connection */
9419     /* has been closed by the server side. By waiting until we get the */
9420     /* zero return we can avoid race conditions that stick us with the */
9421     /* TIME_WAIT connection and not the server. raj 8/96 */
9422 
9423 #ifdef VMWARE_UW
9424     /* why this should be for VMware I'm not sure, but it was given as
9425        part of the patches, so we include it here, but put it under an
9426        ifdef VMWARE_UW. raj 2008-07-25 */
9427     if (sp_bytes_recvd < 0 && errno == ECONNRESET) {
9428       rsp_bytes_recvd = 0;
9429     }
9430 #endif /* VMWARE_UW */
9431 
9432     if (rsp_bytes_recvd == 0) {
9433       /* connection close, call close. we assume that the requisite */
9434       /* number of bytes have been received */
9435       recv_ring = recv_ring->next;
9436 
9437 #ifdef WANT_HISTOGRAM
9438       if (verbosity > 1) {
9439 	HIST_timestamp(&time_two);
9440 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
9441       }
9442 #endif /* WANT_HISTOGRAM */
9443 
9444 #ifdef WANT_DEMO
9445       demo_rr_interval(1);
9446 #endif
9447 
9448       nummessages++;
9449       if (trans_remaining) {
9450 	trans_remaining--;
9451       }
9452 
9453       if (debug > 3) {
9454 	fprintf(where,
9455 		"Transaction %d completed on local port %d\n",
9456 		nummessages,
9457 		get_port_number(local_res));
9458 	fflush(where);
9459       }
9460 
9461       close(send_socket);
9462 
9463     }
9464     else {
9465       /* it was less than zero - an error occured */
9466       if (SOCKET_EINTR(rsp_bytes_recvd))
9467 	  {
9468 	    /* We hit the end of a timed test. */
9469 	    timed_out = 1;
9470 	    break;
9471 	  }
9472 	  perror("send_tcp_conn_rr: data recv error");
9473 	  exit(1);
9474     }
9475 
9476   }
9477 
9478 
9479   /* this call will always give us the elapsed time for the test, and */
9480   /* will also store-away the necessaries for cpu utilization */
9481 
9482   cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being measured? */
9483   /* how long did we really run? */
9484 
9485   if (!no_control) {
9486     /* Get the statistics from the remote end. The remote will have
9487        calculated service demand and all those interesting things. If
9488        it wasn't supposed to care, it will return obvious values. */
9489 
9490     recv_response();
9491     if (!netperf_response.content.serv_errno) {
9492       if (debug)
9493 	fprintf(where,"remote results obtained\n");
9494     }
9495     else {
9496       Set_errno(netperf_response.content.serv_errno);
9497       fprintf(where,
9498 	      "netperf: remote error %d",
9499 	      netperf_response.content.serv_errno);
9500       perror("");
9501       fflush(where);
9502 
9503       exit(1);
9504     }
9505   }
9506 
9507   /* We now calculate what our thruput was for the test. In the future, */
9508   /* we may want to include a calculation of the thruput measured by */
9509   /* the remote, but it should be the case that for a TCP stream test, */
9510   /* that the two numbers should be *very* close... We calculate */
9511   /* bytes_sent regardless of the way the test length was controlled. */
9512   /* If it was time, we needed to, and if it was by bytes, the user may */
9513   /* have specified a number of bytes that wasn't a multiple of the */
9514   /* send_size, so we really didn't send what he asked for ;-) We use */
9515   /* Kbytes/s as the units of thruput for a TCP stream test, where K = */
9516   /* 1024. A future enhancement *might* be to choose from a couple of */
9517   /* unit selections. */
9518 
9519   bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
9520   thruput	= calc_thruput(bytes_xferd);
9521 
9522   if (local_cpu_usage || remote_cpu_usage) {
9523     /* We must now do a little math for service demand and cpu */
9524     /* utilization for the system(s) */
9525     /* Of course, some of the information might be bogus because */
9526     /* there was no idle counter in the kernel(s). We need to make */
9527     /* a note of this for the user's benefit...*/
9528     if (local_cpu_usage) {
9529       if (local_cpu_rate == 0.0) {
9530 	fprintf(where,
9531 		"WARNING WARNING WARNING  WARNING WARNING WARNING  WARNING!\n");
9532 	fprintf(where,
9533 		"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,
9553 		"DANGER  DANGER  DANGER    DANGER  DANGER  DANGER    DANGER!\n");
9554 	fprintf(where,
9555 		"Remote CPU usage numbers based on process information only!\n");
9556 	fflush(where);
9557       }
9558       remote_cpu_utilization = tcp_conn_rr_result->cpu_util;
9559       /* since calc_service demand is doing ms/Kunit we will */
9560       /* multiply the number of transaction by 1024 to get */
9561       /* "good" numbers */
9562       remote_service_demand = calc_service_demand((double) nummessages*1024,
9563 						  0.0,
9564 						  remote_cpu_utilization,
9565 						  tcp_conn_rr_result->num_cpus);
9566     }
9567     else {
9568       remote_cpu_utilization = (float) -1.0;
9569       remote_service_demand  = (float) -1.0;
9570     }
9571 
9572     /* We are now ready to print all the information. If the user */
9573     /* has specified zero-level verbosity, we will just print the */
9574     /* local service demand, or the remote service demand. If the */
9575     /* user has requested verbosity level 1, he will get the basic */
9576     /* "streamperf" numbers. If the user has specified a verbosity */
9577     /* of greater than 1, we will display a veritable plethora of */
9578     /* background information from outside of this block as it it */
9579     /* not cpu_measurement specific...  */
9580 
9581     switch (verbosity) {
9582     case 0:
9583       if (local_cpu_usage) {
9584 	fprintf(where,
9585 		cpu_fmt_0,
9586 		local_service_demand);
9587       }
9588       else {
9589 	fprintf(where,
9590 		cpu_fmt_0,
9591 		remote_service_demand);
9592       }
9593       break;
9594     case 1:
9595     case 2:
9596 
9597       if (print_headers) {
9598 	fprintf(where,
9599 		cpu_title,
9600 		local_cpu_method,
9601 		remote_cpu_method);
9602       }
9603 
9604       fprintf(where,
9605 	      cpu_fmt_1_line_1,		/* the format string */
9606 	      lss_size,		/* local sendbuf size */
9607 	      lsr_size,
9608 	      req_size,		/* how large were the requests */
9609 	      rsp_size,		/* guess */
9610 	      elapsed_time,		/* how long was the test */
9611 	      nummessages/elapsed_time,
9612 	      local_cpu_utilization,	/* local cpu */
9613 	      remote_cpu_utilization,	/* remote cpu */
9614 	      local_service_demand,	/* local service demand */
9615 	      remote_service_demand);	/* remote service demand */
9616       fprintf(where,
9617 	      cpu_fmt_1_line_2,
9618 	      rss_size,
9619 	      rsr_size);
9620       break;
9621     }
9622   }
9623   else {
9624     /* The tester did not wish to measure service demand. */
9625     switch (verbosity) {
9626     case 0:
9627       fprintf(where,
9628 	      tput_fmt_0,
9629 	      nummessages/elapsed_time);
9630       break;
9631     case 1:
9632     case 2:
9633       if (print_headers) {
9634 	fprintf(where,tput_title,format_units());
9635       }
9636 
9637       fprintf(where,
9638 	      tput_fmt_1_line_1,	/* the format string */
9639 	      lss_size,
9640 	      lsr_size,
9641 	      req_size,		/* how large were the requests */
9642 	      rsp_size,		/* how large were the responses */
9643 	      elapsed_time, 		/* how long did it take */
9644 	      nummessages/elapsed_time);
9645       fprintf(where,
9646 	      tput_fmt_1_line_2,
9647 	      rss_size, 		/* remote recvbuf size */
9648 	      rsr_size);
9649 
9650       break;
9651     }
9652   }
9653 
9654   /* it would be a good thing to include information about some of the */
9655   /* other parameters that may have been set for this test, but at the */
9656   /* moment, I do not wish to figure-out all the  formatting, so I will */
9657   /* just put this comment here to help remind me that it is something */
9658   /* that should be done at a later time. */
9659 
9660   if (verbosity > 1) {
9661     /* The user wanted to know it all, so we will give it to him. */
9662     /* This information will include as much as we can find about */
9663     /* TCP statistics, the alignments of the sends and receives */
9664     /* and all that sort of rot... */
9665 
9666     fprintf(where,
9667 	    ksink_fmt,
9668 	    local_send_align,
9669 	    remote_recv_offset,
9670 	    local_send_offset,
9671 	    remote_recv_offset);
9672 
9673 #ifdef WANT_HISTOGRAM
9674     fprintf(where,"\nHistogram of request/response times\n");
9675     fflush(where);
9676     HIST_report(time_hist);
9677 #endif /* WANT_HISTOGRAM */
9678 
9679   }
9680 
9681 }
9682 #endif /* WANT_MIGRATION */
9683 
9684 void
recv_tcp_conn_rr()9685 recv_tcp_conn_rr()
9686 {
9687 
9688   char  *message;
9689   struct addrinfo *local_res;
9690   char local_name[BUFSIZ];
9691   char port_buffer[PORTBUFSIZE];
9692 
9693   struct	sockaddr_storage        myaddr_in, peeraddr_in;
9694   SOCKET	s_listen,s_data;
9695   netperf_socklen_t 	addrlen;
9696   char	*recv_message_ptr;
9697   char	*send_message_ptr;
9698   char	*temp_message_ptr;
9699   int	trans_received;
9700   int	trans_remaining;
9701   int	bytes_sent;
9702   int	request_bytes_recvd;
9703   int	request_bytes_remaining;
9704   int	timed_out = 0;
9705   float	elapsed_time;
9706 
9707   struct	tcp_conn_rr_request_struct	*tcp_conn_rr_request;
9708   struct	tcp_conn_rr_response_struct	*tcp_conn_rr_response;
9709   struct	tcp_conn_rr_results_struct	*tcp_conn_rr_results;
9710 
9711   tcp_conn_rr_request =
9712     (struct tcp_conn_rr_request_struct *)netperf_request.content.test_specific_data;
9713   tcp_conn_rr_response =
9714     (struct tcp_conn_rr_response_struct *)netperf_response.content.test_specific_data;
9715   tcp_conn_rr_results =
9716     (struct tcp_conn_rr_results_struct *)netperf_response.content.test_specific_data;
9717 
9718   if (debug) {
9719     fprintf(where,"netserver: recv_tcp_conn_rr: entered...\n");
9720     fflush(where);
9721   }
9722 
9723   /* We want to set-up the listen socket with all the desired */
9724   /* parameters and then let the initiator know that all is ready. If */
9725   /* socket size defaults are to be used, then the initiator will have */
9726   /* sent us 0's. If the socket sizes cannot be changed, then we will */
9727   /* send-back what they are. If that information cannot be determined, */
9728   /* then we send-back -1's for the sizes. If things go wrong for any */
9729   /* reason, we will drop back ten yards and punt. */
9730 
9731   /* If anything goes wrong, we want the remote to know about it. It */
9732   /* would be best if the error that the remote reports to the user is */
9733   /* the actual error we encountered, rather than some bogus unexpected */
9734   /* response type message. */
9735 
9736   if (debug) {
9737     fprintf(where,"recv_tcp_conn_rr: setting the response type...\n");
9738     fflush(where);
9739   }
9740 
9741   netperf_response.content.response_type = TCP_CRR_RESPONSE;
9742 
9743   if (debug) {
9744     fprintf(where,"recv_tcp_conn_rr: the response type is set...\n");
9745     fflush(where);
9746   }
9747 
9748   /* set-up the data buffer with the requested alignment and offset */
9749   message = (char *)malloc(DATABUFFERLEN);
9750   if (message == NULL) {
9751     printf("malloc(%d) failed!\n", DATABUFFERLEN);
9752     exit(1);
9753   }
9754 
9755   /* We now alter the message_ptr variables to be at the desired */
9756   /* alignments with the desired offsets. */
9757 
9758   if (debug) {
9759     fprintf(where,
9760 	    "recv_tcp_conn_rr: requested recv alignment of %d offset %d\n",
9761 	    tcp_conn_rr_request->recv_alignment,
9762 	    tcp_conn_rr_request->recv_offset);
9763     fprintf(where,
9764 	    "recv_tcp_conn_rr: requested send alignment of %d offset %d\n",
9765 	    tcp_conn_rr_request->send_alignment,
9766 	    tcp_conn_rr_request->send_offset);
9767     fflush(where);
9768   }
9769 
9770   recv_message_ptr = ALIGN_BUFFER(message, tcp_conn_rr_request->recv_alignment, tcp_conn_rr_request->recv_offset);
9771 
9772   send_message_ptr = ALIGN_BUFFER(message, tcp_conn_rr_request->send_alignment, tcp_conn_rr_request->send_offset);
9773 
9774   if (debug) {
9775     fprintf(where,"recv_tcp_conn_rr: receive alignment and offset set...\n");
9776     fflush(where);
9777   }
9778 
9779   /* Grab a socket to listen on, and then listen on it. */
9780 
9781   if (debug) {
9782     fprintf(where,"recv_tcp_conn_rr: grabbing a socket...\n");
9783     fflush(where);
9784   }
9785 
9786   /* create_data_socket expects to find some things in the global */
9787   /* variables, so set the globals based on the values in the request. */
9788   /* once the socket has been created, we will set the response values */
9789   /* based on the updated value of those globals. raj 7/94 */
9790   lss_size_req = tcp_conn_rr_request->send_buf_size;
9791   lsr_size_req = tcp_conn_rr_request->recv_buf_size;
9792   loc_nodelay = tcp_conn_rr_request->no_delay;
9793   loc_rcvavoid = tcp_conn_rr_request->so_rcvavoid;
9794   loc_sndavoid = tcp_conn_rr_request->so_sndavoid;
9795 
9796   set_hostname_and_port(local_name,
9797 			port_buffer,
9798 			nf_to_af(tcp_conn_rr_request->ipfamily),
9799 			tcp_conn_rr_request->port);
9800 
9801   local_res = complete_addrinfo(local_name,
9802 				local_name,
9803 				port_buffer,
9804 				nf_to_af(tcp_conn_rr_request->ipfamily),
9805 				SOCK_STREAM,
9806 				IPPROTO_TCP,
9807 				0);
9808 
9809   s_listen = create_data_socket(local_res);
9810 
9811   if (s_listen == INVALID_SOCKET) {
9812     netperf_response.content.serv_errno = errno;
9813     send_response();
9814     if (debug) {
9815       fprintf(where,"could not create data socket\n");
9816       fflush(where);
9817     }
9818     exit(1);
9819   }
9820 
9821 #ifdef WIN32
9822     /* The test timer can fire during operations on the listening socket,
9823        so to make the start_timer below work we have to move
9824        it to close s_listen while we are blocked on accept. */
9825     win_kludge_socket2 = s_listen;
9826 #endif
9827 
9828 
9829   /* Now, let's set-up the socket to listen for connections */
9830   if (listen(s_listen, 128) == SOCKET_ERROR) {
9831     netperf_response.content.serv_errno = errno;
9832     close(s_listen);
9833     send_response();
9834     if (debug) {
9835       fprintf(where,"could not listen\n");
9836       fflush(where);
9837     }
9838     exit(1);
9839   }
9840 
9841   /* now get the port number assigned by the system  */
9842   addrlen = sizeof(myaddr_in);
9843   if (getsockname(s_listen,
9844 		  (struct sockaddr *)&myaddr_in,
9845 		  &addrlen) == SOCKET_ERROR){
9846     netperf_response.content.serv_errno = errno;
9847     close(s_listen);
9848     send_response();
9849     if (debug) {
9850       fprintf(where,"could not getsockname\n");
9851       fflush(where);
9852     }
9853     exit(1);
9854   }
9855 
9856   /* Now myaddr_in contains the port and the internet address this is */
9857   /* returned to the sender also implicitly telling the sender that the */
9858   /* socket buffer sizing has been done. */
9859 
9860   tcp_conn_rr_response->data_port_number =
9861     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
9862   if (debug) {
9863     fprintf(where,"telling the remote to call me at %d\n",
9864 	    tcp_conn_rr_response->data_port_number);
9865     fflush(where);
9866   }
9867   netperf_response.content.serv_errno   = 0;
9868 
9869   /* But wait, there's more. If the initiator wanted cpu measurements, */
9870   /* then we must call the calibrate routine, which will return the max */
9871   /* rate back to the initiator. If the CPU was not to be measured, or */
9872   /* something went wrong with the calibration, we will return a 0.0 to */
9873   /* the initiator. */
9874 
9875   tcp_conn_rr_response->cpu_rate = (float)0.0; 	/* assume no cpu */
9876   if (tcp_conn_rr_request->measure_cpu) {
9877     tcp_conn_rr_response->measure_cpu = 1;
9878     tcp_conn_rr_response->cpu_rate =
9879       calibrate_local_cpu(tcp_conn_rr_request->cpu_rate);
9880   }
9881 
9882 
9883 
9884   /* before we send the response back to the initiator, pull some of */
9885   /* the socket parms from the globals */
9886   tcp_conn_rr_response->send_buf_size = lss_size;
9887   tcp_conn_rr_response->recv_buf_size = lsr_size;
9888   tcp_conn_rr_response->no_delay = loc_nodelay;
9889   tcp_conn_rr_response->so_rcvavoid = loc_rcvavoid;
9890   tcp_conn_rr_response->so_sndavoid = loc_sndavoid;
9891 
9892   send_response();
9893 
9894   addrlen = sizeof(peeraddr_in);
9895 
9896   /* Now it's time to start receiving data on the connection. We will */
9897   /* first grab the apropriate counters and then start grabbing. */
9898 
9899   cpu_start(tcp_conn_rr_request->measure_cpu);
9900 
9901   /* The loop will exit when the sender does a shutdown, which will */
9902   /* return a length of zero   */
9903 
9904   if (tcp_conn_rr_request->test_length > 0) {
9905     times_up = 0;
9906     trans_remaining = 0;
9907     start_timer(tcp_conn_rr_request->test_length + PAD_TIME);
9908   }
9909   else {
9910     times_up = 1;
9911     trans_remaining = tcp_conn_rr_request->test_length * -1;
9912   }
9913 
9914   trans_received = 0;
9915 
9916   while ((!times_up) || (trans_remaining > 0)) {
9917 
9918     /* accept a connection from the remote */
9919 #ifdef WIN32
9920     /* The test timer will probably fire during this accept,
9921        so to make the start_timer above work we have to move
9922        it to close s_listen while we are blocked on accept. */
9923     win_kludge_socket = s_listen;
9924 #endif
9925     if ((s_data=accept(s_listen,
9926 		       (struct sockaddr *)&peeraddr_in,
9927 		       &addrlen)) == INVALID_SOCKET) {
9928       if (errno == EINTR) {
9929 	/* the timer popped */
9930 	timed_out = 1;
9931 	break;
9932       }
9933       fprintf(where,"recv_tcp_conn_rr: accept: errno = %d\n",errno);
9934       fflush(where);
9935       close(s_listen);
9936 
9937       exit(1);
9938     }
9939 
9940     if (debug) {
9941       fprintf(where,"recv_tcp_conn_rr: accepted data connection.\n");
9942       fflush(where);
9943     }
9944 
9945 #ifdef WIN32
9946   /* this is used so the timer thread can close the socket out from */
9947   /* under us, which to date is the easiest/cleanest/least */
9948   /* Windows-specific way I can find to force the winsock calls to */
9949   /* return WSAEINTR with the test is over. anything that will run on */
9950   /* 95 and NT and is closer to what netperf expects from Unix signals */
9951   /* and such would be appreciated raj 1/96 */
9952   win_kludge_socket = s_data;
9953 #endif /* WIN32 */
9954 
9955 #ifdef KLUDGE_SOCKET_OPTIONS
9956     /* this is for those systems which *INCORRECTLY* fail to pass */
9957     /* attributes across an accept() call. Including this goes against */
9958     /* my better judgement :( raj 11/95 */
9959 
9960     kludge_socket_options(s_data);
9961 
9962 #endif /* KLUDGE_SOCKET_OPTIONS */
9963 
9964     temp_message_ptr	= recv_message_ptr;
9965     request_bytes_remaining	= tcp_conn_rr_request->request_size;
9966 
9967     /* receive the request from the other side */
9968     while (!times_up && (request_bytes_remaining > 0)) {
9969       if((request_bytes_recvd=recv(s_data,
9970 				   temp_message_ptr,
9971 				   request_bytes_remaining,
9972 				   0)) == SOCKET_ERROR) {
9973 	if (SOCKET_EINTR(request_bytes_recvd))
9974 	{
9975 	  /* the timer popped */
9976 	  timed_out = 1;
9977 	  break;
9978 	}
9979 	netperf_response.content.serv_errno = errno;
9980 	send_response();
9981 	exit(1);
9982       }
9983       else if (request_bytes_recvd > 0) {
9984 	request_bytes_remaining -= request_bytes_recvd;
9985 	temp_message_ptr  += request_bytes_recvd;
9986       }
9987       else {
9988       	/* for some reason the remote closed the connection on
9989 	 * us and that is unexpected so we should just close the
9990 	 * socket and move-on. for that we will use an evil goto
9991 	 * neener neener raj 20090622 */
9992     	goto bail;
9993       }
9994     }
9995 
9996     if (timed_out) {
9997       /* we hit the end of the test based on time - lets */
9998       /* bail out of here now... */
9999       fprintf(where,"yo5\n");
10000       fflush(where);
10001       break;
10002     }
10003 
10004     /* Now, send the response to the remote */
10005     if((bytes_sent=send(s_data,
10006 			send_message_ptr,
10007 			tcp_conn_rr_request->response_size,
10008 			0)) == SOCKET_ERROR) {
10009       if (errno == EINTR) {
10010 	/* the test timer has popped */
10011 	timed_out = 1;
10012 	fprintf(where,"yo6\n");
10013 	fflush(where);
10014 	break;
10015       }
10016       netperf_response.content.serv_errno = 99;
10017       send_response();
10018       exit(1);
10019     }
10020 
10021     trans_received++;
10022     if (trans_remaining) {
10023       trans_remaining--;
10024     }
10025 
10026     if (debug) {
10027       fprintf(where,
10028 	      "recv_tcp_conn_rr: Transaction %d complete\n",
10029 	      trans_received);
10030       fflush(where);
10031     }
10032 
10033     /* close the connection. the server will likely do a graceful */
10034     /* close of the connection, insuring that all data has arrived at */
10035     /* the client. for this it will call shutdown(), and then recv() and */
10036     /* then close(). I'm reasonably confident that this is the */
10037     /* appropriate sequence of calls - I would like to hear of */
10038     /* examples in web servers to the contrary. raj 10/95*/
10039 #ifdef TCP_CRR_SHUTDOWN
10040     shutdown(s_data,SHUT_WR);
10041     recv(s_data,
10042 	 recv_message_ptr,
10043 	 1,
10044 	 0);
10045 bail:
10046     close(s_data);
10047 #else
10048 bail:
10049     close(s_data);
10050 #endif /* TCP_CRR_SHUTDOWN */
10051 
10052   }
10053 
10054 
10055   /* The loop now exits due to timeout or transaction count being */
10056   /* reached */
10057 
10058   cpu_stop(tcp_conn_rr_request->measure_cpu,&elapsed_time);
10059 
10060   if (timed_out) {
10061     /* we ended the test by time, which was at least 2 seconds */
10062     /* longer than we wanted to run. so, we want to subtract */
10063     /* PAD_TIME from the elapsed_time. */
10064     elapsed_time -= PAD_TIME;
10065   }
10066   /* send the results to the sender			*/
10067 
10068   if (debug) {
10069     fprintf(where,
10070 	    "recv_tcp_conn_rr: got %d transactions\n",
10071 	    trans_received);
10072     fflush(where);
10073   }
10074 
10075   tcp_conn_rr_results->bytes_received	= (trans_received *
10076 					   (tcp_conn_rr_request->request_size +
10077 					    tcp_conn_rr_request->response_size));
10078   tcp_conn_rr_results->trans_received	= trans_received;
10079   tcp_conn_rr_results->elapsed_time	= elapsed_time;
10080   if (tcp_conn_rr_request->measure_cpu) {
10081     tcp_conn_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
10082   }
10083 
10084   if (debug) {
10085     fprintf(where,
10086 	    "recv_tcp_conn_rr: test complete, sending results.\n");
10087     fflush(where);
10088   }
10089 
10090   send_response();
10091 
10092 }
10093 
10094 
10095 #ifdef DO_1644
10096 
10097  /* this test is intended to test the performance of establishing a */
10098  /* connection, exchanging a request/response pair, and repeating. it */
10099  /* is expected that this would be a good starting-point for */
10100  /* comparision of T/TCP with classic TCP for transactional workloads. */
10101  /* it will also look (can look) much like the communication pattern */
10102  /* of http for www access. */
10103 
10104 int
send_tcp_tran_rr(char remote_host[])10105 send_tcp_tran_rr(char remote_host[])
10106 {
10107 
10108   char *tput_title = "\
10109 Local /Remote\n\
10110 Socket Size   Request  Resp.   Elapsed  Trans.\n\
10111 Send   Recv   Size     Size    Time     Rate         \n\
10112 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
10113 
10114   char *tput_fmt_0 =
10115     "%7.2f\n";
10116 
10117   char *tput_fmt_1_line_1 = "\
10118 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
10119   char *tput_fmt_1_line_2 = "\
10120 %-6d %-6d\n";
10121 
10122   char *cpu_title = "\
10123 Local /Remote\n\
10124 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
10125 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
10126 bytes  bytes  bytes   bytes  secs.   per sec  %%      %%      us/Tr   us/Tr\n\n";
10127 
10128   char *cpu_fmt_0 =
10129     "%6.3f\n";
10130 
10131   char *cpu_fmt_1_line_1 = "\
10132 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f\n";
10133 
10134   char *cpu_fmt_1_line_2 = "\
10135 %-6d %-6d\n";
10136 
10137   char *ksink_fmt = "\n\
10138 Alignment      Offset\n\
10139 Local  Remote  Local  Remote\n\
10140 Send   Recv    Send   Recv\n\
10141 %5d  %5d   %5d  %5d\n";
10142 
10143 
10144   int 			one = 1;
10145   int			timed_out = 0;
10146   float			elapsed_time;
10147 
10148   int	len;
10149   struct ring_elt *send_ring;
10150   struct ring_elt *recv_ring;
10151   char	*temp_message_ptr;
10152   int	nummessages;
10153   SOCKET	send_socket;
10154   int	trans_remaining;
10155   double	bytes_xferd;
10156   int	sock_opt_len = sizeof(int);
10157   int	rsp_bytes_left;
10158   int	rsp_bytes_recvd;
10159 
10160   float	local_cpu_utilization;
10161   float	local_service_demand;
10162   float	remote_cpu_utilization;
10163   float	remote_service_demand;
10164   double	thruput;
10165 
10166   struct	hostent	        *hp;
10167   struct	sockaddr_in	server;
10168   struct        sockaddr_in     *myaddr;
10169   unsigned      int             addr;
10170   int                           myport;
10171 
10172   struct	tcp_tran_rr_request_struct	*tcp_tran_rr_request;
10173   struct	tcp_tran_rr_response_struct	*tcp_tran_rr_response;
10174   struct	tcp_tran_rr_results_struct	*tcp_tran_rr_result;
10175 
10176   tcp_tran_rr_request =
10177     (struct tcp_tran_rr_request_struct *)netperf_request.content.test_specific_data;
10178   tcp_tran_rr_response =
10179     (struct tcp_tran_rr_response_struct *)netperf_response.content.test_specific_data;
10180   tcp_tran_rr_result =
10181     (struct tcp_tran_rr_results_struct *)netperf_response.content.test_specific_data;
10182 
10183 
10184 #ifdef WANT_HISTOGRAM
10185   if (verbosity > 1) {
10186     time_hist = HIST_new();
10187   }
10188 #endif /* WANT_HISTOGRAM */
10189 
10190   /* since we are now disconnected from the code that established the */
10191   /* control socket, and since we want to be able to use different */
10192   /* protocols and such, we are passed the name of the remote host and */
10193   /* must turn that into the test specific addressing information. */
10194 
10195   myaddr = (struct sockaddr_storage *)malloc(sizeof(struct sockaddr_storage));
10196   if (myaddr == NULL) {
10197     printf("malloc(%d) failed!\n", sizeof(struct sockaddr_storage));
10198     exit(1);
10199   }
10200 
10201   bzero((char *)&server,
10202 	sizeof(server));
10203   bzero((char *)myaddr,
10204 	sizeof(struct sockaddr_storage));
10205   myaddr->sin_family = AF_INET;
10206 
10207   complete_addrinfos(&remote_res,
10208 		     &local_res,
10209 		     remote_host,
10210 		     SOCK_STREAM,
10211 		     IPPROTO_TCP,
10212 		     0);
10213 
10214   if ( print_headers ) {
10215     print_top_test_header("TCP Transactional/Request/Response TEST",local_res,remote_res);
10216   }
10217 
10218   /* initialize a few counters */
10219 
10220   nummessages	=	0;
10221   bytes_xferd	=	0.0;
10222   times_up 	= 	0;
10223 
10224   /* set-up the data buffers with the requested alignment and offset */
10225   if (send_width == 0) send_width = 1;
10226   if (recv_width == 0) recv_width = 1;
10227 
10228   send_ring = allocate_buffer_ring(send_width,
10229 				   req_size,
10230 				   local_send_align,
10231 				   local_send_offset);
10232 
10233   recv_ring = allocate_buffer_ring(recv_width,
10234 				   rsp_size,
10235 				   local_recv_align,
10236 				   local_recv_offset);
10237 
10238 
10239   if (debug) {
10240     fprintf(where,"send_tcp_tran_rr: send_socket obtained...\n");
10241   }
10242 
10243   /* If the user has requested cpu utilization measurements, we must */
10244   /* calibrate the cpu(s). We will perform this task within the tests */
10245   /* themselves. If the user has specified the cpu rate, then */
10246   /* calibrate_local_cpu will return rather quickly as it will have */
10247   /* nothing to do. If local_cpu_rate is zero, then we will go through */
10248   /* all the "normal" calibration stuff and return the rate back.*/
10249 
10250   if (local_cpu_usage) {
10251     local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
10252   }
10253 
10254   /* Tell the remote end to do a listen. The server alters the socket */
10255   /* paramters on the other side at this point, hence the reason for */
10256   /* all the values being passed in the setup message. If the user did */
10257   /* not specify any of the parameters, they will be passed as 0, which */
10258   /* will indicate to the remote that no changes beyond the system's */
10259   /* default should be used. Alignment is the exception, it will */
10260   /* default to 8, which will be no alignment alterations. */
10261 
10262   netperf_request.content.request_type	        =	DO_TCP_TRR;
10263   tcp_tran_rr_request->recv_buf_size	=	rsr_size_req;
10264   tcp_tran_rr_request->send_buf_size	=	rss_size_req;
10265   tcp_tran_rr_request->recv_alignment	=	remote_recv_align;
10266   tcp_tran_rr_request->recv_offset	=	remote_recv_offset;
10267   tcp_tran_rr_request->send_alignment	=	remote_send_align;
10268   tcp_tran_rr_request->send_offset	=	remote_send_offset;
10269   tcp_tran_rr_request->request_size	=	req_size;
10270   tcp_tran_rr_request->response_size	=	rsp_size;
10271   tcp_tran_rr_request->no_delay	        =	rem_nodelay;
10272   tcp_tran_rr_request->measure_cpu	=	remote_cpu_usage;
10273   tcp_tran_rr_request->cpu_rate	        =	remote_cpu_rate;
10274   tcp_tran_rr_request->so_rcvavoid	=	rem_rcvavoid;
10275   tcp_tran_rr_request->so_sndavoid	=	rem_sndavoid;
10276   if (test_time) {
10277     tcp_tran_rr_request->test_length	=	test_time;
10278   }
10279   else {
10280     tcp_tran_rr_request->test_length	=	test_trans * -1;
10281   }
10282   tcp_tran_rr_request->port             =       atoi(remote_data_port);
10283   tcp_tran_rr_request->ipfamily        =       af_to_nf(remote_res->ai_family);
10284 
10285   if (debug > 1) {
10286     fprintf(where,"netperf: send_tcp_tran_rr: requesting TCP_TRR test\n");
10287   }
10288 
10289   send_request();
10290 
10291   /* The response from the remote will contain all of the relevant 	*/
10292   /* socket parameters for this test type. We will put them back into 	*/
10293   /* the variables here so they can be displayed if desired.  The	*/
10294   /* remote will have calibrated CPU if necessary, and will have done	*/
10295   /* all the needed set-up we will have calibrated the cpu locally	*/
10296   /* before sending the request, and will grab the counter value right	*/
10297   /* after the connect returns. The remote will grab the counter right	*/
10298   /* after the accept call. This saves the hassle of extra messages	*/
10299   /* being sent for the TCP tests.					*/
10300 
10301   recv_response();
10302 
10303   if (!netperf_response.content.serv_errno) {
10304     rsr_size	=	tcp_tran_rr_response->recv_buf_size;
10305     rss_size	=	tcp_tran_rr_response->send_buf_size;
10306     rem_nodelay	=	tcp_tran_rr_response->no_delay;
10307     remote_cpu_usage=	tcp_tran_rr_response->measure_cpu;
10308     remote_cpu_rate = 	tcp_tran_rr_response->cpu_rate;
10309     /* make sure that port numbers are in network order */
10310     server.sin_port	=	tcp_tran_rr_response->data_port_number;
10311     server.sin_port =	htons(server.sin_port);
10312     if (debug) {
10313       fprintf(where,"remote listen done.\n");
10314       fprintf(where,"remote port is %d\n",ntohs(server.sin_port));
10315       fflush(where);
10316     }
10317   }
10318   else {
10319     Set_errno(netperf_response.content.serv_errno);
10320     fprintf(where,
10321 	    "netperf: remote error %d",
10322 	    netperf_response.content.serv_errno);
10323     perror("");
10324     fflush(where);
10325     exit(1);
10326   }
10327 
10328   /* pick a nice random spot between client_port_min and */
10329   /* client_port_max for our initial port number. if they are the */
10330   /* same, then just set to _min */
10331   if (client_port_max - client_port_min) {
10332     srand(getpid());
10333     myport = client_port_min +
10334       (rand() % (client_port_max - client_port_min));
10335   }
10336   else {
10337     myport = client_port_min;
10338   }
10339 
10340   /* there will be a ++ before the first call to bind, so subtract one */
10341   myport--;
10342   myaddr->sin_port = htons((unsigned short)myport);
10343 
10344   /* Set-up the test end conditions. For a request/response test, they */
10345   /* can be either time or transaction based. */
10346 
10347   if (test_time) {
10348     /* The user wanted to end the test after a period of time. */
10349     times_up = 0;
10350     trans_remaining = 0;
10351     start_timer(test_time);
10352   }
10353   else {
10354     /* The tester wanted to send a number of bytes. */
10355     trans_remaining = test_bytes;
10356     times_up = 1;
10357   }
10358 
10359   /* The cpu_start routine will grab the current time and possibly */
10360   /* value of the idle counter for later use in measuring cpu */
10361   /* utilization and/or service demand and thruput. */
10362 
10363   cpu_start(local_cpu_usage);
10364 
10365   /* We use an "OR" to control test execution. When the test is */
10366   /* controlled by time, the byte count check will always return false. */
10367   /* When the test is controlled by byte count, the time test will */
10368   /* always return false. When the test is finished, the whole */
10369   /* expression will go false and we will stop sending data. I think I */
10370   /* just arbitrarily decrement trans_remaining for the timed test, but */
10371   /* will not do that just yet... One other question is whether or not */
10372   /* the send buffer and the receive buffer should be the same buffer. */
10373 
10374   while ((!times_up) || (trans_remaining > 0)) {
10375 
10376 #ifdef WANT_HISTOGRAM
10377     if (verbosity > 1) {
10378       /* timestamp just before our call to create the socket, and then */
10379       /* again just after the receive raj 3/95 */
10380       HIST_timestamp(&time_one);
10381     }
10382 #endif /* WANT_HISTOGRAM */
10383 
10384     /* set up the data socket - is this really necessary or can I just */
10385     /* re-use the same socket and move this cal out of the while loop. */
10386     /* it does introcudea *boatload* of system calls. I guess that it */
10387     /* all depends on "reality of programming." keeping it this way is */
10388     /* a bit more conservative I imagine - raj 3/95 */
10389     send_socket = create_data_socket(local_res);
10390 
10391     if (send_socket == INVALID_SOCKET) {
10392       perror("netperf: send_tcp_tran_rr: tcp stream data socket");
10393       exit(1);
10394     }
10395 
10396     /* we set SO_REUSEADDR on the premis that no unreserved port */
10397     /* number on the local system is going to be already connected to */
10398     /* the remote netserver's port number. One thing that I might */
10399     /* try later is to have the remote actually allocate a couple of */
10400     /* port numbers and cycle through those as well. depends on if we */
10401     /* can get through all the unreserved port numbers in less than */
10402     /* the length of the TIME_WAIT state raj 8/94 */
10403     one = 1;
10404     if(setsockopt(send_socket, SOL_SOCKET, SO_REUSEADDR,
10405 		  (char *)&one, sock_opt_len) == SOCKET_ERROR) {
10406       perror("netperf: send_tcp_tran_rr: so_reuseaddr");
10407       exit(1);
10408     }
10409 
10410 newport:
10411     /* pick a new port number */
10412     myport = ntohs(myaddr->sin_port);
10413     myport++;
10414 
10415     /* we do not want to use the port number that the server is */
10416     /* sitting at - this would cause us to fail in a loopback test. we */
10417     /* could just rely on the failure of the bind to get us past this, */
10418     /* but I'm guessing that in this one case at least, it is much */
10419     /* faster, given that we *know* that port number is already in use */
10420     /* (or rather would be in a loopback test) */
10421 
10422     if (myport == ntohs(server.sin_port)) myport++;
10423 
10424     /* wrap the port number when we get to 65535. NOTE, some broken */
10425     /* TCP's might treat the port number as a signed 16 bit quantity. */
10426     /* we aren't interested in testing such broken implementations :) */
10427     /* raj 8/94  */
10428     if (myport >= client_port_max) {
10429       myport = client_port_min;
10430     }
10431     myaddr->sin_port = htons((unsigned short)myport);
10432 
10433     if (debug) {
10434       if ((nummessages % 100) == 0) {
10435 	printf("port %d\n",myport);
10436       }
10437     }
10438 
10439     /* we want to bind our socket to a particular port number. */
10440     if (bind(send_socket,
10441 	     (struct sockaddr *)myaddr,
10442 	     sizeof(struct sockaddr_storage)) == SOCKET_ERROR) {
10443       /* if the bind failed, someone else must have that port number */
10444       /* - perhaps in the listen state. since we can't use it, skip to */
10445       /* the next port number. we may have to do this again later, but */
10446       /* that's just too bad :) */
10447       if (debug > 1) {
10448 	fprintf(where,
10449 		"send_tcp_tran_rr: tried to bind to port %d errno %d\n",
10450 		ntohs(myaddr->sin_port),
10451 		errno);
10452 	fflush(where);
10453       }
10454 	/* yes, goto's are supposed to be evil, but they do have their */
10455 	/* uses from time to time. the real world doesn't always have */
10456 	/* to code to ge tthe A in CS 101 :) raj 3/95 */
10457 	goto newport;
10458     }
10459 
10460     /* Connect up to the remote port on the data socket. Since this is */
10461     /* a test for RFC_1644-style transactional TCP, we can use the */
10462     /* sendto() call instead of calling connect and then send() */
10463 
10464     /* send the request */
10465     if((len=sendto(send_socket,
10466 		   send_ring->buffer_ptr,
10467 		   req_size,
10468 		   MSG_EOF,
10469 		   (struct sockaddr *)&server,
10470 		   sizeof(server))) != req_size) {
10471       if (SOCKET_EINTR(len))
10472 	  {
10473 	    /* we hit the end of a */
10474 	    /* timed test. */
10475 	    timed_out = 1;
10476 	    break;
10477       }
10478       perror("send_tcp_tran_rr: data send error");
10479       exit(1);
10480     }
10481     send_ring = send_ring->next;
10482 
10483     /* receive the response */
10484     rsp_bytes_left = rsp_size;
10485     temp_message_ptr  = recv_ring->buffer_ptr;
10486     while(rsp_bytes_left > 0) {
10487       if((rsp_bytes_recvd=recv(send_socket,
10488 			       temp_message_ptr,
10489 			       rsp_bytes_left,
10490 			       0)) == SOCKET_ERROR) {
10491 	    if (SOCKET_EINTR(rsp_bytes_recvd))
10492 		{
10493 	      /* We hit the end of a timed test. */
10494 	      timed_out = 1;
10495 	      break;
10496 		}
10497 	    perror("send_tcp_tran_rr: data recv error");
10498 	    exit(1);
10499       }
10500       rsp_bytes_left -= rsp_bytes_recvd;
10501       temp_message_ptr  += rsp_bytes_recvd;
10502     }
10503     recv_ring = recv_ring->next;
10504 
10505     if (timed_out) {
10506       /* we may have been in a nested while loop - we need */
10507       /* another call to break. */
10508       break;
10509     }
10510 
10511     close(send_socket);
10512 
10513 #ifdef WANT_HISTOGRAM
10514     if (verbosity > 1) {
10515       HIST_timestamp(&time_two);
10516       HIST_add(time_hist,delta_micro(&time_one,&time_two));
10517     }
10518 #endif /* WANT_HISTOGRAM */
10519 
10520     nummessages++;
10521     if (trans_remaining) {
10522       trans_remaining--;
10523     }
10524 
10525     if (debug > 3) {
10526       fprintf(where,
10527 	      "Transaction %d completed on local port %d\n",
10528 	      nummessages,
10529 	      ntohs(myaddr->sin_port));
10530       fflush(where);
10531     }
10532 
10533 
10534   }
10535 
10536   /* this call will always give us the elapsed time for the test, and */
10537   /* will also store-away the necessaries for cpu utilization */
10538 
10539   cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being measured? */
10540   /* how long did we really run? */
10541 
10542   /* Get the statistics from the remote end. The remote will have */
10543   /* calculated service demand and all those interesting things. If it */
10544   /* wasn't supposed to care, it will return obvious values. */
10545 
10546   recv_response();
10547   if (!netperf_response.content.serv_errno) {
10548     if (debug)
10549       fprintf(where,"remote results obtained\n");
10550   }
10551   else {
10552     Set_errno(netperf_response.content.serv_errno);
10553     fprintf(where,
10554 	    "netperf: remote error %d",
10555 	    netperf_response.content.serv_errno);
10556     perror("");
10557     fflush(where);
10558     exit(1);
10559   }
10560 
10561   /* We now calculate what our thruput was for the test. In the future, */
10562   /* we may want to include a calculation of the thruput measured by */
10563   /* the remote, but it should be the case that for a TCP stream test, */
10564   /* that the two numbers should be *very* close... We calculate */
10565   /* bytes_sent regardless of the way the test length was controlled. */
10566   /* If it was time, we needed to, and if it was by bytes, the user may */
10567   /* have specified a number of bytes that wasn't a multiple of the */
10568   /* send_size, so we really didn't send what he asked for ;-) We use */
10569   /* Kbytes/s as the units of thruput for a TCP stream test, where K = */
10570   /* 1024. A future enhancement *might* be to choose from a couple of */
10571   /* unit selections. */
10572 
10573   bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
10574   thruput	= calc_thruput(bytes_xferd);
10575 
10576   if (local_cpu_usage || remote_cpu_usage) {
10577     /* We must now do a little math for service demand and cpu */
10578     /* utilization for the system(s) */
10579     /* Of course, some of the information might be bogus because */
10580     /* there was no idle counter in the kernel(s). We need to make */
10581     /* a note of this for the user's benefit...*/
10582     if (local_cpu_usage) {
10583       if (local_cpu_rate == 0.0) {
10584 	fprintf(where,"WARNING WARNING WARNING  WARNING WARNING WARNING  WARNING!\n");
10585 	fprintf(where,"Local CPU usage numbers based on process information only!\n");
10586 	fflush(where);
10587       }
10588       local_cpu_utilization = calc_cpu_util(0.0);
10589       /* since calc_service demand is doing ms/Kunit we will */
10590       /* multiply the number of transaction by 1024 to get */
10591       /* "good" numbers */
10592       local_service_demand  = calc_service_demand((double) nummessages*1024,
10593 						  0.0,
10594 						  0.0,
10595 						  0);
10596     }
10597     else {
10598       local_cpu_utilization	= (float) -1.0;
10599       local_service_demand	= (float) -1.0;
10600     }
10601 
10602     if (remote_cpu_usage) {
10603       if (remote_cpu_rate == 0.0) {
10604 	fprintf(where,"DANGER  DANGER  DANGER    DANGER  DANGER  DANGER    DANGER!\n");
10605 	fprintf(where,"Remote CPU usage numbers based on process information only!\n");
10606 	fflush(where);
10607       }
10608       remote_cpu_utilization = tcp_tran_rr_result->cpu_util;
10609       /* since calc_service demand is doing ms/Kunit we will */
10610       /* multiply the number of transaction by 1024 to get */
10611       /* "good" numbers */
10612       remote_service_demand = calc_service_demand((double) nummessages*1024,
10613 						  0.0,
10614 						  remote_cpu_utilization,
10615 						  tcp_tran_rr_result->num_cpus);
10616     }
10617     else {
10618       remote_cpu_utilization = (float) -1.0;
10619       remote_service_demand  = (float) -1.0;
10620     }
10621 
10622     /* We are now ready to print all the information. If the user */
10623     /* has specified zero-level verbosity, we will just print the */
10624     /* local service demand, or the remote service demand. If the */
10625     /* user has requested verbosity level 1, he will get the basic */
10626     /* "streamperf" numbers. If the user has specified a verbosity */
10627     /* of greater than 1, we will display a veritable plethora of */
10628     /* background information from outside of this block as it it */
10629     /* not cpu_measurement specific...  */
10630 
10631     switch (verbosity) {
10632     case 0:
10633       if (local_cpu_usage) {
10634 	fprintf(where,
10635 		cpu_fmt_0,
10636 		local_service_demand);
10637       }
10638       else {
10639 	fprintf(where,
10640 		cpu_fmt_0,
10641 		remote_service_demand);
10642       }
10643       break;
10644     case 1:
10645     case 2:
10646 
10647       if (print_headers) {
10648 	fprintf(where,
10649 		cpu_title,
10650 		local_cpu_method,
10651 		remote_cpu_method);
10652       }
10653 
10654       fprintf(where,
10655 	      cpu_fmt_1_line_1,		/* the format string */
10656 	      lss_size,		/* local sendbuf size */
10657 	      lsr_size,
10658 	      req_size,		/* how large were the requests */
10659 	      rsp_size,		/* guess */
10660 	      elapsed_time,		/* how long was the test */
10661 	      nummessages/elapsed_time,
10662 	      local_cpu_utilization,	/* local cpu */
10663 	      remote_cpu_utilization,	/* remote cpu */
10664 	      local_service_demand,	/* local service demand */
10665 	      remote_service_demand);	/* remote service demand */
10666       fprintf(where,
10667 	      cpu_fmt_1_line_2,
10668 	      rss_size,
10669 	      rsr_size);
10670       break;
10671     }
10672   }
10673   else {
10674     /* The tester did not wish to measure service demand. */
10675     switch (verbosity) {
10676     case 0:
10677       fprintf(where,
10678 	      tput_fmt_0,
10679 	      nummessages/elapsed_time);
10680       break;
10681     case 1:
10682     case 2:
10683       if (print_headers) {
10684 	fprintf(where,tput_title,format_units());
10685       }
10686 
10687       fprintf(where,
10688 	      tput_fmt_1_line_1,	/* the format string */
10689 	      lss_size,
10690 	      lsr_size,
10691 	      req_size,		/* how large were the requests */
10692 	      rsp_size,		/* how large were the responses */
10693 	      elapsed_time, 		/* how long did it take */
10694 	      nummessages/elapsed_time);
10695       fprintf(where,
10696 	      tput_fmt_1_line_2,
10697 	      rss_size, 		/* remote recvbuf size */
10698 	      rsr_size);
10699 
10700       break;
10701     }
10702   }
10703 
10704   /* it would be a good thing to include information about some of the */
10705   /* other parameters that may have been set for this test, but at the */
10706   /* moment, I do not wish to figure-out all the  formatting, so I will */
10707   /* just put this comment here to help remind me that it is something */
10708   /* that should be done at a later time. */
10709 
10710   if (verbosity > 1) {
10711     /* The user wanted to know it all, so we will give it to him. */
10712     /* This information will include as much as we can find about */
10713     /* TCP statistics, the alignments of the sends and receives */
10714     /* and all that sort of rot... */
10715 
10716     fprintf(where,
10717 	    ksink_fmt,
10718 	    local_send_align,
10719 	    remote_recv_offset,
10720 	    local_send_offset,
10721 	    remote_recv_offset);
10722 
10723 #ifdef WANT_HISTOGRAM
10724     fprintf(where,"\nHistogram of request/response times\n");
10725     fflush(where);
10726     HIST_report(time_hist);
10727 #endif /* WANT_HISTOGRAM */
10728 
10729   }
10730 
10731 }
10732 
10733 
10734 int
recv_tcp_tran_rr()10735 recv_tcp_tran_rr()
10736 {
10737 
10738   char  *message;
10739   struct	sockaddr_in        myaddr_in,
10740   peeraddr_in;
10741   SOCKET	s_listen,s_data;
10742   netperf_socklen_t 	addrlen;
10743   int   NoPush = 1;
10744 
10745   char	*recv_message_ptr;
10746   char	*send_message_ptr;
10747   char	*temp_message_ptr;
10748   int	trans_received;
10749   int	trans_remaining;
10750   int	bytes_sent;
10751   int	request_bytes_recvd;
10752   int	request_bytes_remaining;
10753   int	timed_out = 0;
10754   float	elapsed_time;
10755 
10756   struct	tcp_tran_rr_request_struct	*tcp_tran_rr_request;
10757   struct	tcp_tran_rr_response_struct	*tcp_tran_rr_response;
10758   struct	tcp_tran_rr_results_struct	*tcp_tran_rr_results;
10759 
10760   tcp_tran_rr_request =
10761     (struct tcp_tran_rr_request_struct *)netperf_request.content.test_specific_data;
10762   tcp_tran_rr_response =
10763     (struct tcp_tran_rr_response_struct *)netperf_response.content.test_specific_data;
10764   tcp_tran_rr_results =
10765     (struct tcp_tran_rr_results_struct *)netperf_response.content.test_specific_data;
10766 
10767   if (debug) {
10768     fprintf(where,"netserver: recv_tcp_tran_rr: entered...\n");
10769     fflush(where);
10770   }
10771 
10772   /* We want to set-up the listen socket with all the desired */
10773   /* parameters and then let the initiator know that all is ready. If */
10774   /* socket size defaults are to be used, then the initiator will have */
10775   /* sent us 0's. If the socket sizes cannot be changed, then we will */
10776   /* send-back what they are. If that information cannot be determined, */
10777   /* then we send-back -1's for the sizes. If things go wrong for any */
10778   /* reason, we will drop back ten yards and punt. */
10779 
10780   /* If anything goes wrong, we want the remote to know about it. It */
10781   /* would be best if the error that the remote reports to the user is */
10782   /* the actual error we encountered, rather than some bogus unexpected */
10783   /* response type message. */
10784 
10785   if (debug) {
10786     fprintf(where,"recv_tcp_tran_rr: setting the response type...\n");
10787     fflush(where);
10788   }
10789 
10790   netperf_response.content.response_type = TCP_TRR_RESPONSE;
10791 
10792   if (debug) {
10793     fprintf(where,"recv_tcp_tran_rr: the response type is set...\n");
10794     fflush(where);
10795   }
10796 
10797   /* set-up the data buffer with the requested alignment and offset */
10798   message = (char *)malloc(DATABUFFERLEN);
10799   if (message == NULL) {
10800     printf("malloc(%d) failed!\n", DATABUFFERLEN);
10801     exit(1);
10802   }
10803 
10804   /* We now alter the message_ptr variables to be at the desired */
10805   /* alignments with the desired offsets. */
10806 
10807   if (debug) {
10808     fprintf(where,
10809 	    "recv_tcp_tran_rr: requested recv alignment of %d offset %d\n",
10810 	    tcp_tran_rr_request->recv_alignment,
10811 	    tcp_tran_rr_request->recv_offset);
10812     fprintf(where,
10813 	    "recv_tcp_tran_rr: requested send alignment of %d offset %d\n",
10814 	    tcp_tran_rr_request->send_alignment,
10815 	    tcp_tran_rr_request->send_offset);
10816     fflush(where);
10817   }
10818 
10819   recv_message_ptr = ALIGN_BUFFER(message, tcp_tran_rr_request->recv_alignment, tcp_tran_rr_request->recv_offset);
10820 
10821   send_message_ptr = ALIGN_BUFFER(message, tcp_tran_rr_request->send_alignment, tcp_tran_rr_request->send_offset);
10822 
10823   if (debug) {
10824     fprintf(where,"recv_tcp_tran_rr: receive alignment and offset set...\n");
10825     fflush(where);
10826   }
10827 
10828   /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */
10829   /* can put in OUR values !-) At some point, we may want to nail this */
10830   /* socket to a particular network-level address, but for now, */
10831   /* INADDR_ANY should be just fine. */
10832 
10833   bzero((char *)&myaddr_in,
10834 	sizeof(myaddr_in));
10835   myaddr_in.sin_family      = AF_INET;
10836   myaddr_in.sin_addr.s_addr = INADDR_ANY;
10837   myaddr_in.sin_port        = htons((unsigned short)tcp_tran_rr_request->port);
10838 
10839   /* Grab a socket to listen on, and then listen on it. */
10840 
10841   if (debug) {
10842     fprintf(where,"recv_tcp_tran_rr: grabbing a socket...\n");
10843     fflush(where);
10844   }
10845 
10846   /* create_data_socket expects to find some things in the global */
10847   /* variables, so set the globals based on the values in the request. */
10848   /* once the socket has been created, we will set the response values */
10849   /* based on the updated value of those globals. raj 7/94 */
10850   lss_size_req = tcp_tran_rr_request->send_buf_size;
10851   lsr_size_req = tcp_tran_rr_request->recv_buf_size;
10852   loc_nodelay = tcp_tran_rr_request->no_delay;
10853   loc_rcvavoid = tcp_tran_rr_request->so_rcvavoid;
10854   loc_sndavoid = tcp_tran_rr_request->so_sndavoid;
10855 
10856   set_hostname_and_port(local_name,
10857 			port_buffer,
10858 			nf_to_af(tcp_tran_rr_request->ipfamily),
10859 			tcp_tran_rr_request->port);
10860 
10861   local_res = complete_addrinfo(local_name,
10862 				local_name,
10863 				port_buffer,
10864 				nf_to_af(tcp_tran_rr_request->ipfamily),
10865 				SOCK_STREAM,
10866 				IPPROTO_TCP,
10867 				0);
10868 
10869   s_listen = create_data_socket(local_res);
10870 
10871   if (s_listen == INVALID_SOCKET) {
10872     netperf_response.content.serv_errno = errno;
10873     send_response();
10874     if (debug) {
10875       fprintf(where,"could not create data socket\n");
10876       fflush(where);
10877     }
10878     exit(1);
10879   }
10880 
10881 #ifdef WIN32
10882   /* The test timer can fire during operations on the listening socket,
10883      so to make the start_timer below work we have to move
10884      it to close s_listen while we are blocked on accept. */
10885   win_kludge_socket2 = s_listen;
10886 #endif
10887 
10888 
10889   /* Let's get an address assigned to this socket so we can tell the */
10890   /* initiator how to reach the data socket. There may be a desire to */
10891   /* nail this socket to a specific IP address in a multi-homed, */
10892   /* multi-connection situation, but for now, we'll ignore the issue */
10893   /* and concentrate on single connection testing. */
10894 
10895   if (bind(s_listen,
10896 	   (struct sockaddr *)&myaddr_in,
10897 	   sizeof(myaddr_in)) == SOCKET_ERROR) {
10898     netperf_response.content.serv_errno = errno;
10899     close(s_listen);
10900     send_response();
10901     if (debug) {
10902       fprintf(where,"could not bind\n");
10903       fflush(where);
10904     }
10905     exit(1);
10906   }
10907 
10908   /* we want to disable the implicit PUSH on all sends. at some point, */
10909   /* this might want to be a parm to the test raj 3/95 */
10910   if (setsockopt(s_listen,
10911 		 IPPROTO_TCP,
10912 		 TCP_NOPUSH,
10913 		 (const char *)&NoPush,
10914 		 sizeof(int)) == SOCKET_ERROR) {
10915     fprintf(where,
10916 	    "recv_tcp_tran_rr: could not set TCP_NOPUSH errno %d\n",
10917 	    errno);
10918     fflush(where);
10919     netperf_response.content.serv_errno = errno;
10920     close(s_listen);
10921     send_response();
10922   }
10923 
10924   /* Now, let's set-up the socket to listen for connections */
10925   if (listen(s_listen, 5) == SOCKET_ERROR) {
10926     netperf_response.content.serv_errno = errno;
10927     close(s_listen);
10928     send_response();
10929     if (debug) {
10930       fprintf(where,"could not listen\n");
10931       fflush(where);
10932     }
10933     exit(1);
10934   }
10935 
10936   /* now get the port number assigned by the system  */
10937   addrlen = sizeof(myaddr_in);
10938   if (getsockname(s_listen,
10939 		  (struct sockaddr *)&myaddr_in,
10940 		  &addrlen) == SOCKET_ERROR){
10941     netperf_response.content.serv_errno = errno;
10942     close(s_listen);
10943     send_response();
10944     if (debug) {
10945       fprintf(where,"could not geetsockname\n");
10946       fflush(where);
10947     }
10948     exit(1);
10949   }
10950 
10951   /* Now myaddr_in contains the port and the internet address this is */
10952   /* returned to the sender also implicitly telling the sender that the */
10953   /* socket buffer sizing has been done. */
10954 
10955   tcp_tran_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port);
10956   if (debug) {
10957     fprintf(where,"telling the remote to call me at %d\n",
10958 	    tcp_tran_rr_response->data_port_number);
10959     fflush(where);
10960   }
10961   netperf_response.content.serv_errno   = 0;
10962 
10963   /* But wait, there's more. If the initiator wanted cpu measurements, */
10964   /* then we must call the calibrate routine, which will return the max */
10965   /* rate back to the initiator. If the CPU was not to be measured, or */
10966   /* something went wrong with the calibration, we will return a 0.0 to */
10967   /* the initiator. */
10968 
10969   tcp_tran_rr_response->cpu_rate = 0.0; 	/* assume no cpu */
10970   if (tcp_tran_rr_request->measure_cpu) {
10971     tcp_tran_rr_response->measure_cpu = 1;
10972     tcp_tran_rr_response->cpu_rate =
10973       calibrate_local_cpu(tcp_tran_rr_request->cpu_rate);
10974   }
10975 
10976 
10977 
10978   /* before we send the response back to the initiator, pull some of */
10979   /* the socket parms from the globals */
10980   tcp_tran_rr_response->send_buf_size = lss_size;
10981   tcp_tran_rr_response->recv_buf_size = lsr_size;
10982   tcp_tran_rr_response->no_delay = loc_nodelay;
10983   tcp_tran_rr_response->so_rcvavoid = loc_rcvavoid;
10984   tcp_tran_rr_response->so_sndavoid = loc_sndavoid;
10985 
10986   send_response();
10987 
10988   addrlen = sizeof(peeraddr_in);
10989 
10990   /* Now it's time to start receiving data on the connection. We will */
10991   /* first grab the apropriate counters and then start grabbing. */
10992 
10993   cpu_start(tcp_tran_rr_request->measure_cpu);
10994 
10995   /* The loop will exit when the sender does a shutdown, which will */
10996   /* return a length of zero   */
10997 
10998   if (tcp_tran_rr_request->test_length > 0) {
10999     times_up = 0;
11000     trans_remaining = 0;
11001     start_timer(tcp_tran_rr_request->test_length + PAD_TIME);
11002   }
11003   else {
11004     times_up = 1;
11005     trans_remaining = tcp_tran_rr_request->test_length * -1;
11006   }
11007 
11008   trans_received = 0;
11009 
11010   while ((!times_up) || (trans_remaining > 0)) {
11011 
11012     /* accept a connection from the remote */
11013     if ((s_data=accept(s_listen,
11014 		       (struct sockaddr *)&peeraddr_in,
11015 		       &addrlen)) == INVALID_SOCKET) {
11016       if (errno == EINTR) {
11017 	/* the timer popped */
11018 	timed_out = 1;
11019 	break;
11020       }
11021       fprintf(where,"recv_tcp_tran_rr: accept: errno = %d\n",errno);
11022       fflush(where);
11023       close(s_listen);
11024 
11025       exit(1);
11026     }
11027 
11028     if (debug) {
11029       fprintf(where,"recv_tcp_tran_rr: accepted data connection.\n");
11030       fflush(where);
11031     }
11032 
11033 #ifdef WIN32
11034   /* this is used so the timer thread can close the socket out from */
11035   /* under us, which to date is the easiest/cleanest/least */
11036   /* Windows-specific way I can find to force the winsock calls to */
11037   /* return WSAEINTR with the test is over. anything that will run on */
11038   /* 95 and NT and is closer to what netperf expects from Unix signals */
11039   /* and such would be appreciated raj 1/96 */
11040   win_kludge_socket = s_data;
11041 #endif /* WIN32 */
11042 
11043 #ifdef KLUDGE_SOCKET_OPTIONS
11044   /* this is for those systems which *INCORRECTLY* fail to pass */
11045   /* attributes across an accept() call. Including this goes against */
11046   /* my better judgement :( raj 11/95 */
11047 
11048   kludge_socket_options(s_data);
11049 
11050 #endif /* KLUDGE_SOCKET_OPTIONS */
11051 
11052     temp_message_ptr	= recv_message_ptr;
11053     request_bytes_remaining	= tcp_tran_rr_request->request_size;
11054 
11055     /* receive the request from the other side. we can just receive */
11056     /* until we get zero bytes, but that would be a slight structure */
11057     /* change in the code, with minimal perfomance effects. If */
11058     /* however, I has variable-length messages, I would want to do */
11059     /* this to avoid needing "double reads" - one for the message */
11060     /* length, and one for the rest of the message raj 3/95 */
11061     while(request_bytes_remaining > 0) {
11062       if((request_bytes_recvd=recv(s_data,
11063 				   temp_message_ptr,
11064 				   request_bytes_remaining,
11065 				   0)) == SOCKET_ERROR) {
11066 	    if ( SOCKET_EINTR(request_bytes_recvd) )
11067 		{
11068 	      /* the timer popped */
11069 	      timed_out = 1;
11070 	      break;
11071 		}
11072 	    netperf_response.content.serv_errno = errno;
11073 	    send_response();
11074 	    exit(1);
11075       }
11076       else {
11077 	request_bytes_remaining -= request_bytes_recvd;
11078 	temp_message_ptr  += request_bytes_recvd;
11079       }
11080     }
11081 
11082     if (timed_out) {
11083       /* we hit the end of the test based on time - lets */
11084       /* bail out of here now... */
11085       fprintf(where,"yo5\n");
11086       fflush(where);
11087       break;
11088     }
11089 
11090     /* Now, send the response to the remote we can use sendto here to */
11091     /* help remind people that this is an rfc 1644 style of test */
11092     if((bytes_sent=sendto(s_data,
11093 			  send_message_ptr,
11094 			  tcp_tran_rr_request->response_size,
11095 			  MSG_EOF,
11096 			  (struct sockaddr *)&peeraddr_in,
11097 			  sizeof(struct sockaddr_storage))) == SOCKET_ERROR) {
11098       if (SOCKET_EINTR(bytes_sent)) {
11099 	/* the test timer has popped */
11100 	timed_out = 1;
11101 	fprintf(where,"yo6\n");
11102 	fflush(where);
11103 	break;
11104       }
11105       netperf_response.content.serv_errno = 99;
11106       send_response();
11107       exit(1);
11108     }
11109 
11110     trans_received++;
11111     if (trans_remaining) {
11112       trans_remaining--;
11113     }
11114 
11115     if (debug) {
11116       fprintf(where,
11117 	      "recv_tcp_tran_rr: Transaction %d complete\n",
11118 	      trans_received);
11119       fflush(where);
11120     }
11121 
11122     /* close the connection. since we have disable PUSH on sends, the */
11123     /* FIN should be tacked-onto our last send instead of being */
11124     /* standalone */
11125     close(s_data);
11126 
11127   }
11128 
11129 
11130   /* The loop now exits due to timeout or transaction count being */
11131   /* reached */
11132 
11133   cpu_stop(tcp_tran_rr_request->measure_cpu,&elapsed_time);
11134 
11135   if (timed_out) {
11136     /* we ended the test by time, which was at least 2 seconds */
11137     /* longer than we wanted to run. so, we want to subtract */
11138     /* PAD_TIME from the elapsed_time. */
11139     elapsed_time -= PAD_TIME;
11140   }
11141   /* send the results to the sender			*/
11142 
11143   if (debug) {
11144     fprintf(where,
11145 	    "recv_tcp_tran_rr: got %d transactions\n",
11146 	    trans_received);
11147     fflush(where);
11148   }
11149 
11150   tcp_tran_rr_results->bytes_received	= (trans_received *
11151 					   (tcp_tran_rr_request->request_size +
11152 					    tcp_tran_rr_request->response_size));
11153   tcp_tran_rr_results->trans_received	= trans_received;
11154   tcp_tran_rr_results->elapsed_time	= elapsed_time;
11155   if (tcp_tran_rr_request->measure_cpu) {
11156     tcp_tran_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
11157   }
11158 
11159   if (debug) {
11160     fprintf(where,
11161 	    "recv_tcp_tran_rr: test complete, sending results.\n");
11162     fflush(where);
11163   }
11164 
11165   send_response();
11166 
11167 }
11168 #endif /* DO_1644 */
11169 
11170 #ifdef DO_NBRR
11171  /* this routine implements the sending (netperf) side of the TCP_RR */
11172  /* test using POSIX-style non-blocking sockets. */
11173 
11174 void
send_tcp_nbrr(char remote_host[])11175 send_tcp_nbrr(char remote_host[])
11176 {
11177 
11178   char *tput_title = "\
11179 Local /Remote\n\
11180 Socket Size   Request  Resp.   Elapsed  Trans.\n\
11181 Send   Recv   Size     Size    Time     Rate         \n\
11182 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
11183 
11184   char *tput_fmt_0 =
11185     "%7.2f\n";
11186 
11187   char *tput_fmt_1_line_1 = "\
11188 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
11189   char *tput_fmt_1_line_2 = "\
11190 %-6d %-6d\n";
11191 
11192   char *cpu_title = "\
11193 Local /Remote\n\
11194 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
11195 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
11196 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
11197 
11198   char *cpu_fmt_0 =
11199     "%6.3f %c\n";
11200 
11201   char *cpu_fmt_1_line_1 = "\
11202 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f  %-6.2f %-6.2f %-6.3f  %-6.3f\n";
11203 
11204   char *cpu_fmt_1_line_2 = "\
11205 %-6d %-6d\n";
11206 
11207   char *ksink_fmt = "\
11208 Alignment      Offset\n\
11209 Local  Remote  Local  Remote\n\
11210 Send   Recv    Send   Recv\n\
11211 %5d  %5d   %5d  %5d\n";
11212 
11213 
11214   int			timed_out = 0;
11215   float			elapsed_time;
11216 
11217   int	len;
11218   char	*temp_message_ptr;
11219   int	nummessages;
11220   SOCKET	send_socket;
11221   int	trans_remaining;
11222   double	bytes_xferd;
11223 
11224   struct ring_elt *send_ring;
11225   struct ring_elt *recv_ring;
11226 
11227   int	rsp_bytes_left;
11228   int	rsp_bytes_recvd;
11229 
11230   float	local_cpu_utilization;
11231   float	local_service_demand;
11232   float	remote_cpu_utilization;
11233   float	remote_service_demand;
11234   double	thruput;
11235 
11236   struct	hostent	        *hp;
11237   struct	sockaddr_storage	server;
11238   unsigned      int             addr;
11239 
11240   struct	tcp_rr_request_struct	*tcp_rr_request;
11241   struct	tcp_rr_response_struct	*tcp_rr_response;
11242   struct	tcp_rr_results_struct	*tcp_rr_result;
11243 
11244   struct addrinfo *remote_res;
11245   struct addrinfo *local_res;
11246 
11247   tcp_rr_request =
11248     (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data;
11249   tcp_rr_response=
11250     (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data;
11251   tcp_rr_result	=
11252     (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data;
11253 
11254 #ifdef WANT_HISTOGRAM
11255   if (verbosity > 1) {
11256     time_hist = HIST_new();
11257   }
11258 #endif /* WANT_HISTOGRAM */
11259 
11260   /* since we are now disconnected from the code that established the */
11261   /* control socket, and since we want to be able to use different */
11262   /* protocols and such, we are passed the name of the remote host and */
11263   /* must turn that into the test specific addressing information. */
11264 
11265   bzero((char *)&server,
11266 	sizeof(server));
11267 
11268   complete_addrinfos(&remote_res,
11269 		     &local_res,
11270 		     remote_host,
11271 		     SOCK_STREAM,
11272 		     IPPROTO_TCP,
11273 		     0);
11274 
11275   if ( print_headers ) {
11276     print_top_test_header("TCP Non-Blocking REQUEST/RESPONSE TEST",local_res,remote_res);
11277   }
11278 
11279   /* initialize a few counters */
11280 
11281   send_ring = NULL;
11282   recv_ring = NULL;
11283   confidence_iteration = 1;
11284   init_stat();
11285 
11286   /* we have a great-big while loop which controls the number of times */
11287   /* we run a particular test. this is for the calculation of a */
11288   /* confidence interval (I really should have stayed awake during */
11289   /* probstats :). If the user did not request confidence measurement */
11290   /* (no confidence is the default) then we will only go though the */
11291   /* loop once. the confidence stuff originates from the folks at IBM */
11292 
11293   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
11294 	 (confidence_iteration <= iteration_min)) {
11295 
11296     /* initialize a few counters. we have to remember that we might be */
11297     /* going through the loop more than once. */
11298 
11299     nummessages     = 0;
11300     bytes_xferd     = 0.0;
11301     times_up        = 0;
11302     timed_out       = 0;
11303     trans_remaining = 0;
11304 
11305     /* set-up the data buffers with the requested alignment and offset. */
11306     /* since this is a request/response test, default the send_width and */
11307     /* recv_width to 1 and not two raj 7/94 */
11308 
11309     if (send_width == 0) send_width = 1;
11310     if (recv_width == 0) recv_width = 1;
11311 
11312     if (send_ring == NULL) {
11313       send_ring = allocate_buffer_ring(send_width,
11314 				       req_size,
11315 				       local_send_align,
11316 				       local_send_offset);
11317     }
11318 
11319     if (recv_ring == NULL) {
11320       recv_ring = allocate_buffer_ring(recv_width,
11321 				       rsp_size,
11322 				       local_recv_align,
11323 				       local_recv_offset);
11324     }
11325 
11326     /*set up the data socket                        */
11327     send_socket = create_data_socket(local_res);
11328 
11329     if (send_socket == INVALID_SOCKET){
11330       perror("netperf: send_tcp_nbrr: tcp stream data socket");
11331       exit(1);
11332     }
11333 
11334     if (debug) {
11335       fprintf(where,"send_tcp_nbrr: send_socket obtained...\n");
11336     }
11337 
11338     /* If the user has requested cpu utilization measurements, we must */
11339     /* calibrate the cpu(s). We will perform this task within the tests */
11340     /* themselves. If the user has specified the cpu rate, then */
11341     /* calibrate_local_cpu will return rather quickly as it will have */
11342     /* nothing to do. If local_cpu_rate is zero, then we will go through */
11343     /* all the "normal" calibration stuff and return the rate back.*/
11344 
11345     if (local_cpu_usage) {
11346       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
11347     }
11348 
11349     /* Tell the remote end to do a listen. The server alters the socket */
11350     /* paramters on the other side at this point, hence the reason for */
11351     /* all the values being passed in the setup message. If the user did */
11352     /* not specify any of the parameters, they will be passed as 0, which */
11353     /* will indicate to the remote that no changes beyond the system's */
11354     /* default should be used. Alignment is the exception, it will */
11355     /* default to 8, which will be no alignment alterations. */
11356 
11357     netperf_request.content.request_type	=	DO_TCP_NBRR;
11358     tcp_rr_request->recv_buf_size	=	rsr_size_req;
11359     tcp_rr_request->send_buf_size	=	rss_size_req;
11360     tcp_rr_request->recv_alignment      =	remote_recv_align;
11361     tcp_rr_request->recv_offset	        =	remote_recv_offset;
11362     tcp_rr_request->send_alignment      =	remote_send_align;
11363     tcp_rr_request->send_offset	        =	remote_send_offset;
11364     tcp_rr_request->request_size	=	req_size;
11365     tcp_rr_request->response_size	=	rsp_size;
11366     tcp_rr_request->no_delay	        =	rem_nodelay;
11367     tcp_rr_request->measure_cpu	        =	remote_cpu_usage;
11368     tcp_rr_request->cpu_rate	        =	remote_cpu_rate;
11369     tcp_rr_request->so_rcvavoid	        =	rem_rcvavoid;
11370     tcp_rr_request->so_sndavoid	        =	rem_sndavoid;
11371     if (test_time) {
11372       tcp_rr_request->test_length	=	test_time;
11373     }
11374     else {
11375       tcp_rr_request->test_length	=	test_trans * -1;
11376     }
11377 
11378     if (debug > 1) {
11379       fprintf(where,"netperf: send_tcp_nbrr: requesting TCP rr test\n");
11380     }
11381 
11382     send_request();
11383 
11384     /* The response from the remote will contain all of the relevant 	*/
11385     /* socket parameters for this test type. We will put them back into */
11386     /* the variables here so they can be displayed if desired.  The	*/
11387     /* remote will have calibrated CPU if necessary, and will have done	*/
11388     /* all the needed set-up we will have calibrated the cpu locally	*/
11389     /* before sending the request, and will grab the counter value right*/
11390     /* after the connect returns. The remote will grab the counter right*/
11391     /* after the accept call. This saves the hassle of extra messages	*/
11392     /* being sent for the TCP tests.					*/
11393 
11394     recv_response();
11395 
11396     if (!netperf_response.content.serv_errno) {
11397       if (debug)
11398 	fprintf(where,"remote listen done.\n");
11399       rsr_size          = tcp_rr_response->recv_buf_size;
11400       rss_size          = tcp_rr_response->send_buf_size;
11401       rem_nodelay       = tcp_rr_response->no_delay;
11402       remote_cpu_usage  = tcp_rr_response->measure_cpu;
11403       remote_cpu_rate   = tcp_rr_response->cpu_rate;
11404       /* make sure that port numbers are in network order */
11405       server.sin_port   = (unsigned short)tcp_rr_response->data_port_number;
11406       server.sin_port   = htons(server.sin_port);
11407     }
11408     else {
11409       Set_errno(netperf_response.content.serv_errno);
11410       fprintf(where,
11411 	      "netperf: remote error %d",
11412 	      netperf_response.content.serv_errno);
11413       perror("");
11414       fflush(where);
11415       exit(1);
11416     }
11417 
11418     /*Connect up to the remote port on the data socket  */
11419     if (connect(send_socket,
11420 		remote_res->ai_addr,
11421 		remote_res->ai_addrlen) == INVALID_SOCKET){
11422       perror("netperf: data socket connect failed");
11423 
11424       exit(1);
11425     }
11426 
11427     /* now that we are connected, mark the socket as non-blocking */
11428     if (!set_nonblock(send_socket)) {
11429       perror("netperf: set_nonblock");
11430       exit(1);
11431     }
11432 
11433 #ifdef WIN32
11434   /* this is used so the timer thread can close the socket out from */
11435   /* under us, which to date is the easiest/cleanest/least */
11436   /* Windows-specific way I can find to force the winsock calls to */
11437   /* return WSAEINTR with the test is over. anything that will run on */
11438   /* 95 and NT and is closer to what netperf expects from Unix signals */
11439   /* and such would be appreciated raj 1/96 */
11440   win_kludge_socket = send_socket;
11441 #endif /* WIN32 */
11442 
11443     /* Data Socket set-up is finished. If there were problems, either the */
11444     /* connect would have failed, or the previous response would have */
11445     /* indicated a problem. I failed to see the value of the extra */
11446     /* message after the accept on the remote. If it failed, we'll see it */
11447     /* here. If it didn't, we might as well start pumping data. */
11448 
11449     /* Set-up the test end conditions. For a request/response test, they */
11450     /* can be either time or transaction based. */
11451 
11452     if (test_time) {
11453       /* The user wanted to end the test after a period of time. */
11454       times_up = 0;
11455       trans_remaining = 0;
11456       start_timer(test_time);
11457     }
11458     else {
11459       /* The tester wanted to send a number of bytes. */
11460       trans_remaining = test_bytes;
11461       times_up = 1;
11462     }
11463 
11464     /* The cpu_start routine will grab the current time and possibly */
11465     /* value of the idle counter for later use in measuring cpu */
11466     /* utilization and/or service demand and thruput. */
11467 
11468     cpu_start(local_cpu_usage);
11469 
11470 #ifdef WANT_INTERVALS
11471     INTERVALS_INIT();
11472 #endif /* WANT_INTERVALS */
11473 
11474     /* We use an "OR" to control test execution. When the test is */
11475     /* controlled by time, the byte count check will always return false. */
11476     /* When the test is controlled by byte count, the time test will */
11477     /* always return false. When the test is finished, the whole */
11478     /* expression will go false and we will stop sending data. I think I */
11479     /* just arbitrarily decrement trans_remaining for the timed test, but */
11480     /* will not do that just yet... One other question is whether or not */
11481     /* the send buffer and the receive buffer should be the same buffer. */
11482 
11483     while ((!times_up) || (trans_remaining > 0)) {
11484       /* send the request. we assume that if we use a blocking socket, */
11485       /* the request will be sent at one shot. */
11486 
11487 #ifdef WANT_HISTOGRAM
11488       if (verbosity > 1) {
11489 	/* timestamp just before our call to send, and then again just */
11490 	/* after the receive raj 8/94 */
11491 	HIST_timestamp(&time_one);
11492       }
11493 #endif /* WANT_HISTOGRAM */
11494 
11495       /* even though this is a non-blocking socket, we will assume for */
11496       /* the time being that we will be able to send an entire request */
11497       /* without getting an EAGAIN */
11498       if((len=send(send_socket,
11499 		   send_ring->buffer_ptr,
11500 		   req_size,
11501 		   0)) != req_size) {
11502 	if (SOCKET_EINTR(len)) {
11503 	  /* we hit the end of a */
11504 	  /* timed test. */
11505 	  timed_out = 1;
11506 	  break;
11507 	}
11508 	perror("send_tcp_nbrr: data send error");
11509 	exit(1);
11510       }
11511       send_ring = send_ring->next;
11512 
11513       /* receive the response. since we are using non-blocking I/O, we */
11514       /* will "spin" on the recvs */
11515       rsp_bytes_left = rsp_size;
11516       temp_message_ptr  = recv_ring->buffer_ptr;
11517       while(rsp_bytes_left > 0) {
11518 	if((rsp_bytes_recvd=recv(send_socket,
11519 				 temp_message_ptr,
11520 				 rsp_bytes_left,
11521 				 0)) == SOCKET_ERROR) {
11522 	  if (SOCKET_EINTR(rsp_bytes_recvd))
11523 	  {
11524 	    /* We hit the end of a timed test. */
11525 	    timed_out = 1;
11526 	    break;
11527 	  }
11528 #ifndef WIN32  // But what does WinNT indicate in this situation...
11529 	  else if (errno == EAGAIN) {
11530 	    Set_errno(0);
11531 	    continue;
11532 	  }
11533 #endif
11534 	  else {
11535 	    perror("send_tcp_nbrr: data recv error");
11536 	    exit(1);
11537 	  }
11538 	}
11539 	rsp_bytes_left -= rsp_bytes_recvd;
11540 	temp_message_ptr  += rsp_bytes_recvd;
11541       }
11542       recv_ring = recv_ring->next;
11543 
11544       if (timed_out) {
11545 	/* we may have been in a nested while loop - we need */
11546 	/* another call to break. */
11547 	break;
11548       }
11549 
11550 #ifdef WANT_HISTOGRAM
11551       if (verbosity > 1) {
11552 	HIST_timestamp(&time_two);
11553 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
11554       }
11555 #endif /* WANT_HISTOGRAM */
11556 #ifdef WANT_INTERVALS
11557       INTERVALS_WAIT();
11558 #endif /* WANT_INTERVALS */
11559 
11560       nummessages++;
11561       if (trans_remaining) {
11562 	trans_remaining--;
11563       }
11564 
11565       if (debug > 3) {
11566 	if ((nummessages % 100) == 0) {
11567 	  fprintf(where,
11568 		  "Transaction %d completed\n",
11569 		  nummessages);
11570 	  fflush(where);
11571 	}
11572       }
11573     }
11574 
11575     /* At this point we used to call shutdown on the data socket to be */
11576     /* sure all the data was delivered, but this was not germane in a */
11577     /* request/response test, and it was causing the tests to "hang" when */
11578     /* they were being controlled by time. So, I have replaced this */
11579     /* shutdown call with a call to close that can be found later in the */
11580     /* procedure. */
11581 
11582     /* this call will always give us the elapsed time for the test, and */
11583     /* will also store-away the necessaries for cpu utilization */
11584 
11585     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
11586 						/* measured? how long */
11587 						/* did we really run? */
11588 
11589     /* Get the statistics from the remote end. The remote will have */
11590     /* calculated service demand and all those interesting things. If it */
11591     /* wasn't supposed to care, it will return obvious values. */
11592 
11593 #if defined(WANT_INTERVALS)
11594 #ifdef WIN32
11595     stop_itimer();
11596 #endif
11597 #endif /* WANT_INTERVALS */
11598 
11599     recv_response();
11600     if (!netperf_response.content.serv_errno) {
11601       if (debug)
11602 	fprintf(where,"remote results obtained\n");
11603     }
11604     else {
11605       Set_errno(netperf_response.content.serv_errno);
11606       fprintf(where,
11607 	      "netperf: remote error %d",
11608 	      netperf_response.content.serv_errno);
11609       perror("");
11610       fflush(where);
11611 
11612       exit(1);
11613     }
11614 
11615     /* We now calculate what our thruput was for the test. */
11616 
11617     bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
11618     thruput	= nummessages/elapsed_time;
11619 
11620     if (local_cpu_usage || remote_cpu_usage) {
11621       /* We must now do a little math for service demand and cpu */
11622       /* utilization for the system(s) */
11623       /* Of course, some of the information might be bogus because */
11624       /* there was no idle counter in the kernel(s). We need to make */
11625       /* a note of this for the user's benefit...*/
11626       if (local_cpu_usage) {
11627 	local_cpu_utilization = calc_cpu_util(0.0);
11628 	/* since calc_service demand is doing ms/Kunit we will */
11629 	/* multiply the number of transaction by 1024 to get */
11630 	/* "good" numbers */
11631 	local_service_demand  = calc_service_demand((double) nummessages*1024,
11632 						    0.0,
11633 						    0.0,
11634 						    0);
11635       }
11636       else {
11637 	local_cpu_utilization	= (float) -1.0;
11638 	local_service_demand	= (float) -1.0;
11639       }
11640 
11641       if (remote_cpu_usage) {
11642 	remote_cpu_utilization = tcp_rr_result->cpu_util;
11643 	/* since calc_service demand is doing ms/Kunit we will */
11644 	/* multiply the number of transaction by 1024 to get */
11645 	/* "good" numbers */
11646 	remote_service_demand = calc_service_demand((double) nummessages*1024,
11647 						    0.0,
11648 						    remote_cpu_utilization,
11649 						    tcp_rr_result->num_cpus);
11650       }
11651       else {
11652 	remote_cpu_utilization = (float) -1.0;
11653 	remote_service_demand  = (float) -1.0;
11654       }
11655 
11656     }
11657     else {
11658       /* we were not measuring cpu, for the confidence stuff, we */
11659       /* should make it -1.0 */
11660       local_cpu_utilization	= (float) -1.0;
11661       local_service_demand	= (float) -1.0;
11662       remote_cpu_utilization = (float) -1.0;
11663       remote_service_demand  = (float) -1.0;
11664     }
11665 
11666     /* at this point, we want to calculate the confidence information. */
11667     /* if debugging is on, calculate_confidence will print-out the */
11668     /* parameters we pass it */
11669 
11670     calculate_confidence(confidence_iteration,
11671 			 elapsed_time,
11672 			 thruput,
11673 			 local_cpu_utilization,
11674 			 remote_cpu_utilization,
11675 			 local_service_demand,
11676 			 remote_service_demand);
11677 
11678 
11679     confidence_iteration++;
11680 
11681     /* we are now done with the socket, so close it */
11682     close(send_socket);
11683 
11684   }
11685 
11686   retrieve_confident_values(&elapsed_time,
11687 			    &thruput,
11688 			    &local_cpu_utilization,
11689 			    &remote_cpu_utilization,
11690 			    &local_service_demand,
11691 			    &remote_service_demand);
11692 
11693   /* We are now ready to print all the information. If the user */
11694   /* has specified zero-level verbosity, we will just print the */
11695   /* local service demand, or the remote service demand. If the */
11696   /* user has requested verbosity level 1, he will get the basic */
11697   /* "streamperf" numbers. If the user has specified a verbosity */
11698   /* of greater than 1, we will display a veritable plethora of */
11699   /* background information from outside of this block as it it */
11700   /* not cpu_measurement specific...  */
11701 
11702   if (confidence < 0) {
11703     /* we did not hit confidence, but were we asked to look for it? */
11704     if (iteration_max > 1) {
11705       display_confidence();
11706     }
11707   }
11708 
11709   if (local_cpu_usage || remote_cpu_usage) {
11710     local_cpu_method = format_cpu_method(cpu_method);
11711     remote_cpu_method = format_cpu_method(tcp_rr_result->cpu_method);
11712 
11713     switch (verbosity) {
11714     case 0:
11715       if (local_cpu_usage) {
11716 	fprintf(where,
11717 		cpu_fmt_0,
11718 		local_service_demand,
11719 		local_cpu_method);
11720       }
11721       else {
11722 	fprintf(where,
11723 		cpu_fmt_0,
11724 		remote_service_demand,
11725 		remote_cpu_method);
11726       }
11727       break;
11728     case 1:
11729     case 2:
11730       if (print_headers) {
11731 	fprintf(where,
11732 		cpu_title,
11733 		local_cpu_method,
11734 		remote_cpu_method);
11735       }
11736 
11737       fprintf(where,
11738 	      cpu_fmt_1_line_1,		/* the format string */
11739 	      lss_size,		/* local sendbuf size */
11740 	      lsr_size,
11741 	      req_size,		/* how large were the requests */
11742 	      rsp_size,		/* guess */
11743 	      elapsed_time,		/* how long was the test */
11744 	      thruput,
11745 	      local_cpu_utilization,	/* local cpu */
11746 	      remote_cpu_utilization,	/* remote cpu */
11747 	      local_service_demand,	/* local service demand */
11748 	      remote_service_demand);	/* remote service demand */
11749       fprintf(where,
11750 	      cpu_fmt_1_line_2,
11751 	      rss_size,
11752 	      rsr_size);
11753       break;
11754     }
11755   }
11756   else {
11757     /* The tester did not wish to measure service demand. */
11758 
11759     switch (verbosity) {
11760     case 0:
11761       fprintf(where,
11762 	      tput_fmt_0,
11763 	      thruput);
11764       break;
11765     case 1:
11766     case 2:
11767       if (print_headers) {
11768 	fprintf(where,tput_title,format_units());
11769       }
11770 
11771       fprintf(where,
11772 	      tput_fmt_1_line_1,	/* the format string */
11773 	      lss_size,
11774 	      lsr_size,
11775 	      req_size,		/* how large were the requests */
11776 	      rsp_size,		/* how large were the responses */
11777 	      elapsed_time, 		/* how long did it take */
11778 	      thruput);
11779       fprintf(where,
11780 	      tput_fmt_1_line_2,
11781 	      rss_size, 		/* remote recvbuf size */
11782 	      rsr_size);
11783 
11784       break;
11785     }
11786   }
11787 
11788   /* it would be a good thing to include information about some of the */
11789   /* other parameters that may have been set for this test, but at the */
11790   /* moment, I do not wish to figure-out all the  formatting, so I will */
11791   /* just put this comment here to help remind me that it is something */
11792   /* that should be done at a later time. */
11793 
11794   /* how to handle the verbose information in the presence of */
11795   /* confidence intervals is yet to be determined... raj 11/94 */
11796   if (verbosity > 1) {
11797     /* The user wanted to know it all, so we will give it to him. */
11798     /* This information will include as much as we can find about */
11799     /* TCP statistics, the alignments of the sends and receives */
11800     /* and all that sort of rot... */
11801 
11802     fprintf(where,
11803 	    ksink_fmt,
11804 	    local_send_align,
11805 	    remote_recv_offset,
11806 	    local_send_offset,
11807 	    remote_recv_offset);
11808 
11809 #ifdef WANT_HISTOGRAM
11810     fprintf(where,"\nHistogram of request/response times\n");
11811     fflush(where);
11812     HIST_report(time_hist);
11813 #endif /* WANT_HISTOGRAM */
11814 
11815   }
11816 
11817 }
11818 
11819  /* this routine implements the receive (netserver) side of a TCP_RR */
11820  /* test */
11821 void
recv_tcp_nbrr()11822 recv_tcp_nbrr()
11823 {
11824 
11825   struct ring_elt *send_ring;
11826   struct ring_elt *recv_ring;
11827 
11828   struct	sockaddr_in        myaddr_in,
11829   peeraddr_in;
11830   SOCKET	s_listen,s_data;
11831   netperf_socklen_t 	addrlen;
11832   char	*temp_message_ptr;
11833   int	trans_received;
11834   int	trans_remaining;
11835   int	bytes_sent;
11836   int	request_bytes_recvd;
11837   int	request_bytes_remaining;
11838   int	timed_out = 0;
11839   float	elapsed_time;
11840 
11841   struct addrinfo *local_res;
11842   char local_name[BUFSIZ];
11843   char port_buffer[PORTBUFSIZE];
11844 
11845   struct	tcp_rr_request_struct	*tcp_rr_request;
11846   struct	tcp_rr_response_struct	*tcp_rr_response;
11847   struct	tcp_rr_results_struct	*tcp_rr_results;
11848 
11849   tcp_rr_request =
11850     (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data;
11851   tcp_rr_response =
11852     (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data;
11853   tcp_rr_results =
11854     (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data;
11855 
11856   if (debug) {
11857     fprintf(where,"netserver: recv_tcp_nbrr: entered...\n");
11858     fflush(where);
11859   }
11860 
11861   /* We want to set-up the listen socket with all the desired */
11862   /* parameters and then let the initiator know that all is ready. If */
11863   /* socket size defaults are to be used, then the initiator will have */
11864   /* sent us 0's. If the socket sizes cannot be changed, then we will */
11865   /* send-back what they are. If that information cannot be determined, */
11866   /* then we send-back -1's for the sizes. If things go wrong for any */
11867   /* reason, we will drop back ten yards and punt. */
11868 
11869   /* If anything goes wrong, we want the remote to know about it. It */
11870   /* would be best if the error that the remote reports to the user is */
11871   /* the actual error we encountered, rather than some bogus unexpected */
11872   /* response type message. */
11873 
11874   if (debug) {
11875     fprintf(where,"recv_tcp_nbrr: setting the response type...\n");
11876     fflush(where);
11877   }
11878 
11879   netperf_response.content.response_type = TCP_RR_RESPONSE;
11880 
11881   if (debug) {
11882     fprintf(where,"recv_tcp_nbrr: the response type is set...\n");
11883     fflush(where);
11884   }
11885 
11886   /* allocate the recv and send rings with the requested alignments */
11887   /* and offsets. raj 7/94 */
11888   if (debug) {
11889     fprintf(where,"recv_tcp_nbrr: requested recv alignment of %d offset %d\n",
11890 	    tcp_rr_request->recv_alignment,
11891 	    tcp_rr_request->recv_offset);
11892     fprintf(where,"recv_tcp_nbrr: requested send alignment of %d offset %d\n",
11893 	    tcp_rr_request->send_alignment,
11894 	    tcp_rr_request->send_offset);
11895     fflush(where);
11896   }
11897 
11898   /* at some point, these need to come to us from the remote system */
11899   if (send_width == 0) send_width = 1;
11900   if (recv_width == 0) recv_width = 1;
11901 
11902   send_ring = allocate_buffer_ring(send_width,
11903 				   tcp_rr_request->response_size,
11904 				   tcp_rr_request->send_alignment,
11905 				   tcp_rr_request->send_offset);
11906 
11907   recv_ring = allocate_buffer_ring(recv_width,
11908 				   tcp_rr_request->request_size,
11909 				   tcp_rr_request->recv_alignment,
11910 				   tcp_rr_request->recv_offset);
11911 
11912 
11913   /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */
11914   /* can put in OUR values !-) At some point, we may want to nail this */
11915   /* socket to a particular network-level address, but for now, */
11916   /* INADDR_ANY should be just fine. */
11917 
11918   bzero((char *)&myaddr_in,
11919 	sizeof(myaddr_in));
11920   myaddr_in.sin_family      = AF_INET;
11921   myaddr_in.sin_addr.s_addr = INADDR_ANY;
11922   myaddr_in.sin_port        = htons((unsigned short)tcp_rr_request->port);
11923 
11924   /* Grab a socket to listen on, and then listen on it. */
11925 
11926   if (debug) {
11927     fprintf(where,"recv_tcp_nbrr: grabbing a socket...\n");
11928     fflush(where);
11929   }
11930 
11931   /* create_data_socket expects to find some things in the global */
11932   /* variables, so set the globals based on the values in the request. */
11933   /* once the socket has been created, we will set the response values */
11934   /* based on the updated value of those globals. raj 7/94 */
11935   lss_size_req = tcp_rr_request->send_buf_size;
11936   lsr_size_req = tcp_rr_request->recv_buf_size;
11937   loc_nodelay = tcp_rr_request->no_delay;
11938   loc_rcvavoid = tcp_rr_request->so_rcvavoid;
11939   loc_sndavoid = tcp_rr_request->so_sndavoid;
11940 
11941   set_hostname_and_port(local_name,
11942 			port_buffer,
11943 			nf_to_af(tcp_rr_request->ipfamily),
11944 			tcp_rr_request->port);
11945 
11946   local_res = complete_addrinfo(local_name,
11947 				local_name,
11948 				port_buffer,
11949 				nf_to_af(tcp_rr_request->ipfamily),
11950 				SOCK_STREAM,
11951 				IPPROTO_TCP,
11952 				0);
11953 
11954   s_listen = create_data_socket(local_res);
11955 
11956   if (s_listen == INVALID_SOCKET) {
11957     netperf_response.content.serv_errno = errno;
11958     send_response();
11959 
11960     exit(1);
11961   }
11962 
11963   /* Let's get an address assigned to this socket so we can tell the */
11964   /* initiator how to reach the data socket. There may be a desire to */
11965   /* nail this socket to a specific IP address in a multi-homed, */
11966   /* multi-connection situation, but for now, we'll ignore the issue */
11967   /* and concentrate on single connection testing. */
11968 
11969   if (bind(s_listen,
11970 	   (struct sockaddr *)&myaddr_in,
11971 	   sizeof(myaddr_in)) == SOCKET_ERROR) {
11972     netperf_response.content.serv_errno = errno;
11973     close(s_listen);
11974     send_response();
11975 
11976     exit(1);
11977   }
11978 
11979   /* Now, let's set-up the socket to listen for connections */
11980   if (listen(s_listen, 5) == SOCKET_ERROR) {
11981     netperf_response.content.serv_errno = errno;
11982     close(s_listen);
11983     send_response();
11984 
11985     exit(1);
11986   }
11987 
11988 
11989   /* now get the port number assigned by the system  */
11990   addrlen = sizeof(myaddr_in);
11991   if (getsockname(s_listen,
11992 		  (struct sockaddr *)&myaddr_in, &addrlen) == SOCKET_ERROR){
11993     netperf_response.content.serv_errno = errno;
11994     close(s_listen);
11995     send_response();
11996 
11997     exit(1);
11998   }
11999 
12000   /* Now myaddr_in contains the port and the internet address this is */
12001   /* returned to the sender also implicitly telling the sender that the */
12002   /* socket buffer sizing has been done. */
12003 
12004   tcp_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port);
12005   netperf_response.content.serv_errno   = 0;
12006 
12007   /* But wait, there's more. If the initiator wanted cpu measurements, */
12008   /* then we must call the calibrate routine, which will return the max */
12009   /* rate back to the initiator. If the CPU was not to be measured, or */
12010   /* something went wrong with the calibration, we will return a 0.0 to */
12011   /* the initiator. */
12012 
12013   tcp_rr_response->cpu_rate = 0.0; 	/* assume no cpu */
12014   tcp_rr_response->measure_cpu = 0;
12015 
12016   if (tcp_rr_request->measure_cpu) {
12017     tcp_rr_response->measure_cpu = 1;
12018     tcp_rr_response->cpu_rate = calibrate_local_cpu(tcp_rr_request->cpu_rate);
12019   }
12020 
12021 
12022   /* before we send the response back to the initiator, pull some of */
12023   /* the socket parms from the globals */
12024   tcp_rr_response->send_buf_size = lss_size;
12025   tcp_rr_response->recv_buf_size = lsr_size;
12026   tcp_rr_response->no_delay = loc_nodelay;
12027   tcp_rr_response->so_rcvavoid = loc_rcvavoid;
12028   tcp_rr_response->so_sndavoid = loc_sndavoid;
12029   tcp_rr_response->test_length = tcp_rr_request->test_length;
12030   send_response();
12031 
12032   addrlen = sizeof(peeraddr_in);
12033 
12034   if ((s_data = accept(s_listen,
12035 		       (struct sockaddr *)&peeraddr_in,
12036 		       &addrlen)) == INVALID_SOCKET) {
12037     /* Let's just punt. The remote will be given some information */
12038     close(s_listen);
12039     exit(1);
12040   }
12041 
12042   if (debug) {
12043     fprintf(where,"recv_tcp_nbrr: accept completes on the data connection.\n");
12044     fflush(where);
12045   }
12046 
12047 #ifdef KLUDGE_SOCKET_OPTIONS
12048   /* this is for those systems which *INCORRECTLY* fail to pass */
12049   /* attributes across an accept() call. Including this goes against */
12050   /* my better judgement :( raj 11/95 */
12051 
12052   kludge_socket_options(s_data);
12053 
12054 #endif /* KLUDGE_SOCKET_OPTIONS */
12055 
12056   /* now that we are connected, mark the socket as non-blocking */
12057   if (!set_nonblock(s_data)) {
12058     close(s_data);
12059     exit(1);
12060   }
12061 
12062 
12063   /* Now it's time to start receiving data on the connection. We will */
12064   /* first grab the apropriate counters and then start grabbing. */
12065 
12066   cpu_start(tcp_rr_request->measure_cpu);
12067 
12068 #ifdef WIN32
12069   /* this is used so the timer thread can close the socket out from */
12070   /* under us, which to date is the easiest/cleanest/least */
12071   /* Windows-specific way I can find to force the winsock calls to */
12072   /* return WSAEINTR with the test is over. anything that will run on */
12073   /* 95 and NT and is closer to what netperf expects from Unix signals */
12074   /* and such would be appreciated raj 1/96 */
12075   win_kludge_socket = s_data;
12076 #endif /* WIN32 */
12077 
12078   /* The loop will exit when the sender does a shutdown, which will */
12079   /* return a length of zero   */
12080 
12081   if (tcp_rr_request->test_length > 0) {
12082     times_up = 0;
12083     trans_remaining = 0;
12084     start_timer(tcp_rr_request->test_length + PAD_TIME);
12085   }
12086   else {
12087     times_up = 1;
12088     trans_remaining = tcp_rr_request->test_length * -1;
12089   }
12090 
12091   trans_received = 0;
12092 
12093   while ((!times_up) || (trans_remaining > 0)) {
12094     temp_message_ptr = recv_ring->buffer_ptr;
12095     request_bytes_remaining	= tcp_rr_request->request_size;
12096     while(request_bytes_remaining > 0) {
12097       if((request_bytes_recvd=recv(s_data,
12098 				   temp_message_ptr,
12099 				   request_bytes_remaining,
12100 				   0)) == SOCKET_ERROR) {
12101 	    if ( SOCKET_EINTR(request_bytes_recvd))
12102 		{
12103 	      /* the timer popped */
12104 	      timed_out = 1;
12105 	      break;
12106 		}
12107 #ifndef WIN32  // But what does WinNT indicate in this situation...
12108 	    else if (errno == EAGAIN) {
12109 	      Set_errno(0);
12110 	      if (times_up) {
12111 	        timed_out = 1;
12112 	        break;
12113 		  }
12114 	      continue;
12115 		}
12116 #endif
12117 	    else {
12118 	      netperf_response.content.serv_errno = errno;
12119 	      send_response();
12120 	      exit(1);
12121 		}
12122       }
12123       else {
12124 	request_bytes_remaining -= request_bytes_recvd;
12125 	temp_message_ptr  += request_bytes_recvd;
12126       }
12127     }
12128 
12129     recv_ring = recv_ring->next;
12130 
12131     if (timed_out) {
12132       /* we hit the end of the test based on time - lets */
12133       /* bail out of here now... */
12134       fprintf(where,"yo5\n");
12135       fflush(where);
12136       break;
12137     }
12138 
12139     /* Now, send the response to the remote */
12140     if((bytes_sent=send(s_data,
12141 			send_ring->buffer_ptr,
12142 			tcp_rr_request->response_size,
12143 			0)) == SOCKET_ERROR) {
12144       if (SOCKET_EINTR(bytes_sent)) {
12145 	/* the test timer has popped */
12146 	timed_out = 1;
12147 	fprintf(where,"yo6\n");
12148 	fflush(where);
12149 	break;
12150       }
12151       netperf_response.content.serv_errno = 992;
12152       send_response();
12153       exit(1);
12154     }
12155 
12156     send_ring = send_ring->next;
12157 
12158     trans_received++;
12159     if (trans_remaining) {
12160       trans_remaining--;
12161     }
12162   }
12163 
12164 
12165   /* The loop now exits due to timeout or transaction count being */
12166   /* reached */
12167 
12168   cpu_stop(tcp_rr_request->measure_cpu,&elapsed_time);
12169 
12170   stop_timer();
12171 
12172   if (timed_out) {
12173     /* we ended the test by time, which was at least 2 seconds */
12174     /* longer than we wanted to run. so, we want to subtract */
12175     /* PAD_TIME from the elapsed_time. */
12176     elapsed_time -= PAD_TIME;
12177   }
12178 
12179   /* send the results to the sender			*/
12180 
12181   if (debug) {
12182     fprintf(where,
12183 	    "recv_tcp_nbrr: got %d transactions\n",
12184 	    trans_received);
12185     fflush(where);
12186   }
12187 
12188   tcp_rr_results->bytes_received = (trans_received *
12189 				    (tcp_rr_request->request_size +
12190 				     tcp_rr_request->response_size));
12191   tcp_rr_results->trans_received = trans_received;
12192   tcp_rr_results->elapsed_time   = elapsed_time;
12193   tcp_rr_results->cpu_method     = cpu_method;
12194   tcp_rr_results->num_cpus       = lib_num_loc_cpus;
12195   if (tcp_rr_request->measure_cpu) {
12196     tcp_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
12197   }
12198 
12199   if (debug) {
12200     fprintf(where,
12201 	    "recv_tcp_nbrr: test complete, sending results.\n");
12202     fflush(where);
12203   }
12204 
12205   /* we are done with the socket, free it */
12206   close(s_data);
12207 
12208   send_response();
12209 
12210 }
12211 
12212 #endif /* DO_NBRR */
12213 
12214 
12215  /* this test is intended to test the performance of establishing a */
12216  /* connection, and then closing it again. this test is of somewhat */
12217  /* arcane interest since no packets are exchanged between the */
12218  /* user-space processes, but it will show the raw overhead of */
12219  /* establishing a TCP connection. that service demand could then be */
12220  /* compared with the sum of the service demands of a TCP_CRR and */
12221  /* TCP_RR test - presumeably, they would all relate */
12222 
12223 void
send_tcp_cc(char remote_host[])12224 send_tcp_cc(char remote_host[])
12225 {
12226 
12227   char *tput_title = "\
12228 Local /Remote\n\
12229 Socket Size   Request  Resp.   Elapsed  Trans.\n\
12230 Send   Recv   Size     Size    Time     Rate         \n\
12231 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
12232 
12233   char *tput_fmt_0 =
12234     "%7.2f\n";
12235 
12236   char *tput_fmt_1_line_1 = "\
12237 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
12238   char *tput_fmt_1_line_2 = "\
12239 %-6d %-6d\n";
12240 
12241   char *cpu_title = "\
12242 Local /Remote\n\
12243 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
12244 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
12245 bytes  bytes  bytes   bytes  secs.   per sec  %%      %%      us/Tr   us/Tr\n\n";
12246 
12247   char *cpu_fmt_0 =
12248     "%6.3f\n";
12249 
12250   char *cpu_fmt_1_line_1 = "\
12251 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f\n";
12252 
12253   char *cpu_fmt_1_line_2 = "\
12254 %-6d %-6d\n";
12255 
12256   char *ksink_fmt = "\n\
12257 Alignment      Offset\n\
12258 Local  Remote  Local  Remote\n\
12259 Send   Recv    Send   Recv\n\
12260 %5d  %5d   %5d  %5d\n";
12261 
12262 
12263   int			timed_out = 0;
12264   float			elapsed_time;
12265 
12266   char	temp_message_ptr[1];
12267   int	nummessages;
12268   SOCKET	send_socket;
12269   int	trans_remaining;
12270   double	bytes_xferd;
12271   int	rsp_bytes_left = 1;
12272   int	rsp_bytes_recvd;
12273 
12274   float	local_cpu_utilization;
12275   float	local_service_demand;
12276   float	remote_cpu_utilization;
12277   float	remote_service_demand;
12278   double	thruput;
12279 
12280   struct addrinfo *local_res;
12281   struct addrinfo *remote_res;
12282 
12283   int                           myport;
12284   int                           ret;
12285 
12286   struct	tcp_cc_request_struct	*tcp_cc_request;
12287   struct	tcp_cc_response_struct	*tcp_cc_response;
12288   struct	tcp_cc_results_struct	*tcp_cc_result;
12289 
12290   tcp_cc_request =
12291     (struct tcp_cc_request_struct *)netperf_request.content.test_specific_data;
12292   tcp_cc_response =
12293     (struct tcp_cc_response_struct *)netperf_response.content.test_specific_data;
12294   tcp_cc_result =
12295     (struct tcp_cc_results_struct *)netperf_response.content.test_specific_data;
12296 
12297 
12298 #ifdef WANT_HISTOGRAM
12299   if (verbosity > 1) {
12300     time_hist = HIST_new();
12301   }
12302 #endif /* WANT_HISTOGRAM */
12303 
12304   /* since we are now disconnected from the code that established the */
12305   /* control socket, and since we want to be able to use different */
12306   /* protocols and such, we are passed the name of the remote host and */
12307   /* must turn that into the test specific addressing information. */
12308 
12309   complete_addrinfos(&remote_res,
12310 		     &local_res,
12311 		     remote_host,
12312 		     SOCK_STREAM,
12313 		     IPPROTO_TCP,
12314 		     0);
12315 
12316   if ( print_headers ) {
12317     print_top_test_header("TCP Connect/Close TEST",local_res,remote_res);
12318   }
12319 
12320   /* initialize a few counters */
12321 
12322   nummessages	=	0;
12323   bytes_xferd	=	0.0;
12324   times_up 	= 	0;
12325 
12326   /* since there are no data buffers in this test, we need no send or */
12327   /* recv rings */
12328 
12329   if (debug) {
12330     fprintf(where,"send_tcp_cc: send_socket obtained...\n");
12331   }
12332 
12333   /* If the user has requested cpu utilization measurements, we must */
12334   /* calibrate the cpu(s). We will perform this task within the tests */
12335   /* themselves. If the user has specified the cpu rate, then */
12336   /* calibrate_local_cpu will return rather quickly as it will have */
12337   /* nothing to do. If local_cpu_rate is zero, then we will go through */
12338   /* all the "normal" calibration stuff and return the rate back.*/
12339 
12340   if (local_cpu_usage) {
12341     local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
12342   }
12343 
12344   /* Tell the remote end to do a listen. The server alters the socket */
12345   /* paramters on the other side at this point, hence the reason for */
12346   /* all the values being passed in the setup message. If the user did */
12347   /* not specify any of the parameters, they will be passed as 0, which */
12348   /* will indicate to the remote that no changes beyond the system's */
12349   /* default should be used. Alignment is the exception, it will */
12350   /* default to 8, which will be no alignment alterations. */
12351 
12352   netperf_request.content.request_type	=	DO_TCP_CC;
12353   tcp_cc_request->recv_buf_size	        =	rsr_size_req;
12354   tcp_cc_request->send_buf_size	        =	rss_size_req;
12355   tcp_cc_request->recv_alignment	=	remote_recv_align;
12356   tcp_cc_request->recv_offset	        =	remote_recv_offset;
12357   tcp_cc_request->send_alignment	=	remote_send_align;
12358   tcp_cc_request->send_offset	        =	remote_send_offset;
12359   tcp_cc_request->request_size	        =	req_size;
12360   tcp_cc_request->response_size	        =	rsp_size;
12361   tcp_cc_request->no_delay	        =	rem_nodelay;
12362   tcp_cc_request->measure_cpu	        =	remote_cpu_usage;
12363   tcp_cc_request->cpu_rate	        =	remote_cpu_rate;
12364   tcp_cc_request->so_rcvavoid	=	rem_rcvavoid;
12365   tcp_cc_request->so_sndavoid	=	rem_sndavoid;
12366   if (test_time) {
12367     tcp_cc_request->test_length	=	test_time;
12368   }
12369   else {
12370     tcp_cc_request->test_length	=	test_trans * -1;
12371   }
12372   tcp_cc_request->port          = atoi(remote_data_port);
12373   tcp_cc_request->ipfamily  = af_to_nf(remote_res->ai_family);
12374 
12375   if (debug > 1) {
12376     fprintf(where,"netperf: send_tcp_cc: requesting TCP crr test\n");
12377   }
12378 
12379   send_request();
12380 
12381   /* The response from the remote will contain all of the relevant 	*/
12382   /* socket parameters for this test type. We will put them back into 	*/
12383   /* the variables here so they can be displayed if desired.  The	*/
12384   /* remote will have calibrated CPU if necessary, and will have done	*/
12385   /* all the needed set-up we will have calibrated the cpu locally	*/
12386   /* before sending the request, and will grab the counter value right	*/
12387   /* after the connect returns. The remote will grab the counter right	*/
12388   /* after the accept call. This saves the hassle of extra messages	*/
12389   /* being sent for the TCP tests.					*/
12390 
12391   recv_response();
12392 
12393   if (!netperf_response.content.serv_errno) {
12394     rsr_size	=	tcp_cc_response->recv_buf_size;
12395     rss_size	=	tcp_cc_response->send_buf_size;
12396     rem_nodelay	=	tcp_cc_response->no_delay;
12397     remote_cpu_usage=	tcp_cc_response->measure_cpu;
12398     remote_cpu_rate = 	tcp_cc_response->cpu_rate;
12399     /* make sure that port numbers are in network order */
12400     set_port_number(remote_res,(unsigned short)tcp_cc_response->data_port_number);
12401 
12402     if (debug) {
12403       fprintf(where,"remote listen done.\n");
12404       fprintf(where,"remote port is %d\n",get_port_number(remote_res));
12405       fflush(where);
12406     }
12407   }
12408   else {
12409     Set_errno(netperf_response.content.serv_errno);
12410     fprintf(where,
12411 	    "netperf: remote error %d",
12412 	    netperf_response.content.serv_errno);
12413     perror("");
12414     fflush(where);
12415     exit(1);
12416   }
12417 
12418 #ifdef WANT_DEMO
12419   demo_rr_setup(100);
12420 #endif
12421 
12422   /* pick a nice random spot between client_port_min and */
12423   /* client_port_max for our initial port number */
12424   srand(getpid());
12425   if (client_port_max - client_port_min) {
12426     myport = client_port_min +
12427       (rand() % (client_port_max - client_port_min));
12428   }
12429   else {
12430     myport = client_port_min;
12431   }
12432   /* there will be a ++ before the first call to bind, so subtract one */
12433   myport--;
12434 
12435   /* Set-up the test end conditions. For a request/response test, they */
12436   /* can be either time or transaction based. */
12437 
12438   if (test_time) {
12439     /* The user wanted to end the test after a period of time. */
12440     times_up = 0;
12441     trans_remaining = 0;
12442     start_timer(test_time);
12443   }
12444   else {
12445     /* The tester wanted to send a number of bytes. */
12446     trans_remaining = test_bytes;
12447     times_up = 1;
12448   }
12449 
12450   /* The cpu_start routine will grab the current time and possibly */
12451   /* value of the idle counter for later use in measuring cpu */
12452   /* utilization and/or service demand and thruput. */
12453 
12454   cpu_start(local_cpu_usage);
12455 
12456 #ifdef WANT_DEMO
12457   if (demo_mode) {
12458     demo_first_timestamp();
12459   }
12460 #endif
12461 
12462   /* We use an "OR" to control test execution. When the test is */
12463   /* controlled by time, the byte count check will always return false. */
12464   /* When the test is controlled by byte count, the time test will */
12465   /* always return false. When the test is finished, the whole */
12466   /* expression will go false and we will stop sending data. I think I */
12467   /* just arbitrarily decrement trans_remaining for the timed test, but */
12468   /* will not do that just yet... One other question is whether or not */
12469   /* the send buffer and the receive buffer should be the same buffer. */
12470 
12471   while ((!times_up) || (trans_remaining > 0)) {
12472 
12473 #ifdef WANT_HISTOGRAM
12474     if (verbosity > 1) {
12475       /* timestamp just before our call to create the socket, and then */
12476       /* again just after the receive raj 3/95 */
12477       HIST_timestamp(&time_one);
12478     }
12479 #endif /* WANT_HISTOGRAM */
12480 
12481     /* set up the data socket */
12482     /* newport: is this label really required any longer? */
12483     /* pick a new port number */
12484     myport++;
12485 
12486     /* wrap the port number when we get to client_port_max. NOTE, some */
12487     /* broken TCP's might treat the port number as a signed 16 bit */
12488     /* quantity.  we aren't interested in testing such broken */
12489     /* implementations :) so we won't make sure that it is below 32767 */
12490     /* raj 8/94  */
12491     if (myport >= client_port_max) {
12492       myport = client_port_min;
12493     }
12494 
12495     /* we do not want to use the port number that the server is */
12496     /* sitting at - this would cause us to fail in a loopback test. we */
12497     /* could just rely on the failure of the bind to get us past this, */
12498     /* but I'm guessing that in this one case at least, it is much */
12499     /* faster, given that we *know* that port number is already in use */
12500     /* (or rather would be in a loopback test) */
12501 
12502     if (myport == get_port_number(remote_res)) myport++;
12503 
12504     if (debug) {
12505       if ((nummessages % 100) == 0) {
12506 	printf("port %d\n",myport);
12507       }
12508     }
12509     set_port_number(local_res, (unsigned short)myport);
12510     send_socket = create_data_socket(local_res);
12511 
12512     if (send_socket == INVALID_SOCKET) {
12513       perror("netperf: send_tcp_cc: tcp stream data socket");
12514       exit(1);
12515     }
12516 
12517 #ifdef WIN32
12518     /* this is used so the timer thread can close the socket out from */
12519     /* under us, which to date is the easiest/cleanest/least */
12520     /* Windows-specific way I can find to force the winsock calls to */
12521     /* return WSAEINTR with the test is over. anything that will run on */
12522     /* 95 and NT and is closer to what netperf expects from Unix signals */
12523     /* and such would be appreciated raj 1/96 */
12524     win_kludge_socket = send_socket;
12525 #endif /* WIN32 */
12526 
12527     /* we used to have a call to bind() here, but that is being
12528        taken care of by create_data_socket(). raj 2005-02-08 */
12529 
12530     /* Connect up to the remote port on the data socket  */
12531     if ((ret = connect(send_socket,
12532 		       remote_res->ai_addr,
12533 		       remote_res->ai_addrlen)) == INVALID_SOCKET){
12534       if (SOCKET_EINTR(ret))
12535 	  {
12536 	    /* we hit the end of a */
12537 	    /* timed test. */
12538 	    timed_out = 1;
12539 	    break;
12540       }
12541       perror("netperf: data socket connect failed");
12542       printf("\tattempted to connect on socket %d to port %d",
12543 	     send_socket,
12544 	     get_port_number(remote_res));
12545       printf(" from port %u \n",get_port_number(local_res));
12546       exit(1);
12547     }
12548 
12549     /* we hang in a recv() to get the remote's close indication */
12550 
12551     rsp_bytes_recvd=recv(send_socket,
12552 			 temp_message_ptr,
12553 			 rsp_bytes_left,
12554 			 0);
12555 
12556 
12557     if (rsp_bytes_recvd == 0) {
12558       /* connection close, call close. we assume that the requisite */
12559       /* number of bytes have been received */
12560 
12561 #ifdef WANT_HISTOGRAM
12562       if (verbosity > 1) {
12563 	HIST_timestamp(&time_two);
12564 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
12565       }
12566 #endif /* WANT_HISTOGRAM */
12567 
12568 #ifdef WANT_DEMO
12569       demo_rr_interval(1);
12570 #endif
12571 
12572       nummessages++;
12573       if (trans_remaining) {
12574 	trans_remaining--;
12575       }
12576 
12577       if (debug > 3) {
12578 	fprintf(where,
12579 		"Transaction %d completed on local port %u\n",
12580 		nummessages,
12581 		get_port_number(local_res));
12582 	fflush(where);
12583       }
12584 
12585       close(send_socket);
12586 
12587     }
12588     else {
12589       /* it was less than zero - an error occured */
12590       if (SOCKET_EINTR(rsp_bytes_recvd))
12591 	  {
12592 	    /* We hit the end of a timed test. */
12593 	    timed_out = 1;
12594 	    break;
12595 	  }
12596 	  perror("send_tcp_cc: data recv error");
12597 	  exit(1);
12598     }
12599 
12600   }
12601 
12602 
12603   /* this call will always give us the elapsed time for the test, and */
12604   /* will also store-away the necessaries for cpu utilization */
12605 
12606   cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being measured? */
12607   /* how long did we really run? */
12608 
12609   /* Get the statistics from the remote end. The remote will have */
12610   /* calculated service demand and all those interesting things. If it */
12611   /* wasn't supposed to care, it will return obvious values. */
12612 
12613   recv_response();
12614   if (!netperf_response.content.serv_errno) {
12615     if (debug)
12616       fprintf(where,"remote results obtained\n");
12617   }
12618   else {
12619     Set_errno(netperf_response.content.serv_errno);
12620     fprintf(where,
12621 	    "netperf: remote error %d",
12622 	     netperf_response.content.serv_errno);
12623     perror("");
12624     fflush(where);
12625 
12626     exit(1);
12627   }
12628 
12629   /* We now calculate what our thruput was for the test. In the future, */
12630   /* we may want to include a calculation of the thruput measured by */
12631   /* the remote, but it should be the case that for a TCP stream test, */
12632   /* that the two numbers should be *very* close... We calculate */
12633   /* bytes_sent regardless of the way the test length was controlled. */
12634   /* If it was time, we needed to, and if it was by bytes, the user may */
12635   /* have specified a number of bytes that wasn't a multiple of the */
12636   /* send_size, so we really didn't send what he asked for ;-) We use */
12637   /* Kbytes/s as the units of thruput for a TCP stream test, where K = */
12638   /* 1024. A future enhancement *might* be to choose from a couple of */
12639   /* unit selections. */
12640 
12641   bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
12642   thruput	= calc_thruput(bytes_xferd);
12643 
12644   if (local_cpu_usage || remote_cpu_usage) {
12645     /* We must now do a little math for service demand and cpu */
12646     /* utilization for the system(s) */
12647     /* Of course, some of the information might be bogus because */
12648     /* there was no idle counter in the kernel(s). We need to make */
12649     /* a note of this for the user's benefit...*/
12650     if (local_cpu_usage) {
12651       if (local_cpu_rate == 0.0) {
12652 	fprintf(where,"WARNING WARNING WARNING  WARNING WARNING WARNING  WARNING!\n");
12653 	fprintf(where,"Local CPU usage numbers based on process information only!\n");
12654 	fflush(where);
12655       }
12656       local_cpu_utilization = calc_cpu_util(0.0);
12657       /* since calc_service demand is doing ms/Kunit we will */
12658       /* multiply the number of transaction by 1024 to get */
12659       /* "good" numbers */
12660       local_service_demand  = calc_service_demand((double) nummessages*1024,
12661 						  0.0,
12662 						  0.0,
12663 						  0);
12664     }
12665     else {
12666       local_cpu_utilization	= (float) -1.0;
12667       local_service_demand	= (float) -1.0;
12668     }
12669 
12670     if (remote_cpu_usage) {
12671       if (remote_cpu_rate == 0.0) {
12672 	fprintf(where,"DANGER  DANGER  DANGER    DANGER  DANGER  DANGER    DANGER!\n");
12673 	fprintf(where,"Remote CPU usage numbers based on process information only!\n");
12674 	fflush(where);
12675       }
12676       remote_cpu_utilization = tcp_cc_result->cpu_util;
12677       /* since calc_service demand is doing ms/Kunit we will */
12678       /* multiply the number of transaction by 1024 to get */
12679       /* "good" numbers */
12680       remote_service_demand = calc_service_demand((double) nummessages*1024,
12681 						  0.0,
12682 						  remote_cpu_utilization,
12683 						  tcp_cc_result->num_cpus);
12684     }
12685     else {
12686       remote_cpu_utilization = (float) -1.0;
12687       remote_service_demand  = (float) -1.0;
12688     }
12689 
12690     /* We are now ready to print all the information. If the user */
12691     /* has specified zero-level verbosity, we will just print the */
12692     /* local service demand, or the remote service demand. If the */
12693     /* user has requested verbosity level 1, he will get the basic */
12694     /* "streamperf" numbers. If the user has specified a verbosity */
12695     /* of greater than 1, we will display a veritable plethora of */
12696     /* background information from outside of this block as it it */
12697     /* not cpu_measurement specific...  */
12698 
12699     switch (verbosity) {
12700     case 0:
12701       if (local_cpu_usage) {
12702 	fprintf(where,
12703 		cpu_fmt_0,
12704 		local_service_demand);
12705       }
12706       else {
12707 	fprintf(where,
12708 		cpu_fmt_0,
12709 		remote_service_demand);
12710       }
12711       break;
12712     case 1:
12713     case 2:
12714 
12715       if (print_headers) {
12716 	fprintf(where,
12717 		cpu_title,
12718 		local_cpu_method,
12719 		remote_cpu_method);
12720       }
12721 
12722       fprintf(where,
12723 	      cpu_fmt_1_line_1,		/* the format string */
12724 	      lss_size,		/* local sendbuf size */
12725 	      lsr_size,
12726 	      req_size,		/* how large were the requests */
12727 	      rsp_size,		/* guess */
12728 	      elapsed_time,		/* how long was the test */
12729 	      nummessages/elapsed_time,
12730 	      local_cpu_utilization,	/* local cpu */
12731 	      remote_cpu_utilization,	/* remote cpu */
12732 	      local_service_demand,	/* local service demand */
12733 	      remote_service_demand);	/* remote service demand */
12734       fprintf(where,
12735 	      cpu_fmt_1_line_2,
12736 	      rss_size,
12737 	      rsr_size);
12738       break;
12739     }
12740   }
12741   else {
12742     /* The tester did not wish to measure service demand. */
12743     switch (verbosity) {
12744     case 0:
12745       fprintf(where,
12746 	      tput_fmt_0,
12747 	      nummessages/elapsed_time);
12748       break;
12749     case 1:
12750     case 2:
12751       if (print_headers) {
12752 	fprintf(where,tput_title,format_units());
12753       }
12754 
12755       fprintf(where,
12756 	      tput_fmt_1_line_1,	/* the format string */
12757 	      lss_size,
12758 	      lsr_size,
12759 	      req_size,		/* how large were the requests */
12760 	      rsp_size,		/* how large were the responses */
12761 	      elapsed_time, 		/* how long did it take */
12762 	      nummessages/elapsed_time);
12763       fprintf(where,
12764 	      tput_fmt_1_line_2,
12765 	      rss_size, 		/* remote recvbuf size */
12766 	      rsr_size);
12767 
12768       break;
12769     }
12770   }
12771 
12772   /* it would be a good thing to include information about some of the */
12773   /* other parameters that may have been set for this test, but at the */
12774   /* moment, I do not wish to figure-out all the  formatting, so I will */
12775   /* just put this comment here to help remind me that it is something */
12776   /* that should be done at a later time. */
12777 
12778   if (verbosity > 1) {
12779     /* The user wanted to know it all, so we will give it to him. */
12780     /* This information will include as much as we can find about */
12781     /* TCP statistics, the alignments of the sends and receives */
12782     /* and all that sort of rot... */
12783 
12784     fprintf(where,
12785 	    ksink_fmt,
12786 	    local_send_align,
12787 	    remote_recv_offset,
12788 	    local_send_offset,
12789 	    remote_recv_offset);
12790 
12791 #ifdef WANT_HISTOGRAM
12792     fprintf(where,"\nHistogram of request/response times\n");
12793     fflush(where);
12794     HIST_report(time_hist);
12795 #endif /* WANT_HISTOGRAM */
12796 
12797   }
12798 
12799 }
12800 
12801 
12802 void
recv_tcp_cc()12803 recv_tcp_cc()
12804 {
12805 
12806   char  *message;
12807 
12808   struct addrinfo *local_res;
12809   char local_name[BUFSIZ];
12810   char port_buffer[PORTBUFSIZE];
12811 
12812   struct	sockaddr_storage        myaddr_in,  peeraddr_in;
12813   SOCKET	s_listen,s_data;
12814   netperf_socklen_t 	addrlen;
12815   char	*recv_message_ptr;
12816   char	*send_message_ptr;
12817   int	trans_received;
12818   int	trans_remaining;
12819   int	timed_out = 0;
12820   float	elapsed_time;
12821 
12822   struct	tcp_cc_request_struct	*tcp_cc_request;
12823   struct	tcp_cc_response_struct	*tcp_cc_response;
12824   struct	tcp_cc_results_struct	*tcp_cc_results;
12825 
12826   tcp_cc_request =
12827     (struct tcp_cc_request_struct *)netperf_request.content.test_specific_data;
12828   tcp_cc_response =
12829     (struct tcp_cc_response_struct *)netperf_response.content.test_specific_data;
12830   tcp_cc_results =
12831     (struct tcp_cc_results_struct *)netperf_response.content.test_specific_data;
12832 
12833   if (debug) {
12834     fprintf(where,"netserver: recv_tcp_cc: entered...\n");
12835     fflush(where);
12836   }
12837 
12838   /* We want to set-up the listen socket with all the desired */
12839   /* parameters and then let the initiator know that all is ready. If */
12840   /* socket size defaults are to be used, then the initiator will have */
12841   /* sent us 0's. If the socket sizes cannot be changed, then we will */
12842   /* send-back what they are. If that information cannot be determined, */
12843   /* then we send-back -1's for the sizes. If things go wrong for any */
12844   /* reason, we will drop back ten yards and punt. */
12845 
12846   /* If anything goes wrong, we want the remote to know about it. It */
12847   /* would be best if the error that the remote reports to the user is */
12848   /* the actual error we encountered, rather than some bogus unexpected */
12849   /* response type message. */
12850 
12851   if (debug) {
12852     fprintf(where,"recv_tcp_cc: setting the response type...\n");
12853     fflush(where);
12854   }
12855 
12856   netperf_response.content.response_type = TCP_CC_RESPONSE;
12857 
12858   if (debug) {
12859     fprintf(where,"recv_tcp_cc: the response type is set...\n");
12860     fflush(where);
12861   }
12862 
12863   /* set-up the data buffer with the requested alignment and offset */
12864   message = (char *)malloc(DATABUFFERLEN);
12865   if (message == NULL) {
12866     printf("malloc(%d) failed!\n", DATABUFFERLEN);
12867     exit(1);
12868   }
12869 
12870   /* We now alter the message_ptr variables to be at the desired */
12871   /* alignments with the desired offsets. */
12872 
12873   if (debug) {
12874     fprintf(where,
12875 	    "recv_tcp_cc: requested recv alignment of %d offset %d\n",
12876 	    tcp_cc_request->recv_alignment,
12877 	    tcp_cc_request->recv_offset);
12878     fprintf(where,
12879 	    "recv_tcp_cc: requested send alignment of %d offset %d\n",
12880 	    tcp_cc_request->send_alignment,
12881 	    tcp_cc_request->send_offset);
12882     fflush(where);
12883   }
12884 
12885   recv_message_ptr = ALIGN_BUFFER(message, tcp_cc_request->recv_alignment, tcp_cc_request->recv_offset);
12886 
12887   send_message_ptr = ALIGN_BUFFER(message, tcp_cc_request->send_alignment, tcp_cc_request->send_offset);
12888 
12889   if (debug) {
12890     fprintf(where,"recv_tcp_cc: receive alignment and offset set...\n");
12891     fflush(where);
12892   }
12893 
12894   /* Grab a socket to listen on, and then listen on it. */
12895 
12896   if (debug) {
12897     fprintf(where,"recv_tcp_cc: grabbing a socket...\n");
12898     fflush(where);
12899   }
12900 
12901   /* create_data_socket expects to find some things in the global */
12902   /* variables, so set the globals based on the values in the request. */
12903   /* once the socket has been created, we will set the response values */
12904   /* based on the updated value of those globals. raj 7/94 */
12905   lss_size_req = tcp_cc_request->send_buf_size;
12906   lsr_size_req = tcp_cc_request->recv_buf_size;
12907   loc_nodelay = tcp_cc_request->no_delay;
12908   loc_rcvavoid = tcp_cc_request->so_rcvavoid;
12909   loc_sndavoid = tcp_cc_request->so_sndavoid;
12910 
12911   set_hostname_and_port(local_name,
12912 			port_buffer,
12913 			nf_to_af(tcp_cc_request->ipfamily),
12914 			tcp_cc_request->port);
12915 
12916   local_res = complete_addrinfo(local_name,
12917 				local_name,
12918 				port_buffer,
12919 				nf_to_af(tcp_cc_request->ipfamily),
12920 				SOCK_STREAM,
12921 				IPPROTO_TCP,
12922 				0);
12923 
12924   s_listen = create_data_socket(local_res);
12925 
12926   if (s_listen == INVALID_SOCKET) {
12927     netperf_response.content.serv_errno = errno;
12928     send_response();
12929     if (debug) {
12930       fprintf(where,"could not create data socket\n");
12931       fflush(where);
12932     }
12933     exit(1);
12934   }
12935 
12936 #ifdef WIN32
12937   /* The test timer can fire during operations on the listening socket,
12938      so to make the start_timer below work we have to move
12939      it to close s_listen while we are blocked on accept. */
12940   win_kludge_socket2 = s_listen;
12941 #endif
12942 
12943 
12944   /* Now, let's set-up the socket to listen for connections */
12945   if (listen(s_listen, 5) == SOCKET_ERROR) {
12946     netperf_response.content.serv_errno = errno;
12947     close(s_listen);
12948     send_response();
12949     if (debug) {
12950       fprintf(where,"could not listen\n");
12951       fflush(where);
12952     }
12953     exit(1);
12954   }
12955 
12956   /* now get the port number assigned by the system  */
12957   addrlen = sizeof(myaddr_in);
12958   if (getsockname(s_listen,
12959 		  (struct sockaddr *)&myaddr_in,
12960 		  &addrlen) == SOCKET_ERROR){
12961     netperf_response.content.serv_errno = errno;
12962     close(s_listen);
12963     send_response();
12964     if (debug) {
12965       fprintf(where,"could not geetsockname\n");
12966       fflush(where);
12967     }
12968     exit(1);
12969   }
12970 
12971   /* Now myaddr_in contains the port and the internet address this is */
12972   /* returned to the sender also implicitly telling the sender that the */
12973   /* socket buffer sizing has been done. */
12974 
12975   tcp_cc_response->data_port_number =
12976     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
12977   if (debug) {
12978     fprintf(where,"telling the remote to call me at %d\n",
12979 	    tcp_cc_response->data_port_number);
12980     fflush(where);
12981   }
12982   netperf_response.content.serv_errno   = 0;
12983 
12984   /* But wait, there's more. If the initiator wanted cpu measurements, */
12985   /* then we must call the calibrate routine, which will return the max */
12986   /* rate back to the initiator. If the CPU was not to be measured, or */
12987   /* something went wrong with the calibration, we will return a 0.0 to */
12988   /* the initiator. */
12989 
12990   tcp_cc_response->cpu_rate = (float)0.0; 	/* assume no cpu */
12991   if (tcp_cc_request->measure_cpu) {
12992     tcp_cc_response->measure_cpu = 1;
12993     tcp_cc_response->cpu_rate =
12994       calibrate_local_cpu(tcp_cc_request->cpu_rate);
12995   }
12996 
12997 
12998 
12999   /* before we send the response back to the initiator, pull some of */
13000   /* the socket parms from the globals */
13001   tcp_cc_response->send_buf_size = lss_size;
13002   tcp_cc_response->recv_buf_size = lsr_size;
13003   tcp_cc_response->no_delay = loc_nodelay;
13004   tcp_cc_response->so_rcvavoid = loc_rcvavoid;
13005   tcp_cc_response->so_sndavoid = loc_sndavoid;
13006 
13007   send_response();
13008 
13009   addrlen = sizeof(peeraddr_in);
13010 
13011   /* Now it's time to start receiving data on the connection. We will */
13012   /* first grab the apropriate counters and then start grabbing. */
13013 
13014   cpu_start(tcp_cc_request->measure_cpu);
13015 
13016   /* The loop will exit when the sender does a shutdown, which will */
13017   /* return a length of zero   */
13018 
13019   if (tcp_cc_request->test_length > 0) {
13020     times_up = 0;
13021     trans_remaining = 0;
13022     start_timer(tcp_cc_request->test_length + PAD_TIME);
13023   }
13024   else {
13025     times_up = 1;
13026     trans_remaining = tcp_cc_request->test_length * -1;
13027   }
13028 
13029   trans_received = 0;
13030 
13031   while ((!times_up) || (trans_remaining > 0)) {
13032 #ifdef WIN32
13033     /* The test timer will probably fire during this accept,
13034        so to make the start_timer above work we have to move
13035        it to close s_listen while we are blocked on accept. */
13036     win_kludge_socket = s_listen;
13037 #endif
13038     /* accept a connection from the remote */
13039     if ((s_data=accept(s_listen,
13040 		       (struct sockaddr *)&peeraddr_in,
13041 		       &addrlen)) == INVALID_SOCKET) {
13042       if (errno == EINTR) {
13043 	/* the timer popped */
13044 	timed_out = 1;
13045 	break;
13046       }
13047       fprintf(where,"recv_tcp_cc: accept: errno = %d\n",errno);
13048       fflush(where);
13049       close(s_listen);
13050 
13051       exit(1);
13052     }
13053 
13054 #ifdef KLUDGE_SOCKET_OPTIONS
13055     /* this is for those systems which *INCORRECTLY* fail to pass */
13056     /* attributes across an accept() call. Including this goes against */
13057     /* my better judgement :( raj 11/95 */
13058 
13059     kludge_socket_options(s_data);
13060 
13061 #endif /* KLUDGE_SOCKET_OPTIONS */
13062 
13063 #ifdef WIN32
13064   /* this is used so the timer thread can close the socket out from */
13065   /* under us, which to date is the easiest/cleanest/least */
13066   /* Windows-specific way I can find to force the winsock calls to */
13067   /* return WSAEINTR with the test is over. anything that will run on */
13068   /* 95 and NT and is closer to what netperf expects from Unix signals */
13069   /* and such would be appreciated raj 1/96 */
13070   win_kludge_socket = s_data;
13071 #endif /* WIN32 */
13072 
13073     if (debug) {
13074       fprintf(where,"recv_tcp_cc: accepted data connection.\n");
13075       fflush(where);
13076     }
13077 
13078 
13079     /* close the connection. the server will likely do a graceful */
13080     /* close of the connection, insuring that all data has arrived at */
13081     /* the client. for this it will call shutdown(), and then recv() and */
13082     /* then close(). I'm reasonably confident that this is the */
13083     /* appropriate sequence of calls - I would like to hear of */
13084     /* examples in web servers to the contrary. raj 10/95*/
13085     close(s_data);
13086 
13087     trans_received++;
13088     if (trans_remaining) {
13089       trans_remaining--;
13090     }
13091 
13092     if (debug) {
13093       fprintf(where,
13094 	      "recv_tcp_cc: Transaction %d complete\n",
13095 	      trans_received);
13096       fflush(where);
13097     }
13098 
13099   }
13100 
13101 
13102   /* The loop now exits due to timeout or transaction count being */
13103   /* reached */
13104 
13105   cpu_stop(tcp_cc_request->measure_cpu,&elapsed_time);
13106 
13107   if (timed_out) {
13108     /* we ended the test by time, which was at least 2 seconds */
13109     /* longer than we wanted to run. so, we want to subtract */
13110     /* PAD_TIME from the elapsed_time. */
13111     elapsed_time -= PAD_TIME;
13112   }
13113   /* send the results to the sender			*/
13114 
13115   if (debug) {
13116     fprintf(where,
13117 	    "recv_tcp_cc: got %d transactions\n",
13118 	    trans_received);
13119     fflush(where);
13120   }
13121 
13122   tcp_cc_results->bytes_received = (trans_received *
13123 				    (tcp_cc_request->request_size +
13124 				     tcp_cc_request->response_size));
13125   tcp_cc_results->trans_received = trans_received;
13126   tcp_cc_results->elapsed_time	 = elapsed_time;
13127   tcp_cc_results->num_cpus       = lib_num_loc_cpus;
13128   if (tcp_cc_request->measure_cpu) {
13129     tcp_cc_results->cpu_util	= calc_cpu_util(elapsed_time);
13130   }
13131 
13132   if (debug) {
13133     fprintf(where,
13134 	    "recv_tcp_cc: test complete, sending results.\n");
13135     fflush(where);
13136   }
13137 
13138   send_response();
13139 
13140 }
13141 
13142 void
print_sockets_usage()13143 print_sockets_usage()
13144 {
13145 
13146   fwrite(sockets_usage, sizeof(char), strlen(sockets_usage), stdout);
13147   exit(1);
13148 
13149 }
13150 
13151 void
scan_sockets_args(int argc,char * argv[])13152 scan_sockets_args(int argc, char *argv[])
13153 
13154 {
13155 
13156 #define SOCKETS_ARGS "aAb:CDnNhH:L:m:M:p:P:r:R:s:S:T:Vw:W:z46"
13157 
13158   extern char	*optarg;	  /* pointer to option string	*/
13159 
13160   int		c;
13161 
13162   char
13163     arg1[BUFSIZ],  /* argument holders		*/
13164     arg2[BUFSIZ];
13165 
13166   if (debug) {
13167     int i;
13168     printf("%s called with the following argument vector\n",
13169 #if _MSC_VER <= 1200
13170 	   "scan_sockets_args");
13171 #else
13172 	   __func__);
13173 #endif
13174     for (i = 0; i< argc; i++) {
13175       printf("%s ",argv[i]);
13176     }
13177     printf("\n");
13178   }
13179 
13180   strncpy(local_data_port,"0",sizeof(local_data_port));
13181   strncpy(remote_data_port,"0",sizeof(remote_data_port));
13182 
13183   /* by default, only a UDP_STREAM test disallows routing, to cover
13184      the backsides of incompetent testers who have bogus setups */
13185   if (strcasecmp(test_name,"UDP_STREAM") == 0) {
13186     routing_allowed = 0;
13187   }
13188 
13189   /* Go through all the command line arguments and break them */
13190   /* out. For those options that take two parms, specifying only */
13191   /* the first will set both to that value. Specifying only the */
13192   /* second will leave the first untouched. To change only the */
13193   /* first, use the form "first," (see the routine break_args.. */
13194 
13195   while ((c= getopt(argc, argv, SOCKETS_ARGS)) != EOF) {
13196     switch (c) {
13197     case '?':
13198     case '4':
13199       remote_data_family = AF_INET;
13200       local_data_family = AF_INET;
13201       break;
13202     case '6':
13203 #if defined(AF_INET6)
13204       remote_data_family = AF_INET6;
13205       local_data_family = AF_INET6;
13206 #else
13207       fprintf(stderr,
13208 	      "This netperf was not compiled on an IPv6 capable host!\n");
13209       fflush(stderr);
13210       exit(-1);
13211 #endif
13212       break;
13213     case 'h':
13214       print_sockets_usage();
13215       exit(1);
13216     case 'a':
13217 #ifdef HAVE_AIO
13218       loc_sndaio = 1;
13219 #else
13220       fprintf(stderr, "Asynchronous I/O not available on this platform\n");
13221 #endif
13222       break;
13223     case 'A':
13224 #ifdef HAVE_AIO
13225       rem_rcvaio = 1;
13226 #else
13227       fprintf(stderr, "Asynchronous I/O not available on this platform\n");
13228 #endif
13229       break;
13230     case 'b':
13231 #ifdef WANT_FIRST_BURST
13232       first_burst_size = atoi(optarg);
13233 #else /* WANT_FIRST_BURST */
13234       printf("Initial request burst functionality not compiled-in!\n");
13235 #endif /* WANT_FIRST_BURST */
13236       break;
13237     case 'C':
13238 #ifdef TCP_CORK
13239       /* set TCP_CORK */
13240       loc_tcpcork = 1;
13241       rem_tcpcork = 1; /* however, at first, we ony have cork affect loc */
13242 #else
13243       printf("WARNING: TCP_CORK not available on this platform!\n");
13244 #endif /* TCP_CORK */
13245       break;
13246     case 'D':
13247       /* set the TCP nodelay flag */
13248       loc_nodelay = 1;
13249       rem_nodelay = 1;
13250       break;
13251     case 'H':
13252       break_args_explicit(optarg,arg1,arg2);
13253       if (arg1[0]) {
13254 	/* make sure we leave room for the NULL termination boys and
13255 	   girls. raj 2005-02-82 */
13256 	remote_data_address = malloc(strlen(arg1)+1);
13257 	strncpy(remote_data_address,arg1,strlen(arg1));
13258       }
13259       if (arg2[0])
13260 	remote_data_family = parse_address_family(arg2);
13261       break;
13262     case 'L':
13263       break_args_explicit(optarg,arg1,arg2);
13264       if (arg1[0]) {
13265 	/* make sure we leave room for the NULL termination boys and
13266 	   girls. raj 2005-02-82 */
13267 	local_data_address = malloc(strlen(arg1)+1);
13268 	strncpy(local_data_address,arg1,strlen(arg1));
13269       }
13270       if (arg2[0])
13271 	local_data_family = parse_address_family(arg2);
13272       break;
13273     case 's':
13274       /* set local socket sizes */
13275       break_args(optarg,arg1,arg2);
13276       if (arg1[0])
13277 	lss_size_req = convert(arg1);
13278       if (arg2[0])
13279 	lsr_size_req = convert(arg2);
13280       break;
13281     case 'S':
13282       /* set remote socket sizes */
13283       break_args(optarg,arg1,arg2);
13284       if (arg1[0])
13285 	rss_size_req = convert(arg1);
13286       if (arg2[0])
13287 	rsr_size_req = convert(arg2);
13288       break;
13289     case 'r':
13290       /* set the request/response sizes */
13291       break_args(optarg,arg1,arg2);
13292       if (arg1[0])
13293 	req_size = convert(arg1);
13294       if (arg2[0])
13295 	rsp_size = convert(arg2);
13296       break;
13297     case 'R':
13298       /* enable/disable routing on the data connection*/
13299       routing_allowed = atoi(optarg);
13300       break;
13301     case 'm':
13302       /* set the send size */
13303       send_size = convert(optarg);
13304       break;
13305     case 'M':
13306       /* set the recv size */
13307       recv_size = convert(optarg);
13308       break;
13309     case 'n':
13310       /* set the local socket type*/
13311       local_connected = 1;
13312       break;
13313     case 'N':
13314       /* set the remote socket type*/
13315       remote_connected = 1;
13316       break;
13317     case 'p':
13318       /* set the min and max port numbers for the TCP_CRR and TCP_TRR */
13319       /* tests. */
13320       break_args(optarg,arg1,arg2);
13321       if (arg1[0])
13322 	client_port_min = atoi(arg1);
13323       if (arg2[0])
13324 	client_port_max = atoi(arg2);
13325       break;
13326     case 'P':
13327       /* set the local and remote data port numbers for the tests to
13328 	 allow them to run through those blankety blank end-to-end
13329 	 breaking firewalls. raj 2004-06-15 */
13330       break_args(optarg,arg1,arg2);
13331       if (arg1[0])
13332 	strncpy(local_data_port,arg1,sizeof(local_data_port));
13333       if (arg2[0])
13334 	strncpy(remote_data_port,arg2,sizeof(remote_data_port));
13335       break;
13336     case 't':
13337       /* set the test name */
13338       strcpy(test_name,optarg);
13339       break;
13340     case 'W':
13341       /* set the "width" of the user space data */
13342       /* buffer. This will be the number of */
13343       /* send_size buffers malloc'd in the */
13344       /* *_STREAM test. It may be enhanced to set */
13345       /* both send and receive "widths" but for now */
13346       /* it is just the sending *_STREAM. */
13347       send_width = convert(optarg);
13348       break;
13349     case 'V' :
13350       /* we want to do copy avoidance and will set */
13351       /* it for everything, everywhere, if we really */
13352       /* can. of course, we don't know anything */
13353       /* about the remote... */
13354 #ifdef SO_SND_COPYAVOID
13355       loc_sndavoid = 1;
13356 #else
13357       loc_sndavoid = 0;
13358       printf("Local send copy avoidance not available.\n");
13359 #endif
13360 #ifdef SO_RCV_COPYAVOID
13361       loc_rcvavoid = 1;
13362 #else
13363       loc_rcvavoid = 0;
13364       printf("Local recv copy avoidance not available.\n");
13365 #endif
13366       rem_sndavoid = 1;
13367       rem_rcvavoid = 1;
13368       break;
13369     };
13370   }
13371 
13372 #if defined(WANT_FIRST_BURST)
13373 #if defined(WANT_HISTOGRAM)
13374   /* if WANT_FIRST_BURST and WANT_HISTOGRAM are defined and the user
13375      indeed wants a non-zero first burst size, and we would emit a
13376      histogram, then we should emit a warning that the two are not
13377      compatible. raj 2006-01-31 */
13378   if ((first_burst_size > 0) && (verbosity >= 2)) {
13379     fprintf(stderr,
13380 	    "WARNING! Histograms and first bursts are incompatible!\n");
13381     fflush(stderr);
13382   }
13383 #endif
13384 #endif
13385 
13386   /* we do not want to make remote_data_address non-NULL because if
13387      the user has not specified a remote adata address, we want to
13388      take it from the hostname in the -H global option. raj
13389      2005-02-08 */
13390 
13391   /* so, if there is to be no control connection, we want to have some
13392      different settings for a few things */
13393 
13394   if (no_control) {
13395 
13396     if (strcmp(remote_data_port,"0") == 0) {
13397       /* we need to select either the discard port, echo port or
13398 	 chargen port dedepending on the test name. raj 2007-02-08 */
13399       if (strstr(test_name,"STREAM") ||
13400 	  strstr(test_name,"SENDFILE")) {
13401 	strncpy(remote_data_port,"discard",sizeof(remote_data_port));
13402       }
13403       else if (strstr(test_name,"RR")) {
13404 	strncpy(remote_data_port,"echo",sizeof(remote_data_port));
13405       }
13406       else if (strstr(test_name,"MAERTS")) {
13407 	strncpy(remote_data_port,"chargen",sizeof(remote_data_port));
13408       }
13409       else {
13410 	printf("No default port known for the %s test, please set one yourself\n",test_name);
13411 	exit(-1);
13412       }
13413     }
13414     remote_data_port[sizeof(remote_data_port) - 1] = '\0';
13415 
13416     /* I go back and forth on whether these should become -1 or if
13417        they should become 0 for a no_control test. what do you think?
13418        raj 2006-02-08 */
13419 
13420     rem_rcvavoid = -1;
13421     rem_sndavoid = -1;
13422     rss_size_req = -1;
13423     rsr_size_req = -1;
13424     rem_nodelay = -1;
13425 
13426     if (strstr(test_name,"STREAM") ||
13427 	strstr(test_name,"SENDFILE")) {
13428       recv_size = -1;
13429     }
13430     else if (strstr(test_name,"MAERTS")) {
13431       send_size = -1;
13432     }
13433   }
13434 }
13435