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/18/2011
39 *****************************************************************************/
40 
41 #ifndef __UDT_H__
42 #define __UDT_H__
43 
44 
45 #ifndef WIN32
46    #include <sys/types.h>
47    #include <sys/socket.h>
48    #include <netinet/in.h>
49 #else
50    #ifdef __MINGW__
51       #include <stdint.h>
52       #include <ws2tcpip.h>
53    #endif
54    #include <windows.h>
55 #endif
56 #include <fstream>
57 #include <set>
58 #include <string>
59 #include <vector>
60 
61 
62 ////////////////////////////////////////////////////////////////////////////////
63 
64 //if compiling on VC6.0 or pre-WindowsXP systems
65 //use -DLEGACY_WIN32
66 
67 //if compiling with MinGW, it only works on XP or above
68 //use -D_WIN32_WINNT=0x0501
69 
70 
71 #ifdef WIN32
72    #ifndef __MINGW__
73       // Explicitly define 32-bit and 64-bit numbers
74       typedef __int32 int32_t;
75       typedef __int64 int64_t;
76       typedef unsigned __int32 uint32_t;
77       #ifndef LEGACY_WIN32
78          typedef unsigned __int64 uint64_t;
79       #else
80          // VC 6.0 does not support unsigned __int64: may cause potential problems.
81          typedef __int64 uint64_t;
82       #endif
83 
84       #ifdef UDT_EXPORTS
85          #define UDT_API __declspec(dllexport)
86       #else
87          #define UDT_API __declspec(dllimport)
88       #endif
89    #else
90       #define UDT_API
91    #endif
92 #else
93    #define UDT_API __attribute__ ((visibility("default")))
94 #endif
95 
96 #define NO_BUSY_WAITING
97 
98 #ifdef WIN32
99    #ifndef __MINGW__
100       typedef SOCKET SYSSOCKET;
101    #else
102       typedef int SYSSOCKET;
103    #endif
104 #else
105    typedef int SYSSOCKET;
106 #endif
107 
108 typedef SYSSOCKET UDPSOCKET;
109 typedef int UDTSOCKET;
110 
111 ////////////////////////////////////////////////////////////////////////////////
112 
113 typedef std::set<UDTSOCKET> ud_set;
114 #define UD_CLR(u, uset) ((uset)->erase(u))
115 #define UD_ISSET(u, uset) ((uset)->find(u) != (uset)->end())
116 #define UD_SET(u, uset) ((uset)->insert(u))
117 #define UD_ZERO(uset) ((uset)->clear())
118 
119 enum EPOLLOpt
120 {
121    // this values are defined same as linux epoll.h
122    // so that if system values are used by mistake, they should have the same effect
123    UDT_EPOLL_IN = 0x1,
124    UDT_EPOLL_OUT = 0x4,
125    UDT_EPOLL_ERR = 0x8
126 };
127 
128 enum UDTSTATUS {INIT = 1, OPENED, LISTENING, CONNECTING, CONNECTED, BROKEN, CLOSING, CLOSED, NONEXIST};
129 
130 ////////////////////////////////////////////////////////////////////////////////
131 
132 enum UDTOpt
133 {
134    UDT_MSS,             // the Maximum Transfer Unit
135    UDT_SNDSYN,          // if sending is blocking
136    UDT_RCVSYN,          // if receiving is blocking
137    UDT_CC,              // custom congestion control algorithm
138    UDT_FC,		// Flight flag size (window size)
139    UDT_SNDBUF,          // maximum buffer in sending queue
140    UDT_RCVBUF,          // UDT receiving buffer size
141    UDT_LINGER,          // waiting for unsent data when closing
142    UDP_SNDBUF,          // UDP sending buffer size
143    UDP_RCVBUF,          // UDP receiving buffer size
144    UDT_MAXMSG,          // maximum datagram message size
145    UDT_MSGTTL,          // time-to-live of a datagram message
146    UDT_RENDEZVOUS,      // rendezvous connection mode
147    UDT_SNDTIMEO,        // send() timeout
148    UDT_RCVTIMEO,        // recv() timeout
149    UDT_REUSEADDR,	// reuse an existing port or create a new one
150    UDT_MAXBW,		// maximum bandwidth (bytes per second) that the connection can use
151    UDT_STATE,		// current socket state, see UDTSTATUS, read only
152    UDT_EVENT,		// current avalable events associated with the socket
153    UDT_SNDDATA,		// size of data in the sending buffer
154    UDT_RCVDATA		// size of data available for recv
155 };
156 
157 ////////////////////////////////////////////////////////////////////////////////
158 
159 struct CPerfMon
160 {
161    // global measurements
162    int64_t msTimeStamp;                 // time since the UDT entity is started, in milliseconds
163    int64_t pktSentTotal;                // total number of sent data packets, including retransmissions
164    int64_t pktRecvTotal;                // total number of received packets
165    int pktSndLossTotal;                 // total number of lost packets (sender side)
166    int pktRcvLossTotal;                 // total number of lost packets (receiver side)
167    int pktRetransTotal;                 // total number of retransmitted packets
168    int pktSentACKTotal;                 // total number of sent ACK packets
169    int pktRecvACKTotal;                 // total number of received ACK packets
170    int pktSentNAKTotal;                 // total number of sent NAK packets
171    int pktRecvNAKTotal;                 // total number of received NAK packets
172    int64_t usSndDurationTotal;		// total time duration when UDT is sending data (idle time exclusive)
173 
174    // local measurements
175    int64_t pktSent;                     // number of sent data packets, including retransmissions
176    int64_t pktRecv;                     // number of received packets
177    int pktSndLoss;                      // number of lost packets (sender side)
178    int pktRcvLoss;                      // number of lost packets (receiver side)
179    int pktRetrans;                      // number of retransmitted packets
180    int pktSentACK;                      // number of sent ACK packets
181    int pktRecvACK;                      // number of received ACK packets
182    int pktSentNAK;                      // number of sent NAK packets
183    int pktRecvNAK;                      // number of received NAK packets
184    double mbpsSendRate;                 // sending rate in Mb/s
185    double mbpsRecvRate;                 // receiving rate in Mb/s
186    int64_t usSndDuration;		// busy sending time (i.e., idle time exclusive)
187 
188    // instant measurements
189    double usPktSndPeriod;               // packet sending period, in microseconds
190    int pktFlowWindow;                   // flow window size, in number of packets
191    int pktCongestionWindow;             // congestion window size, in number of packets
192    int pktFlightSize;                   // number of packets on flight
193    double msRTT;                        // RTT, in milliseconds
194    double mbpsBandwidth;                // estimated bandwidth, in Mb/s
195    int byteAvailSndBuf;                 // available UDT sender buffer size
196    int byteAvailRcvBuf;                 // available UDT receiver buffer size
197 };
198 
199 ////////////////////////////////////////////////////////////////////////////////
200 
201 class UDT_API CUDTException
202 {
203 public:
204    CUDTException(int major = 0, int minor = 0, int err = -1);
205    CUDTException(const CUDTException& e);
206    virtual ~CUDTException();
207 
208       // Functionality:
209       //    Get the description of the exception.
210       // Parameters:
211       //    None.
212       // Returned value:
213       //    Text message for the exception description.
214 
215    virtual const char* getErrorMessage();
216 
217       // Functionality:
218       //    Get the system errno for the exception.
219       // Parameters:
220       //    None.
221       // Returned value:
222       //    errno.
223 
224    virtual int getErrorCode() const;
225 
226       // Functionality:
227       //    Clear the error code.
228       // Parameters:
229       //    None.
230       // Returned value:
231       //    None.
232 
233    virtual void clear();
234 
235 private:
236    int m_iMajor;        // major exception categories
237 
238 // 0: correct condition
239 // 1: network setup exception
240 // 2: network connection broken
241 // 3: memory exception
242 // 4: file exception
243 // 5: method not supported
244 // 6+: undefined error
245 
246    int m_iMinor;		// for specific error reasons
247    int m_iErrno;		// errno returned by the system if there is any
248    std::string m_strMsg;	// text error message
249 
250    std::string m_strAPI;	// the name of UDT function that returns the error
251    std::string m_strDebug;	// debug information, set to the original place that causes the error
252 
253 public: // Error Code
254    static const int SUCCESS;
255    static const int ECONNSETUP;
256    static const int ENOSERVER;
257    static const int ECONNREJ;
258    static const int ESOCKFAIL;
259    static const int ESECFAIL;
260    static const int ECONNFAIL;
261    static const int ECONNLOST;
262    static const int ENOCONN;
263    static const int ERESOURCE;
264    static const int ETHREAD;
265    static const int ENOBUF;
266    static const int EFILE;
267    static const int EINVRDOFF;
268    static const int ERDPERM;
269    static const int EINVWROFF;
270    static const int EWRPERM;
271    static const int EINVOP;
272    static const int EBOUNDSOCK;
273    static const int ECONNSOCK;
274    static const int EINVPARAM;
275    static const int EINVSOCK;
276    static const int EUNBOUNDSOCK;
277    static const int ENOLISTEN;
278    static const int ERDVNOSERV;
279    static const int ERDVUNBOUND;
280    static const int ESTREAMILL;
281    static const int EDGRAMILL;
282    static const int EDUPLISTEN;
283    static const int ELARGEMSG;
284    static const int EINVPOLLID;
285    static const int EASYNCFAIL;
286    static const int EASYNCSND;
287    static const int EASYNCRCV;
288    static const int ETIMEOUT;
289    static const int EPEERERR;
290    static const int EUNKNOWN;
291 };
292 
293 ////////////////////////////////////////////////////////////////////////////////
294 
295 // If you need to export these APIs to be used by a different language,
296 // declare extern "C" for them, and add a "udt_" prefix to each API.
297 // The following APIs: sendfile(), recvfile(), epoll_wait(), geterrormsg(),
298 // include C++ specific feature, please use the corresponding sendfile2(), etc.
299 
300 namespace UDT
301 {
302 
303 typedef CUDTException ERRORINFO;
304 typedef UDTOpt SOCKOPT;
305 typedef CPerfMon TRACEINFO;
306 typedef ud_set UDSET;
307 
308 UDT_API extern const UDTSOCKET INVALID_SOCK;
309 #undef ERROR
310 UDT_API extern const int ERROR;
311 
312 UDT_API int startup();
313 UDT_API int cleanup();
314 UDT_API UDTSOCKET socket(int af, int type, int protocol);
315 UDT_API int bind(UDTSOCKET u, const struct sockaddr* name, int namelen);
316 UDT_API int bind2(UDTSOCKET u, UDPSOCKET udpsock);
317 UDT_API int listen(UDTSOCKET u, int backlog);
318 UDT_API UDTSOCKET accept(UDTSOCKET u, struct sockaddr* addr, int* addrlen);
319 UDT_API int connect(UDTSOCKET u, const struct sockaddr* name, int namelen);
320 UDT_API int close(UDTSOCKET u);
321 UDT_API int getpeername(UDTSOCKET u, struct sockaddr* name, int* namelen);
322 UDT_API int getsockname(UDTSOCKET u, struct sockaddr* name, int* namelen);
323 UDT_API int getsockopt(UDTSOCKET u, int level, SOCKOPT optname, void* optval, int* optlen);
324 UDT_API int setsockopt(UDTSOCKET u, int level, SOCKOPT optname, const void* optval, int optlen);
325 UDT_API int send(UDTSOCKET u, const char* buf, int len, int flags);
326 UDT_API int recv(UDTSOCKET u, char* buf, int len, int flags);
327 UDT_API int sendmsg(UDTSOCKET u, const char* buf, int len, int ttl = -1, bool inorder = false);
328 UDT_API int recvmsg(UDTSOCKET u, char* buf, int len);
329 UDT_API int64_t sendfile(UDTSOCKET u, std::fstream& ifs, int64_t& offset, int64_t size, int block = 364000);
330 UDT_API int64_t recvfile(UDTSOCKET u, std::fstream& ofs, int64_t& offset, int64_t size, int block = 7280000);
331 UDT_API int64_t sendfile2(UDTSOCKET u, const char* path, int64_t* offset, int64_t size, int block = 364000);
332 UDT_API int64_t recvfile2(UDTSOCKET u, const char* path, int64_t* offset, int64_t size, int block = 7280000);
333 
334 // select and selectEX are DEPRECATED; please use epoll.
335 UDT_API int select(int nfds, UDSET* readfds, UDSET* writefds, UDSET* exceptfds, const struct timeval* timeout);
336 UDT_API int selectEx(const std::vector<UDTSOCKET>& fds, std::vector<UDTSOCKET>* readfds,
337                      std::vector<UDTSOCKET>* writefds, std::vector<UDTSOCKET>* exceptfds, int64_t msTimeOut);
338 
339 UDT_API int epoll_create();
340 UDT_API int epoll_add_usock(int eid, UDTSOCKET u, const int* events = NULL);
341 UDT_API int epoll_add_ssock(int eid, SYSSOCKET s, const int* events = NULL);
342 UDT_API int epoll_remove_usock(int eid, UDTSOCKET u);
343 UDT_API int epoll_remove_ssock(int eid, SYSSOCKET s);
344 UDT_API int epoll_wait(int eid, std::set<UDTSOCKET>* readfds, std::set<UDTSOCKET>* writefds, int64_t msTimeOut,
345                        std::set<SYSSOCKET>* lrfds = NULL, std::set<SYSSOCKET>* wrfds = NULL);
346 UDT_API int epoll_wait2(int eid, UDTSOCKET* readfds, int* rnum, UDTSOCKET* writefds, int* wnum, int64_t msTimeOut,
347                         SYSSOCKET* lrfds = NULL, int* lrnum = NULL, SYSSOCKET* lwfds = NULL, int* lwnum = NULL);
348 UDT_API int epoll_release(int eid);
349 UDT_API ERRORINFO& getlasterror();
350 UDT_API int getlasterror_code();
351 UDT_API const char* getlasterror_desc();
352 UDT_API int perfmon(UDTSOCKET u, TRACEINFO* perf, bool clear = true);
353 UDT_API UDTSTATUS getsockstate(UDTSOCKET u);
354 
355 }  // namespace UDT
356 
357 #endif
358