diff options
Diffstat (limited to 'src/main.c.orig')
| -rw-r--r-- | src/main.c.orig | 202 |
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; +} |
