mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-03-25 13:17:43 +00:00
More work on MDP. Removed some debug fluff.
Added framework for MDP ping, and some work towards MDP port binding and sending packets with option to wait for reply. MDP server doesn't yet support port binding, and client doesn't yet support reading replies.
This commit is contained in:
parent
302c9e70fb
commit
70497df7b5
@ -221,6 +221,8 @@ int app_server_start(int argc,char **argv,struct command_line_option *o)
|
||||
" You should probably put something in the interfaces setting.\n");
|
||||
}
|
||||
|
||||
setVerbosity(confValueGet("debug",""));
|
||||
|
||||
int pid=-1;
|
||||
int running = servalNodeRunning(&pid,instancepath);
|
||||
if (running<0) return -1;
|
||||
@ -359,28 +361,28 @@ int app_mdp_ping(int argc,char **argv,struct command_line_option *o)
|
||||
char *sid=cli_arg(argc,argv,o,"SID|broadcast","broadcast");
|
||||
char *instancepath=serval_instancepath();
|
||||
|
||||
/* Open socket to MDP */
|
||||
/* MDP frames consist of:
|
||||
destination SID (32 bytes)
|
||||
destination port (4 bytes)
|
||||
payload length (2 bytes)
|
||||
payload (rest of packet) */
|
||||
overlay_mdp_frame mdp;
|
||||
|
||||
int sock;
|
||||
struct sockaddr_un name;
|
||||
char mdp_socket_name[101];
|
||||
mdp_socket_name[100]=0;
|
||||
snprintf(mdp_socket_name,100,"%s/mdp.socket",instancepath);
|
||||
if (mdp_socket_name[100]) {
|
||||
return WHY("instance path is too long (unix domain named sockets have a short maximum path length)");
|
||||
/* Bind to MDP socket and await confirmation */
|
||||
int port=32768+(random()&32767);
|
||||
mdp.packetTypeAndFlags=MDP_BIND;
|
||||
mdp.bind.port_number=port;
|
||||
int result=overlay_mdp_dispatch(&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;
|
||||
}
|
||||
|
||||
sock = socket(AF_UNIX, SOCK_DGRAM, 0);
|
||||
if (sock < 0) {
|
||||
perror("opening datagram socket");
|
||||
exit(1);
|
||||
}
|
||||
/* Construct name of socket to send to. */
|
||||
name.sun_family = AF_UNIX;
|
||||
strcpy(name.sun_path, mdp_socket_name);
|
||||
close(sock);
|
||||
|
||||
return WHY("Not implmented");
|
||||
return WHY("MDP ping not implemented (we don't send the packet)");
|
||||
}
|
||||
|
||||
int app_server_set(int argc,char **argv,struct command_line_option *o)
|
||||
|
@ -195,6 +195,7 @@ int overlayServerMode()
|
||||
}
|
||||
}
|
||||
overlay_rx_messages();
|
||||
fprintf(stderr,"tick\n");
|
||||
if (rhizome_datastore_path) {
|
||||
rhizome_server_poll();
|
||||
rhizome_fetch_poll();
|
||||
@ -208,6 +209,7 @@ int overlayServerMode()
|
||||
if (rhizome_datastore_path) {
|
||||
rhizome_server_poll();
|
||||
rhizome_fetch_poll();
|
||||
overlay_mdp_poll();
|
||||
}
|
||||
}
|
||||
/* Check if we need to trigger any ticks on any interfaces */
|
||||
|
@ -80,8 +80,9 @@ int ob_makespace(overlay_buffer *b,int bytes)
|
||||
}
|
||||
}
|
||||
|
||||
printf("ob_makespace(%p,%d)\n b->bytes=%p,b->length=%d,b->allocSize=%d\n",
|
||||
b,bytes,b->bytes,b->length,b->allocSize);
|
||||
if (0)
|
||||
printf("ob_makespace(%p,%d)\n b->bytes=%p,b->length=%d,b->allocSize=%d\n",
|
||||
b,bytes,b->bytes,b->length,b->allocSize);
|
||||
|
||||
if (b->length+bytes>=b->allocSize)
|
||||
{
|
||||
@ -94,7 +95,7 @@ int ob_makespace(overlay_buffer *b,int bytes)
|
||||
if (newSize>65536) {
|
||||
if (newSize&65535) newSize+=65536-(newSize&65535);
|
||||
}
|
||||
if (1) printf(" realloc(b->bytes=%p,newSize=%d)\n",
|
||||
if (0) printf(" realloc(b->bytes=%p,newSize=%d)\n",
|
||||
b->bytes,newSize);
|
||||
unsigned char *r=realloc(b->bytes,newSize);
|
||||
if (!r) return WHY("realloc() failed");
|
||||
|
@ -249,7 +249,9 @@ int overlay_interface_init(char *name,struct sockaddr_in src_addr,struct sockadd
|
||||
|
||||
if (name[0]=='>') {
|
||||
I(fileP)=1;
|
||||
I(fd) = open(&name[1],O_APPEND|O_RDWR);
|
||||
char dummyfile[1024];
|
||||
snprintf(dummyfile,1024,"%s/%s",serval_instancepath(),&name[1]);
|
||||
I(fd) = open(dummyfile,O_APPEND|O_RDWR);
|
||||
if (I(fd)<1)
|
||||
return WHY("could not open dummy interface file for append");
|
||||
/* Seek to end of file as initial reading point */
|
||||
|
@ -120,5 +120,84 @@ int overlay_saw_mdp_frame(int interface,overlay_frame *f,long long now)
|
||||
|
||||
int overlay_mdp_poll()
|
||||
{
|
||||
unsigned char buffer[16384];
|
||||
int ttl;
|
||||
struct sockaddr recvaddr;
|
||||
socklen_t recvaddrlen=sizeof(recvaddr);
|
||||
struct sockaddr_un *recvaddr_un=NULL;
|
||||
|
||||
if (mdp_named_socket>-1) {
|
||||
ttl=-1;
|
||||
bzero((void *)&recvaddr,sizeof(recvaddr));
|
||||
fcntl(mdp_named_socket, F_SETFL,
|
||||
fcntl(mdp_named_socket, F_GETFL, NULL)|O_NONBLOCK);
|
||||
int len = recvwithttl(mdp_named_socket,buffer,sizeof(buffer),&ttl,
|
||||
&recvaddr,&recvaddrlen);
|
||||
if (len>0) {
|
||||
dump("packet from unix domain socket",
|
||||
buffer,len);
|
||||
if (debug&DEBUG_PACKETXFER)
|
||||
serval_packetvisualise(stderr,"Read from unix domain socket",
|
||||
buffer,len);
|
||||
}
|
||||
|
||||
recvaddr_un=(struct sockaddr_un *)&recvaddr;
|
||||
fcntl(mdp_named_socket, F_SETFL,
|
||||
fcntl(mdp_named_socket, F_GETFL, NULL)&(~O_NONBLOCK));
|
||||
}
|
||||
|
||||
return WHY("Not implemented");
|
||||
}
|
||||
|
||||
int mdp_client_socket=-1;
|
||||
int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int flags,int timeout_ms)
|
||||
{
|
||||
if (mdp_client_socket==-1) {
|
||||
/* Open socket to MDP server (thus connection is always local) */
|
||||
WHY("Use of abstract name space socket for Linux not implemented");
|
||||
|
||||
mdp_client_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
|
||||
if (mdp_client_socket < 0) {
|
||||
perror("socket");
|
||||
return WHY("Could not open socket to MDP server");
|
||||
}
|
||||
}
|
||||
|
||||
/* Construct name of socket to send to. */
|
||||
char mdp_socket_name[101];
|
||||
mdp_socket_name[100]=0;
|
||||
snprintf(mdp_socket_name,100,"%s/mdp.socket",serval_instancepath());
|
||||
if (mdp_socket_name[100]) {
|
||||
return WHY("instance path is too long (unix domain named sockets have a short maximum path length)");
|
||||
}
|
||||
struct sockaddr_un name;
|
||||
name.sun_family = AF_UNIX;
|
||||
strcpy(name.sun_path, mdp_socket_name);
|
||||
|
||||
/* XXX Sends whole mdp structure, regardless of how much or little is used. */
|
||||
int result=sendto(mdp_client_socket, mdp, sizeof(overlay_mdp_frame), 0,
|
||||
(struct sockaddr *)&name, sizeof(struct sockaddr_un));
|
||||
if (result<0) {
|
||||
perror("sending datagram message");
|
||||
} else {
|
||||
WHY("packet sent");
|
||||
if (!(flags&MDP_AWAITREPLY)) return 0;
|
||||
}
|
||||
|
||||
/* Wait for a reply until timeout */
|
||||
struct pollfd fds[1];
|
||||
int fdcount=1;
|
||||
fds[0].fd=mdp_client_socket; fds[0].events=POLLIN;
|
||||
result = poll(fds,fdcount,timeout_ms);
|
||||
if (result==0) {
|
||||
/* Timeout */
|
||||
mdp->packetTypeAndFlags=MDP_ERROR;
|
||||
mdp->error.error=1;
|
||||
snprintf(mdp->error.message,128,"Timeout waiting for reply to MDP packet (packet was successfully sent).");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if reply available */
|
||||
|
||||
return WHY("Not implemented");
|
||||
}
|
||||
|
@ -87,7 +87,6 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
|
||||
|
||||
if (!rhizome_db) return WHY("Rhizome not enabled");
|
||||
|
||||
dump("buffer (90)",(unsigned char *)e,sizeof(*e));
|
||||
if (ob_append_byte(e,OF_TYPE_RHIZOME_ADVERT))
|
||||
return WHY("could not add rhizome bundle advertisement header");
|
||||
ob_append_byte(e,1); /* TTL */
|
||||
@ -99,9 +98,7 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
|
||||
ob_append_byte(e,OA_CODE_BROADCAST);
|
||||
{ int i; for(i=0;i<8;i++) ob_append_byte(e,random()&0xff); } /* BPI for broadcast */
|
||||
ob_append_byte(e,OA_CODE_PREVIOUS);
|
||||
dump("buffer (102)",(unsigned char *)e,sizeof(*e));
|
||||
ob_append_byte(e,OA_CODE_SELF);
|
||||
dump("buffer (104)",(unsigned char *)e,sizeof(*e));
|
||||
|
||||
/* Randomly choose whether to advertise manifests or BARs first. */
|
||||
int skipmanifests=random()&1;
|
||||
@ -132,8 +129,9 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
|
||||
bundle_offset[0]=0;
|
||||
if (bundles_available==-1||(bundle_offset[1]>=bundles_available))
|
||||
bundle_offset[1]=0;
|
||||
fprintf(stderr,"%d bundles in database (%d %d), slots=%d.\n",bundles_available,
|
||||
bundle_offset[0],bundle_offset[1],slots);
|
||||
if(0)
|
||||
fprintf(stderr,"%d bundles in database (%d %d), slots=%d.\n",bundles_available,
|
||||
bundle_offset[0],bundle_offset[1],slots);
|
||||
|
||||
for(pass=skipmanifests;pass<2;pass++)
|
||||
{
|
||||
@ -194,7 +192,6 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
|
||||
int overhead=0;
|
||||
int frameFull=0;
|
||||
if (!pass) overhead=2;
|
||||
dump("buffer (197)",(unsigned char *)e,sizeof(*e));
|
||||
if (ob_makespace(e,overhead+blob_bytes)) {
|
||||
if (debug&DEBUG_RHIZOME)
|
||||
fprintf(stderr,"Stopped cramming %s into Rhizome advertisement frame.\n",
|
||||
@ -208,7 +205,6 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
|
||||
if (debug&DEBUG_RHIZOME)
|
||||
fprintf(stderr,"length bytes written at offset 0x%x\n",e->length);
|
||||
}
|
||||
dump("buffer (211)",(unsigned char *)e,sizeof(*e));
|
||||
if (frameFull) {
|
||||
goto stopStuffing;
|
||||
}
|
||||
@ -226,8 +222,6 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
|
||||
|
||||
continue;
|
||||
}
|
||||
dump("buffer (211)",(unsigned char *)e,sizeof(*e));
|
||||
e->length+=overhead+blob_bytes;
|
||||
if (e->length>e->allocSize) {
|
||||
WHY("e->length > e->size");
|
||||
abort();
|
||||
@ -241,8 +235,6 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
stopStuffing:
|
||||
dump("buffer (244)",(unsigned char *)e,sizeof(*e));
|
||||
|
||||
if (!pass)
|
||||
{
|
||||
/* Mark end of whole manifests by writing 0xff, which is more than the MSB
|
||||
|
50
serval.h
50
serval.h
@ -984,3 +984,53 @@ char *serval_instancepath();
|
||||
|
||||
int overlay_mdp_get_fds(struct pollfd *fds,int *fdcount,int fdmax);
|
||||
int overlay_mdp_poll();
|
||||
|
||||
typedef struct sockaddr_mdp {
|
||||
unsigned char sid[SID_SIZE];
|
||||
unsigned int port;
|
||||
} sockaddr_mdp;
|
||||
|
||||
#define MDP_TX 1
|
||||
typedef struct overlay_mdp_outgoing_frame {
|
||||
sockaddr_mdp dst;
|
||||
unsigned short payload_length;
|
||||
unsigned char payload[0];
|
||||
} overlay_mdp_outgoing_frame;
|
||||
|
||||
#define MDP_RX 2
|
||||
typedef struct overlay_mdp_incoming_frame {
|
||||
sockaddr_mdp dst;
|
||||
sockaddr_mdp src;
|
||||
unsigned short payload_length;
|
||||
unsigned char payload[0];
|
||||
} overlay_mdp_incoming_frame;
|
||||
|
||||
#define MDP_BIND 3
|
||||
typedef struct overlay_mdp_bind_request {
|
||||
unsigned int port_number;
|
||||
} overlay_mdp_bind_request;
|
||||
|
||||
#define MDP_ERROR 4
|
||||
typedef struct overlay_mdp_error {
|
||||
unsigned int error;
|
||||
char message[0];
|
||||
} overlay_mdp_error;
|
||||
|
||||
typedef struct overlay_mdp_frame {
|
||||
#define MDP_AWAITREPLY 5
|
||||
unsigned int packetTypeAndFlags;
|
||||
union {
|
||||
overlay_mdp_outgoing_frame out;
|
||||
overlay_mdp_incoming_frame in;
|
||||
overlay_mdp_bind_request bind;
|
||||
overlay_mdp_error error;
|
||||
/* 2048 is too large (causes EMSGSIZE errors on OSX, but probably fine on
|
||||
Linux) */
|
||||
char raw[2000];
|
||||
};
|
||||
} overlay_mdp_frame;
|
||||
|
||||
int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int flags,int timeout_ms);
|
||||
|
||||
|
||||
int setVerbosity(char *optarg);
|
||||
|
Loading…
x
Reference in New Issue
Block a user