1/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2/* If you are missing that file, acquire a complete release at teeworlds.com. */
3
4#ifndef BASE_NET_H
5#define BASE_NET_H
6
7#include "types.h"
8
9#include <chrono>
10#include <cstddef>
11#include <string>
12
13#ifdef CONF_FAMILY_UNIX
14#include <sys/un.h> // sockaddr_un
15#endif
16
17/**
18 * @defgroup Network Networking
19 */
20
21/**
22 * @defgroup Network-General General
23 *
24 * @ingroup Network
25 */
26
27/**
28 * @defgroup Network-Address Addresses
29 *
30 * @ingroup Network
31 */
32
33/**
34 * @ingroup Network-Address
35 */
36extern const NETADDR NETADDR_ZEROED;
37
38#ifdef CONF_FAMILY_UNIX
39/**
40 * @ingroup Network-Unix-Sockets
41 */
42typedef int UNIXSOCKET;
43
44/**
45 * @ingroup Network-Unix-Sockets
46 */
47typedef struct sockaddr_un UNIXSOCKETADDR;
48#endif
49
50/**
51 * Compares two network addresses.
52 *
53 * @ingroup Network-Address
54 *
55 * @param a Address to compare.
56 * @param b Address to compare to.
57 *
58 * @return `< 0` if address a is less than address b.
59 * @return `0` if address a is equal to address b.
60 * @return `> 0` if address a is greater than address b.
61 */
62int net_addr_comp(const NETADDR *a, const NETADDR *b);
63
64/**
65 * Compares two network addresses ignoring port.
66 *
67 * @ingroup Network-Address
68 *
69 * @param a Address to compare.
70 * @param b Address to compare to.
71 *
72 * @return `< 0` if address a is less than address b.
73 * @return `0` if address a is equal to address b.
74 * @return `> 0` if address a is greater than address b.
75 */
76int net_addr_comp_noport(const NETADDR *a, const NETADDR *b);
77
78/**
79 * Turns a network address into a representative string.
80 *
81 * @ingroup Network-Address
82 *
83 * @param addr Address to turn into a string.
84 * @param string Buffer to fill with the string.
85 * @param max_length Maximum size of the string.
86 * @param add_port Whether to add the port to the string.
87 *
88 * @remark The string will always be null-terminated.
89 */
90void net_addr_str(const NETADDR *addr, char *string, int max_length, bool add_port);
91
92/**
93 * Turns url string into a network address struct.
94 * The url format is tw-0.6+udp://{ipaddr}[:{port}]
95 * ipaddr: can be ipv4 or ipv6
96 * port: is a optional internet protocol port
97 *
98 * This format is used for parsing the master server, be careful before changing it.
99 *
100 * Examples:
101 * tw-0.6+udp://127.0.0.1
102 * tw-0.6+udp://127.0.0.1:8303
103 *
104 * @ingroup Network-Address
105 *
106 * @param addr Address to fill in.
107 * @param string String to parse.
108 * @param host_buf Pointer to a buffer to write the host to.
109 * It will include the port if one is included in the URL.
110 * It can also be set to `nullptr` then it will be ignored.
111 * @param host_buf_size Size of the host buffer or 0 if no host_buf pointer is given.
112 *
113 * @return `0` on success.
114 * @return `> 0` if the input wasn't a valid DDNet URL,
115 * @return `< 0` if the input is a valid DDNet URL but the host part was not a valid IPv4/IPv6 address
116 */
117int net_addr_from_url(NETADDR *addr, const char *string, char *host_buf, size_t host_buf_size);
118
119/**
120 * Checks if an address is local.
121 *
122 * @ingroup Network-Address
123 *
124 * @param addr Address to check.
125 *
126 * @return `true` if the address is local, `false` otherwise.
127 */
128bool net_addr_is_local(const NETADDR *addr);
129
130/**
131 * Turns string into a network address.
132 *
133 * @ingroup Network-Address
134 *
135 * @param addr Address to fill in.
136 * @param string String to parse.
137 *
138 * @return `0` on success.
139 */
140int net_addr_from_str(NETADDR *addr, const char *string);
141
142/**
143 * Looks up the IP of a hostname.
144 *
145 * @ingroup Network-Address
146 *
147 * @param hostname Host name to look up.
148 * @param addr The output address to write to.
149 * @param types The type of IP that should be returned.
150 *
151 * @return `0` on success.
152 */
153int net_host_lookup(const char *hostname, NETADDR *addr, int types);
154
155/**
156 * Initializes network functionality.
157 *
158 * @ingroup Network-General
159 *
160 * @remark You must call this function before using any other network functions.
161 */
162void net_init();
163
164/**
165 * If a network operation failed, the error code.
166 *
167 * @ingroup Network-General
168 *
169 * @returns The error code.
170 */
171int net_errno();
172
173/**
174 * If a network operation failed, the platform-specific error code and string.
175 *
176 * @ingroup Network-General
177 *
178 * @returns The error code and string combined into one string.
179 */
180std::string net_error_message();
181
182/**
183 * Retrieve network statistics.
184 *
185 * @ingroup Network-General
186 *
187 * @param stats Network statistics to fill in.
188 */
189void net_stats(NETSTATS *stats);
190
191/**
192 * Determine a socket's type.
193 *
194 * @ingroup Network-General
195 *
196 * @param sock Socket whose type should be determined.
197 *
198 * @return The socket type, a bitset of `NETTYPE_IPV4`, `NETTYPE_IPV6`, `NETTYPE_WEBSOCKET_IPV4`
199 * and `NETTYPE_WEBSOCKET_IPV6`, or `NETTYPE_INVALID` if the socket is invalid.
200 */
201int net_socket_type(NETSOCKET sock);
202
203/**
204 * Make a socket not block on operations.
205 *
206 * @ingroup Network-General
207 *
208 * @param sock The socket to set non-blocking mode on.
209 *
210 * @returns `0` on success.
211 */
212int net_set_non_blocking(NETSOCKET sock);
213
214/**
215 * Make a socket block on operations.
216 *
217 * @ingroup Network-General
218 *
219 * @param sock The socket to set blocking mode on.
220 *
221 * @returns `0` on success.
222 */
223int net_set_blocking(NETSOCKET sock);
224
225/**
226 * Determines whether a network operation would block.
227 *
228 * @ingroup Network-General
229 *
230 * @returns `0` if wouldn't block, `1` if would block.
231 */
232int net_would_block();
233
234/**
235 * Waits for a socket to have data available to receive up the specified timeout duration.
236 *
237 * @ingroup Network-General
238 *
239 * @param sock Socket to wait on.
240 * @param nanoseconds Timeout duration to wait.
241 *
242 * @return `1` if data was received within the timeout duration, `0` otherwise.
243 */
244int net_socket_read_wait(NETSOCKET sock, std::chrono::nanoseconds nanoseconds);
245
246/**
247 * @defgroup Network-UDP UDP
248 *
249 * @ingroup Network
250 */
251
252/**
253 * Creates a UDP socket and binds it to a port.
254 *
255 * @ingroup Network-UDP
256 *
257 * @param bindaddr Address to bind the socket to.
258 *
259 * @return On success it returns an handle to the socket. On failure it returns `nullptr`.
260 */
261NETSOCKET net_udp_create(NETADDR bindaddr);
262
263/**
264 * Sends a packet over an UDP socket.
265 *
266 * @ingroup Network-UDP
267 *
268 * @param sock Socket to use.
269 * @param addr Where to send the packet.
270 * @param data Pointer to the packet data to send.
271 * @param size Size of the packet.
272 *
273 * @return On success it returns the number of bytes sent. Returns `-1` on error.
274 */
275int net_udp_send(NETSOCKET sock, const NETADDR *addr, const void *data, int size);
276
277/**
278 * Receives a packet over an UDP socket.
279 *
280 * @ingroup Network-UDP
281 *
282 * @param sock Socket to use.
283 * @param addr Pointer to an NETADDR that will receive the address.
284 * @param data Received data. Will be invalidated when this function is called again.
285 *
286 * @return On success it returns the number of bytes received. Returns `-1` on error.
287 */
288int net_udp_recv(NETSOCKET sock, NETADDR *addr, unsigned char **data);
289
290/**
291 * Closes an UDP socket.
292 *
293 * @ingroup Network-UDP
294 *
295 * @param sock Socket to close.
296 */
297void net_udp_close(NETSOCKET sock);
298
299/**
300 * @defgroup Network-TCP TCP
301 *
302 * @ingroup Network
303 */
304
305/**
306 * Creates a TCP socket.
307 *
308 * @ingroup Network-TCP
309 *
310 * @param bindaddr Address to bind the socket to.
311 *
312 * @return On success it returns an handle to the socket. On failure it returns `nullptr`.
313 */
314NETSOCKET net_tcp_create(NETADDR bindaddr);
315
316/**
317 * Makes the socket start listening for new connections.
318 *
319 * @ingroup Network-TCP
320 *
321 * @param sock Socket to start listen to.
322 * @param backlog Size of the queue of incoming connections to keep.
323 *
324 * @return `0` on success.
325 */
326int net_tcp_listen(NETSOCKET sock, int backlog);
327
328/**
329 * Polls a listening socket for a new connection.
330 *
331 * @ingroup Network-TCP
332 *
333 * @param sock Listening socket to poll.
334 * @param new_sock Pointer to a socket to fill in with the new socket.
335 * @param addr Pointer to an address that will be filled in the remote address, can be `nullptr`.
336 *
337 * @return A non-negative integer on success. Negative integer on failure.
338 */
339int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *addr);
340
341/**
342 * Connects one socket to another.
343 *
344 * @ingroup Network-TCP
345 *
346 * @param sock Socket to connect.
347 * @param addr Address to connect to.
348 *
349 * @return `0` on success.
350 *
351 */
352int net_tcp_connect(NETSOCKET sock, const NETADDR *addr);
353
354/**
355 * Connect a socket to a TCP address without blocking.
356 *
357 * @ingroup Network-TCP
358 *
359 * @param sock The socket to connect with.
360 * @param bindaddr The address to connect to.
361 *
362 * @returns `0` on success.
363 */
364int net_tcp_connect_non_blocking(NETSOCKET sock, NETADDR bindaddr);
365
366/**
367 * Sends data to a TCP stream.
368 *
369 * @ingroup Network-TCP
370 *
371 * @param sock Socket to send data to.
372 * @param data Pointer to the data to send.
373 * @param size Size of the data to send.
374 *
375 * @return Number of bytes sent. Negative value on failure.
376 */
377int net_tcp_send(NETSOCKET sock, const void *data, int size);
378
379/**
380 * Receives data from a TCP stream.
381 *
382 * @ingroup Network-TCP
383 *
384 * @param sock Socket to recvive data from.
385 * @param data Pointer to a buffer to write the data to.
386 * @param maxsize Maximum of data to write to the buffer.
387 *
388 * @return Number of bytes recvived. Negative value on failure. When in
389 * non-blocking mode, it returns 0 when there is no more data to be fetched.
390 */
391int net_tcp_recv(NETSOCKET sock, void *data, int maxsize);
392
393/**
394 * Closes a TCP socket.
395 *
396 * @ingroup Network-TCP
397 *
398 * @param sock Socket to close.
399 */
400void net_tcp_close(NETSOCKET sock);
401
402#if defined(CONF_FAMILY_UNIX)
403/**
404 * @defgroup Network-Unix-Sockets UNIX Sockets
405 *
406 * @ingroup Network
407 */
408
409/**
410 * Creates an unnamed unix datagram socket.
411 *
412 * @ingroup Network-Unix-Sockets
413 *
414 * @return On success it returns a handle to the socket. On failure it returns `-1`.
415 */
416UNIXSOCKET net_unix_create_unnamed();
417
418/**
419 * Sends data to a Unix socket.
420 *
421 * @ingroup Network-Unix-Sockets
422 *
423 * @param sock Socket to use.
424 * @param addr Where to send the packet.
425 * @param data Pointer to the packet data to send.
426 * @param size Size of the packet.
427 *
428 * @return Number of bytes sent. Negative value on failure.
429 */
430int net_unix_send(UNIXSOCKET sock, UNIXSOCKETADDR *addr, void *data, int size);
431
432/**
433 * Sets the unixsocketaddress for a path to a socket file.
434 *
435 * @ingroup Network-Unix-Sockets
436 *
437 * @param addr Pointer to the `UNIXSOCKETADDR` to fill.
438 * @param path Path to the (named) unix socket.
439 */
440void net_unix_set_addr(UNIXSOCKETADDR *addr, const char *path);
441
442/**
443 * Closes a Unix socket.
444 *
445 * @ingroup Network-Unix-Sockets
446 *
447 * @param sock Socket to close.
448 */
449void net_unix_close(UNIXSOCKET sock);
450#endif
451
452#endif
453