aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjustanothercatgirl <sotov2070@gmail.com>2024-06-30 23:54:36 +0300
committerjustanothercatgirl <sotov2070@gmail.com>2024-06-30 23:54:36 +0300
commit0cd383b2c444936dc2290c850c02a0cae11187cd (patch)
tree85805bb2de7b9b942c7de9bba430f6275ede01bf
parentb9251a3c950e75f0d69d5799da42d06dd3e41a63 (diff)
Updated C headers library
m---------include/c_headers0
-rw-r--r--include/packet.c5
-rw-r--r--include/packet.h25
-rw-r--r--server/channel.c54
-rw-r--r--server/channel.h15
5 files changed, 50 insertions, 49 deletions
diff --git a/include/c_headers b/include/c_headers
-Subproject aeaf84ff54a7921195cda875492b7a22f8b0a94
+Subproject ebad5ad23dc6893b0fb75ba04aa961a25a532b5
diff --git a/include/packet.c b/include/packet.c
index db20a12..5f551de 100644
--- a/include/packet.c
+++ b/include/packet.c
@@ -5,8 +5,3 @@ unsigned int system_packet_checksum(struct kv_system_packet *packet) {
(packet->operation_id | (177013 << 10));
}
-int __user_cmp(const void* a, const void* b) {
- struct user *_a = (struct user*)a,
- *_b = (struct user*)b;
- return _a->id - _b->id;
-}
diff --git a/include/packet.h b/include/packet.h
index 224469e..4e73040 100644
--- a/include/packet.h
+++ b/include/packet.h
@@ -1,6 +1,7 @@
#ifndef KV_PACKET_H
#define KV_PACKET_H
+
#define KV_PACKET_SIZE 512
#ifdef DEBUG
@@ -11,29 +12,25 @@
#endif
enum system_operation {
- do_nothing = 0,
- join_channel = -1,
- leave_channel = -2,
- acknowledgement = -4,
-};
-struct user {
- unsigned int ip;
- unsigned short port;
- int id;
-};
-struct channel_handle {
- int sockfd;
- struct user* users;
+ keepalive = (int) 0x80000000, // -2^31
+ join_channel, // 1 - 2^31
+ leave_channel, // 2 - 2^31
+ acknowledgement, // 3 - 2^31
};
+
struct kv_packet {
int id;
unsigned char data[KV_PACKET_SIZE - sizeof(unsigned int)];
};
struct kv_system_packet {
+ // as in system_operation enum.
int operation_id;
+ // could be ignored
int user_id;
+ // calculated with system_packet_checksum function
unsigned int checksum;
- unsigned char sentinel[KV_PACKET_SIZE - 4 * sizeof(int) - sizeof(short)];
+
+ unsigned char sentinel[KV_PACKET_SIZE - 3 * sizeof(int)];
};
unsigned int system_packet_checksum(struct kv_system_packet *packet);
diff --git a/server/channel.c b/server/channel.c
index 4dc1f7b..2d81abb 100644
--- a/server/channel.c
+++ b/server/channel.c
@@ -9,15 +9,21 @@ void thread_loop(void) {
struct kv_packet **recvd_data = array_new(struct kv_packet*, 100);
struct kv_packet work_buffer;
size_t recvd_index = 0;
+ int recv_flag = MSG_DONTWAIT;
while (true) {
struct sockaddr_in client_addr;
- socklen_t client_addr_len;
+ socklen_t client_addr_len; // unused
int recvlength = recvfrom(channel->sockfd, &work_buffer,
- KV_PACKET_SIZE, MSG_DONTWAIT,
+ KV_PACKET_SIZE, recv_flag,
(struct sockaddr*)&client_addr, &client_addr_len);
if (recvlength > 0) {
DEBUGF("rec_id = %i\n", work_buffer.id);
- if (work_buffer.id <= 0) handle_system_packet(&work_buffer, channel);
+ if (work_buffer.id <= 0) {
+ handle_system_packet(&work_buffer, &client_addr, channel);
+ continue;
+ } else {
+ recv_flag |= MSG_DONTWAIT;
+ }
struct kv_packet *kv_copy = malloc(KV_PACKET_SIZE);
memcpy(kv_copy, &work_buffer, KV_PACKET_SIZE);
++recvd_index;
@@ -27,16 +33,14 @@ void thread_loop(void) {
recvd_data[recvd_index] = kv_copy;
}
} else if (errno == EWOULDBLOCK) {
- if (array_size(recvd_data) == 0) {
- // TODO: don't set O_NONBLOCK and wait for data
- continue;
- }
+ if (array_size(recvd_data) == 0) recv_flag &= ~MSG_DONTWAIT;
send_packets_back(recvd_data, channel);
clear_packet_array(recvd_data);
} else {
perror("thread_loop failed");
}
}
+ array_free(recvd_data);
channel_uninit(channel);
}
@@ -67,37 +71,24 @@ struct channel_handle *channel_init(void) {
void channel_uninit(struct channel_handle *handle) {
array_free(handle->users);
- if (close(handle->sockfd) == -1) perror("could not gracefully uninitialize channel");
+ if (close(handle->sockfd) == -1)
+ perror("could not gracefully uninitialize channel");
free(handle);
}
-enum system_operation handle_system_packet(struct kv_packet* packet, struct channel_handle* handle) {
+void handle_system_packet(struct kv_packet* packet, struct sockaddr_in *source, struct channel_handle* handle) {
struct kv_system_packet* spacket = (struct kv_system_packet*) packet;
- if (system_packet_checksum(spacket) != spacket->checksum) return do_nothing;
+ if (system_packet_checksum(spacket) != spacket->checksum) return;
switch (spacket->operation_id) {
- case do_nothing: return do_nothing;
- case join_channel: {
- DEBUGF("someone joined the channel: id=%i\n", spacket->user_id);
- struct user user = {
- .ip = ntohl(spacket->return_address),
- .port = ntohs(spacket->return_port),
- .id = ntohl(spacket->user_id)
- };
- if (!array_binary_search(handle->users, &user, __user_cmp)) {
- array_push(handle->users, user);
- array_qsort(handle->users, __user_cmp);
- }
- struct sockaddr_in reply_addr = {.sin_family = AF_INET, .sin_port = spacket->return_port, .sin_addr = {spacket->return_address} };
- struct kv_system_packet reply = {.user_id = 0, .return_address = 0, .return_port = 0, .operation_id = acknowledgement};
- sendto(handle->sockfd, &reply, KV_PACKET_SIZE, 0, (struct sockaddr*)&reply_addr, sizeof(reply_addr));
- } return do_nothing;
- case shutdown_socket: return shutdown_socket;
- default: return do_nothing;
+ case keepalive: TODO;
+ case join_channel: TODO;
+ case leave_channel: TODO;
+ case acknowledgement: TODO;
+ default: TODO;
}
}
void send_packets_back(struct kv_packet** packets, struct channel_handle* handle) {
- /*DEBUGF("");*/
for (size_t i = 0; i < array_size(handle->users); ++i) {
struct user* current_user = &handle->users[i];
struct sockaddr_in destination = {
@@ -128,3 +119,8 @@ void clear_packet_array(struct kv_packet **array) {
}
}
+int __user_cmp(const void* a, const void* b) {
+ struct user *_a = (struct user*)a,
+ *_b = (struct user*)b;
+ return _a->id - _b->id;
+}
diff --git a/server/channel.h b/server/channel.h
index 4943887..3916212 100644
--- a/server/channel.h
+++ b/server/channel.h
@@ -10,6 +10,19 @@
#include <stdbool.h>
+struct user {
+ long id;
+ unsigned int ip;
+ unsigned short port;
+ unsigned long last_keepalive;
+};
+int __user_cmp(const void* a, const void* b);
+
+struct channel_handle {
+ int sockfd;
+ struct user* users;
+};
+
// main function that manages every channel
void thread_loop(void);
@@ -17,7 +30,7 @@ struct channel_handle *channel_init(void);
void channel_uninit(struct channel_handle *handle);
void send_packets_back(struct kv_packet** packets, struct channel_handle *handle);
-void handle_system_packet(struct kv_packet* packet, struct channel_handle* handle);
+void handle_system_packet(struct kv_packet* packet, struct sockaddr_in *source, struct channel_handle* handle);
void clear_packet_array(struct kv_packet **array);