1 /*
2 * Copyright (c) 2021 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 "softbus_socket.h"
17
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <securec.h>
21
22 #include "softbus_adapter_errcode.h"
23 #include "softbus_adapter_socket.h"
24 #include "softbus_def.h"
25 #include "softbus_errcode.h"
26 #include "softbus_log.h"
27 #include "softbus_tcp_socket.h"
28
29 #define MAX_SOCKET_TYPE 5
30 #define SEND_BUF_SIZE 0x200000 // 2M
31 #define RECV_BUF_SIZE 0x100000 // 1M
32 #define USER_TIMEOUT_MS 500000 // 500000us
33
34 static const SocketInterface *g_socketInterfaces[MAX_SOCKET_TYPE] = { 0 };
35 static SoftBusMutex g_socketsMutex;
36
RegistSocketProtocol(const SocketInterface * interface)37 int32_t RegistSocketProtocol(const SocketInterface *interface)
38 {
39 if (interface == NULL || interface->GetSockPort == NULL || interface->OpenClientSocket == NULL ||
40 interface->OpenServerSocket == NULL || interface->AcceptClient == NULL) {
41 CLOGE("Bad socket interface!");
42 return SOFTBUS_ERR;
43 }
44 int ret = SoftBusMutexLock(&g_socketsMutex);
45 if (ret != SOFTBUS_OK) {
46 CLOGE("get lock failed!ret=%" PRId32, ret);
47 return ret;
48 }
49
50 ret = SOFTBUS_ERR;
51 for (uint8_t i = 0; i < MAX_SOCKET_TYPE; i++) {
52 if (g_socketInterfaces[i] == NULL) {
53 g_socketInterfaces[i] = interface;
54 ret = SOFTBUS_OK;
55 break;
56 }
57 }
58 (void)SoftBusMutexUnlock(&g_socketsMutex);
59 if (ret != SOFTBUS_OK) {
60 CLOGE("socket type list is full!");
61 }
62 return ret;
63 }
64
GetSocketInterface(ProtocolType protocolType)65 const SocketInterface *GetSocketInterface(ProtocolType protocolType)
66 {
67 int ret = SoftBusMutexLock(&g_socketsMutex);
68 if (ret != SOFTBUS_OK) {
69 CLOGE("get lock failed!ret=%" PRId32, ret);
70 return NULL;
71 }
72 const SocketInterface *result = NULL;
73 for (uint8_t i = 0; i < MAX_SOCKET_TYPE; i++) {
74 if (g_socketInterfaces[i] != NULL && g_socketInterfaces[i]->type == protocolType) {
75 result = g_socketInterfaces[i];
76 break;
77 }
78 }
79 (void)SoftBusMutexUnlock(&g_socketsMutex);
80 return result;
81 }
82
RegistNewIpSocket(void)83 int32_t __attribute__((weak)) RegistNewIpSocket(void)
84 {
85 CLOGI("newip not deployed");
86 return SOFTBUS_OK;
87 }
88
ConnInitSockets(void)89 NO_SANITIZE("cfi") int32_t ConnInitSockets(void)
90 {
91 int32_t ret = SoftBusMutexInit(&g_socketsMutex, NULL);
92 if (ret != SOFTBUS_OK) {
93 CLOGE("init mutex failed!ret=%" PRId32, ret);
94 return ret;
95 }
96
97 (void)memset_s(g_socketInterfaces, sizeof(g_socketInterfaces), 0, sizeof(g_socketInterfaces));
98
99 ret = RegistSocketProtocol(GetTcpProtocol());
100 if (ret != SOFTBUS_OK) {
101 CLOGE("regist tcp failed!!ret=%" PRId32, ret);
102 (void)SoftBusMutexDestroy(&g_socketsMutex);
103 return ret;
104 }
105 CLOGI("tcp registed!");
106
107 ret = RegistNewIpSocket();
108 if (ret != SOFTBUS_OK) {
109 CLOGE("regist newip failed!!ret=%" PRId32, ret);
110 (void)SoftBusMutexDestroy(&g_socketsMutex);
111 return ret;
112 }
113
114 return ret;
115 }
116
ConnDeinitSockets(void)117 NO_SANITIZE("cfi") void ConnDeinitSockets(void)
118 {
119 (void)memset_s(g_socketInterfaces, sizeof(g_socketInterfaces), 0, sizeof(g_socketInterfaces));
120 (void)SoftBusMutexDestroy(&g_socketsMutex);
121 }
122
ConnOpenClientSocket(const ConnectOption * option,const char * bindAddr,bool isNonBlock)123 NO_SANITIZE("cfi") int32_t ConnOpenClientSocket(const ConnectOption *option, const char *bindAddr, bool isNonBlock)
124 {
125 if (option == NULL || bindAddr == NULL) {
126 return SOFTBUS_ERR;
127 }
128 const SocketInterface *socketInterface = GetSocketInterface(option->socketOption.protocol);
129 if (socketInterface == NULL) {
130 ALOGE("protocol not supported!protocol=%d", option->socketOption.protocol);
131 return SOFTBUS_ERR;
132 }
133 return socketInterface->OpenClientSocket(option, bindAddr, isNonBlock);
134 }
135
WaitEvent(int fd,short events,int timeout)136 static int WaitEvent(int fd, short events, int timeout)
137 {
138 if (fd < 0) {
139 CLOGE("fd=%d invalid params", fd);
140 return -1;
141 }
142 SoftBusSockTimeOut tv = { 0 };
143 tv.sec = 0;
144 tv.usec = timeout;
145 int rc = 0;
146 switch (events) {
147 case SOFTBUS_SOCKET_OUT: {
148 SoftBusFdSet writeSet;
149 SoftBusSocketFdZero(&writeSet);
150 SoftBusSocketFdSet(fd, &writeSet);
151 rc = SOFTBUS_TEMP_FAILURE_RETRY(SoftBusSocketSelect(fd + 1, NULL, &writeSet, NULL, &tv));
152 if (rc < 0) {
153 break;
154 }
155 if (!SoftBusSocketFdIsset(fd, &writeSet)) {
156 rc = 0;
157 }
158 break;
159 }
160 case SOFTBUS_SOCKET_IN: {
161 SoftBusFdSet readSet;
162 SoftBusSocketFdZero(&readSet);
163 SoftBusSocketFdSet(fd, &readSet);
164 rc = SOFTBUS_TEMP_FAILURE_RETRY(SoftBusSocketSelect(fd + 1, &readSet, NULL, NULL, &tv));
165 if (rc < 0) {
166 break;
167 }
168 if (!SoftBusSocketFdIsset(fd, &readSet)) {
169 rc = 0;
170 }
171 break;
172 }
173 default:
174 break;
175 }
176 return rc;
177 }
ConnToggleNonBlockMode(int32_t fd,bool isNonBlock)178 NO_SANITIZE("cfi") int32_t ConnToggleNonBlockMode(int32_t fd, bool isNonBlock)
179 {
180 if (fd < 0) {
181 return SOFTBUS_INVALID_PARAM;
182 }
183 int32_t flags = fcntl(fd, F_GETFL, 0);
184 if (flags < 0) {
185 CLOGE("fd=%d,fcntl get flag failed, errno=%d", fd, errno);
186 return SOFTBUS_ERR;
187 }
188 if (isNonBlock && ((uint32_t)flags & O_NONBLOCK) == 0) {
189 flags = (int32_t)((uint32_t)flags | O_NONBLOCK);
190 CLOGI("fd=%d set to nonblock", fd);
191 } else if (!isNonBlock && ((uint32_t)flags & O_NONBLOCK) != 0) {
192 flags = (int32_t)((uint32_t)flags & ~O_NONBLOCK);
193 CLOGI("fd=%d set to block", fd);
194 } else {
195 CLOGI("fd=%d nonblock state is already ok", fd);
196 return SOFTBUS_OK;
197 }
198 return fcntl(fd, F_SETFL, flags);
199 }
200
ConnSendSocketData(int32_t fd,const char * buf,size_t len,int32_t timeout)201 NO_SANITIZE("cfi") ssize_t ConnSendSocketData(int32_t fd, const char *buf, size_t len, int32_t timeout)
202 {
203 if (fd < 0 || buf == NULL || len == 0) {
204 CLOGE("fd=%d invalid params", fd);
205 return -1;
206 }
207
208 if (timeout == 0) {
209 timeout = USER_TIMEOUT_MS;
210 }
211
212 int err = WaitEvent(fd, SOFTBUS_SOCKET_OUT, USER_TIMEOUT_MS);
213 if (err <= 0) {
214 CLOGE("wait event error %d", err);
215 return err;
216 }
217 ssize_t bytes = 0;
218 while (1) {
219 ssize_t rc = SOFTBUS_TEMP_FAILURE_RETRY(SoftBusSocketSend(fd, &buf[bytes], len - bytes, 0));
220 if (rc == SOFTBUS_ADAPTER_SOCKET_EAGAIN) {
221 continue;
222 } else if (rc <= 0) {
223 if (bytes == 0) {
224 bytes = -1;
225 }
226 CLOGE("tcp send fail %zd %d", rc, errno);
227 break;
228 }
229 bytes += rc;
230 if (bytes == (ssize_t)(len)) {
231 break;
232 }
233
234 err = WaitEvent(fd, SOFTBUS_SOCKET_OUT, timeout);
235 if (err == 0) {
236 continue;
237 } else if (err < 0) {
238 if (bytes == 0) {
239 CLOGE("send data wait event fail %d", err);
240 bytes = err;
241 }
242 break;
243 }
244 }
245 return bytes;
246 }
247
OnRecvData(int32_t fd,char * buf,size_t len,int timeout,int flags)248 static ssize_t OnRecvData(int32_t fd, char *buf, size_t len, int timeout, int flags)
249 {
250 if (fd < 0 || buf == NULL || len == 0) {
251 CLOGE("fd[%d] len[%zu] invalid params", fd, len);
252 return -1;
253 }
254
255 if (timeout != 0) {
256 int err = WaitEvent(fd, SOFTBUS_SOCKET_IN, timeout);
257 if (err < 0) {
258 CLOGE("recv data wait event err[%d]", err);
259 return err;
260 }
261 }
262
263 ssize_t rc = SOFTBUS_TEMP_FAILURE_RETRY(SoftBusSocketRecv(fd, buf, len, flags));
264 if (rc == SOFTBUS_ADAPTER_SOCKET_EAGAIN) {
265 CLOGW("recv data socket EAGAIN");
266 rc = 0;
267 } else if (rc == 0) {
268 CLOGW("recv data fail, peer close connection, fd=%d", fd);
269 rc = -1;
270 } else if (rc < 0) {
271 CLOGE("recv data fail fd[%d] errno[%d], rc[%d]", fd, errno, rc);
272 rc = -1;
273 }
274 return rc;
275 }
276
ConnRecvSocketData(int32_t fd,char * buf,size_t len,int32_t timeout)277 NO_SANITIZE("cfi") ssize_t ConnRecvSocketData(int32_t fd, char *buf, size_t len, int32_t timeout)
278 {
279 return OnRecvData(fd, buf, len, timeout, 0);
280 }
281
ConnCloseSocket(int32_t fd)282 NO_SANITIZE("cfi") void ConnCloseSocket(int32_t fd)
283 {
284 if (fd >= 0) {
285 CLOGI("close fd=%d", fd);
286 SoftBusSocketClose(fd);
287 }
288 }
289
ConnShutdownSocket(int32_t fd)290 NO_SANITIZE("cfi") void ConnShutdownSocket(int32_t fd)
291 {
292 if (fd >= 0) {
293 CLOGI("shutdown fd=%d", fd);
294 SoftBusSocketShutDown(fd, SOFTBUS_SHUT_RDWR);
295 SoftBusSocketClose(fd);
296 }
297 }
298
ConnGetSocketError(int32_t fd)299 NO_SANITIZE("cfi") int32_t ConnGetSocketError(int32_t fd)
300 {
301 return SoftBusSocketGetError(fd);
302 }
303
ConnGetLocalSocketPort(int32_t fd)304 NO_SANITIZE("cfi") int32_t ConnGetLocalSocketPort(int32_t fd)
305 {
306 const SocketInterface *socketInterface = GetSocketInterface(LNN_PROTOCOL_IP);
307 if (socketInterface == NULL) {
308 CLOGW("LNN_PROTOCOL_IP not supported!");
309 return SOFTBUS_ERR;
310 }
311 return socketInterface->GetSockPort(fd);
312 }
313
ConnGetPeerSocketAddr(int32_t fd,SocketAddr * socketAddr)314 NO_SANITIZE("cfi") int32_t ConnGetPeerSocketAddr(int32_t fd, SocketAddr *socketAddr)
315 {
316 SoftBusSockAddrIn addr;
317 int32_t addrLen = (int32_t)sizeof(addr);
318 if (socketAddr == NULL) {
319 CLOGE("invalid param");
320 return SOFTBUS_INVALID_PARAM;
321 }
322 int rc = SoftBusSocketGetPeerName(fd, (SoftBusSockAddr *)&addr, &addrLen);
323 if (rc != 0) {
324 CLOGE("fd=%d, GetPeerName rc=%d", fd, rc);
325 return SOFTBUS_ERR;
326 }
327 if (SoftBusInetNtoP(SOFTBUS_AF_INET, (void *)&addr.sinAddr, socketAddr->addr, sizeof(socketAddr->addr)) == NULL) {
328 CLOGE("fd=%d, InetNtoP fail", fd);
329 return SOFTBUS_ERR;
330 }
331 socketAddr->port = SoftBusNtoHs(addr.sinPort);
332 return SOFTBUS_OK;
333 }
334