• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef lint
2 char	nettest_id[]="\
3 @(#)nettest_bsd.c (c) Copyright 1993-2012 Hewlett-Packard Co. Version 2.6.0";
4 #endif /* lint */
5 
6 
7 /****************************************************************/
8 /*								*/
9 /*	nettest_bsd.c						*/
10 /*								*/
11 /*      the BSD sockets parsing routine...                      */
12 /*       ...with the addition of Windows NT, this is now also   */
13 /*          a Winsock test... sigh :)                           */
14 /*                                                              */
15 /*      scan_sockets_args()                                     */
16 /*                                                              */
17 /*	the actual test routines...				*/
18 /*								*/
19 /*	send_tcp_stream()	perform a tcp stream test	*/
20 /*	recv_tcp_stream()					*/
21 /*      send_tcp_maerts()       perform a tcp stream test       */
22 /*      recv_tcp_maerts()       in the other direction          */
23 /*	send_tcp_rr()		perform a tcp request/response	*/
24 /*	recv_tcp_rr()						*/
25 /*      send_tcp_conn_rr()      an RR test including connect    */
26 /*      recv_tcp_conn_rr()                                      */
27 /*      send_tcp_cc()           a connect/disconnect test with  */
28 /*      recv_tcp_cc()           no RR                           */
29 /*      send_tcp_mss()          just report the mss             */
30 /*	send_udp_stream()	perform a udp stream test	*/
31 /*	recv_udp_stream()					*/
32 /*	send_udp_rr()		perform a udp request/response	*/
33 /*	recv_udp_rr()						*/
34 /*	loc_cpu_rate()		determine the local cpu maxrate */
35 /*	rem_cpu_rate()		find the remote cpu maxrate	*/
36 /*								*/
37 /****************************************************************/
38 
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 #endif
42 
43 #include <stdio.h>
44 #if HAVE_SYS_TYPES_H
45 # include <sys/types.h>
46 #endif
47 #if HAVE_SYS_STAT_H
48 # include <sys/stat.h>
49 #endif
50 #if STDC_HEADERS
51 # include <stdlib.h>
52 # include <stddef.h>
53 #else
54 # if HAVE_STDLIB_H
55 #  include <stdlib.h>
56 # endif
57 #endif
58 #if HAVE_STRING_H
59 # if !STDC_HEADERS && HAVE_MEMORY_H
60 #  include <memory.h>
61 # endif
62 # include <string.h>
63 #endif
64 #if HAVE_STRINGS_H
65 # include <strings.h>
66 #endif
67 #if HAVE_INTTYPES_H
68 # include <inttypes.h>
69 #else
70 # if HAVE_STDINT_H
71 #  include <stdint.h>
72 # endif
73 #endif
74 #if HAVE_UNISTD_H
75 # include <unistd.h>
76 #endif
77 
78 #include <fcntl.h>
79 #ifndef WIN32
80 #include <errno.h>
81 #include <signal.h>
82 #endif
83 
84 #if TIME_WITH_SYS_TIME
85 # include <sys/time.h>
86 # include <time.h>
87 #else
88 # if HAVE_SYS_TIME_H
89 #  include <sys/time.h>
90 # else
91 #  include <time.h>
92 # endif
93 #endif
94 
95 #ifdef NOSTDLIBH
96 #include <malloc.h>
97 #endif /* NOSTDLIBH */
98 
99 
100 #ifndef WIN32
101 #if !defined(__VMS)
102 #include <sys/ipc.h>
103 #endif /* !__VMS */
104 #include <sys/socket.h>
105 #include <netinet/in.h>
106 #include <netinet/tcp.h>
107 
108 #ifdef HAVE_NETINET_SCTP_H
109 #include <netinet/sctp.h>
110 #endif
111 
112 #include <arpa/inet.h>
113 #include <netdb.h>
114 #else /* WIN32 */
115 #include <process.h>
116 #define netperf_socklen_t socklen_t
117 #include <winsock2.h>
118 #include "missing\stdint.h"
119 /* while it is unlikely that anyone running Windows 2000 or NT 4 is
120    going to be trying to compile this, if they are they will want to
121    define DONT_IPV6 in the sources file */
122 #ifndef DONT_IPV6
123 #include <ws2tcpip.h>
124 #endif
125 #include <windows.h>
126 
127 #define sleep(x) Sleep((x)*1000)
128 
129 #define __func__ __FUNCTION__
130 #endif /* WIN32 */
131 
132 /* We don't want to use bare constants in the shutdown() call.  In the
133    extremely unlikely event that SHUT_WR isn't defined, we will define
134    it to the value we used to be passing to shutdown() anyway.  raj
135    2007-02-08 */
136 #if !defined(SHUT_WR)
137 #define SHUT_WR 1
138 #endif
139 
140 #if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO)
141 # include "missing/getaddrinfo.h"
142 #endif
143 
144 #include "netlib.h"
145 #include "netsh.h"
146 #include "nettest_bsd.h"
147 
148 #if defined(WANT_HISTOGRAM) || defined(WANT_DEMO)
149 #include "hist.h"
150 #endif /* WANT_HISTOGRAM */
151 
152 
153 /* make first_burst_size unconditional so we can use it easily enough
154    when calculating transaction latency for the TCP_RR test. raj
155    2007-06-08 however, change its default value so one can tell in
156    "omni" output whether or not WANT_BURST was enabled. raj
157    2008-01-28 */
158 #if defined(WANT_FIRST_BURST)
159 int first_burst_size=0;
160 #else
161 int first_burst_size=-1;
162 #endif
163 
164 #if defined(HAVE_SENDFILE) && (defined(__linux) || defined(__sun))
165 #include <sys/sendfile.h>
166 #endif /* HAVE_SENDFILE && (__linux || __sun) */
167 
168 
169 
170 /* these variables are specific to the BSD sockets tests, but can
171  * be used elsewhere if needed.  They are externed through nettest_bsd.h
172  */
173 
174 int
175   socket_type,          /* used initially by the "omni" tests */
176   rss_size_req = -1,	/* requested remote socket send buffer size */
177   rsr_size_req = -1,	/* requested remote socket recv buffer size */
178   rss_size,		/* initial remote socket send buffer size */
179   rsr_size,		/* initial remote socket recv buffer size */
180   rss_size_end = -1,    /* final  remote socket send buffer size */
181   rsr_size_end = -1,    /* final  remote socket recv buffer size */
182   lss_size_req = -1,	/* requested local socket send buffer size */
183   lsr_size_req = -1,	/* requested local socket recv buffer size */
184   lss_size,		/* local  socket send buffer size 	*/
185   lsr_size,		/* local  socket recv buffer size 	*/
186   lss_size_end = -1,    /* final local  socket send buffer size */
187   lsr_size_end = -1,    /* final local  socket recv buffer size */
188   req_size = 1,		/* request size                   	*/
189   rsp_size = 1,		/* response size			*/
190   send_size,		/* how big are individual sends		*/
191   recv_size,		/* how big are individual receives	*/
192   transport_mss_req = -1; /* what maximum segment size is wanted */
193 
194 static  int confidence_iteration;
195 static  char  local_cpu_method;
196 static  char  remote_cpu_method;
197 
198 /* these will control the width of port numbers we try to use in the */
199 /* TCP_CRR and/or TCP_TRR tests. raj 3/95 */
200 static int client_port_min = 5000;
201 static int client_port_max = 65535;
202 
203  /* different options for the sockets				*/
204 
205 int
206   loc_nodelay,		/* don't/do use NODELAY	locally		*/
207   rem_nodelay,		/* don't/do use NODELAY remotely	*/
208 #ifdef TCP_CORK
209   loc_tcpcork=0,        /* don't/do use TCP_CORK locally        */
210   rem_tcpcork=0,        /* don't/do use TCP_CORK remotely       */
211 #else
212   loc_tcpcork=-1,
213   rem_tcpcork=-1,
214 #endif /* TCP_CORK */
215   loc_sndavoid,		/* avoid send copies locally		*/
216   loc_rcvavoid,		/* avoid recv copies locally		*/
217   rem_sndavoid,		/* avoid send copies remotely		*/
218   rem_rcvavoid, 	/* avoid recv_copies remotely		*/
219   local_connected = 0,  /* local socket type, connected/non-connected */
220   remote_connected = 0, /* remote socket type, connected/non-connected */
221   routing_allowed = 1;    /* set/clear SO_DONTROUTE on data socket */
222 
223 int multicast_ttl = -1; /* should we set the multicast TTL to a value? */
224 
225 int want_keepalive = 0;
226 
227 #ifdef WANT_HISTOGRAM
228 #ifdef HAVE_GETHRTIME
229 static hrtime_t time_one;
230 static hrtime_t time_two;
231 #elif HAVE_GET_HRT
232 #include "hrt.h"
233 static hrt_t time_one;
234 static hrt_t time_two;
235 #elif defined(WIN32)
236 static LARGE_INTEGER time_one;
237 static LARGE_INTEGER time_two;
238 #else
239 static struct timeval time_one;
240 static struct timeval time_two;
241 #endif /* HAVE_GETHRTIME */
242 static HIST time_hist;
243 #endif /* WANT_HISTOGRAM */
244 
245 #ifdef WANT_INTERVALS
246 int interval_count;
247 #ifndef WANT_SPIN
248 #ifdef WIN32
249 #define INTERVALS_INIT() \
250     if (interval_burst) { \
251       /* zero means that we never pause, so we never should need the \
252          interval timer. we used to use it for demo mode, but we deal \
253 	 with that with a variant on watching the clock rather than \
254 	 waiting for a timer. raj 2006-02-06 */ \
255       start_itimer(interval_wate); \
256     } \
257     interval_count = interval_burst;
258 #else
259 sigset_t signal_set;
260 #define INTERVALS_INIT() \
261     if (interval_burst) { \
262       /* zero means that we never pause, so we never should need the \
263          interval timer. we used to use it for demo mode, but we deal \
264 	 with that with a variant on watching the clock rather than \
265 	 waiting for a timer. raj 2006-02-06 */ \
266       start_itimer(interval_wate); \
267     } \
268     interval_count = interval_burst; \
269     /* get the signal set for the call to sigsuspend */ \
270     if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) { \
271       fprintf(where, \
272 	      "%s: unable to get sigmask errno %d\n", \
273 	      __func__, \
274 	      errno); \
275       fflush(where); \
276       exit(1); \
277     }
278 #endif /* WIN32 */
279 
280 #ifdef WIN32
281 #define INTERVALS_WAIT() \
282       /* in this case, the interval count is the count-down counter \
283 	 to decide to sleep for a little bit */ \
284       if ((interval_burst) && (--interval_count == 0)) { \
285 	/* call WaitForSingleObject and wait for the interval timer to get us \
286 	   out */ \
287 	if (debug > 1) { \
288 	  fprintf(where,"about to suspend\n"); \
289 	  fflush(where); \
290 	} \
291     if (WaitForSingleObject(WinTimer, INFINITE) != WAIT_OBJECT_0) { \
292         fprintf(where, "WaitForSingleObject failed (%d)\n", GetLastError()); \
293 	  fflush(where); \
294 	  exit(1); \
295 	} \
296 	interval_count = interval_burst; \
297       }
298 #else
299 #define INTERVALS_WAIT() \
300       /* in this case, the interval count is the count-down couter \
301 	 to decide to sleep for a little bit */ \
302       if ((interval_burst) && (--interval_count == 0)) { \
303 	/* call sigsuspend and wait for the interval timer to get us \
304 	   out */ \
305 	if (debug > 1) { \
306 	  fprintf(where,"about to suspend\n"); \
307 	  fflush(where); \
308 	} \
309 	if (sigsuspend(&signal_set) == EFAULT) { \
310 	  fprintf(where, \
311 		  "%s: fault with sigsuspend.\n", \
312                   __func__); \
313 	  fflush(where); \
314 	  exit(1); \
315 	} \
316 	interval_count = interval_burst; \
317       }
318 #endif /* WIN32 */
319 #else
320 /* first out timestamp */
321 #ifdef HAVE_GETHRTIME
322 static hrtime_t intvl_one;
323 static hrtime_t intvl_two;
324 static hrtime_t *intvl_one_ptr = &intvl_one;
325 static hrtime_t *intvl_two_ptr = &intvl_two;
326 static hrtime_t *temp_intvl_ptr = &intvl_one;
327 #elif defined(WIN32)
328 static LARGE_INTEGER intvl_one;
329 static LARGE_INTEGER intvl_two;
330 static LARGE_INTEGER *intvl_one_ptr = &intvl_one;
331 static LARGE_INTEGER *intvl_two_ptr = &intvl_two;
332 static LARGE_INTEGER *temp_intvl_ptr = &intvl_one;
333 #else
334 static struct timeval intvl_one;
335 static struct timeval intvl_two;
336 static struct timeval *intvl_one_ptr = &intvl_one;
337 static struct timeval *intvl_two_ptr = &intvl_two;
338 static struct timeval *temp_intvl_ptr = &intvl_one;
339 #endif
340 
341 #define INTERVALS_INIT() \
342       if (interval_burst) { \
343 	HIST_timestamp(intvl_one_ptr); \
344       } \
345       interval_count = interval_burst; \
346 
347 #define INTERVALS_WAIT() \
348       /* in this case, the interval count is the count-down couter \
349 	 to decide to sleep for a little bit */ \
350       if ((interval_burst) && (--interval_count == 0)) { \
351 	/* call sigsuspend and wait for the interval timer to get us \
352 	   out */ \
353 	if (debug > 1) { \
354 	  fprintf(where,"about to spin suspend\n"); \
355 	  fflush(where); \
356 	} \
357         HIST_timestamp(intvl_two_ptr); \
358         while(delta_micro(intvl_one_ptr,intvl_two_ptr) < interval_usecs) { \
359 	  HIST_timestamp(intvl_two_ptr); \
360 	} \
361 	temp_intvl_ptr = intvl_one_ptr; \
362 	intvl_one_ptr = intvl_two_ptr; \
363 	intvl_two_ptr = temp_intvl_ptr; \
364 	interval_count = interval_burst; \
365       }
366 #endif
367 #endif
368 
369 
370 char sockets_usage[] = "\n\
371 Usage: netperf [global options] -- [test options] \n\
372 \n\
373 TCP/UDP BSD Sockets Test Options:\n\
374     -b number         Send number requests at start of _RR tests\n\
375     -C                Set TCP_CORK when available\n\
376     -D [L][,R]        Set TCP_NODELAY locally and/or remotely (TCP_*)\n\
377     -h                Display this text\n\
378     -H name,fam       Use name (or IP) and family as target of data connection\n\
379     -L name,fam       Use name (or IP) and family as source of data connection\n\
380     -m bytes          Set the send size (TCP_STREAM, UDP_STREAM)\n\
381     -M bytes          Set the recv size (TCP_STREAM, UDP_STREAM)\n\
382     -n                Use the connected socket for UDP locally\n\
383     -N                Use the connected socket for UDP remotely\n\
384     -p min[,max]      Set the min/max port numbers for TCP_CRR, TCP_TRR\n\
385     -P local[,remote] Set the local/remote port for the data socket\n\
386     -r req,[rsp]      Set request/response sizes (TCP_RR, UDP_RR)\n\
387     -s send[,recv]    Set local socket send/recv buffer sizes\n\
388     -S send[,recv]    Set remote socket send/recv buffer sizes\n\
389     -4                Use AF_INET (eg IPv4) on both ends of the data conn\n\
390     -6                Use AF_INET6 (eg IPv6) on both ends of the data conn\n\
391 \n\
392 For those options taking two parms, at least one must be specified;\n\
393 specifying one value without a comma will set both parms to that\n\
394 value, specifying a value with a leading comma will set just the second\n\
395 parm, a value with a trailing comma will set just the first. To set\n\
396 each parm to unique values, specify both and separate them with a\n\
397 comma.\n";
398 
399 
400 
401 /* these routines convert between the AF address space and the NF
402    address space since the numeric values of AF_mumble are not the
403    same across the platforms. raj 2005-02-08 */
404 
405 int
nf_to_af(int nf)406 nf_to_af(int nf) {
407   switch(nf) {
408   case NF_INET:
409     return AF_INET;
410   case NF_UNSPEC:
411     return AF_UNSPEC;
412   case NF_INET6:
413 #if defined(AF_INET6)
414     return AF_INET6;
415 #else
416     return AF_UNSPEC;
417 #endif
418   case NF_RDS:
419 #if defined(AF_RDS)
420     return AF_RDS;
421 #else
422     return AF_UNSPEC;
423 #endif
424   default:
425     return AF_UNSPEC;
426   }
427 }
428 
429 int
af_to_nf(int af)430 af_to_nf(int af) {
431 
432   switch(af) {
433   case AF_INET:
434     return NF_INET;
435   case AF_UNSPEC:
436     return NF_UNSPEC;
437 #if defined(AF_INET6)
438   case AF_INET6:
439     return NF_INET6;
440 #endif
441 #if defined(AF_RDS)
442   case AF_RDS:
443     return NF_RDS;
444 #endif
445   default:
446     return NF_UNSPEC;
447   }
448 }
449 
450 
451 /* these routines will convert between the hosts' socket types and
452    those netperf uses.  we need this because different platforms can
453    have different values for SOCK_STREAM, SOCK_DGRAM and the
454    like... */
455 
456 int
nst_to_hst(int nst)457 nst_to_hst(int nst) {
458   switch(nst) {
459 #ifdef SOCK_STREAM
460   case NST_STREAM:
461     return SOCK_STREAM;
462     break;  /* ok, this may not be necessary :) */
463 #endif
464 #ifdef SOCK_DGRAM
465   case NST_DGRAM:
466     return SOCK_DGRAM;
467     break;
468 #endif
469 #ifdef SOCK_DCCP
470   case NST_DCCP:
471     return SOCK_DCCP;
472     break;
473 #endif
474 #ifdef SOCK_SEQPACKET
475   case NST_SEQPACKET:
476     return NST_SEQPACKET;
477 #endif
478   default:
479     return -1;
480   }
481 }
482 
483 int
hst_to_nst(int hst)484 hst_to_nst(int hst) {
485 
486   switch(hst) {
487 #ifdef SOCK_STREAM
488   case SOCK_STREAM:
489     return NST_STREAM;
490     break;
491 #endif
492 #ifdef SOCK_DGRAM
493   case SOCK_DGRAM:
494     return NST_DGRAM;
495     break;
496 #endif
497 #ifdef SOCK_DCCP
498   case SOCK_DCCP:
499     return NST_DCCP;
500     break;
501 #endif
502 #ifdef SOCK_SEQPACKET
503   case SOCK_SEQPACKET:
504     return NST_SEQPACKET;
505 #endif
506   default:
507     return NST_UNKN;
508   }
509 }
510 char *
hst_to_str(int hst)511 hst_to_str(int hst) {
512 
513   switch(hst) {
514 #ifdef SOCK_STREAM
515   case SOCK_STREAM:
516     return "Stream";
517     break;
518 #endif
519 #ifdef SOCK_DGRAM
520   case SOCK_DGRAM:
521     return "Datagram";
522     break;
523 #endif
524 #ifdef SOCK_DCCP
525   case SOCK_DCCP:
526     return "DCCP";
527     break;
528 #endif
529 #ifdef SOCK_SEQPACKET
530   case SOCK_SEQPACKET:
531     return "Seqpacket";
532 #endif
533   default:
534     return "Unknown";
535   }
536 }
537 
538 char *
protocol_to_str(int protocol)539 protocol_to_str(int protocol) {
540   switch(protocol) {
541     /* ass-u-me that everyone has IPPROTO_TCP and IPPROTO_UDP */
542   case IPPROTO_TCP:
543     return "TCP";
544   case IPPROTO_UDP:
545     return "UDP";
546     /* but do not assume that everyone has the others */
547 #ifdef IPPROTO_UDPLITE
548   case IPPROTO_UDPLITE:
549     return "UDPLite";
550 #endif
551 #ifdef IPPROTO_SCTP
552   case IPPROTO_SCTP:
553     return "SCTP";
554 #endif
555 #ifdef IPPROTO_DCCP
556   case IPPROTO_DCCP:
557     return "DCCP";
558 #endif
559 #ifdef IPPROTO_SDP
560   case IPPROTO_SDP:
561     return "SDP";
562 #endif
563 #ifdef IPPROTO_IP
564   case IPPROTO_IP:
565     return "IP Default";
566 #endif
567   default:
568     return "Unknown Protocol";
569   }
570 }
571 
572 
573  /* This routine is intended to retrieve interesting aspects of tcp */
574  /* for the data connection. at first, it attempts to retrieve the */
575  /* maximum segment size. later, it might be modified to retrieve */
576  /* other information, but it must be information that can be */
577  /* retrieved quickly as it is called during the timing of the test. */
578  /* for that reason, a second routine may be created that can be */
579  /* called outside of the timing loop */
580 static
581 void
get_tcp_info(SOCKET socket,int * mss)582 get_tcp_info(SOCKET socket, int *mss)
583 {
584 
585 #ifdef TCP_MAXSEG
586   netperf_socklen_t sock_opt_len;
587 
588   sock_opt_len = sizeof(int);
589   if (getsockopt(socket,
590 		 getprotobyname("tcp")->p_proto,
591 		 TCP_MAXSEG,
592 		 (char *)mss,
593 		 &sock_opt_len) == SOCKET_ERROR) {
594     fprintf(where,
595 	    "netperf: get_tcp_info: getsockopt TCP_MAXSEG: errno %d\n",
596 	    errno);
597     fflush(where);
598     *mss = -1;
599   }
600 #else
601   *mss = -1;
602 #endif /* TCP_MAXSEG */
603 }
604 
605 static
606 void
set_tcp_mss(SOCKET socket,int mss)607 set_tcp_mss(SOCKET socket, int mss) {
608 #ifdef TCP_MAXSEG
609   netperf_socklen_t sock_opt_len;
610 
611   sock_opt_len = sizeof(int);
612   if ((setsockopt(socket,
613 		  getprotobyname("tcp")->p_proto,
614 		  TCP_MAXSEG,
615 		  (const char *)&mss,
616 		  sock_opt_len) == SOCKET_ERROR) && (debug)) {
617     fprintf(where,
618 	    "netperf: %s: setsockopt TCP_MAXSEG: %s (errno %d)\n",
619 	    __FUNCTION__,
620 	    strerror(errno),
621 	    errno);
622     fflush(where);
623   }
624 #else
625   if (debug) {
626     fprintf(where,
627 	    "netperf: %s platform does not know how to set TCP segment size\n",
628 	    __FUNCTION__);
629     fflush(where);
630   }
631 
632 #endif /* TCP_MAXSEG */
633 }
634 
635 
636 
637 /* return a pointer to a completed addrinfo chain - prefer
638    data_address to controlhost and utilize the specified address
639    family */
640 
641 struct addrinfo *
complete_addrinfo(char * controlhost,char * data_address,char * port,int family,int type,int protocol,int flags)642 complete_addrinfo(char *controlhost, char *data_address, char *port, int family, int type, int protocol, int flags)
643 {
644   struct addrinfo hints;
645   struct addrinfo *res;
646   struct addrinfo *temp_res;
647 
648 #define CHANGED_SOCK_TYPE  0x1
649 #define CHANGED_PROTOCOL   0x2
650 #define CHANGED_SCTP       0x4
651 #define CHANGED_DCCP       0x8
652 #define CHANGED_DCCP_SOCK  0x10
653 
654   int    change_info = 0;
655   static int change_warning_displayed = 0;
656 
657   int count = 0;
658   int error = 0;
659 
660   char *hostname;
661 
662   /* take data-address over controlhost */
663   if (data_address)
664     hostname = data_address;
665   else
666     hostname = controlhost;
667 
668   if (debug) {
669     fprintf(where,
670 	    "complete_addrinfo using hostname %s port %s family %s type %s prot %s flags 0x%x\n",
671 	    hostname,
672 	    port,
673 	    inet_ftos(family),
674 	    inet_ttos(type),
675 	    inet_ptos(protocol),
676 	    flags);
677     fflush(where);
678   }
679 
680   memset(&hints, 0, sizeof(hints));
681   hints.ai_family = family;
682   hints.ai_socktype = type;
683   hints.ai_protocol = protocol;
684   hints.ai_flags = flags|AI_CANONNAME|AI_ADDRCONFIG;
685 
686   count = 0;
687   do {
688     error = getaddrinfo((char *)hostname,
689                         (char *)port,
690                         &hints,
691                         &res);
692     count += 1;
693     if (error == EAI_AGAIN) {
694       if (debug) {
695         fprintf(where,"Sleeping on getaddrinfo EAI_AGAIN\n");
696         fflush(where);
697       }
698       sleep(1);
699     }
700     /* while you see this kludge first, it is actually the second, the
701        first being the one for Solaris below. The need for this kludge
702        came after implementing the Solaris broken getaddrinfo kludge -
703        now we see a kludge in Linux getaddrinfo where if it is given
704        SOCK_STREAM and IPPROTO_SCTP it barfs with a -7
705        EAI_SOCKTYPE. so, we check if the error was EAI_SOCKTYPE and if
706        we were asking for IPPROTO_SCTP and if so, kludge, again... raj
707        200?-10-13 and of course, requiring the kludge for SCTP, it is
708        no surprise that linux needs a kludge for DCCP...actually not
709        only does it need the ai_protocol kludge, it needs an
710        ai_socktype kludge too... sigh raj 2008-02-01 */
711 #if defined(IPPROTO_SCTP) || defined (IPPROTO_DCCP)
712     if (EAI_SOCKTYPE == error
713 #ifdef EAI_BADHINTS
714         || EAI_BADHINTS == error
715 #endif
716         ) {
717       /* we ass-u-me this is the Linux getaddrinfo bug, clear the
718 	 hints.ai_protocol field, and set some state "remembering"
719 	 that we did this so the code for the Solaris kludge can do
720 	 the fix-up for us.  also flip error over to EAI_AGAIN and
721 	 make sure we don't "count" this time around the loop. */
722 #if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
723       /* only tweak on this one the second time around, after we've
724 	 kludged the ai_protocol field */
725       if ((hints.ai_socktype == SOCK_DCCP) &&
726 	  (hints.ai_protocol == 0)) {
727 	change_info |= CHANGED_DCCP_SOCK;
728 	hints.ai_socktype = 0;
729 	/* we need to give it some sort of IPPROTO or it gets unhappy,
730 	   so for now, pick one from deep within the colon and use
731 	   IPPROTO_TCP */
732 	hints.ai_protocol = IPPROTO_TCP;
733       }
734 
735       if (hints.ai_protocol == IPPROTO_DCCP) {
736 	change_info |= CHANGED_DCCP;
737 	hints.ai_protocol = 0;
738       }
739 
740 #endif
741 #if defined(IPPROTO_SCTP)
742       if (hints.ai_protocol == IPPROTO_SCTP) {
743 	change_info |= CHANGED_SCTP;
744 	hints.ai_protocol = 0;
745       }
746 #endif
747 
748       error = EAI_AGAIN;
749       count -= 1;
750     }
751 #endif
752   } while ((error == EAI_AGAIN) && (count <= 5));
753 
754   if (error) {
755     fprintf(where,
756 	    "complete_addrinfo: could not resolve '%s' port '%s' af %d"
757 	    "\n\tgetaddrinfo returned %d %s\n",
758 	    hostname,
759 	    port,
760 	    family,
761 	    error,
762 	    gai_strerror(error));
763     fflush(where);
764     exit(-1);
765   }
766 
767   /* there exists at least one platform - Solaris 10 - that does not
768      seem to completely honor the ai_protocol and/or ai_socktype one
769      sets in the hints parm to the getaddrinfo call.  so, we need to
770      walk the list of entries returned and if either of those do not
771      match what we asked for, we need to go ahead and set them
772      "correctly" this is based in part on some earlier SCTP-only code
773      from previous revisions.  raj 2006-10-09 */
774 
775   temp_res = res;
776 
777   while (temp_res) {
778 
779     if ((type)  &&
780 	(temp_res->ai_socktype != type)) {
781       change_info |= CHANGED_SOCK_TYPE;
782       if (debug) {
783 	fprintf(where,
784 		"WARNING! Changed bogus getaddrinfo socket type %d to %d\n",
785 		temp_res->ai_socktype,
786 		type);
787 	fflush(where);
788       }
789       temp_res->ai_socktype = type;
790     }
791 
792     if ((protocol) &&
793 	(temp_res->ai_protocol != protocol)) {
794       change_info |= CHANGED_PROTOCOL;
795       if (debug) {
796 	fprintf(where,
797 		"WARNING! Changed bogus getaddrinfo protocol %d to %d\n",
798 		temp_res->ai_protocol,
799 		protocol);
800 	fflush(where);
801       }
802       temp_res->ai_protocol = protocol;
803     }
804     temp_res = temp_res->ai_next;
805   }
806 
807   if ((change_info & CHANGED_SOCK_TYPE) &&
808       !(change_warning_displayed & CHANGED_SOCK_TYPE)) {
809     change_warning_displayed |= CHANGED_SOCK_TYPE;
810     fprintf(where,
811 	    "WARNING! getaddrinfo returned a socket type which did not\n"
812 	    "match the requested type.  Please contact your vendor for\n"
813 	    "a fix to this bug in getaddrinfo()\n");
814     fflush(where);
815   }
816 
817   /* if we dropped the protocol hint, it would be for a protocol that
818      getaddrinfo() wasn't supporting yet, not for the bug that it took
819      our hint and still returned zero. raj 2006-10-16 */
820   /* as there is now an open bug against (Open)Solaris (id 6847733) on
821      this behaviour we will only emit this warning if debug is set
822      under Solaris and will continue to emit it under any circumstance
823      on other platforms should it arise. raj 2009-06-03 */
824   /* since it has now been two years since that bug was filed, it
825      should be resolved by now, so the "out" given to Sun should no
826      longer be necessary.  either folks are running with the fix or
827      they need to get the fix. raj 2011-07-06 */
828   if ((change_info & CHANGED_PROTOCOL) &&
829       !(change_warning_displayed & CHANGED_PROTOCOL) &&
830       (hints.ai_protocol != 0)) {
831     change_warning_displayed |= CHANGED_PROTOCOL;
832     fprintf(where,
833 	    "WARNING! getaddrinfo returned a protocol other than the\n"
834 	    "requested protocol.  Please contact your vendor for\n"
835 	    "a fix to this bug in getaddrinfo()\n");
836     fflush(where);
837   }
838 
839   if ((change_info & CHANGED_SCTP) &&
840       !(change_warning_displayed & CHANGED_SCTP)) {
841     change_warning_displayed |= CHANGED_SCTP;
842     fprintf(where,
843 	    "WARNING! getaddrinfo on this platform does not accept IPPROTO_SCTP!\n"
844 	    "Please contact your vendor for a fix to this bug in getaddrinfo().\n");
845     fflush(where);
846   }
847 
848   if ((change_info & CHANGED_DCCP) &&
849       !(change_warning_displayed & CHANGED_DCCP)) {
850     change_warning_displayed |= CHANGED_DCCP;
851     fprintf(where,
852 	    "WARNING! getaddrinfo on this platform does not accept IPPROTO_DCCP!\n"
853 	    "Please contact your vendor for a fix to this bug in getaddrinfo().\n");
854     fflush(where);
855   }
856 
857 
858   if (debug) {
859     dump_addrinfo(where, res, hostname, port, family);
860   }
861 
862   return(res);
863 }
864 
865 void
complete_addrinfos(struct addrinfo ** remote,struct addrinfo ** local,char remote_host[],int type,int protocol,int flags)866 complete_addrinfos(struct addrinfo **remote,struct addrinfo **local, char remote_host[], int type, int protocol, int flags) {
867 
868   if (remote_data_family == AF_UNSPEC) {
869     remote_data_family = control_family;
870   }
871 
872   *remote = complete_addrinfo(remote_host,
873 			      remote_data_address,
874 			      remote_data_port,
875 			      remote_data_family,
876 			      type,
877 			      protocol,
878 			      flags);
879 
880   /* OK, if the user has not specified a local data endpoint address
881      (test-specific -L), pick the local data endpoint address based on
882      the remote data family info (test-specific -H or -4 or -6
883      option).  if the user has not specified remote data addressing
884      info (test-specific -H, -4 -6) pick something based on the local
885      control connection address (ie the global -L option). */
886 
887   if (NULL == local_data_address) {
888     local_data_address = malloc(HOSTNAMESIZE);
889     if (NULL == remote_data_address) {
890       if (debug) {
891 	fprintf(where,
892 		"local_data_address not set, using local_host_name of '%s'\n",
893 		local_host_name);
894 	fflush(where);
895       }
896       strcpy(local_data_address,local_host_name);
897     }
898     else {
899       if (debug) {
900 	fprintf(where,
901 		"local_data_address not set, using address family info\n");
902 	fflush(where);
903       }
904       /* by default, use 0.0.0.0 - assume IPv4 */
905       strcpy(local_data_address,"0.0.0.0");
906 #if defined(AF_INET6)
907       if ((AF_INET6 == local_data_family) ||
908 	  ((AF_UNSPEC == local_data_family) &&
909 	   (AF_INET6 == remote_data_family)) ||
910 	  ((AF_UNSPEC == local_data_family) &&
911 	   (AF_INET6 == (*remote)->ai_family))) {
912 	strcpy(local_data_address,"::0");
913       }
914 #endif
915     }
916   }
917 
918   *local = complete_addrinfo("what to put here?",
919 			     local_data_address,
920 			     local_data_port,
921 			     local_data_family,
922 			     type,
923 			     protocol,
924 			     flags|AI_PASSIVE);
925 
926   /* OK, at this point, if remote_data_address is NULL, we know that
927      we used the value of remote_host (the control connection) for the
928      remote, which means we can/should set remote_data_address to
929      remote_host so the "omni" output routines can use that global
930      variable. at least i think I can get away with that :) I'm sure
931      that at some point I'll find-out that I need to allocate
932      something for it rather than mess with the pointers, but that can
933      wait.  famous last words of raj 2008-01-25 */
934   if (remote_data_address == NULL)
935     remote_data_address = remote_host;
936 }
937 
938 void
set_hostname_and_port(char * hostname,char * portstr,int family,int port)939 set_hostname_and_port(char *hostname, char *portstr, int family, int port)
940 {
941   strcpy(hostname,"0.0.0.0");
942 #if defined AF_INET6
943   if (AF_INET6 == family) {
944     strcpy(hostname,"::0");
945   }
946 #endif
947 
948   sprintf(portstr, "%u", port);
949 
950 }
951 
952 static unsigned short
get_port_number(struct addrinfo * res)953 get_port_number(struct addrinfo *res)
954 {
955  switch(res->ai_family) {
956   case AF_INET: {
957     struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr;
958     return(ntohs(foo->sin_port));
959     break;
960   }
961 #if defined(AF_INET6)
962   case AF_INET6: {
963     struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr;
964     return(ntohs(foo->sin6_port));
965     break;
966   }
967 #endif
968   default:
969     fprintf(where,
970 	    "Given Unexpected Address Family of %u\n",res->ai_family);
971     fflush(where);
972     exit(-1);
973   }
974 }
975 
976 static void
extract_inet_address_and_port(struct addrinfo * res,void * addr,int len,int * port)977 extract_inet_address_and_port(struct addrinfo *res, void *addr, int len, int *port)
978 {
979  switch(res->ai_family) {
980   case AF_INET: {
981     struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr;
982     *port = foo->sin_port;
983     memcpy(addr,&(foo->sin_addr),min(len,sizeof(foo->sin_addr)));
984     break;
985   }
986 #if defined(AF_INET6)
987   case AF_INET6: {
988     struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr;
989     *port = foo->sin6_port;
990     memcpy(addr,&(foo->sin6_addr),min(len,sizeof(foo->sin6_addr)));
991     break;
992   }
993 #endif
994   default:
995     *port = 0xDEADBEEF;
996     strncpy(addr,"UNKN FAMILY",len);
997   }
998 }
999 
1000 /* this routine will set the port number of the sockaddr in the
1001    addrinfo to the specified value, based on the address family */
1002 void
set_port_number(struct addrinfo * res,unsigned short port)1003 set_port_number(struct addrinfo *res, unsigned short port)
1004 {
1005   switch(res->ai_family) {
1006   case AF_INET:
1007 #if defined(AF_RDS)
1008   case AF_RDS:
1009 #endif
1010     {
1011       struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr;
1012       foo->sin_port = htons(port);
1013       break;
1014     }
1015 #if defined(AF_INET6)
1016   case AF_INET6: {
1017     struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr;
1018     foo->sin6_port = htons(port);
1019     break;
1020   }
1021 #endif
1022   default:
1023     fprintf(where,
1024 	    "set_port_number Unexpected Address Family of %u\n",res->ai_family);
1025     fflush(where);
1026     exit(-1);
1027   }
1028 }
1029 
1030 /* stuff the address family, port number and address into a
1031    sockaddr. for now, we will go ahead and zero-out the sockaddr
1032    first */
1033 void
set_sockaddr_family_addr_port(struct sockaddr_storage * sockaddr,int family,void * addr,int port)1034 set_sockaddr_family_addr_port(struct sockaddr_storage *sockaddr, int family, void *addr, int port) {
1035 
1036   memset(sockaddr,0,sizeof(struct sockaddr_storage));
1037 
1038   switch (family) {
1039 #if defined(AF_RDS)
1040   case AF_RDS:
1041 #endif
1042   case AF_INET: {
1043     struct sockaddr_in *foo = (struct sockaddr_in *)sockaddr;
1044     foo->sin_port = htons((unsigned short) port);
1045     foo->sin_family = (unsigned short) family;
1046     memcpy(&(foo->sin_addr),addr,sizeof(foo->sin_addr));
1047     *(int *)addr = htonl(*(int *)addr);
1048     break;
1049   }
1050 #if defined(AF_INET6)
1051   case AF_INET6: {
1052     struct sockaddr_in6 *foo = (struct sockaddr_in6 *)sockaddr;
1053     foo->sin6_port = htons((unsigned short) port);
1054     foo->sin6_family = (unsigned short) family;
1055     memcpy(&(foo->sin6_addr),addr,sizeof(foo->sin6_addr));
1056     break;
1057   }
1058 #endif
1059   default:
1060     fprintf(where,
1061 	    "set_sockaddr_family_addr_port Unexpected Address Family of %u\n",family);
1062     fflush(where);
1063     exit(-1);
1064   }
1065 }
1066 
1067 /* pull the port and address out of the sockaddr in host format */
1068 int
get_sockaddr_family_addr_port(struct sockaddr_storage * sockaddr,int family,void * addr,int * port)1069 get_sockaddr_family_addr_port(struct sockaddr_storage *sockaddr, int family, void *addr, int *port)
1070 {
1071   struct sockaddr_in *sin = (struct sockaddr_in *)sockaddr;
1072 
1073   int ret = 0;
1074   if (sin->sin_family != family) {
1075     fprintf(where,
1076 	    "get_sockaddr_family_addr_port family mismatch %d vs %d\n",
1077 	    sin->sin_family,
1078 	    family);
1079     fflush(where);
1080     return -1;
1081   }
1082 
1083   switch(family) {
1084 #if defined(AF_RDS)
1085   case AF_RDS:
1086 #endif
1087   case  AF_INET: {
1088     *port = ntohs(sin->sin_port);
1089     memcpy(addr,&(sin->sin_addr),sizeof(sin->sin_addr));
1090     if (*(int *)addr == INADDR_ANY) ret = 1;
1091     *(int *)addr = ntohl(*(int *)addr);
1092     break;
1093   }
1094 #ifdef AF_INET6
1095   case AF_INET6: {
1096     int i;
1097     struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sockaddr;
1098     *port = ntohs(sin6->sin6_port);
1099     ret = 1;
1100     for (i=0; i < sizeof(struct in6_addr); i++)
1101       if (sin6->sin6_addr.s6_addr[i] != 0) ret=0;
1102     memcpy(addr,&(sin6->sin6_addr), sizeof(sin6->sin6_addr));
1103     break;
1104   }
1105 #endif
1106   default:
1107     fprintf(where,
1108 	    "get_sockaddr_family_addr_port: Unexpected Address Family of %u\n",family);
1109     fflush(where);
1110     exit(-1);
1111   }
1112   return ret;
1113 }
1114 
1115 
1116 int
set_socket_tos(SOCKET sock,int family,int socket_tos)1117 set_socket_tos(SOCKET sock, int family, int socket_tos) {
1118 
1119   int my_tos = -3;
1120   netperf_socklen_t sock_opt_len;
1121 
1122   switch (family) {
1123 #if defined(IP_TOS)
1124   case AF_INET:
1125     /* should I mask-away anything above the byte? */
1126     my_tos = socket_tos;
1127     if (setsockopt(sock,
1128 		   IPPROTO_IP,
1129 		   IP_TOS,
1130 		   (const char *)&my_tos,sizeof(my_tos)) == SOCKET_ERROR) {
1131       fprintf(where,
1132 	      "%s ip_tos failed with %s (errno %d)\n",
1133 	      __FUNCTION__,
1134 	      strerror(errno),
1135 	      errno);
1136       fflush(where);
1137       my_tos = -2;
1138     }
1139     else {
1140       sock_opt_len = sizeof(my_tos);
1141       getsockopt(sock,
1142 		 IPPROTO_IP,
1143 		 IP_TOS,
1144 		 (char *)&my_tos,
1145 		 &sock_opt_len);
1146     }
1147     break;
1148 #endif
1149 #if defined(IPV6_TCLASS)
1150   case AF_INET6:
1151     /* should I mask-away anything above the byte? */
1152     my_tos = socket_tos;
1153     if (setsockopt(sock,
1154 		   IPPROTO_IPV6,
1155 		   IPV6_TCLASS,
1156 		   (const char *)&my_tos,sizeof(my_tos)) == SOCKET_ERROR) {
1157       fprintf(where,
1158 	      "%s ip_tos failed with %s (errno %d)\n",
1159 	      __FUNCTION__,
1160 	      strerror(errno),
1161 	      errno);
1162       fflush(where);
1163       my_tos = -2;
1164     }
1165     else {
1166       sock_opt_len = sizeof(my_tos);
1167       getsockopt(sock,
1168 		 IPPROTO_IPV6,
1169 		 IPV6_TCLASS,
1170 		 (char *)&my_tos,
1171 		 &sock_opt_len);
1172     }
1173     break;
1174 #endif
1175   }
1176   return my_tos;
1177 }
1178 
1179 
1180  /* This routine will create a data (listen) socket with the
1181   apropriate options set and return it to the caller. this replaces
1182   all the duplicate code in each of the test routines and should help
1183   make things a little easier to understand. since this routine can be
1184   called by either the netperf or netserver programs, all output
1185   should be directed towards "where." family is generally AF_INET and
1186   type will be either SOCK_STREAM or SOCK_DGRAM.  This routine will
1187   also be used by the "SCTP" tests, hence the slightly strange-looking
1188   SCTP stuff in the classic bsd sockets test file... vlad/raj
1189   2005-03-15 */
1190 
1191 SOCKET
create_data_socket(struct addrinfo * res)1192 create_data_socket(struct addrinfo *res)
1193 {
1194 
1195   SOCKET temp_socket;
1196   int one = 1;
1197   int on  = 1;
1198   netperf_socklen_t sock_opt_len;
1199 
1200   /*set up the data socket                        */
1201   temp_socket = socket(res->ai_family,
1202 		       res->ai_socktype,
1203 		       res->ai_protocol);
1204 
1205   if (temp_socket == INVALID_SOCKET){
1206     fprintf(where,
1207 	    "netperf: create_data_socket: socket: errno %d fam %s type %s prot %s errmsg %s\n",
1208 	    errno,
1209 	    inet_ftos(res->ai_family),
1210 	    inet_ttos(res->ai_socktype),
1211 	    inet_ptos(res->ai_protocol),
1212 	    strerror(errno));
1213     fflush(where);
1214     exit(1);
1215   }
1216 
1217   if (debug) {
1218     fprintf(where,"create_data_socket: socket %d obtained...\n",temp_socket);
1219     fflush(where);
1220   }
1221 
1222   /* Modify the local socket size. The reason we alter the send buffer
1223    size here rather than when the connection is made is to take care
1224    of decreases in buffer size. Decreasing the window size after
1225    connection establishment is a TCP no-no. Also, by setting the
1226    buffer (window) size before the connection is established, we can
1227    control the TCP MSS (segment size). The MSS is never (well, should
1228    never be) more that 1/2 the minimum receive buffer size at each
1229    half of the connection.  This is why we are altering the receive
1230    buffer size on the sending size of a unidirectional transfer. If
1231    the user has not requested that the socket buffers be altered, we
1232    will try to find-out what their values are. If we cannot touch the
1233    socket buffer in any way, we will set the values to -1 to indicate
1234    that.  */
1235 
1236   /* all the oogy nitty gritty stuff moved from here into the routine
1237      being called below, per patches from davidm to workaround the bug
1238      in Linux getsockopt().  raj 2004-06-15 */
1239   set_sock_buffer (temp_socket, SEND_BUFFER, lss_size_req, &lss_size);
1240   set_sock_buffer (temp_socket, RECV_BUFFER, lsr_size_req, &lsr_size);
1241 
1242   /* now, we may wish to enable the copy avoidance features on the */
1243   /* local system. of course, this may not be possible... */
1244 
1245 #ifdef SO_RCV_COPYAVOID
1246   /* this is ancient vestigial HP-UX code that should probably go away
1247      one day */
1248   if (loc_rcvavoid) {
1249     if (setsockopt(temp_socket,
1250 		   SOL_SOCKET,
1251 		   SO_RCV_COPYAVOID,
1252 		   (const char *)&loc_rcvavoid,
1253 		   sizeof(int)) == SOCKET_ERROR) {
1254       fprintf(where,
1255 	      "netperf: create_data_socket: Could not enable receive copy avoidance");
1256       fflush(where);
1257       loc_rcvavoid = 0;
1258     }
1259   }
1260 #endif
1261 
1262 #ifdef SO_SND_COPYAVOID
1263   if (loc_sndavoid) {
1264     if (setsockopt(temp_socket,
1265 		   SOL_SOCKET,
1266 		   SO_SND_COPYAVOID,
1267 		   (const char *)&loc_sndavoid,
1268 		   sizeof(int)) == SOCKET_ERROR) {
1269       fprintf(where,
1270 	      "netperf: create_data_socket: Could not enable send copy avoidance");
1271       fflush(where);
1272       loc_sndavoid = 0;
1273     }
1274   }
1275 #endif
1276 
1277   /* Now, we will see about setting the TCP_NODELAY flag on the local */
1278   /* socket. We will only do this for those systems that actually */
1279   /* support the option. If it fails, note the fact, but keep going. */
1280   /* If the user tries to enable TCP_NODELAY on a UDP socket, this */
1281   /* will cause an error to be displayed */
1282 
1283   /* well..... long ago and far away that would have happened, in
1284      particular because we would always use IPPROTO_TCP here.
1285      however, now we are using res->ai_protocol, which will be
1286      IPPROT_UDP, and while HP-UX, and I suspect no-one else on the
1287      planet has a UDP_mumble option that overlaps with TCP_NODELAY,
1288      sure as knuth made little green programs, linux has a UDP_CORK
1289      option that is defined as a value of 1, which is the same a
1290      TCP_NODELAY under Linux.  So, when asking for -D and
1291      "TCP_NODELAY" under Linux, we are actually setting UDP_CORK
1292      instead of getting an error like every other OS on the
1293      planet. joy and rupture. this stops a UDP_RR test cold sooo we
1294      have to make sure that res->ai_protocol actually makes sense for
1295      a _NODELAY setsockopt() or a UDP_RR test on Linux where someone
1296      mistakenly sets -D will hang.  raj 2005-04-21 */
1297 
1298 #if defined(TCP_NODELAY) || defined(SCTP_NODELAY)
1299   if ((loc_nodelay) && (res->ai_protocol != IPPROTO_UDP)) {
1300 
1301     /* strictly speaking, since the if defined above is an OR, we
1302        should probably check against TCP_NODELAY being defined here.
1303        however, the likelihood of SCTP_NODELAY being defined and
1304        TCP_NODELAY _NOT_ being defined is, probably :), epsilon.  raj
1305        2005-03-15 */
1306 
1307     int option = TCP_NODELAY;
1308 
1309     /* I suspect that WANT_SCTP would suffice here since that is the
1310        only time we would have called getaddrinfo with a hints asking
1311        for SCTP, but just in case there is an SCTP implementation out
1312        there _without_ SCTP_NODELAY... raj 2005-03-15 */
1313     /* change this to IPPROTO_SCTP rather than WANT_SCTP to better fit
1314        with the modus operandi of the new "omni" tests. raj
1315        2008-02-04 */
1316 #if defined(IPPROTO_SCTP) && defined(SCTP_NODELAY)
1317     if (IPPROTO_SCTP == res->ai_protocol) {
1318       option = SCTP_NODELAY;
1319     }
1320 #endif
1321 
1322     one = 1;
1323     if(setsockopt(temp_socket,
1324 		  res->ai_protocol,
1325 		  option,
1326 		  (char *)&one,
1327 		  sizeof(one)) == SOCKET_ERROR) {
1328       fprintf(where,
1329 	      "netperf: create_data_socket: nodelay: errno %d\n",
1330 	      errno);
1331       fflush(where);
1332     }
1333 
1334     if (debug > 1) {
1335       fprintf(where,
1336 	      "netperf: create_data_socket: [TCP|SCTP]_NODELAY requested...\n");
1337       fflush(where);
1338     }
1339   }
1340 #else /* TCP_NODELAY */
1341 
1342   loc_nodelay = 0;
1343 
1344 #endif /* TCP_NODELAY */
1345 
1346   if ((transport_mss_req != -1) && (IPPROTO_TCP == res->ai_protocol)) {
1347     set_tcp_mss(temp_socket,transport_mss_req);
1348   }
1349 
1350 #if defined(TCP_CORK)
1351 
1352   if (loc_tcpcork > 0) {
1353     /* the user wishes for us to set TCP_CORK on the socket */
1354     if (setsockopt(temp_socket,
1355 		   getprotobyname("tcp")->p_proto,
1356 		   TCP_CORK,
1357 		   (char *)&one,
1358 		   sizeof(one)) == SOCKET_ERROR) {
1359       perror("netperf: create_data_socket: tcp_cork");
1360       exit(1);
1361     }
1362     if (debug) {
1363       fprintf(where,"create_data_socket: tcp_cork...\n");
1364     }
1365   }
1366 
1367 #endif /* TCP_CORK */
1368 
1369   /* well, after Knuth only knows how many years, I have finally
1370     decided to enable setting SO_KEEPALIVE on the data socket.  99
1371     times out of 10 this should not be necessary, but that 100th time,
1372     perhaps when netperf is being (ab)used by functional testers, may
1373     benefit from it.  And it may help clean-up some lingering
1374     netservers from time to time.  raj 2011-06-29 */
1375 
1376 #if defined(SO_KEEPALIVE)
1377 
1378   if (want_keepalive) {
1379     if (setsockopt(temp_socket,
1380 		   SOL_SOCKET,
1381 		   SO_KEEPALIVE,
1382 		   (const char *)&on,
1383 		   sizeof(on)) < 0) {
1384       if (debug) {
1385 	fprintf(where,
1386 		"%s: unable to set SO_KEEPALIVE on data socket: %s (errno %d)\n",
1387 		__FUNCTION__,
1388 		strerror(errno),
1389 		errno);
1390 	fflush(where);
1391       }
1392     }
1393   }
1394 
1395 #endif /* SO_KEEPALIVE */
1396 
1397   /* since some of the UDP tests do not do anything to cause an
1398      implicit bind() call, we need to be rather explicit about our
1399      bind() call here. even if the address and/or the port are zero
1400      (INADDR_ANY etc). raj 2004-07-20 */
1401 
1402   if (setsockopt(temp_socket,
1403 #ifdef IPPROTO_DCCP
1404 		 /* it is REALLY SILLY THAT THIS SHOULD BE NEEDED!! I
1405 		    should be able to use SOL_SOCKET for this just
1406 		    like TCP and SCTP */
1407 		 /* IT IS EVEN SILLIER THAT THERE COULD BE SYSTEMS
1408 		    WITH IPPROTO_DCCP and no SOL_DCCP */
1409 #ifndef SOL_DCCP
1410 #define SOL_DCCP SOL_SOCKET
1411 #define NETPERF_NEED_CLEANUP 1
1412 #endif
1413 		 (res->ai_protocol == IPPROTO_DCCP) ? SOL_DCCP : SOL_SOCKET,
1414 #ifdef NETPERF_NEED_CLEANUP
1415 #undef SOL_DCCP
1416 #undef NETPERF_NEED_CLEANUP
1417 #endif
1418 
1419 #else
1420 		 SOL_SOCKET,
1421 #endif
1422 		 SO_REUSEADDR,
1423 		 (const char *)&on,
1424 		 sizeof(on)) < 0) {
1425     fprintf(where,
1426 	    "netperf: create_data_socket: SO_REUSEADDR failed %d\n",
1427 	    errno);
1428     fflush(where);
1429   }
1430 
1431   if (bind(temp_socket,
1432 	   res->ai_addr,
1433 	   res->ai_addrlen) < 0) {
1434     if (debug) {
1435       fprintf(where,
1436 	      "netperf: create_data_socket: data socket bind failed: %s (errno %d)\n",
1437 	      strerror(errno),
1438 	      errno);
1439       fprintf(where," port: %d\n",get_port_number(res));
1440       fflush(where);
1441     }
1442   }
1443 
1444   /* this one is a slightly grudgingly added backside covering for
1445      those folks who (ab)use netperf as a functional testing tool, and
1446      further compound that error by running tests on systems also
1447      connected to their site networks, and then compound it even
1448      further compound it by running UDP_STREAM tests over links that
1449      generate link-down events and so cause the traffic to be sent out
1450      the default route into their corporate network...  frankly such
1451      people should not be allowed to run netperf in the first place
1452      but there we are... raj 20091026 */
1453 
1454 #if defined (SO_DONTROUTE)
1455   if (!routing_allowed) {
1456     if (setsockopt(temp_socket,
1457 		   SOL_SOCKET,
1458 		   SO_DONTROUTE,
1459 		   (char *)&one,
1460 		   sizeof(one)) == SOCKET_ERROR) {
1461       fprintf(where,
1462 	      "netperf: create_data_socket: so_dontroute: errno %d\n",
1463 	      errno);
1464       fflush(where);
1465     }
1466   }
1467 #endif
1468 
1469 #if defined(SO_PRIORITY)
1470   if (local_socket_prio >= 0) {
1471     if (setsockopt(temp_socket,
1472                   SOL_SOCKET,
1473                   SO_PRIORITY,
1474                   &local_socket_prio,
1475                   sizeof(int)) == SOCKET_ERROR) {
1476       fprintf(where,
1477              "netperf: create_data_socket: so_priority: errno %d\n",
1478              errno);
1479       fflush(where);
1480       local_socket_prio = -2;
1481     }
1482     else {
1483       sock_opt_len = 4;
1484       getsockopt(temp_socket,
1485 		 SOL_SOCKET,
1486 		 SO_PRIORITY,
1487 		 &local_socket_prio,
1488 		 &sock_opt_len);
1489     }
1490   }
1491 #else
1492   local_socket_prio = -3;
1493 #endif
1494 
1495 #if defined (IP_TOS) || defined(IPV6_TCLASS)
1496   if (local_socket_tos > 0)
1497     local_socket_tos = set_socket_tos(temp_socket,res->ai_family, local_socket_tos);
1498 #endif
1499 
1500   return temp_socket;
1501 }
1502 
1503 #ifdef KLUDGE_SOCKET_OPTIONS
1504 
1505 
1506  /* This routine is for those BROKEN systems which do not correctly */
1507  /* pass socket attributes through calls such as accept(). It should */
1508  /* only be called for those broken systems. I *really* don't want to */
1509  /* have this, but even broken systems must be measured. raj 11/95 */
1510 void
kludge_socket_options(int temp_socket)1511 kludge_socket_options(int temp_socket)
1512 {
1513 
1514   set_sock_buffer(temp_socket, SEND_BUFFER, lss_size_req, &lss_size);
1515   set_sock_buffer(temp_socket, RECV_BUFFER, lsr_size_req, &lsr_size);
1516 
1517   /* now, we may wish to enable the copy avoidance features on the */
1518   /* local system. of course, this may not be possible... */
1519   /* those calls were only valid for HP-UX, and I know that HP-UX is */
1520   /* written correctly, and so we do not need to include those calls */
1521   /* in this kludgy routine. raj 11/95 */
1522 
1523 
1524   /* Now, we will see about setting the TCP_NODELAY flag on the local */
1525   /* socket. We will only do this for those systems that actually */
1526   /* support the option. If it fails, note the fact, but keep going. */
1527   /* If the user tries to enable TCP_NODELAY on a UDP socket, this */
1528   /* will cause an error to be displayed */
1529 
1530 #ifdef TCP_NODELAY
1531   if (loc_nodelay) {
1532     one = 1;
1533     if(setsockopt(temp_socket,
1534 		  getprotobyname("tcp")->p_proto,
1535 		  TCP_NODELAY,
1536 		  (char *)&one,
1537 		  sizeof(one)) == SOCKET_ERROR) {
1538       fprintf(where,"netperf: kludge_socket_options: nodelay: errno %d\n",
1539 	      errno);
1540       fflush(where);
1541     }
1542 
1543     if (debug > 1) {
1544       fprintf(where,
1545 	      "netperf: kludge_socket_options: TCP_NODELAY requested...\n");
1546       fflush(where);
1547     }
1548   }
1549 #else /* TCP_NODELAY */
1550 
1551   loc_nodelay = 0;
1552 
1553 #endif /* TCP_NODELAY */
1554 
1555   }
1556 
1557 #endif /* KLUDGE_SOCKET_OPTIONS */
1558 
1559 
1560 static void *
get_address_address(struct addrinfo * info)1561 get_address_address(struct addrinfo *info)
1562 {
1563   struct sockaddr_in *sin;
1564 #if defined(AF_INET6)
1565   struct sockaddr_in6 *sin6;
1566 #endif
1567 
1568   switch(info->ai_family) {
1569   case AF_INET:
1570     sin = (struct sockaddr_in *)info->ai_addr;
1571     return(&(sin->sin_addr));
1572     break;
1573 #if defined(AF_INET6)
1574   case AF_INET6:
1575     sin6 = (struct sockaddr_in6 *)info->ai_addr;
1576     return(&(sin6->sin6_addr));
1577     break;
1578 #endif
1579   default:
1580     fprintf(stderr,"we never expected to get here in get_address_address\n");
1581     fflush(stderr);
1582     exit(-1);
1583   }
1584 }
1585 
1586 #if defined(WIN32)
1587 #if !defined(InetNtop)
1588 /* +*+ Why isn't this in the winsock headers yet? */
1589 const char *
1590 inet_ntop(int af, const void *src, char *dst, size_t size);
1591 #endif
1592 #endif
1593 
1594 /* This routine is a generic test header printer for the topmost header */
1595 void
print_top_test_header(char test_name[],struct addrinfo * source,struct addrinfo * destination)1596 print_top_test_header(char test_name[], struct addrinfo *source, struct addrinfo *destination)
1597 {
1598 
1599   char *address_buf;
1600 
1601 #ifdef AF_INET6
1602   address_buf = malloc(INET6_ADDRSTRLEN);
1603 #else
1604   address_buf = malloc(16); /* magic constant */
1605 #endif
1606 
1607   if (address_buf == NULL) {
1608     fprintf(where,"Unable to allocate address_buf\n");
1609     fflush(where);
1610     exit(1);
1611   }
1612 
1613   /* we want to have some additional, interesting information in the
1614      headers. we know some of it here, but not all, so we will only
1615      print the test title here and will print the results titles after
1616      the test is finished */
1617   fprintf(where,"%s",test_name);
1618 
1619   address_buf[0] = '\0';
1620   inet_ntop(source->ai_family,get_address_address(source),address_buf,sizeof(address_buf));
1621   fprintf(where,
1622 	  " from %s (%s) port %u %s",
1623 	  source->ai_canonname,
1624 	  address_buf,
1625 	  get_port_number(source),
1626 	  inet_ftos(source->ai_family));
1627 
1628   address_buf[0] = '\0';
1629   inet_ntop(destination->ai_family,get_address_address(destination),address_buf,sizeof(address_buf));
1630   fprintf(where,
1631 	  " to %s (%s) port %u %s",
1632 	  destination->ai_canonname,
1633 	  address_buf,
1634 	  get_port_number(destination),
1635 	  inet_ftos(destination->ai_family));
1636 
1637   if (iteration_max > 1) {
1638     fprintf(where,
1639 	    " : +/-%.3f%% @ %2d%% conf. %s",
1640 	    interval/0.02,
1641 	    confidence_level,
1642 	    result_confidence_only ? " on result only" : "");
1643   }
1644   if ((loc_nodelay > 0) || (rem_nodelay > 0)) {
1645     fprintf(where," : nodelay");
1646   }
1647   if ((loc_sndavoid > 0) ||
1648       (loc_rcvavoid > 0) ||
1649       (rem_sndavoid > 0) ||
1650       (rem_rcvavoid > 0)) {
1651     fprintf(where," : copy avoidance");
1652   }
1653 
1654   if (no_control) {
1655     fprintf(where," : no control");
1656   }
1657 
1658 #ifdef WANT_HISTOGRAM
1659   fprintf(where," : histogram");
1660 #endif /* WANT_HISTOGRAM */
1661 
1662 #ifdef WANT_INTERVALS
1663 #ifndef WANT_SPIN
1664   fprintf(where," : interval");
1665 #else
1666   fprintf(where," : spin interval");
1667 #endif
1668 #endif /* WANT_INTERVALS */
1669 
1670 #ifdef DIRTY
1671   fprintf(where," : dirty data");
1672 #endif /* DIRTY */
1673 #ifdef WANT_DEMO
1674   fprintf(where," : demo");
1675 #endif
1676 #ifdef WANT_FIRST_BURST
1677   /* a little hokey perhaps, but we really only want this to be
1678      emitted for tests where it actually is used, which means a
1679      "REQUEST/RESPONSE" test. raj 2005-11-10 */
1680   if (strstr(test_name,"REQUEST/RESPONSE")) {
1681     fprintf(where," : first burst %d",first_burst_size);
1682   }
1683 #endif
1684   if (cpu_binding_requested) {
1685     fprintf(where," : cpu bind");
1686   }
1687   fprintf(where,"\n");
1688 
1689   free(address_buf);
1690 }
1691 
1692 /* if WANT_MIGRATION is defined, we will use the send_tcp_stream()
1693    call in src/nettest_omni.c */
1694 #ifndef WANT_MIGRATION
1695 
1696 /* This routine implements the TCP unidirectional data transfer test */
1697 /* (a.k.a. stream) for the sockets interface. It receives its */
1698 /* parameters via global variables from the shell and writes its */
1699 /* output to the standard output. */
1700 
1701 void
send_tcp_stream(char remote_host[])1702 send_tcp_stream(char remote_host[])
1703 {
1704 
1705   char *tput_title = "\
1706 Recv   Send    Send                          \n\
1707 Socket Socket  Message  Elapsed              \n\
1708 Size   Size    Size     Time     Throughput  \n\
1709 bytes  bytes   bytes    secs.    %s/sec  \n\n";
1710 
1711   char *tput_fmt_0 =
1712     "%7.2f %s\n";
1713 
1714   char *tput_fmt_1 =
1715     "%6d %6d %6d    %-6.2f   %7.2f   %s\n";
1716 
1717   char *cpu_title = "\
1718 Recv   Send    Send                          Utilization       Service Demand\n\
1719 Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
1720 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
1721 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
1722 
1723   char *cpu_fmt_0 =
1724     "%6.3f %c %s\n";
1725 
1726   char *cpu_fmt_1 =
1727     "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f %s\n";
1728 
1729   char *ksink_fmt = "\n\
1730 Alignment      Offset         %-8.8s %-8.8s    Sends   %-8.8s Recvs\n\
1731 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
1732 Send   Recv    Send   Recv             Send (avg)          Recv (avg)\n\
1733 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
1734 
1735   char *ksink_fmt2 = "\n\
1736 Maximum\n\
1737 Segment\n\
1738 Size (bytes)\n\
1739 %6d\n";
1740 
1741 
1742   float			elapsed_time;
1743 
1744   /* what we want is to have a buffer space that is at least one */
1745   /* send-size greater than our send window. this will insure that we */
1746   /* are never trying to re-use a buffer that may still be in the hands */
1747   /* of the transport. This buffer will be malloc'd after we have found */
1748   /* the size of the local senc socket buffer. We will want to deal */
1749   /* with alignment and offset concerns as well. */
1750 
1751   struct ring_elt *send_ring;
1752 
1753   int len;
1754   unsigned int nummessages = 0;
1755   SOCKET send_socket;
1756   int bytes_remaining;
1757   int tcp_mss = -1;  /* possibly uninitialized on printf far below */
1758 
1759   /* with links like fddi, one can send > 32 bits worth of bytes
1760      during a test... ;-) at some point, this should probably become a
1761      64bit integral type, but those are not entirely common
1762      yet... time passes, and 64 bit types do indeed become common. */
1763 #if defined(WIN32) && _MSC_VER <= 1200
1764   __int64 local_bytes_sent = 0;
1765 #else
1766   unsigned long long local_bytes_sent = 0;
1767 #endif
1768 
1769   double	bytes_sent = 0.0;
1770 
1771   float	local_cpu_utilization;
1772   float	local_service_demand;
1773   float	remote_cpu_utilization;
1774   float	remote_service_demand;
1775 
1776   double	thruput;
1777 
1778   struct addrinfo *remote_res;
1779   struct addrinfo *local_res;
1780 
1781   struct	tcp_stream_request_struct	*tcp_stream_request;
1782   struct	tcp_stream_response_struct	*tcp_stream_response;
1783   struct	tcp_stream_results_struct	*tcp_stream_result;
1784 
1785   tcp_stream_request  =
1786     (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
1787   tcp_stream_response =
1788     (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
1789   tcp_stream_result   =
1790     (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
1791 
1792 #ifdef WANT_HISTOGRAM
1793   if (verbosity > 1) {
1794     time_hist = HIST_new();
1795   }
1796 #endif /* WANT_HISTOGRAM */
1797   /* since we are now disconnected from the code that established the */
1798   /* control socket, and since we want to be able to use different */
1799   /* protocols and such, we are passed the name of the remote host and */
1800   /* must turn that into the test specific addressing information. */
1801 
1802   /* complete_addrinfos will either succede or exit the process */
1803   complete_addrinfos(&remote_res,
1804 		     &local_res,
1805 		     remote_host,
1806 		     SOCK_STREAM,
1807 		     IPPROTO_TCP,
1808 		     0);
1809 
1810   if ( print_headers ) {
1811     print_top_test_header("TCP STREAM TEST",local_res,remote_res);
1812   }
1813 
1814   send_ring = NULL;
1815   confidence_iteration = 1;
1816   init_stat();
1817 
1818   /* we have a great-big while loop which controls the number of times */
1819   /* we run a particular test. this is for the calculation of a */
1820   /* confidence interval (I really should have stayed awake during */
1821   /* probstats :). If the user did not request confidence measurement */
1822   /* (no confidence is the default) then we will only go though the */
1823   /* loop once. the confidence stuff originates from the folks at IBM */
1824 
1825   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
1826 	 (confidence_iteration <= iteration_min)) {
1827 
1828     /* initialize a few counters. we have to remember that we might be */
1829     /* going through the loop more than once. */
1830 
1831     nummessages    =	0;
1832     bytes_sent     =	0.0;
1833     times_up       = 	0;
1834 
1835     /*set up the data socket                        */
1836     send_socket = create_data_socket(local_res);
1837 
1838     if (send_socket == INVALID_SOCKET){
1839       perror("netperf: send_tcp_stream: tcp stream data socket");
1840       exit(1);
1841     }
1842 
1843     if (debug) {
1844       fprintf(where,"send_tcp_stream: send_socket obtained...\n");
1845     }
1846 
1847     /* at this point, we have either retrieved the socket buffer sizes, */
1848     /* or have tried to set them, so now, we may want to set the send */
1849     /* size based on that (because the user either did not use a -m */
1850     /* option, or used one with an argument of 0). If the socket buffer */
1851     /* size is not available, we will set the send size to 4KB - no */
1852     /* particular reason, just arbitrary... */
1853     if (send_size == 0) {
1854       if (lss_size > 0) {
1855 	send_size = lss_size;
1856       }
1857       else {
1858 	send_size = 4096;
1859       }
1860     }
1861 
1862     /* set-up the data buffer ring with the requested alignment and offset. */
1863     /* note also that we have allocated a quantity */
1864     /* of memory that is at least one send-size greater than our socket */
1865     /* buffer size. We want to be sure that there are at least two */
1866     /* buffers allocated - this can be a bit of a problem when the */
1867     /* send_size is bigger than the socket size, so we must check... the */
1868     /* user may have wanted to explicitly set the "width" of our send */
1869     /* buffers, we should respect that wish... */
1870     if (send_width == 0) {
1871       send_width = (lss_size/send_size) + 1;
1872       if (send_width == 1) send_width++;
1873     }
1874 
1875     if (send_ring == NULL) {
1876       /* only allocate the send ring once. this is a networking test, */
1877       /* not a memory allocation test. this way, we do not need a */
1878       /* deallocate_buffer_ring() routine, and I don't feel like */
1879       /* writing one anyway :) raj 11/94 */
1880       send_ring = allocate_buffer_ring(send_width,
1881 				       send_size,
1882 				       local_send_align,
1883 				       local_send_offset);
1884     }
1885 
1886     /* If the user has requested cpu utilization measurements, we must */
1887     /* calibrate the cpu(s). We will perform this task within the tests */
1888     /* themselves. If the user has specified the cpu rate, then */
1889     /* calibrate_local_cpu will return rather quickly as it will have */
1890     /* nothing to do. If local_cpu_rate is zero, then we will go through */
1891     /* all the "normal" calibration stuff and return the rate back. */
1892 
1893     if (local_cpu_usage) {
1894       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
1895     }
1896 
1897     if (!no_control) {
1898       /* Tell the remote end to do a listen. The server alters the
1899 	 socket paramters on the other side at this point, hence the
1900 	 reason for all the values being passed in the setup
1901 	 message. If the user did not specify any of the parameters,
1902 	 they will be passed as 0, which will indicate to the remote
1903 	 that no changes beyond the system's default should be
1904 	 used. Alignment is the exception, it will default to 1, which
1905 	 will be no alignment alterations. */
1906 
1907       netperf_request.content.request_type =	DO_TCP_STREAM;
1908       tcp_stream_request->send_buf_size	=	rss_size_req;
1909       tcp_stream_request->recv_buf_size	=	rsr_size_req;
1910       tcp_stream_request->receive_size	=	recv_size;
1911       tcp_stream_request->no_delay	=	rem_nodelay;
1912       tcp_stream_request->recv_alignment	=	remote_recv_align;
1913       tcp_stream_request->recv_offset	=	remote_recv_offset;
1914       tcp_stream_request->measure_cpu	=	remote_cpu_usage;
1915       tcp_stream_request->cpu_rate	=	remote_cpu_rate;
1916       if (test_time) {
1917 	tcp_stream_request->test_length	=	test_time;
1918       }
1919       else {
1920 	tcp_stream_request->test_length	=	test_bytes;
1921       }
1922       tcp_stream_request->so_rcvavoid	=	rem_rcvavoid;
1923       tcp_stream_request->so_sndavoid	=	rem_sndavoid;
1924 #ifdef DIRTY
1925       tcp_stream_request->dirty_count     =       rem_dirty_count;
1926       tcp_stream_request->clean_count     =       rem_clean_count;
1927 #endif /* DIRTY */
1928       tcp_stream_request->port            =    atoi(remote_data_port);
1929       tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
1930       if (debug > 1) {
1931 	fprintf(where,
1932 		"netperf: send_tcp_stream: requesting TCP stream test\n");
1933       }
1934 
1935       send_request();
1936 
1937       /* The response from the remote will contain all of the relevant
1938          socket parameters for this test type. We will put them back
1939          into the variables here so they can be displayed if desired.
1940          The remote will have calibrated CPU if necessary, and will
1941          have done all the needed set-up we will have calibrated the
1942          cpu locally before sending the request, and will grab the
1943          counter value right after the connect returns. The remote
1944          will grab the counter right after the accept call. This saves
1945          the hassle of extra messages being sent for the TCP
1946          tests.  */
1947 
1948       recv_response();
1949 
1950       if (!netperf_response.content.serv_errno) {
1951 	if (debug)
1952 	  fprintf(where,"remote listen done.\n");
1953 	rsr_size	      =	tcp_stream_response->recv_buf_size;
1954 	rss_size	      =	tcp_stream_response->send_buf_size;
1955 	rem_nodelay     =	tcp_stream_response->no_delay;
1956 	remote_cpu_usage=	tcp_stream_response->measure_cpu;
1957 	remote_cpu_rate = tcp_stream_response->cpu_rate;
1958 
1959 	/* we have to make sure that the server port number is in
1960 	   network order */
1961 	set_port_number(remote_res,
1962 			(short)tcp_stream_response->data_port_number);
1963 
1964 	rem_rcvavoid	= tcp_stream_response->so_rcvavoid;
1965 	rem_sndavoid	= tcp_stream_response->so_sndavoid;
1966       }
1967       else {
1968 	Set_errno(netperf_response.content.serv_errno);
1969 	fprintf(where,
1970 		"netperf: remote error %d",
1971 		netperf_response.content.serv_errno);
1972 	perror("");
1973 	fflush(where);
1974 
1975 	exit(1);
1976       }
1977     }
1978 
1979 #ifdef WANT_DEMO
1980     demo_stream_setup(lss_size,rsr_size);
1981 #endif
1982 
1983     /*Connect up to the remote port on the data socket  */
1984     if (connect(send_socket,
1985 		remote_res->ai_addr,
1986 		remote_res->ai_addrlen) == INVALID_SOCKET){
1987       perror("netperf: send_tcp_stream: data socket connect failed");
1988       exit(1);
1989     }
1990 
1991 #ifdef WIN32
1992   /* this is used so the timer thread can close the socket out from */
1993   /* under us, which to date is the easiest/cleanest/least */
1994   /* Windows-specific way I can find to force the winsock calls to */
1995   /* return WSAEINTR with the test is over. anything that will run on */
1996   /* 95 and NT and is closer to what netperf expects from Unix signals */
1997   /* and such would be appreciated raj 1/96 */
1998   win_kludge_socket = send_socket;
1999 #endif /* WIN32 */
2000 
2001     /* Data Socket set-up is finished. If there were problems, either */
2002     /* the connect would have failed, or the previous response would */
2003     /* have indicated a problem. I failed to see the value of the */
2004     /* extra  message after the accept on the remote. If it failed, */
2005     /* we'll see it here. If it didn't, we might as well start pumping */
2006     /* data. */
2007 
2008     /* Set-up the test end conditions. For a stream test, they can be */
2009     /* either time or byte-count based. */
2010 
2011     if (test_time) {
2012       /* The user wanted to end the test after a period of time. */
2013       times_up = 0;
2014       bytes_remaining = 0;
2015       /* in previous revisions, we had the same code repeated throught */
2016       /* all the test suites. this was unnecessary, and meant more */
2017       /* work for me when I wanted to switch to POSIX signals, so I */
2018       /* have abstracted this out into a routine in netlib.c. if you */
2019       /* are experiencing signal problems, you might want to look */
2020       /* there. raj 11/94 */
2021       start_timer(test_time);
2022     }
2023     else {
2024       /* The tester wanted to send a number of bytes. */
2025       bytes_remaining = test_bytes;
2026       times_up = 1;
2027     }
2028 
2029     /* The cpu_start routine will grab the current time and possibly */
2030     /* value of the idle counter for later use in measuring cpu */
2031     /* utilization and/or service demand and thruput. */
2032 
2033     cpu_start(local_cpu_usage);
2034 
2035     /* we only start the interval timer if we are using the
2036        timer-timed intervals rather than the sit and spin ones. raj
2037        2006-02-06 */
2038 #if defined(WANT_INTERVALS)
2039     INTERVALS_INIT();
2040 #endif /* WANT_INTERVALS */
2041 
2042     /* before we start, initialize a few variables */
2043 
2044 #ifdef WANT_DEMO
2045       if (demo_mode) {
2046 	demo_first_timestamp();
2047       }
2048 #endif
2049 
2050 
2051     /* We use an "OR" to control test execution. When the test is */
2052     /* controlled by time, the byte count check will always return false. */
2053     /* When the test is controlled by byte count, the time test will */
2054     /* always return false. When the test is finished, the whole */
2055     /* expression will go false and we will stop sending data. */
2056 
2057     while ((!times_up) || (bytes_remaining > 0)) {
2058 
2059 #ifdef DIRTY
2060       access_buffer(send_ring->buffer_ptr,
2061 		    send_size,
2062 		    loc_dirty_count,
2063 		    loc_clean_count);
2064 #endif /* DIRTY */
2065 
2066 #ifdef WANT_HISTOGRAM
2067       if (verbosity > 1) {
2068 	/* timestamp just before we go into send and then again just
2069 	 after we come out raj 8/94 */
2070 	/* but lets only do this if there is going to be a histogram
2071 	   displayed */
2072 	HIST_timestamp(&time_one);
2073       }
2074 #endif /* WANT_HISTOGRAM */
2075 
2076       if((len=send(send_socket,
2077 		   send_ring->buffer_ptr,
2078 		   send_size,
2079 		   0)) != send_size) {
2080       if ((len >=0) || SOCKET_EINTR(len)) {
2081 	    /* the test was interrupted, must be the end of test */
2082 	    break;
2083 	  }
2084 	perror("netperf: data send error");
2085 	printf("len was %d\n",len);
2086 	exit(1);
2087       }
2088 
2089       local_bytes_sent += send_size;
2090 
2091 #ifdef WANT_HISTOGRAM
2092       if (verbosity > 1) {
2093 	/* timestamp the exit from the send call and update the histogram */
2094 	HIST_timestamp(&time_two);
2095 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
2096       }
2097 #endif /* WANT_HISTOGRAM */
2098 
2099 #ifdef WANT_DEMO
2100       demo_stream_interval(send_size);
2101 #endif
2102 
2103 #if defined(WANT_INTERVALS)
2104       INTERVALS_WAIT();
2105 #endif /* WANT_INTERVALS */
2106 
2107       /* now we want to move our pointer to the next position in the */
2108       /* data buffer...we may also want to wrap back to the "beginning" */
2109       /* of the bufferspace, so we will mod the number of messages sent */
2110       /* by the send width, and use that to calculate the offset to add */
2111       /* to the base pointer. */
2112       nummessages++;
2113       send_ring = send_ring->next;
2114       if (bytes_remaining) {
2115 	bytes_remaining -= send_size;
2116       }
2117     }
2118 
2119     /* The test is over. Flush the buffers to the remote end. We do a */
2120     /* graceful release to insure that all data has been taken by the */
2121     /* remote. */
2122 
2123     /* but first, if the verbosity is greater than 1, find-out what */
2124     /* the TCP maximum segment_size was (if possible) */
2125     if (verbosity > 1) {
2126       tcp_mss = -1;
2127       get_tcp_info(send_socket,&tcp_mss);
2128     }
2129 
2130     if (shutdown(send_socket,SHUT_WR) == SOCKET_ERROR && !times_up) {
2131       perror("netperf: cannot shutdown tcp stream socket");
2132       exit(1);
2133     }
2134 
2135     /* hang a recv() off the socket to block until the remote has */
2136     /* brought all the data up into the application. it will do a */
2137     /* shutdown to cause a FIN to be sent our way. We will assume that */
2138     /* any exit from the recv() call is good... raj 4/93 */
2139 
2140     recv(send_socket, send_ring->buffer_ptr, send_size, 0);
2141 
2142     /* this call will always give us the elapsed time for the test, and */
2143     /* will also store-away the necessaries for cpu utilization */
2144 
2145     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
2146 						/* measured and how */
2147 						/* long did we really */
2148 						/* run? */
2149 
2150     /* we are finished with the socket, so close it to prevent hitting */
2151     /* the limit on maximum open files. */
2152 
2153     close(send_socket);
2154 
2155 #if defined(WANT_INTERVALS)
2156 #ifdef WIN32
2157   stop_itimer();
2158 #endif
2159 #endif /* WANT_INTERVALS */
2160 
2161     if (!no_control) {
2162       /* Get the statistics from the remote end. The remote will have
2163 	 calculated service demand and all those interesting
2164 	 things. If it wasn't supposed to care, it will return obvious
2165 	 values. */
2166 
2167       recv_response();
2168       if (!netperf_response.content.serv_errno) {
2169 	if (debug)
2170 	  fprintf(where,
2171 		  "remote reporting results for %.2f seconds\n",
2172 		  tcp_stream_result->elapsed_time);
2173       }
2174       else {
2175 	Set_errno(netperf_response.content.serv_errno);
2176 	fprintf(where,
2177 		"netperf: remote error %d",
2178 		netperf_response.content.serv_errno);
2179 	perror("");
2180 	fflush(where);
2181 
2182 	exit(1);
2183       }
2184 
2185       /* We now calculate what our thruput was for the test. In the
2186 	 future, we may want to include a calculation of the thruput
2187 	 measured by the remote, but it should be the case that for a
2188 	 TCP stream test, that the two numbers should be *very*
2189 	 close... We calculate bytes_sent regardless of the way the
2190 	 test length was controlled.  If it was time, we needed to,
2191 	 and if it was by bytes, the user may have specified a number
2192 	 of bytes that wasn't a multiple of the send_size, so we
2193 	 really didn't send what he asked for ;-) */
2194 
2195       bytes_sent	= ntohd(tcp_stream_result->bytes_received);
2196     }
2197     else {
2198       bytes_sent = (double)local_bytes_sent;
2199     }
2200 
2201     thruput	= calc_thruput(bytes_sent);
2202 
2203     if (local_cpu_usage || remote_cpu_usage) {
2204       /* We must now do a little math for service demand and cpu */
2205       /* utilization for the system(s) */
2206       /* Of course, some of the information might be bogus because */
2207       /* there was no idle counter in the kernel(s). We need to make */
2208       /* a note of this for the user's benefit...*/
2209       if (local_cpu_usage) {
2210 
2211 	local_cpu_utilization	= calc_cpu_util(0.0);
2212 	local_service_demand	= calc_service_demand(bytes_sent,
2213 						      0.0,
2214 						      0.0,
2215 						      0);
2216       }
2217       else {
2218 	local_cpu_utilization	= (float) -1.0;
2219 	local_service_demand	= (float) -1.0;
2220       }
2221 
2222       if (remote_cpu_usage) {
2223 
2224 	remote_cpu_utilization	= tcp_stream_result->cpu_util;
2225 	remote_service_demand	= calc_service_demand(bytes_sent,
2226 						      0.0,
2227 						      remote_cpu_utilization,
2228 						      tcp_stream_result->num_cpus);
2229       }
2230       else {
2231 	remote_cpu_utilization = (float) -1.0;
2232 	remote_service_demand  = (float) -1.0;
2233       }
2234     }
2235     else {
2236       /* we were not measuring cpu, for the confidence stuff, we */
2237       /* should make it -1.0 */
2238       local_cpu_utilization	= (float) -1.0;
2239       local_service_demand	= (float) -1.0;
2240       remote_cpu_utilization = (float) -1.0;
2241       remote_service_demand  = (float) -1.0;
2242     }
2243 
2244     /* at this point, we want to calculate the confidence information. */
2245     /* if debugging is on, calculate_confidence will print-out the */
2246     /* parameters we pass it */
2247 
2248     calculate_confidence(confidence_iteration,
2249 			 elapsed_time,
2250 			 thruput,
2251 			 local_cpu_utilization,
2252 			 remote_cpu_utilization,
2253 			 local_service_demand,
2254 			 remote_service_demand);
2255 
2256 
2257     confidence_iteration++;
2258   }
2259 
2260   /* at this point, we have finished making all the runs that we */
2261   /* will be making. so, we should extract what the calcuated values */
2262   /* are for all the confidence stuff. we could make the values */
2263   /* global, but that seemed a little messy, and it did not seem worth */
2264   /* all the mucking with header files. so, we create a routine much */
2265   /* like calcualte_confidence, which just returns the mean values. */
2266   /* raj 11/94 */
2267 
2268   retrieve_confident_values(&elapsed_time,
2269 			    &thruput,
2270 			    &local_cpu_utilization,
2271 			    &remote_cpu_utilization,
2272 			    &local_service_demand,
2273 			    &remote_service_demand);
2274 
2275   /* We are now ready to print all the information. If the user */
2276   /* has specified zero-level verbosity, we will just print the */
2277   /* local service demand, or the remote service demand. If the */
2278   /* user has requested verbosity level 1, he will get the basic */
2279   /* "streamperf" numbers. If the user has specified a verbosity */
2280   /* of greater than 1, we will display a veritable plethora of */
2281   /* background information from outside of this block as it it */
2282   /* not cpu_measurement specific...  */
2283 
2284   if (confidence < 0) {
2285     /* we did not hit confidence, but were we asked to look for it? */
2286     if (iteration_max > 1) {
2287       display_confidence();
2288     }
2289   }
2290 
2291   if (local_cpu_usage || remote_cpu_usage) {
2292     local_cpu_method = format_cpu_method(cpu_method);
2293     remote_cpu_method = format_cpu_method(tcp_stream_result->cpu_method);
2294 
2295     switch (verbosity) {
2296     case 0:
2297       if (local_cpu_usage) {
2298 	fprintf(where,
2299 		cpu_fmt_0,
2300 		local_service_demand,
2301 		local_cpu_method,
2302 		((print_headers) ||
2303 		 (result_brand == NULL)) ? "" : result_brand);
2304       }
2305       else {
2306 	fprintf(where,
2307 		cpu_fmt_0,
2308 		remote_service_demand,
2309 		remote_cpu_method,
2310 		((print_headers) ||
2311 		 (result_brand == NULL)) ? "" : result_brand);
2312       }
2313       break;
2314     case 1:
2315     case 2:
2316       if (print_headers) {
2317 		fprintf(where,
2318 		cpu_title,
2319 		format_units(),
2320 		local_cpu_method,
2321 		remote_cpu_method);
2322       }
2323 
2324       fprintf(where,
2325 	      cpu_fmt_1,		/* the format string */
2326 	      rsr_size,		        /* remote recvbuf size */
2327 	      lss_size,		        /* local sendbuf size */
2328 	      send_size,		/* how large were the sends */
2329 	      elapsed_time,		/* how long was the test */
2330 	      thruput, 		        /* what was the xfer rate */
2331 	      local_cpu_utilization,	/* local cpu */
2332 	      remote_cpu_utilization,	/* remote cpu */
2333 	      local_service_demand,	/* local service demand */
2334 	      remote_service_demand,	/* remote service demand */
2335 	      ((print_headers) ||
2336 	       (result_brand == NULL)) ? "" : result_brand);
2337       break;
2338     }
2339   }
2340   else {
2341     /* The tester did not wish to measure service demand. */
2342 
2343     switch (verbosity) {
2344     case 0:
2345       fprintf(where,
2346 	      tput_fmt_0,
2347 	      thruput,
2348 	      ((print_headers) ||
2349 	       (result_brand == NULL)) ? "" : result_brand);
2350       break;
2351     case 1:
2352     case 2:
2353       if (print_headers) {
2354 		fprintf(where,tput_title,format_units());
2355       }
2356       fprintf(where,
2357 	      tput_fmt_1,		/* the format string */
2358 	      rsr_size, 		/* remote recvbuf size */
2359 	      lss_size, 		/* local sendbuf size */
2360 	      send_size,		/* how large were the sends */
2361 	      elapsed_time, 		/* how long did it take */
2362 	      thruput,                  /* how fast did it go */
2363 	      ((print_headers) ||
2364 	       (result_brand == NULL)) ? "" : result_brand);
2365       break;
2366     }
2367   }
2368 
2369   /* it would be a good thing to include information about some of the */
2370   /* other parameters that may have been set for this test, but at the */
2371   /* moment, I do not wish to figure-out all the  formatting, so I will */
2372   /* just put this comment here to help remind me that it is something */
2373   /* that should be done at a later time. */
2374 
2375   if (verbosity > 1) {
2376     /* The user wanted to know it all, so we will give it to him. */
2377     /* This information will include as much as we can find about */
2378     /* TCP statistics, the alignments of the sends and receives */
2379     /* and all that sort of rot... */
2380 
2381     /* this stuff needs to be worked-out in the presence of confidence */
2382     /* intervals and multiple iterations of the test... raj 11/94 */
2383 
2384     fprintf(where,
2385 	    ksink_fmt,
2386 	    "Bytes",
2387 	    "Bytes",
2388 	    "Bytes",
2389 	    local_send_align,
2390 	    remote_recv_align,
2391 	    local_send_offset,
2392 	    remote_recv_offset,
2393 	    bytes_sent,
2394 	    bytes_sent / (double)nummessages,
2395 	    nummessages,
2396 	    bytes_sent / (double)tcp_stream_result->recv_calls,
2397 	    tcp_stream_result->recv_calls);
2398     fprintf(where,
2399 	    ksink_fmt2,
2400 	    tcp_mss);
2401     fflush(where);
2402 #ifdef WANT_HISTOGRAM
2403     fprintf(where,"\n\nHistogram of time spent in send() call.\n");
2404     fflush(where);
2405     HIST_report(time_hist);
2406 #endif /* WANT_HISTOGRAM */
2407   }
2408 
2409 }
2410 
2411 
2412 
2413 /* This routine implements the netperf-side TCP unidirectional data
2414    transfer test (a.k.a. stream) for the sockets interface where the
2415    data flow is from the netserver to the netperf.  It receives its
2416    parameters via global variables from the shell and writes its
2417    output to the standard output. */
2418 
2419 
2420 void
send_tcp_maerts(char remote_host[])2421 send_tcp_maerts(char remote_host[])
2422 {
2423 
2424   char *tput_title = "\
2425 Recv   Send    Send                          \n\
2426 Socket Socket  Message  Elapsed              \n\
2427 Size   Size    Size     Time     Throughput  \n\
2428 bytes  bytes   bytes    secs.    %s/sec  \n\n";
2429 
2430   char *tput_fmt_0 =
2431     "%7.2f %s\n";
2432 
2433   char *tput_fmt_1 =
2434     "%6d %6d %6d    %-6.2f   %7.2f   %s\n";
2435 
2436   char *cpu_title = "\
2437 Recv   Send    Send                          Utilization       Service Demand\n\
2438 Socket Socket  Message  Elapsed              Recv     Send     Recv    Send\n\
2439 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
2440 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
2441 
2442   char *cpu_fmt_0 =
2443     "%6.3f %c %s\n";
2444 
2445   char *cpu_fmt_1 =
2446     "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f %s\n";
2447 
2448   char *ksink_fmt = "\n\
2449 Alignment      Offset         %-8.8s %-8.8s    Recvs   %-8.8s Sends\n\
2450 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
2451 Recv   Send    Recv   Send             Recv (avg)          Send (avg)\n\
2452 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
2453 
2454   char *ksink_fmt2 = "\n\
2455 Maximum\n\
2456 Segment\n\
2457 Size (bytes)\n\
2458 %6d\n";
2459 
2460 
2461   float			elapsed_time;
2462 
2463   /* what we want is to have a buffer space that is at least one */
2464   /* recv-size greater than our recv window. this will insure that we */
2465   /* are never trying to re-use a buffer that may still be in the hands */
2466   /* of the transport. This buffer will be malloc'd after we have found */
2467   /* the size of the local senc socket buffer. We will want to deal */
2468   /* with alignment and offset concerns as well. */
2469 
2470   struct ring_elt *recv_ring;
2471 
2472   int len;
2473   unsigned int nummessages = 0;
2474   SOCKET recv_socket;
2475   int bytes_remaining;
2476   int tcp_mss = -1;  /* possibly uninitialized on printf far below */
2477 
2478   /* with links like fddi, one can recv > 32 bits worth of bytes
2479      during a test... ;-) at some point, this should probably become a
2480      64bit integral type, but those are not entirely common yet.  of
2481      course, time passes and they do become common.
2482  */
2483   double	bytes_sent = 0.0;
2484 
2485 #if defined(WIN32) && (_MSC_VER < 1200)
2486   __int64 local_bytes_recvd = 0;
2487 #else
2488   unsigned long long local_bytes_recvd = 0;
2489 #endif
2490 
2491   float	local_cpu_utilization;
2492   float	local_service_demand;
2493   float	remote_cpu_utilization;
2494   float	remote_service_demand;
2495 
2496   double	thruput;
2497 
2498   struct addrinfo *remote_res;
2499   struct addrinfo *local_res;
2500 
2501   struct	tcp_maerts_request_struct	*tcp_maerts_request;
2502   struct	tcp_maerts_response_struct	*tcp_maerts_response;
2503   struct	tcp_maerts_results_struct	*tcp_maerts_result;
2504 
2505   tcp_maerts_request  =
2506     (struct tcp_maerts_request_struct *)netperf_request.content.test_specific_data;
2507   tcp_maerts_response =
2508     (struct tcp_maerts_response_struct *)netperf_response.content.test_specific_data;
2509   tcp_maerts_result   =
2510     (struct tcp_maerts_results_struct *)netperf_response.content.test_specific_data;
2511 
2512 #ifdef WANT_HISTOGRAM
2513   if (verbosity > 1) {
2514     time_hist = HIST_new();
2515   }
2516 #endif /* WANT_HISTOGRAM */
2517   /* since we are now disconnected from the code that established the */
2518   /* control socket, and since we want to be able to use different */
2519   /* protocols and such, we are passed the name of the remote host and */
2520   /* must turn that into the test specific addressing information. */
2521 
2522   complete_addrinfos(&remote_res,
2523 		     &local_res,
2524 		     remote_host,
2525 		     SOCK_STREAM,
2526 		     IPPROTO_TCP,
2527 		     0);
2528 
2529   if ( print_headers ) {
2530     print_top_test_header("TCP MAERTS TEST",local_res,remote_res);
2531   }
2532 
2533   recv_ring = NULL;
2534   confidence_iteration = 1;
2535   init_stat();
2536 
2537   /* we have a great-big while loop which controls the number of times */
2538   /* we run a particular test. this is for the calculation of a */
2539   /* confidence interval (I really should have stayed awake during */
2540   /* probstats :). If the user did not request confidence measurement */
2541   /* (no confidence is the default) then we will only go though the */
2542   /* loop once. the confidence stuff originates from the folks at IBM */
2543 
2544   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
2545 	 (confidence_iteration <= iteration_min)) {
2546 
2547     /* initialize a few counters. we have to remember that we might be */
2548     /* going through the loop more than once. */
2549 
2550     nummessages    =	0;
2551     bytes_sent     =	0.0;
2552     times_up       = 	0;
2553 
2554     /*set up the data socket                        */
2555     recv_socket = create_data_socket(local_res);
2556 
2557     if (recv_socket == INVALID_SOCKET){
2558       perror("netperf: send_tcp_maerts: tcp stream data socket");
2559       exit(1);
2560     }
2561 
2562     if (debug) {
2563       fprintf(where,"send_tcp_maerts: recv_socket obtained...\n");
2564     }
2565 
2566     /* at this point, we have either retrieved the socket buffer sizes, */
2567     /* or have tried to set them, so now, we may want to set the recv */
2568     /* size based on that (because the user either did not use a -m */
2569     /* option, or used one with an argument of 0). If the socket buffer */
2570     /* size is not available, we will set the recv size to 4KB - no */
2571     /* particular reason, just arbitrary... */
2572     if (recv_size == 0) {
2573       if (lsr_size > 0) {
2574 	recv_size = lsr_size;
2575       }
2576       else {
2577 	recv_size = 4096;
2578       }
2579     }
2580 
2581     /* set-up the data buffer ring with the requested alignment and offset. */
2582     /* note also that we have allocated a quantity */
2583     /* of memory that is at least one recv-size greater than our socket */
2584     /* buffer size. We want to be sure that there are at least two */
2585     /* buffers allocated - this can be a bit of a problem when the */
2586     /* recv_size is bigger than the socket size, so we must check... the */
2587     /* user may have wanted to explicitly set the "width" of our recv */
2588     /* buffers, we should respect that wish... */
2589     if (recv_width == 0) {
2590       recv_width = (lsr_size/recv_size) + 1;
2591       if (recv_width == 1) recv_width++;
2592     }
2593 
2594     if (recv_ring == NULL) {
2595       /* only allocate the recv ring once. this is a networking test, */
2596       /* not a memory allocation test. this way, we do not need a */
2597       /* deallocate_buffer_ring() routine, and I don't feel like */
2598       /* writing one anyway :) raj 11/94 */
2599       recv_ring = allocate_buffer_ring(recv_width,
2600 				       recv_size,
2601 				       local_recv_align,
2602 				       local_recv_offset);
2603     }
2604 
2605     /* If the user has requested cpu utilization measurements, we must */
2606     /* calibrate the cpu(s). We will perform this task within the tests */
2607     /* themselves. If the user has specified the cpu rate, then */
2608     /* calibrate_local_cpu will return rather quickly as it will have */
2609     /* nothing to do. If local_cpu_rate is zero, then we will go through */
2610     /* all the "normal" calibration stuff and return the rate back. */
2611 
2612     if (local_cpu_usage) {
2613       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
2614     }
2615 
2616     if (!no_control) {
2617       /* Tell the remote end to do a listen. The server alters the
2618 	 socket paramters on the other side at this point, hence the
2619 	 reason for all the values being passed in the setup
2620 	 message. If the user did not specify any of the parameters,
2621 	 they will be passed as 0, which will indicate to the remote
2622 	 that no changes beyond the system's default should be
2623 	 used. Alignment is the exception, it will default to 1, which
2624 	 will be no alignment alterations. */
2625 
2626       netperf_request.content.request_type	=	DO_TCP_MAERTS;
2627       tcp_maerts_request->send_buf_size	=	rss_size_req;
2628       tcp_maerts_request->recv_buf_size	=	rsr_size_req;
2629       tcp_maerts_request->send_size	=	send_size;
2630       tcp_maerts_request->no_delay	=	rem_nodelay;
2631       tcp_maerts_request->send_alignment	=	remote_send_align;
2632       tcp_maerts_request->send_offset	=	remote_send_offset;
2633       tcp_maerts_request->measure_cpu	=	remote_cpu_usage;
2634       tcp_maerts_request->cpu_rate	=	remote_cpu_rate;
2635       if (test_time) {
2636 	tcp_maerts_request->test_length	=	test_time;
2637       }
2638       else {
2639 	tcp_maerts_request->test_length	=	test_bytes;
2640       }
2641       tcp_maerts_request->so_rcvavoid	=	rem_rcvavoid;
2642       tcp_maerts_request->so_sndavoid	=	rem_sndavoid;
2643 #ifdef DIRTY
2644       tcp_maerts_request->dirty_count       =       rem_dirty_count;
2645       tcp_maerts_request->clean_count       =       rem_clean_count;
2646 #endif /* DIRTY */
2647       tcp_maerts_request->port            = atoi(remote_data_port);
2648       tcp_maerts_request->ipfamily        = af_to_nf(remote_res->ai_family);
2649       if (debug > 1) {
2650 	fprintf(where,
2651 		"netperf: send_tcp_maerts: requesting TCP maerts test\n");
2652       }
2653 
2654       send_request();
2655 
2656       /* The response from the remote will contain all of the relevant
2657 	 socket parameters for this test type. We will put them back
2658 	 into the variables here so they can be displayed if desired.
2659 	 The remote will have calibrated CPU if necessary, and will
2660 	 have done all the needed set-up we will have calibrated the
2661 	 cpu locally before sending the request, and will grab the
2662 	 counter value right after the connect returns. The remote
2663 	 will grab the counter right after the accept call. This saves
2664 	 the hassle of extra messages being sent for the TCP
2665 	 tests.  */
2666 
2667       recv_response();
2668 
2669       if (!netperf_response.content.serv_errno) {
2670 	if (debug)
2671 	  fprintf(where,"remote listen done.\n");
2672 	rsr_size	=	tcp_maerts_response->recv_buf_size;
2673 	rss_size	=	tcp_maerts_response->send_buf_size;
2674 	rem_nodelay     =	tcp_maerts_response->no_delay;
2675 	remote_cpu_usage=	tcp_maerts_response->measure_cpu;
2676 	remote_cpu_rate = tcp_maerts_response->cpu_rate;
2677 	send_size       = tcp_maerts_response->send_size;
2678 
2679 	/* we have to make sure that the server port number is in
2680 	 network order */
2681       set_port_number(remote_res,
2682 		      (short)tcp_maerts_response->data_port_number);
2683       rem_rcvavoid	= tcp_maerts_response->so_rcvavoid;
2684       rem_sndavoid	= tcp_maerts_response->so_sndavoid;
2685       }
2686       else {
2687 	Set_errno(netperf_response.content.serv_errno);
2688 	fprintf(where,
2689 		"netperf: remote error %d",
2690 		netperf_response.content.serv_errno);
2691 	perror("");
2692 	fflush(where);
2693 
2694 	exit(1);
2695       }
2696     }
2697 
2698 #ifdef WANT_DEMO
2699     demo_stream_setup(lsr_size,rss_size);
2700 #endif
2701 
2702     /*Connect up to the remote port on the data socket  */
2703     if (connect(recv_socket,
2704 		remote_res->ai_addr,
2705 		remote_res->ai_addrlen) == INVALID_SOCKET){
2706       perror("netperf: send_tcp_maerts: data socket connect failed");
2707       exit(1);
2708     }
2709 
2710 #ifdef WIN32
2711   /* this is used so the timer thread can close the socket out from */
2712   /* under us, which to date is the easiest/cleanest/least */
2713   /* Windows-specific way I can find to force the winsock calls to */
2714   /* return WSAEINTR with the test is over. anything that will run on */
2715   /* 95 and NT and is closer to what netperf expects from Unix signals */
2716   /* and such would be appreciated raj 1/96 */
2717   win_kludge_socket = recv_socket;
2718 #endif /* WIN32 */
2719 
2720     /* Data Socket set-up is finished. If there were problems, either */
2721     /* the connect would have failed, or the previous response would */
2722     /* have indicated a problem. I failed to see the value of the */
2723     /* extra  message after the accept on the remote. If it failed, */
2724     /* we'll see it here. If it didn't, we might as well start pumping */
2725     /* data. */
2726 
2727     /* Set-up the test end conditions. For a maerts test, they can be */
2728     /* either time or byte-count based. */
2729 
2730     if (test_time) {
2731       /* The user wanted to end the test after a period of time. */
2732       times_up = 0;
2733       bytes_remaining = 0;
2734       /* in previous revisions, we had the same code repeated throught */
2735       /* all the test suites. this was unnecessary, and meant more */
2736       /* work for me when I wanted to switch to POSIX signals, so I */
2737       /* have abstracted this out into a routine in netlib.c. if you */
2738       /* are experiencing signal problems, you might want to look */
2739       /* there. raj 11/94 */
2740       if (!no_control) {
2741 	/* this is a netperf to netserver test, netserver will close
2742 	   to tell us the test is over, so use PAD_TIME to avoid
2743 	   causing the netserver fits. */
2744 	start_timer(test_time + PAD_TIME);
2745       }
2746       else {
2747 	/* this is a netperf to data source test, no PAD_TIME */
2748 	start_timer(test_time);
2749       }
2750     }
2751     else {
2752       /* The tester wanted to recv a number of bytes. we don't do that
2753 	 in a TCP_MAERTS test. sorry. raj 2002-06-21 */
2754       printf("netperf: send_tcp_maerts: test must be timed\n");
2755       exit(1);
2756     }
2757 
2758     /* The cpu_start routine will grab the current time and possibly */
2759     /* value of the idle counter for later use in measuring cpu */
2760     /* utilization and/or service demand and thruput. */
2761 
2762     cpu_start(local_cpu_usage);
2763 
2764 #ifdef WANT_INTERVALS
2765     INTERVALS_INIT();
2766 #endif /* WANT_INTERVALS */
2767 
2768     /* before we start, initialize a few variables */
2769 
2770 #ifdef WANT_DEMO
2771     if (demo_mode) {
2772       demo_first_timestamp();
2773     }
2774 #endif
2775 
2776     /* the test will continue until we either get a zero-byte recv()
2777        on the socket or our failsafe timer expires. most of the time
2778        we trust that we get a zero-byte recieve from the socket. raj
2779        2002-06-21 */
2780 
2781 #ifdef WANT_HISTOGRAM
2782     if (verbosity > 1) {
2783       /* timestamp just before we go into recv and then again just
2784 	 after we come out raj 8/94 */
2785       /* but only if we are actually going to display a histogram. raj
2786 	 2006-02-07 */
2787       HIST_timestamp(&time_one);
2788     }
2789 #endif /* WANT_HISTOGRAM */
2790 
2791     while ((!times_up) && (len=recv(recv_socket,
2792 				    recv_ring->buffer_ptr,
2793 				    recv_size,
2794 				    0)) > 0 ) {
2795 
2796 #ifdef WANT_HISTOGRAM
2797       if (verbosity > 1) {
2798 	/* timestamp the exit from the recv call and update the histogram */
2799 	HIST_timestamp(&time_two);
2800 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
2801       }
2802 #endif /* WANT_HISTOGRAM */
2803 
2804 #ifdef DIRTY
2805       access_buffer(recv_ring->buffer_ptr,
2806 		    recv_size,
2807 		    loc_dirty_count,
2808 		    loc_clean_count);
2809 #endif /* DIRTY */
2810 
2811 #ifdef WANT_DEMO
2812       demo_stream_interval(len);
2813 #endif
2814 
2815 #ifdef WANT_INTERVALS
2816       INTERVALS_WAIT();
2817 #endif /* WANT_INTERVALS */
2818 
2819       /* now we want to move our pointer to the next position in the */
2820       /* data buffer...we may also want to wrap back to the "beginning" */
2821       /* of the bufferspace, so we will mod the number of messages sent */
2822       /* by the recv width, and use that to calculate the offset to add */
2823       /* to the base pointer. */
2824       nummessages++;
2825       recv_ring = recv_ring->next;
2826       if (bytes_remaining) {
2827 	bytes_remaining -= len;
2828       }
2829 
2830       local_bytes_recvd += len;
2831 
2832 #ifdef WANT_HISTOGRAM
2833       if (verbosity > 1) {
2834 	/* make sure we timestamp just before we go into recv  */
2835 	/* raj 2004-06-15 */
2836 	HIST_timestamp(&time_one);
2837       }
2838 #endif /* WANT_HISTOGRAM */
2839 
2840     }
2841 
2842     /* an EINTR is to be expected when this is a no_control test */
2843     if (((len < 0) || SOCKET_EINTR(len)) && (!no_control)) {
2844       perror("send_tcp_maerts: data recv error");
2845       printf("len was %d\n",len);
2846       exit(1);
2847     }
2848 
2849     /* if we get here, it must mean we had a recv return of 0 before
2850        the watchdog timer expired, or the watchdog timer expired and
2851        this was a no_control test */
2852 
2853     /* The test is over. Flush the buffers to the remote end. We do a
2854        graceful release to tell the  remote we have all the data. */
2855 
2856     /* but first, if the verbosity is greater than 1, find-out what */
2857     /* the TCP maximum segment_size was (if possible) */
2858     if (verbosity > 1) {
2859       tcp_mss = -1;
2860       get_tcp_info(recv_socket,&tcp_mss);
2861     }
2862 
2863     if (shutdown(recv_socket,SHUT_WR) == SOCKET_ERROR) {
2864       perror("netperf: cannot shutdown tcp maerts socket");
2865       exit(1);
2866     }
2867 
2868     stop_timer();
2869 
2870 #if defined(WANT_INTERVALS)
2871 #ifdef WIN32
2872     stop_itimer();
2873 #endif
2874 #endif /* WANT_INTERVALS */
2875 
2876     /* this call will always give us the local elapsed time for the
2877        test, and will also store-away the necessaries for cpu
2878        utilization */
2879 
2880     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
2881 						/* measured and how */
2882 						/* long did we really */
2883 						/* run? */
2884 
2885     /* we are finished with the socket, so close it to prevent hitting */
2886     /* the limit on maximum open files. */
2887 
2888     close(recv_socket);
2889 
2890     if (!no_control) {
2891       /* Get the statistics from the remote end. The remote will have
2892          calculated service demand and all those interesting
2893          things. If it wasn't supposed to care, it will return obvious
2894          values. */
2895 
2896       recv_response();
2897       if (!netperf_response.content.serv_errno) {
2898 	if (debug)
2899 	  fprintf(where,"remote results obtained\n");
2900       }
2901       else {
2902 	Set_errno(netperf_response.content.serv_errno);
2903 	fprintf(where,
2904 		"netperf: remote error %d",
2905 		netperf_response.content.serv_errno);
2906 	perror("");
2907 	fflush(where);
2908 
2909 	exit(1);
2910       }
2911 
2912       /* We now calculate what our thruput was for the test. In the
2913 	 future, we may want to include a calculation of the thruput
2914 	 measured by the remote, but it should be the case that for a
2915 	 TCP maerts test, that the two numbers should be *very*
2916 	 close... We calculate bytes_sent regardless of the way the
2917 	 test length was controlled.  If it was time, we needed to,
2918 	 and if it was by bytes, the user may have specified a number
2919 	 of bytes that wasn't a multiple of the recv_size, so we
2920 	 really didn't recv what he asked for ;-) */
2921 
2922       bytes_sent	= ntohd(tcp_maerts_result->bytes_sent);
2923     }
2924     else {
2925       bytes_sent = (double)local_bytes_recvd;
2926     }
2927 
2928 
2929     thruput	= calc_thruput(bytes_sent);
2930 
2931     if (local_cpu_usage || remote_cpu_usage) {
2932       /* We must now do a little math for service demand and cpu */
2933       /* utilization for the system(s) */
2934       /* Of course, some of the information might be bogus because */
2935       /* there was no idle counter in the kernel(s). We need to make */
2936       /* a note of this for the user's benefit...*/
2937       if (local_cpu_usage) {
2938 
2939 	local_cpu_utilization	= calc_cpu_util(0.0);
2940 	local_service_demand	= calc_service_demand(bytes_sent,
2941 						      0.0,
2942 						      0.0,
2943 						      0);
2944       }
2945       else {
2946 	local_cpu_utilization	= (float) -1.0;
2947 	local_service_demand	= (float) -1.0;
2948       }
2949 
2950       if (remote_cpu_usage) {
2951 
2952 	remote_cpu_utilization	= tcp_maerts_result->cpu_util;
2953 	remote_service_demand	= calc_service_demand(bytes_sent,
2954 						      0.0,
2955 						      remote_cpu_utilization,
2956 						      tcp_maerts_result->num_cpus);
2957       }
2958       else {
2959 	remote_cpu_utilization = (float) -1.0;
2960 	remote_service_demand  = (float) -1.0;
2961       }
2962     }
2963     else {
2964       /* we were not measuring cpu, for the confidence stuff, we */
2965       /* should make it -1.0 */
2966       local_cpu_utilization	= (float) -1.0;
2967       local_service_demand	= (float) -1.0;
2968       remote_cpu_utilization = (float) -1.0;
2969       remote_service_demand  = (float) -1.0;
2970     }
2971 
2972     /* at this point, we want to calculate the confidence information. */
2973     /* if debugging is on, calculate_confidence will print-out the */
2974     /* parameters we pass it */
2975 
2976     calculate_confidence(confidence_iteration,
2977 			 elapsed_time,
2978 			 thruput,
2979 			 local_cpu_utilization,
2980 			 remote_cpu_utilization,
2981 			 local_service_demand,
2982 			 remote_service_demand);
2983 
2984 
2985     confidence_iteration++;
2986   }
2987 
2988   /* at this point, we have finished making all the runs that we */
2989   /* will be making. so, we should extract what the calcuated values */
2990   /* are for all the confidence stuff. we could make the values */
2991   /* global, but that seemed a little messy, and it did not seem worth */
2992   /* all the mucking with header files. so, we create a routine much */
2993   /* like calcualte_confidence, which just returns the mean values. */
2994   /* raj 11/94 */
2995 
2996   retrieve_confident_values(&elapsed_time,
2997 			    &thruput,
2998 			    &local_cpu_utilization,
2999 			    &remote_cpu_utilization,
3000 			    &local_service_demand,
3001 			    &remote_service_demand);
3002 
3003   /* We are now ready to print all the information. If the user */
3004   /* has specified zero-level verbosity, we will just print the */
3005   /* local service demand, or the remote service demand. If the */
3006   /* user has requested verbosity level 1, he will get the basic */
3007   /* "streamperf" numbers. If the user has specified a verbosity */
3008   /* of greater than 1, we will display a veritable plethora of */
3009   /* background information from outside of this block as it it */
3010   /* not cpu_measurement specific...  */
3011 
3012   if (confidence < 0) {
3013     /* we did not hit confidence, but were we asked to look for it? */
3014     if (iteration_max > 1) {
3015       display_confidence();
3016     }
3017   }
3018 
3019   if (local_cpu_usage || remote_cpu_usage) {
3020     local_cpu_method = format_cpu_method(cpu_method);
3021     remote_cpu_method = format_cpu_method(tcp_maerts_result->cpu_method);
3022 
3023     switch (verbosity) {
3024     case 0:
3025       if (local_cpu_usage) {
3026 	fprintf(where,
3027 		cpu_fmt_0,
3028 		local_service_demand,
3029 		local_cpu_method,
3030 		((print_headers) ||
3031 		 (result_brand == NULL)) ? "" : result_brand);
3032       }
3033       else {
3034 	fprintf(where,
3035 		cpu_fmt_0,
3036 		remote_service_demand,
3037 		remote_cpu_method,
3038 		((print_headers) ||
3039 		 (result_brand == NULL)) ? "" : result_brand);
3040       }
3041       break;
3042     case 1:
3043     case 2:
3044       if (print_headers) {
3045 	fprintf(where,
3046 		cpu_title,
3047 		format_units(),
3048 		local_cpu_method,
3049 		remote_cpu_method);
3050       }
3051 
3052       fprintf(where,
3053 	      cpu_fmt_1,		/* the format string */
3054 	      rsr_size,		        /* remote recvbuf size */
3055 	      lss_size,		        /* local sendbuf size */
3056 	      send_size,		/* how large were the recvs */
3057 	      elapsed_time,		/* how long was the test */
3058 	      thruput, 		        /* what was the xfer rate */
3059 	      local_cpu_utilization,	/* local cpu */
3060 	      remote_cpu_utilization,	/* remote cpu */
3061 	      local_service_demand,	/* local service demand */
3062 	      remote_service_demand,	/* remote service demand */
3063 	      ((print_headers) ||
3064 	       (result_brand == NULL)) ? "" : result_brand);
3065       break;
3066     }
3067   }
3068   else {
3069     /* The tester did not wish to measure service demand. */
3070 
3071     switch (verbosity) {
3072     case 0:
3073       fprintf(where,
3074 	      tput_fmt_0,
3075 	      thruput,
3076 	      ((print_headers) ||
3077 	       (result_brand == NULL)) ? "" : result_brand);
3078       break;
3079     case 1:
3080     case 2:
3081       if (print_headers) {
3082 	fprintf(where,tput_title,format_units());
3083       }
3084       fprintf(where,
3085 	      tput_fmt_1,		/* the format string */
3086 	      lsr_size, 		/* local recvbuf size */
3087 	      rss_size, 		/* remot sendbuf size */
3088 	      send_size,		/* how large were the recvs */
3089 	      elapsed_time, 		/* how long did it take */
3090 	      thruput,                  /* how fast did it go */
3091 	      ((print_headers) ||
3092 	       (result_brand == NULL)) ? "" : result_brand);
3093       break;
3094     }
3095   }
3096 
3097   /* it would be a good thing to include information about some of the */
3098   /* other parameters that may have been set for this test, but at the */
3099   /* moment, I do not wish to figure-out all the  formatting, so I will */
3100   /* just put this comment here to help remind me that it is something */
3101   /* that should be done at a later time. */
3102 
3103   if (verbosity > 1) {
3104     /* The user wanted to know it all, so we will give it to him. */
3105     /* This information will include as much as we can find about */
3106     /* TCP statistics, the alignments of the sends and receives */
3107     /* and all that sort of rot... */
3108 
3109     /* this stuff needs to be worked-out in the presence of confidence */
3110     /* intervals and multiple iterations of the test... raj 11/94 */
3111 
3112     fprintf(where,
3113 	    ksink_fmt,
3114 	    "Bytes",
3115 	    "Bytes",
3116 	    "Bytes",
3117 	    local_recv_align,
3118 	    remote_recv_align,
3119 	    local_recv_offset,
3120 	    remote_recv_offset,
3121 	    bytes_sent,
3122 	    bytes_sent / (double)nummessages,
3123 	    nummessages,
3124 	    bytes_sent / (double)tcp_maerts_result->send_calls,
3125 	    tcp_maerts_result->send_calls);
3126     fprintf(where,
3127 	    ksink_fmt2,
3128 	    tcp_mss);
3129     fflush(where);
3130 #ifdef WANT_HISTOGRAM
3131     fprintf(where,"\n\nHistogram of time spent in recv() call.\n");
3132     fflush(where);
3133     HIST_report(time_hist);
3134 #endif /* WANT_HISTOGRAM */
3135   }
3136 
3137 }
3138 #endif /* WANT_MIGRATION */
3139 
3140 
3141 /* this routine implements the TCP_MSS test.  All it does is pretend
3142    to be a TCP_STREAM test and report the TCP_MSS for the data
3143    connection.  No actual data is transferred. raj 2007-11-07
3144 */
3145 void
send_tcp_mss(char remote_host[])3146 send_tcp_mss(char remote_host[])
3147 {
3148 
3149   char *mss_title = "\
3150 Maximum\n\
3151 Segment\n\
3152 Size (bytes)\n\n";
3153 
3154   char *mss_fmt_0 =
3155     "%d %s\n";
3156 
3157   SOCKET send_socket;
3158   int tcp_mss = -1;  /* possibly uninitialized on printf far below */
3159 
3160   struct addrinfo *remote_res;
3161   struct addrinfo *local_res;
3162 
3163   struct	tcp_stream_request_struct	*tcp_stream_request;
3164   struct	tcp_stream_response_struct	*tcp_stream_response;
3165   struct	tcp_stream_results_struct	*tcp_stream_result;
3166 
3167   tcp_stream_request  =
3168     (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
3169   tcp_stream_response =
3170     (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
3171   tcp_stream_result   =
3172     (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
3173 
3174   /* since we are now disconnected from the code that established the */
3175   /* control socket, and since we want to be able to use different */
3176   /* protocols and such, we are passed the name of the remote host and */
3177   /* must turn that into the test specific addressing information. */
3178 
3179   /* complete_addrinfos will either succede or exit the process */
3180   complete_addrinfos(&remote_res,
3181 		     &local_res,
3182 		     remote_host,
3183 		     SOCK_STREAM,
3184 		     IPPROTO_TCP,
3185 		     0);
3186 
3187   if ( print_headers ) {
3188     print_top_test_header("TCP MSS TEST",local_res,remote_res);
3189   }
3190 
3191   /*set up the data socket                        */
3192   send_socket = create_data_socket(local_res);
3193 
3194   if (send_socket == INVALID_SOCKET){
3195     perror("netperf: send_tcp_stream: tcp stream data socket");
3196     exit(1);
3197   }
3198 
3199   if (debug) {
3200     fprintf(where,"send_tcp_stream: send_socket obtained...\n");
3201   }
3202 
3203 
3204   if (!no_control) {
3205     /* Tell the remote end to do a listen. The server alters the
3206        socket paramters on the other side at this point, hence the
3207        reason for all the values being passed in the setup
3208        message. If the user did not specify any of the parameters,
3209        they will be passed as 0, which will indicate to the remote
3210        that no changes beyond the system's default should be
3211        used. Alignment is the exception, it will default to 1, which
3212        will be no alignment alterations. */
3213 
3214     netperf_request.content.request_type =	DO_TCP_STREAM;
3215     tcp_stream_request->send_buf_size	=	rss_size_req;
3216     tcp_stream_request->recv_buf_size	=	rsr_size_req;
3217     tcp_stream_request->receive_size	=	recv_size;
3218     tcp_stream_request->no_delay	=	rem_nodelay;
3219     tcp_stream_request->recv_alignment	=	remote_recv_align;
3220     tcp_stream_request->recv_offset	=	remote_recv_offset;
3221     tcp_stream_request->measure_cpu	=	remote_cpu_usage;
3222     tcp_stream_request->cpu_rate	=	remote_cpu_rate;
3223     if (test_time) {
3224       tcp_stream_request->test_length	=	test_time;
3225     }
3226     else {
3227       tcp_stream_request->test_length	=	test_bytes;
3228     }
3229     tcp_stream_request->so_rcvavoid	=	rem_rcvavoid;
3230     tcp_stream_request->so_sndavoid	=	rem_sndavoid;
3231 #ifdef DIRTY
3232     tcp_stream_request->dirty_count     =       rem_dirty_count;
3233     tcp_stream_request->clean_count     =       rem_clean_count;
3234 #endif /* DIRTY */
3235     tcp_stream_request->port            =    atoi(remote_data_port);
3236     tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
3237     if (debug > 1) {
3238       fprintf(where,
3239 	      "netperf: send_tcp_mss: requesting TCP stream test\n");
3240     }
3241 
3242     send_request();
3243 
3244     /* The response from the remote will contain all of the relevant
3245        socket parameters for this test type. We will put them back
3246        into the variables here so they can be displayed if desired.
3247        The remote will have calibrated CPU if necessary, and will
3248        have done all the needed set-up we will have calibrated the
3249        cpu locally before sending the request, and will grab the
3250        counter value right after the connect returns. The remote
3251        will grab the counter right after the accept call. This saves
3252        the hassle of extra messages being sent for the TCP
3253        tests.  */
3254 
3255     recv_response();
3256 
3257     if (!netperf_response.content.serv_errno) {
3258       if (debug)
3259 	fprintf(where,"remote listen done.\n");
3260       rsr_size	      =	tcp_stream_response->recv_buf_size;
3261       rss_size	      =	tcp_stream_response->send_buf_size;
3262       rem_nodelay     =	tcp_stream_response->no_delay;
3263       remote_cpu_usage=	tcp_stream_response->measure_cpu;
3264       remote_cpu_rate = tcp_stream_response->cpu_rate;
3265 
3266       /* we have to make sure that the server port number is in
3267 	 network order */
3268       set_port_number(remote_res,
3269 		      (short)tcp_stream_response->data_port_number);
3270 
3271       rem_rcvavoid	= tcp_stream_response->so_rcvavoid;
3272       rem_sndavoid	= tcp_stream_response->so_sndavoid;
3273     }
3274     else {
3275       Set_errno(netperf_response.content.serv_errno);
3276       fprintf(where,
3277 	      "netperf: remote error %d",
3278 	      netperf_response.content.serv_errno);
3279       perror("");
3280       fflush(where);
3281 
3282       exit(1);
3283     }
3284   }
3285 
3286   /*Connect up to the remote port on the data socket  */
3287   if (connect(send_socket,
3288 	      remote_res->ai_addr,
3289 	      remote_res->ai_addrlen) == INVALID_SOCKET){
3290     perror("netperf: send_tcp_mss: data socket connect failed");
3291     exit(1);
3292     }
3293 
3294 
3295   /* find-out what the TCP maximum segment_size was (if possible) */
3296   tcp_mss = -1;
3297   get_tcp_info(send_socket,&tcp_mss);
3298 
3299   /* just go ahead and close the socket, the remote should figure it
3300      out */
3301   close(send_socket);
3302 
3303   /* statistics? we don't need no stinking statistics */
3304 
3305 
3306     switch (verbosity) {
3307     case 0:
3308       fprintf(where,
3309 	      mss_fmt_0,
3310 	      tcp_mss,
3311 	      ((print_headers) ||
3312 	       (result_brand == NULL)) ? "" : result_brand);
3313       break;
3314     case 1:
3315     case 2:
3316       if (print_headers) {
3317 		fprintf(where,"%s",mss_title);
3318       }
3319       fprintf(where,
3320 	      mss_fmt_0,		/* the format string */
3321 	      tcp_mss,
3322 	      ((print_headers) ||
3323 	       (result_brand == NULL)) ? "" : result_brand);
3324       break;
3325     }
3326 
3327 
3328 }
3329 
3330 
3331 
3332 #ifdef HAVE_ICSC_EXS
3333 
3334 #include <sys/exs.h>
3335 
3336 
3337 /* This routine implements the TCP unidirectional data transfer test */
3338 /* (a.k.a. stream) for the sockets interface. It receives its */
3339 /* parameters via global variables from the shell and writes its */
3340 /* output to the standard output. */
3341 
3342 void
send_exs_tcp_stream(char remote_host[])3343 send_exs_tcp_stream(char remote_host[])
3344 {
3345 
3346     char *tput_title = "\
3347 Recv   Send    Send                          \n\
3348 Socket Socket  Message  Elapsed              \n\
3349 Size   Size    Size     Time     Throughput  \n\
3350 bytes  bytes   bytes    secs.    %s/sec  \n\n";
3351 
3352     char *tput_fmt_0 =
3353         "%7.2f\n";
3354 
3355     char *tput_fmt_1 =
3356         "%6d %6d %6d    %-6.2f   %7.2f   \n";
3357 
3358     char *cpu_title = "\
3359 Recv   Send    Send                          Utilization       Service Demand\n\
3360 Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
3361 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
3362 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
3363 
3364     char *cpu_fmt_0 =
3365         "%6.3f %c\n";
3366 
3367     char *cpu_fmt_1 =
3368         "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f\n";
3369 
3370     char *ksink_fmt = "\n\
3371 Alignment      Offset         %-8.8s %-8.8s    Sends   %-8.8s Recvs\n\
3372 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
3373 Send   Recv    Send   Recv             Send (avg)          Recv (avg)\n\
3374 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
3375 
3376     char *ksink_fmt2 = "\n\
3377 Maximum\n\
3378 Segment\n\
3379 Size (bytes)\n\
3380 %6d\n";
3381 
3382 
3383     float         elapsed_time;
3384 
3385     /* what we want is to have a buffer space that is at least one */
3386     /* send-size greater than our send window. this will insure that we */
3387     /* are never trying to re-use a buffer that may still be in the hands */
3388     /* of the transport. This buffer will be malloc'd after we have found */
3389     /* the size of the local senc socket buffer. We will want to deal */
3390     /* with alignment and offset concerns as well. */
3391 
3392     struct ring_elt *send_ring;
3393 
3394     int len;
3395     unsigned int nummessages = 0;
3396     SOCKET send_socket;
3397     int bytes_remaining;
3398     int tcp_mss = -1;  /* possibly uninitialized on printf far below */
3399 
3400     exs_mhandle_t exs_mhandle;
3401     exs_qhandle_t exs_qhandle;
3402 #define NETPERF_EXS_PENDING  16
3403     int exs_aio_pending;
3404     int exs_aio_eagain;
3405     int exs_aio_dequeued;
3406     int exs_aio_dequeuecnt;
3407     int exs_evtcnt;
3408 #define NETPERF_EXS_QSIZE    128
3409     exs_event_t exs_evtvec[NETPERF_EXS_QSIZE];
3410 
3411     /* with links like fddi, one can send > 32 bits worth of bytes */
3412     /* during a test... ;-) at some point, this should probably become a */
3413     /* 64bit integral type, but those are not entirely common yet */
3414 
3415     double   bytes_sent = 0.0;
3416 
3417     float   local_cpu_utilization;
3418     float   local_service_demand;
3419     float   remote_cpu_utilization;
3420     float   remote_service_demand;
3421 
3422     double   thruput;
3423 
3424     struct addrinfo *remote_res;
3425     struct addrinfo *local_res;
3426 
3427     struct   tcp_stream_request_struct   *tcp_stream_request;
3428     struct   tcp_stream_response_struct   *tcp_stream_response;
3429     struct   tcp_stream_results_struct   *tcp_stream_result;
3430 
3431     tcp_stream_request  =
3432         (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
3433     tcp_stream_response =
3434         (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
3435     tcp_stream_result   =
3436         (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
3437 
3438 #if 0 /* def WANT_HISTOGRAM */
3439     time_hist = HIST_new();
3440 #endif /* WANT_HISTOGRAM */
3441     /* since we are now disconnected from the code that established the */
3442     /* control socket, and since we want to be able to use different */
3443     /* protocols and such, we are passed the name of the remote host and */
3444     /* must turn that into the test specific addressing information. */
3445 
3446     /* complete_addrinfos will either succede or exit the process */
3447     complete_addrinfos(&remote_res,
3448                        &local_res,
3449                        remote_host,
3450                        SOCK_STREAM,
3451                        IPPROTO_TCP,
3452                        0);
3453 
3454     if ( print_headers ) {
3455         print_top_test_header("EXS TCP STREAM TEST",local_res,remote_res);
3456     }
3457 
3458     send_ring = NULL;
3459     confidence_iteration = 1;
3460     init_stat();
3461 
3462     /* initialize EXS API and create event queue */
3463     if (exs_init (EXS_VERSION) == -1) {
3464         perror ("netperf: send_exs_tcp_stream: exs_init failed");
3465         exit (1);
3466     }
3467 
3468     if ((exs_qhandle = exs_qcreate (NETPERF_EXS_QSIZE)) == EXS_QHANDLE_INVALID) {
3469         perror ("netperf: send_exs_tcp_stream: exs_qcreate failed");
3470         exit (1);
3471     }
3472     if (debug) {
3473         fprintf (where, "send_exs_tcp_stream: qhandle=%d\n", exs_qhandle);
3474     }
3475 
3476     /* we have a great-big while loop which controls the number of times */
3477     /* we run a particular test. this is for the calculation of a */
3478     /* confidence interval (I really should have stayed awake during */
3479     /* probstats :). If the user did not request confidence measurement */
3480     /* (no confidence is the default) then we will only go though the */
3481     /* loop once. the confidence stuff originates from the folks at IBM */
3482 
3483     while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
3484            (confidence_iteration <= iteration_min)) {
3485 
3486         /* initialize a few counters. we have to remember that we might be */
3487         /* going through the loop more than once. */
3488 
3489         nummessages    =   0;
3490         bytes_sent     =   0.0;
3491         times_up       =    0;
3492 
3493         /*set up the data socket                        */
3494         send_socket = create_data_socket(local_res);
3495 
3496         if (send_socket == INVALID_SOCKET){
3497             perror("netperf: send_tcp_stream: tcp stream data socket");
3498             exit(1);
3499         }
3500 
3501         if (debug) {
3502             fprintf(where,"send_tcp_stream: send_socket obtained...\n");
3503         }
3504 
3505         /* at this point, we have either retrieved the socket buffer sizes, */
3506         /* or have tried to set them, so now, we may want to set the send */
3507         /* size based on that (because the user either did not use a -m */
3508         /* option, or used one with an argument of 0). If the socket buffer */
3509         /* size is not available, we will set the send size to 4KB - no */
3510         /* particular reason, just arbitrary... */
3511         if (send_size == 0) {
3512             if (lss_size > 0) {
3513                 send_size = lss_size;
3514             }
3515             else {
3516                 send_size = 4096;
3517             }
3518         }
3519 
3520         /* set-up the data buffer ring with the requested alignment and offset. */
3521         /* note also that we have allocated a quantity */
3522         /* of memory that is at least one send-size greater than our socket */
3523         /* buffer size. We want to be sure that there are at least two */
3524         /* buffers allocated - this can be a bit of a problem when the */
3525         /* send_size is bigger than the socket size, so we must check... the */
3526         /* user may have wanted to explicitly set the "width" of our send */
3527         /* buffers, we should respect that wish... */
3528         if (send_width == 0) {
3529             send_width = (lss_size/send_size) + 1;
3530             if (send_width == 1) send_width++;
3531         }
3532 
3533         if (send_ring == NULL) {
3534             /* only allocate the send ring once. this is a networking test, */
3535             /* not a memory allocation test. this way, we do not need a */
3536             /* deallocate_buffer_ring() routine, and I don't feel like */
3537             /* writing one anyway :) raj 11/94 */
3538             send_ring = allocate_exs_buffer_ring(send_width,
3539                                                  send_size,
3540                                                  local_send_align,
3541                                                  local_send_offset,
3542                                                  &exs_mhandle);
3543         }
3544 
3545         /* If the user has requested cpu utilization measurements, we must */
3546         /* calibrate the cpu(s). We will perform this task within the tests */
3547         /* themselves. If the user has specified the cpu rate, then */
3548         /* calibrate_local_cpu will return rather quickly as it will have */
3549         /* nothing to do. If local_cpu_rate is zero, then we will go through */
3550         /* all the "normal" calibration stuff and return the rate back. */
3551 
3552         if (local_cpu_usage) {
3553             local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
3554         }
3555 
3556         /* Tell the remote end to do a listen. The server alters the socket */
3557         /* paramters on the other side at this point, hence the reason for */
3558         /* all the values being passed in the setup message. If the user did */
3559         /* not specify any of the parameters, they will be passed as 0, which */
3560         /* will indicate to the remote that no changes beyond the system's */
3561         /* default should be used. Alignment is the exception, it will */
3562         /* default to 1, which will be no alignment alterations. */
3563 
3564         netperf_request.content.request_type =   DO_TCP_STREAM;
3565         tcp_stream_request->send_buf_size   =   rss_size_req;
3566         tcp_stream_request->recv_buf_size   =   rsr_size_req;
3567         tcp_stream_request->receive_size   =   recv_size;
3568         tcp_stream_request->no_delay   =   rem_nodelay;
3569         tcp_stream_request->recv_alignment   =   remote_recv_align;
3570         tcp_stream_request->recv_offset   =   remote_recv_offset;
3571         tcp_stream_request->measure_cpu   =   remote_cpu_usage;
3572         tcp_stream_request->cpu_rate   =   remote_cpu_rate;
3573         if (test_time) {
3574             tcp_stream_request->test_length   =   test_time;
3575         }
3576         else {
3577             tcp_stream_request->test_length   =   test_bytes;
3578         }
3579         tcp_stream_request->so_rcvavoid   =   rem_rcvavoid;
3580         tcp_stream_request->so_sndavoid   =   rem_sndavoid;
3581 #ifdef DIRTY
3582         tcp_stream_request->dirty_count     =       rem_dirty_count;
3583         tcp_stream_request->clean_count     =       rem_clean_count;
3584 #endif /* DIRTY */
3585         tcp_stream_request->port            =    atoi(remote_data_port);
3586         tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
3587         if (debug > 1) {
3588             fprintf(where,
3589                     "netperf: send_tcp_stream: requesting TCP stream test\n");
3590         }
3591 
3592         send_request();
3593 
3594         /* The response from the remote will contain all of the relevant    */
3595         /* socket parameters for this test type. We will put them back into */
3596         /* the variables here so they can be displayed if desired.  The   */
3597         /* remote will have calibrated CPU if necessary, and will have done   */
3598         /* all the needed set-up we will have calibrated the cpu locally   */
3599         /* before sending the request, and will grab the counter value right*/
3600         /* after the connect returns. The remote will grab the counter right*/
3601         /* after the accept call. This saves the hassle of extra messages   */
3602         /* being sent for the TCP tests.               */
3603 
3604         recv_response();
3605 
3606         if (!netperf_response.content.serv_errno) {
3607             if (debug)
3608                 fprintf(where,"remote listen done.\n");
3609             rsr_size         =   tcp_stream_response->recv_buf_size;
3610             rss_size         =   tcp_stream_response->send_buf_size;
3611             rem_nodelay     =   tcp_stream_response->no_delay;
3612             remote_cpu_usage=   tcp_stream_response->measure_cpu;
3613             remote_cpu_rate = tcp_stream_response->cpu_rate;
3614 
3615             /* we have to make sure that the server port number is in */
3616             /* network order */
3617             set_port_number(remote_res,(short)tcp_stream_response->data_port_number);
3618 
3619             rem_rcvavoid   = tcp_stream_response->so_rcvavoid;
3620             rem_sndavoid   = tcp_stream_response->so_sndavoid;
3621         }
3622         else {
3623             Set_errno(netperf_response.content.serv_errno);
3624             fprintf(where,
3625                     "netperf: remote error %d",
3626                     netperf_response.content.serv_errno);
3627             perror("");
3628             fflush(where);
3629 
3630             exit(1);
3631         }
3632 
3633 #if 0 /* def WANT_DEMO */
3634         demo_stream_setup(lss_size,rsr_size);
3635 #endif
3636 
3637             /*Connect up to the remote port on the data socket  */
3638             if (connect(send_socket,
3639                         remote_res->ai_addr,
3640                         remote_res->ai_addrlen) == INVALID_SOCKET){
3641                 perror("netperf: send_tcp_stream: data socket connect failed");
3642                 exit(1);
3643             }
3644 
3645 #ifdef WIN32
3646   /* this is used so the timer thread can close the socket out from */
3647   /* under us, which to date is the easiest/cleanest/least */
3648   /* Windows-specific way I can find to force the winsock calls to */
3649   /* return WSAEINTR with the test is over. anything that will run on */
3650   /* 95 and NT and is closer to what netperf expects from Unix signals */
3651   /* and such would be appreciated raj 1/96 */
3652   win_kludge_socket = send_socket;
3653 #endif /* WIN32 */
3654 
3655         /* Data Socket set-up is finished. If there were problems, either */
3656         /* the connect would have failed, or the previous response would */
3657         /* have indicated a problem. I failed to see the value of the */
3658         /* extra  message after the accept on the remote. If it failed, */
3659         /* we'll see it here. If it didn't, we might as well start pumping */
3660         /* data. */
3661 
3662         /* Set-up the test end conditions. For a stream test, they can be */
3663         /* either time or byte-count based. */
3664 
3665         if (test_time) {
3666             /* The user wanted to end the test after a period of time. */
3667             times_up = 0;
3668             bytes_remaining = 0;
3669             /* in previous revisions, we had the same code repeated throught */
3670             /* all the test suites. this was unnecessary, and meant more */
3671             /* work for me when I wanted to switch to POSIX signals, so I */
3672             /* have abstracted this out into a routine in netlib.c. if you */
3673             /* are experiencing signal problems, you might want to look */
3674             /* there. raj 11/94 */
3675             start_timer(test_time);
3676         }
3677         else {
3678             /* The tester wanted to send a number of bytes. */
3679             bytes_remaining = test_bytes;
3680             times_up = 1;
3681         }
3682 
3683         /* The cpu_start routine will grab the current time and possibly */
3684         /* value of the idle counter for later use in measuring cpu */
3685         /* utilization and/or service demand and thruput. */
3686 
3687         cpu_start(local_cpu_usage);
3688 
3689 #if 0 /* def WANT_INTERVALS */
3690 	INTERVALS_INIT();
3691 #endif /* WANT_INTERVALS */
3692 
3693         /* before we start, initialize a few variables */
3694 
3695 #if 0 /* def WANT_DEMO */
3696         if (demo_mode) {
3697 	  demo_first_timestamp();
3698         }
3699 #endif
3700 
3701 
3702         /* We use an "OR" to control test execution. When the test is */
3703         /* controlled by time, the byte count check will always return false. */
3704         /* When the test is controlled by byte count, the time test will */
3705         /* always return false. When the test is finished, the whole */
3706         /* expression will go false and we will stop sending data. */
3707 
3708         exs_aio_pending = 0;
3709         exs_aio_eagain = 0;
3710         exs_aio_dequeuecnt = 0;
3711 
3712         while ((!times_up) || (bytes_remaining > 0)) {
3713 
3714 #ifdef DIRTY
3715 	  access_buffer(send_ring->buffer_ptr,
3716 			send_size,
3717 			loc_dirty_count,
3718 			loc_clean_count);
3719 #endif /* DIRTY */
3720 
3721 #if 0 /* def WANT_HISTOGRAM */
3722             /* timestamp just before we go into send and then again just after */
3723             /* we come out raj 8/94 */
3724             HIST_timestamp(&time_one);
3725 #endif /* WANT_HISTOGRAM */
3726 
3727 
3728             /* post up to NETPERF_EXS_PENDING I/Os  */
3729             while ((exs_aio_pending < NETPERF_EXS_PENDING) &&
3730                    (exs_send (send_socket, send_ring->buffer_ptr, send_size,
3731                               0, exs_qhandle, (exs_ahandle_t)-1, exs_mhandle) == 0)) {
3732                 exs_aio_pending++;
3733 
3734                 /* now we want to move our pointer to the next
3735 		   position in the data buffer...we may also want to
3736 		   wrap back to the "beginning" of the bufferspace, so
3737 		   we will mod the number of messages sent by the send
3738 		   width, and use that to calculate the offset to add
3739 		   to the base pointer. */
3740 
3741                 nummessages++;
3742                 send_ring = send_ring->next;
3743                 if (bytes_remaining) {
3744                     bytes_remaining -= send_size;
3745                 }
3746             }
3747 
3748             /* check exs_send result */
3749             if (exs_aio_pending < NETPERF_EXS_PENDING) {
3750                /* standard flow control case */
3751                 if (errno == EAGAIN)
3752                     exs_aio_eagain++;
3753                 /* case of times_up */
3754                 else if (errno == EINTR)
3755                     break;
3756                 /* strange, let's stop */
3757                 else {
3758                     perror ("netperf: exs_send error");
3759                     exit (1);
3760                 }
3761             }
3762 
3763             /* dequeue events with "threshold" on 1/2 posted */
3764             exs_aio_dequeued =
3765                 exs_qdequeue (exs_qhandle, exs_evtvec,
3766                               -(exs_aio_pending>>1), NULL);
3767             exs_aio_dequeuecnt++;
3768 
3769             /* check exs_dequeue result */
3770             if (exs_aio_dequeued < 0) {
3771                 /* case of times_up */
3772                 if (errno == EINTR)
3773                     break;
3774                 /* strange, let's stop */
3775                 else {
3776                     perror ("netperf: exs_send error");
3777                     exit (1);
3778                 }
3779             }
3780             /* update number of pending I/Os */
3781             else {
3782                 exs_aio_pending -= exs_aio_dequeued;
3783             }
3784 
3785 
3786 #if 0 /* def WANT_HISTOGRAM */
3787             /* timestamp the exit from the send call and update the histogram */
3788             HIST_timestamp(&time_two);
3789             HIST_add(time_hist,delta_micro(&time_one,&time_two));
3790 #endif /* WANT_HISTOGRAM */
3791 
3792 #if 0 /* def WANT_DEMO */
3793             demo_stream_interval(send_size);
3794 #endif
3795 
3796 #if 0 /* def WANT_INTERVALS */
3797 	    INTERVALS_WAIT();
3798 #endif /* WANT_INTERVALS */
3799 
3800         }
3801 
3802         /* Collect the last completion events */
3803         exs_aio_dequeued =
3804             exs_qdequeue (exs_qhandle, exs_evtvec, -exs_aio_pending, NULL);
3805         exs_aio_dequeuecnt++;
3806         /* check exs_dequeue result and update number of pending I/Os */
3807         if (exs_aio_dequeued < 0) {
3808             perror ("netperf: exs_send error");
3809             exit (1);
3810         }
3811         exs_aio_pending -= exs_aio_dequeued;
3812 
3813         /* Display some async I/O debug info */
3814         if (debug) {
3815             fprintf (where, "send_exs_tcp_stream: "
3816                      "aio sent=%d eagain=%d dequeue=%d pending=%d\n",
3817                      nummessages, exs_aio_eagain, exs_aio_dequeuecnt, exs_aio_pending);
3818         }
3819 
3820         /* The test is over. Flush the buffers to the remote end. We do a */
3821         /* graceful release to insure that all data has been taken by the */
3822         /* remote. */
3823 
3824         /* but first, if the verbosity is greater than 1, find-out what */
3825         /* the TCP maximum segment_size was (if possible) */
3826         if (verbosity > 1) {
3827             tcp_mss = -1;
3828             get_tcp_info(send_socket,&tcp_mss);
3829         }
3830 
3831         if (shutdown(send_socket,SHUT_WR) == SOCKET_ERROR) {
3832             perror("netperf: cannot shutdown tcp stream socket");
3833             exit(1);
3834         }
3835 
3836         /* hang a recv() off the socket to block until the remote has */
3837         /* brought all the data up into the application. it will do a */
3838         /* shutdown to cause a FIN to be sent our way. We will assume that */
3839         /* any exit from the recv() call is good... raj 4/93 */
3840 
3841         recv(send_socket, send_ring->buffer_ptr, send_size, 0);
3842 
3843         /* this call will always give us the elapsed time for the test, and */
3844         /* will also store-away the necessaries for cpu utilization */
3845 
3846         cpu_stop(local_cpu_usage,&elapsed_time);   /* was cpu being */
3847         /* measured and how */
3848         /* long did we really */
3849         /* run? */
3850 
3851         /* we are finished with the socket, so close it to prevent hitting */
3852         /* the limit on maximum open files. */
3853 
3854         close(send_socket);
3855 
3856         /* Get the statistics from the remote end. The remote will have */
3857         /* calculated service demand and all those interesting things. If it */
3858         /* wasn't supposed to care, it will return obvious values. */
3859 
3860         recv_response();
3861         if (!netperf_response.content.serv_errno) {
3862             if (debug)
3863                 fprintf(where,"remote results obtained\n");
3864         }
3865         else {
3866             Set_errno(netperf_response.content.serv_errno);
3867             fprintf(where,
3868                     "netperf: remote error %d",
3869                     netperf_response.content.serv_errno);
3870             perror("");
3871             fflush(where);
3872 
3873             exit(1);
3874         }
3875 
3876         /* We now calculate what our thruput was for the test. In the future, */
3877         /* we may want to include a calculation of the thruput measured by */
3878         /* the remote, but it should be the case that for a TCP stream test, */
3879         /* that the two numbers should be *very* close... We calculate */
3880         /* bytes_sent regardless of the way the test length was controlled. */
3881         /* If it was time, we needed to, and if it was by bytes, the user may */
3882         /* have specified a number of bytes that wasn't a multiple of the */
3883         /* send_size, so we really didn't send what he asked for ;-) */
3884 
3885         bytes_sent   = ntohd(tcp_stream_result->bytes_received);
3886 
3887         thruput   = calc_thruput(bytes_sent);
3888 
3889         if (local_cpu_usage || remote_cpu_usage) {
3890             /* We must now do a little math for service demand and cpu */
3891             /* utilization for the system(s) */
3892             /* Of course, some of the information might be bogus because */
3893             /* there was no idle counter in the kernel(s). We need to make */
3894             /* a note of this for the user's benefit...*/
3895             if (local_cpu_usage) {
3896 
3897                 local_cpu_utilization   = calc_cpu_util(0.0);
3898                 local_service_demand   = calc_service_demand(bytes_sent,
3899                                                              0.0,
3900                                                              0.0,
3901                                                              0);
3902             }
3903             else {
3904                 local_cpu_utilization   = (float) -1.0;
3905                 local_service_demand   = (float) -1.0;
3906             }
3907 
3908             if (remote_cpu_usage) {
3909 
3910                 remote_cpu_utilization   = tcp_stream_result->cpu_util;
3911                 remote_service_demand   = calc_service_demand(bytes_sent,
3912                                                               0.0,
3913                                                               remote_cpu_utilization,
3914                                                               tcp_stream_result->num_cpus);
3915             }
3916             else {
3917                 remote_cpu_utilization = (float) -1.0;
3918                 remote_service_demand  = (float) -1.0;
3919             }
3920         }
3921         else {
3922             /* we were not measuring cpu, for the confidence stuff, we */
3923             /* should make it -1.0 */
3924             local_cpu_utilization   = (float) -1.0;
3925             local_service_demand   = (float) -1.0;
3926             remote_cpu_utilization = (float) -1.0;
3927             remote_service_demand  = (float) -1.0;
3928         }
3929 
3930         /* at this point, we want to calculate the confidence information. */
3931         /* if debugging is on, calculate_confidence will print-out the */
3932         /* parameters we pass it */
3933 
3934         calculate_confidence(confidence_iteration,
3935                              elapsed_time,
3936                              thruput,
3937                              local_cpu_utilization,
3938                              remote_cpu_utilization,
3939                              local_service_demand,
3940                              remote_service_demand);
3941 
3942 
3943         confidence_iteration++;
3944     }
3945 
3946     /* at this point, we have finished making all the runs that we */
3947     /* will be making. so, we should extract what the calcuated values */
3948     /* are for all the confidence stuff. we could make the values */
3949     /* global, but that seemed a little messy, and it did not seem worth */
3950     /* all the mucking with header files. so, we create a routine much */
3951     /* like calcualte_confidence, which just returns the mean values. */
3952     /* raj 11/94 */
3953 
3954     retrieve_confident_values(&elapsed_time,
3955                               &thruput,
3956                               &local_cpu_utilization,
3957                               &remote_cpu_utilization,
3958                               &local_service_demand,
3959                               &remote_service_demand);
3960 
3961     /* We are now ready to print all the information. If the user */
3962     /* has specified zero-level verbosity, we will just print the */
3963     /* local service demand, or the remote service demand. If the */
3964     /* user has requested verbosity level 1, he will get the basic */
3965     /* "streamperf" numbers. If the user has specified a verbosity */
3966     /* of greater than 1, we will display a veritable plethora of */
3967     /* background information from outside of this block as it it */
3968     /* not cpu_measurement specific...  */
3969 
3970     if (confidence < 0) {
3971         /* we did not hit confidence, but were we asked to look for it? */
3972         if (iteration_max > 1) {
3973             display_confidence();
3974         }
3975     }
3976 
3977     if (local_cpu_usage || remote_cpu_usage) {
3978         local_cpu_method = format_cpu_method(cpu_method);
3979         remote_cpu_method = format_cpu_method(tcp_stream_result->cpu_method);
3980 
3981         switch (verbosity) {
3982             case 0:
3983                 if (local_cpu_usage) {
3984                     fprintf(where,
3985                             cpu_fmt_0,
3986                             local_service_demand,
3987                             local_cpu_method);
3988                 }
3989                 else {
3990                     fprintf(where,
3991                             cpu_fmt_0,
3992                             remote_service_demand,
3993                             remote_cpu_method);
3994                 }
3995                 break;
3996             case 1:
3997             case 2:
3998                 if (print_headers) {
3999                     fprintf(where,
4000                             cpu_title,
4001                             format_units(),
4002                             local_cpu_method,
4003                             remote_cpu_method);
4004                 }
4005 
4006                 fprintf(where,
4007                         cpu_fmt_1,      /* the format string */
4008                         rsr_size,              /* remote recvbuf size */
4009                         lss_size,              /* local sendbuf size */
4010                         send_size,      /* how large were the sends */
4011                         elapsed_time,      /* how long was the test */
4012                         thruput,               /* what was the xfer rate */
4013                         local_cpu_utilization,   /* local cpu */
4014                         remote_cpu_utilization,   /* remote cpu */
4015                         local_service_demand,   /* local service demand */
4016                         remote_service_demand);   /* remote service demand */
4017                 break;
4018         }
4019     }
4020     else {
4021         /* The tester did not wish to measure service demand. */
4022 
4023         switch (verbosity) {
4024             case 0:
4025                 fprintf(where,
4026                         tput_fmt_0,
4027                         thruput);
4028                 break;
4029             case 1:
4030             case 2:
4031                 if (print_headers) {
4032                     fprintf(where,tput_title,format_units());
4033                 }
4034                 fprintf(where,
4035                         tput_fmt_1,      /* the format string */
4036                         rsr_size,       /* remote recvbuf size */
4037                         lss_size,       /* local sendbuf size */
4038                         send_size,      /* how large were the sends */
4039                         elapsed_time,       /* how long did it take */
4040                         thruput);/* how fast did it go */
4041                 break;
4042         }
4043     }
4044 
4045     /* it would be a good thing to include information about some of the */
4046     /* other parameters that may have been set for this test, but at the */
4047     /* moment, I do not wish to figure-out all the  formatting, so I will */
4048     /* just put this comment here to help remind me that it is something */
4049     /* that should be done at a later time. */
4050 
4051     if (verbosity > 1) {
4052         /* The user wanted to know it all, so we will give it to him. */
4053         /* This information will include as much as we can find about */
4054         /* TCP statistics, the alignments of the sends and receives */
4055         /* and all that sort of rot... */
4056 
4057         /* this stuff needs to be worked-out in the presence of confidence */
4058         /* intervals and multiple iterations of the test... raj 11/94 */
4059 
4060         fprintf(where,
4061                 ksink_fmt,
4062                 "Bytes",
4063                 "Bytes",
4064                 "Bytes",
4065                 local_send_align,
4066                 remote_recv_align,
4067                 local_send_offset,
4068                 remote_recv_offset,
4069                 bytes_sent,
4070                 bytes_sent / (double)nummessages,
4071                 nummessages,
4072                 bytes_sent / (double)tcp_stream_result->recv_calls,
4073                 tcp_stream_result->recv_calls);
4074         fprintf(where,
4075                 ksink_fmt2,
4076                 tcp_mss);
4077         fflush(where);
4078 #if 0 /* def WANT_HISTOGRAM */
4079         fprintf(where,"\n\nHistogram of time spent in send() call.\n");
4080         fflush(where);
4081         HIST_report(time_hist);
4082 #endif /* WANT_HISTOGRAM */
4083     }
4084 
4085 }
4086 
4087 #endif /* HAVE_ICSC_EXS */
4088 
4089 
4090 
4091 #if defined(HAVE_SENDFILE)
4092 
4093 
4094 /* This routine implements the TCP unidirectional data transfer test
4095    (a.k.a. stream) for the sockets interface using the sendfile()
4096    system call - TCP_SENDFILE.  It receives its  parameters via global
4097    variables from the shell and writes its  output to the standard
4098    output. Basically,  this is the same test as the send_tcp_stream()
4099    logic and we even tell the remote to do a TCP_STREAM test since for
4100    all it knows, nothig is different. */
4101 
4102 void
sendfile_tcp_stream(remote_host)4103 sendfile_tcp_stream(remote_host)
4104      char	remote_host[];
4105 {
4106 
4107   char *tput_title = "\
4108 Recv   Send    Send                          \n\
4109 Socket Socket  Message  Elapsed              \n\
4110 Size   Size    Size     Time     Throughput  \n\
4111 bytes  bytes   bytes    secs.    %s/sec  \n\n";
4112 
4113   char *tput_fmt_0 =
4114     "%7.2f %s\n";
4115 
4116   char *tput_fmt_1 =
4117     "%6d %6d %6d    %-6.2f   %7.2f   %s\n";
4118 
4119   char *cpu_title = "\
4120 Recv   Send    Send                          Utilization       Service Demand\n\
4121 Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
4122 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
4123 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
4124 
4125   char *cpu_fmt_0 =
4126     "%6.3f %c %s\n";
4127   char *cpu_fmt_1 =
4128     "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f %s\n";
4129 
4130   char *ksink_fmt = "\n\
4131 Alignment      Offset         %-8.8s %-8.8s    Sends   %-8.8s Recvs\n\
4132 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
4133 Send   Recv    Send   Recv             Send (avg)          Recv (avg)\n\
4134 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
4135 
4136 char *ksink_fmt2 = "\n\
4137 Maximum\n\
4138 Segment\n\
4139 Size (bytes)\n\
4140 %6d\n";
4141 
4142   float			elapsed_time;
4143 
4144   /* what we want is to have a buffer space that is at least one */
4145   /* send-size greater than our send window. this will insure that we */
4146   /* are never trying to re-use a buffer that may still be in the hands */
4147   /* of the transport. This buffer will be malloc'd after we have found */
4148   /* the size of the local senc socket buffer. We will want to deal */
4149   /* with alignment and offset concerns as well. */
4150 
4151   struct ring_elt *send_ring;
4152 
4153   int len;
4154   unsigned int nummessages = 0;
4155   SOCKET send_socket;
4156   int bytes_remaining;
4157   int tcp_mss = -1;  /* possibly uninitialized on printf far below */
4158 
4159   /* with links like fddi, one can send > 32 bits worth of bytes */
4160   /* during a test... ;-) at some point, this should probably become a */
4161   /* 64bit integral type, but those are not entirely common yet */
4162   double	bytes_sent = 0.0;
4163 
4164   float	local_cpu_utilization;
4165   float	local_service_demand;
4166   float	remote_cpu_utilization;
4167   float	remote_service_demand;
4168 
4169   double	thruput;
4170 
4171   struct  addrinfo *remote_res;
4172   struct  addrinfo *local_res;
4173   struct	sockaddr_in	server;
4174 
4175 #if defined(__linux) || defined(__sun)
4176   off_t     scratch_offset;   /* the linux sendfile() call will update
4177 				 the offset variable, which is
4178 				 something we do _not_ want to happen
4179 				 to the value in the send_ring! so, we
4180 				 have to use a scratch variable. */
4181 #endif /* __linux  || defined(__sun) */
4182 #if defined (USE_OSX)
4183    off_t    scratch_len;  /* Darwin 9.x need a value-result parameter  */
4184 #endif
4185 #if defined (__sun)
4186    size_t  scratch_len;	/* the sun sendfilev() needs a place to
4187 			   tell us how many bytes were written,
4188 			   even though it also returns the value */
4189    sendfilevec_t sv;
4190 #endif /* __sun */
4191 
4192   struct	tcp_stream_request_struct	*tcp_stream_request;
4193   struct	tcp_stream_response_struct	*tcp_stream_response;
4194   struct	tcp_stream_results_struct	*tcp_stream_result;
4195 
4196   tcp_stream_request  =
4197     (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
4198   tcp_stream_response =
4199     (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
4200   tcp_stream_result   =
4201     (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
4202 
4203 #ifdef WANT_HISTOGRAM
4204   if (verbosity > 1) {
4205     time_hist = HIST_new();
4206   }
4207 #endif /* WANT_HISTOGRAM */
4208 
4209   /* since we are now disconnected from the code that established the */
4210   /* control socket, and since we want to be able to use different */
4211   /* protocols and such, we are passed the name of the remote host and */
4212   /* must turn that into the test specific addressing information. */
4213 
4214   bzero((char *)&server,
4215 	sizeof(server));
4216 
4217   complete_addrinfos(&remote_res,
4218 		     &local_res,
4219 		     remote_host,
4220 		     SOCK_STREAM,
4221 		     IPPROTO_TCP,
4222 		     0);
4223 
4224   if ( print_headers ) {
4225     /* we want to have some additional, interesting information in */
4226     /* the headers. we know some of it here, but not all, so we will */
4227     /* only print the test title here and will print the results */
4228     /* titles after the test is finished */
4229     print_top_test_header("TCP SENDFILE TEST",local_res,remote_res);
4230   }
4231 
4232   send_ring = NULL;
4233   confidence_iteration = 1;
4234   init_stat();
4235 
4236   /* we have a great-big while loop which controls the number of times */
4237   /* we run a particular test. this is for the calculation of a */
4238   /* confidence interval (I really should have stayed awake during */
4239   /* probstats :). If the user did not request confidence measurement */
4240   /* (no confidence is the default) then we will only go though the */
4241   /* loop once. the confidence stuff originates from the folks at IBM */
4242 
4243   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
4244 	 (confidence_iteration <= iteration_min)) {
4245 
4246     /* initialize a few counters. we have to remember that we might be */
4247     /* going through the loop more than once. */
4248 
4249     nummessages    =	0;
4250     bytes_sent     =	0.0;
4251     times_up       = 	0;
4252 
4253     /* set up the data socket */
4254     send_socket = create_data_socket(local_res);
4255 
4256     if (send_socket == INVALID_SOCKET){
4257       perror("netperf: sendfile_tcp_stream: tcp stream data socket");
4258       exit(1);
4259     }
4260 
4261     if (debug) {
4262       fprintf(where,"sendfile_tcp_stream: send_socket obtained...\n");
4263     }
4264 
4265 #if defined(TCP_CORK)
4266     /* should this even be here?!? */
4267     if (loc_tcpcork > 0) {
4268       /* the user wishes for us to set TCP_CORK on the socket */
4269       int one = 1;
4270       if (setsockopt(send_socket,
4271 		     getprotobyname("tcp")->p_proto,
4272 		     TCP_CORK,
4273 		     (char *)&one,
4274 		     sizeof(one)) == SOCKET_ERROR) {
4275 	perror("netperf: sendfile_tcp_stream: tcp_cork");
4276 	exit(1);
4277       }
4278       if (debug) {
4279 	fprintf(where,"sendfile_tcp_stream: tcp_cork...\n");
4280       }
4281     }
4282 
4283 #endif /* TCP_CORK */
4284 
4285     /* at this point, we have either retrieved the socket buffer sizes, */
4286     /* or have tried to set them, so now, we may want to set the send */
4287     /* size based on that (because the user either did not use a -m */
4288     /* option, or used one with an argument of 0). If the socket buffer */
4289     /* size is not available, we will set the send size to 4KB - no */
4290     /* particular reason, just arbitrary... */
4291 
4292     /*check for file size/ min file size here?  create file here/ back out???*/
4293 
4294     if (send_size == 0) {
4295       if (lss_size > 0) {
4296 	send_size = lss_size;
4297       }
4298       else {
4299 	send_size = 4096;
4300       }
4301     }
4302 
4303     /* set-up the data buffer ring with the requested alignment and
4304        offset. note also that we have allocated a quantity  of memory
4305        that is at least one send-size greater than our socket  buffer
4306        size. We want to be sure that there are at least two  buffers
4307        allocated - this can be a bit of a problem when the  send_size
4308        is bigger than the socket size, so we must check... the  user
4309        may have wanted to explicitly set the "width" of our send
4310        buffers, we should respect that wish... */
4311 
4312     /*sendring -> an offset index that will shift the starting point of the*/
4313     /*section of the file sent throughout the file*/
4314 
4315     if (send_width == 0) {
4316       send_width = (lss_size/send_size) + 1;
4317       if (send_width == 1) send_width++;
4318     }
4319 
4320     if (send_ring == NULL) {
4321 
4322       /* only allocate the send ring once. this is a networking test,
4323 	 not a memory allocation test. this way, we do not need a
4324 	 deallocate_buffer_ring() routine, and I don't feel like
4325 	 writing one anyway :) raj 11/94 */
4326 
4327       send_ring = alloc_sendfile_buf_ring(send_width,
4328 					  send_size,
4329 					  local_send_align,
4330 					  local_send_offset);
4331     }
4332 
4333     /* If the user has requested cpu utilization measurements, we must
4334        calibrate the cpu(s). We will perform this task within the
4335        tests  themselves. If the user has specified the cpu rate, then
4336        calibrate_local_cpu will return rather quickly as it will have
4337        nothing to do. If local_cpu_rate is zero, then we will go
4338        through  all the "normal" calibration stuff and return the rate
4339        back. */
4340 
4341     if (local_cpu_usage) {
4342       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
4343     }
4344 
4345     /* Tell the remote end to do a listen. The server alters the
4346        socket  paramters on the other side at this point, hence the
4347        reason for  all the values being passed in the setup
4348        message. If the user did  not specify any of the parameters,
4349        they will be passed as 0, which  will indicate to the remote
4350        that no changes beyond the system's  default should be
4351        used. Alignment is the exception, it will  default to 1, which
4352        will be no alignment alterations. */
4353 
4354     netperf_request.content.request_type =	DO_TCP_STREAM;
4355     tcp_stream_request->send_buf_size	=	rss_size_req;
4356     tcp_stream_request->recv_buf_size	=	rsr_size_req;
4357     tcp_stream_request->receive_size	=	recv_size;
4358     tcp_stream_request->no_delay	=	rem_nodelay;
4359     tcp_stream_request->recv_alignment	=	remote_recv_align;
4360     tcp_stream_request->recv_offset	=	remote_recv_offset;
4361     tcp_stream_request->measure_cpu	=	remote_cpu_usage;
4362     tcp_stream_request->cpu_rate	=	remote_cpu_rate;
4363 
4364     if (test_time) {
4365       tcp_stream_request->test_length	=	test_time;
4366     }
4367     else {
4368       tcp_stream_request->test_length	=	test_bytes;
4369     }
4370 
4371     tcp_stream_request->so_rcvavoid	=	rem_rcvavoid;
4372     tcp_stream_request->so_sndavoid	=	rem_sndavoid;
4373 
4374 #ifdef DIRTY
4375     tcp_stream_request->dirty_count       =       rem_dirty_count;
4376     tcp_stream_request->clean_count       =       rem_clean_count;
4377 #endif /* DIRTY */
4378     tcp_stream_request->port     = atoi(remote_data_port);
4379     tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
4380 
4381     if (debug > 1) {
4382       fprintf(where,
4383 	      "netperf: send_tcp_stream: requesting TCP stream test\n");
4384     }
4385 
4386     send_request();
4387 
4388     /* The response from the remote will contain all of the relevant
4389        socket parameters for this test type. We will put them back
4390        into the variables here so they can be displayed if desired.
4391        The remote will have calibrated CPU if necessary, and will have
4392        done all the needed set-up we will have calibrated the cpu
4393        locally before sending the request, and will grab the counter
4394        value right after the connect returns. The remote will grab the
4395        counter right after the accept call. This saves the hassle of
4396        extra messages being sent for the TCP tests.  */
4397 
4398     recv_response();
4399 
4400     if (!netperf_response.content.serv_errno) {
4401       if (debug)
4402 	fprintf(where,"remote listen done.\n");
4403       rsr_size	      =	tcp_stream_response->recv_buf_size;
4404       rss_size	      =	tcp_stream_response->send_buf_size;
4405       rem_nodelay     =	tcp_stream_response->no_delay;
4406       remote_cpu_usage=	tcp_stream_response->measure_cpu;
4407       remote_cpu_rate = tcp_stream_response->cpu_rate;
4408 
4409       /* we have to make sure that the server port number is in */
4410       /* network order */
4411       set_port_number(remote_res,(short)tcp_stream_response->data_port_number);
4412       rem_rcvavoid	= tcp_stream_response->so_rcvavoid;
4413       rem_sndavoid	= tcp_stream_response->so_sndavoid;
4414     }
4415     else {
4416       Set_errno(netperf_response.content.serv_errno);
4417       fprintf(where,
4418 	      "netperf: remote error %d",
4419 	      netperf_response.content.serv_errno);
4420       perror("");
4421       fflush(where);
4422 
4423       exit(1);
4424     }
4425 
4426 #ifdef WANT_DEMO
4427     demo_stream_setup(lss_size,rsr_size);
4428 #endif
4429 
4430     /*Connect up to the remote port on the data socket  */
4431     if (connect(send_socket,
4432 		remote_res->ai_addr,
4433 		remote_res->ai_addrlen) == INVALID_SOCKET){
4434       perror("netperf: send_tcp_stream: data socket connect failed");
4435       printf(" port: %d\n",ntohs(server.sin_port));
4436       exit(1);
4437     }
4438 
4439 #ifdef WIN32
4440   /* this is used so the timer thread can close the socket out from */
4441   /* under us, which to date is the easiest/cleanest/least */
4442   /* Windows-specific way I can find to force the winsock calls to */
4443   /* return WSAEINTR with the test is over. anything that will run on */
4444   /* 95 and NT and is closer to what netperf expects from Unix signals */
4445   /* and such would be appreciated raj 1/96 */
4446   win_kludge_socket = send_socket;
4447 #endif /* WIN32 */
4448 
4449     /* Data Socket set-up is finished. If there were problems, either
4450        the connect would have failed, or the previous response would
4451        have indicated a problem. I failed to see the value of the
4452        extra message after the accept on the remote. If it failed,
4453        we'll see it here. If it didn't, we might as well start pumping
4454        data. */
4455 
4456     /* Set-up the test end conditions. For a stream test, they can be */
4457     /* either time or byte-count based. */
4458 
4459     if (test_time) {
4460       /* The user wanted to end the test after a period of time. */
4461       times_up = 0;
4462       bytes_remaining = 0;
4463 
4464       /* in previous revisions, we had the same code repeated throught
4465          all the test suites. this was unnecessary, and meant more
4466          work for me when I wanted to switch to POSIX signals, so I
4467          have abstracted this out into a routine in netlib.c. if you
4468          are experiencing signal problems, you might want to look
4469          there. raj 11/94 */
4470 
4471       start_timer(test_time);
4472     }
4473     else {
4474       /* The tester wanted to send a number of bytes. */
4475       bytes_remaining = test_bytes;
4476       times_up = 1;
4477     }
4478 
4479     /* The cpu_start routine will grab the current time and possibly */
4480     /* value of the idle counter for later use in measuring cpu */
4481     /* utilization and/or service demand and thruput. */
4482 
4483     cpu_start(local_cpu_usage);
4484 
4485 #ifdef WANT_INTERVALS
4486     INTERVALS_INIT();
4487 #endif /* WANT_INTERVALS */
4488 
4489 
4490     /* before we start, initialize a few variables */
4491 
4492 #ifdef WANT_DEMO
4493     if (demo_mode) {
4494       demo_first_timestamp();
4495     }
4496 #endif
4497 
4498     /* We use an "OR" to control test execution. When the test is
4499        controlled by time, the byte count check will always return
4500        false. When the test is controlled by byte count, the time test
4501        will always return false. When the test is finished, the whole
4502        expression will go false and we will stop sending data. */
4503 
4504     while ((!times_up) || (bytes_remaining > 0)) {
4505 
4506       /* the sendfile_tcp_stream test does not support making the buffers
4507 	 dirty. 08/2000 */
4508 
4509 #ifdef WANT_HISTOGRAM
4510       if (verbosity > 1) {
4511 	/* timestamp just before we go into sendfile() and then again
4512          just after we come out raj 08/2000 */
4513 	/* but only if we are actually going to display a histogram */
4514 	HIST_timestamp(&time_one);
4515       }
4516 #endif /* WANT_HISTOGRAM */
4517 
4518       /* you can look at netlib.h for a description of the fields we
4519 	 are passing to sendfile(). 08/2000 */
4520       if (netperf_sendfile(send_socket, send_ring) != send_size) {
4521 	/* the test was interrupted, must be the end of test. the
4522 	   send_tcp_stream code has some WIN32 ifdefs that we do not
4523 	   need here. */
4524 	if ((len >=0) || SOCKET_EINTR(len)) {
4525 	  break;
4526 	}
4527 	perror("netperf: data send error: sendfile");
4528 	fprintf(stderr,
4529 		"len was %d send_size was %d\n",
4530 		len,
4531 		send_size);
4532 	fflush(stderr);
4533 	exit(1);
4534       }
4535 
4536 #ifdef WANT_HISTOGRAM
4537       if (verbosity > 1) {
4538 	/* timestamp the exit from the send call and update the
4539 	   histogram */
4540 
4541 	HIST_timestamp(&time_two);
4542 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
4543       }
4544 #endif /* WANT_HISTOGRAM */
4545 
4546 #ifdef WANT_DEMO
4547       demo_stream_interval(send_size);
4548 #endif
4549 
4550 #ifdef WANT_INTERVALS
4551       INTERVALS_WAIT();
4552 #endif /* WANT_INTERVALS */
4553 
4554       /* now we want to move our pointer to the next position in the */
4555       /* data buffer...we may also want to wrap back to the "beginning" */
4556       /* of the bufferspace, so we will mod the number of messages sent */
4557       /* by the send width, and use that to calculate the offset to add */
4558       /* to the base pointer. */
4559 
4560       nummessages++;
4561       send_ring = send_ring->next;
4562       if (bytes_remaining) {
4563 	bytes_remaining -= send_size;
4564       }
4565     }
4566 
4567     /* The test is over. Flush the buffers to the remote end. We do a
4568        graceful release to insure that all data has been taken by the
4569        remote. */
4570 
4571     /* but first, if the verbosity is greater than 1, find-out what */
4572     /* the TCP maximum segment_size was (if possible) */
4573     if (verbosity > 1) {
4574       tcp_mss = -1;
4575       get_tcp_info(send_socket,&tcp_mss);
4576     }
4577 
4578     if (shutdown(send_socket,SHUT_WR) == SOCKET_ERROR) {
4579       perror("netperf: cannot shutdown tcp stream socket");
4580       exit(1);
4581     }
4582 
4583     /* hang a recv() off the socket to block until the remote has */
4584     /* brought all the data up into the application. it will do a */
4585     /* shutdown to cause a FIN to be sent our way. We will assume that */
4586     /* any exit from the recv() call is good... raj 4/93 */
4587 
4588     /* since we are using sendfile() instead of send, we have no
4589        scratch buffer from the send_ring to use for the
4590        receive. however, since we "know" that the recv should be
4591        returning zero bytes (not that we are making the checks we
4592        should) we can pass the address of the flags field. raj 08/2000
4593     */
4594 
4595     recv(send_socket,
4596 	 &(send_ring->flags),
4597 	 sizeof(send_ring->flags),
4598 	 0);
4599 
4600     /* this call will always give us the elapsed time for the test, and */
4601     /* will also store-away the necessaries for cpu utilization */
4602 
4603     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
4604 						/* measured and how */
4605 						/* long did we really */
4606 						/* run? */
4607 
4608     /* we are finished with the socket, so close it to prevent hitting */
4609     /* the limit on maximum open files. */
4610 
4611     close(send_socket);
4612 
4613  #if defined(WANT_INTERVALS)
4614 #ifdef WIN32
4615     stop_itimer();
4616 #endif
4617 #endif /* WANT_INTERVALS */
4618 
4619    /* Get the statistics from the remote end. The remote will have */
4620     /* calculated service demand and all those interesting things. If it */
4621     /* wasn't supposed to care, it will return obvious values. */
4622 
4623     recv_response();
4624 
4625     if (!netperf_response.content.serv_errno) {
4626       if (debug)
4627 	fprintf(where,"remote results obtained\n");
4628     }
4629 
4630     else {
4631       Set_errno(netperf_response.content.serv_errno);
4632       fprintf(where,
4633 	      "netperf: remote error %d",
4634 	      netperf_response.content.serv_errno);
4635       perror("");
4636       fflush(where);
4637 
4638       exit(1);
4639     }
4640 
4641     /* We now calculate what our thruput was for the test. In the future, */
4642     /* we may want to include a calculation of the thruput measured by */
4643     /* the remote, but it should be the case that for a TCP stream test, */
4644     /* that the two numbers should be *very* close... We calculate */
4645     /* bytes_sent regardless of the way the test length was controlled. */
4646     /* If it was time, we needed to, and if it was by bytes, the user may */
4647     /* have specified a number of bytes that wasn't a multiple of the */
4648     /* send_size, so we really didn't send what he asked for ;-) */
4649 
4650     bytes_sent	= ntohd(tcp_stream_result->bytes_received);
4651 
4652     thruput	= calc_thruput(bytes_sent);
4653 
4654     if (local_cpu_usage || remote_cpu_usage) {
4655 
4656       /* We must now do a little math for service demand and cpu */
4657       /* utilization for the system(s) */
4658       /* Of course, some of the information might be bogus because */
4659       /* there was no idle counter in the kernel(s). We need to make */
4660       /* a note of this for the user's benefit...*/
4661       if (local_cpu_usage) {
4662 
4663 	local_cpu_utilization	= calc_cpu_util(0.0);
4664 	local_service_demand	= calc_service_demand(bytes_sent,
4665 						      0.0,
4666 						      0.0,
4667 						      0);
4668       }
4669       else {
4670 	local_cpu_utilization	= (float) -1.0;
4671 	local_service_demand	= (float) -1.0;
4672       }
4673 
4674       if (remote_cpu_usage) {
4675 
4676 	remote_cpu_utilization	= tcp_stream_result->cpu_util;
4677 	remote_service_demand	= calc_service_demand(bytes_sent,
4678 						      0.0,
4679 						      remote_cpu_utilization,
4680 						      tcp_stream_result->num_cpus);
4681       }
4682       else {
4683 	remote_cpu_utilization = (float) -1.0;
4684 	remote_service_demand  = (float) -1.0;
4685       }
4686     }
4687     else {
4688       /* we were not measuring cpu, for the confidence stuff, we */
4689       /* should make it -1.0 */
4690       local_cpu_utilization	= (float) -1.0;
4691       local_service_demand	= (float) -1.0;
4692       remote_cpu_utilization = (float) -1.0;
4693       remote_service_demand  = (float) -1.0;
4694     }
4695 
4696     /* at this point, we want to calculate the confidence information. */
4697     /* if debugging is on, calculate_confidence will print-out the */
4698     /* parameters we pass it */
4699 
4700     calculate_confidence(confidence_iteration,
4701 			 elapsed_time,
4702 			 thruput,
4703 			 local_cpu_utilization,
4704 			 remote_cpu_utilization,
4705 			 local_service_demand,
4706 			 remote_service_demand);
4707 
4708     confidence_iteration++;
4709   }
4710 
4711   /* at this point, we have finished making all the runs that we */
4712   /* will be making. so, we should extract what the calcuated values */
4713   /* are for all the confidence stuff. we could make the values */
4714   /* global, but that seemed a little messy, and it did not seem worth */
4715   /* all the mucking with header files. so, we create a routine much */
4716   /* like calcualte_confidence, which just returns the mean values. */
4717   /* raj 11/94 */
4718 
4719   retrieve_confident_values(&elapsed_time,
4720 			    &thruput,
4721 			    &local_cpu_utilization,
4722 			    &remote_cpu_utilization,
4723 			    &local_service_demand,
4724 			    &remote_service_demand);
4725 
4726   /* We are now ready to print all the information. If the user */
4727   /* has specified zero-level verbosity, we will just print the */
4728   /* local service demand, or the remote service demand. If the */
4729   /* user has requested verbosity level 1, he will get the basic */
4730   /* "streamperf" numbers. If the user has specified a verbosity */
4731   /* of greater than 1, we will display a veritable plethora of */
4732   /* background information from outside of this block as it it */
4733   /* not cpu_measurement specific...  */
4734 
4735   if (confidence < 0) {
4736     /* we did not hit confidence, but were we asked to look for it? */
4737     if (iteration_max > 1) {
4738       display_confidence();
4739     }
4740   }
4741 
4742   if (local_cpu_usage || remote_cpu_usage) {
4743     local_cpu_method = format_cpu_method(cpu_method);
4744     remote_cpu_method = format_cpu_method(tcp_stream_result->cpu_method);
4745 
4746     switch (verbosity) {
4747     case 0:
4748 
4749     if (local_cpu_usage) {
4750 	fprintf(where,
4751 		cpu_fmt_0,
4752 		local_service_demand,
4753 		local_cpu_method,
4754 		((print_headers) ||
4755 		 (result_brand == NULL)) ? "" : result_brand);
4756       }
4757 
4758       else {
4759 	fprintf(where,
4760 		cpu_fmt_0,
4761 		remote_service_demand,
4762 		remote_cpu_method,
4763 		((print_headers) ||
4764 		 (result_brand == NULL)) ? "" : result_brand);
4765       }
4766 
4767       break;
4768 
4769     case 1:
4770     case 2:
4771       if (print_headers) {
4772 	fprintf(where,
4773 		cpu_title,
4774 		format_units(),
4775 		local_cpu_method,
4776 		remote_cpu_method);
4777       }
4778 
4779       fprintf(where,
4780 	      cpu_fmt_1,		/* the format string */
4781 	      rsr_size,		        /* remote recvbuf size */
4782 	      lss_size,		        /* local sendbuf size */
4783 	      send_size,		/* how large were the sends */
4784 	      elapsed_time,		/* how long was the test */
4785 	      thruput, 		        /* what was the xfer rate */
4786 	      local_cpu_utilization,	/* local cpu */
4787 	      remote_cpu_utilization,	/* remote cpu */
4788 	      local_service_demand,	/* local service demand */
4789 	      remote_service_demand,	/* remote service demand */
4790 	      ((print_headers) ||
4791 	       (result_brand == NULL)) ? "" : result_brand);
4792       break;
4793     }
4794 
4795   }
4796 
4797   else {
4798     /* The tester did not wish to measure service demand. */
4799 
4800     switch (verbosity) {
4801 
4802     case 0:
4803 
4804       fprintf(where,
4805 	      tput_fmt_0,
4806 	      thruput,
4807 	      ((print_headers) ||
4808 	       (result_brand == NULL)) ? "" : result_brand);
4809       break;
4810 
4811     case 1:
4812     case 2:
4813 
4814       if (print_headers) {
4815 	fprintf(where,tput_title,format_units());
4816       }
4817 
4818       fprintf(where,
4819 	      tput_fmt_1,		/* the format string */
4820 	      rsr_size, 		/* remote recvbuf size */
4821 	      lss_size, 		/* local sendbuf size */
4822 	      send_size,		/* how large were the sends */
4823 	      elapsed_time, 		/* how long did it take */
4824 	      thruput,                  /* how fast did it go */
4825 	      ((print_headers) ||
4826 	       (result_brand == NULL)) ? "" : result_brand);
4827       break;
4828     }
4829   }
4830 
4831   /* it would be a good thing to include information about some of the */
4832   /* other parameters that may have been set for this test, but at the */
4833   /* moment, I do not wish to figure-out all the  formatting, so I will */
4834   /* just put this comment here to help remind me that it is something */
4835   /* that should be done at a later time. */
4836 
4837     if (verbosity > 1) {
4838 
4839     /* The user wanted to know it all, so we will give it to him. */
4840     /* This information will include as much as we can find about */
4841     /* TCP statistics, the alignments of the sends and receives */
4842     /* and all that sort of rot... */
4843 
4844     /* this stuff needs to be worked-out in the presence of confidence */
4845     /* intervals and multiple iterations of the test... raj 11/94 */
4846 
4847     fprintf(where,
4848 	    ksink_fmt,
4849 	    "Bytes",
4850 	    "Bytes",
4851 	    "Bytes",
4852 	    local_send_align,
4853 	    remote_recv_align,
4854 	    local_send_offset,
4855 	    remote_recv_offset,
4856 	    bytes_sent,
4857 	    bytes_sent / (double)nummessages,
4858 	    nummessages,
4859 	    bytes_sent / (double)tcp_stream_result->recv_calls,
4860 	    tcp_stream_result->recv_calls);
4861 
4862     fprintf(where,
4863 	    ksink_fmt2,
4864 	    tcp_mss);
4865 
4866     fflush(where);
4867 
4868 #ifdef WANT_HISTOGRAM
4869 
4870     fprintf(where,"\n\nHistogram of time spent in send() call.\n");
4871     fflush(where);
4872     HIST_report(time_hist);
4873 #endif /* WANT_HISTOGRAM */
4874   }
4875 }
4876 
4877 #endif /* HAVE_SENDFILE */
4878 
4879 /* This is the server-side routine for the tcp stream test. It is */
4880 /* implemented as one routine. I could break things-out somewhat, but */
4881 /* didn't feel it was necessary. */
4882 
4883 void
recv_tcp_stream()4884 recv_tcp_stream()
4885 {
4886 
4887   struct sockaddr_storage myaddr_in, peeraddr_in;
4888   SOCKET s_listen,s_data;
4889   netperf_socklen_t addrlen;
4890   int	len;
4891   unsigned int	receive_calls;
4892   float	elapsed_time;
4893   double   bytes_received;
4894 
4895   struct ring_elt *recv_ring;
4896 
4897   struct addrinfo *local_res;
4898   char local_name[BUFSIZ];
4899   char port_buffer[PORTBUFSIZE];
4900 
4901 #ifdef DO_SELECT
4902   fd_set readfds;
4903   struct timeval timeout;
4904 #endif /* DO_SELECT */
4905 
4906   struct	tcp_stream_request_struct	*tcp_stream_request;
4907   struct	tcp_stream_response_struct	*tcp_stream_response;
4908   struct	tcp_stream_results_struct	*tcp_stream_results;
4909 
4910 #ifdef DO_SELECT
4911   FD_ZERO(&readfds);
4912   timeout.tv_sec = 1;
4913   timeout.tv_usec = 0;
4914 #endif /* DO_SELECT */
4915 
4916   tcp_stream_request	=
4917     (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data;
4918   tcp_stream_response	=
4919     (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data;
4920   tcp_stream_results	=
4921     (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data;
4922 
4923   if (debug) {
4924     fprintf(where,"netserver: recv_tcp_stream: entered...\n");
4925     fflush(where);
4926   }
4927 
4928   /* We want to set-up the listen socket with all the desired */
4929   /* parameters and then let the initiator know that all is ready. If */
4930   /* socket size defaults are to be used, then the initiator will have */
4931   /* sent us 0's. If the socket sizes cannot be changed, then we will */
4932   /* send-back what they are. If that information cannot be determined, */
4933   /* then we send-back -1's for the sizes. If things go wrong for any */
4934   /* reason, we will drop back ten yards and punt. */
4935 
4936   /* If anything goes wrong, we want the remote to know about it. It */
4937   /* would be best if the error that the remote reports to the user is */
4938   /* the actual error we encountered, rather than some bogus unexpected */
4939   /* response type message. */
4940 
4941   if (debug) {
4942     fprintf(where,"recv_tcp_stream: setting the response type...\n");
4943     fflush(where);
4944   }
4945 
4946   netperf_response.content.response_type = TCP_STREAM_RESPONSE;
4947 
4948   if (debug) {
4949     fprintf(where,"recv_tcp_stream: the response type is set...\n");
4950     fflush(where);
4951   }
4952 
4953   /* We now alter the message_ptr variable to be at the desired */
4954   /* alignment with the desired offset. */
4955 
4956   if (debug) {
4957     fprintf(where,"recv_tcp_stream: requested alignment of %d\n",
4958 	    tcp_stream_request->recv_alignment);
4959     fflush(where);
4960   }
4961 
4962   /* create_data_socket expects to find some things in the global */
4963   /* variables, so set the globals based on the values in the request. */
4964   /* once the socket has been created, we will set the response values */
4965   /* based on the updated value of those globals. raj 7/94 */
4966   lss_size_req = tcp_stream_request->send_buf_size;
4967   lsr_size_req = tcp_stream_request->recv_buf_size;
4968   loc_nodelay  = tcp_stream_request->no_delay;
4969   loc_rcvavoid = tcp_stream_request->so_rcvavoid;
4970   loc_sndavoid = tcp_stream_request->so_sndavoid;
4971 
4972   set_hostname_and_port(local_name,
4973 			port_buffer,
4974 			nf_to_af(tcp_stream_request->ipfamily),
4975 			tcp_stream_request->port);
4976 
4977   local_res = complete_addrinfo(local_name,
4978 				local_name,
4979 				port_buffer,
4980 				nf_to_af(tcp_stream_request->ipfamily),
4981 				SOCK_STREAM,
4982 				IPPROTO_TCP,
4983 				0);
4984 
4985   s_listen = create_data_socket(local_res);
4986 
4987   if (s_listen == INVALID_SOCKET) {
4988     netperf_response.content.serv_errno = errno;
4989     send_response();
4990     exit(1);
4991   }
4992 
4993 #ifdef WIN32
4994   /* The test timer can fire during operations on the listening socket,
4995      so to make the start_timer below work we have to move
4996      it to close s_listen while we are blocked on accept. */
4997   win_kludge_socket2 = s_listen;
4998 #endif
4999 
5000   /* what sort of sizes did we end-up with? */
5001   if (tcp_stream_request->receive_size == 0) {
5002     if (lsr_size > 0) {
5003       recv_size = lsr_size;
5004     }
5005     else {
5006       recv_size = 4096;
5007     }
5008   }
5009   else {
5010     recv_size = tcp_stream_request->receive_size;
5011   }
5012 
5013   /* we want to set-up our recv_ring in a manner analagous to what we */
5014   /* do on the sending side. this is more for the sake of symmetry */
5015   /* than for the needs of say copy avoidance, but it might also be */
5016   /* more realistic - this way one could conceivably go with a */
5017   /* double-buffering scheme when taking the data an putting it into */
5018   /* the filesystem or something like that. raj 7/94 */
5019 
5020   if (recv_width == 0) {
5021     recv_width = (lsr_size/recv_size) + 1;
5022     if (recv_width == 1) recv_width++;
5023   }
5024 
5025   recv_ring = allocate_buffer_ring(recv_width,
5026 				   recv_size,
5027 				   tcp_stream_request->recv_alignment,
5028 				   tcp_stream_request->recv_offset);
5029 
5030   if (debug) {
5031     fprintf(where,"recv_tcp_stream: receive alignment and offset set...\n");
5032     fflush(where);
5033   }
5034 
5035   /* Now, let's set-up the socket to listen for connections */
5036   if (listen(s_listen, 5) == SOCKET_ERROR) {
5037     netperf_response.content.serv_errno = errno;
5038     close(s_listen);
5039     send_response();
5040 
5041     exit(1);
5042   }
5043 
5044 
5045   /* now get the port number assigned by the system  */
5046   addrlen = sizeof(myaddr_in);
5047   if (getsockname(s_listen,
5048 		  (struct sockaddr *)&myaddr_in,
5049 		  &addrlen) == SOCKET_ERROR){
5050     netperf_response.content.serv_errno = errno;
5051     close(s_listen);
5052     send_response();
5053 
5054     exit(1);
5055   }
5056 
5057   /* Now myaddr_in contains the port and the internet address this is */
5058   /* returned to the sender also implicitly telling the sender that the */
5059   /* socket buffer sizing has been done. */
5060 
5061   tcp_stream_response->data_port_number =
5062     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
5063   netperf_response.content.serv_errno   = 0;
5064 
5065   /* But wait, there's more. If the initiator wanted cpu measurements, */
5066   /* then we must call the calibrate routine, which will return the max */
5067   /* rate back to the initiator. If the CPU was not to be measured, or */
5068   /* something went wrong with the calibration, we will return a -1 to */
5069   /* the initiator. */
5070 
5071   tcp_stream_response->cpu_rate = (float)0.0; 	/* assume no cpu */
5072   if (tcp_stream_request->measure_cpu) {
5073     tcp_stream_response->measure_cpu = 1;
5074     tcp_stream_response->cpu_rate =
5075       calibrate_local_cpu(tcp_stream_request->cpu_rate);
5076   }
5077   else {
5078     tcp_stream_response->measure_cpu = 0;
5079   }
5080 
5081   /* before we send the response back to the initiator, pull some of */
5082   /* the socket parms from the globals */
5083   tcp_stream_response->send_buf_size = lss_size;
5084   tcp_stream_response->recv_buf_size = lsr_size;
5085   tcp_stream_response->no_delay = loc_nodelay;
5086   tcp_stream_response->so_rcvavoid = loc_rcvavoid;
5087   tcp_stream_response->so_sndavoid = loc_sndavoid;
5088   tcp_stream_response->receive_size = recv_size;
5089 
5090   send_response();
5091 
5092   addrlen = sizeof(peeraddr_in);
5093 
5094   if ((s_data=accept(s_listen,
5095 		     (struct sockaddr *)&peeraddr_in,
5096 		     &addrlen)) == INVALID_SOCKET) {
5097     /* Let's just punt. The remote will be given some information */
5098     close(s_listen);
5099     exit(1);
5100   }
5101 
5102 #ifdef WIN32
5103   /* this is used so the timer thread can close the socket out from */
5104   /* under us, which to date is the easiest/cleanest/least */
5105   /* Windows-specific way I can find to force the winsock calls to */
5106   /* return WSAEINTR with the test is over. anything that will run on */
5107   /* 95 and NT and is closer to what netperf expects from Unix signals */
5108   /* and such would be appreciated raj 1/96 */
5109   win_kludge_socket = s_data;
5110   win_kludge_socket2 = INVALID_SOCKET;
5111 #endif /* WIN32 */
5112 
5113   times_up = 0;
5114 
5115   start_timer(tcp_stream_request->test_length + PAD_TIME);
5116 
5117 #ifdef KLUDGE_SOCKET_OPTIONS
5118   /* this is for those systems which *INCORRECTLY* fail to pass */
5119   /* attributes across an accept() call. Including this goes against */
5120   /* my better judgement :( raj 11/95 */
5121 
5122   kludge_socket_options(s_data);
5123 
5124 #endif /* KLUDGE_SOCKET_OPTIONS */
5125 
5126   /* Now it's time to start receiving data on the connection. We will */
5127   /* first grab the apropriate counters and then start grabbing. */
5128 
5129   cpu_start(tcp_stream_request->measure_cpu);
5130 
5131   /* The loop will exit when the sender does a shutdown, which will */
5132   /* return a length of zero   */
5133 
5134   /* there used to be an #ifdef DIRTY call to access_buffer() here,
5135      but we have switched from accessing the buffer before the recv()
5136      call to accessing the buffer after the recv() call.  The
5137      accessing before was, IIRC, related to having dirty data when
5138      doing page-flipping copy avoidance. */
5139 
5140   bytes_received = 0;
5141   receive_calls  = 0;
5142 
5143   while (!times_up && ((len = recv(s_data, recv_ring->buffer_ptr, recv_size, 0)) != 0)) {
5144     if (len == SOCKET_ERROR ) {
5145       if (times_up) {
5146 	break;
5147       }
5148       netperf_response.content.serv_errno = errno;
5149       send_response();
5150       exit(1);
5151     }
5152     bytes_received += len;
5153     receive_calls++;
5154 
5155 #ifdef DIRTY
5156     /* we access the buffer after the recv() call now, rather than before */
5157     access_buffer(recv_ring->buffer_ptr,
5158 		  recv_size,
5159 		  tcp_stream_request->dirty_count,
5160 		  tcp_stream_request->clean_count);
5161 #endif /* DIRTY */
5162 
5163 
5164     /* move to the next buffer in the recv_ring */
5165     recv_ring = recv_ring->next;
5166 
5167 #ifdef PAUSE
5168     sleep(1);
5169 #endif /* PAUSE */
5170 
5171 #ifdef DO_SELECT
5172 	FD_SET(s_data,&readfds);
5173 	select(s_data+1,&readfds,NULL,NULL,&timeout);
5174 #endif /* DO_SELECT */
5175 
5176   }
5177 
5178   /* perform a shutdown to signal the sender that */
5179   /* we have received all the data sent. raj 4/93 */
5180 
5181   if (shutdown(s_data,SHUT_WR) == SOCKET_ERROR && !times_up) {
5182       netperf_response.content.serv_errno = errno;
5183       send_response();
5184       exit(1);
5185     }
5186 
5187   cpu_stop(tcp_stream_request->measure_cpu,&elapsed_time);
5188 
5189   /* send the results to the sender			*/
5190 
5191   if (debug) {
5192     fprintf(where,
5193 	    "recv_tcp_stream: got %g bytes\n",
5194 	    bytes_received);
5195     fprintf(where,
5196 	    "recv_tcp_stream: got %d recvs\n",
5197 	    receive_calls);
5198     fflush(where);
5199   }
5200 
5201   tcp_stream_results->bytes_received	= htond(bytes_received);
5202   tcp_stream_results->elapsed_time	= elapsed_time;
5203   tcp_stream_results->recv_calls	= receive_calls;
5204 
5205   tcp_stream_results->cpu_method = cpu_method;
5206   tcp_stream_results->num_cpus   = lib_num_loc_cpus;
5207 
5208   if (tcp_stream_request->measure_cpu) {
5209     tcp_stream_results->cpu_util	= calc_cpu_util(0.0);
5210   };
5211 
5212   if (debug) {
5213     fprintf(where,
5214 	    "recv_tcp_stream: test complete, sending results.\n");
5215     fprintf(where,
5216 	    "                 bytes_received %g receive_calls %d\n",
5217 	    bytes_received,
5218 	    receive_calls);
5219     fprintf(where,
5220 	    "                 len %d\n",
5221 	    len);
5222     fflush(where);
5223   }
5224 
5225   send_response();
5226 
5227   /* we are now done with the sockets */
5228   close(s_data);
5229   close(s_listen);
5230 
5231   }
5232 
5233 /* This is the server-side routine for the tcp maerts test. It is
5234    implemented as one routine. I could break things-out somewhat, but
5235    didn't feel it was necessary. */
5236 
5237 void
recv_tcp_maerts()5238 recv_tcp_maerts()
5239 {
5240 
5241   struct sockaddr_storage myaddr_in, peeraddr_in;
5242   struct addrinfo *local_res;
5243   char  local_name[BUFSIZ];
5244   char  port_buffer[PORTBUFSIZE];
5245 
5246   SOCKET	s_listen,s_data;
5247   netperf_socklen_t 	addrlen;
5248   int	len;
5249   unsigned int	send_calls;
5250   float	elapsed_time;
5251   double   bytes_sent = 0.0 ;
5252 
5253   struct ring_elt *send_ring;
5254 
5255   struct	tcp_maerts_request_struct	*tcp_maerts_request;
5256   struct	tcp_maerts_response_struct	*tcp_maerts_response;
5257   struct	tcp_maerts_results_struct	*tcp_maerts_results;
5258 
5259   tcp_maerts_request	=
5260     (struct tcp_maerts_request_struct *)netperf_request.content.test_specific_data;
5261   tcp_maerts_response	=
5262     (struct tcp_maerts_response_struct *)netperf_response.content.test_specific_data;
5263   tcp_maerts_results	=
5264     (struct tcp_maerts_results_struct *)netperf_response.content.test_specific_data;
5265 
5266   if (debug) {
5267     fprintf(where,"netserver: recv_tcp_maerts: entered...\n");
5268     fflush(where);
5269   }
5270 
5271   /* We want to set-up the listen socket with all the desired
5272      parameters and then let the initiator know that all is ready. If
5273      socket size defaults are to be used, then the initiator will have
5274      sent us 0's. If the socket sizes cannot be changed, then we will
5275      send-back what they are. If that information cannot be
5276      determined, then we send-back -1's for the sizes. If things go
5277      wrong for any reason, we will drop back ten yards and punt. */
5278 
5279   /* If anything goes wrong, we want the remote to know about it. It
5280      would be best if the error that the remote reports to the user is
5281      the actual error we encountered, rather than some bogus
5282      unexpected response type message. */
5283 
5284   if (debug) {
5285     fprintf(where,"recv_tcp_maerts: setting the response type...\n");
5286     fflush(where);
5287   }
5288 
5289   netperf_response.content.response_type = TCP_MAERTS_RESPONSE;
5290 
5291   if (debug) {
5292     fprintf(where,"recv_tcp_maerts: the response type is set...\n");
5293     fflush(where);
5294   }
5295 
5296   /* We now alter the message_ptr variable to be at the desired */
5297   /* alignment with the desired offset. */
5298 
5299   if (debug) {
5300     fprintf(where,"recv_tcp_maerts: requested alignment of %d\n",
5301 	    tcp_maerts_request->send_alignment);
5302     fflush(where);
5303   }
5304 
5305   /* Grab a socket to listen on, and then listen on it. */
5306 
5307   if (debug) {
5308     fprintf(where,"recv_tcp_maerts: grabbing a socket...\n");
5309     fflush(where);
5310   }
5311 
5312   /* create_data_socket expects to find some things in the global */
5313   /* variables, so set the globals based on the values in the request. */
5314   /* once the socket has been created, we will set the response values */
5315   /* based on the updated value of those globals. raj 7/94 */
5316   lss_size_req = tcp_maerts_request->send_buf_size;
5317   lsr_size_req = tcp_maerts_request->recv_buf_size;
5318   loc_nodelay = tcp_maerts_request->no_delay;
5319   loc_rcvavoid = tcp_maerts_request->so_rcvavoid;
5320   loc_sndavoid = tcp_maerts_request->so_sndavoid;
5321 
5322   set_hostname_and_port(local_name,
5323 			port_buffer,
5324 			nf_to_af(tcp_maerts_request->ipfamily),
5325 			tcp_maerts_request->port);
5326 
5327   local_res = complete_addrinfo(local_name,
5328 				local_name,
5329 				port_buffer,
5330 				nf_to_af(tcp_maerts_request->ipfamily),
5331 				SOCK_STREAM,
5332 				IPPROTO_TCP,
5333 				0);
5334 
5335   s_listen = create_data_socket(local_res);
5336 
5337   if (s_listen == INVALID_SOCKET) {
5338     netperf_response.content.serv_errno = errno;
5339     send_response();
5340     exit(1);
5341   }
5342 
5343 #ifdef WIN32
5344   /* The test timer can fire during operations on the listening socket,
5345      so to make the start_timer below work we have to move
5346      it to close s_listen while we are blocked on accept. */
5347   win_kludge_socket2 = s_listen;
5348 #endif
5349 
5350 
5351   /* what sort of sizes did we end-up with? */
5352   if (tcp_maerts_request->send_size == 0) {
5353     if (lss_size > 0) {
5354       send_size = lss_size;
5355     }
5356     else {
5357       send_size = 4096;
5358     }
5359   }
5360   else {
5361     send_size = tcp_maerts_request->send_size;
5362   }
5363 
5364   /* we want to set-up our recv_ring in a manner analagous to what we */
5365   /* do on the recving side. this is more for the sake of symmetry */
5366   /* than for the needs of say copy avoidance, but it might also be */
5367   /* more realistic - this way one could conceivably go with a */
5368   /* double-buffering scheme when taking the data an putting it into */
5369   /* the filesystem or something like that. raj 7/94 */
5370 
5371   if (send_width == 0) {
5372     send_width = (lsr_size/send_size) + 1;
5373     if (send_width == 1) send_width++;
5374   }
5375 
5376   send_ring = allocate_buffer_ring(send_width,
5377 				   send_size,
5378 				   tcp_maerts_request->send_alignment,
5379 				   tcp_maerts_request->send_offset);
5380 
5381   if (debug) {
5382     fprintf(where,"recv_tcp_maerts: receive alignment and offset set...\n");
5383     fflush(where);
5384   }
5385 
5386   /* Now, let's set-up the socket to listen for connections */
5387   if (listen(s_listen, 5) == SOCKET_ERROR) {
5388     netperf_response.content.serv_errno = errno;
5389     close(s_listen);
5390     send_response();
5391 
5392     exit(1);
5393   }
5394 
5395 
5396   /* now get the port number assigned by the system  */
5397   addrlen = sizeof(myaddr_in);
5398   if (getsockname(s_listen,
5399 		  (struct sockaddr *)&myaddr_in,
5400 		  &addrlen) == SOCKET_ERROR){
5401     netperf_response.content.serv_errno = errno;
5402     close(s_listen);
5403     send_response();
5404 
5405     exit(1);
5406   }
5407 
5408   /* Now myaddr_in contains the port and the internet address this is */
5409   /* returned to the sender also implicitly telling the sender that the */
5410   /* socket buffer sizing has been done. */
5411 
5412   tcp_maerts_response->data_port_number =
5413     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
5414   netperf_response.content.serv_errno   = 0;
5415 
5416   /* But wait, there's more. If the initiator wanted cpu measurements, */
5417   /* then we must call the calibrate routine, which will return the max */
5418   /* rate back to the initiator. If the CPU was not to be measured, or */
5419   /* something went wrong with the calibration, we will return a -1 to */
5420   /* the initiator. */
5421 
5422   tcp_maerts_response->cpu_rate = (float)0.0; 	/* assume no cpu */
5423   if (tcp_maerts_request->measure_cpu) {
5424     tcp_maerts_response->measure_cpu = 1;
5425     tcp_maerts_response->cpu_rate =
5426       calibrate_local_cpu(tcp_maerts_request->cpu_rate);
5427   }
5428   else {
5429     tcp_maerts_response->measure_cpu = 0;
5430   }
5431 
5432   /* before we send the response back to the initiator, pull some of */
5433   /* the socket parms from the globals */
5434   tcp_maerts_response->send_buf_size = lss_size;
5435   tcp_maerts_response->recv_buf_size = lsr_size;
5436   tcp_maerts_response->no_delay = loc_nodelay;
5437   tcp_maerts_response->so_rcvavoid = loc_rcvavoid;
5438   tcp_maerts_response->so_sndavoid = loc_sndavoid;
5439   tcp_maerts_response->send_size = send_size;
5440 
5441   send_response();
5442 
5443   addrlen = sizeof(peeraddr_in);
5444 
5445   /* we will start the timer before the accept() to be somewhat
5446      analagous to the starting of the timer before the connect() call
5447      in the TCP_STREAM test. raj 2002-06-21 */
5448 
5449   start_timer(tcp_maerts_request->test_length);
5450 
5451   /* Now it's time to start receiving data on the connection. We will
5452      first grab the apropriate counters and then start grabbing. */
5453 
5454   cpu_start(tcp_maerts_request->measure_cpu);
5455 
5456 
5457   if ((s_data=accept(s_listen,
5458 		     (struct sockaddr *)&peeraddr_in,
5459 		     &addrlen)) == INVALID_SOCKET) {
5460     /* Let's just punt. The remote will be given some information */
5461     close(s_listen);
5462     exit(1);
5463   }
5464 
5465 #ifdef WIN32
5466   /* this is used so the timer thread can close the socket out from */
5467   /* under us, which to date is the easiest/cleanest/least */
5468   /* Windows-specific way I can find to force the winsock calls to */
5469   /* return WSAEINTR with the test is over. anything that will run on */
5470   /* 95 and NT and is closer to what netperf expects from Unix signals */
5471   /* and such would be appreciated raj 1/96 */
5472   win_kludge_socket = s_data;
5473   win_kludge_socket2 = INVALID_SOCKET;
5474 #endif /* WIN32 */
5475 
5476 #ifdef KLUDGE_SOCKET_OPTIONS
5477 
5478   /* this is for those systems which *INCORRECTLY* fail to pass
5479      attributes across an accept() call. Including this goes against
5480      my better judgement :( raj 11/95 */
5481 
5482   kludge_socket_options(s_data);
5483 
5484 #endif /* KLUDGE_SOCKET_OPTIONS */
5485 
5486   /* The loop will exit when the sender does a shutdown, which will */
5487   /* return a length of zero   */
5488 
5489   bytes_sent = 0.0;
5490   send_calls  = 0;
5491 
5492   len = 0;   /* nt-lint; len is not initialized (printf far below) if
5493 		times_up initially true.*/
5494   times_up = 0; /* must remember to initialize this little beauty */
5495   while (!times_up) {
5496 
5497 #ifdef DIRTY
5498     /* we want to dirty some number of consecutive integers in the buffer */
5499     /* we are about to send. we may also want to bring some number of */
5500     /* them cleanly into the cache. The clean ones will follow any dirty */
5501     /* ones into the cache. */
5502 
5503   access_buffer(send_ring->buffer_ptr,
5504 		send_size,
5505 		tcp_maerts_request->dirty_count,
5506 		tcp_maerts_request->clean_count);
5507 
5508 #endif /* DIRTY */
5509 
5510     if((len=send(s_data,
5511 		 send_ring->buffer_ptr,
5512 		 send_size,
5513 		 0)) != send_size) {
5514 		if ((len >=0) || SOCKET_EINTR(len)) {
5515 	      /* the test was interrupted, must be the end of test */
5516 	      break;
5517 		}
5518       netperf_response.content.serv_errno = errno;
5519       send_response();
5520       exit(1);
5521     }
5522 
5523     bytes_sent += len;
5524     send_calls++;
5525 
5526     /* more to the next buffer in the send_ring */
5527     send_ring = send_ring->next;
5528 
5529   }
5530 
5531   /* perform a shutdown to signal the sender that */
5532   /* we have received all the data sent. raj 4/93 */
5533 
5534   if (shutdown(s_data,SHUT_WR) == SOCKET_ERROR) {
5535       netperf_response.content.serv_errno = errno;
5536       send_response();
5537       exit(1);
5538     }
5539 
5540   /* hang a recv() off the socket to block until the remote has
5541      brought all the data up into the application. it will do a
5542      shutdown to cause a FIN to be sent our way. We will assume that
5543      any exit from the recv() call is good... raj 4/93 */
5544 
5545   recv(s_data, send_ring->buffer_ptr, send_size, 0);
5546 
5547 
5548   cpu_stop(tcp_maerts_request->measure_cpu,&elapsed_time);
5549 
5550   /* send the results to the sender			*/
5551 
5552   if (debug) {
5553     fprintf(where,
5554 	    "recv_tcp_maerts: got %g bytes\n",
5555 	    bytes_sent);
5556     fprintf(where,
5557 	    "recv_tcp_maerts: got %d sends\n",
5558 	    send_calls);
5559     fflush(where);
5560   }
5561 
5562   tcp_maerts_results->bytes_sent	= htond(bytes_sent);
5563   tcp_maerts_results->elapsed_time	= elapsed_time;
5564   tcp_maerts_results->send_calls	= send_calls;
5565 
5566   if (tcp_maerts_request->measure_cpu) {
5567     tcp_maerts_results->cpu_util	= calc_cpu_util(0.0);
5568   };
5569 
5570   if (debug) {
5571     fprintf(where,
5572 	    "recv_tcp_maerts: test complete, sending results.\n");
5573     fprintf(where,
5574 	    "                 bytes_sent %g send_calls %d\n",
5575 	    bytes_sent,
5576 	    send_calls);
5577     fprintf(where,
5578 	    "                 len %d\n",
5579 	    len);
5580     fflush(where);
5581   }
5582 
5583   tcp_maerts_results->cpu_method = cpu_method;
5584   tcp_maerts_results->num_cpus   = lib_num_loc_cpus;
5585   send_response();
5586 
5587   /* we are now done with the sockets */
5588   close(s_data);
5589   close(s_listen);
5590 
5591   }
5592 
5593 
5594  /* this routine implements the sending (netperf) side of the TCP_RR */
5595  /* test. */
5596 #ifndef WANT_MIGRATION
5597 void
send_tcp_rr(char remote_host[])5598 send_tcp_rr(char remote_host[])
5599 {
5600 
5601   char *tput_title = "\
5602 Local /Remote\n\
5603 Socket Size   Request  Resp.   Elapsed  Trans.\n\
5604 Send   Recv   Size     Size    Time     Rate         \n\
5605 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
5606 
5607   char *tput_title_band = "\
5608 Local /Remote\n\
5609 Socket Size   Request  Resp.   Elapsed  \n\
5610 Send   Recv   Size     Size    Time     Throughput \n\
5611 bytes  Bytes  bytes    bytes   secs.    %s/sec   \n\n";
5612 
5613   char *tput_fmt_0 =
5614     "%7.2f %s\n";
5615 
5616   char *tput_fmt_1_line_1 = "\
5617 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   %s\n";
5618   char *tput_fmt_1_line_2 = "\
5619 %-6d %-6d\n";
5620 
5621   char *cpu_title = "\
5622 Local /Remote\n\
5623 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
5624 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
5625 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
5626 
5627   char *cpu_title_tput = "\
5628 Local /Remote\n\
5629 Socket Size   Request Resp.  Elapsed Tput     CPU    CPU    S.dem   S.dem\n\
5630 Send   Recv   Size    Size   Time    %-8.8s local  remote local   remote\n\
5631 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
5632 
5633   char *cpu_title_latency = "\
5634 Local /Remote\n\
5635 Socket Size   Request Resp.  Elapsed Latency  CPU    CPU    S.dem   S.dem\n\
5636 Send   Recv   Size    Size   Time    usecs    local  remote local   remote\n\
5637 bytes  bytes  bytes   bytes  secs.   per tran %% %c    %% %c    us/Tr   us/Tr\n\n";
5638 
5639   char *cpu_fmt_0 =
5640     "%6.3f %c %s\n";
5641 
5642   char *cpu_fmt_1_line_1 = "\
5643 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f  %-6.2f %-6.2f %-6.3f  %-6.3f %s\n";
5644 
5645   char *cpu_fmt_1_line_2 = "\
5646 %-6d %-6d\n";
5647 
5648   char *ksink_fmt = "\
5649 Alignment      Offset         RoundTrip  Trans    Throughput\n\
5650 Local  Remote  Local  Remote  Latency    Rate     %-8.8s/s\n\
5651 Send   Recv    Send   Recv    usec/Tran  per sec  Outbound   Inbound\n\
5652 %5d  %5d   %5d  %5d   %-6.3f   %-6.3f %-6.3f    %-6.3f\n";
5653 
5654 
5655   int			timed_out = 0;
5656   float			elapsed_time;
5657 
5658   int	len;
5659   char	*temp_message_ptr;
5660   int	nummessages;
5661   SOCKET	send_socket;
5662   int	trans_remaining;
5663   double	bytes_xferd;
5664 
5665   struct ring_elt *send_ring;
5666   struct ring_elt *recv_ring;
5667 
5668   int	rsp_bytes_left;
5669   int	rsp_bytes_recvd;
5670 
5671   float	local_cpu_utilization;
5672   float	local_service_demand;
5673   float	remote_cpu_utilization;
5674   float	remote_service_demand;
5675   double	thruput;
5676 
5677   struct addrinfo *local_res;
5678   struct addrinfo *remote_res;
5679 
5680   struct	tcp_rr_request_struct	*tcp_rr_request;
5681   struct	tcp_rr_response_struct	*tcp_rr_response;
5682   struct	tcp_rr_results_struct	*tcp_rr_result;
5683 
5684 #ifdef WANT_FIRST_BURST
5685 #define REQUEST_CWND_INITIAL 2
5686   /* "in the beginning..." the WANT_FIRST_BURST stuff was like both
5687      Unix and the state of New Jersey - both were simple an unspoiled.
5688      then it was realized that some stacks are quite picky about
5689      initial congestion windows and a non-trivial initial burst of
5690      requests would not be individual segments even with TCP_NODELAY
5691      set. so, we have to start tracking a poor-man's congestion window
5692      up here in window space because we want to try to make something
5693      happen that frankly, we cannot guarantee with the specification
5694      of TCP.  ain't that grand?-)  raj 2006-01-30 */
5695   int requests_outstanding = 0;
5696   int request_cwnd = REQUEST_CWND_INITIAL;  /* we ass-u-me that having
5697 					       three requests
5698 					       outstanding at the
5699 					       beginning of the test
5700 					       is ok with TCP stacks
5701 					       of interest. the first
5702 					       two will come from our
5703 					       first_burst loop, and
5704 					       the third from our
5705 					       regularly scheduled
5706 					       send */
5707 #endif
5708 
5709   tcp_rr_request =
5710     (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data;
5711   tcp_rr_response=
5712     (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data;
5713   tcp_rr_result	=
5714     (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data;
5715 
5716 #ifdef WANT_HISTOGRAM
5717   if (verbosity > 1) {
5718     time_hist = HIST_new();
5719   }
5720 #endif /* WANT_HISTOGRAM */
5721 
5722   /* since we are now disconnected from the code that established the */
5723   /* control socket, and since we want to be able to use different */
5724   /* protocols and such, we are passed the name of the remote host and */
5725   /* must turn that into the test specific addressing information. */
5726 
5727   complete_addrinfos(&remote_res,
5728 		     &local_res,
5729 		     remote_host,
5730 		     SOCK_STREAM,
5731 		     IPPROTO_TCP,
5732 		     0);
5733 
5734   if ( print_headers ) {
5735     print_top_test_header("TCP REQUEST/RESPONSE TEST",local_res,remote_res);
5736   }
5737 
5738   /* initialize a few counters */
5739 
5740   send_ring = NULL;
5741   recv_ring = NULL;
5742   confidence_iteration = 1;
5743   init_stat();
5744 
5745   /* we have a great-big while loop which controls the number of times */
5746   /* we run a particular test. this is for the calculation of a */
5747   /* confidence interval (I really should have stayed awake during */
5748   /* probstats :). If the user did not request confidence measurement */
5749   /* (no confidence is the default) then we will only go though the */
5750   /* loop once. the confidence stuff originates from the folks at IBM */
5751 
5752   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
5753 	 (confidence_iteration <= iteration_min)) {
5754 
5755     /* initialize a few counters. we have to remember that we might be */
5756     /* going through the loop more than once. */
5757 
5758     nummessages     = 0;
5759     bytes_xferd     = 0.0;
5760     times_up        = 0;
5761     timed_out       = 0;
5762     trans_remaining = 0;
5763 
5764 #ifdef WANT_FIRST_BURST
5765     /* we have to remember to reset the number of transactions
5766        outstanding and the "congestion window for each new
5767        iteration. raj 2006-01-31 */
5768     requests_outstanding = 0;
5769     request_cwnd = REQUEST_CWND_INITIAL;
5770 #endif
5771 
5772 
5773     /* set-up the data buffers with the requested alignment and offset. */
5774     /* since this is a request/response test, default the send_width and */
5775     /* recv_width to 1 and not two raj 7/94 */
5776 
5777     if (send_width == 0) send_width = 1;
5778     if (recv_width == 0) recv_width = 1;
5779 
5780     if (send_ring == NULL) {
5781       send_ring = allocate_buffer_ring(send_width,
5782 				       req_size,
5783 				       local_send_align,
5784 				       local_send_offset);
5785     }
5786 
5787     if (recv_ring == NULL) {
5788       recv_ring = allocate_buffer_ring(recv_width,
5789 				       rsp_size,
5790 				       local_recv_align,
5791 				       local_recv_offset);
5792     }
5793 
5794     /*set up the data socket                        */
5795     send_socket = create_data_socket(local_res);
5796 
5797     if (send_socket == INVALID_SOCKET){
5798       perror("netperf: send_tcp_rr: tcp stream data socket");
5799       exit(1);
5800     }
5801 
5802     if (debug) {
5803       fprintf(where,"send_tcp_rr: send_socket obtained...\n");
5804     }
5805 
5806     /* If the user has requested cpu utilization measurements, we must */
5807     /* calibrate the cpu(s). We will perform this task within the tests */
5808     /* themselves. If the user has specified the cpu rate, then */
5809     /* calibrate_local_cpu will return rather quickly as it will have */
5810     /* nothing to do. If local_cpu_rate is zero, then we will go through */
5811     /* all the "normal" calibration stuff and return the rate back.*/
5812 
5813     if (local_cpu_usage) {
5814       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
5815     }
5816 
5817     if (!no_control) {
5818       /* Tell the remote end to do a listen. The server alters the
5819 	 socket paramters on the other side at this point, hence the
5820 	 reason for all the values being passed in the setup
5821 	 message. If the user did not specify any of the parameters,
5822 	 they will be passed as 0, which will indicate to the remote
5823 	 that no changes beyond the system's default should be
5824 	 used. Alignment is the exception, it will default to 8, which
5825 	 will be no alignment alterations. */
5826 
5827       netperf_request.content.request_type	=	DO_TCP_RR;
5828       tcp_rr_request->recv_buf_size	=	rsr_size_req;
5829       tcp_rr_request->send_buf_size	=	rss_size_req;
5830       tcp_rr_request->recv_alignment    =	remote_recv_align;
5831       tcp_rr_request->recv_offset	=	remote_recv_offset;
5832       tcp_rr_request->send_alignment    =	remote_send_align;
5833       tcp_rr_request->send_offset	=	remote_send_offset;
5834       tcp_rr_request->request_size	=	req_size;
5835       tcp_rr_request->response_size	=	rsp_size;
5836       tcp_rr_request->no_delay	        =	rem_nodelay;
5837       tcp_rr_request->measure_cpu	=	remote_cpu_usage;
5838       tcp_rr_request->cpu_rate	        =	remote_cpu_rate;
5839       tcp_rr_request->so_rcvavoid	=	rem_rcvavoid;
5840       tcp_rr_request->so_sndavoid	=	rem_sndavoid;
5841       if (test_time) {
5842 	tcp_rr_request->test_length	=	test_time;
5843       }
5844       else {
5845 	tcp_rr_request->test_length	=	test_trans * -1;
5846       }
5847       tcp_rr_request->port              =      atoi(remote_data_port);
5848       tcp_rr_request->ipfamily = af_to_nf(remote_res->ai_family);
5849 
5850       if (debug > 1) {
5851 	fprintf(where,"netperf: send_tcp_rr: requesting TCP rr test\n");
5852       }
5853 
5854       send_request();
5855 
5856       /* The response from the remote will contain all of the relevant
5857 	 socket parameters for this test type. We will put them back
5858 	 into the variables here so they can be displayed if desired.
5859 	 The remote will have calibrated CPU if necessary, and will
5860 	 have done all the needed set-up we will have calibrated the
5861 	 cpu locally before sending the request, and will grab the
5862 	 counter value right after the connect returns. The remote
5863 	 will grab the counter right after the accept call. This saves
5864 	 the hassle of extra messages being sent for the TCP
5865 	 tests.  */
5866 
5867       recv_response();
5868 
5869       if (!netperf_response.content.serv_errno) {
5870 	if (debug)
5871 	  fprintf(where,"remote listen done.\n");
5872 	rsr_size          = tcp_rr_response->recv_buf_size;
5873 	rss_size          = tcp_rr_response->send_buf_size;
5874 	rem_nodelay       = tcp_rr_response->no_delay;
5875 	remote_cpu_usage  = tcp_rr_response->measure_cpu;
5876 	remote_cpu_rate   = tcp_rr_response->cpu_rate;
5877 	/* make sure that port numbers are in network order */
5878 	set_port_number(remote_res,(short)tcp_rr_response->data_port_number);
5879       }
5880       else {
5881 	Set_errno(netperf_response.content.serv_errno);
5882 	fprintf(where,
5883 		"netperf: remote error %d",
5884 		netperf_response.content.serv_errno);
5885 	perror("");
5886 	fflush(where);
5887 
5888 	exit(1);
5889       }
5890     }
5891 
5892 #ifdef WANT_DEMO
5893     demo_rr_setup(1000);
5894 #endif
5895 
5896     /*Connect up to the remote port on the data socket  */
5897     if (connect(send_socket,
5898 		remote_res->ai_addr,
5899 		remote_res->ai_addrlen) == INVALID_SOCKET){
5900       perror("netperf: data socket connect failed");
5901 
5902       exit(1);
5903     }
5904 
5905 #ifdef WIN32
5906     /* this is used so the timer thread can close the socket out from */
5907     /* under us, which to date is the easiest/cleanest/least */
5908     /* Windows-specific way I can find to force the winsock calls to */
5909     /* return WSAEINTR with the test is over. anything that will run on */
5910     /* 95 and NT and is closer to what netperf expects from Unix signals */
5911     /* and such would be appreciated raj 1/96 */
5912     win_kludge_socket = send_socket;
5913 #endif /* WIN32 */
5914 
5915     /* Data Socket set-up is finished. If there were problems, either the */
5916     /* connect would have failed, or the previous response would have */
5917     /* indicated a problem. I failed to see the value of the extra */
5918     /* message after the accept on the remote. If it failed, we'll see it */
5919     /* here. If it didn't, we might as well start pumping data. */
5920 
5921     /* Set-up the test end conditions. For a request/response test, they */
5922     /* can be either time or transaction based. */
5923 
5924     if (test_time) {
5925       /* The user wanted to end the test after a period of time. */
5926       times_up = 0;
5927       trans_remaining = 0;
5928       start_timer(test_time);
5929     }
5930     else {
5931       /* The tester wanted to send a number of bytes. */
5932       trans_remaining = test_bytes;
5933       times_up = 1;
5934     }
5935 
5936     /* The cpu_start routine will grab the current time and possibly */
5937     /* value of the idle counter for later use in measuring cpu */
5938     /* utilization and/or service demand and thruput. */
5939 
5940     cpu_start(local_cpu_usage);
5941 
5942 #ifdef WANT_INTERVALS
5943     INTERVALS_INIT();
5944 #endif /* WANT_INTERVALS */
5945 
5946     /* We use an "OR" to control test execution. When the test is */
5947     /* controlled by time, the byte count check will always return false. */
5948     /* When the test is controlled by byte count, the time test will */
5949     /* always return false. When the test is finished, the whole */
5950     /* expression will go false and we will stop sending data. I think I */
5951     /* just arbitrarily decrement trans_remaining for the timed test, but */
5952     /* will not do that just yet... One other question is whether or not */
5953     /* the send buffer and the receive buffer should be the same buffer. */
5954 
5955 #ifdef WANT_DEMO
5956       if (demo_mode) {
5957 	demo_first_timestamp();
5958       }
5959 #endif
5960 
5961     while ((!times_up) || (trans_remaining > 0)) {
5962       /* send the request. we assume that if we use a blocking socket, */
5963       /* the request will be sent at one shot. */
5964 
5965 #ifdef WANT_FIRST_BURST
5966       /* we can inject no more than request_cwnd, which will grow with
5967 	 time, and no more than first_burst_size.  we don't use <= to
5968 	 account for the "regularly scheduled" send call.  of course
5969 	 that makes it more a "max_outstanding_ than a
5970 	 "first_burst_size" but for now we won't fix the names. also,
5971 	 I suspect the extra check against < first_burst_size is
5972 	 redundant since later I expect to make sure that request_cwnd
5973 	 can never get larger than first_burst_size, but just at the
5974 	 moment I'm feeling like a belt and suspenders kind of
5975 	 programmer. raj 2006-01-30 */
5976       while ((first_burst_size > 0) &&
5977 	     (requests_outstanding < request_cwnd) &&
5978 	     (requests_outstanding < first_burst_size)) {
5979 	if (debug) {
5980 	  fprintf(where,
5981 		  "injecting, req_outstndng %d req_cwnd %d burst %d\n",
5982 		  requests_outstanding,
5983 		  request_cwnd,
5984 		  first_burst_size);
5985 	}
5986 	if ((len = send(send_socket,
5987 			send_ring->buffer_ptr,
5988 			req_size,
5989 			0)) != req_size) {
5990 	  /* we should never hit the end of the test in the first burst */
5991 	  perror("send_tcp_rr: initial burst data send error");
5992 	  exit(-1);
5993 	}
5994 	requests_outstanding += 1;
5995       }
5996 
5997 #endif /* WANT_FIRST_BURST */
5998 
5999 #ifdef WANT_HISTOGRAM
6000       if (verbosity > 1) {
6001 	/* timestamp just before our call to send, and then again just
6002 	   after the receive raj 8/94 */
6003 	/* but only if we are actually going to display one. raj
6004 	   2007-02-07 */
6005 
6006 	HIST_timestamp(&time_one);
6007       }
6008 #endif /* WANT_HISTOGRAM */
6009 
6010       if ((len = send(send_socket,
6011 		      send_ring->buffer_ptr,
6012 		      req_size,
6013 		      0)) != req_size) {
6014 	if (SOCKET_EINTR(len) || (errno == 0)) {
6015 	  /* we hit the end of a */
6016 	  /* timed test. */
6017 	  timed_out = 1;
6018 	  break;
6019 	}
6020 	perror("send_tcp_rr: data send error");
6021 	exit(1);
6022       }
6023       send_ring = send_ring->next;
6024 
6025 #ifdef WANT_FIRST_BURST
6026       requests_outstanding += 1;
6027 #endif
6028 
6029       /* receive the response */
6030       rsp_bytes_left = rsp_size;
6031       temp_message_ptr  = recv_ring->buffer_ptr;
6032       while(rsp_bytes_left > 0) {
6033 	if((rsp_bytes_recvd=recv(send_socket,
6034 				 temp_message_ptr,
6035 				 rsp_bytes_left,
6036 				 0)) == SOCKET_ERROR || rsp_bytes_recvd == 0) {
6037 		if ( SOCKET_EINTR(rsp_bytes_recvd) ) {
6038 		    /* We hit the end of a timed test. */
6039 			timed_out = 1;
6040 			break;
6041 		}
6042 	  perror("send_tcp_rr: data recv error");
6043 	  exit(1);
6044 	}
6045 	rsp_bytes_left -= rsp_bytes_recvd;
6046 	temp_message_ptr  += rsp_bytes_recvd;
6047       }
6048       recv_ring = recv_ring->next;
6049 
6050 #ifdef WANT_FIRST_BURST
6051       /* so, since we've gotten a response back, update the
6052 	 bookkeeping accordingly.  there is one less request
6053 	 outstanding and we can put one more out there than before. */
6054       requests_outstanding -= 1;
6055       if (request_cwnd < first_burst_size) {
6056 	request_cwnd += 1;
6057 	if (debug) {
6058 	  fprintf(where,
6059 		  "incr req_cwnd to %d first_burst %d reqs_outstndng %d\n",
6060 		  request_cwnd,
6061 		  first_burst_size,
6062 		  requests_outstanding);
6063 	}
6064       }
6065 #endif
6066       if (timed_out) {
6067 	/* we may have been in a nested while loop - we need */
6068 	/* another call to break. */
6069 	break;
6070       }
6071 
6072 #ifdef WANT_HISTOGRAM
6073       if (verbosity > 1) {
6074 	HIST_timestamp(&time_two);
6075 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
6076       }
6077 #endif /* WANT_HISTOGRAM */
6078 
6079 #ifdef WANT_DEMO
6080       demo_rr_interval(1);
6081 #endif
6082 
6083 #ifdef WANT_INTERVALS
6084       INTERVALS_WAIT();
6085 #endif /* WANT_INTERVALS */
6086 
6087       nummessages++;
6088       if (trans_remaining) {
6089 	trans_remaining--;
6090       }
6091 
6092       if (debug > 3) {
6093 	if ((nummessages % 100) == 0) {
6094 	  fprintf(where,
6095 		  "Transaction %d completed\n",
6096 		  nummessages);
6097 	  fflush(where);
6098 	}
6099       }
6100     }
6101 
6102     /* At this point we used to call shutdown on the data socket to be
6103        sure all the data was delivered, but this was not germane in a
6104        request/response test, and it was causing the tests to "hang"
6105        when they were being controlled by time. So, I have replaced
6106        this shutdown call with a call to close that can be found later
6107        in the procedure. */
6108 
6109     /* this call will always give us the elapsed time for the test,
6110        and will also store-away the necessaries for cpu utilization */
6111 
6112     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
6113 						/* measured? how long */
6114 						/* did we really run? */
6115 
6116 #if defined(WANT_INTERVALS)
6117 #ifdef WIN32
6118     stop_itimer();
6119 #endif
6120 #endif /* WANT_INTERVALS */
6121 
6122     if (!no_control) {
6123       /* Get the statistics from the remote end. The remote will have
6124 	 calculated CPU utilization. If it wasn't supposed to care, it
6125 	 will return obvious values. */
6126 
6127       recv_response();
6128       if (!netperf_response.content.serv_errno) {
6129 	if (debug)
6130 	  fprintf(where,"remote results obtained\n");
6131       }
6132       else {
6133 	Set_errno(netperf_response.content.serv_errno);
6134 	fprintf(where,"netperf: remote error %d",
6135 		netperf_response.content.serv_errno);
6136 	perror("");
6137 	fflush(where);
6138 	exit(1);
6139       }
6140     }
6141 
6142     /* We now calculate what our "throughput" was for the test. */
6143 
6144     bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
6145     thruput	= nummessages/elapsed_time;
6146 
6147     if (local_cpu_usage || remote_cpu_usage) {
6148       /* We must now do a little math for service demand and cpu
6149        utilization for the system(s) Of course, some of the
6150        information might be bogus because there was no idle counter in
6151        the kernel(s). We need to make a note of this for the user's
6152        benefit... */
6153       if (local_cpu_usage) {
6154 	local_cpu_utilization = calc_cpu_util(0.0);
6155  	/* since calc_service demand is doing ms/Kunit we will
6156 	   multiply the number of transaction by 1024 to get "good"
6157 	   numbers */
6158 	local_service_demand  = calc_service_demand((double) nummessages*1024,
6159 						    0.0,
6160 						    0.0,
6161 						    0);
6162       }
6163       else {
6164 	local_cpu_utilization	= (float) -1.0;
6165 	local_service_demand	= (float) -1.0;
6166       }
6167 
6168       if (remote_cpu_usage) {
6169 	remote_cpu_utilization = tcp_rr_result->cpu_util;
6170 	/* since calc_service demand is doing ms/Kunit we will
6171 	   multiply the number of transaction by 1024 to get "good"
6172 	   numbers */
6173 	remote_service_demand = calc_service_demand((double) nummessages*1024,
6174 						    0.0,
6175 						    remote_cpu_utilization,
6176 						    tcp_rr_result->num_cpus);
6177       }
6178       else {
6179 	remote_cpu_utilization = (float) -1.0;
6180 	remote_service_demand  = (float) -1.0;
6181       }
6182 
6183     }
6184     else {
6185       /* we were not measuring cpu, for the confidence stuff, we */
6186       /* should make it -1.0 */
6187       local_cpu_utilization	= (float) -1.0;
6188       local_service_demand	= (float) -1.0;
6189       remote_cpu_utilization = (float) -1.0;
6190       remote_service_demand  = (float) -1.0;
6191     }
6192 
6193     /* at this point, we want to calculate the confidence information.
6194        if debugging is on, calculate_confidence will print-out the
6195        parameters we pass it */
6196 
6197     calculate_confidence(confidence_iteration,
6198 			 elapsed_time,
6199 			 thruput,
6200 			 local_cpu_utilization,
6201 			 remote_cpu_utilization,
6202 			 local_service_demand,
6203 			 remote_service_demand);
6204 
6205 
6206     confidence_iteration++;
6207 
6208     /* we are now done with the socket, so close it */
6209     close(send_socket);
6210 
6211   }
6212 
6213   retrieve_confident_values(&elapsed_time,
6214 			    &thruput,
6215 			    &local_cpu_utilization,
6216 			    &remote_cpu_utilization,
6217 			    &local_service_demand,
6218 			    &remote_service_demand);
6219 
6220   /* We are now ready to print all the information. If the user has
6221      specified zero-level verbosity, we will just print the local
6222      service demand, or the remote service demand. If the user has
6223      requested verbosity level 1, he will get the basic "streamperf"
6224      numbers. If the user has specified a verbosity of greater than 1,
6225      we will display a veritable plethora of background information
6226      from outside of this block as it it not cpu_measurement
6227      specific...  */
6228 
6229   if (confidence < 0) {
6230     /* we did not hit confidence, but were we asked to look for it? */
6231     if (iteration_max > 1) {
6232       display_confidence();
6233     }
6234   }
6235 
6236   if (local_cpu_usage || remote_cpu_usage) {
6237     local_cpu_method = format_cpu_method(cpu_method);
6238     remote_cpu_method = format_cpu_method(tcp_rr_result->cpu_method);
6239 
6240     switch (verbosity) {
6241     case 0:
6242       if (local_cpu_usage) {
6243 	fprintf(where,
6244 		cpu_fmt_0,
6245 		local_service_demand,
6246 		local_cpu_method,
6247 		((print_headers) ||
6248 		 (result_brand == NULL)) ? "" : result_brand);
6249       }
6250       else {
6251 	fprintf(where,
6252 		cpu_fmt_0,
6253 		remote_service_demand,
6254 		remote_cpu_method,
6255 		((print_headers) ||
6256 		 (result_brand == NULL)) ? "" : result_brand);
6257       }
6258       break;
6259     case 1:
6260     case 2:
6261       if (print_headers) {
6262 	if ('x' == libfmt) {
6263 	  fprintf(where,
6264 		  cpu_title,
6265 		  local_cpu_method,
6266 		  remote_cpu_method);
6267 	}
6268 	else {
6269 	  fprintf(where,
6270 		  cpu_title_tput,
6271 		  format_units(),
6272 		  local_cpu_method,
6273 		  remote_cpu_method);
6274 	}
6275       }
6276 
6277       fprintf(where,
6278 	      cpu_fmt_1_line_1,		/* the format string */
6279 	      lss_size,		/* local sendbuf size */
6280 	      lsr_size,
6281 	      req_size,		/* how large were the requests */
6282 	      rsp_size,		/* guess */
6283 	      elapsed_time,		/* how long was the test */
6284 	      ('x' == libfmt) ? thruput :
6285 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
6286 					 1.0),
6287 	      local_cpu_utilization,	/* local cpu */
6288 	      remote_cpu_utilization,	/* remote cpu */
6289 	      local_service_demand,	/* local service demand */
6290 	      remote_service_demand,	/* remote service demand */
6291 	      ((print_headers) ||
6292 	       (result_brand == NULL)) ? "" : result_brand);
6293       fprintf(where,
6294 	      cpu_fmt_1_line_2,
6295 	      rss_size,
6296 	      rsr_size);
6297       break;
6298     }
6299   }
6300   else {
6301     /* The tester did not wish to measure service demand. */
6302 
6303     switch (verbosity) {
6304     case 0:
6305       fprintf(where,
6306 	      tput_fmt_0,
6307 	      ('x' == libfmt) ? thruput :
6308 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
6309 					 1.0),
6310 	      ((print_headers) ||
6311 	       (result_brand == NULL)) ? "" : result_brand);
6312       break;
6313     case 1:
6314     case 2:
6315       if (print_headers) {
6316 	fprintf(where,
6317 		('x' == libfmt) ? tput_title : tput_title_band,
6318 		format_units());
6319       }
6320 
6321       fprintf(where,
6322 	      tput_fmt_1_line_1,	/* the format string */
6323 	      lss_size,
6324 	      lsr_size,
6325 	      req_size,		/* how large were the requests */
6326 	      rsp_size,		/* how large were the responses */
6327 	      elapsed_time, 		/* how long did it take */
6328 	      /* are we trans or do we need to convert to bytes then
6329 		 bits? at this point, thruput is in our "confident"
6330 		 transactions per second. we can convert to a
6331 		 bidirectional bitrate by multiplying that by the sum
6332 		 of the req_size and rsp_size.  we pass that to
6333 		 calc_thruput_interval_omni with an elapsed time of
6334 		 1.0 s to get it converted to [kmg]bits/s or
6335 		 [KMG]Bytes/s */
6336 	      ('x' == libfmt) ?  thruput :
6337 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
6338 					 1.0),
6339 	      ((print_headers) ||
6340 	       (result_brand == NULL)) ? "" : result_brand);
6341       fprintf(where,
6342 	      tput_fmt_1_line_2,
6343 	      rss_size, 		/* remote recvbuf size */
6344 	      rsr_size);
6345 
6346       break;
6347     }
6348   }
6349 
6350   /* it would be a good thing to include information about some of the */
6351   /* other parameters that may have been set for this test, but at the */
6352   /* moment, I do not wish to figure-out all the  formatting, so I will */
6353   /* just put this comment here to help remind me that it is something */
6354   /* that should be done at a later time. */
6355 
6356   /* how to handle the verbose information in the presence of */
6357   /* confidence intervals is yet to be determined... raj 11/94 */
6358   if (verbosity > 1) {
6359     /* The user wanted to know it all, so we will give it to him. */
6360     /* This information will include as much as we can find about */
6361     /* TCP statistics, the alignments of the sends and receives */
6362     /* and all that sort of rot... */
6363 
6364     /* normally, you might think that if we were messing about with
6365        the value of libfmt we would need to put it back again, but
6366        since this is basically the last thing we are going to do with
6367        it, it does not matter.  so there :) raj 2007-06-08 */
6368     /* if the user was asking for transactions, then we report
6369        megabits per second for the unidirectional throughput,
6370        otherwise we use the desired units. */
6371     if ('x' == libfmt) {
6372       libfmt = 'm';
6373     }
6374 
6375     fprintf(where,
6376 	    ksink_fmt,
6377 	    format_units(),
6378 	    local_send_align,
6379 	    remote_recv_offset,
6380 	    local_send_offset,
6381 	    remote_recv_offset,
6382 	    /* if the user has enable burst mode, we have to remember
6383 	       to account for that in the number of transactions
6384 	       outstanding at any one time. otherwise we will
6385 	       underreport the latency of individual
6386 	       transactions. learned from saf by raj 2007-06-08  */
6387 	    (((double)1.0/thruput)*(double)1000000.0) *
6388 	    (double) (1 + ((first_burst_size > 0) ? first_burst_size : 0)),
6389 	    thruput,
6390 	    calc_thruput_interval_omni(thruput * (double)req_size,1.0),
6391 	    calc_thruput_interval_omni(thruput * (double)rsp_size,1.0));
6392 
6393 #ifdef WANT_HISTOGRAM
6394     fprintf(where,"\nHistogram of request/response times\n");
6395     fflush(where);
6396     HIST_report(time_hist);
6397 #endif /* WANT_HISTOGRAM */
6398 
6399   }
6400 
6401 }
6402 #endif /* WANT_MIGRATION */
6403 
6404 #if defined(__linux)
6405 /*
6406  * Linux has this odd behavior where if the socket buffers are larger than
6407  * a device's txqueuelen, the kernel will silently drop transmits which would
6408  * not fit into the tx queue, and not  pass an ENOBUFS error back to the
6409  * application.  As a result, a UDP stream test can report absurd transmit
6410  * bandwidths (like 20Gb/s on a 1GbE NIC).  This behavior can be avoided if
6411  * you  request extended error reporting on the socket.  This is done by
6412  * setting the IP_RECVERR socket option at the IP level.
6413  */
6414 static void
enable_enobufs(int s)6415 enable_enobufs(int s)
6416 {
6417   struct protoent *pr;
6418   int on = 1;
6419 
6420   if ((pr = getprotobyname("ip")) == NULL) {
6421     fprintf(where, "enable_enobufs failed: getprotobyname\n");
6422     fflush(where);
6423     return;
6424   }
6425   if (setsockopt(s, pr->p_proto, IP_RECVERR, (char *)&on, sizeof(on)) < 0) {
6426     fprintf(where, "enable_enobufs failed: setsockopt\n");
6427     fflush(where);
6428     return;
6429   }
6430 }
6431 #endif
6432 
6433 #ifndef WANT_MIGRATION
6434 void
send_udp_stream(char remote_host[])6435 send_udp_stream(char remote_host[])
6436 {
6437   /**********************************************************************/
6438   /*									*/
6439   /*               	UDP Unidirectional Send Test                    */
6440   /*									*/
6441   /**********************************************************************/
6442 
6443 #define UDP_LENGTH_MAX 0XFFFF - 28
6444 
6445   char *tput_title = "\
6446 Socket  Message  Elapsed      Messages                \n\
6447 Size    Size     Time         Okay Errors   Throughput\n\
6448 bytes   bytes    secs            #      #   %s/sec\n\n";
6449 
6450   char *tput_fmt_0 =
6451     "%7.2f\n";
6452 
6453   char *tput_fmt_1 = "\
6454 %6d  %6d   %-7.2f   %7d %6d    %7.2f\n\
6455 %6d           %-7.2f   %7d           %7.2f\n\n";
6456 
6457 
6458   char *cpu_title = "\
6459 Socket  Message  Elapsed      Messages                   CPU      Service\n\
6460 Size    Size     Time         Okay Errors   Throughput   Util     Demand\n\
6461 bytes   bytes    secs            #      #   %s/sec %% %c%c     us/KB\n\n";
6462 
6463   char *cpu_fmt_0 =
6464     "%6.2f %c\n";
6465 
6466   char *cpu_fmt_1 = "\
6467 %6d  %6d   %-7.2f   %7d %6d    %7.1f     %-6.2f   %-6.3f\n\
6468 %6d           %-7.2f   %7d           %7.1f     %-6.2f   %-6.3f\n\n";
6469 
6470   unsigned int	messages_recvd;
6471   unsigned int 	messages_sent;
6472   unsigned int	failed_sends;
6473 
6474   float	elapsed_time,
6475         local_cpu_utilization,
6476         remote_cpu_utilization;
6477 
6478   float	 local_service_demand, remote_service_demand;
6479   double local_thruput, remote_thruput;
6480   double bytes_sent;
6481   double bytes_recvd;
6482 
6483 
6484   int	len;
6485   struct ring_elt *send_ring;
6486   SOCKET 	data_socket;
6487 
6488   unsigned int sum_messages_sent;
6489   unsigned int sum_messages_recvd;
6490   unsigned int sum_failed_sends;
6491   double sum_local_thruput;
6492 
6493   struct addrinfo *local_res;
6494   struct addrinfo *remote_res;
6495 
6496   struct	udp_stream_request_struct	*udp_stream_request;
6497   struct	udp_stream_response_struct	*udp_stream_response;
6498   struct	udp_stream_results_struct	*udp_stream_results;
6499 
6500   udp_stream_request	=
6501     (struct udp_stream_request_struct *)netperf_request.content.test_specific_data;
6502   udp_stream_response	=
6503     (struct udp_stream_response_struct *)netperf_response.content.test_specific_data;
6504   udp_stream_results	=
6505     (struct udp_stream_results_struct *)netperf_response.content.test_specific_data;
6506 
6507 #ifdef WANT_HISTOGRAM
6508   if (verbosity > 1) {
6509     time_hist = HIST_new();
6510   }
6511 #endif /* WANT_HISTOGRAM */
6512 
6513   /* since we are now disconnected from the code that established the */
6514   /* control socket, and since we want to be able to use different */
6515   /* protocols and such, we are passed the name of the remote host and */
6516   /* must turn that into the test specific addressing information. */
6517 
6518   complete_addrinfos(&remote_res,
6519 		     &local_res,
6520 		     remote_host,
6521 		     SOCK_DGRAM,
6522 		     IPPROTO_UDP,
6523 		     0);
6524 
6525   if ( print_headers ) {
6526     print_top_test_header("UDP UNIDIRECTIONAL SEND TEST",local_res,remote_res);
6527   }
6528 
6529   send_ring            = NULL;
6530   confidence_iteration = 1;
6531   init_stat();
6532   sum_messages_sent    = 0;
6533   sum_messages_recvd   = 0;
6534   sum_failed_sends     = 0;
6535   sum_local_thruput    = 0.0;
6536 
6537   /* we have a great-big while loop which controls the number of times */
6538   /* we run a particular test. this is for the calculation of a */
6539   /* confidence interval (I really should have stayed awake during */
6540   /* probstats :). If the user did not request confidence measurement */
6541   /* (no confidence is the default) then we will only go though the */
6542   /* loop once. the confidence stuff originates from the folks at IBM */
6543 
6544   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
6545 	 (confidence_iteration <= iteration_min)) {
6546 
6547     /* initialize a few counters. we have to remember that we might be */
6548     /* going through the loop more than once. */
6549     messages_sent  = 0;
6550     messages_recvd = 0;
6551     failed_sends   = 0;
6552     times_up       = 0;
6553 
6554     /*set up the data socket			*/
6555     data_socket = create_data_socket(local_res);
6556 
6557     if (data_socket == INVALID_SOCKET){
6558       perror("udp_send: data socket");
6559       exit(1);
6560     }
6561 
6562     /* now, we want to see if we need to set the send_size */
6563     if (send_size == 0) {
6564       if (lss_size > 0) {
6565 	send_size = (lss_size < UDP_LENGTH_MAX ? lss_size : UDP_LENGTH_MAX);
6566       }
6567       else {
6568 	send_size = 4096;
6569       }
6570     }
6571 
6572 
6573     /* set-up the data buffer with the requested alignment and offset, */
6574     /* most of the numbers here are just a hack to pick something nice */
6575     /* and big in an attempt to never try to send a buffer a second time */
6576     /* before it leaves the node...unless the user set the width */
6577     /* explicitly. */
6578     if (send_width == 0) send_width = 32;
6579 
6580     if (send_ring == NULL ) {
6581       send_ring = allocate_buffer_ring(send_width,
6582 				       send_size,
6583 				       local_send_align,
6584 				       local_send_offset);
6585     }
6586 
6587 
6588     /* if the user supplied a cpu rate, this call will complete rather */
6589     /* quickly, otherwise, the cpu rate will be retured to us for */
6590     /* possible display. The Library will keep it's own copy of this data */
6591     /* for use elsewhere. We will only display it. (Does that make it */
6592     /* "opaque" to us?) */
6593 
6594     if (local_cpu_usage)
6595       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
6596 
6597     if (!no_control) {
6598       /* Tell the remote end to set up the data connection. The server
6599          sends back the port number and alters the socket parameters
6600          there.  Of course this is a datagram service so no connection
6601          is actually set up, the server just sets up the socket and
6602          binds it. */
6603 
6604       netperf_request.content.request_type      = DO_UDP_STREAM;
6605       udp_stream_request->recv_buf_size  = rsr_size_req;
6606       udp_stream_request->message_size   = send_size;
6607       udp_stream_request->recv_connected = remote_connected;
6608       udp_stream_request->recv_alignment = remote_recv_align;
6609       udp_stream_request->recv_offset    = remote_recv_offset;
6610       udp_stream_request->measure_cpu    = remote_cpu_usage;
6611       udp_stream_request->cpu_rate       = remote_cpu_rate;
6612       udp_stream_request->test_length    = test_time;
6613       udp_stream_request->so_rcvavoid    = rem_rcvavoid;
6614       udp_stream_request->so_sndavoid    = rem_sndavoid;
6615       udp_stream_request->port           = atoi(remote_data_port);
6616       udp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
6617 
6618       send_request();
6619 
6620       recv_response();
6621 
6622       if (!netperf_response.content.serv_errno) {
6623 	if (debug)
6624 	  fprintf(where,"send_udp_stream: remote data connection done.\n");
6625       }
6626       else {
6627 	Set_errno(netperf_response.content.serv_errno);
6628 	perror("send_udp_stream: error on remote");
6629 	exit(1);
6630       }
6631 
6632       /* Place the port number returned by the remote into the sockaddr */
6633       /* structure so our sends can be sent to the correct place. Also get */
6634       /* some of the returned socket buffer information for user display. */
6635 
6636       /* make sure that port numbers are in the proper order */
6637       set_port_number(remote_res,(short)udp_stream_response->data_port_number);
6638 
6639       rsr_size        = udp_stream_response->recv_buf_size;
6640       rss_size        = udp_stream_response->send_buf_size;
6641       remote_cpu_rate = udp_stream_response->cpu_rate;
6642     }
6643 
6644 #ifdef WANT_DEMO
6645     demo_stream_setup(lss_size,rsr_size);
6646 #endif
6647 
6648     /* We "connect" up to the remote post to allow is to use the send */
6649     /* call instead of the sendto call. Presumeably, this is a little */
6650     /* simpler, and a little more efficient. I think that it also means */
6651     /* that we can be informed of certain things, but am not sure */
6652     /* yet...also, this is the way I would expect a client to behave */
6653     /* when talking to a server */
6654     if (local_connected) {
6655        if (connect(data_socket,
6656       		   remote_res->ai_addr,
6657 		   remote_res->ai_addrlen) == INVALID_SOCKET){
6658           perror("send_udp_stream: data socket connect failed");
6659           exit(1);
6660        } else if (debug) {
6661           fprintf(where,"send_udp_stream: connected data socket.\n");
6662           fflush(where);
6663        }
6664     }
6665 
6666 #if defined (__linux)
6667   enable_enobufs(data_socket);
6668 #endif
6669 
6670 #ifdef WIN32
6671   /* this is used so the timer thread can close the socket out from */
6672   /* under us, which to date is the easiest/cleanest/least */
6673   /* Windows-specific way I can find to force the winsock calls to */
6674   /* return WSAEINTR with the test is over. anything that will run on */
6675   /* 95 and NT and is closer to what netperf expects from Unix signals */
6676   /* and such would be appreciated raj 1/96 */
6677     win_kludge_socket = data_socket;
6678 #endif /* WIN32 */
6679 
6680     /* set up the timer to call us after test_time. one of these days, */
6681     /* it might be nice to figure-out a nice reliable way to have the */
6682     /* test controlled by a byte count as well, but since UDP is not */
6683     /* reliable, that could prove difficult. so, in the meantime, we */
6684     /* only allow a UDP_STREAM test to be a timed test. */
6685 
6686     if (test_time) {
6687       times_up = 0;
6688       start_timer(test_time);
6689     }
6690     else {
6691       fprintf(where,"Sorry, UDP_STREAM tests must be timed.\n");
6692       fflush(where);
6693     }
6694 
6695     /* Get the start count for the idle counter and the start time */
6696 
6697     cpu_start(local_cpu_usage);
6698 
6699 #ifdef WANT_INTERVALS
6700     INTERVALS_INIT();
6701 #endif /* WANT_INTERVALS */
6702 
6703 #ifdef WANT_DEMO
6704     if (demo_mode) {
6705       demo_first_timestamp();
6706     }
6707 #endif
6708 
6709     /* Send datagrams like there was no tomorrow. at somepoint it might */
6710     /* be nice to set this up so that a quantity of bytes could be sent, */
6711     /* but we still need some sort of end of test trigger on the receive */
6712     /* side. that could be a select with a one second timeout, but then */
6713     /* if there is a test where none of the data arrives for awile and */
6714     /* then starts again, we would end the test too soon. something to */
6715     /* think about... */
6716     while (!times_up) {
6717 
6718 #ifdef DIRTY
6719       /* we want to dirty some number of consecutive integers in the buffer */
6720       /* we are about to send. we may also want to bring some number of */
6721       /* them cleanly into the cache. The clean ones will follow any dirty */
6722       /* ones into the cache. */
6723 
6724       access_buffer(send_ring->buffer_ptr,
6725 		    send_size,
6726 		    loc_dirty_count,
6727 		    loc_clean_count);
6728 #endif /* DIRTY */
6729 
6730 #ifdef WANT_HISTOGRAM
6731       if (verbosity > 1) {
6732 	HIST_timestamp(&time_one);
6733       }
6734 #endif /* WANT_HISTOGRAM */
6735 
6736       if (local_connected) {
6737          len = send(data_socket,
6738 	  	    send_ring->buffer_ptr,
6739 		    send_size,
6740 		    0);
6741       } else {
6742          len = sendto(data_socket,
6743 		      send_ring->buffer_ptr,
6744 		      send_size,
6745 		      0,
6746 		      remote_res->ai_addr,
6747 		      remote_res->ai_addrlen);
6748       }
6749 
6750       if (len != send_size) {
6751 	if ((len >= 0) ||
6752 	    SOCKET_EINTR(len))
6753 	  break;
6754 	if (errno == ENOBUFS) {
6755 	  failed_sends++;
6756 	  continue;
6757 	}
6758 	perror("udp_send: data send error");
6759 	exit(1);
6760       }
6761       messages_sent++;
6762 
6763       /* now we want to move our pointer to the next position in the */
6764       /* data buffer... */
6765 
6766       send_ring = send_ring->next;
6767 
6768 
6769 #ifdef WANT_HISTOGRAM
6770       if (verbosity > 1) {
6771 	/* get the second timestamp */
6772 	HIST_timestamp(&time_two);
6773 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
6774       }
6775 #endif /* WANT_HISTOGRAM */
6776 
6777 #ifdef WANT_DEMO
6778       demo_stream_interval(send_size);
6779 #endif
6780 
6781 #ifdef WANT_INTERVALS
6782       INTERVALS_WAIT();
6783 #endif /* WANT_INTERVALS */
6784 
6785     }
6786 
6787     /* This is a timed test, so the remote will be returning to us after */
6788     /* a time. We should not need to send any "strange" messages to tell */
6789     /* the remote that the test is completed, unless we decide to add a */
6790     /* number of messages to the test. */
6791 
6792     /* the test is over, so get stats and stuff */
6793     cpu_stop(local_cpu_usage,
6794 	     &elapsed_time);
6795 
6796 #if defined(WANT_INTERVALS)
6797 #ifdef WIN32
6798     stop_itimer();
6799 #endif
6800 #endif /* WANT_INTERVALS */
6801 
6802     if (!no_control) {
6803       /* Get the statistics from the remote end	*/
6804       recv_response();
6805       if (!netperf_response.content.serv_errno) {
6806 	if (debug)
6807 	  fprintf(where,"send_udp_stream: remote results obtained\n");
6808       }
6809       else {
6810 	Set_errno(netperf_response.content.serv_errno);
6811 	perror("send_udp_stream: error on remote");
6812 	exit(1);
6813       }
6814       messages_recvd = udp_stream_results->messages_recvd;
6815       bytes_recvd    = (double) send_size * (double) messages_recvd;
6816     }
6817     else {
6818       /* since there was no control connection, we've no idea what was
6819 	 actually received. raj 2007-02-08 */
6820       messages_recvd = -1;
6821       bytes_recvd = -1.0;
6822     }
6823 
6824     bytes_sent    = (double) send_size * (double) messages_sent;
6825     local_thruput = calc_thruput(bytes_sent);
6826 
6827 
6828     /* we asume that the remote ran for as long as we did */
6829 
6830     remote_thruput = calc_thruput(bytes_recvd);
6831 
6832     /* print the results for this socket and message size */
6833 
6834     if (local_cpu_usage || remote_cpu_usage) {
6835       /* We must now do a little math for service demand and cpu */
6836       /* utilization for the system(s) We pass zeros for the local */
6837       /* cpu utilization and elapsed time to tell the routine to use */
6838       /* the libraries own values for those. */
6839       if (local_cpu_usage) {
6840 	local_cpu_utilization	= calc_cpu_util(0.0);
6841 	/* shouldn't this really be based on bytes_recvd, since that is */
6842 	/* the effective throughput of the test? I think that it should, */
6843 	/* so will make the change raj 11/94 */
6844 	local_service_demand	= calc_service_demand(bytes_recvd,
6845 						      0.0,
6846 						      0.0,
6847 						      0);
6848       }
6849       else {
6850 	local_cpu_utilization	= (float) -1.0;
6851 	local_service_demand	= (float) -1.0;
6852       }
6853 
6854       /* The local calculations could use variables being kept by */
6855       /* the local netlib routines. The remote calcuations need to */
6856       /* have a few things passed to them. */
6857       if (remote_cpu_usage) {
6858 	remote_cpu_utilization	= udp_stream_results->cpu_util;
6859 	remote_service_demand	= calc_service_demand(bytes_recvd,
6860 						      0.0,
6861 						      remote_cpu_utilization,
6862 						      udp_stream_results->num_cpus);
6863       }
6864       else {
6865 	remote_cpu_utilization	= (float) -1.0;
6866 	remote_service_demand	= (float) -1.0;
6867       }
6868     }
6869     else {
6870       /* we were not measuring cpu, for the confidence stuff, we */
6871       /* should make it -1.0 */
6872       local_cpu_utilization  = (float) -1.0;
6873       local_service_demand   = (float) -1.0;
6874       remote_cpu_utilization = (float) -1.0;
6875       remote_service_demand  = (float) -1.0;
6876     }
6877 
6878     /* at this point, we want to calculate the confidence information. */
6879     /* if debugging is on, calculate_confidence will print-out the */
6880     /* parameters we pass it */
6881 
6882     calculate_confidence(confidence_iteration,
6883 			 elapsed_time,
6884 			 remote_thruput,
6885 			 local_cpu_utilization,
6886 			 remote_cpu_utilization,
6887 			 local_service_demand,
6888 			 remote_service_demand);
6889 
6890     /* since the routine calculate_confidence is rather generic, and */
6891     /* we have a few other parms of interest, we will do a little work */
6892     /* here to caclulate their average. */
6893     sum_messages_sent  += messages_sent;
6894     sum_messages_recvd += messages_recvd;
6895     sum_failed_sends   += failed_sends;
6896     sum_local_thruput  += local_thruput;
6897 
6898     confidence_iteration++;
6899 
6900     /* this datapoint is done, so we don't need the socket any longer */
6901     close(data_socket);
6902 
6903   }
6904 
6905   /* we should reach this point once the test is finished */
6906 
6907   retrieve_confident_values(&elapsed_time,
6908 			    &remote_thruput,
6909 			    &local_cpu_utilization,
6910 			    &remote_cpu_utilization,
6911 			    &local_service_demand,
6912 			    &remote_service_demand);
6913 
6914   /* some of the interesting values aren't covered by the generic */
6915   /* confidence routine */
6916   messages_sent    = sum_messages_sent / (confidence_iteration -1);
6917   messages_recvd   = sum_messages_recvd / (confidence_iteration -1);
6918   failed_sends     = sum_failed_sends / (confidence_iteration -1);
6919   local_thruput    = sum_local_thruput / (confidence_iteration -1);
6920 
6921   /* We are now ready to print all the information. If the user */
6922   /* has specified zero-level verbosity, we will just print the */
6923   /* local service demand, or the remote service demand. If the */
6924   /* user has requested verbosity level 1, he will get the basic */
6925   /* "streamperf" numbers. If the user has specified a verbosity */
6926   /* of greater than 1, we will display a veritable plethora of */
6927   /* background information from outside of this block as it it */
6928   /* not cpu_measurement specific...  */
6929 
6930 
6931   if (confidence < 0) {
6932     /* we did not hit confidence, but were we asked to look for it? */
6933     if (iteration_max > 1) {
6934       display_confidence();
6935     }
6936   }
6937 
6938   if (local_cpu_usage || remote_cpu_usage) {
6939     local_cpu_method = format_cpu_method(cpu_method);
6940     remote_cpu_method = format_cpu_method(udp_stream_results->cpu_method);
6941 
6942     switch (verbosity) {
6943     case 0:
6944       if (local_cpu_usage) {
6945 	fprintf(where,
6946 		cpu_fmt_0,
6947 		local_service_demand,
6948 		local_cpu_method);
6949       }
6950       else {
6951 	fprintf(where,
6952 		cpu_fmt_0,
6953 		remote_service_demand,
6954 		local_cpu_method);
6955       }
6956       break;
6957     case 1:
6958     case 2:
6959       if (print_headers) {
6960 	fprintf(where,
6961 		cpu_title,
6962 		format_units(),
6963 		local_cpu_method,
6964 		remote_cpu_method);
6965       }
6966 
6967       fprintf(where,
6968 	      cpu_fmt_1,		/* the format string */
6969 	      lss_size,		        /* local sendbuf size */
6970 	      send_size,		/* how large were the sends */
6971 	      elapsed_time,		/* how long was the test */
6972 	      messages_sent,
6973 	      failed_sends,
6974 	      local_thruput, 		/* what was the xfer rate */
6975 	      local_cpu_utilization,	/* local cpu */
6976 	      local_service_demand,	/* local service demand */
6977 	      rsr_size,
6978 	      elapsed_time,
6979 	      messages_recvd,
6980 	      remote_thruput,
6981 	      remote_cpu_utilization,	/* remote cpu */
6982 	      remote_service_demand);	/* remote service demand */
6983       break;
6984     }
6985   }
6986   else {
6987     /* The tester did not wish to measure service demand. */
6988     switch (verbosity) {
6989     case 0:
6990       fprintf(where,
6991 	      tput_fmt_0,
6992 	      local_thruput);
6993       break;
6994     case 1:
6995     case 2:
6996       if (print_headers) {
6997 	fprintf(where,tput_title,format_units());
6998       }
6999       fprintf(where,
7000 	      tput_fmt_1,		/* the format string */
7001 	      lss_size, 		/* local sendbuf size */
7002 	      send_size,		/* how large were the sends */
7003 	      elapsed_time, 		/* how long did it take */
7004 	      messages_sent,
7005 	      failed_sends,
7006 	      local_thruput,
7007 	      rsr_size, 		/* remote recvbuf size */
7008 	      elapsed_time,
7009 	      messages_recvd,
7010 	      remote_thruput);
7011       break;
7012     }
7013   }
7014 
7015   fflush(where);
7016 #ifdef WANT_HISTOGRAM
7017   if (verbosity > 1) {
7018     fprintf(where,"\nHistogram of time spent in send() call\n");
7019     fflush(where);
7020     HIST_report(time_hist);
7021   }
7022 #endif /* WANT_HISTOGRAM */
7023 
7024 }
7025 #endif /* WANT_MIGRATION */
7026 
7027 
7028  /* this routine implements the receive side (netserver) of the */
7029  /* UDP_STREAM performance test. */
7030 
7031 void
recv_udp_stream()7032 recv_udp_stream()
7033 {
7034   struct ring_elt *recv_ring;
7035   struct addrinfo *local_res;
7036   char local_name[BUFSIZ];
7037   char port_buffer[PORTBUFSIZE];
7038 
7039   struct sockaddr_storage myaddr_in;
7040   SOCKET	s_data;
7041   netperf_socklen_t 	addrlen;
7042   struct sockaddr_storage remote_addr;
7043   netperf_socklen_t remote_addrlen;
7044 
7045   int	len = 0;
7046   unsigned int	bytes_received = 0;
7047   float	elapsed_time;
7048 
7049   int	message_size;
7050   unsigned int	messages_recvd = 0;
7051 
7052   struct	udp_stream_request_struct	*udp_stream_request;
7053   struct	udp_stream_response_struct	*udp_stream_response;
7054   struct	udp_stream_results_struct	*udp_stream_results;
7055 
7056   udp_stream_request  =
7057     (struct udp_stream_request_struct *)netperf_request.content.test_specific_data;
7058   udp_stream_response =
7059     (struct udp_stream_response_struct *)netperf_response.content.test_specific_data;
7060   udp_stream_results  =
7061     (struct udp_stream_results_struct *)netperf_response.content.test_specific_data;
7062 
7063   if (debug) {
7064     fprintf(where,"netserver: recv_udp_stream: entered...\n");
7065     fflush(where);
7066   }
7067 
7068   /* We want to set-up the listen socket with all the desired */
7069   /* parameters and then let the initiator know that all is ready. If */
7070   /* socket size defaults are to be used, then the initiator will have */
7071   /* sent us 0's. If the socket sizes cannot be changed, then we will */
7072   /* send-back what they are. If that information cannot be determined, */
7073   /* then we send-back -1's for the sizes. If things go wrong for any */
7074   /* reason, we will drop back ten yards and punt. */
7075 
7076   /* If anything goes wrong, we want the remote to know about it. It */
7077   /* would be best if the error that the remote reports to the user is */
7078   /* the actual error we encountered, rather than some bogus unexpected */
7079   /* response type message. */
7080 
7081   if (debug > 1) {
7082     fprintf(where,"recv_udp_stream: setting the response type...\n");
7083     fflush(where);
7084   }
7085 
7086   netperf_response.content.response_type = UDP_STREAM_RESPONSE;
7087 
7088   if (debug > 2) {
7089     fprintf(where,"recv_udp_stream: the response type is set...\n");
7090     fflush(where);
7091   }
7092 
7093   /* We now alter the message_ptr variable to be at the desired */
7094   /* alignment with the desired offset. */
7095 
7096   if (debug > 1) {
7097     fprintf(where,"recv_udp_stream: requested alignment of %d\n",
7098 	    udp_stream_request->recv_alignment);
7099     fflush(where);
7100   }
7101 
7102   if (recv_width == 0) recv_width = 1;
7103 
7104   recv_ring = allocate_buffer_ring(recv_width,
7105 				   udp_stream_request->message_size,
7106 				   udp_stream_request->recv_alignment,
7107 				   udp_stream_request->recv_offset);
7108 
7109   if (debug > 1) {
7110     fprintf(where,"recv_udp_stream: receive alignment and offset set...\n");
7111     fflush(where);
7112   }
7113 
7114   /* Grab a socket to listen on, and then listen on it. */
7115 
7116   if (debug > 1) {
7117     fprintf(where,"recv_udp_stream: grabbing a socket...\n");
7118     fflush(where);
7119   }
7120 
7121   /* create_data_socket expects to find some things in the global */
7122   /* variables, so set the globals based on the values in the request. */
7123   /* once the socket has been created, we will set the response values */
7124   /* based on the updated value of those globals. raj 7/94 */
7125   lsr_size_req = udp_stream_request->recv_buf_size;
7126   loc_rcvavoid = udp_stream_request->so_rcvavoid;
7127   loc_sndavoid = udp_stream_request->so_sndavoid;
7128   local_connected = udp_stream_request->recv_connected;
7129 
7130   set_hostname_and_port(local_name,
7131 			port_buffer,
7132 			nf_to_af(udp_stream_request->ipfamily),
7133 			udp_stream_request->port);
7134 
7135   local_res = complete_addrinfo(local_name,
7136 				local_name,
7137 				port_buffer,
7138 				nf_to_af(udp_stream_request->ipfamily),
7139 				SOCK_DGRAM,
7140 				IPPROTO_UDP,
7141 				0);
7142 
7143   s_data = create_data_socket(local_res);
7144 
7145   if (s_data == INVALID_SOCKET) {
7146     netperf_response.content.serv_errno = errno;
7147     send_response();
7148     exit(1);
7149   }
7150 
7151   udp_stream_response->test_length = udp_stream_request->test_length;
7152 
7153   /* now get the port number assigned by the system  */
7154   addrlen = sizeof(myaddr_in);
7155   if (getsockname(s_data,
7156 		  (struct sockaddr *)&myaddr_in,
7157 		  &addrlen) == SOCKET_ERROR){
7158     netperf_response.content.serv_errno = errno;
7159     close(s_data);
7160     send_response();
7161 
7162     exit(1);
7163   }
7164 
7165   /* Now myaddr_in contains the port and the internet address this is */
7166   /* returned to the sender also implicitly telling the sender that the */
7167   /* socket buffer sizing has been done. */
7168 
7169   udp_stream_response->data_port_number =
7170     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
7171   netperf_response.content.serv_errno   = 0;
7172 
7173   /* But wait, there's more. If the initiator wanted cpu measurements, */
7174   /* then we must call the calibrate routine, which will return the max */
7175   /* rate back to the initiator. If the CPU was not to be measured, or */
7176   /* something went wrong with the calibration, we will return a -1 to */
7177   /* the initiator. */
7178 
7179   udp_stream_response->cpu_rate    = (float)0.0; /* assume no cpu */
7180   udp_stream_response->measure_cpu = 0;
7181   if (udp_stream_request->measure_cpu) {
7182     /* We will pass the rate into the calibration routine. If the */
7183     /* user did not specify one, it will be 0.0, and we will do a */
7184     /* "real" calibration. Otherwise, all it will really do is */
7185     /* store it away... */
7186     udp_stream_response->measure_cpu = 1;
7187     udp_stream_response->cpu_rate =
7188       calibrate_local_cpu(udp_stream_request->cpu_rate);
7189   }
7190 
7191   message_size	= udp_stream_request->message_size;
7192   test_time	= udp_stream_request->test_length;
7193 
7194   /* before we send the response back to the initiator, pull some of */
7195   /* the socket parms from the globals */
7196   udp_stream_response->send_buf_size = lss_size;
7197   udp_stream_response->recv_buf_size = lsr_size;
7198   udp_stream_response->so_rcvavoid = loc_rcvavoid;
7199   udp_stream_response->so_sndavoid = loc_sndavoid;
7200 
7201   send_response();
7202 
7203   /* Now it's time to start receiving data on the connection. We will */
7204   /* first grab the apropriate counters and then start grabbing. */
7205 
7206   cpu_start(udp_stream_request->measure_cpu);
7207 
7208 #ifdef WIN32
7209   /* this is used so the timer thread can close the socket out from */
7210   /* under us, which to date is the easiest/cleanest/least */
7211   /* Windows-specific way I can find to force the winsock calls to */
7212   /* return WSAEINTR with the test is over. anything that will run on */
7213   /* 95 and NT and is closer to what netperf expects from Unix signals */
7214   /* and such would be appreciated raj 1/96 */
7215   win_kludge_socket = s_data;
7216 #endif /* WIN32 */
7217 
7218   /* The loop will exit when the timer pops, or if we happen to recv a */
7219   /* message of less than send_size bytes... */
7220 
7221   times_up = 0;
7222 
7223   start_timer(test_time + PAD_TIME);
7224 
7225   if (debug) {
7226     fprintf(where,"recv_udp_stream: about to enter inner sanctum.\n");
7227     fflush(where);
7228   }
7229 
7230   /* We "connect" up to the remote post to allow us to use the recv */
7231   /* call instead of the recvfrom call. Presumeably, this is a little */
7232   /* simpler, and a little more efficient. */
7233 
7234   if (local_connected) {
7235 
7236     /* Receive the first message using recvfrom to find the remote address */
7237     remote_addrlen = sizeof(remote_addr);
7238     len = recvfrom(s_data, recv_ring->buffer_ptr,
7239                    message_size, 0,
7240                    (struct sockaddr*)&remote_addr, &remote_addrlen);
7241     if (len != message_size) {
7242       if ((len == SOCKET_ERROR) && !SOCKET_EINTR(len)) {
7243             netperf_response.content.serv_errno = errno;
7244             send_response();
7245             exit(1);
7246       }
7247     }
7248     messages_recvd++;
7249     recv_ring = recv_ring->next;
7250 
7251 
7252     /* Now connect with the remote socket address */
7253     if (connect(s_data,
7254                 (struct sockaddr*)&remote_addr,
7255                 remote_addrlen )== INVALID_SOCKET) {
7256         netperf_response.content.serv_errno = errno;
7257         close(s_data);
7258         send_response();
7259         exit(1);
7260     }
7261 
7262     if (debug) {
7263         fprintf(where,"recv_udp_stream: connected data socket\n");
7264         fflush(where);
7265      }
7266   }
7267 
7268   while (!times_up) {
7269     if(local_connected) {
7270        len = recv(s_data,
7271                   recv_ring->buffer_ptr,
7272                   message_size,
7273                   0);
7274     } else {
7275        len = recvfrom(s_data,
7276                       recv_ring->buffer_ptr,
7277     	              message_size,
7278 		      0,0,0);
7279     }
7280 
7281     if (len != message_size) {
7282       if ((len == SOCKET_ERROR) && !SOCKET_EINTR(len)) {
7283             netperf_response.content.serv_errno = errno;
7284 	    send_response();
7285 	    exit(1);
7286       }
7287       break;
7288     }
7289     messages_recvd++;
7290     recv_ring = recv_ring->next;
7291   }
7292 
7293   if (debug) {
7294     fprintf(where,"recv_udp_stream: got %d messages.\n",messages_recvd);
7295     fflush(where);
7296   }
7297 
7298 
7299   /* The loop now exits due timer or < send_size bytes received. in */
7300   /* reality, we only really support a timed UDP_STREAM test. raj */
7301   /* 12/95 */
7302 
7303   cpu_stop(udp_stream_request->measure_cpu,&elapsed_time);
7304 
7305   if (times_up) {
7306     /* we ended on a timer, subtract the PAD_TIME */
7307     elapsed_time -= (float)PAD_TIME;
7308   }
7309   else {
7310     stop_timer();
7311   }
7312 
7313   if (debug) {
7314     fprintf(where,"recv_udp_stream: test ended in %f seconds.\n",elapsed_time);
7315     fflush(where);
7316   }
7317 
7318 
7319   /* We will count the "off" message that got us out of the loop */
7320   bytes_received = (messages_recvd * message_size) + len;
7321 
7322   /* send the results to the sender			*/
7323 
7324   if (debug) {
7325     fprintf(where,
7326 	    "recv_udp_stream: got %d bytes\n",
7327 	    bytes_received);
7328     fflush(where);
7329   }
7330 
7331   netperf_response.content.response_type	= UDP_STREAM_RESULTS;
7332   udp_stream_results->bytes_received	= bytes_received;
7333   udp_stream_results->messages_recvd	= messages_recvd;
7334   udp_stream_results->elapsed_time	= elapsed_time;
7335   udp_stream_results->cpu_method        = cpu_method;
7336   udp_stream_results->num_cpus          = lib_num_loc_cpus;
7337   if (udp_stream_request->measure_cpu) {
7338     udp_stream_results->cpu_util	= calc_cpu_util(elapsed_time);
7339   }
7340   else {
7341     udp_stream_results->cpu_util	= (float) -1.0;
7342   }
7343 
7344   if (debug > 1) {
7345     fprintf(where,
7346 	    "recv_udp_stream: test complete, sending results.\n");
7347     fflush(where);
7348   }
7349 
7350   send_response();
7351 
7352   close(s_data);
7353 
7354 }
7355 
7356 #ifndef WANT_MIGRATION
7357 void
send_udp_rr(char remote_host[])7358 send_udp_rr(char remote_host[])
7359 {
7360 
7361   char *tput_title = "\
7362 Local /Remote\n\
7363 Socket Size   Request  Resp.   Elapsed  Trans.\n\
7364 Send   Recv   Size     Size    Time     Rate         \n\
7365 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
7366 
7367   char *tput_title_band = "\
7368 Local /Remote\n\
7369 Socket Size   Request  Resp.   Elapsed  \n\
7370 Send   Recv   Size     Size    Time     Throughput \n\
7371 bytes  Bytes  bytes    bytes   secs.    %s/sec   \n\n";
7372 
7373   char *tput_fmt_0 =
7374     "%7.2f %s\n";
7375 
7376   char *tput_fmt_1_line_1 = "\
7377 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   %s\n";
7378 
7379   char *tput_fmt_1_line_2 = "\
7380 %-6d %-6d\n";
7381 
7382   char *cpu_title = "\
7383 Local /Remote\n\
7384 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
7385 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
7386 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
7387 
7388   char *cpu_title_tput = "\
7389 Local /Remote\n\
7390 Socket Size   Request Resp.  Elapsed Tput     CPU    CPU    S.dem   S.dem\n\
7391 Send   Recv   Size    Size   Time    %-8.8s local  remote local   remote\n\
7392 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
7393 
7394   char *cpu_fmt_0 =
7395     "%6.3f %c %s\n";
7396 
7397   char *cpu_fmt_1_line_1 = "\
7398 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f %s\n";
7399 
7400   char *cpu_fmt_1_line_2 = "\
7401 %-6d %-6d\n";
7402 
7403   float			elapsed_time;
7404 
7405   struct ring_elt *send_ring;
7406   struct ring_elt *recv_ring;
7407 
7408   int	len;
7409   int	nummessages;
7410   SOCKET	send_socket;
7411   int	trans_remaining;
7412   int	bytes_xferd;
7413 
7414   int	rsp_bytes_recvd;
7415 
7416   float	local_cpu_utilization;
7417   float	local_service_demand;
7418   float	remote_cpu_utilization;
7419   float	remote_service_demand;
7420   double	thruput;
7421 
7422   struct addrinfo *local_res;
7423   struct addrinfo *remote_res;
7424 
7425   struct	udp_rr_request_struct	*udp_rr_request;
7426   struct	udp_rr_response_struct	*udp_rr_response;
7427   struct	udp_rr_results_struct	*udp_rr_result;
7428 
7429   udp_rr_request  =
7430     (struct udp_rr_request_struct *)netperf_request.content.test_specific_data;
7431   udp_rr_response =
7432     (struct udp_rr_response_struct *)netperf_response.content.test_specific_data;
7433   udp_rr_result	 =
7434     (struct udp_rr_results_struct *)netperf_response.content.test_specific_data;
7435 
7436 #ifdef WANT_HISTOGRAM
7437   if (verbosity > 1) {
7438     time_hist = HIST_new();
7439   }
7440 #endif
7441 
7442   /* since we are now disconnected from the code that established the */
7443   /* control socket, and since we want to be able to use different */
7444   /* protocols and such, we are passed the name of the remote host and */
7445   /* must turn that into the test specific addressing information. */
7446 
7447   complete_addrinfos(&remote_res,
7448 		     &local_res,
7449 		     remote_host,
7450 		     SOCK_DGRAM,
7451 		     IPPROTO_UDP,
7452 		     0);
7453 
7454   if ( print_headers ) {
7455     print_top_test_header("UDP REQUEST/RESPONSE TEST",local_res,remote_res);
7456   }
7457 
7458   /* initialize a few counters */
7459 
7460   send_ring     = NULL;
7461   recv_ring     = NULL;
7462   nummessages	= 0;
7463   bytes_xferd	= 0;
7464   times_up 	= 0;
7465   confidence_iteration = 1;
7466   init_stat();
7467 
7468   /* we have a great-big while loop which controls the number of times */
7469   /* we run a particular test. this is for the calculation of a */
7470   /* confidence interval (I really should have stayed awake during */
7471   /* probstats :). If the user did not request confidence measurement */
7472   /* (no confidence is the default) then we will only go though the */
7473   /* loop once. the confidence stuff originates from the folks at IBM */
7474 
7475   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
7476 	 (confidence_iteration <= iteration_min)) {
7477 
7478     nummessages     = 0;
7479     bytes_xferd     = 0;
7480     times_up        = 0;
7481     trans_remaining = 0;
7482 
7483     /* set-up the data buffers with the requested alignment and offset */
7484 
7485     if (send_width == 0) send_width = 1;
7486     if (recv_width == 0) recv_width = 1;
7487 
7488     if (send_ring == NULL) {
7489       send_ring = allocate_buffer_ring(send_width,
7490 				       req_size,
7491 				       local_send_align,
7492 				       local_send_offset);
7493     }
7494 
7495     if (recv_ring == NULL) {
7496       recv_ring = allocate_buffer_ring(recv_width,
7497 				       rsp_size,
7498 				       local_recv_align,
7499 				       local_recv_offset);
7500     }
7501 
7502     /*set up the data socket                        */
7503     send_socket = create_data_socket(local_res);
7504 
7505     if (send_socket == INVALID_SOCKET){
7506       perror("netperf: send_udp_rr: udp rr data socket");
7507       exit(1);
7508     }
7509 
7510     if (debug) {
7511       fprintf(where,"send_udp_rr: send_socket obtained...\n");
7512     }
7513 
7514     /* If the user has requested cpu utilization measurements, we must */
7515     /* calibrate the cpu(s). We will perform this task within the tests */
7516     /* themselves. If the user has specified the cpu rate, then */
7517     /* calibrate_local_cpu will return rather quickly as it will have */
7518     /* nothing to do. If local_cpu_rate is zero, then we will go through */
7519     /* all the "normal" calibration stuff and return the rate back. If */
7520     /* there is no idle counter in the kernel idle loop, the */
7521     /* local_cpu_rate will be set to -1. */
7522 
7523     if (local_cpu_usage) {
7524       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
7525     }
7526 
7527     if (!no_control) {
7528       /* Tell the remote end to do a listen. The server alters the
7529 	 socket paramters on the other side at this point, hence the
7530 	 reason for all the values being passed in the setup
7531 	 message. If the user did not specify any of the parameters,
7532 	 they will be passed as 0, which will indicate to the remote
7533 	 that no changes beyond the system's default should be
7534 	 used. Alignment is the exception, it will default to 8, which
7535 	 will be no alignment alterations. */
7536 
7537       netperf_request.content.request_type	= DO_UDP_RR;
7538       udp_rr_request->recv_buf_size	= rsr_size_req;
7539       udp_rr_request->send_buf_size	= rss_size_req;
7540       udp_rr_request->recv_alignment      = remote_recv_align;
7541       udp_rr_request->recv_offset	        = remote_recv_offset;
7542       udp_rr_request->send_alignment      = remote_send_align;
7543       udp_rr_request->send_offset	        = remote_send_offset;
7544       udp_rr_request->request_size	= req_size;
7545       udp_rr_request->response_size	= rsp_size;
7546       udp_rr_request->measure_cpu	        = remote_cpu_usage;
7547       udp_rr_request->cpu_rate	        = remote_cpu_rate;
7548       udp_rr_request->so_rcvavoid	        = rem_rcvavoid;
7549       udp_rr_request->so_sndavoid	        = rem_sndavoid;
7550       if (test_time) {
7551 	udp_rr_request->test_length	= test_time;
7552       }
7553       else {
7554 	udp_rr_request->test_length	= test_trans * -1;
7555       }
7556       udp_rr_request->port                = atoi(remote_data_port);
7557       udp_rr_request->ipfamily = af_to_nf(remote_res->ai_family);
7558 
7559       if (debug > 1) {
7560 	fprintf(where,"netperf: send_udp_rr: requesting UDP r/r test\n");
7561       }
7562 
7563       send_request();
7564 
7565       /* The response from the remote will contain all of the relevant
7566 	 socket parameters for this test type. We will put them back
7567 	 into the variables here so they can be displayed if desired.
7568 	 The remote will have calibrated CPU if necessary, and will
7569 	 have done all the needed set-up we will have calibrated the
7570 	 cpu locally before sending the request, and will grab the
7571 	 counter value right after the connect returns. The remote
7572 	 will grab the counter right after the accept call. This saves
7573 	 the hassle of extra messages being sent for the UDP
7574 	 tests.  */
7575 
7576       recv_response();
7577 
7578       if (!netperf_response.content.serv_errno) {
7579 	if (debug)
7580 	  fprintf(where,"remote listen done.\n");
7581 	rsr_size	       =	udp_rr_response->recv_buf_size;
7582 	rss_size	       =	udp_rr_response->send_buf_size;
7583 	remote_cpu_usage =	udp_rr_response->measure_cpu;
7584 	remote_cpu_rate  = 	udp_rr_response->cpu_rate;
7585 	/* port numbers in proper order */
7586 	set_port_number(remote_res,(short)udp_rr_response->data_port_number);
7587       }
7588       else {
7589 	Set_errno(netperf_response.content.serv_errno);
7590 	fprintf(where,
7591 		"netperf: remote error %d",
7592 		netperf_response.content.serv_errno);
7593 	perror("");
7594 	fflush(where);
7595 	exit(1);
7596       }
7597     }
7598 
7599 #ifdef WANT_DEMO
7600     demo_rr_setup(100);
7601 #endif
7602 
7603     /* Connect up to the remote port on the data socket. This will set */
7604     /* the default destination address on this socket. With UDP, this */
7605     /* does make a performance difference as we may not have to do as */
7606     /* many routing lookups, however, I expect that a client would */
7607     /* behave this way. raj 1/94 */
7608 
7609     if ( connect(send_socket,
7610 		 remote_res->ai_addr,
7611 		 remote_res->ai_addrlen) == INVALID_SOCKET ) {
7612       perror("netperf: data socket connect failed");
7613       exit(1);
7614     }
7615 
7616 #ifdef WIN32
7617   /* this is used so the timer thread can close the socket out from */
7618   /* under us, which to date is the easiest/cleanest/least */
7619   /* Windows-specific way I can find to force the winsock calls to */
7620   /* return WSAEINTR with the test is over. anything that will run on */
7621   /* 95 and NT and is closer to what netperf expects from Unix signals */
7622   /* and such would be appreciated raj 1/96 */
7623   win_kludge_socket = send_socket;
7624 #endif /* WIN32 */
7625 
7626     /* Data Socket set-up is finished. If there were problems, either the */
7627     /* connect would have failed, or the previous response would have */
7628     /* indicated a problem. I failed to see the value of the extra */
7629     /* message after the accept on the remote. If it failed, we'll see it */
7630     /* here. If it didn't, we might as well start pumping data. */
7631 
7632     /* Set-up the test end conditions. For a request/response test, they */
7633     /* can be either time or transaction based. */
7634 
7635     if (test_time) {
7636       /* The user wanted to end the test after a period of time. */
7637       times_up = 0;
7638       trans_remaining = 0;
7639       start_timer(test_time);
7640     }
7641     else {
7642       /* The tester wanted to send a number of bytes. */
7643       trans_remaining = test_bytes;
7644       times_up = 1;
7645     }
7646 
7647     /* The cpu_start routine will grab the current time and possibly */
7648     /* value of the idle counter for later use in measuring cpu */
7649     /* utilization and/or service demand and thruput. */
7650 
7651     cpu_start(local_cpu_usage);
7652 
7653 #ifdef WANT_DEMO
7654     if (demo_mode) {
7655       demo_first_timestamp();
7656     }
7657 #endif
7658 
7659 #ifdef WANT_INTERVALS
7660     INTERVALS_INIT();
7661 #endif /* WANT_INTERVALS */
7662 
7663     /* We use an "OR" to control test execution. When the test is */
7664     /* controlled by time, the byte count check will always return */
7665     /* false. When the test is controlled by byte count, the time test */
7666     /* will always return false. When the test is finished, the whole */
7667     /* expression will go false and we will stop sending data. I think */
7668     /* I just arbitrarily decrement trans_remaining for the timed */
7669     /* test, but will not do that just yet... One other question is */
7670     /* whether or not the send buffer and the receive buffer should be */
7671     /* the same buffer. */
7672 
7673 #ifdef WANT_FIRST_BURST
7674     {
7675       int i;
7676       for (i = 0; i < first_burst_size; i++) {
7677 	if((len=send(send_socket,
7678 		     send_ring->buffer_ptr,
7679 		     req_size,
7680 		     0)) != req_size) {
7681 	  /* we should never hit the end of the test in the first burst */
7682 	  perror("send_udp_rr: initial burst data send error");
7683 	  exit(-1);
7684 	}
7685       }
7686     }
7687 #endif /* WANT_FIRST_BURST */
7688 
7689     while ((!times_up) || (trans_remaining > 0)) {
7690       /* send the request */
7691 #ifdef WANT_HISTOGRAM
7692       if (verbosity > 1) {
7693 	HIST_timestamp(&time_one);
7694       }
7695 #endif
7696       if((len=send(send_socket,
7697 		   send_ring->buffer_ptr,
7698 		   req_size,
7699 		   0)) != req_size) {
7700         if (SOCKET_EINTR(len)) {
7701 	      /* We likely hit */
7702 	      /* test-end time. */
7703 	      break;
7704 		}
7705 	    perror("send_udp_rr: data send error");
7706 	    exit(1);
7707 	  }
7708       send_ring = send_ring->next;
7709 
7710       /* receive the response. with UDP we will get it all, or nothing */
7711 
7712       if((rsp_bytes_recvd=recv(send_socket,
7713 			       recv_ring->buffer_ptr,
7714 			       rsp_size,
7715 			       0)) != rsp_size) {
7716 	    if (SOCKET_EINTR(rsp_bytes_recvd))
7717 		{
7718     	  /* Again, we have likely hit test-end time */
7719 	      break;
7720 		}
7721 	    perror("send_udp_rr: data recv error");
7722 	    exit(1);
7723       }
7724       recv_ring = recv_ring->next;
7725 
7726 #ifdef WANT_HISTOGRAM
7727       if (verbosity > 1) {
7728 	HIST_timestamp(&time_two);
7729 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
7730       }
7731 
7732 #endif
7733 
7734       /* at this point, we may wish to sleep for some period of */
7735       /* time, so we see how long that last transaction just took, */
7736       /* and sleep for the difference of that and the interval. We */
7737       /* will not sleep if the time would be less than a */
7738       /* millisecond.  */
7739 
7740 #ifdef WANT_DEMO
7741       demo_rr_interval(1);
7742 #endif
7743 
7744 #ifdef WANT_INTERVALS
7745       INTERVALS_WAIT();
7746 #endif /* WANT_INTERVALS */
7747 
7748       nummessages++;
7749       if (trans_remaining) {
7750 	trans_remaining--;
7751       }
7752 
7753       if (debug > 3) {
7754 	if ((nummessages % 100) == 0) {
7755 	  fprintf(where,"Transaction %d completed\n",nummessages);
7756 	  fflush(where);
7757 	}
7758       }
7759 
7760     }
7761 
7762     /* for some strange reason, I used to call shutdown on the UDP */
7763     /* data socket here. I'm not sure why, because it would not have */
7764     /* any effect... raj 11/94 */
7765 
7766     /* this call will always give us the elapsed time for the test, and */
7767     /* will also store-away the necessaries for cpu utilization */
7768 
7769     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
7770 						/* measured? how long */
7771 						/* did we really run? */
7772 
7773 #if defined(WANT_INTERVALS)
7774 #ifdef WIN32
7775     stop_itimer();
7776 #endif
7777 #endif /* WANT_INTERVALS */
7778 
7779     if (!no_control) {
7780       /* Get the statistics from the remote end. The remote will have
7781 	 calculated service demand and all those interesting
7782 	 things. If it wasn't supposed to care, it will return obvious
7783 	 values. */
7784 
7785       recv_response();
7786       if (!netperf_response.content.serv_errno) {
7787 	if (debug)
7788 	  fprintf(where,"remote results obtained\n");
7789       }
7790       else {
7791 	Set_errno(netperf_response.content.serv_errno);
7792 	fprintf(where,
7793 		"netperf: remote error %d",
7794 		netperf_response.content.serv_errno);
7795 	perror("");
7796 	fflush(where);
7797 	exit(1);
7798       }
7799     }
7800 
7801     /* We now calculate what our thruput was for the test. In the */
7802     /* future, we may want to include a calculation of the thruput */
7803     /* measured by the remote, but it should be the case that for a */
7804     /* UDP rr test, that the two numbers should be *very* close... */
7805     /* We calculate bytes_sent regardless of the way the test length */
7806     /* was controlled.  */
7807 
7808     bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
7809     thruput	= nummessages / elapsed_time;
7810 
7811     if (local_cpu_usage || remote_cpu_usage) {
7812 
7813       /* We must now do a little math for service demand and cpu */
7814       /* utilization for the system(s) Of course, some of the */
7815       /* information might be bogus because there was no idle counter */
7816       /* in the kernel(s). We need to make a note of this for the */
7817       /* user's benefit by placing a code for the metod used in the */
7818       /* test banner */
7819 
7820       if (local_cpu_usage) {
7821 	local_cpu_utilization = calc_cpu_util(0.0);
7822 
7823 	/* since calc_service demand is doing ms/Kunit we will */
7824 	/* multiply the number of transaction by 1024 to get */
7825 	/* "good" numbers */
7826 
7827 	local_service_demand  = calc_service_demand((double) nummessages*1024,
7828 						    0.0,
7829 						    0.0,
7830 						    0);
7831       }
7832       else {
7833 	local_cpu_utilization	= (float) -1.0;
7834 	local_service_demand	= (float) -1.0;
7835       }
7836 
7837       if (remote_cpu_usage) {
7838 	remote_cpu_utilization = udp_rr_result->cpu_util;
7839 
7840 	/* since calc_service demand is doing ms/Kunit we will */
7841 	/* multiply the number of transaction by 1024 to get */
7842 	/* "good" numbers */
7843 
7844 	remote_service_demand  = calc_service_demand((double) nummessages*1024,
7845 						     0.0,
7846 						     remote_cpu_utilization,
7847 						     udp_rr_result->num_cpus);
7848       }
7849       else {
7850 	remote_cpu_utilization = (float) -1.0;
7851 	remote_service_demand  = (float) -1.0;
7852       }
7853     }
7854     else {
7855       /* we were not measuring cpu, for the confidence stuff, we */
7856       /* should make it -1.0 */
7857       local_cpu_utilization	= (float) -1.0;
7858       local_service_demand	= (float) -1.0;
7859       remote_cpu_utilization = (float) -1.0;
7860       remote_service_demand  = (float) -1.0;
7861     }
7862 
7863     /* at this point, we want to calculate the confidence information. */
7864     /* if debugging is on, calculate_confidence will print-out the */
7865     /* parameters we pass it */
7866 
7867     calculate_confidence(confidence_iteration,
7868 			 elapsed_time,
7869 			 thruput,
7870 			 local_cpu_utilization,
7871 			 remote_cpu_utilization,
7872 			 local_service_demand,
7873 			 remote_service_demand);
7874 
7875 
7876     confidence_iteration++;
7877 
7878     /* we are done with the socket */
7879     close(send_socket);
7880   }
7881 
7882   /* at this point, we have made all the iterations we are going to */
7883   /* make. */
7884   retrieve_confident_values(&elapsed_time,
7885 			    &thruput,
7886 			    &local_cpu_utilization,
7887 			    &remote_cpu_utilization,
7888 			    &local_service_demand,
7889 			    &remote_service_demand);
7890 
7891   /* We are now ready to print all the information. If the user */
7892   /* has specified zero-level verbosity, we will just print the */
7893   /* local service demand, or the remote service demand. If the */
7894   /* user has requested verbosity level 1, he will get the basic */
7895   /* "streamperf" numbers. If the user has specified a verbosity */
7896   /* of greater than 1, we will display a veritable plethora of */
7897   /* background information from outside of this block as it it */
7898   /* not cpu_measurement specific...  */
7899 
7900   if (confidence < 0) {
7901     /* we did not hit confidence, but were we asked to look for it? */
7902     if (iteration_max > 1) {
7903       display_confidence();
7904     }
7905   }
7906 
7907   if (local_cpu_usage || remote_cpu_usage) {
7908     local_cpu_method = format_cpu_method(cpu_method);
7909     remote_cpu_method = format_cpu_method(udp_rr_result->cpu_method);
7910 
7911     switch (verbosity) {
7912     case 0:
7913       if (local_cpu_usage) {
7914 	fprintf(where,
7915 		cpu_fmt_0,
7916 		local_service_demand,
7917 		local_cpu_method,
7918                 ((print_headers) ||
7919                  (result_brand == NULL)) ? "" : result_brand);
7920 
7921       }
7922       else {
7923 	fprintf(where,
7924 		cpu_fmt_0,
7925 		remote_service_demand,
7926 		remote_cpu_method,
7927                 ((print_headers) ||
7928                  (result_brand == NULL)) ? "" : result_brand);
7929 
7930       }
7931       break;
7932     case 1:
7933     case 2:
7934       if (print_headers) {
7935         if ('x' == libfmt) {
7936           fprintf(where,
7937                   cpu_title,
7938                   local_cpu_method,
7939                   remote_cpu_method);
7940         }
7941         else {
7942           fprintf(where,
7943                   cpu_title_tput,
7944                   format_units(),
7945                   local_cpu_method,
7946                   remote_cpu_method);
7947         }
7948       }
7949 
7950       fprintf(where,
7951 	      cpu_fmt_1_line_1,		/* the format string */
7952 	      lss_size,		/* local sendbuf size */
7953 	      lsr_size,
7954 	      req_size,		/* how large were the requests */
7955 	      rsp_size,		/* guess */
7956 	      elapsed_time,		/* how long was the test */
7957 	      ('x' == libfmt) ? thruput :
7958 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
7959 									 1.0),
7960 	      local_cpu_utilization,	/* local cpu */
7961 	      remote_cpu_utilization,	/* remote cpu */
7962 	      local_service_demand,	/* local service demand */
7963 	      remote_service_demand,	/* remote service demand */
7964 	      ((print_headers) ||
7965 	       (result_brand == NULL)) ? "" : result_brand);
7966       fprintf(where,
7967 	      cpu_fmt_1_line_2,
7968 	      rss_size,
7969 	      rsr_size);
7970       break;
7971     }
7972   }
7973   else {
7974     /* The tester did not wish to measure service demand. */
7975     switch (verbosity) {
7976     case 0:
7977       fprintf(where,
7978 	      tput_fmt_0,
7979 	      ('x' == libfmt) ? thruput :
7980 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
7981 					 1.0),
7982 	      ((print_headers) ||
7983 	       (result_brand == NULL)) ? "" : result_brand);
7984       break;
7985     case 1:
7986     case 2:
7987       if (print_headers) {
7988 	fprintf(where,
7989 		('x' == libfmt) ? tput_title : tput_title_band,
7990 		format_units());
7991       }
7992 
7993       fprintf(where,
7994 	      tput_fmt_1_line_1,	/* the format string */
7995 	      lss_size,
7996 	      lsr_size,
7997 	      req_size,		/* how large were the requests */
7998 	      rsp_size,		/* how large were the responses */
7999 	      elapsed_time, 		/* how long did it take */
8000 	      ('x' == libfmt) ?  thruput :
8001 	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
8002 					 1.0),
8003 	      ((print_headers) ||
8004 	       (result_brand == NULL)) ? "" : result_brand);
8005       fprintf(where,
8006 	      tput_fmt_1_line_2,
8007 	      rss_size, 		/* remote recvbuf size */
8008 	      rsr_size);
8009 
8010       break;
8011     }
8012   }
8013   fflush(where);
8014 
8015   /* it would be a good thing to include information about some of the */
8016   /* other parameters that may have been set for this test, but at the */
8017   /* moment, I do not wish to figure-out all the  formatting, so I will */
8018   /* just put this comment here to help remind me that it is something */
8019   /* that should be done at a later time. */
8020 
8021   /* how to handle the verbose information in the presence of */
8022   /* confidence intervals is yet to be determined... raj 11/94 */
8023 
8024   if (verbosity > 1) {
8025     /* The user wanted to know it all, so we will give it to him. */
8026     /* This information will include as much as we can find about */
8027     /* UDP statistics, the alignments of the sends and receives */
8028     /* and all that sort of rot... */
8029 
8030 #ifdef WANT_HISTOGRAM
8031     fprintf(where,"\nHistogram of request/reponse times.\n");
8032     fflush(where);
8033     HIST_report(time_hist);
8034 #endif /* WANT_HISTOGRAM */
8035   }
8036 }
8037 #endif /* WANT_MIGRATION */
8038 
8039  /* this routine implements the receive side (netserver) of a UDP_RR */
8040  /* test. */
8041 void
recv_udp_rr()8042 recv_udp_rr()
8043 {
8044 
8045   struct ring_elt *recv_ring;
8046   struct ring_elt *send_ring;
8047 
8048   struct addrinfo *local_res;
8049   char local_name[BUFSIZ];
8050   char port_buffer[PORTBUFSIZE];
8051 
8052   struct sockaddr_storage        myaddr_in;
8053   struct sockaddr_storage    peeraddr;
8054   SOCKET	s_data;
8055   netperf_socklen_t 	addrlen;
8056   int	trans_received;
8057   int	trans_remaining;
8058   int   request_bytes_recvd;
8059   int   response_bytes_sent;
8060   float	elapsed_time;
8061 
8062   struct	udp_rr_request_struct	*udp_rr_request;
8063   struct	udp_rr_response_struct	*udp_rr_response;
8064   struct	udp_rr_results_struct	*udp_rr_results;
8065 
8066   udp_rr_request  =
8067     (struct udp_rr_request_struct *)netperf_request.content.test_specific_data;
8068   udp_rr_response =
8069     (struct udp_rr_response_struct *)netperf_response.content.test_specific_data;
8070   udp_rr_results  =
8071     (struct udp_rr_results_struct *)netperf_response.content.test_specific_data;
8072 
8073   if (debug) {
8074     fprintf(where,"netserver: recv_udp_rr: entered...\n");
8075     fflush(where);
8076   }
8077 
8078   /* We want to set-up the listen socket with all the desired */
8079   /* parameters and then let the initiator know that all is ready. If */
8080   /* socket size defaults are to be used, then the initiator will have */
8081   /* sent us 0's. If the socket sizes cannot be changed, then we will */
8082   /* send-back what they are. If that information cannot be determined, */
8083   /* then we send-back -1's for the sizes. If things go wrong for any */
8084   /* reason, we will drop back ten yards and punt. */
8085 
8086   /* If anything goes wrong, we want the remote to know about it. It */
8087   /* would be best if the error that the remote reports to the user is */
8088   /* the actual error we encountered, rather than some bogus unexpected */
8089   /* response type message. */
8090 
8091   if (debug) {
8092     fprintf(where,"recv_udp_rr: setting the response type...\n");
8093     fflush(where);
8094   }
8095 
8096   netperf_response.content.response_type = UDP_RR_RESPONSE;
8097 
8098   if (debug) {
8099     fprintf(where,"recv_udp_rr: the response type is set...\n");
8100     fflush(where);
8101   }
8102 
8103   /* We now alter the message_ptr variables to be at the desired */
8104   /* alignments with the desired offsets. */
8105 
8106   if (debug) {
8107     fprintf(where,"recv_udp_rr: requested recv alignment of %d offset %d\n",
8108 	    udp_rr_request->recv_alignment,
8109 	    udp_rr_request->recv_offset);
8110     fprintf(where,"recv_udp_rr: requested send alignment of %d offset %d\n",
8111 	    udp_rr_request->send_alignment,
8112 	    udp_rr_request->send_offset);
8113     fflush(where);
8114   }
8115 
8116   if (send_width == 0) send_width = 1;
8117   if (recv_width == 0) recv_width = 1;
8118 
8119   recv_ring = allocate_buffer_ring(recv_width,
8120 				   udp_rr_request->request_size,
8121 				   udp_rr_request->recv_alignment,
8122 				   udp_rr_request->recv_offset);
8123 
8124   send_ring = allocate_buffer_ring(send_width,
8125 				   udp_rr_request->response_size,
8126 				   udp_rr_request->send_alignment,
8127 				   udp_rr_request->send_offset);
8128 
8129   if (debug) {
8130     fprintf(where,"recv_udp_rr: receive alignment and offset set...\n");
8131     fflush(where);
8132   }
8133 
8134   /* Grab a socket to listen on, and then listen on it. */
8135 
8136   if (debug) {
8137     fprintf(where,"recv_udp_rr: grabbing a socket...\n");
8138     fflush(where);
8139   }
8140 
8141 
8142   /* create_data_socket expects to find some things in the global */
8143   /* variables, so set the globals based on the values in the request. */
8144   /* once the socket has been created, we will set the response values */
8145   /* based on the updated value of those globals. raj 7/94 */
8146   lss_size_req = udp_rr_request->send_buf_size;
8147   lsr_size_req = udp_rr_request->recv_buf_size;
8148   loc_rcvavoid = udp_rr_request->so_rcvavoid;
8149   loc_sndavoid = udp_rr_request->so_sndavoid;
8150 
8151   set_hostname_and_port(local_name,
8152 			port_buffer,
8153 			nf_to_af(udp_rr_request->ipfamily),
8154 			udp_rr_request->port);
8155 
8156   local_res = complete_addrinfo(local_name,
8157 				local_name,
8158 				port_buffer,
8159 				nf_to_af(udp_rr_request->ipfamily),
8160 				SOCK_DGRAM,
8161 				IPPROTO_UDP,
8162 				0);
8163 
8164   s_data = create_data_socket(local_res);
8165 
8166   if (s_data == INVALID_SOCKET) {
8167     netperf_response.content.serv_errno = errno;
8168     send_response();
8169 
8170     exit(1);
8171   }
8172 
8173   /* now get the port number assigned by the system  */
8174   addrlen = sizeof(myaddr_in);
8175   if (getsockname(s_data,
8176 		  (struct sockaddr *)&myaddr_in,
8177 		  &addrlen) == SOCKET_ERROR){
8178     netperf_response.content.serv_errno = errno;
8179     close(s_data);
8180     send_response();
8181 
8182     exit(1);
8183   }
8184 
8185   /* Now myaddr_in contains the port and the internet address this is */
8186   /* returned to the sender also implicitly telling the sender that the */
8187   /* socket buffer sizing has been done. */
8188 
8189   udp_rr_response->data_port_number =
8190     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
8191   netperf_response.content.serv_errno   = 0;
8192 
8193   if (debug) {
8194     fprintf(where,
8195 	    "recv port number %d\n",
8196 	    ((struct sockaddr_in *)&myaddr_in)->sin_port);
8197     fflush(where);
8198   }
8199 
8200   /* But wait, there's more. If the initiator wanted cpu measurements, */
8201   /* then we must call the calibrate routine, which will return the max */
8202   /* rate back to the initiator. If the CPU was not to be measured, or */
8203   /* something went wrong with the calibration, we will return a 0.0 to */
8204   /* the initiator. */
8205 
8206   udp_rr_response->cpu_rate    = (float)0.0; 	/* assume no cpu */
8207   udp_rr_response->measure_cpu = 0;
8208   if (udp_rr_request->measure_cpu) {
8209     udp_rr_response->measure_cpu = 1;
8210     udp_rr_response->cpu_rate = calibrate_local_cpu(udp_rr_request->cpu_rate);
8211   }
8212 
8213   /* before we send the response back to the initiator, pull some of */
8214   /* the socket parms from the globals */
8215   udp_rr_response->send_buf_size = lss_size;
8216   udp_rr_response->recv_buf_size = lsr_size;
8217   udp_rr_response->so_rcvavoid   = loc_rcvavoid;
8218   udp_rr_response->so_sndavoid   = loc_sndavoid;
8219 
8220   send_response();
8221 
8222 
8223   /* Now it's time to start receiving data on the connection. We will */
8224   /* first grab the apropriate counters and then start grabbing. */
8225 
8226   cpu_start(udp_rr_request->measure_cpu);
8227 
8228 #ifdef WIN32
8229   /* this is used so the timer thread can close the socket out from */
8230   /* under us, which to date is the easiest/cleanest/least */
8231   /* Windows-specific way I can find to force the winsock calls to */
8232   /* return WSAEINTR with the test is over. anything that will run on */
8233   /* 95 and NT and is closer to what netperf expects from Unix signals */
8234   /* and such would be appreciated raj 1/96 */
8235   win_kludge_socket = s_data;
8236 #endif /* WIN32 */
8237 
8238   if (udp_rr_request->test_length > 0) {
8239     times_up = 0;
8240     trans_remaining = 0;
8241     start_timer(udp_rr_request->test_length + PAD_TIME);
8242   }
8243   else {
8244     times_up = 1;
8245     trans_remaining = udp_rr_request->test_length * -1;
8246   }
8247 
8248   addrlen = sizeof(peeraddr);
8249   bzero((char *)&peeraddr, addrlen);
8250 
8251   trans_received = 0;
8252 
8253   while ((!times_up) || (trans_remaining > 0)) {
8254 
8255     /* receive the request from the other side */
8256     if ((request_bytes_recvd = recvfrom(s_data,
8257 		 recv_ring->buffer_ptr,
8258 		 udp_rr_request->request_size,
8259 		 0,
8260 		 (struct sockaddr *)&peeraddr,
8261 		 &addrlen)) != udp_rr_request->request_size) {
8262 	  if ( SOCKET_EINTR(request_bytes_recvd) )
8263 	  {
8264 	    /* we must have hit the end of test time. */
8265 	    break;
8266       }
8267       netperf_response.content.serv_errno = errno;
8268       send_response();
8269       exit(1);
8270     }
8271     recv_ring = recv_ring->next;
8272 
8273     /* Now, send the response to the remote */
8274     if ((response_bytes_sent = sendto(s_data,
8275 				      send_ring->buffer_ptr,
8276 				      udp_rr_request->response_size,
8277 				      0,
8278 				      (struct sockaddr *)&peeraddr,
8279 				      addrlen)) !=
8280 	udp_rr_request->response_size) {
8281       if ( SOCKET_EINTR(response_bytes_sent) )
8282 	  {
8283 	    /* we have hit end of test time. */
8284 	    break;
8285       }
8286       netperf_response.content.serv_errno = errno;
8287       send_response();
8288       exit(1);
8289     }
8290     send_ring = send_ring->next;
8291 
8292     trans_received++;
8293     if (trans_remaining) {
8294       trans_remaining--;
8295     }
8296 
8297     if (debug) {
8298       fprintf(where,
8299 	      "recv_udp_rr: Transaction %d complete.\n",
8300 	      trans_received);
8301       fflush(where);
8302     }
8303 
8304   }
8305 
8306 
8307   /* The loop now exits due to timeout or transaction count being */
8308   /* reached */
8309 
8310   cpu_stop(udp_rr_request->measure_cpu,&elapsed_time);
8311 
8312   if (times_up) {
8313     /* we ended the test by time, which was at least 2 seconds */
8314     /* longer than we wanted to run. so, we want to subtract */
8315     /* PAD_TIME from the elapsed_time. */
8316     elapsed_time -= PAD_TIME;
8317   }
8318   /* send the results to the sender			*/
8319 
8320   if (debug) {
8321     fprintf(where,
8322 	    "recv_udp_rr: got %d transactions\n",
8323 	    trans_received);
8324     fflush(where);
8325   }
8326 
8327   udp_rr_results->bytes_received = (trans_received *
8328 				    (udp_rr_request->request_size +
8329 				     udp_rr_request->response_size));
8330   udp_rr_results->trans_received = trans_received;
8331   udp_rr_results->elapsed_time	 = elapsed_time;
8332   udp_rr_results->cpu_method     = cpu_method;
8333   udp_rr_results->num_cpus       = lib_num_loc_cpus;
8334   if (udp_rr_request->measure_cpu) {
8335     udp_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
8336   }
8337 
8338   if (debug) {
8339     fprintf(where,
8340 	    "recv_udp_rr: test complete, sending results.\n");
8341     fflush(where);
8342   }
8343 
8344   send_response();
8345 
8346   /* we are done with the socket now */
8347   close(s_data);
8348 
8349       }
8350 
8351 
8352  /* this routine implements the receive (netserver) side of a TCP_RR */
8353  /* test */
8354 void
recv_tcp_rr()8355 recv_tcp_rr()
8356 {
8357 
8358   struct ring_elt *send_ring;
8359   struct ring_elt *recv_ring;
8360 
8361   struct addrinfo *local_res;
8362   char local_name[BUFSIZ];
8363   char port_buffer[PORTBUFSIZE];
8364 
8365   struct	sockaddr_storage        myaddr_in,
8366   peeraddr_in;
8367   SOCKET	s_listen,s_data;
8368   netperf_socklen_t 	addrlen;
8369   char	*temp_message_ptr;
8370   int	trans_received;
8371   int	trans_remaining;
8372   int	bytes_sent;
8373   int	request_bytes_recvd;
8374   int	request_bytes_remaining;
8375   int	timed_out = 0;
8376   int   sock_closed = 0;
8377   float	elapsed_time;
8378 
8379   struct	tcp_rr_request_struct	*tcp_rr_request;
8380   struct	tcp_rr_response_struct	*tcp_rr_response;
8381   struct	tcp_rr_results_struct	*tcp_rr_results;
8382 
8383   tcp_rr_request =
8384     (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data;
8385   tcp_rr_response =
8386     (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data;
8387   tcp_rr_results =
8388     (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data;
8389 
8390   if (debug) {
8391     fprintf(where,"netserver: recv_tcp_rr: entered...\n");
8392     fflush(where);
8393   }
8394 
8395   /* We want to set-up the listen socket with all the desired */
8396   /* parameters and then let the initiator know that all is ready. If */
8397   /* socket size defaults are to be used, then the initiator will have */
8398   /* sent us 0's. If the socket sizes cannot be changed, then we will */
8399   /* send-back what they are. If that information cannot be determined, */
8400   /* then we send-back -1's for the sizes. If things go wrong for any */
8401   /* reason, we will drop back ten yards and punt. */
8402 
8403   /* If anything goes wrong, we want the remote to know about it. It */
8404   /* would be best if the error that the remote reports to the user is */
8405   /* the actual error we encountered, rather than some bogus unexpected */
8406   /* response type message. */
8407 
8408   if (debug) {
8409     fprintf(where,"recv_tcp_rr: setting the response type...\n");
8410     fflush(where);
8411   }
8412 
8413   netperf_response.content.response_type = TCP_RR_RESPONSE;
8414 
8415   if (debug) {
8416     fprintf(where,"recv_tcp_rr: the response type is set...\n");
8417     fflush(where);
8418   }
8419 
8420   /* allocate the recv and send rings with the requested alignments */
8421   /* and offsets. raj 7/94 */
8422   if (debug) {
8423     fprintf(where,"recv_tcp_rr: requested recv alignment of %d offset %d\n",
8424 	    tcp_rr_request->recv_alignment,
8425 	    tcp_rr_request->recv_offset);
8426     fprintf(where,"recv_tcp_rr: requested send alignment of %d offset %d\n",
8427 	    tcp_rr_request->send_alignment,
8428 	    tcp_rr_request->send_offset);
8429     fflush(where);
8430   }
8431 
8432   /* at some point, these need to come to us from the remote system */
8433   if (send_width == 0) send_width = 1;
8434   if (recv_width == 0) recv_width = 1;
8435 
8436   send_ring = allocate_buffer_ring(send_width,
8437 				   tcp_rr_request->response_size,
8438 				   tcp_rr_request->send_alignment,
8439 				   tcp_rr_request->send_offset);
8440 
8441   recv_ring = allocate_buffer_ring(recv_width,
8442 				   tcp_rr_request->request_size,
8443 				   tcp_rr_request->recv_alignment,
8444 				   tcp_rr_request->recv_offset);
8445 
8446 
8447   /* Grab a socket to listen on, and then listen on it. */
8448 
8449   if (debug) {
8450     fprintf(where,"recv_tcp_rr: grabbing a socket...\n");
8451     fflush(where);
8452   }
8453 
8454   /* create_data_socket expects to find some things in the global */
8455   /* variables, so set the globals based on the values in the request. */
8456   /* once the socket has been created, we will set the response values */
8457   /* based on the updated value of those globals. raj 7/94 */
8458   lss_size_req = tcp_rr_request->send_buf_size;
8459   lsr_size_req = tcp_rr_request->recv_buf_size;
8460   loc_nodelay = tcp_rr_request->no_delay;
8461   loc_rcvavoid = tcp_rr_request->so_rcvavoid;
8462   loc_sndavoid = tcp_rr_request->so_sndavoid;
8463 
8464   set_hostname_and_port(local_name,
8465 			port_buffer,
8466 			nf_to_af(tcp_rr_request->ipfamily),
8467 			tcp_rr_request->port);
8468 
8469   local_res = complete_addrinfo(local_name,
8470 				local_name,
8471 				port_buffer,
8472 				nf_to_af(tcp_rr_request->ipfamily),
8473 				SOCK_STREAM,
8474 				IPPROTO_TCP,
8475 				0);
8476 
8477   s_listen = create_data_socket(local_res);
8478 
8479   if (s_listen == INVALID_SOCKET) {
8480     netperf_response.content.serv_errno = errno;
8481     send_response();
8482 
8483     exit(1);
8484   }
8485 
8486 
8487 #ifdef WIN32
8488   /* The test timer can fire during operations on the listening socket,
8489      so to make the start_timer below work we have to move
8490      it to close s_listen while we are blocked on accept. */
8491   win_kludge_socket2 = s_listen;
8492 #endif
8493 
8494 
8495   /* Now, let's set-up the socket to listen for connections */
8496   if (listen(s_listen, 5) == SOCKET_ERROR) {
8497     netperf_response.content.serv_errno = errno;
8498     close(s_listen);
8499     send_response();
8500 
8501     exit(1);
8502   }
8503 
8504 
8505   /* now get the port number assigned by the system  */
8506   addrlen = sizeof(myaddr_in);
8507   if (getsockname(s_listen,
8508 		  (struct sockaddr *)&myaddr_in,
8509 		  &addrlen) == SOCKET_ERROR) {
8510     netperf_response.content.serv_errno = errno;
8511     close(s_listen);
8512     send_response();
8513 
8514     exit(1);
8515   }
8516 
8517   /* Now myaddr_in contains the port and the internet address this is */
8518   /* returned to the sender also implicitly telling the sender that the */
8519   /* socket buffer sizing has been done. */
8520 
8521   tcp_rr_response->data_port_number =
8522     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
8523   netperf_response.content.serv_errno   = 0;
8524 
8525   /* But wait, there's more. If the initiator wanted cpu measurements, */
8526   /* then we must call the calibrate routine, which will return the max */
8527   /* rate back to the initiator. If the CPU was not to be measured, or */
8528   /* something went wrong with the calibration, we will return a 0.0 to */
8529   /* the initiator. */
8530 
8531   tcp_rr_response->cpu_rate = (float)0.0; 	/* assume no cpu */
8532   tcp_rr_response->measure_cpu = 0;
8533 
8534   if (tcp_rr_request->measure_cpu) {
8535     tcp_rr_response->measure_cpu = 1;
8536     tcp_rr_response->cpu_rate = calibrate_local_cpu(tcp_rr_request->cpu_rate);
8537   }
8538 
8539 
8540   /* before we send the response back to the initiator, pull some of */
8541   /* the socket parms from the globals */
8542   tcp_rr_response->send_buf_size = lss_size;
8543   tcp_rr_response->recv_buf_size = lsr_size;
8544   tcp_rr_response->no_delay = loc_nodelay;
8545   tcp_rr_response->so_rcvavoid = loc_rcvavoid;
8546   tcp_rr_response->so_sndavoid = loc_sndavoid;
8547   tcp_rr_response->test_length = tcp_rr_request->test_length;
8548   send_response();
8549 
8550   addrlen = sizeof(peeraddr_in);
8551 
8552   if ((s_data = accept(s_listen,
8553 		       (struct sockaddr *)&peeraddr_in,
8554 		       &addrlen)) == INVALID_SOCKET) {
8555     /* Let's just punt. The remote will be given some information */
8556     close(s_listen);
8557 
8558     exit(1);
8559   }
8560 
8561 #ifdef KLUDGE_SOCKET_OPTIONS
8562   /* this is for those systems which *INCORRECTLY* fail to pass */
8563   /* attributes across an accept() call. Including this goes against */
8564   /* my better judgement :( raj 11/95 */
8565 
8566   kludge_socket_options(s_data);
8567 
8568 #endif /* KLUDGE_SOCKET_OPTIONS */
8569 
8570 #ifdef WIN32
8571   /* this is used so the timer thread can close the socket out from */
8572   /* under us, which to date is the easiest/cleanest/least */
8573   /* Windows-specific way I can find to force the winsock calls to */
8574   /* return WSAEINTR with the test is over. anything that will run on */
8575   /* 95 and NT and is closer to what netperf expects from Unix signals */
8576   /* and such would be appreciated raj 1/96 */
8577   win_kludge_socket = s_data;
8578   win_kludge_socket2 = INVALID_SOCKET;
8579 #endif /* WIN32 */
8580 
8581   if (debug) {
8582     fprintf(where,"recv_tcp_rr: accept completes on the data connection.\n");
8583     fflush(where);
8584   }
8585 
8586   /* Now it's time to start receiving data on the connection. We will */
8587   /* first grab the apropriate counters and then start grabbing. */
8588 
8589   cpu_start(tcp_rr_request->measure_cpu);
8590 
8591   /* The loop will exit when we hit the end of the test time, or when */
8592   /* we have exchanged the requested number of transactions. */
8593 
8594   if (tcp_rr_request->test_length > 0) {
8595     times_up = 0;
8596     trans_remaining = 0;
8597     start_timer(tcp_rr_request->test_length + PAD_TIME);
8598   }
8599   else {
8600     times_up = 1;
8601     trans_remaining = tcp_rr_request->test_length * -1;
8602   }
8603 
8604   trans_received = 0;
8605 
8606   while ((!times_up) || (trans_remaining > 0)) {
8607     temp_message_ptr = recv_ring->buffer_ptr;
8608     request_bytes_remaining	= tcp_rr_request->request_size;
8609     while(request_bytes_remaining > 0) {
8610       if((request_bytes_recvd=recv(s_data,
8611 				   temp_message_ptr,
8612 				   request_bytes_remaining,
8613 				   0)) == SOCKET_ERROR) {
8614 	if (SOCKET_EINTR(request_bytes_recvd))
8615 	{
8616 	  timed_out = 1;
8617 	  break;
8618 	}
8619 
8620 	netperf_response.content.serv_errno = errno;
8621 	send_response();
8622 	exit(1);
8623       }
8624       else if( request_bytes_recvd == 0 ) {
8625 	if (debug) {
8626 	  fprintf(where,"zero is my hero\n");
8627 	  fflush(where);
8628 	}
8629 	sock_closed = 1;
8630 	break;
8631       }
8632       else {
8633 	request_bytes_remaining -= request_bytes_recvd;
8634 	temp_message_ptr  += request_bytes_recvd;
8635       }
8636     }
8637 
8638     recv_ring = recv_ring->next;
8639 
8640     if ((timed_out) || (sock_closed)) {
8641       /* we hit the end of the test based on time - or the socket
8642 	 closed on us along the way.  bail out of here now... */
8643       if (debug) {
8644 	fprintf(where,"yo5\n");
8645 	fflush(where);
8646       }
8647       break;
8648     }
8649 
8650     /* Now, send the response to the remote */
8651     if((bytes_sent=send(s_data,
8652 			send_ring->buffer_ptr,
8653 			tcp_rr_request->response_size,
8654 			0)) == SOCKET_ERROR) {
8655       if (SOCKET_EINTR(bytes_sent)) {
8656 	/* the test timer has popped */
8657 	timed_out = 1;
8658 	fprintf(where,"yo6\n");
8659 	fflush(where);
8660 	break;
8661       }
8662       netperf_response.content.serv_errno = 992;
8663       send_response();
8664       exit(1);
8665     }
8666 
8667     send_ring = send_ring->next;
8668 
8669     trans_received++;
8670     if (trans_remaining) {
8671       trans_remaining--;
8672     }
8673   }
8674 
8675 
8676   /* The loop now exits due to timeout or transaction count being */
8677   /* reached */
8678 
8679   cpu_stop(tcp_rr_request->measure_cpu,&elapsed_time);
8680 
8681   stop_timer();
8682 
8683   if (timed_out) {
8684     /* we ended the test by time, which was at least 2 seconds */
8685     /* longer than we wanted to run. so, we want to subtract */
8686     /* PAD_TIME from the elapsed_time. */
8687     elapsed_time -= PAD_TIME;
8688   }
8689 
8690   /* send the results to the sender			*/
8691 
8692   if (debug) {
8693     fprintf(where,
8694 	    "recv_tcp_rr: got %d transactions\n",
8695 	    trans_received);
8696     fflush(where);
8697   }
8698 
8699   tcp_rr_results->bytes_received = (trans_received *
8700 				    (tcp_rr_request->request_size +
8701 				     tcp_rr_request->response_size));
8702   tcp_rr_results->trans_received = trans_received;
8703   tcp_rr_results->elapsed_time   = elapsed_time;
8704   tcp_rr_results->cpu_method     = cpu_method;
8705   tcp_rr_results->num_cpus       = lib_num_loc_cpus;
8706   if (tcp_rr_request->measure_cpu) {
8707     tcp_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
8708   }
8709 
8710   if (debug) {
8711     fprintf(where,
8712 	    "recv_tcp_rr: test complete, sending results.\n");
8713     fflush(where);
8714   }
8715 
8716   /* we are now done with the sockets */
8717   close(s_data);
8718   close(s_listen);
8719 
8720   send_response();
8721 
8722 }
8723 
8724 
8725 void
loc_cpu_rate()8726 loc_cpu_rate()
8727 {
8728 #if defined(USE_LOOPER)
8729   float dummy;
8730 #endif
8731 
8732   /* a rather simple little test - it merely calibrates the local cpu */
8733   /* and prints the results. There are no headers to allow someone to */
8734   /* find a rate and use it in other tests automagically by setting a */
8735   /* variable equal to the output of this test. We ignore any rates */
8736   /* that may have been specified. In fact, we ignore all of the */
8737   /* command line args! */
8738 
8739   fprintf(where,
8740 	  "%g",
8741 	  calibrate_local_cpu(0.0));
8742 
8743   if (verbosity > 1)
8744     fprintf(where,
8745 	    "\nThere %s %d local %s\n",
8746 	    (lib_num_loc_cpus > 1) ? "are" : "is",
8747 	    lib_num_loc_cpus,
8748 	    (lib_num_loc_cpus > 1) ? "cpus" : "cpu");
8749 
8750   /* we need the cpu_start, cpu_stop in the looper case to kill the */
8751   /* child proceses raj 4/95 */
8752 
8753 #ifdef USE_LOOPER
8754   cpu_start(1);
8755   cpu_stop(1,&dummy);
8756 #endif /* USE_LOOPER */
8757 
8758 }
8759 
8760 void
rem_cpu_rate()8761 rem_cpu_rate()
8762 {
8763   /* this test is much like the local variant, except that it works for */
8764   /* the remote system, so in this case, we do pay attention to the */
8765   /* value of the '-H' command line argument. */
8766 
8767   fprintf(where,
8768 	  "%g",
8769 	  calibrate_remote_cpu());
8770 
8771   if (verbosity > 1)
8772     fprintf(where,
8773 	    "\nThere %s %d remote %s\n",
8774 	    (lib_num_rem_cpus > 1) ? "are" : "is",
8775 	    lib_num_rem_cpus,
8776 	    (lib_num_rem_cpus > 1) ? "cpus" : "cpu");
8777 
8778 }
8779 
8780 
8781 #ifndef WANT_MIGRATION
8782  /* this test is intended to test the performance of establishing a
8783     connection, exchanging a request/response pair, and repeating. it
8784     is expected that this would be a good starting-point for
8785     comparision of T/TCP with classic TCP for transactional workloads.
8786     it will also look (can look) much like the communication pattern
8787     of http for www access. */
8788 
8789 void
send_tcp_conn_rr(char remote_host[])8790 send_tcp_conn_rr(char remote_host[])
8791 {
8792 
8793   char *tput_title = "\
8794 Local /Remote\n\
8795 Socket Size   Request  Resp.   Elapsed  Trans.\n\
8796 Send   Recv   Size     Size    Time     Rate         \n\
8797 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
8798 
8799   char *tput_fmt_0 =
8800     "%7.2f\n";
8801 
8802   char *tput_fmt_1_line_1 = "\
8803 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
8804   char *tput_fmt_1_line_2 = "\
8805 %-6d %-6d\n";
8806 
8807   char *cpu_title = "\
8808 Local /Remote\n\
8809 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
8810 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
8811 bytes  bytes  bytes   bytes  secs.   per sec  %%      %%      us/Tr   us/Tr\n\n";
8812 
8813   char *cpu_fmt_0 =
8814     "%6.3f\n";
8815 
8816   char *cpu_fmt_1_line_1 = "\
8817 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f\n";
8818 
8819   char *cpu_fmt_1_line_2 = "\
8820 %-6d %-6d\n";
8821 
8822   char *ksink_fmt = "\n\
8823 Alignment      Offset\n\
8824 Local  Remote  Local  Remote\n\
8825 Send   Recv    Send   Recv\n\
8826 %5d  %5d   %5d  %5d\n";
8827 
8828 
8829   int			timed_out = 0;
8830   float			elapsed_time;
8831 
8832   int	len;
8833   struct ring_elt *send_ring;
8834   struct ring_elt *recv_ring;
8835   char	*temp_message_ptr;
8836   int	nummessages;
8837   SOCKET	send_socket;
8838   int	trans_remaining;
8839   double	bytes_xferd;
8840   int	rsp_bytes_left;
8841   int	rsp_bytes_recvd;
8842 
8843   float	local_cpu_utilization;
8844   float	local_service_demand;
8845   float	remote_cpu_utilization;
8846   float	remote_service_demand;
8847   double	thruput;
8848 
8849   struct addrinfo *local_res;
8850   struct addrinfo *remote_res;
8851 
8852   int                           myport;
8853   int                           ret;
8854 
8855   struct	tcp_conn_rr_request_struct	*tcp_conn_rr_request;
8856   struct	tcp_conn_rr_response_struct	*tcp_conn_rr_response;
8857   struct	tcp_conn_rr_results_struct	*tcp_conn_rr_result;
8858 
8859   tcp_conn_rr_request =
8860     (struct tcp_conn_rr_request_struct *)netperf_request.content.test_specific_data;
8861   tcp_conn_rr_response =
8862     (struct tcp_conn_rr_response_struct *)netperf_response.content.test_specific_data;
8863   tcp_conn_rr_result =
8864     (struct tcp_conn_rr_results_struct *)netperf_response.content.test_specific_data;
8865 
8866 
8867 #ifdef WANT_HISTOGRAM
8868   if (verbosity > 1) {
8869     time_hist = HIST_new();
8870   }
8871 #endif /* WANT_HISTOGRAM */
8872 
8873   /* since we are now disconnected from the code that established the */
8874   /* control socket, and since we want to be able to use different */
8875   /* protocols and such, we are passed the name of the remote host and */
8876   /* must turn that into the test specific addressing information. */
8877 
8878   complete_addrinfos(&remote_res,
8879 		     &local_res,
8880 		     remote_host,
8881 		     SOCK_STREAM,
8882 		     IPPROTO_TCP,
8883 		     0);
8884 
8885   if ( print_headers ) {
8886     print_top_test_header("TCP Connect/Request/Response TEST",local_res,remote_res);
8887   }
8888 
8889   /* initialize a few counters */
8890 
8891   nummessages	=	0;
8892   bytes_xferd	=	0.0;
8893   times_up 	= 	0;
8894 
8895   /* set-up the data buffers with the requested alignment and offset */
8896   if (send_width == 0) send_width = 1;
8897   if (recv_width == 0) recv_width = 1;
8898 
8899   send_ring = allocate_buffer_ring(send_width,
8900 				   req_size,
8901 				   local_send_align,
8902 				   local_send_offset);
8903 
8904   recv_ring = allocate_buffer_ring(recv_width,
8905 				   rsp_size,
8906 				   local_recv_align,
8907 				   local_recv_offset);
8908 
8909 
8910   if (debug) {
8911     fprintf(where,"send_tcp_conn_rr: send_socket obtained...\n");
8912   }
8913 
8914   /* If the user has requested cpu utilization measurements, we must */
8915   /* calibrate the cpu(s). We will perform this task within the tests */
8916   /* themselves. If the user has specified the cpu rate, then */
8917   /* calibrate_local_cpu will return rather quickly as it will have */
8918   /* nothing to do. If local_cpu_rate is zero, then we will go through */
8919   /* all the "normal" calibration stuff and return the rate back.*/
8920 
8921   if (local_cpu_usage) {
8922     local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
8923   }
8924 
8925   if (!no_control) {
8926 
8927     /* Tell the remote end to do a listen. The server alters the
8928        socket paramters on the other side at this point, hence the
8929        reason for all the values being passed in the setup message. If
8930        the user did not specify any of the parameters, they will be
8931        passed as 0, which will indicate to the remote that no changes
8932        beyond the system's default should be used. Alignment is the
8933        exception, it will default to 8, which will be no alignment
8934        alterations. */
8935 
8936     netperf_request.content.request_type =	DO_TCP_CRR;
8937     tcp_conn_rr_request->recv_buf_size	=	rsr_size_req;
8938     tcp_conn_rr_request->send_buf_size	=	rss_size_req;
8939     tcp_conn_rr_request->recv_alignment	=	remote_recv_align;
8940     tcp_conn_rr_request->recv_offset	=	remote_recv_offset;
8941     tcp_conn_rr_request->send_alignment	=	remote_send_align;
8942     tcp_conn_rr_request->send_offset	=	remote_send_offset;
8943     tcp_conn_rr_request->request_size	=	req_size;
8944     tcp_conn_rr_request->response_size	=	rsp_size;
8945     tcp_conn_rr_request->no_delay	=	rem_nodelay;
8946     tcp_conn_rr_request->measure_cpu	=	remote_cpu_usage;
8947     tcp_conn_rr_request->cpu_rate	=	remote_cpu_rate;
8948     tcp_conn_rr_request->so_rcvavoid	=	rem_rcvavoid;
8949     tcp_conn_rr_request->so_sndavoid	=	rem_sndavoid;
8950     if (test_time) {
8951       tcp_conn_rr_request->test_length	=	test_time;
8952     }
8953     else {
8954       tcp_conn_rr_request->test_length	=	test_trans * -1;
8955     }
8956     tcp_conn_rr_request->port           = atoi(remote_data_port);
8957     tcp_conn_rr_request->ipfamily       = af_to_nf(remote_res->ai_family);
8958 
8959     if (debug > 1) {
8960       fprintf(where,"netperf: send_tcp_conn_rr: requesting TCP crr test\n");
8961     }
8962 
8963     send_request();
8964 
8965     /* The response from the remote will contain all of the relevant
8966        socket parameters for this test type. We will put them back
8967        into the variables here so they can be displayed if desired.
8968        The remote will have calibrated CPU if necessary, and will have
8969        done all the needed set-up we will have calibrated the cpu
8970        locally before sending the request, and will grab the counter
8971        value right after the connect returns. The remote will grab the
8972        counter right after the accept call. This saves the hassle of
8973        extra messages being sent for the TCP tests.  */
8974 
8975     recv_response();
8976 
8977     if (!netperf_response.content.serv_errno) {
8978       rsr_size	       =	tcp_conn_rr_response->recv_buf_size;
8979       rss_size	       =	tcp_conn_rr_response->send_buf_size;
8980       rem_nodelay      =	tcp_conn_rr_response->no_delay;
8981       remote_cpu_usage =	tcp_conn_rr_response->measure_cpu;
8982       remote_cpu_rate  = 	tcp_conn_rr_response->cpu_rate;
8983       /* make sure that port numbers are in network order */
8984       set_port_number(remote_res,
8985 		      (unsigned short)tcp_conn_rr_response->data_port_number);
8986 
8987       if (debug) {
8988 	fprintf(where,"remote listen done.\n");
8989 	fprintf(where,"remote port is %u\n",get_port_number(remote_res));
8990 	fflush(where);
8991       }
8992     }
8993     else {
8994       Set_errno(netperf_response.content.serv_errno);
8995       fprintf(where,
8996 	      "netperf: remote error %d",
8997 	      netperf_response.content.serv_errno);
8998       perror("");
8999       fflush(where);
9000       exit(1);
9001     }
9002   }
9003 #ifdef WANT_DEMO
9004   demo_rr_setup(100);
9005 #endif
9006 
9007   /* pick a nice random spot between client_port_min and */
9008   /* client_port_max for our initial port number */
9009   srand(getpid());
9010   if (client_port_max - client_port_min) {
9011     myport = client_port_min +
9012       (rand() % (client_port_max - client_port_min));
9013   }
9014   else {
9015     myport = client_port_min;
9016   }
9017   /* there will be a ++ before the first call to bind, so subtract one */
9018   myport--;
9019   /* Set-up the test end conditions. For a request/response test, they */
9020   /* can be either time or transaction based. */
9021 
9022   if (test_time) {
9023     /* The user wanted to end the test after a period of time. */
9024     times_up = 0;
9025     trans_remaining = 0;
9026     start_timer(test_time);
9027   }
9028   else {
9029     /* The tester wanted to send a number of bytes. */
9030     trans_remaining = test_bytes;
9031     times_up = 1;
9032   }
9033 
9034   /* The cpu_start routine will grab the current time and possibly */
9035   /* value of the idle counter for later use in measuring cpu */
9036   /* utilization and/or service demand and thruput. */
9037 
9038 
9039   cpu_start(local_cpu_usage);
9040 
9041 #ifdef WANT_DEMO
9042       if (demo_mode) {
9043 	demo_first_timestamp();
9044       }
9045 #endif
9046 
9047   /* We use an "OR" to control test execution. When the test is */
9048   /* controlled by time, the byte count check will always return false. */
9049   /* When the test is controlled by byte count, the time test will */
9050   /* always return false. When the test is finished, the whole */
9051   /* expression will go false and we will stop sending data. I think I */
9052   /* just arbitrarily decrement trans_remaining for the timed test, but */
9053   /* will not do that just yet... One other question is whether or not */
9054   /* the send buffer and the receive buffer should be the same buffer. */
9055 
9056   while ((!times_up) || (trans_remaining > 0)) {
9057 
9058 #ifdef WANT_HISTOGRAM
9059     if (verbosity > 1) {
9060       /* timestamp just before our call to create the socket, and then */
9061       /* again just after the receive raj 3/95 */
9062       HIST_timestamp(&time_one);
9063     }
9064 #endif /* WANT_HISTOGRAM */
9065 
9066 newport:
9067     /* pick a new port number */
9068     myport++;
9069 
9070     /* wrap the port number when we get to client_port_max. NOTE, some */
9071     /* broken TCP's might treat the port number as a signed 16 bit */
9072     /* quantity.  we aren't interested in testing such broken */
9073     /* implementations :) so we won't make sure that it is below 32767 */
9074     /* raj 8/94  */
9075     if (myport >= client_port_max) {
9076       myport = client_port_min;
9077     }
9078 
9079     /* we do not want to use the port number that the server is */
9080     /* sitting at - this would cause us to fail in a loopback test. we */
9081     /* could just rely on the failure of the bind to get us past this, */
9082     /* but I'm guessing that in this one case at least, it is much */
9083     /* faster, given that we *know* that port number is already in use */
9084     /* (or rather would be in a loopback test) */
9085 
9086     if (myport == get_port_number(remote_res)) myport++;
9087 
9088     if (debug) {
9089       if ((nummessages % 100) == 0) {
9090 	printf("port %d\n",myport);
9091       }
9092     }
9093 
9094     /* set up the data socket */
9095     set_port_number(local_res, (unsigned short)myport);
9096     send_socket = create_data_socket(local_res);
9097 
9098     if (send_socket == INVALID_SOCKET) {
9099       perror("netperf: send_tcp_conn_rr: tcp stream data socket");
9100       exit(1);
9101     }
9102 
9103 
9104     /* we used to call bind here, but that is now taken-care-of by the
9105        create_data_socket routine. */
9106 
9107     /* Connect up to the remote port on the data socket  */
9108     if ((ret = connect(send_socket,
9109 		       remote_res->ai_addr,
9110 		       remote_res->ai_addrlen)) == INVALID_SOCKET){
9111       if (SOCKET_EINTR(ret))
9112 	  {
9113 	    /* we hit the end of a */
9114 	    /* timed test. */
9115 	    timed_out = 1;
9116 	    break;
9117       }
9118       if ((SOCKET_EADDRINUSE(ret)) || SOCKET_EADDRNOTAVAIL(ret)) {
9119 	/* likely something our explicit bind() would have caught in
9120            the past, so go get another port, via create_data_socket.
9121            yes, this is a bit more overhead than before, but the
9122            condition should be rather rare.  raj 2005-02-08 */
9123 	close(send_socket);
9124 	goto newport;
9125       }
9126       perror("netperf: data socket connect failed");
9127       printf("\tattempted to connect on socket %d to port %d",
9128 	     send_socket,
9129 	     get_port_number(remote_res));
9130       printf(" from port %d \n",get_port_number(local_res));
9131       exit(1);
9132     }
9133 
9134 
9135     /* send the request */
9136     if((len=send(send_socket,
9137 		 send_ring->buffer_ptr,
9138 		 req_size,
9139 		 0)) != req_size) {
9140       if (SOCKET_EINTR(len))
9141 	  {
9142 	    /* we hit the end of a */
9143 	    /* timed test. */
9144 	    timed_out = 1;
9145 	    break;
9146       }
9147       perror("send_tcp_conn_rr: data send error");
9148       exit(1);
9149     }
9150     send_ring = send_ring->next;
9151 
9152     /* receive the response */
9153     rsp_bytes_left = rsp_size;
9154     temp_message_ptr  = recv_ring->buffer_ptr;
9155 
9156 
9157     do {
9158       rsp_bytes_recvd = recv(send_socket,
9159 			     temp_message_ptr,
9160 			     rsp_bytes_left,
9161 			     0);
9162       if (rsp_bytes_recvd > 0) {
9163 	rsp_bytes_left -= rsp_bytes_recvd;
9164 	temp_message_ptr += rsp_bytes_recvd;
9165       }
9166       else {
9167 	break;
9168       }
9169     } while (rsp_bytes_left);
9170 
9171 
9172     /* OK, we are out of the loop - now what? */
9173     if (rsp_bytes_recvd < 0) {
9174       /* did the timer hit, or was there an error? */
9175       if (SOCKET_EINTR(rsp_bytes_recvd))
9176 	  {
9177 	    /* We hit the end of a timed test. */
9178 	    timed_out = 1;
9179 	    break;
9180 	  }
9181 	  perror("send_tcp_conn_rr: data recv error");
9182 	  exit(1);
9183     }
9184 
9185     /* if this is a no_control test, we initiate connection close,
9186        otherwise the remote netserver does it to remain just like
9187        previous behaviour. raj 2007-27-08 */
9188     if (!no_control) {
9189       shutdown(send_socket,SHUT_WR);
9190     }
9191 
9192     /* we are expecting to get either a return of zero indicating
9193        connection close, or an error.  */
9194     rsp_bytes_recvd = recv(send_socket,
9195 			   temp_message_ptr,
9196 			   1,
9197 			   0);
9198 
9199     /* our exit from the while loop should generally be when */
9200     /* tmp_bytes_recvd is equal to zero, which implies the connection */
9201     /* has been closed by the server side. By waiting until we get the */
9202     /* zero return we can avoid race conditions that stick us with the */
9203     /* TIME_WAIT connection and not the server. raj 8/96 */
9204 
9205 #ifdef VMWARE_UW
9206     /* why this should be for VMware I'm not sure, but it was given as
9207        part of the patches, so we include it here, but put it under an
9208        ifdef VMWARE_UW. raj 2008-07-25 */
9209     if (sp_bytes_recvd < 0 && errno == ECONNRESET) {
9210       rsp_bytes_recvd = 0;
9211     }
9212 #endif /* VMWARE_UW */
9213 
9214     if (rsp_bytes_recvd == 0) {
9215       /* connection close, call close. we assume that the requisite */
9216       /* number of bytes have been received */
9217       recv_ring = recv_ring->next;
9218 
9219 #ifdef WANT_HISTOGRAM
9220       if (verbosity > 1) {
9221 	HIST_timestamp(&time_two);
9222 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
9223       }
9224 #endif /* WANT_HISTOGRAM */
9225 
9226 #ifdef WANT_DEMO
9227       demo_rr_interval(1);
9228 #endif
9229 
9230       nummessages++;
9231       if (trans_remaining) {
9232 	trans_remaining--;
9233       }
9234 
9235       if (debug > 3) {
9236 	fprintf(where,
9237 		"Transaction %d completed on local port %d\n",
9238 		nummessages,
9239 		get_port_number(local_res));
9240 	fflush(where);
9241       }
9242 
9243       close(send_socket);
9244 
9245     }
9246     else {
9247       /* it was less than zero - an error occured */
9248       if (SOCKET_EINTR(rsp_bytes_recvd))
9249 	  {
9250 	    /* We hit the end of a timed test. */
9251 	    timed_out = 1;
9252 	    break;
9253 	  }
9254 	  perror("send_tcp_conn_rr: data recv error");
9255 	  exit(1);
9256     }
9257 
9258   }
9259 
9260 
9261   /* this call will always give us the elapsed time for the test, and */
9262   /* will also store-away the necessaries for cpu utilization */
9263 
9264   cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being measured? */
9265   /* how long did we really run? */
9266 
9267   if (!no_control) {
9268     /* Get the statistics from the remote end. The remote will have
9269        calculated service demand and all those interesting things. If
9270        it wasn't supposed to care, it will return obvious values. */
9271 
9272     recv_response();
9273     if (!netperf_response.content.serv_errno) {
9274       if (debug)
9275 	fprintf(where,"remote results obtained\n");
9276     }
9277     else {
9278       Set_errno(netperf_response.content.serv_errno);
9279       fprintf(where,
9280 	      "netperf: remote error %d",
9281 	      netperf_response.content.serv_errno);
9282       perror("");
9283       fflush(where);
9284 
9285       exit(1);
9286     }
9287   }
9288 
9289   /* We now calculate what our thruput was for the test. In the future, */
9290   /* we may want to include a calculation of the thruput measured by */
9291   /* the remote, but it should be the case that for a TCP stream test, */
9292   /* that the two numbers should be *very* close... We calculate */
9293   /* bytes_sent regardless of the way the test length was controlled. */
9294   /* If it was time, we needed to, and if it was by bytes, the user may */
9295   /* have specified a number of bytes that wasn't a multiple of the */
9296   /* send_size, so we really didn't send what he asked for ;-) We use */
9297   /* Kbytes/s as the units of thruput for a TCP stream test, where K = */
9298   /* 1024. A future enhancement *might* be to choose from a couple of */
9299   /* unit selections. */
9300 
9301   bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
9302   thruput	= calc_thruput(bytes_xferd);
9303 
9304   if (local_cpu_usage || remote_cpu_usage) {
9305     /* We must now do a little math for service demand and cpu */
9306     /* utilization for the system(s) */
9307     /* Of course, some of the information might be bogus because */
9308     /* there was no idle counter in the kernel(s). We need to make */
9309     /* a note of this for the user's benefit...*/
9310     if (local_cpu_usage) {
9311       if (local_cpu_rate == 0.0) {
9312 	fprintf(where,
9313 		"WARNING WARNING WARNING  WARNING WARNING WARNING  WARNING!\n");
9314 	fprintf(where,
9315 		"Local CPU usage numbers based on process information only!\n");
9316 	fflush(where);
9317       }
9318       local_cpu_utilization = calc_cpu_util(0.0);
9319       /* since calc_service demand is doing ms/Kunit we will */
9320       /* multiply the number of transaction by 1024 to get */
9321       /* "good" numbers */
9322       local_service_demand  = calc_service_demand((double) nummessages*1024,
9323 						  0.0,
9324 						  0.0,
9325 						  0);
9326     }
9327     else {
9328       local_cpu_utilization	= (float) -1.0;
9329       local_service_demand	= (float) -1.0;
9330     }
9331 
9332     if (remote_cpu_usage) {
9333       if (remote_cpu_rate == 0.0) {
9334 	fprintf(where,
9335 		"DANGER  DANGER  DANGER    DANGER  DANGER  DANGER    DANGER!\n");
9336 	fprintf(where,
9337 		"Remote CPU usage numbers based on process information only!\n");
9338 	fflush(where);
9339       }
9340       remote_cpu_utilization = tcp_conn_rr_result->cpu_util;
9341       /* since calc_service demand is doing ms/Kunit we will */
9342       /* multiply the number of transaction by 1024 to get */
9343       /* "good" numbers */
9344       remote_service_demand = calc_service_demand((double) nummessages*1024,
9345 						  0.0,
9346 						  remote_cpu_utilization,
9347 						  tcp_conn_rr_result->num_cpus);
9348     }
9349     else {
9350       remote_cpu_utilization = (float) -1.0;
9351       remote_service_demand  = (float) -1.0;
9352     }
9353 
9354     /* We are now ready to print all the information. If the user */
9355     /* has specified zero-level verbosity, we will just print the */
9356     /* local service demand, or the remote service demand. If the */
9357     /* user has requested verbosity level 1, he will get the basic */
9358     /* "streamperf" numbers. If the user has specified a verbosity */
9359     /* of greater than 1, we will display a veritable plethora of */
9360     /* background information from outside of this block as it it */
9361     /* not cpu_measurement specific...  */
9362 
9363     switch (verbosity) {
9364     case 0:
9365       if (local_cpu_usage) {
9366 	fprintf(where,
9367 		cpu_fmt_0,
9368 		local_service_demand);
9369       }
9370       else {
9371 	fprintf(where,
9372 		cpu_fmt_0,
9373 		remote_service_demand);
9374       }
9375       break;
9376     case 1:
9377     case 2:
9378 
9379       if (print_headers) {
9380 	fprintf(where,
9381 		cpu_title,
9382 		local_cpu_method,
9383 		remote_cpu_method);
9384       }
9385 
9386       fprintf(where,
9387 	      cpu_fmt_1_line_1,		/* the format string */
9388 	      lss_size,		/* local sendbuf size */
9389 	      lsr_size,
9390 	      req_size,		/* how large were the requests */
9391 	      rsp_size,		/* guess */
9392 	      elapsed_time,		/* how long was the test */
9393 	      nummessages/elapsed_time,
9394 	      local_cpu_utilization,	/* local cpu */
9395 	      remote_cpu_utilization,	/* remote cpu */
9396 	      local_service_demand,	/* local service demand */
9397 	      remote_service_demand);	/* remote service demand */
9398       fprintf(where,
9399 	      cpu_fmt_1_line_2,
9400 	      rss_size,
9401 	      rsr_size);
9402       break;
9403     }
9404   }
9405   else {
9406     /* The tester did not wish to measure service demand. */
9407     switch (verbosity) {
9408     case 0:
9409       fprintf(where,
9410 	      tput_fmt_0,
9411 	      nummessages/elapsed_time);
9412       break;
9413     case 1:
9414     case 2:
9415       if (print_headers) {
9416 	fprintf(where,tput_title,format_units());
9417       }
9418 
9419       fprintf(where,
9420 	      tput_fmt_1_line_1,	/* the format string */
9421 	      lss_size,
9422 	      lsr_size,
9423 	      req_size,		/* how large were the requests */
9424 	      rsp_size,		/* how large were the responses */
9425 	      elapsed_time, 		/* how long did it take */
9426 	      nummessages/elapsed_time);
9427       fprintf(where,
9428 	      tput_fmt_1_line_2,
9429 	      rss_size, 		/* remote recvbuf size */
9430 	      rsr_size);
9431 
9432       break;
9433     }
9434   }
9435 
9436   /* it would be a good thing to include information about some of the */
9437   /* other parameters that may have been set for this test, but at the */
9438   /* moment, I do not wish to figure-out all the  formatting, so I will */
9439   /* just put this comment here to help remind me that it is something */
9440   /* that should be done at a later time. */
9441 
9442   if (verbosity > 1) {
9443     /* The user wanted to know it all, so we will give it to him. */
9444     /* This information will include as much as we can find about */
9445     /* TCP statistics, the alignments of the sends and receives */
9446     /* and all that sort of rot... */
9447 
9448     fprintf(where,
9449 	    ksink_fmt,
9450 	    local_send_align,
9451 	    remote_recv_offset,
9452 	    local_send_offset,
9453 	    remote_recv_offset);
9454 
9455 #ifdef WANT_HISTOGRAM
9456     fprintf(where,"\nHistogram of request/response times\n");
9457     fflush(where);
9458     HIST_report(time_hist);
9459 #endif /* WANT_HISTOGRAM */
9460 
9461   }
9462 
9463 }
9464 #endif /* WANT_MIGRATION */
9465 
9466 void
recv_tcp_conn_rr()9467 recv_tcp_conn_rr()
9468 {
9469 
9470   char  *message;
9471   struct addrinfo *local_res;
9472   char local_name[BUFSIZ];
9473   char port_buffer[PORTBUFSIZE];
9474 
9475   struct	sockaddr_storage        myaddr_in, peeraddr_in;
9476   SOCKET	s_listen,s_data;
9477   netperf_socklen_t 	addrlen;
9478   char	*recv_message_ptr;
9479   char	*send_message_ptr;
9480   char	*temp_message_ptr;
9481   int	trans_received;
9482   int	trans_remaining;
9483   int	bytes_sent;
9484   int	request_bytes_recvd;
9485   int	request_bytes_remaining;
9486   int	timed_out = 0;
9487   float	elapsed_time;
9488 
9489   struct	tcp_conn_rr_request_struct	*tcp_conn_rr_request;
9490   struct	tcp_conn_rr_response_struct	*tcp_conn_rr_response;
9491   struct	tcp_conn_rr_results_struct	*tcp_conn_rr_results;
9492 
9493   tcp_conn_rr_request =
9494     (struct tcp_conn_rr_request_struct *)netperf_request.content.test_specific_data;
9495   tcp_conn_rr_response =
9496     (struct tcp_conn_rr_response_struct *)netperf_response.content.test_specific_data;
9497   tcp_conn_rr_results =
9498     (struct tcp_conn_rr_results_struct *)netperf_response.content.test_specific_data;
9499 
9500   if (debug) {
9501     fprintf(where,"netserver: recv_tcp_conn_rr: entered...\n");
9502     fflush(where);
9503   }
9504 
9505   /* We want to set-up the listen socket with all the desired */
9506   /* parameters and then let the initiator know that all is ready. If */
9507   /* socket size defaults are to be used, then the initiator will have */
9508   /* sent us 0's. If the socket sizes cannot be changed, then we will */
9509   /* send-back what they are. If that information cannot be determined, */
9510   /* then we send-back -1's for the sizes. If things go wrong for any */
9511   /* reason, we will drop back ten yards and punt. */
9512 
9513   /* If anything goes wrong, we want the remote to know about it. It */
9514   /* would be best if the error that the remote reports to the user is */
9515   /* the actual error we encountered, rather than some bogus unexpected */
9516   /* response type message. */
9517 
9518   if (debug) {
9519     fprintf(where,"recv_tcp_conn_rr: setting the response type...\n");
9520     fflush(where);
9521   }
9522 
9523   netperf_response.content.response_type = TCP_CRR_RESPONSE;
9524 
9525   if (debug) {
9526     fprintf(where,"recv_tcp_conn_rr: the response type is set...\n");
9527     fflush(where);
9528   }
9529 
9530   /* set-up the data buffer with the requested alignment and offset */
9531   message = (char *)malloc(DATABUFFERLEN);
9532   if (message == NULL) {
9533     printf("malloc(%d) failed!\n", DATABUFFERLEN);
9534     exit(1);
9535   }
9536 
9537   /* We now alter the message_ptr variables to be at the desired */
9538   /* alignments with the desired offsets. */
9539 
9540   if (debug) {
9541     fprintf(where,
9542 	    "recv_tcp_conn_rr: requested recv alignment of %d offset %d\n",
9543 	    tcp_conn_rr_request->recv_alignment,
9544 	    tcp_conn_rr_request->recv_offset);
9545     fprintf(where,
9546 	    "recv_tcp_conn_rr: requested send alignment of %d offset %d\n",
9547 	    tcp_conn_rr_request->send_alignment,
9548 	    tcp_conn_rr_request->send_offset);
9549     fflush(where);
9550   }
9551 
9552   recv_message_ptr = ALIGN_BUFFER(message, tcp_conn_rr_request->recv_alignment, tcp_conn_rr_request->recv_offset);
9553 
9554   send_message_ptr = ALIGN_BUFFER(message, tcp_conn_rr_request->send_alignment, tcp_conn_rr_request->send_offset);
9555 
9556   if (debug) {
9557     fprintf(where,"recv_tcp_conn_rr: receive alignment and offset set...\n");
9558     fflush(where);
9559   }
9560 
9561   /* Grab a socket to listen on, and then listen on it. */
9562 
9563   if (debug) {
9564     fprintf(where,"recv_tcp_conn_rr: grabbing a socket...\n");
9565     fflush(where);
9566   }
9567 
9568   /* create_data_socket expects to find some things in the global */
9569   /* variables, so set the globals based on the values in the request. */
9570   /* once the socket has been created, we will set the response values */
9571   /* based on the updated value of those globals. raj 7/94 */
9572   lss_size_req = tcp_conn_rr_request->send_buf_size;
9573   lsr_size_req = tcp_conn_rr_request->recv_buf_size;
9574   loc_nodelay = tcp_conn_rr_request->no_delay;
9575   loc_rcvavoid = tcp_conn_rr_request->so_rcvavoid;
9576   loc_sndavoid = tcp_conn_rr_request->so_sndavoid;
9577 
9578   set_hostname_and_port(local_name,
9579 			port_buffer,
9580 			nf_to_af(tcp_conn_rr_request->ipfamily),
9581 			tcp_conn_rr_request->port);
9582 
9583   local_res = complete_addrinfo(local_name,
9584 				local_name,
9585 				port_buffer,
9586 				nf_to_af(tcp_conn_rr_request->ipfamily),
9587 				SOCK_STREAM,
9588 				IPPROTO_TCP,
9589 				0);
9590 
9591   s_listen = create_data_socket(local_res);
9592 
9593   if (s_listen == INVALID_SOCKET) {
9594     netperf_response.content.serv_errno = errno;
9595     send_response();
9596     if (debug) {
9597       fprintf(where,"could not create data socket\n");
9598       fflush(where);
9599     }
9600     exit(1);
9601   }
9602 
9603 #ifdef WIN32
9604     /* The test timer can fire during operations on the listening socket,
9605        so to make the start_timer below work we have to move
9606        it to close s_listen while we are blocked on accept. */
9607     win_kludge_socket2 = s_listen;
9608 #endif
9609 
9610 
9611   /* Now, let's set-up the socket to listen for connections */
9612   if (listen(s_listen, 128) == SOCKET_ERROR) {
9613     netperf_response.content.serv_errno = errno;
9614     close(s_listen);
9615     send_response();
9616     if (debug) {
9617       fprintf(where,"could not listen\n");
9618       fflush(where);
9619     }
9620     exit(1);
9621   }
9622 
9623   /* now get the port number assigned by the system  */
9624   addrlen = sizeof(myaddr_in);
9625   if (getsockname(s_listen,
9626 		  (struct sockaddr *)&myaddr_in,
9627 		  &addrlen) == SOCKET_ERROR){
9628     netperf_response.content.serv_errno = errno;
9629     close(s_listen);
9630     send_response();
9631     if (debug) {
9632       fprintf(where,"could not getsockname\n");
9633       fflush(where);
9634     }
9635     exit(1);
9636   }
9637 
9638   /* Now myaddr_in contains the port and the internet address this is */
9639   /* returned to the sender also implicitly telling the sender that the */
9640   /* socket buffer sizing has been done. */
9641 
9642   tcp_conn_rr_response->data_port_number =
9643     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
9644   if (debug) {
9645     fprintf(where,"telling the remote to call me at %d\n",
9646 	    tcp_conn_rr_response->data_port_number);
9647     fflush(where);
9648   }
9649   netperf_response.content.serv_errno   = 0;
9650 
9651   /* But wait, there's more. If the initiator wanted cpu measurements, */
9652   /* then we must call the calibrate routine, which will return the max */
9653   /* rate back to the initiator. If the CPU was not to be measured, or */
9654   /* something went wrong with the calibration, we will return a 0.0 to */
9655   /* the initiator. */
9656 
9657   tcp_conn_rr_response->cpu_rate = (float)0.0; 	/* assume no cpu */
9658   if (tcp_conn_rr_request->measure_cpu) {
9659     tcp_conn_rr_response->measure_cpu = 1;
9660     tcp_conn_rr_response->cpu_rate =
9661       calibrate_local_cpu(tcp_conn_rr_request->cpu_rate);
9662   }
9663 
9664 
9665 
9666   /* before we send the response back to the initiator, pull some of */
9667   /* the socket parms from the globals */
9668   tcp_conn_rr_response->send_buf_size = lss_size;
9669   tcp_conn_rr_response->recv_buf_size = lsr_size;
9670   tcp_conn_rr_response->no_delay = loc_nodelay;
9671   tcp_conn_rr_response->so_rcvavoid = loc_rcvavoid;
9672   tcp_conn_rr_response->so_sndavoid = loc_sndavoid;
9673 
9674   send_response();
9675 
9676   addrlen = sizeof(peeraddr_in);
9677 
9678   /* Now it's time to start receiving data on the connection. We will */
9679   /* first grab the apropriate counters and then start grabbing. */
9680 
9681   cpu_start(tcp_conn_rr_request->measure_cpu);
9682 
9683   /* The loop will exit when the sender does a shutdown, which will */
9684   /* return a length of zero   */
9685 
9686   if (tcp_conn_rr_request->test_length > 0) {
9687     times_up = 0;
9688     trans_remaining = 0;
9689     start_timer(tcp_conn_rr_request->test_length + PAD_TIME);
9690   }
9691   else {
9692     times_up = 1;
9693     trans_remaining = tcp_conn_rr_request->test_length * -1;
9694   }
9695 
9696   trans_received = 0;
9697 
9698   while ((!times_up) || (trans_remaining > 0)) {
9699 
9700     /* accept a connection from the remote */
9701 #ifdef WIN32
9702     /* The test timer will probably fire during this accept,
9703        so to make the start_timer above work we have to move
9704        it to close s_listen while we are blocked on accept. */
9705     win_kludge_socket = s_listen;
9706 #endif
9707     if ((s_data=accept(s_listen,
9708 		       (struct sockaddr *)&peeraddr_in,
9709 		       &addrlen)) == INVALID_SOCKET) {
9710       if (errno == EINTR) {
9711 	/* the timer popped */
9712 	timed_out = 1;
9713 	break;
9714       }
9715       fprintf(where,"recv_tcp_conn_rr: accept: errno = %d\n",errno);
9716       fflush(where);
9717       close(s_listen);
9718 
9719       exit(1);
9720     }
9721 
9722     if (debug) {
9723       fprintf(where,"recv_tcp_conn_rr: accepted data connection.\n");
9724       fflush(where);
9725     }
9726 
9727 #ifdef WIN32
9728   /* this is used so the timer thread can close the socket out from */
9729   /* under us, which to date is the easiest/cleanest/least */
9730   /* Windows-specific way I can find to force the winsock calls to */
9731   /* return WSAEINTR with the test is over. anything that will run on */
9732   /* 95 and NT and is closer to what netperf expects from Unix signals */
9733   /* and such would be appreciated raj 1/96 */
9734   win_kludge_socket = s_data;
9735 #endif /* WIN32 */
9736 
9737 #ifdef KLUDGE_SOCKET_OPTIONS
9738     /* this is for those systems which *INCORRECTLY* fail to pass */
9739     /* attributes across an accept() call. Including this goes against */
9740     /* my better judgement :( raj 11/95 */
9741 
9742     kludge_socket_options(s_data);
9743 
9744 #endif /* KLUDGE_SOCKET_OPTIONS */
9745 
9746     temp_message_ptr	= recv_message_ptr;
9747     request_bytes_remaining	= tcp_conn_rr_request->request_size;
9748 
9749     /* receive the request from the other side */
9750     while (!times_up && (request_bytes_remaining > 0)) {
9751       if((request_bytes_recvd=recv(s_data,
9752 				   temp_message_ptr,
9753 				   request_bytes_remaining,
9754 				   0)) == SOCKET_ERROR) {
9755 	if (SOCKET_EINTR(request_bytes_recvd))
9756 	{
9757 	  /* the timer popped */
9758 	  timed_out = 1;
9759 	  break;
9760 	}
9761 	netperf_response.content.serv_errno = errno;
9762 	send_response();
9763 	exit(1);
9764       }
9765       else if (request_bytes_recvd > 0) {
9766 	request_bytes_remaining -= request_bytes_recvd;
9767 	temp_message_ptr  += request_bytes_recvd;
9768       }
9769       else {
9770       	/* for some reason the remote closed the connection on
9771 	 * us and that is unexpected so we should just close the
9772 	 * socket and move-on. for that we will use an evil goto
9773 	 * neener neener raj 20090622 */
9774     	goto bail;
9775       }
9776     }
9777 
9778     if (timed_out) {
9779       /* we hit the end of the test based on time - lets */
9780       /* bail out of here now... */
9781       fprintf(where,"yo5\n");
9782       fflush(where);
9783       break;
9784     }
9785 
9786     /* Now, send the response to the remote */
9787     if((bytes_sent=send(s_data,
9788 			send_message_ptr,
9789 			tcp_conn_rr_request->response_size,
9790 			0)) == SOCKET_ERROR) {
9791       if (errno == EINTR) {
9792 	/* the test timer has popped */
9793 	timed_out = 1;
9794 	fprintf(where,"yo6\n");
9795 	fflush(where);
9796 	break;
9797       }
9798       netperf_response.content.serv_errno = 99;
9799       send_response();
9800       exit(1);
9801     }
9802 
9803     trans_received++;
9804     if (trans_remaining) {
9805       trans_remaining--;
9806     }
9807 
9808     if (debug) {
9809       fprintf(where,
9810 	      "recv_tcp_conn_rr: Transaction %d complete\n",
9811 	      trans_received);
9812       fflush(where);
9813     }
9814 
9815     /* close the connection. the server will likely do a graceful */
9816     /* close of the connection, insuring that all data has arrived at */
9817     /* the client. for this it will call shutdown(), and then recv() and */
9818     /* then close(). I'm reasonably confident that this is the */
9819     /* appropriate sequence of calls - I would like to hear of */
9820     /* examples in web servers to the contrary. raj 10/95*/
9821 #ifdef TCP_CRR_SHUTDOWN
9822     shutdown(s_data,SHUT_WR);
9823     recv(s_data,
9824 	 recv_message_ptr,
9825 	 1,
9826 	 0);
9827 bail:
9828     close(s_data);
9829 #else
9830 bail:
9831     close(s_data);
9832 #endif /* TCP_CRR_SHUTDOWN */
9833 
9834   }
9835 
9836 
9837   /* The loop now exits due to timeout or transaction count being */
9838   /* reached */
9839 
9840   cpu_stop(tcp_conn_rr_request->measure_cpu,&elapsed_time);
9841 
9842   if (timed_out) {
9843     /* we ended the test by time, which was at least 2 seconds */
9844     /* longer than we wanted to run. so, we want to subtract */
9845     /* PAD_TIME from the elapsed_time. */
9846     elapsed_time -= PAD_TIME;
9847   }
9848   /* send the results to the sender			*/
9849 
9850   if (debug) {
9851     fprintf(where,
9852 	    "recv_tcp_conn_rr: got %d transactions\n",
9853 	    trans_received);
9854     fflush(where);
9855   }
9856 
9857   tcp_conn_rr_results->bytes_received	= (trans_received *
9858 					   (tcp_conn_rr_request->request_size +
9859 					    tcp_conn_rr_request->response_size));
9860   tcp_conn_rr_results->trans_received	= trans_received;
9861   tcp_conn_rr_results->elapsed_time	= elapsed_time;
9862   if (tcp_conn_rr_request->measure_cpu) {
9863     tcp_conn_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
9864   }
9865 
9866   if (debug) {
9867     fprintf(where,
9868 	    "recv_tcp_conn_rr: test complete, sending results.\n");
9869     fflush(where);
9870   }
9871 
9872   send_response();
9873 
9874 }
9875 
9876 
9877 #ifdef DO_1644
9878 
9879  /* this test is intended to test the performance of establishing a */
9880  /* connection, exchanging a request/response pair, and repeating. it */
9881  /* is expected that this would be a good starting-point for */
9882  /* comparision of T/TCP with classic TCP for transactional workloads. */
9883  /* it will also look (can look) much like the communication pattern */
9884  /* of http for www access. */
9885 
9886 int
send_tcp_tran_rr(char remote_host[])9887 send_tcp_tran_rr(char remote_host[])
9888 {
9889 
9890   char *tput_title = "\
9891 Local /Remote\n\
9892 Socket Size   Request  Resp.   Elapsed  Trans.\n\
9893 Send   Recv   Size     Size    Time     Rate         \n\
9894 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
9895 
9896   char *tput_fmt_0 =
9897     "%7.2f\n";
9898 
9899   char *tput_fmt_1_line_1 = "\
9900 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
9901   char *tput_fmt_1_line_2 = "\
9902 %-6d %-6d\n";
9903 
9904   char *cpu_title = "\
9905 Local /Remote\n\
9906 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
9907 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
9908 bytes  bytes  bytes   bytes  secs.   per sec  %%      %%      us/Tr   us/Tr\n\n";
9909 
9910   char *cpu_fmt_0 =
9911     "%6.3f\n";
9912 
9913   char *cpu_fmt_1_line_1 = "\
9914 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f\n";
9915 
9916   char *cpu_fmt_1_line_2 = "\
9917 %-6d %-6d\n";
9918 
9919   char *ksink_fmt = "\n\
9920 Alignment      Offset\n\
9921 Local  Remote  Local  Remote\n\
9922 Send   Recv    Send   Recv\n\
9923 %5d  %5d   %5d  %5d\n";
9924 
9925 
9926   int 			one = 1;
9927   int			timed_out = 0;
9928   float			elapsed_time;
9929 
9930   int	len;
9931   struct ring_elt *send_ring;
9932   struct ring_elt *recv_ring;
9933   char	*temp_message_ptr;
9934   int	nummessages;
9935   SOCKET	send_socket;
9936   int	trans_remaining;
9937   double	bytes_xferd;
9938   int	sock_opt_len = sizeof(int);
9939   int	rsp_bytes_left;
9940   int	rsp_bytes_recvd;
9941 
9942   float	local_cpu_utilization;
9943   float	local_service_demand;
9944   float	remote_cpu_utilization;
9945   float	remote_service_demand;
9946   double	thruput;
9947 
9948   struct	hostent	        *hp;
9949   struct	sockaddr_in	server;
9950   struct        sockaddr_in     *myaddr;
9951   unsigned      int             addr;
9952   int                           myport;
9953 
9954   struct	tcp_tran_rr_request_struct	*tcp_tran_rr_request;
9955   struct	tcp_tran_rr_response_struct	*tcp_tran_rr_response;
9956   struct	tcp_tran_rr_results_struct	*tcp_tran_rr_result;
9957 
9958   tcp_tran_rr_request =
9959     (struct tcp_tran_rr_request_struct *)netperf_request.content.test_specific_data;
9960   tcp_tran_rr_response =
9961     (struct tcp_tran_rr_response_struct *)netperf_response.content.test_specific_data;
9962   tcp_tran_rr_result =
9963     (struct tcp_tran_rr_results_struct *)netperf_response.content.test_specific_data;
9964 
9965 
9966 #ifdef WANT_HISTOGRAM
9967   if (verbosity > 1) {
9968     time_hist = HIST_new();
9969   }
9970 #endif /* WANT_HISTOGRAM */
9971 
9972   /* since we are now disconnected from the code that established the */
9973   /* control socket, and since we want to be able to use different */
9974   /* protocols and such, we are passed the name of the remote host and */
9975   /* must turn that into the test specific addressing information. */
9976 
9977   myaddr = (struct sockaddr_storage *)malloc(sizeof(struct sockaddr_storage));
9978   if (myaddr == NULL) {
9979     printf("malloc(%d) failed!\n", sizeof(struct sockaddr_storage));
9980     exit(1);
9981   }
9982 
9983   bzero((char *)&server,
9984 	sizeof(server));
9985   bzero((char *)myaddr,
9986 	sizeof(struct sockaddr_storage));
9987   myaddr->sin_family = AF_INET;
9988 
9989   complete_addrinfos(&remote_res,
9990 		     &local_res,
9991 		     remote_host,
9992 		     SOCK_STREAM,
9993 		     IPPROTO_TCP,
9994 		     0);
9995 
9996   if ( print_headers ) {
9997     print_top_test_header("TCP Transactional/Request/Response TEST",local_res,remote_res);
9998   }
9999 
10000   /* initialize a few counters */
10001 
10002   nummessages	=	0;
10003   bytes_xferd	=	0.0;
10004   times_up 	= 	0;
10005 
10006   /* set-up the data buffers with the requested alignment and offset */
10007   if (send_width == 0) send_width = 1;
10008   if (recv_width == 0) recv_width = 1;
10009 
10010   send_ring = allocate_buffer_ring(send_width,
10011 				   req_size,
10012 				   local_send_align,
10013 				   local_send_offset);
10014 
10015   recv_ring = allocate_buffer_ring(recv_width,
10016 				   rsp_size,
10017 				   local_recv_align,
10018 				   local_recv_offset);
10019 
10020 
10021   if (debug) {
10022     fprintf(where,"send_tcp_tran_rr: send_socket obtained...\n");
10023   }
10024 
10025   /* If the user has requested cpu utilization measurements, we must */
10026   /* calibrate the cpu(s). We will perform this task within the tests */
10027   /* themselves. If the user has specified the cpu rate, then */
10028   /* calibrate_local_cpu will return rather quickly as it will have */
10029   /* nothing to do. If local_cpu_rate is zero, then we will go through */
10030   /* all the "normal" calibration stuff and return the rate back.*/
10031 
10032   if (local_cpu_usage) {
10033     local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
10034   }
10035 
10036   /* Tell the remote end to do a listen. The server alters the socket */
10037   /* paramters on the other side at this point, hence the reason for */
10038   /* all the values being passed in the setup message. If the user did */
10039   /* not specify any of the parameters, they will be passed as 0, which */
10040   /* will indicate to the remote that no changes beyond the system's */
10041   /* default should be used. Alignment is the exception, it will */
10042   /* default to 8, which will be no alignment alterations. */
10043 
10044   netperf_request.content.request_type	        =	DO_TCP_TRR;
10045   tcp_tran_rr_request->recv_buf_size	=	rsr_size_req;
10046   tcp_tran_rr_request->send_buf_size	=	rss_size_req;
10047   tcp_tran_rr_request->recv_alignment	=	remote_recv_align;
10048   tcp_tran_rr_request->recv_offset	=	remote_recv_offset;
10049   tcp_tran_rr_request->send_alignment	=	remote_send_align;
10050   tcp_tran_rr_request->send_offset	=	remote_send_offset;
10051   tcp_tran_rr_request->request_size	=	req_size;
10052   tcp_tran_rr_request->response_size	=	rsp_size;
10053   tcp_tran_rr_request->no_delay	        =	rem_nodelay;
10054   tcp_tran_rr_request->measure_cpu	=	remote_cpu_usage;
10055   tcp_tran_rr_request->cpu_rate	        =	remote_cpu_rate;
10056   tcp_tran_rr_request->so_rcvavoid	=	rem_rcvavoid;
10057   tcp_tran_rr_request->so_sndavoid	=	rem_sndavoid;
10058   if (test_time) {
10059     tcp_tran_rr_request->test_length	=	test_time;
10060   }
10061   else {
10062     tcp_tran_rr_request->test_length	=	test_trans * -1;
10063   }
10064   tcp_tran_rr_request->port             =       atoi(remote_data_port);
10065   tcp_tran_rr_request->ipfamily        =       af_to_nf(remote_res->ai_family);
10066 
10067   if (debug > 1) {
10068     fprintf(where,"netperf: send_tcp_tran_rr: requesting TCP_TRR test\n");
10069   }
10070 
10071   send_request();
10072 
10073   /* The response from the remote will contain all of the relevant 	*/
10074   /* socket parameters for this test type. We will put them back into 	*/
10075   /* the variables here so they can be displayed if desired.  The	*/
10076   /* remote will have calibrated CPU if necessary, and will have done	*/
10077   /* all the needed set-up we will have calibrated the cpu locally	*/
10078   /* before sending the request, and will grab the counter value right	*/
10079   /* after the connect returns. The remote will grab the counter right	*/
10080   /* after the accept call. This saves the hassle of extra messages	*/
10081   /* being sent for the TCP tests.					*/
10082 
10083   recv_response();
10084 
10085   if (!netperf_response.content.serv_errno) {
10086     rsr_size	=	tcp_tran_rr_response->recv_buf_size;
10087     rss_size	=	tcp_tran_rr_response->send_buf_size;
10088     rem_nodelay	=	tcp_tran_rr_response->no_delay;
10089     remote_cpu_usage=	tcp_tran_rr_response->measure_cpu;
10090     remote_cpu_rate = 	tcp_tran_rr_response->cpu_rate;
10091     /* make sure that port numbers are in network order */
10092     server.sin_port	=	tcp_tran_rr_response->data_port_number;
10093     server.sin_port =	htons(server.sin_port);
10094     if (debug) {
10095       fprintf(where,"remote listen done.\n");
10096       fprintf(where,"remote port is %d\n",ntohs(server.sin_port));
10097       fflush(where);
10098     }
10099   }
10100   else {
10101     Set_errno(netperf_response.content.serv_errno);
10102     fprintf(where,
10103 	    "netperf: remote error %d",
10104 	    netperf_response.content.serv_errno);
10105     perror("");
10106     fflush(where);
10107     exit(1);
10108   }
10109 
10110   /* pick a nice random spot between client_port_min and */
10111   /* client_port_max for our initial port number. if they are the */
10112   /* same, then just set to _min */
10113   if (client_port_max - client_port_min) {
10114     srand(getpid());
10115     myport = client_port_min +
10116       (rand() % (client_port_max - client_port_min));
10117   }
10118   else {
10119     myport = client_port_min;
10120   }
10121 
10122   /* there will be a ++ before the first call to bind, so subtract one */
10123   myport--;
10124   myaddr->sin_port = htons((unsigned short)myport);
10125 
10126   /* Set-up the test end conditions. For a request/response test, they */
10127   /* can be either time or transaction based. */
10128 
10129   if (test_time) {
10130     /* The user wanted to end the test after a period of time. */
10131     times_up = 0;
10132     trans_remaining = 0;
10133     start_timer(test_time);
10134   }
10135   else {
10136     /* The tester wanted to send a number of bytes. */
10137     trans_remaining = test_bytes;
10138     times_up = 1;
10139   }
10140 
10141   /* The cpu_start routine will grab the current time and possibly */
10142   /* value of the idle counter for later use in measuring cpu */
10143   /* utilization and/or service demand and thruput. */
10144 
10145   cpu_start(local_cpu_usage);
10146 
10147   /* We use an "OR" to control test execution. When the test is */
10148   /* controlled by time, the byte count check will always return false. */
10149   /* When the test is controlled by byte count, the time test will */
10150   /* always return false. When the test is finished, the whole */
10151   /* expression will go false and we will stop sending data. I think I */
10152   /* just arbitrarily decrement trans_remaining for the timed test, but */
10153   /* will not do that just yet... One other question is whether or not */
10154   /* the send buffer and the receive buffer should be the same buffer. */
10155 
10156   while ((!times_up) || (trans_remaining > 0)) {
10157 
10158 #ifdef WANT_HISTOGRAM
10159     if (verbosity > 1) {
10160       /* timestamp just before our call to create the socket, and then */
10161       /* again just after the receive raj 3/95 */
10162       HIST_timestamp(&time_one);
10163     }
10164 #endif /* WANT_HISTOGRAM */
10165 
10166     /* set up the data socket - is this really necessary or can I just */
10167     /* re-use the same socket and move this cal out of the while loop. */
10168     /* it does introcudea *boatload* of system calls. I guess that it */
10169     /* all depends on "reality of programming." keeping it this way is */
10170     /* a bit more conservative I imagine - raj 3/95 */
10171     send_socket = create_data_socket(local_res);
10172 
10173     if (send_socket == INVALID_SOCKET) {
10174       perror("netperf: send_tcp_tran_rr: tcp stream data socket");
10175       exit(1);
10176     }
10177 
10178     /* we set SO_REUSEADDR on the premis that no unreserved port */
10179     /* number on the local system is going to be already connected to */
10180     /* the remote netserver's port number. One thing that I might */
10181     /* try later is to have the remote actually allocate a couple of */
10182     /* port numbers and cycle through those as well. depends on if we */
10183     /* can get through all the unreserved port numbers in less than */
10184     /* the length of the TIME_WAIT state raj 8/94 */
10185     one = 1;
10186     if(setsockopt(send_socket, SOL_SOCKET, SO_REUSEADDR,
10187 		  (char *)&one, sock_opt_len) == SOCKET_ERROR) {
10188       perror("netperf: send_tcp_tran_rr: so_reuseaddr");
10189       exit(1);
10190     }
10191 
10192 newport:
10193     /* pick a new port number */
10194     myport = ntohs(myaddr->sin_port);
10195     myport++;
10196 
10197     /* we do not want to use the port number that the server is */
10198     /* sitting at - this would cause us to fail in a loopback test. we */
10199     /* could just rely on the failure of the bind to get us past this, */
10200     /* but I'm guessing that in this one case at least, it is much */
10201     /* faster, given that we *know* that port number is already in use */
10202     /* (or rather would be in a loopback test) */
10203 
10204     if (myport == ntohs(server.sin_port)) myport++;
10205 
10206     /* wrap the port number when we get to 65535. NOTE, some broken */
10207     /* TCP's might treat the port number as a signed 16 bit quantity. */
10208     /* we aren't interested in testing such broken implementations :) */
10209     /* raj 8/94  */
10210     if (myport >= client_port_max) {
10211       myport = client_port_min;
10212     }
10213     myaddr->sin_port = htons((unsigned short)myport);
10214 
10215     if (debug) {
10216       if ((nummessages % 100) == 0) {
10217 	printf("port %d\n",myport);
10218       }
10219     }
10220 
10221     /* we want to bind our socket to a particular port number. */
10222     if (bind(send_socket,
10223 	     (struct sockaddr *)myaddr,
10224 	     sizeof(struct sockaddr_storage)) == SOCKET_ERROR) {
10225       /* if the bind failed, someone else must have that port number */
10226       /* - perhaps in the listen state. since we can't use it, skip to */
10227       /* the next port number. we may have to do this again later, but */
10228       /* that's just too bad :) */
10229       if (debug > 1) {
10230 	fprintf(where,
10231 		"send_tcp_tran_rr: tried to bind to port %d errno %d\n",
10232 		ntohs(myaddr->sin_port),
10233 		errno);
10234 	fflush(where);
10235       }
10236 	/* yes, goto's are supposed to be evil, but they do have their */
10237 	/* uses from time to time. the real world doesn't always have */
10238 	/* to code to ge tthe A in CS 101 :) raj 3/95 */
10239 	goto newport;
10240     }
10241 
10242     /* Connect up to the remote port on the data socket. Since this is */
10243     /* a test for RFC_1644-style transactional TCP, we can use the */
10244     /* sendto() call instead of calling connect and then send() */
10245 
10246     /* send the request */
10247     if((len=sendto(send_socket,
10248 		   send_ring->buffer_ptr,
10249 		   req_size,
10250 		   MSG_EOF,
10251 		   (struct sockaddr *)&server,
10252 		   sizeof(server))) != req_size) {
10253       if (SOCKET_EINTR(len))
10254 	  {
10255 	    /* we hit the end of a */
10256 	    /* timed test. */
10257 	    timed_out = 1;
10258 	    break;
10259       }
10260       perror("send_tcp_tran_rr: data send error");
10261       exit(1);
10262     }
10263     send_ring = send_ring->next;
10264 
10265     /* receive the response */
10266     rsp_bytes_left = rsp_size;
10267     temp_message_ptr  = recv_ring->buffer_ptr;
10268     while(rsp_bytes_left > 0) {
10269       if((rsp_bytes_recvd=recv(send_socket,
10270 			       temp_message_ptr,
10271 			       rsp_bytes_left,
10272 			       0)) == SOCKET_ERROR) {
10273 	    if (SOCKET_EINTR(rsp_bytes_recvd))
10274 		{
10275 	      /* We hit the end of a timed test. */
10276 	      timed_out = 1;
10277 	      break;
10278 		}
10279 	    perror("send_tcp_tran_rr: data recv error");
10280 	    exit(1);
10281       }
10282       rsp_bytes_left -= rsp_bytes_recvd;
10283       temp_message_ptr  += rsp_bytes_recvd;
10284     }
10285     recv_ring = recv_ring->next;
10286 
10287     if (timed_out) {
10288       /* we may have been in a nested while loop - we need */
10289       /* another call to break. */
10290       break;
10291     }
10292 
10293     close(send_socket);
10294 
10295 #ifdef WANT_HISTOGRAM
10296     if (verbosity > 1) {
10297       HIST_timestamp(&time_two);
10298       HIST_add(time_hist,delta_micro(&time_one,&time_two));
10299     }
10300 #endif /* WANT_HISTOGRAM */
10301 
10302     nummessages++;
10303     if (trans_remaining) {
10304       trans_remaining--;
10305     }
10306 
10307     if (debug > 3) {
10308       fprintf(where,
10309 	      "Transaction %d completed on local port %d\n",
10310 	      nummessages,
10311 	      ntohs(myaddr->sin_port));
10312       fflush(where);
10313     }
10314 
10315 
10316   }
10317 
10318   /* this call will always give us the elapsed time for the test, and */
10319   /* will also store-away the necessaries for cpu utilization */
10320 
10321   cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being measured? */
10322   /* how long did we really run? */
10323 
10324   /* Get the statistics from the remote end. The remote will have */
10325   /* calculated service demand and all those interesting things. If it */
10326   /* wasn't supposed to care, it will return obvious values. */
10327 
10328   recv_response();
10329   if (!netperf_response.content.serv_errno) {
10330     if (debug)
10331       fprintf(where,"remote results obtained\n");
10332   }
10333   else {
10334     Set_errno(netperf_response.content.serv_errno);
10335     fprintf(where,
10336 	    "netperf: remote error %d",
10337 	    netperf_response.content.serv_errno);
10338     perror("");
10339     fflush(where);
10340     exit(1);
10341   }
10342 
10343   /* We now calculate what our thruput was for the test. In the future, */
10344   /* we may want to include a calculation of the thruput measured by */
10345   /* the remote, but it should be the case that for a TCP stream test, */
10346   /* that the two numbers should be *very* close... We calculate */
10347   /* bytes_sent regardless of the way the test length was controlled. */
10348   /* If it was time, we needed to, and if it was by bytes, the user may */
10349   /* have specified a number of bytes that wasn't a multiple of the */
10350   /* send_size, so we really didn't send what he asked for ;-) We use */
10351   /* Kbytes/s as the units of thruput for a TCP stream test, where K = */
10352   /* 1024. A future enhancement *might* be to choose from a couple of */
10353   /* unit selections. */
10354 
10355   bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
10356   thruput	= calc_thruput(bytes_xferd);
10357 
10358   if (local_cpu_usage || remote_cpu_usage) {
10359     /* We must now do a little math for service demand and cpu */
10360     /* utilization for the system(s) */
10361     /* Of course, some of the information might be bogus because */
10362     /* there was no idle counter in the kernel(s). We need to make */
10363     /* a note of this for the user's benefit...*/
10364     if (local_cpu_usage) {
10365       if (local_cpu_rate == 0.0) {
10366 	fprintf(where,"WARNING WARNING WARNING  WARNING WARNING WARNING  WARNING!\n");
10367 	fprintf(where,"Local CPU usage numbers based on process information only!\n");
10368 	fflush(where);
10369       }
10370       local_cpu_utilization = calc_cpu_util(0.0);
10371       /* since calc_service demand is doing ms/Kunit we will */
10372       /* multiply the number of transaction by 1024 to get */
10373       /* "good" numbers */
10374       local_service_demand  = calc_service_demand((double) nummessages*1024,
10375 						  0.0,
10376 						  0.0,
10377 						  0);
10378     }
10379     else {
10380       local_cpu_utilization	= (float) -1.0;
10381       local_service_demand	= (float) -1.0;
10382     }
10383 
10384     if (remote_cpu_usage) {
10385       if (remote_cpu_rate == 0.0) {
10386 	fprintf(where,"DANGER  DANGER  DANGER    DANGER  DANGER  DANGER    DANGER!\n");
10387 	fprintf(where,"Remote CPU usage numbers based on process information only!\n");
10388 	fflush(where);
10389       }
10390       remote_cpu_utilization = tcp_tran_rr_result->cpu_util;
10391       /* since calc_service demand is doing ms/Kunit we will */
10392       /* multiply the number of transaction by 1024 to get */
10393       /* "good" numbers */
10394       remote_service_demand = calc_service_demand((double) nummessages*1024,
10395 						  0.0,
10396 						  remote_cpu_utilization,
10397 						  tcp_tran_rr_result->num_cpus);
10398     }
10399     else {
10400       remote_cpu_utilization = (float) -1.0;
10401       remote_service_demand  = (float) -1.0;
10402     }
10403 
10404     /* We are now ready to print all the information. If the user */
10405     /* has specified zero-level verbosity, we will just print the */
10406     /* local service demand, or the remote service demand. If the */
10407     /* user has requested verbosity level 1, he will get the basic */
10408     /* "streamperf" numbers. If the user has specified a verbosity */
10409     /* of greater than 1, we will display a veritable plethora of */
10410     /* background information from outside of this block as it it */
10411     /* not cpu_measurement specific...  */
10412 
10413     switch (verbosity) {
10414     case 0:
10415       if (local_cpu_usage) {
10416 	fprintf(where,
10417 		cpu_fmt_0,
10418 		local_service_demand);
10419       }
10420       else {
10421 	fprintf(where,
10422 		cpu_fmt_0,
10423 		remote_service_demand);
10424       }
10425       break;
10426     case 1:
10427     case 2:
10428 
10429       if (print_headers) {
10430 	fprintf(where,
10431 		cpu_title,
10432 		local_cpu_method,
10433 		remote_cpu_method);
10434       }
10435 
10436       fprintf(where,
10437 	      cpu_fmt_1_line_1,		/* the format string */
10438 	      lss_size,		/* local sendbuf size */
10439 	      lsr_size,
10440 	      req_size,		/* how large were the requests */
10441 	      rsp_size,		/* guess */
10442 	      elapsed_time,		/* how long was the test */
10443 	      nummessages/elapsed_time,
10444 	      local_cpu_utilization,	/* local cpu */
10445 	      remote_cpu_utilization,	/* remote cpu */
10446 	      local_service_demand,	/* local service demand */
10447 	      remote_service_demand);	/* remote service demand */
10448       fprintf(where,
10449 	      cpu_fmt_1_line_2,
10450 	      rss_size,
10451 	      rsr_size);
10452       break;
10453     }
10454   }
10455   else {
10456     /* The tester did not wish to measure service demand. */
10457     switch (verbosity) {
10458     case 0:
10459       fprintf(where,
10460 	      tput_fmt_0,
10461 	      nummessages/elapsed_time);
10462       break;
10463     case 1:
10464     case 2:
10465       if (print_headers) {
10466 	fprintf(where,tput_title,format_units());
10467       }
10468 
10469       fprintf(where,
10470 	      tput_fmt_1_line_1,	/* the format string */
10471 	      lss_size,
10472 	      lsr_size,
10473 	      req_size,		/* how large were the requests */
10474 	      rsp_size,		/* how large were the responses */
10475 	      elapsed_time, 		/* how long did it take */
10476 	      nummessages/elapsed_time);
10477       fprintf(where,
10478 	      tput_fmt_1_line_2,
10479 	      rss_size, 		/* remote recvbuf size */
10480 	      rsr_size);
10481 
10482       break;
10483     }
10484   }
10485 
10486   /* it would be a good thing to include information about some of the */
10487   /* other parameters that may have been set for this test, but at the */
10488   /* moment, I do not wish to figure-out all the  formatting, so I will */
10489   /* just put this comment here to help remind me that it is something */
10490   /* that should be done at a later time. */
10491 
10492   if (verbosity > 1) {
10493     /* The user wanted to know it all, so we will give it to him. */
10494     /* This information will include as much as we can find about */
10495     /* TCP statistics, the alignments of the sends and receives */
10496     /* and all that sort of rot... */
10497 
10498     fprintf(where,
10499 	    ksink_fmt,
10500 	    local_send_align,
10501 	    remote_recv_offset,
10502 	    local_send_offset,
10503 	    remote_recv_offset);
10504 
10505 #ifdef WANT_HISTOGRAM
10506     fprintf(where,"\nHistogram of request/response times\n");
10507     fflush(where);
10508     HIST_report(time_hist);
10509 #endif /* WANT_HISTOGRAM */
10510 
10511   }
10512 
10513 }
10514 
10515 
10516 int
recv_tcp_tran_rr()10517 recv_tcp_tran_rr()
10518 {
10519 
10520   char  *message;
10521   struct	sockaddr_in        myaddr_in,
10522   peeraddr_in;
10523   SOCKET	s_listen,s_data;
10524   netperf_socklen_t 	addrlen;
10525   int   NoPush = 1;
10526 
10527   char	*recv_message_ptr;
10528   char	*send_message_ptr;
10529   char	*temp_message_ptr;
10530   int	trans_received;
10531   int	trans_remaining;
10532   int	bytes_sent;
10533   int	request_bytes_recvd;
10534   int	request_bytes_remaining;
10535   int	timed_out = 0;
10536   float	elapsed_time;
10537 
10538   struct	tcp_tran_rr_request_struct	*tcp_tran_rr_request;
10539   struct	tcp_tran_rr_response_struct	*tcp_tran_rr_response;
10540   struct	tcp_tran_rr_results_struct	*tcp_tran_rr_results;
10541 
10542   tcp_tran_rr_request =
10543     (struct tcp_tran_rr_request_struct *)netperf_request.content.test_specific_data;
10544   tcp_tran_rr_response =
10545     (struct tcp_tran_rr_response_struct *)netperf_response.content.test_specific_data;
10546   tcp_tran_rr_results =
10547     (struct tcp_tran_rr_results_struct *)netperf_response.content.test_specific_data;
10548 
10549   if (debug) {
10550     fprintf(where,"netserver: recv_tcp_tran_rr: entered...\n");
10551     fflush(where);
10552   }
10553 
10554   /* We want to set-up the listen socket with all the desired */
10555   /* parameters and then let the initiator know that all is ready. If */
10556   /* socket size defaults are to be used, then the initiator will have */
10557   /* sent us 0's. If the socket sizes cannot be changed, then we will */
10558   /* send-back what they are. If that information cannot be determined, */
10559   /* then we send-back -1's for the sizes. If things go wrong for any */
10560   /* reason, we will drop back ten yards and punt. */
10561 
10562   /* If anything goes wrong, we want the remote to know about it. It */
10563   /* would be best if the error that the remote reports to the user is */
10564   /* the actual error we encountered, rather than some bogus unexpected */
10565   /* response type message. */
10566 
10567   if (debug) {
10568     fprintf(where,"recv_tcp_tran_rr: setting the response type...\n");
10569     fflush(where);
10570   }
10571 
10572   netperf_response.content.response_type = TCP_TRR_RESPONSE;
10573 
10574   if (debug) {
10575     fprintf(where,"recv_tcp_tran_rr: the response type is set...\n");
10576     fflush(where);
10577   }
10578 
10579   /* set-up the data buffer with the requested alignment and offset */
10580   message = (char *)malloc(DATABUFFERLEN);
10581   if (message == NULL) {
10582     printf("malloc(%d) failed!\n", DATABUFFERLEN);
10583     exit(1);
10584   }
10585 
10586   /* We now alter the message_ptr variables to be at the desired */
10587   /* alignments with the desired offsets. */
10588 
10589   if (debug) {
10590     fprintf(where,
10591 	    "recv_tcp_tran_rr: requested recv alignment of %d offset %d\n",
10592 	    tcp_tran_rr_request->recv_alignment,
10593 	    tcp_tran_rr_request->recv_offset);
10594     fprintf(where,
10595 	    "recv_tcp_tran_rr: requested send alignment of %d offset %d\n",
10596 	    tcp_tran_rr_request->send_alignment,
10597 	    tcp_tran_rr_request->send_offset);
10598     fflush(where);
10599   }
10600 
10601   recv_message_ptr = ALIGN_BUFFER(message, tcp_tran_rr_request->recv_alignment, tcp_tran_rr_request->recv_offset);
10602 
10603   send_message_ptr = ALIGN_BUFFER(message, tcp_tran_rr_request->send_alignment, tcp_tran_rr_request->send_offset);
10604 
10605   if (debug) {
10606     fprintf(where,"recv_tcp_tran_rr: receive alignment and offset set...\n");
10607     fflush(where);
10608   }
10609 
10610   /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */
10611   /* can put in OUR values !-) At some point, we may want to nail this */
10612   /* socket to a particular network-level address, but for now, */
10613   /* INADDR_ANY should be just fine. */
10614 
10615   bzero((char *)&myaddr_in,
10616 	sizeof(myaddr_in));
10617   myaddr_in.sin_family      = AF_INET;
10618   myaddr_in.sin_addr.s_addr = INADDR_ANY;
10619   myaddr_in.sin_port        = htons((unsigned short)tcp_tran_rr_request->port);
10620 
10621   /* Grab a socket to listen on, and then listen on it. */
10622 
10623   if (debug) {
10624     fprintf(where,"recv_tcp_tran_rr: grabbing a socket...\n");
10625     fflush(where);
10626   }
10627 
10628   /* create_data_socket expects to find some things in the global */
10629   /* variables, so set the globals based on the values in the request. */
10630   /* once the socket has been created, we will set the response values */
10631   /* based on the updated value of those globals. raj 7/94 */
10632   lss_size_req = tcp_tran_rr_request->send_buf_size;
10633   lsr_size_req = tcp_tran_rr_request->recv_buf_size;
10634   loc_nodelay = tcp_tran_rr_request->no_delay;
10635   loc_rcvavoid = tcp_tran_rr_request->so_rcvavoid;
10636   loc_sndavoid = tcp_tran_rr_request->so_sndavoid;
10637 
10638   set_hostname_and_port(local_name,
10639 			port_buffer,
10640 			nf_to_af(tcp_tran_rr_request->ipfamily),
10641 			tcp_tran_rr_request->port);
10642 
10643   local_res = complete_addrinfo(local_name,
10644 				local_name,
10645 				port_buffer,
10646 				nf_to_af(tcp_tran_rr_request->ipfamily),
10647 				SOCK_STREAM,
10648 				IPPROTO_TCP,
10649 				0);
10650 
10651   s_listen = create_data_socket(local_res);
10652 
10653   if (s_listen == INVALID_SOCKET) {
10654     netperf_response.content.serv_errno = errno;
10655     send_response();
10656     if (debug) {
10657       fprintf(where,"could not create data socket\n");
10658       fflush(where);
10659     }
10660     exit(1);
10661   }
10662 
10663 #ifdef WIN32
10664   /* The test timer can fire during operations on the listening socket,
10665      so to make the start_timer below work we have to move
10666      it to close s_listen while we are blocked on accept. */
10667   win_kludge_socket2 = s_listen;
10668 #endif
10669 
10670 
10671   /* Let's get an address assigned to this socket so we can tell the */
10672   /* initiator how to reach the data socket. There may be a desire to */
10673   /* nail this socket to a specific IP address in a multi-homed, */
10674   /* multi-connection situation, but for now, we'll ignore the issue */
10675   /* and concentrate on single connection testing. */
10676 
10677   if (bind(s_listen,
10678 	   (struct sockaddr *)&myaddr_in,
10679 	   sizeof(myaddr_in)) == SOCKET_ERROR) {
10680     netperf_response.content.serv_errno = errno;
10681     close(s_listen);
10682     send_response();
10683     if (debug) {
10684       fprintf(where,"could not bind\n");
10685       fflush(where);
10686     }
10687     exit(1);
10688   }
10689 
10690   /* we want to disable the implicit PUSH on all sends. at some point, */
10691   /* this might want to be a parm to the test raj 3/95 */
10692   if (setsockopt(s_listen,
10693 		 IPPROTO_TCP,
10694 		 TCP_NOPUSH,
10695 		 (const char *)&NoPush,
10696 		 sizeof(int)) == SOCKET_ERROR) {
10697     fprintf(where,
10698 	    "recv_tcp_tran_rr: could not set TCP_NOPUSH errno %d\n",
10699 	    errno);
10700     fflush(where);
10701     netperf_response.content.serv_errno = errno;
10702     close(s_listen);
10703     send_response();
10704   }
10705 
10706   /* Now, let's set-up the socket to listen for connections */
10707   if (listen(s_listen, 5) == SOCKET_ERROR) {
10708     netperf_response.content.serv_errno = errno;
10709     close(s_listen);
10710     send_response();
10711     if (debug) {
10712       fprintf(where,"could not listen\n");
10713       fflush(where);
10714     }
10715     exit(1);
10716   }
10717 
10718   /* now get the port number assigned by the system  */
10719   addrlen = sizeof(myaddr_in);
10720   if (getsockname(s_listen,
10721 		  (struct sockaddr *)&myaddr_in,
10722 		  &addrlen) == SOCKET_ERROR){
10723     netperf_response.content.serv_errno = errno;
10724     close(s_listen);
10725     send_response();
10726     if (debug) {
10727       fprintf(where,"could not geetsockname\n");
10728       fflush(where);
10729     }
10730     exit(1);
10731   }
10732 
10733   /* Now myaddr_in contains the port and the internet address this is */
10734   /* returned to the sender also implicitly telling the sender that the */
10735   /* socket buffer sizing has been done. */
10736 
10737   tcp_tran_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port);
10738   if (debug) {
10739     fprintf(where,"telling the remote to call me at %d\n",
10740 	    tcp_tran_rr_response->data_port_number);
10741     fflush(where);
10742   }
10743   netperf_response.content.serv_errno   = 0;
10744 
10745   /* But wait, there's more. If the initiator wanted cpu measurements, */
10746   /* then we must call the calibrate routine, which will return the max */
10747   /* rate back to the initiator. If the CPU was not to be measured, or */
10748   /* something went wrong with the calibration, we will return a 0.0 to */
10749   /* the initiator. */
10750 
10751   tcp_tran_rr_response->cpu_rate = 0.0; 	/* assume no cpu */
10752   if (tcp_tran_rr_request->measure_cpu) {
10753     tcp_tran_rr_response->measure_cpu = 1;
10754     tcp_tran_rr_response->cpu_rate =
10755       calibrate_local_cpu(tcp_tran_rr_request->cpu_rate);
10756   }
10757 
10758 
10759 
10760   /* before we send the response back to the initiator, pull some of */
10761   /* the socket parms from the globals */
10762   tcp_tran_rr_response->send_buf_size = lss_size;
10763   tcp_tran_rr_response->recv_buf_size = lsr_size;
10764   tcp_tran_rr_response->no_delay = loc_nodelay;
10765   tcp_tran_rr_response->so_rcvavoid = loc_rcvavoid;
10766   tcp_tran_rr_response->so_sndavoid = loc_sndavoid;
10767 
10768   send_response();
10769 
10770   addrlen = sizeof(peeraddr_in);
10771 
10772   /* Now it's time to start receiving data on the connection. We will */
10773   /* first grab the apropriate counters and then start grabbing. */
10774 
10775   cpu_start(tcp_tran_rr_request->measure_cpu);
10776 
10777   /* The loop will exit when the sender does a shutdown, which will */
10778   /* return a length of zero   */
10779 
10780   if (tcp_tran_rr_request->test_length > 0) {
10781     times_up = 0;
10782     trans_remaining = 0;
10783     start_timer(tcp_tran_rr_request->test_length + PAD_TIME);
10784   }
10785   else {
10786     times_up = 1;
10787     trans_remaining = tcp_tran_rr_request->test_length * -1;
10788   }
10789 
10790   trans_received = 0;
10791 
10792   while ((!times_up) || (trans_remaining > 0)) {
10793 
10794     /* accept a connection from the remote */
10795     if ((s_data=accept(s_listen,
10796 		       (struct sockaddr *)&peeraddr_in,
10797 		       &addrlen)) == INVALID_SOCKET) {
10798       if (errno == EINTR) {
10799 	/* the timer popped */
10800 	timed_out = 1;
10801 	break;
10802       }
10803       fprintf(where,"recv_tcp_tran_rr: accept: errno = %d\n",errno);
10804       fflush(where);
10805       close(s_listen);
10806 
10807       exit(1);
10808     }
10809 
10810     if (debug) {
10811       fprintf(where,"recv_tcp_tran_rr: accepted data connection.\n");
10812       fflush(where);
10813     }
10814 
10815 #ifdef WIN32
10816   /* this is used so the timer thread can close the socket out from */
10817   /* under us, which to date is the easiest/cleanest/least */
10818   /* Windows-specific way I can find to force the winsock calls to */
10819   /* return WSAEINTR with the test is over. anything that will run on */
10820   /* 95 and NT and is closer to what netperf expects from Unix signals */
10821   /* and such would be appreciated raj 1/96 */
10822   win_kludge_socket = s_data;
10823 #endif /* WIN32 */
10824 
10825 #ifdef KLUDGE_SOCKET_OPTIONS
10826   /* this is for those systems which *INCORRECTLY* fail to pass */
10827   /* attributes across an accept() call. Including this goes against */
10828   /* my better judgement :( raj 11/95 */
10829 
10830   kludge_socket_options(s_data);
10831 
10832 #endif /* KLUDGE_SOCKET_OPTIONS */
10833 
10834     temp_message_ptr	= recv_message_ptr;
10835     request_bytes_remaining	= tcp_tran_rr_request->request_size;
10836 
10837     /* receive the request from the other side. we can just receive */
10838     /* until we get zero bytes, but that would be a slight structure */
10839     /* change in the code, with minimal perfomance effects. If */
10840     /* however, I has variable-length messages, I would want to do */
10841     /* this to avoid needing "double reads" - one for the message */
10842     /* length, and one for the rest of the message raj 3/95 */
10843     while(request_bytes_remaining > 0) {
10844       if((request_bytes_recvd=recv(s_data,
10845 				   temp_message_ptr,
10846 				   request_bytes_remaining,
10847 				   0)) == SOCKET_ERROR) {
10848 	    if ( SOCKET_EINTR(request_bytes_recvd) )
10849 		{
10850 	      /* the timer popped */
10851 	      timed_out = 1;
10852 	      break;
10853 		}
10854 	    netperf_response.content.serv_errno = errno;
10855 	    send_response();
10856 	    exit(1);
10857       }
10858       else {
10859 	request_bytes_remaining -= request_bytes_recvd;
10860 	temp_message_ptr  += request_bytes_recvd;
10861       }
10862     }
10863 
10864     if (timed_out) {
10865       /* we hit the end of the test based on time - lets */
10866       /* bail out of here now... */
10867       fprintf(where,"yo5\n");
10868       fflush(where);
10869       break;
10870     }
10871 
10872     /* Now, send the response to the remote we can use sendto here to */
10873     /* help remind people that this is an rfc 1644 style of test */
10874     if((bytes_sent=sendto(s_data,
10875 			  send_message_ptr,
10876 			  tcp_tran_rr_request->response_size,
10877 			  MSG_EOF,
10878 			  (struct sockaddr *)&peeraddr_in,
10879 			  sizeof(struct sockaddr_storage))) == SOCKET_ERROR) {
10880       if (SOCKET_EINTR(bytes_sent)) {
10881 	/* the test timer has popped */
10882 	timed_out = 1;
10883 	fprintf(where,"yo6\n");
10884 	fflush(where);
10885 	break;
10886       }
10887       netperf_response.content.serv_errno = 99;
10888       send_response();
10889       exit(1);
10890     }
10891 
10892     trans_received++;
10893     if (trans_remaining) {
10894       trans_remaining--;
10895     }
10896 
10897     if (debug) {
10898       fprintf(where,
10899 	      "recv_tcp_tran_rr: Transaction %d complete\n",
10900 	      trans_received);
10901       fflush(where);
10902     }
10903 
10904     /* close the connection. since we have disable PUSH on sends, the */
10905     /* FIN should be tacked-onto our last send instead of being */
10906     /* standalone */
10907     close(s_data);
10908 
10909   }
10910 
10911 
10912   /* The loop now exits due to timeout or transaction count being */
10913   /* reached */
10914 
10915   cpu_stop(tcp_tran_rr_request->measure_cpu,&elapsed_time);
10916 
10917   if (timed_out) {
10918     /* we ended the test by time, which was at least 2 seconds */
10919     /* longer than we wanted to run. so, we want to subtract */
10920     /* PAD_TIME from the elapsed_time. */
10921     elapsed_time -= PAD_TIME;
10922   }
10923   /* send the results to the sender			*/
10924 
10925   if (debug) {
10926     fprintf(where,
10927 	    "recv_tcp_tran_rr: got %d transactions\n",
10928 	    trans_received);
10929     fflush(where);
10930   }
10931 
10932   tcp_tran_rr_results->bytes_received	= (trans_received *
10933 					   (tcp_tran_rr_request->request_size +
10934 					    tcp_tran_rr_request->response_size));
10935   tcp_tran_rr_results->trans_received	= trans_received;
10936   tcp_tran_rr_results->elapsed_time	= elapsed_time;
10937   if (tcp_tran_rr_request->measure_cpu) {
10938     tcp_tran_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
10939   }
10940 
10941   if (debug) {
10942     fprintf(where,
10943 	    "recv_tcp_tran_rr: test complete, sending results.\n");
10944     fflush(where);
10945   }
10946 
10947   send_response();
10948 
10949 }
10950 #endif /* DO_1644 */
10951 
10952 #ifdef DO_NBRR
10953  /* this routine implements the sending (netperf) side of the TCP_RR */
10954  /* test using POSIX-style non-blocking sockets. */
10955 
10956 void
send_tcp_nbrr(char remote_host[])10957 send_tcp_nbrr(char remote_host[])
10958 {
10959 
10960   char *tput_title = "\
10961 Local /Remote\n\
10962 Socket Size   Request  Resp.   Elapsed  Trans.\n\
10963 Send   Recv   Size     Size    Time     Rate         \n\
10964 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
10965 
10966   char *tput_fmt_0 =
10967     "%7.2f\n";
10968 
10969   char *tput_fmt_1_line_1 = "\
10970 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
10971   char *tput_fmt_1_line_2 = "\
10972 %-6d %-6d\n";
10973 
10974   char *cpu_title = "\
10975 Local /Remote\n\
10976 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
10977 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
10978 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
10979 
10980   char *cpu_fmt_0 =
10981     "%6.3f %c\n";
10982 
10983   char *cpu_fmt_1_line_1 = "\
10984 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f  %-6.2f %-6.2f %-6.3f  %-6.3f\n";
10985 
10986   char *cpu_fmt_1_line_2 = "\
10987 %-6d %-6d\n";
10988 
10989   char *ksink_fmt = "\
10990 Alignment      Offset\n\
10991 Local  Remote  Local  Remote\n\
10992 Send   Recv    Send   Recv\n\
10993 %5d  %5d   %5d  %5d\n";
10994 
10995 
10996   int			timed_out = 0;
10997   float			elapsed_time;
10998 
10999   int	len;
11000   char	*temp_message_ptr;
11001   int	nummessages;
11002   SOCKET	send_socket;
11003   int	trans_remaining;
11004   double	bytes_xferd;
11005 
11006   struct ring_elt *send_ring;
11007   struct ring_elt *recv_ring;
11008 
11009   int	rsp_bytes_left;
11010   int	rsp_bytes_recvd;
11011 
11012   float	local_cpu_utilization;
11013   float	local_service_demand;
11014   float	remote_cpu_utilization;
11015   float	remote_service_demand;
11016   double	thruput;
11017 
11018   struct	hostent	        *hp;
11019   struct	sockaddr_storage	server;
11020   unsigned      int             addr;
11021 
11022   struct	tcp_rr_request_struct	*tcp_rr_request;
11023   struct	tcp_rr_response_struct	*tcp_rr_response;
11024   struct	tcp_rr_results_struct	*tcp_rr_result;
11025 
11026   struct addrinfo *remote_res;
11027   struct addrinfo *local_res;
11028 
11029   tcp_rr_request =
11030     (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data;
11031   tcp_rr_response=
11032     (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data;
11033   tcp_rr_result	=
11034     (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data;
11035 
11036 #ifdef WANT_HISTOGRAM
11037   if (verbosity > 1) {
11038     time_hist = HIST_new();
11039   }
11040 #endif /* WANT_HISTOGRAM */
11041 
11042   /* since we are now disconnected from the code that established the */
11043   /* control socket, and since we want to be able to use different */
11044   /* protocols and such, we are passed the name of the remote host and */
11045   /* must turn that into the test specific addressing information. */
11046 
11047   bzero((char *)&server,
11048 	sizeof(server));
11049 
11050   complete_addrinfos(&remote_res,
11051 		     &local_res,
11052 		     remote_host,
11053 		     SOCK_STREAM,
11054 		     IPPROTO_TCP,
11055 		     0);
11056 
11057   if ( print_headers ) {
11058     print_top_test_header("TCP Non-Blocking REQUEST/RESPONSE TEST",local_res,remote_res);
11059   }
11060 
11061   /* initialize a few counters */
11062 
11063   send_ring = NULL;
11064   recv_ring = NULL;
11065   confidence_iteration = 1;
11066   init_stat();
11067 
11068   /* we have a great-big while loop which controls the number of times */
11069   /* we run a particular test. this is for the calculation of a */
11070   /* confidence interval (I really should have stayed awake during */
11071   /* probstats :). If the user did not request confidence measurement */
11072   /* (no confidence is the default) then we will only go though the */
11073   /* loop once. the confidence stuff originates from the folks at IBM */
11074 
11075   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
11076 	 (confidence_iteration <= iteration_min)) {
11077 
11078     /* initialize a few counters. we have to remember that we might be */
11079     /* going through the loop more than once. */
11080 
11081     nummessages     = 0;
11082     bytes_xferd     = 0.0;
11083     times_up        = 0;
11084     timed_out       = 0;
11085     trans_remaining = 0;
11086 
11087     /* set-up the data buffers with the requested alignment and offset. */
11088     /* since this is a request/response test, default the send_width and */
11089     /* recv_width to 1 and not two raj 7/94 */
11090 
11091     if (send_width == 0) send_width = 1;
11092     if (recv_width == 0) recv_width = 1;
11093 
11094     if (send_ring == NULL) {
11095       send_ring = allocate_buffer_ring(send_width,
11096 				       req_size,
11097 				       local_send_align,
11098 				       local_send_offset);
11099     }
11100 
11101     if (recv_ring == NULL) {
11102       recv_ring = allocate_buffer_ring(recv_width,
11103 				       rsp_size,
11104 				       local_recv_align,
11105 				       local_recv_offset);
11106     }
11107 
11108     /*set up the data socket                        */
11109     send_socket = create_data_socket(local_res);
11110 
11111     if (send_socket == INVALID_SOCKET){
11112       perror("netperf: send_tcp_nbrr: tcp stream data socket");
11113       exit(1);
11114     }
11115 
11116     if (debug) {
11117       fprintf(where,"send_tcp_nbrr: send_socket obtained...\n");
11118     }
11119 
11120     /* If the user has requested cpu utilization measurements, we must */
11121     /* calibrate the cpu(s). We will perform this task within the tests */
11122     /* themselves. If the user has specified the cpu rate, then */
11123     /* calibrate_local_cpu will return rather quickly as it will have */
11124     /* nothing to do. If local_cpu_rate is zero, then we will go through */
11125     /* all the "normal" calibration stuff and return the rate back.*/
11126 
11127     if (local_cpu_usage) {
11128       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
11129     }
11130 
11131     /* Tell the remote end to do a listen. The server alters the socket */
11132     /* paramters on the other side at this point, hence the reason for */
11133     /* all the values being passed in the setup message. If the user did */
11134     /* not specify any of the parameters, they will be passed as 0, which */
11135     /* will indicate to the remote that no changes beyond the system's */
11136     /* default should be used. Alignment is the exception, it will */
11137     /* default to 8, which will be no alignment alterations. */
11138 
11139     netperf_request.content.request_type	=	DO_TCP_NBRR;
11140     tcp_rr_request->recv_buf_size	=	rsr_size_req;
11141     tcp_rr_request->send_buf_size	=	rss_size_req;
11142     tcp_rr_request->recv_alignment      =	remote_recv_align;
11143     tcp_rr_request->recv_offset	        =	remote_recv_offset;
11144     tcp_rr_request->send_alignment      =	remote_send_align;
11145     tcp_rr_request->send_offset	        =	remote_send_offset;
11146     tcp_rr_request->request_size	=	req_size;
11147     tcp_rr_request->response_size	=	rsp_size;
11148     tcp_rr_request->no_delay	        =	rem_nodelay;
11149     tcp_rr_request->measure_cpu	        =	remote_cpu_usage;
11150     tcp_rr_request->cpu_rate	        =	remote_cpu_rate;
11151     tcp_rr_request->so_rcvavoid	        =	rem_rcvavoid;
11152     tcp_rr_request->so_sndavoid	        =	rem_sndavoid;
11153     if (test_time) {
11154       tcp_rr_request->test_length	=	test_time;
11155     }
11156     else {
11157       tcp_rr_request->test_length	=	test_trans * -1;
11158     }
11159 
11160     if (debug > 1) {
11161       fprintf(where,"netperf: send_tcp_nbrr: requesting TCP rr test\n");
11162     }
11163 
11164     send_request();
11165 
11166     /* The response from the remote will contain all of the relevant 	*/
11167     /* socket parameters for this test type. We will put them back into */
11168     /* the variables here so they can be displayed if desired.  The	*/
11169     /* remote will have calibrated CPU if necessary, and will have done	*/
11170     /* all the needed set-up we will have calibrated the cpu locally	*/
11171     /* before sending the request, and will grab the counter value right*/
11172     /* after the connect returns. The remote will grab the counter right*/
11173     /* after the accept call. This saves the hassle of extra messages	*/
11174     /* being sent for the TCP tests.					*/
11175 
11176     recv_response();
11177 
11178     if (!netperf_response.content.serv_errno) {
11179       if (debug)
11180 	fprintf(where,"remote listen done.\n");
11181       rsr_size          = tcp_rr_response->recv_buf_size;
11182       rss_size          = tcp_rr_response->send_buf_size;
11183       rem_nodelay       = tcp_rr_response->no_delay;
11184       remote_cpu_usage  = tcp_rr_response->measure_cpu;
11185       remote_cpu_rate   = tcp_rr_response->cpu_rate;
11186       /* make sure that port numbers are in network order */
11187       server.sin_port   = (unsigned short)tcp_rr_response->data_port_number;
11188       server.sin_port   = htons(server.sin_port);
11189     }
11190     else {
11191       Set_errno(netperf_response.content.serv_errno);
11192       fprintf(where,
11193 	      "netperf: remote error %d",
11194 	      netperf_response.content.serv_errno);
11195       perror("");
11196       fflush(where);
11197       exit(1);
11198     }
11199 
11200     /*Connect up to the remote port on the data socket  */
11201     if (connect(send_socket,
11202 		remote_res->ai_addr,
11203 		remote_res->ai_addrlen) == INVALID_SOCKET){
11204       perror("netperf: data socket connect failed");
11205 
11206       exit(1);
11207     }
11208 
11209     /* now that we are connected, mark the socket as non-blocking */
11210     if (!set_nonblock(send_socket)) {
11211       perror("netperf: set_nonblock");
11212       exit(1);
11213     }
11214 
11215 #ifdef WIN32
11216   /* this is used so the timer thread can close the socket out from */
11217   /* under us, which to date is the easiest/cleanest/least */
11218   /* Windows-specific way I can find to force the winsock calls to */
11219   /* return WSAEINTR with the test is over. anything that will run on */
11220   /* 95 and NT and is closer to what netperf expects from Unix signals */
11221   /* and such would be appreciated raj 1/96 */
11222   win_kludge_socket = send_socket;
11223 #endif /* WIN32 */
11224 
11225     /* Data Socket set-up is finished. If there were problems, either the */
11226     /* connect would have failed, or the previous response would have */
11227     /* indicated a problem. I failed to see the value of the extra */
11228     /* message after the accept on the remote. If it failed, we'll see it */
11229     /* here. If it didn't, we might as well start pumping data. */
11230 
11231     /* Set-up the test end conditions. For a request/response test, they */
11232     /* can be either time or transaction based. */
11233 
11234     if (test_time) {
11235       /* The user wanted to end the test after a period of time. */
11236       times_up = 0;
11237       trans_remaining = 0;
11238       start_timer(test_time);
11239     }
11240     else {
11241       /* The tester wanted to send a number of bytes. */
11242       trans_remaining = test_bytes;
11243       times_up = 1;
11244     }
11245 
11246     /* The cpu_start routine will grab the current time and possibly */
11247     /* value of the idle counter for later use in measuring cpu */
11248     /* utilization and/or service demand and thruput. */
11249 
11250     cpu_start(local_cpu_usage);
11251 
11252 #ifdef WANT_INTERVALS
11253     INTERVALS_INIT();
11254 #endif /* WANT_INTERVALS */
11255 
11256     /* We use an "OR" to control test execution. When the test is */
11257     /* controlled by time, the byte count check will always return false. */
11258     /* When the test is controlled by byte count, the time test will */
11259     /* always return false. When the test is finished, the whole */
11260     /* expression will go false and we will stop sending data. I think I */
11261     /* just arbitrarily decrement trans_remaining for the timed test, but */
11262     /* will not do that just yet... One other question is whether or not */
11263     /* the send buffer and the receive buffer should be the same buffer. */
11264 
11265     while ((!times_up) || (trans_remaining > 0)) {
11266       /* send the request. we assume that if we use a blocking socket, */
11267       /* the request will be sent at one shot. */
11268 
11269 #ifdef WANT_HISTOGRAM
11270       if (verbosity > 1) {
11271 	/* timestamp just before our call to send, and then again just */
11272 	/* after the receive raj 8/94 */
11273 	HIST_timestamp(&time_one);
11274       }
11275 #endif /* WANT_HISTOGRAM */
11276 
11277       /* even though this is a non-blocking socket, we will assume for */
11278       /* the time being that we will be able to send an entire request */
11279       /* without getting an EAGAIN */
11280       if((len=send(send_socket,
11281 		   send_ring->buffer_ptr,
11282 		   req_size,
11283 		   0)) != req_size) {
11284 	if (SOCKET_EINTR(len)) {
11285 	  /* we hit the end of a */
11286 	  /* timed test. */
11287 	  timed_out = 1;
11288 	  break;
11289 	}
11290 	perror("send_tcp_nbrr: data send error");
11291 	exit(1);
11292       }
11293       send_ring = send_ring->next;
11294 
11295       /* receive the response. since we are using non-blocking I/O, we */
11296       /* will "spin" on the recvs */
11297       rsp_bytes_left = rsp_size;
11298       temp_message_ptr  = recv_ring->buffer_ptr;
11299       while(rsp_bytes_left > 0) {
11300 	if((rsp_bytes_recvd=recv(send_socket,
11301 				 temp_message_ptr,
11302 				 rsp_bytes_left,
11303 				 0)) == SOCKET_ERROR) {
11304 	  if (SOCKET_EINTR(rsp_bytes_recvd))
11305 	  {
11306 	    /* We hit the end of a timed test. */
11307 	    timed_out = 1;
11308 	    break;
11309 	  }
11310 #ifndef WIN32  // But what does WinNT indicate in this situation...
11311 	  else if (errno == EAGAIN) {
11312 	    Set_errno(0);
11313 	    continue;
11314 	  }
11315 #endif
11316 	  else {
11317 	    perror("send_tcp_nbrr: data recv error");
11318 	    exit(1);
11319 	  }
11320 	}
11321 	rsp_bytes_left -= rsp_bytes_recvd;
11322 	temp_message_ptr  += rsp_bytes_recvd;
11323       }
11324       recv_ring = recv_ring->next;
11325 
11326       if (timed_out) {
11327 	/* we may have been in a nested while loop - we need */
11328 	/* another call to break. */
11329 	break;
11330       }
11331 
11332 #ifdef WANT_HISTOGRAM
11333       if (verbosity > 1) {
11334 	HIST_timestamp(&time_two);
11335 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
11336       }
11337 #endif /* WANT_HISTOGRAM */
11338 #ifdef WANT_INTERVALS
11339       INTERVALS_WAIT();
11340 #endif /* WANT_INTERVALS */
11341 
11342       nummessages++;
11343       if (trans_remaining) {
11344 	trans_remaining--;
11345       }
11346 
11347       if (debug > 3) {
11348 	if ((nummessages % 100) == 0) {
11349 	  fprintf(where,
11350 		  "Transaction %d completed\n",
11351 		  nummessages);
11352 	  fflush(where);
11353 	}
11354       }
11355     }
11356 
11357     /* At this point we used to call shutdown on the data socket to be */
11358     /* sure all the data was delivered, but this was not germane in a */
11359     /* request/response test, and it was causing the tests to "hang" when */
11360     /* they were being controlled by time. So, I have replaced this */
11361     /* shutdown call with a call to close that can be found later in the */
11362     /* procedure. */
11363 
11364     /* this call will always give us the elapsed time for the test, and */
11365     /* will also store-away the necessaries for cpu utilization */
11366 
11367     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
11368 						/* measured? how long */
11369 						/* did we really run? */
11370 
11371     /* Get the statistics from the remote end. The remote will have */
11372     /* calculated service demand and all those interesting things. If it */
11373     /* wasn't supposed to care, it will return obvious values. */
11374 
11375 #if defined(WANT_INTERVALS)
11376 #ifdef WIN32
11377     stop_itimer();
11378 #endif
11379 #endif /* WANT_INTERVALS */
11380 
11381     recv_response();
11382     if (!netperf_response.content.serv_errno) {
11383       if (debug)
11384 	fprintf(where,"remote results obtained\n");
11385     }
11386     else {
11387       Set_errno(netperf_response.content.serv_errno);
11388       fprintf(where,
11389 	      "netperf: remote error %d",
11390 	      netperf_response.content.serv_errno);
11391       perror("");
11392       fflush(where);
11393 
11394       exit(1);
11395     }
11396 
11397     /* We now calculate what our thruput was for the test. */
11398 
11399     bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
11400     thruput	= nummessages/elapsed_time;
11401 
11402     if (local_cpu_usage || remote_cpu_usage) {
11403       /* We must now do a little math for service demand and cpu */
11404       /* utilization for the system(s) */
11405       /* Of course, some of the information might be bogus because */
11406       /* there was no idle counter in the kernel(s). We need to make */
11407       /* a note of this for the user's benefit...*/
11408       if (local_cpu_usage) {
11409 	local_cpu_utilization = calc_cpu_util(0.0);
11410 	/* since calc_service demand is doing ms/Kunit we will */
11411 	/* multiply the number of transaction by 1024 to get */
11412 	/* "good" numbers */
11413 	local_service_demand  = calc_service_demand((double) nummessages*1024,
11414 						    0.0,
11415 						    0.0,
11416 						    0);
11417       }
11418       else {
11419 	local_cpu_utilization	= (float) -1.0;
11420 	local_service_demand	= (float) -1.0;
11421       }
11422 
11423       if (remote_cpu_usage) {
11424 	remote_cpu_utilization = tcp_rr_result->cpu_util;
11425 	/* since calc_service demand is doing ms/Kunit we will */
11426 	/* multiply the number of transaction by 1024 to get */
11427 	/* "good" numbers */
11428 	remote_service_demand = calc_service_demand((double) nummessages*1024,
11429 						    0.0,
11430 						    remote_cpu_utilization,
11431 						    tcp_rr_result->num_cpus);
11432       }
11433       else {
11434 	remote_cpu_utilization = (float) -1.0;
11435 	remote_service_demand  = (float) -1.0;
11436       }
11437 
11438     }
11439     else {
11440       /* we were not measuring cpu, for the confidence stuff, we */
11441       /* should make it -1.0 */
11442       local_cpu_utilization	= (float) -1.0;
11443       local_service_demand	= (float) -1.0;
11444       remote_cpu_utilization = (float) -1.0;
11445       remote_service_demand  = (float) -1.0;
11446     }
11447 
11448     /* at this point, we want to calculate the confidence information. */
11449     /* if debugging is on, calculate_confidence will print-out the */
11450     /* parameters we pass it */
11451 
11452     calculate_confidence(confidence_iteration,
11453 			 elapsed_time,
11454 			 thruput,
11455 			 local_cpu_utilization,
11456 			 remote_cpu_utilization,
11457 			 local_service_demand,
11458 			 remote_service_demand);
11459 
11460 
11461     confidence_iteration++;
11462 
11463     /* we are now done with the socket, so close it */
11464     close(send_socket);
11465 
11466   }
11467 
11468   retrieve_confident_values(&elapsed_time,
11469 			    &thruput,
11470 			    &local_cpu_utilization,
11471 			    &remote_cpu_utilization,
11472 			    &local_service_demand,
11473 			    &remote_service_demand);
11474 
11475   /* We are now ready to print all the information. If the user */
11476   /* has specified zero-level verbosity, we will just print the */
11477   /* local service demand, or the remote service demand. If the */
11478   /* user has requested verbosity level 1, he will get the basic */
11479   /* "streamperf" numbers. If the user has specified a verbosity */
11480   /* of greater than 1, we will display a veritable plethora of */
11481   /* background information from outside of this block as it it */
11482   /* not cpu_measurement specific...  */
11483 
11484   if (confidence < 0) {
11485     /* we did not hit confidence, but were we asked to look for it? */
11486     if (iteration_max > 1) {
11487       display_confidence();
11488     }
11489   }
11490 
11491   if (local_cpu_usage || remote_cpu_usage) {
11492     local_cpu_method = format_cpu_method(cpu_method);
11493     remote_cpu_method = format_cpu_method(tcp_rr_result->cpu_method);
11494 
11495     switch (verbosity) {
11496     case 0:
11497       if (local_cpu_usage) {
11498 	fprintf(where,
11499 		cpu_fmt_0,
11500 		local_service_demand,
11501 		local_cpu_method);
11502       }
11503       else {
11504 	fprintf(where,
11505 		cpu_fmt_0,
11506 		remote_service_demand,
11507 		remote_cpu_method);
11508       }
11509       break;
11510     case 1:
11511     case 2:
11512       if (print_headers) {
11513 	fprintf(where,
11514 		cpu_title,
11515 		local_cpu_method,
11516 		remote_cpu_method);
11517       }
11518 
11519       fprintf(where,
11520 	      cpu_fmt_1_line_1,		/* the format string */
11521 	      lss_size,		/* local sendbuf size */
11522 	      lsr_size,
11523 	      req_size,		/* how large were the requests */
11524 	      rsp_size,		/* guess */
11525 	      elapsed_time,		/* how long was the test */
11526 	      thruput,
11527 	      local_cpu_utilization,	/* local cpu */
11528 	      remote_cpu_utilization,	/* remote cpu */
11529 	      local_service_demand,	/* local service demand */
11530 	      remote_service_demand);	/* remote service demand */
11531       fprintf(where,
11532 	      cpu_fmt_1_line_2,
11533 	      rss_size,
11534 	      rsr_size);
11535       break;
11536     }
11537   }
11538   else {
11539     /* The tester did not wish to measure service demand. */
11540 
11541     switch (verbosity) {
11542     case 0:
11543       fprintf(where,
11544 	      tput_fmt_0,
11545 	      thruput);
11546       break;
11547     case 1:
11548     case 2:
11549       if (print_headers) {
11550 	fprintf(where,tput_title,format_units());
11551       }
11552 
11553       fprintf(where,
11554 	      tput_fmt_1_line_1,	/* the format string */
11555 	      lss_size,
11556 	      lsr_size,
11557 	      req_size,		/* how large were the requests */
11558 	      rsp_size,		/* how large were the responses */
11559 	      elapsed_time, 		/* how long did it take */
11560 	      thruput);
11561       fprintf(where,
11562 	      tput_fmt_1_line_2,
11563 	      rss_size, 		/* remote recvbuf size */
11564 	      rsr_size);
11565 
11566       break;
11567     }
11568   }
11569 
11570   /* it would be a good thing to include information about some of the */
11571   /* other parameters that may have been set for this test, but at the */
11572   /* moment, I do not wish to figure-out all the  formatting, so I will */
11573   /* just put this comment here to help remind me that it is something */
11574   /* that should be done at a later time. */
11575 
11576   /* how to handle the verbose information in the presence of */
11577   /* confidence intervals is yet to be determined... raj 11/94 */
11578   if (verbosity > 1) {
11579     /* The user wanted to know it all, so we will give it to him. */
11580     /* This information will include as much as we can find about */
11581     /* TCP statistics, the alignments of the sends and receives */
11582     /* and all that sort of rot... */
11583 
11584     fprintf(where,
11585 	    ksink_fmt,
11586 	    local_send_align,
11587 	    remote_recv_offset,
11588 	    local_send_offset,
11589 	    remote_recv_offset);
11590 
11591 #ifdef WANT_HISTOGRAM
11592     fprintf(where,"\nHistogram of request/response times\n");
11593     fflush(where);
11594     HIST_report(time_hist);
11595 #endif /* WANT_HISTOGRAM */
11596 
11597   }
11598 
11599 }
11600 
11601  /* this routine implements the receive (netserver) side of a TCP_RR */
11602  /* test */
11603 void
recv_tcp_nbrr()11604 recv_tcp_nbrr()
11605 {
11606 
11607   struct ring_elt *send_ring;
11608   struct ring_elt *recv_ring;
11609 
11610   struct	sockaddr_in        myaddr_in,
11611   peeraddr_in;
11612   SOCKET	s_listen,s_data;
11613   netperf_socklen_t 	addrlen;
11614   char	*temp_message_ptr;
11615   int	trans_received;
11616   int	trans_remaining;
11617   int	bytes_sent;
11618   int	request_bytes_recvd;
11619   int	request_bytes_remaining;
11620   int	timed_out = 0;
11621   float	elapsed_time;
11622 
11623   struct addrinfo *local_res;
11624   char local_name[BUFSIZ];
11625   char port_buffer[PORTBUFSIZE];
11626 
11627   struct	tcp_rr_request_struct	*tcp_rr_request;
11628   struct	tcp_rr_response_struct	*tcp_rr_response;
11629   struct	tcp_rr_results_struct	*tcp_rr_results;
11630 
11631   tcp_rr_request =
11632     (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data;
11633   tcp_rr_response =
11634     (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data;
11635   tcp_rr_results =
11636     (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data;
11637 
11638   if (debug) {
11639     fprintf(where,"netserver: recv_tcp_nbrr: entered...\n");
11640     fflush(where);
11641   }
11642 
11643   /* We want to set-up the listen socket with all the desired */
11644   /* parameters and then let the initiator know that all is ready. If */
11645   /* socket size defaults are to be used, then the initiator will have */
11646   /* sent us 0's. If the socket sizes cannot be changed, then we will */
11647   /* send-back what they are. If that information cannot be determined, */
11648   /* then we send-back -1's for the sizes. If things go wrong for any */
11649   /* reason, we will drop back ten yards and punt. */
11650 
11651   /* If anything goes wrong, we want the remote to know about it. It */
11652   /* would be best if the error that the remote reports to the user is */
11653   /* the actual error we encountered, rather than some bogus unexpected */
11654   /* response type message. */
11655 
11656   if (debug) {
11657     fprintf(where,"recv_tcp_nbrr: setting the response type...\n");
11658     fflush(where);
11659   }
11660 
11661   netperf_response.content.response_type = TCP_RR_RESPONSE;
11662 
11663   if (debug) {
11664     fprintf(where,"recv_tcp_nbrr: the response type is set...\n");
11665     fflush(where);
11666   }
11667 
11668   /* allocate the recv and send rings with the requested alignments */
11669   /* and offsets. raj 7/94 */
11670   if (debug) {
11671     fprintf(where,"recv_tcp_nbrr: requested recv alignment of %d offset %d\n",
11672 	    tcp_rr_request->recv_alignment,
11673 	    tcp_rr_request->recv_offset);
11674     fprintf(where,"recv_tcp_nbrr: requested send alignment of %d offset %d\n",
11675 	    tcp_rr_request->send_alignment,
11676 	    tcp_rr_request->send_offset);
11677     fflush(where);
11678   }
11679 
11680   /* at some point, these need to come to us from the remote system */
11681   if (send_width == 0) send_width = 1;
11682   if (recv_width == 0) recv_width = 1;
11683 
11684   send_ring = allocate_buffer_ring(send_width,
11685 				   tcp_rr_request->response_size,
11686 				   tcp_rr_request->send_alignment,
11687 				   tcp_rr_request->send_offset);
11688 
11689   recv_ring = allocate_buffer_ring(recv_width,
11690 				   tcp_rr_request->request_size,
11691 				   tcp_rr_request->recv_alignment,
11692 				   tcp_rr_request->recv_offset);
11693 
11694 
11695   /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */
11696   /* can put in OUR values !-) At some point, we may want to nail this */
11697   /* socket to a particular network-level address, but for now, */
11698   /* INADDR_ANY should be just fine. */
11699 
11700   bzero((char *)&myaddr_in,
11701 	sizeof(myaddr_in));
11702   myaddr_in.sin_family      = AF_INET;
11703   myaddr_in.sin_addr.s_addr = INADDR_ANY;
11704   myaddr_in.sin_port        = htons((unsigned short)tcp_rr_request->port);
11705 
11706   /* Grab a socket to listen on, and then listen on it. */
11707 
11708   if (debug) {
11709     fprintf(where,"recv_tcp_nbrr: grabbing a socket...\n");
11710     fflush(where);
11711   }
11712 
11713   /* create_data_socket expects to find some things in the global */
11714   /* variables, so set the globals based on the values in the request. */
11715   /* once the socket has been created, we will set the response values */
11716   /* based on the updated value of those globals. raj 7/94 */
11717   lss_size_req = tcp_rr_request->send_buf_size;
11718   lsr_size_req = tcp_rr_request->recv_buf_size;
11719   loc_nodelay = tcp_rr_request->no_delay;
11720   loc_rcvavoid = tcp_rr_request->so_rcvavoid;
11721   loc_sndavoid = tcp_rr_request->so_sndavoid;
11722 
11723   set_hostname_and_port(local_name,
11724 			port_buffer,
11725 			nf_to_af(tcp_rr_request->ipfamily),
11726 			tcp_rr_request->port);
11727 
11728   local_res = complete_addrinfo(local_name,
11729 				local_name,
11730 				port_buffer,
11731 				nf_to_af(tcp_rr_request->ipfamily),
11732 				SOCK_STREAM,
11733 				IPPROTO_TCP,
11734 				0);
11735 
11736   s_listen = create_data_socket(local_res);
11737 
11738   if (s_listen == INVALID_SOCKET) {
11739     netperf_response.content.serv_errno = errno;
11740     send_response();
11741 
11742     exit(1);
11743   }
11744 
11745   /* Let's get an address assigned to this socket so we can tell the */
11746   /* initiator how to reach the data socket. There may be a desire to */
11747   /* nail this socket to a specific IP address in a multi-homed, */
11748   /* multi-connection situation, but for now, we'll ignore the issue */
11749   /* and concentrate on single connection testing. */
11750 
11751   if (bind(s_listen,
11752 	   (struct sockaddr *)&myaddr_in,
11753 	   sizeof(myaddr_in)) == SOCKET_ERROR) {
11754     netperf_response.content.serv_errno = errno;
11755     close(s_listen);
11756     send_response();
11757 
11758     exit(1);
11759   }
11760 
11761   /* Now, let's set-up the socket to listen for connections */
11762   if (listen(s_listen, 5) == SOCKET_ERROR) {
11763     netperf_response.content.serv_errno = errno;
11764     close(s_listen);
11765     send_response();
11766 
11767     exit(1);
11768   }
11769 
11770 
11771   /* now get the port number assigned by the system  */
11772   addrlen = sizeof(myaddr_in);
11773   if (getsockname(s_listen,
11774 		  (struct sockaddr *)&myaddr_in, &addrlen) == SOCKET_ERROR){
11775     netperf_response.content.serv_errno = errno;
11776     close(s_listen);
11777     send_response();
11778 
11779     exit(1);
11780   }
11781 
11782   /* Now myaddr_in contains the port and the internet address this is */
11783   /* returned to the sender also implicitly telling the sender that the */
11784   /* socket buffer sizing has been done. */
11785 
11786   tcp_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port);
11787   netperf_response.content.serv_errno   = 0;
11788 
11789   /* But wait, there's more. If the initiator wanted cpu measurements, */
11790   /* then we must call the calibrate routine, which will return the max */
11791   /* rate back to the initiator. If the CPU was not to be measured, or */
11792   /* something went wrong with the calibration, we will return a 0.0 to */
11793   /* the initiator. */
11794 
11795   tcp_rr_response->cpu_rate = 0.0; 	/* assume no cpu */
11796   tcp_rr_response->measure_cpu = 0;
11797 
11798   if (tcp_rr_request->measure_cpu) {
11799     tcp_rr_response->measure_cpu = 1;
11800     tcp_rr_response->cpu_rate = calibrate_local_cpu(tcp_rr_request->cpu_rate);
11801   }
11802 
11803 
11804   /* before we send the response back to the initiator, pull some of */
11805   /* the socket parms from the globals */
11806   tcp_rr_response->send_buf_size = lss_size;
11807   tcp_rr_response->recv_buf_size = lsr_size;
11808   tcp_rr_response->no_delay = loc_nodelay;
11809   tcp_rr_response->so_rcvavoid = loc_rcvavoid;
11810   tcp_rr_response->so_sndavoid = loc_sndavoid;
11811   tcp_rr_response->test_length = tcp_rr_request->test_length;
11812   send_response();
11813 
11814   addrlen = sizeof(peeraddr_in);
11815 
11816   if ((s_data = accept(s_listen,
11817 		       (struct sockaddr *)&peeraddr_in,
11818 		       &addrlen)) == INVALID_SOCKET) {
11819     /* Let's just punt. The remote will be given some information */
11820     close(s_listen);
11821     exit(1);
11822   }
11823 
11824   if (debug) {
11825     fprintf(where,"recv_tcp_nbrr: accept completes on the data connection.\n");
11826     fflush(where);
11827   }
11828 
11829 #ifdef KLUDGE_SOCKET_OPTIONS
11830   /* this is for those systems which *INCORRECTLY* fail to pass */
11831   /* attributes across an accept() call. Including this goes against */
11832   /* my better judgement :( raj 11/95 */
11833 
11834   kludge_socket_options(s_data);
11835 
11836 #endif /* KLUDGE_SOCKET_OPTIONS */
11837 
11838   /* now that we are connected, mark the socket as non-blocking */
11839   if (!set_nonblock(s_data)) {
11840     close(s_data);
11841     exit(1);
11842   }
11843 
11844 
11845   /* Now it's time to start receiving data on the connection. We will */
11846   /* first grab the apropriate counters and then start grabbing. */
11847 
11848   cpu_start(tcp_rr_request->measure_cpu);
11849 
11850 #ifdef WIN32
11851   /* this is used so the timer thread can close the socket out from */
11852   /* under us, which to date is the easiest/cleanest/least */
11853   /* Windows-specific way I can find to force the winsock calls to */
11854   /* return WSAEINTR with the test is over. anything that will run on */
11855   /* 95 and NT and is closer to what netperf expects from Unix signals */
11856   /* and such would be appreciated raj 1/96 */
11857   win_kludge_socket = s_data;
11858 #endif /* WIN32 */
11859 
11860   /* The loop will exit when the sender does a shutdown, which will */
11861   /* return a length of zero   */
11862 
11863   if (tcp_rr_request->test_length > 0) {
11864     times_up = 0;
11865     trans_remaining = 0;
11866     start_timer(tcp_rr_request->test_length + PAD_TIME);
11867   }
11868   else {
11869     times_up = 1;
11870     trans_remaining = tcp_rr_request->test_length * -1;
11871   }
11872 
11873   trans_received = 0;
11874 
11875   while ((!times_up) || (trans_remaining > 0)) {
11876     temp_message_ptr = recv_ring->buffer_ptr;
11877     request_bytes_remaining	= tcp_rr_request->request_size;
11878     while(request_bytes_remaining > 0) {
11879       if((request_bytes_recvd=recv(s_data,
11880 				   temp_message_ptr,
11881 				   request_bytes_remaining,
11882 				   0)) == SOCKET_ERROR) {
11883 	    if ( SOCKET_EINTR(request_bytes_recvd))
11884 		{
11885 	      /* the timer popped */
11886 	      timed_out = 1;
11887 	      break;
11888 		}
11889 #ifndef WIN32  // But what does WinNT indicate in this situation...
11890 	    else if (errno == EAGAIN) {
11891 	      Set_errno(0);
11892 	      if (times_up) {
11893 	        timed_out = 1;
11894 	        break;
11895 		  }
11896 	      continue;
11897 		}
11898 #endif
11899 	    else {
11900 	      netperf_response.content.serv_errno = errno;
11901 	      send_response();
11902 	      exit(1);
11903 		}
11904       }
11905       else {
11906 	request_bytes_remaining -= request_bytes_recvd;
11907 	temp_message_ptr  += request_bytes_recvd;
11908       }
11909     }
11910 
11911     recv_ring = recv_ring->next;
11912 
11913     if (timed_out) {
11914       /* we hit the end of the test based on time - lets */
11915       /* bail out of here now... */
11916       fprintf(where,"yo5\n");
11917       fflush(where);
11918       break;
11919     }
11920 
11921     /* Now, send the response to the remote */
11922     if((bytes_sent=send(s_data,
11923 			send_ring->buffer_ptr,
11924 			tcp_rr_request->response_size,
11925 			0)) == SOCKET_ERROR) {
11926       if (SOCKET_EINTR(bytes_sent)) {
11927 	/* the test timer has popped */
11928 	timed_out = 1;
11929 	fprintf(where,"yo6\n");
11930 	fflush(where);
11931 	break;
11932       }
11933       netperf_response.content.serv_errno = 992;
11934       send_response();
11935       exit(1);
11936     }
11937 
11938     send_ring = send_ring->next;
11939 
11940     trans_received++;
11941     if (trans_remaining) {
11942       trans_remaining--;
11943     }
11944   }
11945 
11946 
11947   /* The loop now exits due to timeout or transaction count being */
11948   /* reached */
11949 
11950   cpu_stop(tcp_rr_request->measure_cpu,&elapsed_time);
11951 
11952   stop_timer();
11953 
11954   if (timed_out) {
11955     /* we ended the test by time, which was at least 2 seconds */
11956     /* longer than we wanted to run. so, we want to subtract */
11957     /* PAD_TIME from the elapsed_time. */
11958     elapsed_time -= PAD_TIME;
11959   }
11960 
11961   /* send the results to the sender			*/
11962 
11963   if (debug) {
11964     fprintf(where,
11965 	    "recv_tcp_nbrr: got %d transactions\n",
11966 	    trans_received);
11967     fflush(where);
11968   }
11969 
11970   tcp_rr_results->bytes_received = (trans_received *
11971 				    (tcp_rr_request->request_size +
11972 				     tcp_rr_request->response_size));
11973   tcp_rr_results->trans_received = trans_received;
11974   tcp_rr_results->elapsed_time   = elapsed_time;
11975   tcp_rr_results->cpu_method     = cpu_method;
11976   tcp_rr_results->num_cpus       = lib_num_loc_cpus;
11977   if (tcp_rr_request->measure_cpu) {
11978     tcp_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
11979   }
11980 
11981   if (debug) {
11982     fprintf(where,
11983 	    "recv_tcp_nbrr: test complete, sending results.\n");
11984     fflush(where);
11985   }
11986 
11987   /* we are done with the socket, free it */
11988   close(s_data);
11989 
11990   send_response();
11991 
11992 }
11993 
11994 #endif /* DO_NBRR */
11995 
11996 
11997  /* this test is intended to test the performance of establishing a */
11998  /* connection, and then closing it again. this test is of somewhat */
11999  /* arcane interest since no packets are exchanged between the */
12000  /* user-space processes, but it will show the raw overhead of */
12001  /* establishing a TCP connection. that service demand could then be */
12002  /* compared with the sum of the service demands of a TCP_CRR and */
12003  /* TCP_RR test - presumeably, they would all relate */
12004 
12005 void
send_tcp_cc(char remote_host[])12006 send_tcp_cc(char remote_host[])
12007 {
12008 
12009   char *tput_title = "\
12010 Local /Remote\n\
12011 Socket Size   Request  Resp.   Elapsed  Trans.\n\
12012 Send   Recv   Size     Size    Time     Rate         \n\
12013 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
12014 
12015   char *tput_fmt_0 =
12016     "%7.2f\n";
12017 
12018   char *tput_fmt_1_line_1 = "\
12019 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
12020   char *tput_fmt_1_line_2 = "\
12021 %-6d %-6d\n";
12022 
12023   char *cpu_title = "\
12024 Local /Remote\n\
12025 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
12026 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
12027 bytes  bytes  bytes   bytes  secs.   per sec  %%      %%      us/Tr   us/Tr\n\n";
12028 
12029   char *cpu_fmt_0 =
12030     "%6.3f\n";
12031 
12032   char *cpu_fmt_1_line_1 = "\
12033 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f\n";
12034 
12035   char *cpu_fmt_1_line_2 = "\
12036 %-6d %-6d\n";
12037 
12038   char *ksink_fmt = "\n\
12039 Alignment      Offset\n\
12040 Local  Remote  Local  Remote\n\
12041 Send   Recv    Send   Recv\n\
12042 %5d  %5d   %5d  %5d\n";
12043 
12044 
12045   int			timed_out = 0;
12046   float			elapsed_time;
12047 
12048   char	temp_message_ptr[1];
12049   int	nummessages;
12050   SOCKET	send_socket;
12051   int	trans_remaining;
12052   double	bytes_xferd;
12053   int	rsp_bytes_left = 1;
12054   int	rsp_bytes_recvd;
12055 
12056   float	local_cpu_utilization;
12057   float	local_service_demand;
12058   float	remote_cpu_utilization;
12059   float	remote_service_demand;
12060   double	thruput;
12061 
12062   struct addrinfo *local_res;
12063   struct addrinfo *remote_res;
12064 
12065   int                           myport;
12066   int                           ret;
12067 
12068   struct	tcp_cc_request_struct	*tcp_cc_request;
12069   struct	tcp_cc_response_struct	*tcp_cc_response;
12070   struct	tcp_cc_results_struct	*tcp_cc_result;
12071 
12072   tcp_cc_request =
12073     (struct tcp_cc_request_struct *)netperf_request.content.test_specific_data;
12074   tcp_cc_response =
12075     (struct tcp_cc_response_struct *)netperf_response.content.test_specific_data;
12076   tcp_cc_result =
12077     (struct tcp_cc_results_struct *)netperf_response.content.test_specific_data;
12078 
12079 
12080 #ifdef WANT_HISTOGRAM
12081   if (verbosity > 1) {
12082     time_hist = HIST_new();
12083   }
12084 #endif /* WANT_HISTOGRAM */
12085 
12086   /* since we are now disconnected from the code that established the */
12087   /* control socket, and since we want to be able to use different */
12088   /* protocols and such, we are passed the name of the remote host and */
12089   /* must turn that into the test specific addressing information. */
12090 
12091   complete_addrinfos(&remote_res,
12092 		     &local_res,
12093 		     remote_host,
12094 		     SOCK_STREAM,
12095 		     IPPROTO_TCP,
12096 		     0);
12097 
12098   if ( print_headers ) {
12099     print_top_test_header("TCP Connect/Close TEST",local_res,remote_res);
12100   }
12101 
12102   /* initialize a few counters */
12103 
12104   nummessages	=	0;
12105   bytes_xferd	=	0.0;
12106   times_up 	= 	0;
12107 
12108   /* since there are no data buffers in this test, we need no send or */
12109   /* recv rings */
12110 
12111   if (debug) {
12112     fprintf(where,"send_tcp_cc: send_socket obtained...\n");
12113   }
12114 
12115   /* If the user has requested cpu utilization measurements, we must */
12116   /* calibrate the cpu(s). We will perform this task within the tests */
12117   /* themselves. If the user has specified the cpu rate, then */
12118   /* calibrate_local_cpu will return rather quickly as it will have */
12119   /* nothing to do. If local_cpu_rate is zero, then we will go through */
12120   /* all the "normal" calibration stuff and return the rate back.*/
12121 
12122   if (local_cpu_usage) {
12123     local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
12124   }
12125 
12126   /* Tell the remote end to do a listen. The server alters the socket */
12127   /* paramters on the other side at this point, hence the reason for */
12128   /* all the values being passed in the setup message. If the user did */
12129   /* not specify any of the parameters, they will be passed as 0, which */
12130   /* will indicate to the remote that no changes beyond the system's */
12131   /* default should be used. Alignment is the exception, it will */
12132   /* default to 8, which will be no alignment alterations. */
12133 
12134   netperf_request.content.request_type	=	DO_TCP_CC;
12135   tcp_cc_request->recv_buf_size	        =	rsr_size_req;
12136   tcp_cc_request->send_buf_size	        =	rss_size_req;
12137   tcp_cc_request->recv_alignment	=	remote_recv_align;
12138   tcp_cc_request->recv_offset	        =	remote_recv_offset;
12139   tcp_cc_request->send_alignment	=	remote_send_align;
12140   tcp_cc_request->send_offset	        =	remote_send_offset;
12141   tcp_cc_request->request_size	        =	req_size;
12142   tcp_cc_request->response_size	        =	rsp_size;
12143   tcp_cc_request->no_delay	        =	rem_nodelay;
12144   tcp_cc_request->measure_cpu	        =	remote_cpu_usage;
12145   tcp_cc_request->cpu_rate	        =	remote_cpu_rate;
12146   tcp_cc_request->so_rcvavoid	=	rem_rcvavoid;
12147   tcp_cc_request->so_sndavoid	=	rem_sndavoid;
12148   if (test_time) {
12149     tcp_cc_request->test_length	=	test_time;
12150   }
12151   else {
12152     tcp_cc_request->test_length	=	test_trans * -1;
12153   }
12154   tcp_cc_request->port          = atoi(remote_data_port);
12155   tcp_cc_request->ipfamily  = af_to_nf(remote_res->ai_family);
12156 
12157   if (debug > 1) {
12158     fprintf(where,"netperf: send_tcp_cc: requesting TCP crr test\n");
12159   }
12160 
12161   send_request();
12162 
12163   /* The response from the remote will contain all of the relevant 	*/
12164   /* socket parameters for this test type. We will put them back into 	*/
12165   /* the variables here so they can be displayed if desired.  The	*/
12166   /* remote will have calibrated CPU if necessary, and will have done	*/
12167   /* all the needed set-up we will have calibrated the cpu locally	*/
12168   /* before sending the request, and will grab the counter value right	*/
12169   /* after the connect returns. The remote will grab the counter right	*/
12170   /* after the accept call. This saves the hassle of extra messages	*/
12171   /* being sent for the TCP tests.					*/
12172 
12173   recv_response();
12174 
12175   if (!netperf_response.content.serv_errno) {
12176     rsr_size	=	tcp_cc_response->recv_buf_size;
12177     rss_size	=	tcp_cc_response->send_buf_size;
12178     rem_nodelay	=	tcp_cc_response->no_delay;
12179     remote_cpu_usage=	tcp_cc_response->measure_cpu;
12180     remote_cpu_rate = 	tcp_cc_response->cpu_rate;
12181     /* make sure that port numbers are in network order */
12182     set_port_number(remote_res,(unsigned short)tcp_cc_response->data_port_number);
12183 
12184     if (debug) {
12185       fprintf(where,"remote listen done.\n");
12186       fprintf(where,"remote port is %d\n",get_port_number(remote_res));
12187       fflush(where);
12188     }
12189   }
12190   else {
12191     Set_errno(netperf_response.content.serv_errno);
12192     fprintf(where,
12193 	    "netperf: remote error %d",
12194 	    netperf_response.content.serv_errno);
12195     perror("");
12196     fflush(where);
12197     exit(1);
12198   }
12199 
12200 #ifdef WANT_DEMO
12201   demo_rr_setup(100);
12202 #endif
12203 
12204   /* pick a nice random spot between client_port_min and */
12205   /* client_port_max for our initial port number */
12206   srand(getpid());
12207   if (client_port_max - client_port_min) {
12208     myport = client_port_min +
12209       (rand() % (client_port_max - client_port_min));
12210   }
12211   else {
12212     myport = client_port_min;
12213   }
12214   /* there will be a ++ before the first call to bind, so subtract one */
12215   myport--;
12216 
12217   /* Set-up the test end conditions. For a request/response test, they */
12218   /* can be either time or transaction based. */
12219 
12220   if (test_time) {
12221     /* The user wanted to end the test after a period of time. */
12222     times_up = 0;
12223     trans_remaining = 0;
12224     start_timer(test_time);
12225   }
12226   else {
12227     /* The tester wanted to send a number of bytes. */
12228     trans_remaining = test_bytes;
12229     times_up = 1;
12230   }
12231 
12232   /* The cpu_start routine will grab the current time and possibly */
12233   /* value of the idle counter for later use in measuring cpu */
12234   /* utilization and/or service demand and thruput. */
12235 
12236   cpu_start(local_cpu_usage);
12237 
12238 #ifdef WANT_DEMO
12239   if (demo_mode) {
12240     demo_first_timestamp();
12241   }
12242 #endif
12243 
12244   /* We use an "OR" to control test execution. When the test is */
12245   /* controlled by time, the byte count check will always return false. */
12246   /* When the test is controlled by byte count, the time test will */
12247   /* always return false. When the test is finished, the whole */
12248   /* expression will go false and we will stop sending data. I think I */
12249   /* just arbitrarily decrement trans_remaining for the timed test, but */
12250   /* will not do that just yet... One other question is whether or not */
12251   /* the send buffer and the receive buffer should be the same buffer. */
12252 
12253   while ((!times_up) || (trans_remaining > 0)) {
12254 
12255 #ifdef WANT_HISTOGRAM
12256     if (verbosity > 1) {
12257       /* timestamp just before our call to create the socket, and then */
12258       /* again just after the receive raj 3/95 */
12259       HIST_timestamp(&time_one);
12260     }
12261 #endif /* WANT_HISTOGRAM */
12262 
12263     /* set up the data socket */
12264     /* newport: is this label really required any longer? */
12265     /* pick a new port number */
12266     myport++;
12267 
12268     /* wrap the port number when we get to client_port_max. NOTE, some */
12269     /* broken TCP's might treat the port number as a signed 16 bit */
12270     /* quantity.  we aren't interested in testing such broken */
12271     /* implementations :) so we won't make sure that it is below 32767 */
12272     /* raj 8/94  */
12273     if (myport >= client_port_max) {
12274       myport = client_port_min;
12275     }
12276 
12277     /* we do not want to use the port number that the server is */
12278     /* sitting at - this would cause us to fail in a loopback test. we */
12279     /* could just rely on the failure of the bind to get us past this, */
12280     /* but I'm guessing that in this one case at least, it is much */
12281     /* faster, given that we *know* that port number is already in use */
12282     /* (or rather would be in a loopback test) */
12283 
12284     if (myport == get_port_number(remote_res)) myport++;
12285 
12286     if (debug) {
12287       if ((nummessages % 100) == 0) {
12288 	printf("port %d\n",myport);
12289       }
12290     }
12291     set_port_number(local_res, (unsigned short)myport);
12292     send_socket = create_data_socket(local_res);
12293 
12294     if (send_socket == INVALID_SOCKET) {
12295       perror("netperf: send_tcp_cc: tcp stream data socket");
12296       exit(1);
12297     }
12298 
12299 #ifdef WIN32
12300     /* this is used so the timer thread can close the socket out from */
12301     /* under us, which to date is the easiest/cleanest/least */
12302     /* Windows-specific way I can find to force the winsock calls to */
12303     /* return WSAEINTR with the test is over. anything that will run on */
12304     /* 95 and NT and is closer to what netperf expects from Unix signals */
12305     /* and such would be appreciated raj 1/96 */
12306     win_kludge_socket = send_socket;
12307 #endif /* WIN32 */
12308 
12309     /* we used to have a call to bind() here, but that is being
12310        taken care of by create_data_socket(). raj 2005-02-08 */
12311 
12312     /* Connect up to the remote port on the data socket  */
12313     if ((ret = connect(send_socket,
12314 		       remote_res->ai_addr,
12315 		       remote_res->ai_addrlen)) == INVALID_SOCKET){
12316       if (SOCKET_EINTR(ret))
12317 	  {
12318 	    /* we hit the end of a */
12319 	    /* timed test. */
12320 	    timed_out = 1;
12321 	    break;
12322       }
12323       perror("netperf: data socket connect failed");
12324       printf("\tattempted to connect on socket %d to port %d",
12325 	     send_socket,
12326 	     get_port_number(remote_res));
12327       printf(" from port %u \n",get_port_number(local_res));
12328       exit(1);
12329     }
12330 
12331     /* we hang in a recv() to get the remote's close indication */
12332 
12333     rsp_bytes_recvd=recv(send_socket,
12334 			 temp_message_ptr,
12335 			 rsp_bytes_left,
12336 			 0);
12337 
12338 
12339     if (rsp_bytes_recvd == 0) {
12340       /* connection close, call close. we assume that the requisite */
12341       /* number of bytes have been received */
12342 
12343 #ifdef WANT_HISTOGRAM
12344       if (verbosity > 1) {
12345 	HIST_timestamp(&time_two);
12346 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
12347       }
12348 #endif /* WANT_HISTOGRAM */
12349 
12350 #ifdef WANT_DEMO
12351       demo_rr_interval(1);
12352 #endif
12353 
12354       nummessages++;
12355       if (trans_remaining) {
12356 	trans_remaining--;
12357       }
12358 
12359       if (debug > 3) {
12360 	fprintf(where,
12361 		"Transaction %d completed on local port %u\n",
12362 		nummessages,
12363 		get_port_number(local_res));
12364 	fflush(where);
12365       }
12366 
12367       close(send_socket);
12368 
12369     }
12370     else {
12371       /* it was less than zero - an error occured */
12372       if (SOCKET_EINTR(rsp_bytes_recvd))
12373 	  {
12374 	    /* We hit the end of a timed test. */
12375 	    timed_out = 1;
12376 	    break;
12377 	  }
12378 	  perror("send_tcp_cc: data recv error");
12379 	  exit(1);
12380     }
12381 
12382   }
12383 
12384 
12385   /* this call will always give us the elapsed time for the test, and */
12386   /* will also store-away the necessaries for cpu utilization */
12387 
12388   cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being measured? */
12389   /* how long did we really run? */
12390 
12391   /* Get the statistics from the remote end. The remote will have */
12392   /* calculated service demand and all those interesting things. If it */
12393   /* wasn't supposed to care, it will return obvious values. */
12394 
12395   recv_response();
12396   if (!netperf_response.content.serv_errno) {
12397     if (debug)
12398       fprintf(where,"remote results obtained\n");
12399   }
12400   else {
12401     Set_errno(netperf_response.content.serv_errno);
12402     fprintf(where,
12403 	    "netperf: remote error %d",
12404 	     netperf_response.content.serv_errno);
12405     perror("");
12406     fflush(where);
12407 
12408     exit(1);
12409   }
12410 
12411   /* We now calculate what our thruput was for the test. In the future, */
12412   /* we may want to include a calculation of the thruput measured by */
12413   /* the remote, but it should be the case that for a TCP stream test, */
12414   /* that the two numbers should be *very* close... We calculate */
12415   /* bytes_sent regardless of the way the test length was controlled. */
12416   /* If it was time, we needed to, and if it was by bytes, the user may */
12417   /* have specified a number of bytes that wasn't a multiple of the */
12418   /* send_size, so we really didn't send what he asked for ;-) We use */
12419   /* Kbytes/s as the units of thruput for a TCP stream test, where K = */
12420   /* 1024. A future enhancement *might* be to choose from a couple of */
12421   /* unit selections. */
12422 
12423   bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
12424   thruput	= calc_thruput(bytes_xferd);
12425 
12426   if (local_cpu_usage || remote_cpu_usage) {
12427     /* We must now do a little math for service demand and cpu */
12428     /* utilization for the system(s) */
12429     /* Of course, some of the information might be bogus because */
12430     /* there was no idle counter in the kernel(s). We need to make */
12431     /* a note of this for the user's benefit...*/
12432     if (local_cpu_usage) {
12433       if (local_cpu_rate == 0.0) {
12434 	fprintf(where,"WARNING WARNING WARNING  WARNING WARNING WARNING  WARNING!\n");
12435 	fprintf(where,"Local CPU usage numbers based on process information only!\n");
12436 	fflush(where);
12437       }
12438       local_cpu_utilization = calc_cpu_util(0.0);
12439       /* since calc_service demand is doing ms/Kunit we will */
12440       /* multiply the number of transaction by 1024 to get */
12441       /* "good" numbers */
12442       local_service_demand  = calc_service_demand((double) nummessages*1024,
12443 						  0.0,
12444 						  0.0,
12445 						  0);
12446     }
12447     else {
12448       local_cpu_utilization	= (float) -1.0;
12449       local_service_demand	= (float) -1.0;
12450     }
12451 
12452     if (remote_cpu_usage) {
12453       if (remote_cpu_rate == 0.0) {
12454 	fprintf(where,"DANGER  DANGER  DANGER    DANGER  DANGER  DANGER    DANGER!\n");
12455 	fprintf(where,"Remote CPU usage numbers based on process information only!\n");
12456 	fflush(where);
12457       }
12458       remote_cpu_utilization = tcp_cc_result->cpu_util;
12459       /* since calc_service demand is doing ms/Kunit we will */
12460       /* multiply the number of transaction by 1024 to get */
12461       /* "good" numbers */
12462       remote_service_demand = calc_service_demand((double) nummessages*1024,
12463 						  0.0,
12464 						  remote_cpu_utilization,
12465 						  tcp_cc_result->num_cpus);
12466     }
12467     else {
12468       remote_cpu_utilization = (float) -1.0;
12469       remote_service_demand  = (float) -1.0;
12470     }
12471 
12472     /* We are now ready to print all the information. If the user */
12473     /* has specified zero-level verbosity, we will just print the */
12474     /* local service demand, or the remote service demand. If the */
12475     /* user has requested verbosity level 1, he will get the basic */
12476     /* "streamperf" numbers. If the user has specified a verbosity */
12477     /* of greater than 1, we will display a veritable plethora of */
12478     /* background information from outside of this block as it it */
12479     /* not cpu_measurement specific...  */
12480 
12481     switch (verbosity) {
12482     case 0:
12483       if (local_cpu_usage) {
12484 	fprintf(where,
12485 		cpu_fmt_0,
12486 		local_service_demand);
12487       }
12488       else {
12489 	fprintf(where,
12490 		cpu_fmt_0,
12491 		remote_service_demand);
12492       }
12493       break;
12494     case 1:
12495     case 2:
12496 
12497       if (print_headers) {
12498 	fprintf(where,
12499 		cpu_title,
12500 		local_cpu_method,
12501 		remote_cpu_method);
12502       }
12503 
12504       fprintf(where,
12505 	      cpu_fmt_1_line_1,		/* the format string */
12506 	      lss_size,		/* local sendbuf size */
12507 	      lsr_size,
12508 	      req_size,		/* how large were the requests */
12509 	      rsp_size,		/* guess */
12510 	      elapsed_time,		/* how long was the test */
12511 	      nummessages/elapsed_time,
12512 	      local_cpu_utilization,	/* local cpu */
12513 	      remote_cpu_utilization,	/* remote cpu */
12514 	      local_service_demand,	/* local service demand */
12515 	      remote_service_demand);	/* remote service demand */
12516       fprintf(where,
12517 	      cpu_fmt_1_line_2,
12518 	      rss_size,
12519 	      rsr_size);
12520       break;
12521     }
12522   }
12523   else {
12524     /* The tester did not wish to measure service demand. */
12525     switch (verbosity) {
12526     case 0:
12527       fprintf(where,
12528 	      tput_fmt_0,
12529 	      nummessages/elapsed_time);
12530       break;
12531     case 1:
12532     case 2:
12533       if (print_headers) {
12534 	fprintf(where,tput_title,format_units());
12535       }
12536 
12537       fprintf(where,
12538 	      tput_fmt_1_line_1,	/* the format string */
12539 	      lss_size,
12540 	      lsr_size,
12541 	      req_size,		/* how large were the requests */
12542 	      rsp_size,		/* how large were the responses */
12543 	      elapsed_time, 		/* how long did it take */
12544 	      nummessages/elapsed_time);
12545       fprintf(where,
12546 	      tput_fmt_1_line_2,
12547 	      rss_size, 		/* remote recvbuf size */
12548 	      rsr_size);
12549 
12550       break;
12551     }
12552   }
12553 
12554   /* it would be a good thing to include information about some of the */
12555   /* other parameters that may have been set for this test, but at the */
12556   /* moment, I do not wish to figure-out all the  formatting, so I will */
12557   /* just put this comment here to help remind me that it is something */
12558   /* that should be done at a later time. */
12559 
12560   if (verbosity > 1) {
12561     /* The user wanted to know it all, so we will give it to him. */
12562     /* This information will include as much as we can find about */
12563     /* TCP statistics, the alignments of the sends and receives */
12564     /* and all that sort of rot... */
12565 
12566     fprintf(where,
12567 	    ksink_fmt,
12568 	    local_send_align,
12569 	    remote_recv_offset,
12570 	    local_send_offset,
12571 	    remote_recv_offset);
12572 
12573 #ifdef WANT_HISTOGRAM
12574     fprintf(where,"\nHistogram of request/response times\n");
12575     fflush(where);
12576     HIST_report(time_hist);
12577 #endif /* WANT_HISTOGRAM */
12578 
12579   }
12580 
12581 }
12582 
12583 
12584 void
recv_tcp_cc()12585 recv_tcp_cc()
12586 {
12587 
12588   char  *message;
12589 
12590   struct addrinfo *local_res;
12591   char local_name[BUFSIZ];
12592   char port_buffer[PORTBUFSIZE];
12593 
12594   struct	sockaddr_storage        myaddr_in,  peeraddr_in;
12595   SOCKET	s_listen,s_data;
12596   netperf_socklen_t 	addrlen;
12597   char	*recv_message_ptr;
12598   char	*send_message_ptr;
12599   int	trans_received;
12600   int	trans_remaining;
12601   int	timed_out = 0;
12602   float	elapsed_time;
12603 
12604   struct	tcp_cc_request_struct	*tcp_cc_request;
12605   struct	tcp_cc_response_struct	*tcp_cc_response;
12606   struct	tcp_cc_results_struct	*tcp_cc_results;
12607 
12608   tcp_cc_request =
12609     (struct tcp_cc_request_struct *)netperf_request.content.test_specific_data;
12610   tcp_cc_response =
12611     (struct tcp_cc_response_struct *)netperf_response.content.test_specific_data;
12612   tcp_cc_results =
12613     (struct tcp_cc_results_struct *)netperf_response.content.test_specific_data;
12614 
12615   if (debug) {
12616     fprintf(where,"netserver: recv_tcp_cc: entered...\n");
12617     fflush(where);
12618   }
12619 
12620   /* We want to set-up the listen socket with all the desired */
12621   /* parameters and then let the initiator know that all is ready. If */
12622   /* socket size defaults are to be used, then the initiator will have */
12623   /* sent us 0's. If the socket sizes cannot be changed, then we will */
12624   /* send-back what they are. If that information cannot be determined, */
12625   /* then we send-back -1's for the sizes. If things go wrong for any */
12626   /* reason, we will drop back ten yards and punt. */
12627 
12628   /* If anything goes wrong, we want the remote to know about it. It */
12629   /* would be best if the error that the remote reports to the user is */
12630   /* the actual error we encountered, rather than some bogus unexpected */
12631   /* response type message. */
12632 
12633   if (debug) {
12634     fprintf(where,"recv_tcp_cc: setting the response type...\n");
12635     fflush(where);
12636   }
12637 
12638   netperf_response.content.response_type = TCP_CC_RESPONSE;
12639 
12640   if (debug) {
12641     fprintf(where,"recv_tcp_cc: the response type is set...\n");
12642     fflush(where);
12643   }
12644 
12645   /* set-up the data buffer with the requested alignment and offset */
12646   message = (char *)malloc(DATABUFFERLEN);
12647   if (message == NULL) {
12648     printf("malloc(%d) failed!\n", DATABUFFERLEN);
12649     exit(1);
12650   }
12651 
12652   /* We now alter the message_ptr variables to be at the desired */
12653   /* alignments with the desired offsets. */
12654 
12655   if (debug) {
12656     fprintf(where,
12657 	    "recv_tcp_cc: requested recv alignment of %d offset %d\n",
12658 	    tcp_cc_request->recv_alignment,
12659 	    tcp_cc_request->recv_offset);
12660     fprintf(where,
12661 	    "recv_tcp_cc: requested send alignment of %d offset %d\n",
12662 	    tcp_cc_request->send_alignment,
12663 	    tcp_cc_request->send_offset);
12664     fflush(where);
12665   }
12666 
12667   recv_message_ptr = ALIGN_BUFFER(message, tcp_cc_request->recv_alignment, tcp_cc_request->recv_offset);
12668 
12669   send_message_ptr = ALIGN_BUFFER(message, tcp_cc_request->send_alignment, tcp_cc_request->send_offset);
12670 
12671   if (debug) {
12672     fprintf(where,"recv_tcp_cc: receive alignment and offset set...\n");
12673     fflush(where);
12674   }
12675 
12676   /* Grab a socket to listen on, and then listen on it. */
12677 
12678   if (debug) {
12679     fprintf(where,"recv_tcp_cc: grabbing a socket...\n");
12680     fflush(where);
12681   }
12682 
12683   /* create_data_socket expects to find some things in the global */
12684   /* variables, so set the globals based on the values in the request. */
12685   /* once the socket has been created, we will set the response values */
12686   /* based on the updated value of those globals. raj 7/94 */
12687   lss_size_req = tcp_cc_request->send_buf_size;
12688   lsr_size_req = tcp_cc_request->recv_buf_size;
12689   loc_nodelay = tcp_cc_request->no_delay;
12690   loc_rcvavoid = tcp_cc_request->so_rcvavoid;
12691   loc_sndavoid = tcp_cc_request->so_sndavoid;
12692 
12693   set_hostname_and_port(local_name,
12694 			port_buffer,
12695 			nf_to_af(tcp_cc_request->ipfamily),
12696 			tcp_cc_request->port);
12697 
12698   local_res = complete_addrinfo(local_name,
12699 				local_name,
12700 				port_buffer,
12701 				nf_to_af(tcp_cc_request->ipfamily),
12702 				SOCK_STREAM,
12703 				IPPROTO_TCP,
12704 				0);
12705 
12706   s_listen = create_data_socket(local_res);
12707 
12708   if (s_listen == INVALID_SOCKET) {
12709     netperf_response.content.serv_errno = errno;
12710     send_response();
12711     if (debug) {
12712       fprintf(where,"could not create data socket\n");
12713       fflush(where);
12714     }
12715     exit(1);
12716   }
12717 
12718 #ifdef WIN32
12719   /* The test timer can fire during operations on the listening socket,
12720      so to make the start_timer below work we have to move
12721      it to close s_listen while we are blocked on accept. */
12722   win_kludge_socket2 = s_listen;
12723 #endif
12724 
12725 
12726   /* Now, let's set-up the socket to listen for connections */
12727   if (listen(s_listen, 5) == SOCKET_ERROR) {
12728     netperf_response.content.serv_errno = errno;
12729     close(s_listen);
12730     send_response();
12731     if (debug) {
12732       fprintf(where,"could not listen\n");
12733       fflush(where);
12734     }
12735     exit(1);
12736   }
12737 
12738   /* now get the port number assigned by the system  */
12739   addrlen = sizeof(myaddr_in);
12740   if (getsockname(s_listen,
12741 		  (struct sockaddr *)&myaddr_in,
12742 		  &addrlen) == SOCKET_ERROR){
12743     netperf_response.content.serv_errno = errno;
12744     close(s_listen);
12745     send_response();
12746     if (debug) {
12747       fprintf(where,"could not geetsockname\n");
12748       fflush(where);
12749     }
12750     exit(1);
12751   }
12752 
12753   /* Now myaddr_in contains the port and the internet address this is */
12754   /* returned to the sender also implicitly telling the sender that the */
12755   /* socket buffer sizing has been done. */
12756 
12757   tcp_cc_response->data_port_number =
12758     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
12759   if (debug) {
12760     fprintf(where,"telling the remote to call me at %d\n",
12761 	    tcp_cc_response->data_port_number);
12762     fflush(where);
12763   }
12764   netperf_response.content.serv_errno   = 0;
12765 
12766   /* But wait, there's more. If the initiator wanted cpu measurements, */
12767   /* then we must call the calibrate routine, which will return the max */
12768   /* rate back to the initiator. If the CPU was not to be measured, or */
12769   /* something went wrong with the calibration, we will return a 0.0 to */
12770   /* the initiator. */
12771 
12772   tcp_cc_response->cpu_rate = (float)0.0; 	/* assume no cpu */
12773   if (tcp_cc_request->measure_cpu) {
12774     tcp_cc_response->measure_cpu = 1;
12775     tcp_cc_response->cpu_rate =
12776       calibrate_local_cpu(tcp_cc_request->cpu_rate);
12777   }
12778 
12779 
12780 
12781   /* before we send the response back to the initiator, pull some of */
12782   /* the socket parms from the globals */
12783   tcp_cc_response->send_buf_size = lss_size;
12784   tcp_cc_response->recv_buf_size = lsr_size;
12785   tcp_cc_response->no_delay = loc_nodelay;
12786   tcp_cc_response->so_rcvavoid = loc_rcvavoid;
12787   tcp_cc_response->so_sndavoid = loc_sndavoid;
12788 
12789   send_response();
12790 
12791   addrlen = sizeof(peeraddr_in);
12792 
12793   /* Now it's time to start receiving data on the connection. We will */
12794   /* first grab the apropriate counters and then start grabbing. */
12795 
12796   cpu_start(tcp_cc_request->measure_cpu);
12797 
12798   /* The loop will exit when the sender does a shutdown, which will */
12799   /* return a length of zero   */
12800 
12801   if (tcp_cc_request->test_length > 0) {
12802     times_up = 0;
12803     trans_remaining = 0;
12804     start_timer(tcp_cc_request->test_length + PAD_TIME);
12805   }
12806   else {
12807     times_up = 1;
12808     trans_remaining = tcp_cc_request->test_length * -1;
12809   }
12810 
12811   trans_received = 0;
12812 
12813   while ((!times_up) || (trans_remaining > 0)) {
12814 #ifdef WIN32
12815     /* The test timer will probably fire during this accept,
12816        so to make the start_timer above work we have to move
12817        it to close s_listen while we are blocked on accept. */
12818     win_kludge_socket = s_listen;
12819 #endif
12820     /* accept a connection from the remote */
12821     if ((s_data=accept(s_listen,
12822 		       (struct sockaddr *)&peeraddr_in,
12823 		       &addrlen)) == INVALID_SOCKET) {
12824       if (errno == EINTR) {
12825 	/* the timer popped */
12826 	timed_out = 1;
12827 	break;
12828       }
12829       fprintf(where,"recv_tcp_cc: accept: errno = %d\n",errno);
12830       fflush(where);
12831       close(s_listen);
12832 
12833       exit(1);
12834     }
12835 
12836 #ifdef KLUDGE_SOCKET_OPTIONS
12837     /* this is for those systems which *INCORRECTLY* fail to pass */
12838     /* attributes across an accept() call. Including this goes against */
12839     /* my better judgement :( raj 11/95 */
12840 
12841     kludge_socket_options(s_data);
12842 
12843 #endif /* KLUDGE_SOCKET_OPTIONS */
12844 
12845 #ifdef WIN32
12846   /* this is used so the timer thread can close the socket out from */
12847   /* under us, which to date is the easiest/cleanest/least */
12848   /* Windows-specific way I can find to force the winsock calls to */
12849   /* return WSAEINTR with the test is over. anything that will run on */
12850   /* 95 and NT and is closer to what netperf expects from Unix signals */
12851   /* and such would be appreciated raj 1/96 */
12852   win_kludge_socket = s_data;
12853 #endif /* WIN32 */
12854 
12855     if (debug) {
12856       fprintf(where,"recv_tcp_cc: accepted data connection.\n");
12857       fflush(where);
12858     }
12859 
12860 
12861     /* close the connection. the server will likely do a graceful */
12862     /* close of the connection, insuring that all data has arrived at */
12863     /* the client. for this it will call shutdown(), and then recv() and */
12864     /* then close(). I'm reasonably confident that this is the */
12865     /* appropriate sequence of calls - I would like to hear of */
12866     /* examples in web servers to the contrary. raj 10/95*/
12867     close(s_data);
12868 
12869     trans_received++;
12870     if (trans_remaining) {
12871       trans_remaining--;
12872     }
12873 
12874     if (debug) {
12875       fprintf(where,
12876 	      "recv_tcp_cc: Transaction %d complete\n",
12877 	      trans_received);
12878       fflush(where);
12879     }
12880 
12881   }
12882 
12883 
12884   /* The loop now exits due to timeout or transaction count being */
12885   /* reached */
12886 
12887   cpu_stop(tcp_cc_request->measure_cpu,&elapsed_time);
12888 
12889   if (timed_out) {
12890     /* we ended the test by time, which was at least 2 seconds */
12891     /* longer than we wanted to run. so, we want to subtract */
12892     /* PAD_TIME from the elapsed_time. */
12893     elapsed_time -= PAD_TIME;
12894   }
12895   /* send the results to the sender			*/
12896 
12897   if (debug) {
12898     fprintf(where,
12899 	    "recv_tcp_cc: got %d transactions\n",
12900 	    trans_received);
12901     fflush(where);
12902   }
12903 
12904   tcp_cc_results->bytes_received = (trans_received *
12905 				    (tcp_cc_request->request_size +
12906 				     tcp_cc_request->response_size));
12907   tcp_cc_results->trans_received = trans_received;
12908   tcp_cc_results->elapsed_time	 = elapsed_time;
12909   tcp_cc_results->num_cpus       = lib_num_loc_cpus;
12910   if (tcp_cc_request->measure_cpu) {
12911     tcp_cc_results->cpu_util	= calc_cpu_util(elapsed_time);
12912   }
12913 
12914   if (debug) {
12915     fprintf(where,
12916 	    "recv_tcp_cc: test complete, sending results.\n");
12917     fflush(where);
12918   }
12919 
12920   send_response();
12921 
12922 }
12923 
12924 void
print_sockets_usage()12925 print_sockets_usage()
12926 {
12927 
12928   fwrite(sockets_usage, sizeof(char), strlen(sockets_usage), stdout);
12929   exit(1);
12930 
12931 }
12932 
12933 void
scan_sockets_args(int argc,char * argv[])12934 scan_sockets_args(int argc, char *argv[])
12935 
12936 {
12937 
12938 #define SOCKETS_ARGS "b:CDnNhH:L:m:M:p:P:r:R:s:S:T:Vw:W:z46"
12939 
12940   extern char	*optarg;	  /* pointer to option string	*/
12941 
12942   int		c;
12943 
12944   char
12945     arg1[BUFSIZ],  /* argument holders		*/
12946     arg2[BUFSIZ];
12947 
12948   if (debug) {
12949     int i;
12950     printf("%s called with the following argument vector\n",
12951 #if _MSC_VER <= 1200
12952 	   "scan_sockets_args");
12953 #else
12954 	   __func__);
12955 #endif
12956     for (i = 0; i< argc; i++) {
12957       printf("%s ",argv[i]);
12958     }
12959     printf("\n");
12960   }
12961 
12962   strncpy(local_data_port,"0",sizeof(local_data_port));
12963   strncpy(remote_data_port,"0",sizeof(remote_data_port));
12964 
12965   /* by default, only a UDP_STREAM test disallows routing, to cover
12966      the backsides of incompetent testers who have bogus setups */
12967   if (strcasecmp(test_name,"UDP_STREAM") == 0) {
12968     routing_allowed = 0;
12969   }
12970 
12971   /* Go through all the command line arguments and break them */
12972   /* out. For those options that take two parms, specifying only */
12973   /* the first will set both to that value. Specifying only the */
12974   /* second will leave the first untouched. To change only the */
12975   /* first, use the form "first," (see the routine break_args.. */
12976 
12977   while ((c= getopt(argc, argv, SOCKETS_ARGS)) != EOF) {
12978     switch (c) {
12979     case '?':
12980     case '4':
12981       remote_data_family = AF_INET;
12982       local_data_family = AF_INET;
12983       break;
12984     case '6':
12985 #if defined(AF_INET6)
12986       remote_data_family = AF_INET6;
12987       local_data_family = AF_INET6;
12988 #else
12989       fprintf(stderr,
12990 	      "This netperf was not compiled on an IPv6 capable host!\n");
12991       fflush(stderr);
12992       exit(-1);
12993 #endif
12994       break;
12995     case 'h':
12996       print_sockets_usage();
12997       exit(1);
12998     case 'b':
12999 #ifdef WANT_FIRST_BURST
13000       first_burst_size = atoi(optarg);
13001 #else /* WANT_FIRST_BURST */
13002       printf("Initial request burst functionality not compiled-in!\n");
13003 #endif /* WANT_FIRST_BURST */
13004       break;
13005     case 'C':
13006 #ifdef TCP_CORK
13007       /* set TCP_CORK */
13008       loc_tcpcork = 1;
13009       rem_tcpcork = 1; /* however, at first, we ony have cork affect loc */
13010 #else
13011       printf("WARNING: TCP_CORK not available on this platform!\n");
13012 #endif /* TCP_CORK */
13013       break;
13014     case 'D':
13015       /* set the TCP nodelay flag */
13016       loc_nodelay = 1;
13017       rem_nodelay = 1;
13018       break;
13019     case 'H':
13020       break_args_explicit(optarg,arg1,arg2);
13021       if (arg1[0]) {
13022 	/* make sure we leave room for the NULL termination boys and
13023 	   girls. raj 2005-02-82 */
13024 	remote_data_address = malloc(strlen(arg1)+1);
13025 	strncpy(remote_data_address,arg1,strlen(arg1));
13026       }
13027       if (arg2[0])
13028 	remote_data_family = parse_address_family(arg2);
13029       break;
13030     case 'L':
13031       break_args_explicit(optarg,arg1,arg2);
13032       if (arg1[0]) {
13033 	/* make sure we leave room for the NULL termination boys and
13034 	   girls. raj 2005-02-82 */
13035 	local_data_address = malloc(strlen(arg1)+1);
13036 	strncpy(local_data_address,arg1,strlen(arg1));
13037       }
13038       if (arg2[0])
13039 	local_data_family = parse_address_family(arg2);
13040       break;
13041     case 's':
13042       /* set local socket sizes */
13043       break_args(optarg,arg1,arg2);
13044       if (arg1[0])
13045 	lss_size_req = convert(arg1);
13046       if (arg2[0])
13047 	lsr_size_req = convert(arg2);
13048       break;
13049     case 'S':
13050       /* set remote socket sizes */
13051       break_args(optarg,arg1,arg2);
13052       if (arg1[0])
13053 	rss_size_req = convert(arg1);
13054       if (arg2[0])
13055 	rsr_size_req = convert(arg2);
13056       break;
13057     case 'r':
13058       /* set the request/response sizes */
13059       break_args(optarg,arg1,arg2);
13060       if (arg1[0])
13061 	req_size = convert(arg1);
13062       if (arg2[0])
13063 	rsp_size = convert(arg2);
13064       break;
13065     case 'R':
13066       /* enable/disable routing on the data connection*/
13067       routing_allowed = atoi(optarg);
13068       break;
13069     case 'm':
13070       /* set the send size */
13071       send_size = convert(optarg);
13072       break;
13073     case 'M':
13074       /* set the recv size */
13075       recv_size = convert(optarg);
13076       break;
13077     case 'n':
13078       /* set the local socket type*/
13079       local_connected = 1;
13080       break;
13081     case 'N':
13082       /* set the remote socket type*/
13083       remote_connected = 1;
13084       break;
13085     case 'p':
13086       /* set the min and max port numbers for the TCP_CRR and TCP_TRR */
13087       /* tests. */
13088       break_args(optarg,arg1,arg2);
13089       if (arg1[0])
13090 	client_port_min = atoi(arg1);
13091       if (arg2[0])
13092 	client_port_max = atoi(arg2);
13093       break;
13094     case 'P':
13095       /* set the local and remote data port numbers for the tests to
13096 	 allow them to run through those blankety blank end-to-end
13097 	 breaking firewalls. raj 2004-06-15 */
13098       break_args(optarg,arg1,arg2);
13099       if (arg1[0])
13100 	strncpy(local_data_port,arg1,sizeof(local_data_port));
13101       if (arg2[0])
13102 	strncpy(remote_data_port,arg2,sizeof(remote_data_port));
13103       break;
13104     case 't':
13105       /* set the test name */
13106       strcpy(test_name,optarg);
13107       break;
13108     case 'W':
13109       /* set the "width" of the user space data */
13110       /* buffer. This will be the number of */
13111       /* send_size buffers malloc'd in the */
13112       /* *_STREAM test. It may be enhanced to set */
13113       /* both send and receive "widths" but for now */
13114       /* it is just the sending *_STREAM. */
13115       send_width = convert(optarg);
13116       break;
13117     case 'V' :
13118       /* we want to do copy avoidance and will set */
13119       /* it for everything, everywhere, if we really */
13120       /* can. of course, we don't know anything */
13121       /* about the remote... */
13122 #ifdef SO_SND_COPYAVOID
13123       loc_sndavoid = 1;
13124 #else
13125       loc_sndavoid = 0;
13126       printf("Local send copy avoidance not available.\n");
13127 #endif
13128 #ifdef SO_RCV_COPYAVOID
13129       loc_rcvavoid = 1;
13130 #else
13131       loc_rcvavoid = 0;
13132       printf("Local recv copy avoidance not available.\n");
13133 #endif
13134       rem_sndavoid = 1;
13135       rem_rcvavoid = 1;
13136       break;
13137     };
13138   }
13139 
13140 #if defined(WANT_FIRST_BURST)
13141 #if defined(WANT_HISTOGRAM)
13142   /* if WANT_FIRST_BURST and WANT_HISTOGRAM are defined and the user
13143      indeed wants a non-zero first burst size, and we would emit a
13144      histogram, then we should emit a warning that the two are not
13145      compatible. raj 2006-01-31 */
13146   if ((first_burst_size > 0) && (verbosity >= 2)) {
13147     fprintf(stderr,
13148 	    "WARNING! Histograms and first bursts are incompatible!\n");
13149     fflush(stderr);
13150   }
13151 #endif
13152 #endif
13153 
13154   /* we do not want to make remote_data_address non-NULL because if
13155      the user has not specified a remote adata address, we want to
13156      take it from the hostname in the -H global option. raj
13157      2005-02-08 */
13158 
13159   /* so, if there is to be no control connection, we want to have some
13160      different settings for a few things */
13161 
13162   if (no_control) {
13163 
13164     if (strcmp(remote_data_port,"0") == 0) {
13165       /* we need to select either the discard port, echo port or
13166 	 chargen port dedepending on the test name. raj 2007-02-08 */
13167       if (strstr(test_name,"STREAM") ||
13168 	  strstr(test_name,"SENDFILE")) {
13169 	strncpy(remote_data_port,"discard",sizeof(remote_data_port));
13170       }
13171       else if (strstr(test_name,"RR")) {
13172 	strncpy(remote_data_port,"echo",sizeof(remote_data_port));
13173       }
13174       else if (strstr(test_name,"MAERTS")) {
13175 	strncpy(remote_data_port,"chargen",sizeof(remote_data_port));
13176       }
13177       else {
13178 	printf("No default port known for the %s test, please set one yourself\n",test_name);
13179 	exit(-1);
13180       }
13181     }
13182     remote_data_port[sizeof(remote_data_port) - 1] = '\0';
13183 
13184     /* I go back and forth on whether these should become -1 or if
13185        they should become 0 for a no_control test. what do you think?
13186        raj 2006-02-08 */
13187 
13188     rem_rcvavoid = -1;
13189     rem_sndavoid = -1;
13190     rss_size_req = -1;
13191     rsr_size_req = -1;
13192     rem_nodelay = -1;
13193 
13194     if (strstr(test_name,"STREAM") ||
13195 	strstr(test_name,"SENDFILE")) {
13196       recv_size = -1;
13197     }
13198     else if (strstr(test_name,"MAERTS")) {
13199       send_size = -1;
13200     }
13201   }
13202 }
13203