summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c109
1 files changed, 96 insertions, 13 deletions
diff --git a/src/main.c b/src/main.c
index 20cd376..4a28a1d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,9 +1,74 @@
#include "proto.h"
+#include "peers.h"
#include "log.h"
#include <time.h>
#include <assert.h>
#include <errno.h>
+#include <signal.h>
+
+static volatile bool killed = false;
+void sigint_handler(int sig) {
+ killed = true;
+}
+
+#define CONF_ENO 1
+
+void save_config() {
+ FILE* config = fopen("conf.dmp", "w");
+ if(config == NULL)
+ fatal("Couldn't open config for writing");
+
+ if(fwrite(&myID, sizeof(struct nodeid), 1, config) != 1)
+ fatal("Couldn't write state");
+ if(fwrite(table, sizeof(struct entry), table_size, config) != table_size)
+ fatal("Couldn't write state");
+
+ long pos = ftell(config);
+ dbg("Routing stops at 0x%04lX", pos);
+
+ if(fwrite(&peer_table_size, sizeof(peer_table_size), 1, config) != 1)
+ fatal("Couldn't write peer table size");
+ if(fwrite(&peer_table_load, sizeof(peer_table_load), 1, config) != 1)
+ fatal("Couldn't write peer table load");
+ if(fwrite(peer_table, sizeof(struct peer_entry), peer_table_size, config) != peer_table_size)
+ fatal("Couldn't write peer table");
+
+ if(fclose(config) != 0)
+ fatal("Couldn't close config file");
+}
+
+int read_config() {
+ FILE* config = fopen("conf.dmp", "r");
+ if(config == NULL)
+ return CONF_ENO;
+
+ if(fread(&myID, sizeof(struct nodeid), 1, config) != 1)
+ fatal("Couldn't read routing table");
+ if(fread(table, sizeof(struct entry), table_size, config) != table_size)
+ fatal("Couldn't read routing table");
+
+ if(fread(&peer_table_size, sizeof(peer_table_size), 1, config) != 1)
+ fatal("Couldn't read peer table");
+ if(fread(&peer_table_load, sizeof(peer_table_load), 1, config) != 1)
+ fatal("Couldn't read peer table");
+
+ peer_table = malloc(sizeof(struct peer_entry) * peer_table_size);
+ assert(peer_table != NULL);
+
+ if(fread(peer_table, sizeof(struct peer_entry), peer_table_size, config) != peer_table_size)
+ fatal("Couldn't read peer table");
+
+ long pos = ftell(config);
+ fseek(config, 0, SEEK_END);
+ if(pos != ftell(config))
+ fatal("The config file was too long?");
+
+ if(fclose(config) != 0)
+ fatal("Couldn't close config file");
+
+ return 0;
+}
void flush_messages(int sfd, struct message* cursor, const struct message* const end) {
dbg("Flushing %ld pending messages", end - cursor);
@@ -11,7 +76,7 @@ void flush_messages(int sfd, struct message* cursor, const struct message* const
//now reply the client with the same data
int rc = sendto(sfd, cursor->payload, cursor->payload_len, 0, (const struct sockaddr*)&cursor->dest, cursor->dest_len);
if (rc < 0) {
- fatal("Failed to send message");
+ fatal("Failed to send message %m");
}
}
}
@@ -19,30 +84,43 @@ void flush_messages(int sfd, struct message* cursor, const struct message* const
int main(int argc, char** argv) {
struct message outbuff[32] = {0};
+ struct sigaction sa;
+ sa.sa_handler = sigint_handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+
+ if(sigaction(SIGINT, &sa, NULL) == -1)
+ fatal("Couldn't set signal handler");
+
struct dht dht;
- dht.self = (struct nodeid){.inner={0xebe9bbf1, 0x3cdba6b3, 0x993e0c87, 0x900d5e25}};
- routing_init(&dht.self);
+ {
+ int rc = read_config();
+ if(rc == CONF_ENO) {
+ myID = (struct nodeid){.inner={0xebe9bbf1, 0x3cdba6b3, 0x993e0c87, 0x900d5e25}};
+ routing_flush();
+ allocate_hashtable();
+ }
+
+ dht.self = myID;
+ }
struct message* message_cursor = outbuff;
proto_begin(&dht, time(NULL), &message_cursor, outbuff+32);
flush_messages(dht.sfd, outbuff, message_cursor);
- char buff_storage[2049];
+#define RECV_BUFF_SIZE 4096
+ char buff_storage[RECV_BUFF_SIZE+1];
int rc = 0;
- while(rc == 0) {
+ while(rc == 0 && !killed) {
char* buff = buff_storage;
- printf("Waiting for data...");
- fflush(stdout);
bool timedout = false;
time_t next = 0;
if(!dht.pause){
-
struct entry* oldest;
routing_oldest(&oldest);
if(oldest != NULL)
next = oldest->expire;
-
} else {
dbg("DHT timeout is paused");
}
@@ -75,18 +153,21 @@ int main(int argc, char** argv) {
socklen_t remote_len = sizeof(remote);
ssize_t recv_len;
if(!timedout) {
- recv_len = recvfrom(dht.sfd, buff, 2048, 0, (struct sockaddr *)&remote, &remote_len);
+ recv_len = recvfrom(dht.sfd, buff, RECV_BUFF_SIZE, 0, (struct sockaddr *)&remote, &remote_len);
if(recv_len == -1) {
// This is really strange. The man pages say we should be getting
// an ETIMEDOUT here, but instead linux gives us this.
if(errno == EAGAIN) {
buff = NULL;
recv_len = 0;
+ } else if(errno == EINTR) {
+ continue;
} else {
- fatal("RECV failed %d %m", errno, errno);
+ fatal("RECV failed %d %m", errno);
}
- } else if(recv_len >= 2048) {
- fatal("Receive buffer too small");
+ } else if(recv_len >= RECV_BUFF_SIZE) {
+ dbg("Receive buffer too small");
+ continue;
}
// Null terminate the packet
if(buff != NULL) {
@@ -104,6 +185,8 @@ int main(int argc, char** argv) {
}
proto_end(&dht);
+ dbg("Writing out config");
+ save_config();
return rc;
}