dna lookup command line utility mostly done. Now to make server

respond.
This commit is contained in:
gardners 2012-04-25 15:24:21 +09:30
parent cd00204893
commit f8a1ffc4c9
3 changed files with 142 additions and 26 deletions

View File

@ -441,14 +441,79 @@ int app_echo(int argc, const char *const *argv, struct command_line_option *o)
int app_dna_lookup(int argc, const char *const *argv, struct command_line_option *o)
{
int i;
/* Create the instance directory if it does not yet exist */
if (create_serval_instance_dir() == -1)
return -1;
const char *did;
if (cli_arg(argc, argv, o, "did", &did, NULL, "*") == -1)
return -1;
/* Bind to MDP socket and await confirmation */
unsigned char srcsid[SID_SIZE];
int port=32768+(random()&32767);
if (overlay_mdp_getmyaddr(0,srcsid)) return WHY("Could not get local address");
if (overlay_mdp_bind(srcsid,port)) return WHY("Could not bind to MDP socket");
WHY("bound port");
/* use MDP to send the lookup request to MDP_PORT_DNALOOKUP, and wait for
replies. */
overlay_mdp_frame mdp;
bzero(&mdp,sizeof(mdp));
return WHY("Not implemented");
mdp.packetTypeAndFlags=MDP_TX|MDP_NOCRYPT;
/* set source address to a local address, and pick a random port */
mdp.out.src.port=port;
bcopy(&srcsid[0],&mdp.out.src.sid[0],SID_SIZE);
/* Send to broadcast address and DNA lookup port */
for(i=0;i<SID_SIZE;i++) mdp.out.dst.sid[i]=0xff;
mdp.out.dst.port=MDP_PORT_DNALOOKUP;
/* put DID into packet */
bcopy(did,&mdp.out.payload[0],strlen(did)+1);
mdp.out.payload_length=strlen(did)+1;
/* Now repeatedly send resolution request and collect results until we reach
timeout. */
unsigned long long timeout=overlay_gettime_ms()+3000;
unsigned long long last_tx=0;
while(timeout>overlay_gettime_ms())
{
unsigned long long now=overlay_gettime_ms();
if ((last_tx+125)<now)
{
overlay_mdp_send(&mdp,0,0);
last_tx=now;
}
long long short_timeout=125;
while(short_timeout>0) {
if (overlay_mdp_client_poll(short_timeout))
{
overlay_mdp_frame rx;
int ttl;
while (overlay_mdp_recv(&rx,&ttl)==0)
{
if (rx.packetTypeAndFlags==MDP_ERROR)
{
fprintf(stderr," Error message: %s\n",mdp.error.message);
}
else if (rx.packetTypeAndFlags==MDP_RX)
fprintf(stderr,"%s:%s\n",
overlay_render_sid(&rx.in.payload[0]),
&rx.in.payload[SID_SIZE]);
if (servalShutdown) break;
}
}
if (servalShutdown) break;
short_timeout=125-(overlay_gettime_ms()-now);
}
if (servalShutdown) break;
}
return 0;
}
int confValueRotor=0;
@ -641,30 +706,12 @@ int app_mdp_ping(int argc, const char *const *argv, struct command_line_option *
return -1;
overlay_mdp_frame mdp;
/* Bind to MDP socket and await confirmation */
int port=32768+(random()&32767);
mdp.packetTypeAndFlags=MDP_BIND;
if (0)
bzero(&mdp.bind.sid[0],SID_SIZE); // listen on all addressses
else
/* Listen on a local address.
Must be done before setting anything else in mdp.bind, since mdp.bind
and mdp.addrlist share storage as a union in the mdp structure. */
bcopy(&mdp.addrlist.sids[0][0],mdp.bind.sid,SID_SIZE);
unsigned char srcsid[SID_SIZE];
if (overlay_mdp_getmyaddr(0,mdp.bind.sid)) return -1;
bcopy(mdp.bind.sid,srcsid,SID_SIZE);
mdp.bind.port_number=port;
int result=overlay_mdp_send(&mdp,MDP_AWAITREPLY,5000);
if (result) {
if (mdp.packetTypeAndFlags==MDP_ERROR)
fprintf(stderr,"Could not bind to MDP port %d: error=%d, message='%s'\n",
port,mdp.error.error,mdp.error.message);
else
fprintf(stderr,"Could not bind to MDP port %d (no reason given)\n",port);
return -1;
}
int port=32768+(random()&32767);
if (overlay_mdp_getmyaddr(0,srcsid)) return WHY("Could not get local address");
if (overlay_mdp_bind(srcsid,port)) return WHY("Could not bind to MDP socket");
/* First sequence number in the echo frames */
unsigned int firstSeq=random();
@ -726,7 +773,7 @@ int app_mdp_ping(int argc, const char *const *argv, struct command_line_option *
while(now<timeout) {
long long timeout_ms=timeout-overlay_gettime_ms();
result = overlay_mdp_client_poll(timeout_ms);
int result = overlay_mdp_client_poll(timeout_ms);
if (result>0) {
int ttl=-1;
@ -1089,7 +1136,7 @@ command_line_option command_line_options[]={
{cli_usage,{"help",NULL},0,
"Display command usage."},
{app_echo,{"echo","...",NULL},CLIFLAG_STANDALONE,
"Lookup the SIP/MDP address of the supplied telephone number (DID)."},
"Output the supplied string."},
{app_server_start,{"node","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,

View File

@ -459,6 +459,56 @@ int overlay_saw_mdp_frame(int interface, overlay_mdp_frame *mdp,long long now)
verfies out okay. */
WHY("key mapping request");
return keyring_mapping_request(keyring,mdp);
case MDP_PORT_DNALOOKUP: /* attempt to resolve DID to SID */
{
int cn=0,in=0,kp=0;
char did[64+1];
int pll=mdp->out.payload_length;
/* get did from the packet */
if (mdp->out.payload_length>=64)
return WHY("DNA DID resolution contains excessively long DID");
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;
overlay_mdp_swap_src_dst(mdp);
while(keyring_find_did(keyring,&cn,&in,&kp,did))
{
/* package DID plus SID into reply (we include the DID because
it could be a wild-card DID search). */
if (keyring->contexts[cn]->identities[in]->keypairs[kp]
->private_key_len>64)
/* skip excessively long DID records */
continue;
/* copy SID out */
bcopy(keyring->contexts[cn]->identities[in]->keypairs[0]
->public_key,&mdp->out.payload[0],
keyring->contexts[cn]->identities[in]->keypairs[0]
->public_key_len);
/* and null-terminated DID */
bcopy(keyring->contexts[cn]->identities[in]->keypairs[kp]
->private_key,&mdp->out.payload[SID_SIZE],
keyring->contexts[cn]->identities[in]->keypairs[kp]
->private_key_len);
/* set length */
mdp->out.payload_length=SID_SIZE+
keyring->contexts[cn]->identities[in]->keypairs[kp]
->private_key_len;
overlay_mdp_dispatch(mdp,0 /* system generated */,
NULL,0);
}
/* and switch addresses back around in case the caller was planning on
using MDP structure again (this happens if there is a loop-back reply
and the frame needs sending on, as happens with broadcasts. MDP ping
is a simple application where this occurs).
Similarly restore MDP payload content and length */
overlay_mdp_swap_src_dst(mdp);
bcopy(&did[0],&mdp->out.payload[0],pll);
mdp->out.payload_length=pll;
return 0;
}
break;
case MDP_PORT_ECHO: /* well known ECHO port for TCP/UDP and now MDP */
{
/* Echo is easy: we swap the sender and receiver addresses (and thus port
@ -1135,6 +1185,24 @@ int overlay_mdp_recv(overlay_mdp_frame *mdp,int *ttl)
return 0;
} else
/* no packet received */
return WHY("No packet received");
return -1;
}
int overlay_mdp_bind(unsigned char *localaddr,int port)
{
overlay_mdp_frame mdp;
mdp.packetTypeAndFlags=MDP_BIND;
bcopy(localaddr,mdp.bind.sid,SID_SIZE);
mdp.bind.port_number=port;
int result=overlay_mdp_send(&mdp,MDP_AWAITREPLY,5000);
if (result) {
if (mdp.packetTypeAndFlags==MDP_ERROR)
fprintf(stderr,"Could not bind to MDP port %d: error=%d, message='%s'\n",
port,mdp.error.error,mdp.error.message);
else
fprintf(stderr,"Could not bind to MDP port %d (no reason given)\n",port);
return -1;
}
return 0;
}

View File

@ -1337,6 +1337,7 @@ int cli_printf(const char *fmt, ...);
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 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);