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