summaryrefslogtreecommitdiff
path: root/libs/raylib/src/rnet.h
blob: ef4b90bd17e946613ce4743d19f34682878bc5e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
/**********************************************************************************************
*
*   rnet - Provides cross-platform network defines, macros etc
*
*   DEPENDENCIES:
*       <limits.h>    - Used for cross-platform type specifiers
*
*   INSPIRED BY:
*       SFML Sockets - https://www.sfml-dev.org/documentation/2.5.1/classsf_1_1Socket.php
*       SDL_net - https://www.libsdl.org/projects/SDL_net/
*       BSD Sockets - https://www.gnu.org/software/libc/manual/html_node/Sockets.html
*       BEEJ - https://beej.us/guide/bgnet/html/single/bgnet.html
*       Winsock2 - https://docs.microsoft.com/en-us/windows/desktop/api/winsock2
*
*
*   CONTRIBUTORS:
*       Jak Barnes (github: @syphonx) (Feb. 2019) - Initial version
*
*
*   LICENSE: zlib/libpng
*
*   Copyright (c) 2019 Jak Barnes (github: @syphonx) and Ramon Santamaria (@raysan5)
*
*   This software is provided "as-is", without any express or implied warranty. In no event
*   will the authors be held liable for any damages arising from the use of this software.
*
*   Permission is granted to anyone to use this software for any purpose, including commercial
*   applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
*     1. The origin of this software must not be misrepresented; you must not claim that you
*     wrote the original software. If you use this software in a product, an acknowledgment
*     in the product documentation would be appreciated but is not required.
*
*     2. Altered source versions must be plainly marked as such, and must not be misrepresented
*     as being the original software.
*
*     3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/

#ifndef RNET_H
#define RNET_H

#include <limits.h>         // Required for limits
#include <inttypes.h>       // Required for platform type sizes

//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------

// Undefine any conflicting windows.h symbols
// If defined, the following flags inhibit definition of the indicated items.
#define NOGDICAPMASKS     // CC_*, LC_*, PC_*, CP_*, TC_*, RC_
#define NOVIRTUALKEYCODES // VK_*
#define NOWINMESSAGES     // WM_*, EM_*, LB_*, CB_*
#define NOWINSTYLES       // WS_*, CS_*, ES_*, LBS_*, SBS_*, CBS_*
#define NOSYSMETRICS      // SM_*
#define NOMENUS           // MF_*
#define NOICONS           // IDI_*
#define NOKEYSTATES       // MK_*
#define NOSYSCOMMANDS     // SC_*
#define NORASTEROPS       // Binary and Tertiary raster ops
#define NOSHOWWINDOW      // SW_*
#define OEMRESOURCE       // OEM Resource values
#define NOATOM            // Atom Manager routines
#define NOCLIPBOARD       // Clipboard routines
#define NOCOLOR           // Screen colors
#define NOCTLMGR          // Control and Dialog routines
#define NODRAWTEXT        // DrawText() and DT_*
#define NOGDI             // All GDI defines and routines
#define NOKERNEL          // All KERNEL defines and routines
#define NOUSER            // All USER defines and routines
#define NONLS             // All NLS defines and routines
#define NOMB              // MB_* and MessageBox()
#define NOMEMMGR          // GMEM_*, LMEM_*, GHND, LHND, associated routines
#define NOMETAFILE        // typedef METAFILEPICT
#define NOMINMAX          // Macros min(a,b) and max(a,b)
#define NOMSG             // typedef MSG and associated routines
#define NOOPENFILE        // OpenFile(), OemToAnsi, AnsiToOem, and OF_*
#define NOSCROLL          // SB_* and scrolling routines
#define NOSERVICE          // All Service Controller routines, SERVICE_ equates, etc.
#define NOSOUND              // Sound driver routines
#define NOTEXTMETRIC      // typedef TEXTMETRIC and associated routines
#define NOWH              // SetWindowsHook and WH_*
#define NOWINOFFSETS      // GWL_*, GCL_*, associated routines
#define NOCOMM              // COMM driver routines
#define NOKANJI              // Kanji support stuff.
#define NOHELP              // Help engine interface.
#define NOPROFILER          // Profiler interface.
#define NODEFERWINDOWPOS  // DeferWindowPos routines
#define NOMCX             // Modem Configuration Extensions
#define MMNOSOUND

// Allow custom memory allocators
#ifndef RNET_MALLOC
    #define RNET_MALLOC(sz)       malloc(sz)
#endif
#ifndef RNET_CALLOC
    #define RNET_CALLOC(n,sz)     calloc(n,sz)
#endif
#ifndef RNET_FREE
    #define RNET_FREE(p)          free(p)
#endif

//----------------------------------------------------------------------------------
// Platform type definitions
// From: https://github.com/DFHack/clsocket/blob/master/src/Host.h
//----------------------------------------------------------------------------------

#ifdef WIN32
typedef int socklen_t;
#endif

#ifndef RESULT_SUCCESS
#    define RESULT_SUCCESS 0
#endif // RESULT_SUCCESS

#ifndef RESULT_FAILURE
#    define RESULT_FAILURE 1
#endif // RESULT_FAILURE

#ifndef htonll
#    ifdef _BIG_ENDIAN
#        define htonll(x) (x)
#        define ntohll(x) (x)
#    else
#        define htonll(x) ((((uint64) htonl(x)) << 32) + htonl(x >> 32))
#        define ntohll(x) ((((uint64) ntohl(x)) << 32) + ntohl(x >> 32))
#    endif // _BIG_ENDIAN
#endif     // htonll

//----------------------------------------------------------------------------------
// Platform specific network includes
// From: https://github.com/SDL-mirror/SDL_net/blob/master/SDLnetsys.h
//----------------------------------------------------------------------------------

// Include system network headers
#if defined(_WIN32)
    #define __USE_W32_SOCKETS
    #define WIN32_LEAN_AND_MEAN
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <io.h>
    #define IPTOS_LOWDELAY 0x10
#else   // Unix
    #include <sys/types.h>
    #include <fcntl.h>
    #include <netinet/in.h>
    #include <sys/ioctl.h>
    #include <sys/time.h>
    #include <unistd.h>
    #include <net/if.h>
    #include <netdb.h>
    #include <netinet/tcp.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
#endif

#ifndef INVALID_SOCKET
    #define INVALID_SOCKET ~(0)
#endif

#ifndef __USE_W32_SOCKETS
    #define closesocket close
    #define SOCKET int
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
#endif

#ifdef __USE_W32_SOCKETS
    #ifndef EINTR
        #define EINTR WSAEINTR
    #endif
#endif

//----------------------------------------------------------------------------------
// Module defines
//----------------------------------------------------------------------------------

// Network connection related defines
#define SOCKET_MAX_SET_SIZE                     (32)   // Maximum sockets in a set
#define SOCKET_MAX_QUEUE_SIZE                   (16)   // Maximum socket queue size
#define SOCKET_MAX_SOCK_OPTS (4)        // Maximum socket options
#define SOCKET_MAX_UDPCHANNELS (32)        // Maximum UDP channels
#define SOCKET_MAX_UDPADDRESSES (4)        // Maximum bound UDP addresses


// Network address related defines
#define ADDRESS_IPV4_ADDRSTRLEN                 (22)   // IPv4 string length
#define ADDRESS_IPV6_ADDRSTRLEN                 (65)   // IPv6 string length
#define ADDRESS_TYPE_ANY                        (0)    // AF_UNSPEC
#define ADDRESS_TYPE_IPV4                       (2)    // AF_INET
#define ADDRESS_TYPE_IPV6                       (23)   // AF_INET6
#define ADDRESS_MAXHOST                         (1025) // Max size of a fully-qualified domain name
#define ADDRESS_MAXSERV                         (32)   // Max size of a service name

// Network address related defines
#define ADDRESS_ANY                             ((unsigned long) 0x00000000)
#define ADDRESS_LOOPBACK                        (0x7f000001)
#define ADDRESS_BROADCAST                       ((unsigned long) 0xffffffff)
#define ADDRESS_NONE                            (0xffffffff)

// Address resolution related defines
#if defined(_WIN32)
    #define ADDRESS_INFO_PASSIVE                (0x00000001)  // Socket address will be used in bind() call
    #define ADDRESS_INFO_CANONNAME              (0x00000002)  // Return canonical name in first ai_canonname
    #define ADDRESS_INFO_NUMERICHOST            (0x00000004)  // Nodename must be a numeric address string
    #define ADDRESS_INFO_NUMERICSERV            (0x00000008)  // Servicename must be a numeric port number
    #define ADDRESS_INFO_DNS_ONLY               (0x00000010)  // Restrict queries to unicast DNS only (no LLMNR, netbios, etc.)
    #define ADDRESS_INFO_ALL                    (0x00000100)  // Query both IP6 and IP4 with AI_V4MAPPED
    #define ADDRESS_INFO_ADDRCONFIG             (0x00000400)  // Resolution only if global address configured
    #define ADDRESS_INFO_V4MAPPED               (0x00000800)  // On v6 failure, query v4 and convert to V4MAPPED format
    #define ADDRESS_INFO_NON_AUTHORITATIVE      (0x00004000)  // LUP_NON_AUTHORITATIVE
    #define ADDRESS_INFO_SECURE                 (0x00008000)  // LUP_SECURE
    #define ADDRESS_INFO_RETURN_PREFERRED_NAMES (0x00010000)  // LUP_RETURN_PREFERRED_NAMES
    #define ADDRESS_INFO_FQDN                   (0x00020000)  // Return the FQDN in ai_canonname
    #define ADDRESS_INFO_FILESERVER             (0x00040000)  // Resolving fileserver name resolution
    #define ADDRESS_INFO_DISABLE_IDN_ENCODING   (0x00080000)  // Disable Internationalized Domain Names handling
    #define ADDRESS_INFO_EXTENDED               (0x80000000)  // Indicates this is extended ADDRINFOEX(2/..) struct
    #define ADDRESS_INFO_RESOLUTION_HANDLE      (0x40000000)  // Request resolution handle
#endif

// Network resolution related defines
#define NAME_INFO_DEFAULT                       (0x00) // No flags set
#define NAME_INFO_NOFQDN                        (0x01) // Only return nodename portion for local hosts
#define NAME_INFO_NUMERICHOST                   (0x02) // Return numeric form of the host's address
#define NAME_INFO_NAMEREQD                      (0x04) // Error if the host's name not in DNS
#define NAME_INFO_NUMERICSERV                   (0x08) // Return numeric form of the service (port #)
#define NAME_INFO_DGRAM                         (0x10) // Service is a datagram service

//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------

// Boolean type
#if defined(__STDC__) && __STDC_VERSION__ >= 199901L
    #include <stdbool.h>
#elif !defined(__cplusplus) && !defined(bool)
    typedef enum { false, true } bool;
#endif

// Network typedefs
typedef uint32_t SocketChannel;
typedef struct _AddressInformation *AddressInformation;
typedef struct _SocketAddress *SocketAddress;
typedef struct _SocketAddressIPv4 *SocketAddressIPv4;
typedef struct _SocketAddressIPv6 *SocketAddressIPv6;
typedef struct _SocketAddressStorage *SocketAddressStorage;

// IPAddress definition (in network byte order)
typedef struct IPAddress {
    unsigned long  host; /* 32-bit IPv4 host address */
    unsigned short port; /* 16-bit protocol port */
} IPAddress;

// An option ID, value, sizeof(value) tuple for setsockopt(2).
typedef struct SocketOpt {
    int id;
    void *value;
    int valueLen;
} SocketOpt;

typedef enum {
    SOCKET_TCP = 0, // SOCK_STREAM
    SOCKET_UDP = 1  // SOCK_DGRAM
} SocketType;

typedef struct UDPChannel {
    int numbound; // The total number of addresses this channel is bound to
    IPAddress address[SOCKET_MAX_UDPADDRESSES]; // The list of remote addresses this channel is bound to
} UDPChannel;

typedef struct Socket {
    int  ready;    // Is the socket ready? i.e. has information
    int  status;   // The last status code to have occured using this socket
    bool isServer; // Is this socket a server socket (i.e. TCP/UDP Listen Server)
    SocketChannel channel; // The socket handle id
    SocketType    type;    // Is this socket a TCP or UDP socket?
    bool          isIPv6;  // Is this socket address an ipv6 address?
    SocketAddressIPv4 addripv4; // The host/target IPv4 for this socket (in network byte order)
    SocketAddressIPv6 addripv6; // The host/target IPv6 for this socket (in network byte order)

    struct UDPChannel binding[SOCKET_MAX_UDPCHANNELS]; // The amount of channels (if UDP) this socket is bound to
} Socket;

typedef struct SocketSet {
    int numsockets;
    int maxsockets;
    struct Socket **sockets;
} SocketSet;

typedef struct SocketDataPacket {
    int            channel; // The src/dst channel of the packet
    unsigned char *data;    // The packet data
    int            len;     // The length of the packet data
    int            maxlen;  // The size of the data buffer
    int            status;  // packet status after sending
    IPAddress address; // The source/dest address of an incoming/outgoing packet
} SocketDataPacket;

// Configuration for a socket.
typedef struct SocketConfig {
    char *     host;   // The host address in xxx.xxx.xxx.xxx form
    char *     port;   // The target port/service in the form "http" or "25565"
    bool       server; // Listen for incoming clients?
    SocketType type;   // The type of socket, TCP/UDP
    bool       nonblocking;  // non-blocking operation?
    int        backlog_size; // set a custom backlog size
    SocketOpt  sockopts[SOCKET_MAX_SOCK_OPTS];
} SocketConfig;

// Result from calling open with a given config.
typedef struct SocketResult {
    int status;
    Socket *socket;
} SocketResult;

// Packet type
typedef struct Packet {
    uint32_t size; // The total size of bytes in data
    uint32_t offs; // The offset to data access
    uint32_t maxs; // The max size of data
    uint8_t *data; // Data stored in network byte order
} Packet;


#ifdef __cplusplus
extern "C" {            // Prevents name mangling of functions
#endif

//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
//...

//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------

// Initialisation and cleanup
bool InitNetwork(void);
void CloseNetwork(void);

// Address API
void ResolveIP(const char *ip, const char *service, int flags, char *outhost, char *outserv);
int ResolveHost(const char *address, const char *service, int addressType, int flags, AddressInformation *outAddr);
int GetAddressFamily(AddressInformation address);
int GetAddressSocketType(AddressInformation address);
int GetAddressProtocol(AddressInformation address);
char* GetAddressCanonName(AddressInformation address);
char* GetAddressHostAndPort(AddressInformation address, char *outhost, int *outport);
void PrintAddressInfo(AddressInformation address);

// Address Memory API
AddressInformation AllocAddress();
void FreeAddress(AddressInformation *addressInfo);
AddressInformation *AllocAddressList(int size);

// Socket API
bool SocketCreate(SocketConfig *config, SocketResult *result);
bool SocketBind(SocketConfig *config, SocketResult *result);
bool SocketListen(SocketConfig *config, SocketResult *result);
bool SocketConnect(SocketConfig *config, SocketResult *result);
Socket *SocketAccept(Socket *server, SocketConfig *config);

// UDP Socket API
int SocketSetChannel(Socket *socket, int channel, const IPAddress *address);
void SocketUnsetChannel(Socket *socket, int channel);

// UDP DataPacket API
SocketDataPacket *AllocPacket(int size);
int ResizePacket(SocketDataPacket *packet, int newsize);
void FreePacket(SocketDataPacket *packet);
SocketDataPacket **AllocPacketList(int count, int size);
void FreePacketList(SocketDataPacket **packets);

// General Socket API
int SocketSend(Socket *sock, const void *datap, int len);
int SocketReceive(Socket *sock, void *data, int maxlen);
void SocketClose(Socket *sock);
SocketAddressStorage SocketGetPeerAddress(Socket *sock);
char* GetSocketAddressHost(SocketAddressStorage storage);
short GetSocketAddressPort(SocketAddressStorage storage);

// Socket Memory API
Socket *AllocSocket();
void FreeSocket(Socket **sock);
SocketResult *AllocSocketResult();
void FreeSocketResult(SocketResult **result);
SocketSet *AllocSocketSet(int max);
void FreeSocketSet(SocketSet *sockset);

// Socket I/O API
bool IsSocketReady(Socket *sock);
bool IsSocketConnected(Socket *sock);
int AddSocket(SocketSet *set, Socket *sock);
int RemoveSocket(SocketSet *set, Socket *sock);
int CheckSockets(SocketSet *set, unsigned int timeout);

// Packet API
void PacketSend(Packet *packet);
void PacketReceive(Packet *packet);
void PacketWrite8(Packet *packet, uint16_t value);
void PacketWrite16(Packet *packet, uint16_t value);
void PacketWrite32(Packet *packet, uint32_t value);
void PacketWrite64(Packet *packet, uint64_t value);
uint16_t PacketRead8(Packet *packet);
uint16_t PacketRead16(Packet *packet);
uint32_t PacketRead32(Packet *packet);
uint64_t PacketRead64(Packet *packet);

#ifdef __cplusplus
}
#endif

#endif  // RNET_H