OLD | NEW |
| (Empty) |
1 /***************************************************************************** | |
2 Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. | |
3 All rights reserved. | |
4 | |
5 Redistribution and use in source and binary forms, with or without | |
6 modification, are permitted provided that the following conditions are | |
7 met: | |
8 | |
9 * Redistributions of source code must retain the above | |
10 copyright notice, this list of conditions and the | |
11 following disclaimer. | |
12 | |
13 * Redistributions in binary form must reproduce the | |
14 above copyright notice, this list of conditions | |
15 and the following disclaimer in the documentation | |
16 and/or other materials provided with the distribution. | |
17 | |
18 * Neither the name of the University of Illinois | |
19 nor the names of its contributors may be used to | |
20 endorse or promote products derived from this | |
21 software without specific prior written permission. | |
22 | |
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | |
24 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
25 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
26 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
31 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
34 *****************************************************************************/ | |
35 | |
36 /***************************************************************************** | |
37 written by | |
38 Yunhong Gu, last updated 01/27/2011 | |
39 *****************************************************************************/ | |
40 | |
41 #ifndef __UDT_CORE_H__ | |
42 #define __UDT_CORE_H__ | |
43 | |
44 | |
45 #include "udt.h" | |
46 #include "common.h" | |
47 #include "list.h" | |
48 #include "buffer.h" | |
49 #include "window.h" | |
50 #include "packet.h" | |
51 #include "channel.h" | |
52 #include "api.h" | |
53 #include "ccc.h" | |
54 #include "cache.h" | |
55 #include "queue.h" | |
56 | |
57 enum UDTSockType {UDT_STREAM = 1, UDT_DGRAM}; | |
58 | |
59 class CUDT | |
60 { | |
61 friend class CUDTSocket; | |
62 friend class CUDTUnited; | |
63 friend class CCC; | |
64 friend struct CUDTComp; | |
65 friend class CCache; | |
66 friend class CSndQueue; | |
67 friend class CRcvQueue; | |
68 friend class CSndUList; | |
69 friend class CRcvUList; | |
70 | |
71 private: // constructor and desctructor | |
72 CUDT(); | |
73 CUDT(const CUDT& ancestor); | |
74 const CUDT& operator=(const CUDT&) {return *this;} | |
75 ~CUDT(); | |
76 | |
77 public: //API | |
78 static int startup(); | |
79 static int cleanup(); | |
80 static UDTSOCKET socket(int af, int type = SOCK_STREAM, int protocol = 0); | |
81 static int bind(UDTSOCKET u, const sockaddr* name, int namelen); | |
82 static int bind(UDTSOCKET u, UDPSOCKET udpsock); | |
83 static int listen(UDTSOCKET u, int backlog); | |
84 static UDTSOCKET accept(UDTSOCKET u, sockaddr* addr, int* addrlen); | |
85 static int connect(UDTSOCKET u, const sockaddr* name, int namelen); | |
86 static int close(UDTSOCKET u); | |
87 static int getpeername(UDTSOCKET u, sockaddr* name, int* namelen); | |
88 static int getsockname(UDTSOCKET u, sockaddr* name, int* namelen); | |
89 static int getsockopt(UDTSOCKET u, int level, UDTOpt optname, void* optval, i
nt* optlen); | |
90 static int setsockopt(UDTSOCKET u, int level, UDTOpt optname, const void* opt
val, int optlen); | |
91 static int send(UDTSOCKET u, const char* buf, int len, int flags); | |
92 static int recv(UDTSOCKET u, char* buf, int len, int flags); | |
93 static int sendmsg(UDTSOCKET u, const char* buf, int len, int ttl = -1, bool
inorder = false); | |
94 static int recvmsg(UDTSOCKET u, char* buf, int len); | |
95 static int64_t sendfile(UDTSOCKET u, std::fstream& ifs, int64_t& offset, cons
t int64_t& size, const int& block = 364000); | |
96 static int64_t recvfile(UDTSOCKET u, std::fstream& ofs, int64_t& offset, cons
t int64_t& size, const int& block = 7280000); | |
97 static int select(int nfds, ud_set* readfds, ud_set* writefds, ud_set* except
fds, const timeval* timeout); | |
98 static int selectEx(const std::vector<UDTSOCKET>& fds, std::vector<UDTSOCKET>
* readfds, std::vector<UDTSOCKET>* writefds, std::vector<UDTSOCKET>* exceptfds,
int64_t msTimeOut); | |
99 static int epoll_create(); | |
100 static int epoll_add_usock(const int eid, const UDTSOCKET u, const int* event
s = NULL); | |
101 static int epoll_add_ssock(const int eid, const SYSSOCKET s, const int* event
s = NULL); | |
102 static int epoll_remove_usock(const int eid, const UDTSOCKET u, const int* ev
ents = NULL); | |
103 static int epoll_remove_ssock(const int eid, const SYSSOCKET s, const int* ev
ents = NULL); | |
104 static int epoll_wait(const int eid, std::set<UDTSOCKET>* readfds, std::set<U
DTSOCKET>* writefds, int64_t msTimeOut, std::set<SYSSOCKET>* lrfds = NULL, std::
set<SYSSOCKET>* wrfds = NULL); | |
105 static int epoll_release(const int eid); | |
106 static CUDTException& getlasterror(); | |
107 static int perfmon(UDTSOCKET u, CPerfMon* perf, bool clear = true); | |
108 static UDTSTATUS getsockstate(UDTSOCKET u); | |
109 | |
110 public: // internal API | |
111 static CUDT* getUDTHandle(UDTSOCKET u); | |
112 | |
113 private: | |
114 // Functionality: | |
115 // initialize a UDT entity and bind to a local address. | |
116 // Parameters: | |
117 // None. | |
118 // Returned value: | |
119 // None. | |
120 | |
121 void open(); | |
122 | |
123 // Functionality: | |
124 // Start listening to any connection request. | |
125 // Parameters: | |
126 // None. | |
127 // Returned value: | |
128 // None. | |
129 | |
130 void listen(); | |
131 | |
132 // Functionality: | |
133 // Connect to a UDT entity listening at address "peer". | |
134 // Parameters: | |
135 // 0) [in] peer: The address of the listening UDT entity. | |
136 // Returned value: | |
137 // None. | |
138 | |
139 void connect(const sockaddr* peer); | |
140 | |
141 // Functionality: | |
142 // Connect to a UDT entity listening at address "peer", which has sent
"hs" request. | |
143 // Parameters: | |
144 // 0) [in] peer: The address of the listening UDT entity. | |
145 // 1) [in/out] hs: The handshake information sent by the peer side (in)
, negotiated value (out). | |
146 // Returned value: | |
147 // None. | |
148 | |
149 void connect(const sockaddr* peer, CHandShake* hs); | |
150 | |
151 // Functionality: | |
152 // Close the opened UDT entity. | |
153 // Parameters: | |
154 // None. | |
155 // Returned value: | |
156 // None. | |
157 | |
158 void close(); | |
159 | |
160 // Functionality: | |
161 // Request UDT to send out a data block "data" with size of "len". | |
162 // Parameters: | |
163 // 0) [in] data: The address of the application data to be sent. | |
164 // 1) [in] len: The size of the data block. | |
165 // Returned value: | |
166 // Actual size of data sent. | |
167 | |
168 int send(const char* data, const int& len); | |
169 | |
170 // Functionality: | |
171 // Request UDT to receive data to a memory block "data" with size of "l
en". | |
172 // Parameters: | |
173 // 0) [out] data: data received. | |
174 // 1) [in] len: The desired size of data to be received. | |
175 // Returned value: | |
176 // Actual size of data received. | |
177 | |
178 int recv(char* data, const int& len); | |
179 | |
180 // Functionality: | |
181 // send a message of a memory block "data" with size of "len". | |
182 // Parameters: | |
183 // 0) [out] data: data received. | |
184 // 1) [in] len: The desired size of data to be received. | |
185 // 2) [in] ttl: the time-to-live of the message. | |
186 // 3) [in] inorder: if the message should be delivered in order. | |
187 // Returned value: | |
188 // Actual size of data sent. | |
189 | |
190 int sendmsg(const char* data, const int& len, const int& ttl, const bool& ino
rder); | |
191 | |
192 // Functionality: | |
193 // Receive a message to buffer "data". | |
194 // Parameters: | |
195 // 0) [out] data: data received. | |
196 // 1) [in] len: size of the buffer. | |
197 // Returned value: | |
198 // Actual size of data received. | |
199 | |
200 int recvmsg(char* data, const int& len); | |
201 | |
202 // Functionality: | |
203 // Request UDT to send out a file described as "fd", starting from "off
set", with size of "size". | |
204 // Parameters: | |
205 // 0) [in] ifs: The input file stream. | |
206 // 1) [in, out] offset: From where to read and send data; output is the
new offset when the call returns. | |
207 // 2) [in] size: How many data to be sent. | |
208 // 3) [in] block: size of block per read from disk | |
209 // Returned value: | |
210 // Actual size of data sent. | |
211 | |
212 int64_t sendfile(std::fstream& ifs, int64_t& offset, const int64_t& size, con
st int& block = 366000); | |
213 | |
214 // Functionality: | |
215 // Request UDT to receive data into a file described as "fd", starting
from "offset", with expected size of "size". | |
216 // Parameters: | |
217 // 0) [out] ofs: The output file stream. | |
218 // 1) [in, out] offset: From where to write data; output is the new off
set when the call returns. | |
219 // 2) [in] size: How many data to be received. | |
220 // 3) [in] block: size of block per write to disk | |
221 // Returned value: | |
222 // Actual size of data received. | |
223 | |
224 int64_t recvfile(std::fstream& ofs, int64_t& offset, const int64_t& size, con
st int& block = 7320000); | |
225 | |
226 // Functionality: | |
227 // Configure UDT options. | |
228 // Parameters: | |
229 // 0) [in] optName: The enum name of a UDT option. | |
230 // 1) [in] optval: The value to be set. | |
231 // 2) [in] optlen: size of "optval". | |
232 // Returned value: | |
233 // None. | |
234 | |
235 void setOpt(UDTOpt optName, const void* optval, const int& optlen); | |
236 | |
237 // Functionality: | |
238 // Read UDT options. | |
239 // Parameters: | |
240 // 0) [in] optName: The enum name of a UDT option. | |
241 // 1) [in] optval: The value to be returned. | |
242 // 2) [out] optlen: size of "optval". | |
243 // Returned value: | |
244 // None. | |
245 | |
246 void getOpt(UDTOpt optName, void* optval, int& optlen); | |
247 | |
248 // Functionality: | |
249 // read the performance data since last sample() call. | |
250 // Parameters: | |
251 // 0) [in, out] perf: pointer to a CPerfMon structure to record the per
formance data. | |
252 // 1) [in] clear: flag to decide if the local performance trace should
be cleared. | |
253 // Returned value: | |
254 // None. | |
255 | |
256 void sample(CPerfMon* perf, bool clear = true); | |
257 | |
258 private: | |
259 static CUDTUnited s_UDTUnited; // UDT global management base | |
260 | |
261 public: | |
262 static const UDTSOCKET INVALID_SOCK; // invalid socket descriptor | |
263 static const int ERROR; // socket api error returned val
ue | |
264 | |
265 private: // Identification | |
266 UDTSOCKET m_SocketID; // UDT socket number | |
267 UDTSockType m_iSockType; // Type of the UDT connection (S
OCK_STREAM or SOCK_DGRAM) | |
268 UDTSOCKET m_PeerID; // peer id, for multiplexer | |
269 static const int m_iVersion; // UDT version, for compatibilit
y use | |
270 | |
271 private: // Packet sizes | |
272 int m_iPktSize; // Maximum/regular packet size,
in bytes | |
273 int m_iPayloadSize; // Maximum/regular payload size,
in bytes | |
274 | |
275 private: // Options | |
276 int m_iMSS; // Maximum Segment Size, in byte
s | |
277 bool m_bSynSending; // Sending syncronization mode | |
278 bool m_bSynRecving; // Receiving syncronization mode | |
279 int m_iFlightFlagSize; // Maximum number of packets in
flight from the peer side | |
280 int m_iSndBufSize; // Maximum UDT sender buffer siz
e | |
281 int m_iRcvBufSize; // Maximum UDT receiver buffer s
ize | |
282 linger m_Linger; // Linger information on close | |
283 int m_iUDPSndBufSize; // UDP sending buffer size | |
284 int m_iUDPRcvBufSize; // UDP receiving buffer size | |
285 int m_iIPversion; // IP version | |
286 bool m_bRendezvous; // Rendezvous connection mode | |
287 int m_iSndTimeOut; // sending timeout in millisecon
ds | |
288 int m_iRcvTimeOut; // receiving timeout in millisec
onds | |
289 bool m_bReuseAddr; // reuse an exiting port or not,
for UDP multiplexer | |
290 int64_t m_llMaxBW; // maximum data transfer rate (t
hreshold) | |
291 | |
292 private: // congestion control | |
293 CCCVirtualFactory* m_pCCFactory; // Factory class to create a spe
cific CC instance | |
294 CCC* m_pCC; // congestion control class | |
295 CCache* m_pCache; // network information cache | |
296 | |
297 private: // Status | |
298 volatile bool m_bListening; // If the UDT entit is listening
to connection | |
299 volatile bool m_bConnected; // Whether the connection is on
or off | |
300 volatile bool m_bClosing; // If the UDT entity is closing | |
301 volatile bool m_bShutdown; // If the peer side has shutdown
the connection | |
302 volatile bool m_bBroken; // If the connection has been br
oken | |
303 volatile bool m_bPeerHealth; // If the peer status is normal | |
304 bool m_bOpened; // If the UDT entity has been op
ened | |
305 int m_iBrokenCounter; // a counter (number of GC check
s) to let the GC tag this socket as disconnected | |
306 | |
307 int m_iEXPCount; // Expiration counter | |
308 int m_iBandwidth; // Estimated bandwidth, number o
f packets per second | |
309 int m_iRTT; // RTT, in microseconds | |
310 int m_iRTTVar; // RTT variance | |
311 int m_iDeliveryRate; // Packet arrival rate at the re
ceiver side | |
312 | |
313 uint64_t m_ullLingerExpiration; // Linger expiration time (for G
C to close a socket with data in sending buffer) | |
314 | |
315 private: // Sending related data | |
316 CSndBuffer* m_pSndBuffer; // Sender buffer | |
317 CSndLossList* m_pSndLossList; // Sender loss list | |
318 CPktTimeWindow* m_pSndTimeWindow; // Packet sending time window | |
319 | |
320 volatile uint64_t m_ullInterval; // Inter-packet time, in CPU clo
ck cycles | |
321 uint64_t m_ullTimeDiff; // aggregate difference in inter
-packet time | |
322 | |
323 volatile int m_iFlowWindowSize; // Flow control window size | |
324 volatile double m_dCongestionWindow; // congestion window size | |
325 | |
326 volatile int32_t m_iSndLastAck; // Last ACK received | |
327 volatile int32_t m_iSndLastDataAck; // The real last ACK that update
s the sender buffer and loss list | |
328 volatile int32_t m_iSndCurrSeqNo; // The largest sequence number t
hat has been sent | |
329 int32_t m_iLastDecSeq; // Sequence number sent last dec
rease occurs | |
330 int32_t m_iSndLastAck2; // Last ACK2 sent back | |
331 uint64_t m_ullSndLastAck2Time; // The time when last ACK2 was s
ent back | |
332 | |
333 int32_t m_iISN; // Initial Sequence Number | |
334 | |
335 private: // Receiving related data | |
336 CRcvBuffer* m_pRcvBuffer; // Receiver buffer | |
337 CRcvLossList* m_pRcvLossList; // Receiver loss list | |
338 CACKWindow* m_pACKWindow; // ACK history window | |
339 CPktTimeWindow* m_pRcvTimeWindow; // Packet arrival time window | |
340 | |
341 int32_t m_iRcvLastAck; // Last sent ACK | |
342 uint64_t m_ullLastAckTime; // Timestamp of last ACK | |
343 int32_t m_iRcvLastAckAck; // Last sent ACK that has been a
cknowledged | |
344 int32_t m_iAckSeqNo; // Last ACK sequence number | |
345 int32_t m_iRcvCurrSeqNo; // Largest received sequence num
ber | |
346 | |
347 uint64_t m_ullLastWarningTime; // Last time that a warning mess
age is sent | |
348 | |
349 int32_t m_iPeerISN; // Initial Sequence Number of th
e peer side | |
350 | |
351 private: // synchronization: mutexes and conditions | |
352 pthread_mutex_t m_ConnectionLock; // used to synchronize connectio
n operation | |
353 | |
354 pthread_cond_t m_SendBlockCond; // used to block "send" call | |
355 pthread_mutex_t m_SendBlockLock; // lock associated to m_SendBloc
kCond | |
356 | |
357 pthread_mutex_t m_AckLock; // used to protected sender's lo
ss list when processing ACK | |
358 | |
359 pthread_cond_t m_RecvDataCond; // used to block "recv" when the
re is no data | |
360 pthread_mutex_t m_RecvDataLock; // lock associated to m_RecvData
Cond | |
361 | |
362 pthread_mutex_t m_SendLock; // used to synchronize "send" ca
ll | |
363 pthread_mutex_t m_RecvLock; // used to synchronize "recv" ca
ll | |
364 | |
365 void initSynch(); | |
366 void destroySynch(); | |
367 void releaseSynch(); | |
368 | |
369 private: // Generation and processing of packets | |
370 void sendCtrl(const int& pkttype, void* lparam = NULL, void* rparam = NULL, c
onst int& size = 0); | |
371 void processCtrl(CPacket& ctrlpkt); | |
372 int packData(CPacket& packet, uint64_t& ts); | |
373 int processData(CUnit* unit); | |
374 int listen(sockaddr* addr, CPacket& packet); | |
375 | |
376 private: // Trace | |
377 uint64_t m_StartTime; // timestamp when the UDT entity
is started | |
378 int64_t m_llSentTotal; // total number of sent data pac
kets, including retransmissions | |
379 int64_t m_llRecvTotal; // total number of received pack
ets | |
380 int m_iSndLossTotal; // total number of lost packets
(sender side) | |
381 int m_iRcvLossTotal; // total number of lost packets
(receiver side) | |
382 int m_iRetransTotal; // total number of retransmitted
packets | |
383 int m_iSentACKTotal; // total number of sent ACK pack
ets | |
384 int m_iRecvACKTotal; // total number of received ACK
packets | |
385 int m_iSentNAKTotal; // total number of sent NAK pack
ets | |
386 int m_iRecvNAKTotal; // total number of received NAK
packets | |
387 int64_t m_llSndDurationTotal; // total real time for sending | |
388 | |
389 uint64_t m_LastSampleTime; // last performance sample time | |
390 int64_t m_llTraceSent; // number of pakctes sent in the
last trace interval | |
391 int64_t m_llTraceRecv; // number of pakctes received in
the last trace interval | |
392 int m_iTraceSndLoss; // number of lost packets in the
last trace interval (sender side) | |
393 int m_iTraceRcvLoss; // number of lost packets in the
last trace interval (receiver side) | |
394 int m_iTraceRetrans; // number of retransmitted packe
ts in the last trace interval | |
395 int m_iSentACK; // number of ACKs sent in the la
st trace interval | |
396 int m_iRecvACK; // number of ACKs received in th
e last trace interval | |
397 int m_iSentNAK; // number of NAKs sent in the la
st trace interval | |
398 int m_iRecvNAK; // number of NAKs received in th
e last trace interval | |
399 int64_t m_llSndDuration; // real time for sending | |
400 int64_t m_llSndDurationCounter; // timers to record the sending
duration | |
401 | |
402 private: // Timers | |
403 uint64_t m_ullCPUFrequency; // CPU clock frequency, used for
Timer, ticks per microsecond | |
404 | |
405 static const int m_iSYNInterval; // Periodical Rate Control Inter
val, 10000 microsecond | |
406 static const int m_iSelfClockInterval; // ACK interval for self-clockin
g | |
407 | |
408 uint64_t m_ullNextACKTime; // Next ACK time, in CPU clock c
ycles, same below | |
409 uint64_t m_ullNextNAKTime; // Next NAK time | |
410 uint64_t m_ullNextEXPTime; // Next timeout | |
411 | |
412 volatile uint64_t m_ullSYNInt; // SYN interval | |
413 volatile uint64_t m_ullACKInt; // ACK interval | |
414 volatile uint64_t m_ullNAKInt; // NAK interval | |
415 volatile uint64_t m_ullEXPInt; // EXP interval | |
416 volatile int64_t m_llLastRspTime; // time stamp of last response f
rom the peer | |
417 | |
418 uint64_t m_ullMinNakInt; // NAK timeout lower bound; too
small value can cause unnecessary retransmission | |
419 uint64_t m_ullMinExpInt; // timeout lower bound threshold
: too small timeout can cause problem | |
420 | |
421 int m_iPktCount; // packet counter for ACK | |
422 int m_iLightACKCount; // light ACK counter | |
423 | |
424 uint64_t m_ullTargetTime; // scheduled time of next packet
sending | |
425 | |
426 void checkTimers(); | |
427 | |
428 private: // for UDP multiplexer | |
429 CSndQueue* m_pSndQueue; // packet sending queue | |
430 CRcvQueue* m_pRcvQueue; // packet receiving queue | |
431 sockaddr* m_pPeerAddr; // peer address | |
432 uint32_t m_piSelfIP[4]; // local UDP IP address | |
433 CSNode* m_pSNode; // node information for UDT list
used in snd queue | |
434 CRNode* m_pRNode; // node information for UDT list
used in rcv queue | |
435 | |
436 private: // for epoll | |
437 std::set<int> m_sPollID; // set of epoll ID to trigger | |
438 void addEPoll(const int eid); | |
439 void removeEPoll(const int eid); | |
440 }; | |
441 | |
442 | |
443 #endif | |
OLD | NEW |