1 /*
2  * Copyright (c) 2021-2023 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 #ifndef COMMUNICATIONNETSTACK_SOCKET_EXEC_H
17 #define COMMUNICATIONNETSTACK_SOCKET_EXEC_H
18 
19 #include "bind_context.h"
20 #include "common_context.h"
21 #include "connect_context.h"
22 #include "multicast_get_loopback_context.h"
23 #include "multicast_get_ttl_context.h"
24 #include "multicast_membership_context.h"
25 #include "multicast_set_loopback_context.h"
26 #include "multicast_set_ttl_context.h"
27 #include "safe_map.h"
28 #include "tcp_extra_context.h"
29 #include "tcp_send_context.h"
30 #include "tcp_server_common_context.h"
31 #include "tcp_server_extra_context.h"
32 #include "tcp_server_listen_context.h"
33 #include "tcp_server_send_context.h"
34 #include "udp_extra_context.h"
35 #include "udp_send_context.h"
36 #include "napi_utils.h"
37 
38 #include <set>
39 
40 namespace OHOS::NetStack::Socket::SocketExec {
41 void NotifyRegisterEvent();
42 
43 /* async work execute */
44 bool ExecUdpBind(BindContext *context);
45 
46 bool ExecUdpSend(UdpSendContext *context);
47 
48 bool ExecUdpAddMembership(MulticastMembershipContext *context);
49 
50 bool ExecUdpDropMembership(MulticastMembershipContext *context);
51 
52 bool ExecSetMulticastTTL(MulticastSetTTLContext *context);
53 
54 bool ExecGetMulticastTTL(MulticastGetTTLContext *context);
55 
56 bool ExecSetLoopbackMode(MulticastSetLoopbackContext *context);
57 
58 bool ExecGetLoopbackMode(MulticastGetLoopbackContext *context);
59 
60 bool ExecTcpBind(BindContext *context);
61 
62 bool ExecConnect(ConnectContext *context);
63 
64 bool ExecTcpSend(TcpSendContext *context);
65 
66 bool ExecClose(CloseContext *context);
67 
68 bool ExecGetState(GetStateContext *context);
69 
70 bool ExecGetRemoteAddress(GetRemoteAddressContext *context);
71 
72 bool ExecGetLocalAddress(GetLocalAddressContext *context);
73 
74 bool ExecTcpSetExtraOptions(TcpSetExtraOptionsContext *context);
75 
76 bool ExecUdpSetExtraOptions(UdpSetExtraOptionsContext *context);
77 
78 bool ExecTcpGetSocketFd(GetSocketFdContext *context);
79 
80 bool ExecUdpGetSocketFd(GetSocketFdContext *context);
81 
82 bool ExecTcpConnectionSend(TcpServerSendContext *context);
83 
84 bool ExecTcpConnectionGetRemoteAddress(TcpServerGetRemoteAddressContext *context);
85 
86 bool ExecTcpConnectionGetLocalAddress(TcpServerGetLocalAddressContext *context);
87 
88 bool ExecTcpConnectionClose(TcpServerCloseContext *context);
89 
90 bool ExecTcpServerListen(TcpServerListenContext *context);
91 
92 bool ExecTcpServerSetExtraOptions(TcpServerSetExtraOptionsContext *context);
93 
94 bool ExecTcpServerGetState(TcpServerGetStateContext *context);
95 
96 bool ExecTcpServerGetLocalAddress(TcpServerGetLocalAddressContext *context);
97 
98 /* async work callback */
99 napi_value BindCallback(BindContext *context);
100 
101 napi_value UdpSendCallback(UdpSendContext *context);
102 
103 napi_value UdpAddMembershipCallback(MulticastMembershipContext *context);
104 
105 napi_value UdpDropMembershipCallback(MulticastMembershipContext *context);
106 
107 napi_value UdpSetMulticastTTLCallback(MulticastSetTTLContext *context);
108 
109 napi_value UdpGetMulticastTTLCallback(MulticastGetTTLContext *context);
110 
111 napi_value UdpSetLoopbackModeCallback(MulticastSetLoopbackContext *context);
112 
113 napi_value UdpGetLoopbackModeCallback(MulticastGetLoopbackContext *context);
114 
115 napi_value ConnectCallback(ConnectContext *context);
116 
117 napi_value TcpSendCallback(TcpSendContext *context);
118 
119 napi_value CloseCallback(CloseContext *context);
120 
121 napi_value GetStateCallback(GetStateContext *context);
122 
123 napi_value GetRemoteAddressCallback(GetRemoteAddressContext *context);
124 
125 napi_value GetLocalAddressCallback(GetLocalAddressContext *context);
126 
127 napi_value TcpSetExtraOptionsCallback(TcpSetExtraOptionsContext *context);
128 
129 napi_value UdpSetExtraOptionsCallback(UdpSetExtraOptionsContext *context);
130 
131 napi_value TcpGetSocketFdCallback(GetSocketFdContext *context);
132 
133 napi_value TcpConnectionSendCallback(TcpServerSendContext *context);
134 
135 napi_value TcpConnectionCloseCallback(TcpServerCloseContext *context);
136 
137 napi_value TcpConnectionGetRemoteAddressCallback(TcpServerGetRemoteAddressContext *context);
138 
139 napi_value TcpConnectionGetLocalAddressCallback(TcpServerGetLocalAddressContext *context);
140 
141 napi_value ListenCallback(TcpServerListenContext *context);
142 
143 napi_value TcpServerSetExtraOptionsCallback(TcpServerSetExtraOptionsContext *context);
144 
145 napi_value TcpServerGetStateCallback(TcpServerGetStateContext *context);
146 
147 napi_value TcpServerGetLocalAddressCallback(TcpServerGetLocalAddressContext *context);
148 
149 napi_value UdpGetSocketFdCallback(GetSocketFdContext *context);
150 
CallbackTemplate(uv_work_t * work,int status)151 template <napi_value (*MakeJsValue)(napi_env, void *)> static void CallbackTemplate(uv_work_t *work, int status)
152 {
153     (void)status;
154 
155     auto workWrapper = static_cast<UvWorkWrapper *>(work->data);
156     napi_env env = workWrapper->env;
157     auto closeScope = [env](napi_handle_scope scope) { NapiUtils::CloseScope(env, scope); };
158     std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scope(NapiUtils::OpenScope(env), closeScope);
159 
160     napi_value obj = MakeJsValue(env, workWrapper->data);
161 
162     std::pair<napi_value, napi_value> arg = {NapiUtils::GetUndefined(workWrapper->env), obj};
163     workWrapper->manager->Emit(workWrapper->type, arg);
164 
165     delete workWrapper;
166     delete work;
167 }
168 
169 struct MessageData {
170     MessageData() = delete;
MessageDataMessageData171     MessageData(void *d, size_t l, const SocketRemoteInfo &info) : data(d), len(l), remoteInfo(info) {}
~MessageDataMessageData172     ~MessageData()
173     {
174         if (data) {
175             free(data);
176         }
177     }
178 
179     void *data;
180     size_t len;
181     SocketRemoteInfo remoteInfo;
182 };
183 
184 struct TcpConnection {
185     TcpConnection() = delete;
TcpConnectionTcpConnection186     explicit TcpConnection(int32_t clientid) : clientId(clientid) {}
187     ~TcpConnection() = default;
188 
189     int32_t clientId;
190 };
191 
192 class SingletonSocketConfig {
193 public:
GetInstance()194     static SingletonSocketConfig& GetInstance()
195     {
196         static SingletonSocketConfig instance;
197         return instance;
198     }
199 
SetTcpExtraOptions(int listenFd,const TCPExtraOptions & option)200     void SetTcpExtraOptions(int listenFd, const TCPExtraOptions& option)
201     {
202         tcpExtraOptions_.EnsureInsert(listenFd, option);
203     }
204 
GetTcpExtraOptions(int listenFd,TCPExtraOptions & option)205     bool GetTcpExtraOptions(int listenFd, TCPExtraOptions& option)
206     {
207         return tcpExtraOptions_.Find(listenFd, option);
208     }
209 
AddNewListenSocket(int listenFd)210     void AddNewListenSocket(int listenFd)
211     {
212         tcpClients_.Insert(listenFd, {});
213     }
214 
AddNewAcceptSocket(int listenFd,int acceptFd)215     void AddNewAcceptSocket(int listenFd, int acceptFd)
216     {
217         std::set<int> fdSet;
218         auto fn = [&](std::set<int> &value) -> void {
219             value.emplace(acceptFd);
220         };
221         if (tcpClients_.Find(listenFd, fdSet)) {
222             tcpClients_.ChangeValueByLambda(listenFd, fn);
223         }
224     }
225 
RemoveAcceptSocket(int acceptFd)226     void RemoveAcceptSocket(int acceptFd)
227     {
228         tcpClients_.Iterate([acceptFd](int listenFd, std::set<int> fdSet) {
229             if (auto ite = fdSet.find(acceptFd); ite != fdSet.end()) {
230                 fdSet.erase(ite);
231             }
232         });
233     }
234 
GetClients(int listenFd)235     std::set<int> GetClients(int listenFd)
236     {
237         std::set<int> fdSet;
238         tcpClients_.Find(listenFd, fdSet);
239         return fdSet;
240     }
241 
RemoveServerSocket(int listenFd)242     void RemoveServerSocket(int listenFd)
243     {
244         tcpExtraOptions_.Erase(listenFd);
245         tcpClients_.Erase(listenFd);
246     }
247 
248 private:
SingletonSocketConfig()249     SingletonSocketConfig() {}
~SingletonSocketConfig()250     ~SingletonSocketConfig() {}
251 
252     SingletonSocketConfig(const SingletonSocketConfig& singleton) = delete;
253     SingletonSocketConfig& operator=(const SingletonSocketConfig& singleton) = delete;
254 
255     SafeMap<int, TCPExtraOptions> tcpExtraOptions_;
256     SafeMap<int, std::set<int>> tcpClients_;
257 };
258 
259 class MessageCallback {
260 public:
261     MessageCallback() = delete;
262 
263     virtual ~MessageCallback() = default;
264 
MessageCallback(EventManager * manager)265     explicit MessageCallback(EventManager *manager) : manager_(manager) {}
266 
267     virtual void OnError(int err) const = 0;
268 
269     virtual void OnCloseMessage(EventManager *manager) const = 0;
270 
271     virtual bool OnMessage(void *data, size_t dataLen, sockaddr *addr) const = 0;
272 
273     virtual bool OnMessage(int sock, void *data, size_t dataLen, sockaddr *addr, EventManager *manager) const = 0;
274 
275     virtual void OnTcpConnectionMessage(int32_t id) const = 0;
276 
277     [[nodiscard]] EventManager *GetEventManager() const;
278 
279 protected:
280     EventManager *manager_;
281 };
282 } // namespace OHOS::NetStack::Socket::SocketExec
283 #endif /* COMMUNICATIONNETSTACK_SOCKET_EXEC_H */
284