-
Notifications
You must be signed in to change notification settings - Fork 1
/
javelin.h
178 lines (156 loc) · 5.51 KB
/
javelin.h
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
#ifndef JAVELIN_H
#define JAVELIN_H
#ifndef JAVELIN_MAX_MESSAGE_SIZE
#define JAVELIN_MAX_MESSAGE_SIZE 128
#endif
#ifndef JAVELIN_MAX_MESSAGES
#define JAVELIN_MAX_MESSAGES 4096
#endif
#ifndef JAVELIN_MAX_PACKET_SIZE
#define JAVELIN_MAX_PACKET_SIZE 1400
#endif
#ifndef JAVELIN_MAX_PENDING_CONNECTIONS
#define JAVELIN_MAX_PENDING_CONNECTIONS 128
#endif
#ifndef JAVELIN_CONNECTION_TIMEOUT_MS
#define JAVELIN_CONNECTION_TIMEOUT_MS 5000
#endif
#define JAVELIN_DEFAULT_RETRY_TIME_MS 100
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#ifdef _WIN32
#include <winsock2.h>
#else
#include <sys/socket.h>
#endif
typedef uint8_t javelin_u8;
typedef uint16_t javelin_u16;
typedef int16_t javelin_s16;
typedef uint32_t javelin_u32;
typedef int32_t javelin_s32;
typedef uint64_t javelin_u64;
typedef int64_t javelin_s64;
enum JavelinError {
JAVELIN_ERROR_OK = 0,
JAVELIN_ERROR_WINSOCK,
JAVELIN_ERROR_MEMORY,
JAVELIN_ERROR_SOCKET,
JAVELIN_ERROR_GETADDRINFO,
JAVELIN_ERROR_INVALID_ADDRESS,
JAVELIN_ERROR_CONNECTION_LIMIT,
JAVELIN_ERROR_INVALID_MESSAGE,
JAVELIN_ERROR_MESSAGE_FULL,
JAVELIN_ERROR_MESSAGE_BUFFER_FULL,
JAVELIN_ERROR_CHAR_ARRAY_TOO_LONG,
JAVELIN_ERROR_RANDOM_GENERATOR_REQUIRED,
};
enum JavelinConnectionStateType {
JAVELIN_CONNECTIONSTATE_NONE = 0,
JAVELIN_CONNECTIONSTATE_CONNECTING,
JAVELIN_CONNECTIONSTATE_CONNECTED,
JAVELIN_CONNECTIONSTATE_DISCONNECTING,
JAVELIN_CONNECTIONSTATE_DISCONNECTED,
};
enum JavelinPacketType {
JAVELIN_PACKET_UNKNOWN = 0,
JAVELIN_PACKET_CONNECT_REQUEST,
JAVELIN_PACKET_CONNECT_CHALLENGE,
JAVELIN_PACKET_CONNECT_CHALLENGE_RESPONSE,
JAVELIN_PACKET_CONNECT_ACCEPT,
JAVELIN_PACKET_CONNECT_REJECT,
JAVELIN_PACKET_DISCONNECT,
JAVELIN_PACKET_PING,
JAVELIN_PACKET_DATA,
JAVELIN_PACKET_SERVER_FULL,
};
struct JavelinPacketHeader {
// TODO: header, crc, salt, etc.
enum JavelinPacketType type;
javelin_u32 ackMessageId;
javelin_u32 salt;
};
struct JavelinMessageBlock {
javelin_u32 messageId;
javelin_u64 outgoingLastSendTime;
size_t incomingReadOffset;
size_t size;
javelin_u8 payload[JAVELIN_MAX_MESSAGE_SIZE];
};
struct JavelinConnection {
bool isActive;
size_t slot;
size_t userValue;
struct sockaddr_storage address;
enum JavelinConnectionStateType connectionState;
javelin_u32 localSalt;
javelin_u32 remoteSalt;
javelin_u64 lastSendTime;
javelin_u64 lastReceiveTime;
javelin_u32 retryTime;
struct JavelinMessageBlock incomingMessageBuffer[JAVELIN_MAX_MESSAGES];
javelin_u16 incomingLastIdProcessed;
struct JavelinMessageBlock outgoingMessageBuffer[JAVELIN_MAX_MESSAGES];
javelin_u16 outgoingLastIdSent;
javelin_u16 outgoingLastIdAcknowledged;
};
struct JavelinPendingConnection {
struct sockaddr_storage address;
enum JavelinConnectionStateType connectionState;
javelin_u32 localSalt;
javelin_u32 remoteSalt;
javelin_u64 lastSendTime;
javelin_u64 lastReceiveTime;
};
struct JavelinState {
javelin_u32 (*randomGenerator)( void );
struct JavelinConnection* connectionSlots;
javelin_u32 connectionLimit;
struct JavelinPendingConnection pendingConnectionSlots[JAVELIN_MAX_PENDING_CONNECTIONS];
javelin_u32 pendingConnectionCount;
javelin_u32 incomingLastPacketSlot;
javelin_u8 outgoingPacketBuffer[JAVELIN_MAX_PACKET_SIZE];
size_t outgoingPacketSize;
int socket;
struct sockaddr_storage address;
};
enum JavelinEventType {
JAVELIN_EVENT_DATA = 0,
JAVELIN_EVENT_CONNECT,
JAVELIN_EVENT_DISCONNECT,
};
struct JavelinEvent {
struct JavelinConnection* connection;
enum JavelinEventType type;
struct JavelinMessageBlock* message;
};
enum JavelinError javelinCreate( struct JavelinState* state, const char* address, const javelin_u16 port, const javelin_u32 maxConnections, javelin_u32 (*randomGenerator)( void ) );
void javelinDestroy( struct JavelinState* state );
enum JavelinError javelinConnect( struct JavelinState* state, const char* address, const javelin_u16 port );
void javelinDisconnect( struct JavelinState* state );
bool javelinProcess( struct JavelinState* state, struct JavelinEvent* outEvent );
struct JavelinMessageBlock javelinCreateMessage( void );
enum JavelinError javelinQueueMessage( struct JavelinConnection* connection, struct JavelinMessageBlock* block );
enum JavelinError javelinWriteCharArray( struct JavelinMessageBlock* block, const char* values, const size_t length );
enum JavelinError javelinWriteU8( struct JavelinMessageBlock* block, const javelin_u8 value );
enum JavelinError javelinWriteU16( struct JavelinMessageBlock* block, const javelin_u16 value );
enum JavelinError javelinWriteS16( struct JavelinMessageBlock* block, const javelin_s16 value );
enum JavelinError javelinWriteU32( struct JavelinMessageBlock* block, const javelin_u32 value );
enum JavelinError javelinWriteS32( struct JavelinMessageBlock* block, const javelin_s32 value );
enum JavelinError javelinWriteU64( struct JavelinMessageBlock* block, const javelin_u64 value );
enum JavelinError javelinWriteS64( struct JavelinMessageBlock* block, const javelin_s64 value );
size_t javelinReadCharArray( struct JavelinMessageBlock* block, char* buffer, const size_t bufferSize );
javelin_u8 javelinReadU8( struct JavelinMessageBlock* block );
javelin_u16 javelinReadU16( struct JavelinMessageBlock* block );
javelin_s16 javelinReadS16( struct JavelinMessageBlock* block );
javelin_u32 javelinReadU32( struct JavelinMessageBlock* block );
javelin_s32 javelinReadS32( struct JavelinMessageBlock* block );
javelin_u64 javelinReadU64( struct JavelinMessageBlock* block );
javelin_s64 javelinReadS64( struct JavelinMessageBlock* block );
#ifdef __cplusplus
}
#endif
#endif // JAVELIN_H