mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-18 02:39:44 +00:00
Refactor source and build process to split out test commands
This commit is contained in:
parent
44ed0ba575
commit
7bc253e844
30
Makefile.in
30
Makefile.in
@ -18,6 +18,17 @@ OBJSDIR_TOOLS = objs
|
||||
|
||||
OBJSDIRS = $(OBJSDIR_SERVALD) $(OBJSDIR_LIB) $(OBJSDIR_TOOLS)
|
||||
|
||||
ALL_SOURCES = \
|
||||
$(SERVAL_CLIENT_SOURCES) \
|
||||
$(MDP_CLIENT_SOURCES) \
|
||||
$(SERVAL_DAEMON_SOURCES) \
|
||||
$(NACL_SOURCES) \
|
||||
$(TEST_SOURCES) \
|
||||
$(SERVAL_LIB_SOURCES) \
|
||||
$(MONITOR_CLIENT_SRCS) \
|
||||
$(SIMULATOR_SOURCES) \
|
||||
$(SQLITE3_SOURCES)
|
||||
|
||||
SERVAL_DAEMON_OBJS = \
|
||||
$(addprefix $(OBJSDIR_SERVALD)/, $(SERVAL_CLIENT_SOURCES:.c=.o)) \
|
||||
$(addprefix $(OBJSDIR_SERVALD)/, $(MDP_CLIENT_SOURCES:.c=.o)) \
|
||||
@ -26,6 +37,10 @@ SERVALD_OBJS = \
|
||||
$(addprefix $(OBJSDIR_SERVALD)/, $(notdir $(SQLITE3_SOURCES:.c=.o))) \
|
||||
$(addprefix $(OBJSDIR_SERVALD)/, $(NACL_SOURCES:.c=.o)) \
|
||||
$(SERVAL_DAEMON_OBJS)
|
||||
TEST_OBJS = \
|
||||
$(addprefix $(OBJSDIR_SERVALD)/, $(TEST_SOURCES:.c=.o)) \
|
||||
$(addprefix $(OBJSDIR_SERVALD)/, $(NACL_SOURCES:.c=.o)) \
|
||||
$(addprefix $(OBJSDIR_SERVALD)/, $(SERVAL_CLIENT_SOURCES:.c=.o))
|
||||
LIB_SERVAL_OBJS = \
|
||||
$(addprefix $(OBJSDIR_LIB)/, $(SERVAL_CLIENT_SOURCES:.c=.o)) \
|
||||
$(addprefix $(OBJSDIR_LIB)/, $(SERVAL_LIB_SOURCES:.c=.o)) \
|
||||
@ -67,7 +82,7 @@ DEFS= @DEFS@
|
||||
|
||||
all: servald libserval.so libmonitorclient.so libmonitorclient.a test
|
||||
|
||||
test: tfw_createfile directory_service fakeradio config_test simulator
|
||||
test: tfw_createfile directory_service fakeradio simulator serval-tests
|
||||
|
||||
covzero: | is_built_with_coverage
|
||||
@echo REMOVE all .gcda files
|
||||
@ -117,7 +132,7 @@ config.status: configure
|
||||
configure: configure.in
|
||||
$(warning configure may be out of date, please run autoreconf -f -i)
|
||||
|
||||
$(OBJSDIR_TOOLS)/version.o: $(SERVALD_OBJS) version_servald.c version_string.sh $(wildcard VERSION.txt) COPYRIGHT.txt
|
||||
$(OBJSDIR_TOOLS)/version.o: $(ALL_SOURCES) $(HDRS) version_servald.c version_string.sh $(wildcard VERSION.txt) COPYRIGHT.txt
|
||||
@echo CC version_servald.c
|
||||
@mkdir -p $(dir $@)
|
||||
@$(RM) $(@:.o=.gcno) $(@:.o=.gcda)
|
||||
@ -159,14 +174,15 @@ $(SERVALD_OBJS): Makefile
|
||||
$(LIB_SERVAL_OBJS): $(HDRS) Makefile
|
||||
$(MONITOR_CLIENT_OBJS): $(HDRS) Makefile
|
||||
$(SIMULATOR_OBJS): $(HDRS) Makefile
|
||||
$(OBJSDIR_TOOLS)/directory_service.o $(OBJSDIR_TOOLS)/tfw_createfile.o $(OBJSDIR_TOOLS)/fakeradio.o \
|
||||
$(OBJSDIR_TOOLS)/config_test.o $(OBJSDIR_TOOLS)/conf_om.o $(OBJSDIR_TOOLS)/conf_schema.o $(OBJSDIR_TOOLS)/conf_parse.o libserval.a \
|
||||
: $(HDRS) Makefile
|
||||
|
||||
servald: $(SERVALD_OBJS) $(OBJSDIR_TOOLS)/version.o
|
||||
@echo LINK $@
|
||||
@$(CC) -Wall -o $@ $(SERVALD_OBJS) $(OBJSDIR_TOOLS)/version.o $(LDFLAGS)
|
||||
|
||||
serval-tests: $(TEST_OBJS) $(OBJSDIR_TOOLS)/version.o
|
||||
@echo LINK $@
|
||||
@$(CC) -Wall -o $@ $(TEST_OBJS) $(OBJSDIR_TOOLS)/version.o $(LDFLAGS)
|
||||
|
||||
libserval.a: $(LIB_SERVAL_OBJS) $(OBJSDIR_TOOLS)/version.o
|
||||
@echo AR $@
|
||||
@$(AR) -cr $@ $(LIB_SERVAL_OBJS) $(OBJSDIR_TOOLS)/version.o
|
||||
@ -187,10 +203,6 @@ simulator: $(SIMULATOR_OBJS) libserval.a
|
||||
@echo LINK $@
|
||||
@$(CC) -Wall -o $@ $(SIMULATOR_OBJS) libserval.a $(LDFLAGS)
|
||||
|
||||
config_test: $(OBJSDIR_TOOLS)/config_test.o $(OBJSDIR_TOOLS)/conf_om.o $(OBJSDIR_TOOLS)/conf_schema.o $(OBJSDIR_TOOLS)/conf_parse.o libserval.a
|
||||
@echo LINK $@
|
||||
@$(CC) -Wall -o $@ $(OBJSDIR_TOOLS)/config_test.o $(OBJSDIR_TOOLS)/conf_om.o $(OBJSDIR_TOOLS)/conf_schema.o $(OBJSDIR_TOOLS)/conf_parse.o libserval.a $(LDFLAGS)
|
||||
|
||||
copyright:
|
||||
@if [ -x "$(COPYRIGHT_TOOL)" ]; then \
|
||||
echo GENERATE COPYRIGHT.txt; \
|
||||
|
280
commandline.c
280
commandline.c
@ -250,10 +250,7 @@ int parseCommandLine(struct cli_context *context, const char *argv0, int argc, c
|
||||
break;
|
||||
}
|
||||
|
||||
/* clean up after ourselves */
|
||||
rhizome_close_db();
|
||||
free_subscribers();
|
||||
assert(keyring==NULL);
|
||||
cli_cleanup();
|
||||
|
||||
OUT();
|
||||
|
||||
@ -555,278 +552,3 @@ static int app_log(const struct cli_parsed *parsed, struct cli_context *UNUSED(c
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lookup_send_request(int mdp_sockfd, const sid_t *srcsid, int srcport, const sid_t *dstsid, const char *did)
|
||||
{
|
||||
overlay_mdp_frame mdp;
|
||||
bzero(&mdp,sizeof(mdp));
|
||||
|
||||
/* set source address to the local address and port */
|
||||
mdp.out.src.port = srcport;
|
||||
mdp.out.src.sid = *srcsid;
|
||||
|
||||
/* Send to destination address and DNA lookup port */
|
||||
if (dstsid) {
|
||||
/* Send an encrypted unicast packet */
|
||||
mdp.packetTypeAndFlags=MDP_TX;
|
||||
mdp.out.dst.sid = *dstsid;
|
||||
}else{
|
||||
/* Send a broadcast packet, flooding across the local mesh network */
|
||||
mdp.packetTypeAndFlags=MDP_TX|MDP_NOCRYPT;
|
||||
mdp.out.dst.sid = SID_BROADCAST;
|
||||
}
|
||||
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;
|
||||
|
||||
overlay_mdp_send(mdp_sockfd, &mdp, 0, 0);
|
||||
|
||||
/* Also send an encrypted unicast request to a configured directory service */
|
||||
if (!dstsid){
|
||||
if (!is_sid_t_any(config.directory.service)) {
|
||||
mdp.out.dst.sid = config.directory.service;
|
||||
mdp.packetTypeAndFlags=MDP_TX;
|
||||
overlay_mdp_send(mdp_sockfd, &mdp,0,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_CMD(app_dna_lookup, 0,
|
||||
"Lookup the subscribers (SID) with the supplied telephone number (DID).",
|
||||
"dna","lookup","<did>","[<timeout>]");
|
||||
static int app_dna_lookup(const struct cli_parsed *parsed, struct cli_context *context)
|
||||
{
|
||||
int mdp_sockfd;
|
||||
if (config.debug.verbose)
|
||||
DEBUG_cli_parsed(parsed);
|
||||
|
||||
/* Create the instance directory if it does not yet exist */
|
||||
if (create_serval_instance_dir() == -1)
|
||||
return -1;
|
||||
|
||||
int uri_count=0;
|
||||
#define MAXREPLIES 256
|
||||
#define MAXURILEN 256
|
||||
char uris[MAXREPLIES][MAXURILEN];
|
||||
|
||||
const char *did, *delay;
|
||||
if (cli_arg(parsed, "did", &did, cli_lookup_did, "*") == -1)
|
||||
return -1;
|
||||
if (cli_arg(parsed, "timeout", &delay, NULL, "3000") == -1)
|
||||
return -1;
|
||||
|
||||
int idelay=atoi(delay);
|
||||
int one_reply=0;
|
||||
|
||||
// Ugly hack, if timeout is negative, stop after first reply
|
||||
if (idelay<0){
|
||||
one_reply=1;
|
||||
idelay=-idelay;
|
||||
}
|
||||
|
||||
if ((mdp_sockfd = overlay_mdp_client_socket()) < 0)
|
||||
return WHY("Cannot create MDP socket");
|
||||
|
||||
/* Bind to MDP socket and await confirmation */
|
||||
sid_t srcsid;
|
||||
mdp_port_t port=32768+(random()&32767);
|
||||
if (overlay_mdp_getmyaddr(mdp_sockfd, 0, &srcsid)) {
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
return WHY("Could not get local address");
|
||||
}
|
||||
if (overlay_mdp_bind(mdp_sockfd, &srcsid, port)) {
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
return WHY("Could not bind to MDP socket");
|
||||
}
|
||||
|
||||
/* use MDP to send the lookup request to MDP_PORT_DNALOOKUP, and wait for
|
||||
replies. */
|
||||
|
||||
/* Now repeatedly send resolution request and collect results until we reach
|
||||
timeout. */
|
||||
time_ms_t timeout = gettime_ms() + idelay;
|
||||
time_ms_t last_tx = 0;
|
||||
time_ms_t now;
|
||||
int interval=125;
|
||||
|
||||
const char *names[]={
|
||||
"uri",
|
||||
"did",
|
||||
"name"
|
||||
};
|
||||
cli_columns(context, 3, names);
|
||||
size_t rowcount = 0;
|
||||
|
||||
while (timeout > (now = gettime_ms())){
|
||||
if ((last_tx+interval)<now){
|
||||
lookup_send_request(mdp_sockfd, &srcsid, port, NULL, did);
|
||||
last_tx=now;
|
||||
interval+=interval>>1;
|
||||
}
|
||||
time_ms_t short_timeout=125;
|
||||
while(short_timeout>0) {
|
||||
if (overlay_mdp_client_poll(mdp_sockfd, short_timeout)){
|
||||
overlay_mdp_frame rx;
|
||||
int ttl;
|
||||
if (overlay_mdp_recv(mdp_sockfd, &rx, port, &ttl)==0){
|
||||
if (rx.packetTypeAndFlags==MDP_ERROR){
|
||||
WHYF(" Error message: %s", rx.error.message);
|
||||
} else if ((rx.packetTypeAndFlags&MDP_TYPE_MASK)==MDP_TX) {
|
||||
/* Extract DID, Name, URI from response. */
|
||||
if (strlen((char *)rx.out.payload)<512) {
|
||||
char sidhex[SID_STRLEN + 1];
|
||||
char did[DID_MAXSIZE + 1];
|
||||
char name[64];
|
||||
char uri[512];
|
||||
if ( !parseDnaReply((char *)rx.out.payload, rx.out.payload_length, sidhex, did, name, uri, NULL)
|
||||
|| !str_is_subscriber_id(sidhex)
|
||||
|| !str_is_did(did)
|
||||
|| !str_is_uri(uri)
|
||||
) {
|
||||
WHYF("Received malformed DNA reply: %s", alloca_toprint(160, (const char *)rx.out.payload, rx.out.payload_length));
|
||||
} else {
|
||||
/* Have we seen this response before? */
|
||||
int i;
|
||||
for(i=0;i<uri_count;i++)
|
||||
if (!strcmp(uri,uris[i])) break;
|
||||
if (i==uri_count) {
|
||||
/* Not previously seen, so report it */
|
||||
cli_put_string(context, uri, ":");
|
||||
cli_put_string(context, did, ":");
|
||||
cli_put_string(context, name, "\n");
|
||||
rowcount++;
|
||||
|
||||
if (one_reply){
|
||||
timeout=now;
|
||||
short_timeout=0;
|
||||
}
|
||||
|
||||
/* Remember that we have seen it */
|
||||
if (uri_count<MAXREPLIES&&strlen(uri)<MAXURILEN) {
|
||||
strcpy(uris[uri_count++],uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else WHYF("packettype=0x%x",rx.packetTypeAndFlags);
|
||||
}
|
||||
}
|
||||
short_timeout=125-(gettime_ms()-now);
|
||||
}
|
||||
}
|
||||
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
cli_row_count(context, rowcount);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_CMD(app_reverse_lookup, 0,
|
||||
"Lookup the phone number (DID) and name of a given subscriber (SID)",
|
||||
"reverse", "lookup", "<sid>", "[<timeout>]");
|
||||
static int app_reverse_lookup(const struct cli_parsed *parsed, struct cli_context *context)
|
||||
{
|
||||
int mdp_sockfd;
|
||||
if (config.debug.verbose)
|
||||
DEBUG_cli_parsed(parsed);
|
||||
const char *sidhex, *delay;
|
||||
if (cli_arg(parsed, "sid", &sidhex, str_is_subscriber_id, "") == -1)
|
||||
return -1;
|
||||
if (cli_arg(parsed, "timeout", &delay, NULL, "3000") == -1)
|
||||
return -1;
|
||||
|
||||
mdp_port_t port=32768+(random()&0xffff);
|
||||
|
||||
sid_t srcsid;
|
||||
sid_t dstsid;
|
||||
|
||||
if (str_to_sid_t(&dstsid, sidhex) == -1)
|
||||
return WHY("str_to_sid_t() failed");
|
||||
|
||||
if ((mdp_sockfd = overlay_mdp_client_socket()) < 0)
|
||||
return WHY("Cannot create MDP socket");
|
||||
|
||||
if (overlay_mdp_getmyaddr(mdp_sockfd, 0, &srcsid)){
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
return WHY("Unable to get my address");
|
||||
}
|
||||
if (overlay_mdp_bind(mdp_sockfd, &srcsid, port)){
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
return WHY("Unable to bind port");
|
||||
}
|
||||
|
||||
time_ms_t now = gettime_ms();
|
||||
time_ms_t timeout = now + atoi(delay);
|
||||
time_ms_t next_send = now;
|
||||
overlay_mdp_frame mdp_reply;
|
||||
|
||||
while (now < timeout){
|
||||
now=gettime_ms();
|
||||
|
||||
if (now >= next_send){
|
||||
/* Send a unicast packet to this node, asking for any did */
|
||||
lookup_send_request(mdp_sockfd, &srcsid, port, &dstsid, "");
|
||||
next_send+=125;
|
||||
continue;
|
||||
}
|
||||
|
||||
time_ms_t poll_timeout = (next_send>timeout?timeout:next_send) - now;
|
||||
if (overlay_mdp_client_poll(mdp_sockfd, poll_timeout)<=0)
|
||||
continue;
|
||||
|
||||
int ttl=-1;
|
||||
if (overlay_mdp_recv(mdp_sockfd, &mdp_reply, port, &ttl))
|
||||
continue;
|
||||
|
||||
if ((mdp_reply.packetTypeAndFlags&MDP_TYPE_MASK)==MDP_ERROR){
|
||||
// TODO log error?
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mdp_reply.packetTypeAndFlags!=MDP_TX) {
|
||||
WHYF("MDP returned an unexpected message (type=0x%x)",
|
||||
mdp_reply.packetTypeAndFlags);
|
||||
|
||||
if (mdp_reply.packetTypeAndFlags==MDP_ERROR)
|
||||
WHYF("MDP message is return/error: %d:%s",
|
||||
mdp_reply.error.error,mdp_reply.error.message);
|
||||
continue;
|
||||
}
|
||||
|
||||
// we might receive a late response from an ealier request on the same socket, ignore it
|
||||
if (cmp_sid_t(&mdp_reply.out.src.sid, &dstsid) != 0) {
|
||||
WHYF("Unexpected result from SID %s", alloca_tohex_sid_t(mdp_reply.out.src.sid));
|
||||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
char sidhex[SID_STRLEN + 1];
|
||||
char did[DID_MAXSIZE + 1];
|
||||
char name[64];
|
||||
char uri[512];
|
||||
if ( !parseDnaReply((char *)mdp_reply.out.payload, mdp_reply.out.payload_length, sidhex, did, name, uri, NULL)
|
||||
|| !str_is_subscriber_id(sidhex)
|
||||
|| !str_is_did(did)
|
||||
|| !str_is_uri(uri)
|
||||
) {
|
||||
WHYF("Received malformed DNA reply: %s",
|
||||
alloca_toprint(160, (const char *)mdp_reply.out.payload, mdp_reply.out.payload_length));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Got a good DNA reply, copy it into place and stop polling */
|
||||
cli_field_name(context, "sid", ":");
|
||||
cli_put_string(context, sidhex, "\n");
|
||||
cli_field_name(context, "did", ":");
|
||||
cli_put_string(context, did, "\n");
|
||||
cli_field_name(context, "name", ":");
|
||||
cli_put_string(context, name, "\n");
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -67,4 +67,6 @@ void cli_put_string(struct cli_context *context, const char *value, const char *
|
||||
void cli_put_hexvalue(struct cli_context *context, const unsigned char *value, int length, const char *delim);
|
||||
int cli_write(struct cli_context *context, const unsigned char *buf, size_t len);
|
||||
|
||||
void cli_cleanup();
|
||||
|
||||
#endif
|
4
conf.c
4
conf.c
@ -51,7 +51,7 @@ static int reload(const char *path, int *resultp)
|
||||
if (config.debug.config)
|
||||
DEBUGF(" file path=%s", alloca_str_toprint(path));
|
||||
struct file_meta meta;
|
||||
if (get_file_meta(conffile_path(), &meta) == -1)
|
||||
if (get_file_meta(path, &meta) == -1)
|
||||
return -1;
|
||||
if (config.debug.config) {
|
||||
DEBUGF(" file meta=%s", alloca_file_meta(&meta));
|
||||
@ -60,7 +60,7 @@ static int reload(const char *path, int *resultp)
|
||||
if (cmp_file_meta(&meta, &conffile_meta) == 0)
|
||||
return 0;
|
||||
if (conffile_meta.mtime.tv_sec != -1)
|
||||
INFOF("config file %s -- detected new version", conffile_path());
|
||||
INFOF("config file %s -- detected new version", path);
|
||||
char *buf = NULL;
|
||||
if (meta.mtime.tv_sec == -1) {
|
||||
WARNF("config file %s does not exist -- using all defaults", path);
|
||||
|
114
config_test.c
114
config_test.c
@ -1,114 +0,0 @@
|
||||
/*
|
||||
Serval DNA configuration stand-alone configuration check utility
|
||||
Copyright 2013 Serval Project Inc.
|
||||
|
||||
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 <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "str.h"
|
||||
#define __SERVAL_LOG_INLINE
|
||||
#include "log.h"
|
||||
#include "conf.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i < argc; ++i) {
|
||||
int fd = open(argv[i], O_RDONLY);
|
||||
if (fd == -1) {
|
||||
perror("open");
|
||||
exit(1);
|
||||
}
|
||||
struct stat st;
|
||||
fstat(fd, &st);
|
||||
char *buf = malloc(st.st_size);
|
||||
if (!buf) {
|
||||
perror("malloc");
|
||||
exit(1);
|
||||
}
|
||||
if (read(fd, buf, st.st_size) != st.st_size) {
|
||||
perror("read");
|
||||
exit(1);
|
||||
}
|
||||
struct cf_om_node *root = NULL;
|
||||
int ret = cf_om_parse(argv[i], buf, st.st_size, &root);
|
||||
close(fd);
|
||||
DEBUGF("ret = %s", strbuf_str(strbuf_cf_flags(strbuf_alloca(128), ret)));
|
||||
//cf_dump_node(root, 0);
|
||||
struct config_main config;
|
||||
memset(&config, 0, sizeof config);
|
||||
cf_dfl_config_main(&config);
|
||||
int result = root ? cf_opt_config_main(&config, root) : CFEMPTY;
|
||||
cf_om_free_node(&root);
|
||||
free(buf);
|
||||
DEBUGF("result = %s", strbuf_str(strbuf_cf_flags(strbuf_alloca(128), result)));
|
||||
DEBUGF("config.log.file.path = %s", alloca_str_toprint(config.log.file.path));
|
||||
DEBUGF("config.log.file.show_pid = %d", config.log.file.show_pid);
|
||||
DEBUGF("config.log.file.show_time = %d", config.log.file.show_time);
|
||||
DEBUGF("config.server.chdir = %s", alloca_str_toprint(config.server.chdir));
|
||||
DEBUGF("config.debug.verbose = %d", config.debug.verbose);
|
||||
DEBUGF("config.directory.service = %s", alloca_tohex_sid_t(config.directory.service));
|
||||
DEBUGF("config.rhizome.api.addfile.allow_host = %s", inet_ntoa(config.rhizome.api.addfile.allow_host));
|
||||
unsigned j;
|
||||
for (j = 0; j < config.mdp.iftype.ac; ++j) {
|
||||
DEBUGF("config.mdp.iftype.%u", config.mdp.iftype.av[j].key);
|
||||
DEBUGF(" .tick_ms = %u", config.mdp.iftype.av[j].value.tick_ms);
|
||||
}
|
||||
for (j = 0; j < config.dna.helper.argv.ac; ++j) {
|
||||
DEBUGF("config.dna.helper.argv.%u=%s", config.dna.helper.argv.av[j].key, config.dna.helper.argv.av[j].value);
|
||||
}
|
||||
for (j = 0; j < config.rhizome.direct.peer.ac; ++j) {
|
||||
DEBUGF("config.rhizome.direct.peer.%s", config.rhizome.direct.peer.av[j].key);
|
||||
DEBUGF(" .protocol = %s", alloca_str_toprint(config.rhizome.direct.peer.av[j].value.protocol));
|
||||
DEBUGF(" .host = %s", alloca_str_toprint(config.rhizome.direct.peer.av[j].value.host));
|
||||
DEBUGF(" .port = %u", config.rhizome.direct.peer.av[j].value.port);
|
||||
}
|
||||
for (j = 0; j < config.interfaces.ac; ++j) {
|
||||
DEBUGF("config.interfaces.%u", config.interfaces.av[j].key);
|
||||
DEBUGF(" .exclude = %d", config.interfaces.av[j].value.exclude);
|
||||
DEBUGF(" .match = [");
|
||||
unsigned k;
|
||||
for (k = 0; k < config.interfaces.av[j].value.match.patc; ++k)
|
||||
DEBUGF(" %s", alloca_str_toprint(config.interfaces.av[j].value.match.patv[k]));
|
||||
DEBUGF(" ]");
|
||||
DEBUGF(" .type = %d", config.interfaces.av[j].value.type);
|
||||
DEBUGF(" .port = %u", config.interfaces.av[j].value.port);
|
||||
DEBUGF(" .drop_broadcasts = %d", (int) config.interfaces.av[j].value.drop_broadcasts);
|
||||
DEBUGF(" .drop_unicasts = %d", (int) config.interfaces.av[j].value.drop_unicasts);
|
||||
DEBUGF(" .drop_packets = %u", (unsigned) config.interfaces.av[j].value.drop_packets);
|
||||
}
|
||||
for (j = 0; j < config.hosts.ac; ++j) {
|
||||
char sidhex[SID_STRLEN + 1];
|
||||
tohex(sidhex, SID_STRLEN, config.hosts.av[j].key.binary);
|
||||
DEBUGF("config.hosts.%s", sidhex);
|
||||
DEBUGF(" .interface = %s", alloca_str_toprint(config.hosts.av[j].value.interface));
|
||||
DEBUGF(" .address = %s", inet_ntoa(config.hosts.av[j].value.address));
|
||||
DEBUGF(" .port = %u", config.hosts.av[j].value.port);
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void cf_on_config_change()
|
||||
{
|
||||
}
|
@ -60,14 +60,7 @@ struct radio_state {
|
||||
#define STATE_PLUSPLUSPLUS 3
|
||||
#define STATE_COMMAND 4
|
||||
|
||||
int64_t gettime_ms()
|
||||
{
|
||||
struct timeval nowtv;
|
||||
// If gettimeofday() fails or returns an invalid value, all else is lost!
|
||||
if (gettimeofday(&nowtv, NULL) == -1)
|
||||
perror("gettimeofday");
|
||||
return nowtv.tv_sec * 1000LL + nowtv.tv_usec / 1000;
|
||||
}
|
||||
void cf_on_config_change(){}
|
||||
|
||||
void log_time(){
|
||||
struct timeval tv;
|
||||
|
115
log.c
115
log.c
@ -17,6 +17,7 @@ along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <libgen.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
@ -29,7 +30,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <libgen.h>
|
||||
#include <dirent.h>
|
||||
#include <assert.h>
|
||||
|
||||
@ -401,14 +401,6 @@ static void _log_iterator_vprintf_nl(_log_iterator *it, int level, struct __sour
|
||||
}
|
||||
}
|
||||
|
||||
static void _log_iterator_printf_nl(_log_iterator *it, int level, struct __sourceloc whence, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
_log_iterator_vprintf_nl(it, level, whence, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void _logs_vprintf_nl(int level, struct __sourceloc whence, const char *fmt, va_list ap)
|
||||
{
|
||||
_log_iterator it;
|
||||
@ -688,108 +680,3 @@ void logConfigChanged()
|
||||
logFlush();
|
||||
}
|
||||
|
||||
int logBacktrace(int level, struct __sourceloc whence)
|
||||
{
|
||||
#ifndef NO_BACKTRACE
|
||||
_log_iterator it;
|
||||
_log_iterator_start(&it);
|
||||
_rotate_log_file(&it);
|
||||
char execpath[MAXPATHLEN];
|
||||
if (get_self_executable_path(execpath, sizeof execpath) == -1)
|
||||
return WHY("cannot log backtrace: own executable path unknown");
|
||||
char tempfile[MAXPATHLEN];
|
||||
if (!FORMF_SERVAL_TMP_PATH(tempfile, "servalgdb.XXXXXX"))
|
||||
return -1;
|
||||
int tmpfd = mkstemp(tempfile);
|
||||
if (tmpfd == -1)
|
||||
return WHYF_perror("mkstemp(%s)", alloca_str_toprint(tempfile));
|
||||
if (write_str(tmpfd, "backtrace\n") == -1) {
|
||||
close(tmpfd);
|
||||
unlink(tempfile);
|
||||
return -1;
|
||||
}
|
||||
if (close(tmpfd) == -1) {
|
||||
WHY_perror("close");
|
||||
unlink(tempfile);
|
||||
return -1;
|
||||
}
|
||||
char pidstr[12];
|
||||
snprintf(pidstr, sizeof pidstr, "%jd", (intmax_t)getpid());
|
||||
int stdout_fds[2];
|
||||
if (pipe(stdout_fds) == -1)
|
||||
return WHY_perror("pipe");
|
||||
pid_t child_pid;
|
||||
switch (child_pid = fork()) {
|
||||
case -1: // error
|
||||
WHY_perror("fork");
|
||||
close(stdout_fds[0]);
|
||||
close(stdout_fds[1]);
|
||||
return WHY("cannot log backtrace: fork failed");
|
||||
case 0: // child
|
||||
if (dup2(stdout_fds[1], 1) == -1 || dup2(stdout_fds[1], 2) == -1) {
|
||||
perror("dup2");
|
||||
_exit(-1);
|
||||
}
|
||||
close(0);
|
||||
if (open("/dev/null", O_RDONLY) != 0) {
|
||||
perror("open(\"/dev/null\")");
|
||||
_exit(-2);
|
||||
}
|
||||
close(stdout_fds[0]);
|
||||
// Need the (void*) cast on Solaris because it defines NULL as 0L and gcc doesn't accept it as a
|
||||
// sentinal
|
||||
execlp("gdb", "gdb", "-n", "-batch", "-x", tempfile, execpath, pidstr, (void*)NULL);
|
||||
perror("execlp(\"gdb\")");
|
||||
do { _exit(-3); } while (1);
|
||||
break;
|
||||
}
|
||||
// parent
|
||||
close(stdout_fds[1]);
|
||||
_log_iterator_printf_nl(&it, level, whence, "GDB BACKTRACE");
|
||||
char buf[1024];
|
||||
char *const bufe = buf + sizeof buf;
|
||||
char *linep = buf;
|
||||
char *readp = buf;
|
||||
ssize_t nr;
|
||||
while ((nr = read(stdout_fds[0], readp, bufe - readp)) > 0) {
|
||||
char *p = readp;
|
||||
readp = readp + nr;
|
||||
for (; p < readp; ++p)
|
||||
if (*p == '\n' || *p == '\0') {
|
||||
*p = '\0';
|
||||
_log_iterator_printf_nl(&it, level, __NOWHERE__, "GDB %s", linep);
|
||||
linep = p + 1;
|
||||
}
|
||||
if (readp >= bufe && linep == buf) {
|
||||
// Line does not fit into buffer.
|
||||
char t = bufe[-1];
|
||||
bufe[-1] = '\0';
|
||||
_log_iterator_printf_nl(&it, level, __NOWHERE__, "GDB %s", buf);
|
||||
buf[0] = t;
|
||||
readp = buf + 1;
|
||||
} else if (readp + 120 >= bufe && linep != buf) {
|
||||
// Buffer low on space.
|
||||
if (linep < readp)
|
||||
memmove(buf, linep, readp - linep);
|
||||
readp -= linep - buf;
|
||||
linep = buf;
|
||||
}
|
||||
// Invariant: readp < bufe
|
||||
}
|
||||
if (nr == -1)
|
||||
WHY_perror("read");
|
||||
if (readp > linep) {
|
||||
*readp = '\0';
|
||||
_log_iterator_printf_nl(&it, level, __NOWHERE__, "GDB %s", linep);
|
||||
}
|
||||
close(stdout_fds[0]);
|
||||
int status = 0;
|
||||
if (waitpid(child_pid, &status, 0) == -1)
|
||||
WHY_perror("waitpid");
|
||||
strbuf b = strbuf_local(buf, sizeof buf);
|
||||
strbuf_append_exit_status(b, status);
|
||||
_log_iterator_printf_nl(&it, level, __NOWHERE__, "gdb %s", buf);
|
||||
unlink(tempfile);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
111
log_util.c
111
log_util.c
@ -17,9 +17,17 @@ along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <libgen.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/param.h>
|
||||
#include "log.h"
|
||||
#include "strbuf.h"
|
||||
#include "strbuf_helpers.h"
|
||||
#include "instance.h"
|
||||
#include "str.h"
|
||||
#include "net.h"
|
||||
|
||||
int logDump(int level, struct __sourceloc whence, char *name, const unsigned char *addr, size_t len)
|
||||
{
|
||||
@ -104,3 +112,106 @@ int string_to_log_level(const char *text)
|
||||
if (strcasecmp(text, "silent") == 0) return LOG_LEVEL_SILENT;
|
||||
return LOG_LEVEL_INVALID;
|
||||
}
|
||||
|
||||
int logBacktrace(int level, struct __sourceloc whence)
|
||||
{
|
||||
#ifndef NO_BACKTRACE
|
||||
char execpath[MAXPATHLEN];
|
||||
if (get_self_executable_path(execpath, sizeof execpath) == -1)
|
||||
return WHY("cannot log backtrace: own executable path unknown");
|
||||
char tempfile[MAXPATHLEN];
|
||||
if (!FORMF_SERVAL_TMP_PATH(tempfile, "servalgdb.XXXXXX"))
|
||||
return -1;
|
||||
int tmpfd = mkstemp(tempfile);
|
||||
if (tmpfd == -1)
|
||||
return WHYF_perror("mkstemp(%s)", alloca_str_toprint(tempfile));
|
||||
if (write_str(tmpfd, "backtrace\n") == -1) {
|
||||
close(tmpfd);
|
||||
unlink(tempfile);
|
||||
return -1;
|
||||
}
|
||||
if (close(tmpfd) == -1) {
|
||||
WHY_perror("close");
|
||||
unlink(tempfile);
|
||||
return -1;
|
||||
}
|
||||
char pidstr[12];
|
||||
snprintf(pidstr, sizeof pidstr, "%jd", (intmax_t)getpid());
|
||||
int stdout_fds[2];
|
||||
if (pipe(stdout_fds) == -1)
|
||||
return WHY_perror("pipe");
|
||||
pid_t child_pid;
|
||||
switch (child_pid = fork()) {
|
||||
case -1: // error
|
||||
WHY_perror("fork");
|
||||
close(stdout_fds[0]);
|
||||
close(stdout_fds[1]);
|
||||
return WHY("cannot log backtrace: fork failed");
|
||||
case 0: // child
|
||||
if (dup2(stdout_fds[1], 1) == -1 || dup2(stdout_fds[1], 2) == -1) {
|
||||
perror("dup2");
|
||||
_exit(-1);
|
||||
}
|
||||
close(0);
|
||||
if (open("/dev/null", O_RDONLY) != 0) {
|
||||
perror("open(\"/dev/null\")");
|
||||
_exit(-2);
|
||||
}
|
||||
close(stdout_fds[0]);
|
||||
// Need the (void*) cast on Solaris because it defines NULL as 0L and gcc doesn't accept it as a
|
||||
// sentinal
|
||||
execlp("gdb", "gdb", "-n", "-batch", "-x", tempfile, execpath, pidstr, (void*)NULL);
|
||||
perror("execlp(\"gdb\")");
|
||||
do { _exit(-3); } while (1);
|
||||
break;
|
||||
}
|
||||
// parent
|
||||
close(stdout_fds[1]);
|
||||
logMessage(level, whence, "GDB BACKTRACE");
|
||||
char buf[1024];
|
||||
char *const bufe = buf + sizeof buf;
|
||||
char *linep = buf;
|
||||
char *readp = buf;
|
||||
ssize_t nr;
|
||||
while ((nr = read(stdout_fds[0], readp, bufe - readp)) > 0) {
|
||||
char *p = readp;
|
||||
readp = readp + nr;
|
||||
for (; p < readp; ++p)
|
||||
if (*p == '\n' || *p == '\0') {
|
||||
*p = '\0';
|
||||
logMessage(level, __NOWHERE__, "GDB %s", linep);
|
||||
linep = p + 1;
|
||||
}
|
||||
if (readp >= bufe && linep == buf) {
|
||||
// Line does not fit into buffer.
|
||||
char t = bufe[-1];
|
||||
bufe[-1] = '\0';
|
||||
logMessage(level, __NOWHERE__, "GDB %s", buf);
|
||||
buf[0] = t;
|
||||
readp = buf + 1;
|
||||
} else if (readp + 120 >= bufe && linep != buf) {
|
||||
// Buffer low on space.
|
||||
if (linep < readp)
|
||||
memmove(buf, linep, readp - linep);
|
||||
readp -= linep - buf;
|
||||
linep = buf;
|
||||
}
|
||||
// Invariant: readp < bufe
|
||||
}
|
||||
if (nr == -1)
|
||||
WHY_perror("read");
|
||||
if (readp > linep) {
|
||||
*readp = '\0';
|
||||
logMessage(level, __NOWHERE__, "GDB %s", linep);
|
||||
}
|
||||
close(stdout_fds[0]);
|
||||
int status = 0;
|
||||
if (waitpid(child_pid, &status, 0) == -1)
|
||||
WHY_perror("waitpid");
|
||||
strbuf b = strbuf_local(buf, sizeof buf);
|
||||
strbuf_append_exit_status(b, status);
|
||||
logMessage(level, __NOWHERE__, "gdb %s", buf);
|
||||
unlink(tempfile);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
279
network_cli.c
279
network_cli.c
@ -27,6 +27,10 @@
|
||||
#include "conf.h"
|
||||
#include "commandline.h"
|
||||
#include "sighandlers.h"
|
||||
#include "instance.h"
|
||||
#include "serval.h"
|
||||
#include "overlay_buffer.h"
|
||||
|
||||
|
||||
DEFINE_CMD(app_mdp_ping, 0,
|
||||
"Attempts to ping specified node via Mesh Datagram Protocol (MDP).",
|
||||
@ -530,3 +534,278 @@ static int app_network_scan(const struct cli_parsed *parsed, struct cli_context
|
||||
cli_put_string(context, mdp.error.message, "\n");
|
||||
return mdp.error.error;
|
||||
}
|
||||
|
||||
static void lookup_send_request(int mdp_sockfd, const sid_t *srcsid, int srcport, const sid_t *dstsid, const char *did)
|
||||
{
|
||||
overlay_mdp_frame mdp;
|
||||
bzero(&mdp,sizeof(mdp));
|
||||
|
||||
/* set source address to the local address and port */
|
||||
mdp.out.src.port = srcport;
|
||||
mdp.out.src.sid = *srcsid;
|
||||
|
||||
/* Send to destination address and DNA lookup port */
|
||||
if (dstsid) {
|
||||
/* Send an encrypted unicast packet */
|
||||
mdp.packetTypeAndFlags=MDP_TX;
|
||||
mdp.out.dst.sid = *dstsid;
|
||||
}else{
|
||||
/* Send a broadcast packet, flooding across the local mesh network */
|
||||
mdp.packetTypeAndFlags=MDP_TX|MDP_NOCRYPT;
|
||||
mdp.out.dst.sid = SID_BROADCAST;
|
||||
}
|
||||
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;
|
||||
|
||||
overlay_mdp_send(mdp_sockfd, &mdp, 0, 0);
|
||||
|
||||
/* Also send an encrypted unicast request to a configured directory service */
|
||||
if (!dstsid){
|
||||
if (!is_sid_t_any(config.directory.service)) {
|
||||
mdp.out.dst.sid = config.directory.service;
|
||||
mdp.packetTypeAndFlags=MDP_TX;
|
||||
overlay_mdp_send(mdp_sockfd, &mdp,0,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_CMD(app_dna_lookup, 0,
|
||||
"Lookup the subscribers (SID) with the supplied telephone number (DID).",
|
||||
"dna","lookup","<did>","[<timeout>]");
|
||||
static int app_dna_lookup(const struct cli_parsed *parsed, struct cli_context *context)
|
||||
{
|
||||
int mdp_sockfd;
|
||||
if (config.debug.verbose)
|
||||
DEBUG_cli_parsed(parsed);
|
||||
|
||||
/* Create the instance directory if it does not yet exist */
|
||||
if (create_serval_instance_dir() == -1)
|
||||
return -1;
|
||||
|
||||
int uri_count=0;
|
||||
#define MAXREPLIES 256
|
||||
#define MAXURILEN 256
|
||||
char uris[MAXREPLIES][MAXURILEN];
|
||||
|
||||
const char *did, *delay;
|
||||
if (cli_arg(parsed, "did", &did, cli_lookup_did, "*") == -1)
|
||||
return -1;
|
||||
if (cli_arg(parsed, "timeout", &delay, NULL, "3000") == -1)
|
||||
return -1;
|
||||
|
||||
int idelay=atoi(delay);
|
||||
int one_reply=0;
|
||||
|
||||
// Ugly hack, if timeout is negative, stop after first reply
|
||||
if (idelay<0){
|
||||
one_reply=1;
|
||||
idelay=-idelay;
|
||||
}
|
||||
|
||||
if ((mdp_sockfd = overlay_mdp_client_socket()) < 0)
|
||||
return WHY("Cannot create MDP socket");
|
||||
|
||||
/* Bind to MDP socket and await confirmation */
|
||||
sid_t srcsid;
|
||||
mdp_port_t port=32768+(random()&32767);
|
||||
if (overlay_mdp_getmyaddr(mdp_sockfd, 0, &srcsid)) {
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
return WHY("Could not get local address");
|
||||
}
|
||||
if (overlay_mdp_bind(mdp_sockfd, &srcsid, port)) {
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
return WHY("Could not bind to MDP socket");
|
||||
}
|
||||
|
||||
/* use MDP to send the lookup request to MDP_PORT_DNALOOKUP, and wait for
|
||||
replies. */
|
||||
|
||||
/* Now repeatedly send resolution request and collect results until we reach
|
||||
timeout. */
|
||||
time_ms_t timeout = gettime_ms() + idelay;
|
||||
time_ms_t last_tx = 0;
|
||||
time_ms_t now;
|
||||
int interval=125;
|
||||
|
||||
const char *names[]={
|
||||
"uri",
|
||||
"did",
|
||||
"name"
|
||||
};
|
||||
cli_columns(context, 3, names);
|
||||
size_t rowcount = 0;
|
||||
|
||||
while (timeout > (now = gettime_ms())){
|
||||
if ((last_tx+interval)<now){
|
||||
lookup_send_request(mdp_sockfd, &srcsid, port, NULL, did);
|
||||
last_tx=now;
|
||||
interval+=interval>>1;
|
||||
}
|
||||
time_ms_t short_timeout=125;
|
||||
while(short_timeout>0) {
|
||||
if (overlay_mdp_client_poll(mdp_sockfd, short_timeout)){
|
||||
overlay_mdp_frame rx;
|
||||
int ttl;
|
||||
if (overlay_mdp_recv(mdp_sockfd, &rx, port, &ttl)==0){
|
||||
if (rx.packetTypeAndFlags==MDP_ERROR){
|
||||
WHYF(" Error message: %s", rx.error.message);
|
||||
} else if ((rx.packetTypeAndFlags&MDP_TYPE_MASK)==MDP_TX) {
|
||||
/* Extract DID, Name, URI from response. */
|
||||
if (strlen((char *)rx.out.payload)<512) {
|
||||
char sidhex[SID_STRLEN + 1];
|
||||
char did[DID_MAXSIZE + 1];
|
||||
char name[64];
|
||||
char uri[512];
|
||||
if ( !parseDnaReply((char *)rx.out.payload, rx.out.payload_length, sidhex, did, name, uri, NULL)
|
||||
|| !str_is_subscriber_id(sidhex)
|
||||
|| !str_is_did(did)
|
||||
|| !str_is_uri(uri)
|
||||
) {
|
||||
WHYF("Received malformed DNA reply: %s", alloca_toprint(160, (const char *)rx.out.payload, rx.out.payload_length));
|
||||
} else {
|
||||
/* Have we seen this response before? */
|
||||
int i;
|
||||
for(i=0;i<uri_count;i++)
|
||||
if (!strcmp(uri,uris[i])) break;
|
||||
if (i==uri_count) {
|
||||
/* Not previously seen, so report it */
|
||||
cli_put_string(context, uri, ":");
|
||||
cli_put_string(context, did, ":");
|
||||
cli_put_string(context, name, "\n");
|
||||
rowcount++;
|
||||
|
||||
if (one_reply){
|
||||
timeout=now;
|
||||
short_timeout=0;
|
||||
}
|
||||
|
||||
/* Remember that we have seen it */
|
||||
if (uri_count<MAXREPLIES&&strlen(uri)<MAXURILEN) {
|
||||
strcpy(uris[uri_count++],uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else WHYF("packettype=0x%x",rx.packetTypeAndFlags);
|
||||
}
|
||||
}
|
||||
short_timeout=125-(gettime_ms()-now);
|
||||
}
|
||||
}
|
||||
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
cli_row_count(context, rowcount);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_CMD(app_reverse_lookup, 0,
|
||||
"Lookup the phone number (DID) and name of a given subscriber (SID)",
|
||||
"reverse", "lookup", "<sid>", "[<timeout>]");
|
||||
static int app_reverse_lookup(const struct cli_parsed *parsed, struct cli_context *context)
|
||||
{
|
||||
int mdp_sockfd;
|
||||
if (config.debug.verbose)
|
||||
DEBUG_cli_parsed(parsed);
|
||||
const char *sidhex, *delay;
|
||||
if (cli_arg(parsed, "sid", &sidhex, str_is_subscriber_id, "") == -1)
|
||||
return -1;
|
||||
if (cli_arg(parsed, "timeout", &delay, NULL, "3000") == -1)
|
||||
return -1;
|
||||
|
||||
mdp_port_t port=32768+(random()&0xffff);
|
||||
|
||||
sid_t srcsid;
|
||||
sid_t dstsid;
|
||||
|
||||
if (str_to_sid_t(&dstsid, sidhex) == -1)
|
||||
return WHY("str_to_sid_t() failed");
|
||||
|
||||
if ((mdp_sockfd = overlay_mdp_client_socket()) < 0)
|
||||
return WHY("Cannot create MDP socket");
|
||||
|
||||
if (overlay_mdp_getmyaddr(mdp_sockfd, 0, &srcsid)){
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
return WHY("Unable to get my address");
|
||||
}
|
||||
if (overlay_mdp_bind(mdp_sockfd, &srcsid, port)){
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
return WHY("Unable to bind port");
|
||||
}
|
||||
|
||||
time_ms_t now = gettime_ms();
|
||||
time_ms_t timeout = now + atoi(delay);
|
||||
time_ms_t next_send = now;
|
||||
overlay_mdp_frame mdp_reply;
|
||||
|
||||
while (now < timeout){
|
||||
now=gettime_ms();
|
||||
|
||||
if (now >= next_send){
|
||||
/* Send a unicast packet to this node, asking for any did */
|
||||
lookup_send_request(mdp_sockfd, &srcsid, port, &dstsid, "");
|
||||
next_send+=125;
|
||||
continue;
|
||||
}
|
||||
|
||||
time_ms_t poll_timeout = (next_send>timeout?timeout:next_send) - now;
|
||||
if (overlay_mdp_client_poll(mdp_sockfd, poll_timeout)<=0)
|
||||
continue;
|
||||
|
||||
int ttl=-1;
|
||||
if (overlay_mdp_recv(mdp_sockfd, &mdp_reply, port, &ttl))
|
||||
continue;
|
||||
|
||||
if ((mdp_reply.packetTypeAndFlags&MDP_TYPE_MASK)==MDP_ERROR){
|
||||
// TODO log error?
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mdp_reply.packetTypeAndFlags!=MDP_TX) {
|
||||
WHYF("MDP returned an unexpected message (type=0x%x)",
|
||||
mdp_reply.packetTypeAndFlags);
|
||||
|
||||
if (mdp_reply.packetTypeAndFlags==MDP_ERROR)
|
||||
WHYF("MDP message is return/error: %d:%s",
|
||||
mdp_reply.error.error,mdp_reply.error.message);
|
||||
continue;
|
||||
}
|
||||
|
||||
// we might receive a late response from an ealier request on the same socket, ignore it
|
||||
if (cmp_sid_t(&mdp_reply.out.src.sid, &dstsid) != 0) {
|
||||
WHYF("Unexpected result from SID %s", alloca_tohex_sid_t(mdp_reply.out.src.sid));
|
||||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
char sidhex[SID_STRLEN + 1];
|
||||
char did[DID_MAXSIZE + 1];
|
||||
char name[64];
|
||||
char uri[512];
|
||||
if ( !parseDnaReply((char *)mdp_reply.out.payload, mdp_reply.out.payload_length, sidhex, did, name, uri, NULL)
|
||||
|| !str_is_subscriber_id(sidhex)
|
||||
|| !str_is_did(did)
|
||||
|| !str_is_uri(uri)
|
||||
) {
|
||||
WHYF("Received malformed DNA reply: %s",
|
||||
alloca_toprint(160, (const char *)mdp_reply.out.payload, mdp_reply.out.payload_length));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Got a good DNA reply, copy it into place and stop polling */
|
||||
cli_field_name(context, "sid", ":");
|
||||
cli_put_string(context, sidhex, "\n");
|
||||
cli_field_name(context, "did", ":");
|
||||
cli_put_string(context, did, "\n");
|
||||
cli_field_name(context, "name", ":");
|
||||
cli_put_string(context, name, "\n");
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
return 1;
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "constants.h"
|
||||
#include "os.h" // for time_ms_t
|
||||
#include "socket.h"
|
||||
#include "overlay_buffer.h" // for struct overlay_buffer
|
||||
|
||||
// not reachable
|
||||
#define REACHABLE_NONE 0
|
||||
@ -48,6 +47,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#define BROADCAST_LEN 8
|
||||
|
||||
struct packet_rule;
|
||||
struct overlay_buffer;
|
||||
|
||||
// This structure supports both our own routing protocol which can store calculation details in *node
|
||||
// or IP4 addresses reachable via any other kind of normal layer3 routing protocol, eg olsr
|
||||
|
7
server.c
7
server.c
@ -55,6 +55,13 @@ static const char *_server_pidfile_path(struct __sourceloc __whence);
|
||||
#define server_pidfile_path() (_server_pidfile_path(__WHENCE__))
|
||||
void server_shutdown_check(struct sched_ent *alarm);
|
||||
|
||||
void cli_cleanup(){
|
||||
/* clean up after ourselves */
|
||||
rhizome_close_db();
|
||||
free_subscribers();
|
||||
assert(keyring==NULL);
|
||||
}
|
||||
|
||||
/** Return the PID of the currently running server process, return 0 if there is none.
|
||||
*/
|
||||
int server_pid()
|
||||
|
@ -50,7 +50,6 @@ SERVAL_DAEMON_SOURCES = \
|
||||
rhizome_cli.c \
|
||||
keyring_cli.c \
|
||||
network_cli.c \
|
||||
test_cli.c \
|
||||
crypto.c \
|
||||
directory_client.c \
|
||||
dna_helper.c \
|
||||
@ -102,7 +101,13 @@ SERVAL_DAEMON_SOURCES = \
|
||||
fec-3.0.1/ccsds_tables.c \
|
||||
fec-3.0.1/decode_rs_8.c \
|
||||
fec-3.0.1/encode_rs_8.c \
|
||||
fec-3.0.1/init_rs_char.c \
|
||||
fec-3.0.1/init_rs_char.c
|
||||
|
||||
TEST_SOURCES = \
|
||||
commandline.c \
|
||||
main.c \
|
||||
test_cli.c \
|
||||
log_stderr.c \
|
||||
context1.c
|
||||
|
||||
MDP_CLIENT_SOURCES = \
|
||||
|
89
test_cli.c
89
test_cli.c
@ -17,12 +17,24 @@
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "serval_types.h"
|
||||
#include "dataformats.h"
|
||||
#include "os.h"
|
||||
#include "cli.h"
|
||||
#include "conf.h"
|
||||
#include "commandline.h"
|
||||
#include "mem.h"
|
||||
|
||||
void cli_cleanup(){}
|
||||
void cf_on_config_change(){}
|
||||
|
||||
DEFINE_CMD(app_byteorder_test, 0,
|
||||
"Run byte order handling test",
|
||||
@ -260,3 +272,80 @@ static int app_mem_test(const struct cli_parsed *UNUSED(parsed), struct cli_cont
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_CMD(app_config_test, 0,
|
||||
"Load a test config file and log various fields",
|
||||
"config","test","<file>");
|
||||
static int app_config_test(const struct cli_parsed *UNUSED(parsed), struct cli_context *UNUSED(context))
|
||||
{
|
||||
const char *filename;
|
||||
if (cli_arg(parsed, "file", &filename, NULL, NULL)==-1)
|
||||
return -1;
|
||||
|
||||
int fd = open(filename, O_RDONLY);
|
||||
if (fd == -1)
|
||||
return WHY_perror("open");
|
||||
struct stat st;
|
||||
fstat(fd, &st);
|
||||
char *buf = emalloc(st.st_size);
|
||||
if (!buf)
|
||||
return -1;
|
||||
if (read(fd, buf, st.st_size) != st.st_size)
|
||||
return WHY_perror("read");
|
||||
struct cf_om_node *root = NULL;
|
||||
int ret = cf_om_parse(filename, buf, st.st_size, &root);
|
||||
close(fd);
|
||||
DEBUGF("ret = %s", strbuf_str(strbuf_cf_flags(strbuf_alloca(128), ret)));
|
||||
//cf_dump_node(root, 0);
|
||||
struct config_main config;
|
||||
memset(&config, 0, sizeof config);
|
||||
cf_dfl_config_main(&config);
|
||||
int result = root ? cf_opt_config_main(&config, root) : CFEMPTY;
|
||||
cf_om_free_node(&root);
|
||||
free(buf);
|
||||
DEBUGF("result = %s", strbuf_str(strbuf_cf_flags(strbuf_alloca(128), result)));
|
||||
DEBUGF("config.log.file.path = %s", alloca_str_toprint(config.log.file.path));
|
||||
DEBUGF("config.log.file.show_pid = %d", config.log.file.show_pid);
|
||||
DEBUGF("config.log.file.show_time = %d", config.log.file.show_time);
|
||||
DEBUGF("config.server.chdir = %s", alloca_str_toprint(config.server.chdir));
|
||||
DEBUGF("config.debug.verbose = %d", config.debug.verbose);
|
||||
DEBUGF("config.directory.service = %s", alloca_tohex_sid_t(config.directory.service));
|
||||
DEBUGF("config.rhizome.api.addfile.allow_host = %s", inet_ntoa(config.rhizome.api.addfile.allow_host));
|
||||
unsigned j;
|
||||
for (j = 0; j < config.mdp.iftype.ac; ++j) {
|
||||
DEBUGF("config.mdp.iftype.%u", config.mdp.iftype.av[j].key);
|
||||
DEBUGF(" .tick_ms = %u", config.mdp.iftype.av[j].value.tick_ms);
|
||||
}
|
||||
for (j = 0; j < config.dna.helper.argv.ac; ++j) {
|
||||
DEBUGF("config.dna.helper.argv.%u=%s", config.dna.helper.argv.av[j].key, config.dna.helper.argv.av[j].value);
|
||||
}
|
||||
for (j = 0; j < config.rhizome.direct.peer.ac; ++j) {
|
||||
DEBUGF("config.rhizome.direct.peer.%s", config.rhizome.direct.peer.av[j].key);
|
||||
DEBUGF(" .protocol = %s", alloca_str_toprint(config.rhizome.direct.peer.av[j].value.protocol));
|
||||
DEBUGF(" .host = %s", alloca_str_toprint(config.rhizome.direct.peer.av[j].value.host));
|
||||
DEBUGF(" .port = %u", config.rhizome.direct.peer.av[j].value.port);
|
||||
}
|
||||
for (j = 0; j < config.interfaces.ac; ++j) {
|
||||
DEBUGF("config.interfaces.%u", config.interfaces.av[j].key);
|
||||
DEBUGF(" .exclude = %d", config.interfaces.av[j].value.exclude);
|
||||
DEBUGF(" .match = [");
|
||||
unsigned k;
|
||||
for (k = 0; k < config.interfaces.av[j].value.match.patc; ++k)
|
||||
DEBUGF(" %s", alloca_str_toprint(config.interfaces.av[j].value.match.patv[k]));
|
||||
DEBUGF(" ]");
|
||||
DEBUGF(" .type = %d", config.interfaces.av[j].value.type);
|
||||
DEBUGF(" .port = %u", config.interfaces.av[j].value.port);
|
||||
DEBUGF(" .drop_broadcasts = %d", (int) config.interfaces.av[j].value.drop_broadcasts);
|
||||
DEBUGF(" .drop_unicasts = %d", (int) config.interfaces.av[j].value.drop_unicasts);
|
||||
DEBUGF(" .drop_packets = %u", (unsigned) config.interfaces.av[j].value.drop_packets);
|
||||
}
|
||||
for (j = 0; j < config.hosts.ac; ++j) {
|
||||
char sidhex[SID_STRLEN + 1];
|
||||
tohex(sidhex, SID_STRLEN, config.hosts.av[j].key.binary);
|
||||
DEBUGF("config.hosts.%s", sidhex);
|
||||
DEBUGF(" .interface = %s", alloca_str_toprint(config.hosts.av[j].value.interface));
|
||||
DEBUGF(" .address = %s", inet_ntoa(config.hosts.av[j].value.address));
|
||||
DEBUGF(" .port = %u", config.hosts.av[j].value.port);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user