1 /*
2 * Copyright (C) 2021-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 "net.h"
17 #include <fcntl.h>
18 #include <poll.h>
19 #include <unistd.h>
20 #include <securec.h>
21 #include <sys/socket.h>
22 #include <sys/un.h>
23 #include "common.h"
24 #include "errno.h"
25 #include "log.h"
26
27 #undef LOG_TAG
28 #define LOG_TAG "WifiRpcNet"
29
SetNonBlock(int fd,int type)30 int SetNonBlock(int fd, int type)
31 {
32 int flags = fcntl(fd, F_GETFL, 0);
33 if (flags < 0) {
34 LOGE("get socket flags failed!");
35 return -1;
36 }
37 if (type == 1) {
38 flags |= O_NONBLOCK;
39 } else {
40 flags &= ~O_NONBLOCK;
41 }
42 if (fcntl(fd, F_SETFL, flags) < 0) {
43 LOGE("set socket O_NONBLOCK failed!");
44 return -1;
45 }
46 return 0;
47 }
48
MyRead(int fd,char * buf,int count)49 int MyRead(int fd, char *buf, int count)
50 {
51 int pos = 0;
52 while (count > 0) {
53 int ret = read(fd, buf + pos, count);
54 if (ret == 0) {
55 buf[pos] = 0;
56 return SOCK_CLOSE;
57 } else if (ret < 0) {
58 if (errno == EWOULDBLOCK || errno == EINTR || errno == EAGAIN) {
59 break;
60 } else {
61 LOGE("read failed! error is %{public}d", errno);
62 return SOCK_ERR;
63 }
64 } else {
65 pos += ret;
66 count -= ret;
67 }
68 }
69 buf[pos] = 0;
70 #ifdef DEBUG
71 LOGD("read: %{private}s", buf);
72 #endif
73 return pos;
74 }
75
MyWrite(int fd,const char * buf,int count)76 int MyWrite(int fd, const char *buf, int count)
77 {
78 int pos = 0;
79 while (count > 0) {
80 int ret = write(fd, buf + pos, count);
81 if (ret == 0) {
82 return SOCK_CLOSE;
83 } else if (ret < 0) {
84 if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) {
85 break;
86 } else {
87 LOGE("write failed! error is %{public}d", errno);
88 return SOCK_ERR;
89 }
90 }
91 #ifdef DEBUG
92 int tmpSize = ret + 1;
93 char *szTmp = (char *)calloc(tmpSize, sizeof(char));
94 if (szTmp != NULL) {
95 if (strncpy_s(szTmp, tmpSize, buf + pos, ret) == EOK) {
96 LOGD("write: %{private}s", szTmp);
97 }
98 free(szTmp);
99 szTmp = NULL;
100 }
101 #endif
102 pos += ret;
103 count -= ret;
104 }
105 return pos;
106 }
107
CreateSocket(int domain)108 static int CreateSocket(int domain)
109 {
110 int sock = socket(domain, SOCK_STREAM, 0);
111 if (sock < 0) {
112 LOGE("create socket failed!");
113 return -1;
114 }
115 return sock;
116 }
117
CreateUnixServer(const char * path,int backlog)118 int CreateUnixServer(const char *path, int backlog)
119 {
120 struct sockaddr_un sockAddr;
121 if (memset_s(&sockAddr, sizeof(sockAddr), 0, sizeof(sockAddr)) != EOK) {
122 return -1;
123 }
124 sockAddr.sun_family = AF_LOCAL;
125 if (strncpy_s(sockAddr.sun_path, sizeof(sockAddr.sun_path), path, strlen(path)) != EOK) {
126 return -1;
127 }
128 int sock = CreateSocket(AF_LOCAL);
129 if (sock < 0) {
130 return -1;
131 }
132 int keepAlive = 1;
133 if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive)) < 0) {
134 LOGE("setsockopt failed!");
135 close(sock);
136 return -1;
137 }
138 int reuseaddr = 1;
139 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&reuseaddr, sizeof(reuseaddr)) < 0) {
140 LOGE("setsockopt failed!");
141 close(sock);
142 return -1;
143 }
144 int ret = bind(sock, (struct sockaddr *)&sockAddr, sizeof(sockAddr));
145 if (ret < 0) {
146 LOGE("bind failed, ret: %{public}d, errno: %{public}d!", ret, errno);
147 close(sock);
148 return -1;
149 }
150 if (SetNonBlock(sock, 1) != 0) {
151 LOGE("set socket non block failed, errno: %{public}d!", errno);
152 close(sock);
153 return -1;
154 }
155 fcntl(sock, F_SETFD, FD_CLOEXEC);
156 if (listen(sock, backlog) < 0) {
157 LOGE("listen failed, errno: %{public}d!", errno);
158 close(sock);
159 return -1;
160 }
161 return sock;
162 }
163
ConnectUnixServer(const char * path)164 int ConnectUnixServer(const char *path)
165 {
166 struct sockaddr_un sockAddr;
167 if (memset_s(&sockAddr, sizeof(sockAddr), 0, sizeof(sockAddr)) != EOK) {
168 return -1;
169 }
170 sockAddr.sun_family = AF_LOCAL;
171 if (strncpy_s(sockAddr.sun_path, sizeof(sockAddr.sun_path), path, strlen(path)) != EOK) {
172 return -1;
173 }
174 int sock = CreateSocket(AF_LOCAL);
175 if (sock < 0) {
176 return -1;
177 }
178 if (connect(sock, (struct sockaddr *)&sockAddr, sizeof(sockAddr)) < 0) {
179 LOGE("connect failed!");
180 close(sock);
181 return -1;
182 }
183 return sock;
184 }
185
WaitFdEvent(int fd,unsigned int mask,int milliseconds)186 int WaitFdEvent(int fd, unsigned int mask, int milliseconds)
187 {
188 struct pollfd pFd = {0};
189 pFd.fd = fd;
190 if (mask & READ_EVENT) {
191 pFd.events |= POLLIN;
192 }
193 if (mask & WRIT_EVENT) {
194 pFd.events |= POLLOUT;
195 }
196 int ret = poll(&pFd, 1, milliseconds);
197 if (ret < 0) {
198 LOGE("poll failed! errno=%{public}d", errno);
199 if (errno == EINTR) {
200 return 0;
201 }
202 return -1;
203 } else if (ret == 0) {
204 return 0;
205 } else {
206 return 1;
207 }
208 }
209