work towards "node info" command, and renamed stop/start etc to

drop node keyword, that in retrospect is not appropriate.
This commit is contained in:
gardners 2012-04-26 07:14:01 +09:30
parent d56780852c
commit 88ba56b68b
4 changed files with 207 additions and 8 deletions

View File

@ -569,7 +569,7 @@ int cli_absolute_path(const char *arg)
int app_server_start(int argc, const char *const *argv, struct command_line_option *o)
{
/* Process optional arguments */
int foregroundP= (argc >= 3 && !strcasecmp(argv[2], "foreground"));
int foregroundP= (argc >= 2 && !strcasecmp(argv[1], "foreground"));
if (cli_arg(argc, argv, o, "instance path", &thisinstancepath, cli_absolute_path, NULL) == -1)
return -1;
@ -1165,6 +1165,50 @@ int app_id_self(int argc, const char *const *argv, struct command_line_option *o
return 0;
}
int app_node_info(int argc, const char *const *argv, struct command_line_option *o)
{
const char *sid;
cli_arg(argc, argv, o, "sid", &sid, NULL, "");
unsigned char packed_sid[SID_SIZE];
overlay_mdp_frame mdp;
bzero(&mdp,sizeof(mdp));
mdp.packetTypeAndFlags=MDP_NODEINFO;
if (argc>3) mdp.nodeinfo.resolve_did=1;
/* get SID or SID prefix */
int i;
mdp.nodeinfo.sid_prefix_length=0;
for(i = 0; i != SID_SIZE&&sid[i<<1]&&sid[(i<<1)+1]; ++i) {
packed_sid[mdp.nodeinfo.sid_prefix_length] = hexvalue(sid[i<<1]) << 4;
packed_sid[mdp.nodeinfo.sid_prefix_length++] |= hexvalue(sid[(i<<1)+1]);
}
int result=overlay_mdp_send(&mdp,MDP_AWAITREPLY,5000);
if (result) {
if (mdp.packetTypeAndFlags==MDP_ERROR)
{
return WHYF(" MDP Server error #%d: '%s'",mdp.error.error,mdp.error.message);
}
else
return WHYF("Could not get information about node.");
}
cli_printf("%d:%d:%s:%s:%s:%s:%s:%d:%d\n",
mdp.nodeinfo.index,
mdp.nodeinfo.count,
mdp.nodeinfo.foundP?"found":"noresult",
overlay_render_sid(mdp.nodeinfo.sid),
mdp.nodeinfo.resolve_did?mdp.nodeinfo.did:"did-not-resolved",
mdp.nodeinfo.localP?"self":"peer",
mdp.nodeinfo.neighbourP?"direct":"indirect",
mdp.nodeinfo.score,
mdp.nodeinfo.interface_number);
return 0;
}
/* NULL marks ends of command structure.
"<anystring>" marks an arg that can take any value.
"[<anystring>]" marks an optional arg that can take any value.
@ -1189,19 +1233,19 @@ command_line_option command_line_options[]={
"Display command usage."},
{app_echo,{"echo","...",NULL},CLIFLAG_STANDALONE,
"Output the supplied string."},
{app_server_start,{"node","start",NULL},CLIFLAG_STANDALONE,
{app_server_start,{"start",NULL},CLIFLAG_STANDALONE,
"Start Serval Mesh node process with instance path taken from SERVALINSTANCE_PATH environment variable."},
{app_server_start,{"node","start","in","<instance path>",NULL},CLIFLAG_STANDALONE,
{app_server_start,{"start","in","<instance path>",NULL},CLIFLAG_STANDALONE,
"Start Serval Mesh node process with given instance path."},
{app_server_start,{"node","start","foreground",NULL},CLIFLAG_STANDALONE,
{app_server_start,{"start","foreground",NULL},CLIFLAG_STANDALONE,
"Start Serval Mesh node process without detatching from foreground."},
{app_server_start,{"node","start","foreground","in","<instance path>",NULL},CLIFLAG_STANDALONE,
{app_server_start,{"start","foreground","in","<instance path>",NULL},CLIFLAG_STANDALONE,
"Start Serval Mesh node process with given instance path, without detatching from foreground."},
{app_server_stop,{"node","stop",NULL},0,
{app_server_stop,{"stop",NULL},0,
"Stop a running Serval Mesh node process with instance path taken from SERVALINSTANCE_PATH environment variable."},
{app_server_stop,{"node","stop","in","<instance path>",NULL},0,
{app_server_stop,{"stop","in","<instance path>",NULL},0,
"Stop a running Serval Mesh node process with given instance path."},
{app_server_status,{"node","status",NULL},0,
{app_server_status,{"status",NULL},0,
"Display information about any running Serval Mesh node."},
{app_mdp_ping,{"mdp","ping","<SID|broadcast>",NULL},CLIFLAG_STANDALONE,
"Attempts to ping specified node via Mesh Datagram Protocol (MDP)."},
@ -1239,6 +1283,8 @@ command_line_option command_line_options[]={
"Return my own identity(s) as SIDs"},
{app_id_self,{"id","peers",NULL},0,
"Return identity of known peers as SIDs"},
{app_node_info,{"node","info","<sid>","[<did>]",NULL},0,
"Return information about SID, and optionally ask for DID resolution via network"},
#ifdef HAVE_VOIPTEST
{app_pa_phone,{"phone",NULL},0,
"Run phone test application"},

View File

@ -902,6 +902,8 @@ int overlay_mdp_poll()
switch(mdp->packetTypeAndFlags&MDP_TYPE_MASK) {
case MDP_VOMPEVENT:
return vomp_mdp_event(mdp,recvaddr_un,recvaddrlen);
case MDP_NODEINFO:
return overlay_route_node_info(mdp,recvaddr_un,recvaddrlen);
case MDP_GETADDRS:
{
overlay_mdp_frame mdpreply;
@ -1019,6 +1021,10 @@ int overlay_mdp_relevant_bytes(overlay_mdp_frame *mdp)
/* XXX too hard to work out precisely for now. */
len=sizeof(overlay_mdp_frame);
break;
case MDP_NODEINFO:
len=&mdp->nodeinfo.count-(int *)mdp;
len+=sizeof(mdp->nodeinfo.count);
break;
default:
return WHY("Illegal MDP frame type.");
}

View File

@ -1264,3 +1264,131 @@ int overlay_route_tick_node(int bin,int slot,long long now)
return overlay_route_recalc_node_metrics(&overlay_nodes[bin][slot],now);
}
int overlay_route_node_info(overlay_mdp_frame *mdp,
struct sockaddr_un *addr,int addrlen)
{
int bin,slot,n;
long long now=overlay_gettime_ms();
/* check if it is a local identity */
int cn,in,kp;
for(cn=0;cn<keyring->context_count;cn++)
for(in=0;in<keyring->contexts[cn]->identity_count;in++)
for(kp=0;kp<keyring->contexts[cn]->identities[in]->keypair_count;kp++)
if (keyring->contexts[cn]->identities[in]->keypairs[kp]->type
==KEYTYPE_CRYPTOBOX)
{
if (!bcmp(&mdp->nodeinfo.sid[0],
&keyring->contexts[cn]->identities[in]
->keypairs[kp]->public_key[0],
mdp->nodeinfo.sid_prefix_length))
{
if (mdp->nodeinfo.count==mdp->nodeinfo.index)
{
mdp->nodeinfo.foundP=1;
mdp->nodeinfo.localP=1;
mdp->nodeinfo.neighbourP=0;
mdp->nodeinfo.time_since_last_observation=0;
mdp->nodeinfo.score=256;
mdp->nodeinfo.interface_number=-1;
bcopy(&keyring->contexts[cn]->identities[in]
->keypairs[kp]->public_key[0],
&mdp->nodeinfo.sid[0],SID_SIZE);
mdp->nodeinfo.did[0]=0;
if (mdp->nodeinfo.resolve_did) {
mdp->nodeinfo.resolve_did=0;
int k2;
for(k2=0;k2<keyring->contexts[cn]->identities[in]
->keypair_count;k2++)
if (keyring->contexts[cn]->identities[in]->keypairs[k2]->type
==KEYTYPE_DID)
{
/* private key field has packed did */
extractDid(keyring->contexts[cn]->identities[in]
->keypairs[k2]->private_key,0,
&mdp->nodeinfo.did[0]);
mdp->nodeinfo.resolve_did=1;
}
}
}
mdp->nodeinfo.count++;
}
}
/* check neighbour table, i.e., if directly connected */
for(n=0;n<overlay_neighbour_count;n++)
if (overlay_neighbours[n].node)
{
if (!bcmp(&mdp->nodeinfo.sid[0],
&overlay_neighbours[n].node->sid[0],
mdp->nodeinfo.sid_prefix_length))
{
if (mdp->nodeinfo.count==mdp->nodeinfo.index)
{
mdp->nodeinfo.foundP=1;
mdp->nodeinfo.localP=0;
mdp->nodeinfo.neighbourP=1;
mdp->nodeinfo.time_since_last_observation
=overlay_gettime_ms()
-overlay_neighbours[n].last_observation_time_ms;
mdp->nodeinfo.score=-1;
mdp->nodeinfo.interface_number=-1;
int i;
for(i=0;i<OVERLAY_MAX_INTERFACES;i++)
if (overlay_neighbours[n].scores[i]>mdp->nodeinfo.score)
{
mdp->nodeinfo.score=overlay_neighbours[n].scores[i];
mdp->nodeinfo.interface_number=i;
}
bcopy(&overlay_neighbours[n].node->sid[0],
&mdp->nodeinfo.sid[0],SID_SIZE);
}
mdp->nodeinfo.count++;
}
}
/* check if it is an indirectly connected node that we know about */
for(bin=0;bin<overlay_bin_count;bin++)
for(slot=0;slot<overlay_bin_size;slot++)
{
if (!overlay_nodes[bin][slot].sid[0]) continue;
if (!bcmp(&mdp->nodeinfo.sid[0],
&overlay_nodes[bin][slot].sid[0],
mdp->nodeinfo.sid_prefix_length))
{
if (mdp->nodeinfo.count==mdp->nodeinfo.index)
{
mdp->nodeinfo.foundP=1;
mdp->nodeinfo.localP=0;
mdp->nodeinfo.neighbourP=0;
mdp->nodeinfo.time_since_last_observation=overlay_gettime_ms();
mdp->nodeinfo.score=-1;
mdp->nodeinfo.interface_number=-1;
int o;
for(o=0;o<OVERLAY_MAX_OBSERVATIONS;o++)
if (overlay_nodes[bin][slot].observations[o].observed_score)
{
overlay_node_observation *ob
=&overlay_nodes[bin][slot].observations[o];
if (ob->corrected_score>mdp->nodeinfo.score) {
mdp->nodeinfo.score=ob->corrected_score;
}
if ((now-ob->rx_time)
<mdp->nodeinfo.time_since_last_observation)
mdp->nodeinfo.time_since_last_observation=now-ob->rx_time;
}
bcopy(&overlay_nodes[bin][slot].sid[0],
&mdp->nodeinfo.sid[0],SID_SIZE);
}
mdp->nodeinfo.count++;
}
}
return overlay_mdp_reply(mdp_named_socket,addr,addrlen,mdp);
return 0;
}

View File

@ -1193,6 +1193,22 @@ typedef struct overlay_mdp_vompevent {
};
} overlay_mdp_vompevent;
#define MDP_NODEINFO 8
typedef struct overlay_mdp_nodeinfo {
unsigned char sid[SID_SIZE];
int sid_prefix_length; /* allow wildcard matching */
char did[64];
int foundP;
int localP;
int neighbourP;
int score;
int interface_number;
int resolve_did;
unsigned long long time_since_last_observation;
int index; /* which record to return or was returned (incase there are multiple matches) */
int count; /* number of matching records */
} overlay_mdp_nodeinfo;
typedef struct overlay_mdp_frame {
#define MDP_AWAITREPLY 9999
unsigned int packetTypeAndFlags;
@ -1202,6 +1218,7 @@ typedef struct overlay_mdp_frame {
overlay_mdp_bind_request bind;
overlay_mdp_addrlist addrlist;
overlay_mdp_vompevent vompevent;
overlay_mdp_nodeinfo nodeinfo;
overlay_mdp_error error;
/* 2048 is too large (causes EMSGSIZE errors on OSX, but probably fine on
Linux) */
@ -1338,6 +1355,8 @@ int cli_delim(const char *opt);
int overlay_mdp_getmyaddr(int index,unsigned char *sid);
int overlay_mdp_bind(unsigned char *localaddr,int port);
int overlay_route_node_info(overlay_mdp_frame *mdp,
struct sockaddr_un *addr,int addrlen);
int app_vomp_status(int argc, const char *const *argv, struct command_line_option *o);
int app_vomp_dial(int argc, const char *const *argv, struct command_line_option *o);