more work on dna helper interface.

Also added missing dna_helper.c file from previous changes.
moved sigpipe/sigio detection code to own file.
This commit is contained in:
gardners 2012-06-21 10:30:08 +09:30
parent e5394dd143
commit dceeed8d35
6 changed files with 158 additions and 15 deletions

View File

@ -43,6 +43,7 @@ SERVALD_SRC_FILES = \
serval-dna/vomp.c \
serval-dna/lsif.c \
serval-dna/dna_helper.c \
serval-dna/sighandlers.c \
serval-dna/monitor.c \
serval-dna/monitor-cli.c \
serval-dna/codecs.c \

View File

@ -46,6 +46,7 @@ SRCS= main.c \
monitor.c \
monitor-cli.c \
dna_helper.c \
sighandlers.c \
codecs.c \
audiodevices.c \
audio_msm_g1.c \

118
dna_helper.c Normal file
View File

@ -0,0 +1,118 @@
/*
Serval Distributed Numbering Architecture (DNA)
Copyright (C) 2012 Paul Gardner-Stephen
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "serval.h"
/*
The challenge with making an interface for calling an external program to
resolve a DID into a URI is that it really should be asynchronous, so that
servald can't pause due to delays in looking up DIDs by helper applications.
This can be partially mitigated by having a cache, so that at least for repeated
requests the helper doesn't need to be called each time. This is very important
because the DNA protocol relies on pre-emptive retries to ensure reception of
a request over a lossy network.
The second part of the solution is to create an asynchronous queue for requests,
by passing them via file descriptor to a single persistent instance of the DNA
helper application, and polling the output of that application for results, and
then passing them out to their destinations. This ensures that the process is
asynchronous and non-blocking, regardless of how much time the helper application
requires. Then the helper will just be another file descriptor to poll in the
main loop.
*/
int dna_helper_stdin=-1;
int dna_helper_stdout=-1;
int dna_helper_start(const char *command)
{
return -1;
}
int dna_helper_enqueue(char *did, unsigned char *requestorSid)
{
/* Check if we have a helper configured. If not, then set
dna_helper_stdin to magic value of -2 so that we don't waste time
in future looking up the dna helper configuration value. */
if (dna_helper_stdin==-2) return -1;
if (dna_helper_stdin==-1) {
const char *dna_helper = confValueGet("dna.helper",NULL);
if (!dna_helper||!dna_helper[0]) {
dna_helper_stdin=-2;
return -1;
}
/* Okay, so we have a helper configured.
Run it */
dna_helper_start(dna_helper);
if (dna_helper_stdin<0)
return -1;
}
/* Write request to dna helper.
Request takes form: DID<space>SID-of-Requestor\n
By passing the requestor's SID to the helper, we don't need to maintain
any state, as all we have to do is wait for responses from the helper,
which will include the requestor's SID.
*/
signal(SIGPIPE,sigPipeHandler);
sigPipeFlag=0;
write(dna_helper_stdin,did,strlen(did));
write(dna_helper_stdin," ",1);
write(dna_helper_stdin,overlay_render_sid(requestorSid),SID_SIZE*2);
write(dna_helper_stdin,"\n",1);
if (sigPipeFlag) {
/* Assume broken pipe due to dead helper.
Next request will cause it to be restarted.
(Losing the current request is not a big problem, because
DNA preemptively retries, anyway.
XXX In fact, we should probably have a limit to the number of restarts
in quick succession so that we don't waste lots of time with a buggy or
suicidal helper.
*/
close(dna_helper_stdin);
close(dna_helper_stdout);
dna_helper_stdin=-1;
dna_helper_stdout=-1;
return -1;
}
return 0;
}
int dna_return_resolution(overlay_mdp_frame *mdp, unsigned char *fromSid,
const char *did,const char *name,const char *uri)
{
/* copy SID out into source address of frame */
bcopy(fromSid,&mdp->out.src.sid[0],SID_SIZE);
/* and build reply as did\nname\nURI<NUL> */
snprintf((char *)&mdp->out.payload[0],512,"%s\n%s\n%s",
did,name,uri);
mdp->out.payload_length=strlen((char *)mdp->out.payload)+1;
/* Dispatch response */
mdp->packetTypeAndFlags&=MDP_FLAG_MASK;
mdp->packetTypeAndFlags|=MDP_TX;
overlay_mdp_dispatch(mdp,0 /* system generated */,
NULL,0);
return 0;
}

View File

@ -31,8 +31,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
int rhizome_server_socket=-1;
int sigPipeFlag=0;
int sigIoFlag=0;
rhizome_http_request *rhizome_live_http_requests[RHIZOME_SERVER_MAX_LIVE_REQUESTS];
int rhizome_server_live_request_count=0;
@ -62,19 +60,6 @@ unsigned char favicon_bytes[]={
,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int favicon_len=318;
void sigPipeHandler(int signal)
{
sigPipeFlag++;
return;
}
void sigIoHandler(int signal)
{
WHY("sigio");
sigIoFlag++;
return;
}
int rhizome_server_start()
{
if (rhizome_server_socket>-1) return 0;

View File

@ -1523,3 +1523,8 @@ int server_probe(int *pid);
int dna_helper_enqueue(char *did, unsigned char *requestorSid);
int dna_return_resolution(overlay_mdp_frame *mdp, unsigned char *fromSid,
const char *did,const char *name,const char *uri);
extern int sigPipeFlag;
extern int sigIoFlag;
void sigPipeHandler(int signal);
void sigIoHandler(int signal);

33
sighandlers.c Normal file
View File

@ -0,0 +1,33 @@
/*
Serval Distributed Numbering Architecture (DNA)
Copyright (C) 2012 Paul Gardner-Stephen
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
int sigPipeFlag=0;
int sigIoFlag=0;
void sigPipeHandler(int signal)
{
sigPipeFlag++;
return;
}
void sigIoHandler(int signal)
{
sigIoFlag++;
return;
}