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 "auth_tcp_connection.h"
17 
18 #include <securec.h>
19 
20 #include "auth_channel.h"
21 #include "auth_common.h"
22 #include "auth_log.h"
23 #include "auth_meta_manager.h"
24 #include "bus_center_manager.h"
25 #include "softbus_adapter_mem.h"
26 #include "softbus_adapter_socket.h"
27 #include "softbus_base_listener.h"
28 #include "softbus_def.h"
29 #include "softbus_socket.h"
30 #include "softbus_tcp_socket.h"
31 #include "trans_lane_manager.h"
32 
33 #define MAGIC_NUMBER  0xBABEFACE
34 #define AUTH_PKT_HEAD_LEN 24
35 #define AUTH_SOCKET_MAX_DATA_LEN (64 * 1024)
36 #define TCP_KEEPALIVE_TOS_VAL 180
37 
38 typedef struct {
39     int32_t keepaliveIdle;
40     int32_t keepaliveIntvl;
41     int32_t keepaliveCount;
42     uint32_t userTimeout;
43 } TcpKeepaliveOption;
44 
45 typedef struct {
46     int32_t module;
47     AuthChannelListener listener;
48 } InnerChannelListener;
49 
50 static InnerChannelListener g_listener[] = {
51     {
52         .module = MODULE_AUTH_CHANNEL,
53         .listener = { NULL, NULL },
54     },
55     {
56         .module = MODULE_AUTH_MSG,
57         .listener = { NULL, NULL },
58     },
59 };
60 
61 static SocketCallback g_callback = {NULL, NULL, NULL};
62 
63 static void NotifyChannelDisconnected(int32_t channelId);
64 static void NotifyChannelDataReceived(int32_t channelId, const SocketPktHead *head, const uint8_t *data);
RouteBuildServerAuthManager(int32_t cfd, const ConnectOption *clientAddr)65 int32_t __attribute__((weak)) RouteBuildServerAuthManager(int32_t cfd, const ConnectOption *clientAddr)
66 {
67     (void)cfd;
68     (void)clientAddr;
69     return SOFTBUS_OK;
70 }
71 
GetSocketPktSize(uint32_t len)72 static uint32_t GetSocketPktSize(uint32_t len)
73 {
74     return AUTH_PKT_HEAD_LEN + len;
75 }
76 
PackSocketPkt(const SocketPktHead *pktHead, const uint8_t *data, uint8_t *buf, uint32_t size)77 static int32_t PackSocketPkt(const SocketPktHead *pktHead, const uint8_t *data,
78     uint8_t *buf, uint32_t size)
79 {
80     if (size < GetSocketPktSize(pktHead->len)) {
81         AUTH_LOGE(AUTH_CONN, "buffer not enough.");
82         return SOFTBUS_NO_ENOUGH_DATA;
83     }
84     uint32_t offset = 0;
85     *(uint32_t *)buf = SoftBusHtoLl((uint32_t)pktHead->magic);
86     offset += sizeof(uint32_t);
87     *(uint32_t *)(buf + offset) = SoftBusHtoLl((uint32_t)pktHead->module);
88     offset += sizeof(uint32_t);
89     *(uint64_t *)(buf + offset) = SoftBusHtoLll((uint64_t)pktHead->seq);
90     offset += sizeof(uint64_t);
91     *(uint32_t *)(buf + offset) = SoftBusHtoLl((uint32_t)pktHead->flag);
92     offset += sizeof(uint32_t);
93     *(uint32_t *)(buf + offset) = SoftBusHtoLl(pktHead->len);
94     offset += sizeof(uint32_t);
95     if (memcpy_s(buf + offset, size - offset, data, pktHead->len) != EOK) {
96         AUTH_LOGE(AUTH_CONN, "pack fail.");
97         return SOFTBUS_MEM_ERR;
98     }
99     return SOFTBUS_OK;
100 }
101 
UnpackSocketPkt(const uint8_t *data, uint32_t len, SocketPktHead *head)102 static int32_t UnpackSocketPkt(const uint8_t *data, uint32_t len, SocketPktHead *head)
103 {
104     if (len < GetSocketPktSize(0)) {
105         AUTH_LOGE(AUTH_CONN, "head not enough.");
106         return SOFTBUS_NO_ENOUGH_DATA;
107     }
108     uint32_t offset = 0;
109     head->magic = (int32_t)SoftBusLtoHl(*(uint32_t *)data);
110     offset += sizeof(uint32_t);
111     head->module = (int32_t)SoftBusLtoHl(*(uint32_t *)(data + offset));
112     offset += sizeof(uint32_t);
113     head->seq = (int64_t)SoftBusLtoHll(*(uint64_t *)(data + offset));
114     offset += sizeof(uint64_t);
115     head->flag = (int32_t)SoftBusLtoHl(*(uint32_t *)(data + offset));
116     offset += sizeof(uint32_t);
117     head->len = SoftBusLtoHl(*(uint32_t *)(data + offset));
118     return SOFTBUS_OK;
119 }
120 
NotifyConnected(ListenerModule module, int32_t fd, bool isClient)121 static void NotifyConnected(ListenerModule module, int32_t fd, bool isClient)
122 {
123     if (g_callback.onConnected != NULL) {
124         g_callback.onConnected(module, fd, isClient);
125     }
126 }
127 
NotifyDisconnected(int32_t fd)128 static void NotifyDisconnected(int32_t fd)
129 {
130     if (g_callback.onDisconnected != NULL) {
131         g_callback.onDisconnected(fd);
132     }
133     NotifyChannelDisconnected(fd);
134 }
135 
ModuleToDataType(int32_t module)136 static uint32_t ModuleToDataType(int32_t module)
137 {
138     switch (module) {
139         case MODULE_TRUST_ENGINE:
140             return DATA_TYPE_DEVICE_ID;
141         case MODULE_AUTH_SDK:
142             return DATA_TYPE_AUTH;
143         case MODULE_AUTH_CONNECTION:
144             return DATA_TYPE_DEVICE_INFO;
145         case MODULE_AUTH_CANCEL:
146             return DATA_TYPE_CANCEL_AUTH;
147         default:
148             break;
149     }
150     return DATA_TYPE_CONNECTION;
151 }
152 
NotifyDataReceived(ListenerModule module, int32_t fd, const SocketPktHead *pktHead, const uint8_t *data)153 static void NotifyDataReceived(ListenerModule module, int32_t fd,
154     const SocketPktHead *pktHead, const uint8_t *data)
155 {
156     if (pktHead->module == MODULE_AUTH_CHANNEL || pktHead->module == MODULE_AUTH_MSG) {
157         NotifyChannelDataReceived(fd, pktHead, data);
158         return;
159     }
160     if (pktHead->module == MODULE_META_AUTH) {
161         AuthMetaNotifyDataReceived(fd, pktHead, data);
162         return;
163     }
164     AuthDataHead head = {
165         .dataType = ModuleToDataType(pktHead->module),
166         .module = pktHead->module,
167         .seq = pktHead->seq,
168         .flag = pktHead->flag,
169         .len = pktHead->len,
170     };
171     if (g_callback.onDataReceived != NULL) {
172         g_callback.onDataReceived(module, fd, &head, data);
173     }
174 }
175 
RecvPacketHead(ListenerModule module, int32_t fd, SocketPktHead *head)176 static int32_t RecvPacketHead(ListenerModule module, int32_t fd, SocketPktHead *head)
177 {
178     uint8_t buf[AUTH_PKT_HEAD_LEN] = {0};
179     ssize_t len = ConnRecvSocketData(fd, (char *)&buf[0], sizeof(buf), 0);
180     if (len < AUTH_PKT_HEAD_LEN) {
181         if (len < 0) {
182             AUTH_LOGE(AUTH_CONN, "recv head fail. ret=%{public}d", ConnGetSocketError(fd));
183             (void)DelTrigger(module, fd, READ_TRIGGER);
184             NotifyDisconnected(fd);
185         }
186         AUTH_LOGE(AUTH_CONN, "head not enough, abandon it. len=%{public}zd", len);
187         return SOFTBUS_ERR;
188     }
189     return UnpackSocketPkt(buf, len, head);
190 }
191 
RecvPacketData(int32_t fd, uint32_t len)192 static uint8_t *RecvPacketData(int32_t fd, uint32_t len)
193 {
194     uint8_t *data = (uint8_t *)SoftBusCalloc(len);
195     if (data == NULL) {
196         AUTH_LOGE(AUTH_CONN, "malloc data buf fail.");
197         return NULL;
198     }
199     uint32_t offset = 0;
200     while (offset < len) {
201         ssize_t recvLen = ConnRecvSocketData(fd, (char *)(data + offset), (size_t)(len - offset), 0);
202         if (recvLen < 0) {
203             AUTH_LOGE(AUTH_CONN, "recv data fail. ret=%{public}d", ConnGetSocketError(fd));
204             SoftBusFree(data);
205             return NULL;
206         }
207         offset += (uint32_t)recvLen;
208     }
209     return data;
210 }
211 
ProcessSocketOutEvent(ListenerModule module, int32_t fd)212 static int32_t ProcessSocketOutEvent(ListenerModule module, int32_t fd)
213 {
214     AUTH_LOGI(AUTH_CONN, "socket client connect succ: fd=%{public}d.", fd);
215     (void)DelTrigger(module, fd, WRITE_TRIGGER);
216     if (AddTrigger(module, fd, READ_TRIGGER) != SOFTBUS_OK) {
217         AUTH_LOGE(AUTH_CONN, "AddTrigger fail.");
218         goto FAIL;
219     }
220     if (ConnToggleNonBlockMode(fd, true) != SOFTBUS_OK) {
221         AUTH_LOGE(AUTH_CONN, "set none block mode fail.");
222         goto FAIL;
223     }
224     NotifyConnected(module, fd, true);
225     return SOFTBUS_OK;
226 
227 FAIL:
228     (void)DelTrigger(module, fd, READ_TRIGGER);
229     ConnShutdownSocket(fd);
230     NotifyDisconnected(fd);
231     return SOFTBUS_ERR;
232 }
233 
ProcessSocketInEvent(ListenerModule module, int32_t fd)234 static int32_t ProcessSocketInEvent(ListenerModule module, int32_t fd)
235 {
236     SocketPktHead head = {0};
237     if (RecvPacketHead(module, fd, &head) != SOFTBUS_OK) {
238         return SOFTBUS_ERR;
239     }
240     AUTH_LOGI(AUTH_CONN,
241         "RecvSocketData: fd=%{public}d, module=%{public}d, seq=%{public}" PRId64 ", flag=%{public}d, len=%{public}u.",
242         fd, head.module, head.seq, head.flag, head.len);
243     if (head.len == 0 || head.len > AUTH_SOCKET_MAX_DATA_LEN) {
244         AUTH_LOGW(AUTH_CONN, "data is out of size, abandon it.");
245         return SOFTBUS_ERR;
246     }
247     if (head.magic != (int32_t)MAGIC_NUMBER) {
248         AUTH_LOGE(AUTH_CONN, "magic number not match.");
249         return SOFTBUS_ERR;
250     }
251     uint8_t *data = RecvPacketData(fd, head.len);
252     if (data == NULL) {
253         return SOFTBUS_ERR;
254     }
255     NotifyDataReceived(module, fd, &head, data);
256     SoftBusFree(data);
257     return SOFTBUS_OK;
258 }
259 
IsEnhanceP2pModuleId(ListenerModule moduleId)260 static bool IsEnhanceP2pModuleId(ListenerModule moduleId)
261 {
262     if (moduleId >= AUTH_ENHANCED_P2P_START && moduleId <= AUTH_ENHANCED_P2P_END) {
263         return true;
264     }
265     return false;
266 }
267 
OnConnectEvent(ListenerModule module, int32_t cfd, const ConnectOption *clientAddr)268 static int32_t OnConnectEvent(ListenerModule module, int32_t cfd, const ConnectOption *clientAddr)
269 {
270     if (cfd < 0) {
271         AUTH_LOGE(AUTH_CONN, "invalid param.");
272         return SOFTBUS_INVALID_PARAM;
273     }
274     if (ConnSetTcpKeepalive(cfd, (int32_t)DEFAULT_FREQ_CYCLE, TCP_KEEPALIVE_INTERVAL, TCP_KEEPALIVE_DEFAULT_COUNT) !=
275         SOFTBUS_OK) {
276         AUTH_LOGE(AUTH_CONN, "set keepalive fail!");
277         ConnShutdownSocket(cfd);
278         return SOFTBUS_ERR;
279     }
280     int32_t ipTos = TCP_KEEPALIVE_TOS_VAL;
281     if (module == AUTH) {
282         if (SoftBusSocketSetOpt(cfd, SOFTBUS_IPPROTO_IP_, SOFTBUS_IP_TOS_, &ipTos, sizeof(ipTos)) !=
283             SOFTBUS_ADAPTER_OK) {
284             AUTH_LOGE(AUTH_CONN, "set option fail!");
285             ConnShutdownSocket(cfd);
286             return SOFTBUS_ERR;
287         }
288     }
289     if (AddTrigger(module, cfd, READ_TRIGGER) != SOFTBUS_OK) {
290         AUTH_LOGE(AUTH_CONN, "AddTrigger fail.");
291         ConnShutdownSocket(cfd);
292         return SOFTBUS_ERR;
293     }
294     if (module != AUTH && module != AUTH_P2P &&  module != AUTH_RAW_P2P_CLIENT &&!IsEnhanceP2pModuleId(module)) {
295         AUTH_LOGI(AUTH_CONN, "newip auth process");
296         if (RouteBuildServerAuthManager(cfd, clientAddr) != SOFTBUS_OK) {
297             AUTH_LOGE(AUTH_CONN, "build auth manager fail.");
298             (void)DelTrigger(module, cfd, READ_TRIGGER);
299             ConnShutdownSocket(cfd);
300             return SOFTBUS_ERR;
301         }
302         return SOFTBUS_OK;
303     }
304     NotifyConnected(module, cfd, false);
305     return SOFTBUS_OK;
306 }
307 
OnDataEvent(ListenerModule module, int32_t events, int32_t fd)308 static int32_t OnDataEvent(ListenerModule module, int32_t events, int32_t fd)
309 {
310     if (events == SOFTBUS_SOCKET_OUT) {
311         return ProcessSocketOutEvent(module, fd);
312     } else if (events == SOFTBUS_SOCKET_IN) {
313         return ProcessSocketInEvent(module, fd);
314     }
315     return SOFTBUS_ERR;
316 }
317 
SetSocketCallback(const SocketCallback *cb)318 int32_t SetSocketCallback(const SocketCallback *cb)
319 {
320     CHECK_NULL_PTR_RETURN_VALUE(cb, SOFTBUS_INVALID_PARAM);
321     if (memcpy_s(&g_callback, sizeof(SocketCallback), cb, sizeof(SocketCallback)) != EOK) {
322         AUTH_LOGE(AUTH_CONN, "set SocketCallback fail.");
323         return SOFTBUS_MEM_ERR;
324     }
325     return SOFTBUS_OK;
326 }
327 
UnsetSocketCallback(void)328 void UnsetSocketCallback(void)
329 {
330     (void)memset_s(&g_callback, sizeof(SocketCallback), 0, sizeof(SocketCallback));
331 }
332 
StartSocketListening(ListenerModule module, const LocalListenerInfo *info)333 int32_t StartSocketListening(ListenerModule module, const LocalListenerInfo *info)
334 {
335     SoftbusBaseListener listener = {
336         .onConnectEvent = OnConnectEvent,
337         .onDataEvent = OnDataEvent,
338     };
339     int32_t port = StartBaseListener(info, &listener);
340     if (port <= 0) {
341         AUTH_LOGE(AUTH_CONN, "StartBaseListener fail. port=%{public}d", port);
342         return SOFTBUS_ERR;
343     }
344     return port;
345 }
346 
StopSocketListening(ListenerModule moduleId)347 void StopSocketListening(ListenerModule moduleId)
348 {
349     AUTH_LOGI(AUTH_CONN, "stop socket listening. moduleId=%{public}d", moduleId);
350     if (StopBaseListener(moduleId) != SOFTBUS_OK) {
351         AUTH_LOGE(AUTH_CONN, "StopBaseListener fail.");
352     }
353 }
354 
AuthTcpCreateListener(ListenerModule module, int32_t fd, TriggerType trigger)355 static int32_t AuthTcpCreateListener(ListenerModule module, int32_t fd, TriggerType trigger)
356 {
357     if (!IsListenerNodeExist(module)) {
358         SoftbusBaseListener listener = {
359             .onConnectEvent = OnConnectEvent,
360             .onDataEvent = OnDataEvent,
361         };
362         if (StartBaseClient(module, &listener) != SOFTBUS_OK) {
363             AUTH_LOGE(AUTH_CONN, "StartBaseClient fail.");
364         }
365     }
366     return AddTrigger(module, fd, trigger);
367 }
368 
SocketConnectInner(const char *localIp, const char *peerIp, int32_t port, ListenerModule module, bool isBlockMode)369 static int32_t SocketConnectInner(const char *localIp, const char *peerIp, int32_t port, ListenerModule module,
370     bool isBlockMode)
371 {
372     if (localIp == NULL || peerIp == NULL) {
373         AUTH_LOGE(AUTH_CONN, "ip is invalid param.");
374         return AUTH_INVALID_FD;
375     }
376     ConnectOption option = {
377         .type = CONNECT_TCP,
378         .socketOption = {
379             .addr = "",
380             .port = port,
381             .moduleId = module,
382             .protocol = LNN_PROTOCOL_IP
383         }
384     };
385     if (strcpy_s(option.socketOption.addr, sizeof(option.socketOption.addr), peerIp) != EOK) {
386         AUTH_LOGE(AUTH_CONN, "copy remote ip fail.");
387         return AUTH_INVALID_FD;
388     }
389     int32_t ret = ConnOpenClientSocket(&option, localIp, !isBlockMode);
390     if (ret < 0) {
391         AUTH_LOGE(AUTH_CONN, "ConnOpenClientSocket fail, error=%{public}d", ret);
392         return ret;
393     }
394     int32_t fd = ret;
395     TriggerType triggerMode = isBlockMode ? READ_TRIGGER : WRITE_TRIGGER;
396     if (AuthTcpCreateListener(AUTH, fd, triggerMode) != SOFTBUS_OK) {
397         AUTH_LOGE(AUTH_CONN, "AddTrigger fail.");
398         ConnShutdownSocket(fd);
399         return AUTH_INVALID_FD;
400     }
401     if (ConnSetTcpKeepalive(fd, (int32_t)DEFAULT_FREQ_CYCLE, TCP_KEEPALIVE_INTERVAL, TCP_KEEPALIVE_DEFAULT_COUNT) !=
402         SOFTBUS_OK) {
403         AUTH_LOGE(AUTH_CONN, "set tcp keep alive fail.");
404         (void)DelTrigger(AUTH, fd, triggerMode);
405         ConnShutdownSocket(fd);
406         return AUTH_INVALID_FD;
407     }
408     return fd;
409 }
410 
SocketConnectDeviceWithAllIp(const char *localIp, const char *peerIp, int32_t port, bool isBlockMode)411 int32_t SocketConnectDeviceWithAllIp(const char *localIp, const char *peerIp, int32_t port, bool isBlockMode)
412 {
413     return SocketConnectInner(localIp, peerIp, port, AUTH_RAW_P2P_CLIENT, isBlockMode);
414 }
415 
SocketConnectDevice(const char *ip, int32_t port, bool isBlockMode)416 int32_t SocketConnectDevice(const char *ip, int32_t port, bool isBlockMode)
417 {
418     CHECK_NULL_PTR_RETURN_VALUE(ip, AUTH_INVALID_FD);
419     char localIp[MAX_ADDR_LEN] = {0};
420     if (LnnGetLocalStrInfo(STRING_KEY_WLAN_IP, localIp, MAX_ADDR_LEN) != SOFTBUS_OK) {
421         AUTH_LOGE(AUTH_CONN, "get local ip fail.");
422         return AUTH_INVALID_FD;
423     }
424     ConnectOption option = {
425         .type = CONNECT_TCP,
426         .socketOption = {
427             .addr = "",
428             .port = port,
429             .moduleId = AUTH,
430             .protocol = LNN_PROTOCOL_IP
431         }
432     };
433     if (strcpy_s(option.socketOption.addr, sizeof(option.socketOption.addr), ip) != EOK) {
434         AUTH_LOGE(AUTH_CONN, "copy remote ip fail.");
435         return AUTH_INVALID_FD;
436     }
437     int32_t ret = ConnOpenClientSocket(&option, localIp, !isBlockMode);
438     if (ret < 0) {
439         AUTH_LOGE(AUTH_CONN, "ConnOpenClientSocket fail, error=%{public}d", ret);
440         return ret;
441     }
442     int32_t fd = ret;
443     TriggerType triggerMode = isBlockMode ? READ_TRIGGER : WRITE_TRIGGER;
444     if (AddTrigger(AUTH, fd, triggerMode) != SOFTBUS_OK) {
445         AUTH_LOGE(AUTH_CONN, "AddTrigger fail.");
446         ConnShutdownSocket(fd);
447         return AUTH_INVALID_FD;
448     }
449     if (ConnSetTcpKeepalive(fd, (int32_t)DEFAULT_FREQ_CYCLE, TCP_KEEPALIVE_INTERVAL, TCP_KEEPALIVE_DEFAULT_COUNT) !=
450         SOFTBUS_OK) {
451         AUTH_LOGE(AUTH_CONN, "set tcp keep alive fail.");
452         (void)DelTrigger(AUTH, fd, triggerMode);
453         ConnShutdownSocket(fd);
454         return AUTH_INVALID_FD;
455     }
456     int32_t ipTos = TCP_KEEPALIVE_TOS_VAL;
457     if (SoftBusSocketSetOpt(fd, SOFTBUS_IPPROTO_IP_, SOFTBUS_IP_TOS_, &ipTos, sizeof(ipTos)) != SOFTBUS_ADAPTER_OK) {
458         AUTH_LOGE(AUTH_CONN, "set option fail.");
459         (void)DelTrigger(AUTH, fd, triggerMode);
460         ConnShutdownSocket(fd);
461         return AUTH_INVALID_FD;
462     }
463     return fd;
464 }
465 
NipSocketConnectDevice(ListenerModule module, const char *addr, int32_t port, bool isBlockMode)466 int32_t NipSocketConnectDevice(ListenerModule module,
467     const char *addr, int32_t port, bool isBlockMode)
468 {
469     if (addr == NULL) {
470         AUTH_LOGE(AUTH_CONN, "addr is invalid param.");
471         return AUTH_INVALID_FD;
472     }
473     ConnectOption option = {
474         .type = CONNECT_TCP,
475         .socketOption = {
476             .addr = "",
477             .port = port,
478             .moduleId = module,
479             .protocol = LNN_PROTOCOL_NIP
480         }
481     };
482     if (strcpy_s(option.socketOption.addr, sizeof(option.socketOption.addr), addr) != EOK) {
483         AUTH_LOGE(AUTH_CONN, "copy remote ip fail.");
484         return AUTH_INVALID_FD;
485     }
486     int32_t fd = ConnOpenClientSocket(&option, BIND_ADDR_ALL, !isBlockMode);
487     if (fd < 0) {
488         AUTH_LOGE(AUTH_CONN, "ConnOpenClientSocket fail.");
489         return AUTH_INVALID_FD;
490     }
491     TriggerType triggerMode = isBlockMode ? READ_TRIGGER : WRITE_TRIGGER;
492     if (AddTrigger(module, fd, triggerMode) != SOFTBUS_OK) {
493         AUTH_LOGE(AUTH_CONN, "AddTrigger fail.");
494         ConnShutdownSocket(fd);
495         return AUTH_INVALID_FD;
496     }
497     if (ConnSetTcpKeepalive(fd, (int32_t)DEFAULT_FREQ_CYCLE, TCP_KEEPALIVE_INTERVAL, TCP_KEEPALIVE_DEFAULT_COUNT) !=
498         SOFTBUS_OK) {
499         AUTH_LOGE(AUTH_CONN, "set tcp keep alive fail.");
500         (void)DelTrigger(module, fd, triggerMode);
501         ConnShutdownSocket(fd);
502         return AUTH_INVALID_FD;
503     }
504     return fd;
505 }
506 
SocketDisconnectDevice(ListenerModule module, int32_t fd)507 void SocketDisconnectDevice(ListenerModule module, int32_t fd)
508 {
509     if (fd < 0) {
510         AUTH_LOGD(AUTH_CONN, "invalid fd, maybe has shutdown. fd=%{public}d", fd);
511         return;
512     }
513     (void)DelTrigger(module, fd, RW_TRIGGER);
514     ConnShutdownSocket(fd);
515 }
516 
SocketPostBytes(int32_t fd, const AuthDataHead *head, const uint8_t *data)517 int32_t SocketPostBytes(int32_t fd, const AuthDataHead *head, const uint8_t *data)
518 {
519     CHECK_NULL_PTR_RETURN_VALUE(head, SOFTBUS_INVALID_PARAM);
520     CHECK_NULL_PTR_RETURN_VALUE(data, SOFTBUS_INVALID_PARAM);
521     uint32_t size = GetSocketPktSize(head->len);
522     uint8_t *buf = (uint8_t *)SoftBusCalloc(size);
523     if (buf == NULL) {
524         AUTH_LOGE(AUTH_CONN, "malloc pkt err.");
525         return SOFTBUS_ERR;
526     }
527     SocketPktHead pktHead = {
528         .magic = MAGIC_NUMBER,
529         .module = head->module,
530         .seq = head->seq,
531         .flag = head->flag,
532         .len = head->len,
533     };
534     if (PackSocketPkt(&pktHead, data, buf, size) != SOFTBUS_OK) {
535         AUTH_LOGE(AUTH_CONN, "pack socket pkt fail.");
536         SoftBusFree(buf);
537         return SOFTBUS_ERR;
538     }
539 
540     AUTH_LOGI(AUTH_CONN, "fd=%{public}d, module=%{public}d, seq=%{public}" PRId64 ", flag=%{public}d, len=%{public}u.",
541         fd, pktHead.module, pktHead.seq, pktHead.flag, pktHead.len);
542     ssize_t ret = ConnSendSocketData(fd, (const char *)buf, (size_t)size, 0);
543     SoftBusFree(buf);
544     if (ret != (ssize_t)size) {
545         AUTH_LOGE(AUTH_CONN, "fail. ret=%{public}zd", ret);
546         return SOFTBUS_ERR;
547     }
548     return SOFTBUS_OK;
549 }
550 
SocketGetConnInfo(int32_t fd, AuthConnInfo *connInfo, bool *isServer)551 int32_t SocketGetConnInfo(int32_t fd, AuthConnInfo *connInfo, bool *isServer)
552 {
553     CHECK_NULL_PTR_RETURN_VALUE(connInfo, SOFTBUS_INVALID_PARAM);
554     CHECK_NULL_PTR_RETURN_VALUE(isServer, SOFTBUS_INVALID_PARAM);
555     SocketAddr socket;
556     if (ConnGetPeerSocketAddr(fd, &socket) != SOFTBUS_OK) {
557         AUTH_LOGE(AUTH_CONN, "fail, fd=%{public}d.", fd);
558         return SOFTBUS_ERR;
559     }
560     int32_t localPort = ConnGetLocalSocketPort(fd);
561     if (localPort <= 0) {
562         AUTH_LOGE(AUTH_CONN, "fail, fd=%{public}d.", fd);
563         return SOFTBUS_ERR;
564     }
565     connInfo->type = AUTH_LINK_TYPE_WIFI;
566     if (strcpy_s(connInfo->info.ipInfo.ip, sizeof(connInfo->info.ipInfo.ip), socket.addr) != EOK) {
567         AUTH_LOGE(AUTH_CONN, "copy ip fail, fd=%{public}d.", fd);
568         return SOFTBUS_MEM_ERR;
569     }
570     connInfo->info.ipInfo.port = socket.port;
571     int32_t serverPort = 0;
572     if (LnnGetLocalNumInfo(NUM_KEY_AUTH_PORT, &serverPort) != SOFTBUS_OK) {
573         AUTH_LOGE(AUTH_CONN, "get local auth port fail.");
574     }
575     *isServer = (serverPort != localPort);
576     return SOFTBUS_OK;
577 }
578 
579 /* Auth Channel */
NotifyChannelDataReceived(int32_t channelId, const SocketPktHead *head, const uint8_t *data)580 static void NotifyChannelDataReceived(int32_t channelId, const SocketPktHead *head,
581     const uint8_t *data)
582 {
583     uint32_t i;
584     AuthChannelListener *listener = NULL;
585     for (i = 0; i < sizeof(g_listener) / sizeof(InnerChannelListener); i++) {
586         if (g_listener[i].module == head->module) {
587             listener = &g_listener[i].listener;
588             break;
589         }
590     }
591     if (listener == NULL || listener->onDataReceived == NULL) {
592         AUTH_LOGE(AUTH_CONN, "AuthChannelListener not set.");
593         return;
594     }
595 
596     AuthChannelData channelData = {0};
597     channelData.module = head->module;
598     channelData.seq = head->seq;
599     channelData.flag = head->flag;
600     channelData.len = head->len;
601     channelData.data = data;
602     listener->onDataReceived(channelId, &channelData);
603 }
604 
NotifyChannelDisconnected(int32_t channelId)605 static void NotifyChannelDisconnected(int32_t channelId)
606 {
607     uint32_t i;
608     for (i = 0; i < sizeof(g_listener) / sizeof(InnerChannelListener); i++) {
609         if (g_listener[i].listener.onDisconnected != NULL) {
610             g_listener[i].listener.onDisconnected(channelId);
611         }
612     }
613 }
614 
RegAuthChannelListener(int32_t module, const AuthChannelListener *listener)615 int32_t RegAuthChannelListener(int32_t module, const AuthChannelListener *listener)
616 {
617     if (listener == NULL || listener->onDataReceived == NULL) {
618         AUTH_LOGE(AUTH_CONN, "invalid listener.");
619         return SOFTBUS_INVALID_PARAM;
620     }
621     uint32_t i;
622     for (i = 0; i < sizeof(g_listener) / sizeof(InnerChannelListener); i++) {
623         if (g_listener[i].module == module) {
624             g_listener[i].listener.onDataReceived = listener->onDataReceived;
625             g_listener[i].listener.onDisconnected = listener->onDisconnected;
626             return SOFTBUS_OK;
627         }
628     }
629     AUTH_LOGE(AUTH_CONN, "unknown module. module=%{public}d", module);
630     return SOFTBUS_ERR;
631 }
632 
UnregAuthChannelListener(int32_t module)633 void UnregAuthChannelListener(int32_t module)
634 {
635     uint32_t i;
636     for (i = 0; i < sizeof(g_listener) / sizeof(InnerChannelListener); i++) {
637         if (g_listener[i].module == module) {
638             g_listener[i].listener.onDataReceived = NULL;
639             g_listener[i].listener.onDisconnected = NULL;
640             return;
641         }
642     }
643 }
644 
AuthOpenChannelWithAllIp(const char *localIp, const char *remoteIp, int32_t port)645 int32_t AuthOpenChannelWithAllIp(const char *localIp, const char *remoteIp, int32_t port)
646 {
647     if (localIp == NULL || remoteIp == NULL || port <= 0) {
648         AUTH_LOGE(AUTH_CONN, "invalid param.");
649         return SOFTBUS_INVALID_PARAM;
650     }
651     int32_t fd = SocketConnectDeviceWithAllIp(localIp, remoteIp, port, true);
652     if (fd < 0) {
653         AUTH_LOGE(AUTH_CONN, "connect fail.");
654         return INVALID_CHANNEL_ID;
655     }
656     AUTH_LOGI(AUTH_CONN, "open auth channel succ, channelId=%{public}d.", fd);
657     return fd;
658 }
659 
AuthOpenChannel(const char *ip, int32_t port)660 int32_t AuthOpenChannel(const char *ip, int32_t port)
661 {
662     if (ip == NULL || port <= 0) {
663         AUTH_LOGE(AUTH_CONN, "invalid param.");
664         return INVALID_CHANNEL_ID;
665     }
666     int32_t fd = SocketConnectDevice(ip, port, true);
667     if (fd < 0) {
668         AUTH_LOGE(AUTH_CONN, "connect fail.");
669         return INVALID_CHANNEL_ID;
670     }
671     AUTH_LOGI(AUTH_CONN, "open auth channel succ, channelId=%{public}d.", fd);
672     return fd;
673 }
674 
AuthCloseChannel(int32_t channelId, int32_t moduleId)675 void AuthCloseChannel(int32_t channelId, int32_t moduleId)
676 {
677     AUTH_LOGI(AUTH_CONN, "close auth channel, moduleId=%{public}d, id=%{public}d.", moduleId, channelId);
678     SocketDisconnectDevice((ListenerModule)moduleId, channelId);
679 }
680 
AuthPostChannelData(int32_t channelId, const AuthChannelData *data)681 int32_t AuthPostChannelData(int32_t channelId, const AuthChannelData *data)
682 {
683     if (channelId < 0 || data == NULL || data->data == NULL || data->len == 0) {
684         AUTH_LOGE(AUTH_CONN, "invalid param, channelId=%{public}d.", channelId);
685         return SOFTBUS_INVALID_PARAM;
686     }
687     AuthDataHead head = {
688         .dataType = DATA_TYPE_CONNECTION,
689         .module = data->module,
690         .seq = data->seq,
691         .flag = data->flag,
692         .len = data->len,
693     };
694     return SocketPostBytes(channelId, &head, data->data);
695 }
696 
GetTcpKeepaliveOptionByCycle(ModeCycle cycle, TcpKeepaliveOption *tcpKeepaliveOption)697 static int32_t GetTcpKeepaliveOptionByCycle(ModeCycle cycle, TcpKeepaliveOption *tcpKeepaliveOption)
698 {
699     if (tcpKeepaliveOption == NULL) {
700         AUTH_LOGE(AUTH_CONN, "invalid param");
701         return SOFTBUS_INVALID_PARAM;
702     }
703     switch (cycle) {
704         case HIGH_FREQ_CYCLE:
705             tcpKeepaliveOption->keepaliveCount = TCP_KEEPALIVE_HIGH_COUNT;
706             tcpKeepaliveOption->userTimeout = TCP_KEEPALIVE_HIGH_USER_TIMEOUT;
707             break;
708         case MID_FREQ_CYCLE:
709             tcpKeepaliveOption->keepaliveCount = TCP_KEEPALIVE_MID_COUNT;
710             tcpKeepaliveOption->userTimeout = TCP_KEEPALIVE_MID_USER_TIMEOUT;
711             break;
712         case LOW_FREQ_CYCLE:
713             tcpKeepaliveOption->keepaliveCount = TCP_KEEPALIVE_LOW_COUNT;
714             tcpKeepaliveOption->userTimeout = TCP_KEEPALIVE_LOW_USER_TIMEOUT;
715             break;
716         case DEFAULT_FREQ_CYCLE:
717             tcpKeepaliveOption->keepaliveCount = TCP_KEEPALIVE_DEFAULT_COUNT;
718             tcpKeepaliveOption->userTimeout = TCP_KEEPALIVE_DEFAULT_USER_TIMEOUT;
719             break;
720         default:
721             AUTH_LOGE(AUTH_CONN, "no match cycle, cycle=%{public}d", cycle);
722             return SOFTBUS_ERR;
723     }
724     tcpKeepaliveOption->keepaliveIdle = (int32_t)cycle;
725     tcpKeepaliveOption->keepaliveIntvl = TCP_KEEPALIVE_INTERVAL;
726     return SOFTBUS_OK;
727 }
728 
AuthSetTcpKeepaliveOption(int32_t fd, ModeCycle cycle)729 int32_t AuthSetTcpKeepaliveOption(int32_t fd, ModeCycle cycle)
730 {
731     if (fd <= 0 || cycle < HIGH_FREQ_CYCLE || cycle > DEFAULT_FREQ_CYCLE) {
732         AUTH_LOGE(AUTH_CONN, "invalid param");
733         return SOFTBUS_INVALID_PARAM;
734     }
735     TcpKeepaliveOption tcpKeepaliveOption = { 0 };
736 
737     if (GetTcpKeepaliveOptionByCycle(cycle, &tcpKeepaliveOption) != SOFTBUS_OK) {
738         AUTH_LOGE(AUTH_CONN, "get tcp keepalive option by cycle fail");
739         return SOFTBUS_ERR;
740     }
741     if (ConnSetTcpUserTimeOut(fd, tcpKeepaliveOption.userTimeout) != SOFTBUS_OK) {
742         AUTH_LOGE(AUTH_CONN, "set TCP_USER_TIMEOUT fail, fd=%{public}d", fd);
743         return SOFTBUS_ADAPTER_ERR;
744     }
745     if (ConnSetTcpKeepalive(fd, tcpKeepaliveOption.keepaliveIdle, tcpKeepaliveOption.keepaliveIntvl,
746             tcpKeepaliveOption.keepaliveCount) != SOFTBUS_OK) {
747         AUTH_LOGE(AUTH_CONN, "set tcp keepalive fail, fd=%{public}d", fd);
748         return SOFTBUS_ADAPTER_ERR;
749     }
750 
751     AUTH_LOGI(AUTH_CONN,
752         "set tcp keepalive successful, fd=%{public}d, keepaliveIdle=%{public}d, keepaliveIntvl=%{public}d, "
753         "keepaliveCount=%{public}d, userTimeout=%{public}u",
754         fd, tcpKeepaliveOption.keepaliveIdle, tcpKeepaliveOption.keepaliveIntvl, tcpKeepaliveOption.keepaliveCount,
755         tcpKeepaliveOption.userTimeout);
756     return SOFTBUS_OK;
757 }