mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-02-02 17:21:11 +00:00
Merge branch 'development' into install-target
This commit is contained in:
commit
ad21cef345
@ -2614,9 +2614,9 @@ struct cli_schema command_line_options[]={
|
||||
"Return identity(s) as URIs of own node, or of known routable peers, or all known peers"},
|
||||
{app_id_pin, {"id", "enter", "pin", "<entry-pin>", NULL}, 0,
|
||||
"Unlock any pin protected identities and enable routing packets to them"},
|
||||
{app_revoke_pin, {"id", "revoke", "pin", "<entry-pin>", NULL}, 0,
|
||||
{app_revoke_pin, {"id", "relinquish", "pin", "<entry-pin>", NULL}, 0,
|
||||
"Unload any identities protected by this pin and drop all routes to them"},
|
||||
{app_revoke_pin, {"id", "revoke", "sid", "<sid>", NULL}, 0,
|
||||
{app_revoke_pin, {"id", "relinquish", "sid", "<sid>", NULL}, 0,
|
||||
"Unload a specific identity and drop all routes to it"},
|
||||
{app_route_print, {"route","print",NULL}, 0,
|
||||
"Print the routing table"},
|
||||
|
@ -215,4 +215,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#define ENCAP_OVERLAY 1
|
||||
#define ENCAP_SINGLE 2
|
||||
|
||||
// numbers chosen to not conflict with KEYTYPE flags
|
||||
#define UNLOCK_REQUEST (0xF0)
|
||||
#define UNLOCK_CHALLENGE (0xF1)
|
||||
#define UNLOCK_RESPONSE (0xF2)
|
||||
|
||||
|
||||
#endif // __SERVALD_CONSTANTS_H
|
||||
|
3
crypto.c
3
crypto.c
@ -43,6 +43,9 @@ int crypto_verify_message(struct subscriber *subscriber, unsigned char *message,
|
||||
return WHY("SAS key not currently on record, cannot verify");
|
||||
}
|
||||
|
||||
if (*message_len < SIGNATURE_BYTES)
|
||||
return WHY("Message is too short to include a signature");
|
||||
|
||||
*message_len -= SIGNATURE_BYTES;
|
||||
|
||||
unsigned char hash[crypto_hash_sha512_BYTES];
|
||||
|
222
keyring.c
222
keyring.c
@ -27,6 +27,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "rhizome.h"
|
||||
#include "nacl.h"
|
||||
#include "overlay_address.h"
|
||||
#include "crypto.h"
|
||||
#include "overlay_packet.h"
|
||||
|
||||
static void keyring_free_keypair(keypair *kp);
|
||||
static void keyring_free_context(keyring_context *c);
|
||||
@ -182,11 +184,12 @@ static void add_subscriber(keyring_identity *id, unsigned keypair)
|
||||
assert(id->keypairs[keypair]->type == KEYTYPE_CRYPTOBOX);
|
||||
id->subscriber = find_subscriber(id->keypairs[keypair]->public_key, SID_SIZE, 1);
|
||||
if (id->subscriber) {
|
||||
if (id->subscriber->reachable == REACHABLE_NONE)
|
||||
if (id->subscriber->reachable == REACHABLE_NONE){
|
||||
id->subscriber->reachable = REACHABLE_SELF;
|
||||
if (!my_subscriber)
|
||||
my_subscriber = id->subscriber;
|
||||
}
|
||||
id->subscriber->identity = id;
|
||||
if (!my_subscriber)
|
||||
my_subscriber = id->subscriber;
|
||||
}
|
||||
}
|
||||
|
||||
@ -248,6 +251,14 @@ void keyring_release_identity(keyring_file *k, int cn, int id){
|
||||
}
|
||||
}
|
||||
|
||||
void keyring_release_subscriber(keyring_file *k, const sid_t *sid)
|
||||
{
|
||||
int cn=0,in=0,kp=0;
|
||||
if (keyring_find_sid(keyring, &cn, &in, &kp, sid)
|
||||
&& keyring->contexts[cn]->identities[in]->subscriber != my_subscriber)
|
||||
keyring_release_identity(keyring, cn, in);
|
||||
}
|
||||
|
||||
static void keyring_free_context(keyring_context *c)
|
||||
{
|
||||
int i;
|
||||
@ -288,11 +299,8 @@ void keyring_free_identity(keyring_identity *id)
|
||||
for(i=0;i<PKR_MAX_KEYPAIRS;i++)
|
||||
if (id->keypairs[i])
|
||||
keyring_free_keypair(id->keypairs[i]);
|
||||
if (id->subscriber) {
|
||||
id->subscriber->identity=NULL;
|
||||
if (id->subscriber->reachable == REACHABLE_SELF)
|
||||
id->subscriber->reachable = REACHABLE_NONE;
|
||||
}
|
||||
if (id->subscriber)
|
||||
link_stop_routing(id->subscriber);
|
||||
bzero(id,sizeof(keyring_identity));
|
||||
free(id);
|
||||
return;
|
||||
@ -1569,7 +1577,137 @@ static int keyring_store_sas(overlay_mdp_frame *req)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int keyring_mapping_request(keyring_file *k, overlay_mdp_frame *req)
|
||||
static int keyring_respond_sas(keyring_file *k, overlay_mdp_frame *req)
|
||||
{
|
||||
/* It's a request, so find the SAS for the SID the request was addressed to,
|
||||
use that to sign that SID, and then return it in an authcrypted frame. */
|
||||
unsigned char *sas_public=NULL;
|
||||
unsigned char *sas_priv =keyring_find_sas_private(k, &req->out.dst.sid, &sas_public);
|
||||
|
||||
if ((!sas_priv)||(!sas_public))
|
||||
return WHY("I don't have that SAS key");
|
||||
|
||||
unsigned long long slen;
|
||||
/* type of key being verified */
|
||||
req->out.payload[0]=KEYTYPE_CRYPTOSIGN;
|
||||
/* the public key itself */
|
||||
bcopy(sas_public,&req->out.payload[1], SAS_SIZE);
|
||||
/* and a signature of the SID using the SAS key, to prove possession of
|
||||
the key. Possession of the SID has already been established by the
|
||||
decrypting of the surrounding MDP packet.
|
||||
XXX - We could chop the SID out of the middle of the signed block here,
|
||||
just as we do for signed MDP packets to save 32 bytes. We won't worry
|
||||
about doing this, however, as the mapping process is only once per session,
|
||||
not once per packet. Unless I get excited enough to do it, that is.
|
||||
*/
|
||||
if (crypto_sign_edwards25519sha512batch(&req->out.payload[1+SAS_SIZE], &slen, req->out.dst.sid.binary, SID_SIZE, sas_priv))
|
||||
return WHY("crypto_sign() failed");
|
||||
/* chop the SID from the end of the signature, since it can be reinserted on reception */
|
||||
slen-=SID_SIZE;
|
||||
/* and record the full length of this */
|
||||
req->out.payload_length = 1 + SAS_SIZE + slen;
|
||||
overlay_mdp_swap_src_dst(req);
|
||||
req->out.ttl=0;
|
||||
req->packetTypeAndFlags=MDP_TX; /* crypt and sign */
|
||||
req->out.queue=OQ_MESH_MANAGEMENT;
|
||||
if (config.debug.keyring)
|
||||
DEBUGF("Sending SID:SAS mapping, %d bytes, %s:%"PRImdp_port_t" -> %s:%"PRImdp_port_t,
|
||||
req->out.payload_length,
|
||||
alloca_tohex_sid_t(req->out.src.sid), req->out.src.port,
|
||||
alloca_tohex_sid_t(req->out.dst.sid), req->out.dst.port
|
||||
);
|
||||
return overlay_mdp_dispatch(req,0,NULL,0);
|
||||
}
|
||||
|
||||
// someone else is claiming to be me on this network
|
||||
// politely request that they release my identity
|
||||
int keyring_send_unlock(struct subscriber *subscriber)
|
||||
{
|
||||
if (!subscriber->identity)
|
||||
return WHY("Cannot unlock an identity we don't have in our keyring");
|
||||
if (subscriber->reachable==REACHABLE_SELF)
|
||||
return 0;
|
||||
|
||||
overlay_mdp_frame mdp;
|
||||
memset(&mdp,0,sizeof(overlay_mdp_frame));
|
||||
|
||||
mdp.packetTypeAndFlags=MDP_TX;
|
||||
mdp.out.queue=OQ_MESH_MANAGEMENT;
|
||||
mdp.out.dst.sid = subscriber->sid;
|
||||
mdp.out.dst.port=MDP_PORT_KEYMAPREQUEST;
|
||||
mdp.out.src.port=MDP_PORT_KEYMAPREQUEST;
|
||||
mdp.out.src.sid = my_subscriber->sid;
|
||||
mdp.out.payload[0]=UNLOCK_REQUEST;
|
||||
int len=1;
|
||||
if (crypto_sign_message(subscriber, mdp.out.payload, sizeof(mdp.out.payload), &len))
|
||||
return -1;
|
||||
mdp.out.payload_length=len;
|
||||
return overlay_mdp_dispatch(&mdp, 0 /* system generated */, NULL, 0);
|
||||
}
|
||||
|
||||
static int keyring_send_challenge(struct subscriber *source, struct subscriber *dest)
|
||||
{
|
||||
overlay_mdp_frame mdp;
|
||||
memset(&mdp,0,sizeof(overlay_mdp_frame));
|
||||
|
||||
mdp.packetTypeAndFlags=MDP_TX;
|
||||
mdp.out.queue=OQ_MESH_MANAGEMENT;
|
||||
mdp.out.dst.sid = dest->sid;
|
||||
mdp.out.dst.port=MDP_PORT_KEYMAPREQUEST;
|
||||
mdp.out.src.port=MDP_PORT_KEYMAPREQUEST;
|
||||
mdp.out.src.sid = source->sid;
|
||||
mdp.out.payload_length=1;
|
||||
mdp.out.payload[0]=UNLOCK_CHALLENGE;
|
||||
|
||||
time_ms_t now = gettime_ms();
|
||||
if (source->identity->challenge_expires < now){
|
||||
source->identity->challenge_expires = now + 5000;
|
||||
urandombytes(source->identity->challenge, sizeof(source->identity->challenge));
|
||||
}
|
||||
bcopy(source->identity->challenge, &mdp.out.payload[1], sizeof(source->identity->challenge));
|
||||
mdp.out.payload_length+=sizeof(source->identity->challenge);
|
||||
|
||||
return overlay_mdp_dispatch(&mdp, 0 /* system generated */, NULL, 0);
|
||||
}
|
||||
|
||||
static int keyring_respond_challenge(struct subscriber *subscriber, overlay_mdp_frame *req)
|
||||
{
|
||||
if (!subscriber->identity)
|
||||
return WHY("Cannot unlock an identity we don't have in our keyring");
|
||||
if (subscriber->reachable==REACHABLE_SELF)
|
||||
return 0;
|
||||
overlay_mdp_frame mdp;
|
||||
memset(&mdp,0,sizeof(overlay_mdp_frame));
|
||||
|
||||
mdp.packetTypeAndFlags=MDP_TX;
|
||||
mdp.out.queue=OQ_MESH_MANAGEMENT;
|
||||
mdp.out.dst.sid = subscriber->sid;
|
||||
mdp.out.dst.port=MDP_PORT_KEYMAPREQUEST;
|
||||
mdp.out.src.port=MDP_PORT_KEYMAPREQUEST;
|
||||
mdp.out.src.sid = my_subscriber->sid;
|
||||
mdp.out.payload[0]=UNLOCK_RESPONSE;
|
||||
bcopy(&req->out.payload[1], &mdp.out.payload[1], req->out.payload_length -1);
|
||||
int len=req->out.payload_length;
|
||||
if (crypto_sign_message(subscriber, mdp.out.payload, sizeof(mdp.out.payload), &len))
|
||||
return -1;
|
||||
mdp.out.payload_length=len;
|
||||
return overlay_mdp_dispatch(&mdp, 0 /* system generated */, NULL, 0);
|
||||
}
|
||||
|
||||
static int keyring_process_challenge(keyring_file *k, struct subscriber *subscriber, overlay_mdp_frame *req)
|
||||
{
|
||||
time_ms_t now = gettime_ms();
|
||||
if (subscriber->identity->challenge_expires < now)
|
||||
return WHY("Identity challenge has already expired");
|
||||
if (req->out.payload_length-1 != sizeof(subscriber->identity->challenge))
|
||||
return WHY("Challenge was not the right size");
|
||||
if (memcmp(&req->out.payload[1], subscriber->identity->challenge, sizeof(subscriber->identity->challenge)))
|
||||
return WHY("Challenge failed");
|
||||
keyring_release_subscriber(k, &subscriber->sid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int keyring_mapping_request(keyring_file *k, struct overlay_frame *frame, overlay_mdp_frame *req)
|
||||
{
|
||||
if (!k) return WHY("keyring is null");
|
||||
if (!req) return WHY("req is null");
|
||||
@ -1578,46 +1716,32 @@ int keyring_mapping_request(keyring_file *k, overlay_mdp_frame *req)
|
||||
owner of the SID, and so is absolutely compulsory. */
|
||||
if (req->packetTypeAndFlags&(MDP_NOCRYPT|MDP_NOSIGN))
|
||||
return WHY("mapping requests must be performed under authcryption");
|
||||
|
||||
if (req->out.payload_length==1) {
|
||||
/* It's a request, so find the SAS for the SID the request was addressed to,
|
||||
use that to sign that SID, and then return it in an authcrypted frame. */
|
||||
unsigned char *sas_public=NULL;
|
||||
unsigned char *sas_priv =keyring_find_sas_private(keyring, &req->out.dst.sid, &sas_public);
|
||||
|
||||
if ((!sas_priv)||(!sas_public)) return WHY("I don't have that SAS key");
|
||||
unsigned long long slen;
|
||||
/* type of key being verified */
|
||||
req->out.payload[0]=KEYTYPE_CRYPTOSIGN;
|
||||
/* the public key itself */
|
||||
bcopy(sas_public,&req->out.payload[1], SAS_SIZE);
|
||||
/* and a signature of the SID using the SAS key, to prove possession of
|
||||
the key. Possession of the SID has already been established by the
|
||||
decrypting of the surrounding MDP packet.
|
||||
XXX - We could chop the SID out of the middle of the signed block here,
|
||||
just as we do for signed MDP packets to save 32 bytes. We won't worry
|
||||
about doing this, however, as the mapping process is only once per session,
|
||||
not once per packet. Unless I get excited enough to do it, that is.
|
||||
*/
|
||||
if (crypto_sign_edwards25519sha512batch(&req->out.payload[1+SAS_SIZE], &slen, req->out.dst.sid.binary, SID_SIZE, sas_priv))
|
||||
return WHY("crypto_sign() failed");
|
||||
/* chop the SID from the end of the signature, since it can be reinserted on reception */
|
||||
slen-=SID_SIZE;
|
||||
/* and record the full length of this */
|
||||
req->out.payload_length = 1 + SAS_SIZE + slen;
|
||||
overlay_mdp_swap_src_dst(req);
|
||||
req->out.ttl=0;
|
||||
req->packetTypeAndFlags=MDP_TX; /* crypt and sign */
|
||||
req->out.queue=OQ_MESH_MANAGEMENT;
|
||||
if (config.debug.keyring)
|
||||
DEBUGF("Sending SID:SAS mapping, %d bytes, %s:%"PRImdp_port_t" -> %s:%"PRImdp_port_t,
|
||||
req->out.payload_length,
|
||||
alloca_tohex_sid_t(req->out.src.sid), req->out.src.port,
|
||||
alloca_tohex_sid_t(req->out.dst.sid), req->out.dst.port
|
||||
);
|
||||
return overlay_mdp_dispatch(req,0,NULL,0);
|
||||
} else {
|
||||
return keyring_store_sas(req);
|
||||
|
||||
switch(req->out.payload[0]){
|
||||
case KEYTYPE_CRYPTOSIGN:
|
||||
if (req->out.payload_length==1)
|
||||
return keyring_respond_sas(k, req);
|
||||
else
|
||||
return keyring_store_sas(req);
|
||||
break;
|
||||
case UNLOCK_REQUEST:
|
||||
{
|
||||
int len = req->out.payload_length;
|
||||
if (crypto_verify_message(frame->destination, req->out.payload, &len))
|
||||
return WHY("Signature check failed");
|
||||
req->out.payload_length = len;
|
||||
}
|
||||
return keyring_send_challenge(frame->destination, frame->source);
|
||||
case UNLOCK_CHALLENGE:
|
||||
return keyring_respond_challenge(frame->source, req);
|
||||
case UNLOCK_RESPONSE:
|
||||
{
|
||||
int len = req->out.payload_length;
|
||||
if (crypto_verify_message(frame->destination, req->out.payload, &len))
|
||||
return WHY("Signature check failed");
|
||||
req->out.payload_length = len;
|
||||
}
|
||||
return keyring_process_challenge(k, frame->destination, req);
|
||||
}
|
||||
return WHY("Not implemented");
|
||||
}
|
||||
|
@ -1000,10 +1000,7 @@ static int mdp_process_identity_request(struct mdp_client *client, struct mdp_he
|
||||
break;
|
||||
case TYPE_SID:
|
||||
while(payload_len>=SID_SIZE){
|
||||
int cn=0,in=0,kp=0;
|
||||
if (keyring_find_sid(keyring, &cn, &in, &kp, (const sid_t *)payload)
|
||||
&& keyring->contexts[cn]->identities[in]->subscriber != my_subscriber)
|
||||
keyring_release_identity(keyring, cn, in);
|
||||
keyring_release_subscriber(keyring, (const sid_t*)payload);
|
||||
payload+=SID_SIZE;
|
||||
payload_len-=SID_SIZE;
|
||||
}
|
||||
|
@ -374,7 +374,7 @@ int overlay_mdp_try_interal_services(struct overlay_frame *frame, overlay_mdp_fr
|
||||
switch(mdp->out.dst.port) {
|
||||
case MDP_PORT_LINKSTATE: RETURN(link_receive(frame, mdp));
|
||||
case MDP_PORT_VOMP: RETURN(vomp_mdp_received(mdp));
|
||||
case MDP_PORT_KEYMAPREQUEST: RETURN(keyring_mapping_request(keyring,mdp));
|
||||
case MDP_PORT_KEYMAPREQUEST: RETURN(keyring_mapping_request(keyring, frame, mdp));
|
||||
case MDP_PORT_DNALOOKUP: RETURN(overlay_mdp_service_dnalookup(mdp));
|
||||
case MDP_PORT_ECHO: RETURN(overlay_mdp_service_echo(mdp));
|
||||
case MDP_PORT_TRACE: RETURN(overlay_mdp_service_trace(mdp));
|
||||
|
@ -103,7 +103,7 @@ int rhizome_bundle_import_files(rhizome_manifest *m, const char *manifest_path,
|
||||
if (ret==0){
|
||||
buffer_len = read_uint16(marker);
|
||||
if (buffer_len < 1 || buffer_len > MAX_MANIFEST_BYTES)
|
||||
ret=WHYF("Invalid manifest length %d", buffer_len);
|
||||
ret=WHYF("Invalid manifest length %zd", buffer_len);
|
||||
}
|
||||
|
||||
if (ret==0){
|
||||
|
@ -93,7 +93,7 @@ ssize_t read_whole_file(const char *path, unsigned char *buffer, size_t buffer_s
|
||||
return WHYF_perror("open(%s,O_RDONLY)", alloca_str_toprint(path));
|
||||
ssize_t ret = read(fd, buffer, buffer_size);
|
||||
if (ret == -1)
|
||||
ret = WHYF_perror("read(%s,%u)", alloca_str_toprint(path), buffer_size);
|
||||
ret = WHYF_perror("read(%s,%zu)", alloca_str_toprint(path), buffer_size);
|
||||
if (close(fd) == -1)
|
||||
ret = WHY_perror("close");
|
||||
return ret;
|
||||
@ -367,7 +367,7 @@ int rhizome_hash_file(rhizome_manifest *m, const char *path, rhizome_filehash_t
|
||||
ssize_t r;
|
||||
while ((r = read(fd, buffer, sizeof buffer))) {
|
||||
if (r == -1) {
|
||||
WHYF_perror("read(%s,%u)", alloca_str_toprint(path), sizeof buffer);
|
||||
WHYF_perror("read(%s,%zu)", alloca_str_toprint(path), sizeof buffer);
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
@ -661,7 +661,7 @@ int _sqlite_vbind(struct __sourceloc __whence, int log_level, sqlite_retry_state
|
||||
BIND_NULL(SID_T);
|
||||
} else {
|
||||
const char *sid_hex = alloca_tohex_sid_t(*sidp);
|
||||
BIND_DEBUG(SID_T, sqlite3_bind_text, "%s,%d,SQLITE_TRANSIENT", sid_hex, SID_STRLEN);
|
||||
BIND_DEBUG(SID_T, sqlite3_bind_text, "%s,%u,SQLITE_TRANSIENT", sid_hex, SID_STRLEN);
|
||||
BIND_RETRY(sqlite3_bind_text, sid_hex, SID_STRLEN, SQLITE_TRANSIENT);
|
||||
}
|
||||
}
|
||||
@ -673,7 +673,7 @@ int _sqlite_vbind(struct __sourceloc __whence, int log_level, sqlite_retry_state
|
||||
BIND_NULL(RHIZOME_BID_T);
|
||||
} else {
|
||||
const char *bid_hex = alloca_tohex_rhizome_bid_t(*bidp);
|
||||
BIND_DEBUG(RHIZOME_BID_T, sqlite3_bind_text, "%s,%d,SQLITE_TRANSIENT", bid_hex, RHIZOME_MANIFEST_ID_STRLEN);
|
||||
BIND_DEBUG(RHIZOME_BID_T, sqlite3_bind_text, "%s,%u,SQLITE_TRANSIENT", bid_hex, RHIZOME_MANIFEST_ID_STRLEN);
|
||||
BIND_RETRY(sqlite3_bind_text, bid_hex, RHIZOME_MANIFEST_ID_STRLEN, SQLITE_TRANSIENT);
|
||||
}
|
||||
}
|
||||
@ -686,7 +686,7 @@ int _sqlite_vbind(struct __sourceloc __whence, int log_level, sqlite_retry_state
|
||||
} else {
|
||||
char hash_hex[RHIZOME_FILEHASH_STRLEN];
|
||||
tohex(hash_hex, sizeof hash_hex, hashp->binary);
|
||||
BIND_DEBUG(RHIZOME_FILEHASH_T, sqlite3_bind_text, "%s,%d,SQLITE_TRANSIENT", hash_hex, sizeof hash_hex);
|
||||
BIND_DEBUG(RHIZOME_FILEHASH_T, sqlite3_bind_text, "%s,%zu,SQLITE_TRANSIENT", hash_hex, sizeof hash_hex);
|
||||
BIND_RETRY(sqlite3_bind_text, hash_hex, sizeof hash_hex, SQLITE_TRANSIENT);
|
||||
}
|
||||
}
|
||||
@ -699,7 +699,7 @@ int _sqlite_vbind(struct __sourceloc __whence, int log_level, sqlite_retry_state
|
||||
BIND_NULL(TOHEX);
|
||||
} else {
|
||||
const char *hex = alloca_tohex(binary, bytes);
|
||||
BIND_DEBUG(TOHEX, sqlite3_bind_text, "%s,%d,SQLITE_TRANSIENT", hex, bytes * 2);
|
||||
BIND_DEBUG(TOHEX, sqlite3_bind_text, "%s,%u,SQLITE_TRANSIENT", hex, bytes * 2);
|
||||
BIND_RETRY(sqlite3_bind_text, hex, bytes * 2, SQLITE_TRANSIENT);
|
||||
}
|
||||
}
|
||||
@ -713,7 +713,7 @@ int _sqlite_vbind(struct __sourceloc __whence, int log_level, sqlite_retry_state
|
||||
unsigned bytes = strlen(text);
|
||||
char upper[bytes + 1];
|
||||
str_toupper_inplace(strcpy(upper, text));
|
||||
BIND_DEBUG(TEXT_TOUPPER, sqlite3_bind_text, "%s,%d,SQLITE_TRANSIENT", alloca_toprint(-1, upper, bytes), bytes);
|
||||
BIND_DEBUG(TEXT_TOUPPER, sqlite3_bind_text, "%s,%u,SQLITE_TRANSIENT", alloca_toprint(-1, upper, bytes), bytes);
|
||||
BIND_RETRY(sqlite3_bind_text, upper, bytes, SQLITE_TRANSIENT);
|
||||
}
|
||||
}
|
||||
@ -729,7 +729,7 @@ int _sqlite_vbind(struct __sourceloc __whence, int log_level, sqlite_retry_state
|
||||
unsigned i;
|
||||
for (i = 0; i != bytes; ++i)
|
||||
upper[i] = toupper(text[i]);
|
||||
BIND_DEBUG(TEXT_LEN_TOUPPER, sqlite3_bind_text, "%s,%d,SQLITE_TRANSIENT", alloca_toprint(-1, upper, bytes), bytes);
|
||||
BIND_DEBUG(TEXT_LEN_TOUPPER, sqlite3_bind_text, "%s,%u,SQLITE_TRANSIENT", alloca_toprint(-1, upper, bytes), bytes);
|
||||
BIND_RETRY(sqlite3_bind_text, upper, bytes, SQLITE_TRANSIENT);
|
||||
}
|
||||
}
|
||||
|
31
route_link.c
31
route_link.c
@ -357,7 +357,7 @@ static struct link * find_best_link(struct subscriber *subscriber)
|
||||
IN();
|
||||
if (subscriber->reachable==REACHABLE_SELF)
|
||||
RETURN(NULL);
|
||||
|
||||
|
||||
struct link_state *state = get_link_state(subscriber);
|
||||
if (state->route_version == route_version)
|
||||
RETURN(state->link);
|
||||
@ -420,11 +420,14 @@ next:
|
||||
|
||||
if (next_hop == subscriber)
|
||||
next_hop = NULL;
|
||||
|
||||
if (set_reachable(subscriber, destination, next_hop))
|
||||
changed = 1;
|
||||
|
||||
if (subscriber->identity && subscriber->reachable==REACHABLE_NONE){
|
||||
if (subscriber->identity && subscriber->reachable == REACHABLE_NONE){
|
||||
subscriber->reachable=REACHABLE_SELF;
|
||||
changed = 1;
|
||||
best_link = NULL;
|
||||
if (config.debug.overlayrouting || config.debug.linkstate)
|
||||
DEBUGF("REACHABLE via self %s", alloca_tohex_sid_t(subscriber->sid));
|
||||
}
|
||||
@ -519,6 +522,8 @@ static int append_link(struct subscriber *subscriber, void *context)
|
||||
|
||||
time_ms_t now = gettime_ms();
|
||||
|
||||
struct link *best_link = find_best_link(subscriber);
|
||||
|
||||
if (subscriber->reachable==REACHABLE_SELF){
|
||||
if (state->next_update - INCLUDE_ANYWAY <= now){
|
||||
// Other entries in our keyring are always one hop away from us.
|
||||
@ -530,8 +535,10 @@ static int append_link(struct subscriber *subscriber, void *context)
|
||||
state->next_update = now + 5000;
|
||||
}
|
||||
} else {
|
||||
struct link *best_link = find_best_link(subscriber);
|
||||
|
||||
|
||||
if (subscriber->identity)
|
||||
keyring_send_unlock(subscriber);
|
||||
|
||||
if (state->next_update - INCLUDE_ANYWAY <= now){
|
||||
if (append_link_state(payload, 0, state->transmitter, subscriber, -1,
|
||||
best_link?best_link->link_version:-1, -1, 0, best_link?best_link->drop_rate:32)){
|
||||
@ -909,6 +916,20 @@ static void update_alarm(time_ms_t limit){
|
||||
}
|
||||
}
|
||||
|
||||
int link_stop_routing(struct subscriber *subscriber)
|
||||
{
|
||||
if (subscriber->reachable!=REACHABLE_SELF)
|
||||
return 0;
|
||||
subscriber->reachable = REACHABLE_NONE;
|
||||
subscriber->identity=NULL;
|
||||
if (subscriber==my_subscriber)
|
||||
my_subscriber=NULL;
|
||||
struct link_state *state = get_link_state(subscriber);
|
||||
state->next_update = gettime_ms();
|
||||
update_alarm(state->next_update);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct link_in * get_neighbour_link(struct neighbour *neighbour, struct overlay_interface *interface, int sender_interface, int unicast)
|
||||
{
|
||||
struct link_in *link = neighbour->links;
|
||||
@ -1174,7 +1195,7 @@ int link_received_packet(struct decode_context *context, int sender_seq, char un
|
||||
|
||||
// force an update when we start hearing a new neighbour link
|
||||
if (link->link_timeout < now){
|
||||
if (neighbour->next_neighbour_update > now + 10);
|
||||
if (neighbour->next_neighbour_update > now + 10)
|
||||
neighbour->next_neighbour_update = now + 10;
|
||||
}
|
||||
link->link_timeout = now + (context->interface->destination->tick_ms *5);
|
||||
|
7
serval.h
7
serval.h
@ -263,6 +263,8 @@ typedef struct keypair {
|
||||
typedef struct keyring_identity {
|
||||
char *PKRPin;
|
||||
struct subscriber *subscriber;
|
||||
time_ms_t challenge_expires;
|
||||
unsigned char challenge[24];
|
||||
unsigned int slot;
|
||||
unsigned int keypair_count;
|
||||
keypair *keypairs[PKR_MAX_KEYPAIRS];
|
||||
@ -700,7 +702,9 @@ typedef struct overlay_mdp_frame {
|
||||
};
|
||||
} overlay_mdp_frame;
|
||||
|
||||
int keyring_mapping_request(keyring_file *k,overlay_mdp_frame *req);
|
||||
int keyring_mapping_request(keyring_file *k, struct overlay_frame *frame, overlay_mdp_frame *req);
|
||||
int keyring_send_unlock(struct subscriber *subscriber);
|
||||
void keyring_release_subscriber(keyring_file *k, const sid_t *sid);
|
||||
|
||||
/* Server-side MDP functions */
|
||||
int overlay_mdp_swap_src_dst(overlay_mdp_frame *mdp);
|
||||
@ -909,6 +913,7 @@ int link_unicast_ack(struct subscriber *subscriber, struct overlay_interface *in
|
||||
int link_add_destinations(struct overlay_frame *frame);
|
||||
void link_neighbour_short_status_html(struct strbuf *b, const char *link_prefix);
|
||||
void link_neighbour_status_html(struct strbuf *b, struct subscriber *neighbour);
|
||||
int link_stop_routing(struct subscriber *subscriber);
|
||||
|
||||
int generate_nonce(unsigned char *nonce,int bytes);
|
||||
|
||||
|
@ -235,13 +235,13 @@ test_KeyringEntryPinServer() {
|
||||
assertStdoutGrep --fixed-strings "$ONE"
|
||||
assertStdoutGrep --fixed-strings "$TWOA"
|
||||
assertStdoutGrep --fixed-strings "$TWOB"
|
||||
executeOk_servald id revoke pin 'one'
|
||||
executeOk_servald id relinquish pin 'one'
|
||||
executeOk_servald id self
|
||||
assertStdoutLineCount == 3
|
||||
assertStdoutGrep --fixed-strings "$SIDA"
|
||||
assertStdoutGrep --fixed-strings "$TWOA"
|
||||
assertStdoutGrep --fixed-strings "$TWOB"
|
||||
executeOk_servald id revoke sid "$TWOB"
|
||||
executeOk_servald id relinquish sid "$TWOB"
|
||||
tfw_cat --stderr
|
||||
executeOk_servald id self
|
||||
assertStdoutLineCount == 2
|
||||
|
@ -164,7 +164,7 @@ test_unlock_ids() {
|
||||
executeOk_servald id enter pin 'entry-pin'
|
||||
wait_until has_link +B +A +A $SIDA $SIDX
|
||||
set_instance +A
|
||||
executeOk_servald id revoke pin 'entry-pin'
|
||||
executeOk_servald id relinquish pin 'entry-pin'
|
||||
set_instance +B
|
||||
wait_until --timeout=30 sid_offline $SIDX
|
||||
}
|
||||
@ -192,8 +192,6 @@ test_migrate_id() {
|
||||
wait_until has_link +B +A +A $SIDA $SIDX
|
||||
set_instance +B
|
||||
executeOk_servald id enter pin 'entry-pin'
|
||||
set_instance +A
|
||||
executeOk_servald id revoke pin 'entry-pin'
|
||||
wait_until --timeout=30 has_link +A +B +B $SIDB $SIDX
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,11 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
if [ ! -e .git ]; then
|
||||
echo "UNKNOWN-VERSION"
|
||||
exit
|
||||
fi
|
||||
|
||||
usage() {
|
||||
echo "Usage: ${0##*/} [options]"'
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user