1 /* SCTP kernel Implementation
2 * (C) Copyright IBM Corp. 2002, 2003
3 * Copyright (c) 1999-2000 Cisco, Inc.
4 * Copyright (c) 1999-2001 Motorola, Inc.
5 * Copyright (c) 2001 Intel Corp.
6 * Copyright (c) 2001 Nokia, Inc.
8 * The SCTP implementation is free software;
9 * you can redistribute it and/or modify it under the terms of
10 * the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
14 * The SCTP implementation is distributed in the hope that it
15 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16 * ************************
17 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 * See the GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with GNU CC; see the file COPYING. If not, write to
22 * the Free Software Foundation, 59 Temple Place - Suite 330,
23 * Boston, MA 02111-1307, USA.
25 * Please send any bug reports or fixes you make to the
27 * lksctp developers <lksctp-developers@lists.sourceforge.net>
29 * Or submit a bug report through the following website:
30 * http://www.sf.net/projects/lksctp
32 * Any bugs reported to us we will try to fix... any fixes shared will
33 * be incorporated into the next SCTP release.
35 * Written or modified by:
36 * Ardelle Fan <ardelle.fan@intel.com>
37 * Sridhar Samudrala <sri@us.ibm.com>
40 /* This is a receiver for the performance test to verify Nagle's algorithm.
41 * It creates a socket, binds to a address specified as a parameter and
42 * goes into a receive loop waiting for 1,000,000 packets. Then it calculates
43 * the packet receive rate, i.e. packets/second.
50 #include <sys/types.h>
51 #include <sys/socket.h>
53 #include <netinet/in.h>
54 #include <sys/errno.h>
56 #include <netinet/sctp.h>
62 char *TCID = __FILE__;
69 fprintf(stderr, "Usage: %s -H hostname [-P port]\n", progname);
70 fprintf(stderr, " -H, --local\t\t local hostname,\n");
71 fprintf(stderr, " -P, --local-port\t local port,\n");
75 main(int argc, char *argv[])
79 sockaddr_storage_t host;
80 sockaddr_storage_t msgname;
82 struct msghdr inmessage;
83 char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
85 int pf_class, af_family;
87 char *local_host = NULL;
88 int local_port = SCTP_TESTPORT_1;
91 int bytes_received = 0;
93 static struct option long_options[] = {
95 {"local-port", 1, 0, 2},
99 /* Rather than fflush() throughout the code, set stdout to
102 setvbuf(stdout, NULL, _IONBF, 0);
104 /* Parse the arguments. */
106 c = getopt_long (argc, argv, "H:P:",
107 long_options, &option_index);
113 printf("option %s", long_options[option_index].name);
115 printf(" with arg %s", optarg);
119 case 1: /* local host */
123 case 2: /* local port */
125 local_port = atoi(optarg);
132 printf ("%s: unrecognized option 0%c\n", argv[0], c);
140 fprintf(stderr, "%s: non-option arguments are illegal: ",
142 while (optind < argc)
143 fprintf(stderr, "%s ", argv[optind++]);
144 fprintf (stderr, "\n");
150 fprintf(stderr, "%s: : option -H, --local is required\n",
156 /* Set some basic values which depend on the address family. */
158 hst = gethostbyname2(local_host, AF_INET6);
159 if (hst == NULL || hst->h_length < 1) {
160 fprintf(stderr, "%s: bad hostname: %s\n", argv[0], local_host);
164 af_family = AF_INET6;
166 host.v6.sin6_family = AF_INET6;
167 memcpy(&host.v6.sin_addr, hst->h_addr_list[0], hst->h_length);
168 host.v6.sin6_port = htons(local_port);
171 hst = gethostbyname(local_host);
172 if (hst == NULL || hst->h_length < 1) {
173 fprintf(stderr, "%s: bad hostname: %s\n", argv[0], local_host);
179 host.v4.sin_family = AF_INET;
180 memcpy(&host.v4.sin_addr, hst->h_addr_list[0], hst->h_length);
181 host.v4.sin_port = htons(local_port);
185 /* Create the endpoint which will talk to nagle_snd. */
186 sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
188 /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
189 test_enable_assoc_change(sk);
191 /* Bind the sockets to the test port. */
192 test_bind(sk, &host.sa, sizeof(host));
194 /* Mark sk as being able to accept new associations. */
197 printf("Listening on port:%d\n", local_port);
199 /* Initialize inmessage for receives. */
200 memset(&inmessage, 0, sizeof(inmessage));
201 big_buffer = test_malloc(REALLY_BIG);
202 iov.iov_base = big_buffer;
203 iov.iov_len = REALLY_BIG;
204 inmessage.msg_iov = &iov;
205 inmessage.msg_iovlen = 1;
206 inmessage.msg_control = incmsg;
207 inmessage.msg_controllen = sizeof(incmsg);
208 inmessage.msg_name = &msgname;
209 inmessage.msg_namelen = sizeof(msgname);
210 memset(&msgname, 0, sizeof(msgname));
212 /* Get the communication up message on sk. */
213 error = test_recvmsg(sk, &inmessage, MSG_WAITALL);
214 test_check_msg_notification(&inmessage, error,
215 sizeof(struct sctp_assoc_change),
216 SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
218 printf("Established connection with ");
219 if (AF_INET == msgname.sa.sa_family)
220 printf("%d.%d.%d.%d(%d)\n", NIPQUAD(msgname.v4.sin_addr),
221 ntohs(msgname.v4.sin_port));
222 if (AF_INET6 == msgname.sa.sa_family)
223 printf("%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x(%d)\n",
224 NIP6(msgname.v6.sin6_addr), ntohs(msgname.v6.sin6_port));
227 for (i=0; i<1000000; i++) {
228 inmessage.msg_controllen = sizeof(incmsg);
229 inmessage.msg_namelen = sizeof(msgname);
230 error = test_recvmsg(sk, &inmessage, MSG_WAITALL);
231 if (inmessage.msg_flags & MSG_NOTIFICATION)
233 printf("Received %d bytes of data\n", error);
234 bytes_received += error;
238 printf("\t%d messages(%d bytes) successfully received in %ld "
239 "seconds.\n", i, bytes_received, to - from);
240 printf("The receive rate is %ld bytes/second\n",
241 bytes_received/(to - from));
243 /* Shut down the link. */