aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
m---------include/c_headers0
-rw-r--r--include/kv.h2
-rw-r--r--include/packet.c65
-rw-r--r--include/packet.h192
4 files changed, 235 insertions, 24 deletions
diff --git a/include/c_headers b/include/c_headers
-Subproject ebad5ad23dc6893b0fb75ba04aa961a25a532b5
+Subproject 8989b7dc005af7960aa66fd99b197a3b0b7a4fb
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 <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 {
- 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