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