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