• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "client_trans_tcp_direct_listener.h"
22 #include "softbus_adapter_errcode.h"
23 #include "softbus_adapter_socket.h"
24 #include "softbus_conn_common.h"
25 #include "softbus_error_code.h"
26 #include "softbus_socket.h"
27 #include "trans_log.h"
28 
SetReuseAddr(int fd,int on)29 static int SetReuseAddr(int fd, int on)
30 {
31     int rc = SoftBusSocketSetOpt(fd, SOFTBUS_SOL_SOCKET, SOFTBUS_SO_REUSEADDR, &on, sizeof(on));
32     if (rc != SOFTBUS_OK) {
33         TRANS_LOGE(TRANS_FILE, "set SO_REUSEADDR error. fd=%{public}d", fd);
34         return SOFTBUS_INVALID_FD;
35     }
36     return SOFTBUS_OK;
37 }
38 
SetReusePort(int fd,int on)39 static int SetReusePort(int fd, int on)
40 {
41     int rc = SoftBusSocketSetOpt(fd, SOFTBUS_SOL_SOCKET, SOFTBUS_SO_REUSEPORT, &on, sizeof(on));
42     if (rc != SOFTBUS_OK) {
43         TRANS_LOGE(TRANS_FILE, "set SO_REUSEPORT error. fd=%{public}d", fd);
44         return SOFTBUS_INVALID_FD;
45     }
46     return SOFTBUS_OK;
47 }
48 
CreateServerSocketByIpv4(const char * ip,int port)49 static int CreateServerSocketByIpv4(const char *ip, int port)
50 {
51     SoftBusSockAddrIn addr;
52     int32_t ret = Ipv4AddrToAddrIn(&addr, ip, port);
53     if (ret != SOFTBUS_OK) {
54         TRANS_LOGE(TRANS_FILE, "init addr error, ret=%{public}d", ret);
55         return ret;
56     }
57 
58     int fd;
59 
60     ret = SoftBusSocketCreate(SOFTBUS_AF_INET, SOFTBUS_SOCK_STREAM | SOFTBUS_SOCK_NONBLOCK |
61         SOFTBUS_SOCK_CLOEXEC, 0, &fd);
62     if (ret != SOFTBUS_OK) {
63         TRANS_LOGE(TRANS_FILE, "create socket error, ret=%{public}d.", ret);
64         return ret;
65     }
66 
67     ret = SetReuseAddr(fd, 1);
68     if (ret != SOFTBUS_OK) {
69         TRANS_LOGE(TRANS_FILE, "reuse addr error, ret=%{public}d.", ret);
70         TransTdcReleaseFd(fd);
71         return ret;
72     }
73 
74     ret = SetReusePort(fd, 1);
75     if (ret != SOFTBUS_OK) {
76         TRANS_LOGE(TRANS_FILE, "reuse port error, ret=%{public}d.", ret);
77         TransTdcReleaseFd(fd);
78         return ret;
79     }
80 
81     ret = SOFTBUS_TEMP_FAILURE_RETRY(SoftBusSocketBind(fd, (SoftBusSockAddr *)&addr, sizeof(addr)));
82     if (ret != SOFTBUS_ADAPTER_OK) {
83         TRANS_LOGE(TRANS_FILE, "bind error, ret=%{public}d.", ret);
84         TransTdcReleaseFd(fd);
85         return ret;
86     }
87 
88     return fd;
89 }
90 
CreateServerSocketByIpv6(const char * ip,int port)91 static int CreateServerSocketByIpv6(const char *ip, int port)
92 {
93     SoftBusSockAddrIn6 addr;
94     int32_t ret = Ipv6AddrToAddrIn(&addr, ip, port);
95     if (ret != SOFTBUS_OK) {
96         TRANS_LOGE(TRANS_FILE, "init addr error, ret=%{public}d", ret);
97         return ret;
98     }
99 
100     int fd;
101     ret = SoftBusSocketCreate(SOFTBUS_AF_INET6, SOFTBUS_SOCK_STREAM | SOFTBUS_SOCK_NONBLOCK |
102         SOFTBUS_SOCK_CLOEXEC, 0, &fd);
103     if (ret != SOFTBUS_OK) {
104         TRANS_LOGE(TRANS_FILE, "create socket error, ret=%{public}d.", ret);
105         return ret;
106     }
107 
108     ret = SetReuseAddr(fd, 1);
109     if (ret != SOFTBUS_OK) {
110         TRANS_LOGE(TRANS_FILE, "reuse addr error, ret=%{public}d.", ret);
111         TransTdcReleaseFd(fd);
112         return ret;
113     }
114 
115     ret = SetReusePort(fd, 1);
116     if (ret != SOFTBUS_OK) {
117         TRANS_LOGE(TRANS_FILE, "reuse port error, ret=%{public}d.", ret);
118         TransTdcReleaseFd(fd);
119         return ret;
120     }
121 
122     ret = SOFTBUS_TEMP_FAILURE_RETRY(SoftBusSocketBind(fd, (SoftBusSockAddr *)&addr, sizeof(addr)));
123     TRANS_LOGI(TRANS_FILE, "bind addr port=%{public}#x", addr.sin6Port);
124     if (ret != SOFTBUS_ADAPTER_OK) {
125         TRANS_LOGE(TRANS_FILE, "bind error, ret=%{public}d.", ret);
126         TransTdcReleaseFd(fd);
127         return ret;
128     }
129     return fd;
130 }
131 
CreateServerSocket(const char * ip,int32_t * fd,int32_t * port)132 static int32_t CreateServerSocket(const char *ip, int32_t *fd, int32_t *port)
133 {
134     if (ip == NULL || fd == NULL || port == NULL) {
135         TRANS_LOGE(TRANS_FILE, "invalid param.");
136         return SOFTBUS_INVALID_PARAM;
137     }
138 
139     int32_t socketFd = -1;
140     if (GetDomainByAddr(ip) == SOFTBUS_AF_INET6) {
141         socketFd = CreateServerSocketByIpv6(ip, 0);
142     } else {
143         socketFd = CreateServerSocketByIpv4(ip, 0);
144     }
145 
146     if (socketFd < 0) {
147         TRANS_LOGE(TRANS_FILE, "failed to start tcp server for getting port");
148         return SOFTBUS_FILE_ERR;
149     }
150     const SocketInterface *interface = GetSocketInterface(LNN_PROTOCOL_IP);
151     if (interface == NULL) {
152         TRANS_LOGE(TRANS_FILE, "no ip supportted");
153         TransTdcReleaseFd(socketFd);
154         return SOFTBUS_NOT_FIND;
155     }
156     int32_t socketPort = interface->GetSockPort(socketFd);
157     if (socketPort < 0) {
158         TRANS_LOGE(TRANS_FILE, "failed to get port from tcp socket");
159         TransTdcReleaseFd(socketFd);
160         return SOFTBUS_INVALID_PORT;
161     }
162     *fd = socketFd;
163     *port = socketPort;
164     TRANS_LOGI(TRANS_FILE, "create socket success, fd=%{public}d, port=%{public}d", socketFd, socketPort);
165     return SOFTBUS_OK;
166 }
167 
InitSockAddrInByIpPort(const char * ip,int32_t port,struct sockaddr_in * addr)168 static int32_t InitSockAddrInByIpPort(const char *ip, int32_t port, struct sockaddr_in *addr)
169 {
170     if (ip == NULL || port < 0 || addr == NULL) {
171         TRANS_LOGE(TRANS_FILE, "invalid param.");
172         return SOFTBUS_INVALID_PARAM;
173     }
174 
175     (void)memset_s(addr, sizeof(struct sockaddr_in), 0, sizeof(struct sockaddr_in));
176     addr->sin_family = AF_INET;
177     addr->sin_port = port;
178     addr->sin_addr.s_addr = SoftBusNtoHl(SoftBusInetAddr(ip));
179     return SOFTBUS_OK;
180 }
181 
InitSockAddrIn6ByIpPort(const char * ip,int32_t port,struct sockaddr_in6 * addr)182 static int32_t InitSockAddrIn6ByIpPort(const char *ip, int32_t port, struct sockaddr_in6 *addr)
183 {
184     if (ip == NULL || port < 0 || addr == NULL) {
185         TRANS_LOGE(TRANS_FILE, "invalid param.");
186         return SOFTBUS_INVALID_PARAM;
187     }
188 
189     SoftBusSockAddrIn6 addrIn6;
190     int32_t ret = Ipv6AddrToAddrIn(&addrIn6, ip, port);
191     addrIn6.sin6Port = port;
192     if (ret != SOFTBUS_OK) {
193         TRANS_LOGE(TRANS_FILE, "init addr error, ret=%{public}d", ret);
194         return ret;
195     }
196 
197     (void)memset_s(addr, sizeof(struct sockaddr_in6), 0, sizeof(struct sockaddr_in6));
198     addr->sin6_family = AF_INET6;
199     addr->sin6_port = addrIn6.sin6Port;
200     addr->sin6_scope_id = addrIn6.sin6ScopeId;
201     if (memcpy_s(&addr->sin6_addr, sizeof(addr->sin6_addr), &addrIn6.sin6Addr, sizeof(addrIn6.sin6Addr)) != EOK) {
202         TRANS_LOGE(TRANS_FILE, "failed to get ip, ret=%{public}d", ret);
203         return SOFTBUS_MEM_ERR;
204     }
205     return SOFTBUS_OK;
206 }
207 
StartNStackXDFileServer(const char * myIp,const uint8_t * key,uint32_t keyLen,DFileMsgReceiver msgReceiver,int32_t * filePort)208 int32_t StartNStackXDFileServer(
209     const char *myIp, const uint8_t *key, uint32_t keyLen, DFileMsgReceiver msgReceiver, int32_t *filePort)
210 {
211     if (myIp == NULL || filePort == NULL) {
212         TRANS_LOGE(TRANS_FILE, "invalid param.");
213         return SOFTBUS_INVALID_PARAM;
214     }
215     int32_t port = -1;
216     int32_t fd = -1;
217     int32_t ret = CreateServerSocket(myIp, &fd, &port);
218     if (ret != SOFTBUS_OK) {
219         TRANS_LOGE(TRANS_FILE, "failed to start tcp server for getting port");
220         return ret;
221     }
222     int sessionId = -1;
223     if (GetDomainByAddr(myIp) == SOFTBUS_AF_INET6) {
224         struct sockaddr_in6 localAddr = { 0 };
225         ret = InitSockAddrIn6ByIpPort(myIp, port, &localAddr);
226         if (ret != SOFTBUS_OK) {
227             TransTdcReleaseFd(fd);
228             TRANS_LOGE(TRANS_FILE, "failed to create sockaddr_in6, ret=%{public}d", ret);
229             return ret;
230         }
231         socklen_t addrLen = sizeof(struct sockaddr_in6);
232         sessionId = NSTACKX_DFileServer((struct sockaddr_in *)&localAddr, addrLen, key, keyLen, msgReceiver);
233     } else {
234         struct sockaddr_in localAddr = { 0 };
235         ret = InitSockAddrInByIpPort(myIp, port, &localAddr);
236         if (ret != SOFTBUS_OK) {
237             TransTdcReleaseFd(fd);
238             TRANS_LOGE(TRANS_FILE, "failed to create sockaddr_in, ret=%{public}d", ret);
239             return ret;
240         }
241         socklen_t addrLen = sizeof(struct sockaddr_in);
242         sessionId = NSTACKX_DFileServer(&localAddr, addrLen, key, keyLen, msgReceiver);
243     }
244     *filePort = port;
245     TransTdcReleaseFd(fd);
246     if (sessionId < 0) {
247         TRANS_LOGE(TRANS_FILE, "failed to start dfile server.");
248         return SOFTBUS_TRANS_INVALID_SESSION_ID;
249     }
250 
251     char animizedIp[IP_LEN] = { 0 };
252     ConvertAnonymizeIpAddress(animizedIp, IP_LEN, myIp, IP_LEN);
253     TRANS_LOGI(TRANS_FILE, "start dfile server, ip=%{public}s, port=%{public}d", animizedIp, port);
254     return sessionId;
255 }
256 
StartNStackXDFileClient(const char * peerIp,int32_t peerPort,const uint8_t * key,uint32_t keyLen,DFileMsgReceiver msgReceiver)257 int32_t StartNStackXDFileClient(
258     const char *peerIp, int32_t peerPort, const uint8_t *key, uint32_t keyLen, DFileMsgReceiver msgReceiver)
259 {
260     if (peerIp == NULL) {
261         TRANS_LOGW(TRANS_FILE, "invalid param.");
262         return SOFTBUS_INVALID_PARAM;
263     }
264 
265     int32_t sessionId = -1;
266     if (GetDomainByAddr(peerIp) == SOFTBUS_AF_INET6) {
267         struct sockaddr_in6 localAddr = { 0 };
268         int32_t ret = InitSockAddrIn6ByIpPort(peerIp, peerPort, &localAddr);
269         if (ret != SOFTBUS_OK) {
270             TRANS_LOGE(TRANS_FILE, "failed to create sockaddr_in6, ret=%{public}d", ret);
271             return ret;
272         }
273         socklen_t addrLen = sizeof(struct sockaddr_in6);
274         sessionId = NSTACKX_DFileClient((struct sockaddr_in *)&localAddr, addrLen, key, keyLen, msgReceiver);
275     } else {
276         struct sockaddr_in localAddr = { 0 };
277         int32_t ret = InitSockAddrInByIpPort(peerIp, peerPort, &localAddr);
278         if (ret != SOFTBUS_OK) {
279             TRANS_LOGE(TRANS_FILE, "failed to create sockaddr_in, ret=%{public}d", ret);
280             return ret;
281         }
282         socklen_t addrLen = sizeof(struct sockaddr_in);
283         sessionId = NSTACKX_DFileClient(&localAddr, addrLen, key, keyLen, msgReceiver);
284     }
285 
286     if (sessionId < 0) {
287         TRANS_LOGE(TRANS_FILE, "failed to start dfile client");
288         return SOFTBUS_TRANS_INVALID_SESSION_ID;
289     }
290 
291     char animizedIp[IP_LEN] = { 0 };
292     ConvertAnonymizeIpAddress(animizedIp, IP_LEN, peerIp, IP_LEN);
293     TRANS_LOGI(TRANS_FILE, "start dfile client, peerIp=%{public}s, peerPort=%{public}d", animizedIp, peerPort);
294     return sessionId;
295 }
296