• 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 #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