added code to time various servald functions and report periodic

statistics.  Handles nested calls to correctly aportion call time
among children.
This commit is contained in:
gardners 2012-06-26 09:22:51 +09:30
parent fb7397a51b
commit 97cd8f5255
5 changed files with 221 additions and 111 deletions

View File

@ -252,6 +252,19 @@ func_descriptions func_names[]={
{NULL,NULL}
};
#define MAX_FUNCS 1024
struct callback_stats called_funcs[MAX_FUNCS];
const char *called_func_names[MAX_FUNCS];
int func_count=0;
#define MAX_CALL_DEPTH 128
struct {
int func_id;
int enter_time;
int child_time;
} call_stack[MAX_CALL_DEPTH];
int call_stack_depth=0;
char *fd_funcname(void *addr)
{
int j;
@ -299,7 +312,7 @@ int fd_tallystats(struct callback_stats *total,struct callback_stats *a)
return 0;
}
int fd_showstat(struct callback_stats *total, struct callback_stats *a, char *msg)
int fd_showstat(struct callback_stats *total, struct callback_stats *a, const char *msg)
{
WHYF("%lldms (%2.1f%%) in %d calls (max %lldms, avg %.1fms) : %s",
a->total_time,a->total_time*100.0/total->total_time,
@ -325,6 +338,9 @@ int fd_clearstats()
fd_clearstat(&alarms[i].stats);
for(i=0;i<fdcount;i++)
fd_clearstat(&fd_stats[fds[i].fd]);
for(i=0;i<func_count;i++)
fd_clearstat(&called_funcs[i]);
return 0;
}
@ -355,6 +371,10 @@ int fd_showstats()
fd_showstat(&total,&fd_stats[fds[i].fd],desc);
}
fd_showstat(&total,&total,"TOTAL");
INFOF("servald function time statistics:");
for(i=0;i<func_count;i++)
fd_showstat(&total,&called_funcs[i],called_func_names[i]);
return 0;
}
@ -363,3 +383,40 @@ void fd_periodicstats()
fd_showstats();
fd_clearstats();
}
int fd_next_funcid(const char *funcname)
{
if (func_count>=MAX_FUNCS) return MAX_FUNCS-1;
fd_clearstat(&called_funcs[func_count]);
called_func_names[func_count]=funcname;
return func_count++;
}
int fd_func_enter(int funcid)
{
if (call_stack_depth>=MAX_CALL_DEPTH) return 0;
call_stack[call_stack_depth].func_id=funcid;
call_stack[call_stack_depth].enter_time=overlay_gettime_ms();
call_stack[call_stack_depth].child_time=0;
call_stack_depth++;
return 0;
}
int fd_func_exit(int funcid)
{
if (funcid!=call_stack[call_stack_depth-1].func_id)
exit(WHYF("func_id mismatch: entered through %s(), but exited through %s()",
called_func_names[call_stack[call_stack_depth-1].func_id],
called_func_names[funcid]));
long long elapsed=overlay_gettime_ms()-call_stack[call_stack_depth-1].enter_time;
long long self_elapsed=elapsed-call_stack[call_stack_depth-1].child_time;
if (call_stack_depth>1) {
int d=call_stack_depth-2;
call_stack[d].child_time+=elapsed;
}
fd_update_stats(&called_funcs[funcid],self_elapsed);
call_stack_depth--;
return 0;
}

View File

@ -1118,10 +1118,12 @@ int keyring_sanitise_position(const keyring_file *k,int *cn,int *in,int *kp)
unsigned char *keyring_find_sas_private(keyring_file *k,unsigned char *sid,
unsigned char **sas_public)
{
IN();
int cn=0,in=0,kp=0;
if (!keyring_find_sid(k,&cn,&in,&kp,sid))
return WHYNULL("Could not find SID in keyring, so can't find SAS");
if (!keyring_find_sid(k,&cn,&in,&kp,sid)) {
RETURN(WHYNULL("Could not find SID in keyring, so can't find SAS"));
}
for(kp=0;kp<k->contexts[cn]->identities[in]->keypair_count;kp++)
if (k->contexts[cn]->identities[in]->keypairs[kp]->type==KEYTYPE_CRYPTOSIGN)
@ -1129,10 +1131,11 @@ unsigned char *keyring_find_sas_private(keyring_file *k,unsigned char *sid,
if (sas_public)
*sas_public=
k->contexts[cn]->identities[in]->keypairs[kp]->public_key;
return k->contexts[cn]->identities[in]->keypairs[kp]->private_key;
WHYF("Found SAS entry for %s*",overlay_render_sid_prefix(sid,7));
RETURN(k->contexts[cn]->identities[in]->keypairs[kp]->private_key);
}
return WHYNULL("Identity lacks SAS");
RETURN(WHYNULL("Identity lacks SAS"));
}
struct sid_sas_mapping {
@ -1182,6 +1185,8 @@ int keyring_mapping_request(keyring_file *k,overlay_mdp_frame *req)
if (crypto_sign_edwards25519sha512batch
(&req->out.payload[1+keybytes],&slen,req->out.dst.sid,SID_SIZE,sas_priv))
return WHY("crypto_sign() failed");
dump("SAS reply before compaction",
&req->out.payload[1+keybytes],slen);
/* chop the SID out of the signature, since it can be reinserted on reception */
bcopy(&req->out.payload[1+keybytes+32+SID_SIZE],
&req->out.payload[1+keybytes+32],sigbytes-32);
@ -1201,6 +1206,8 @@ int keyring_mapping_request(keyring_file *k,overlay_mdp_frame *req)
return overlay_mdp_dispatch(req,1,NULL,0);
} else {
/* It's probably a response. */
WHYF("Received %d byte key mapping response",
req->out.payload_length);
switch(req->out.payload[0]) {
case KEYTYPE_CRYPTOSIGN:
{
@ -1219,6 +1226,9 @@ int keyring_mapping_request(keyring_file *k,overlay_mdp_frame *req)
bcopy(&compactsignature[0],&signature[0],32);
bcopy(&req->out.src.sid[0],&signature[32],SID_SIZE);
bcopy(&compactsignature[32],&signature[32+SID_SIZE],32);
dump("SAS reply after decompaction",
signature,siglen);
int r=crypto_sign_edwards25519sha512batch_open(plain,&plain_len,
signature,siglen,
sas_public);
@ -1276,19 +1286,25 @@ unsigned char *keyring_find_sas_public(keyring_file *k,unsigned char *sid)
For now we will just use a non-persistent cache for safety (and it happens
to be easy to implement as well :)
*/
IN();
int i;
long long now=overlay_gettime_ms();
for(i=0;i<sid_sas_mapping_count;i++)
{
if (memcmp(sid,sid_sas_mappings[i].sid,SID_SIZE)) continue;
if (sid_sas_mappings[i].validP) return sid_sas_mappings[i].sas_public;
if (sid_sas_mappings[i].validP)
{ WHYF("Found SAS public entry for %s*",overlay_render_sid_prefix(sid,7));
RETURN(sid_sas_mappings[i].sas_public); }
/* Don't flood the network with mapping requests */
if ((now-sid_sas_mappings[i].last_request_time_in_ms)<1000) return NULL;
if (((now-sid_sas_mappings[i].last_request_time_in_ms)<1000)
&&((now-sid_sas_mappings[i].last_request_time_in_ms)>=0))
{ WHYF("Too soon to ask for SAS mapping again."); RETURN(NULL); }
/* we can request again, so fall out to where we do that.
i is set to this mapping, so the request process will update this
record. */
break;
}
WHYF("Asking for SAS mapping for %s",overlay_render_sid(sid));
/* allocate mapping slot or replace one at random, depending on how full things
are */
@ -1304,7 +1320,7 @@ unsigned char *keyring_find_sas_public(keyring_file *k,unsigned char *sid)
sid_sas_mappings[i].validP=0;
sid_sas_mappings[i].last_request_time_in_ms=now;
/* request mapping. */
/* request mapping (send request auth-crypted). */
overlay_mdp_frame mdp;
mdp.packetTypeAndFlags=MDP_TX;
bcopy(&sid[0],&mdp.out.dst.sid[0],SID_SIZE);
@ -1316,12 +1332,14 @@ unsigned char *keyring_find_sas_public(keyring_file *k,unsigned char *sid)
==KEYTYPE_CRYPTOBOX)
bcopy(keyring->contexts[0]->identities[0]->keypairs[0]->public_key,
mdp.out.src.sid,SID_SIZE);
else return WHYNULL("couldn't request SAS (I don't know who I am)");
else { RETURN(WHYNULL("couldn't request SAS (I don't know who I am)")); }
mdp.out.payload_length=1;
mdp.out.payload[0]=KEYTYPE_CRYPTOSIGN;
overlay_mdp_dispatch(&mdp,0 /* system generated */,
NULL,0);
return NULL;
if (overlay_mdp_dispatch(&mdp,0 /* system generated */,
NULL,0))
{ RETURN(WHYNULL("Failed to send SAS resolution request")); }
WHYF("Dispatched SAS resolution request");
RETURN(NULL);
}
int keyring_find_sid(const keyring_file *k,int *cn,int *in,int *kp, const unsigned char *sid)
@ -1434,9 +1452,10 @@ struct nm_record nm_cache[NM_CACHE_SLOTS];
unsigned char *keyring_get_nm_bytes(sockaddr_mdp *known,sockaddr_mdp *unknown)
{
if (!known) return WHYNULL("known pub key is null");
if (!unknown) return WHYNULL("unknown pub key is null");
if (!keyring) return WHYNULL("keyring is null");
IN();
if (!known) { RETURN(WHYNULL("known pub key is null")); }
if (!unknown) { RETURN(WHYNULL("unknown pub key is null")); }
if (!keyring) { RETURN(WHYNULL("keyring is null")); }
int i;
@ -1447,14 +1466,14 @@ unsigned char *keyring_get_nm_bytes(sockaddr_mdp *known,sockaddr_mdp *unknown)
crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES)) continue;
if (memcmp(nm_cache[i].unknown_key,unknown->sid,
crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES)) continue;
return nm_cache[i].nm_bytes;
{ RETURN(nm_cache[i].nm_bytes); }
}
/* Not in the cache, so prepare to cache it (or return failure if known is not
in fact a known key */
int cn=0,in=0,kp=0;
if (!keyring_find_sid(keyring,&cn,&in,&kp,known->sid))
return WHYNULL("known key is not in fact known.");
{ RETURN(WHYNULL("known key is not in fact known.")); }
/* work out where to store it */
if (nm_slots_used<NM_CACHE_SLOTS) {
@ -1475,5 +1494,5 @@ unsigned char *keyring_get_nm_bytes(sockaddr_mdp *known,sockaddr_mdp *unknown)
->identities[in]
->keypairs[kp]->private_key);
return nm_cache[i].nm_bytes;
RETURN(nm_cache[i].nm_bytes);
}

View File

@ -154,12 +154,13 @@ int overlayServerMode()
int overlay_frame_process(int interface,overlay_frame *f)
{
if (!f) return WHY("f==NULL");
IN();
if (!f) RETURN(WHY("f==NULL"));
long long now=overlay_gettime_ms();
if (f->source_address_status==OA_RESOLVED&&overlay_address_is_local(f->source))
return WHY("Dropping frame claiming to come from myself.");
RETURN(WHY("Dropping frame claiming to come from myself."));
if (debug&DEBUG_OVERLAYFRAMES) fprintf(stderr,">>> Received frame (type=%02x, bytes=%d)\n",f->type,f->payload?f->payload->length:-1);
@ -176,13 +177,13 @@ int overlay_frame_process(int interface,overlay_frame *f)
{
case OA_UNINITIALISED:
/* Um? Right. */
return WHY("frame passed with ununitialised nexthop address");
RETURN(WHY("frame passed with ununitialised nexthop address"));
break;
case OA_RESOLVED:
/* Great, we have the address, so we can get on with things */
break;
case OA_PLEASEEXPLAIN:
return -1; // WHY("Address cannot be resolved -- aborting packet processing.");
RETURN(-1); // WHY("Address cannot be resolved -- aborting packet processing.");
/* XXX Should send a please explain to get this address resolved. */
break;
case OA_UNSUPPORTED:
@ -194,7 +195,7 @@ int overlay_frame_process(int interface,overlay_frame *f)
to itself. */
WHY("Packet with unsupported address format");
overlay_interface_repeat_abbreviation_policy[interface]=1;
return -1;
RETURN(-1);
break;
}
@ -214,7 +215,7 @@ int overlay_frame_process(int interface,overlay_frame *f)
if (forMe) {
/* It's for us, so resolve the addresses */
if (overlay_frame_resolve_addresses(interface,f))
return WHY("Failed to resolve destination and sender addresses in frame");
RETURN(WHY("Failed to resolve destination and sender addresses in frame"));
broadcast=overlay_address_is_broadcast(f->destination);
if (debug&DEBUG_OVERLAYFRAMES) {
fprintf(stderr,"Destination for this frame is (resolve code=%d): ",f->destination_address_status);
@ -227,7 +228,7 @@ int overlay_frame_process(int interface,overlay_frame *f)
if (f->source_address_status!=OA_RESOLVED) {
if (debug&DEBUG_OVERLAYFRAMES) WHY("Source address could not be resolved, so dropping frame.");
return -1;
RETURN(-1);
}
if (overlay_address_is_local(f->source))
{
@ -235,7 +236,7 @@ int overlay_frame_process(int interface,overlay_frame *f)
you hear everything you send. */
if (debug&DEBUG_OVERLAYROUTING)
WHY("Dropping frame claiming to come from myself.");
return -1;
RETURN(-1);
}
if (f->destination_address_status==OA_RESOLVED) {
@ -244,7 +245,7 @@ int overlay_frame_process(int interface,overlay_frame *f)
if (overlay_address_is_local(f->destination)) ultimatelyForMe=1;
} else {
if (debug&DEBUG_OVERLAYFRAMES) WHY("Destination address could not be resolved, so dropping frame.");
return WHY("could not resolve destination address");
RETURN(WHY("could not resolve destination address"));
}
}
@ -257,12 +258,12 @@ int overlay_frame_process(int interface,overlay_frame *f)
if (duplicateBroadcast) {
if (0) WHY("Packet is duplicate broadcast");
return 0;
RETURN(0);
}
/* Not for us? Then just ignore it */
if (!forMe) {
return 0;
RETURN(0);
}
/* Is this a frame we have to forward on? */
@ -318,7 +319,7 @@ int overlay_frame_process(int interface,overlay_frame *f)
printf("reject nexthop is %s\n",overlay_render_sid(f->nexthop));
printf("reject destination is %s\n",
overlay_render_sid(f->destination));
return WHY("Not forwarding or reading duplicate broadcast");
RETURN(WHY("Not forwarding or reading duplicate broadcast"));
}
}
@ -350,7 +351,7 @@ int overlay_frame_process(int interface,overlay_frame *f)
/* If the frame was a broadcast frame, then we need to hang around
so that we can process it, since we are one of the recipients.
Otherwise, return triumphant. */
if (!broadcast) return 0;
if (!broadcast) RETURN(0);
}
}
@ -383,10 +384,10 @@ int overlay_frame_process(int interface,overlay_frame *f)
break;
default:
fprintf(stderr,"Unsupported f->type=0x%x\n",f->type);
return WHY("Support for that f->type not yet implemented");
RETURN(WHY("Support for that f->type not yet implemented"));
break;
}
return 0;
RETURN(0);
}

View File

@ -273,58 +273,49 @@ int overlay_mdp_process_bind_request(int sock,overlay_mdp_frame *mdp,
return overlay_mdp_reply_ok(sock,recvaddr,recvaddrlen,"Port bound");
}
int overlay_saw_mdp_containing_frame(int interface,overlay_frame *f,long long now)
unsigned char *overlay_mdp_decrypt(overlay_frame *f,overlay_mdp_frame *mdp,
int *len)
{
/* Take frame source and destination and use them to populate mdp->in->{src,dst}
SIDs.
Take ports from mdp frame itself.
Take payload from mdp frame itself.
*/
overlay_mdp_frame mdp;
IN();
/* Get source and destination addresses */
bcopy(&f->destination[0],&mdp.in.dst.sid[0],SID_SIZE);
bcopy(&f->source[0],&mdp.in.src.sid[0],SID_SIZE);
int len=f->payload->length;
*len=f->payload->length;
unsigned char *b = NULL;
unsigned char plain_block[len+16];
unsigned char plain_block[(*len)+16];
if (len<10) return WHY("Invalid MDP frame");
/* copy crypto flags from frame so that we know if we need to decrypt or verify it */
switch(f->modifiers&OF_CRYPTO_BITS) {
case 0:
/* get payload */
b=&f->payload->bytes[0];
len=f->payload->length;
mdp.packetTypeAndFlags|=MDP_NOCRYPT|MDP_NOSIGN; break;
*len=f->payload->length;
mdp->packetTypeAndFlags|=MDP_NOCRYPT|MDP_NOSIGN; break;
case OF_CRYPTO_CIPHERED:
return WHY("decryption not implemented");
mdp.packetTypeAndFlags|=MDP_NOSIGN; break;
WHY("decryption not implemented");
RETURN(NULL);
mdp->packetTypeAndFlags|=MDP_NOSIGN; break;
case OF_CRYPTO_SIGNED:
{
/* This call below will dispatch the request for the SAS if we don't
already have it. In the meantime, we just drop the frame if the SAS
is not available. */
unsigned char *key=keyring_find_sas_public(keyring,mdp.out.src.sid);
if (!key) return WHY("SAS key not currently on record, so cannot verify");
unsigned char *key=keyring_find_sas_public(keyring,mdp->out.src.sid);
if (!key) { WHY("SAS key not currently on record, so cannot verify");
RETURN(NULL); }
/* get payload and following compacted signature */
b=&f->payload->bytes[0];
len=f->payload->length-crypto_sign_edwards25519sha512batch_BYTES;
*len=f->payload->length-crypto_sign_edwards25519sha512batch_BYTES;
/* get hash */
unsigned char hash[crypto_hash_sha512_BYTES];
crypto_hash_sha512(hash,b,len);
crypto_hash_sha512(hash,b,*len);
/* reconstitute signature by putting hash between two halves of signature */
unsigned char signature[crypto_hash_sha512_BYTES
+crypto_sign_edwards25519sha512batch_BYTES];
bcopy(&b[len],&signature[0],32);
crypto_hash_sha512(&signature[32],b,len);
bcopy(&b[*len],&signature[0],32);
crypto_hash_sha512(&signature[32],b,*len);
if (0) dump("hash for verification",hash,crypto_hash_sha512_BYTES);
bcopy(&b[len+32],&signature[32+crypto_hash_sha512_BYTES],32);
bcopy(&b[(*len)+32],&signature[32+crypto_hash_sha512_BYTES],32);
/* verify signature */
unsigned char m[crypto_hash_sha512_BYTES];
@ -333,24 +324,27 @@ int overlay_saw_mdp_containing_frame(int interface,overlay_frame *f,long long no
=crypto_sign_edwards25519sha512batch_open(m,&mlen,
signature,sizeof(signature),
key);
if (result) return WHY("Signature verification failed: incorrect signature");
else if (0) DEBUG("signature check passed");
if (result) {
WHY("Signature verification failed: incorrect signature");
RETURN(NULL);
} else if (1) DEBUG("signature check passed");
}
mdp.packetTypeAndFlags|=MDP_NOCRYPT; break;
mdp->packetTypeAndFlags|=MDP_NOCRYPT; break;
case OF_CRYPTO_CIPHERED|OF_CRYPTO_SIGNED:
{
if (0) {
fflush(stderr);
printf("crypted MDP frame for %s\n",
overlay_render_sid(mdp.out.dst.sid));
overlay_render_sid(mdp->out.dst.sid));
fflush(stdout);
}
unsigned char *k=keyring_get_nm_bytes(&mdp.out.dst,&mdp.out.src);
unsigned char *k=keyring_get_nm_bytes(&mdp->out.dst,&mdp->out.src);
unsigned char *nonce=&f->payload->bytes[0];
int nb=crypto_box_curve25519xsalsa20poly1305_NONCEBYTES;
int zb=crypto_box_curve25519xsalsa20poly1305_ZEROBYTES;
if (!k) return WHY("I don't have the private key required to decrypt that");
if (!k) { WHY("I don't have the private key required to decrypt that");
RETURN(NULL); }
bzero(&plain_block[0],crypto_box_curve25519xsalsa20poly1305_ZEROBYTES-16);
int cipher_len=f->payload->length-nb;
bcopy(&f->payload->bytes[nb],&plain_block[16],cipher_len);
@ -360,17 +354,42 @@ int overlay_saw_mdp_containing_frame(int interface,overlay_frame *f,long long no
dump("cipher block",&plain_block[16],cipher_len);
}
if (crypto_box_curve25519xsalsa20poly1305_open_afternm
(plain_block,plain_block,cipher_len+16,nonce,k))
return WHYF("crypto_box_open_afternm() failed (forged or corrupted packet of %d bytes)",cipher_len+16);
(plain_block,plain_block,cipher_len+16,nonce,k)) {
WHYF("crypto_box_open_afternm() failed (forged or corrupted packet of %d bytes)",cipher_len+16);
RETURN(NULL);
}
if (0) dump("plain block",&plain_block[zb],cipher_len-16);
b=&plain_block[zb];
len=cipher_len-16;
*len=cipher_len-16;
break;
}
}
RETURN(b);
}
int overlay_saw_mdp_containing_frame(int interface,overlay_frame *f,long long now)
{
IN();
/* Take frame source and destination and use them to populate mdp->in->{src,dst}
SIDs.
Take ports from mdp frame itself.
Take payload from mdp frame itself.
*/
overlay_mdp_frame mdp;
int len=f->payload->length;
/* Get source and destination addresses */
bcopy(&f->destination[0],&mdp.in.dst.sid[0],SID_SIZE);
bcopy(&f->source[0],&mdp.in.src.sid[0],SID_SIZE);
if (len<10) RETURN(WHY("Invalid MDP frame"));
/* copy crypto flags from frame so that we know if we need to decrypt or verify it */
unsigned char *b = overlay_mdp_decrypt(f,&mdp,&len);
if (!b) RETURN(-1);
int version=(b[0]<<8)+b[1];
if (version!=0x0101) return WHY("Saw unsupported MDP frame version");
if (version!=0x0101) RETURN(WHY("Saw unsupported MDP frame version"));
/* Indicate MDP message type */
mdp.packetTypeAndFlags=MDP_TX;
@ -385,7 +404,7 @@ int overlay_saw_mdp_containing_frame(int interface,overlay_frame *f,long long no
bcopy(&b[10],&mdp.in.payload[0],mdp.in.payload_length);
/* and do something with it! */
return overlay_saw_mdp_frame(interface,&mdp,now);
RETURN(overlay_saw_mdp_frame(interface,&mdp,now));
}
int overlay_mdp_swap_src_dst(overlay_mdp_frame *mdp)
@ -399,6 +418,7 @@ int overlay_mdp_swap_src_dst(overlay_mdp_frame *mdp)
int overlay_saw_mdp_frame(int interface, overlay_mdp_frame *mdp,long long now)
{
IN();
int i;
int match=-1;
@ -419,7 +439,7 @@ int overlay_saw_mdp_frame(int interface, overlay_mdp_frame *mdp,long long now)
if ((!overlay_address_is_local(mdp->out.dst.sid))
&&(!overlay_address_is_broadcast(mdp->out.dst.sid)))
{
return WHY("Asked to process an MDP packet that was not addressed to this node.");
RETURN(WHY("Asked to process an MDP packet that was not addressed to this node."));
}
for(i=0;i<MDP_MAX_BINDINGS;i++)
@ -462,25 +482,26 @@ int overlay_saw_mdp_frame(int interface, overlay_mdp_frame *mdp,long long now)
int len=overlay_mdp_relevant_bytes(mdp);
int r=sendto(mdp_named_socket,mdp,len,0,(struct sockaddr*)&addr,sizeof(addr));
if (r==overlay_mdp_relevant_bytes(mdp)) {
return 0;
RETURN(0);
}
WHY("didn't send mdp packet");
if (errno==ENOENT) {
/* far-end of socket has died, so drop binding */
printf("Closing dead MDP client '%s'\n",mdp_bindings_sockets[match]);
overlay_mdp_releasebindings(&addr,mdp_bindings_socket_name_lengths[match]);
}
WHY_perror("sendto(e)");
return WHY("Failed to pass received MDP frame to client");
RETURN(WHY("Failed to pass received MDP frame to client"));
} else {
/* No socket is bound, ignore the packet ... except for magic sockets */
switch(mdp->out.dst.port) {
case MDP_PORT_VOMP:
return vomp_mdp_received(mdp);
RETURN(vomp_mdp_received(mdp));
case MDP_PORT_KEYMAPREQUEST:
/* Either respond with the appropriate SAS, or record this one if it
verfies out okay. */
DEBUG("key mapping request");
return keyring_mapping_request(keyring,mdp);
RETURN(keyring_mapping_request(keyring,mdp));
case MDP_PORT_DNALOOKUP: /* attempt to resolve DID to SID */
{
int cn=0,in=0,kp=0;
@ -488,8 +509,8 @@ int overlay_saw_mdp_frame(int interface, overlay_mdp_frame *mdp,long long now)
int pll=mdp->out.payload_length;
if (pll>64) pll=64;
/* get did from the packet */
if (mdp->out.payload_length<1)
return WHY("Empty DID in DNA resolution request");
if (mdp->out.payload_length<1) {
RETURN(WHY("Empty DID in DNA resolution request")); }
bcopy(&mdp->out.payload[0],&did[0],pll);
/* make sure it is null terminated */
did[pll]=0;
@ -553,7 +574,8 @@ int overlay_saw_mdp_frame(int interface, overlay_mdp_frame *mdp,long long now)
*/
dna_helper_enqueue(did,mdp->out.src.sid);
}
return 0;
RETURN(0);
DEBUG("Got here");
}
break;
case MDP_PORT_ECHO: /* well known ECHO port for TCP/UDP and now MDP */
@ -564,7 +586,9 @@ int overlay_saw_mdp_frame(int interface, overlay_mdp_frame *mdp,long long now)
/* Swap addresses */
overlay_mdp_swap_src_dst(mdp);
if (mdp->out.dst.port==MDP_PORT_ECHO) return WHY("echo loop averted");
if (mdp->out.dst.port==MDP_PORT_ECHO) {
RETURN(WHY("echo loop averted"));
}
/* If the packet was sent to broadcast, then replace broadcast address
with our local address. For now just responds with first local address */
if (overlay_address_is_broadcast(mdp->out.src.sid))
@ -589,23 +613,23 @@ int overlay_saw_mdp_frame(int interface, overlay_mdp_frame *mdp,long long now)
and the frame needs sending on, as happens with broadcasts. MDP ping
is a simple application where this occurs). */
overlay_mdp_swap_src_dst(mdp);
}
break;
default:
/* Unbound socket. We won't be sending ICMP style connection refused
messages, partly because they are a waste of bandwidth. */
return WHYF("Received packet for which no listening process exists (MDP ports: src=%d, dst=%d",
mdp->out.src.port,mdp->out.dst.port);
RETURN(WHYF("Received packet for which no listening process exists (MDP ports: src=%d, dst=%d",
mdp->out.src.port,mdp->out.dst.port));
}
}
break;
default:
return WHYF("We should only see MDP_TX frames here (MDP message type = 0x%x)",
mdp->packetTypeAndFlags);
RETURN(WHYF("We should only see MDP_TX frames here (MDP message type = 0x%x)",
mdp->packetTypeAndFlags));
}
return WHY("Not implemented");
RETURN(0);
}
int overlay_mdp_sanitytest_sourceaddr(sockaddr_mdp *src,int userGeneratedFrameP,
@ -682,17 +706,18 @@ int overlay_mdp_sanitytest_sourceaddr(sockaddr_mdp *src,int userGeneratedFrameP,
int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
struct sockaddr_un *recvaddr,int recvaddrlen)
{
IN();
/* Work out if destination is broadcast or not */
int broadcast=1;
if (overlay_mdp_sanitytest_sourceaddr(&mdp->out.src,userGeneratedFrameP,
recvaddr,recvaddrlen))
return overlay_mdp_reply_error
(mdp_named_socket,
(struct sockaddr_un *)recvaddr,
recvaddrlen,8,
"Source address is invalid (you must bind to a source address before"
" you can send packets");
RETURN(overlay_mdp_reply_error
(mdp_named_socket,
(struct sockaddr_un *)recvaddr,
recvaddrlen,8,
"Source address is invalid (you must bind to a source address before"
" you can send packets"));
if (!overlay_address_is_broadcast(mdp->out.dst.sid)) broadcast=0;
@ -704,7 +729,7 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
if (!broadcast) {
/* Is local, and is not broadcast, so shouldn't get sent out
on the wire. */
return 0;
RETURN(0);
}
}
@ -713,14 +738,14 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
NaCl cryptobox keys can be used for signing. */
if (broadcast) {
if (!(mdp->packetTypeAndFlags&MDP_NOCRYPT))
return overlay_mdp_reply_error(mdp_named_socket,
RETURN(overlay_mdp_reply_error(mdp_named_socket,
recvaddr,recvaddrlen,5,
"Broadcast packets cannot be encrypted "); }
"Broadcast packets cannot be encrypted ")); }
/* Prepare the overlay frame for dispatch */
struct overlay_frame *frame;
frame=calloc(sizeof(overlay_frame),1);
if (!frame) return WHY_perror("calloc");
if (!frame) RETURN(WHY_perror("calloc"));
/* give voice packets priority */
if (mdp->out.dst.port==MDP_PORT_VOMP) frame->type=OF_TYPE_DATA_VOICE;
else frame->type=OF_TYPE_DATA;
@ -749,7 +774,7 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
unsigned char nonce[crypto_box_curve25519xsalsa20poly1305_NONCEBYTES];
if (urandombytes(nonce,crypto_box_curve25519xsalsa20poly1305_NONCEBYTES)) {
op_free(frame);
return WHY("urandombytes() failed to generate nonce");
RETURN(WHY("urandombytes() failed to generate nonce"));
}
fe|= ob_append_bytes(frame->payload,nonce,crypto_box_curve25519xsalsa20poly1305_NONCEBYTES);
/* generate plain message with zero bytes and get ready to cipher it */
@ -777,16 +802,16 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
/* get pre-computed PKxSK bytes (the slow part of auth-cryption that can be
retained and reused, and use that to do the encryption quickly. */
unsigned char *k=keyring_get_nm_bytes(&mdp->out.src,&mdp->out.dst);
if (!k) { op_free(frame); return WHY("could not compute Curve25519(NxM)"); }
if (!k) { op_free(frame); RETURN(WHY("could not compute Curve25519(NxM)")); }
/* Get pointer to place in frame where the ciphered text needs to go */
int cipher_offset=frame->payload->length;
unsigned char *cipher_text=ob_append_space(frame->payload,cipher_len);
if (fe||(!cipher_text))
{ op_free(frame); return WHY("could not make space for ciphered text"); }
{ op_free(frame); RETURN(WHY("could not make space for ciphered text")); }
/* Actually authcrypt the payload */
if (crypto_box_curve25519xsalsa20poly1305_afternm
(cipher_text,plain,cipher_len,nonce,k))
{ op_free(frame); return WHY("crypto_box_afternm() failed"); }
{ op_free(frame); RETURN(WHY("crypto_box_afternm() failed")); }
/* now shuffle down 16 bytes to get rid of the temporary space that crypto_box
uses. */
bcopy(&cipher_text[16],&cipher_text[0],cipher_len-16);
@ -811,7 +836,7 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
*/
frame->modifiers=OF_CRYPTO_CIPHERED;
op_free(frame);
return WHY("ciphered MDP packets not implemented");
RETURN(WHY("ciphered MDP packets not implemented"));
break;
case MDP_NOCRYPT:
/* Payload is sent unencrypted, but signed.
@ -834,7 +859,7 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
+mdp->out.payload_length);
{
unsigned char *key=keyring_find_sas_private(keyring,mdp->out.src.sid,NULL);
if (!key) { op_free(frame); return WHY("could not find signing key"); }
if (!key) { op_free(frame); RETURN(WHY("could not find signing key")); }
/* Build plain-text that includes header and hash it so that
we can sign that hash. */
@ -864,7 +889,7 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
crypto_sign_edwards25519sha512batch(signature,&sig_len,
hash,crypto_hash_sha512_BYTES,
key);
if (!sig_len) { op_free(frame); return WHY("Signing MDP frame failed"); }
if (!sig_len) { op_free(frame); RETURN(WHY("Signing MDP frame failed")); }
/* chop hash out of middle of signature since it has to be recomputed
at the far end, anyway, as described above. */
bcopy(&signature[32+64],&signature[32],32);
@ -918,11 +943,11 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
if (overlay_payload_enqueue(q,frame,0))
{
if (frame) op_free(frame);
return WHY("Error enqueuing frame");
RETURN(WHY("Error enqueuing frame"));
}
else {
if (debug&DEBUG_OVERLAYINTERFACES) DEBUG("queued frame");
return 0;
RETURN(0);
}
}

View File

@ -1538,6 +1538,13 @@ void sigIoHandler(int signal);
#define WRITE_STR(fd, str) write(fd, str, strlen(str))
int rhizome_server_start();
void rhizome_enqueue_suggestions();
int overlay_mdp_setup_sockets();
void overlay_interface_poll(int fd);
void overlay_dummy_poll();
void rhizome_client_poll(int fd);
/* Event queue handling functions */
int fd_poll();
int fd_checkalarms();
@ -1548,10 +1555,11 @@ int fd_list();
char *fd_funcname(void *addr);
int fd_showstats();
void fd_periodicstats();
int fd_next_funcid();
int fd_func_exit(int funcid);
int fd_func_enter(int funcid);
int fd_next_funcid(const char *funcname);
int rhizome_server_start();
void rhizome_enqueue_suggestions();
int overlay_mdp_setup_sockets();
void overlay_interface_poll(int fd);
void overlay_dummy_poll();
void rhizome_client_poll(int fd);
#define IN() static int _func_id=-1; if (_func_id<0) _func_id=fd_next_funcid(__FUNCTION__); fd_func_enter(_func_id);
#define OUT() fd_func_exit(_func_id);
#define RETURN(X) { OUT() return(X); }