Home | History | Annotate | Download | only in netperf
      1 #ifndef lint
      2 char	nettest_sctp[]="\
      3 @(#)nettest_sctp.c (c) Copyright 2005-2007 Hewlett-Packard Co. Version 2.4.3";
      4 #else
      5 #define DIRTY
      6 #define WANT_HISTOGRAM
      7 #define WANT_INTERVALS
      8 #endif /* lint */
      9 
     10 /****************************************************************/
     11 /*								*/
     12 /*	nettest_sctp.c						*/
     13 /*								*/
     14 /*                                                              */
     15 /*      scan_sctp_args()        get the sctp command line args  */
     16 /*                                                              */
     17 /*	the actual test routines...				*/
     18 /*								*/
     19 /*	send_sctp_stream()	perform a sctp stream test	*/
     20 /*	recv_sctp_stream()					*/
     21 /*	send_sctp_rr()		perform a sctp request/response	*/
     22 /*	recv_sctp_rr()						*/
     23 /*	send_sctp_stream_udp()	perform a sctp request/response	*/
     24 /*	recv_sctp_stream_upd()	using UDP style API		*/
     25 /*	send_sctp_rr_udp()	perform a sctp request/response	*/
     26 /*	recv_sctp_rr_upd()	using UDP style API		*/
     27 /*								*/
     28 /*      relies on create_data_socket in nettest_bsd.c           */
     29 /****************************************************************/
     30 
     31 #if HAVE_CONFIG_H
     32 # include <config.h>
     33 #endif
     34 
     35 #if defined(WANT_SCTP)
     36 
     37 #include <sys/types.h>
     38 #include <fcntl.h>
     39 #include <errno.h>
     40 #include <signal.h>
     41 #include <stdio.h>
     42 #include <string.h>
     43 #include <time.h>
     44 #ifdef NOSTDLIBH
     45 #include <malloc.h>
     46 #else /* NOSTDLIBH */
     47 #include <stdlib.h>
     48 #endif /* NOSTDLIBH */
     49 
     50 #if !defined(__VMS)
     51 #include <sys/ipc.h>
     52 #endif /* !defined(__VMS) */
     53 #include <unistd.h>
     54 #include <sys/types.h>
     55 #include <sys/socket.h>
     56 #include <netinet/in.h>
     57 #include <netinet/tcp.h>
     58 #include <netinet/sctp.h>
     59 #include <arpa/inet.h>
     60 #include <netdb.h>
     61 
     62 /* would seem that not all sctp.h files define a MSG_EOF, but that
     63    MSG_EOF can be the same as MSG_FIN so lets work with that
     64    assumption.  initial find by Jon Pedersen. raj 2006-02-01 */
     65 #ifndef MSG_EOF
     66 #ifdef MSG_FIN
     67 #define MSG_EOF MSG_FIN
     68 #else
     69 #error Must have either MSG_EOF or MSG_FIN defined
     70 #endif
     71 #endif
     72 
     73 #include "netlib.h"
     74 #include "netsh.h"
     75 /* get some of the functions from nettest_bsd.c */
     76 #include "nettest_bsd.h"
     77 #include "nettest_sctp.h"
     78 
     79 #ifdef WANT_HISTOGRAM
     80 #ifdef __sgi
     81 #include <sys/time.h>
     82 #endif /* __sgi */
     83 #include "hist.h"
     84 #endif /* WANT_HISTOGRAM */
     85 
     86 #ifdef WANT_FIRST_BURST
     87 extern int first_burst_size;
     88 #endif /* WANT_FIRST_BURST */
     89 
     90 
     91 
     93 /* these variables are specific to SCTP tests. declare */
     94 /* them static to make them global only to this file. */
     95 
     96 static int
     97   msg_count = 0,	/* number of messages to transmit on association */
     98   non_block = 0,	/* default to blocking sockets */
     99   num_associations = 1; /* number of associations on the endpoint */
    100 
    101 static  int confidence_iteration;
    102 static  char  local_cpu_method;
    103 static  char  remote_cpu_method;
    104 
    105 #ifdef WANT_HISTOGRAM
    106 static struct timeval time_one;
    107 static struct timeval time_two;
    108 static HIST time_hist;
    109 #endif /* WANT_HISTOGRAM */
    110 
    111 
    112 char sctp_usage[] = "\n\
    113 Usage: netperf [global options] -- [test options] \n\
    114 \n\
    115 SCTP Sockets Test Options:\n\
    116     -b number         Send number requests at the start of _RR tests\n\
    117     -D [L][,R]        Set SCTP_NODELAY locally and/or remotely\n\
    118     -h                Display this text\n\
    119     -H name,fam       Use name (or IP) and family as target of data connection\n\
    120     -L name,fam       Use name (or IP) and family as source of data connextion\n\
    121     -m bytes          Set the size of each sent message\n\
    122     -M bytes          Set the size of each received messages\n\
    123     -P local[,remote] Set the local/remote port for the data socket\n\
    124     -r req,[rsp]      Set request/response sizes (_RR tests)\n\
    125     -s send[,recv]    Set local socket send/recv buffer sizes\n\
    126     -S send[,recv]    Set remote socket send/recv buffer sizes\n\
    127     -V 		      Enable copy avoidance if supported\n\
    128     -N number	      Specifies the number of messages to send (_STREAM tests)\n\
    129     -B		      run the test in non-blocking mode\n\
    130     -T number	      Number of associations to create (_MANY tests)\n\
    131     -4                Use AF_INET (eg IPv4) on both ends of the data conn\n\
    132     -6                Use AF_INET6 (eg IPv6) on both ends of the data conn\n\
    133 \n\
    134 For those options taking two parms, at least one must be specified;\n\
    135 specifying one value without a comma will set both parms to that\n\
    136 value, specifying a value with a leading comma will set just the second\n\
    137 parm, a value with a trailing comma will set just the first. To set\n\
    138 each parm to unique values, specify both and separate them with a\n\
    139 comma.\n";
    140 
    141 
    142  /* This routine is intended to retrieve interesting aspects of tcp */
    144  /* for the data connection. at first, it attempts to retrieve the */
    145  /* maximum segment size. later, it might be modified to retrieve */
    146  /* other information, but it must be information that can be */
    147  /* retrieved quickly as it is called during the timing of the test. */
    148  /* for that reason, a second routine may be created that can be */
    149  /* called outside of the timing loop */
    150 static
    151 void
    152 get_sctp_info(socket, mss)
    153      int socket;
    154      int *mss;
    155 {
    156 
    157   int sock_opt_len;
    158 
    159   if (sctp_opt_info(socket,
    160 		    0,
    161 		    SCTP_MAXSEG,
    162 		    mss,
    163 		    &sock_opt_len) < 0) {
    164     lss_size = -1;
    165   }
    166 }
    167 
    168 
    169 static
    171 void
    172 sctp_enable_events(socket, ev_mask)
    173     int socket;
    174     int ev_mask;
    175 {
    176     struct sctp_event_subscribe ev;
    177 
    178     bzero(&ev, sizeof(ev));
    179 
    180     if (ev_mask & SCTP_SNDRCV_INFO_EV)
    181 	ev.sctp_data_io_event = 1;
    182 
    183     if (ev_mask & SCTP_ASSOC_CHANGE_EV)
    184 	ev.sctp_association_event = 1;
    185 
    186     if (ev_mask & SCTP_PEERADDR_CHANGE_EV)
    187 	ev.sctp_address_event = 1;
    188 
    189     if (ev_mask & SCTP_SND_FAILED_EV)
    190 	ev.sctp_send_failure_event = 1;
    191 
    192     if (ev_mask & SCTP_REMOTE_ERROR_EV)
    193 	ev.sctp_peer_error_event = 1;
    194 
    195     if (ev_mask & SCTP_SHUTDOWN_EV)
    196 	ev.sctp_shutdown_event = 1;
    197 
    198     if (ev_mask & SCTP_PD_EV)
    199 	ev.sctp_partial_delivery_event = 1;
    200 
    201     if (ev_mask & SCTP_ADAPT_EV)
    202 #ifdef HAVE_SCTP_ADAPTATION_LAYER_EVENT
    203 	ev.sctp_adaptation_layer_event = 1;
    204 #else
    205 	ev.sctp_adaption_layer_event = 1;
    206 #endif
    207 
    208     if (setsockopt(socket,
    209 		   IPPROTO_SCTP,
    210 #ifdef SCTP_EVENTS
    211 		   SCTP_EVENTS,
    212 #else
    213 		   SCTP_SET_EVENTS,
    214 #endif
    215 		   (const char*)&ev,
    216 		   sizeof(ev)) != 0 ) {
    217       fprintf(where,
    218 	      "sctp_enable_event: could not set sctp events errno %d\n",
    219 	      errno);
    220       fflush(where);
    221       exit(1);
    222     }
    223 }
    224 
    225 
    227 static
    228 sctp_disposition_t
    229 sctp_process_event(socket, buf)
    230     int socket;
    231     void *buf;
    232 {
    233 
    234     struct sctp_assoc_change *sac;
    235     struct sctp_send_failed *ssf;
    236     struct sctp_paddr_change *spc;
    237     struct sctp_remote_error *sre;
    238     union sctp_notification *snp;
    239 
    240     snp = buf;
    241 
    242     switch (snp->sn_header.sn_type) {
    243     case SCTP_ASSOC_CHANGE:
    244 	if (debug) {
    245 	    fprintf(where, "\tSCTP_ASSOC_CHANGE event, type:");
    246 	    fflush(where);
    247 	}
    248 	sac = &snp->sn_assoc_change;
    249 	switch (sac->sac_type) {
    250 	    case SCTP_COMM_UP:
    251 		if (debug) {
    252 		    fprintf(where, "  SCTP_COMM_UP\n");
    253 		    fflush(where);
    254 		}
    255 		break;
    256 	    case SCTP_RESTART:
    257 		if (debug) {
    258 		    fprintf(where, "  SCTP_RESTART\n");
    259 		    fflush(where);
    260 		}
    261 		break;
    262 	    case SCTP_CANT_STR_ASSOC:
    263 		if (debug) {
    264 		    fprintf(where, "  SCTP_CANT_STR_ASSOC\n");
    265 		    fflush(where);
    266 		}
    267 		break;	/* FIXME ignore above status changes */
    268 	    case SCTP_COMM_LOST:
    269 		if (debug) {
    270 		    fprintf(where, "  SCTP_COMM_LOST\n");
    271 		    fflush(where);
    272 		}
    273 		return SCTP_CLOSE;
    274 	    case SCTP_SHUTDOWN_COMP:
    275 		if (debug) {
    276 		    fprintf(where, "  SCTP_SHUTDOWN_COMPLETE\n");
    277 		    fflush(where);
    278 		}
    279 		return SCTP_CLOSE;
    280 		break;
    281 	}
    282 
    283     case SCTP_SEND_FAILED:
    284 	if (debug) {
    285 	    fprintf(where, "\tSCTP_SEND_FAILED event\n");
    286 	    fflush(where);
    287 	}
    288 	ssf = &snp->sn_send_failed;
    289 	break;  /* FIXME ??? ignore this for now */
    290 
    291     case SCTP_PEER_ADDR_CHANGE:
    292 	if (debug) {
    293 	    fprintf(where, "\tSCTP_PEER_ADDR_CHANGE event\n");
    294 	    fflush(where);
    295 	}
    296 	spc = &snp->sn_paddr_change;
    297 	break;	/* FIXME ??? ignore this for now */
    298 
    299     case SCTP_REMOTE_ERROR:
    300 	if (debug) {
    301 	    fprintf(where, "\tSCTP_REMOTE_ERROR event\n");
    302 	    fflush(where);
    303 	}
    304 	sre = &snp->sn_remote_error;
    305 	break;	/* FIXME ??? ignore this for now */
    306     case SCTP_SHUTDOWN_EVENT:
    307 	if (debug) {
    308 	    fprintf(where, "\tSCTP_SHUTDOWN event\n");
    309 	    fflush(where);
    310 	}
    311 	return SCTP_CLOSE;
    312     default:
    313 	fprintf(where, "unknown type: %hu\n", snp->sn_header.sn_type);
    314 	fflush(where);
    315 	break;
    316     }
    317     return SCTP_OK;
    318 }
    319 
    320 
    321 
    323 /* This routine implements the SCTP unidirectional data transfer test */
    324 /* (a.k.a. stream) for the sockets interface. It receives its */
    325 /* parameters via global variables from the shell and writes its */
    326 /* output to the standard output. */
    327 
    328 
    329 void
    330 send_sctp_stream(remote_host)
    331 char	remote_host[];
    332 {
    333 
    334   char *tput_title = "\
    335 Recv   Send    Send                          \n\
    336 Socket Socket  Message  Elapsed              \n\
    337 Size   Size    Size     Time     Throughput  \n\
    338 bytes  bytes   bytes    secs.    %s/sec  \n\n";
    339 
    340   char *tput_fmt_0 =
    341     "%7.2f\n";
    342 
    343   char *tput_fmt_1 =
    344     "%6d %6d %6d    %-6.2f   %7.2f   \n";
    345 
    346   char *cpu_title = "\
    347 Recv   Send    Send                          Utilization       Service Demand\n\
    348 Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
    349 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
    350 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
    351 
    352   char *cpu_fmt_0 =
    353     "%6.3f %c\n";
    354 
    355   char *cpu_fmt_1 =
    356     "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f\n";
    357 
    358   char *ksink_fmt = "\n\
    359 Alignment      Offset         %-8.8s %-8.8s    Sends   %-8.8s Recvs\n\
    360 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
    361 Send   Recv    Send   Recv             Send (avg)          Recv (avg)\n\
    362 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
    363 
    364   char *ksink_fmt2 = "\n\
    365 Maximum\n\
    366 Segment\n\
    367 Size (bytes)\n\
    368 %6d\n";
    369 
    370 
    371   float			elapsed_time;
    372 
    373 #ifdef WANT_INTERVALS
    374   int interval_count;
    375   sigset_t signal_set;
    376 #endif
    377 
    378   /* what we want is to have a buffer space that is at least one */
    379   /* send-size greater than our send window. this will insure that we */
    380   /* are never trying to re-use a buffer that may still be in the hands */
    381   /* of the transport. This buffer will be malloc'd after we have found */
    382   /* the size of the local senc socket buffer. We will want to deal */
    383   /* with alignment and offset concerns as well. */
    384 
    385 #ifdef DIRTY
    386   int	*message_int_ptr;
    387 #endif
    388 
    389   struct ring_elt *send_ring;
    390 
    391   int len;
    392   unsigned int nummessages = 0;
    393   int send_socket;
    394   int bytes_remaining;
    395   int sctp_mss;
    396   int timed_out;
    397 
    398   /* with links like fddi, one can send > 32 bits worth of bytes */
    399   /* during a test... ;-) at some point, this should probably become a */
    400   /* 64bit integral type, but those are not entirely common yet */
    401   double	bytes_sent = 0.0;
    402 
    403 #ifdef DIRTY
    404   int	i;
    405 #endif /* DIRTY */
    406 
    407   float	local_cpu_utilization;
    408   float	local_service_demand;
    409   float	remote_cpu_utilization;
    410   float	remote_service_demand;
    411 
    412   double	thruput;
    413 
    414   struct addrinfo	*remote_res;
    415   struct addrinfo	*local_res;
    416   struct addrinfo	*local_remote_res;
    417   struct addrinfo	*local_local_res;
    418 
    419   struct	sctp_stream_request_struct	*sctp_stream_request;
    420   struct	sctp_stream_response_struct	*sctp_stream_response;
    421   struct	sctp_stream_results_struct	*sctp_stream_result;
    422 
    423   sctp_stream_request  =
    424     (struct sctp_stream_request_struct *)netperf_request.content.test_specific_data;
    425   sctp_stream_response =
    426     (struct sctp_stream_response_struct *)netperf_response.content.test_specific_data;
    427   sctp_stream_result   =
    428     (struct sctp_stream_results_struct *)netperf_response.content.test_specific_data;
    429 
    430 #ifdef WANT_HISTOGRAM
    431   time_hist = HIST_new();
    432 #endif /* WANT_HISTOGRAM */
    433   /* since we are now disconnected from the code that established the */
    434   /* control socket, and since we want to be able to use different */
    435   /* protocols and such, we are passed the name of the remote host and */
    436   /* must turn that into the test specific addressing information. */
    437 
    438   /* complete_addrinfos will either succede or exit the process */
    439   complete_addrinfos(&remote_res,
    440 		     &local_res,
    441 		     remote_host,
    442 		     SOCK_STREAM,
    443 		     IPPROTO_SCTP,
    444 		     0);
    445 
    446   if ( print_headers ) {
    447     print_top_test_header("SCTP STREAM TEST", local_res, remote_res);
    448   }
    449 
    450   send_ring = NULL;
    451   confidence_iteration = 1;
    452   init_stat();
    453 
    454   /* we have a great-big while loop which controls the number of times */
    455   /* we run a particular test. this is for the calculation of a */
    456   /* confidence interval (I really should have stayed awake during */
    457   /* probstats :). If the user did not request confidence measurement */
    458   /* (no confidence is the default) then we will only go though the */
    459   /* loop once. the confidence stuff originates from the folks at IBM */
    460 
    461   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
    462 	 (confidence_iteration <= iteration_min)) {
    463 
    464     /* initialize a few counters. we have to remember that we might be */
    465     /* going through the loop more than once. */
    466 
    467     nummessages    =	0;
    468     bytes_sent     =	0.0;
    469     times_up       = 	0;
    470     timed_out	   =    0;
    471 
    472     /*set up the data socket                        */
    473     send_socket = create_data_socket(local_res);
    474 
    475     if (send_socket == INVALID_SOCKET){
    476       perror("netperf: send_sctp_stream: sctp stream data socket");
    477       exit(1);
    478     }
    479 
    480     if (debug) {
    481       fprintf(where,"send_sctp_stream: send_socket obtained...\n");
    482     }
    483 
    484     /* at this point, we have either retrieved the socket buffer sizes, */
    485     /* or have tried to set them, so now, we may want to set the send */
    486     /* size based on that (because the user either did not use a -m */
    487     /* option, or used one with an argument of 0). If the socket buffer */
    488     /* size is not available, we will set the send size to 4KB - no */
    489     /* particular reason, just arbitrary... */
    490     if (send_size == 0) {
    491       if (lss_size > 0) {
    492 	send_size = lss_size;
    493       }
    494       else {
    495 	send_size = 4096;
    496       }
    497     }
    498 
    499     /* set-up the data buffer ring with the requested alignment and offset. */
    500     /* note also that we have allocated a quantity */
    501     /* of memory that is at least one send-size greater than our socket */
    502     /* buffer size. We want to be sure that there are at least two */
    503     /* buffers allocated - this can be a bit of a problem when the */
    504     /* send_size is bigger than the socket size, so we must check... the */
    505     /* user may have wanted to explicitly set the "width" of our send */
    506     /* buffers, we should respect that wish... */
    507     if (send_width == 0) {
    508       send_width = (lss_size/send_size) + 1;
    509       if (send_width == 1) send_width++;
    510     }
    511 
    512     if (send_ring == NULL) {
    513       /* only allocate the send ring once. this is a networking test, */
    514       /* not a memory allocation test. this way, we do not need a */
    515       /* deallocate_buffer_ring() routine, and I don't feel like */
    516       /* writing one anyway :) raj 11/94 */
    517       send_ring = allocate_buffer_ring(send_width,
    518 				       send_size,
    519 				       local_send_align,
    520 				       local_send_offset);
    521     }
    522 
    523     /* If the user has requested cpu utilization measurements, we must */
    524     /* calibrate the cpu(s). We will perform this task within the tests */
    525     /* themselves. If the user has specified the cpu rate, then */
    526     /* calibrate_local_cpu will return rather quickly as it will have */
    527     /* nothing to do. If local_cpu_rate is zero, then we will go through */
    528     /* all the "normal" calibration stuff and return the rate back. */
    529 
    530     if (local_cpu_usage) {
    531       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
    532     }
    533 
    534     /* Tell the remote end to do a listen. The server alters the socket */
    535     /* paramters on the other side at this point, hence the reason for */
    536     /* all the values being passed in the setup message. If the user did */
    537     /* not specify any of the parameters, they will be passed as 0, which */
    538     /* will indicate to the remote that no changes beyond the system's */
    539     /* default should be used. Alignment is the exception, it will */
    540     /* default to 1, which will be no alignment alterations. */
    541 
    542     netperf_request.content.request_type	=	DO_SCTP_STREAM;
    543     sctp_stream_request->send_buf_size	=	rss_size_req;
    544     sctp_stream_request->recv_buf_size	=	rsr_size_req;
    545     sctp_stream_request->receive_size	=	recv_size;
    546     sctp_stream_request->no_delay	=	rem_nodelay;
    547     sctp_stream_request->recv_alignment	=	remote_recv_align;
    548     sctp_stream_request->recv_offset	=	remote_recv_offset;
    549     sctp_stream_request->measure_cpu	=	remote_cpu_usage;
    550     sctp_stream_request->cpu_rate	=	remote_cpu_rate;
    551     if (test_time) {
    552       sctp_stream_request->test_length	=	test_time;
    553     }
    554     else {
    555       if (msg_count)
    556 	  test_bytes = send_size * msg_count;
    557 
    558       sctp_stream_request->test_length	=	test_bytes;
    559     }
    560     sctp_stream_request->so_rcvavoid	=	rem_rcvavoid;
    561     sctp_stream_request->so_sndavoid	=	rem_sndavoid;
    562 #ifdef DIRTY
    563     sctp_stream_request->dirty_count    =       rem_dirty_count;
    564     sctp_stream_request->clean_count    =       rem_clean_count;
    565 #endif /* DIRTY */
    566     sctp_stream_request->port		=	htonl(atoi(remote_data_port));
    567     sctp_stream_request->ipfamily	=	af_to_nf(remote_res->ai_family);
    568     sctp_stream_request->non_blocking   =	non_block;
    569 
    570 
    571     if (debug > 1) {
    572       fprintf(where,
    573 	      "netperf: send_sctp_stream: requesting sctp stream test\n");
    574     }
    575 
    576     send_request();
    577 
    578     /* The response from the remote will contain all of the relevant 	*/
    579     /* socket parameters for this test type. We will put them back into */
    580     /* the variables here so they can be displayed if desired.  The	*/
    581     /* remote will have calibrated CPU if necessary, and will have done	*/
    582     /* all the needed set-up we will have calibrated the cpu locally	*/
    583     /* before sending the request, and will grab the counter value right*/
    584     /* after the connect returns. The remote will grab the counter right*/
    585     /* after the accept call. This saves the hassle of extra messages	*/
    586     /* being sent for the sctp tests.					*/
    587 
    588     recv_response();
    589 
    590     if (!netperf_response.content.serv_errno) {
    591       if (debug)
    592 	fprintf(where,"remote listen done.\n");
    593       rsr_size	      =	sctp_stream_response->recv_buf_size;
    594       rss_size	      =	sctp_stream_response->send_buf_size;
    595       rem_nodelay     =	sctp_stream_response->no_delay;
    596       remote_cpu_usage=	sctp_stream_response->measure_cpu;
    597       remote_cpu_rate = sctp_stream_response->cpu_rate;
    598 
    599       /* we have to make sure that the server port number is in */
    600       /* network order */
    601       set_port_number(remote_res, (short)sctp_stream_response->data_port_number);
    602 
    603       rem_rcvavoid	= sctp_stream_response->so_rcvavoid;
    604       rem_sndavoid	= sctp_stream_response->so_sndavoid;
    605     }
    606     else {
    607       Set_errno(netperf_response.content.serv_errno);
    608       fprintf(where,
    609 	      "netperf: remote error %d",
    610 	      netperf_response.content.serv_errno);
    611       perror("");
    612       fflush(where);
    613 
    614       exit(1);
    615     }
    616 
    617     /*Connect up to the remote port on the data socket  */
    618     if (connect(send_socket,
    619 		remote_res->ai_addr,
    620 		remote_res->ai_addrlen) == INVALID_SOCKET) {
    621       perror("netperf: send_sctp_stream: data socket connect failed");
    622       exit(1);
    623     }
    624 
    625     sctp_enable_events(send_socket, SCTP_ASSOC_CHANGE_EV);
    626 
    627     if (non_block) {
    628 	/* now that we are connected, mark the socket as non-blocking */
    629 	if (!set_nonblock(send_socket)) {
    630 	  perror("netperf: fcntl");
    631 	  exit(1);
    632 	}
    633     }
    634 
    635     /* Data Socket set-up is finished. If there were problems, either */
    636     /* the connect would have failed, or the previous response would */
    637     /* have indicated a problem. I failed to see the value of the */
    638     /* extra  message after the accept on the remote. If it failed, */
    639     /* we'll see it here. If it didn't, we might as well start pumping */
    640     /* data. */
    641 
    642     /* Set-up the test end conditions. For a stream test, they can be */
    643     /* either time or byte-count based. */
    644 
    645     if (test_time) {
    646       /* The user wanted to end the test after a period of time. */
    647       times_up = 0;
    648       bytes_remaining = 0;
    649       /* in previous revisions, we had the same code repeated throught */
    650       /* all the test suites. this was unnecessary, and meant more */
    651       /* work for me when I wanted to switch to POSIX signals, so I */
    652       /* have abstracted this out into a routine in netlib.c. if you */
    653       /* are experiencing signal problems, you might want to look */
    654       /* there. raj 11/94 */
    655       start_timer(test_time);
    656     }
    657     else {
    658       /* The tester wanted to send a number of bytes. */
    659       bytes_remaining = test_bytes;
    660       times_up = 1;
    661     }
    662 
    663     /* The cpu_start routine will grab the current time and possibly */
    664     /* value of the idle counter for later use in measuring cpu */
    665     /* utilization and/or service demand and thruput. */
    666 
    667     cpu_start(local_cpu_usage);
    668 
    669 #ifdef WANT_INTERVALS
    670     if ((interval_burst) || (demo_mode)) {
    671       /* zero means that we never pause, so we never should need the */
    672       /* interval timer, unless we are in demo_mode */
    673       start_itimer(interval_wate);
    674     }
    675     interval_count = interval_burst;
    676     /* get the signal set for the call to sigsuspend */
    677     if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) {
    678       fprintf(where,
    679 	      "send_sctp_stream: unable to get sigmask errno %d\n",
    680 	      errno);
    681       fflush(where);
    682       exit(1);
    683     }
    684 #endif /* WANT_INTERVALS */
    685 
    686 #ifdef DIRTY
    687     /* initialize the random number generator for putting dirty stuff */
    688     /* into the send buffer. raj */
    689     srand((int) getpid());
    690 #endif
    691 
    692     /* before we start, initialize a few variables */
    693 
    694     /* We use an "OR" to control test execution. When the test is */
    695     /* controlled by time, the byte count check will always return false. */
    696     /* When the test is controlled by byte count, the time test will */
    697     /* always return false. When the test is finished, the whole */
    698     /* expression will go false and we will stop sending data. */
    699 
    700     while ((!times_up) || (bytes_remaining > 0)) {
    701 
    702 #ifdef DIRTY
    703       /* we want to dirty some number of consecutive integers in the buffer */
    704       /* we are about to send. we may also want to bring some number of */
    705       /* them cleanly into the cache. The clean ones will follow any dirty */
    706       /* ones into the cache. at some point, we might want to replace */
    707       /* the rand() call with something from a table to reduce our call */
    708       /* overhead during the test, but it is not a high priority item. */
    709       message_int_ptr = (int *)(send_ring->buffer_ptr);
    710       for (i = 0; i < loc_dirty_count; i++) {
    711 	*message_int_ptr = rand();
    712 	message_int_ptr++;
    713       }
    714       for (i = 0; i < loc_clean_count; i++) {
    715 	loc_dirty_count = *message_int_ptr;
    716 	message_int_ptr++;
    717       }
    718 #endif /* DIRTY */
    719 
    720 #ifdef WANT_HISTOGRAM
    721       /* timestamp just before we go into send and then again just after */
    722       /* we come out raj 8/94 */
    723       HIST_timestamp(&time_one);
    724 #endif /* WANT_HISTOGRAM */
    725 
    726       while ((len=sctp_sendmsg(send_socket,
    727 			       send_ring->buffer_ptr, send_size,
    728 			       NULL, 0,
    729 			       0, 0, 0, 0, 0)) != send_size) {
    730 	if (non_block && errno == EAGAIN)
    731 	    continue;
    732 	else if ((len >=0) || SOCKET_EINTR(len)) {
    733 	  /* the test was interrupted, must be the end of test */
    734 	  timed_out = 1;
    735 	  break;
    736 	}
    737 	perror("netperf: data send error");
    738 	printf("len was %d\n",len);
    739 	exit(1);
    740       }
    741 
    742       if (timed_out)
    743 	  break;	/* we timed out durint sendmsg, done with test */
    744 
    745 #ifdef WANT_HISTOGRAM
    746       /* timestamp the exit from the send call and update the histogram */
    747       HIST_timestamp(&time_two);
    748       HIST_add(time_hist,delta_micro(&time_one,&time_two));
    749 #endif /* WANT_HISTOGRAM */
    750 
    751 #ifdef WANT_INTERVALS
    752       if (demo_mode) {
    753 	units_this_tick += send_size;
    754       }
    755       /* in this case, the interval count is the count-down couter */
    756       /* to decide to sleep for a little bit */
    757       if ((interval_burst) && (--interval_count == 0)) {
    758 	/* call sigsuspend and wait for the interval timer to get us */
    759 	/* out */
    760 	if (debug > 1) {
    761 	  fprintf(where,"about to suspend\n");
    762 	  fflush(where);
    763 	}
    764 	if (sigsuspend(&signal_set) == EFAULT) {
    765 	  fprintf(where,
    766 		  "send_sctp_stream: fault with sigsuspend.\n");
    767 	  fflush(where);
    768 	  exit(1);
    769 	}
    770 	interval_count = interval_burst;
    771       }
    772 #endif /* WANT_INTERVALS */
    773 
    774       /* now we want to move our pointer to the next position in the */
    775       /* data buffer...we may also want to wrap back to the "beginning" */
    776       /* of the bufferspace, so we will mod the number of messages sent */
    777       /* by the send width, and use that to calculate the offset to add */
    778       /* to the base pointer. */
    779       nummessages++;
    780       send_ring = send_ring->next;
    781       if (bytes_remaining) {
    782 	bytes_remaining -= send_size;
    783       }
    784     }
    785 
    786     /* The test is over. Flush the buffers to the remote end. We do a */
    787     /* graceful release to insure that all data has been taken by the */
    788     /* remote. */
    789 
    790     /* but first, if the verbosity is greater than 1, find-out what */
    791     /* the sctp maximum segment_size was (if possible) */
    792     if (verbosity > 1) {
    793       sctp_mss = -1;
    794       get_sctp_info(send_socket, &sctp_mss);
    795     }
    796 
    797     shutdown(send_socket, SHUT_WR);
    798 
    799     /* The test server will signal to us when it wants to shutdown.
    800      * In blocking mode, we can call recvmsg.  In non-blocking
    801      * mode, we need to select on the socket for reading.
    802      * We'll assume that all returns are succefull
    803      */
    804     if (non_block) {
    805 	fd_set readfds;
    806 
    807 	FD_ZERO(&readfds);
    808 	FD_SET(send_socket, &readfds);
    809 	select(send_socket+1, &readfds, NULL, NULL, NULL);
    810     } else {
    811 	sctp_recvmsg(send_socket, send_ring->buffer_ptr, send_size, NULL,
    812 		0, NULL, 0);
    813     }
    814 
    815     /* this call will always give us the elapsed time for the test, and */
    816     /* will also store-away the necessaries for cpu utilization */
    817 
    818     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
    819 						/* measured and how */
    820 						/* long did we really */
    821 						/* run? */
    822 
    823     /* we are finished with the socket, so close it to prevent hitting */
    824     /* the limit on maximum open files. */
    825     close(send_socket);
    826 
    827     /* Get the statistics from the remote end. The remote will have */
    828     /* calculated service demand and all those interesting things. If it */
    829     /* wasn't supposed to care, it will return obvious values. */
    830 
    831     recv_response();
    832     if (!netperf_response.content.serv_errno) {
    833       if (debug)
    834 	fprintf(where,"remote results obtained\n");
    835     }
    836     else {
    837       Set_errno(netperf_response.content.serv_errno);
    838       fprintf(where,
    839 	      "netperf: remote error %d",
    840 	      netperf_response.content.serv_errno);
    841       perror("");
    842       fflush(where);
    843 
    844       exit(1);
    845     }
    846 
    847     /* We now calculate what our thruput was for the test. In the future, */
    848     /* we may want to include a calculation of the thruput measured by */
    849     /* the remote, but it should be the case that for a sctp stream test, */
    850     /* that the two numbers should be *very* close... We calculate */
    851     /* bytes_sent regardless of the way the test length was controlled. */
    852     /* If it was time, we needed to, and if it was by bytes, the user may */
    853     /* have specified a number of bytes that wasn't a multiple of the */
    854     /* send_size, so we really didn't send what he asked for ;-) */
    855 
    856     bytes_sent	= ntohd(sctp_stream_result->bytes_received);
    857 
    858     thruput	= (double) calc_thruput(bytes_sent);
    859 
    860     if (local_cpu_usage || remote_cpu_usage) {
    861       /* We must now do a little math for service demand and cpu */
    862       /* utilization for the system(s) */
    863       /* Of course, some of the information might be bogus because */
    864       /* there was no idle counter in the kernel(s). We need to make */
    865       /* a note of this for the user's benefit...*/
    866       if (local_cpu_usage) {
    867 
    868 	local_cpu_utilization	= calc_cpu_util(0.0);
    869 	local_service_demand	= calc_service_demand(bytes_sent,
    870 						      0.0,
    871 						      0.0,
    872 						      0);
    873       }
    874       else {
    875 	local_cpu_utilization	= (float) -1.0;
    876 	local_service_demand	= (float) -1.0;
    877       }
    878 
    879       if (remote_cpu_usage) {
    880 
    881 	remote_cpu_utilization	= sctp_stream_result->cpu_util;
    882 	remote_service_demand	= calc_service_demand(bytes_sent,
    883 						      0.0,
    884 						      remote_cpu_utilization,
    885 						      sctp_stream_result->num_cpus);
    886       }
    887       else {
    888 	remote_cpu_utilization = (float) -1.0;
    889 	remote_service_demand  = (float) -1.0;
    890       }
    891     }
    892     else {
    893       /* we were not measuring cpu, for the confidence stuff, we */
    894       /* should make it -1.0 */
    895       local_cpu_utilization	= (float) -1.0;
    896       local_service_demand	= (float) -1.0;
    897       remote_cpu_utilization = (float) -1.0;
    898       remote_service_demand  = (float) -1.0;
    899     }
    900 
    901     /* at this point, we want to calculate the confidence information. */
    902     /* if debugging is on, calculate_confidence will print-out the */
    903     /* parameters we pass it */
    904 
    905     calculate_confidence(confidence_iteration,
    906 			 elapsed_time,
    907 			 thruput,
    908 			 local_cpu_utilization,
    909 			 remote_cpu_utilization,
    910 			 local_service_demand,
    911 			 remote_service_demand);
    912 
    913 
    914     confidence_iteration++;
    915   }
    916 
    917   /* at this point, we have finished making all the runs that we */
    918   /* will be making. so, we should extract what the calcuated values */
    919   /* are for all the confidence stuff. we could make the values */
    920   /* global, but that seemed a little messy, and it did not seem worth */
    921   /* all the mucking with header files. so, we create a routine much */
    922   /* like calcualte_confidence, which just returns the mean values. */
    923   /* raj 11/94 */
    924 
    925   retrieve_confident_values(&elapsed_time,
    926 			    &thruput,
    927 			    &local_cpu_utilization,
    928 			    &remote_cpu_utilization,
    929 			    &local_service_demand,
    930 			    &remote_service_demand);
    931 
    932   /* We are now ready to print all the information. If the user */
    933   /* has specified zero-level verbosity, we will just print the */
    934   /* local service demand, or the remote service demand. If the */
    935   /* user has requested verbosity level 1, he will get the basic */
    936   /* "streamperf" numbers. If the user has specified a verbosity */
    937   /* of greater than 1, we will display a veritable plethora of */
    938   /* background information from outside of this block as it it */
    939   /* not cpu_measurement specific...  */
    940 
    941   if (confidence < 0) {
    942     /* we did not hit confidence, but were we asked to look for it? */
    943     if (iteration_max > 1) {
    944       display_confidence();
    945     }
    946   }
    947 
    948   if (local_cpu_usage || remote_cpu_usage) {
    949     local_cpu_method = format_cpu_method(cpu_method);
    950     remote_cpu_method = format_cpu_method(sctp_stream_result->cpu_method);
    951 
    952     switch (verbosity) {
    953     case 0:
    954       if (local_cpu_usage) {
    955 	fprintf(where,
    956 		cpu_fmt_0,
    957 		local_service_demand,
    958 		local_cpu_method);
    959       }
    960       else {
    961 	fprintf(where,
    962 		cpu_fmt_0,
    963 		remote_service_demand,
    964 		remote_cpu_method);
    965       }
    966       break;
    967     case 1:
    968     case 2:
    969       if (print_headers) {
    970 	fprintf(where,
    971 		cpu_title,
    972 		format_units(),
    973 		local_cpu_method,
    974 		remote_cpu_method);
    975       }
    976 
    977       fprintf(where,
    978 	      cpu_fmt_1,		/* the format string */
    979 	      rsr_size,		        /* remote recvbuf size */
    980 	      lss_size,		        /* local sendbuf size */
    981 	      send_size,		/* how large were the sends */
    982 	      elapsed_time,		/* how long was the test */
    983 	      thruput, 		        /* what was the xfer rate */
    984 	      local_cpu_utilization,	/* local cpu */
    985 	      remote_cpu_utilization,	/* remote cpu */
    986 	      local_service_demand,	/* local service demand */
    987 	      remote_service_demand);	/* remote service demand */
    988       break;
    989     }
    990   }
    991   else {
    992     /* The tester did not wish to measure service demand. */
    993 
    994     switch (verbosity) {
    995     case 0:
    996       fprintf(where,
    997 	      tput_fmt_0,
    998 	      thruput);
    999       break;
   1000     case 1:
   1001     case 2:
   1002       if (print_headers) {
   1003 	fprintf(where,tput_title,format_units());
   1004       }
   1005       fprintf(where,
   1006 	      tput_fmt_1,		/* the format string */
   1007 	      rsr_size, 		/* remote recvbuf size */
   1008 	      lss_size, 		/* local sendbuf size */
   1009 	      send_size,		/* how large were the sends */
   1010 	      elapsed_time, 		/* how long did it take */
   1011 	      thruput);/* how fast did it go */
   1012       break;
   1013     }
   1014   }
   1015 
   1016   /* it would be a good thing to include information about some of the */
   1017   /* other parameters that may have been set for this test, but at the */
   1018   /* moment, I do not wish to figure-out all the  formatting, so I will */
   1019   /* just put this comment here to help remind me that it is something */
   1020   /* that should be done at a later time. */
   1021 
   1022   if (verbosity > 1) {
   1023     /* The user wanted to know it all, so we will give it to him. */
   1024     /* This information will include as much as we can find about */
   1025     /* sctp statistics, the alignments of the sends and receives */
   1026     /* and all that sort of rot... */
   1027 
   1028     /* this stuff needs to be worked-out in the presence of confidence */
   1029     /* intervals and multiple iterations of the test... raj 11/94 */
   1030 
   1031     fprintf(where,
   1032 	    ksink_fmt,
   1033 	    "Bytes",
   1034 	    "Bytes",
   1035 	    "Bytes",
   1036 	    local_send_align,
   1037 	    remote_recv_align,
   1038 	    local_send_offset,
   1039 	    remote_recv_offset,
   1040 	    bytes_sent,
   1041 	    bytes_sent / (double)nummessages,
   1042 	    nummessages,
   1043 	    bytes_sent / (double)sctp_stream_result->recv_calls,
   1044 	    sctp_stream_result->recv_calls);
   1045     fprintf(where,
   1046 	    ksink_fmt2,
   1047 	    sctp_mss);
   1048     fflush(where);
   1049 #ifdef WANT_HISTOGRAM
   1050     fprintf(where,"\n\nHistogram of time spent in send() call.\n");
   1051     fflush(where);
   1052     HIST_report(time_hist);
   1053 #endif /* WANT_HISTOGRAM */
   1054   }
   1055 
   1056 }
   1057 
   1058 
   1059 
   1061 
   1062 /* This is the server-side routine for the sctp stream test. It is */
   1063 /* implemented as one routine. I could break things-out somewhat, but */
   1064 /* didn't feel it was necessary. */
   1065 
   1066 void
   1067 recv_sctp_stream()
   1068 {
   1069 
   1070   struct sockaddr_in myaddr_in; /* needed to get port number */
   1071   struct sockaddr_storage peeraddr;	/* used in accept */
   1072   int	s_listen,s_data;
   1073   int 	addrlen;
   1074   int	len;
   1075   unsigned int	receive_calls;
   1076   float	elapsed_time;
   1077   double   bytes_received;
   1078 
   1079   struct ring_elt *recv_ring;
   1080 
   1081   struct addrinfo *local_res;
   1082   char local_name[BUFSIZ];
   1083   char port_buffer[PORTBUFSIZE];
   1084   int  msg_flags = 0;
   1085 
   1086 #ifdef DIRTY
   1087   int   *message_int_ptr;
   1088   int   dirty_count;
   1089   int   clean_count;
   1090   int   i;
   1091 #endif
   1092 
   1093 #ifdef DO_SELECT
   1094   fd_set readfds;
   1095   struct timeval timeout;
   1096 #endif /* DO_SELECT */
   1097 
   1098   struct	sctp_stream_request_struct	*sctp_stream_request;
   1099   struct	sctp_stream_response_struct	*sctp_stream_response;
   1100   struct	sctp_stream_results_struct	*sctp_stream_results;
   1101 
   1102 #ifdef DO_SELECT
   1103   FD_ZERO(&readfds);
   1104   timeout.tv_sec = 1;
   1105   timeout.tv_usec = 0;
   1106 #endif /* DO_SELECT */
   1107 
   1108   sctp_stream_request	=
   1109     (struct sctp_stream_request_struct *)netperf_request.content.test_specific_data;
   1110   sctp_stream_response	=
   1111     (struct sctp_stream_response_struct *)netperf_response.content.test_specific_data;
   1112   sctp_stream_results	=
   1113     (struct sctp_stream_results_struct *)netperf_response.content.test_specific_data;
   1114 
   1115   if (debug) {
   1116     fprintf(where,"netserver: recv_sctp_stream: entered...\n");
   1117     fflush(where);
   1118   }
   1119 
   1120   /* We want to set-up the listen socket with all the desired */
   1121   /* parameters and then let the initiator know that all is ready. If */
   1122   /* socket size defaults are to be used, then the initiator will have */
   1123   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   1124   /* send-back what they are. If that information cannot be determined, */
   1125   /* then we send-back -1's for the sizes. If things go wrong for any */
   1126   /* reason, we will drop back ten yards and punt. */
   1127 
   1128   /* If anything goes wrong, we want the remote to know about it. It */
   1129   /* would be best if the error that the remote reports to the user is */
   1130   /* the actual error we encountered, rather than some bogus unexpected */
   1131   /* response type message. */
   1132 
   1133   if (debug) {
   1134     fprintf(where,"recv_sctp_stream: setting the response type...\n");
   1135     fflush(where);
   1136   }
   1137 
   1138   netperf_response.content.response_type = SCTP_STREAM_RESPONSE;
   1139 
   1140   if (debug) {
   1141     fprintf(where,"recv_sctp_stream: the response type is set...\n");
   1142     fflush(where);
   1143   }
   1144 
   1145   /* We now alter the message_ptr variable to be at the desired */
   1146   /* alignment with the desired offset. */
   1147 
   1148   if (debug) {
   1149     fprintf(where,"recv_sctp_stream: requested alignment of %d\n",
   1150 	    sctp_stream_request->recv_alignment);
   1151     fflush(where);
   1152   }
   1153 
   1154   /* create_data_socket expects to find some things in the global */
   1155   /* variables, so set the globals based on the values in the request. */
   1156   /* once the socket has been created, we will set the response values */
   1157   /* based on the updated value of those globals. raj 7/94 */
   1158   lss_size_req = sctp_stream_request->send_buf_size;
   1159   lsr_size_req = sctp_stream_request->recv_buf_size;
   1160   loc_nodelay = sctp_stream_request->no_delay;
   1161   loc_rcvavoid = sctp_stream_request->so_rcvavoid;
   1162   loc_sndavoid = sctp_stream_request->so_sndavoid;
   1163   non_block = sctp_stream_request->non_blocking;
   1164 
   1165   set_hostname_and_port(local_name,
   1166 			port_buffer,
   1167 			nf_to_af(sctp_stream_request->ipfamily),
   1168 			sctp_stream_request->port);
   1169 
   1170   local_res = complete_addrinfo(local_name,
   1171 				local_name,
   1172 				port_buffer,
   1173 				nf_to_af(sctp_stream_request->ipfamily),
   1174 				SOCK_STREAM,
   1175 				IPPROTO_SCTP,
   1176 				0);
   1177 
   1178   s_listen = create_data_socket(local_res);
   1179 
   1180   if (s_listen < 0) {
   1181     netperf_response.content.serv_errno = errno;
   1182     send_response();
   1183     exit(1);
   1184   }
   1185 
   1186   /* what sort of sizes did we end-up with? */
   1187   if (sctp_stream_request->receive_size == 0) {
   1188     if (lsr_size > 0) {
   1189       recv_size = lsr_size;
   1190     }
   1191     else {
   1192       recv_size = 4096;
   1193     }
   1194   }
   1195   else {
   1196     recv_size = sctp_stream_request->receive_size;
   1197   }
   1198 
   1199   /* we want to set-up our recv_ring in a manner analagous to what we */
   1200   /* do on the sending side. this is more for the sake of symmetry */
   1201   /* than for the needs of say copy avoidance, but it might also be */
   1202   /* more realistic - this way one could conceivably go with a */
   1203   /* double-buffering scheme when taking the data an putting it into */
   1204   /* the filesystem or something like that. raj 7/94 */
   1205 
   1206   if (recv_width == 0) {
   1207     recv_width = (lsr_size/recv_size) + 1;
   1208     if (recv_width == 1) recv_width++;
   1209   }
   1210 
   1211   recv_ring = allocate_buffer_ring(recv_width,
   1212 				   recv_size,
   1213 				   sctp_stream_request->recv_alignment,
   1214 				   sctp_stream_request->recv_offset);
   1215 
   1216   if (debug) {
   1217     fprintf(where,"recv_sctp_stream: set recv_size = %d, align = %d, offset = %d.\n",
   1218 		   recv_size, sctp_stream_request->recv_alignment,
   1219 		   sctp_stream_request->recv_offset);
   1220     fflush(where);
   1221   }
   1222 
   1223   /* now get the port number assigned by the system  */
   1224   addrlen = sizeof(myaddr_in);
   1225   if (getsockname(s_listen,
   1226 		  (struct sockaddr *)&myaddr_in,
   1227 		  &addrlen) == -1){
   1228     netperf_response.content.serv_errno = errno;
   1229     close(s_listen);
   1230     send_response();
   1231 
   1232     exit(1);
   1233   }
   1234 
   1235   /* Now myaddr_in contains the port and the internet address this is */
   1236   /* returned to the sender also implicitly telling the sender that the */
   1237   /* socket buffer sizing has been done. */
   1238 
   1239   sctp_stream_response->data_port_number = (int) ntohs(myaddr_in.sin_port);
   1240   netperf_response.content.serv_errno   = 0;
   1241 
   1242   /* But wait, there's more. If the initiator wanted cpu measurements, */
   1243   /* then we must call the calibrate routine, which will return the max */
   1244   /* rate back to the initiator. If the CPU was not to be measured, or */
   1245   /* something went wrong with the calibration, we will return a -1 to */
   1246   /* the initiator. */
   1247 
   1248   sctp_stream_response->cpu_rate = (float)0.0; 	/* assume no cpu */
   1249   if (sctp_stream_request->measure_cpu) {
   1250     sctp_stream_response->measure_cpu = 1;
   1251     sctp_stream_response->cpu_rate =
   1252       calibrate_local_cpu(sctp_stream_request->cpu_rate);
   1253   }
   1254   else {
   1255     sctp_stream_response->measure_cpu = 0;
   1256   }
   1257 
   1258   /* before we send the response back to the initiator, pull some of */
   1259   /* the socket parms from the globals */
   1260   sctp_stream_response->send_buf_size = lss_size;
   1261   sctp_stream_response->recv_buf_size = lsr_size;
   1262   sctp_stream_response->no_delay = loc_nodelay;
   1263   sctp_stream_response->so_rcvavoid = loc_rcvavoid;
   1264   sctp_stream_response->so_sndavoid = loc_sndavoid;
   1265   sctp_stream_response->receive_size = recv_size;
   1266 
   1267   /* Now, let's set-up the socket to listen for connections */
   1268   if (listen(s_listen, 5) == -1) {
   1269     netperf_response.content.serv_errno = errno;
   1270     close(s_listen);
   1271     send_response();
   1272 
   1273     exit(1);
   1274   }
   1275 
   1276   send_response();
   1277 
   1278   addrlen = sizeof(peeraddr);
   1279 
   1280   if ((s_data = accept(s_listen,
   1281 		      (struct sockaddr *)&peeraddr,
   1282 		      &addrlen)) == INVALID_SOCKET) {
   1283     /* Let's just punt. The remote will be given some information */
   1284     close(s_listen);
   1285     exit(1);
   1286   }
   1287 
   1288   sctp_enable_events(s_data, SCTP_ASSOC_CHANGE_EV | SCTP_SHUTDOWN_EV);
   1289 
   1290   /* now that we are connected, mark the socket as non-blocking */
   1291   if (non_block) {
   1292       fprintf(where, "setting socket as nonblocking\n");
   1293       fflush(where);
   1294       if (!set_nonblock(s_data)) {
   1295 	close(s_data);
   1296 	exit(1);
   1297       }
   1298   }
   1299 
   1300 #ifdef KLUDGE_SOCKET_OPTIONS
   1301   /* this is for those systems which *INCORRECTLY* fail to pass */
   1302   /* attributes across an accept() call. Including this goes against */
   1303   /* my better judgement :( raj 11/95 */
   1304 
   1305   kludge_socket_options(s_data);
   1306 
   1307 #endif /* KLUDGE_SOCKET_OPTIONS */
   1308 
   1309   /* Now it's time to start receiving data on the connection. We will */
   1310   /* first grab the apropriate counters and then start grabbing. */
   1311 
   1312   cpu_start(sctp_stream_request->measure_cpu);
   1313 
   1314   /* The loop will exit when the sender does a shutdown, which will */
   1315   /* return a length of zero   */
   1316 
   1317 #ifdef DIRTY
   1318     /* we want to dirty some number of consecutive integers in the buffer */
   1319     /* we are about to recv. we may also want to bring some number of */
   1320     /* them cleanly into the cache. The clean ones will follow any dirty */
   1321     /* ones into the cache. */
   1322 
   1323   dirty_count = sctp_stream_request->dirty_count;
   1324   clean_count = sctp_stream_request->clean_count;
   1325   message_int_ptr = (int *)recv_ring->buffer_ptr;
   1326   for (i = 0; i < dirty_count; i++) {
   1327     *message_int_ptr = rand();
   1328     message_int_ptr++;
   1329   }
   1330   for (i = 0; i < clean_count; i++) {
   1331     dirty_count = *message_int_ptr;
   1332     message_int_ptr++;
   1333   }
   1334 #endif /* DIRTY */
   1335 
   1336   bytes_received = 0;
   1337   receive_calls  = 0;
   1338 
   1339   while ((len = sctp_recvmsg(s_data,
   1340 			    recv_ring->buffer_ptr, recv_size,
   1341 			    NULL, 0, NULL, &msg_flags)) != 0) {
   1342     if (len == SOCKET_ERROR) {
   1343 	if (non_block && errno == EAGAIN) {
   1344 	   if (debug){
   1345 	     fprintf(where,
   1346 		    "recv_sctp_stream: sctp_recvmsg timed out, trying again\n");
   1347 	     fflush(where);
   1348 	   }
   1349 	   Set_errno(0);
   1350 	   continue;
   1351 	}
   1352 	if (debug) {
   1353 	    fprintf(where,
   1354 		    "recv_sctp_stream: sctp_recvmsg error %d, exiting",
   1355 		    errno);
   1356 	    fflush(where);
   1357         }
   1358 	netperf_response.content.serv_errno = errno;
   1359 	send_response();
   1360 	close(s_data);
   1361 	exit(1);
   1362     }
   1363 
   1364     if (msg_flags & MSG_NOTIFICATION) {
   1365 	 msg_flags = 0;
   1366 	 if (debug) {
   1367 	   fprintf(where,
   1368 		    "recv_sctp_stream: Got notification... processing\n");
   1369 	     fflush(where);
   1370 	}
   1371 	if (sctp_process_event(s_data, recv_ring->buffer_ptr) == SCTP_CLOSE)
   1372 	    break;	/* break out of the recvmsg loop */
   1373 
   1374 	continue;
   1375     }
   1376 
   1377     bytes_received += len;
   1378     receive_calls++;
   1379 
   1380     /* more to the next buffer in the recv_ring */
   1381     recv_ring = recv_ring->next;
   1382 
   1383 #ifdef PAUSE
   1384     sleep(1);
   1385 #endif /* PAUSE */
   1386 
   1387 #ifdef DIRTY
   1388     message_int_ptr = (int *)(recv_ring->buffer_ptr);
   1389     for (i = 0; i < dirty_count; i++) {
   1390       *message_int_ptr = rand();
   1391       message_int_ptr++;
   1392     }
   1393     for (i = 0; i < clean_count; i++) {
   1394       dirty_count = *message_int_ptr;
   1395       message_int_ptr++;
   1396     }
   1397 #endif /* DIRTY */
   1398 
   1399 #ifdef DO_SELECT
   1400 	FD_SET(s_data,&readfds);
   1401 	select(s_data+1,&readfds,NULL,NULL,&timeout);
   1402 #endif /* DO_SELECT */
   1403 
   1404   }
   1405 
   1406   /* perform a shutdown to signal the sender that */
   1407   /* we have received all the data sent. raj 4/93 */
   1408 
   1409   if (close(s_data) == -1) {
   1410       netperf_response.content.serv_errno = errno;
   1411       send_response();
   1412       exit(1);
   1413     }
   1414 
   1415   cpu_stop(sctp_stream_request->measure_cpu,&elapsed_time);
   1416 
   1417   /* send the results to the sender			*/
   1418 
   1419   if (debug) {
   1420     fprintf(where,
   1421 	    "recv_sctp_stream: got %g bytes\n",
   1422 	    bytes_received);
   1423     fprintf(where,
   1424 	    "recv_sctp_stream: got %d recvs\n",
   1425 	    receive_calls);
   1426     fflush(where);
   1427   }
   1428 
   1429   sctp_stream_results->bytes_received	= htond(bytes_received);
   1430   sctp_stream_results->elapsed_time	= elapsed_time;
   1431   sctp_stream_results->recv_calls	= receive_calls;
   1432 
   1433   if (sctp_stream_request->measure_cpu) {
   1434     sctp_stream_results->cpu_util	= calc_cpu_util(0.0);
   1435   };
   1436 
   1437   if (debug) {
   1438     fprintf(where,
   1439 	    "recv_sctp_stream: test complete, sending results.\n");
   1440     fprintf(where,
   1441 	    "                 bytes_received %g receive_calls %d\n",
   1442 	    bytes_received,
   1443 	    receive_calls);
   1444     fprintf(where,
   1445 	    "                 len %d\n",
   1446 	    len);
   1447     fflush(where);
   1448   }
   1449 
   1450   sctp_stream_results->cpu_method = cpu_method;
   1451   sctp_stream_results->num_cpus   = lib_num_loc_cpus;
   1452   send_response();
   1453 
   1454   /* we are now done with the sockets */
   1455   close(s_listen);
   1456 
   1457 }
   1458 
   1459 
   1461 /* This routine implements the SCTP unidirectional data transfer test */
   1462 /* (a.k.a. stream) for the sockets interface. It receives its */
   1463 /* parameters via global variables from the shell and writes its */
   1464 /* output to the standard output. */
   1465 
   1466 
   1467 void
   1468 send_sctp_stream_1toMany(remote_host)
   1469 char	remote_host[];
   1470 {
   1471 
   1472   char *tput_title = "\
   1473 Recv   Send    Send                          \n\
   1474 Socket Socket  Message  Elapsed              \n\
   1475 Size   Size    Size     Time     Throughput  \n\
   1476 bytes  bytes   bytes    secs.    %s/sec  \n\n";
   1477 
   1478   char *tput_fmt_0 =
   1479     "%7.2f\n";
   1480 
   1481   char *tput_fmt_1 =
   1482     "%6d %6d %6d    %-6.2f   %7.2f   \n";
   1483 
   1484   char *cpu_title = "\
   1485 Recv   Send    Send                          Utilization       Service Demand\n\
   1486 Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
   1487 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
   1488 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
   1489 
   1490   char *cpu_fmt_0 =
   1491     "%6.3f %c\n";
   1492 
   1493   char *cpu_fmt_1 =
   1494     "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f\n";
   1495 
   1496   char *ksink_fmt = "\n\
   1497 Alignment      Offset         %-8.8s %-8.8s    Sends   %-8.8s Recvs\n\
   1498 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
   1499 Send   Recv    Send   Recv             Send (avg)          Recv (avg)\n\
   1500 %5d   %5d  %5d   %5d %6.4g  %6.2f    %6d   %6.2f %6d\n";
   1501 
   1502   char *ksink_fmt2 = "\n\
   1503 Maximum\n\
   1504 Segment\n\
   1505 Size (bytes)\n\
   1506 %6d\n";
   1507 
   1508 
   1509   float			elapsed_time;
   1510 
   1511 #ifdef WANT_INTERVALS
   1512   int interval_count;
   1513   sigset_t signal_set;
   1514 #endif
   1515 
   1516   /* what we want is to have a buffer space that is at least one */
   1517   /* send-size greater than our send window. this will insure that we */
   1518   /* are never trying to re-use a buffer that may still be in the hands */
   1519   /* of the transport. This buffer will be malloc'd after we have found */
   1520   /* the size of the local senc socket buffer. We will want to deal */
   1521   /* with alignment and offset concerns as well. */
   1522 
   1523 #ifdef DIRTY
   1524   int	*message_int_ptr;
   1525 #endif
   1526 
   1527   struct ring_elt *send_ring;
   1528 
   1529   int len;
   1530   unsigned int nummessages = 0;
   1531   int *send_socket;
   1532   int bytes_remaining;
   1533   int sctp_mss;
   1534 
   1535   /* with links like fddi, one can send > 32 bits worth of bytes */
   1536   /* during a test... ;-) at some point, this should probably become a */
   1537   /* 64bit integral type, but those are not entirely common yet */
   1538   double	bytes_sent = 0.0;
   1539 
   1540 #ifdef DIRTY
   1541   int	i;
   1542 #endif /* DIRTY */
   1543   int j;
   1544 
   1545   float	local_cpu_utilization;
   1546   float	local_service_demand;
   1547   float	remote_cpu_utilization;
   1548   float	remote_service_demand;
   1549 
   1550   double	thruput;
   1551 
   1552   struct addrinfo *remote_res;
   1553   struct addrinfo *local_res;
   1554   struct addrinfo *last_remote_res;
   1555   struct addrinfo *last_local_res;
   1556 
   1557   struct	sctp_stream_request_struct	*sctp_stream_request;
   1558   struct	sctp_stream_response_struct	*sctp_stream_response;
   1559   struct	sctp_stream_results_struct	*sctp_stream_result;
   1560 
   1561   sctp_stream_request  =
   1562     (struct sctp_stream_request_struct *)netperf_request.content.test_specific_data;
   1563   sctp_stream_response =
   1564     (struct sctp_stream_response_struct *)netperf_response.content.test_specific_data;
   1565   sctp_stream_result   =
   1566     (struct sctp_stream_results_struct *)netperf_response.content.test_specific_data;
   1567 
   1568 #ifdef WANT_HISTOGRAM
   1569   time_hist = HIST_new();
   1570 #endif /* WANT_HISTOGRAM */
   1571 
   1572   complete_addrinfos(&remote_res,
   1573 		     &local_res,
   1574 		     remote_host,
   1575 		     SOCK_SEQPACKET,
   1576 		     IPPROTO_SCTP,
   1577 		     0);
   1578 
   1579   if ( print_headers ) {
   1580     print_top_test_header("SCTP 1-TO-MANY STREAM TEST",local_res,remote_res);
   1581   }
   1582 
   1583   send_ring = NULL;
   1584   confidence_iteration = 1;
   1585   init_stat();
   1586 
   1587   send_socket = malloc(sizeof (int) * num_associations);
   1588   if (send_socket == NULL) {
   1589       fprintf(where, "send_sctp_stream_1toMany: failed to allocation sockets!\n");
   1590       exit(1);
   1591   }
   1592 
   1593   /* we have a great-big while loop which controls the number of times */
   1594   /* we run a particular test. this is for the calculation of a */
   1595   /* confidence interval (I really should have stayed awake during */
   1596   /* probstats :). If the user did not request confidence measurement */
   1597   /* (no confidence is the default) then we will only go though the */
   1598   /* loop once. the confidence stuff originates from the folks at IBM */
   1599 
   1600   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   1601 	 (confidence_iteration <= iteration_min)) {
   1602 
   1603     int		j=0;
   1604     int		timed_out = 0;
   1605 
   1606 
   1607     /* initialize a few counters. we have to remember that we might be */
   1608     /* going through the loop more than once. */
   1609 
   1610     nummessages    =	0;
   1611     bytes_sent     =	0.0;
   1612     times_up       = 	0;
   1613 
   1614     /* at this point, we have either retrieved the socket buffer sizes, */
   1615     /* or have tried to set them, so now, we may want to set the send */
   1616     /* size based on that (because the user either did not use a -m */
   1617     /* option, or used one with an argument of 0). If the socket buffer */
   1618     /* size is not available, we will set the send size to 4KB - no */
   1619     /* particular reason, just arbitrary... */
   1620     if (send_size == 0) {
   1621       if (lss_size > 0) {
   1622 	send_size = lss_size;
   1623       }
   1624       else {
   1625 	send_size = 4096;
   1626       }
   1627     }
   1628 
   1629     /* set-up the data buffer ring with the requested alignment and offset. */
   1630     /* note also that we have allocated a quantity */
   1631     /* of memory that is at least one send-size greater than our socket */
   1632     /* buffer size. We want to be sure that there are at least two */
   1633     /* buffers allocated - this can be a bit of a problem when the */
   1634     /* send_size is bigger than the socket size, so we must check... the */
   1635     /* user may have wanted to explicitly set the "width" of our send */
   1636     /* buffers, we should respect that wish... */
   1637     if (send_width == 0) {
   1638       send_width = (lss_size/send_size) + 1;
   1639       if (send_width == 1) send_width++;
   1640     }
   1641 
   1642     if (send_ring == NULL) {
   1643       /* only allocate the send ring once. this is a networking test, */
   1644       /* not a memory allocation test. this way, we do not need a */
   1645       /* deallocate_buffer_ring() routine, and I don't feel like */
   1646       /* writing one anyway :) raj 11/94 */
   1647       send_ring = allocate_buffer_ring(send_width,
   1648 				       send_size,
   1649 				       local_send_align,
   1650 				       local_send_offset);
   1651     }
   1652 
   1653     /* If the user has requested cpu utilization measurements, we must */
   1654     /* calibrate the cpu(s). We will perform this task within the tests */
   1655     /* themselves. If the user has specified the cpu rate, then */
   1656     /* calibrate_local_cpu will return rather quickly as it will have */
   1657     /* nothing to do. If local_cpu_rate is zero, then we will go through */
   1658     /* all the "normal" calibration stuff and return the rate back. */
   1659 
   1660     if (local_cpu_usage) {
   1661       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   1662     }
   1663 
   1664     /* Tell the remote end to do a listen. The server alters the socket */
   1665     /* paramters on the other side at this point, hence the reason for */
   1666     /* all the values being passed in the setup message. If the user did */
   1667     /* not specify any of the parameters, they will be passed as 0, which */
   1668     /* will indicate to the remote that no changes beyond the system's */
   1669     /* default should be used. Alignment is the exception, it will */
   1670     /* default to 1, which will be no alignment alterations. */
   1671 
   1672     netperf_request.content.request_type	=	DO_SCTP_STREAM_MANY;
   1673     sctp_stream_request->send_buf_size	=	rss_size_req;
   1674     sctp_stream_request->recv_buf_size	=	rsr_size_req;
   1675     sctp_stream_request->receive_size	=	recv_size;
   1676     sctp_stream_request->no_delay	=	rem_nodelay;
   1677     sctp_stream_request->recv_alignment	=	remote_recv_align;
   1678     sctp_stream_request->recv_offset	=	remote_recv_offset;
   1679     sctp_stream_request->measure_cpu	=	remote_cpu_usage;
   1680     sctp_stream_request->cpu_rate	=	remote_cpu_rate;
   1681     if (test_time) {
   1682       sctp_stream_request->test_length	=	test_time;
   1683     }
   1684     else {
   1685       if (msg_count)
   1686 	  test_bytes = send_size * msg_count;
   1687 
   1688       sctp_stream_request->test_length	=	test_bytes*num_associations;
   1689     }
   1690     sctp_stream_request->so_rcvavoid	=	rem_rcvavoid;
   1691     sctp_stream_request->so_sndavoid	=	rem_sndavoid;
   1692 #ifdef DIRTY
   1693     sctp_stream_request->dirty_count    =       rem_dirty_count;
   1694     sctp_stream_request->clean_count    =       rem_clean_count;
   1695 #endif /* DIRTY */
   1696     sctp_stream_request->port		= 	(atoi(remote_data_port));
   1697     sctp_stream_request->ipfamily	=	af_to_nf(remote_res->ai_family);
   1698     sctp_stream_request->non_blocking   =	non_block;
   1699 
   1700 
   1701     if (debug > 1) {
   1702       fprintf(where,
   1703 	      "netperf: send_sctp_stream_1toMany: requesting sctp stream test\n");
   1704     }
   1705 
   1706     send_request();
   1707 
   1708     /* The response from the remote will contain all of the relevant 	*/
   1709     /* socket parameters for this test type. We will put them back into */
   1710     /* the variables here so they can be displayed if desired.  The	*/
   1711     /* remote will have calibrated CPU if necessary, and will have done	*/
   1712     /* all the needed set-up we will have calibrated the cpu locally	*/
   1713     /* before sending the request, and will grab the counter value right*/
   1714     /* after the connect returns. The remote will grab the counter right*/
   1715     /* after the accept call. This saves the hassle of extra messages	*/
   1716     /* being sent for the sctp tests.					*/
   1717 
   1718     recv_response();
   1719 
   1720     if (!netperf_response.content.serv_errno) {
   1721       if (debug)
   1722 	fprintf(where,"remote listen done.\n");
   1723       rsr_size	      =	sctp_stream_response->recv_buf_size;
   1724       rss_size	      =	sctp_stream_response->send_buf_size;
   1725       rem_nodelay     =	sctp_stream_response->no_delay;
   1726       remote_cpu_usage=	sctp_stream_response->measure_cpu;
   1727       remote_cpu_rate = sctp_stream_response->cpu_rate;
   1728 
   1729       /* we have to make sure that the server port number is in */
   1730       /* network order */
   1731       set_port_number(remote_res, (unsigned short)sctp_stream_response->data_port_number);
   1732       rem_rcvavoid	= sctp_stream_response->so_rcvavoid;
   1733       rem_sndavoid	= sctp_stream_response->so_sndavoid;
   1734     }
   1735     else {
   1736       Set_errno(netperf_response.content.serv_errno);
   1737       fprintf(where,
   1738 	      "netperf: remote error %d",
   1739 	      netperf_response.content.serv_errno);
   1740       perror("");
   1741       fflush(where);
   1742 
   1743       exit(1);
   1744     }
   1745 
   1746     /*set up the the array of data sockets  and connect them to the server */
   1747 
   1748     for (j = 0; j < num_associations; j++) {
   1749 	send_socket[j] = create_data_socket(local_res);
   1750 
   1751 	if (send_socket[j] < 0){
   1752 	  perror("netperf: send_sctp_stream_1toMany: sctp stream data socket");
   1753 	  exit(1);
   1754 	}
   1755 
   1756 	if (debug) {
   1757 	  fprintf(where,"send_sctp_stream_1toMany: send_socket obtained...\n");
   1758 	}
   1759 
   1760 	/*Connect up to the remote port on the data socket  */
   1761 	if (connect(send_socket[j],
   1762 		    remote_res->ai_addr,
   1763 		    remote_res->ai_addrlen) == INVALID_SOCKET){
   1764 	  perror("netperf: send_sctp_stream_1toMany: data socket connect failed");
   1765 	  exit(1);
   1766 	}
   1767 
   1768 	/* Do it after connect is successfull, so that we don't see COMM_UP */
   1769 	sctp_enable_events(send_socket[j], SCTP_ASSOC_CHANGE_EV);
   1770 
   1771 	if (non_block) {
   1772 	    /* now that we are connected, mark the socket as non-blocking */
   1773 	    if (!set_nonblock(send_socket[j])) {
   1774 	      perror("netperf: fcntl");
   1775 	      exit(1);
   1776 	    }
   1777 	}
   1778     }
   1779 
   1780     /* Data Socket set-up is finished. If there were problems, either */
   1781     /* the connect would have failed, or the previous response would */
   1782     /* have indicated a problem. I failed to see the value of the */
   1783     /* extra  message after the accept on the remote. If it failed, */
   1784     /* we'll see it here. If it didn't, we might as well start pumping */
   1785     /* data. */
   1786 
   1787     /* Set-up the test end conditions. For a stream test, they can be */
   1788     /* either time or byte-count based. */
   1789 
   1790     if (test_time) {
   1791       /* The user wanted to end the test after a period of time. */
   1792       times_up = 0;
   1793       bytes_remaining = 0;
   1794       /* in previous revisions, we had the same code repeated throught */
   1795       /* all the test suites. this was unnecessary, and meant more */
   1796       /* work for me when I wanted to switch to POSIX signals, so I */
   1797       /* have abstracted this out into a routine in netlib.c. if you */
   1798       /* are experiencing signal problems, you might want to look */
   1799       /* there. raj 11/94 */
   1800       start_timer(test_time);
   1801     }
   1802     else {
   1803       /* The tester wanted to send a number of bytes. */
   1804       bytes_remaining = test_bytes * num_associations;
   1805       times_up = 1;
   1806     }
   1807 
   1808     /* The cpu_start routine will grab the current time and possibly */
   1809     /* value of the idle counter for later use in measuring cpu */
   1810     /* utilization and/or service demand and thruput. */
   1811 
   1812     cpu_start(local_cpu_usage);
   1813 
   1814 #ifdef WANT_INTERVALS
   1815     if ((interval_burst) || (demo_mode)) {
   1816       /* zero means that we never pause, so we never should need the */
   1817       /* interval timer, unless we are in demo_mode */
   1818       start_itimer(interval_wate);
   1819     }
   1820     interval_count = interval_burst;
   1821     /* get the signal set for the call to sigsuspend */
   1822     if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) {
   1823       fprintf(where,
   1824 	      "send_sctp_stream_1toMany: unable to get sigmask errno %d\n",
   1825 	      errno);
   1826       fflush(where);
   1827       exit(1);
   1828     }
   1829 #endif /* WANT_INTERVALS */
   1830 
   1831 #ifdef DIRTY
   1832     /* initialize the random number generator for putting dirty stuff */
   1833     /* into the send buffer. raj */
   1834     srand((int) getpid());
   1835 #endif
   1836 
   1837     /* before we start, initialize a few variables */
   1838 
   1839     /* We use an "OR" to control test execution. When the test is */
   1840     /* controlled by time, the byte count check will always return false. */
   1841     /* When the test is controlled by byte count, the time test will */
   1842     /* always return false. When the test is finished, the whole */
   1843     /* expression will go false and we will stop sending data. */
   1844 
   1845     while ((!times_up) || (bytes_remaining > 0)) {
   1846 
   1847 #ifdef DIRTY
   1848       /* we want to dirty some number of consecutive integers in the buffer */
   1849       /* we are about to send. we may also want to bring some number of */
   1850       /* them cleanly into the cache. The clean ones will follow any dirty */
   1851       /* ones into the cache. at some point, we might want to replace */
   1852       /* the rand() call with something from a table to reduce our call */
   1853       /* overhead during the test, but it is not a high priority item. */
   1854       message_int_ptr = (int *)(send_ring->buffer_ptr);
   1855       for (i = 0; i < loc_dirty_count; i++) {
   1856 	*message_int_ptr = rand();
   1857 	message_int_ptr++;
   1858       }
   1859       for (i = 0; i < loc_clean_count; i++) {
   1860 	loc_dirty_count = *message_int_ptr;
   1861 	message_int_ptr++;
   1862       }
   1863 #endif /* DIRTY */
   1864 
   1865 #ifdef WANT_HISTOGRAM
   1866       /* timestamp just before we go into send and then again just after */
   1867       /* we come out raj 8/94 */
   1868       gettimeofday(&time_one,NULL);
   1869 #endif /* WANT_HISTOGRAM */
   1870 
   1871       for (j = 0; j < num_associations; j++) {
   1872 
   1873 	  if((len=sctp_sendmsg(send_socket[j],
   1874 			       send_ring->buffer_ptr,
   1875 			       send_size,
   1876 			       (struct sockaddr *)remote_res->ai_addr,
   1877 			       remote_res->ai_addrlen,
   1878 			       0, 0, 0, 0, 0)) != send_size) {
   1879 	    if ((len >=0) || SOCKET_EINTR(len)) {
   1880 	      /* the test was interrupted, must be the end of test */
   1881 	      timed_out = 1;
   1882 	      break;
   1883 	    } else if (non_block && errno == EAGAIN) {
   1884 		j--;	 /* send again on the same socket */
   1885 		Set_errno(0);
   1886 		continue;
   1887 	    }
   1888 	    perror("netperf: data send error");
   1889 	    printf("len was %d\n",len);
   1890 	    exit(1);
   1891 	  }
   1892       }
   1893 
   1894       if (timed_out)
   1895 	  break;	/* test is over, try next iteration */
   1896 
   1897 #ifdef WANT_HISTOGRAM
   1898       /* timestamp the exit from the send call and update the histogram */
   1899       gettimeofday(&time_two,NULL);
   1900       HIST_add(time_hist,delta_micro(&time_one,&time_two));
   1901 #endif /* WANT_HISTOGRAM */
   1902 
   1903 #ifdef WANT_INTERVALS
   1904       if (demo_mode) {
   1905 	units_this_tick += send_size;
   1906       }
   1907       /* in this case, the interval count is the count-down couter */
   1908       /* to decide to sleep for a little bit */
   1909       if ((interval_burst) && (--interval_count == 0)) {
   1910 	/* call sigsuspend and wait for the interval timer to get us */
   1911 	/* out */
   1912 	if (debug > 1) {
   1913 	  fprintf(where,"about to suspend\n");
   1914 	  fflush(where);
   1915 	}
   1916 	if (sigsuspend(&signal_set) == EFAULT) {
   1917 	  fprintf(where,
   1918 		  "send_sctp_stream_1toMany: fault with sigsuspend.\n");
   1919 	  fflush(where);
   1920 	  exit(1);
   1921 	}
   1922 	interval_count = interval_burst;
   1923       }
   1924 #endif /* WANT_INTERVALS */
   1925 
   1926       /* now we want to move our pointer to the next position in the */
   1927       /* data buffer...we may also want to wrap back to the "beginning" */
   1928       /* of the bufferspace, so we will mod the number of messages sent */
   1929       /* by the send width, and use that to calculate the offset to add */
   1930       /* to the base pointer. */
   1931       nummessages++;
   1932       send_ring = send_ring->next;
   1933       if (bytes_remaining) {
   1934 	bytes_remaining -= send_size;
   1935       }
   1936     }
   1937 
   1938     /* The test is over. Flush the buffers to the remote end. We do a */
   1939     /* graceful release to insure that all data has been taken by the */
   1940     /* remote. */
   1941 
   1942     /* but first, if the verbosity is greater than 1, find-out what */
   1943     /* the sctp maximum segment_size was (if possible) */
   1944     if (verbosity > 1) {
   1945       sctp_mss = -1;
   1946       get_sctp_info(send_socket[0], &sctp_mss);
   1947     }
   1948 
   1949     /* signal the server that we are all done writing, this will
   1950      * initiate a shutdonw of one of the associations on the
   1951      * server and trigger an event telling the server it's all done
   1952      */
   1953     sctp_sendmsg(send_socket[0], NULL, 0, remote_res->ai_addr,
   1954 		 remote_res->ai_addrlen, 0, MSG_EOF, 0, 0, 0);
   1955 
   1956 
   1957     /* The test server will initiate closure of all associations
   1958      * when it's done reading. We want a basic mechanism to catch this
   1959      * and are using SCTP events for this.
   1960      * In blocking mode, we can call recvmsg with the last socket we created.
   1961      * In non-blocking  mode, we need to select on the socket for reading.
   1962      * We'll assume that all returns are succefull and signify
   1963      * closure.
   1964      * It is sufficient to do this on a single socket in the client.
   1965      * We choose to do it on a socket other then the one that send MSG_EOF.
   1966      * This means that anything comming in on that socket will be a shutdown.
   1967      */
   1968     if (non_block) {
   1969 	fd_set readfds;
   1970 
   1971 	FD_ZERO(&readfds);
   1972 	FD_SET(send_socket[num_associations-1], &readfds);
   1973 	select(send_socket[num_associations-1]+1, &readfds, NULL, NULL, NULL);
   1974     } else {
   1975 	sctp_recvmsg(send_socket[num_associations], send_ring->buffer_ptr,
   1976 		     send_size, NULL, 0, NULL, 0);
   1977     }
   1978 
   1979     /* this call will always give us the elapsed time for the test, and */
   1980     /* will also store-away the necessaries for cpu utilization */
   1981 
   1982     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
   1983 						/* measured and how */
   1984 						/* long did we really */
   1985 						/* run? */
   1986 
   1987     /* we are finished with our sockets, so close them to prevent hitting */
   1988     /* the limit on maximum open files. */
   1989     for (j = 0; j < num_associations; j++)
   1990 	close(send_socket[j]);
   1991 
   1992     /* Get the statistics from the remote end. The remote will have */
   1993     /* calculated service demand and all those interesting things. If it */
   1994     /* wasn't supposed to care, it will return obvious values. */
   1995 
   1996     recv_response();
   1997     if (!netperf_response.content.serv_errno) {
   1998       if (debug)
   1999 	fprintf(where,"remote results obtained\n");
   2000     }
   2001     else {
   2002       Set_errno(netperf_response.content.serv_errno);
   2003       fprintf(where,
   2004 	      "netperf: remote error %d",
   2005 	      netperf_response.content.serv_errno);
   2006       perror("");
   2007       fflush(where);
   2008 
   2009       exit(1);
   2010     }
   2011 
   2012     /* We now calculate what our thruput was for the test. In the future, */
   2013     /* we may want to include a calculation of the thruput measured by */
   2014     /* the remote, but it should be the case that for a sctp stream test, */
   2015     /* that the two numbers should be *very* close... We calculate */
   2016     /* bytes_sent regardless of the way the test length was controlled. */
   2017     /* If it was time, we needed to, and if it was by bytes, the user may */
   2018     /* have specified a number of bytes that wasn't a multiple of the */
   2019     /* send_size, so we really didn't send what he asked for ;-) */
   2020 
   2021     bytes_sent	= ntohd(sctp_stream_result->bytes_received);
   2022 
   2023     thruput	= (double) calc_thruput(bytes_sent);
   2024 
   2025     if (local_cpu_usage || remote_cpu_usage) {
   2026       /* We must now do a little math for service demand and cpu */
   2027       /* utilization for the system(s) */
   2028       /* Of course, some of the information might be bogus because */
   2029       /* there was no idle counter in the kernel(s). We need to make */
   2030       /* a note of this for the user's benefit...*/
   2031       if (local_cpu_usage) {
   2032 
   2033 	local_cpu_utilization	= calc_cpu_util(0.0);
   2034 	local_service_demand	= calc_service_demand(bytes_sent,
   2035 						      0.0,
   2036 						      0.0,
   2037 						      0);
   2038       }
   2039       else {
   2040 	local_cpu_utilization	= (float) -1.0;
   2041 	local_service_demand	= (float) -1.0;
   2042       }
   2043 
   2044       if (remote_cpu_usage) {
   2045 
   2046 	remote_cpu_utilization	= sctp_stream_result->cpu_util;
   2047 	remote_service_demand	= calc_service_demand(bytes_sent,
   2048 						      0.0,
   2049 						      remote_cpu_utilization,
   2050 						      sctp_stream_result->num_cpus);
   2051       }
   2052       else {
   2053 	remote_cpu_utilization = (float) -1.0;
   2054 	remote_service_demand  = (float) -1.0;
   2055       }
   2056     }
   2057     else {
   2058       /* we were not measuring cpu, for the confidence stuff, we */
   2059       /* should make it -1.0 */
   2060       local_cpu_utilization	= (float) -1.0;
   2061       local_service_demand	= (float) -1.0;
   2062       remote_cpu_utilization = (float) -1.0;
   2063       remote_service_demand  = (float) -1.0;
   2064     }
   2065 
   2066     /* at this point, we want to calculate the confidence information. */
   2067     /* if debugging is on, calculate_confidence will print-out the */
   2068     /* parameters we pass it */
   2069 
   2070     calculate_confidence(confidence_iteration,
   2071 			 elapsed_time,
   2072 			 thruput,
   2073 			 local_cpu_utilization,
   2074 			 remote_cpu_utilization,
   2075 			 local_service_demand,
   2076 			 remote_service_demand);
   2077 
   2078 
   2079     confidence_iteration++;
   2080   }
   2081 
   2082   /* at this point, we have finished making all the runs that we */
   2083   /* will be making. so, we should extract what the calcuated values */
   2084   /* are for all the confidence stuff. we could make the values */
   2085   /* global, but that seemed a little messy, and it did not seem worth */
   2086   /* all the mucking with header files. so, we create a routine much */
   2087   /* like calcualte_confidence, which just returns the mean values. */
   2088   /* raj 11/94 */
   2089 
   2090   retrieve_confident_values(&elapsed_time,
   2091 			    &thruput,
   2092 			    &local_cpu_utilization,
   2093 			    &remote_cpu_utilization,
   2094 			    &local_service_demand,
   2095 			    &remote_service_demand);
   2096 
   2097   /* We are now ready to print all the information. If the user */
   2098   /* has specified zero-level verbosity, we will just print the */
   2099   /* local service demand, or the remote service demand. If the */
   2100   /* user has requested verbosity level 1, he will get the basic */
   2101   /* "streamperf" numbers. If the user has specified a verbosity */
   2102   /* of greater than 1, we will display a veritable plethora of */
   2103   /* background information from outside of this block as it it */
   2104   /* not cpu_measurement specific...  */
   2105 
   2106   if (confidence < 0) {
   2107     /* we did not hit confidence, but were we asked to look for it? */
   2108     if (iteration_max > 1) {
   2109       display_confidence();
   2110     }
   2111   }
   2112 
   2113   if (local_cpu_usage || remote_cpu_usage) {
   2114     local_cpu_method = format_cpu_method(cpu_method);
   2115     remote_cpu_method = format_cpu_method(sctp_stream_result->cpu_method);
   2116 
   2117     switch (verbosity) {
   2118     case 0:
   2119       if (local_cpu_usage) {
   2120 	fprintf(where,
   2121 		cpu_fmt_0,
   2122 		local_service_demand,
   2123 		local_cpu_method);
   2124       }
   2125       else {
   2126 	fprintf(where,
   2127 		cpu_fmt_0,
   2128 		remote_service_demand,
   2129 		remote_cpu_method);
   2130       }
   2131       break;
   2132     case 1:
   2133     case 2:
   2134       if (print_headers) {
   2135 	fprintf(where,
   2136 		cpu_title,
   2137 		format_units(),
   2138 		local_cpu_method,
   2139 		remote_cpu_method);
   2140       }
   2141 
   2142       fprintf(where,
   2143 	      cpu_fmt_1,		/* the format string */
   2144 	      rsr_size,		        /* remote recvbuf size */
   2145 	      lss_size,		        /* local sendbuf size */
   2146 	      send_size,		/* how large were the sends */
   2147 	      elapsed_time,		/* how long was the test */
   2148 	      thruput, 		        /* what was the xfer rate */
   2149 	      local_cpu_utilization,	/* local cpu */
   2150 	      remote_cpu_utilization,	/* remote cpu */
   2151 	      local_service_demand,	/* local service demand */
   2152 	      remote_service_demand);	/* remote service demand */
   2153       break;
   2154     }
   2155   }
   2156   else {
   2157     /* The tester did not wish to measure service demand. */
   2158 
   2159     switch (verbosity) {
   2160     case 0:
   2161       fprintf(where,
   2162 	      tput_fmt_0,
   2163 	      thruput);
   2164       break;
   2165     case 1:
   2166     case 2:
   2167       if (print_headers) {
   2168 	fprintf(where,tput_title,format_units());
   2169       }
   2170       fprintf(where,
   2171 	      tput_fmt_1,		/* the format string */
   2172 	      rsr_size, 		/* remote recvbuf size */
   2173 	      lss_size, 		/* local sendbuf size */
   2174 	      send_size,		/* how large were the sends */
   2175 	      elapsed_time, 		/* how long did it take */
   2176 	      thruput);/* how fast did it go */
   2177       break;
   2178     }
   2179   }
   2180 
   2181   /* it would be a good thing to include information about some of the */
   2182   /* other parameters that may have been set for this test, but at the */
   2183   /* moment, I do not wish to figure-out all the  formatting, so I will */
   2184   /* just put this comment here to help remind me that it is something */
   2185   /* that should be done at a later time. */
   2186 
   2187   if (verbosity > 1) {
   2188     /* The user wanted to know it all, so we will give it to him. */
   2189     /* This information will include as much as we can find about */
   2190     /* sctp statistics, the alignments of the sends and receives */
   2191     /* and all that sort of rot... */
   2192 
   2193     /* this stuff needs to be worked-out in the presence of confidence */
   2194     /* intervals and multiple iterations of the test... raj 11/94 */
   2195 
   2196     fprintf(where,
   2197 	    ksink_fmt,
   2198 	    "Bytes",
   2199 	    "Bytes",
   2200 	    "Bytes",
   2201 	    local_send_align,
   2202 	    remote_recv_align,
   2203 	    local_send_offset,
   2204 	    remote_recv_offset,
   2205 	    bytes_sent,
   2206 	    bytes_sent / (double)nummessages,
   2207 	    nummessages,
   2208 	    bytes_sent / (double)sctp_stream_result->recv_calls,
   2209 	    sctp_stream_result->recv_calls);
   2210     fprintf(where,
   2211 	    ksink_fmt2,
   2212 	    sctp_mss);
   2213     fflush(where);
   2214 #ifdef WANT_HISTOGRAM
   2215     fprintf(where,"\n\nHistogram of time spent in send() call.\n");
   2216     fflush(where);
   2217     HIST_report(time_hist);
   2218 #endif /* WANT_HISTOGRAM */
   2219   }
   2220 
   2221 }
   2222 
   2223 
   2224 
   2226 /* This is the server-side routine for the sctp stream test. It is */
   2227 /* implemented as one routine. I could break things-out somewhat, but */
   2228 /* didn't feel it was necessary. */
   2229 
   2230 void
   2231 recv_sctp_stream_1toMany()
   2232 {
   2233 
   2234   struct sockaddr_in myaddr_in;
   2235   int	s_recv;
   2236   int 	addrlen;
   2237   int	len;
   2238   unsigned int	receive_calls;
   2239   float	elapsed_time;
   2240   double   bytes_received;
   2241   int	msg_flags = 0;
   2242 
   2243   struct ring_elt *recv_ring;
   2244 
   2245   struct addrinfo *local_res;
   2246   char local_name[BUFSIZ];
   2247   char port_buffer[PORTBUFSIZE];
   2248 
   2249 #ifdef DIRTY
   2250   int   *message_int_ptr;
   2251   int   dirty_count;
   2252   int   clean_count;
   2253   int   i;
   2254 #endif
   2255 
   2256 #ifdef DO_SELECT
   2257   fd_set readfds;
   2258   struct timeval timeout;
   2259 #endif
   2260 
   2261   struct	sctp_stream_request_struct	*sctp_stream_request;
   2262   struct	sctp_stream_response_struct	*sctp_stream_response;
   2263   struct	sctp_stream_results_struct	*sctp_stream_results;
   2264 
   2265 #ifdef DO_SELECT
   2266   FD_ZERO(&readfds);
   2267   timeout.tv_sec = 1;
   2268   timeout.tv_usec = 0;
   2269 #endif
   2270 
   2271   sctp_stream_request	=
   2272     (struct sctp_stream_request_struct *)netperf_request.content.test_specific_data;
   2273   sctp_stream_response	=
   2274     (struct sctp_stream_response_struct *)netperf_response.content.test_specific_data;
   2275   sctp_stream_results	=
   2276     (struct sctp_stream_results_struct *)netperf_response.content.test_specific_data;
   2277 
   2278   if (debug) {
   2279     fprintf(where,"netserver: recv_sctp_stream: entered...\n");
   2280     fflush(where);
   2281   }
   2282 
   2283   /* We want to set-up the listen socket with all the desired */
   2284   /* parameters and then let the initiator know that all is ready. If */
   2285   /* socket size defaults are to be used, then the initiator will have */
   2286   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   2287   /* send-back what they are. If that information cannot be determined, */
   2288   /* then we send-back -1's for the sizes. If things go wrong for any */
   2289   /* reason, we will drop back ten yards and punt. */
   2290 
   2291   /* If anything goes wrong, we want the remote to know about it. It */
   2292   /* would be best if the error that the remote reports to the user is */
   2293   /* the actual error we encountered, rather than some bogus unexpected */
   2294   /* response type message. */
   2295 
   2296   if (debug) {
   2297     fprintf(where,"recv_sctp_stream_1toMany: setting the response type...\n");
   2298     fflush(where);
   2299   }
   2300 
   2301   netperf_response.content.response_type = SCTP_STREAM_MANY_RESPONSE;
   2302 
   2303   if (debug) {
   2304     fprintf(where,"recv_sctp_stream_1toMany: the response type is set...\n");
   2305     fflush(where);
   2306   }
   2307 
   2308   /* We now alter the message_ptr variable to be at the desired */
   2309   /* alignment with the desired offset. */
   2310 
   2311   if (debug) {
   2312     fprintf(where,"recv_sctp_stream_1toMany: requested alignment of %d\n",
   2313 	    sctp_stream_request->recv_alignment);
   2314     fflush(where);
   2315   }
   2316 
   2317   /* create_data_socket expects to find some things in the global */
   2318   /* variables, so set the globals based on the values in the request. */
   2319   /* once the socket has been created, we will set the response values */
   2320   /* based on the updated value of those globals. raj 7/94 */
   2321   lss_size_req = sctp_stream_request->send_buf_size;
   2322   lsr_size_req = sctp_stream_request->recv_buf_size;
   2323   loc_nodelay = sctp_stream_request->no_delay;
   2324   loc_rcvavoid = sctp_stream_request->so_rcvavoid;
   2325   loc_sndavoid = sctp_stream_request->so_sndavoid;
   2326   non_block = sctp_stream_request->non_blocking;
   2327 
   2328   set_hostname_and_port(local_name,
   2329 			port_buffer,
   2330 			nf_to_af(sctp_stream_request->ipfamily),
   2331 			sctp_stream_request->port);
   2332 
   2333   local_res = complete_addrinfo(local_name,
   2334 				local_name,
   2335 				port_buffer,
   2336 				nf_to_af(sctp_stream_request->ipfamily),
   2337 				SOCK_SEQPACKET,
   2338 				IPPROTO_SCTP,
   2339 				0);
   2340 
   2341   s_recv = create_data_socket(local_res);
   2342 
   2343   if (s_recv < 0) {
   2344     netperf_response.content.serv_errno = errno;
   2345     send_response();
   2346     exit(1);
   2347   }
   2348 
   2349   /* what sort of sizes did we end-up with? */
   2350   if (sctp_stream_request->receive_size == 0) {
   2351     if (lsr_size > 0) {
   2352       recv_size = lsr_size;
   2353     }
   2354     else {
   2355       recv_size = 4096;
   2356     }
   2357   }
   2358   else {
   2359     recv_size = sctp_stream_request->receive_size;
   2360   }
   2361 
   2362   /* we want to set-up our recv_ring in a manner analagous to what we */
   2363   /* do on the sending side. this is more for the sake of symmetry */
   2364   /* than for the needs of say copy avoidance, but it might also be */
   2365   /* more realistic - this way one could conceivably go with a */
   2366   /* double-buffering scheme when taking the data an putting it into */
   2367   /* the filesystem or something like that. raj 7/94 */
   2368 
   2369   if (recv_width == 0) {
   2370     recv_width = (lsr_size/recv_size) + 1;
   2371     if (recv_width == 1) recv_width++;
   2372   }
   2373 
   2374   recv_ring = allocate_buffer_ring(recv_width,
   2375 				   recv_size,
   2376 				   sctp_stream_request->recv_alignment,
   2377 				   sctp_stream_request->recv_offset);
   2378 
   2379   if (debug) {
   2380     fprintf(where,"recv_sctp_stream: receive alignment and offset set...\n");
   2381     fflush(where);
   2382   }
   2383 
   2384   /* Now, let's set-up the socket to listen for connections */
   2385   if (listen(s_recv, 5) == -1) {
   2386     netperf_response.content.serv_errno = errno;
   2387     close(s_recv);
   2388     send_response();
   2389 
   2390     exit(1);
   2391   }
   2392 
   2393   /* now get the port number assigned by the system  */
   2394   addrlen = sizeof(myaddr_in);
   2395   if (getsockname(s_recv,
   2396 		  (struct sockaddr *)&myaddr_in,
   2397 		  &addrlen) == -1){
   2398     netperf_response.content.serv_errno = errno;
   2399     close(s_recv);
   2400     send_response();
   2401 
   2402     exit(1);
   2403   }
   2404 
   2405   /* Now myaddr_in contains the port and the internet address this is */
   2406   /* returned to the sender also implicitly telling the sender that the */
   2407   /* socket buffer sizing has been done. */
   2408 
   2409   sctp_stream_response->data_port_number = (int) ntohs(myaddr_in.sin_port);
   2410   netperf_response.content.serv_errno   = 0;
   2411 
   2412   /* But wait, there's more. If the initiator wanted cpu measurements, */
   2413   /* then we must call the calibrate routine, which will return the max */
   2414   /* rate back to the initiator. If the CPU was not to be measured, or */
   2415   /* something went wrong with the calibration, we will return a -1 to */
   2416   /* the initiator. */
   2417 
   2418   sctp_stream_response->cpu_rate = (float)0.0; 	/* assume no cpu */
   2419   if (sctp_stream_request->measure_cpu) {
   2420     sctp_stream_response->measure_cpu = 1;
   2421     sctp_stream_response->cpu_rate =
   2422       calibrate_local_cpu(sctp_stream_request->cpu_rate);
   2423   }
   2424   else {
   2425     sctp_stream_response->measure_cpu = 0;
   2426   }
   2427 
   2428   /* before we send the response back to the initiator, pull some of */
   2429   /* the socket parms from the globals */
   2430   sctp_stream_response->send_buf_size = lss_size;
   2431   sctp_stream_response->recv_buf_size = lsr_size;
   2432   sctp_stream_response->no_delay = loc_nodelay;
   2433   sctp_stream_response->so_rcvavoid = loc_rcvavoid;
   2434   sctp_stream_response->so_sndavoid = loc_sndavoid;
   2435   sctp_stream_response->receive_size = recv_size;
   2436 
   2437   send_response();
   2438 
   2439 
   2440   sctp_enable_events(s_recv, SCTP_ASSOC_CHANGE_EV | SCTP_SHUTDOWN_EV);
   2441 
   2442   /* now that we are connected, mark the socket as non-blocking */
   2443   if (non_block) {
   2444       if (!set_nonblock(s_recv)) {
   2445 	close(s_recv);
   2446 	exit(1);
   2447       }
   2448   }
   2449 
   2450 
   2451   /* Now it's time to start receiving data on the connection. We will */
   2452   /* first grab the apropriate counters and then start grabbing. */
   2453 
   2454   cpu_start(sctp_stream_request->measure_cpu);
   2455 
   2456   /* The loop will exit when the sender does a shutdown, which will */
   2457   /* return a length of zero   */
   2458 
   2459 #ifdef DIRTY
   2460     /* we want to dirty some number of consecutive integers in the buffer */
   2461     /* we are about to recv. we may also want to bring some number of */
   2462     /* them cleanly into the cache. The clean ones will follow any dirty */
   2463     /* ones into the cache. */
   2464 
   2465   dirty_count = sctp_stream_request->dirty_count;
   2466   clean_count = sctp_stream_request->clean_count;
   2467   message_int_ptr = (int *)recv_ring->buffer_ptr;
   2468   for (i = 0; i < dirty_count; i++) {
   2469     *message_int_ptr = rand();
   2470     message_int_ptr++;
   2471   }
   2472   for (i = 0; i < clean_count; i++) {
   2473     dirty_count = *message_int_ptr;
   2474     message_int_ptr++;
   2475   }
   2476 #endif /* DIRTY */
   2477 
   2478   bytes_received = 0;
   2479   receive_calls  = 0;
   2480 
   2481   while ((len = sctp_recvmsg(s_recv, recv_ring->buffer_ptr, recv_size,
   2482 			     NULL, 0,  /* we don't care who it's from */
   2483 			     NULL, &msg_flags)) != 0) {
   2484     if (len < 0) {
   2485       if (non_block && errno == EAGAIN) {
   2486 	Set_errno(0);
   2487 	continue;
   2488       }
   2489       netperf_response.content.serv_errno = errno;
   2490       send_response();
   2491       close(s_recv);
   2492       exit(1);
   2493     }
   2494 
   2495     if (msg_flags & MSG_NOTIFICATION) {
   2496 	if (sctp_process_event(s_recv, recv_ring->buffer_ptr) == SCTP_CLOSE)
   2497 	    break;
   2498 
   2499 	continue;
   2500     }
   2501 
   2502     bytes_received += len;
   2503     receive_calls++;
   2504 
   2505     /* more to the next buffer in the recv_ring */
   2506     recv_ring = recv_ring->next;
   2507 
   2508 #ifdef PAUSE
   2509     sleep(1);
   2510 #endif /* PAUSE */
   2511 
   2512 #ifdef DIRTY
   2513     message_int_ptr = (int *)(recv_ring->buffer_ptr);
   2514     for (i = 0; i < dirty_count; i++) {
   2515       *message_int_ptr = rand();
   2516       message_int_ptr++;
   2517     }
   2518     for (i = 0; i < clean_count; i++) {
   2519       dirty_count = *message_int_ptr;
   2520       message_int_ptr++;
   2521     }
   2522 #endif /* DIRTY */
   2523 
   2524 #ifdef DO_SELECT
   2525 	FD_SET(s_recv,&readfds);
   2526 	select(s_recv+1,&readfds,NULL,NULL,&timeout);
   2527 #endif /* DO_SELECT */
   2528 
   2529   }
   2530 
   2531   /* perform a shutdown to signal the sender.  in this case, sctp
   2532    * will close all associations on this socket
   2533    */
   2534   if (close(s_recv) == -1) {
   2535       netperf_response.content.serv_errno = errno;
   2536       send_response();
   2537       exit(1);
   2538   }
   2539 
   2540   cpu_stop(sctp_stream_request->measure_cpu,&elapsed_time);
   2541 
   2542   /* send the results to the sender			*/
   2543 
   2544   if (debug) {
   2545     fprintf(where,
   2546 	    "recv_sctp_stream: got %g bytes\n",
   2547 	    bytes_received);
   2548     fprintf(where,
   2549 	    "recv_sctp_stream: got %d recvs\n",
   2550 	    receive_calls);
   2551     fflush(where);
   2552   }
   2553 
   2554   sctp_stream_results->bytes_received	= htond(bytes_received);
   2555   sctp_stream_results->elapsed_time	= elapsed_time;
   2556   sctp_stream_results->recv_calls	= receive_calls;
   2557 
   2558   if (sctp_stream_request->measure_cpu) {
   2559     sctp_stream_results->cpu_util	= calc_cpu_util(0.0);
   2560   };
   2561 
   2562   if (debug) {
   2563     fprintf(where,
   2564 	    "recv_sctp_stream: test complete, sending results.\n");
   2565     fprintf(where,
   2566 	    "                 bytes_received %g receive_calls %d\n",
   2567 	    bytes_received,
   2568 	    receive_calls);
   2569     fprintf(where,
   2570 	    "                 len %d\n",
   2571 	    len);
   2572     fflush(where);
   2573   }
   2574 
   2575   sctp_stream_results->cpu_method = cpu_method;
   2576   sctp_stream_results->num_cpus   = lib_num_loc_cpus;
   2577   send_response();
   2578 }
   2579 
   2580 
   2582  /* this routine implements the sending (netperf) side of the SCTP_RR */
   2583  /* test. */
   2584 
   2585 void
   2586 send_sctp_rr(remote_host)
   2587      char	remote_host[];
   2588 {
   2589 
   2590   char *tput_title = "\
   2591 Local /Remote\n\
   2592 Socket Size   Request  Resp.   Elapsed  Trans.\n\
   2593 Send   Recv   Size     Size    Time     Rate         \n\
   2594 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
   2595 
   2596   char *tput_fmt_0 =
   2597     "%7.2f\n";
   2598 
   2599   char *tput_fmt_1_line_1 = "\
   2600 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
   2601   char *tput_fmt_1_line_2 = "\
   2602 %-6d %-6d\n";
   2603 
   2604   char *cpu_title = "\
   2605 Local /Remote\n\
   2606 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
   2607 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
   2608 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
   2609 
   2610   char *cpu_fmt_0 =
   2611     "%6.3f %c\n";
   2612 
   2613   char *cpu_fmt_1_line_1 = "\
   2614 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f  %-6.2f %-6.2f %-6.3f  %-6.3f\n";
   2615 
   2616   char *cpu_fmt_1_line_2 = "\
   2617 %-6d %-6d\n";
   2618 
   2619   char *ksink_fmt = "\
   2620 Alignment      Offset\n\
   2621 Local  Remote  Local  Remote\n\
   2622 Send   Recv    Send   Recv\n\
   2623 %5d  %5d   %5d  %5d\n";
   2624 
   2625 
   2626   int			timed_out = 0;
   2627   float			elapsed_time;
   2628 
   2629   int	len;
   2630   char	*temp_message_ptr;
   2631   int	nummessages;
   2632   int	send_socket;
   2633   int	trans_remaining;
   2634   int   msg_flags = 0;
   2635   double	bytes_xferd;
   2636 
   2637   struct ring_elt *send_ring;
   2638   struct ring_elt *recv_ring;
   2639 
   2640   int	rsp_bytes_left;
   2641   int	rsp_bytes_recvd;
   2642 
   2643   float	local_cpu_utilization;
   2644   float	local_service_demand;
   2645   float	remote_cpu_utilization;
   2646   float	remote_service_demand;
   2647   double	thruput;
   2648 
   2649   struct sockaddr_storage peer;
   2650   struct addrinfo *remote_res;
   2651   struct addrinfo *local_res;
   2652 
   2653   struct	sctp_rr_request_struct	*sctp_rr_request;
   2654   struct	sctp_rr_response_struct	*sctp_rr_response;
   2655   struct	sctp_rr_results_struct	*sctp_rr_result;
   2656 
   2657 #ifdef WANT_INTERVALS
   2658   int	interval_count;
   2659   sigset_t signal_set;
   2660 #endif /* WANT_INTERVALS */
   2661 
   2662   sctp_rr_request =
   2663     (struct sctp_rr_request_struct *)netperf_request.content.test_specific_data;
   2664   sctp_rr_response =
   2665     (struct sctp_rr_response_struct *)netperf_response.content.test_specific_data;
   2666   sctp_rr_result =
   2667     (struct sctp_rr_results_struct *)netperf_response.content.test_specific_data;
   2668 
   2669 #ifdef WANT_HISTOGRAM
   2670   time_hist = HIST_new();
   2671 #endif /* WANT_HISTOGRAM */
   2672 
   2673   /* since we are now disconnected from the code that established the */
   2674   /* control socket, and since we want to be able to use different */
   2675   /* protocols and such, we are passed the name of the remote host and */
   2676   /* must turn that into the test specific addressing information. */
   2677 
   2678   /* complete_addrinfos will either succede or exit the process */
   2679   complete_addrinfos(&remote_res,
   2680 		     &local_res,
   2681 		     remote_host,
   2682 		     SOCK_STREAM,
   2683 		     IPPROTO_SCTP,
   2684 		     0);
   2685 
   2686   if ( print_headers ) {
   2687     print_top_test_header("SCTP REQUEST/RESPONSE TEST", local_res, remote_res);
   2688   }
   2689 
   2690   /* initialize a few counters */
   2691 
   2692   send_ring = NULL;
   2693   recv_ring = NULL;
   2694   confidence_iteration = 1;
   2695   init_stat();
   2696 
   2697   /* we have a great-big while loop which controls the number of times */
   2698   /* we run a particular test. this is for the calculation of a */
   2699   /* confidence interval (I really should have stayed awake during */
   2700   /* probstats :). If the user did not request confidence measurement */
   2701   /* (no confidence is the default) then we will only go though the */
   2702   /* loop once. the confidence stuff originates from the folks at IBM */
   2703 
   2704   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   2705 	 (confidence_iteration <= iteration_min)) {
   2706 
   2707     /* initialize a few counters. we have to remember that we might be */
   2708     /* going through the loop more than once. */
   2709 
   2710     nummessages     = 0;
   2711     bytes_xferd     = 0.0;
   2712     times_up        = 0;
   2713     timed_out       = 0;
   2714     trans_remaining = 0;
   2715 
   2716     /* set-up the data buffers with the requested alignment and offset. */
   2717     /* since this is a request/response test, default the send_width and */
   2718     /* recv_width to 1 and not two raj 7/94 */
   2719 
   2720     if (send_width == 0) send_width = 1;
   2721     if (recv_width == 0) recv_width = 1;
   2722 
   2723     if (send_ring == NULL) {
   2724       send_ring = allocate_buffer_ring(send_width,
   2725 				       req_size,
   2726 				       local_send_align,
   2727 				       local_send_offset);
   2728     }
   2729 
   2730     if (recv_ring == NULL) {
   2731       recv_ring = allocate_buffer_ring(recv_width,
   2732 				       rsp_size,
   2733 				       local_recv_align,
   2734 				       local_recv_offset);
   2735     }
   2736 
   2737     /*set up the data socket                        */
   2738     send_socket = create_data_socket(local_res);
   2739 
   2740     if (send_socket < 0){
   2741       perror("netperf: send_sctp_rr: sctp stream data socket");
   2742       exit(1);
   2743     }
   2744 
   2745     if (debug) {
   2746       fprintf(where,"send_sctp_rr: send_socket obtained...\n");
   2747     }
   2748 
   2749     /* If the user has requested cpu utilization measurements, we must */
   2750     /* calibrate the cpu(s). We will perform this task within the tests */
   2751     /* themselves. If the user has specified the cpu rate, then */
   2752     /* calibrate_local_cpu will return rather quickly as it will have */
   2753     /* nothing to do. If local_cpu_rate is zero, then we will go through */
   2754     /* all the "normal" calibration stuff and return the rate back.*/
   2755 
   2756     if (local_cpu_usage) {
   2757       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   2758     }
   2759 
   2760     /* Tell the remote end to do a listen. The server alters the socket */
   2761     /* paramters on the other side at this point, hence the reason for */
   2762     /* all the values being passed in the setup message. If the user did */
   2763     /* not specify any of the parameters, they will be passed as 0, which */
   2764     /* will indicate to the remote that no changes beyond the system's */
   2765     /* default should be used. Alignment is the exception, it will */
   2766     /* default to 8, which will be no alignment alterations. */
   2767 
   2768     netperf_request.content.request_type	=	DO_SCTP_RR;
   2769     sctp_rr_request->recv_buf_size	=	rsr_size_req;
   2770     sctp_rr_request->send_buf_size	=	rss_size_req;
   2771     sctp_rr_request->recv_alignment     =	remote_recv_align;
   2772     sctp_rr_request->recv_offset        =	remote_recv_offset;
   2773     sctp_rr_request->send_alignment     =	remote_send_align;
   2774     sctp_rr_request->send_offset	=	remote_send_offset;
   2775     sctp_rr_request->request_size	=	req_size;
   2776     sctp_rr_request->response_size	=	rsp_size;
   2777     sctp_rr_request->no_delay	        =	rem_nodelay;
   2778     sctp_rr_request->measure_cpu	=	remote_cpu_usage;
   2779     sctp_rr_request->cpu_rate	        =	remote_cpu_rate;
   2780     sctp_rr_request->so_rcvavoid	        =	rem_rcvavoid;
   2781     sctp_rr_request->so_sndavoid	        =	rem_sndavoid;
   2782     if (test_time) {
   2783       sctp_rr_request->test_length	=	test_time;
   2784     }
   2785     else {
   2786       sctp_rr_request->test_length	=	test_trans * -1;
   2787     }
   2788     sctp_rr_request->non_blocking	= 	non_block;
   2789     sctp_rr_request->ipfamily           = af_to_nf(remote_res->ai_family);
   2790 
   2791     if (debug > 1) {
   2792       fprintf(where,"netperf: send_sctp_rr: requesting SCTP rr test\n");
   2793     }
   2794 
   2795     send_request();
   2796 
   2797     /* The response from the remote will contain all of the relevant 	*/
   2798     /* socket parameters for this test type. We will put them back into */
   2799     /* the variables here so they can be displayed if desired.  The	*/
   2800     /* remote will have calibrated CPU if necessary, and will have done	*/
   2801     /* all the needed set-up we will have calibrated the cpu locally	*/
   2802     /* before sending the request, and will grab the counter value right*/
   2803     /* after the connect returns. The remote will grab the counter right*/
   2804     /* after the accept call. This saves the hassle of extra messages	*/
   2805     /* being sent for the sctp tests.					*/
   2806 
   2807     recv_response();
   2808 
   2809     if (!netperf_response.content.serv_errno) {
   2810       if (debug)
   2811 	fprintf(where,"remote listen done.\n");
   2812       rsr_size          = sctp_rr_response->recv_buf_size;
   2813       rss_size          = sctp_rr_response->send_buf_size;
   2814       rem_nodelay       = sctp_rr_response->no_delay;
   2815       remote_cpu_usage  = sctp_rr_response->measure_cpu;
   2816       remote_cpu_rate   = sctp_rr_response->cpu_rate;
   2817       /* make sure that port numbers are in network order */
   2818       set_port_number(remote_res,
   2819 		      (unsigned short)sctp_rr_response->data_port_number);
   2820     }
   2821     else {
   2822       Set_errno(netperf_response.content.serv_errno);
   2823       fprintf(where,
   2824 	      "netperf: remote error %d",
   2825 	      netperf_response.content.serv_errno);
   2826       perror("");
   2827       fflush(where);
   2828 
   2829       exit(1);
   2830     }
   2831 
   2832     /*Connect up to the remote port on the data socket  */
   2833     if (connect(send_socket,
   2834 		remote_res->ai_addr,
   2835 		remote_res->ai_addrlen) <0){
   2836       perror("netperf: send_sctp_rr data socket connect failed");
   2837       exit(1);
   2838     }
   2839 
   2840     /* don't need events for 1-to-1 API with request-response tests */
   2841     sctp_enable_events(send_socket, 0);
   2842 
   2843     /* set non-blocking if needed */
   2844     if (non_block) {
   2845        if (!set_nonblock(send_socket)) {
   2846 	    close(send_socket);
   2847 	    exit(1);
   2848 	}
   2849     }
   2850 
   2851     /* Data Socket set-up is finished. If there were problems, either the */
   2852     /* connect would have failed, or the previous response would have */
   2853     /* indicated a problem. I failed to see the value of the extra */
   2854     /* message after the accept on the remote. If it failed, we'll see it */
   2855     /* here. If it didn't, we might as well start pumping data. */
   2856 
   2857     /* Set-up the test end conditions. For a request/response test, they */
   2858     /* can be either time or transaction based. */
   2859 
   2860     if (test_time) {
   2861       /* The user wanted to end the test after a period of time. */
   2862       times_up = 0;
   2863       trans_remaining = 0;
   2864       start_timer(test_time);
   2865     }
   2866     else {
   2867       /* The tester wanted to send a number of bytes. */
   2868       trans_remaining = test_bytes;
   2869       times_up = 1;
   2870     }
   2871 
   2872     /* The cpu_start routine will grab the current time and possibly */
   2873     /* value of the idle counter for later use in measuring cpu */
   2874     /* utilization and/or service demand and thruput. */
   2875 
   2876     cpu_start(local_cpu_usage);
   2877 
   2878 #ifdef WANT_INTERVALS
   2879     if ((interval_burst) || (demo_mode)) {
   2880       /* zero means that we never pause, so we never should need the */
   2881       /* interval timer, unless we are in demo_mode */
   2882       start_itimer(interval_wate);
   2883     }
   2884     interval_count = interval_burst;
   2885     /* get the signal set for the call to sigsuspend */
   2886     if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) {
   2887       fprintf(where,
   2888 	      "send_sctp_rr: unable to get sigmask errno %d\n",
   2889 	      errno);
   2890       fflush(where);
   2891       exit(1);
   2892     }
   2893 #endif /* WANT_INTERVALS */
   2894 
   2895     /* We use an "OR" to control test execution. When the test is */
   2896     /* controlled by time, the byte count check will always return false. */
   2897     /* When the test is controlled by byte count, the time test will */
   2898     /* always return false. When the test is finished, the whole */
   2899     /* expression will go false and we will stop sending data. I think I */
   2900     /* just arbitrarily decrement trans_remaining for the timed test, but */
   2901     /* will not do that just yet... One other question is whether or not */
   2902     /* the send buffer and the receive buffer should be the same buffer. */
   2903 
   2904 #ifdef WANT_FIRST_BURST
   2905     {
   2906       int i;
   2907       for (i = 0; i < first_burst_size; i++) {
   2908  	if((len=sctp_sendmsg(send_socket,
   2909  			     send_ring->buffer_ptr, req_size,
   2910  			     NULL, 0,	/* don't need addrs with 1-to-1 */
   2911  			     0, 0, 0, 0, 0)) != req_size) {
   2912 	  /* we should never hit the end of the test in the first burst */
   2913 	  perror("send_sctp_rr: initial burst data send error");
   2914 	  exit(1);
   2915 	}
   2916       }
   2917     }
   2918 #endif /* WANT_FIRST_BURST */
   2919 
   2920     while ((!times_up) || (trans_remaining > 0)) {
   2921       /* send the request. we assume that if we use a blocking socket, */
   2922       /* the request will be sent at one shot. */
   2923 
   2924 #ifdef WANT_HISTOGRAM
   2925       /* timestamp just before our call to send, and then again just */
   2926       /* after the receive raj 8/94 */
   2927       HIST_timestamp(&time_one);
   2928 #endif /* WANT_HISTOGRAM */
   2929 
   2930       while ((len=sctp_sendmsg(send_socket,
   2931 			       send_ring->buffer_ptr, req_size,
   2932 			       NULL, 0, /* don't need addrs with 1-to-1 */
   2933 			       0, 0, 0, 0, 0)) != req_size) {
   2934 	if (non_block && errno == EAGAIN) {
   2935 	    /* try sending again */
   2936 	    continue;
   2937 	} else if (SOCKET_EINTR(len) || (errno == 0)) {
   2938 	  /* we hit the end of a */
   2939 	  /* timed test. */
   2940 	  timed_out = 1;
   2941 	  break;
   2942 	}
   2943 	perror("send_sctp_rr: data send error");
   2944 	exit(1);
   2945       }
   2946 
   2947       if (timed_out) {
   2948 	/* we timed out while sending. break out another level */
   2949 	break;
   2950       }
   2951       send_ring = send_ring->next;
   2952 
   2953       /* receive the response */
   2954       rsp_bytes_left = rsp_size;
   2955       temp_message_ptr  = recv_ring->buffer_ptr;
   2956       do {
   2957 	msg_flags = 0;
   2958 	if ((rsp_bytes_recvd=sctp_recvmsg(send_socket,
   2959 					 temp_message_ptr, rsp_bytes_left,
   2960 					 NULL, 0,
   2961 					 NULL, &msg_flags)) < 0) {
   2962 	  if (errno == EINTR) {
   2963 	    /* We hit the end of a timed test. */
   2964 	    timed_out = 1;
   2965 	    break;
   2966 	  } else if (non_block && errno == EAGAIN) {
   2967 	      continue;
   2968 	  }
   2969 	  perror("send_sctp_rr: data recv error");
   2970 	  exit(1);
   2971 	}
   2972 	rsp_bytes_left -= rsp_bytes_recvd;
   2973 	temp_message_ptr  += rsp_bytes_recvd;
   2974       }	while (!(msg_flags & MSG_EOR));
   2975 
   2976       recv_ring = recv_ring->next;
   2977 
   2978       if (timed_out) {
   2979 	/* we may have been in a nested while loop - we need */
   2980 	/* another call to break. */
   2981 	break;
   2982       }
   2983 
   2984 #ifdef WANT_HISTOGRAM
   2985       HIST_timestamp(&time_two);
   2986       HIST_add(time_hist,delta_micro(&time_one,&time_two));
   2987 #endif /* WANT_HISTOGRAM */
   2988 #ifdef WANT_INTERVALS
   2989       if (demo_mode) {
   2990 	units_this_tick += 1;
   2991       }
   2992       /* in this case, the interval count is the count-down couter */
   2993       /* to decide to sleep for a little bit */
   2994       if ((interval_burst) && (--interval_count == 0)) {
   2995 	/* call sigsuspend and wait for the interval timer to get us */
   2996 	/* out */
   2997 	if (debug > 1) {
   2998 	  fprintf(where,"about to suspend\n");
   2999 	  fflush(where);
   3000 	}
   3001 	if (sigsuspend(&signal_set) == EFAULT) {
   3002 	  fprintf(where,
   3003 		  "send_sctp_rr: fault with signal set!\n");
   3004 	  fflush(where);
   3005 	  exit(1);
   3006 	}
   3007 	interval_count = interval_burst;
   3008       }
   3009 #endif /* WANT_INTERVALS */
   3010 
   3011       nummessages++;
   3012       if (trans_remaining) {
   3013 	trans_remaining--;
   3014       }
   3015 
   3016       if (debug > 3) {
   3017 	if ((nummessages % 100) == 0) {
   3018 	  fprintf(where,
   3019 		  "Transaction %d completed\n",
   3020 		  nummessages);
   3021 	  fflush(where);
   3022 	}
   3023       }
   3024     }
   3025 
   3026     /* At this point we used to call shutdown on the data socket to be */
   3027     /* sure all the data was delivered, but this was not germane in a */
   3028     /* request/response test, and it was causing the tests to "hang" when */
   3029     /* they were being controlled by time. So, I have replaced this */
   3030     /* shutdown call with a call to close that can be found later in the */
   3031     /* procedure. */
   3032 
   3033     /* this call will always give us the elapsed time for the test, and */
   3034     /* will also store-away the necessaries for cpu utilization */
   3035 
   3036     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
   3037 						/* measured? how long */
   3038 						/* did we really run? */
   3039 
   3040     /* Get the statistics from the remote end. The remote will have */
   3041     /* calculated CPU utilization. If it wasn't supposed to care, it */
   3042     /* will return obvious values. */
   3043 
   3044     recv_response();
   3045     if (!netperf_response.content.serv_errno) {
   3046       if (debug)
   3047 	fprintf(where,"remote results obtained\n");
   3048     }
   3049     else {
   3050       Set_errno(netperf_response.content.serv_errno);
   3051       fprintf(where,"netperf: remote error %d",
   3052 	      netperf_response.content.serv_errno);
   3053       perror("");
   3054       fflush(where);
   3055       exit(1);
   3056     }
   3057 
   3058     /* We now calculate what our throughput was for the test. */
   3059 
   3060     bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
   3061     thruput	= nummessages/elapsed_time;
   3062 
   3063     if (local_cpu_usage || remote_cpu_usage) {
   3064       /* We must now do a little math for service demand and cpu */
   3065       /* utilization for the system(s) */
   3066       /* Of course, some of the information might be bogus because */
   3067       /* there was no idle counter in the kernel(s). We need to make */
   3068       /* a note of this for the user's benefit...*/
   3069       if (local_cpu_usage) {
   3070 	local_cpu_utilization = calc_cpu_util(0.0);
   3071 	/* since calc_service demand is doing ms/Kunit we will */
   3072 	/* multiply the number of transaction by 1024 to get */
   3073 	/* "good" numbers */
   3074 	local_service_demand  = calc_service_demand((double) nummessages*1024,
   3075 						    0.0,
   3076 						    0.0,
   3077 						    0);
   3078       }
   3079       else {
   3080 	local_cpu_utilization	= (float) -1.0;
   3081 	local_service_demand	= (float) -1.0;
   3082       }
   3083 
   3084       if (remote_cpu_usage) {
   3085 	remote_cpu_utilization = sctp_rr_result->cpu_util;
   3086 	/* since calc_service demand is doing ms/Kunit we will */
   3087 	/* multiply the number of transaction by 1024 to get */
   3088 	/* "good" numbers */
   3089 	remote_service_demand = calc_service_demand((double) nummessages*1024,
   3090 						    0.0,
   3091 						    remote_cpu_utilization,
   3092 						    sctp_rr_result->num_cpus);
   3093       }
   3094       else {
   3095 	remote_cpu_utilization = (float) -1.0;
   3096 	remote_service_demand  = (float) -1.0;
   3097       }
   3098 
   3099     }
   3100     else {
   3101       /* we were not measuring cpu, for the confidence stuff, we */
   3102       /* should make it -1.0 */
   3103       local_cpu_utilization	= (float) -1.0;
   3104       local_service_demand	= (float) -1.0;
   3105       remote_cpu_utilization = (float) -1.0;
   3106       remote_service_demand  = (float) -1.0;
   3107     }
   3108 
   3109     /* at this point, we want to calculate the confidence information. */
   3110     /* if debugging is on, calculate_confidence will print-out the */
   3111     /* parameters we pass it */
   3112 
   3113     calculate_confidence(confidence_iteration,
   3114 			 elapsed_time,
   3115 			 thruput,
   3116 			 local_cpu_utilization,
   3117 			 remote_cpu_utilization,
   3118 			 local_service_demand,
   3119 			 remote_service_demand);
   3120 
   3121 
   3122     confidence_iteration++;
   3123 
   3124     /* we are now done with the socket, so close it */
   3125     close(send_socket);
   3126 
   3127   }
   3128 
   3129   retrieve_confident_values(&elapsed_time,
   3130 			    &thruput,
   3131 			    &local_cpu_utilization,
   3132 			    &remote_cpu_utilization,
   3133 			    &local_service_demand,
   3134 			    &remote_service_demand);
   3135 
   3136   /* We are now ready to print all the information. If the user */
   3137   /* has specified zero-level verbosity, we will just print the */
   3138   /* local service demand, or the remote service demand. If the */
   3139   /* user has requested verbosity level 1, he will get the basic */
   3140   /* "streamperf" numbers. If the user has specified a verbosity */
   3141   /* of greater than 1, we will display a veritable plethora of */
   3142   /* background information from outside of this block as it it */
   3143   /* not cpu_measurement specific...  */
   3144 
   3145   if (confidence < 0) {
   3146     /* we did not hit confidence, but were we asked to look for it? */
   3147     if (iteration_max > 1) {
   3148       display_confidence();
   3149     }
   3150   }
   3151 
   3152   if (local_cpu_usage || remote_cpu_usage) {
   3153     local_cpu_method = format_cpu_method(cpu_method);
   3154     remote_cpu_method = format_cpu_method(sctp_rr_result->cpu_method);
   3155 
   3156     switch (verbosity) {
   3157     case 0:
   3158       if (local_cpu_usage) {
   3159 	fprintf(where,
   3160 		cpu_fmt_0,
   3161 		local_service_demand,
   3162 		local_cpu_method);
   3163       }
   3164       else {
   3165 	fprintf(where,
   3166 		cpu_fmt_0,
   3167 		remote_service_demand,
   3168 		remote_cpu_method);
   3169       }
   3170       break;
   3171     case 1:
   3172     case 2:
   3173       if (print_headers) {
   3174 	fprintf(where,
   3175 		cpu_title,
   3176 		local_cpu_method,
   3177 		remote_cpu_method);
   3178       }
   3179 
   3180       fprintf(where,
   3181 	      cpu_fmt_1_line_1,		/* the format string */
   3182 	      lss_size,		/* local sendbuf size */
   3183 	      lsr_size,
   3184 	      req_size,		/* how large were the requests */
   3185 	      rsp_size,		/* guess */
   3186 	      elapsed_time,		/* how long was the test */
   3187 	      thruput,
   3188 	      local_cpu_utilization,	/* local cpu */
   3189 	      remote_cpu_utilization,	/* remote cpu */
   3190 	      local_service_demand,	/* local service demand */
   3191 	      remote_service_demand);	/* remote service demand */
   3192       fprintf(where,
   3193 	      cpu_fmt_1_line_2,
   3194 	      rss_size,
   3195 	      rsr_size);
   3196       break;
   3197     }
   3198   }
   3199   else {
   3200     /* The tester did not wish to measure service demand. */
   3201 
   3202     switch (verbosity) {
   3203     case 0:
   3204       fprintf(where,
   3205 	      tput_fmt_0,
   3206 	      thruput);
   3207       break;
   3208     case 1:
   3209     case 2:
   3210       if (print_headers) {
   3211 	fprintf(where,tput_title,format_units());
   3212       }
   3213 
   3214       fprintf(where,
   3215 	      tput_fmt_1_line_1,	/* the format string */
   3216 	      lss_size,
   3217 	      lsr_size,
   3218 	      req_size,		/* how large were the requests */
   3219 	      rsp_size,		/* how large were the responses */
   3220 	      elapsed_time, 		/* how long did it take */
   3221 	      thruput);
   3222       fprintf(where,
   3223 	      tput_fmt_1_line_2,
   3224 	      rss_size, 		/* remote recvbuf size */
   3225 	      rsr_size);
   3226 
   3227       break;
   3228     }
   3229   }
   3230 
   3231   /* it would be a good thing to include information about some of the */
   3232   /* other parameters that may have been set for this test, but at the */
   3233   /* moment, I do not wish to figure-out all the  formatting, so I will */
   3234   /* just put this comment here to help remind me that it is something */
   3235   /* that should be done at a later time. */
   3236 
   3237   /* how to handle the verbose information in the presence of */
   3238   /* confidence intervals is yet to be determined... raj 11/94 */
   3239   if (verbosity > 1) {
   3240     /* The user wanted to know it all, so we will give it to him. */
   3241     /* This information will include as much as we can find about */
   3242     /* TCP statistics, the alignments of the sends and receives */
   3243     /* and all that sort of rot... */
   3244 
   3245     fprintf(where,
   3246 	    ksink_fmt,
   3247 	    local_send_align,
   3248 	    remote_recv_offset,
   3249 	    local_send_offset,
   3250 	    remote_recv_offset);
   3251 
   3252 #ifdef WANT_HISTOGRAM
   3253     fprintf(where,"\nHistogram of request/response times\n");
   3254     fflush(where);
   3255     HIST_report(time_hist);
   3256 #endif /* WANT_HISTOGRAM */
   3257 
   3258   }
   3259 
   3260 }
   3261 
   3262 
   3263  /* this routine implements the receive (netserver) side of a TCP_RR */
   3265  /* test */
   3266 void
   3267 recv_sctp_rr()
   3268 {
   3269 
   3270   struct ring_elt *send_ring;
   3271   struct ring_elt *recv_ring;
   3272 
   3273   struct addrinfo *local_res;
   3274   char local_name[BUFSIZ];
   3275   char port_buffer[PORTBUFSIZE];
   3276 
   3277   struct sockaddr_in        myaddr_in, peeraddr_in;
   3278   int	s_listen, s_data;
   3279   int 	addrlen;
   3280   char	*temp_message_ptr;
   3281   int	trans_received;
   3282   int	trans_remaining;
   3283   int	bytes_sent;
   3284   int	request_bytes_recvd;
   3285   int	request_bytes_remaining;
   3286   int	timed_out = 0;
   3287   float	elapsed_time;
   3288 
   3289   struct	sctp_rr_request_struct	*sctp_rr_request;
   3290   struct	sctp_rr_response_struct	*sctp_rr_response;
   3291   struct	sctp_rr_results_struct	*sctp_rr_results;
   3292 
   3293   sctp_rr_request =
   3294     (struct sctp_rr_request_struct *)netperf_request.content.test_specific_data;
   3295   sctp_rr_response =
   3296     (struct sctp_rr_response_struct *)netperf_response.content.test_specific_data;
   3297   sctp_rr_results =
   3298     (struct sctp_rr_results_struct *)netperf_response.content.test_specific_data;
   3299 
   3300   if (debug) {
   3301     fprintf(where,"netserver: recv_sctp_rr: entered...\n");
   3302     fflush(where);
   3303   }
   3304 
   3305   /* We want to set-up the listen socket with all the desired */
   3306   /* parameters and then let the initiator know that all is ready. If */
   3307   /* socket size defaults are to be used, then the initiator will have */
   3308   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   3309   /* send-back what they are. If that information cannot be determined, */
   3310   /* then we send-back -1's for the sizes. If things go wrong for any */
   3311   /* reason, we will drop back ten yards and punt. */
   3312 
   3313   /* If anything goes wrong, we want the remote to know about it. It */
   3314   /* would be best if the error that the remote reports to the user is */
   3315   /* the actual error we encountered, rather than some bogus unexpected */
   3316   /* response type message. */
   3317 
   3318   if (debug) {
   3319     fprintf(where,"recv_sctp_rr: setting the response type...\n");
   3320     fflush(where);
   3321   }
   3322 
   3323   netperf_response.content.response_type = SCTP_RR_RESPONSE;
   3324 
   3325   if (debug) {
   3326     fprintf(where,"recv_sctp_rr: the response type is set...\n");
   3327     fflush(where);
   3328   }
   3329 
   3330   /* allocate the recv and send rings with the requested alignments */
   3331   /* and offsets. raj 7/94 */
   3332   if (debug) {
   3333     fprintf(where,"recv_sctp_rr: requested recv alignment of %d offset %d\n",
   3334 	    sctp_rr_request->recv_alignment,
   3335 	    sctp_rr_request->recv_offset);
   3336     fprintf(where,"recv_sctp_rr: requested send alignment of %d offset %d\n",
   3337 	    sctp_rr_request->send_alignment,
   3338 	    sctp_rr_request->send_offset);
   3339     fflush(where);
   3340   }
   3341 
   3342   /* at some point, these need to come to us from the remote system */
   3343   if (send_width == 0) send_width = 1;
   3344   if (recv_width == 0) recv_width = 1;
   3345 
   3346   send_ring = allocate_buffer_ring(send_width,
   3347 				   sctp_rr_request->response_size,
   3348 				   sctp_rr_request->send_alignment,
   3349 				   sctp_rr_request->send_offset);
   3350 
   3351   recv_ring = allocate_buffer_ring(recv_width,
   3352 				   sctp_rr_request->request_size,
   3353 				   sctp_rr_request->recv_alignment,
   3354 				   sctp_rr_request->recv_offset);
   3355 
   3356 
   3357   /* Grab a socket to listen on, and then listen on it. */
   3358 
   3359   if (debug) {
   3360     fprintf(where,"recv_sctp_rr: grabbing a socket...\n");
   3361     fflush(where);
   3362   }
   3363 
   3364   /* create_data_socket expects to find some things in the global */
   3365   /* variables, so set the globals based on the values in the request. */
   3366   /* once the socket has been created, we will set the response values */
   3367   /* based on the updated value of those globals. raj 7/94 */
   3368   lss_size_req = sctp_rr_request->send_buf_size;
   3369   lsr_size_req = sctp_rr_request->recv_buf_size;
   3370   loc_nodelay = sctp_rr_request->no_delay;
   3371   loc_rcvavoid = sctp_rr_request->so_rcvavoid;
   3372   loc_sndavoid = sctp_rr_request->so_sndavoid;
   3373   non_block = sctp_rr_request->non_blocking;
   3374 
   3375   set_hostname_and_port(local_name,
   3376 			port_buffer,
   3377 			nf_to_af(sctp_rr_request->ipfamily),
   3378 			sctp_rr_request->port);
   3379 
   3380   local_res = complete_addrinfo(local_name,
   3381 				local_name,
   3382 				port_buffer,
   3383 				nf_to_af(sctp_rr_request->ipfamily),
   3384 				SOCK_STREAM,
   3385 				IPPROTO_SCTP,
   3386 				0);
   3387 
   3388   s_listen = create_data_socket(local_res);
   3389 
   3390   if (s_listen < 0) {
   3391     netperf_response.content.serv_errno = errno;
   3392     send_response();
   3393 
   3394     exit(1);
   3395   }
   3396 
   3397   /* Now, let's set-up the socket to listen for connections */
   3398   if (listen(s_listen, 5) == -1) {
   3399     netperf_response.content.serv_errno = errno;
   3400     close(s_listen);
   3401     send_response();
   3402 
   3403     exit(1);
   3404   }
   3405 
   3406 
   3407   /* now get the port number assigned by the system  */
   3408   addrlen = sizeof(myaddr_in);
   3409   if (getsockname(s_listen,
   3410 		  (struct sockaddr *)&myaddr_in, &addrlen) == -1){
   3411     netperf_response.content.serv_errno = errno;
   3412     close(s_listen);
   3413     send_response();
   3414 
   3415     exit(1);
   3416   }
   3417 
   3418   /* Now myaddr_in contains the port and the internet address this is */
   3419   /* returned to the sender also implicitly telling the sender that the */
   3420   /* socket buffer sizing has been done. */
   3421 
   3422   sctp_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port);
   3423   netperf_response.content.serv_errno   = 0;
   3424 
   3425   /* But wait, there's more. If the initiator wanted cpu measurements, */
   3426   /* then we must call the calibrate routine, which will return the max */
   3427   /* rate back to the initiator. If the CPU was not to be measured, or */
   3428   /* something went wrong with the calibration, we will return a 0.0 to */
   3429   /* the initiator. */
   3430 
   3431   sctp_rr_response->cpu_rate = (float)0.0; 	/* assume no cpu */
   3432   sctp_rr_response->measure_cpu = 0;
   3433 
   3434   if (sctp_rr_request->measure_cpu) {
   3435     sctp_rr_response->measure_cpu = 1;
   3436     sctp_rr_response->cpu_rate = calibrate_local_cpu(sctp_rr_request->cpu_rate);
   3437   }
   3438 
   3439 
   3440   /* before we send the response back to the initiator, pull some of */
   3441   /* the socket parms from the globals */
   3442   sctp_rr_response->send_buf_size = lss_size;
   3443   sctp_rr_response->recv_buf_size = lsr_size;
   3444   sctp_rr_response->no_delay = loc_nodelay;
   3445   sctp_rr_response->so_rcvavoid = loc_rcvavoid;
   3446   sctp_rr_response->so_sndavoid = loc_sndavoid;
   3447   sctp_rr_response->test_length = sctp_rr_request->test_length;
   3448   send_response();
   3449 
   3450   addrlen = sizeof(peeraddr_in);
   3451 
   3452   if ((s_data = accept(s_listen,
   3453 		       (struct sockaddr *)&peeraddr_in,
   3454 		       &addrlen)) == -1) {
   3455     /* Let's just punt. The remote will be given some information */
   3456     close(s_listen);
   3457 
   3458     exit(1);
   3459   }
   3460 
   3461   /* we do not need events on a 1-to-1 RR test.  The test will finish
   3462    * once all transactions are done.
   3463    */
   3464 
   3465   /* now that we are connected, mark the socket as non-blocking */
   3466   if (non_block) {
   3467     if (!set_nonblock(s_data)) {
   3468       perror("netperf: set_nonblock");
   3469 	exit(1);
   3470     }
   3471   }
   3472 
   3473 #ifdef KLUDGE_SOCKET_OPTIONS
   3474   /* this is for those systems which *INCORRECTLY* fail to pass */
   3475   /* attributes across an accept() call. Including this goes against */
   3476   /* my better judgement :( raj 11/95 */
   3477 
   3478   kludge_socket_options(s_data);
   3479 
   3480 #endif /* KLUDGE_SOCKET_OPTIONS */
   3481 
   3482   if (debug) {
   3483     fprintf(where,"recv_sctp_rr: accept completes on the data connection.\n");
   3484     fflush(where);
   3485   }
   3486 
   3487   /* Now it's time to start receiving data on the connection. We will */
   3488   /* first grab the apropriate counters and then start grabbing. */
   3489 
   3490   cpu_start(sctp_rr_request->measure_cpu);
   3491 
   3492   /* The loop will exit when we hit the end of the test time, or when */
   3493   /* we have exchanged the requested number of transactions. */
   3494 
   3495   if (sctp_rr_request->test_length > 0) {
   3496     times_up = 0;
   3497     trans_remaining = 0;
   3498     start_timer(sctp_rr_request->test_length + PAD_TIME);
   3499   }
   3500   else {
   3501     times_up = 1;
   3502     trans_remaining = sctp_rr_request->test_length * -1;
   3503   }
   3504 
   3505   trans_received = 0;
   3506 
   3507   while ((!times_up) || (trans_remaining > 0)) {
   3508     int msg_flags = 0;
   3509 
   3510     temp_message_ptr = recv_ring->buffer_ptr;
   3511     request_bytes_remaining = sctp_rr_request->request_size;
   3512     while(!(msg_flags & MSG_EOR)) {
   3513       if((request_bytes_recvd=sctp_recvmsg(s_data,
   3514 					temp_message_ptr,
   3515 					request_bytes_remaining,
   3516 					NULL, 0,
   3517 					NULL, &msg_flags)) < 0) {
   3518 	if (errno == EINTR) {
   3519 	  /* the timer popped */
   3520 	  timed_out = 1;
   3521 	  break;
   3522 	} else if (non_block && errno == EAGAIN) {
   3523 	    continue;  /* while request_bytes_remaining */
   3524 	}
   3525 	netperf_response.content.serv_errno = errno;
   3526 	send_response();
   3527 	exit(1);
   3528       }
   3529       request_bytes_remaining -= request_bytes_recvd;
   3530       temp_message_ptr += request_bytes_recvd;
   3531     }
   3532 
   3533     recv_ring = recv_ring->next;
   3534 
   3535     if (timed_out) {
   3536       /* we hit the end of the test based on time - lets */
   3537       /* bail out of here now... */
   3538       if (debug) {
   3539 	fprintf(where,"yo55\n");
   3540 	fflush(where);
   3541       }
   3542       break;
   3543     }
   3544 
   3545 
   3546     /* Now, send the response to the remote
   3547      * In 1-to-1 API destination addr is not needed.
   3548      */
   3549     while ((bytes_sent=sctp_sendmsg(s_data,
   3550 				    send_ring->buffer_ptr,
   3551 				    sctp_rr_request->response_size,
   3552 				    NULL, 0,
   3553 				    0, 0, 0, 0, 0)) == -1) {
   3554       if (errno == EINTR) {
   3555 	/* the test timer has popped */
   3556 	timed_out = 1;
   3557 	break;
   3558       } else if (non_block && errno == EAGAIN) {
   3559 	 continue;
   3560       }
   3561 
   3562       netperf_response.content.serv_errno = 982;
   3563       send_response();
   3564       exit(1);
   3565     }
   3566 
   3567     if (timed_out) {
   3568       /* we hit the end of the test based on time - lets */
   3569       /* bail out of here now... */
   3570       if (debug) {
   3571 	fprintf(where,"yo6\n");
   3572 	fflush(where);
   3573       }
   3574       break;
   3575     }
   3576 
   3577     send_ring = send_ring->next;
   3578 
   3579     trans_received++;
   3580     if (trans_remaining) {
   3581       trans_remaining--;
   3582     }
   3583   }
   3584 
   3585 
   3586   /* The loop now exits due to timeout or transaction count being */
   3587   /* reached */
   3588 
   3589   cpu_stop(sctp_rr_request->measure_cpu,&elapsed_time);
   3590 
   3591   stop_timer();
   3592 
   3593   if (timed_out) {
   3594     /* we ended the test by time, which was at least 2 seconds */
   3595     /* longer than we wanted to run. so, we want to subtract */
   3596     /* PAD_TIME from the elapsed_time. */
   3597     elapsed_time -= PAD_TIME;
   3598   }
   3599 
   3600   /* send the results to the sender			*/
   3601 
   3602   if (debug) {
   3603     fprintf(where,
   3604 	    "recv_sctp_rr: got %d transactions\n",
   3605 	    trans_received);
   3606     fflush(where);
   3607   }
   3608 
   3609   sctp_rr_results->bytes_received = (trans_received *
   3610 				    (sctp_rr_request->request_size +
   3611 				     sctp_rr_request->response_size));
   3612   sctp_rr_results->trans_received = trans_received;
   3613   sctp_rr_results->elapsed_time   = elapsed_time;
   3614   sctp_rr_results->cpu_method     = cpu_method;
   3615   sctp_rr_results->num_cpus       = lib_num_loc_cpus;
   3616   if (sctp_rr_request->measure_cpu) {
   3617     sctp_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
   3618   }
   3619 
   3620   if (debug) {
   3621     fprintf(where,
   3622 	    "recv_sctp_rr: test complete, sending results.\n");
   3623     fflush(where);
   3624   }
   3625 
   3626   /* we are now done with the sockets */
   3627   send_response();
   3628 
   3629   close(s_data);
   3630   close(s_listen);
   3631 
   3632 }
   3633 
   3634 
   3635 
   3637 /* this routine implements the sending (netperf) side of the
   3638    SCTP_RR_1TOMANY test */
   3639 
   3640 void
   3641 send_sctp_rr_1toMany(remote_host)
   3642      char	remote_host[];
   3643 {
   3644 
   3645   char *tput_title = "\
   3646 Local /Remote\n\
   3647 Socket Size   Request  Resp.   Elapsed  Trans.\n\
   3648 Send   Recv   Size     Size    Time     Rate         \n\
   3649 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
   3650 
   3651   char *tput_fmt_0 =
   3652     "%7.2f\n";
   3653 
   3654   char *tput_fmt_1_line_1 = "\
   3655 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
   3656   char *tput_fmt_1_line_2 = "\
   3657 %-6d %-6d\n";
   3658 
   3659   char *cpu_title = "\
   3660 Local /Remote\n\
   3661 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
   3662 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
   3663 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
   3664 
   3665   char *cpu_fmt_0 =
   3666     "%6.3f %c\n";
   3667 
   3668   char *cpu_fmt_1_line_1 = "\
   3669 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f  %-6.2f %-6.2f %-6.3f  %-6.3f\n";
   3670 
   3671   char *cpu_fmt_1_line_2 = "\
   3672 %-6d %-6d\n";
   3673 
   3674   char *ksink_fmt = "\
   3675 Alignment      Offset\n\
   3676 Local  Remote  Local  Remote\n\
   3677 Send   Recv    Send   Recv\n\
   3678 %5d  %5d   %5d  %5d\n";
   3679 
   3680 
   3681   int			timed_out = 0;
   3682   float			elapsed_time;
   3683 
   3684   int	len, j = 0;
   3685   char	*temp_message_ptr;
   3686   int	nummessages;
   3687   int	*send_socket;
   3688   int	trans_remaining;
   3689   double	bytes_xferd;
   3690   int   msg_flags = 0;
   3691 
   3692   struct ring_elt *send_ring;
   3693   struct ring_elt *recv_ring;
   3694 
   3695   int	rsp_bytes_left;
   3696   int	rsp_bytes_recvd;
   3697 
   3698   float	local_cpu_utilization;
   3699   float	local_service_demand;
   3700   float	remote_cpu_utilization;
   3701   float	remote_service_demand;
   3702   double	thruput;
   3703 
   3704   struct sockaddr_storage peer;
   3705   struct addrinfo *local_res;
   3706   struct addrinfo *remote_res;
   3707 
   3708   struct	sctp_rr_request_struct	*sctp_rr_request;
   3709   struct	sctp_rr_response_struct	*sctp_rr_response;
   3710   struct	sctp_rr_results_struct	*sctp_rr_result;
   3711 
   3712 #ifdef WANT_INTERVALS
   3713   int	interval_count;
   3714   sigset_t signal_set;
   3715 #endif /* WANT_INTERVALS */
   3716 
   3717   sctp_rr_request =
   3718     (struct sctp_rr_request_struct *)netperf_request.content.test_specific_data;
   3719   sctp_rr_response =
   3720     (struct sctp_rr_response_struct *)netperf_response.content.test_specific_data;
   3721   sctp_rr_result =
   3722     (struct sctp_rr_results_struct *)netperf_response.content.test_specific_data;
   3723 
   3724 #ifdef WANT_HISTOGRAM
   3725   time_hist = HIST_new();
   3726 #endif /* WANT_HISTOGRAM */
   3727 
   3728   /* since we are now disconnected from the code that established the */
   3729   /* control socket, and since we want to be able to use different */
   3730   /* protocols and such, we are passed the name of the remote host and */
   3731   /* must turn that into the test specific addressing information. */
   3732 
   3733   complete_addrinfos(&remote_res,
   3734 		     &local_res,
   3735 		     remote_host,
   3736 		     SOCK_SEQPACKET,
   3737 		     IPPROTO_SCTP,
   3738 		     0);
   3739 
   3740   if ( print_headers ) {
   3741     print_top_test_header("SCTP 1-TO-MANY REQUEST/RESPONSE TEST",local_res,remote_res);
   3742   }
   3743 
   3744   /* initialize a few counters */
   3745 
   3746   send_ring = NULL;
   3747   recv_ring = NULL;
   3748   confidence_iteration = 1;
   3749   init_stat();
   3750 
   3751   send_socket = malloc(sizeof(int) * num_associations);
   3752   if (send_socket == NULL) {
   3753       fprintf(where,
   3754 	      "Could not create the socket array for %d associations",
   3755 	      num_associations);
   3756       fflush(where);
   3757       exit(1);
   3758   }
   3759 
   3760   /* we have a great-big while loop which controls the number of times */
   3761   /* we run a particular test. this is for the calculation of a */
   3762   /* confidence interval (I really should have stayed awake during */
   3763   /* probstats :). If the user did not request confidence measurement */
   3764   /* (no confidence is the default) then we will only go though the */
   3765   /* loop once. the confidence stuff originates from the folks at IBM */
   3766 
   3767   while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
   3768 	 (confidence_iteration <= iteration_min)) {
   3769 
   3770     /* initialize a few counters. we have to remember that we might be */
   3771     /* going through the loop more than once. */
   3772 
   3773     nummessages     = 0;
   3774     bytes_xferd     = 0.0;
   3775     times_up        = 0;
   3776     timed_out       = 0;
   3777     trans_remaining = 0;
   3778 
   3779     /* set-up the data buffers with the requested alignment and offset. */
   3780     /* since this is a request/response test, default the send_width and */
   3781     /* recv_width to 1 and not two raj 7/94 */
   3782 
   3783     if (send_width == 0) send_width = 1;
   3784     if (recv_width == 0) recv_width = 1;
   3785 
   3786     if (send_ring == NULL) {
   3787       send_ring = allocate_buffer_ring(send_width,
   3788 				       req_size,
   3789 				       local_send_align,
   3790 				       local_send_offset);
   3791     }
   3792 
   3793     if (recv_ring == NULL) {
   3794       recv_ring = allocate_buffer_ring(recv_width,
   3795 				       rsp_size,
   3796 				       local_recv_align,
   3797 				       local_recv_offset);
   3798     }
   3799 
   3800     /* If the user has requested cpu utilization measurements, we must */
   3801     /* calibrate the cpu(s). We will perform this task within the tests */
   3802     /* themselves. If the user has specified the cpu rate, then */
   3803     /* calibrate_local_cpu will return rather quickly as it will have */
   3804     /* nothing to do. If local_cpu_rate is zero, then we will go through */
   3805     /* all the "normal" calibration stuff and return the rate back.*/
   3806 
   3807     if (local_cpu_usage) {
   3808       local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
   3809     }
   3810 
   3811     /* Tell the remote end to do a listen. The server alters the socket */
   3812     /* paramters on the other side at this point, hence the reason for */
   3813     /* all the values being passed in the setup message. If the user did */
   3814     /* not specify any of the parameters, they will be passed as 0, which */
   3815     /* will indicate to the remote that no changes beyond the system's */
   3816     /* default should be used. Alignment is the exception, it will */
   3817     /* default to 8, which will be no alignment alterations. */
   3818 
   3819     netperf_request.content.request_type =	DO_SCTP_RR_MANY;
   3820     sctp_rr_request->recv_buf_size     =	rsr_size_req;
   3821     sctp_rr_request->send_buf_size     =	rss_size_req;
   3822     sctp_rr_request->recv_alignment    =	remote_recv_align;
   3823     sctp_rr_request->recv_offset       =	remote_recv_offset;
   3824     sctp_rr_request->send_alignment    =	remote_send_align;
   3825     sctp_rr_request->send_offset       =	remote_send_offset;
   3826     sctp_rr_request->request_size      =	req_size;
   3827     sctp_rr_request->response_size     =	rsp_size;
   3828     sctp_rr_request->no_delay	       =	rem_nodelay;
   3829     sctp_rr_request->measure_cpu       =	remote_cpu_usage;
   3830     sctp_rr_request->cpu_rate	       =	remote_cpu_rate;
   3831     sctp_rr_request->so_rcvavoid       =	rem_rcvavoid;
   3832     sctp_rr_request->so_sndavoid       =	rem_sndavoid;
   3833     if (test_time) {
   3834       sctp_rr_request->test_length     =	test_time;
   3835     }
   3836     else {
   3837       sctp_rr_request->test_length     =	test_trans * num_associations
   3838 						* -1;
   3839     }
   3840     sctp_rr_request->non_blocking      = 	non_block;
   3841     sctp_rr_request->port              =       atoi(remote_data_port);
   3842     sctp_rr_request->ipfamily          =       af_to_nf(remote_res->ai_family);
   3843     if (debug > 1) {
   3844       fprintf(where,"netperf: send_sctp_rr_1toMany: requesting SCTP rr test\n");
   3845     }
   3846 
   3847     send_request();
   3848 
   3849     /* The response from the remote will contain all of the relevant 	*/
   3850     /* socket parameters for this test type. We will put them back into */
   3851     /* the variables here so they can be displayed if desired.  The	*/
   3852     /* remote will have calibrated CPU if necessary, and will have done	*/
   3853     /* all the needed set-up we will have calibrated the cpu locally	*/
   3854     /* before sending the request, and will grab the counter value right*/
   3855     /* after the connect returns. The remote will grab the counter right*/
   3856     /* after the accept call. This saves the hassle of extra messages	*/
   3857     /* being sent for the sctp tests.					*/
   3858 
   3859     recv_response();
   3860 
   3861     if (!netperf_response.content.serv_errno) {
   3862       rsr_size          = sctp_rr_response->recv_buf_size;
   3863       rss_size          = sctp_rr_response->send_buf_size;
   3864       rem_nodelay       = sctp_rr_response->no_delay;
   3865       remote_cpu_usage  = sctp_rr_response->measure_cpu;
   3866       remote_cpu_rate   = sctp_rr_response->cpu_rate;
   3867       /* make sure that port numbers are in network order */
   3868       set_port_number(remote_res,
   3869 		      (unsigned short)sctp_rr_response->data_port_number);
   3870     }
   3871     else {
   3872       Set_errno(netperf_response.content.serv_errno);
   3873       fprintf(where,
   3874 	      "netperf: remote error %d",
   3875 	      netperf_response.content.serv_errno);
   3876       perror("");
   3877       fflush(where);
   3878 
   3879       exit(1);
   3880     }
   3881 
   3882     /*set up the data socket list  */
   3883     for (j = 0; j < num_associations; j++) {
   3884       send_socket[j] = create_data_socket(local_res);
   3885 
   3886       if (send_socket < 0){
   3887 	perror("netperf: send_sctp_rr_1toMany: sctp stream data socket");
   3888 	exit(1);
   3889       }
   3890 
   3891       /*Connect up to the remote port on the data socket  */
   3892       if (connect(send_socket[j],
   3893 		  remote_res->ai_addr,
   3894 		  remote_res->ai_addrlen) < 0){
   3895 	perror("netperf: data socket connect failed");
   3896 
   3897 	exit(1);
   3898       }
   3899 
   3900       /* The client end of the 1-to-Many test uses 1-to-1 sockets.
   3901        * it doesn't need events.
   3902        */
   3903       sctp_enable_events(send_socket[j], 0);
   3904 
   3905       if (non_block) {
   3906         if (!set_nonblock(send_socket[j])) {
   3907 	  close(send_socket[j]);
   3908 	  exit(1);
   3909 	}
   3910       }
   3911     }
   3912 
   3913     /* Data Socket set-up is finished. If there were problems, either the */
   3914     /* connect would have failed, or the previous response would have */
   3915     /* indicated a problem. I failed to see the value of the extra */
   3916     /* message after the accept on the remote. If it failed, we'll see it */
   3917     /* here. If it didn't, we might as well start pumping data. */
   3918 
   3919     /* Set-up the test end conditions. For a request/response test, they */
   3920     /* can be either time or transaction based. */
   3921 
   3922     if (test_time) {
   3923       /* The user wanted to end the test after a period of time. */
   3924       times_up = 0;
   3925       trans_remaining = 0;
   3926       start_timer(test_time);
   3927     }
   3928     else {
   3929       /* The tester wanted to send a number of bytes. */
   3930       trans_remaining = test_bytes * num_associations;
   3931       times_up = 1;
   3932     }
   3933 
   3934     /* The cpu_start routine will grab the current time and possibly */
   3935     /* value of the idle counter for later use in measuring cpu */
   3936     /* utilization and/or service demand and thruput. */
   3937 
   3938     cpu_start(local_cpu_usage);
   3939 
   3940 #ifdef WANT_INTERVALS
   3941     if ((interval_burst) || (demo_mode)) {
   3942       /* zero means that we never pause, so we never should need the */
   3943       /* interval timer, unless we are in demo_mode */
   3944       start_itimer(interval_wate);
   3945     }
   3946     interval_count = interval_burst;
   3947     /* get the signal set for the call to sigsuspend */
   3948     if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) {
   3949       fprintf(where,
   3950 	      "send_sctp_rr_1toMany: unable to get sigmask errno %d\n",
   3951 	      errno);
   3952       fflush(where);
   3953       exit(1);
   3954     }
   3955 #endif /* WANT_INTERVALS */
   3956 
   3957     /* We use an "OR" to control test execution. When the test is */
   3958     /* controlled by time, the byte count check will always return false. */
   3959     /* When the test is controlled by byte count, the time test will */
   3960     /* always return false. When the test is finished, the whole */
   3961     /* expression will go false and we will stop sending data. I think I */
   3962     /* just arbitrarily decrement trans_remaining for the timed test, but */
   3963     /* will not do that just yet... One other question is whether or not */
   3964     /* the send buffer and the receive buffer should be the same buffer. */
   3965 
   3966 #ifdef WANT_FIRST_BURST
   3967     {
   3968       int i;
   3969       for (j = 0; j < num_associations; j++) {
   3970 	  for (i = 0; i < first_burst_size; i++) {
   3971 	    if((len=sctp_sendmsg(send_socket[j],
   3972 			 send_ring->buffer_ptr, send_size,
   3973 			 remote_res->ai_addr,
   3974 			 remote_res->ai_addrlen,
   3975 			 0, 0, 0, 0, 0)) != req_size) {
   3976 	      /* we should never hit the end of the test in the first burst */
   3977 	      perror("send_sctp_rr_1toMany: initial burst data send error");
   3978 	      exit(1);
   3979 	    }
   3980 	  }
   3981       }
   3982     }
   3983 #endif /* WANT_FIRST_BURST */
   3984 
   3985     while ((!times_up) || (trans_remaining > 0)) {
   3986       /* send the request. we assume that if we use a blocking socket, */
   3987       /* the request will be sent at one shot. */
   3988 
   3989       /* this is a fairly poor way of testing 1toMany connections.
   3990        * For each association we measure round trip time to account for
   3991        * any delay in lookups and delivery.  To stress the server a bit
   3992        * more we would need a distributed client test, or at least multiple
   3993        * processes.  I want to force as much paralellism as possible, but
   3994        * this will do for the fist take. vlad
   3995        */
   3996       for (j = 0; j < num_associations; j++) {
   3997 #ifdef WANT_HISTOGRAM
   3998 	/* timestamp just before our call to send, and then again just */
   3999 	/* after the receive raj 8/94 */
   4000 	gettimeofday(&time_one,NULL);
   4001 #endif /* WANT_HISTOGRAM */
   4002 
   4003 	while ((len=sctp_sendmsg(send_socket[j],
   4004 				 send_ring->buffer_ptr, send_size,
   4005 				 remote_res->ai_addr,
   4006 				 remote_res->ai_addrlen,
   4007 				 0, 0, 0, 0, 0)) != req_size) {
   4008 	  if (non_block && errno == EAGAIN) {
   4009 	    /* try sending again */
   4010 	    continue;
   4011 	  } else if ((errno == EINTR) || (errno == 0)) {
   4012 	    /* we hit the end of a */
   4013 	    /* timed test. */
   4014 	    timed_out = 1;
   4015 	    break;
   4016 	  }
   4017 	  perror("send_sctp_rr_1toMany: data send error");
   4018 	  exit(1);
   4019 	}
   4020 
   4021 	if (timed_out) {
   4022 	  /* we may have been in a nested while loop - we need */
   4023 	  /* another call to break. */
   4024 	  break;
   4025 	}
   4026 
   4027 	/* setup for the next time */
   4028 	send_ring = send_ring->next;
   4029 
   4030 	rsp_bytes_left = rsp_size;
   4031 	temp_message_ptr  = recv_ring->buffer_ptr;
   4032 	while (!(msg_flags & MSG_EOR)) {
   4033 	  if((rsp_bytes_recvd = sctp_recvmsg(send_socket[j],
   4034 					     temp_message_ptr,
   4035 					     rsp_bytes_left,
   4036 					     NULL, 0,
   4037 					     NULL, &msg_flags)) < 0) {
   4038 	    if (errno == EINTR) {
   4039 	      /* We hit the end of a timed test. */
   4040 	      timed_out = 1;
   4041 	      break;
   4042 	    } else if (non_block && errno == EAGAIN) {
   4043 	      continue;
   4044 	    }
   4045 	    perror("send_sctp_rr_1toMany: data recv error");
   4046 	    exit(1);
   4047 	  }
   4048 	  rsp_bytes_left -= rsp_bytes_recvd;
   4049 	  temp_message_ptr  += rsp_bytes_recvd;
   4050 	}
   4051 	recv_ring = recv_ring->next;
   4052 
   4053 	if (timed_out) {
   4054 	  /* we may have been in a nested while loop - we need */
   4055 	  /* another call to break. */
   4056 	  break;
   4057 	}
   4058 
   4059 #ifdef WANT_HISTOGRAM
   4060 	gettimeofday(&time_two,NULL);
   4061 	HIST_add(time_hist,delta_micro(&time_one,&time_two));
   4062 #endif /* WANT_HISTOGRAM */
   4063 
   4064 	nummessages++;
   4065 	if (trans_remaining) {
   4066 	  trans_remaining--;
   4067 	}
   4068 
   4069 	if (debug > 3) {
   4070 	  if ((nummessages % 100) == 0) {
   4071 	    fprintf(where,
   4072 		    "Transaction %d completed\n",
   4073 		    nummessages);
   4074 	    fflush(where);
   4075 	  }
   4076 	}
   4077       }
   4078     }
   4079 
   4080     /* At this point we used to call shutdown on the data socket to be */
   4081     /* sure all the data was delivered, but this was not germane in a */
   4082     /* request/response test, and it was causing the tests to "hang" when */
   4083     /* they were being controlled by time. So, I have replaced this */
   4084     /* shutdown call with a call to close that can be found later in the */
   4085     /* procedure. */
   4086 
   4087     /* this call will always give us the elapsed time for the test, and */
   4088     /* will also store-away the necessaries for cpu utilization */
   4089 
   4090     cpu_stop(local_cpu_usage,&elapsed_time);	/* was cpu being */
   4091 						/* measured? how long */
   4092 						/* did we really run? */
   4093 
   4094     /* Get the statistics from the remote end. The remote will have */
   4095     /* calculated CPU utilization. If it wasn't supposed to care, it */
   4096     /* will return obvious values. */
   4097 
   4098     recv_response();
   4099     if (!netperf_response.content.serv_errno) {
   4100       if (debug)
   4101 	fprintf(where,"remote results obtained\n");
   4102     }
   4103     else {
   4104       Set_errno(netperf_response.content.serv_errno);
   4105       fprintf(where,"netperf: remote error %d",
   4106 	      netperf_response.content.serv_errno);
   4107       perror("");
   4108       fflush(where);
   4109       exit(1);
   4110     }
   4111 
   4112     /* We now calculate what our throughput was for the test. */
   4113 
   4114     bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
   4115     thruput	= nummessages/elapsed_time;
   4116 
   4117     if (local_cpu_usage || remote_cpu_usage) {
   4118       /* We must now do a little math for service demand and cpu */
   4119       /* utilization for the system(s) */
   4120       /* Of course, some of the information might be bogus because */
   4121       /* there was no idle counter in the kernel(s). We need to make */
   4122       /* a note of this for the user's benefit...*/
   4123       if (local_cpu_usage) {
   4124 	local_cpu_utilization = calc_cpu_util(0.0);
   4125 	/* since calc_service demand is doing ms/Kunit we will */
   4126 	/* multiply the number of transaction by 1024 to get */
   4127 	/* "good" numbers */
   4128 	local_service_demand  = calc_service_demand((double) nummessages*1024,
   4129 						    0.0,
   4130 						    0.0,
   4131 						    0);
   4132       }
   4133       else {
   4134 	local_cpu_utilization	= (float) -1.0;
   4135 	local_service_demand	= (float) -1.0;
   4136       }
   4137 
   4138       if (remote_cpu_usage) {
   4139 	remote_cpu_utilization = sctp_rr_result->cpu_util;
   4140 	/* since calc_service demand is doing ms/Kunit we will */
   4141 	/* multiply the number of transaction by 1024 to get */
   4142 	/* "good" numbers */
   4143 	remote_service_demand = calc_service_demand((double) nummessages*1024,
   4144 						    0.0,
   4145 						    remote_cpu_utilization,
   4146 						    sctp_rr_result->num_cpus);
   4147       }
   4148       else {
   4149 	remote_cpu_utilization = (float) -1.0;
   4150 	remote_service_demand  = (float) -1.0;
   4151       }
   4152 
   4153     }
   4154     else {
   4155       /* we were not measuring cpu, for the confidence stuff, we */
   4156       /* should make it -1.0 */
   4157       local_cpu_utilization	= (float) -1.0;
   4158       local_service_demand	= (float) -1.0;
   4159       remote_cpu_utilization = (float) -1.0;
   4160       remote_service_demand  = (float) -1.0;
   4161     }
   4162 
   4163     /* at this point, we want to calculate the confidence information. */
   4164     /* if debugging is on, calculate_confidence will print-out the */
   4165     /* parameters we pass it */
   4166 
   4167     calculate_confidence(confidence_iteration,
   4168 			 elapsed_time,
   4169 			 thruput,
   4170 			 local_cpu_utilization,
   4171 			 remote_cpu_utilization,
   4172 			 local_service_demand,
   4173 			 remote_service_demand);
   4174 
   4175 
   4176     confidence_iteration++;
   4177 
   4178     /* we are now done with the socket, so close it */
   4179     for (j = 0; j < num_associations; j++)
   4180 	close(send_socket[j]);
   4181   }
   4182 
   4183   retrieve_confident_values(&elapsed_time,
   4184 			    &thruput,
   4185 			    &local_cpu_utilization,
   4186 			    &remote_cpu_utilization,
   4187 			    &local_service_demand,
   4188 			    &remote_service_demand);
   4189 
   4190   /* We are now ready to print all the information. If the user */
   4191   /* has specified zero-level verbosity, we will just print the */
   4192   /* local service demand, or the remote service demand. If the */
   4193   /* user has requested verbosity level 1, he will get the basic */
   4194   /* "streamperf" numbers. If the user has specified a verbosity */
   4195   /* of greater than 1, we will display a veritable plethora of */
   4196   /* background information from outside of this block as it it */
   4197   /* not cpu_measurement specific...  */
   4198 
   4199   if (confidence < 0) {
   4200     /* we did not hit confidence, but were we asked to look for it? */
   4201     if (iteration_max > 1) {
   4202       display_confidence();
   4203     }
   4204   }
   4205 
   4206   if (local_cpu_usage || remote_cpu_usage) {
   4207     local_cpu_method = format_cpu_method(cpu_method);
   4208     remote_cpu_method = format_cpu_method(sctp_rr_result->cpu_method);
   4209 
   4210     switch (verbosity) {
   4211     case 0:
   4212       if (local_cpu_usage) {
   4213 	fprintf(where,
   4214 		cpu_fmt_0,
   4215 		local_service_demand,
   4216 		local_cpu_method);
   4217       }
   4218       else {
   4219 	fprintf(where,
   4220 		cpu_fmt_0,
   4221 		remote_service_demand,
   4222 		remote_cpu_method);
   4223       }
   4224       break;
   4225     case 1:
   4226     case 2:
   4227       if (print_headers) {
   4228 	fprintf(where,
   4229 		cpu_title,
   4230 		local_cpu_method,
   4231 		remote_cpu_method);
   4232       }
   4233 
   4234       fprintf(where,
   4235 	      cpu_fmt_1_line_1,		/* the format string */
   4236 	      lss_size,		/* local sendbuf size */
   4237 	      lsr_size,
   4238 	      req_size,		/* how large were the requests */
   4239 	      rsp_size,		/* guess */
   4240 	      elapsed_time,		/* how long was the test */
   4241 	      thruput,
   4242 	      local_cpu_utilization,	/* local cpu */
   4243 	      remote_cpu_utilization,	/* remote cpu */
   4244 	      local_service_demand,	/* local service demand */
   4245 	      remote_service_demand);	/* remote service demand */
   4246       fprintf(where,
   4247 	      cpu_fmt_1_line_2,
   4248 	      rss_size,
   4249 	      rsr_size);
   4250       break;
   4251     }
   4252   }
   4253   else {
   4254     /* The tester did not wish to measure service demand. */
   4255 
   4256     switch (verbosity) {
   4257     case 0:
   4258       fprintf(where,
   4259 	      tput_fmt_0,
   4260 	      thruput);
   4261       break;
   4262     case 1:
   4263     case 2:
   4264       if (print_headers) {
   4265 	fprintf(where,tput_title,format_units());
   4266       }
   4267 
   4268       fprintf(where,
   4269 	      tput_fmt_1_line_1,	/* the format string */
   4270 	      lss_size,
   4271 	      lsr_size,
   4272 	      req_size,		/* how large were the requests */
   4273 	      rsp_size,		/* how large were the responses */
   4274 	      elapsed_time, 		/* how long did it take */
   4275 	      thruput);
   4276       fprintf(where,
   4277 	      tput_fmt_1_line_2,
   4278 	      rss_size, 		/* remote recvbuf size */
   4279 	      rsr_size);
   4280 
   4281       break;
   4282     }
   4283   }
   4284 
   4285   /* it would be a good thing to include information about some of the */
   4286   /* other parameters that may have been set for this test, but at the */
   4287   /* moment, I do not wish to figure-out all the  formatting, so I will */
   4288   /* just put this comment here to help remind me that it is something */
   4289   /* that should be done at a later time. */
   4290 
   4291   /* how to handle the verbose information in the presence of */
   4292   /* confidence intervals is yet to be determined... raj 11/94 */
   4293   if (verbosity > 1) {
   4294     /* The user wanted to know it all, so we will give it to him. */
   4295     /* This information will include as much as we can find about */
   4296     /* TCP statistics, the alignments of the sends and receives */
   4297     /* and all that sort of rot... */
   4298 
   4299     fprintf(where,
   4300 	    ksink_fmt,
   4301 	    local_send_align,
   4302 	    remote_recv_offset,
   4303 	    local_send_offset,
   4304 	    remote_recv_offset);
   4305 
   4306 #ifdef WANT_HISTOGRAM
   4307     fprintf(where,"\nHistogram of request/response times\n");
   4308     fflush(where);
   4309     HIST_report(time_hist);
   4310 #endif /* WANT_HISTOGRAM */
   4311 
   4312   }
   4313 
   4314 }
   4315 
   4316 
   4317  /* this routine implements the receive (netserver) side of a TCP_RR */
   4319  /* test */
   4320 void
   4321 recv_sctp_rr_1toMany()
   4322 {
   4323 
   4324   struct ring_elt *send_ring;
   4325   struct ring_elt *recv_ring;
   4326 
   4327 
   4328   struct sockaddr_in        myaddr_in; 	/* needed to get the port number */
   4329   struct sockaddr_storage   peeraddr;   /* to communicate with peer */
   4330   struct addrinfo *local_res;
   4331   char   local_name[BUFSIZ];
   4332   char   port_buffer[PORTBUFSIZE];
   4333   int    msg_flags;
   4334 
   4335   int	s_rcv;
   4336   int 	addrlen;
   4337   char	*temp_message_ptr;
   4338   int	trans_received;
   4339   int	trans_remaining;
   4340   int	bytes_sent;
   4341   int	bytes_recvd;
   4342   int	recv_buf_size;
   4343   int	timed_out = 0;
   4344   float	elapsed_time;
   4345 
   4346   struct	sctp_rr_request_struct	*sctp_rr_request;
   4347   struct	sctp_rr_response_struct	*sctp_rr_response;
   4348   struct	sctp_rr_results_struct	*sctp_rr_results;
   4349 
   4350   sctp_rr_request =
   4351     (struct sctp_rr_request_struct *)netperf_request.content.test_specific_data;
   4352   sctp_rr_response =
   4353     (struct sctp_rr_response_struct *)netperf_response.content.test_specific_data;
   4354   sctp_rr_results =
   4355     (struct sctp_rr_results_struct *)netperf_response.content.test_specific_data;
   4356 
   4357   if (debug) {
   4358     fprintf(where,"netserver: recv_sctp_rr_1toMany: entered...\n");
   4359     fflush(where);
   4360   }
   4361 
   4362   /* We want to set-up the listen socket with all the desired */
   4363   /* parameters and then let the initiator know that all is ready. If */
   4364   /* socket size defaults are to be used, then the initiator will have */
   4365   /* sent us 0's. If the socket sizes cannot be changed, then we will */
   4366   /* send-back what they are. If that information cannot be determined, */
   4367   /* then we send-back -1's for the sizes. If things go wrong for any */
   4368   /* reason, we will drop back ten yards and punt. */
   4369 
   4370   /* If anything goes wrong, we want the remote to know about it. It */
   4371   /* would be best if the error that the remote reports to the user is */
   4372   /* the actual error we encountered, rather than some bogus unexpected */
   4373   /* response type message. */
   4374 
   4375   if (debug) {
   4376     fprintf(where,"recv_sctp_rr_1toMany: setting the response type...\n");
   4377     fflush(where);
   4378   }
   4379 
   4380   netperf_response.content.response_type = SCTP_RR_MANY_RESPONSE;
   4381 
   4382   if (debug) {
   4383     fprintf(where,"recv_sctp_rr_1toMany: the response type is set...\n");
   4384     fflush(where);
   4385   }
   4386 
   4387   /* allocate the recv and send rings with the requested alignments */
   4388   /* and offsets. raj 7/94 */
   4389   if (debug) {
   4390     fprintf(where,"recv_sctp_rr_1toMany: requested recv alignment of %d offset %d\n",
   4391 	    sctp_rr_request->recv_alignment,
   4392 	    sctp_rr_request->recv_offset);
   4393     fprintf(where,"recv_sctp_rr_1toMany: requested send alignment of %d offset %d\n",
   4394 	    sctp_rr_request->send_alignment,
   4395 	    sctp_rr_request->send_offset);
   4396     fflush(where);
   4397   }
   4398 
   4399   /* at some point, these need to come to us from the remote system */
   4400   if (send_width == 0) send_width = 1;
   4401   if (recv_width == 0) recv_width = 1;
   4402 
   4403   send_ring = allocate_buffer_ring(send_width,
   4404 				   sctp_rr_request->response_size,
   4405 				   sctp_rr_request->send_alignment,
   4406 				   sctp_rr_request->send_offset);
   4407 
   4408   recv_ring = allocate_buffer_ring(recv_width,
   4409 				   sctp_rr_request->request_size,
   4410 				   sctp_rr_request->recv_alignment,
   4411 				   sctp_rr_request->recv_offset);
   4412 
   4413 
   4414   /* create_data_socket expects to find some things in the global */
   4415   /* variables, so set the globals based on the values in the request. */
   4416   /* once the socket has been created, we will set the response values */
   4417   /* based on the updated value of those globals. raj 7/94 */
   4418   lss_size_req = sctp_rr_request->send_buf_size;
   4419   lsr_size_req = sctp_rr_request->recv_buf_size;
   4420   loc_nodelay = sctp_rr_request->no_delay;
   4421   loc_rcvavoid = sctp_rr_request->so_rcvavoid;
   4422   loc_sndavoid = sctp_rr_request->so_sndavoid;
   4423   non_block = sctp_rr_request->non_blocking;
   4424 
   4425   set_hostname_and_port(local_name,
   4426 		        port_buffer,
   4427 			nf_to_af(sctp_rr_request->ipfamily),
   4428 			sctp_rr_request->port);
   4429 
   4430   local_res = complete_addrinfo(local_name,
   4431 				local_name,
   4432 				port_buffer,
   4433 				nf_to_af(sctp_rr_request->ipfamily),
   4434 				SOCK_SEQPACKET,
   4435 				IPPROTO_SCTP,
   4436 				0);
   4437 
   4438   /* Grab a socket to listen on, and then listen on it. */
   4439   if (debug) {
   4440     fprintf(where,"recv_sctp_rr_1toMany: grabbing a socket...\n");
   4441     fflush(where);
   4442   }
   4443 
   4444   s_rcv = create_data_socket(local_res);
   4445 
   4446   if (s_rcv < 0) {
   4447     netperf_response.content.serv_errno = errno;
   4448     send_response();
   4449 
   4450     exit(1);
   4451   }
   4452 
   4453   /* Now, let's set-up the socket to listen for connections */
   4454   if (listen(s_rcv, 5) == -1) {
   4455     netperf_response.content.serv_errno = errno;
   4456     close(s_rcv);
   4457     send_response();
   4458 
   4459     exit(1);
   4460   }
   4461 
   4462 
   4463   /* now get the port number assigned by the system  */
   4464   addrlen = sizeof(myaddr_in);
   4465   if (getsockname(s_rcv,
   4466 		  (struct sockaddr *)&myaddr_in, &addrlen) == -1){
   4467     netperf_response.content.serv_errno = errno;
   4468     close(s_rcv);
   4469     send_response();
   4470 
   4471     exit(1);
   4472   }
   4473 
   4474   /* Now myaddr_in contains the port and the internet address this is */
   4475   /* returned to the sender also implicitly telling the sender that the */
   4476   /* socket buffer sizing has been done. */
   4477 
   4478   sctp_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port);
   4479   netperf_response.content.serv_errno   = 0;
   4480 
   4481   /* But wait, there's more. If the initiator wanted cpu measurements, */
   4482   /* then we must call the calibrate routine, which will return the max */
   4483   /* rate back to the initiator. If the CPU was not to be measured, or */
   4484   /* something went wrong with the calibration, we will return a 0.0 to */
   4485   /* the initiator. */
   4486 
   4487   sctp_rr_response->cpu_rate = (float)0.0; 	/* assume no cpu */
   4488   sctp_rr_response->measure_cpu = 0;
   4489 
   4490   if (sctp_rr_request->measure_cpu) {
   4491     sctp_rr_response->measure_cpu = 1;
   4492     sctp_rr_response->cpu_rate = calibrate_local_cpu(sctp_rr_request->cpu_rate);
   4493   }
   4494 
   4495 
   4496   /* before we send the response back to the initiator, pull some of */
   4497   /* the socket parms from the globals */
   4498   sctp_rr_response->send_buf_size = lss_size;
   4499   sctp_rr_response->recv_buf_size = lsr_size;
   4500   sctp_rr_response->no_delay = loc_nodelay;
   4501   sctp_rr_response->so_rcvavoid = loc_rcvavoid;
   4502   sctp_rr_response->so_sndavoid = loc_sndavoid;
   4503   sctp_rr_response->test_length = sctp_rr_request->test_length;
   4504   send_response();
   4505 
   4506   /* Don't need events */
   4507   sctp_enable_events(s_rcv, 0);
   4508 
   4509   /* now that we are connected, mark the socket as non-blocking */
   4510   if (non_block) {
   4511     if (!set_nonblock(s_rcv)) {
   4512       perror("netperf: set_nonblock");
   4513 	exit(1);
   4514     }
   4515   }
   4516 
   4517   /* FIXME:  The way 1-to-Many test operates right now, we are including
   4518    * association setup time into our measurements.  The reason for this
   4519    * is that the client creates multiple endpoints and connects each
   4520    * endpoint to us using the connect call.  On this end we simply call
   4521    * recvmsg() to get data becuase there is no equivalen of accept() for
   4522    * 1-to-Many API.
   4523    * I think this is OK, but if it were to be fixed, the server side
   4524    * would need to know how many associations are being setup and
   4525    * have a recvmsg() loop with SCTP_ASSOC_CHANGE events waiting for
   4526    * all the associations to be be established.
   4527    * I am punting on this for now.
   4528    */
   4529 
   4530 
   4531   addrlen = sizeof(peeraddr);
   4532 
   4533   /* Now it's time to start receiving data on the connection. We will */
   4534   /* first grab the apropriate counters and then start grabbing. */
   4535 
   4536   cpu_start(sctp_rr_request->measure_cpu);
   4537 
   4538   /* The loop will exit when we hit the end of the test time, or when */
   4539   /* we have exchanged the requested number of transactions. */
   4540 
   4541   if (sctp_rr_request->test_length > 0) {
   4542     times_up = 0;
   4543     trans_remaining = 0;
   4544     start_timer(sctp_rr_request->test_length + PAD_TIME);
   4545   }
   4546   else {
   4547     times_up = 1;
   4548     trans_remaining = sctp_rr_request->test_length * -1;
   4549   }
   4550 
   4551   trans_received = 0;
   4552 
   4553   while ((!times_up) || (trans_remaining > 0)) {
   4554 
   4555     recv_buf_size = sctp_rr_request->request_size;
   4556 
   4557     /* Receive the data.  We don't particularly care which association
   4558      * the data came in on.  We'll simply be doing a receive untill
   4559      * we get and MSG_EOR flag (meaning that a single transmission was
   4560      * received) and a send to the same address, so the RR would be for
   4561      * the same associations.
   4562      * We can get away with this because the client will establish all
   4563      * the associations before transmitting any data.  Any partial data
   4564      * will not have EOR thus will we will not send a response untill
   4565      * we get everything.
   4566      */
   4567 
   4568     do {
   4569       msg_flags = 0;
   4570       if((bytes_recvd = sctp_recvmsg(s_rcv,
   4571 				     recv_ring->buffer_ptr,
   4572 				     recv_buf_size,
   4573 				     (struct sockaddr *)&peeraddr, &addrlen,
   4574 				     0, &msg_flags)) == SOCKET_ERROR) {
   4575 	if (SOCKET_EINTR(bytes_recvd)) {
   4576 	  /* the timer popped */
   4577 	  timed_out = 1;
   4578 	  break;
   4579 	} else if (non_block & errno == EAGAIN) {
   4580 	    /* do recvmsg again */
   4581 	    continue;
   4582 	}
   4583 	netperf_response.content.serv_errno = errno;
   4584 	send_response();
   4585 	exit(1);
   4586       }
   4587     } while(!(msg_flags & MSG_EOR));
   4588 
   4589     recv_ring = recv_ring->next;
   4590 
   4591     if (timed_out) {
   4592       /* we hit the end of the test based on time - lets */
   4593       /* bail out of here now... */
   4594       if (debug) {
   4595 	fprintf(where,"yo5\n");
   4596 	fflush(where);
   4597       }
   4598       break;
   4599     }
   4600 
   4601     /* Now, send the response to the remote */
   4602     while ((bytes_sent=sctp_sendmsg(s_rcv,
   4603 			      send_ring->buffer_ptr,
   4604 			      sctp_rr_request->response_size,
   4605 			      (struct sockaddr *)&peeraddr, addrlen,
   4606 			      0, 0, 0, 0, 0)) == SOCKET_ERROR) {
   4607       if (SOCKET_EINTR(bytes_sent)) {
   4608 	/* the test timer has popped */
   4609 	timed_out = 1;
   4610 	break;
   4611       } else if (non_block && errno == EAGAIN) {
   4612 	 continue;
   4613       }
   4614 
   4615       netperf_response.content.serv_errno = 992;
   4616       send_response();
   4617       exit(1);
   4618     }
   4619 
   4620     if (timed_out) {
   4621       if (debug) {
   4622 	fprintf(where,"yo6\n");
   4623 	fflush(where);
   4624       }
   4625       /* we hit the end of the test based on time - lets */
   4626       /* bail out of here now... */
   4627       break;
   4628     }
   4629 
   4630     send_ring = send_ring->next;
   4631 
   4632     trans_received++;
   4633     if (trans_remaining) {
   4634       trans_remaining--;
   4635     }
   4636   }
   4637 
   4638 
   4639   /* The loop now exits due to timeout or transaction count being */
   4640   /* reached */
   4641 
   4642   cpu_stop(sctp_rr_request->measure_cpu,&elapsed_time);
   4643 
   4644   stop_timer();
   4645 
   4646   if (timed_out) {
   4647     /* we ended the test by time, which was at least 2 seconds */
   4648     /* longer than we wanted to run. so, we want to subtract */
   4649     /* PAD_TIME from the elapsed_time. */
   4650     elapsed_time -= PAD_TIME;
   4651   }
   4652 
   4653   /* send the results to the sender			*/
   4654 
   4655   if (debug) {
   4656     fprintf(where,
   4657 	    "recv_sctp_rr: got %d transactions\n",
   4658 	    trans_received);
   4659     fflush(where);
   4660   }
   4661 
   4662   sctp_rr_results->bytes_received = (trans_received *
   4663 				    (sctp_rr_request->request_size +
   4664 				     sctp_rr_request->response_size));
   4665   sctp_rr_results->trans_received = trans_received;
   4666   sctp_rr_results->elapsed_time   = elapsed_time;
   4667   sctp_rr_results->cpu_method     = cpu_method;
   4668   sctp_rr_results->num_cpus       = lib_num_loc_cpus;
   4669   if (sctp_rr_request->measure_cpu) {
   4670     sctp_rr_results->cpu_util	= calc_cpu_util(elapsed_time);
   4671   }
   4672 
   4673   if (debug) {
   4674     fprintf(where,
   4675 	    "recv_sctp_rr: test complete, sending results.\n");
   4676     fflush(where);
   4677   }
   4678 
   4679   /* we are now done with the sockets */
   4680   close(s_rcv);
   4681 
   4682   send_response();
   4683 
   4684 }
   4685 
   4686 
   4687 void
   4688 print_sctp_usage()
   4689 {
   4690 
   4691   printf("%s",sctp_usage);
   4692   exit(1);
   4693 
   4694 }
   4695 void
   4696 scan_sctp_args(argc, argv)
   4697      int	argc;
   4698      char	*argv[];
   4699 
   4700 {
   4701 
   4702 #define SOCKETS_ARGS "BDhH:I:L:m:M:P:r:s:S:VN:T:46"
   4703 
   4704   extern char	*optarg;	  /* pointer to option string	*/
   4705 
   4706   int		c;
   4707 
   4708   char
   4709     arg1[BUFSIZ],  /* argument holders		*/
   4710     arg2[BUFSIZ];
   4711 
   4712   if (no_control) {
   4713     fprintf(where,
   4714 	    "The SCTP tests do not know how to deal with no control tests\n");
   4715     exit(-1);
   4716   }
   4717 
   4718   strncpy(local_data_port,"0",sizeof(local_data_port));
   4719   strncpy(remote_data_port,"0",sizeof(remote_data_port));
   4720 
   4721   /* Go through all the command line arguments and break them */
   4722   /* out. For those options that take two parms, specifying only */
   4723   /* the first will set both to that value. Specifying only the */
   4724   /* second will leave the first untouched. To change only the */
   4725   /* first, use the form "first," (see the routine break_args.. */
   4726 
   4727   while ((c= getopt(argc, argv, SOCKETS_ARGS)) != EOF) {
   4728     switch (c) {
   4729     case '?':
   4730     case '4':
   4731       remote_data_family = AF_INET;
   4732       local_data_family = AF_INET;
   4733       break;
   4734     case '6':
   4735 #if defined(AF_INET6)
   4736       remote_data_family = AF_INET6;
   4737       local_data_family = AF_INET6;
   4738 #else
   4739       fprintf(stderr,
   4740 	      "This netperf was not compiled on an IPv6 capable host!\n");
   4741       fflush(stderr);
   4742       exit(-1);
   4743 #endif
   4744       break;
   4745     case 'h':
   4746       print_sctp_usage();
   4747       exit(1);
   4748     case 'b':
   4749 #ifdef WANT_FIRST_BURST
   4750       first_burst_size = atoi(optarg);
   4751 #else /* WANT_FIRST_BURST */
   4752       printf("Initial request burst functionality not compiled-in!\n");
   4753 #endif /* WANT_FIRST_BURST */
   4754       break;
   4755     case 'D':
   4756       /* set the nodelay flag */
   4757       loc_nodelay = 1;
   4758       rem_nodelay = 1;
   4759       break;
   4760     case 'H':
   4761       break_args_explicit(optarg,arg1,arg2);
   4762       if (arg1[0]) {
   4763 	/* make sure we leave room for the NULL termination boys and
   4764 	   girls. raj 2005-02-82 */
   4765 	remote_data_address = malloc(strlen(arg1)+1);
   4766 	strncpy(remote_data_address,arg1,strlen(arg1));
   4767       }
   4768       if (arg2[0])
   4769 	remote_data_family = parse_address_family(arg2);
   4770       break;
   4771     case 'L':
   4772       break_args_explicit(optarg,arg1,arg2);
   4773       if (arg1[0]) {
   4774 	/* make sure we leave room for the NULL termination boys and
   4775 	   girls. raj 2005-02-82 */
   4776 	local_data_address = malloc(strlen(arg1)+1);
   4777 	strncpy(local_data_address,arg1,strlen(arg1));
   4778       }
   4779       if (arg2[0])
   4780 	local_data_family = parse_address_family(arg2);
   4781       break;
   4782     case 'P':
   4783       /* set the local and remote data port numbers for the tests to
   4784 	 allow them to run through those blankety blank end-to-end
   4785 	 breaking firewalls. raj 2004-06-15 */
   4786       break_args(optarg,arg1,arg2);
   4787       if (arg1[0])
   4788 	strncpy(local_data_port,arg1,sizeof(local_data_port));
   4789       if (arg2[0])
   4790 	strncpy(remote_data_port,arg2,sizeof(remote_data_port));
   4791       break;
   4792     case 's':
   4793       /* set local socket sizes */
   4794       break_args(optarg,arg1,arg2);
   4795       if (arg1[0])
   4796 	lss_size_req = convert(arg1);
   4797       if (arg2[0])
   4798 	lsr_size_req = convert(arg2);
   4799       break;
   4800     case 'S':
   4801       /* set remote socket sizes */
   4802       break_args(optarg,arg1,arg2);
   4803       if (arg1[0])
   4804 	rss_size_req = convert(arg1);
   4805       if (arg2[0])
   4806 	rsr_size_req = convert(arg2);
   4807       break;
   4808     case 'r':
   4809       /* set the request/response sizes */
   4810       break_args(optarg,arg1,arg2);
   4811       if (arg1[0])
   4812 	req_size = convert(arg1);
   4813       if (arg2[0])
   4814 	rsp_size = convert(arg2);
   4815       break;
   4816     case 'm':
   4817       /* set size of the buffer for each sent message */
   4818       send_size = convert(optarg);
   4819       break;
   4820     case 'M':
   4821       /* set the size of the buffer for each received message */
   4822       recv_size = convert(optarg);
   4823       break;
   4824     case 't':
   4825       /* set the test name */
   4826       strcpy(test_name,optarg);
   4827       break;
   4828     case 'W':
   4829 	/* set the "width" of the user space data */
   4830 	/* buffer. This will be the number of */
   4831 	/* send_size buffers malloc'd in the */
   4832 	/* *_STREAM test. It may be enhanced to set */
   4833 	/* both send and receive "widths" but for now */
   4834 	/* it is just the sending *_STREAM. */
   4835 	send_width = convert(optarg);
   4836 	break;
   4837     case 'V':
   4838       /* we want to do copy avoidance and will set */
   4839       /* it for everything, everywhere, if we really */
   4840       /* can. of course, we don't know anything */
   4841       /* about the remote... */
   4842 #ifdef SO_SND_COPYAVOID
   4843       loc_sndavoid = 1;
   4844 #else
   4845       loc_sndavoid = 0;
   4846       printf("Local send copy avoidance not available.\n");
   4847 #endif
   4848 #ifdef SO_RCV_COPYAVOID
   4849       loc_rcvavoid = 1;
   4850 #else
   4851       loc_rcvavoid = 0;
   4852       printf("Local recv copy avoidance not available.\n");
   4853 #endif
   4854       rem_sndavoid = 1;
   4855       rem_rcvavoid = 1;
   4856       break;
   4857     case 'N':
   4858       /* this opton allows the user to set the number of
   4859        * messages to send.  This in effect modifies the test
   4860        * time.  If we know the message size, then the we can
   4861        * express the test time as message_size * number_messages
   4862        */
   4863       msg_count = convert (optarg);
   4864       if (msg_count > 0)
   4865 	  test_time = 0;
   4866       break;
   4867     case 'B':
   4868       non_block = 1;
   4869       break;
   4870     case 'T':
   4871       num_associations = atoi(optarg);
   4872       if (num_associations <= 1) {
   4873 	  printf("Number of SCTP associations must be >= 1\n");
   4874 	  exit(1);
   4875       }
   4876       break;
   4877     };
   4878   }
   4879 }
   4880 
   4881 #endif  /* WANT_SCTP */
   4882