Implemented DHT
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.5)
|
|||||||
project(RN-Praxis)
|
project(RN-Praxis)
|
||||||
set(CMAKE_C_STANDARD 11)
|
set(CMAKE_C_STANDARD 11)
|
||||||
|
|
||||||
add_executable(webserver webserver.c http.c util.c data.c)
|
add_executable(webserver webserver.c http.c util.c data.c dht.c lookup.c)
|
||||||
target_compile_options(webserver PRIVATE -Wall -Wextra -Wpedantic)
|
target_compile_options(webserver PRIVATE -Wall -Wextra -Wpedantic)
|
||||||
target_link_libraries(webserver PRIVATE -lm)
|
target_link_libraries(webserver PRIVATE -lm)
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,77 @@
|
|||||||
#include "dht.h"
|
#include "dht.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#define cpy(x, y, z) char *x_c = x; char *y_c = y; while(*y_c && z--) *x_c++ = *y_c++
|
// #define cpy(x, y, z) char *x_c = x; char *y_c = y; while(*y_c && z--) *x_c++ = *y_c++
|
||||||
|
|
||||||
void lookup_request_init(lookup_request* lr, int node_id, char *node_ip, int node_port, uint16_t hash_id, char *node_request)
|
void build_lookup_request(lookup_request* lr){
|
||||||
|
char *lrreq = lr->node_request;
|
||||||
|
snprintf(lr->node_request, HTTP_MAX_SIZE, "%d|%hd|%d|%s|%d\r\n\r\n", lr->message_type, lr->hash_id, lr->node_id, lr->node_ip, lr->node_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lookup_request_init(lookup_request* lr, int message_type, int node_id, char *node_ip, int node_port, uint16_t hash_id, char *node_request)
|
||||||
{
|
{
|
||||||
int size = NODE_IP_MAX_SIZE;
|
lr->message_type = message_type;
|
||||||
lr->node_id = node_id;
|
lr->node_id = node_id;
|
||||||
{ cpy(lr->node_ip, node_ip, size); }
|
strncpy(lr->node_ip, node_ip, NODE_IP_MAX_SIZE);
|
||||||
lr->node_port = node_port;
|
lr->node_port = node_port;
|
||||||
lr->hash_id = hash_id;
|
lr->hash_id = hash_id;
|
||||||
size = HTTP_MAX_SIZE;
|
if(node_request != NULL)
|
||||||
cpy(lr->node_request, node_request, size);
|
strncpy(lr->node_request, node_request, HTTP_MAX_SIZE);
|
||||||
|
build_lookup_request(lr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void extract_lookup_request(lookup_request* lr, char* request){
|
||||||
|
sscanf(request, "%d|%hd|%d|%s|%d\r\n\r\n", &lr->message_type, &lr->hash_id, &lr->node_id, lr->node_ip, &lr->node_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
int call_network(lookup_request* lr, char *ip, int port){
|
||||||
|
int succ_sock;
|
||||||
|
struct addrinfo hints, *servinfo, *p;
|
||||||
|
int rv;
|
||||||
|
int numbytes;
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof hints);
|
||||||
|
hints.ai_family = AF_INET;
|
||||||
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
|
|
||||||
|
char port_str[6];
|
||||||
|
snprintf(port_str, sizeof port_str, "%d", port);
|
||||||
|
|
||||||
|
if ((rv = getaddrinfo(ip, port_str, &hints, &servinfo)) != 0) {
|
||||||
|
fprintf(stderr, "Func: call_network - getaddrinfo: %s\n", gai_strerror(rv));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(p = servinfo; p != NULL; p = p->ai_next) {
|
||||||
|
if ((succ_sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
|
||||||
|
perror("Func: call_network - socket");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p == NULL) {
|
||||||
|
fprintf(stderr, "Func: call_network - failed to create socket\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((numbytes = sendto(succ_sock, lr->node_request, strlen(lr->node_request), 0, p->ai_addr, p->ai_addrlen)) == -1) {
|
||||||
|
perror("Func: call_network - sendto");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
freeaddrinfo(servinfo);
|
||||||
|
close(succ_sock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clone_lookup_request(lookup_request* dest, lookup_request* source){
|
||||||
|
memcpy(dest, source, sizeof(lookup_request));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#define NODE_IP_MAX_SIZE 16
|
#define NODE_IP_MAX_SIZE 16
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
|
int message_type;
|
||||||
int node_id;
|
int node_id;
|
||||||
char node_ip[NODE_IP_MAX_SIZE];
|
char node_ip[NODE_IP_MAX_SIZE];
|
||||||
int node_port;
|
int node_port;
|
||||||
@@ -14,7 +15,13 @@ typedef struct{
|
|||||||
char node_request[HTTP_MAX_SIZE];
|
char node_request[HTTP_MAX_SIZE];
|
||||||
}lookup_request;
|
}lookup_request;
|
||||||
|
|
||||||
void lookup_request_init(lookup_request*, int node_id, char *node_ip, int node_port, uint16_t hash_id, char *node_request);
|
void lookup_request_init(lookup_request*, int message_type, int node_id, char *node_ip, int node_port, uint16_t hash_id, char *node_request);
|
||||||
void create_lookup_request(lookup_request*, char *request);
|
void build_lookup_request(lookup_request*);
|
||||||
|
|
||||||
|
void extract_lookup_request(lookup_request*, char*);
|
||||||
|
|
||||||
|
int call_network(lookup_request*, char*, int);
|
||||||
|
|
||||||
|
void clone_lookup_request(lookup_request* dest, lookup_request* source);
|
||||||
|
|
||||||
#endif //DHT_H
|
#endif //DHT_H
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#include "lookup.h"
|
||||||
|
|
||||||
|
void init_lookup_table()
|
||||||
|
{
|
||||||
|
table = malloc(sizeof(lookup_head));
|
||||||
|
if (table == NULL) return;
|
||||||
|
table->head = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_lookup(lookup_request *request)
|
||||||
|
{
|
||||||
|
if (free_space == 0)
|
||||||
|
{
|
||||||
|
lookup_table *infront = table->head;
|
||||||
|
while (infront->next != NULL && infront->next->next != NULL)
|
||||||
|
{
|
||||||
|
infront = infront->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(infront->next->request);
|
||||||
|
free(infront->next);
|
||||||
|
infront->next = NULL;
|
||||||
|
// if malloc fails this does not leak space
|
||||||
|
free_space++;
|
||||||
|
}
|
||||||
|
|
||||||
|
lookup_table *new = (lookup_table*)malloc(sizeof(lookup_table));
|
||||||
|
if (new == NULL) return;
|
||||||
|
new->request = request;
|
||||||
|
new->next = table->head;
|
||||||
|
table->head = new;
|
||||||
|
free_space--;
|
||||||
|
}
|
||||||
|
|
||||||
|
lookup_request *find_lookup(const uint16_t hash_id)
|
||||||
|
{
|
||||||
|
const lookup_table *current = table->head;
|
||||||
|
while (current != NULL && current->request->hash_id != hash_id)
|
||||||
|
current = current->next;
|
||||||
|
return current == NULL ? NULL : current->request;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_lookup_table()
|
||||||
|
{
|
||||||
|
if (table == NULL) return;
|
||||||
|
lookup_table *current = table->head;
|
||||||
|
|
||||||
|
while (current != NULL)
|
||||||
|
{
|
||||||
|
lookup_table *temp = current;
|
||||||
|
current = current->next;
|
||||||
|
free(temp->request);
|
||||||
|
free(temp);
|
||||||
|
}
|
||||||
|
free(table);
|
||||||
|
table = NULL;
|
||||||
|
free_space = TABLE_SIZE;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef LOOKUP_H
|
||||||
|
#define LOOKUP_H
|
||||||
|
#include "dht.h"
|
||||||
|
|
||||||
|
#define TABLE_SIZE 10
|
||||||
|
|
||||||
|
typedef struct lookup_table
|
||||||
|
{
|
||||||
|
lookup_request *request;
|
||||||
|
struct lookup_table *next;
|
||||||
|
}lookup_table;
|
||||||
|
|
||||||
|
typedef struct lookup_head
|
||||||
|
{
|
||||||
|
lookup_table *head;
|
||||||
|
}lookup_head;
|
||||||
|
|
||||||
|
static lookup_head *table;
|
||||||
|
static int free_space = TABLE_SIZE;
|
||||||
|
|
||||||
|
void init_lookup_table();
|
||||||
|
|
||||||
|
void push_lookup(lookup_request *request);
|
||||||
|
|
||||||
|
lookup_request *find_lookup(const uint16_t hash_id);
|
||||||
|
|
||||||
|
void free_lookup_table();
|
||||||
|
|
||||||
|
#endif //LOOKUP_H
|
||||||
+92
-45
@@ -16,6 +16,8 @@
|
|||||||
#include "data.h"
|
#include "data.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "dht.h"
|
||||||
|
#include "lookup.h"
|
||||||
|
|
||||||
#define elif else if
|
#define elif else if
|
||||||
|
|
||||||
@@ -31,7 +33,7 @@ bool _DO_UDP = false;
|
|||||||
|
|
||||||
int _NODE_ID;
|
int _NODE_ID;
|
||||||
const char *_NODE_IP;
|
const char *_NODE_IP;
|
||||||
const char *_NODE_PORT;
|
int _NODE_PORT;
|
||||||
|
|
||||||
#define MAX_RESOURCES 100
|
#define MAX_RESOURCES 100
|
||||||
|
|
||||||
@@ -87,6 +89,21 @@ void send_reply(int conn, struct request *request) {
|
|||||||
uint16_t resource_hash = hash_uri(request->uri);
|
uint16_t resource_hash = hash_uri(request->uri);
|
||||||
neighbor responsible = check_neighborhood(resource_hash);
|
neighbor responsible = check_neighborhood(resource_hash);
|
||||||
|
|
||||||
|
lookup_request *req = find_lookup(resource_hash);
|
||||||
|
if (req != NULL)
|
||||||
|
{
|
||||||
|
if (req->message_type != 1)
|
||||||
|
{
|
||||||
|
printf("404\n");
|
||||||
|
reply = "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n";
|
||||||
|
offset = strlen(reply);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (responsible == res) {
|
if (responsible == res) {
|
||||||
sprintf(reply, "HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
|
sprintf(reply, "HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
|
||||||
offset = strlen(reply);
|
offset = strlen(reply);
|
||||||
@@ -94,9 +111,19 @@ void send_reply(int conn, struct request *request) {
|
|||||||
}
|
}
|
||||||
elif(responsible == res_303)
|
elif(responsible == res_303)
|
||||||
{
|
{
|
||||||
sprintf(reply, "HTTP/1.1 303 See Other\r\nLocation: http://%s:%d%s\r\nContent-Length: 0\r\n\r\n", _SUCC_IP, _SUCC_PORT, request->uri);
|
int suc_id = _SUCC_ID;
|
||||||
offset = strlen(reply);
|
if (resource_hash <= suc_id || suc_id >= 0 && suc_id < _NODE_ID)
|
||||||
printf("303\n");
|
{
|
||||||
|
printf("404\n");
|
||||||
|
reply = "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n";
|
||||||
|
offset = strlen(reply);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(reply, "HTTP/1.1 303 See Other\r\nLocation: http://%s:%d%s\r\nContent-Length: 0\r\n\r\n", _SUCC_IP, _SUCC_PORT, request->uri);
|
||||||
|
offset = strlen(reply);
|
||||||
|
printf("303\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
elif(responsible == not_res)
|
elif(responsible == not_res)
|
||||||
{
|
{
|
||||||
@@ -104,6 +131,10 @@ void send_reply(int conn, struct request *request) {
|
|||||||
offset = strlen(reply);
|
offset = strlen(reply);
|
||||||
printf("503\n");
|
printf("503\n");
|
||||||
// TODO: Call other dht
|
// TODO: Call other dht
|
||||||
|
lookup_request lookreq;
|
||||||
|
lookup_request_init(&lookreq, 0, _NODE_ID, (char*)_NODE_IP, _NODE_PORT, resource_hash, NULL);
|
||||||
|
|
||||||
|
call_network(&lookreq, _SUCC_IP, _SUCC_PORT);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printf("404\n");
|
printf("404\n");
|
||||||
@@ -364,16 +395,15 @@ neighbor check_neighborhood(uint16_t hash) {
|
|||||||
int suc_id = _SUCC_ID;
|
int suc_id = _SUCC_ID;
|
||||||
|
|
||||||
if(pre_id == suc_id){
|
if(pre_id == suc_id){
|
||||||
if(hash <= id && hash > suc_id) return res_303;
|
if(hash > id && hash <= suc_id) return res_303;
|
||||||
if(hash > id && hash <= suc_id) return not_res;
|
return res;
|
||||||
return res_303; // hash is in between suc and 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check correctness
|
// TODO: check correctness
|
||||||
if ((pre_id == id && suc_id == id) || (id < pre_id && ((hash > pre_id && hash < 65535)) || hash <= id) || (hash > pre_id && hash <= id))
|
if ((pre_id == id && suc_id == id) || (id < pre_id && ((hash > pre_id && hash < 65535)) || hash <= id) || (hash > pre_id && hash <= id))
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
if ((id < suc_id && hash > id && hash <= suc_id) || (hash > id || hash <= suc_id))
|
if ((id < suc_id && hash > id && hash <= suc_id) || (id > suc_id && (hash > id || hash <= suc_id)))
|
||||||
return not_res;
|
return not_res;
|
||||||
|
|
||||||
return dunno;
|
return dunno;
|
||||||
@@ -403,45 +433,60 @@ static void handle_udp_request(int _sock){
|
|||||||
|
|
||||||
// HASH Received
|
// HASH Received
|
||||||
// TODO: alter buffer
|
// TODO: alter buffer
|
||||||
uint16_t hash = atoi(buffer);
|
lookup_request lr = {0};
|
||||||
printf("Hash: %u\n", hash);
|
extract_lookup_request(&lr, buffer);
|
||||||
// Check belonging
|
|
||||||
int pre_id = _PRED_ID;
|
|
||||||
int suc_id = _SUCC_ID;
|
|
||||||
neighbor responsibility = check_neighborhood(hash);
|
|
||||||
|
|
||||||
if (responsibility == res) {
|
printf("Received:\n\tMessage-type: %d\n\tlookup-hash: %hd\n", lr.message_type, lr.hash_id);
|
||||||
char res[] = "HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n";
|
|
||||||
if (sendto(_sock, res, strlen(res), 0, (struct sockaddr *) &caller_addr, addrlen) == -1) {
|
// DO LOOKUP
|
||||||
perror("Func: handle_udp_request - failed to send 200 data to caller!");
|
if (lr.message_type == 0)
|
||||||
exit(EXIT_FAILURE);
|
{
|
||||||
}
|
// Check belonging
|
||||||
printf("Sent: %s", res);
|
const int suc_id = _SUCC_ID;
|
||||||
}
|
char *callback_ip = lr.node_ip;
|
||||||
/*
|
int callback_port = lr.node_port;
|
||||||
TODO: return 404
|
|
||||||
elif (responsibility == res_303) {
|
lookup_request backfire = {0};
|
||||||
fprintf(stderr, "Sent 303!\n");
|
|
||||||
char res[1024] = {0};
|
if (lr.node_id == suc_id)
|
||||||
snprintf(res, 1024, "HTTP/1.1 303 See Other\r\nLocation: http://%s:%s/%d\r\nContent-Length: 0\r\n\r\n", _NODE_IP, _NODE_PORT, suc_id);
|
|
||||||
if(sendto(_sock, res, strlen(res), 0, (struct sockaddr *) &caller_addr, addrlen) == -1){
|
|
||||||
perror("Func: handle_udp_request - failed to send 303 data to caller!");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
printf("Sent: %s", res);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
elif (responsibility == not_res) {
|
|
||||||
// TODO: DIRECT TO NEXT NODE
|
|
||||||
const char res[] = "HTTP/1.1 503 Service Unavailable\r\nRetry-After: 1\r\nContent-Length: 0\r\n\r\n";
|
|
||||||
if(sendto(_sock, res, strlen(res), 0, (struct sockaddr *) &caller_addr, addrlen) == -1)
|
|
||||||
{
|
{
|
||||||
perror("Func: handle_udp_request - failed to send 503 data to caller!");
|
// Send back 404 not found
|
||||||
exit(EXIT_FAILURE);
|
clone_lookup_request(&backfire, &lr);
|
||||||
|
backfire.message_type = -1;
|
||||||
}
|
}
|
||||||
printf("Sent: %s", res);
|
else
|
||||||
|
{
|
||||||
|
const neighbor responsibility = check_neighborhood(lr.hash_id);
|
||||||
|
|
||||||
|
if (responsibility == res) {
|
||||||
|
lookup_request_init(&backfire, 1, _NODE_ID, (char*)_NODE_IP, _NODE_PORT, _PRED_ID, lr.node_request);
|
||||||
|
}
|
||||||
|
elif (responsibility == not_res) {
|
||||||
|
// is succ responsible
|
||||||
|
if (lr.hash_id <= suc_id)
|
||||||
|
{
|
||||||
|
lookup_request_init(&backfire, 1, suc_id, _SUCC_IP, _SUCC_PORT, _NODE_ID, lr.node_request);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lookup_request_init(&backfire, 1, suc_id, _SUCC_IP, _SUCC_PORT, _NODE_ID, lr.node_request);
|
||||||
|
callback_ip = _SUCC_IP; // TODO: Check validity
|
||||||
|
callback_port = _SUCC_PORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
call_network(&backfire, callback_ip, callback_port);
|
||||||
|
}
|
||||||
|
elif (lr.message_type == 1)
|
||||||
|
{
|
||||||
|
lookup_request *toLookup = malloc(sizeof(lookup_request));
|
||||||
|
clone_lookup_request(toLookup, &lr);
|
||||||
|
|
||||||
|
push_lookup(toLookup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
//call_other_dht();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -457,11 +502,13 @@ int main(int argc, char **argv) {
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init_lookup_table();
|
||||||
|
|
||||||
if(argc == 3) _NODE_ID = 0;
|
if(argc == 3) _NODE_ID = 0;
|
||||||
elif(argc == 4) _NODE_ID = atoi(argv[3]);
|
elif(argc == 4) _NODE_ID = atoi(argv[3]);
|
||||||
|
|
||||||
// Set this DHT-Nodes ID
|
// Set this DHT-Nodes ID
|
||||||
_NODE_PORT = argv[2];
|
_NODE_PORT = atoi(argv[2]);
|
||||||
_NODE_IP = argv[1];
|
_NODE_IP = argv[1];
|
||||||
|
|
||||||
struct sockaddr_in addr = derive_sockaddr(argv[1], argv[2]);
|
struct sockaddr_in addr = derive_sockaddr(argv[1], argv[2]);
|
||||||
@@ -534,6 +581,6 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free_lookup_table();
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user