mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-18 20:57:56 +00:00
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:
parent
e5394dd143
commit
dceeed8d35
@ -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 \
|
||||
|
@ -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
118
dna_helper.c
Normal 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;
|
||||
}
|
@ -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;
|
||||
|
5
serval.h
5
serval.h
@ -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
33
sighandlers.c
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user