summaryrefslogtreecommitdiff
path: root/src/proto.h
blob: 328c9ca4486349182bb82ce0d5731f011a4f26b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#pragma once 

#include "routing.h"
#include "sha256.h"
#include <sys/socket.h>
#include <arpa/inet.h>

#define TOKEN_ITMO 20
#define TOKEN_VTMO 60
#define TOKEN_TLEN 32
#define TOKEN_KNUM (TOKEN_VTMO/TOKEN_ITMO)

#define TOK_VALI 1
#define TOK_INVA 0

struct tokens {
	SHA256_CTX ctx;

	char ticket[TOKEN_KNUM][TOKEN_TLEN];
	time_t issued[TOKEN_KNUM];
	size_t head;
};

enum Operation {
	OP_EMPTY,
	OP_PENDING,
	OP_ACTIVE,
	OP_COMPLETED,
};

struct lookup {
	enum Operation state;
	struct nodeid target;

	struct nodeid closest[8];
	struct addr closest_addr[8];

	time_t timeout;
};

void token_create(struct tokens* tokens, time_t now, struct addr* remote, char* token);
int token_validate(struct tokens* tokens, time_t now, struct addr* remote, char* token);

// 192.0.2.0
#define UNDEF_ADDR (struct in_addr){0xC0000200}
#define MAX_DISC 32
#define MAX_INFLIGHT 128

#define PROTO_UNCTM 60*5
#define PROTO_TMOUT 30

struct ping {
	struct nodeid remote_id;
	int attempt;
	bool is_new;
};

union message_cont {
	struct ping ping;
	struct lookup *lookup;
};

struct dht;
struct msgbuff {
	struct message** messages;
	const struct message* const messages_end;
};


#define PROCESS_REPONSE(NAME) int (NAME)(struct dht* dht, time_t now, union message_cont* cont, char* packet, size_t packet_len, int socket, struct sockaddr* remote, socklen_t remote_len, struct msgbuff* msgbuff)
typedef PROCESS_REPONSE(resp);

#define PROCESS_TIMEOUT(NAME) int (NAME)(struct dht* dht, struct nodeid* self, time_t now, union message_cont* cont, struct msgbuff* msgbuff)
typedef PROCESS_TIMEOUT(tmout);

struct dht {
	struct nodeid self;
	int sfd;

	bool pause;

	bool reqalloc[MAX_INFLIGHT];
	struct {
		struct sockaddr_storage addr;
		socklen_t addr_len;
		resp* fun;
		time_t timeout;
		tmout* timeout_fun;
		union message_cont cont;
	} requestdata[MAX_INFLIGHT];

	struct lookup lookup;

	time_t wake;
	struct tokens tokens;
};

struct message {
	char payload[1024];
	size_t payload_len;
	struct sockaddr_storage dest;
	socklen_t dest_len;
};

int send_lookup(struct dht* dht, struct nodeid* target, time_t now, const struct sockaddr* dest_addr, socklen_t dest_len, struct msgbuff* msgbuff);

void proto_begin(struct dht* dht, time_t now, struct message** output, const struct message* const output_end);
int proto_run(struct dht* dht, char* buffer, size_t buffer_len, struct sockaddr_in* remote, socklen_t remote_len, time_t now, struct message** output, const struct message* const output_end);
void proto_end(struct dht* dht);