summaryrefslogtreecommitdiff
path: root/src/main.c.orig
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c.orig')
-rw-r--r--src/main.c.orig202
1 files changed, 202 insertions, 0 deletions
diff --git a/src/main.c.orig b/src/main.c.orig
new file mode 100644
index 0000000..95dc2b9
--- /dev/null
+++ b/src/main.c.orig
@@ -0,0 +1,202 @@
+#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);
+ for(; cursor < end; cursor++) {
+ //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 %m");
+ }
+ }
+}
+
+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;
+<<<<<<< HEAD
+ 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;
+ }
+>>>>>>> 685b13e (I don't remember)
+
+ struct message* message_cursor = outbuff;
+ proto_begin(&dht, time(NULL), &message_cursor, outbuff+32);
+ flush_messages(dht.sfd, outbuff, message_cursor);
+
+<<<<<<< HEAD
+ char buff_storage[2049];
+=======
+
+#define RECV_BUFF_SIZE 4096
+ char buff_storage[RECV_BUFF_SIZE+1];
+>>>>>>> 685b13e (I don't remember)
+ int rc = 0;
+ while(rc == 0 && !killed) {
+ char* buff = buff_storage;
+
+ 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");
+ }
+
+ for(int i = 0; i < MAX_INFLIGHT; i++) {
+ if(!dht.reqalloc[i])
+ continue;
+
+ time_t timeout = dht.requestdata[i].timeout;
+ if(next == 0 || (timeout != 0 && difftime(timeout, next) < 0))
+ next = timeout;
+ }
+
+ if(next != 0) {
+ time_t sleepfor = next - time(NULL);
+ dbg("Set timeout to %ld", sleepfor);
+ struct timeval tv = {
+ .tv_sec = sleepfor,
+ .tv_usec = 0,
+ };
+ if(tv.tv_sec <= 0) {
+ timedout = true;
+ } else {
+ setsockopt(dht.sfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+ }
+ }
+
+ // Try to receive some data, this is a blocking call
+ struct sockaddr_storage remote;
+ socklen_t remote_len = sizeof(remote);
+ ssize_t recv_len;
+ if(!timedout) {
+ 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);
+ }
+ } else if(recv_len >= RECV_BUFF_SIZE) {
+ dbg("Receive buffer too small");
+ continue;
+ }
+ // Null terminate the packet
+ if(buff != NULL) {
+ buff[recv_len] = '\0';
+ }
+ } else {
+ buff = NULL;
+ recv_len = 0;
+ }
+
+ struct message* message_cursor = outbuff;
+ time_t now = time(NULL);
+ rc = proto_run(&dht, buff, recv_len, (struct sockaddr_in*)&remote, remote_len, now, &message_cursor, outbuff+10);
+ flush_messages(dht.sfd, outbuff, message_cursor);
+ }
+
+ proto_end(&dht);
+ dbg("Writing out config");
+ save_config();
+
+ return rc;
+}