1 /*
2  * Copyright (c) 2010-2013 BitTorrent, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 module upromised.c.utp;
24 
25 version(Posix) {
26 	import core.sys.posix.netdb : sockaddr, socklen_t;
27 } else version(Windows) {
28 	import core.sys.windows.winsock2 : sockaddr, socklen_t;
29 }
30 alias uint32 = uint;
31 alias uint64 = ulong;
32 alias uint16 = ushort;
33 alias ssize_t = size_t;
34 
35 extern (C) {
36 
37 struct utp_socket;
38 struct utp_context;
39 
40 enum {
41 	UTP_UDP_DONTFRAG = 2,	// Used to be a #define as UDP_IP_DONTFRAG
42 }
43 
44 enum {
45 	// socket has reveived syn-ack (notification only for outgoing connection completion)
46 	// this implies writability
47 	UTP_STATE_CONNECT = 1,
48 
49 	// socket is able to send more data
50 	UTP_STATE_WRITABLE = 2,
51 
52 	// connection closed
53 	UTP_STATE_EOF = 3,
54 
55 	// socket is being destroyed, meaning all data has been sent if possible.
56 	// it is not valid to refer to the socket after this state change occurs
57 	UTP_STATE_DESTROYING = 4,
58 }
59 
60 extern const(char)*[] utp_state_names;
61 
62 // Errors codes that can be passed to UTP_ON_ERROR callback
63 enum {
64 	UTP_ECONNREFUSED = 0,
65 	UTP_ECONNRESET,
66 	UTP_ETIMEDOUT,
67 }
68 
69 extern const(char)*[] utp_error_code_names;
70 
71 enum {
72 	// callback names
73 	UTP_ON_FIREWALL = 0,
74 	UTP_ON_ACCEPT,
75 	UTP_ON_CONNECT,
76 	UTP_ON_ERROR,
77 	UTP_ON_READ,
78 	UTP_ON_OVERHEAD_STATISTICS,
79 	UTP_ON_STATE_CHANGE,
80 	UTP_GET_READ_BUFFER_SIZE,
81 	UTP_ON_DELAY_SAMPLE,
82 	UTP_GET_UDP_MTU,
83 	UTP_GET_UDP_OVERHEAD,
84 	UTP_GET_MILLISECONDS,
85 	UTP_GET_MICROSECONDS,
86 	UTP_GET_RANDOM,
87 	UTP_LOG,
88 	UTP_SENDTO,
89 
90 	// context and socket options that may be set/queried
91     UTP_LOG_NORMAL,
92     UTP_LOG_MTU,
93     UTP_LOG_DEBUG,
94 	UTP_SNDBUF,
95 	UTP_RCVBUF,
96 	UTP_TARGET_DELAY,
97 
98 	UTP_ARRAY_SIZE,	// must be last
99 };
100 
101 extern const(char)*[] utp_callback_names;
102 
103 struct utp_callback_arguments {
104 	utp_context *context;
105 	utp_socket *socket;
106 	size_t len;
107 	uint32 flags;
108 	int callback_type;
109 	const(byte)* buf;
110 
111 	union {
112 		const(sockaddr)* address;
113 		int send;
114 		int sample_ms;
115 		int error_code;
116 		int state;
117 	}
118 
119 	union {
120 		socklen_t address_len;
121 		int type;
122 	}
123 }
124 
125 alias utp_callback_t = uint64 function(utp_callback_arguments*);
126 
127 // Returned by utp_get_context_stats()
128 struct utp_context_stats {
129 	uint32[5] _nraw_recv;	// total packets recieved less than 300/600/1200/MTU bytes fpr all connections (context-wide)
130 	uint32[5] _nraw_send;	// total packets sent     less than 300/600/1200/MTU bytes for all connections (context-wide)
131 }
132 
133 // Returned by utp_get_stats()
134 struct utp_socket_stats {
135 	uint64 nbytes_recv;	// total bytes received
136 	uint64 nbytes_xmit;	// total bytes transmitted
137 	uint32 rexmit;		// retransmit counter
138 	uint32 fastrexmit;	// fast retransmit counter
139 	uint32 nxmit;		// transmit counter
140 	uint32 nrecv;		// receive counter (total)
141 	uint32 nduprecv;	// duplicate receive counter
142 	uint32 mtu_guess;	// Best guess at MTU
143 };
144 
145 enum UTP_IOV_MAX = 1024;
146 
147 // For utp_writev, to writes data from multiple buffers
148 struct utp_iovec {
149 	void *iov_base;
150 	size_t iov_len;
151 }
152 
153 // Public Functions
154 utp_context*	utp_init						(int version_) nothrow;
155 void			utp_destroy						(utp_context *ctx) nothrow;
156 void			utp_set_callback				(utp_context *ctx, int callback_name, utp_callback_t proc) nothrow;
157 void*			utp_context_set_userdata		(utp_context *ctx, void *userdata) nothrow;
158 void*			utp_context_get_userdata		(utp_context *ctx) nothrow;
159 int				utp_context_set_option			(utp_context *ctx, int opt, int val) nothrow;
160 int				utp_context_get_option			(utp_context *ctx, int opt) nothrow;
161 int				utp_process_udp					(utp_context *ctx, const(byte)* buf, size_t len, const(sockaddr)* to, socklen_t tolen) nothrow;
162 int				utp_process_icmp_error			(utp_context *ctx, const(byte)* buffer, size_t len, const(sockaddr)* to, socklen_t tolen) nothrow;
163 int				utp_process_icmp_fragmentation	(utp_context *ctx, const(byte)* buffer, size_t len, const(sockaddr)* to, socklen_t tolen, uint16 next_hop_mtu) nothrow;
164 void			utp_check_timeouts				(utp_context *ctx) nothrow;
165 void			utp_issue_deferred_acks			(utp_context *ctx) nothrow;
166 utp_context_stats* utp_get_context_stats		(utp_context *ctx) nothrow;
167 utp_socket*		utp_create_socket				(utp_context *ctx) nothrow;
168 void*			utp_set_userdata				(utp_socket *s, void *userdata) nothrow;
169 void*			utp_get_userdata				(utp_socket *s) nothrow;
170 int				utp_setsockopt					(utp_socket *s, int opt, int val) nothrow;
171 int				utp_getsockopt					(utp_socket *s, int opt) nothrow;
172 int				utp_connect						(utp_socket *s, const(sockaddr) *to, socklen_t tolen) nothrow;
173 ssize_t			utp_write						(utp_socket *s, void *buf, size_t count) nothrow;
174 ssize_t			utp_writev						(utp_socket *s, utp_iovec *iovec, size_t num_iovecs) nothrow;
175 int				utp_getpeername					(utp_socket *s, sockaddr *addr, socklen_t *addrlen) nothrow;
176 void			utp_read_drained				(utp_socket *s) nothrow;
177 int				utp_get_delays					(utp_socket *s, uint32 *ours, uint32 *theirs, uint32 *age) nothrow;
178 utp_socket_stats* utp_get_stats					(utp_socket *s) nothrow;
179 utp_context*	utp_get_context					(utp_socket *s) nothrow;
180 void			utp_close						(utp_socket *s) nothrow;
181 
182 }