Home | History | Annotate | Download | only in src
      1 #ifndef lint
      2 char	nettest_sdp[]="\
      3 @(#)nettest_sdp.c (c) Copyright 2007-2012 Hewlett-Packard Co. Version 2.6.0";
      4 #else
      5 #define DIRTY
      6 #define WANT_HISTOGRAM
      7 #define WANT_INTERVALS
      8 #endif /* lint */
      9 
     10 /****************************************************************/
     11 /*								*/
     12 /*	nettest_sdp.c						*/
     13 /*								*/
     14 /*                                                              */
     15 /*      scan_sdp_args()        get the sdp command line args  */
     16 /*                                                              */
     17 /*	the actual test routines...				*/
     18 /*								*/
     19 /*	send_sdp_stream()	perform a sdp stream test	*/
     20 /*	recv_sdp_stream()					*/
     21 /*	send_sdp_rr()		perform a sdp request/response	*/
     22 /*	recv_sdp_rr()						*/
     23 /*								*/
     24 /*      relies on create_data_socket in nettest_bsd.c           */
     25 /****************************************************************/
     26 
     27 #if HAVE_CONFIG_H
     28 # include <config.h>
     29 #endif
     30 
     31 #if defined(WANT_SDP)
     32 
     33 #include <sys/types.h>
     34 #include <fcntl.h>
     35 #include <errno.h>
     36 #include <signal.h>
     37 #include <stdio.h>
     38 #include <string.h>
     39 #include <time.h>
     40 #ifdef NOSTDLIBH
     41 #include <malloc.h>
     42 #else /* NOSTDLIBH */
     43 #include <stdlib.h>
     44 #endif /* NOSTDLIBH */
     45 
     46 #if !defined(__VMS)
     47 #include <sys/ipc.h>
     48 #endif /* !defined(__VMS) */
     49 #include <unistd.h>
     50 #include <sys/types.h>
     51 #include <sys/socket.h>
     52 #include <netinet/in.h>
     53 #include <netinet/tcp.h>
     54 #include <arpa/inet.h>
     55 #include <netdb.h>
     56 
     57 /* would seem that not all sdp.h files define a MSG_EOF, but that
     58    MSG_EOF can be the same as MSG_FIN so lets work with that
     59    assumption.  initial find by Jon Pedersen. raj 2006-02-01 */
     60 #ifndef MSG_EOF
     61 #ifdef MSG_FIN
     62 #define MSG_EOF MSG_FIN
     63 #else
     64 #error Must have either MSG_EOF or MSG_FIN defined
     65 #endif
     66 #endif
     67 
     68 #include "netlib.h"
     69 #include "netsh.h"
     70 /* get some of the functions from nettest_bsd.c */
     71 #include "nettest_bsd.h"
     72 #include "nettest_sdp.h"
     73 
     74 #ifdef WANT_HISTOGRAM
     75 #ifdef __sgi
     76 #include <sys/time.h>
     77 #endif /* __sgi */
     78 #include "hist.h"
     79 #endif /* WANT_HISTOGRAM */
     80 
     81 #ifdef WANT_FIRST_BURST
     82 extern int first_burst_size;
     83 #endif /* WANT_FIRST_BURST */
     84 
     85 
     86 
     88 /* these variables are specific to SDP tests. declare */
     89 /* them static to make them global only to this file. */
     90 
     91 static int
     92   msg_count = 0,	/* number of messages to transmit on association */
     93   non_block = 0,	/* default to blocking sockets */
     94   num_associations = 1; /* number of associations on the endpoint */
     95 
     96 static  int confidence_iteration;
     97 static  char  local_cpu_method;
     98 static  char  remote_cpu_method;
     99 
    100 #ifdef WANT_HISTOGRAM
    101 static struct timeval time_one;
    102 static struct timeval time_two;
    103 static HIST time_hist;
    104 #endif /* WANT_HISTOGRAM */
    105 
    106 
    107 char sdp_usage[] = "\n\
    108 Usage: netperf [global options] -- [test options] \n\
    109 \n\
    110 SDP Sockets Test Options:\n\
    111     -b number         Send number requests at the start of _RR tests\n\
    112     -D [L][,R]        Set SDP_NODELAY locally and/or remotely\n\
    113     -h                Display this text\n\
    114     -H name,fam       Use name (or IP) and family as target of data connection\n\
    115     -L name,fam       Use name (or IP) and family as source of data connextion\n\
    116     -m bytes          Set the size of each sent message\n\
    117     -M bytes          Set the size of each received messages\n\
    118     -P local[,remote] Set the local/remote port for the data socket\n\
    119     -r req,[rsp]      Set request/response sizes (_RR tests)\n\
    120     -s send[,recv]    Set local socket send/recv buffer sizes\n\
    121     -S send[,recv]    Set remote socket send/recv buffer sizes\n\
    122     -V 		      Enable copy avoidance if supported\n\
    123     -4                Use AF_INET (eg IPv4) on both ends of the data conn\n\
    124     -6                Use AF_INET6 (eg IPv6) on both ends of the data conn\n\
    125 \n\
    126 For those options taking two parms, at least one must be specified;\n\
    127 specifying one value without a comma will set both parms to that\n\
    128 value, specifying a value with a leading comma will set just the second\n\
    129 parm, a value with a trailing comma will set just the first. To set\n\
    130 each parm to unique values, specify both and separate them with a\n\
    131 comma.\n";
    132 
    133 
    134  /* This routine is intended to retrieve interesting aspects of sdp */
    136  /* for the data connection. at first, it attempts to retrieve the */
    137  /* maximum segment size. later, it might be modified to retrieve */
    138  /* other information, but it must be information that can be */
    139  /* retrieved quickly as it is called during the timing of the test. */
    140  /* for that reason, a second routine may be created that can be */
    141  /* called outside of the timing loop */
    142 static
    143 void
    144 get_sdp_info(int socket, int * mss)
    145 {
    146 
    147 #ifdef TCP_MAXSEG
    148   netperf_socklen_t sock_opt_len;
    149 
    150   sock_opt_len = sizeof(netperf_socklen_t);
    151   if (getsockopt(socket,
    152 		 getprotobyname("tcp")->p_proto,
    153 		 TCP_MAXSEG,
    154 		 (char *)mss,
    155 		 &sock_opt_len) == SOCKET_ERROR) {
    156     fprintf(where,
    157 	    "netperf: get_sdp_info: getsockopt TCP_MAXSEG: errno %d\n",
    158 	    errno);
    159     fflush(where);
    160     *mss = -1;
    161   }
    162 #else
    163   *mss = -1;
    164 #endif /* TCP_MAXSEG */
    165 
    166 }
    167 
    168 void
    169 send_sdp_stream(char remote_host[])
    170 {
    171 
    172   char *tput_title = "\
    173 Recv   Send    Send                          \n\
    174 Socket Socket  Message  Elapsed              \n\
    175 Size   Size    Size     Time     Throughput  \n\
    176 bytes  bytes   bytes    secs.    %s/sec  \n\n";
    177 
    178   char *tput_fmt_0 =
    179     "%7.2f %s\n";
    180 
    181   char *tput_fmt_1 =
    182     "%6d %6d %6d    %-6.2f   %7.2f   %s\n";
    183 
    184   char *cpu_title = "\
    185 Recv   Send    Send                          Utilization       Service Demand\n\
    186 Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
    187 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
    188 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
    189 
    190   char *cpu_fmt_0 =
    191     "%6.3f %c %s\n";
    192 
    193   char *cpu_fmt_1 =
    194     "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f %s\n";
    195 
    196   char *ksink_fmt = "\n\
    197 Alignment      Offset         %-8.8s %-8.8s    Sends   %-8.8s Recvs\n\
    198 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
    199 Send   Recv    Send   Recv             Send (avg)          Recv (avg)\n\
    200 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
    201 
    202   char *ksink_fmt2 = "\n\
    203 Maximum\n\
    204 Segment\n\
    205 Size (bytes)\n\
    206 %6d\n";
    207 
    208 
    209   float			elapsed_time;
    210 
    211   /* what we want is to have a buffer space that is at least one */
    212   /* send-size greater than our send window. this will insure that we */
    213   /* are never trying to re-use a buffer that may still be in the hands */
    214   /* of the transport. This buffer will be malloc'd after we have found */
    215   /* the size of the local senc socket buffer. We will want to deal */
    216   /* with alignment and offset concerns as well. */
    217 
    218   struct ring_elt *send_ring;
    219 
    220   int len;
    221   unsigned int nummessages = 0;
    222   SOCKET send_socket;
    223   int bytes_remaining;
    224   int sdp_mss = -1;  /* possibly uninitialized on printf far below */
    225 
    226   /* with links like fddi, one can send > 32 bits worth of bytes */
    227   /* during a test... ;-) at some point, this should probably become a */
    228   /* 64bit integral type, but those are not entirely common yet */
    229 
    230   unsigned long long local_bytes_sent = 0;
    231   double	bytes_sent = 0.0;
    232 
    233   float	local_cpu_utilization;
    234   float	local_service_demand;
    235   float	remote_cpu_utilization;
    236   float	remote_service_demand;
    237 
    238   double	thruput;
    239 
    240   struct addrinfo *remote_res;
    241   struct addrinfo *local_res;
    242 
    243   struct	sdp_stream_request_struct	*sdp_stream_request;
    244   struct	sdp_stream_response_struct	*sdp_stream_response;
    245   struct	sdp_stream_results_struct	*sdp_stream_result;
    246 
    247   sdp_stream_request  =
    248     (struct sdp_stream_request_struct *)netperf_request.content.test_specific_data;
    249   sdp_stream_response =
    250     (struct sdp_stream_response_struct *)netperf_response.content.test_specific_data;
    251   sdp_stream_result   =
    252     (struct sdp_stream_results_struct *)netperf_response.content.test_specific_data;
    253 
    254 #ifdef WANT_HISTOGRAM
    255   if (verbosity > 1) {
    256     time_hist = HIST_new();
    257   }
    258 #endif /* WANT_HISTOGRAM */
    259   /* since we are now disconnected from the code that established the */
    260   /* control socket, and since we want to be able to use different */
    261   /* protocols and such, we are passed the name of the remote host and */
    262   /* must turn that into the test specific addressing information. */
    263 
    264   /* complete_addrinfos will either succede or exit the process */
    265   complete_addrinfos(&remote_res,
    266 		     &local_res,
    267 		     remote_host,
    268 		     SOCK_STREAM,
    269 		     IPPROTO_TCP,
    270 		     0);
    271 
    272   if ( print_headers ) {
    273     print_top_test_header("SDP STREAM TEST",local_res,remote_res);
    274   }
    275 
    276   send_ring = NULL;
    277   confidence_iteration = 1;
    278   init_stat();
    279 
    280   /* we have a great-big while loop which controls the number of times */
    281   /* we run a particular test. this is for the calculation of a */
    282   /* confidence interval (I really should have stayed awake during */
    283   /* probstats :). If the user did not request confidence measurement */
    284   /* (no confidence is the default) then we will only go though the */
    285   /* loop once. the confidence stuff originates from the folks at IBM */
    286 
    287   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
    288 	 (confidence_iteration <= iteration_min)) {
    289 
    290     /* initialize a few counters. we have to remember that we might be */
    291     /* going through the loop more than once. */
    292 
    293     nummessages    =	0;
    294     bytes_sent     =	0.0;
    295     times_up       = 	0;
    296 
    297     /*set up the data socket                        */
    298     /* fake things out by changing local_res->ai_family to AF_INET_SDP */
    299     local_res->ai_family = AF_INET_SDP;
    300     local_res->ai_protocol = 0;
    301     send_socket = create_data_socket(local_res);
    302 
    303     if (send_socket == INVALID_SOCKET){
    304       perror("netperf: send_sdp_stream: sdp stream data socket");
    305       exit(1);
    306     }
    307 
    308     if (debug) {
    309       fprintf(where,"send_sdp_stream: send_socket obtained...\n");
    310     }
    311 
    312     /* at this point, we have either retrieved the socket buffer sizes, */
    313     /* or have tried to set them, so now, we may want to set the send */
    314     /* size based on that (because the user either did not use a -m */
    315     /* option, or used one with an argument of 0). If the socket buffer */
    316     /* size is not available, we will set the send size to 4KB - no */
    317     /* particular reason, just arbitrary... */
    318     if (send_size == 0) {
    319       if (lss_size > 0) {
    320 	send_size = lss_size;
    321       }
    322       else {
    323 	send_size = 4096;
    324       }
    325     }
    326 
    327     /* set-up the data buffer ring with the requested alignment and offset. */
    328     /* note also that we have allocated a quantity */
    329     /* of memory that is at least one send-size greater than our socket */
    330     /* buffer size. We want to be sure that there are at least two */
    331     /* buffers allocated - this can be a bit of a problem when the */
    332     /* send_size is bigger than the socket size, so we must check... the */
    333     /* user may have wanted to explicitly set the "width" of our send */
    334     /* buffers, we should respect that wish... */
    335     if (send_width == 0) {
    336       send_width = (lss_size/send_size) + 1;
    337       if (send_width == 1) send_width++;
    338     }
    339 
    340     if (send_ring == NULL) {
    341       /* only allocate the send ring once. this is a networking test, */
    342       /* not a memory allocation test. this way, we do not need a */
    343       /* deallocate_buffer_ring() routine, and I don't feel like */
    344       /* writing one anyway :) raj 11/94 */
    345       send_ring = allocate_buffer_ring(send_width,
    346 				       send_size,
    347 				       local_send_align,
    348 				       local_send_offset);
    349     }
    350 
    351     /* If the user has requested cpu utilization measurements, we must */
    352     /* calibrate the cpu(s). We will perform this task within the tests */
    353     /* themselves. If the user has specified the cpu rate, then */
    354     /* calibrate_local_cpu will return rather quickly as it will have */
    355     /* nothing to do. If local_cpu_rate is zero, then we will go through */
    356     /* all the "normal" calibration stuff and return the rate back. */
    357 
    358     if (local_cpu_usage) {
    359       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
    360     }
    361 
    362     if (!no_control) {
    363       /* Tell the remote end to do a listen. The server alters the
    364 	 socket paramters on the other side at this point, hence the
    365 	 reason for all the values being passed in the setup
    366 	 message. If the user did not specify any of the parameters,
    367 	 they will be passed as 0, which will indicate to the remote
    368 	 that no changes beyond the system's default should be
    369 	 used. Alignment is the exception, it will default to 1, which
    370 	 will be no alignment alterations. */
    371 
    372       netperf_request.content.request_type =	DO_SDP_STREAM;
    373       sdp_stream_request->send_buf_size	=	rss_size_req;
    374       sdp_stream_request->recv_buf_size	=	rsr_size_req;
    375       sdp_stream_request->receive_size	=	recv_size;
    376       sdp_stream_request->no_delay	=	rem_nodelay;
    377       sdp_stream_request->recv_alignment	=	remote_recv_align;
    378       sdp_stream_request->recv_offset	=	remote_recv_offset;
    379       sdp_stream_request->measure_cpu	=	remote_cpu_usage;
    380       sdp_stream_request->cpu_rate	=	remote_cpu_rate;
    381       if (test_time) {
    382 	sdp_stream_request->test_length	=	test_time;
    383       }
    384       else {
    385 	sdp_stream_request->test_length	=	test_bytes;
    386       }
    387       sdp_stream_request->so_rcvavoid	=	rem_rcvavoid;
    388       sdp_stream_request->so_sndavoid	=	rem_sndavoid;
    389 #ifdef DIRTY
    390       sdp_stream_request->dirty_count     =       rem_dirty_count;
    391       sdp_stream_request->clean_count     =       rem_clean_count;
    392 #endif /* DIRTY */
    393       sdp_stream_request->port            =    atoi(remote_data_port);
    394       sdp_stream_request->ipfamily = af_to_nf(remote_res->ai_family);
    395       if (debug > 1) {
    396 	fprintf(where,
    397 		"netperf: send_sdp_stream: requesting SDP stream test\n");
    398       }
    399 
    400       send_request();
    401 
    402       /* The response from the remote will contain all of the relevant
    403          socket parameters for this test type. We will put them back
    404          into the variables here so they can be displayed if desired.
    405          The remote will have calibrated CPU if necessary, and will
    406          have done all the needed set-up we will have calibrated the
    407          cpu locally before sending the request, and will grab the
    408          counter value right after the connect returns. The remote
    409          will grab the counter right after the accept call. This saves
    410          the hassle of extra messages being sent for the SDP
    411          tests.  */
    412 
    413       recv_response();
    414 
    415       if (!netperf_response.content.serv_errno) {
    416 	if (debug)
    417 	  fprintf(where,"remote listen done.\n");
    418 	rsr_size	      =	sdp_stream_response->recv_buf_size;
    419 	rss_size	      =	sdp_stream_response->send_buf_size;
    420 	rem_nodelay     =	sdp_stream_response->no_delay;
    421 	remote_cpu_usage=	sdp_stream_response->measure_cpu;
    422 	remote_cpu_rate = sdp_stream_response->cpu_rate;
    423 
    424 	/* we have to make sure that the server port number is in
    425 	   network order */
    426 	set_port_number(remote_res,
    427 			(short)sdp_stream_response->data_port_number);
    428 
    429 	rem_rcvavoid	= sdp_stream_response->so_rcvavoid;
    430 	rem_sndavoid	= sdp_stream_response->so_sndavoid;
    431       }
    432       else {
    433 	Set_errno(netperf_response.content.serv_errno);
    434 	fprintf(where,
    435 		"netperf: remote error %d",
    436 		netperf_response.content.serv_errno);
    437 	perror("");
    438 	fflush(where);
    439 
    440 	exit(1);
    441       }
    442     }
    443 
    444 #ifdef WANT_DEMO
    445     DEMO_STREAM_SETUP(lss_size,rsr_size)
    446 #endif
    447 
    448     /*Connect up to the remote port on the data socket  */
    449     if (connect(send_socket,
    450 		remote_res->ai_addr,
    451 		remote_res->ai_addrlen) == INVALID_SOCKET){
    452       perror("netperf: send_sdp_stream: data socket connect failed");
    453       exit(1);
    454     }
    455 
    456     /* Data Socket set-up is finished. If there were problems, either */
    457     /* the connect would have failed, or the previous response would */
    458     /* have indicated a problem. I failed to see the value of the */
    459     /* extra  message after the accept on the remote. If it failed, */
    460     /* we'll see it here. If it didn't, we might as well start pumping */
    461     /* data. */
    462 
    463     /* Set-up the test end conditions. For a stream test, they can be */
    464     /* either time or byte-count based. */
    465 
    466     if (test_time) {
    467       /* The user wanted to end the test after a period of time. */
    468       times_up = 0;
    469       bytes_remaining = 0;
    470       /* in previous revisions, we had the same code repeated throught */
    471       /* all the test suites. this was unnecessary, and meant more */
    472       /* work for me when I wanted to switch to POSIX signals, so I */
    473       /* have abstracted this out into a routine in netlib.c. if you */
    474       /* are experiencing signal problems, you might want to look */
    475       /* there. raj 11/94 */
    476       start_timer(test_time);
    477     }
    478     else {
    479       /* The tester wanted to send a number of bytes. */
    480       bytes_remaining = test_bytes;
    481       times_up = 1;
    482     }
    483 
    484     /* The cpu_start routine will grab the current time and possibly */
    485     /* value of the idle counter for later use in measuring cpu */
    486     /* utilization and/or service demand and thruput. */
    487 
    488     cpu_start(local_cpu_usage);
    489 
    490     /* we only start the interval timer if we are using the
    491        timer-timed intervals rather than the sit and spin ones. raj
    492        2006-02-06 */
    493 #if defined(WANT_INTERVALS)
    494     INTERVALS_INIT();
    495 #endif /* WANT_INTERVALS */
    496 
    497     /* before we start, initialize a few variables */
    498 
    499 #ifdef WANT_DEMO
    500       if (demo_mode) {
    501 	HIST_timestamp(demo_one_ptr);
    502       }
    503 #endif
    504 
    505 
    506     /* We use an "OR" to control test execution. When the test is */
    507     /* controlled by time, the byte count check will always return false. */
    508     /* When the test is controlled by byte count, the time test will */
    509     /* always return false. When the test is finished, the whole */
    510     /* expression will go false and we will stop sending data. */
    511 
    512     while ((!times_up) || (bytes_remaining > 0)) {
    513 
    514 #ifdef DIRTY
    515       access_buffer(send_ring->buffer_ptr,
    516 		    send_size,
    517 		    loc_dirty_count,
    518 		    loc_clean_count);
    519 #endif /* DIRTY */
    520 
    521 #ifdef WANT_HISTOGRAM
    522       if (verbosity > 1) {
    523 	/* timestamp just before we go into send and then again just
    524 	 after we come out raj 8/94 */
    525 	/* but lets only do this if there is going to be a histogram
    526 	   displayed */
    527 	HIST_timestamp(&time_one);
    528       }
    529 #endif /* WANT_HISTOGRAM */
    530 
    531       if((len=send(send_socket,
    532 		   send_ring->buffer_ptr,
    533 		   send_size,
    534 		   0)) != send_size) {
    535       if ((len >=0) || SOCKET_EINTR(len)) {
    536 	    /* the test was interrupted, must be the end of test */
    537 	    break;
    538 	  }
    539 	perror("netperf: data send error");
    540 	printf("len was %d\n",len);
    541 	exit(1);
    542       }
    543 
    544       local_bytes_sent += send_size;
    545 
    546 #ifdef WANT_HISTOGRAM
    547       if (verbosity > 1) {
    548 	/* timestamp the exit from the send call and update the histogram */
    549 	HIST_timestamp(&time_two);
    550 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
    551       }
    552 #endif /* WANT_HISTOGRAM */
    553 
    554 #ifdef WANT_DEMO
    555       DEMO_STREAM_INTERVAL(send_size)
    556 #endif
    557 
    558 #if defined(WANT_INTERVALS)
    559       INTERVALS_WAIT();
    560 #endif /* WANT_INTERVALS */
    561 
    562       /* now we want to move our pointer to the next position in the */
    563       /* data buffer...we may also want to wrap back to the "beginning" */
    564       /* of the bufferspace, so we will mod the number of messages sent */
    565       /* by the send width, and use that to calculate the offset to add */
    566       /* to the base pointer. */
    567       nummessages++;
    568       send_ring = send_ring->next;
    569       if (bytes_remaining) {
    570 	bytes_remaining -= send_size;
    571       }
    572     }
    573 
    574     /* The test is over. Flush the buffers to the remote end. We do a */
    575     /* graceful release to insure that all data has been taken by the */
    576     /* remote. */
    577 
    578     /* but first, if the verbosity is greater than 1, find-out what */
    579     /* the SDP maximum segment_size was (if possible) */
    580     if (verbosity > 1) {
    581       sdp_mss = -1;
    582       get_sdp_info(send_socket,&sdp_mss);
    583     }
    584 
    585     if (shutdown(send_socket,SHUT_WR) == SOCKET_ERROR) {
    586       perror("netperf: cannot shutdown sdp stream socket");
    587       exit(1);
    588     }
    589 
    590     /* hang a recv() off the socket to block until the remote has */
    591     /* brought all the data up into the application. it will do a */
    592     /* shutdown to cause a FIN to be sent our way. We will assume that */
    593     /* any exit from the recv() call is good... raj 4/93 */
    594 
    595     recv(send_socket, send_ring->buffer_ptr, send_size, 0);
    596 
    597     /* this call will always give us the elapsed time for the test, and */
    598     /* will also store-away the necessaries for cpu utilization */
    599 
    600     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
    601 						/* measured and how */
    602 						/* long did we really */
    603 						/* run? */
    604 
    605     /* we are finished with the socket, so close it to prevent hitting */
    606     /* the limit on maximum open files. */
    607 
    608     close(send_socket);
    609 
    610     if (!no_control) {
    611       /* Get the statistics from the remote end. The remote will have
    612 	 calculated service demand and all those interesting
    613 	 things. If it wasn't supposed to care, it will return obvious
    614 	 values. */
    615 
    616       recv_response();
    617       if (!netperf_response.content.serv_errno) {
    618 	if (debug)
    619 	  fprintf(where,"remote results obtained\n");
    620       }
    621       else {
    622 	Set_errno(netperf_response.content.serv_errno);
    623 	fprintf(where,
    624 		"netperf: remote error %d",
    625 		netperf_response.content.serv_errno);
    626 	perror("");
    627 	fflush(where);
    628 
    629 	exit(1);
    630       }
    631 
    632       /* We now calculate what our thruput was for the test. In the
    633 	 future, we may want to include a calculation of the thruput
    634 	 measured by the remote, but it should be the case that for a
    635 	 SDP stream test, that the two numbers should be *very*
    636 	 close... We calculate bytes_sent regardless of the way the
    637 	 test length was controlled.  If it was time, we needed to,
    638 	 and if it was by bytes, the user may have specified a number
    639 	 of bytes that wasn't a multiple of the send_size, so we
    640 	 really didn't send what he asked for ;-) */
    641 
    642       bytes_sent	= ntohd(sdp_stream_result->bytes_received);
    643     }
    644     else {
    645       bytes_sent = (double)local_bytes_sent;
    646     }
    647 
    648     thruput	= calc_thruput(bytes_sent);
    649 
    650     if (local_cpu_usage || remote_cpu_usage) {
    651       /* We must now do a little math for service demand and cpu */
    652       /* utilization for the system(s) */
    653       /* Of course, some of the information might be bogus because */
    654       /* there was no idle counter in the kernel(s). We need to make */
    655       /* a note of this for the user's benefit...*/
    656       if (local_cpu_usage) {
    657 
    658 	local_cpu_utilization	= calc_cpu_util(0.0);
    659 	local_service_demand	= calc_service_demand(bytes_sent,
    660 						      0.0,
    661 						      0.0,
    662 						      0);
    663       }
    664       else {
    665 	local_cpu_utilization	= (float) -1.0;
    666 	local_service_demand	= (float) -1.0;
    667       }
    668 
    669       if (remote_cpu_usage) {
    670 
    671 	remote_cpu_utilization	= sdp_stream_result->cpu_util;
    672 	remote_service_demand	= calc_service_demand(bytes_sent,
    673 						      0.0,
    674 						      remote_cpu_utilization,
    675 						      sdp_stream_result->num_cpus);
    676       }
    677       else {
    678 	remote_cpu_utilization = (float) -1.0;
    679 	remote_service_demand  = (float) -1.0;
    680       }
    681     }
    682     else {
    683       /* we were not measuring cpu, for the confidence stuff, we */
    684       /* should make it -1.0 */
    685       local_cpu_utilization	= (float) -1.0;
    686       local_service_demand	= (float) -1.0;
    687       remote_cpu_utilization = (float) -1.0;
    688       remote_service_demand  = (float) -1.0;
    689     }
    690 
    691     /* at this point, we want to calculate the confidence information. */
    692     /* if debugging is on, calculate_confidence will print-out the */
    693     /* parameters we pass it */
    694 
    695     calculate_confidence(confidence_iteration,
    696 			 elapsed_time,
    697 			 thruput,
    698 			 local_cpu_utilization,
    699 			 remote_cpu_utilization,
    700 			 local_service_demand,
    701 			 remote_service_demand);
    702 
    703 
    704     confidence_iteration++;
    705   }
    706 
    707   /* at this point, we have finished making all the runs that we */
    708   /* will be making. so, we should extract what the calcuated values */
    709   /* are for all the confidence stuff. we could make the values */
    710   /* global, but that seemed a little messy, and it did not seem worth */
    711   /* all the mucking with header files. so, we create a routine much */
    712   /* like calcualte_confidence, which just returns the mean values. */
    713   /* raj 11/94 */
    714 
    715   retrieve_confident_values(&elapsed_time,
    716 			    &thruput,
    717 			    &local_cpu_utilization,
    718 			    &remote_cpu_utilization,
    719 			    &local_service_demand,
    720 			    &remote_service_demand);
    721 
    722   /* We are now ready to print all the information. If the user */
    723   /* has specified zero-level verbosity, we will just print the */
    724   /* local service demand, or the remote service demand. If the */
    725   /* user has requested verbosity level 1, he will get the basic */
    726   /* "streamperf" numbers. If the user has specified a verbosity */
    727   /* of greater than 1, we will display a veritable plethora of */
    728   /* background information from outside of this block as it it */
    729   /* not cpu_measurement specific...  */
    730 
    731   if (confidence < 0) {
    732     /* we did not hit confidence, but were we asked to look for it? */
    733     if (iteration_max > 1) {
    734       display_confidence();
    735     }
    736   }
    737 
    738   if (local_cpu_usage || remote_cpu_usage) {
    739     local_cpu_method = format_cpu_method(cpu_method);
    740     remote_cpu_method = format_cpu_method(sdp_stream_result->cpu_method);
    741 
    742     switch (verbosity) {
    743     case 0:
    744       if (local_cpu_usage) {
    745 	fprintf(where,
    746 		cpu_fmt_0,
    747 		local_service_demand,
    748 		local_cpu_method,
    749 		((print_headers) ||
    750 		 (result_brand == NULL)) ? "" : result_brand);
    751       }
    752       else {
    753 	fprintf(where,
    754 		cpu_fmt_0,
    755 		remote_service_demand,
    756 		remote_cpu_method,
    757 		((print_headers) ||
    758 		 (result_brand == NULL)) ? "" : result_brand);
    759       }
    760       break;
    761     case 1:
    762     case 2:
    763       if (print_headers) {
    764 		fprintf(where,
    765 		cpu_title,
    766 		format_units(),
    767 		local_cpu_method,
    768 		remote_cpu_method);
    769       }
    770 
    771       fprintf(where,
    772 	      cpu_fmt_1,		/* the format string */
    773 	      rsr_size,		        /* remote recvbuf size */
    774 	      lss_size,		        /* local sendbuf size */
    775 	      send_size,		/* how large were the sends */
    776 	      elapsed_time,		/* how long was the test */
    777 	      thruput, 		        /* what was the xfer rate */
    778 	      local_cpu_utilization,	/* local cpu */
    779 	      remote_cpu_utilization,	/* remote cpu */
    780 	      local_service_demand,	/* local service demand */
    781 	      remote_service_demand,	/* remote service demand */
    782 	      ((print_headers) ||
    783 	       (result_brand == NULL)) ? "" : result_brand);
    784       break;
    785     }
    786   }
    787   else {
    788     /* The tester did not wish to measure service demand. */
    789 
    790     switch (verbosity) {
    791     case 0:
    792       fprintf(where,
    793 	      tput_fmt_0,
    794 	      thruput,
    795 	      ((print_headers) ||
    796 	       (result_brand == NULL)) ? "" : result_brand);
    797       break;
    798     case 1:
    799     case 2:
    800       if (print_headers) {
    801 		fprintf(where,tput_title,format_units());
    802       }
    803       fprintf(where,
    804 	      tput_fmt_1,		/* the format string */
    805 	      rsr_size, 		/* remote recvbuf size */
    806 	      lss_size, 		/* local sendbuf size */
    807 	      send_size,		/* how large were the sends */
    808 	      elapsed_time, 		/* how long did it take */
    809 	      thruput,                  /* how fast did it go */
    810 	      ((print_headers) ||
    811 	       (result_brand == NULL)) ? "" : result_brand);
    812       break;
    813     }
    814   }
    815 
    816   /* it would be a good thing to include information about some of the */
    817   /* other parameters that may have been set for this test, but at the */
    818   /* moment, I do not wish to figure-out all the  formatting, so I will */
    819   /* just put this comment here to help remind me that it is something */
    820   /* that should be done at a later time. */
    821 
    822   if (verbosity > 1) {
    823     /* The user wanted to know it all, so we will give it to him. */
    824     /* This information will include as much as we can find about */
    825     /* SDP statistics, the alignments of the sends and receives */
    826     /* and all that sort of rot... */
    827 
    828     /* this stuff needs to be worked-out in the presence of confidence */
    829     /* intervals and multiple iterations of the test... raj 11/94 */
    830 
    831     fprintf(where,
    832 	    ksink_fmt,
    833 	    "Bytes",
    834 	    "Bytes",
    835 	    "Bytes",
    836 	    local_send_align,
    837 	    remote_recv_align,
    838 	    local_send_offset,
    839 	    remote_recv_offset,
    840 	    bytes_sent,
    841 	    bytes_sent / (double)nummessages,
    842 	    nummessages,
    843 	    bytes_sent / (double)sdp_stream_result->recv_calls,
    844 	    sdp_stream_result->recv_calls);
    845     fprintf(where,
    846 	    ksink_fmt2,
    847 	    sdp_mss);
    848     fflush(where);
    849 #ifdef WANT_HISTOGRAM
    850     fprintf(where,"\n\nHistogram of time spent in send() call.\n");
    851     fflush(where);
    852     HIST_report(time_hist);
    853 #endif /* WANT_HISTOGRAM */
    854   }
    855 
    856 }
    857 
    858 
    859 
    861 /* This routine implements the netperf-side SDP unidirectional data
    862    transfer test (a.k.a. stream) for the sockets interface where the
    863    data flow is from the netserver to the netperf.  It receives its
    864    parameters via global variables from the shell and writes its
    865    output to the standard output. */
    866 
    867 
    868 void
    869 send_sdp_maerts(char remote_host[])
    870 {
    871 
    872   char *tput_title = "\
    873 Recv   Send    Send                          \n\
    874 Socket Socket  Message  Elapsed              \n\
    875 Size   Size    Size     Time     Throughput  \n\
    876 bytes  bytes   bytes    secs.    %s/sec  \n\n";
    877 
    878   char *tput_fmt_0 =
    879     "%7.2f %s\n";
    880 
    881   char *tput_fmt_1 =
    882     "%6d %6d %6d    %-6.2f   %7.2f   \n %s";
    883 
    884   char *cpu_title = "\
    885 Recv   Send    Send                          Utilization       Service Demand\n\
    886 Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
    887 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
    888 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
    889 
    890   char *cpu_fmt_0 =
    891     "%6.3f %c %s\n";
    892 
    893   char *cpu_fmt_1 =
    894     "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f %s\n";
    895 
    896   char *ksink_fmt = "\n\
    897 Alignment      Offset         %-8.8s %-8.8s    Recvs   %-8.8s Sends\n\
    898 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
    899 Recv   Send    Recv   Send             Recv (avg)          Send (avg)\n\
    900 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
    901 
    902   char *ksink_fmt2 = "\n\
    903 Maximum\n\
    904 Segment\n\
    905 Size (bytes)\n\
    906 %6d\n";
    907 
    908 
    909   float			elapsed_time;
    910 
    911   /* what we want is to have a buffer space that is at least one */
    912   /* recv-size greater than our recv window. this will insure that we */
    913   /* are never trying to re-use a buffer that may still be in the hands */
    914   /* of the transport. This buffer will be malloc'd after we have found */
    915   /* the size of the local senc socket buffer. We will want to deal */
    916   /* with alignment and offset concerns as well. */
    917 
    918   struct ring_elt *recv_ring;
    919 
    920   int len;
    921   unsigned int nummessages = 0;
    922   SOCKET recv_socket;
    923   int bytes_remaining;
    924   int sdp_mss = -1;  /* possibly uninitialized on printf far below */
    925 
    926   /* with links like fddi, one can recv > 32 bits worth of bytes */
    927   /* during a test... ;-) at some point, this should probably become a */
    928   /* 64bit integral type, but those are not entirely common yet */
    929   double	bytes_sent = 0.0;
    930   unsigned long long local_bytes_recvd = 0;
    931 
    932   float	local_cpu_utilization;
    933   float	local_service_demand;
    934   float	remote_cpu_utilization;
    935   float	remote_service_demand;
    936 
    937   double	thruput;
    938 
    939   struct addrinfo *remote_res;
    940   struct addrinfo *local_res;
    941 
    942   struct	sdp_maerts_request_struct	*sdp_maerts_request;
    943   struct	sdp_maerts_response_struct	*sdp_maerts_response;
    944   struct	sdp_maerts_results_struct	*sdp_maerts_result;
    945 
    946   sdp_maerts_request  =
    947     (struct sdp_maerts_request_struct *)netperf_request.content.test_specific_data;
    948   sdp_maerts_response =
    949     (struct sdp_maerts_response_struct *)netperf_response.content.test_specific_data;
    950   sdp_maerts_result   =
    951     (struct sdp_maerts_results_struct *)netperf_response.content.test_specific_data;
    952 
    953 #ifdef WANT_HISTOGRAM
    954   if (verbosity > 1) {
    955     time_hist = HIST_new();
    956   }
    957 #endif /* WANT_HISTOGRAM */
    958   /* since we are now disconnected from the code that established the */
    959   /* control socket, and since we want to be able to use different */
    960   /* protocols and such, we are passed the name of the remote host and */
    961   /* must turn that into the test specific addressing information. */
    962 
    963   complete_addrinfos(&remote_res,
    964 		     &local_res,
    965 		     remote_host,
    966 		     SOCK_STREAM,
    967 		     IPPROTO_TCP,
    968 		     0);
    969 
    970   if ( print_headers ) {
    971     print_top_test_header("SDP MAERTS TEST",local_res,remote_res);
    972   }
    973 
    974   recv_ring = NULL;
    975   confidence_iteration = 1;
    976   init_stat();
    977 
    978   /* we have a great-big while loop which controls the number of times */
    979   /* we run a particular test. this is for the calculation of a */
    980   /* confidence interval (I really should have stayed awake during */
    981   /* probstats :). If the user did not request confidence measurement */
    982   /* (no confidence is the default) then we will only go though the */
    983   /* loop once. the confidence stuff originates from the folks at IBM */
    984 
    985   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
    986 	 (confidence_iteration <= iteration_min)) {
    987 
    988     /* initialize a few counters. we have to remember that we might be */
    989     /* going through the loop more than once. */
    990 
    991     nummessages    =	0;
    992     bytes_sent     =	0.0;
    993     times_up       = 	0;
    994 
    995     /*set up the data socket                        */
    996     /* fake things out by changing local_res->ai_family to AF_INET_SDP */
    997     local_res->ai_family = AF_INET_SDP;
    998     local_res->ai_protocol = 0;
    999     recv_socket = create_data_socket(local_res);
   1000 
   1001     if (recv_socket == INVALID_SOCKET){
   1002       perror("netperf: send_sdp_maerts: sdp stream data socket");
   1003       exit(1);
   1004     }
   1005 
   1006     if (debug) {
   1007       fprintf(where,"send_sdp_maerts: recv_socket obtained...\n");
   1008     }
   1009 
   1010     /* at this point, we have either retrieved the socket buffer sizes, */
   1011     /* or have tried to set them, so now, we may want to set the recv */
   1012     /* size based on that (because the user either did not use a -m */
   1013     /* option, or used one with an argument of 0). If the socket buffer */
   1014     /* size is not available, we will set the recv size to 4KB - no */
   1015     /* particular reason, just arbitrary... */
   1016     if (recv_size == 0) {
   1017       if (lsr_size > 0) {
   1018 	recv_size = lsr_size;
   1019       }
   1020       else {
   1021 	recv_size = 4096;
   1022       }
   1023     }
   1024 
   1025     /* set-up the data buffer ring with the requested alignment and offset. */
   1026     /* note also that we have allocated a quantity */
   1027     /* of memory that is at least one recv-size greater than our socket */
   1028     /* buffer size. We want to be sure that there are at least two */
   1029     /* buffers allocated - this can be a bit of a problem when the */
   1030     /* recv_size is bigger than the socket size, so we must check... the */
   1031     /* user may have wanted to explicitly set the "width" of our recv */
   1032     /* buffers, we should respect that wish... */
   1033     if (recv_width == 0) {
   1034       recv_width = (lsr_size/recv_size) + 1;
   1035       if (recv_width == 1) recv_width++;
   1036     }
   1037 
   1038     if (recv_ring == NULL) {
   1039       /* only allocate the recv ring once. this is a networking test, */
   1040       /* not a memory allocation test. this way, we do not need a */
   1041       /* deallocate_buffer_ring() routine, and I don't feel like */
   1042       /* writing one anyway :) raj 11/94 */
   1043       recv_ring = allocate_buffer_ring(recv_width,
   1044 				       recv_size,
   1045 				       local_recv_align,
   1046 				       local_recv_offset);
   1047     }
   1048 
   1049     /* If the user has requested cpu utilization measurements, we must */
   1050     /* calibrate the cpu(s). We will perform this task within the tests */
   1051     /* themselves. If the user has specified the cpu rate, then */
   1052     /* calibrate_local_cpu will return rather quickly as it will have */
   1053     /* nothing to do. If local_cpu_rate is zero, then we will go through */
   1054     /* all the "normal" calibration stuff and return the rate back. */
   1055 
   1056     if (local_cpu_usage) {
   1057       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   1058     }
   1059 
   1060     if (!no_control) {
   1061       /* Tell the remote end to do a listen. The server alters the
   1062 	 socket paramters on the other side at this point, hence the
   1063 	 reason for all the values being passed in the setup
   1064 	 message. If the user did not specify any of the parameters,
   1065 	 they will be passed as 0, which will indicate to the remote
   1066 	 that no changes beyond the system's default should be
   1067 	 used. Alignment is the exception, it will default to 1, which
   1068 	 will be no alignment alterations. */
   1069 
   1070       netperf_request.content.request_type	=	DO_SDP_MAERTS;
   1071       sdp_maerts_request->send_buf_size	=	rss_size_req;
   1072       sdp_maerts_request->recv_buf_size	=	rsr_size_req;
   1073       sdp_maerts_request->send_size	=	send_size;
   1074       sdp_maerts_request->no_delay	=	rem_nodelay;
   1075       sdp_maerts_request->send_alignment	=	remote_send_align;
   1076       sdp_maerts_request->send_offset	=	remote_send_offset;
   1077       sdp_maerts_request->measure_cpu	=	remote_cpu_usage;
   1078       sdp_maerts_request->cpu_rate	=	remote_cpu_rate;
   1079       if (test_time) {
   1080 	sdp_maerts_request->test_length	=	test_time;
   1081       }
   1082       else {
   1083 	sdp_maerts_request->test_length	=	test_bytes;
   1084       }
   1085       sdp_maerts_request->so_rcvavoid	=	rem_rcvavoid;
   1086       sdp_maerts_request->so_sndavoid	=	rem_sndavoid;
   1087 #ifdef DIRTY
   1088       sdp_maerts_request->dirty_count       =       rem_dirty_count;
   1089       sdp_maerts_request->clean_count       =       rem_clean_count;
   1090 #endif /* DIRTY */
   1091       sdp_maerts_request->port            = atoi(remote_data_port);
   1092       sdp_maerts_request->ipfamily        = af_to_nf(remote_res->ai_family);
   1093       if (debug > 1) {
   1094 	fprintf(where,
   1095 		"netperf: send_sdp_maerts: requesting SDP maerts test\n");
   1096       }
   1097 
   1098       send_request();
   1099 
   1100       /* The response from the remote will contain all of the relevant
   1101 	 socket parameters for this test type. We will put them back
   1102 	 into the variables here so they can be displayed if desired.
   1103 	 The remote will have calibrated CPU if necessary, and will
   1104 	 have done all the needed set-up we will have calibrated the
   1105 	 cpu locally before sending the request, and will grab the
   1106 	 counter value right after the connect returns. The remote
   1107 	 will grab the counter right after the accept call. This saves
   1108 	 the hassle of extra messages being sent for the SDP
   1109 	 tests.  */
   1110 
   1111       recv_response();
   1112 
   1113       if (!netperf_response.content.serv_errno) {
   1114 	if (debug)
   1115 	  fprintf(where,"remote listen done.\n");
   1116 	rsr_size	=	sdp_maerts_response->recv_buf_size;
   1117 	rss_size	=	sdp_maerts_response->send_buf_size;
   1118 	rem_nodelay     =	sdp_maerts_response->no_delay;
   1119 	remote_cpu_usage=	sdp_maerts_response->measure_cpu;
   1120 	remote_cpu_rate = sdp_maerts_response->cpu_rate;
   1121 	send_size       = sdp_maerts_response->send_size;
   1122 
   1123 	/* we have to make sure that the server port number is in
   1124 	 network order */
   1125       set_port_number(remote_res,
   1126 		      (short)sdp_maerts_response->data_port_number);
   1127       rem_rcvavoid	= sdp_maerts_response->so_rcvavoid;
   1128       rem_sndavoid	= sdp_maerts_response->so_sndavoid;
   1129       }
   1130       else {
   1131 	Set_errno(netperf_response.content.serv_errno);
   1132 	fprintf(where,
   1133 		"netperf: remote error %d",
   1134 		netperf_response.content.serv_errno);
   1135 	perror("");
   1136 	fflush(where);
   1137 
   1138 	exit(1);
   1139       }
   1140     }
   1141 
   1142 #ifdef WANT_DEMO
   1143     DEMO_STREAM_SETUP(lsr_size,rss_size)
   1144 #endif
   1145 
   1146     /*Connect up to the remote port on the data socket  */
   1147     if (connect(recv_socket,
   1148 		remote_res->ai_addr,
   1149 		remote_res->ai_addrlen) == INVALID_SOCKET){
   1150       perror("netperf: send_sdp_maerts: data socket connect failed");
   1151       exit(1);
   1152     }
   1153 
   1154     /* Data Socket set-up is finished. If there were problems, either */
   1155     /* the connect would have failed, or the previous response would */
   1156     /* have indicated a problem. I failed to see the value of the */
   1157     /* extra  message after the accept on the remote. If it failed, */
   1158     /* we'll see it here. If it didn't, we might as well start pumping */
   1159     /* data. */
   1160 
   1161     /* Set-up the test end conditions. For a maerts test, they can be */
   1162     /* either time or byte-count based. */
   1163 
   1164     if (test_time) {
   1165       /* The user wanted to end the test after a period of time. */
   1166       times_up = 0;
   1167       bytes_remaining = 0;
   1168       /* in previous revisions, we had the same code repeated throught */
   1169       /* all the test suites. this was unnecessary, and meant more */
   1170       /* work for me when I wanted to switch to POSIX signals, so I */
   1171       /* have abstracted this out into a routine in netlib.c. if you */
   1172       /* are experiencing signal problems, you might want to look */
   1173       /* there. raj 11/94 */
   1174       if (!no_control) {
   1175 	/* this is a netperf to netserver test, netserver will close
   1176 	   to tell us the test is over, so use PAD_TIME to avoid
   1177 	   causing the netserver fits. */
   1178 	start_timer(test_time + PAD_TIME);
   1179       }
   1180       else {
   1181 	/* this is a netperf to data source test, no PAD_TIME */
   1182 	start_timer(test_time);
   1183       }
   1184     }
   1185     else {
   1186       /* The tester wanted to recv a number of bytes. we don't do that
   1187 	 in a SDP_MAERTS test. sorry. raj 2002-06-21 */
   1188       printf("netperf: send_sdp_maerts: test must be timed\n");
   1189       exit(1);
   1190     }
   1191 
   1192     /* The cpu_start routine will grab the current time and possibly */
   1193     /* value of the idle counter for later use in measuring cpu */
   1194     /* utilization and/or service demand and thruput. */
   1195 
   1196     cpu_start(local_cpu_usage);
   1197 
   1198 #ifdef WANT_INTERVALS
   1199     INTERVALS_INIT();
   1200 #endif /* WANT_INTERVALS */
   1201 
   1202     /* before we start, initialize a few variables */
   1203 
   1204 #ifdef WANT_DEMO
   1205     if (demo_mode) {
   1206       HIST_timestamp(demo_one_ptr);
   1207     }
   1208 #endif
   1209 
   1210     /* the test will continue until we either get a zero-byte recv()
   1211        on the socket or our failsafe timer expires. most of the time
   1212        we trust that we get a zero-byte recieve from the socket. raj
   1213        2002-06-21 */
   1214 
   1215 #ifdef WANT_HISTOGRAM
   1216     if (verbosity > 1) {
   1217       /* timestamp just before we go into recv and then again just
   1218 	 after we come out raj 8/94 */
   1219       /* but only if we are actually going to display a histogram. raj
   1220 	 2006-02-07 */
   1221       HIST_timestamp(&time_one);
   1222     }
   1223 #endif /* WANT_HISTOGRAM */
   1224 
   1225     while ((!times_up) && (len=recv(recv_socket,
   1226 				    recv_ring->buffer_ptr,
   1227 				    recv_size,
   1228 				    0)) > 0 ) {
   1229 
   1230 #ifdef WANT_HISTOGRAM
   1231       if (verbosity > 1) {
   1232 	/* timestamp the exit from the recv call and update the histogram */
   1233 	HIST_timestamp(&time_two);
   1234 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   1235       }
   1236 #endif /* WANT_HISTOGRAM */
   1237 
   1238 #ifdef DIRTY
   1239       access_buffer(recv_ring->buffer_ptr,
   1240 		    recv_size,
   1241 		    loc_dirty_count,
   1242 		    loc_clean_count);
   1243 #endif /* DIRTY */
   1244 
   1245 #ifdef WANT_DEMO
   1246       DEMO_STREAM_INTERVAL(len);
   1247 #endif
   1248 
   1249 #ifdef WANT_INTERVALS
   1250       INTERVALS_WAIT();
   1251 #endif /* WANT_INTERVALS */
   1252 
   1253       /* now we want to move our pointer to the next position in the */
   1254       /* data buffer...we may also want to wrap back to the "beginning" */
   1255       /* of the bufferspace, so we will mod the number of messages sent */
   1256       /* by the recv width, and use that to calculate the offset to add */
   1257       /* to the base pointer. */
   1258       nummessages++;
   1259       recv_ring = recv_ring->next;
   1260       if (bytes_remaining) {
   1261 	bytes_remaining -= len;
   1262       }
   1263 
   1264       local_bytes_recvd += len;
   1265 
   1266 #ifdef WANT_HISTOGRAM
   1267       if (verbosity > 1) {
   1268 	/* make sure we timestamp just before we go into recv  */
   1269 	/* raj 2004-06-15 */
   1270 	HIST_timestamp(&time_one);
   1271       }
   1272 #endif /* WANT_HISTOGRAM */
   1273 
   1274     }
   1275 
   1276     /* an EINTR is to be expected when this is a no_control test */
   1277     if (((len < 0) || SOCKET_EINTR(len)) && (!no_control)) {
   1278       perror("send_sdp_maerts: data recv error");
   1279       printf("len was %d\n",len);
   1280       exit(1);
   1281     }
   1282 
   1283     /* if we get here, it must mean we had a recv return of 0 before
   1284        the watchdog timer expired, or the watchdog timer expired and
   1285        this was a no_control test */
   1286 
   1287     /* The test is over. Flush the buffers to the remote end. We do a
   1288        graceful release to tell the  remote we have all the data. */
   1289 
   1290     /* but first, if the verbosity is greater than 1, find-out what */
   1291     /* the SDP maximum segment_size was (if possible) */
   1292     if (verbosity > 1) {
   1293       sdp_mss = -1;
   1294       get_sdp_info(recv_socket,&sdp_mss);
   1295     }
   1296 
   1297     if (shutdown(recv_socket,SHUT_WR) == SOCKET_ERROR) {
   1298       perror("netperf: cannot shutdown sdp maerts socket");
   1299       exit(1);
   1300     }
   1301 
   1302     stop_timer();
   1303 
   1304     /* this call will always give us the local elapsed time for the
   1305        test, and will also store-away the necessaries for cpu
   1306        utilization */
   1307 
   1308     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
   1309 						/* measured and how */
   1310 						/* long did we really */
   1311 						/* run? */
   1312 
   1313     /* we are finished with the socket, so close it to prevent hitting */
   1314     /* the limit on maximum open files. */
   1315 
   1316     close(recv_socket);
   1317 
   1318     if (!no_control) {
   1319       /* Get the statistics from the remote end. The remote will have
   1320          calculated service demand and all those interesting
   1321          things. If it wasn't supposed to care, it will return obvious
   1322          values. */
   1323 
   1324       recv_response();
   1325       if (!netperf_response.content.serv_errno) {
   1326 	if (debug)
   1327 	  fprintf(where,"remote results obtained\n");
   1328       }
   1329       else {
   1330 	Set_errno(netperf_response.content.serv_errno);
   1331 	fprintf(where,
   1332 		"netperf: remote error %d",
   1333 		netperf_response.content.serv_errno);
   1334 	perror("");
   1335 	fflush(where);
   1336 
   1337 	exit(1);
   1338       }
   1339 
   1340       /* We now calculate what our thruput was for the test. In the
   1341 	 future, we may want to include a calculation of the thruput
   1342 	 measured by the remote, but it should be the case that for a
   1343 	 SDP maerts test, that the two numbers should be *very*
   1344 	 close... We calculate bytes_sent regardless of the way the
   1345 	 test length was controlled.  If it was time, we needed to,
   1346 	 and if it was by bytes, the user may have specified a number
   1347 	 of bytes that wasn't a multiple of the recv_size, so we
   1348 	 really didn't recv what he asked for ;-) */
   1349 
   1350       bytes_sent	= ntohd(sdp_maerts_result->bytes_sent);
   1351     }
   1352     else {
   1353       bytes_sent = (double)local_bytes_recvd;
   1354     }
   1355 
   1356 
   1357     thruput	= calc_thruput(bytes_sent);
   1358 
   1359     if (local_cpu_usage || remote_cpu_usage) {
   1360       /* We must now do a little math for service demand and cpu */
   1361       /* utilization for the system(s) */
   1362       /* Of course, some of the information might be bogus because */
   1363       /* there was no idle counter in the kernel(s). We need to make */
   1364       /* a note of this for the user's benefit...*/
   1365       if (local_cpu_usage) {
   1366 
   1367 	local_cpu_utilization	= calc_cpu_util(0.0);
   1368 	local_service_demand	= calc_service_demand(bytes_sent,
   1369 						      0.0,
   1370 						      0.0,
   1371 						      0);
   1372       }
   1373       else {
   1374 	local_cpu_utilization	= (float) -1.0;
   1375 	local_service_demand	= (float) -1.0;
   1376       }
   1377 
   1378       if (remote_cpu_usage) {
   1379 
   1380 	remote_cpu_utilization	= sdp_maerts_result->cpu_util;
   1381 	remote_service_demand	= calc_service_demand(bytes_sent,
   1382 						      0.0,
   1383 						      remote_cpu_utilization,
   1384 						      sdp_maerts_result->num_cpus);
   1385       }
   1386       else {
   1387 	remote_cpu_utilization = (float) -1.0;
   1388 	remote_service_demand  = (float) -1.0;
   1389       }
   1390     }
   1391     else {
   1392       /* we were not measuring cpu, for the confidence stuff, we */
   1393       /* should make it -1.0 */
   1394       local_cpu_utilization	= (float) -1.0;
   1395       local_service_demand	= (float) -1.0;
   1396       remote_cpu_utilization = (float) -1.0;
   1397       remote_service_demand  = (float) -1.0;
   1398     }
   1399 
   1400     /* at this point, we want to calculate the confidence information. */
   1401     /* if debugging is on, calculate_confidence will print-out the */
   1402     /* parameters we pass it */
   1403 
   1404     calculate_confidence(confidence_iteration,
   1405 			 elapsed_time,
   1406 			 thruput,
   1407 			 local_cpu_utilization,
   1408 			 remote_cpu_utilization,
   1409 			 local_service_demand,
   1410 			 remote_service_demand);
   1411 
   1412 
   1413     confidence_iteration++;
   1414   }
   1415 
   1416   /* at this point, we have finished making all the runs that we */
   1417   /* will be making. so, we should extract what the calcuated values */
   1418   /* are for all the confidence stuff. we could make the values */
   1419   /* global, but that seemed a little messy, and it did not seem worth */
   1420   /* all the mucking with header files. so, we create a routine much */
   1421   /* like calcualte_confidence, which just returns the mean values. */
   1422   /* raj 11/94 */
   1423 
   1424   retrieve_confident_values(&elapsed_time,
   1425 			    &thruput,
   1426 			    &local_cpu_utilization,
   1427 			    &remote_cpu_utilization,
   1428 			    &local_service_demand,
   1429 			    &remote_service_demand);
   1430 
   1431   /* We are now ready to print all the information. If the user */
   1432   /* has specified zero-level verbosity, we will just print the */
   1433   /* local service demand, or the remote service demand. If the */
   1434   /* user has requested verbosity level 1, he will get the basic */
   1435   /* "streamperf" numbers. If the user has specified a verbosity */
   1436   /* of greater than 1, we will display a veritable plethora of */
   1437   /* background information from outside of this block as it it */
   1438   /* not cpu_measurement specific...  */
   1439 
   1440   if (confidence < 0) {
   1441     /* we did not hit confidence, but were we asked to look for it? */
   1442     if (iteration_max > 1) {
   1443       display_confidence();
   1444     }
   1445   }
   1446 
   1447   if (local_cpu_usage || remote_cpu_usage) {
   1448     local_cpu_method = format_cpu_method(cpu_method);
   1449     remote_cpu_method = format_cpu_method(sdp_maerts_result->cpu_method);
   1450 
   1451     switch (verbosity) {
   1452     case 0:
   1453       if (local_cpu_usage) {
   1454 	fprintf(where,
   1455 		cpu_fmt_0,
   1456 		local_service_demand,
   1457 		local_cpu_method,
   1458 		((print_headers) ||
   1459 		 (result_brand == NULL)) ? "" : result_brand);
   1460       }
   1461       else {
   1462 	fprintf(where,
   1463 		cpu_fmt_0,
   1464 		remote_service_demand,
   1465 		remote_cpu_method,
   1466 		((print_headers) ||
   1467 		 (result_brand == NULL)) ? "" : result_brand);
   1468       }
   1469       break;
   1470     case 1:
   1471     case 2:
   1472       if (print_headers) {
   1473 	fprintf(where,
   1474 		cpu_title,
   1475 		format_units(),
   1476 		local_cpu_method,
   1477 		remote_cpu_method);
   1478       }
   1479 
   1480       fprintf(where,
   1481 	      cpu_fmt_1,		/* the format string */
   1482 	      rsr_size,		        /* remote recvbuf size */
   1483 	      lss_size,		        /* local sendbuf size */
   1484 	      send_size,		/* how large were the recvs */
   1485 	      elapsed_time,		/* how long was the test */
   1486 	      thruput, 		        /* what was the xfer rate */
   1487 	      local_cpu_utilization,	/* local cpu */
   1488 	      remote_cpu_utilization,	/* remote cpu */
   1489 	      local_service_demand,	/* local service demand */
   1490 	      remote_service_demand,	/* remote service demand */
   1491 	      ((print_headers) ||
   1492 	       (result_brand == NULL)) ? "" : result_brand);
   1493       break;
   1494     }
   1495   }
   1496   else {
   1497     /* The tester did not wish to measure service demand. */
   1498 
   1499     switch (verbosity) {
   1500     case 0:
   1501       fprintf(where,
   1502 	      tput_fmt_0,
   1503 	      thruput,
   1504 	      ((print_headers) ||
   1505 	       (result_brand == NULL)) ? "" : result_brand);
   1506       break;
   1507     case 1:
   1508     case 2:
   1509       if (print_headers) {
   1510 	fprintf(where,tput_title,format_units());
   1511       }
   1512       fprintf(where,
   1513 	      tput_fmt_1,		/* the format string */
   1514 	      lsr_size, 		/* local recvbuf size */
   1515 	      rss_size, 		/* remot sendbuf size */
   1516 	      send_size,		/* how large were the recvs */
   1517 	      elapsed_time, 		/* how long did it take */
   1518 	      thruput,                  /* how fast did it go */
   1519 	      ((print_headers) ||
   1520 	       (result_brand == NULL)) ? "" : result_brand);
   1521       break;
   1522     }
   1523   }
   1524 
   1525   /* it would be a good thing to include information about some of the */
   1526   /* other parameters that may have been set for this test, but at the */
   1527   /* moment, I do not wish to figure-out all the  formatting, so I will */
   1528   /* just put this comment here to help remind me that it is something */
   1529   /* that should be done at a later time. */
   1530 
   1531   if (verbosity > 1) {
   1532     /* The user wanted to know it all, so we will give it to him. */
   1533     /* This information will include as much as we can find about */
   1534     /* SDP statistics, the alignments of the sends and receives */
   1535     /* and all that sort of rot... */
   1536 
   1537     /* this stuff needs to be worked-out in the presence of confidence */
   1538     /* intervals and multiple iterations of the test... raj 11/94 */
   1539 
   1540     fprintf(where,
   1541 	    ksink_fmt,
   1542 	    "Bytes",
   1543 	    "Bytes",
   1544 	    "Bytes",
   1545 	    local_recv_align,
   1546 	    remote_recv_align,
   1547 	    local_recv_offset,
   1548 	    remote_recv_offset,
   1549 	    bytes_sent,
   1550 	    bytes_sent / (double)nummessages,
   1551 	    nummessages,
   1552 	    bytes_sent / (double)sdp_maerts_result->send_calls,
   1553 	    sdp_maerts_result->send_calls);
   1554     fprintf(where,
   1555 	    ksink_fmt2,
   1556 	    sdp_mss);
   1557     fflush(where);
   1558 #ifdef WANT_HISTOGRAM
   1559     fprintf(where,"\n\nHistogram of time spent in recv() call.\n");
   1560     fflush(where);
   1561     HIST_report(time_hist);
   1562 #endif /* WANT_HISTOGRAM */
   1563   }
   1564 
   1565 }
   1566 /* This is the server-side routine for the sdp stream test. It is */
   1567 /* implemented as one routine. I could break things-out somewhat, but */
   1568 /* didn't feel it was necessary. */
   1569 
   1570 void
   1571 recv_sdp_stream()
   1572 {
   1573 
   1574   struct sockaddr_in myaddr_in, peeraddr_in;
   1575   SOCKET s_listen,s_data;
   1576   netperf_socklen_t addrlen;
   1577   int	len;
   1578   unsigned int	receive_calls;
   1579   float	elapsed_time;
   1580   double   bytes_received;
   1581 
   1582   struct ring_elt *recv_ring;
   1583 
   1584   struct addrinfo *local_res;
   1585   char local_name[BUFSIZ];
   1586   char port_buffer[PORTBUFSIZE];
   1587 
   1588 #ifdef DO_SELECT
   1589   fd_set readfds;
   1590   struct timeval timeout;
   1591 #endif /* DO_SELECT */
   1592 
   1593   struct	sdp_stream_request_struct	*sdp_stream_request;
   1594   struct	sdp_stream_response_struct	*sdp_stream_response;
   1595   struct	sdp_stream_results_struct	*sdp_stream_results;
   1596 
   1597 #ifdef DO_SELECT
   1598   FD_ZERO(&readfds);
   1599   timeout.tv_sec = 1;
   1600   timeout.tv_usec = 0;
   1601 #endif /* DO_SELECT */
   1602 
   1603   sdp_stream_request	=
   1604     (struct sdp_stream_request_struct *)netperf_request.content.test_specific_data;
   1605   sdp_stream_response	=
   1606     (struct sdp_stream_response_struct *)netperf_response.content.test_specific_data;
   1607   sdp_stream_results	=
   1608     (struct sdp_stream_results_struct *)netperf_response.content.test_specific_data;
   1609 
   1610   if (debug) {
   1611     fprintf(where,"netserver: recv_sdp_stream: entered...\n");
   1612     fflush(where);
   1613   }
   1614 
   1615   /* We want to set-up the listen socket with all the desired */
   1616   /* parameters and then let the initiator know that all is ready. If */
   1617   /* socket size defaults are to be used, then the initiator will have */
   1618   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   1619   /* send-back what they are. If that information cannot be determined, */
   1620   /* then we send-back -1's for the sizes. If things go wrong for any */
   1621   /* reason, we will drop back ten yards and punt. */
   1622 
   1623   /* If anything goes wrong, we want the remote to know about it. It */
   1624   /* would be best if the error that the remote reports to the user is */
   1625   /* the actual error we encountered, rather than some bogus unexpected */
   1626   /* response type message. */
   1627 
   1628   if (debug) {
   1629     fprintf(where,"recv_sdp_stream: setting the response type...\n");
   1630     fflush(where);
   1631   }
   1632 
   1633   netperf_response.content.response_type = SDP_STREAM_RESPONSE;
   1634 
   1635   if (debug) {
   1636     fprintf(where,"recv_sdp_stream: the response type is set...\n");
   1637     fflush(where);
   1638   }
   1639 
   1640   /* We now alter the message_ptr variable to be at the desired */
   1641   /* alignment with the desired offset. */
   1642 
   1643   if (debug) {
   1644     fprintf(where,"recv_sdp_stream: requested alignment of %d\n",
   1645 	    sdp_stream_request->recv_alignment);
   1646     fflush(where);
   1647   }
   1648 
   1649   /* create_data_socket expects to find some things in the global */
   1650   /* variables, so set the globals based on the values in the request. */
   1651   /* once the socket has been created, we will set the response values */
   1652   /* based on the updated value of those globals. raj 7/94 */
   1653   lss_size_req = sdp_stream_request->send_buf_size;
   1654   lsr_size_req = sdp_stream_request->recv_buf_size;
   1655   loc_nodelay  = sdp_stream_request->no_delay;
   1656   loc_rcvavoid = sdp_stream_request->so_rcvavoid;
   1657   loc_sndavoid = sdp_stream_request->so_sndavoid;
   1658 
   1659   set_hostname_and_port(local_name,
   1660 			port_buffer,
   1661 			nf_to_af(sdp_stream_request->ipfamily),
   1662 			sdp_stream_request->port);
   1663 
   1664   local_res = complete_addrinfo(local_name,
   1665 				local_name,
   1666 				port_buffer,
   1667 				nf_to_af(sdp_stream_request->ipfamily),
   1668 				SOCK_STREAM,
   1669 				IPPROTO_TCP,
   1670 				0);
   1671 
   1672   /* fake things out by changing local_res->ai_family to AF_INET_SDP */
   1673   local_res->ai_family = AF_INET_SDP;
   1674   local_res->ai_protocol = 0;
   1675   s_listen = create_data_socket(local_res);
   1676 
   1677   if (s_listen == INVALID_SOCKET) {
   1678     netperf_response.content.serv_errno = errno;
   1679     send_response();
   1680     exit(1);
   1681   }
   1682 
   1683 #ifdef WIN32
   1684   /* The test timer can fire during operations on the listening socket,
   1685      so to make the start_timer below work we have to move
   1686      it to close s_listen while we are blocked on accept. */
   1687   win_kludge_socket2 = s_listen;
   1688 #endif
   1689 
   1690   /* what sort of sizes did we end-up with? */
   1691   if (sdp_stream_request->receive_size == 0) {
   1692     if (lsr_size > 0) {
   1693       recv_size = lsr_size;
   1694     }
   1695     else {
   1696       recv_size = 4096;
   1697     }
   1698   }
   1699   else {
   1700     recv_size = sdp_stream_request->receive_size;
   1701   }
   1702 
   1703   /* we want to set-up our recv_ring in a manner analagous to what we */
   1704   /* do on the sending side. this is more for the sake of symmetry */
   1705   /* than for the needs of say copy avoidance, but it might also be */
   1706   /* more realistic - this way one could conceivably go with a */
   1707   /* double-buffering scheme when taking the data an putting it into */
   1708   /* the filesystem or something like that. raj 7/94 */
   1709 
   1710   if (recv_width == 0) {
   1711     recv_width = (lsr_size/recv_size) + 1;
   1712     if (recv_width == 1) recv_width++;
   1713   }
   1714 
   1715   recv_ring = allocate_buffer_ring(recv_width,
   1716 				   recv_size,
   1717 				   sdp_stream_request->recv_alignment,
   1718 				   sdp_stream_request->recv_offset);
   1719 
   1720   if (debug) {
   1721     fprintf(where,"recv_sdp_stream: receive alignment and offset set...\n");
   1722     fflush(where);
   1723   }
   1724 
   1725   /* Now, let's set-up the socket to listen for connections */
   1726   if (listen(s_listen, 5) == SOCKET_ERROR) {
   1727     netperf_response.content.serv_errno = errno;
   1728     close(s_listen);
   1729     send_response();
   1730 
   1731     exit(1);
   1732   }
   1733 
   1734 
   1735   /* now get the port number assigned by the system  */
   1736   addrlen = sizeof(myaddr_in);
   1737   if (getsockname(s_listen,
   1738 		  (struct sockaddr *)&myaddr_in,
   1739 		  &addrlen) == SOCKET_ERROR){
   1740     netperf_response.content.serv_errno = errno;
   1741     close(s_listen);
   1742     send_response();
   1743 
   1744     exit(1);
   1745   }
   1746 
   1747   /* Now myaddr_in contains the port and the internet address this is */
   1748   /* returned to the sender also implicitly telling the sender that the */
   1749   /* socket buffer sizing has been done. */
   1750 
   1751   sdp_stream_response->data_port_number = (int) ntohs(myaddr_in.sin_port);
   1752   netperf_response.content.serv_errno   = 0;
   1753 
   1754   /* But wait, there's more. If the initiator wanted cpu measurements, */
   1755   /* then we must call the calibrate routine, which will return the max */
   1756   /* rate back to the initiator. If the CPU was not to be measured, or */
   1757   /* something went wrong with the calibration, we will return a -1 to */
   1758   /* the initiator. */
   1759 
   1760   sdp_stream_response->cpu_rate = (float)0.0; 	/* assume no cpu */
   1761   if (sdp_stream_request->measure_cpu) {
   1762     sdp_stream_response->measure_cpu = 1;
   1763     sdp_stream_response->cpu_rate =
   1764       calibrate_local_cpu(sdp_stream_request->cpu_rate);
   1765   }
   1766   else {
   1767     sdp_stream_response->measure_cpu = 0;
   1768   }
   1769 
   1770   /* before we send the response back to the initiator, pull some of */
   1771   /* the socket parms from the globals */
   1772   sdp_stream_response->send_buf_size = lss_size;
   1773   sdp_stream_response->recv_buf_size = lsr_size;
   1774   sdp_stream_response->no_delay = loc_nodelay;
   1775   sdp_stream_response->so_rcvavoid = loc_rcvavoid;
   1776   sdp_stream_response->so_sndavoid = loc_sndavoid;
   1777   sdp_stream_response->receive_size = recv_size;
   1778 
   1779   send_response();
   1780 
   1781   addrlen = sizeof(peeraddr_in);
   1782 
   1783   if ((s_data=accept(s_listen,
   1784 		     (struct sockaddr *)&peeraddr_in,
   1785 		     &addrlen)) == INVALID_SOCKET) {
   1786     /* Let's just punt. The remote will be given some information */
   1787     close(s_listen);
   1788     exit(1);
   1789   }
   1790 
   1791 #ifdef KLUDGE_SOCKET_OPTIONS
   1792   /* this is for those systems which *INCORRECTLY* fail to pass */
   1793   /* attributes across an accept() call. Including this goes against */
   1794   /* my better judgement :( raj 11/95 */
   1795 
   1796   kludge_socket_options(s_data);
   1797 
   1798 #endif /* KLUDGE_SOCKET_OPTIONS */
   1799 
   1800   /* Now it's time to start receiving data on the connection. We will */
   1801   /* first grab the apropriate counters and then start grabbing. */
   1802 
   1803   cpu_start(sdp_stream_request->measure_cpu);
   1804 
   1805   /* The loop will exit when the sender does a shutdown, which will */
   1806   /* return a length of zero   */
   1807 
   1808   /* there used to be an #ifdef DIRTY call to access_buffer() here,
   1809      but we have switched from accessing the buffer before the recv()
   1810      call to accessing the buffer after the recv() call.  The
   1811      accessing before was, IIRC, related to having dirty data when
   1812      doing page-flipping copy avoidance. */
   1813 
   1814   bytes_received = 0;
   1815   receive_calls  = 0;
   1816 
   1817   while ((len = recv(s_data, recv_ring->buffer_ptr, recv_size, 0)) != 0) {
   1818     if (len == SOCKET_ERROR )
   1819 	{
   1820       netperf_response.content.serv_errno = errno;
   1821       send_response();
   1822       exit(1);
   1823     }
   1824     bytes_received += len;
   1825     receive_calls++;
   1826 
   1827 #ifdef DIRTY
   1828     /* we access the buffer after the recv() call now, rather than before */
   1829     access_buffer(recv_ring->buffer_ptr,
   1830 		  recv_size,
   1831 		  sdp_stream_request->dirty_count,
   1832 		  sdp_stream_request->clean_count);
   1833 #endif /* DIRTY */
   1834 
   1835 
   1836     /* move to the next buffer in the recv_ring */
   1837     recv_ring = recv_ring->next;
   1838 
   1839 #ifdef PAUSE
   1840     sleep(1);
   1841 #endif /* PAUSE */
   1842 
   1843 #ifdef DO_SELECT
   1844 	FD_SET(s_data,&readfds);
   1845 	select(s_data+1,&readfds,NULL,NULL,&timeout);
   1846 #endif /* DO_SELECT */
   1847 
   1848   }
   1849 
   1850   /* perform a shutdown to signal the sender that */
   1851   /* we have received all the data sent. raj 4/93 */
   1852 
   1853   if (shutdown(s_data,SHUT_WR) == SOCKET_ERROR) {
   1854       netperf_response.content.serv_errno = errno;
   1855       send_response();
   1856       exit(1);
   1857     }
   1858 
   1859   cpu_stop(sdp_stream_request->measure_cpu,&elapsed_time);
   1860 
   1861   /* send the results to the sender			*/
   1862 
   1863   if (debug) {
   1864     fprintf(where,
   1865 	    "recv_sdp_stream: got %g bytes\n",
   1866 	    bytes_received);
   1867     fprintf(where,
   1868 	    "recv_sdp_stream: got %d recvs\n",
   1869 	    receive_calls);
   1870     fflush(where);
   1871   }
   1872 
   1873   sdp_stream_results->bytes_received	= htond(bytes_received);
   1874   sdp_stream_results->elapsed_time	= elapsed_time;
   1875   sdp_stream_results->recv_calls	= receive_calls;
   1876 
   1877   sdp_stream_results->cpu_method = cpu_method;
   1878   sdp_stream_results->num_cpus   = lib_num_loc_cpus;
   1879 
   1880   if (sdp_stream_request->measure_cpu) {
   1881     sdp_stream_results->cpu_util	= calc_cpu_util(0.0);
   1882   };
   1883 
   1884   if (debug) {
   1885     fprintf(where,
   1886 	    "recv_sdp_stream: test complete, sending results.\n");
   1887     fprintf(where,
   1888 	    "                 bytes_received %g receive_calls %d\n",
   1889 	    bytes_received,
   1890 	    receive_calls);
   1891     fprintf(where,
   1892 	    "                 len %d\n",
   1893 	    len);
   1894     fflush(where);
   1895   }
   1896 
   1897   send_response();
   1898 
   1899   /* we are now done with the sockets */
   1900   close(s_data);
   1901   close(s_listen);
   1902 
   1903   }
   1904 
   1905 /* This is the server-side routine for the sdp maerts test. It is
   1907    implemented as one routine. I could break things-out somewhat, but
   1908    didn't feel it was necessary. */
   1909 
   1910 void
   1911 recv_sdp_maerts()
   1912 {
   1913 
   1914   struct sockaddr_in myaddr_in, peeraddr_in;
   1915   struct addrinfo *local_res;
   1916   char  local_name[BUFSIZ];
   1917   char  port_buffer[PORTBUFSIZE];
   1918 
   1919   SOCKET	s_listen,s_data;
   1920   netperf_socklen_t 	addrlen;
   1921   int	len;
   1922   unsigned int	send_calls;
   1923   float	elapsed_time;
   1924   double   bytes_sent = 0.0 ;
   1925 
   1926   struct ring_elt *send_ring;
   1927 
   1928   struct	sdp_maerts_request_struct	*sdp_maerts_request;
   1929   struct	sdp_maerts_response_struct	*sdp_maerts_response;
   1930   struct	sdp_maerts_results_struct	*sdp_maerts_results;
   1931 
   1932   sdp_maerts_request	=
   1933     (struct sdp_maerts_request_struct *)netperf_request.content.test_specific_data;
   1934   sdp_maerts_response	=
   1935     (struct sdp_maerts_response_struct *)netperf_response.content.test_specific_data;
   1936   sdp_maerts_results	=
   1937     (struct sdp_maerts_results_struct *)netperf_response.content.test_specific_data;
   1938 
   1939   if (debug) {
   1940     fprintf(where,"netserver: recv_sdp_maerts: entered...\n");
   1941     fflush(where);
   1942   }
   1943 
   1944   /* We want to set-up the listen socket with all the desired
   1945      parameters and then let the initiator know that all is ready. If
   1946      socket size defaults are to be used, then the initiator will have
   1947      sent us 0's. If the socket sizes cannot be changed, then we will
   1948      send-back what they are. If that information cannot be
   1949      determined, then we send-back -1's for the sizes. If things go
   1950      wrong for any reason, we will drop back ten yards and punt. */
   1951 
   1952   /* If anything goes wrong, we want the remote to know about it. It
   1953      would be best if the error that the remote reports to the user is
   1954      the actual error we encountered, rather than some bogus
   1955      unexpected response type message. */
   1956 
   1957   if (debug) {
   1958     fprintf(where,"recv_sdp_maerts: setting the response type...\n");
   1959     fflush(where);
   1960   }
   1961 
   1962   netperf_response.content.response_type = SDP_MAERTS_RESPONSE;
   1963 
   1964   if (debug) {
   1965     fprintf(where,"recv_sdp_maerts: the response type is set...\n");
   1966     fflush(where);
   1967   }
   1968 
   1969   /* We now alter the message_ptr variable to be at the desired */
   1970   /* alignment with the desired offset. */
   1971 
   1972   if (debug) {
   1973     fprintf(where,"recv_sdp_maerts: requested alignment of %d\n",
   1974 	    sdp_maerts_request->send_alignment);
   1975     fflush(where);
   1976   }
   1977 
   1978   /* Grab a socket to listen on, and then listen on it. */
   1979 
   1980   if (debug) {
   1981     fprintf(where,"recv_sdp_maerts: grabbing a socket...\n");
   1982     fflush(where);
   1983   }
   1984 
   1985   /* create_data_socket expects to find some things in the global */
   1986   /* variables, so set the globals based on the values in the request. */
   1987   /* once the socket has been created, we will set the response values */
   1988   /* based on the updated value of those globals. raj 7/94 */
   1989   lss_size_req = sdp_maerts_request->send_buf_size;
   1990   lsr_size_req = sdp_maerts_request->recv_buf_size;
   1991   loc_nodelay = sdp_maerts_request->no_delay;
   1992   loc_rcvavoid = sdp_maerts_request->so_rcvavoid;
   1993   loc_sndavoid = sdp_maerts_request->so_sndavoid;
   1994 
   1995   set_hostname_and_port(local_name,
   1996 			port_buffer,
   1997 			nf_to_af(sdp_maerts_request->ipfamily),
   1998 			sdp_maerts_request->port);
   1999 
   2000   local_res = complete_addrinfo(local_name,
   2001 				local_name,
   2002 				port_buffer,
   2003 				nf_to_af(sdp_maerts_request->ipfamily),
   2004 				SOCK_STREAM,
   2005 				IPPROTO_TCP,
   2006 				0);
   2007 
   2008   /* fake things out by changing local_res->ai_family to AF_INET_SDP */
   2009   local_res->ai_family = AF_INET_SDP;
   2010   local_res->ai_protocol = 0;
   2011   s_listen = create_data_socket(local_res);
   2012 
   2013   if (s_listen == INVALID_SOCKET) {
   2014     netperf_response.content.serv_errno = errno;
   2015     send_response();
   2016     exit(1);
   2017   }
   2018 
   2019 #ifdef WIN32
   2020   /* The test timer can fire during operations on the listening socket,
   2021      so to make the start_timer below work we have to move
   2022      it to close s_listen while we are blocked on accept. */
   2023   win_kludge_socket2 = s_listen;
   2024 #endif
   2025 
   2026 
   2027   /* what sort of sizes did we end-up with? */
   2028   if (sdp_maerts_request->send_size == 0) {
   2029     if (lss_size > 0) {
   2030       send_size = lss_size;
   2031     }
   2032     else {
   2033       send_size = 4096;
   2034     }
   2035   }
   2036   else {
   2037     send_size = sdp_maerts_request->send_size;
   2038   }
   2039 
   2040   /* we want to set-up our recv_ring in a manner analagous to what we */
   2041   /* do on the recving side. this is more for the sake of symmetry */
   2042   /* than for the needs of say copy avoidance, but it might also be */
   2043   /* more realistic - this way one could conceivably go with a */
   2044   /* double-buffering scheme when taking the data an putting it into */
   2045   /* the filesystem or something like that. raj 7/94 */
   2046 
   2047   if (send_width == 0) {
   2048     send_width = (lsr_size/send_size) + 1;
   2049     if (send_width == 1) send_width++;
   2050   }
   2051 
   2052   send_ring = allocate_buffer_ring(send_width,
   2053 				   send_size,
   2054 				   sdp_maerts_request->send_alignment,
   2055 				   sdp_maerts_request->send_offset);
   2056 
   2057   if (debug) {
   2058     fprintf(where,"recv_sdp_maerts: receive alignment and offset set...\n");
   2059     fflush(where);
   2060   }
   2061 
   2062   /* Now, let's set-up the socket to listen for connections */
   2063   if (listen(s_listen, 5) == SOCKET_ERROR) {
   2064     netperf_response.content.serv_errno = errno;
   2065     close(s_listen);
   2066     send_response();
   2067 
   2068     exit(1);
   2069   }
   2070 
   2071 
   2072   /* now get the port number assigned by the system  */
   2073   addrlen = sizeof(myaddr_in);
   2074   if (getsockname(s_listen,
   2075 		  (struct sockaddr *)&myaddr_in,
   2076 		  &addrlen) == SOCKET_ERROR){
   2077     netperf_response.content.serv_errno = errno;
   2078     close(s_listen);
   2079     send_response();
   2080 
   2081     exit(1);
   2082   }
   2083 
   2084   /* Now myaddr_in contains the port and the internet address this is */
   2085   /* returned to the sender also implicitly telling the sender that the */
   2086   /* socket buffer sizing has been done. */
   2087 
   2088   sdp_maerts_response->data_port_number = (int) ntohs(myaddr_in.sin_port);
   2089   netperf_response.content.serv_errno   = 0;
   2090 
   2091   /* But wait, there's more. If the initiator wanted cpu measurements, */
   2092   /* then we must call the calibrate routine, which will return the max */
   2093   /* rate back to the initiator. If the CPU was not to be measured, or */
   2094   /* something went wrong with the calibration, we will return a -1 to */
   2095   /* the initiator. */
   2096 
   2097   sdp_maerts_response->cpu_rate = (float)0.0; 	/* assume no cpu */
   2098   if (sdp_maerts_request->measure_cpu) {
   2099     sdp_maerts_response->measure_cpu = 1;
   2100     sdp_maerts_response->cpu_rate =
   2101       calibrate_local_cpu(sdp_maerts_request->cpu_rate);
   2102   }
   2103   else {
   2104     sdp_maerts_response->measure_cpu = 0;
   2105   }
   2106 
   2107   /* before we send the response back to the initiator, pull some of */
   2108   /* the socket parms from the globals */
   2109   sdp_maerts_response->send_buf_size = lss_size;
   2110   sdp_maerts_response->recv_buf_size = lsr_size;
   2111   sdp_maerts_response->no_delay = loc_nodelay;
   2112   sdp_maerts_response->so_rcvavoid = loc_rcvavoid;
   2113   sdp_maerts_response->so_sndavoid = loc_sndavoid;
   2114   sdp_maerts_response->send_size = send_size;
   2115 
   2116   send_response();
   2117 
   2118   addrlen = sizeof(peeraddr_in);
   2119 
   2120   /* we will start the timer before the accept() to be somewhat
   2121      analagous to the starting of the timer before the connect() call
   2122      in the SDP_STREAM test. raj 2002-06-21 */
   2123 
   2124   start_timer(sdp_maerts_request->test_length);
   2125 
   2126   /* Now it's time to start receiving data on the connection. We will
   2127      first grab the apropriate counters and then start grabbing. */
   2128 
   2129   cpu_start(sdp_maerts_request->measure_cpu);
   2130 
   2131 
   2132   if ((s_data=accept(s_listen,
   2133 		     (struct sockaddr *)&peeraddr_in,
   2134 		     &addrlen)) == INVALID_SOCKET) {
   2135     /* Let's just punt. The remote will be given some information */
   2136     close(s_listen);
   2137     exit(1);
   2138   }
   2139 
   2140 #ifdef KLUDGE_SOCKET_OPTIONS
   2141 
   2142   /* this is for those systems which *INCORRECTLY* fail to pass
   2143      attributes across an accept() call. Including this goes against
   2144      my better judgement :( raj 11/95 */
   2145 
   2146   kludge_socket_options(s_data);
   2147 
   2148 #endif /* KLUDGE_SOCKET_OPTIONS */
   2149 
   2150   /* The loop will exit when the sender does a shutdown, which will */
   2151   /* return a length of zero   */
   2152 
   2153   bytes_sent = 0.0;
   2154   send_calls  = 0;
   2155 
   2156   len = 0;   /* nt-lint; len is not initialized (printf far below) if
   2157 		times_up initially true.*/
   2158   times_up = 0; /* must remember to initialize this little beauty */
   2159   while (!times_up) {
   2160 
   2161 #ifdef DIRTY
   2162     /* we want to dirty some number of consecutive integers in the buffer */
   2163     /* we are about to send. we may also want to bring some number of */
   2164     /* them cleanly into the cache. The clean ones will follow any dirty */
   2165     /* ones into the cache. */
   2166 
   2167   access_buffer(send_ring->buffer_ptr,
   2168 		send_size,
   2169 		sdp_maerts_request->dirty_count,
   2170 		sdp_maerts_request->clean_count);
   2171 
   2172 #endif /* DIRTY */
   2173 
   2174     if((len=send(s_data,
   2175 		 send_ring->buffer_ptr,
   2176 		 send_size,
   2177 		 0)) != send_size) {
   2178 		if ((len >=0) || SOCKET_EINTR(len)) {
   2179 	      /* the test was interrupted, must be the end of test */
   2180 	      break;
   2181 		}
   2182       netperf_response.content.serv_errno = errno;
   2183       send_response();
   2184       exit(1);
   2185     }
   2186 
   2187     bytes_sent += len;
   2188     send_calls++;
   2189 
   2190     /* more to the next buffer in the send_ring */
   2191     send_ring = send_ring->next;
   2192 
   2193   }
   2194 
   2195   /* perform a shutdown to signal the sender that */
   2196   /* we have received all the data sent. raj 4/93 */
   2197 
   2198   if (shutdown(s_data,SHUT_WR) == SOCKET_ERROR) {
   2199       netperf_response.content.serv_errno = errno;
   2200       send_response();
   2201       exit(1);
   2202     }
   2203 
   2204   /* hang a recv() off the socket to block until the remote has
   2205      brought all the data up into the application. it will do a
   2206      shutdown to cause a FIN to be sent our way. We will assume that
   2207      any exit from the recv() call is good... raj 4/93 */
   2208 
   2209   recv(s_data, send_ring->buffer_ptr, send_size, 0);
   2210 
   2211 
   2212   cpu_stop(sdp_maerts_request->measure_cpu,&elapsed_time);
   2213 
   2214   /* send the results to the sender			*/
   2215 
   2216   if (debug) {
   2217     fprintf(where,
   2218 	    "recv_sdp_maerts: got %g bytes\n",
   2219 	    bytes_sent);
   2220     fprintf(where,
   2221 	    "recv_sdp_maerts: got %d sends\n",
   2222 	    send_calls);
   2223     fflush(where);
   2224   }
   2225 
   2226   sdp_maerts_results->bytes_sent	= htond(bytes_sent);
   2227   sdp_maerts_results->elapsed_time	= elapsed_time;
   2228   sdp_maerts_results->send_calls	= send_calls;
   2229 
   2230   if (sdp_maerts_request->measure_cpu) {
   2231     sdp_maerts_results->cpu_util	= calc_cpu_util(0.0);
   2232   };
   2233 
   2234   if (debug) {
   2235     fprintf(where,
   2236 	    "recv_sdp_maerts: test complete, sending results.\n");
   2237     fprintf(where,
   2238 	    "                 bytes_sent %g send_calls %d\n",
   2239 	    bytes_sent,
   2240 	    send_calls);
   2241     fprintf(where,
   2242 	    "                 len %d\n",
   2243 	    len);
   2244     fflush(where);
   2245   }
   2246 
   2247   sdp_maerts_results->cpu_method = cpu_method;
   2248   sdp_maerts_results->num_cpus   = lib_num_loc_cpus;
   2249   send_response();
   2250 
   2251   /* we are now done with the sockets */
   2252   close(s_data);
   2253   close(s_listen);
   2254 
   2255   }
   2256 
   2257 
   2259  /* this routine implements the sending (netperf) side of the SDP_RR */
   2260  /* test. */
   2261 
   2262 void
   2263 send_sdp_rr(char remote_host[])
   2264 {
   2265 
   2266   char *tput_title = "\
   2267 Local /Remote\n\
   2268 Socket Size   Request  Resp.   Elapsed  Trans.\n\
   2269 Send   Recv   Size     Size    Time     Rate         \n\
   2270 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
   2271 
   2272   char *tput_fmt_0 =
   2273     "%7.2f %s\n";
   2274 
   2275   char *tput_fmt_1_line_1 = "\
   2276 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   %s\n";
   2277   char *tput_fmt_1_line_2 = "\
   2278 %-6d %-6d\n";
   2279 
   2280   char *cpu_title = "\
   2281 Local /Remote\n\
   2282 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
   2283 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
   2284 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
   2285 
   2286   char *cpu_fmt_0 =
   2287     "%6.3f %c %s\n";
   2288 
   2289   char *cpu_fmt_1_line_1 = "\
   2290 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f  %-6.2f %-6.2f %-6.3f  %-6.3f %s\n";
   2291 
   2292   char *cpu_fmt_1_line_2 = "\
   2293 %-6d %-6d\n";
   2294 
   2295   char *ksink_fmt = "\
   2296 Alignment      Offset\n\
   2297 Local  Remote  Local  Remote\n\
   2298 Send   Recv    Send   Recv\n\
   2299 %5d  %5d   %5d  %5d\n";
   2300 
   2301 
   2302   int			timed_out = 0;
   2303   float			elapsed_time;
   2304 
   2305   int	len;
   2306   char	*temp_message_ptr;
   2307   int	nummessages;
   2308   SOCKET	send_socket;
   2309   int	trans_remaining;
   2310   double	bytes_xferd;
   2311 
   2312   struct ring_elt *send_ring;
   2313   struct ring_elt *recv_ring;
   2314 
   2315   int	rsp_bytes_left;
   2316   int	rsp_bytes_recvd;
   2317 
   2318   float	local_cpu_utilization;
   2319   float	local_service_demand;
   2320   float	remote_cpu_utilization;
   2321   float	remote_service_demand;
   2322   double	thruput;
   2323 
   2324   struct addrinfo *local_res;
   2325   struct addrinfo *remote_res;
   2326 
   2327   struct	sdp_rr_request_struct	*sdp_rr_request;
   2328   struct	sdp_rr_response_struct	*sdp_rr_response;
   2329   struct	sdp_rr_results_struct	*sdp_rr_result;
   2330 
   2331 #ifdef WANT_FIRST_BURST
   2332 #define REQUEST_CWND_INITIAL 2
   2333   /* "in the beginning..." the WANT_FIRST_BURST stuff was like both
   2334      Unix and the state of New Jersey - both were simple an unspoiled.
   2335      then it was realized that some stacks are quite picky about
   2336      initial congestion windows and a non-trivial initial burst of
   2337      requests would not be individual segments even with TCP_NODELAY
   2338      set. so, we have to start tracking a poor-man's congestion window
   2339      up here in window space because we want to try to make something
   2340      happen that frankly, we cannot guarantee with the specification
   2341      of SDP.  ain't that grand?-)  raj 2006-01-30 */
   2342   int requests_outstanding = 0;
   2343   int request_cwnd = REQUEST_CWND_INITIAL;  /* we ass-u-me that having
   2344 					       three requests
   2345 					       outstanding at the
   2346 					       beginning of the test
   2347 					       is ok with SDP stacks
   2348 					       of interest. the first
   2349 					       two will come from our
   2350 					       first_burst loop, and
   2351 					       the third from our
   2352 					       regularly scheduled
   2353 					       send */
   2354 #endif
   2355 
   2356   sdp_rr_request =
   2357     (struct sdp_rr_request_struct *)netperf_request.content.test_specific_data;
   2358   sdp_rr_response=
   2359     (struct sdp_rr_response_struct *)netperf_response.content.test_specific_data;
   2360   sdp_rr_result	=
   2361     (struct sdp_rr_results_struct *)netperf_response.content.test_specific_data;
   2362 
   2363 #ifdef WANT_HISTOGRAM
   2364   if (verbosity > 1) {
   2365     time_hist = HIST_new();
   2366   }
   2367 #endif /* WANT_HISTOGRAM */
   2368 
   2369   /* since we are now disconnected from the code that established the */
   2370   /* control socket, and since we want to be able to use different */
   2371   /* protocols and such, we are passed the name of the remote host and */
   2372   /* must turn that into the test specific addressing information. */
   2373 
   2374   complete_addrinfos(&remote_res,
   2375 		     &local_res,
   2376 		     remote_host,
   2377 		     SOCK_STREAM,
   2378 		     IPPROTO_TCP,
   2379 		     0);
   2380 
   2381   if ( print_headers ) {
   2382     print_top_test_header("SDP REQUEST/RESPONSE TEST",local_res,remote_res);
   2383   }
   2384 
   2385   /* initialize a few counters */
   2386 
   2387   send_ring = NULL;
   2388   recv_ring = NULL;
   2389   confidence_iteration = 1;
   2390   init_stat();
   2391 
   2392   /* we have a great-big while loop which controls the number of times */
   2393   /* we run a particular test. this is for the calculation of a */
   2394   /* confidence interval (I really should have stayed awake during */
   2395   /* probstats :). If the user did not request confidence measurement */
   2396   /* (no confidence is the default) then we will only go though the */
   2397   /* loop once. the confidence stuff originates from the folks at IBM */
   2398 
   2399   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   2400 	 (confidence_iteration <= iteration_min)) {
   2401 
   2402     /* initialize a few counters. we have to remember that we might be */
   2403     /* going through the loop more than once. */
   2404 
   2405     nummessages     = 0;
   2406     bytes_xferd     = 0.0;
   2407     times_up        = 0;
   2408     timed_out       = 0;
   2409     trans_remaining = 0;
   2410 
   2411 #ifdef WANT_FIRST_BURST
   2412     /* we have to remember to reset the number of transactions
   2413        outstanding and the "congestion window for each new
   2414        iteration. raj 2006-01-31 */
   2415     requests_outstanding = 0;
   2416     request_cwnd = REQUEST_CWND_INITIAL;
   2417 #endif
   2418 
   2419 
   2420     /* set-up the data buffers with the requested alignment and offset. */
   2421     /* since this is a request/response test, default the send_width and */
   2422     /* recv_width to 1 and not two raj 7/94 */
   2423 
   2424     if (send_width == 0) send_width = 1;
   2425     if (recv_width == 0) recv_width = 1;
   2426 
   2427     if (send_ring == NULL) {
   2428       send_ring = allocate_buffer_ring(send_width,
   2429 				       req_size,
   2430 				       local_send_align,
   2431 				       local_send_offset);
   2432     }
   2433 
   2434     if (recv_ring == NULL) {
   2435       recv_ring = allocate_buffer_ring(recv_width,
   2436 				       rsp_size,
   2437 				       local_recv_align,
   2438 				       local_recv_offset);
   2439     }
   2440 
   2441     /*set up the data socket                        */
   2442     /* fake things out by changing local_res->ai_family to AF_INET_SDP */
   2443     local_res->ai_family = AF_INET_SDP;
   2444     local_res->ai_protocol = 0;
   2445     send_socket = create_data_socket(local_res);
   2446 
   2447     if (send_socket == INVALID_SOCKET){
   2448       perror("netperf: send_sdp_rr: sdp stream data socket");
   2449       exit(1);
   2450     }
   2451 
   2452     if (debug) {
   2453       fprintf(where,"send_sdp_rr: send_socket obtained...\n");
   2454     }
   2455 
   2456     /* If the user has requested cpu utilization measurements, we must */
   2457     /* calibrate the cpu(s). We will perform this task within the tests */
   2458     /* themselves. If the user has specified the cpu rate, then */
   2459     /* calibrate_local_cpu will return rather quickly as it will have */
   2460     /* nothing to do. If local_cpu_rate is zero, then we will go through */
   2461     /* all the "normal" calibration stuff and return the rate back.*/
   2462 
   2463     if (local_cpu_usage) {
   2464       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   2465     }
   2466 
   2467     if (!no_control) {
   2468       /* Tell the remote end to do a listen. The server alters the
   2469 	 socket paramters on the other side at this point, hence the
   2470 	 reason for all the values being passed in the setup
   2471 	 message. If the user did not specify any of the parameters,
   2472 	 they will be passed as 0, which will indicate to the remote
   2473 	 that no changes beyond the system's default should be
   2474 	 used. Alignment is the exception, it will default to 8, which
   2475 	 will be no alignment alterations. */
   2476 
   2477       netperf_request.content.request_type	=	DO_SDP_RR;
   2478       sdp_rr_request->recv_buf_size	=	rsr_size_req;
   2479       sdp_rr_request->send_buf_size	=	rss_size_req;
   2480       sdp_rr_request->recv_alignment    =	remote_recv_align;
   2481       sdp_rr_request->recv_offset	=	remote_recv_offset;
   2482       sdp_rr_request->send_alignment    =	remote_send_align;
   2483       sdp_rr_request->send_offset	=	remote_send_offset;
   2484       sdp_rr_request->request_size	=	req_size;
   2485       sdp_rr_request->response_size	=	rsp_size;
   2486       sdp_rr_request->no_delay	        =	rem_nodelay;
   2487       sdp_rr_request->measure_cpu	=	remote_cpu_usage;
   2488       sdp_rr_request->cpu_rate	        =	remote_cpu_rate;
   2489       sdp_rr_request->so_rcvavoid	=	rem_rcvavoid;
   2490       sdp_rr_request->so_sndavoid	=	rem_sndavoid;
   2491       if (test_time) {
   2492 	sdp_rr_request->test_length	=	test_time;
   2493       }
   2494       else {
   2495 	sdp_rr_request->test_length	=	test_trans * -1;
   2496       }
   2497       sdp_rr_request->port              =      atoi(remote_data_port);
   2498       sdp_rr_request->ipfamily = af_to_nf(remote_res->ai_family);
   2499 
   2500       if (debug > 1) {
   2501 	fprintf(where,"netperf: send_sdp_rr: requesting SDP rr test\n");
   2502       }
   2503 
   2504       send_request();
   2505 
   2506       /* The response from the remote will contain all of the relevant
   2507 	 socket parameters for this test type. We will put them back
   2508 	 into the variables here so they can be displayed if desired.
   2509 	 The remote will have calibrated CPU if necessary, and will
   2510 	 have done all the needed set-up we will have calibrated the
   2511 	 cpu locally before sending the request, and will grab the
   2512 	 counter value right after the connect returns. The remote
   2513 	 will grab the counter right after the accept call. This saves
   2514 	 the hassle of extra messages being sent for the SDP
   2515 	 tests.  */
   2516 
   2517       recv_response();
   2518 
   2519       if (!netperf_response.content.serv_errno) {
   2520 	if (debug)
   2521 	  fprintf(where,"remote listen done.\n");
   2522 	rsr_size          = sdp_rr_response->recv_buf_size;
   2523 	rss_size          = sdp_rr_response->send_buf_size;
   2524 	rem_nodelay       = sdp_rr_response->no_delay;
   2525 	remote_cpu_usage  = sdp_rr_response->measure_cpu;
   2526 	remote_cpu_rate   = sdp_rr_response->cpu_rate;
   2527 	/* make sure that port numbers are in network order */
   2528 	set_port_number(remote_res,(short)sdp_rr_response->data_port_number);
   2529       }
   2530       else {
   2531 	Set_errno(netperf_response.content.serv_errno);
   2532 	fprintf(where,
   2533 		"netperf: remote error %d",
   2534 		netperf_response.content.serv_errno);
   2535 	perror("");
   2536 	fflush(where);
   2537 
   2538 	exit(1);
   2539       }
   2540     }
   2541 
   2542 #ifdef WANT_DEMO
   2543     DEMO_RR_SETUP(1000)
   2544 #endif
   2545 
   2546     /*Connect up to the remote port on the data socket  */
   2547     if (connect(send_socket,
   2548 		remote_res->ai_addr,
   2549 		remote_res->ai_addrlen) == INVALID_SOCKET){
   2550       perror("netperf: data socket connect failed");
   2551 
   2552       exit(1);
   2553     }
   2554 
   2555     /* Data Socket set-up is finished. If there were problems, either the */
   2556     /* connect would have failed, or the previous response would have */
   2557     /* indicated a problem. I failed to see the value of the extra */
   2558     /* message after the accept on the remote. If it failed, we'll see it */
   2559     /* here. If it didn't, we might as well start pumping data. */
   2560 
   2561     /* Set-up the test end conditions. For a request/response test, they */
   2562     /* can be either time or transaction based. */
   2563 
   2564     if (test_time) {
   2565       /* The user wanted to end the test after a period of time. */
   2566       times_up = 0;
   2567       trans_remaining = 0;
   2568       start_timer(test_time);
   2569     }
   2570     else {
   2571       /* The tester wanted to send a number of bytes. */
   2572       trans_remaining = test_bytes;
   2573       times_up = 1;
   2574     }
   2575 
   2576     /* The cpu_start routine will grab the current time and possibly */
   2577     /* value of the idle counter for later use in measuring cpu */
   2578     /* utilization and/or service demand and thruput. */
   2579 
   2580     cpu_start(local_cpu_usage);
   2581 
   2582 #ifdef WANT_INTERVALS
   2583     INTERVALS_INIT();
   2584 #endif /* WANT_INTERVALS */
   2585 
   2586     /* We use an "OR" to control test execution. When the test is */
   2587     /* controlled by time, the byte count check will always return false. */
   2588     /* When the test is controlled by byte count, the time test will */
   2589     /* always return false. When the test is finished, the whole */
   2590     /* expression will go false and we will stop sending data. I think I */
   2591     /* just arbitrarily decrement trans_remaining for the timed test, but */
   2592     /* will not do that just yet... One other question is whether or not */
   2593     /* the send buffer and the receive buffer should be the same buffer. */
   2594 
   2595 #ifdef WANT_DEMO
   2596       if (demo_mode) {
   2597 	HIST_timestamp(demo_one_ptr);
   2598       }
   2599 #endif
   2600 
   2601     while ((!times_up) || (trans_remaining > 0)) {
   2602       /* send the request. we assume that if we use a blocking socket, */
   2603       /* the request will be sent at one shot. */
   2604 
   2605 #ifdef WANT_FIRST_BURST
   2606       /* we can inject no more than request_cwnd, which will grow with
   2607 	 time, and no more than first_burst_size.  we don't use <= to
   2608 	 account for the "regularly scheduled" send call.  of course
   2609 	 that makes it more a "max_outstanding_ than a
   2610 	 "first_burst_size" but for now we won't fix the names. also,
   2611 	 I suspect the extra check against < first_burst_size is
   2612 	 redundant since later I expect to make sure that request_cwnd
   2613 	 can never get larger than first_burst_size, but just at the
   2614 	 moment I'm feeling like a belt and suspenders kind of
   2615 	 programmer. raj 2006-01-30 */
   2616       while ((first_burst_size > 0) &&
   2617 	     (requests_outstanding < request_cwnd) &&
   2618 	     (requests_outstanding < first_burst_size)) {
   2619 	if (debug) {
   2620 	  fprintf(where,
   2621 		  "injecting, req_outstndng %d req_cwnd %d burst %d\n",
   2622 		  requests_outstanding,
   2623 		  request_cwnd,
   2624 		  first_burst_size);
   2625 	}
   2626 	if ((len = send(send_socket,
   2627 			send_ring->buffer_ptr,
   2628 			req_size,
   2629 			0)) != req_size) {
   2630 	  /* we should never hit the end of the test in the first burst */
   2631 	  perror("send_sdp_rr: initial burst data send error");
   2632 	  exit(-1);
   2633 	}
   2634 	requests_outstanding += 1;
   2635       }
   2636 
   2637 #endif /* WANT_FIRST_BURST */
   2638 
   2639 #ifdef WANT_HISTOGRAM
   2640       if (verbosity > 1) {
   2641 	/* timestamp just before our call to send, and then again just
   2642 	   after the receive raj 8/94 */
   2643 	/* but only if we are actually going to display one. raj
   2644 	   2007-02-07 */
   2645 
   2646 	HIST_timestamp(&time_one);
   2647       }
   2648 #endif /* WANT_HISTOGRAM */
   2649 
   2650       if ((len = send(send_socket,
   2651 		      send_ring->buffer_ptr,
   2652 		      req_size,
   2653 		      0)) != req_size) {
   2654 	if (SOCKET_EINTR(len) || (errno == 0)) {
   2655 	  /* we hit the end of a */
   2656 	  /* timed test. */
   2657 	  timed_out = 1;
   2658 	  break;
   2659 	}
   2660 	perror("send_sdp_rr: data send error");
   2661 	exit(1);
   2662       }
   2663       send_ring = send_ring->next;
   2664 
   2665 #ifdef WANT_FIRST_BURST
   2666       requests_outstanding += 1;
   2667 #endif
   2668 
   2669       /* receive the response */
   2670       rsp_bytes_left = rsp_size;
   2671       temp_message_ptr  = recv_ring->buffer_ptr;
   2672       while(rsp_bytes_left > 0) {
   2673 	if((rsp_bytes_recvd=recv(send_socket,
   2674 				 temp_message_ptr,
   2675 				 rsp_bytes_left,
   2676 				 0)) == SOCKET_ERROR) {
   2677 		if ( SOCKET_EINTR(rsp_bytes_recvd) ) {
   2678 		    /* We hit the end of a timed test. */
   2679 			timed_out = 1;
   2680 			break;
   2681 		}
   2682 	  perror("send_sdp_rr: data recv error");
   2683 	  exit(1);
   2684 	}
   2685 	rsp_bytes_left -= rsp_bytes_recvd;
   2686 	temp_message_ptr  += rsp_bytes_recvd;
   2687       }
   2688       recv_ring = recv_ring->next;
   2689 
   2690 #ifdef WANT_FIRST_BURST
   2691       /* so, since we've gotten a response back, update the
   2692 	 bookkeeping accordingly.  there is one less request
   2693 	 outstanding and we can put one more out there than before. */
   2694       requests_outstanding -= 1;
   2695       if (request_cwnd < first_burst_size) {
   2696 	request_cwnd += 1;
   2697 	if (debug) {
   2698 	  fprintf(where,
   2699 		  "incr req_cwnd to %d first_burst %d reqs_outstndng %d\n",
   2700 		  request_cwnd,
   2701 		  first_burst_size,
   2702 		  requests_outstanding);
   2703 	}
   2704       }
   2705 #endif
   2706       if (timed_out) {
   2707 	/* we may have been in a nested while loop - we need */
   2708 	/* another call to break. */
   2709 	break;
   2710       }
   2711 
   2712 #ifdef WANT_HISTOGRAM
   2713       if (verbosity > 1) {
   2714 	HIST_timestamp(&time_two);
   2715 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   2716       }
   2717 #endif /* WANT_HISTOGRAM */
   2718 
   2719 #ifdef WANT_DEMO
   2720       DEMO_RR_INTERVAL(1);
   2721 #endif
   2722 
   2723 #ifdef WANT_INTERVALS
   2724       INTERVALS_WAIT();
   2725 #endif /* WANT_INTERVALS */
   2726 
   2727       nummessages++;
   2728       if (trans_remaining) {
   2729 	trans_remaining--;
   2730       }
   2731 
   2732       if (debug > 3) {
   2733 	if ((nummessages % 100) == 0) {
   2734 	  fprintf(where,
   2735 		  "Transaction %d completed\n",
   2736 		  nummessages);
   2737 	  fflush(where);
   2738 	}
   2739       }
   2740     }
   2741 
   2742     /* At this point we used to call shutdown on the data socket to be
   2743        sure all the data was delivered, but this was not germane in a
   2744        request/response test, and it was causing the tests to "hang"
   2745        when they were being controlled by time. So, I have replaced
   2746        this shutdown call with a call to close that can be found later
   2747        in the procedure. */
   2748 
   2749     /* this call will always give us the elapsed time for the test,
   2750        and will also store-away the necessaries for cpu utilization */
   2751 
   2752     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
   2753 						/* measured? how long */
   2754 						/* did we really run? */
   2755 
   2756     if (!no_control) {
   2757       /* Get the statistics from the remote end. The remote will have
   2758 	 calculated CPU utilization. If it wasn't supposed to care, it
   2759 	 will return obvious values. */
   2760 
   2761       recv_response();
   2762       if (!netperf_response.content.serv_errno) {
   2763 	if (debug)
   2764 	  fprintf(where,"remote results obtained\n");
   2765       }
   2766       else {
   2767 	Set_errno(netperf_response.content.serv_errno);
   2768 	fprintf(where,"netperf: remote error %d",
   2769 		netperf_response.content.serv_errno);
   2770 	perror("");
   2771 	fflush(where);
   2772 	exit(1);
   2773       }
   2774     }
   2775 
   2776     /* We now calculate what our throughput was for the test. */
   2777 
   2778     bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
   2779     thruput	= nummessages/elapsed_time;
   2780 
   2781     if (local_cpu_usage || remote_cpu_usage) {
   2782       /* We must now do a little math for service demand and cpu
   2783        utilization for the system(s) Of course, some of the
   2784        information might be bogus because there was no idle counter in
   2785        the kernel(s). We need to make a note of this for the user's
   2786        benefit... */
   2787       if (local_cpu_usage) {
   2788 	local_cpu_utilization = calc_cpu_util(0.0);
   2789  	/* since calc_service demand is doing ms/Kunit we will
   2790 	   multiply the number of transaction by 1024 to get "good"
   2791 	   numbers */
   2792 	local_service_demand  = calc_service_demand((double) nummessages*1024,
   2793 						    0.0,
   2794 						    0.0,
   2795 						    0);
   2796       }
   2797       else {
   2798 	local_cpu_utilization	= (float) -1.0;
   2799 	local_service_demand	= (float) -1.0;
   2800       }
   2801 
   2802       if (remote_cpu_usage) {
   2803 	remote_cpu_utilization = sdp_rr_result->cpu_util;
   2804 	/* since calc_service demand is doing ms/Kunit we will
   2805 	   multiply the number of transaction by 1024 to get "good"
   2806 	   numbers */
   2807 	remote_service_demand = calc_service_demand((double) nummessages*1024,
   2808 						    0.0,
   2809 						    remote_cpu_utilization,
   2810 						    sdp_rr_result->num_cpus);
   2811       }
   2812       else {
   2813 	remote_cpu_utilization = (float) -1.0;
   2814 	remote_service_demand  = (float) -1.0;
   2815       }
   2816 
   2817     }
   2818     else {
   2819       /* we were not measuring cpu, for the confidence stuff, we */
   2820       /* should make it -1.0 */
   2821       local_cpu_utilization	= (float) -1.0;
   2822       local_service_demand	= (float) -1.0;
   2823       remote_cpu_utilization = (float) -1.0;
   2824       remote_service_demand  = (float) -1.0;
   2825     }
   2826 
   2827     /* at this point, we want to calculate the confidence information.
   2828        if debugging is on, calculate_confidence will print-out the
   2829        parameters we pass it */
   2830 
   2831     calculate_confidence(confidence_iteration,
   2832 			 elapsed_time,
   2833 			 thruput,
   2834 			 local_cpu_utilization,
   2835 			 remote_cpu_utilization,
   2836 			 local_service_demand,
   2837 			 remote_service_demand);
   2838 
   2839 
   2840     confidence_iteration++;
   2841 
   2842     /* we are now done with the socket, so close it */
   2843     close(send_socket);
   2844 
   2845   }
   2846 
   2847   retrieve_confident_values(&elapsed_time,
   2848 			    &thruput,
   2849 			    &local_cpu_utilization,
   2850 			    &remote_cpu_utilization,
   2851 			    &local_service_demand,
   2852 			    &remote_service_demand);
   2853 
   2854   /* We are now ready to print all the information. If the user has
   2855      specified zero-level verbosity, we will just print the local
   2856      service demand, or the remote service demand. If the user has
   2857      requested verbosity level 1, he will get the basic "streamperf"
   2858      numbers. If the user has specified a verbosity of greater than 1,
   2859      we will display a veritable plethora of background information
   2860      from outside of this block as it it not cpu_measurement
   2861      specific...  */
   2862 
   2863   if (confidence < 0) {
   2864     /* we did not hit confidence, but were we asked to look for it? */
   2865     if (iteration_max > 1) {
   2866       display_confidence();
   2867     }
   2868   }
   2869 
   2870   if (local_cpu_usage || remote_cpu_usage) {
   2871     local_cpu_method = format_cpu_method(cpu_method);
   2872     remote_cpu_method = format_cpu_method(sdp_rr_result->cpu_method);
   2873 
   2874     switch (verbosity) {
   2875     case 0:
   2876       if (local_cpu_usage) {
   2877 	fprintf(where,
   2878 		cpu_fmt_0,
   2879 		local_service_demand,
   2880 		local_cpu_method,
   2881 		((print_headers) ||
   2882 		 (result_brand == NULL)) ? "" : result_brand);
   2883       }
   2884       else {
   2885 	fprintf(where,
   2886 		cpu_fmt_0,
   2887 		remote_service_demand,
   2888 		remote_cpu_method,
   2889 		((print_headers) ||
   2890 		 (result_brand == NULL)) ? "" : result_brand);
   2891       }
   2892       break;
   2893     case 1:
   2894     case 2:
   2895       if (print_headers) {
   2896 	fprintf(where,
   2897 		cpu_title,
   2898 		local_cpu_method,
   2899 		remote_cpu_method);
   2900       }
   2901 
   2902       fprintf(where,
   2903 	      cpu_fmt_1_line_1,		/* the format string */
   2904 	      lss_size,		/* local sendbuf size */
   2905 	      lsr_size,
   2906 	      req_size,		/* how large were the requests */
   2907 	      rsp_size,		/* guess */
   2908 	      elapsed_time,		/* how long was the test */
   2909 	      thruput,
   2910 	      local_cpu_utilization,	/* local cpu */
   2911 	      remote_cpu_utilization,	/* remote cpu */
   2912 	      local_service_demand,	/* local service demand */
   2913 	      remote_service_demand,	/* remote service demand */
   2914 	      ((print_headers) ||
   2915 	       (result_brand == NULL)) ? "" : result_brand);
   2916       fprintf(where,
   2917 	      cpu_fmt_1_line_2,
   2918 	      rss_size,
   2919 	      rsr_size);
   2920       break;
   2921     }
   2922   }
   2923   else {
   2924     /* The tester did not wish to measure service demand. */
   2925 
   2926     switch (verbosity) {
   2927     case 0:
   2928       fprintf(where,
   2929 	      tput_fmt_0,
   2930 	      thruput,
   2931 	      ((print_headers) ||
   2932 	       (result_brand == NULL)) ? "" : result_brand);
   2933       break;
   2934     case 1:
   2935     case 2:
   2936       if (print_headers) {
   2937 	fprintf(where,tput_title,format_units());
   2938       }
   2939 
   2940       fprintf(where,
   2941 	      tput_fmt_1_line_1,	/* the format string */
   2942 	      lss_size,
   2943 	      lsr_size,
   2944 	      req_size,		/* how large were the requests */
   2945 	      rsp_size,		/* how large were the responses */
   2946 	      elapsed_time, 		/* how long did it take */
   2947 	      thruput,
   2948 	      ((print_headers) ||
   2949 	       (result_brand == NULL)) ? "" : result_brand);
   2950       fprintf(where,
   2951 	      tput_fmt_1_line_2,
   2952 	      rss_size, 		/* remote recvbuf size */
   2953 	      rsr_size);
   2954 
   2955       break;
   2956     }
   2957   }
   2958 
   2959   /* it would be a good thing to include information about some of the */
   2960   /* other parameters that may have been set for this test, but at the */
   2961   /* moment, I do not wish to figure-out all the  formatting, so I will */
   2962   /* just put this comment here to help remind me that it is something */
   2963   /* that should be done at a later time. */
   2964 
   2965   /* how to handle the verbose information in the presence of */
   2966   /* confidence intervals is yet to be determined... raj 11/94 */
   2967   if (verbosity > 1) {
   2968     /* The user wanted to know it all, so we will give it to him. */
   2969     /* This information will include as much as we can find about */
   2970     /* SDP statistics, the alignments of the sends and receives */
   2971     /* and all that sort of rot... */
   2972 
   2973     fprintf(where,
   2974 	    ksink_fmt,
   2975 	    local_send_align,
   2976 	    remote_recv_offset,
   2977 	    local_send_offset,
   2978 	    remote_recv_offset);
   2979 
   2980 #ifdef WANT_HISTOGRAM
   2981     fprintf(where,"\nHistogram of request/response times\n");
   2982     fflush(where);
   2983     HIST_report(time_hist);
   2984 #endif /* WANT_HISTOGRAM */
   2985 
   2986   }
   2987 
   2988 }
   2989  /* this routine implements the receive (netserver) side of a SDP_RR */
   2990  /* test */
   2991 void
   2992 recv_sdp_rr()
   2993 {
   2994 
   2995   struct ring_elt *send_ring;
   2996   struct ring_elt *recv_ring;
   2997 
   2998   struct addrinfo *local_res;
   2999   char local_name[BUFSIZ];
   3000   char port_buffer[PORTBUFSIZE];
   3001 
   3002   struct	sockaddr_in        myaddr_in,
   3003   peeraddr_in;
   3004   SOCKET	s_listen,s_data;
   3005   netperf_socklen_t 	addrlen;
   3006   char	*temp_message_ptr;
   3007   int	trans_received;
   3008   int	trans_remaining;
   3009   int	bytes_sent;
   3010   int	request_bytes_recvd;
   3011   int	request_bytes_remaining;
   3012   int	timed_out = 0;
   3013   int   sock_closed = 0;
   3014   float	elapsed_time;
   3015 
   3016   struct	sdp_rr_request_struct	*sdp_rr_request;
   3017   struct	sdp_rr_response_struct	*sdp_rr_response;
   3018   struct	sdp_rr_results_struct	*sdp_rr_results;
   3019 
   3020   sdp_rr_request =
   3021     (struct sdp_rr_request_struct *)netperf_request.content.test_specific_data;
   3022   sdp_rr_response =
   3023     (struct sdp_rr_response_struct *)netperf_response.content.test_specific_data;
   3024   sdp_rr_results =
   3025     (struct sdp_rr_results_struct *)netperf_response.content.test_specific_data;
   3026 
   3027   if (debug) {
   3028     fprintf(where,"netserver: recv_sdp_rr: entered...\n");
   3029     fflush(where);
   3030   }
   3031 
   3032   /* We want to set-up the listen socket with all the desired */
   3033   /* parameters and then let the initiator know that all is ready. If */
   3034   /* socket size defaults are to be used, then the initiator will have */
   3035   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   3036   /* send-back what they are. If that information cannot be determined, */
   3037   /* then we send-back -1's for the sizes. If things go wrong for any */
   3038   /* reason, we will drop back ten yards and punt. */
   3039 
   3040   /* If anything goes wrong, we want the remote to know about it. It */
   3041   /* would be best if the error that the remote reports to the user is */
   3042   /* the actual error we encountered, rather than some bogus unexpected */
   3043   /* response type message. */
   3044 
   3045   if (debug) {
   3046     fprintf(where,"recv_sdp_rr: setting the response type...\n");
   3047     fflush(where);
   3048   }
   3049 
   3050   netperf_response.content.response_type = SDP_RR_RESPONSE;
   3051 
   3052   if (debug) {
   3053     fprintf(where,"recv_sdp_rr: the response type is set...\n");
   3054     fflush(where);
   3055   }
   3056 
   3057   /* allocate the recv and send rings with the requested alignments */
   3058   /* and offsets. raj 7/94 */
   3059   if (debug) {
   3060     fprintf(where,"recv_sdp_rr: requested recv alignment of %d offset %d\n",
   3061 	    sdp_rr_request->recv_alignment,
   3062 	    sdp_rr_request->recv_offset);
   3063     fprintf(where,"recv_sdp_rr: requested send alignment of %d offset %d\n",
   3064 	    sdp_rr_request->send_alignment,
   3065 	    sdp_rr_request->send_offset);
   3066     fflush(where);
   3067   }
   3068 
   3069   /* at some point, these need to come to us from the remote system */
   3070   if (send_width == 0) send_width = 1;
   3071   if (recv_width == 0) recv_width = 1;
   3072 
   3073   send_ring = allocate_buffer_ring(send_width,
   3074 				   sdp_rr_request->response_size,
   3075 				   sdp_rr_request->send_alignment,
   3076 				   sdp_rr_request->send_offset);
   3077 
   3078   recv_ring = allocate_buffer_ring(recv_width,
   3079 				   sdp_rr_request->request_size,
   3080 				   sdp_rr_request->recv_alignment,
   3081 				   sdp_rr_request->recv_offset);
   3082 
   3083 
   3084   /* Grab a socket to listen on, and then listen on it. */
   3085 
   3086   if (debug) {
   3087     fprintf(where,"recv_sdp_rr: grabbing a socket...\n");
   3088     fflush(where);
   3089   }
   3090 
   3091   /* create_data_socket expects to find some things in the global */
   3092   /* variables, so set the globals based on the values in the request. */
   3093   /* once the socket has been created, we will set the response values */
   3094   /* based on the updated value of those globals. raj 7/94 */
   3095   lss_size_req = sdp_rr_request->send_buf_size;
   3096   lsr_size_req = sdp_rr_request->recv_buf_size;
   3097   loc_nodelay = sdp_rr_request->no_delay;
   3098   loc_rcvavoid = sdp_rr_request->so_rcvavoid;
   3099   loc_sndavoid = sdp_rr_request->so_sndavoid;
   3100 
   3101   set_hostname_and_port(local_name,
   3102 			port_buffer,
   3103 			nf_to_af(sdp_rr_request->ipfamily),
   3104 			sdp_rr_request->port);
   3105 
   3106   local_res = complete_addrinfo(local_name,
   3107 				local_name,
   3108 				port_buffer,
   3109 				nf_to_af(sdp_rr_request->ipfamily),
   3110 				SOCK_STREAM,
   3111 				IPPROTO_TCP,
   3112 				0);
   3113 
   3114   /* fake things out by changing local_res->ai_family to AF_INET_SDP */
   3115   local_res->ai_family = AF_INET_SDP;
   3116   local_res->ai_protocol = 0;
   3117   s_listen = create_data_socket(local_res);
   3118 
   3119   if (s_listen == INVALID_SOCKET) {
   3120     netperf_response.content.serv_errno = errno;
   3121     send_response();
   3122 
   3123     exit(1);
   3124   }
   3125 
   3126 
   3127 #ifdef WIN32
   3128   /* The test timer can fire during operations on the listening socket,
   3129      so to make the start_timer below work we have to move
   3130      it to close s_listen while we are blocked on accept. */
   3131   win_kludge_socket2 = s_listen;
   3132 #endif
   3133 
   3134 
   3135   /* Now, let's set-up the socket to listen for connections */
   3136   if (listen(s_listen, 5) == SOCKET_ERROR) {
   3137     netperf_response.content.serv_errno = errno;
   3138     close(s_listen);
   3139     send_response();
   3140 
   3141     exit(1);
   3142   }
   3143 
   3144 
   3145   /* now get the port number assigned by the system  */
   3146   addrlen = sizeof(myaddr_in);
   3147   if (getsockname(s_listen,
   3148 		  (struct sockaddr *)&myaddr_in,
   3149 		  &addrlen) == SOCKET_ERROR) {
   3150     netperf_response.content.serv_errno = errno;
   3151     close(s_listen);
   3152     send_response();
   3153 
   3154     exit(1);
   3155   }
   3156 
   3157   /* Now myaddr_in contains the port and the internet address this is */
   3158   /* returned to the sender also implicitly telling the sender that the */
   3159   /* socket buffer sizing has been done. */
   3160 
   3161   sdp_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port);
   3162   netperf_response.content.serv_errno   = 0;
   3163 
   3164   /* But wait, there's more. If the initiator wanted cpu measurements, */
   3165   /* then we must call the calibrate routine, which will return the max */
   3166   /* rate back to the initiator. If the CPU was not to be measured, or */
   3167   /* something went wrong with the calibration, we will return a 0.0 to */
   3168   /* the initiator. */
   3169 
   3170   sdp_rr_response->cpu_rate = (float)0.0; 	/* assume no cpu */
   3171   sdp_rr_response->measure_cpu = 0;
   3172 
   3173   if (sdp_rr_request->measure_cpu) {
   3174     sdp_rr_response->measure_cpu = 1;
   3175     sdp_rr_response->cpu_rate = calibrate_local_cpu(sdp_rr_request->cpu_rate);
   3176   }
   3177 
   3178 
   3179   /* before we send the response back to the initiator, pull some of */
   3180   /* the socket parms from the globals */
   3181   sdp_rr_response->send_buf_size = lss_size;
   3182   sdp_rr_response->recv_buf_size = lsr_size;
   3183   sdp_rr_response->no_delay = loc_nodelay;
   3184   sdp_rr_response->so_rcvavoid = loc_rcvavoid;
   3185   sdp_rr_response->so_sndavoid = loc_sndavoid;
   3186   sdp_rr_response->test_length = sdp_rr_request->test_length;
   3187   send_response();
   3188 
   3189   addrlen = sizeof(peeraddr_in);
   3190 
   3191   if ((s_data = accept(s_listen,
   3192 		       (struct sockaddr *)&peeraddr_in,
   3193 		       &addrlen)) == INVALID_SOCKET) {
   3194     /* Let's just punt. The remote will be given some information */
   3195     close(s_listen);
   3196 
   3197     exit(1);
   3198   }
   3199 
   3200 #ifdef KLUDGE_SOCKET_OPTIONS
   3201   /* this is for those systems which *INCORRECTLY* fail to pass */
   3202   /* attributes across an accept() call. Including this goes against */
   3203   /* my better judgement :( raj 11/95 */
   3204 
   3205   kludge_socket_options(s_data);
   3206 
   3207 #endif /* KLUDGE_SOCKET_OPTIONS */
   3208 
   3209 #ifdef WIN32
   3210   /* this is used so the timer thread can close the socket out from */
   3211   /* under us, which to date is the easiest/cleanest/least */
   3212   /* Windows-specific way I can find to force the winsock calls to */
   3213   /* return WSAEINTR with the test is over. anything that will run on */
   3214   /* 95 and NT and is closer to what netperf expects from Unix signals */
   3215   /* and such would be appreciated raj 1/96 */
   3216   win_kludge_socket = s_data;
   3217 #endif /* WIN32 */
   3218 
   3219   if (debug) {
   3220     fprintf(where,"recv_sdp_rr: accept completes on the data connection.\n");
   3221     fflush(where);
   3222   }
   3223 
   3224   /* Now it's time to start receiving data on the connection. We will */
   3225   /* first grab the apropriate counters and then start grabbing. */
   3226 
   3227   cpu_start(sdp_rr_request->measure_cpu);
   3228 
   3229   /* The loop will exit when we hit the end of the test time, or when */
   3230   /* we have exchanged the requested number of transactions. */
   3231 
   3232   if (sdp_rr_request->test_length > 0) {
   3233     times_up = 0;
   3234     trans_remaining = 0;
   3235     start_timer(sdp_rr_request->test_length + PAD_TIME);
   3236   }
   3237   else {
   3238     times_up = 1;
   3239     trans_remaining = sdp_rr_request->test_length * -1;
   3240   }
   3241 
   3242   trans_received = 0;
   3243 
   3244   while ((!times_up) || (trans_remaining > 0)) {
   3245     temp_message_ptr = recv_ring->buffer_ptr;
   3246     request_bytes_remaining	= sdp_rr_request->request_size;
   3247     while(request_bytes_remaining > 0) {
   3248       if((request_bytes_recvd=recv(s_data,
   3249 				   temp_message_ptr,
   3250 				   request_bytes_remaining,
   3251 				   0)) == SOCKET_ERROR) {
   3252 	if (SOCKET_EINTR(request_bytes_recvd))
   3253 	{
   3254 	  timed_out = 1;
   3255 	  break;
   3256 	}
   3257 
   3258 	netperf_response.content.serv_errno = errno;
   3259 	send_response();
   3260 	exit(1);
   3261       }
   3262       else if( request_bytes_recvd == 0 ) {
   3263 	if (debug) {
   3264 	  fprintf(where,"zero is my hero\n");
   3265 	  fflush(where);
   3266 	}
   3267 	sock_closed = 1;
   3268 	break;
   3269       }
   3270       else {
   3271 	request_bytes_remaining -= request_bytes_recvd;
   3272 	temp_message_ptr  += request_bytes_recvd;
   3273       }
   3274     }
   3275 
   3276     recv_ring = recv_ring->next;
   3277 
   3278     if ((timed_out) || (sock_closed)) {
   3279       /* we hit the end of the test based on time - or the socket
   3280 	 closed on us along the way.  bail out of here now... */
   3281       if (debug) {
   3282 	fprintf(where,"yo5\n");
   3283 	fflush(where);
   3284       }
   3285       break;
   3286     }
   3287 
   3288     /* Now, send the response to the remote */
   3289     if((bytes_sent=send(s_data,
   3290 			send_ring->buffer_ptr,
   3291 			sdp_rr_request->response_size,
   3292 			0)) == SOCKET_ERROR) {
   3293       if (SOCKET_EINTR(bytes_sent)) {
   3294 	/* the test timer has popped */
   3295 	timed_out = 1;
   3296 	fprintf(where,"yo6\n");
   3297 	fflush(where);
   3298 	break;
   3299       }
   3300       netperf_response.content.serv_errno = 992;
   3301       send_response();
   3302       exit(1);
   3303     }
   3304 
   3305     send_ring = send_ring->next;
   3306 
   3307     trans_received++;
   3308     if (trans_remaining) {
   3309       trans_remaining--;
   3310     }
   3311   }
   3312 
   3313 
   3314   /* The loop now exits due to timeout or transaction count being */
   3315   /* reached */
   3316 
   3317   cpu_stop(sdp_rr_request->measure_cpu,&elapsed_time);
   3318 
   3319   stop_timer();
   3320 
   3321   if (timed_out) {
   3322     /* we ended the test by time, which was at least 2 seconds */
   3323     /* longer than we wanted to run. so, we want to subtract */
   3324     /* PAD_TIME from the elapsed_time. */
   3325     elapsed_time -= PAD_TIME;
   3326   }
   3327 
   3328   /* send the results to the sender			*/
   3329 
   3330   if (debug) {
   3331     fprintf(where,
   3332 	    "recv_sdp_rr: got %d transactions\n",
   3333 	    trans_received);
   3334     fflush(where);
   3335   }
   3336 
   3337   sdp_rr_results->bytes_received = (trans_received *
   3338 				    (sdp_rr_request->request_size +
   3339 				     sdp_rr_request->response_size));
   3340   sdp_rr_results->trans_received = trans_received;
   3341   sdp_rr_results->elapsed_time   = elapsed_time;
   3342   sdp_rr_results->cpu_method     = cpu_method;
   3343   sdp_rr_results->num_cpus       = lib_num_loc_cpus;
   3344   if (sdp_rr_request->measure_cpu) {
   3345     sdp_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
   3346   }
   3347 
   3348   if (debug) {
   3349     fprintf(where,
   3350 	    "recv_sdp_rr: test complete, sending results.\n");
   3351     fflush(where);
   3352   }
   3353 
   3354   /* we are now done with the sockets */
   3355   close(s_data);
   3356   close(s_listen);
   3357 
   3358   send_response();
   3359 
   3360 }
   3361 
   3362 
   3363 
   3364 void
   3365 print_sdp_usage()
   3366 {
   3367 
   3368   printf("%s",sdp_usage);
   3369   exit(1);
   3370 
   3371 }
   3372 void
   3373 scan_sdp_args(argc, argv)
   3374      int	argc;
   3375      char	*argv[];
   3376 
   3377 {
   3378 
   3379 #define SOCKETS_ARGS "b:DhH:I:L:m:M:P:r:s:S:V46"
   3380 
   3381   extern char	*optarg;	  /* pointer to option string	*/
   3382 
   3383   int		c;
   3384 
   3385   char
   3386     arg1[BUFSIZ],  /* argument holders		*/
   3387     arg2[BUFSIZ];
   3388 
   3389   if (no_control) {
   3390     fprintf(where,
   3391 	    "The SDP tests do not know how to deal with no control tests\n");
   3392     exit(-1);
   3393   }
   3394 
   3395   strncpy(local_data_port,"0",sizeof(local_data_port));
   3396   strncpy(remote_data_port,"0",sizeof(remote_data_port));
   3397 
   3398   /* Go through all the command line arguments and break them */
   3399   /* out. For those options that take two parms, specifying only */
   3400   /* the first will set both to that value. Specifying only the */
   3401   /* second will leave the first untouched. To change only the */
   3402   /* first, use the form "first," (see the routine break_args.. */
   3403 
   3404   while ((c= getopt(argc, argv, SOCKETS_ARGS)) != EOF) {
   3405     switch (c) {
   3406     case '?':
   3407     case '4':
   3408       remote_data_family = AF_INET;
   3409       local_data_family = AF_INET;
   3410       break;
   3411     case '6':
   3412 #if defined(AF_INET6)
   3413       remote_data_family = AF_INET6;
   3414       local_data_family = AF_INET6;
   3415 #else
   3416       fprintf(stderr,
   3417 	      "This netperf was not compiled on an IPv6 capable host!\n");
   3418       fflush(stderr);
   3419       exit(-1);
   3420 #endif
   3421       break;
   3422     case 'h':
   3423       print_sdp_usage();
   3424       exit(1);
   3425     case 'b':
   3426 #ifdef WANT_FIRST_BURST
   3427       first_burst_size = atoi(optarg);
   3428 #else /* WANT_FIRST_BURST */
   3429       printf("Initial request burst functionality not compiled-in!\n");
   3430 #endif /* WANT_FIRST_BURST */
   3431       break;
   3432     case 'D':
   3433       /* set the nodelay flag */
   3434       loc_nodelay = 1;
   3435       rem_nodelay = 1;
   3436       break;
   3437     case 'H':
   3438       break_args_explicit(optarg,arg1,arg2);
   3439       if (arg1[0]) {
   3440 	/* make sure we leave room for the NULL termination boys and
   3441 	   girls. raj 2005-02-82 */
   3442 	remote_data_address = malloc(strlen(arg1)+1);
   3443 	strncpy(remote_data_address,arg1,strlen(arg1));
   3444       }
   3445       if (arg2[0])
   3446 	remote_data_family = parse_address_family(arg2);
   3447       break;
   3448     case 'L':
   3449       break_args_explicit(optarg,arg1,arg2);
   3450       if (arg1[0]) {
   3451 	/* make sure we leave room for the NULL termination boys and
   3452 	   girls. raj 2005-02-82 */
   3453 	local_data_address = malloc(strlen(arg1)+1);
   3454 	strncpy(local_data_address,arg1,strlen(arg1));
   3455       }
   3456       if (arg2[0])
   3457 	local_data_family = parse_address_family(arg2);
   3458       break;
   3459     case 'P':
   3460       /* set the local and remote data port numbers for the tests to
   3461 	 allow them to run through those blankety blank end-to-end
   3462 	 breaking firewalls. raj 2004-06-15 */
   3463       break_args(optarg,arg1,arg2);
   3464       if (arg1[0])
   3465 	strncpy(local_data_port,arg1,sizeof(local_data_port));
   3466       if (arg2[0])
   3467 	strncpy(remote_data_port,arg2,sizeof(remote_data_port));
   3468       break;
   3469     case 's':
   3470       /* set local socket sizes */
   3471       break_args(optarg,arg1,arg2);
   3472       if (arg1[0])
   3473 	lss_size_req = convert(arg1);
   3474       if (arg2[0])
   3475 	lsr_size_req = convert(arg2);
   3476       break;
   3477     case 'S':
   3478       /* set remote socket sizes */
   3479       break_args(optarg,arg1,arg2);
   3480       if (arg1[0])
   3481 	rss_size_req = convert(arg1);
   3482       if (arg2[0])
   3483 	rsr_size_req = convert(arg2);
   3484       break;
   3485     case 'r':
   3486       /* set the request/response sizes */
   3487       break_args(optarg,arg1,arg2);
   3488       if (arg1[0])
   3489 	req_size = convert(arg1);
   3490       if (arg2[0])
   3491 	rsp_size = convert(arg2);
   3492       break;
   3493     case 'm':
   3494       /* set size of the buffer for each sent message */
   3495       send_size = convert(optarg);
   3496       break;
   3497     case 'M':
   3498       /* set the size of the buffer for each received message */
   3499       recv_size = convert(optarg);
   3500       break;
   3501     case 't':
   3502       /* set the test name */
   3503       strcpy(test_name,optarg);
   3504       break;
   3505     case 'W':
   3506 	/* set the "width" of the user space data */
   3507 	/* buffer. This will be the number of */
   3508 	/* send_size buffers malloc'd in the */
   3509 	/* *_STREAM test. It may be enhanced to set */
   3510 	/* both send and receive "widths" but for now */
   3511 	/* it is just the sending *_STREAM. */
   3512 	send_width = convert(optarg);
   3513 	break;
   3514     case 'V':
   3515       /* we want to do copy avoidance and will set */
   3516       /* it for everything, everywhere, if we really */
   3517       /* can. of course, we don't know anything */
   3518       /* about the remote... */
   3519 #ifdef SO_SND_COPYAVOID
   3520       loc_sndavoid = 1;
   3521 #else
   3522       loc_sndavoid = 0;
   3523       printf("Local send copy avoidance not available.\n");
   3524 #endif
   3525 #ifdef SO_RCV_COPYAVOID
   3526       loc_rcvavoid = 1;
   3527 #else
   3528       loc_rcvavoid = 0;
   3529       printf("Local recv copy avoidance not available.\n");
   3530 #endif
   3531       rem_sndavoid = 1;
   3532       rem_rcvavoid = 1;
   3533       break;
   3534     case 'N':
   3535       /* this opton allows the user to set the number of
   3536        * messages to send.  This in effect modifies the test
   3537        * time.  If we know the message size, then the we can
   3538        * express the test time as message_size * number_messages
   3539        */
   3540       msg_count = convert (optarg);
   3541       if (msg_count > 0)
   3542 	  test_time = 0;
   3543       break;
   3544     case 'B':
   3545       non_block = 1;
   3546       break;
   3547     case 'T':
   3548       num_associations = atoi(optarg);
   3549       if (num_associations <= 1) {
   3550 	  printf("Number of SDP associations must be >= 1\n");
   3551 	  exit(1);
   3552       }
   3553       break;
   3554     };
   3555   }
   3556 }
   3557 
   3558 #endif  /* WANT_SDP */
   3559