mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-02-20 09:26:37 +00:00
Add new mdp trace command
This commit is contained in:
parent
9e9f93b079
commit
bb8b3d6376
@ -43,6 +43,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "mdp_client.h"
|
||||
#include "cli.h"
|
||||
#include "overlay_address.h"
|
||||
#include "overlay_buffer.h"
|
||||
|
||||
extern struct cli_schema command_line_options[];
|
||||
|
||||
@ -1070,6 +1071,68 @@ int app_mdp_ping(const struct cli_parsed *parsed, void *context)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int app_trace(const struct cli_parsed *parsed, void *context){
|
||||
|
||||
const char *sidhex;
|
||||
if (cli_arg(parsed, "SID", &sidhex, str_is_subscriber_id, NULL) == -1)
|
||||
return -1;
|
||||
|
||||
sid_t srcsid;
|
||||
sid_t dstsid;
|
||||
if (str_to_sid_t(&dstsid, sidhex) == -1)
|
||||
return WHY("str_to_sid_t() failed");
|
||||
|
||||
overlay_mdp_frame mdp;
|
||||
bzero(&mdp, sizeof(mdp));
|
||||
|
||||
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");
|
||||
|
||||
bcopy(srcsid.binary, mdp.out.src.sid, SID_SIZE);
|
||||
bcopy(srcsid.binary, mdp.out.dst.sid, SID_SIZE);
|
||||
mdp.out.src.port=port;
|
||||
mdp.out.dst.port=MDP_PORT_TRACE;
|
||||
mdp.packetTypeAndFlags=MDP_TX;
|
||||
struct overlay_buffer *b = ob_static(mdp.out.payload, sizeof(mdp.out.payload));
|
||||
|
||||
ob_append_byte(b, SID_SIZE);
|
||||
ob_append_bytes(b, srcsid.binary, SID_SIZE);
|
||||
|
||||
ob_append_byte(b, SID_SIZE);
|
||||
ob_append_bytes(b, dstsid.binary, SID_SIZE);
|
||||
|
||||
mdp.out.payload_length = ob_position(b);
|
||||
cli_printf("Tracing the network path from %s to %s",
|
||||
alloca_tohex_sid(srcsid.binary), alloca_tohex_sid(dstsid.binary));
|
||||
cli_delim("\n");
|
||||
int ret=overlay_mdp_send(&mdp,MDP_AWAITREPLY,5000);
|
||||
ob_free(b);
|
||||
if (ret)
|
||||
DEBUGF("overlay_mdp_send returned %d", ret);
|
||||
else{
|
||||
int offset=0;
|
||||
{
|
||||
// skip the first two sid's
|
||||
int len = mdp.out.payload[offset++];
|
||||
offset+=len;
|
||||
len = mdp.out.payload[offset++];
|
||||
offset+=len;
|
||||
}
|
||||
int i=0;
|
||||
while(offset<mdp.out.payload_length){
|
||||
int len = mdp.out.payload[offset++];
|
||||
cli_printf("%d: ",i);
|
||||
cli_puts(alloca_tohex(&mdp.out.payload[offset], len));
|
||||
cli_delim("\n");
|
||||
offset+=len;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
overlay_mdp_client_done();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int app_config_schema(const struct cli_parsed *parsed, void *context)
|
||||
{
|
||||
if (config.debug.verbose)
|
||||
@ -2216,8 +2279,10 @@ struct cli_schema command_line_options[]={
|
||||
"Stop a running Serval Mesh node process with given instance path."},
|
||||
{app_server_status,{"status",NULL},CLIFLAG_PERMISSIVE_CONFIG,
|
||||
"Display information about any running Serval Mesh node."},
|
||||
{app_mdp_ping,{"mdp","ping","<SID|broadcast>","[<count>]",NULL},CLIFLAG_STANDALONE,
|
||||
{app_mdp_ping,{"mdp","ping","<SID|broadcast>","[<count>]",NULL},0,
|
||||
"Attempts to ping specified node via Mesh Datagram Protocol (MDP)."},
|
||||
{app_trace,{"mdp","trace","<SID>",NULL},0,
|
||||
"Trace through the network to the specified node via MDP."},
|
||||
{app_config_schema,{"config","schema",NULL},CLIFLAG_STANDALONE|CLIFLAG_PERMISSIVE_CONFIG,
|
||||
"Dump configuration schema."},
|
||||
{app_config_set,{"config","set","<variable>","<value>","...",NULL},CLIFLAG_STANDALONE|CLIFLAG_PERMISSIVE_CONFIG,
|
||||
|
@ -132,6 +132,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#define MDP_PORT_STUN 5
|
||||
#define MDP_PORT_PROBE 6
|
||||
#define MDP_PORT_ECHO 7
|
||||
#define MDP_PORT_TRACE 8
|
||||
#define MDP_PORT_DNALOOKUP 10
|
||||
#define MDP_PORT_VOMP 12
|
||||
#define MDP_PORT_RHIZOME_REQUEST 13
|
||||
|
@ -63,7 +63,7 @@ int overlay_mdp_send(overlay_mdp_frame *mdp,int flags,int timeout_ms)
|
||||
|
||||
int port=0;
|
||||
if ((mdp->packetTypeAndFlags&MDP_TYPE_MASK) == MDP_TX)
|
||||
port = mdp->out.dst.port;
|
||||
port = mdp->out.src.port;
|
||||
|
||||
time_ms_t started = gettime_ms();
|
||||
while(timeout_ms>=0 && overlay_mdp_client_poll(timeout_ms)>0){
|
||||
|
@ -502,6 +502,9 @@ int overlay_mdp_dnalookup_reply(const sockaddr_mdp *dstaddr, const unsigned char
|
||||
int overlay_mdp_check_binding(struct subscriber *subscriber, int port, int userGeneratedFrameP,
|
||||
struct sockaddr_un *recvaddr, int recvaddrlen)
|
||||
{
|
||||
/* System generated frames can send anything they want */
|
||||
if (!userGeneratedFrameP)
|
||||
return 0;
|
||||
|
||||
/* Check if the address is in the list of bound addresses,
|
||||
and that the recvaddr matches. */
|
||||
@ -521,24 +524,6 @@ int overlay_mdp_check_binding(struct subscriber *subscriber, int port, int userG
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for build-in port listeners */
|
||||
if (!userGeneratedFrameP){
|
||||
switch(port) {
|
||||
case MDP_PORT_NOREPLY:
|
||||
case MDP_PORT_ECHO:
|
||||
case MDP_PORT_KEYMAPREQUEST:
|
||||
case MDP_PORT_VOMP:
|
||||
case MDP_PORT_DNALOOKUP:
|
||||
case MDP_PORT_RHIZOME_RESPONSE:
|
||||
case MDP_PORT_RHIZOME_REQUEST:
|
||||
case MDP_PORT_RHIZOME_MANIFEST_REQUEST:
|
||||
case MDP_PORT_PROBE:
|
||||
case MDP_PORT_STUNREQ:
|
||||
case MDP_PORT_STUN:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return WHYF("No such binding: recvaddr=%p %s addr=%s port=%u (0x%x) -- possible spoofing attack",
|
||||
recvaddr,
|
||||
recvaddr ? alloca_toprint(-1, recvaddr->sun_path, recvaddrlen - sizeof(short)) : "",
|
||||
|
@ -281,6 +281,91 @@ int overlay_mdp_service_echo(overlay_mdp_frame *mdp)
|
||||
RETURN(0);
|
||||
}
|
||||
|
||||
static int overlay_mdp_service_trace(overlay_mdp_frame *mdp){
|
||||
IN();
|
||||
int ret=0;
|
||||
|
||||
struct overlay_buffer *b = ob_static(mdp->out.payload, sizeof(mdp->out.payload));
|
||||
ob_limitsize(b, mdp->out.payload_length);
|
||||
|
||||
struct subscriber *src=NULL, *dst=NULL, *last=NULL, *next=NULL;
|
||||
struct decode_context context;
|
||||
bzero(&context, sizeof context);
|
||||
|
||||
if (overlay_address_parse(&context, b, &src)){
|
||||
ret=WHYF("Invalid trace packet");
|
||||
goto end;
|
||||
}
|
||||
if (overlay_address_parse(&context, b, &dst)){
|
||||
ret=WHYF("Invalid trace packet");
|
||||
goto end;
|
||||
}
|
||||
if (context.invalid_addresses){
|
||||
ret=WHYF("Invalid address in trace packet");
|
||||
goto end;
|
||||
}
|
||||
|
||||
INFOF("Trace from %s to %s", alloca_tohex_sid(src->sid), alloca_tohex_sid(dst->sid));
|
||||
|
||||
while(ob_remaining(b)>0){
|
||||
struct subscriber *trace=NULL;
|
||||
if (overlay_address_parse(&context, b, &trace)){
|
||||
ret=WHYF("Invalid trace packet");
|
||||
goto end;
|
||||
}
|
||||
if (context.invalid_addresses){
|
||||
ret=WHYF("Invalid address in trace packet");
|
||||
goto end;
|
||||
}
|
||||
INFOF("Via %s", alloca_tohex_sid(trace->sid));
|
||||
|
||||
if (trace->reachable==REACHABLE_SELF && !next)
|
||||
// We're already in this trace, send the next packet to the node before us in the list
|
||||
next = last;
|
||||
last = trace;
|
||||
}
|
||||
|
||||
if (src->reachable==REACHABLE_SELF && last){
|
||||
// it came back to us, we can send the reply to our mdp client...
|
||||
next=src;
|
||||
mdp->out.dst.port=mdp->out.src.port;
|
||||
mdp->out.src.port=MDP_PORT_TRACE;
|
||||
}
|
||||
|
||||
if (!next){
|
||||
// destination is our neighbour?
|
||||
if (dst->reachable & REACHABLE_DIRECT)
|
||||
next = dst;
|
||||
// destination is indirect?
|
||||
else if (dst->reachable & REACHABLE_INDIRECT)
|
||||
next = dst->next_hop;
|
||||
// destination is not reachable or is ourselves? bounce back to the previous node or the sender.
|
||||
else if (last)
|
||||
next = last;
|
||||
else
|
||||
next = src;
|
||||
}
|
||||
|
||||
INFOF("Next node is %s", alloca_tohex_sid(next->sid));
|
||||
|
||||
ob_unlimitsize(b);
|
||||
// always write a full sid into the payload
|
||||
my_subscriber->send_full=1;
|
||||
if (overlay_address_append(&context, b, my_subscriber)){
|
||||
ret = WHYF("Unable to append my address to the trace");
|
||||
goto end;
|
||||
}
|
||||
|
||||
mdp->out.payload_length = ob_position(b);
|
||||
bcopy(my_subscriber->sid, mdp->out.src.sid, SID_SIZE);
|
||||
bcopy(next->sid, mdp->out.dst.sid, SID_SIZE);
|
||||
|
||||
ret = overlay_mdp_dispatch(mdp, 0, NULL, 0);
|
||||
end:
|
||||
ob_free(b);
|
||||
RETURN(ret);
|
||||
}
|
||||
|
||||
static int overlay_mdp_service_manifest_response(overlay_mdp_frame *mdp){
|
||||
int offset=0;
|
||||
char id_hex[RHIZOME_MANIFEST_ID_STRLEN];
|
||||
@ -310,6 +395,7 @@ int overlay_mdp_try_interal_services(overlay_mdp_frame *mdp)
|
||||
case MDP_PORT_KEYMAPREQUEST: RETURN(keyring_mapping_request(keyring,mdp));
|
||||
case MDP_PORT_DNALOOKUP: RETURN(overlay_mdp_service_dnalookup(mdp));
|
||||
case MDP_PORT_ECHO: RETURN(overlay_mdp_service_echo(mdp));
|
||||
case MDP_PORT_TRACE: RETURN(overlay_mdp_service_trace(mdp));
|
||||
case MDP_PORT_PROBE: RETURN(overlay_mdp_service_probe(mdp));
|
||||
case MDP_PORT_STUNREQ: RETURN(overlay_mdp_service_stun_req(mdp));
|
||||
case MDP_PORT_STUN: RETURN(overlay_mdp_service_stun(mdp));
|
||||
|
@ -229,6 +229,8 @@ test_multihop_linear() {
|
||||
set_instance +A
|
||||
executeOk_servald mdp ping $SIDD 1
|
||||
tfw_cat --stdout --stderr
|
||||
executeOk_servald mdp trace $SIDD
|
||||
tfw_cat --stdout --stderr
|
||||
executeOk_servald route print
|
||||
assertStdoutGrep --matches=1 "^$SIDB:BROADCAST UNICAST :"
|
||||
assertStdoutGrep --matches=1 "^$SIDC:INDIRECT :"
|
||||
|
Loading…
x
Reference in New Issue
Block a user