Overall tcp performance improvements (VPP-846)
[vpp.git] / src / uri / uri_socket_test.c
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <stdio.h>
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <netinet/in.h>
20 #include <netdb.h>
21 #include <vppinfra/format.h>
22 #include <sys/time.h>
23
24 int
25 main (int argc, char *argv[])
26 {
27   int sockfd, portno, n;
28   struct sockaddr_in serv_addr;
29   struct hostent *server;
30   u8 *rx_buffer = 0, *tx_buffer = 0, no_echo = 0, test_bytes = 0;
31   u32 offset;
32   long bytes = 1 << 20, to_send;
33   int i;
34   struct timeval start, end;
35   double deltat;
36
37   if (argc >= 3)
38     {
39       bytes = ((long) atoi (argv[4])) << 20;
40       no_echo = atoi (argv[3]);
41       portno = atoi (argv[2]);
42       server = gethostbyname (argv[1]);
43       if (server == NULL)
44         {
45           clib_unix_warning ("gethostbyname");
46           exit (1);
47         }
48     }
49   else
50     {
51       portno = 1234;            // atoi(argv[2]);
52       server = gethostbyname ("6.0.1.1" /* argv[1] */ );
53       if (server == NULL)
54         {
55           clib_unix_warning ("gethostbyname");
56           exit (1);
57         }
58     }
59
60   to_send = bytes;
61   sockfd = socket (AF_INET, SOCK_STREAM, 0);
62   if (sockfd < 0)
63     {
64       clib_unix_error ("socket");
65       exit (1);
66     }
67
68   bzero ((char *) &serv_addr, sizeof (serv_addr));
69   serv_addr.sin_family = AF_INET;
70   bcopy ((char *) server->h_addr,
71          (char *) &serv_addr.sin_addr.s_addr, server->h_length);
72   serv_addr.sin_port = htons (portno);
73   if (connect (sockfd, (const void *) &serv_addr, sizeof (serv_addr)) < 0)
74     {
75       clib_unix_warning ("connect");
76       exit (1);
77     }
78
79   vec_validate (rx_buffer, 128 << 10);
80   vec_validate (tx_buffer, 128 << 10);
81
82   for (i = 0; i < vec_len (tx_buffer); i++)
83     tx_buffer[i] = (i + 1) % 0xff;
84
85   /*
86    * Send one packet to warm up the RX pipeline
87    */
88   n = send (sockfd, tx_buffer, vec_len (tx_buffer), 0 /* flags */ );
89   if (n != vec_len (tx_buffer))
90     {
91       clib_unix_warning ("write");
92       exit (0);
93     }
94
95   gettimeofday (&start, NULL);
96   while (bytes > 0)
97     {
98       /*
99        * TX
100        */
101       n = send (sockfd, tx_buffer, vec_len (tx_buffer), 0 /* flags */ );
102       if (n != vec_len (tx_buffer))
103         {
104           clib_unix_warning ("write");
105           exit (0);
106         }
107       bytes -= n;
108
109       if (no_echo)
110         continue;
111
112       /*
113        * RX
114        */
115
116       offset = 0;
117       do
118         {
119           n = recv (sockfd, rx_buffer + offset,
120                     vec_len (rx_buffer) - offset, 0 /* flags */ );
121           if (n < 0)
122             {
123               clib_unix_warning ("read");
124               exit (0);
125             }
126           offset += n;
127         }
128       while (offset < vec_len (rx_buffer));
129
130       if (test_bytes)
131         {
132           for (i = 0; i < vec_len (rx_buffer); i++)
133             {
134               if (rx_buffer[i] != tx_buffer[i])
135                 {
136                   clib_warning ("[%d] read 0x%x not 0x%x", rx_buffer[i],
137                                 tx_buffer[i]);
138                   exit (1);
139                 }
140             }
141         }
142     }
143   close (sockfd);
144   gettimeofday (&end, NULL);
145
146   deltat = (end.tv_sec - start.tv_sec);
147   deltat += (end.tv_usec - start.tv_usec) / 1000000.0;  // us to ms
148   clib_warning ("Finished in %.6f", deltat);
149   clib_warning ("%.4f Gbit/second %s", (((f64) to_send * 8.0) / deltat / 1e9),
150                 no_echo ? "half" : "full");
151   return 0;
152 }
153
154
155 /*
156  * fd.io coding-style-patch-verification: ON
157  *
158  * Local Variables:
159  * eval: (c-set-style "gnu")
160  * End:
161  */