initial http parsing

This commit is contained in:
2024-11-11 00:50:39 +01:00
parent 7db494eaaf
commit e5e40c795c
17 changed files with 176 additions and 32 deletions

98
src/utils/hashmap.c Normal file
View File

@@ -0,0 +1,98 @@
#include "utils/hashmap.h"
int hash(int sockfd) { return sockfd % HASHMAP_MAX_CLIENTS; }
void hm_init(bucket_t *bucket) {
/* Initialize everything to 0 for the struct, then -1 for fd and next to NULL */
memset(bucket, 0, sizeof(bucket_t) * HASHMAP_MAX_CLIENTS);
for (size_t i = 0; i < HASHMAP_MAX_CLIENTS; ++i) {
bucket[i].sockfd = -1;
bucket[i].next = NULL;
bucket[i].prev = NULL;
}
}
void hm_insert(bucket_t *bucket, int sockfd, struct sockaddr_storage *sas) {
int index = hash(sockfd);
if (bucket[index].sockfd == -1) {
/* Current slot is empty */
bucket[index].sockfd = sockfd;
bucket[index].sas = *sas;
} else {
/* Append the new key to the head (not the first element because it belongs to the array) of the linked
* list */
bucket_t *p = &bucket[index];
bucket_t *new = malloc(sizeof(bucket_t));
new->sockfd = sockfd;
new->sas = *sas;
new->next = p->next;
new->prev = p;
p->next = new;
}
}
bucket_t *hm_lookup(bucket_t *bucket, int sockfd) {
int index = hash(sockfd);
if (bucket[index].sockfd != sockfd) {
bucket_t *p;
for (p = bucket[index].next; p != NULL && p->sockfd != sockfd; p = p->next);
return p;
} else {
return &bucket[index];
}
return NULL;
}
void hm_push(bucket_t *bucket, int sockfd, struct sockaddr_storage *sas) {
if (hm_lookup(bucket, sockfd) == NULL) {
hm_insert(bucket, sockfd, sas);
}
}
void hm_remove(bucket_t *bucket, int sockfd) {
if (hm_is_in_bucket_array(bucket, sockfd)) {
/* Instead of doing this I could copy the memory of the next node into the head */
int index = hash(sockfd);
bucket[index].sockfd = -1;
return;
}
/* Key not in the bucket array, let's search in the linked list */
bucket_t *p = hm_lookup(bucket, sockfd);
if (p == NULL) return;
p->prev->next = p->next;
if (p->next != NULL) {
/* If there's a next node update the previous node */
p->next->prev = p->prev;
}
free(p);
}
void hm_free(bucket_t *bucket) {
bucket_t *p, *next;
for (size_t i = 0; i < HASHMAP_MAX_CLIENTS; ++i) {
if (bucket[i].next != NULL) {
/* Free the malloc */
p = bucket[i].next;
next = p->next;
do {
free(p);
p = next;
next = p != NULL ? p->next : NULL;
} while (p != NULL);
}
}
}
bool hm_is_in_bucket_array(bucket_t *bucket, int sockfd) {
int index = hash(sockfd);
if (bucket[index].sockfd == sockfd) return true;
return false;
}

42
src/utils/utils.c Normal file
View File

@@ -0,0 +1,42 @@
#include "utils/utils.h"
#include "utils/colors.h"
void print_ips(const char *hostname, const char *port) {
struct addrinfo ai;
struct addrinfo *res;
memset(&ai, 0, sizeof ai);
ai.ai_family = AF_UNSPEC;
ai.ai_socktype = SOCK_STREAM;
int status = getaddrinfo(hostname, port, &ai, &res);
if (status < 0) {
fprintf(stderr, RED "getaddrinfo(): %s\n" RESET, gai_strerror(status));
exit(1);
}
char ipv4[INET_ADDRSTRLEN];
char ipv6[INET6_ADDRSTRLEN];
for (struct addrinfo *p = res; p != NULL; p = p->ai_next) {
if (p->ai_family == AF_INET) {
struct sockaddr_in *sin = (struct sockaddr_in *)p->ai_addr;
inet_ntop(AF_INET, &sin->sin_addr, ipv4, INET_ADDRSTRLEN);
fprintf(stdout, BLUE "%s\n" RESET, ipv4);
} else if (p->ai_family == AF_INET6) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)p->ai_addr;
inet_ntop(AF_INET6, &sin6->sin6_addr, ipv6, INET6_ADDRSTRLEN);
fprintf(stdout, BLUE "%s\n" RESET, ipv6);
}
}
freeaddrinfo(res);
}
void get_client_ip(struct sockaddr_storage *sa, char *ip) {
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
inet_ntop(AF_INET, &sin->sin_addr, ip, INET_ADDRSTRLEN);
}