From 3eeee14d5d5c93ae3d156aabae5a96d1c09f185a Mon Sep 17 00:00:00 2001 From: justanothercatgirl Date: Thu, 4 Jul 2024 20:49:53 +0300 Subject: Renamed types, migrated to make, changed directory hierarchy --- include/c_headers | 2 +- include/kv.h | 2 - include/packet.c | 65 +++++++++++++++++- include/packet.h | 192 ++++++++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 236 insertions(+), 25 deletions(-) (limited to 'include') diff --git a/include/c_headers b/include/c_headers index ebad5ad..8989b7d 160000 --- a/include/c_headers +++ b/include/c_headers @@ -1 +1 @@ -Subproject commit ebad5ad23dc6893b0fb75ba04aa961a25a532b5f +Subproject commit 8989b7dc005af7960aa66fd99b197a3b0b7a4fbc diff --git a/include/kv.h b/include/kv.h index b5f9842..ff28ce3 100644 --- a/include/kv.h +++ b/include/kv.h @@ -1,8 +1,6 @@ #ifndef JUSTANOTHERCATGIRL_KV_H #define JUSTANOTHERCATGIRL_KV_H -#include "packet.h" - #define KV_SERVER_ADDRESS_STRING "95.164.2.199" #define KV_SERVER_ADDRESS_INT ((95 << 24) | (164 << 16) | (2 << 8) | (199 << 0)) diff --git a/include/packet.c b/include/packet.c index 5f551de..a523285 100644 --- a/include/packet.c +++ b/include/packet.c @@ -1,7 +1,66 @@ #include "packet.h" -unsigned int system_packet_checksum(struct kv_system_packet *packet) { - return (packet->user_id << 8) ^ - (packet->operation_id | (177013 << 10)); +i64 const commd_size_lookup[64] = {[CMD_CREATE] = sizeof(struct commd_create), + [CMD_DELETE] = sizeof(struct commd_delete), + [CMD_JOIN] = sizeof(struct commd_join), + [CMD_LEAVE] = sizeof(struct commd_leave), + [CMD_REGISTER] = sizeof(struct commd_register), + [CMD_UNREGISTER] = sizeof(struct commd_unregister), + [CMD_GET_PORT] = sizeof(struct commd_get_port), + [CMD_GET_CHANNELS] = 0, // You can not get a sizeof(void) + 0}; + +u32 system_packet_checksum(struct kv_system_packet *packet) +{ + return ((packet->user_id << 8) ^ (ntoh64(packet->operation_id) | (177013 << 10)) ^ packet->ackid) & + packet->magic_bytes; +} +u8 is_system_packet(struct kv_packet *p) +{ + struct kv_system_packet *sysp = (struct kv_system_packet *)p; + if (sysp->magic_bytes == SYS_PACKET_MAGIC_BYTES && (signed int)ntohl(sysp->operation_id) < 0) return 1; + return 0; +} + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +u64 hton64(u64 a) +{ + #if __SIZEOF_SIZE_T__ == 8 + return ((u64)htonl((u32)(a & 0xFFFFFFFF)) << 32) | (u64)htonl((u32)(a >> 32)); + #else + return htonl((u32)a); + #endif +} +u64 ntoh64(u64 a) +{ + #if __SIZEOF_SIZE_T__ == 8 + return ((u64)ntohl((u32)(a & 0xFFFFFFFF)) << 32) | (u64)ntohl((u32)(a >> 32)); + #else + return ntohl((u32)a); + #endif } +#else +u64 htonzu(u64 a) { return a; } +u64 ntohzu(u64 a) { return a; } +#endif +const char *kv_strerror(enum commd_error e) +{ + switch (e) { + case ERR_SUCCESS: + return "Success"; + case ERR_SERV: + return "Internal server error"; + case ERR_ACCESS: + return "No access"; + case ERR_INVAL: + return "Invalid/insufficient parameters"; + case ERR_PARAM: + return "Incorrect parameters"; + case ERR_NOIMPL: + return "Not implemented"; + case ERR_DO_IT_YOURSELF: + return "You should not have recieved this error. This is either server or network fault"; + } + return "Unknown error"; +} diff --git a/include/packet.h b/include/packet.h index 4e73040..f1b1e60 100644 --- a/include/packet.h +++ b/include/packet.h @@ -1,40 +1,194 @@ #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 -#ifdef DEBUG -#define DEBUGF(fmt, ...) fprintf(stderr, "DEBUG: %s:%d:%s(): " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__) +#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 DEBUGF(fmt, ...) \ - do { } while (0) +# define NONNULL +# define NULLABLE #endif +#include +#include +#include + +// all ones so that ntohl is not needed +#define SYS_PACKET_MAGIC_BYTES 0xFFFFFFFFU + +extern i64 const commd_size_lookup[]; + enum system_operation { - keepalive = (int) 0x80000000, // -2^31 - join_channel, // 1 - 2^31 - leave_channel, // 2 - 2^31 - acknowledgement, // 3 - 2^31 -}; + 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 { - int id; - unsigned char data[KV_PACKET_SIZE - sizeof(unsigned int)]; + 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. - int operation_id; + i32 operation_id; // could be ignored - int user_id; + u64 user_id; + // id to be returned in acknowledgement. if 0, don't acknowledge. + u32 ackid; // calculated with system_packet_checksum function - unsigned int checksum; - - unsigned char sentinel[KV_PACKET_SIZE - 3 * sizeof(int)]; + u32 checksum; + // TODO: add server signature here + + u8 sentinel[KV_PACKET_SIZE - 4 * sizeof(u32) - sizeof(u64)]; }; -unsigned int system_packet_checksum(struct kv_system_packet *packet); -int __user_cmp(const void* a, const void* b); +u32 system_packet_checksum(struct kv_system_packet *packet); +u8 is_system_packet(struct kv_packet *p); -#endif // KV_PACKET_H +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, + // 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, +}; +// 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 -- cgit v1.2.3-70-g09d2