• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2020-2023. All rights reserved.
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 <netdb.h>
17 #include <netinet/in.h>
18 #include <sys/socket.h>
19 #include <arpa/inet.h>
20 #include <unistd.h>
21 #include <pthread.h>
22 #include "util.h"
23 
24 constexpr int PORT = 1500; // port
25 constexpr int PIPE_FD_COUNT = 2;
26 constexpr int BUFFER_SIZE = 100;
27 constexpr int MSG_COUNT = 10;
28 
Bm_function_socket_server(benchmark::State & state)29 static void Bm_function_socket_server(benchmark::State &state)
30 {
31     struct sockaddr_in serverAddr;
32     memset(&serverAddr, 0, sizeof(serverAddr));
33     serverAddr.sin_family = AF_INET;
34     serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); // Any IP address of this host
35     serverAddr.sin_port = htons(PORT);
36     int eight = 8;
37     bzero(&(serverAddr.sin_zero), eight); // Set other attributes to 0
38     for (auto _ : state) {
39         int serverFd = socket(AF_INET, SOCK_STREAM, 0);
40         if (serverFd == -1) {
41             printf("socket failed:%d", errno);
42             break;
43         }
44         close(serverFd);
45     }
46     state.SetBytesProcessed(state.iterations());
47 }
48 
Bm_function_socketpair_sendmsg_recvmsg(benchmark::State & state)49 static void Bm_function_socketpair_sendmsg_recvmsg(benchmark::State &state)
50 {
51     int ret;
52     int socks[2];
53     struct msghdr msg;
54     struct iovec iov[1];
55     char sendBuf[BUFFER_SIZE] = "it is a test";
56     struct msghdr msgr;
57     struct iovec iovr[1];
58     char recvBuf[BUFFER_SIZE];
59 
60     for (auto _ : state) {
61         ret = socketpair(AF_LOCAL, SOCK_STREAM, 0, socks);
62         if (ret == -1) {
63             printf("socketpair sendmsg err\n");
64             break;
65         }
66 
67         bzero(&msg, sizeof(msg));
68         msg.msg_name = nullptr;
69         msg.msg_namelen = 0;
70         iov[0].iov_base = sendBuf;
71         iov[0].iov_len = sizeof(sendBuf);
72         msg.msg_iov = iov;
73         msg.msg_iovlen = 1;
74 
75         ret = sendmsg(socks[1], &msg, 0);
76         if (ret == -1) {
77             printf("sendmsg err\n");
78             close(socks[0]);
79             close(socks[1]);
80             break;
81         }
82 
83         bzero(&msgr, sizeof(msgr));
84         msgr.msg_name = nullptr;
85         msgr.msg_namelen = 0;
86         iovr[0].iov_base = &recvBuf;
87         iovr[0].iov_len = sizeof(recvBuf);
88         msgr.msg_iov = iovr;
89         msgr.msg_iovlen = 1;
90         ret = recvmsg(socks[0], &msgr, 0);
91         if (ret == -1) {
92             printf("recvmsg err\n");
93         }
94         close(socks[0]);
95         close(socks[1]);
96     }
97     state.SetBytesProcessed(state.iterations());
98 }
99 
Bm_function_socketpair_sendmmsg_recvmmsg(benchmark::State & state)100 static void Bm_function_socketpair_sendmmsg_recvmmsg(benchmark::State &state)
101 {
102     int ret;
103     int socks[2];
104     struct mmsghdr msgs[MSG_COUNT];
105     struct iovec iovs[MSG_COUNT][1];
106     char sendBuf[BUFFER_SIZE] = "it is a test";
107     struct mmsghdr msgsr[MSG_COUNT];
108     struct iovec iovsr[MSG_COUNT][1];
109     char recvBuf[BUFFER_SIZE];
110 
111     for (auto _ : state) {
112         ret = socketpair(AF_LOCAL, SOCK_STREAM, 0, socks);
113         if (ret == -1) {
114             printf("socketpair sendmsg err\n");
115             break;
116         }
117 
118         for (int i = 0; i < MSG_COUNT; i++) {
119             bzero(&msgs[i], sizeof(msgs[i]));
120             msgs[i].msg_hdr.msg_name = nullptr;
121             msgs[i].msg_hdr.msg_namelen = 0;
122             iovs[i][0].iov_base = sendBuf;
123             iovs[i][0].iov_len = sizeof(sendBuf);
124             msgs[i].msg_hdr.msg_iov = iovs[i];
125             msgs[i].msg_hdr.msg_iovlen = 1;
126         }
127 
128         ret = sendmmsg(socks[1], msgs, MSG_COUNT, 0);
129         if (ret == -1) {
130             printf("sendmmsg err\n");
131             close(socks[0]);
132             close(socks[1]);
133             break;
134         }
135 
136         for (int i = 0; i < MSG_COUNT; i++) {
137             bzero(&msgsr[i], sizeof(msgsr[i]));
138             msgsr[i].msg_hdr.msg_name = nullptr;
139             msgsr[i].msg_hdr.msg_namelen = 0;
140             iovsr[i][0].iov_base = &recvBuf;
141             iovsr[i][0].iov_len = sizeof(recvBuf);
142             msgsr[i].msg_hdr.msg_iov = iovsr[i];
143             msgsr[i].msg_hdr.msg_iovlen = 1;
144         }
145         ret = recvmmsg(socks[0], msgsr, MSG_COUNT, 0, nullptr);
146         if (ret == -1) {
147             printf("recvmmsg err\n");
148         }
149         close(socks[0]);
150         close(socks[1]);
151     }
152     state.SetBytesProcessed(state.iterations());
153 }
154 
Bm_function_socketpair_sendto_recvfrom(benchmark::State & state)155 static void Bm_function_socketpair_sendto_recvfrom(benchmark::State &state)
156 {
157     int ret;
158     int socks[2];
159     char sendBuf[BUFFER_SIZE] = "it is a test";
160     char recvBuf[BUFFER_SIZE];
161 
162     for (auto _ : state) {
163         ret = socketpair(AF_LOCAL, SOCK_STREAM, 0, socks);
164         if (ret == -1) {
165             printf("socketpair sendto err\n");
166             break;
167         }
168 
169         ret = sendto(socks[1], sendBuf, sizeof(sendBuf), 0, nullptr, 0);
170         if (ret == -1) {
171             printf("sendto err\n");
172             close(socks[0]);
173             close(socks[1]);
174             break;
175         }
176 
177         ret = recvfrom(socks[0], recvBuf, sizeof(recvBuf), 0, nullptr, 0);
178         if (ret == -1) {
179             printf("recvfrom err\n");
180         }
181         close(socks[0]);
182         close(socks[1]);
183     }
184     state.SetBytesProcessed(state.iterations());
185 }
186 
Bm_function_getsockopt(benchmark::State & state)187 static void Bm_function_getsockopt(benchmark::State &state)
188 {
189     int optVal;
190     socklen_t optLen = sizeof(optVal);
191 
192     for (auto _ : state) {
193         int sockFd = socket(AF_INET, SOCK_STREAM, 0);
194         if (getsockopt(sockFd, SOL_SOCKET, SO_SNDBUF, &optVal, &optLen) < 0) {
195             printf("fail to getsockopt");
196         }
197         close(sockFd);
198     }
199     state.SetBytesProcessed(state.iterations());
200 }
201 
Bm_function_setsockopt(benchmark::State & state)202 static void Bm_function_setsockopt(benchmark::State &state)
203 {
204     for (auto _ : state) {
205         int nRecvBuf = 32*1024; // Set to 32K
206         int sockFd = socket(AF_INET, SOCK_STREAM, 0);
207         if (setsockopt(sockFd, SOL_SOCKET, SO_RCVBUF, (const char*)&nRecvBuf, sizeof(int)) < 0) {
208             printf("fail to setsockopt");
209         }
210         close(sockFd);
211     }
212     state.SetBytesProcessed(state.iterations());
213 }
214 
Bm_function_sockpair(benchmark::State & state)215 static void Bm_function_sockpair(benchmark::State &state)
216 {
217     for (auto _ : state) {
218         int fd[PIPE_FD_COUNT] = {-1, -1};
219         benchmark::DoNotOptimize(socketpair(0, SOCK_STREAM, 0, fd));
220         state.PauseTiming();
221         for (size_t i = 0; i < PIPE_FD_COUNT; i++) {
222             if (fd[i] >= 0) {
223                 close(fd[i]);
224             }
225         }
226         state.ResumeTiming();
227     }
228 }
229 
Bm_function_pipe(benchmark::State & state)230 static void Bm_function_pipe(benchmark::State &state)
231 {
232     for (auto _ : state) {
233         int fd[PIPE_FD_COUNT] = {-1, -1};
234         benchmark::DoNotOptimize(pipe(fd));
235         state.PauseTiming();
236         for (size_t i = 0; i < PIPE_FD_COUNT; i++) {
237             if (fd[i] >= 0) {
238                 close(fd[i]);
239             }
240         }
241         state.ResumeTiming();
242     }
243 }
244 
ConnectTo(const char * host,const char * port,int socktype,struct addrinfo * addr)245 static int ConnectTo(const char *host, const char *port, int socktype, struct addrinfo *addr)
246 {
247     struct addrinfo hint;
248     struct addrinfo *res;
249     bzero(&hint, sizeof(struct addrinfo));
250     hint.ai_flags = 0;
251     hint.ai_family = AF_UNSPEC;
252     hint.ai_protocol = 0;
253     hint.ai_socktype = socktype;
254 
255     int n = getaddrinfo(host, port, &hint, &res);
256     if (n != 0) {
257         perror("getaddrinfo");
258         return -1;
259     }
260 
261     int sfd = -1;
262     for (struct addrinfo *rp = res; rp != nullptr; rp = rp->ai_next) {
263         sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
264         if (sfd == -1) {
265             continue;
266         }
267 
268         if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) {
269             if (addr != nullptr) {
270                 struct sockaddr *aiAddr = addr->ai_addr;
271                 *addr = *rp;
272                 *aiAddr = *rp->ai_addr;
273                 addr->ai_addr = aiAddr;
274             }
275             break;
276         }
277 
278         close(sfd);
279         sfd = -1;
280     }
281 
282     freeaddrinfo(res);
283 
284     if (sfd == -1) {
285         perror("connect");
286     }
287 
288     return sfd;
289 }
290 
BindAt(const char * port)291 static int BindAt(const char *port)
292 {
293     struct addrinfo hint;
294     struct addrinfo *res;
295     bzero(&hint, sizeof(struct addrinfo));
296     hint.ai_flags = AI_PASSIVE;
297     hint.ai_family = AF_UNSPEC;
298     hint.ai_protocol = 0;
299     hint.ai_socktype = SOCK_STREAM;
300 
301     int n = getaddrinfo("127.0.0.1", port, &hint, &res);
302     if (n != 0) {
303         perror("getaddrinfo");
304         return -1;
305     }
306 
307     int sfd = -1;
308     for (struct addrinfo *rp = res; rp != nullptr; rp = rp->ai_next) {
309         sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
310         if (sfd == -1) {
311             continue;
312         }
313 
314         int reuse = 1;
315         if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) {
316             close(sfd);
317             continue;
318         }
319 
320         if (bind(sfd, rp->ai_addr, rp->ai_addrlen) != -1) {
321             break;
322         }
323 
324         close(sfd);
325         sfd = -1;
326     }
327 
328     freeaddrinfo(res);
329 
330     if (sfd == -1) {
331         perror("bind");
332     }
333 
334     return sfd;
335 }
336 
Bm_function_getpeername_client_local(benchmark::State & state)337 static void Bm_function_getpeername_client_local(benchmark::State &state)
338 {
339     int sfd = ConnectTo("127.0.0.1", "80", SOCK_DGRAM, nullptr);
340     if (sfd == -1) {
341     }
342 
343     struct sockaddr_in peerAddr;
344     socklen_t peerLen = sizeof(peerAddr);
345     for (auto _ : state) {
346         if (getpeername(sfd, (struct sockaddr *)&peerAddr, &peerLen) == -1) {
347             perror("getpeername");
348             printf("peer addr: %s:%d\n", inet_ntoa(peerAddr.sin_addr), ntohs(peerAddr.sin_port));
349         }
350     }
351 
352     close(sfd);
353 }
354 
Bm_function_getpeername_client_external(benchmark::State & state)355 static void Bm_function_getpeername_client_external(benchmark::State &state)
356 {
357     int sfd = ConnectTo("www.baidu.com", "80", SOCK_DGRAM, nullptr);
358     if (sfd == -1) {
359     }
360 
361     struct sockaddr_in peerAddr;
362     socklen_t peerLen = sizeof(peerAddr);
363     for (auto _ : state) {
364         if (getpeername(sfd, (struct sockaddr *)&peerAddr, &peerLen) == -1) {
365             perror("getpeername");
366             printf("peer addr: %s:%d\n", inet_ntoa(peerAddr.sin_addr), ntohs(peerAddr.sin_port));
367         }
368     }
369 
370     close(sfd);
371 }
372 
ThreadTaskClient(void * arg)373 void* ThreadTaskClient(void* arg)
374 {
375     int sfd = ConnectTo("127.0.0.1", "1500", SOCK_STREAM, nullptr);
376     if (sfd == -1) {
377         return (void*)-1;
378     }
379 
380     close(sfd);
381     return nullptr;
382 }
383 
StartServer(int * connfd)384 static int StartServer(int *connfd)
385 {
386     int sfd = BindAt("1500");
387     if (sfd == -1) {
388         return -1;
389     }
390 
391     if (listen(sfd, 1) < 0) {
392         perror("listen");
393         return -1;
394     }
395 
396     pthread_t thread;
397     void *res;
398     pthread_create(&thread, nullptr, ThreadTaskClient, nullptr);
399     pthread_join(thread, &res);
400     if (res == (void*)-1) {
401         return -1;
402     }
403 
404     *connfd = accept(sfd, nullptr, nullptr);
405     if (*connfd < 0) {
406         perror("accept");
407         return -1;
408     }
409 
410     return sfd;
411 }
412 
Bm_function_getpeername_server(benchmark::State & state)413 static void Bm_function_getpeername_server(benchmark::State &state)
414 {
415     int connfd;
416     int sfd = StartServer(&connfd);
417     if (sfd < 0) {
418     }
419 
420     struct sockaddr_in peerAddr;
421     socklen_t peerLen = sizeof(peerAddr);
422     for (auto _ : state) {
423         if (getpeername(connfd, (struct sockaddr *)&peerAddr, &peerLen) == -1) {
424             perror("getpeername");
425             printf("peer addr: %s:%d\n", inet_ntoa(peerAddr.sin_addr), ntohs(peerAddr.sin_port));
426         }
427     }
428 
429     close(sfd);
430 }
431 
Bm_function_getsockname_client_local(benchmark::State & state)432 static void Bm_function_getsockname_client_local(benchmark::State &state)
433 {
434     int sfd = ConnectTo("127.0.0.1", "80", SOCK_DGRAM, nullptr);
435     if (sfd == -1) {
436     }
437 
438     struct sockaddr_in addr;
439     socklen_t len = sizeof(addr);
440     for (auto _ : state) {
441         if (getsockname(sfd, (struct sockaddr *)&addr, &len) == -1) {
442             perror("getsockname");
443             printf("sock addr: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
444         }
445     }
446 
447     close(sfd);
448 }
449 
Bm_function_getsockname_client_external(benchmark::State & state)450 static void Bm_function_getsockname_client_external(benchmark::State &state)
451 {
452     int sfd = ConnectTo("www.baidu.com", "80", SOCK_DGRAM, nullptr);
453     if (sfd == -1) {
454     }
455 
456     struct sockaddr_in addr;
457     socklen_t len = sizeof(addr);
458     for (auto _ : state) {
459         if (getsockname(sfd, (struct sockaddr *)&addr, &len) == -1) {
460             perror("getsockname");
461             printf("sock addr: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
462         }
463     }
464 
465     close(sfd);
466 }
467 
Bm_function_getsockname_server(benchmark::State & state)468 static void Bm_function_getsockname_server(benchmark::State &state)
469 {
470     int connfd;
471     int sfd = StartServer(&connfd);
472     if (sfd < 0) {
473     }
474 
475     struct sockaddr_in addr;
476     socklen_t len = sizeof(addr);
477     for (auto _ : state) {
478         if (getsockname(connfd, (struct sockaddr *)&addr, &len) == -1) {
479             perror("getsockname");
480             printf("sock addr: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
481         }
482     }
483 
484     close(sfd);
485 }
486 
Bm_function_connect_local_dgram(benchmark::State & state)487 static void Bm_function_connect_local_dgram(benchmark::State &state)
488 {
489     struct addrinfo addr;
490     struct sockaddr_in aiAddr;
491     addr.ai_addr = (struct sockaddr*)&aiAddr;
492     int sfd = ConnectTo("127.0.0.1", "80", SOCK_DGRAM, &addr);
493     if (sfd < 0) {
494     }
495 
496     for (auto _ : state) {
497         if (connect(sfd, addr.ai_addr, addr.ai_addrlen) == -1) {
498             perror("connect");
499         }
500     }
501 
502     close(sfd);
503 }
504 
Bm_function_connect_accept(benchmark::State & state)505 static void Bm_function_connect_accept(benchmark::State &state)
506 {
507     int sfd = BindAt("1500");
508     if (sfd == -1) {
509     }
510 
511     if (listen(sfd, 1) < 0) {
512         perror("listen");
513     }
514 
515     struct addrinfo addr;
516     struct sockaddr_in aiAddr;
517     addr.ai_addr = (struct sockaddr*)&aiAddr;
518     int sfd2 = ConnectTo("127.0.0.1", "1500", SOCK_STREAM, &addr);
519     if (sfd2 == -1) {
520     }
521 
522     for (auto _ : state) {
523         int connfd = accept(sfd, nullptr, nullptr);
524         if (connfd < 0) {
525             perror("accept");
526         }
527 
528         state.PauseTiming();
529         close(connfd);
530         close(sfd2);
531         sfd2 = socket(addr.ai_family, addr.ai_socktype, addr.ai_protocol);
532         if (sfd == -1) {
533             perror("socket");
534         }
535         if (connect(sfd2, addr.ai_addr, addr.ai_addrlen) == -1) {
536             perror("connect2");
537         }
538         state.ResumeTiming();
539     }
540 
541     close(sfd);
542 }
543 
Bm_function_bind(benchmark::State & state)544 static void Bm_function_bind(benchmark::State &state)
545 {
546     struct sockaddr_in addr;
547     memset(&addr, 0, sizeof(addr));
548     addr.sin_family = AF_INET;
549     addr.sin_addr.s_addr = htonl(INADDR_ANY);
550     addr.sin_port = htons(PORT);
551 
552     for (auto _ : state) {
553         state.PauseTiming();
554         int sfd = socket(AF_INET, SOCK_STREAM, 0);
555         if (sfd == -1) {
556             perror("socket");
557         }
558 
559         int reuse = 1;
560         if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) {
561             perror("setsockopt");
562             close(sfd);
563         }
564 
565         state.ResumeTiming();
566 
567         if (bind(sfd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
568             perror("bind");
569         }
570 
571         state.PauseTiming();
572         close(sfd);
573         state.ResumeTiming();
574     }
575 }
576 
577 MUSL_BENCHMARK(Bm_function_socket_server);
578 MUSL_BENCHMARK(Bm_function_socketpair_sendmsg_recvmsg);
579 MUSL_BENCHMARK(Bm_function_socketpair_sendmmsg_recvmmsg);
580 MUSL_BENCHMARK(Bm_function_socketpair_sendto_recvfrom);
581 MUSL_BENCHMARK(Bm_function_getsockopt);
582 MUSL_BENCHMARK(Bm_function_setsockopt);
583 MUSL_BENCHMARK(Bm_function_sockpair);
584 MUSL_BENCHMARK(Bm_function_pipe);
585 MUSL_BENCHMARK(Bm_function_getpeername_client_local);
586 MUSL_BENCHMARK(Bm_function_getpeername_client_external);
587 MUSL_BENCHMARK(Bm_function_getpeername_server);
588 MUSL_BENCHMARK(Bm_function_getsockname_client_local);
589 MUSL_BENCHMARK(Bm_function_getsockname_client_external);
590 MUSL_BENCHMARK(Bm_function_getsockname_server);
591 MUSL_BENCHMARK(Bm_function_connect_local_dgram);
592 MUSL_BENCHMARK(Bm_function_connect_accept);
593 MUSL_BENCHMARK(Bm_function_bind);
594