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