diff options
| author | Jesper Jensen <DelusionalLogic@users.noreply.github.com> | 2021-10-27 20:29:41 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-10-27 20:29:41 +0200 |
| commit | 4527a87385c56cb2a5cf0269d4638b604a1f039b (patch) | |
| tree | 031e8a09ec26229b31f58e2189d0023898881d20 /src | |
| parent | ef39868b6bffa3030c7cbc083df1301849fba0f7 (diff) | |
| parent | 42a627aab5e47c3f3e05460322b9c1c3f2c69214 (diff) | |
Merge pull request #1 from DelusionalLogic/mainflush
Mainflush
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.c | 3 | ||||
| -rw-r--r-- | src/proto.c | 11 | ||||
| -rw-r--r-- | src/proto.h | 2 | ||||
| -rw-r--r-- | src/routing.c | 79 | ||||
| -rw-r--r-- | src/routing.h | 6 |
5 files changed, 53 insertions, 48 deletions
@@ -21,11 +21,12 @@ int main(int argc, char** argv) { struct dht dht; dht.self = (struct nodeid){.inner={0xebe9bbf1, 0x3cdba6b3, 0x993e0c87, 0x900d5e25}}; + routing_init(&dht.self); + 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]; int rc = 0; while(rc == 0) { diff --git a/src/proto.c b/src/proto.c index 8f4f737..b518f79 100644 --- a/src/proto.c +++ b/src/proto.c @@ -180,7 +180,7 @@ PROCESS_TIMEOUT(getclient_timeout) { size_t reqId = (typeof(dht->requestdata[0])*)((void*)cont - offsetof(typeof(dht->requestdata[0]), cont)) - dht->requestdata; if(cont->ping.attempt >= 2) { - dbg("Timing out request %d after %d attempts", reqId, cont->ping.attempt); + dbg("Timing out request %ld after %d attempts", reqId, cont->ping.attempt); if(cont->ping.is_new) return 0; @@ -190,7 +190,7 @@ PROCESS_TIMEOUT(getclient_timeout) { return 0; } - dbg("Retrying request %d", reqId); + dbg("Retrying request %ld", reqId); if(*msgbuff->messages >= msgbuff->messages_end) return PROTO_ENOREQ; @@ -320,6 +320,7 @@ PROCESS_REPONSE(getclient_response) { } } else { struct entry* entry = routing_get(&id); + assert(entry != NULL); entry->expire = now + PROTO_UNCTM; } @@ -356,7 +357,6 @@ enum commandType { }; void proto_begin(struct dht* dht, time_t now, struct message** output, const struct message* const output_end) { - routing_flush(); struct msgbuff msgbuff = { output, output_end, @@ -367,7 +367,6 @@ void proto_begin(struct dht* dht, time_t now, struct message** output, const str dht->reqalloc[i] = false; } - routing_init(&dht->self); dbgl_id(&dht->self); dht->sfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); @@ -459,7 +458,7 @@ int handle_packet(struct dht* dht, time_t now, enum commandType type, char* tran assert(*msgbuff->messages < msgbuff->messages_end); struct message* message = *msgbuff->messages; - char* end = message->payload+128; + char* end = message->payload+sizeof(message->payload); char* cursor = message->payload; int rc = snprintf(cursor, end-cursor , "d1:t%ld:", transaction_len); @@ -646,7 +645,7 @@ int proto_run(struct dht* dht, char* buff, size_t recv_len, struct sockaddr_in* } } - dbg("%d/%d requests pending", allocated, MAX_INFLIGHT); + dbg("%ld/%ld requests pending", allocated, MAX_INFLIGHT); } { int filled; diff --git a/src/proto.h b/src/proto.h index 76718de..1bdc05d 100644 --- a/src/proto.h +++ b/src/proto.h @@ -49,7 +49,7 @@ struct dht { }; struct message { - char payload[128]; + char payload[1024]; size_t payload_len; struct sockaddr_storage dest; socklen_t dest_len; diff --git a/src/routing.c b/src/routing.c index d77f87c..313a7cc 100644 --- a/src/routing.c +++ b/src/routing.c @@ -32,22 +32,21 @@ // <----------Detail----------> // -#define IDBITS 160 -#define BUCKETSIZE 8 -// The 3 here is log2(BUCKETSIZE), since the final bucket will contain all those combinations -#define BUCKETBITS 3 -#define ROUTINGSIZE (IDBITS * BUCKETSIZE) +struct table { + struct nodeid myID; + struct entry table[RT_SIZE]; +}; -struct nodeid myID; -struct entry table[ROUTINGSIZE]; +struct table* pTable; void routing_init(struct nodeid* myid) { - myID = *myid; + pTable = malloc(sizeof(struct table)); + pTable->myID = *myid; routing_flush(); } void routing_flush() { - memset(table, 0, sizeof(table)); + memset(pTable->table, 0, sizeof(pTable->table)); } // Calculate the common bit prefix between two node ids. @@ -68,16 +67,16 @@ static uint8_t prefix(struct nodeid* a, struct nodeid* b) { } static int8_t scan(uint16_t baseIndex, struct nodeid* id) { - assert(baseIndex < ROUTINGSIZE - BUCKETSIZE); + assert(baseIndex < RT_SIZE - RT_BSIZE); int8_t index = -2; - for(size_t i = baseIndex; i < baseIndex + BUCKETSIZE; i++) { - if(!table[i].set) { + for(size_t i = baseIndex; i < baseIndex + RT_BSIZE; i++) { + if(!pTable->table[i].set) { index = index == -2 ? i - baseIndex : index; continue; } - if(memcmp(&table[i].id, id, sizeof(struct nodeid)) == 0) { + if(memcmp(&pTable->table[i].id, id, sizeof(struct nodeid)) == 0) { return -1; } } @@ -86,23 +85,23 @@ static int8_t scan(uint16_t baseIndex, struct nodeid* id) { } static uint16_t base_bucket(struct nodeid* id) { - uint16_t bucketIndex = prefix(&myID, id); - assert(bucketIndex != IDBITS); + uint16_t bucketIndex = prefix(&pTable->myID, id); + assert(bucketIndex != RT_IDBITS); // If they are sufficiently similar they end up in the final bucket. Clamp the index to ensure. - bucketIndex = bucketIndex > (IDBITS - BUCKETBITS) ? (IDBITS - BUCKETBITS) : bucketIndex; - assert(bucketIndex <= IDBITS - BUCKETBITS); + bucketIndex = bucketIndex > (RT_IDBITS - RT_BBITS) ? (RT_IDBITS - RT_BBITS) : bucketIndex; + assert(bucketIndex <= RT_IDBITS - RT_BBITS); - return bucketIndex * BUCKETSIZE; + return bucketIndex * RT_BSIZE; } struct entry* routing_get(struct nodeid* id) { uint16_t baseIndex = base_bucket(id); - for(size_t i = baseIndex; i < baseIndex + BUCKETSIZE; i++) { - if(!table[i].set) continue; + for(size_t i = baseIndex; i < baseIndex + RT_BSIZE; i++) { + if(!pTable->table[i].set) continue; - if(memcmp(&table[i].id, id, sizeof(struct nodeid)) == 0) { - return &table[i]; + if(memcmp(&pTable->table[i].id, id, sizeof(struct nodeid)) == 0) { + return &pTable->table[i]; } } @@ -116,9 +115,9 @@ void routing_remove(struct nodeid* id) { } bool routing_interested(struct nodeid* id) { - uint16_t bucketIndex = prefix(&myID, id); + uint16_t bucketIndex = prefix(&pTable->myID, id); // The nodeid is the same as our own - if(bucketIndex == IDBITS) { + if(bucketIndex == RT_IDBITS) { return false; } @@ -135,9 +134,9 @@ bool routing_interested(struct nodeid* id) { // Offer the routing table a new node bool routing_offer(struct nodeid* id, struct entry **dest) { - uint16_t bucketIndex = prefix(&myID, id); + uint16_t bucketIndex = prefix(&pTable->myID, id); // The nodeid is the same as our own - if(bucketIndex == IDBITS) { + if(bucketIndex == RT_IDBITS) { return false; } @@ -149,7 +148,7 @@ bool routing_offer(struct nodeid* id, struct entry **dest) { return false; } - struct entry* entry = &table[baseIndex + inBucketIndex]; + struct entry* entry = &pTable->table[baseIndex + inBucketIndex]; entry->set = true; entry->id = *id; @@ -174,16 +173,16 @@ int compareItem(const void* a_v, const void* b_v) { } size_t routing_closest(struct nodeid* needle, size_t n, struct entry** res) { - assert(n <= ROUTINGSIZE); - static struct item items[ROUTINGSIZE] = {0}; - for(uint16_t i = 0; i < ROUTINGSIZE; i++) { + assert(n <= RT_SIZE); + static struct item items[RT_SIZE] = {0}; + for(uint16_t i = 0; i < RT_SIZE; i++) { items[i].index = i; } { struct item* item; struct entry* entry; - for(item = &items[0], entry = &table[0]; item < &items[ROUTINGSIZE] && entry < &table[ROUTINGSIZE]; item++, entry++){ + for(item = &items[0], entry = &pTable->table[0]; item < &items[RT_SIZE] && entry < &pTable->table[RT_SIZE]; item++, entry++){ item->set = entry->set; for(uint8_t j = 0; j < 5; j++) { item->distance.inner[j] = entry->id.inner[j] ^ needle->inner[j]; @@ -194,13 +193,13 @@ size_t routing_closest(struct nodeid* needle, size_t n, struct entry** res) { // @PERFORMANCE: There's an algorithm known as quickselect which can select // the top k elements from a list while only doing a partial sort. // I imagine that would be more efficient than this full sort. - qsort(items, ROUTINGSIZE, sizeof(struct item), compareItem); + qsort(items, RT_SIZE, sizeof(struct item), compareItem); size_t read; for(read = 0; read < n; read++) { if(!items[read].set) break; - res[read] = &table[items[read].index]; + res[read] = &pTable->table[items[read].index]; } return read; @@ -209,7 +208,7 @@ size_t routing_closest(struct nodeid* needle, size_t n, struct entry** res) { void routing_oldest(struct entry** dest) { *dest = NULL; - for(struct entry* entry = table; entry < table+ROUTINGSIZE; entry++){ + for(struct entry* entry = pTable->table; entry < pTable->table+RT_SIZE; entry++){ if(!entry->set) continue; @@ -228,17 +227,17 @@ void routing_oldest(struct entry** dest) { } void routing_status(int* filled, int* size, double* load_factor, size_t load_factor_len) { - *size = ROUTINGSIZE; + *size = RT_SIZE; *filled = 0; - for(size_t i = 0; i < ROUTINGSIZE; i++) { - if(table[i].set) + for(size_t i = 0; i < RT_SIZE; i++) { + if(pTable->table[i].set) (*filled)++; } - int per_bucket = ROUTINGSIZE / load_factor_len; - int overflow = ROUTINGSIZE % load_factor_len; - struct entry* table_cursor = table; + int per_bucket = RT_SIZE / load_factor_len; + int overflow = RT_SIZE % load_factor_len; + struct entry* table_cursor = pTable->table; for(int i = 0; i < load_factor_len; i++) { int is_overflow = i < overflow; for(int j = 0; j < per_bucket + is_overflow; j++) { diff --git a/src/routing.h b/src/routing.h index a7cd8c6..f4164fe 100644 --- a/src/routing.h +++ b/src/routing.h @@ -6,6 +6,12 @@ #include <time.h> #include <stdio.h> +#define RT_IDBITS 160 +#define RT_BSIZE 8 +// The 3 here is log2(BUCKETSIZE), since the final bucket will contain all those combinations +#define RT_BBITS 3 +#define RT_SIZE (RT_IDBITS * RT_BSIZE) + struct addr { uint32_t ip; uint16_t port; |
