forked from servalproject/serval-dna
-
Notifications
You must be signed in to change notification settings - Fork 0
/
directory_client.c
123 lines (95 loc) · 3.71 KB
/
directory_client.c
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
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
Serval Directory Service client
When servald starts, load the SID, IP (or domain name) & port of a directory server.
When an interface comes up with a route to this server, and periodically thereafter,
send our SID name and number to the configured server.
When we perform a lookup, send an additional copy of the request to the directory server.
*/
#include "serval.h"
#include "str.h"
#include "overlay_address.h"
#include "conf.h"
struct subscriber *directory_service;
static void directory_update(struct sched_ent *alarm);
static struct profile_total directory_timing={
.name="directory_update",
};
struct sched_ent directory_alarm={
.function=directory_update,
.stats=&directory_timing,
};
#define DIRECTORY_UPDATE_INTERVAL 120000
// send a registration packet
static void directory_send(struct subscriber *directory_service, const unsigned char *sid, const char *did, const char *name){
overlay_mdp_frame request;
memset(&request, 0, sizeof(overlay_mdp_frame));
request.packetTypeAndFlags = MDP_TX;
bcopy(sid, request.out.src.sid, SID_SIZE);
request.out.src.port=MDP_PORT_NOREPLY;
request.out.queue=OQ_ORDINARY;
bcopy(directory_service->sid, request.out.dst.sid, SID_SIZE);
request.out.dst.port=MDP_PORT_DIRECTORY;
request.out.payload_length = snprintf((char *)request.out.payload, sizeof(request.out.payload),
"%s|%s", did, name);
// Used by tests
INFOF("Sending directory registration for %s, %s, %s to %s",
alloca_tohex(sid,7), did, name, alloca_tohex(directory_service->sid, 7));
overlay_mdp_dispatch(&request, 0, NULL, 0);
}
// send a registration packet for each unlocked identity
static void directory_send_keyring(struct subscriber *directory_service){
int cn=0, in=0, kp=0, k2;
for (; !keyring_sanitise_position(keyring, &cn, &in, &kp); ++kp){
keyring_identity *i = keyring->contexts[cn]->identities[in];
if (i->keypairs[kp]->type == KEYTYPE_CRYPTOBOX){
const unsigned char *packedSid = i->keypairs[0]->public_key;
for(k2=0; k2 < i->keypair_count; k2++){
if (i->keypairs[k2]->type==KEYTYPE_DID){
const char *unpackedDid = (const char *) i->keypairs[k2]->private_key;
const char *name = (const char *) i->keypairs[k2]->public_key;
directory_send(directory_service, packedSid, unpackedDid, name);
// send the first DID only
break;
}
}
}
}
}
static int load_directory_config()
{
if (!directory_service && !is_sid_any(config.directory.service.binary)) {
directory_service = find_subscriber(config.directory.service.binary, SID_SIZE, 1);
if (!directory_service)
return WHYF("Failed to create subscriber record");
// used by tests
INFOF("ADD DIRECTORY SERVICE %s", alloca_tohex_sid(directory_service->sid));
}
// always attempt to reload the address, may depend on DNS resolution
return load_subscriber_address(directory_service);
}
static void directory_update(struct sched_ent *alarm){
load_directory_config();
if (directory_service){
if (subscriber_is_reachable(directory_service) & REACHABLE){
directory_send_keyring(directory_service);
unschedule(alarm);
alarm->alarm = gettime_ms() + DIRECTORY_UPDATE_INTERVAL;
alarm->deadline = alarm->alarm + 10000;
schedule(alarm);
}else
DEBUGF("Directory service is not reachable");
}
}
int directory_service_init(){
directory_update(&directory_alarm);
return 0;
}
// called when we discover a route to the directory service SID
int directory_registration(){
// give the route & SAS keys a moment to propagate
unschedule(&directory_alarm);
directory_alarm.alarm = gettime_ms() + 200;
directory_alarm.deadline = directory_alarm.alarm + 10000;
schedule(&directory_alarm);
return 0;
}