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 "file_adapter.h"
17
18 #include <securec.h>
19 #include <unistd.h>
20
21 #include "softbus_adapter_errcode.h"
22 #include "softbus_adapter_socket.h"
23 #include "softbus_errcode.h"
24 #include "softbus_log.h"
25 #include "softbus_socket.h"
26
27
SetReuseAddr(int fd,int on)28 static int SetReuseAddr(int fd, int on)
29 {
30 int rc = SoftBusSocketSetOpt(fd, SOFTBUS_SOL_SOCKET, SOFTBUS_SO_REUSEADDR, &on, sizeof(on));
31 if (rc != SOFTBUS_OK) {
32 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "fd=%d set SO_REUSEADDR error", fd);
33 return SOFTBUS_ERR;
34 }
35 return SOFTBUS_OK;
36 }
37
SetReusePort(int fd,int on)38 static int SetReusePort(int fd, int on)
39 {
40 int rc = SoftBusSocketSetOpt(fd, SOFTBUS_SOL_SOCKET, SOFTBUS_SO_REUSEPORT, &on, sizeof(on));
41 if (rc != 0) {
42 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "fd=%d set SO_REUSEPORT error", fd);
43 return SOFTBUS_ERR;
44 }
45 return SOFTBUS_OK;
46 }
47
OpenTcpServer(const char * ip,int port)48 static int OpenTcpServer(const char *ip, int port)
49 {
50 SoftBusSockAddrIn addr;
51 (void)memset_s(&addr, sizeof(addr), 0, sizeof(addr));
52 int rc = SoftBusInetPtoN(SOFTBUS_AF_INET, ip, &addr.sinAddr);
53 if (rc != SOFTBUS_ADAPTER_OK) {
54 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "rc=%d", rc);
55 return SOFTBUS_ERR;
56 }
57 addr.sinFamily = SOFTBUS_AF_INET;
58 addr.sinPort = SoftBusHtoNs(port);
59 int fd;
60 int ret = SoftBusSocketCreate(SOFTBUS_AF_INET, SOFTBUS_SOCK_STREAM | SOFTBUS_SOCK_NONBLOCK |
61 SOFTBUS_SOCK_CLOEXEC, 0, &fd);
62 if (ret != SOFTBUS_OK) {
63 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "OpenTcpServer Create error, ret=%d.", ret);
64 return SOFTBUS_ERR;
65 }
66
67 (void)SetReuseAddr(fd, 1);
68 (void)SetReusePort(fd, 1);
69 rc = SOFTBUS_TEMP_FAILURE_RETRY(SoftBusSocketBind(fd, (SoftBusSockAddr *)&addr, sizeof(addr)));
70 if (rc != SOFTBUS_ADAPTER_OK) {
71 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "OpenTcpServer Bind error, rc=%d.", rc);
72 ConnShutdownSocket(fd);
73 return SOFTBUS_ERR;
74 }
75 return fd;
76 }
77
StartNStackXDFileServer(const char * myIP,const uint8_t * key,uint32_t keyLen,DFileMsgReceiver msgReceiver,int32_t * filePort)78 int32_t StartNStackXDFileServer(const char *myIP, const uint8_t *key,
79 uint32_t keyLen, DFileMsgReceiver msgReceiver, int32_t *filePort)
80 {
81 if (myIP == NULL || filePort == NULL) {
82 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "%s:invalid param.", __func__);
83 return SOFTBUS_INVALID_PARAM;
84 }
85 int fd = OpenTcpServer(myIP, 0);
86 if (fd < 0) {
87 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "failed to start tcp server for getting port");
88 return SOFTBUS_ERR;
89 }
90 const SocketInterface *ip = GetSocketInterface(LNN_PROTOCOL_IP);
91 if (ip == NULL) {
92 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "no ip supportted");
93 ConnShutdownSocket(fd);
94 return SOFTBUS_NOT_FIND;
95 }
96 int port = ip->GetSockPort(fd);
97 if (port < 0) {
98 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "failed to get port from tcp socket");
99 ConnShutdownSocket(fd);
100 return SOFTBUS_ERR;
101 }
102 *filePort = port;
103 struct sockaddr_in localAddr;
104 (void)memset_s(&localAddr, sizeof(localAddr), 0, sizeof(localAddr));
105 localAddr.sin_family = AF_INET;
106 localAddr.sin_port = (uint16_t)port;
107 localAddr.sin_addr.s_addr = SoftBusNtoHl(SoftBusInetAddr(myIP));
108 socklen_t addrLen = sizeof(struct sockaddr_in);
109
110 int sessionId = NSTACKX_DFileServer(&localAddr, addrLen, key, keyLen, msgReceiver);
111 ConnShutdownSocket(fd);
112 if (sessionId < 0) {
113 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "failed to start dfile server.");
114 return SOFTBUS_ERR;
115 }
116 return sessionId;
117 }
118
StartNStackXDFileClient(const char * peerIp,int32_t peerPort,const uint8_t * key,uint32_t keyLen,DFileMsgReceiver msgReceiver)119 int32_t StartNStackXDFileClient(const char *peerIp, int32_t peerPort, const uint8_t *key,
120 uint32_t keyLen, DFileMsgReceiver msgReceiver)
121 {
122 if (peerIp == NULL) {
123 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "%s:invalid param.", __func__);
124 return SOFTBUS_INVALID_PARAM;
125 }
126
127 struct sockaddr_in localAddr;
128 (void)memset_s(&localAddr, sizeof(localAddr), 0, sizeof(localAddr));
129 localAddr.sin_family = AF_INET;
130 localAddr.sin_port = (uint16_t)peerPort;
131 localAddr.sin_addr.s_addr = SoftBusNtoHl(SoftBusInetAddr(peerIp));
132 socklen_t addrLen = sizeof(struct sockaddr_in);
133
134 int32_t sessionId = NSTACKX_DFileClient(&localAddr, addrLen, key, keyLen, msgReceiver);
135 if (sessionId < 0) {
136 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "failed to start dfile client");
137 return SOFTBUS_ERR;
138 }
139 return sessionId;
140 }
141