aboutsummaryrefslogtreecommitdiffstats
path: root/include/packet.h
blob: 01c006eda51cd83f5e7d9159ba39d2417e6f41f0 (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
#ifndef KV_PACKET_H
#define KV_PACKET_H

#ifdef __cplusplus
	Once upon a time, there was a C++ programmer.
	He Really liked programming, but he
	did not know that C++ is an overbloated 
	pile of garbage. And so he died alone, 
	fat and ugly. The morale is the following:
	Kids, stop using C++. Let us make the world
	a better place together. 

	Thank you for not using C++.
#endif

#define KV_PACKET_SIZE 512

// These macros became obsolete due to log.h header in c_headers
// TODO: remove
/*
#ifdef DBG
#	define DEBUGF(fmt, ...) fprintf(stderr, "DEBUG: %s:%d:%s(): " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
#	define DEBUG(msg) fprintf(stderr, "DEBUG: %s:%d:%s(): " msg, __FILE__, __LINE__, __func__)
#	define WHERE fprintf(stderr, "DEBUG: %s:%d:%s()\n", __FILE__, __LINE__, __func__)
#else
#	define DEBUGF(fmt, ...)
#	define DEBUG(fmt)
#	define WHERE
#endif
*/
#ifdef __clang__
#	pragma GCC diagnostic ignored "-Wnullability-extension" // SHUT UP I'VE ALREADY PUT IT BEHIND A MACRO
#	define NONNULL _Nonnull
#	define NULLABLE _Nullable
#else
#	define NONNULL
#	define NULLABLE
#endif


#include <arpa/inet.h>
#include <stddef.h>
#include <rstypes.h>

// all ones so that ntohl is not needed
#define SYS_PACKET_MAGIC_BYTES 0xFFFFFFFFU

extern i64 const commd_size_lookup[];

enum system_operation {
	SYS_KEEPALIVE = (i32)0x80000000, // -2^31
	SYS_JOIN,		 	 // 1 - 2^31
	SYS_LEAVE,		 	 // 2 - 2^31
	SYS_ACK,	     		 // 3 - 2^31
	SYS_KYS,			 // 4 - 2^31
}; // Yes, KYS stands for kill yourself

struct kv_packet {
	u64 uid;
	u8 data[KV_PACKET_SIZE - sizeof(u64)];
};
// ONLY `operation_id` field is in network byte order.
// Everything else is host byte order since these packets 
// are never to leave the server
struct kv_system_packet {
	const u32 magic_bytes /* = 0xFFFFFFFF */;
	// as in system_operation enum.
	i32 operation_id;
	// could be ignored
	u64 user_id;
	// id to be returned in acknowledgement. if 0, don't acknowledge.
	u32 ackid;
	// calculated with system_packet_checksum function
	u32 checksum;
	// TODO: add server signature here

	u8 sentinel[KV_PACKET_SIZE - 4 * sizeof(u32) - sizeof(u64)];
};

u32 system_packet_checksum(struct kv_system_packet *packet);
u8 is_system_packet(struct kv_packet *p);

enum permissions {
	PERM_NONE	 	= 0,
	PERM_REGISTER_USER	= 1 << 1,
	PERM_UNREGISTER_USER	= 1 << 2,
	PERM_ADD_CHANNEL 	= 1 << 3,
	PERM_UNADD_CHANNEL 	= 1 << 4,
	PERM_JOIN_USER	 	= 1 << 5,
	PERM_KICK_USER	 	= 1 << 6,
	PERM_ADMIN		= 0x7FFFFFFF,
};

enum commd_error {
	// No error
	ERR_SUCCESS,
	// Internal server error
	ERR_SERV,
	// Error in parameters (e.g. nonexistant UID)
	ERR_PARAM,
	// The command does not exist
	ERR_TYPE,
	// Invalid parameters (e.g. not enough params)
	ERR_INVAL,
	// Access violation
	ERR_ACCESS,
	// Operation not implemented yet
	ERR_NOIMPL,
	// Internal indication that function can not process request
	ERR_DO_IT_YOURSELF, // should never be sent out to suer
};

struct tcp_user {
	u64 id;
	u64 joined_channel;
	i32 permissions;
	char *pubkey;
};
struct tcp_channel {
	u64 id;
	u64 owner;
	int fd;
	char *name;
};

enum commd_type {
	CMD_CREATE = 0,
	CMD_DELETE,
	CMD_JOIN,
	CMD_LEAVE,
	CMD_REGISTER,
	CMD_UNREGISTER,
	CMD_GET_PORT,
	CMD_GET_CHANNELS,
	CMD_LAST,
};
// Somehow, this is pretty similar to linux sockaddr.
struct commd {
	unsigned char command[32];
};
struct commd_register {
	// Administrator UID. Optional.
	u64 auid;
	// Permissions
	u64 perm;
};
struct commd_unregister {
	// Administrator UID. Optional.
	u64 auid;
	// UID to be unregistered.
	u64 uid;
};
struct commd_create {
	// UID of user creating the channel.
	u64 uid;
};
struct commd_delete {
	// UID of user deleting a channel.
	u64 uid;
	// CHID of channel being deleted.
	u64 chid;
};
struct commd_join {
	// UID of user performing operation.
	u64 uid;
	// UID of user to be joined to channel.
	u64 juid;
	// CHID of the channel to be joined.
	u64 chid;
};
struct commd_leave {
	// UID of user performing operation.
	u64 uid;
	// UID of user leaving channel.
	u64 luid;
	// CHID of channel to be left by user `luid`.
	u64 chid;
};
struct commd_get_port {
	// CHID of channel to get the UDP port of
	u64 cihd;
};
typedef void commd_get_channels;
struct commd_conv {
	u64 _1;
	u64 _2; 
	u64 _3;
	u64 _4;
};

u64 hton64(u64 a);
u64 ntoh64(u64 a);

#define hton32 htonl
#define ntoh32 ntohl

#define hton16 htons
#define ntoh16 ntohs

const char* kv_strerror(enum commd_error e);

#endif // KV_PACKET_H
/* vim: set ts=8 noet: */