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 #ifndef NSTACKX_DFILE_SESSION_H
17 #define NSTACKX_DFILE_SESSION_H
18 #include "nstackx_event.h"
19 #include "nstackx_socket.h"
20 #include "nstackx_dfile_transfer.h"
21 #include "nstackx_dfile_private.h"
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25
26 #define MAX_EPOLL_SIZE 128
27 #define MAX_PEERINFO_SIZE 10
28 #define MAX_SEND_TRANSFERDONE_ACK_FRAME_COUNT 14
29 #define MAX_TRANSFERDONE_ACK_NODE_COUNT 100
30 #define MAX_TRANSTATELISTSIZE 100
31
32 typedef enum {
33 DFILE_SESSION_TYPE_CLIENT = 1,
34 DFILE_SESSION_TYPE_SERVER,
35 } DFileSessionType;
36
37 typedef struct {
38 List list;
39 uint32_t sendLen;
40 uint8_t *frame;
41 size_t length;
42 struct sockaddr_in peerAddr;
43 uint8_t socketIndex;
44 } QueueNode;
45
46 typedef struct {
47 pthread_t senderTid;
48 sem_t sendWait;
49 sem_t semNewCycle;
50 } SendThreadPara;
51
52 typedef struct {
53 List entry;
54 void *addr;
55 size_t len;
56 } IovList;
57
58 typedef struct {
59 List list;
60 uint16_t transId;
61 uint16_t sendNum;
62 } TransferDoneAckNode;
63
64 typedef struct {
65 uint8_t isWorking;
66 uint16_t transId;
67 PeerInfo *peerInfo;
68 } TransSlot;
69
70 struct DFileSession {
71 List list;
72 uint16_t sessionId; /* reserve for multi session */
73 DFileSessionType sessionType;
74 SocketProtocol protocol;
75 Socket *socket[NSTACKX_MULTI_PATH_NUM];
76 Socket *acceptSocket;
77 pthread_t tid;
78 EpollDesc epollfd;
79 List eventNodeChain;
80 uint8_t closeFlag;
81 uint32_t vtransDefaultSize;
82 List vtransManagerList;
83 pthread_mutex_t transIdLock;
84 BindType bindType;
85 DFileMsgReceiver msgReceiver;
86 OnDFileRenameFile onRenameFile;
87 uint16_t lastDFileTransId; /* for client, server will use client trans id */
88 List dFileTransChain;
89 List peerInfoChain;
90 MutexList transferDoneAckList; /* DATA:FileListTask */
91 uint32_t peerInfoCnt;
92 FileManager *fileManager;
93 pthread_t senderTid[NSTACKX_MULTI_PATH_NUM];
94 SendThreadPara sendThreadPara[NSTACKX_MAX_CLIENT_SEND_THREAD_NUM];
95 uint8_t addiSenderCloseFlag;
96 pthread_t receiverTid;
97 pthread_t controlTid;
98 List outboundQueue;
99 List inboundQueue;
100 pthread_mutex_t outboundQueueLock;
101 pthread_mutex_t inboundQueueLock;
102 sem_t outboundQueueWait[NSTACKX_MULTI_PATH_NUM];
103 uint64_t outboundQueueSize;
104 uint64_t inboundQueueSize;
105 List pendingFileLists;
106 #ifdef NSTACKX_SMALL_FILE_SUPPORT
107 List smallFileLists;
108 #endif
109 uint32_t fileListProcessingCnt;
110 uint32_t fileListPendingCnt;
111 uint32_t smallListProcessingCnt;
112 #ifdef NSTACKX_SMALL_FILE_SUPPORT
113 uint32_t smallListPendingCnt;
114 #endif
115 /*
116 * Receiver thread is blocking at "select" most of time.
117 * This "receiverPipe" is used to unblock "select" and terminate receiver thread during NSTACKX_DFileClose(),
118 * decreasing the closing time.
119 */
120 struct timespec measureBefore;
121 PipeDesc receiverPipe[PIPE_FD_NUM];
122 uint64_t recvBlockNumDirect;
123 uint64_t recvBlockNumInner;
124 atomic_t totalSendBlocks;
125 atomic_t totalRecvBlocks;
126 uint8_t partReadFlag;
127 atomic_t sendBlockListEmptyTimes;
128 atomic_t noPendingDataTimes;
129 uint32_t sleepTimes;
130 uint16_t clientSendThreadNum;
131 uint8_t cycleRunning[2];
132 struct timespec startTs;
133 uint64_t bytesTransferred;
134 uint32_t transCount;
135 atomic_t unprocessedReadEventCount;
136 uint8_t mainLoopActiveReadFlag;
137 List freeIovList[NSTACKX_MAX_CLIENT_SEND_THREAD_NUM];
138 uint8_t transFlag;
139 uint32_t capability;
140 uint32_t internalCaps;
141 uint32_t capsCheck;
142 MutexList tranIdStateList;
143 uint32_t wlanCatagory;
144 TransSlot transSlot[NSTACKX_FILE_MANAGER_THREAD_NUM];
145 uint8_t *recvBuffer;
146 uint32_t recvLen;
147 uint8_t acceptFlag;
148 uint8_t sendRemain;
149 int32_t allTaskCount;
150 pthread_mutex_t backPressLock;
151 uint32_t stopSendCnt[NSTACKX_MAX_CLIENT_SEND_THREAD_NUM];
152 uint32_t cipherCapability;
153 };
154
155 PeerInfo *CreatePeerInfo(DFileSession *session, const struct sockaddr_in *peerAddr,
156 uint16_t mtu, uint16_t connType, uint8_t socketIndex);
157 int32_t DFileWriteHandle(const uint8_t *frame, size_t len, void *context);
158 void NotifyMsgRecver(const DFileSession *session, DFileMsgType msgType, const DFileMsg *msg);
159 void TerminateMainThreadInner(void *arg);
160 void *DFileMainLoop(void *arg);
161 void *DFileSenderHandle(void *arg);
162 void *DFileReceiverHandle(void *arg);
163 void NotifyPipeEvent(const DFileSession *session);
164 int32_t CreateReceiverPipe(DFileSession *session);
165 int32_t CreateFileManager(DFileSession *session, const uint8_t *key, uint32_t keyLen, uint8_t isSender,
166 uint16_t connType);
167 int32_t DFileStartTrans(DFileSession *session, FileListInfo *fileListInfo);
168 int32_t StartDFileThreadsInner(DFileSession *session);
169 void DFileSessionSendSetting(PeerInfo *peerInfo);
170 void UpdateAllTransRetryCount(DFileSession *session, PeerInfo *peerInfo);
171 void CalculateSessionTransferRatePrepare(DFileSession *session);
172
173 void DestroyQueueNode(QueueNode *queueNode);
174 PeerInfo *ClientGetPeerInfoBySocketIndex(uint8_t socketIndex, const DFileSession *session);
175 void NoticeSessionProgress(DFileSession *session);
176 int32_t DFileSessionHandleReadBuffer(DFileSession *session, const uint8_t *buf, size_t bufLen,
177 struct sockaddr_in *peerAddr, uint8_t socketIndex);
178 int32_t DFileAcceptSocket(DFileSession *session);
179
180 int32_t WaitSocketEvent(const DFileSession *session, SocketDesc fd, uint32_t timeoutMs,
181 uint8_t *canRead, uint8_t *canWrite);
182
183 int32_t CheckFdSetSize(SocketDesc sock);
184 void DestroyReceiverPipe(DFileSession *session);
185
186 #define DFILE_SESSION_TERMINATE_FLAG 0x01
187 #define DFILE_SESSION_FATAL_FLAG 0x02
188
DFileSessionSetFatalFlag(struct DFileSession * session)189 static inline void DFileSessionSetFatalFlag(struct DFileSession *session)
190 {
191 session->closeFlag |= DFILE_SESSION_FATAL_FLAG;
192 }
193
DFileSessionSetTerminateFlag(struct DFileSession * session)194 static inline void DFileSessionSetTerminateFlag(struct DFileSession *session)
195 {
196 session->closeFlag |= DFILE_SESSION_TERMINATE_FLAG;
197 }
198
DFileSessionCheckFatalFlag(const struct DFileSession * session)199 static inline int32_t DFileSessionCheckFatalFlag(const struct DFileSession *session)
200 {
201 return session->closeFlag & DFILE_SESSION_FATAL_FLAG;
202 }
203
ClearSessionStats(struct DFileSession * session)204 static inline void ClearSessionStats(struct DFileSession *session)
205 {
206 session->sleepTimes = 0;
207 NSTACKX_ATOM_SET(&(session->sendBlockListEmptyTimes), 0);
208 NSTACKX_ATOM_SET(&(session->noPendingDataTimes), 0);
209 session->fileManager->sendListFullTimes = 0;
210 session->fileManager->iorBytes = 0;
211 }
212
CapsGSO(const struct DFileSession * session)213 static inline bool CapsGSO(const struct DFileSession *session)
214 {
215 return session->capability & NSTACKX_CAPS_UDP_GSO;
216 }
217
CapsLinkSeq(const struct DFileSession * session)218 static inline bool CapsLinkSeq(const struct DFileSession *session)
219 {
220 return session->capability & NSTACKX_CAPS_LINK_SEQUENCE;
221 }
222
CapsNoRW(const struct DFileSession * session)223 static inline bool CapsNoRW(const struct DFileSession *session)
224 {
225 return session->internalCaps & NSTACKX_INTERNAL_CAPS_NORW;
226 }
227
CapsTcp(const struct DFileSession * session)228 static inline bool CapsTcp(const struct DFileSession *session)
229 {
230 return ((session->capability & NSTACKX_CAPS_WLAN_CATAGORY) && (session->wlanCatagory == NSTACKX_WLAN_CAT_TCP));
231 }
232
CapsRecvFeedback(const struct DFileSession * session)233 static inline bool CapsRecvFeedback(const struct DFileSession *session)
234 {
235 return session->capsCheck & NSTACKX_INTERNAL_CAPS_RECV_FEEDBACK;
236 }
237
CapsChaCha(const struct DFileSession * session)238 static inline bool CapsChaCha(const struct DFileSession *session)
239 {
240 return (session->fileManager->keyLen == CHACHA20_KEY_LENGTH) &&
241 (session->cipherCapability & NSTACKX_CIPHER_CHACHA);
242 }
243
244 void NSTACKX_DFileAssembleFunc(void *softObj, const DFileEvent *info);
245 void DFileSetEvent(void *softObj, DFileEventFunc func);
246
247 #ifdef __cplusplus
248 }
249 #endif
250 #endif // NSTACKX_DFILE_SESSION_H
251