• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
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 <arpa/inet.h>
17 #include <netinet/ip.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <sys/select.h>
22 #include <sys/socket.h>
23 #include <sys/wait.h>
24 #include <time.h>
25 #include "functionalext.h"
26 
27 #define TEST_MSG_PORT 7788
28 #define TEST_BUF_SIZE 256
29 #define TEST_TIMEOUT 5
30 
31 const char *text = "This is a simple test case.";
32 
fill_socket_addr(struct sockaddr_in * addr)33 void fill_socket_addr(struct sockaddr_in *addr)
34 {
35     if (addr) {
36         bzero(addr, sizeof(struct sockaddr_in));
37         addr->sin_family = AF_INET;
38         inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
39         addr->sin_port = htons(TEST_MSG_PORT);
40     }
41 }
42 
check_recv_message(int sockfd)43 int check_recv_message(int sockfd)
44 {
45     struct timeval t;
46     fd_set rset;
47 
48     int timeout = TEST_TIMEOUT;
49     int ret;
50     while (timeout > 0) {
51         FD_ZERO(&rset);
52         FD_SET(sockfd, &rset);
53         t.tv_sec = 1;
54         t.tv_usec = 0;
55 
56         ret = select(sockfd + 1, &rset, NULL, NULL, &t);
57         if (ret == 0) {
58             timeout--;
59         } else if (ret < 0) {
60             return ret;
61         } else {
62             if (FD_ISSET(sockfd, &rset)) {
63                 return ret;
64             }
65         }
66     }
67     return -1;
68 }
69 
send_message(int flag,const char * msg)70 void send_message(int flag, const char *msg)
71 {
72     int sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
73     if (sockfd == -1) {
74         t_error("[%s] failed\n", msg);
75         return;
76     }
77 
78     struct sockaddr_in addr;
79     struct msghdr msg_send;
80     struct iovec iov_send;
81     char buf[TEST_BUF_SIZE];
82 
83     fill_socket_addr(&addr);
84     memset(&msg_send, 0x0, sizeof(struct msghdr));
85     memset(&iov_send, 0x0, sizeof(struct iovec));
86 
87     iov_send.iov_base = buf;
88     iov_send.iov_len = TEST_BUF_SIZE;
89 
90     msg_send.msg_iovlen = 1;
91     msg_send.msg_iov = &iov_send;
92     msg_send.msg_control = 0;
93     msg_send.msg_controllen = 0;
94 
95     if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
96         close(sockfd);
97         t_error("[%s] failed\n", msg);
98         return;
99     }
100 
101     int ret = sendmsg(sockfd, &msg_send, flag);
102     close(sockfd);
103     EXPECT_TRUE(msg, ret > 0);
104 }
105 
recv_message(int flag,const char * msg)106 int recv_message(int flag, const char *msg)
107 {
108     int sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
109     if (sockfd == -1) {
110         t_error("[%s] failed\n", msg);
111         exit(1);
112     }
113 
114     struct sockaddr_in addr;
115     struct msghdr msg_recv;
116     struct iovec iov_recv;
117     char buf[TEST_BUF_SIZE];
118     char control[TEST_BUF_SIZE];
119 
120     fill_socket_addr(&addr);
121     memset(&msg_recv, 0x0, sizeof(struct msghdr));
122     memset(&iov_recv, 0x0, sizeof(struct iovec));
123     memset(buf, 0x0, sizeof(buf));
124 
125     iov_recv.iov_base = (void *)buf;
126     iov_recv.iov_len = TEST_BUF_SIZE;
127 
128     msg_recv.msg_name = &addr;
129     msg_recv.msg_iovlen = 1;
130     msg_recv.msg_iov = &iov_recv;
131     msg_recv.msg_control = control;
132     msg_recv.msg_controllen = TEST_BUF_SIZE;
133     msg_recv.msg_flags = 0;
134 
135     if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
136         close(sockfd);
137         t_error("[%s] failed\n", msg);
138         exit(1);
139     }
140 
141     int ret = check_recv_message(sockfd);
142     EXPECT_TRUE(msg, ret > 0);
143     if (ret > 0) {
144         ret = recvmsg(sockfd, &msg_recv, flag);
145         EXPECT_TRUE(msg, ret > 0);
146         EXPECT_STREQ(msg, iov_recv.iov_base, text);
147     }
148     close(sockfd);
149     exit(0);
150 }
151 
152 /**
153  * @tc.name      : recvmsg_0100
154  * @tc.desc      : Test recvmsg to recv messages through socket
155  * @tc.level     : Level 0
156  */
recvmsg_0100(void)157 void recvmsg_0100(void)
158 {
159     pid_t pid = fork();
160     if (pid == 0) {
161         recv_message(0, "recvmsg_0100");
162     } else if (pid > 0) {
163         sleep(1);
164         send_message(0, "recvmsg_0100");
165         wait(NULL);
166     } else {
167         t_error("recvmsg_0100 fork error");
168     }
169 }
170 
main(void)171 int main(void)
172 {
173     recvmsg_0100();
174     return t_status;
175 }