From 263232b2efbfe9f1c445cdd8e688169be4c7d7f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Tue, 6 Nov 2012 21:02:35 +0100 Subject: [PATCH 01/24] Make overlay_mdp_client_socket_path local There is no reason for this variable to be external. It is used in init() and was used in done(), but the unlink() in done() is useless: it was already called on init() so the file was already unlinked. --- mdp_client.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/mdp_client.c b/mdp_client.c index ccf2ee91..e73ef976 100644 --- a/mdp_client.c +++ b/mdp_client.c @@ -85,11 +85,10 @@ int overlay_mdp_send(overlay_mdp_frame *mdp,int flags,int timeout_ms) return -1; /* WHY("Timeout waiting for server response"); */ } -char overlay_mdp_client_socket_path[1024]; -int overlay_mdp_client_socket_path_len=-1; - int overlay_mdp_client_init() { + char overlay_mdp_client_socket_path[1024]; + int overlay_mdp_client_socket_path_len=-1; if (mdp_client_socket==-1) { /* Open socket to MDP server (thus connection is always local) */ if (0) WHY("Use of abstract name space socket for Linux not implemented"); @@ -145,8 +144,6 @@ int overlay_mdp_client_done() overlay_mdp_send(&mdp,0,0); } - if (overlay_mdp_client_socket_path_len>-1) - unlink(overlay_mdp_client_socket_path); if (mdp_client_socket!=-1) close(mdp_client_socket); mdp_client_socket=-1; From f55e2b7ea22f5b12326c36ce3e6782fc33505c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Tue, 6 Nov 2012 20:48:54 +0100 Subject: [PATCH 02/24] MDP sockets support Provide MDP sockets instead of using a global one. --- commandline.c | 104 ++++++++++++++++++++++++++--------- mdp_client.c | 149 ++++++++++++++++++++++++-------------------------- mdp_client.h | 12 ++-- serval.h | 4 +- 4 files changed, 156 insertions(+), 113 deletions(-) diff --git a/commandline.c b/commandline.c index ba778bec..61e6e246 100644 --- a/commandline.c +++ b/commandline.c @@ -187,7 +187,6 @@ int parseCommandLine(const char *argv0, int argc, const char *const *args) int result = cli_execute(argv0, argc, args, command_line_options, NULL); /* clean up after ourselves */ - overlay_mdp_client_done(); rhizome_close_db(); OUT(); @@ -317,11 +316,14 @@ int app_echo(int argc, const char *const *argv, struct command_line_option *o, v } void lookup_send_request(unsigned char *srcsid, int srcport, unsigned char *dstsid, const char *did){ + int mdp_sockfd; int i; overlay_mdp_frame mdp; bzero(&mdp,sizeof(mdp)); - - + + if ((mdp_sockfd = overlay_mdp_client_socket()) < 0) + WHY("Cannot create MDP socket"); + /* set source address to a local address, and pick a random port */ mdp.out.src.port=srcport; bcopy(srcsid,mdp.out.src.sid,SID_SIZE); @@ -344,7 +346,7 @@ void lookup_send_request(unsigned char *srcsid, int srcport, unsigned char *dsts bcopy(did,&mdp.out.payload[0],strlen(did)+1); mdp.out.payload_length=strlen(did)+1; - overlay_mdp_send(&mdp,0,0); + overlay_mdp_send(mdp_sockfd, &mdp, 0, 0); /* Also send an encrypted unicast request to a configured directory service */ if (!dstsid){ @@ -354,14 +356,17 @@ void lookup_send_request(unsigned char *srcsid, int srcport, unsigned char *dsts WHYF("Invalid directory server SID %s", directory_service); }else{ mdp.packetTypeAndFlags=MDP_TX; - overlay_mdp_send(&mdp,0,0); + overlay_mdp_send(mdp_sockfd, &mdp, 0, 0); } } } + + overlay_mdp_client_close(mdp_sockfd); } int app_dna_lookup(int argc, const char *const *argv, struct command_line_option *o, void *context) { + int mdp_sockfd; if (debug & DEBUG_VERBOSE) DEBUG_argv("command", argc, argv); /* Create the instance directory if it does not yet exist */ @@ -387,12 +392,21 @@ int app_dna_lookup(int argc, const char *const *argv, struct command_line_option one_reply=1; idelay=-idelay; } - + + if ((mdp_sockfd = overlay_mdp_client_socket()) < 0) + WHY("Cannot create MDP socket"); + /* Bind to MDP socket and await confirmation */ unsigned char srcsid[SID_SIZE]; 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"); + 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. */ @@ -416,11 +430,11 @@ int app_dna_lookup(int argc, const char *const *argv, struct command_line_option } time_ms_t short_timeout=125; while(short_timeout>0) { - if (overlay_mdp_client_poll(short_timeout)) + if (overlay_mdp_client_poll(mdp_sockfd, short_timeout)) { overlay_mdp_frame rx; int ttl; - if (overlay_mdp_recv(&rx, port, &ttl)==0) + if (overlay_mdp_recv(mdp_sockfd, &rx, port, &ttl)==0) { if (rx.packetTypeAndFlags==MDP_ERROR) { @@ -473,7 +487,7 @@ int app_dna_lookup(int argc, const char *const *argv, struct command_line_option if (servalShutdown) break; } - overlay_mdp_client_done(); + overlay_mdp_client_close(mdp_sockfd); return 0; } @@ -745,6 +759,7 @@ int app_server_status(int argc, const char *const *argv, struct command_line_opt int app_mdp_ping(int argc, const char *const *argv, struct command_line_option *o, void *context) { + int mdp_sockfd; if (debug & DEBUG_VERBOSE) DEBUG_argv("command", argc, argv); const char *sid, *count; if (cli_arg(argc, argv, o, "SID|broadcast", &sid, str_is_subscriber_id, "broadcast") == -1) @@ -756,13 +771,22 @@ int app_mdp_ping(int argc, const char *const *argv, struct command_line_option * int ret=-1; int icount=atoi(count); + if ((mdp_sockfd = overlay_mdp_client_socket()) < 0) + WHY("Cannot create MDP socket"); + overlay_mdp_frame mdp; bzero(&mdp, sizeof(overlay_mdp_frame)); /* Bind to MDP socket and await confirmation */ unsigned char srcsid[SID_SIZE]; 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"); + 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"); + } /* First sequence number in the echo frames */ unsigned int firstSeq=random(); @@ -808,7 +832,7 @@ int app_mdp_ping(int argc, const char *const *argv, struct command_line_option * long long *txtime=(long long *)&mdp.out.payload[4]; *txtime=gettime_ms(); - int res=overlay_mdp_send(&mdp,0,0); + int res=overlay_mdp_send(mdp_sockfd, &mdp, 0, 0); if (res) { WHYF("ERROR: Could not dispatch PING frame #%d (error %d)", sequence_number - firstSeq, res); if (mdp.packetTypeAndFlags==MDP_ERROR) @@ -822,11 +846,11 @@ int app_mdp_ping(int argc, const char *const *argv, struct command_line_option * while(now0) { int ttl=-1; - if (overlay_mdp_recv(&mdp, port, &ttl)==0) { + if (overlay_mdp_recv(mdp_sockfd, &mdp, port, &ttl)==0) { switch(mdp.packetTypeAndFlags&MDP_TYPE_MASK) { case MDP_ERROR: WHYF("mdpping: overlay_mdp_recv: %s (code %d)", mdp.error.message, mdp.error.error); @@ -886,7 +910,7 @@ int app_mdp_ping(int argc, const char *const *argv, struct command_line_option * (samplestimeout?timeout:next_send) - now; - if (overlay_mdp_client_poll(timeout_ms)<=0) + if (overlay_mdp_client_poll(mdp_sockfd, timeout_ms)<=0) continue; int ttl=-1; - if (overlay_mdp_recv(&mdp_reply, port, &ttl)) + if (overlay_mdp_recv(mdp_sockfd, &mdp_reply, port, &ttl)) continue; if ((mdp_reply.packetTypeAndFlags&MDP_TYPE_MASK)==MDP_ERROR){ @@ -1787,6 +1835,8 @@ int app_node_info(int argc, const char *const *argv, struct command_line_option cli_printf("%s",mdp.nodeinfo.resolve_did?mdp.nodeinfo.name:"name-not-resolved"); cli_delim("\n"); + overlay_mdp_client_close(mdp_sockfd); + return 0; } diff --git a/mdp_client.c b/mdp_client.c index e73ef976..ca1dc522 100644 --- a/mdp_client.c +++ b/mdp_client.c @@ -24,14 +24,12 @@ #include "overlay_packet.h" #include "mdp_client.h" -int mdp_client_socket=-1; -int overlay_mdp_send(overlay_mdp_frame *mdp,int flags,int timeout_ms) +/* Send an mdp frame and return 0 if everything is OK, -1 otherwise. + * Warning: does not return the length of characters sent like sendto(). + */ +int overlay_mdp_send(int mdp_sockfd, overlay_mdp_frame *mdp, int flags, int timeout_ms) { - int len=4; - - if (mdp_client_socket==-1) - if (overlay_mdp_client_init() != 0) - return -1; + int len; /* Minimise frame length to save work and prevent accidental disclosure of memory contents. */ @@ -44,10 +42,10 @@ int overlay_mdp_send(overlay_mdp_frame *mdp,int flags,int timeout_ms) if (!FORM_SERVAL_INSTANCE_PATH(name.sun_path, "mdp.socket")) return -1; - set_nonblock(mdp_client_socket); - int result=sendto(mdp_client_socket, mdp, len, 0, + set_nonblock(mdp_sockfd); + int result=sendto(mdp_sockfd, mdp, len, 0, (struct sockaddr *)&name, sizeof(struct sockaddr_un)); - set_block(mdp_client_socket); + set_block(mdp_sockfd); if (result<0) { mdp->packetTypeAndFlags=MDP_ERROR; mdp->error.error=1; @@ -62,9 +60,9 @@ int overlay_mdp_send(overlay_mdp_frame *mdp,int flags,int timeout_ms) int port=mdp->out.dst.port; time_ms_t started = gettime_ms(); - while(timeout_ms>=0 && overlay_mdp_client_poll(timeout_ms)>0){ + while(timeout_ms>=0 && overlay_mdp_client_poll(mdp_sockfd, timeout_ms)>0){ int ttl=-1; - if (!overlay_mdp_recv(mdp, port, &ttl)) { + if (!overlay_mdp_recv(mdp_sockfd, mdp, port, &ttl)) { /* If all is well, examine result and return error code provided */ if ((mdp->packetTypeAndFlags&MDP_TYPE_MASK)==MDP_ERROR) return mdp->error.error; @@ -85,77 +83,70 @@ int overlay_mdp_send(overlay_mdp_frame *mdp,int flags,int timeout_ms) return -1; /* WHY("Timeout waiting for server response"); */ } -int overlay_mdp_client_init() +/** Create a new MDP socket and return its descriptor (-1 on error). */ +int overlay_mdp_client_socket(void) { + int mdp_sockfd; char overlay_mdp_client_socket_path[1024]; - int overlay_mdp_client_socket_path_len=-1; - if (mdp_client_socket==-1) { - /* Open socket to MDP server (thus connection is always local) */ - if (0) 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) { - WHY_perror("socket"); - return WHY("Could not open socket to MDP server"); - } - - /* We must bind to a temporary file name */ - struct sockaddr_un name; - unsigned int random_value; - if (urandombytes((unsigned char *)&random_value,sizeof(int))) - return WHY("urandombytes() failed"); - name.sun_family = AF_UNIX; - if (overlay_mdp_client_socket_path_len==-1) { - char fmt[1024]; - if (!FORM_SERVAL_INSTANCE_PATH(fmt, "mdp-client-%d-%08x.socket")) - return WHY("Could not form MDP client socket name"); - snprintf(overlay_mdp_client_socket_path,1024,fmt,getpid(),random_value); - overlay_mdp_client_socket_path_len=strlen(overlay_mdp_client_socket_path)+1; - if(debug&DEBUG_IO) DEBUGF("MDP client socket name='%s'",overlay_mdp_client_socket_path); - } - if (overlay_mdp_client_socket_path_len > 104 - 1) - FATALF("MDP socket path too long (%d > %d)", overlay_mdp_client_socket_path_len, 104 - 1); - - bcopy(overlay_mdp_client_socket_path,name.sun_path, - overlay_mdp_client_socket_path_len); - unlink(name.sun_path); - int len = 1 + strlen(name.sun_path) + sizeof(name.sun_family) + 1; - int r=bind(mdp_client_socket, (struct sockaddr *)&name, len); - if (r) { - WHY_perror("bind"); - return WHY("Could not bind MDP client socket to file name"); - } - - int send_buffer_size=128*1024; - if (setsockopt(mdp_client_socket, SOL_SOCKET, SO_RCVBUF, - &send_buffer_size, sizeof(send_buffer_size)) == -1) - WARN_perror("setsockopt"); + int overlay_mdp_client_socket_path_len; + /* Open socket to MDP server (thus connection is always local) */ + if (0) WHY("Use of abstract name space socket for Linux not implemented"); + + mdp_sockfd = socket(AF_UNIX, SOCK_DGRAM, 0); + if (mdp_sockfd < 0) { + WHY_perror("socket"); + return WHY("Could not open socket to MDP server"); + } + + /* We must bind to a temporary file name */ + struct sockaddr_un name; + unsigned int random_value; + if (urandombytes((unsigned char *)&random_value,sizeof(int))) + return WHY("urandombytes() failed"); + name.sun_family = AF_UNIX; + char fmt[1024]; + if (!FORM_SERVAL_INSTANCE_PATH(fmt, "mdp-client-%d-%08x.socket")) + return WHY("Could not form MDP client socket name"); + snprintf(overlay_mdp_client_socket_path,1024,fmt,getpid(),random_value); + overlay_mdp_client_socket_path_len=strlen(overlay_mdp_client_socket_path)+1; + if(debug&DEBUG_IO) DEBUGF("MDP client socket name='%s'",overlay_mdp_client_socket_path); + if (overlay_mdp_client_socket_path_len > 104 - 1) + FATALF("MDP socket path too long (%d > %d)", overlay_mdp_client_socket_path_len, 104 - 1); + + bcopy(overlay_mdp_client_socket_path,name.sun_path, + overlay_mdp_client_socket_path_len); + unlink(name.sun_path); + int len = 1 + strlen(name.sun_path) + sizeof(name.sun_family) + 1; + int r=bind(mdp_sockfd, (struct sockaddr *)&name, len); + if (r) { + WHY_perror("bind"); + return WHY("Could not bind MDP client socket to file name"); } - return 0; + int send_buffer_size=128*1024; + if (setsockopt(mdp_sockfd, SOL_SOCKET, SO_RCVBUF, + &send_buffer_size, sizeof(send_buffer_size)) == -1) + WARN_perror("setsockopt"); + + return mdp_sockfd; } -int overlay_mdp_client_done() +int overlay_mdp_client_close(int mdp_sockfd) { - if (mdp_client_socket!=-1) { - /* Tell MDP server to release all our bindings */ - overlay_mdp_frame mdp; - mdp.packetTypeAndFlags=MDP_GOODBYE; - overlay_mdp_send(&mdp,0,0); - } - - if (mdp_client_socket!=-1) - close(mdp_client_socket); - mdp_client_socket=-1; - return 0; + /* Tell MDP server to release all our bindings */ + overlay_mdp_frame mdp; + mdp.packetTypeAndFlags=MDP_GOODBYE; + overlay_mdp_send(mdp_sockfd, &mdp, 0, 0); + + return close(mdp_sockfd); } -int overlay_mdp_client_poll(time_ms_t timeout_ms) +int overlay_mdp_client_poll(int mdp_sockfd, time_ms_t timeout_ms) { fd_set r; int ret; FD_ZERO(&r); - FD_SET(mdp_client_socket,&r); + FD_SET(mdp_sockfd, &r); if (timeout_ms<0) timeout_ms=0; struct timeval tv; @@ -163,14 +154,16 @@ int overlay_mdp_client_poll(time_ms_t timeout_ms) if (timeout_ms>=0) { tv.tv_sec=timeout_ms/1000; tv.tv_usec=(timeout_ms%1000)*1000; - ret=select(mdp_client_socket+1,&r,NULL,&r,&tv); + /* What is this +1? */ + ret=select(mdp_sockfd+1,&r,NULL,&r,&tv); } else - ret=select(mdp_client_socket+1,&r,NULL,&r,NULL); + /* What is this +1? */ + ret=select(mdp_sockfd+1,&r,NULL,&r,NULL); return ret; } -int overlay_mdp_recv(overlay_mdp_frame *mdp, int port, int *ttl) +int overlay_mdp_recv(int mdp_sockfd, overlay_mdp_frame *mdp, int port, int *ttl) { char mdp_socket_name[101]; unsigned char recvaddrbuffer[1024]; @@ -184,7 +177,7 @@ int overlay_mdp_recv(overlay_mdp_frame *mdp, int port, int *ttl) /* Check if reply available */ set_nonblock(mdp_client_socket); - ssize_t len = recvwithttl(mdp_client_socket,(unsigned char *)mdp, sizeof(overlay_mdp_frame),ttl,recvaddr,&recvaddrlen); + ssize_t len = recvwithttl(mdp_sockfd,(unsigned char *)mdp, sizeof(overlay_mdp_frame),ttl,recvaddr,&recvaddrlen); set_block(mdp_client_socket); recvaddr_un=(struct sockaddr_un *)recvaddr; @@ -223,13 +216,13 @@ int overlay_mdp_recv(overlay_mdp_frame *mdp, int port, int *ttl) } // send a request to servald deamon to add a port binding -int overlay_mdp_bind(unsigned char *localaddr,int port) +int overlay_mdp_bind(int mdp_sockfd, unsigned char *localaddr, int port) { overlay_mdp_frame mdp; mdp.packetTypeAndFlags=MDP_BIND|MDP_FORCE; bcopy(localaddr,mdp.bind.sid,SID_SIZE); mdp.bind.port=port; - int result=overlay_mdp_send(&mdp,MDP_AWAITREPLY,5000); + int result=overlay_mdp_send(mdp_sockfd, &mdp,MDP_AWAITREPLY,5000); if (result) { if (mdp.packetTypeAndFlags==MDP_ERROR) WHYF("Could not bind to MDP port %d: error=%d, message='%s'", @@ -241,7 +234,7 @@ int overlay_mdp_bind(unsigned char *localaddr,int port) return 0; } -int overlay_mdp_getmyaddr(int index,unsigned char *sid) +int overlay_mdp_getmyaddr(int mdp_sockfd, int index, unsigned char *sid) { overlay_mdp_frame a; memset(&a, 0, sizeof(a)); @@ -251,7 +244,7 @@ int overlay_mdp_getmyaddr(int index,unsigned char *sid) a.addrlist.first_sid=index; a.addrlist.last_sid=0x7fffffff; a.addrlist.frame_sid_count=MDP_MAX_SID_REQUEST; - int result=overlay_mdp_send(&a,MDP_AWAITREPLY,5000); + int result=overlay_mdp_send(mdp_sockfd,&a,MDP_AWAITREPLY,5000); if (result) { if (a.packetTypeAndFlags == MDP_ERROR) DEBUGF("MDP Server error #%d: '%s'", a.error.error, a.error.message); diff --git a/mdp_client.h b/mdp_client.h index 2459d28f..b17b8755 100644 --- a/mdp_client.h +++ b/mdp_client.h @@ -23,11 +23,11 @@ /* Client-side MDP function */ extern int mdp_client_socket; -int overlay_mdp_client_init(); -int overlay_mdp_client_done(); -int overlay_mdp_client_poll(time_ms_t timeout_ms); -int overlay_mdp_recv(overlay_mdp_frame *mdp, int port, int *ttl); -int overlay_mdp_send(overlay_mdp_frame *mdp,int flags,int timeout_ms); +int overlay_mdp_client_socket(void); +int overlay_mdp_client_close(int mdp_sockfd); +int overlay_mdp_client_poll(int mdp_sockfd, time_ms_t timeout_ms); +int overlay_mdp_recv(int mdp_sockfd, overlay_mdp_frame *mdp, int port, int *ttl); +int overlay_mdp_send(int mdp_sockfd, overlay_mdp_frame *mdp,int flags,int timeout_ms); int overlay_mdp_relevant_bytes(overlay_mdp_frame *mdp); -#endif \ No newline at end of file +#endif diff --git a/serval.h b/serval.h index 223b3f7a..b613434b 100644 --- a/serval.h +++ b/serval.h @@ -675,8 +675,8 @@ int cli_delim(const char *opt); int is_configvarname(const char *arg); -int overlay_mdp_getmyaddr(int index,unsigned char *sid); -int overlay_mdp_bind(unsigned char *localaddr,int port); +int overlay_mdp_getmyaddr(int mpd_sockfd, int index, unsigned char *sid); +int overlay_mdp_bind(int mdp_sockfd, unsigned char *localaddr, int port); int overlay_route_node_info(overlay_mdp_nodeinfo *node_info); int overlay_interface_register(char *name, struct in_addr addr, From 9d443866983a9321176d451fd29e5d59078a34b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Tue, 6 Nov 2012 23:13:07 +0100 Subject: [PATCH 03/24] overlay_mdp_recv must be blocking --- mdp_client.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/mdp_client.c b/mdp_client.c index ca1dc522..f7dc979e 100644 --- a/mdp_client.c +++ b/mdp_client.c @@ -176,9 +176,7 @@ int overlay_mdp_recv(int mdp_sockfd, overlay_mdp_frame *mdp, int port, int *ttl) mdp->packetTypeAndFlags=0; /* Check if reply available */ - set_nonblock(mdp_client_socket); ssize_t len = recvwithttl(mdp_sockfd,(unsigned char *)mdp, sizeof(overlay_mdp_frame),ttl,recvaddr,&recvaddrlen); - set_block(mdp_client_socket); recvaddr_un=(struct sockaddr_un *)recvaddr; /* Null terminate received address so that the stat() call below can succeed */ From 61c35db6711a206828ba83a54b041544126d94d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Wed, 7 Nov 2012 11:00:22 +0100 Subject: [PATCH 04/24] Remove useless external declaration I removed the definition of mdp_client_socket, but an external declaration was remaining. --- mdp_client.h | 1 - 1 file changed, 1 deletion(-) diff --git a/mdp_client.h b/mdp_client.h index b17b8755..6a13022e 100644 --- a/mdp_client.h +++ b/mdp_client.h @@ -22,7 +22,6 @@ #include "serval.h" /* Client-side MDP function */ -extern int mdp_client_socket; int overlay_mdp_client_socket(void); int overlay_mdp_client_close(int mdp_sockfd); int overlay_mdp_client_poll(int mdp_sockfd, time_ms_t timeout_ms); From 4b273b4393a97ebda74afaed17687484ae0d680e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Fri, 9 Nov 2012 11:03:33 +0100 Subject: [PATCH 05/24] Fix broken dna lookup lookup_send_request() must use the socket of the caller, not create a new one (detected by dnaprotocol test script). --- commandline.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/commandline.c b/commandline.c index 61e6e246..e345d333 100644 --- a/commandline.c +++ b/commandline.c @@ -315,15 +315,13 @@ int app_echo(int argc, const char *const *argv, struct command_line_option *o, v return 0; } -void lookup_send_request(unsigned char *srcsid, int srcport, unsigned char *dstsid, const char *did){ - int mdp_sockfd; +void lookup_send_request(int mdp_sockfd, unsigned char *srcsid, int srcport, unsigned char *dstsid, const char *did) +{ int i; overlay_mdp_frame mdp; bzero(&mdp,sizeof(mdp)); - - if ((mdp_sockfd = overlay_mdp_client_socket()) < 0) - WHY("Cannot create MDP socket"); - + + /* set source address to a local address, and pick a random port */ mdp.out.src.port=srcport; bcopy(srcsid,mdp.out.src.sid,SID_SIZE); @@ -360,8 +358,6 @@ void lookup_send_request(unsigned char *srcsid, int srcport, unsigned char *dsts } } } - - overlay_mdp_client_close(mdp_sockfd); } int app_dna_lookup(int argc, const char *const *argv, struct command_line_option *o, void *context) @@ -423,7 +419,7 @@ int app_dna_lookup(int argc, const char *const *argv, struct command_line_option if ((last_tx+interval)>1; @@ -1761,7 +1757,7 @@ int app_node_info(int argc, const char *const *argv, struct command_line_option if (now >= next_send){ /* Send a unicast packet to this node, asking for any did */ - lookup_send_request(srcsid, port, mdp.nodeinfo.sid, ""); + lookup_send_request(mdp_sockfd, srcsid, port, mdp.nodeinfo.sid, ""); next_send+=125; continue; } From f5a6dc7799878f3f002ca57ce26f68e95d71c6f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Fri, 16 Nov 2012 15:31:28 +0100 Subject: [PATCH 06/24] overlay_mdp_bind must be visible in MDP API --- mdp_client.h | 1 + 1 file changed, 1 insertion(+) diff --git a/mdp_client.h b/mdp_client.h index 6a13022e..7b5fe60e 100644 --- a/mdp_client.h +++ b/mdp_client.h @@ -25,6 +25,7 @@ int overlay_mdp_client_socket(void); int overlay_mdp_client_close(int mdp_sockfd); int overlay_mdp_client_poll(int mdp_sockfd, time_ms_t timeout_ms); +int overlay_mdp_bind(int mdp_sockfd, unsigned char *localaddr, int port); int overlay_mdp_recv(int mdp_sockfd, overlay_mdp_frame *mdp, int port, int *ttl); int overlay_mdp_send(int mdp_sockfd, overlay_mdp_frame *mdp,int flags,int timeout_ms); int overlay_mdp_relevant_bytes(overlay_mdp_frame *mdp); From 0bfa34d79b5d63f54b0706e6ac9d2237d47d0b18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Fri, 16 Nov 2012 11:50:31 +0100 Subject: [PATCH 07/24] overlay_mdp_send must be blocking Else, once the buffer is full, we get errno=11 --- mdp_client.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/mdp_client.c b/mdp_client.c index f7dc979e..08566065 100644 --- a/mdp_client.c +++ b/mdp_client.c @@ -42,10 +42,8 @@ int overlay_mdp_send(int mdp_sockfd, overlay_mdp_frame *mdp, int flags, int time if (!FORM_SERVAL_INSTANCE_PATH(name.sun_path, "mdp.socket")) return -1; - set_nonblock(mdp_sockfd); int result=sendto(mdp_sockfd, mdp, len, 0, (struct sockaddr *)&name, sizeof(struct sockaddr_un)); - set_block(mdp_sockfd); if (result<0) { mdp->packetTypeAndFlags=MDP_ERROR; mdp->error.error=1; From 1b81ad77218d02ca6ac10699af2b9ec24bda091c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Mon, 12 Nov 2012 17:23:32 +0100 Subject: [PATCH 08/24] Native-part of MDP JNI bindings --- mdp_jni.c | 351 +++++++++++++++++++++++++++++++++++++++++++++++++ mdp_jni.h | 61 +++++++++ sourcefiles.mk | 1 + 3 files changed, 413 insertions(+) create mode 100644 mdp_jni.c create mode 100644 mdp_jni.h diff --git a/mdp_jni.c b/mdp_jni.c new file mode 100644 index 00000000..dcb9caee --- /dev/null +++ b/mdp_jni.c @@ -0,0 +1,351 @@ +/* JNI bindings for MDP protocol. + * + * Author(s): + * - Romain Vimont (®om) + */ + +#ifdef HAVE_JNI_H +#include +#include "serval.h" + +#define THROW_NULL_POINTER_EXCEPTION \ + (*env)->ThrowNew(env, cl_nullpointerexception, NULL); +#define THROW_OUT_OF_MEMORY_ERROR \ + (*env)->ThrowNew(env, cl_outofmemoryerror, NULL); +#define THROW_MESH_SOCKET_EXCEPTION(x) \ + (*env)->ThrowNew(env, cl_meshsocketexception, (x)); + +/* jfieldID and jmethodID do not need global ref. */ + +/* Get jfieldID ref. */ +#define G_FIELD(env, cls, name, type) \ + (jfieldID) (*(env))->GetFieldID(env, cls, name, type) +/* Get jmethodID ref. */ +#define G_METHOD(env, cls, name, type) \ + (jmethodID) (*(env))->GetMethodID(env, cls, name, type) +/* Get global jclass ref. */ +#define GG_CLASS(env, name) \ + (jclass) (*(env))->NewGlobalRef(env,(*(env))->FindClass(env, name)) + +/* Classes */ +static jclass cl_meshpacket; +static jclass cl_subscriberid; + +/* Methods */ +static jmethodID m_subscriberid_init; + +/* MeshSocket fields */ +static jfieldID f_meshsocket_fd; +static jfieldID f_meshsocket_rawsid; +static jfieldID f_meshsocket_port; + +/* MeshPacket fields */ +static jfieldID f_meshpacket_buf; +static jfieldID f_meshpacket_offset; +static jfieldID f_meshpacket_length; +static jfieldID f_meshpacket_sid; +static jfieldID f_meshpacket_port; + +/* SubscriberId fields */ +static jfieldID f_subscriberid_binary; + +/* Throwables */ +static jclass cl_meshsocketexception; +static jclass cl_nullpointerexception; +static jclass cl_outofmemoryerror; + +JNIEXPORT void JNICALL +Java_org_servalproject_servald_mdp_MeshSocket_init(JNIEnv * env, jclass cls) +{ + /* Keep JNI refs of fields, methods and classes. */ + + f_meshsocket_fd = G_FIELD(env, cls, "fd", "I"); + f_meshsocket_rawsid = G_FIELD(env, cls, "rawSid", "[B"); + f_meshsocket_port = G_FIELD(env, cls, "port", "I"); + + cl_meshpacket = GG_CLASS(env, "org/servalproject/servald/mdp/MeshPacket"); + f_meshpacket_buf = G_FIELD(env, cl_meshpacket, "buf", "[B"); + f_meshpacket_offset = G_FIELD(env, cl_meshpacket, "offset", "I"); + f_meshpacket_length = G_FIELD(env, cl_meshpacket, "length", "I"); + f_meshpacket_sid = + G_FIELD(env, cl_meshpacket, "sid", + "Lorg/servalproject/servald/SubscriberId;"); + f_meshpacket_port = G_FIELD(env, cl_meshpacket, "port", "I"); + + cl_subscriberid = GG_CLASS(env, "org/servalproject/servald/SubscriberId"); + f_subscriberid_binary = G_FIELD(env, cl_subscriberid, "binary", "[B"); + m_subscriberid_init = G_METHOD(env, cl_subscriberid, "", "([B)V"); + + cl_meshsocketexception = + GG_CLASS(env, "org/servalproject/servald/mdp/MeshSocketException"); + cl_nullpointerexception = GG_CLASS(env, "java/lang/NullPointerException"); + cl_outofmemoryerror = GG_CLASS(env, "java/lang/OutOfMemoryError"); +} + +JNIEXPORT void JNICALL +Java_org_servalproject_servald_mdp_MeshSocket__1create(JNIEnv * env, + jobject this) +{ + jint fd; + + /* Create mesh socket. */ + + if ((fd = overlay_mdp_client_socket()) < 0) { + THROW_MESH_SOCKET_EXCEPTION("Cannot create socket"); + return; /* No resources to clean. */ + } + + /* this.fd = fd; */ + (*env)->SetIntField(env, this, f_meshsocket_fd, fd); +} + +JNIEXPORT void JNICALL +Java_org_servalproject_servald_mdp_MeshSocket__1bind(JNIEnv * env, + jobject this, jint port, + jobject sid_obj) +{ + jint fd; + jbyteArray jsid; + jbyte *sid = NULL; + char any[SID_SIZE]; + + /* Retrieve values from java objects. */ + + if (sid_obj != NULL) { + /* jsid = sid_obj.binary; */ + if ((jsid = + (jbyteArray) (*env)->GetObjectField(env, sid_obj, + f_subscriberid_binary)) == + NULL) { + THROW_NULL_POINTER_EXCEPTION; + WHY("jsid is NULL"); + return; /* No resources to clean. */ + } + + /* Convert jsid array. */ + if ((sid = + (jbyte *) (*env)->GetByteArrayElements(env, jsid, NULL)) == NULL) { + THROW_OUT_OF_MEMORY_ERROR; + WHY("Cannot create sid"); + goto finally; + } + } else { + /* If sid_obj is NULL, then use sid = 0. */ + memset(any, 0, SID_SIZE); + sid = any; + } + + /* fd = this.fd; */ + fd = (*env)->GetIntField(env, this, f_meshsocket_fd); + + /* Bind. */ + + if (overlay_mdp_bind(fd, sid, port)) { + THROW_MESH_SOCKET_EXCEPTION("Cannot bind to MDP socket"); + /* fall through finally */ + } + +finally: + if (sid_obj != NULL) { + (*env)->ReleaseByteArrayElements(env, jsid, sid, 0); + } +} + +JNIEXPORT void JNICALL +Java_org_servalproject_servald_mdp_MeshSocket__1send(JNIEnv * env, + jobject this, + jobject mdppack) +{ + jint fd, localport, offset, length, port; + jobject sid_obj; + jbyteArray jbuf, jsid, jlocalsid; + jbyte *buf, *sid, *localsid = NULL; + int src_port; + overlay_mdp_frame mdp = { }; /* Init with zeros */ + + /* Retrieve values from java objects. */ + + /* length = mdppack.length; */ + length = (*env)->GetIntField(env, mdppack, f_meshpacket_length); + if (length > MDP_MTU) { + THROW_MESH_SOCKET_EXCEPTION("Mesh packet too big"); + WHYF("Mesh packet too big (size=%d, MTU=%d)", length, MDP_MTU); + return; + } + + /* fd = this.fd; */ + fd = (*env)->GetIntField(env, this, f_meshsocket_fd); + + /* jlocalsid = this.rawSid; */ + jlocalsid = + (jbyteArray) (*env)->GetObjectField(env, this, f_meshsocket_rawsid); + + /* localport = this.port; */ + localport = (*env)->GetIntField(env, this, f_meshsocket_port); + + /* offset = mdppack.offset; */ + offset = (*env)->GetIntField(env, mdppack, f_meshpacket_offset); + + /* port = mdppack.port; */ + port = (*env)->GetIntField(env, mdppack, f_meshpacket_port); + + /* sid_obj = mdppack.sid; */ + if ((sid_obj = + (*env)->GetObjectField(env, mdppack, f_meshpacket_sid)) == NULL) { + THROW_NULL_POINTER_EXCEPTION; + WHY("sid_obj is NULL"); + return; /* No resources to clean. */ + } + + /* jsid = mdppack.sid.binary; */ + if ((jsid = + (jbyteArray) (*env)->GetObjectField(env, sid_obj, + f_subscriberid_binary)) == NULL) { + THROW_NULL_POINTER_EXCEPTION; + WHY("jsid is NULL"); + return; /* No resources to clean. */ + } + + /* jbuf = mdppack.buf; */ + if ((jbuf = + (jbyteArray) (*env)->GetObjectField(env, mdppack, + f_meshpacket_buf)) == NULL) { + THROW_NULL_POINTER_EXCEPTION; + WHY("jbuf is NULL"); + return; /* No resources to clean. */ + }; + + /* Convert arrays. */ + + /* jlocalsid can be NULL: the user wants to use its own SID. */ + if (jlocalsid != NULL + && (localsid = + (jbyte *) (*env)->GetByteArrayElements(env, jlocalsid, + NULL)) == NULL) { + THROW_OUT_OF_MEMORY_ERROR; + WHY("Cannot create localsid"); + return; /* No resources to clean. */ + } + + if ((sid = (jbyte *) (*env)->GetByteArrayElements(env, jsid, NULL)) == NULL) { + THROW_OUT_OF_MEMORY_ERROR; + WHY("Cannot create sid"); + goto finally1; + } + + if ((buf = (jbyte *) malloc(length * sizeof(jbyte))) == NULL) { + THROW_OUT_OF_MEMORY_ERROR; + WHY("Cannot create buf"); + goto finally2; + } + + (*env)->GetByteArrayRegion(env, jbuf, offset, length, buf); + if ((*env)->ExceptionCheck(env) == JNI_TRUE) { + WHY("IndexOutOfBoundsException while filling buf"); + goto finally3; + } + + /* Fill mdp structure. */ + + mdp.packetTypeAndFlags = MDP_TX; + mdp.out.src.port = localport; + if (localsid != NULL) { + memcpy(mdp.out.src.sid, localsid, SID_SIZE); + /* else, src.sid is let to 0, so servald will automatically fill it with + my sid. */ + } + memcpy(mdp.out.dst.sid, sid, SID_SIZE); + mdp.out.dst.port = port; + mdp.out.payload_length = length; + memcpy(mdp.out.payload, buf, length); + + /* Send data. */ + if (overlay_mdp_send(fd, &mdp, 0, 0)) { + THROW_MESH_SOCKET_EXCEPTION("Cannot send data to servald"); + /* fall through finally */ + } + + /* Finally, release resources. */ + +finally3: + free(buf); + +finally2: + (*env)->ReleaseByteArrayElements(env, jsid, sid, 0); + +finally1: + if (localsid != NULL) { + (*env)->ReleaseByteArrayElements(env, jlocalsid, localsid, 0); + } +} + +JNIEXPORT void JNICALL +Java_org_servalproject_servald_mdp_MeshSocket__1receive(JNIEnv * env, + jobject this, + jobject mdppack) +{ + jint fd, localport, offset, length, port; + int buf_length; + jobject sid_obj; + jbyteArray jbuf, jsid; + jbyte *buf, *sid; + overlay_mdp_frame mdp; + + /* fd = this.fd; */ + fd = (*env)->GetIntField(env, this, f_meshsocket_fd); + + /* localport = this.port; */ + localport = (*env)->GetIntField(env, this, f_meshsocket_port); + + /* length = mdppack.length; */ + length = (*env)->GetIntField(env, mdppack, f_meshpacket_length); + + /* Receive data. */ + if (overlay_mdp_recv(fd, &mdp, localport, -1)) { + (*env)->ThrowNew(env, cl_meshsocketexception, + "Cannot receive data from servald"); + WHY("Cannot receive data from servald"); + return; + } + + /* offset = mdppack.offset; */ + offset = (*env)->GetIntField(env, mdppack, f_meshpacket_offset); + + /* If payload is too big, it is truncated. */ + buf_length = + length < mdp.in.payload_length ? length : mdp.in.payload_length; + + /* Write payload. */ + jbuf = (jbyteArray) (*env)->GetObjectField(env, mdppack, f_meshpacket_buf); + (*env)->SetByteArrayRegion(env, jbuf, offset, buf_length, mdp.in.payload); + + /* Write payload length (received length, not truncated). */ + (*env)->SetIntField(env, mdppack, f_meshpacket_length, + mdp.in.payload_length); + + /* Write source sid. */ + jsid = (*env)->NewByteArray(env, SID_SIZE); + sid = (*env)->GetByteArrayElements(env, jsid, NULL); + memcpy(sid, mdp.in.src.sid, SID_SIZE); + (*env)->ReleaseByteArrayElements(env, jsid, sid, JNI_COMMIT); + + /* sid_obj = new SubscriberId(jsid); */ + sid_obj = + (*env)->NewObject(env, cl_subscriberid, m_subscriberid_init, jsid); + (*env)->SetObjectField(env, mdppack, f_meshpacket_sid, sid_obj); + + /* Write source port. */ + (*env)->SetIntField(env, mdppack, f_meshpacket_port, mdp.in.src.port); +} + +JNIEXPORT void JNICALL +Java_org_servalproject_servald_mdp_MeshSocket__1close(JNIEnv * env, + jobject this) +{ + /* fd = this.fd; */ + jint fd = (*env)->GetIntField(env, this, f_meshsocket_fd); + + /* Close socket. */ + overlay_mdp_client_close(fd); +} +#endif diff --git a/mdp_jni.h b/mdp_jni.h new file mode 100644 index 00000000..a4d5cbc2 --- /dev/null +++ b/mdp_jni.h @@ -0,0 +1,61 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_servalproject_servald_mdp_MeshSocket */ + +#ifndef _Included_org_servalproject_servald_mdp_MeshSocket +#define _Included_org_servalproject_servald_mdp_MeshSocket +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_servalproject_servald_mdp_MeshSocket + * Method: init + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_servalproject_servald_mdp_MeshSocket_init + (JNIEnv *, jclass); + +/* + * Class: org_servalproject_servald_mdp_MeshSocket + * Method: _create + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_servalproject_servald_mdp_MeshSocket__1create + (JNIEnv *, jobject); + +/* + * Class: org_servalproject_servald_mdp_MeshSocket + * Method: _bind + * Signature: (ILorg/servalproject/servald/SubscriberId;)V + */ +JNIEXPORT void JNICALL Java_org_servalproject_servald_mdp_MeshSocket__1bind + (JNIEnv *, jobject, jint, jobject); + +/* + * Class: org_servalproject_servald_mdp_MeshSocket + * Method: _send + * Signature: (Lorg/servalproject/servald/mdp/MeshPacket;)V + */ +JNIEXPORT void JNICALL Java_org_servalproject_servald_mdp_MeshSocket__1send + (JNIEnv *, jobject, jobject); + +/* + * Class: org_servalproject_servald_mdp_MeshSocket + * Method: _receive + * Signature: (Lorg/servalproject/servald/mdp/MeshPacket;)V + */ +JNIEXPORT void JNICALL Java_org_servalproject_servald_mdp_MeshSocket__1receive + (JNIEnv *, jobject, jobject); + +/* + * Class: org_servalproject_servald_mdp_MeshSocket + * Method: _close + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_servalproject_servald_mdp_MeshSocket__1close + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/sourcefiles.mk b/sourcefiles.mk index 4cc6281c..9b454fe1 100644 --- a/sourcefiles.mk +++ b/sourcefiles.mk @@ -16,6 +16,7 @@ SERVAL_SOURCES = $(SERVAL_BASE)audiodevices.c \ $(SERVAL_BASE)lsif.c \ $(SERVAL_BASE)main.c \ $(SERVAL_BASE)mdp_client.c \ + $(SERVAL_BASE)mdp_jni.c \ $(SERVAL_BASE)mkdir.c \ $(SERVAL_BASE)monitor.c \ $(SERVAL_BASE)monitor-client.c \ From cf81ee48439aaaf2aaa1b44b12ba0a2b001f6921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Thu, 22 Nov 2012 10:32:35 +0100 Subject: [PATCH 09/24] Missing free for a JNI buffer ReleaseByteArrayElements last parameter is mode. Its value is: - 0: copy back the content and free the buffer; - JNI_COMMIT: copy back the content and *do not* free the buffer; - JNI_ABORT: free the buffer without copying back the possible changes. We definitely want 0. With JNI_COMMIT, after receiving more than ~1024 packets, it crashes: ReferenceTable overflow (max=1024) --- mdp_jni.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdp_jni.c b/mdp_jni.c index dcb9caee..943d6cc5 100644 --- a/mdp_jni.c +++ b/mdp_jni.c @@ -327,7 +327,7 @@ Java_org_servalproject_servald_mdp_MeshSocket__1receive(JNIEnv * env, jsid = (*env)->NewByteArray(env, SID_SIZE); sid = (*env)->GetByteArrayElements(env, jsid, NULL); memcpy(sid, mdp.in.src.sid, SID_SIZE); - (*env)->ReleaseByteArrayElements(env, jsid, sid, JNI_COMMIT); + (*env)->ReleaseByteArrayElements(env, jsid, sid, 0); /* sid_obj = new SubscriberId(jsid); */ sid_obj = From 0fa6f78a979a14f5f06d131288e26b5ab18fd584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Mon, 7 Jan 2013 14:39:33 +0100 Subject: [PATCH 10/24] Include mdp_client.h instead of serval.h --- mdp_jni.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdp_jni.c b/mdp_jni.c index 943d6cc5..88ab2c36 100644 --- a/mdp_jni.c +++ b/mdp_jni.c @@ -6,7 +6,7 @@ #ifdef HAVE_JNI_H #include -#include "serval.h" +#include "mdp_client.h" #define THROW_NULL_POINTER_EXCEPTION \ (*env)->ThrowNew(env, cl_nullpointerexception, NULL); From 80cb5e294b5cc8db4a039d67b36b4fa3e05cf08c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Mon, 7 Jan 2013 14:40:07 +0100 Subject: [PATCH 11/24] Fix compilation warnings (unused, signed/unsigned variables...) --- mdp_jni.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/mdp_jni.c b/mdp_jni.c index 88ab2c36..16ef3f2b 100644 --- a/mdp_jni.c +++ b/mdp_jni.c @@ -105,7 +105,7 @@ Java_org_servalproject_servald_mdp_MeshSocket__1bind(JNIEnv * env, jobject sid_obj) { jint fd; - jbyteArray jsid; + jbyteArray jsid = NULL; jbyte *sid = NULL; char any[SID_SIZE]; @@ -132,7 +132,7 @@ Java_org_servalproject_servald_mdp_MeshSocket__1bind(JNIEnv * env, } else { /* If sid_obj is NULL, then use sid = 0. */ memset(any, 0, SID_SIZE); - sid = any; + sid = (jbyte *) any; } /* fd = this.fd; */ @@ -140,7 +140,7 @@ Java_org_servalproject_servald_mdp_MeshSocket__1bind(JNIEnv * env, /* Bind. */ - if (overlay_mdp_bind(fd, sid, port)) { + if (overlay_mdp_bind(fd, (unsigned char *) sid, port)) { THROW_MESH_SOCKET_EXCEPTION("Cannot bind to MDP socket"); /* fall through finally */ } @@ -160,7 +160,6 @@ Java_org_servalproject_servald_mdp_MeshSocket__1send(JNIEnv * env, jobject sid_obj; jbyteArray jbuf, jsid, jlocalsid; jbyte *buf, *sid, *localsid = NULL; - int src_port; overlay_mdp_frame mdp = { }; /* Init with zeros */ /* Retrieve values from java objects. */ @@ -284,11 +283,11 @@ Java_org_servalproject_servald_mdp_MeshSocket__1receive(JNIEnv * env, jobject this, jobject mdppack) { - jint fd, localport, offset, length, port; - int buf_length; + jint fd, localport, offset, length; + int buf_length, ttl; jobject sid_obj; jbyteArray jbuf, jsid; - jbyte *buf, *sid; + jbyte *sid; overlay_mdp_frame mdp; /* fd = this.fd; */ @@ -301,7 +300,7 @@ Java_org_servalproject_servald_mdp_MeshSocket__1receive(JNIEnv * env, length = (*env)->GetIntField(env, mdppack, f_meshpacket_length); /* Receive data. */ - if (overlay_mdp_recv(fd, &mdp, localport, -1)) { + if (overlay_mdp_recv(fd, &mdp, localport, &ttl)) { (*env)->ThrowNew(env, cl_meshsocketexception, "Cannot receive data from servald"); WHY("Cannot receive data from servald"); @@ -317,7 +316,8 @@ Java_org_servalproject_servald_mdp_MeshSocket__1receive(JNIEnv * env, /* Write payload. */ jbuf = (jbyteArray) (*env)->GetObjectField(env, mdppack, f_meshpacket_buf); - (*env)->SetByteArrayRegion(env, jbuf, offset, buf_length, mdp.in.payload); + (*env)->SetByteArrayRegion(env, jbuf, offset, buf_length, + (jbyte *) mdp.in.payload); /* Write payload length (received length, not truncated). */ (*env)->SetIntField(env, mdppack, f_meshpacket_length, From dd1a7c4aa02346b125398a8967d0a3a8b781e136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Tue, 8 Jan 2013 13:05:31 +0100 Subject: [PATCH 12/24] Remove question-comment Using fd+1 is the right way to use select() --- mdp_client.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/mdp_client.c b/mdp_client.c index aab339e1..3f88113a 100644 --- a/mdp_client.c +++ b/mdp_client.c @@ -156,11 +156,9 @@ int overlay_mdp_client_poll(int mdp_sockfd, time_ms_t timeout_ms) if (timeout_ms>=0) { tv.tv_sec=timeout_ms/1000; tv.tv_usec=(timeout_ms%1000)*1000; - /* What is this +1? */ ret=select(mdp_sockfd+1,&r,NULL,&r,&tv); } else - /* What is this +1? */ ret=select(mdp_sockfd+1,&r,NULL,&r,NULL); return ret; } From 92a28a2eaa41136ee335b4904b13ff03b4daab0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Mon, 14 Jan 2013 17:10:28 +0100 Subject: [PATCH 13/24] Remove sun_path file on MDP socket close Avoid to keep a lot of useless files like: var/serval-node/mdp-client-XXXX-XXXXXXXX.socket --- mdp_client.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/mdp_client.c b/mdp_client.c index 3f88113a..b1501e39 100644 --- a/mdp_client.c +++ b/mdp_client.c @@ -26,6 +26,69 @@ #include "overlay_packet.h" #include "mdp_client.h" +/* We randomly generate UNIX socket path names for communicating with servald, + * and handle only mdp_sockfd. But when we close the socket, the file is not + * deleted. Thus, we need to keep a mapping between mdp_sockfd and sun_path. + * Every time a MDP socket is open, we store it with its path_name. + * Every time a MDP socket is closed, we remove it from the list and delete the + * file. + */ + +/* Item mapping mdp_sockfd and sun_path. */ +struct mdp_sock_node { + int mdp_sockfd; + char sun_path[108]; /* same size as struct sockaddr_un sun_path */ + struct mdp_sock_node *next; /* next item for linked-list */ +}; + +/* Linked-list storing the mapping between mdp_sockfd and sun_path for open MDP + * sockets. */ +static struct mdp_sock_node *open_mdp_sock_list; + +/* Add the socket to the open MDP socket list. */ +static void mdp_sock_opened(int mdp_sockfd, char *sun_path) +{ + struct mdp_sock_node *old_head = open_mdp_sock_list; + + /* The new item becomes the head. */ + open_mdp_sock_list = + (struct mdp_sock_node *) malloc(sizeof(struct mdp_sock_node)); + + open_mdp_sock_list->mdp_sockfd = mdp_sockfd; + strncpy(open_mdp_sock_list->sun_path, sun_path, 108); + open_mdp_sock_list->next = old_head; +} + +/* Remove the socket from the list and delete associated file on filesystem. */ +static void mdp_sock_closed(int mdp_sockfd) +{ + struct mdp_sock_node *node = open_mdp_sock_list; + struct mdp_sock_node *prev_node = NULL; + + /* Find the node having the same mdp_sockfd. */ + while (node != NULL && node->mdp_sockfd != mdp_sockfd) { + prev_node = node; + node = node->next; + } + + if (node != NULL) { + /* Node found. */ + + if (prev_node != NULL) { + /* General case. */ + prev_node->next = node->next; + } else { + /* Special case for the first item. */ + open_mdp_sock_list = node->next; + } + /* Remove socket file. */ + unlink(node->sun_path); + free(node); + } else { + WARN("Socket to remove not found"); + } +} + /* Send an mdp frame and return 0 if everything is OK, -1 otherwise. * Warning: does not return the length of characters sent like sendto(). */ @@ -117,6 +180,10 @@ int overlay_mdp_client_socket(void) bcopy(overlay_mdp_client_socket_path,name.sun_path, overlay_mdp_client_socket_path_len); + + /* Store the mapping sockfd/sun_path. */ + mdp_sock_opened(mdp_sockfd, name.sun_path); + unlink(name.sun_path); int len = 1 + strlen(name.sun_path) + sizeof(name.sun_family) + 1; int r=bind(mdp_sockfd, (struct sockaddr *)&name, len); @@ -140,7 +207,12 @@ int overlay_mdp_client_close(int mdp_sockfd) mdp.packetTypeAndFlags=MDP_GOODBYE; overlay_mdp_send(mdp_sockfd, &mdp, 0, 0); - return close(mdp_sockfd); + int res = close(mdp_sockfd); + + /* Remove the socket file. */ + mdp_sock_closed(mdp_sockfd); + + return res; } int overlay_mdp_client_poll(int mdp_sockfd, time_ms_t timeout_ms) From db2fefcf00c9d412007ce851b7af847b6faf10f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Tue, 15 Jan 2013 13:42:58 +0100 Subject: [PATCH 14/24] Delete all socket files on servald start If serval does not close properly, socket files are kept in /data/data/org.servalproject/var/serval-node. Therefore, we need to clean up when servald starts. --- commandline.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/commandline.c b/commandline.c index 8fc37cc9..c3c96d69 100644 --- a/commandline.c +++ b/commandline.c @@ -22,6 +22,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include #include +#include +#include +#include #ifdef HAVE_STRINGS_H #include #endif @@ -528,6 +531,40 @@ int app_dna_lookup(int argc, const char *const *argv, const struct command_line_ return 0; } +/* Delete all UNIX socket files in instance directory. */ +static void clean_socket_files() +{ + const char *instance_path = serval_instancepath(); + char path[PATH_MAX]; + DIR *dir; + struct dirent *dp; + struct stat st; + + /* Open instance_path directory. */ + if ((dir = opendir(instance_path)) == NULL) { + WARNF("Can't open %s\n", instance_path); + return; + } + + /* Read all files in instance_path directory. */ + while ((dp = readdir(dir)) != NULL) { + + /* Concatenate dir and name. */ + sprintf(path, "%s/%s", instance_path, dp->d_name); + + /* Retrieve stat info. */ + if (stat(path, &st)) { + WARNF("Cannot stat %s (errno=%d)\n", path, errno); + continue; + } + + if (S_ISSOCK(st.st_mode)) { + /* The file is a UNIX socket, delete it. */ + unlink(path); + } + } +} + int app_server_start(int argc, const char *const *argv, const struct command_line_option *o, void *context) { if (config.debug.verbose) DEBUG_argv("command", argc, argv); @@ -591,6 +628,8 @@ int app_server_start(int argc, const char *const *argv, const struct command_lin /* Create the instance directory if it does not yet exist */ if (create_serval_instance_dir() == -1) return -1; + /* Clean old socket files from instance directory. */ + clean_socket_files(); /* Now that we know our instance path, we can ask for the default set of network interfaces that we will take interest in. */ if (config.interfaces.ac == 0) From 8454944653d0a2ab8dd833d93104d35bbc632f8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Mon, 11 Feb 2013 11:18:32 +0100 Subject: [PATCH 15/24] Add QoS and flags management --- mdp_jni.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/mdp_jni.c b/mdp_jni.c index 16ef3f2b..7ef8bed2 100644 --- a/mdp_jni.c +++ b/mdp_jni.c @@ -45,6 +45,8 @@ static jfieldID f_meshpacket_offset; static jfieldID f_meshpacket_length; static jfieldID f_meshpacket_sid; static jfieldID f_meshpacket_port; +static jfieldID f_meshpacket_flags; +static jfieldID f_meshpacket_qos; /* SubscriberId fields */ static jfieldID f_subscriberid_binary; @@ -71,6 +73,8 @@ Java_org_servalproject_servald_mdp_MeshSocket_init(JNIEnv * env, jclass cls) G_FIELD(env, cl_meshpacket, "sid", "Lorg/servalproject/servald/SubscriberId;"); f_meshpacket_port = G_FIELD(env, cl_meshpacket, "port", "I"); + f_meshpacket_flags = G_FIELD(env, cl_meshpacket, "flags", "I"); + f_meshpacket_qos = G_FIELD(env, cl_meshpacket, "qos", "I"); cl_subscriberid = GG_CLASS(env, "org/servalproject/servald/SubscriberId"); f_subscriberid_binary = G_FIELD(env, cl_subscriberid, "binary", "[B"); @@ -156,7 +160,7 @@ Java_org_servalproject_servald_mdp_MeshSocket__1send(JNIEnv * env, jobject this, jobject mdppack) { - jint fd, localport, offset, length, port; + jint fd, localport, offset, length, port, flags, qos; jobject sid_obj; jbyteArray jbuf, jsid, jlocalsid; jbyte *buf, *sid, *localsid = NULL; @@ -188,6 +192,12 @@ Java_org_servalproject_servald_mdp_MeshSocket__1send(JNIEnv * env, /* port = mdppack.port; */ port = (*env)->GetIntField(env, mdppack, f_meshpacket_port); + /* flags = mdppack.flags; */ + flags = (*env)->GetIntField(env, mdppack, f_meshpacket_flags); + + /* qos = mdppack.qos; */ + qos = (*env)->GetIntField(env, mdppack, f_meshpacket_qos); + /* sid_obj = mdppack.sid; */ if ((sid_obj = (*env)->GetObjectField(env, mdppack, f_meshpacket_sid)) == NULL) { @@ -246,7 +256,8 @@ Java_org_servalproject_servald_mdp_MeshSocket__1send(JNIEnv * env, /* Fill mdp structure. */ - mdp.packetTypeAndFlags = MDP_TX; + mdp.packetTypeAndFlags = MDP_TX | flags & MDP_FLAG_MASK; + mdp.out.queue = qos; mdp.out.src.port = localport; if (localsid != NULL) { memcpy(mdp.out.src.sid, localsid, SID_SIZE); From f93642c15c596334b32f864ffd866b4ffc3d860a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Thu, 21 Feb 2013 16:29:16 +0100 Subject: [PATCH 16/24] shutdown() socket instead of close() Makes any blocking recv exit --- mdp_client.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mdp_client.c b/mdp_client.c index b1501e39..acad9e69 100644 --- a/mdp_client.c +++ b/mdp_client.c @@ -207,7 +207,9 @@ int overlay_mdp_client_close(int mdp_sockfd) mdp.packetTypeAndFlags=MDP_GOODBYE; overlay_mdp_send(mdp_sockfd, &mdp, 0, 0); - int res = close(mdp_sockfd); + /* shutdown() makes any blocking recv exit, close() does not. */ + int res = shutdown(mdp_sockfd, SHUT_RDWR); + // int res = close(mdp_sockfd); /* Remove the socket file. */ mdp_sock_closed(mdp_sockfd); From 8d2ce4b9f3d80db8af1be05a2bb4face041f7ce6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Thu, 21 Feb 2013 16:30:13 +0100 Subject: [PATCH 17/24] Special return code for "socket closed" Blocking recv calls return a special return code (-2) for notifying the socket is closed (this information is useful for MDP socket users). This implementation is unsatisfactory: return code should instead be consistent with recvfrom(), that is always returning the length of received data (0 for socket closed). --- mdp_client.c | 4 ++++ mdp_jni.c | 15 +++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/mdp_client.c b/mdp_client.c index acad9e69..ae7f6473 100644 --- a/mdp_client.c +++ b/mdp_client.c @@ -251,6 +251,10 @@ int overlay_mdp_recv(int mdp_sockfd, overlay_mdp_frame *mdp, int port, int *ttl) /* Check if reply available */ ssize_t len = recvwithttl(mdp_sockfd,(unsigned char *)mdp, sizeof(overlay_mdp_frame),ttl,recvaddr,&recvaddrlen); + if (len == 0) { + /* Socket is closed. */ + return -2; /* would be better to always return len */ + } recvaddr_un=(struct sockaddr_un *)recvaddr; /* Null terminate received address so that the stat() call below can succeed */ diff --git a/mdp_jni.c b/mdp_jni.c index 7ef8bed2..1736dfe3 100644 --- a/mdp_jni.c +++ b/mdp_jni.c @@ -300,6 +300,8 @@ Java_org_servalproject_servald_mdp_MeshSocket__1receive(JNIEnv * env, jbyteArray jbuf, jsid; jbyte *sid; overlay_mdp_frame mdp; + int res; + char *msg; /* fd = this.fd; */ fd = (*env)->GetIntField(env, this, f_meshsocket_fd); @@ -311,10 +313,15 @@ Java_org_servalproject_servald_mdp_MeshSocket__1receive(JNIEnv * env, length = (*env)->GetIntField(env, mdppack, f_meshpacket_length); /* Receive data. */ - if (overlay_mdp_recv(fd, &mdp, localport, &ttl)) { - (*env)->ThrowNew(env, cl_meshsocketexception, - "Cannot receive data from servald"); - WHY("Cannot receive data from servald"); + if (res = (overlay_mdp_recv(fd, &mdp, localport, &ttl))) { + if (res == -2) { + /* Socket is closed. */ + msg = "Socket closed"; + } else { + msg = "Cannot receive data from servald"; + } + (*env)->ThrowNew(env, cl_meshsocketexception, msg); + WHY(msg); return; } From 9be2d1ab3fcb461511ed936f63af2f07856a9f4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Wed, 6 Mar 2013 15:25:32 +0100 Subject: [PATCH 18/24] mdp_client sid type changed --- mdp_client.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdp_client.h b/mdp_client.h index 21ff7e65..53ba0feb 100644 --- a/mdp_client.h +++ b/mdp_client.h @@ -36,7 +36,7 @@ struct overlay_mdp_scan{ int overlay_mdp_client_socket(void); int overlay_mdp_client_close(int mdp_sockfd); int overlay_mdp_client_poll(int mdp_sockfd, time_ms_t timeout_ms); -int overlay_mdp_bind(int mdp_sockfd, unsigned char *localaddr, int port); +int overlay_mdp_bind(int mdp_sockfd, const sid_t *localaddr, int port); int overlay_mdp_recv(int mdp_sockfd, overlay_mdp_frame *mdp, int port, int *ttl); int overlay_mdp_send(int mdp_sockfd, overlay_mdp_frame *mdp,int flags,int timeout_ms); int overlay_mdp_relevant_bytes(overlay_mdp_frame *mdp); From 8d1fea907d32d1cc29e7d4f4b59fd466abaca672 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Wed, 6 Mar 2013 15:28:05 +0100 Subject: [PATCH 19/24] Fail when cannot create MDP socket --- commandline.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/commandline.c b/commandline.c index fd25f349..6504f6b0 100644 --- a/commandline.c +++ b/commandline.c @@ -571,7 +571,7 @@ int app_dna_lookup(const struct cli_parsed *parsed, void *context) } if ((mdp_sockfd = overlay_mdp_client_socket()) < 0) - WHY("Cannot create MDP socket"); + return WHY("Cannot create MDP socket"); /* Bind to MDP socket and await confirmation */ sid_t srcsid; @@ -994,7 +994,7 @@ int app_mdp_ping(const struct cli_parsed *parsed, void *context) int icount=atoi(count); if ((mdp_sockfd = overlay_mdp_client_socket()) < 0) - WHY("Cannot create MDP socket"); + return WHY("Cannot create MDP socket"); overlay_mdp_frame mdp; bzero(&mdp, sizeof(overlay_mdp_frame)); @@ -1951,7 +1951,7 @@ int app_id_self(const struct cli_parsed *parsed, void *context) a.addrlist.first_sid=0; if ((mdp_sockfd = overlay_mdp_client_socket()) < 0) - WHY("Cannot create MDP socket"); + return WHY("Cannot create MDP socket"); do{ result=overlay_mdp_send(mdp_sockfd, &a, MDP_AWAITREPLY, 5000); @@ -1990,7 +1990,7 @@ int app_count_peers(const struct cli_parsed *parsed, void *context) if (config.debug.verbose) DEBUG_cli_parsed(parsed); if ((mdp_sockfd = overlay_mdp_client_socket()) < 0) - WHY("Cannot create MDP socket"); + return WHY("Cannot create MDP socket"); overlay_mdp_frame a; bzero(&a, sizeof(overlay_mdp_frame)); @@ -2182,7 +2182,7 @@ int app_node_info(const struct cli_parsed *parsed, void *context) cli_arg(parsed, "sid", &sid, NULL, ""); if ((mdp_sockfd = overlay_mdp_client_socket()) < 0) - WHY("Cannot create MDP socket"); + return WHY("Cannot create MDP socket"); overlay_mdp_frame mdp; bzero(&mdp,sizeof(mdp)); @@ -2230,7 +2230,7 @@ int app_route_print(const struct cli_parsed *parsed, void *context) if (config.debug.verbose) DEBUG_cli_parsed(parsed); if ((mdp_sockfd = overlay_mdp_client_socket()) < 0) - WHY("Cannot create MDP socket"); + return WHY("Cannot create MDP socket"); overlay_mdp_frame mdp; bzero(&mdp,sizeof(mdp)); @@ -2287,7 +2287,7 @@ int app_reverse_lookup(const struct cli_parsed *parsed, void *context) if (config.debug.verbose) DEBUG_cli_parsed(parsed); if ((mdp_sockfd = overlay_mdp_client_socket()) < 0) - WHY("Cannot create MDP socket"); + return WHY("Cannot create MDP socket"); const char *sidhex, *delay; if (cli_arg(parsed, "sid", &sidhex, str_is_subscriber_id, "") == -1) @@ -2396,7 +2396,7 @@ int app_network_scan(const struct cli_parsed *parsed, void *context) if (config.debug.verbose) DEBUG_cli_parsed(parsed); if ((mdp_sockfd = overlay_mdp_client_socket()) < 0) - WHY("Cannot create MDP socket"); + return WHY("Cannot create MDP socket"); overlay_mdp_frame mdp; bzero(&mdp,sizeof(mdp)); From be8b48e09d4a6e512b5272f930ccdca8b42de5ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Wed, 6 Mar 2013 15:45:25 +0100 Subject: [PATCH 20/24] Use MDP sockets in app_trace --- commandline.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/commandline.c b/commandline.c index 6504f6b0..aa657e81 100644 --- a/commandline.c +++ b/commandline.c @@ -1131,8 +1131,9 @@ int app_mdp_ping(const struct cli_parsed *parsed, void *context) return ret; } -int app_trace(const struct cli_parsed *parsed, void *context){ - +int app_trace(const struct cli_parsed *parsed, void *context) +{ + int mdp_sockfd; const char *sidhex; if (cli_arg(parsed, "SID", &sidhex, str_is_subscriber_id, NULL) == -1) return -1; @@ -1141,13 +1142,22 @@ int app_trace(const struct cli_parsed *parsed, void *context){ 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"); + 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"); + 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"); + } bcopy(srcsid.binary, mdp.out.src.sid, SID_SIZE); bcopy(srcsid.binary, mdp.out.dst.sid, SID_SIZE); @@ -1166,7 +1176,7 @@ int app_trace(const struct cli_parsed *parsed, void *context){ 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); + int ret=overlay_mdp_send(mdp_sockfd, &mdp, MDP_AWAITREPLY, 5000); ob_free(b); if (ret) DEBUGF("overlay_mdp_send returned %d", ret); @@ -1189,7 +1199,7 @@ int app_trace(const struct cli_parsed *parsed, void *context){ i++; } } - overlay_mdp_client_done(); + overlay_mdp_client_close(mdp_sockfd); return ret; } From a9a8b88772a5f3607b7adf281ff22e41e47237cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Wed, 6 Mar 2013 16:37:08 +0100 Subject: [PATCH 21/24] Open MDP sockets as late as possible Avoid to open/close it if something goes wrong early. --- commandline.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/commandline.c b/commandline.c index aa657e81..aff73347 100644 --- a/commandline.c +++ b/commandline.c @@ -988,6 +988,13 @@ int app_mdp_ping(const struct cli_parsed *parsed, void *context) return -1; if (cli_arg(parsed, "count", &count, NULL, "0") == -1) return -1; + + /* Get SID that we want to ping. + TODO - allow lookup of SID prefixes and telephone numbers + (that would require MDP lookup of phone numbers, which doesn't yet occur) */ + sid_t ping_sid; + if (str_to_sid_t(&ping_sid, sidhex) == -1) + return WHY("str_to_sid_t() failed"); // assume we wont hear any responses int ret=-1; @@ -1014,12 +1021,6 @@ int app_mdp_ping(const struct cli_parsed *parsed, void *context) unsigned int firstSeq=random(); unsigned int sequence_number=firstSeq; - /* Get SID that we want to ping. - TODO - allow lookup of SID prefixes and telephone numbers - (that would require MDP lookup of phone numbers, which doesn't yet occur) */ - sid_t ping_sid; - if (str_to_sid_t(&ping_sid, sidhex) == -1) - return WHY("str_to_sid_t() failed"); int broadcast = is_sid_broadcast(ping_sid.binary); /* TODO Eventually we should try to resolve SID to phone number and vice versa */ @@ -2296,15 +2297,15 @@ int app_reverse_lookup(const struct cli_parsed *parsed, void *context) int mdp_sockfd; if (config.debug.verbose) DEBUG_cli_parsed(parsed); - if ((mdp_sockfd = overlay_mdp_client_socket()) < 0) - return WHY("Cannot create MDP socket"); - 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; + if ((mdp_sockfd = overlay_mdp_client_socket()) < 0) + return WHY("Cannot create MDP socket"); + int port=32768+(random()&0xffff); sid_t srcsid; @@ -2405,9 +2406,6 @@ int app_network_scan(const struct cli_parsed *parsed, void *context) int mdp_sockfd; if (config.debug.verbose) DEBUG_cli_parsed(parsed); - if ((mdp_sockfd = overlay_mdp_client_socket()) < 0) - return WHY("Cannot create MDP socket"); - overlay_mdp_frame mdp; bzero(&mdp,sizeof(mdp)); @@ -2425,9 +2423,13 @@ int app_network_scan(const struct cli_parsed *parsed, void *context) }else DEBUGF("Scanning local networks"); + if ((mdp_sockfd = overlay_mdp_client_socket()) < 0) + return WHY("Cannot create MDP socket"); overlay_mdp_send(mdp_sockfd, &mdp, MDP_AWAITREPLY, 5000); - if (mdp.packetTypeAndFlags!=MDP_ERROR) + if (mdp.packetTypeAndFlags!=MDP_ERROR) { + overlay_mdp_client_close(mdp_sockfd); return -1; + } cli_puts(mdp.error.message); cli_delim("\n"); From 68482794d0a7c9b1be34a028a9df9bd16c091ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Wed, 6 Mar 2013 16:47:06 +0100 Subject: [PATCH 22/24] Use SID_ANY and sid_t instead of char* --- mdp_jni.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mdp_jni.c b/mdp_jni.c index 1736dfe3..ef07a207 100644 --- a/mdp_jni.c +++ b/mdp_jni.c @@ -111,7 +111,6 @@ Java_org_servalproject_servald_mdp_MeshSocket__1bind(JNIEnv * env, jint fd; jbyteArray jsid = NULL; jbyte *sid = NULL; - char any[SID_SIZE]; /* Retrieve values from java objects. */ @@ -135,8 +134,7 @@ Java_org_servalproject_servald_mdp_MeshSocket__1bind(JNIEnv * env, } } else { /* If sid_obj is NULL, then use sid = 0. */ - memset(any, 0, SID_SIZE); - sid = (jbyte *) any; + sid = (jbyte *) SID_ANY.binary; } /* fd = this.fd; */ @@ -144,7 +142,7 @@ Java_org_servalproject_servald_mdp_MeshSocket__1bind(JNIEnv * env, /* Bind. */ - if (overlay_mdp_bind(fd, (unsigned char *) sid, port)) { + if (overlay_mdp_bind(fd, (const sid_t *) sid, port)) { THROW_MESH_SOCKET_EXCEPTION("Cannot bind to MDP socket"); /* fall through finally */ } From 69e7f7a3debbcda047fdc43e497ff0e9add7b4cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Thu, 7 Mar 2013 11:42:30 +0100 Subject: [PATCH 23/24] Use MDP sockets in tests/directory_service.c --- directory_service.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/directory_service.c b/directory_service.c index 0670618b..a6d5418c 100644 --- a/directory_service.c +++ b/directory_service.c @@ -69,11 +69,11 @@ static void add_item(char *key, char *value){ fprintf(stderr, "PUBLISHED \"%s\" = \"%s\"\n", key, value); } -static void add_record(){ +static void add_record(int mdp_sockfd){ int ttl; overlay_mdp_frame mdp; - if (overlay_mdp_recv(&mdp, MDP_PORT_DIRECTORY, &ttl)) + if (overlay_mdp_recv(mdp_sockfd, &mdp, MDP_PORT_DIRECTORY, &ttl)) return; if (mdp.packetTypeAndFlags&MDP_NOCRYPT){ @@ -160,17 +160,25 @@ static void resolve_request(){ int main(int argc, char **argv){ struct pollfd fds[2]; + int mdp_sockfd; + + if ((mdp_sockfd = overlay_mdp_client_socket()) < 0) + return WHY("Cannot create MDP socket"); // bind for incoming directory updates sid_t srcsid; - if (overlay_mdp_getmyaddr(0, &srcsid)) + 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(&srcsid, MDP_PORT_DIRECTORY)) + } + if (overlay_mdp_bind(mdp_sockfd, &srcsid, MDP_PORT_DIRECTORY)) { + overlay_mdp_client_close(mdp_sockfd); return WHY("Could not bind to MDP socket"); + } fds[0].fd = STDIN_FILENO; fds[0].events = POLLIN; - fds[1].fd = mdp_client_socket; + fds[1].fd = mdp_sockfd; fds[1].events = POLLIN; printf("STARTED\n"); @@ -180,15 +188,15 @@ int main(int argc, char **argv){ int r = poll(fds, 2, 100); if (r>0){ if (fds[0].revents & POLLIN) - resolve_request(); + resolve_request(); if (fds[1].revents & POLLIN) - add_record(); + add_record(mdp_sockfd); if (fds[0].revents & (POLLHUP | POLLERR)) break; } } - overlay_mdp_client_done(); + overlay_mdp_client_close(mdp_sockfd); return 0; } From 30b875763d3c3531a45a4a526dc3808b68b265ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Sat, 20 Jul 2013 23:23:48 +0200 Subject: [PATCH 24/24] Fix compiler warnings --- mdp_client.c | 2 +- mdp_jni.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mdp_client.c b/mdp_client.c index 2be9f90c..614954dd 100644 --- a/mdp_client.c +++ b/mdp_client.c @@ -176,7 +176,7 @@ int overlay_mdp_client_socket(void) overlay_mdp_client_socket_path_len=strlen(overlay_mdp_client_socket_path)+1; if(config.debug.io) DEBUGF("MDP client socket name='%s'",overlay_mdp_client_socket_path); if (overlay_mdp_client_socket_path_len > sizeof(name.sun_path) - 1) - FATALF("MDP socket path too long (%d > %d)", overlay_mdp_client_socket_path_len, sizeof(name.sun_path) - 1); + FATALF("MDP socket path too long (%d > %zu)", overlay_mdp_client_socket_path_len, sizeof(name.sun_path) - 1); bcopy(overlay_mdp_client_socket_path,name.sun_path, overlay_mdp_client_socket_path_len); diff --git a/mdp_jni.c b/mdp_jni.c index ef07a207..be72fd79 100644 --- a/mdp_jni.c +++ b/mdp_jni.c @@ -254,7 +254,7 @@ Java_org_servalproject_servald_mdp_MeshSocket__1send(JNIEnv * env, /* Fill mdp structure. */ - mdp.packetTypeAndFlags = MDP_TX | flags & MDP_FLAG_MASK; + mdp.packetTypeAndFlags = MDP_TX | (flags & MDP_FLAG_MASK); mdp.out.queue = qos; mdp.out.src.port = localport; if (localsid != NULL) { @@ -311,7 +311,7 @@ Java_org_servalproject_servald_mdp_MeshSocket__1receive(JNIEnv * env, length = (*env)->GetIntField(env, mdppack, f_meshpacket_length); /* Receive data. */ - if (res = (overlay_mdp_recv(fd, &mdp, localport, &ttl))) { + if ((res = (overlay_mdp_recv(fd, &mdp, localport, &ttl)))) { if (res == -2) { /* Socket is closed. */ msg = "Socket closed";