mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-02-21 09:51:50 +00:00
Issue #20: merge branch 'sockets' into 'development'
Daniel's improvements to the local file/abstract socket code, with many improvements to bring it up to date.
This commit is contained in:
commit
2b3119b49b
@ -16,7 +16,7 @@ SERVALD_LOCAL_CFLAGS = \
|
|||||||
-DHAVE_STRING_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_SOCKET_H=1 \
|
-DHAVE_STRING_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_SOCKET_H=1 \
|
||||||
-DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_POLL_H=1 -DHAVE_NETDB_H=1 \
|
-DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_POLL_H=1 -DHAVE_NETDB_H=1 \
|
||||||
-DHAVE_JNI_H=1 -DHAVE_STRUCT_UCRED=1 -DHAVE_CRYPTO_SIGN_NACL_GE25519_H=1 \
|
-DHAVE_JNI_H=1 -DHAVE_STRUCT_UCRED=1 -DHAVE_CRYPTO_SIGN_NACL_GE25519_H=1 \
|
||||||
-DBYTE_ORDER=_BYTE_ORDER -DHAVE_LINUX_STRUCT_UCRED \
|
-DBYTE_ORDER=_BYTE_ORDER -DHAVE_LINUX_STRUCT_UCRED -DUSE_ABSTRACT_NAMESPACE \
|
||||||
-DHAVE_BCOPY -DHAVE_BZERO \
|
-DHAVE_BCOPY -DHAVE_BZERO \
|
||||||
-I$(NACL_INC) \
|
-I$(NACL_INC) \
|
||||||
-I$(SQLITE3_INC)
|
-I$(SQLITE3_INC)
|
||||||
|
@ -107,6 +107,14 @@ AC_CHECK_HEADER([alsa/asoundlib.h], [have_alsa=1], [have_alsa=0])
|
|||||||
AS_IF([test x"$have_alsa" = "x1"], [AC_DEFINE([HAVE_ALSA_ASOUNDLIB_H])])
|
AS_IF([test x"$have_alsa" = "x1"], [AC_DEFINE([HAVE_ALSA_ASOUNDLIB_H])])
|
||||||
AS_IF([test x"$have_alsa" = "x1"], [AC_SUBST(HAVE_ALSA,1)], [AC_SUBST(HAVE_ALSA,0)])
|
AS_IF([test x"$have_alsa" = "x1"], [AC_SUBST(HAVE_ALSA,1)], [AC_SUBST(HAVE_ALSA,0)])
|
||||||
|
|
||||||
|
dnl Lazy way of checking for Linux
|
||||||
|
AC_CHECK_HEADER([sys/socket.h])
|
||||||
|
AC_CHECK_HEADER([linux/if.h], [AC_DEFINE([USE_ABSTRACT_NAMESPACE])],, [
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
])
|
||||||
|
|
||||||
AC_CHECK_LIB(m,sqrtf,[LDFLAGS="$LDFLAGS -lm"])
|
AC_CHECK_LIB(m,sqrtf,[LDFLAGS="$LDFLAGS -lm"])
|
||||||
AC_CHECK_LIB(nsl,callrpc,[LDFLAGS="$LDFLAGS -lnsl"])
|
AC_CHECK_LIB(nsl,callrpc,[LDFLAGS="$LDFLAGS -lnsl"])
|
||||||
AC_CHECK_LIB(socket,socket,[LDFLAGS="$LDFLAGS -lsocket"])
|
AC_CHECK_LIB(socket,socket,[LDFLAGS="$LDFLAGS -lsocket"])
|
||||||
|
@ -49,10 +49,10 @@ int form_serval_instance_path(char *buf, size_t bufsiz, const char *path)
|
|||||||
strbuf_path_join(b, serval_instancepath(), path, NULL);
|
strbuf_path_join(b, serval_instancepath(), path, NULL);
|
||||||
if (!strbuf_overrun(b))
|
if (!strbuf_overrun(b))
|
||||||
return 1;
|
return 1;
|
||||||
WHYF("Cannot form pathname from %s and %s -- buffer too small (%lu bytes)",
|
WHYF("instance path overflow (strlen %lu, sizeof buffer %lu): %s",
|
||||||
alloca_str_toprint(serval_instancepath()),
|
(unsigned long)strbuf_count(b),
|
||||||
alloca_str_toprint(path),
|
(unsigned long)bufsiz,
|
||||||
(unsigned long)bufsiz);
|
alloca_str_toprint(buf));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
|
#include "strbuf_helpers.h"
|
||||||
|
|
||||||
#include "monitor-client.h"
|
#include "monitor-client.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -65,54 +66,21 @@ struct monitor_state {
|
|||||||
int bufferBytes;
|
int bufferBytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
int monitor_socket_name(struct sockaddr_un *name){
|
|
||||||
int len;
|
|
||||||
#ifdef linux
|
|
||||||
/* Use abstract namespace as Android has no writable FS which supports sockets.
|
|
||||||
Abstract namespace is just plain better, anyway, as no dead files end up
|
|
||||||
hanging around. */
|
|
||||||
name->sun_path[0] = '\0';
|
|
||||||
/* XXX: 104 comes from OSX sys/un.h - no #define (note Linux has UNIX_PATH_MAX and it's 108(!)) */
|
|
||||||
snprintf(&name->sun_path[1],104-2,"%s", config.monitor.socket);
|
|
||||||
/* Doesn't include trailing nul */
|
|
||||||
len = 1+strlen(&name->sun_path[1]) + sizeof(name->sun_family);
|
|
||||||
#else
|
|
||||||
snprintf(name->sun_path,104-1,"%s/%s",
|
|
||||||
serval_instancepath(),
|
|
||||||
config.monitor.socket
|
|
||||||
);
|
|
||||||
/* Includes trailing nul */
|
|
||||||
len = 1+strlen(name->sun_path) + sizeof(name->sun_family);
|
|
||||||
#endif
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open monitor interface abstract domain named socket */
|
/* Open monitor interface abstract domain named socket */
|
||||||
int monitor_client_open(struct monitor_state **res)
|
int monitor_client_open(struct monitor_state **res)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
||||||
|
return WHYF_perror("socket(AF_UNIX, SOCK_STREAM, 0)");
|
||||||
struct sockaddr_un addr;
|
struct sockaddr_un addr;
|
||||||
|
socklen_t addrlen;
|
||||||
if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
|
if (socket_setname(&addr, config.monitor.socket, &addrlen) == -1)
|
||||||
WHYF_perror("socket(AF_UNIX, SOCK_STREAM, 0)");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
INFOF("Attempting to connect to %s", alloca_sockaddr(&addr, addrlen));
|
||||||
|
if (socket_connect(fd, (struct sockaddr*)&addr, addrlen) == -1) {
|
||||||
memset(&addr, 0, sizeof(addr));
|
|
||||||
addr.sun_family = AF_UNIX;
|
|
||||||
int len = monitor_socket_name(&addr);
|
|
||||||
|
|
||||||
INFOF("Attempting to connect to %s %s",
|
|
||||||
addr.sun_path[0] ? "local" : "abstract",
|
|
||||||
alloca_str_toprint(addr.sun_path[0] ? &addr.sun_path[0] : &addr.sun_path[1])
|
|
||||||
);
|
|
||||||
|
|
||||||
if (connect(fd, (struct sockaddr*)&addr, len) == -1) {
|
|
||||||
WHYF_perror("connect(%d, %s)", fd, alloca_toprint(-1, &addr, len));
|
|
||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*res = (struct monitor_state*)malloc(sizeof(struct monitor_state));
|
*res = (struct monitor_state*)malloc(sizeof(struct monitor_state));
|
||||||
memset(*res,0,sizeof(struct monitor_state));
|
memset(*res,0,sizeof(struct monitor_state));
|
||||||
return fd;
|
return fd;
|
||||||
|
48
monitor.c
48
monitor.c
@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#include "rhizome.h"
|
#include "rhizome.h"
|
||||||
#include "cli.h"
|
#include "cli.h"
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
|
#include "strbuf_helpers.h"
|
||||||
#include "overlay_address.h"
|
#include "overlay_address.h"
|
||||||
#include "monitor-client.h"
|
#include "monitor-client.h"
|
||||||
|
|
||||||
@ -76,45 +77,24 @@ struct profile_total client_stats;
|
|||||||
|
|
||||||
int monitor_setup_sockets()
|
int monitor_setup_sockets()
|
||||||
{
|
{
|
||||||
struct sockaddr_un name;
|
int sock = -1;
|
||||||
int len;
|
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
|
||||||
int sock;
|
|
||||||
|
|
||||||
bzero(&name, sizeof(name));
|
|
||||||
name.sun_family = AF_UNIX;
|
|
||||||
|
|
||||||
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0))==-1) {
|
|
||||||
WHYF_perror("socket(AF_UNIX, SOCK_STREAM, 0)");
|
WHYF_perror("socket(AF_UNIX, SOCK_STREAM, 0)");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
struct sockaddr_un addr;
|
||||||
len = monitor_socket_name(&name);
|
socklen_t addrlen;
|
||||||
#ifndef linux
|
if (socket_setname(&addr, config.monitor.socket, &addrlen) == -1)
|
||||||
unlink(name.sun_path);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(bind(sock, (struct sockaddr *)&name, len)==-1) {
|
|
||||||
WHYF_perror("bind(%d, %s)", sock, alloca_toprint(-1, &name, len));
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
if (socket_bind(sock, (struct sockaddr*)&addr, addrlen) == -1)
|
||||||
if(listen(sock,MAX_MONITOR_SOCKETS)==-1) {
|
|
||||||
WHYF_perror("listen(%d, %d)", sock, MAX_MONITOR_SOCKETS);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
if (socket_listen(sock, MAX_MONITOR_SOCKETS) == -1)
|
||||||
|
goto error;
|
||||||
int reuseP=1;
|
if (socket_set_reuseaddr(sock, 1) == -1)
|
||||||
if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseP, sizeof reuseP) < 0) {
|
|
||||||
WHYF_perror("setsockopt(%d, SOL_SOCKET, SO_REUSEADDR, &%d, %d)", sock, reuseP, (int)sizeof reuseP);
|
|
||||||
WHY("Could not indicate reuse addresses. Not necessarily a problem (yet)");
|
WHY("Could not indicate reuse addresses. Not necessarily a problem (yet)");
|
||||||
}
|
socket_set_rcvbufsize(sock, 64 * 1024);
|
||||||
|
|
||||||
int send_buffer_size=64*1024;
|
|
||||||
if(setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &send_buffer_size, sizeof send_buffer_size)==-1)
|
|
||||||
WHYF_perror("setsockopt(%d, SOL_SOCKET, SO_RCVBUF, &%d, %d)", sock, send_buffer_size, (int)sizeof send_buffer_size);
|
|
||||||
|
|
||||||
if (config.debug.io || config.debug.verbose_io)
|
if (config.debug.io || config.debug.verbose_io)
|
||||||
DEBUGF("Monitor server socket bound to %s", alloca_toprint(-1, &name, len));
|
DEBUGF("Monitor server socket bound to %s", alloca_sockaddr(&addr, addrlen));
|
||||||
|
|
||||||
named_socket.function=monitor_poll;
|
named_socket.function=monitor_poll;
|
||||||
named_stats.name="monitor_poll";
|
named_stats.name="monitor_poll";
|
||||||
named_socket.stats=&named_stats;
|
named_socket.stats=&named_stats;
|
||||||
@ -123,8 +103,8 @@ int monitor_setup_sockets()
|
|||||||
watch(&named_socket);
|
watch(&named_socket);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (sock>=0)
|
if (sock != -1)
|
||||||
close(sock);
|
close(sock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
124
overlay_mdp.c
124
overlay_mdp.c
@ -29,17 +29,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#include "mdp_client.h"
|
#include "mdp_client.h"
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
|
|
||||||
struct profile_total mdp_stats={.name="overlay_mdp_poll"};
|
static struct profile_total mdp_stats = { .name="overlay_mdp_poll" };
|
||||||
|
static struct sched_ent mdp_sock = STRUCT_SCHED_ENT_UNUSED;
|
||||||
struct sched_ent mdp_abstract={
|
|
||||||
.function = overlay_mdp_poll,
|
|
||||||
.stats = &mdp_stats,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sched_ent mdp_named={
|
|
||||||
.function = overlay_mdp_poll,
|
|
||||||
.stats = &mdp_stats,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int overlay_saw_mdp_frame(struct overlay_frame *frame, overlay_mdp_frame *mdp, time_ms_t now);
|
static int overlay_saw_mdp_frame(struct overlay_frame *frame, overlay_mdp_frame *mdp, time_ms_t now);
|
||||||
|
|
||||||
@ -79,83 +70,36 @@ static void overlay_mdp_clean_socket_files()
|
|||||||
|
|
||||||
int overlay_mdp_setup_sockets()
|
int overlay_mdp_setup_sockets()
|
||||||
{
|
{
|
||||||
struct sockaddr_un name;
|
struct sockaddr_un addr;
|
||||||
int len;
|
socklen_t addrlen;
|
||||||
|
|
||||||
/* Clean old socket files from instance directory. */
|
/* Delete stale socket files from instance directory. */
|
||||||
overlay_mdp_clean_socket_files();
|
overlay_mdp_clean_socket_files();
|
||||||
|
|
||||||
name.sun_family = AF_UNIX;
|
|
||||||
|
|
||||||
#ifndef HAVE_LINUX_IF_H
|
|
||||||
/* Abstrack name space (i.e., non-file represented) unix domain sockets are a
|
|
||||||
linux-only thing. */
|
|
||||||
mdp_abstract.poll.fd = -1;
|
|
||||||
#else
|
|
||||||
if (mdp_abstract.poll.fd<=0) {
|
|
||||||
/* Abstract name space unix sockets is a special Linux thing, which is
|
|
||||||
convenient for us because Android is Linux, but does not have a shared
|
|
||||||
writable path that is on a UFS partition, so we cannot use traditional
|
|
||||||
named unix domain sockets. So the abstract name space gives us a solution. */
|
|
||||||
name.sun_path[0]=0;
|
|
||||||
/* XXX The 100 should be replaced with the actual maximum allowed.
|
|
||||||
Apparently POSIX requires it to be at least 100, but I would still feel
|
|
||||||
more comfortable with using the appropriate constant. */
|
|
||||||
if (!form_serval_instance_path(&name.sun_path[0], sizeof name.sun_path, "mdp.socket"))
|
|
||||||
return WHY("Cannot construct name of unix domain socket.");
|
|
||||||
len = 1+strlen(&name.sun_path[1]) + sizeof(name.sun_family);
|
|
||||||
|
|
||||||
mdp_abstract.poll.fd = socket(AF_UNIX, SOCK_DGRAM, 0);
|
|
||||||
if (mdp_abstract.poll.fd>-1) {
|
|
||||||
int reuseP=1;
|
|
||||||
if (setsockopt( mdp_abstract.poll.fd, SOL_SOCKET, SO_REUSEADDR, &reuseP, sizeof(reuseP)) == -1) {
|
|
||||||
WARN_perror("setsockopt(SO_REUSEADDR)");
|
|
||||||
WARN("Could not set socket reuse addresses");
|
|
||||||
}
|
|
||||||
if (bind(mdp_abstract.poll.fd, (struct sockaddr *)&name, len) == -1) {
|
|
||||||
WARN_perror("bind");
|
|
||||||
close(mdp_abstract.poll.fd);
|
|
||||||
mdp_abstract.poll.fd = -1;
|
|
||||||
WARN("bind of abstract name space socket failed (not a problem on non-linux systems)");
|
|
||||||
}
|
|
||||||
int send_buffer_size=64*1024;
|
|
||||||
if (setsockopt(mdp_abstract.poll.fd, SOL_SOCKET, SO_SNDBUF, &send_buffer_size, sizeof(send_buffer_size)) == -1)
|
|
||||||
WARN_perror("setsockopt(SO_SNDBUF)");
|
|
||||||
mdp_abstract.poll.events = POLLIN;
|
|
||||||
watch(&mdp_abstract);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (mdp_named.poll.fd<=0) {
|
|
||||||
if (!form_serval_instance_path(&name.sun_path[0], sizeof name.sun_path, "mdp.socket"))
|
|
||||||
return WHY("Cannot construct name of unix domain socket.");
|
|
||||||
unlink(&name.sun_path[0]);
|
|
||||||
len = 0+strlen(&name.sun_path[0]) + sizeof(name.sun_family)+1;
|
|
||||||
mdp_named.poll.fd = socket(AF_UNIX, SOCK_DGRAM, 0);
|
|
||||||
if (mdp_named.poll.fd>-1) {
|
|
||||||
int reuseP=1;
|
|
||||||
if(setsockopt( mdp_named.poll.fd, SOL_SOCKET, SO_REUSEADDR, &reuseP, sizeof(reuseP)) == -1) {
|
|
||||||
WARN_perror("setsockopt(SO_REUSEADDR)");
|
|
||||||
WARN("Could not set socket reuse addresses");
|
|
||||||
}
|
|
||||||
if (bind(mdp_named.poll.fd, (struct sockaddr *)&name, len) == -1) {
|
|
||||||
WARN_perror("bind");
|
|
||||||
close(mdp_named.poll.fd);
|
|
||||||
mdp_named.poll.fd = -1;
|
|
||||||
WARN("Could not bind named unix domain socket");
|
|
||||||
}
|
|
||||||
int send_buffer_size=64*1024;
|
|
||||||
if (setsockopt(mdp_named.poll.fd, SOL_SOCKET, SO_RCVBUF, &send_buffer_size, sizeof(send_buffer_size)) == -1)
|
|
||||||
WARN_perror("setsockopt(SO_RCVBUF)");
|
|
||||||
mdp_named.function = overlay_mdp_poll;
|
|
||||||
mdp_named.stats = &mdp_stats;
|
|
||||||
mdp_named.poll.events = POLLIN;
|
|
||||||
watch(&mdp_named);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (mdp_sock.poll.fd == -1) {
|
||||||
|
if (socket_setname(&addr, "mdp.socket", &addrlen) == -1)
|
||||||
|
return -1;
|
||||||
|
if ((mdp_sock.poll.fd = esocket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
|
||||||
|
return -1;
|
||||||
|
if (socket_set_reuseaddr(mdp_sock.poll.fd, 1) == -1)
|
||||||
|
WARN("Could not set socket to reuse addresses");
|
||||||
|
if (socket_bind(mdp_sock.poll.fd, (struct sockaddr *)&addr, addrlen) == -1) {
|
||||||
|
close(mdp_sock.poll.fd);
|
||||||
|
mdp_sock.poll.fd = -1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
socket_set_rcvbufsize(mdp_sock.poll.fd, 64 * 1024);
|
||||||
|
/*
|
||||||
|
int buffer_size = 64 * 1024;
|
||||||
|
if (setsockopt(mdp_sock.poll.fd, SOL_SOCKET, SO_SNDBUF, &buffer_size, sizeof(buffer_size)) == -1)
|
||||||
|
WARNF_perror("setsockopt(%d,SOL_SOCKET,SO_SNDBUF,&%d,%d)", mdp_sock.poll.fd, buffer_size, sizeof buffer_size);
|
||||||
|
*/
|
||||||
|
mdp_sock.function = overlay_mdp_poll;
|
||||||
|
mdp_sock.stats = &mdp_stats;
|
||||||
|
mdp_sock.poll.events = POLLIN;
|
||||||
|
watch(&mdp_sock);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MDP_MAX_BINDINGS 100
|
#define MDP_MAX_BINDINGS 100
|
||||||
@ -497,7 +441,7 @@ static int overlay_saw_mdp_frame(struct overlay_frame *frame, overlay_mdp_frame
|
|||||||
addr.sun_family=AF_UNIX;
|
addr.sun_family=AF_UNIX;
|
||||||
errno=0;
|
errno=0;
|
||||||
int len=overlay_mdp_relevant_bytes(mdp);
|
int len=overlay_mdp_relevant_bytes(mdp);
|
||||||
int r=sendto(mdp_named.poll.fd,mdp,len,0,(struct sockaddr*)&addr,sizeof(addr));
|
int r=sendto(mdp_sock.poll.fd,mdp,len,0,(struct sockaddr*)&addr,sizeof(addr));
|
||||||
if (r==overlay_mdp_relevant_bytes(mdp)) {
|
if (r==overlay_mdp_relevant_bytes(mdp)) {
|
||||||
RETURN(0);
|
RETURN(0);
|
||||||
}
|
}
|
||||||
@ -754,7 +698,7 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
|
|||||||
if (overlay_mdp_check_binding(source, mdp->out.src.port, userGeneratedFrameP,
|
if (overlay_mdp_check_binding(source, mdp->out.src.port, userGeneratedFrameP,
|
||||||
recvaddr, recvaddrlen)){
|
recvaddr, recvaddrlen)){
|
||||||
RETURN(overlay_mdp_reply_error
|
RETURN(overlay_mdp_reply_error
|
||||||
(mdp_named.poll.fd,
|
(mdp_sock.poll.fd,
|
||||||
(struct sockaddr_un *)recvaddr,
|
(struct sockaddr_un *)recvaddr,
|
||||||
recvaddrlen,8,
|
recvaddrlen,8,
|
||||||
"Source address is invalid (you must bind to a source address before"
|
"Source address is invalid (you must bind to a source address before"
|
||||||
@ -767,7 +711,7 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
|
|||||||
flag is not set. Also, MDP_NOSIGN must also be applied, until
|
flag is not set. Also, MDP_NOSIGN must also be applied, until
|
||||||
NaCl cryptobox keys can be used for signing. */
|
NaCl cryptobox keys can be used for signing. */
|
||||||
if (!(mdp->packetTypeAndFlags&MDP_NOCRYPT))
|
if (!(mdp->packetTypeAndFlags&MDP_NOCRYPT))
|
||||||
RETURN(overlay_mdp_reply_error(mdp_named.poll.fd,
|
RETURN(overlay_mdp_reply_error(mdp_sock.poll.fd,
|
||||||
recvaddr,recvaddrlen,5,
|
recvaddr,recvaddrlen,5,
|
||||||
"Broadcast packets cannot be encrypted "));
|
"Broadcast packets cannot be encrypted "));
|
||||||
}else{
|
}else{
|
||||||
@ -778,9 +722,7 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
|
|||||||
if (mdp->out.ttl == 0)
|
if (mdp->out.ttl == 0)
|
||||||
mdp->out.ttl = PAYLOAD_TTL_DEFAULT;
|
mdp->out.ttl = PAYLOAD_TTL_DEFAULT;
|
||||||
else if (mdp->out.ttl > PAYLOAD_TTL_MAX) {
|
else if (mdp->out.ttl > PAYLOAD_TTL_MAX) {
|
||||||
RETURN(overlay_mdp_reply_error(mdp_named.poll.fd,
|
RETURN(overlay_mdp_reply_error(mdp_sock.poll.fd, recvaddr,recvaddrlen,9, "TTL out of range"));
|
||||||
recvaddr,recvaddrlen,9,
|
|
||||||
"TTL out of range"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mdp->out.queue == 0)
|
if (mdp->out.queue == 0)
|
||||||
@ -929,7 +871,7 @@ static int routing_table(struct subscriber *subscriber, void *context){
|
|||||||
strcpy(r->interface_name, subscriber->destination->interface->name);
|
strcpy(r->interface_name, subscriber->destination->interface->name);
|
||||||
else
|
else
|
||||||
r->interface_name[0]=0;
|
r->interface_name[0]=0;
|
||||||
overlay_mdp_reply(mdp_named.poll.fd, state->recvaddr_un, state->recvaddrlen, &reply);
|
overlay_mdp_reply(mdp_sock.poll.fd, state->recvaddr_un, state->recvaddrlen, &reply);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +189,8 @@ int rhizome_fetch_status_html(struct strbuf *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct sched_ent sched_activate = STRUCT_SCHED_ENT_UNUSED;
|
static struct sched_ent sched_activate = STRUCT_SCHED_ENT_UNUSED;
|
||||||
static struct profile_total fetch_stats;
|
static struct profile_total rsnqf_stats = { .name="rhizome_start_next_queued_fetches" };
|
||||||
|
static struct profile_total fetch_stats = { .name="rhizome_fetch_poll" };
|
||||||
|
|
||||||
/* Find a queue suitable for a fetch of the given number of bytes. If there is no suitable queue,
|
/* Find a queue suitable for a fetch of the given number of bytes. If there is no suitable queue,
|
||||||
* return NULL.
|
* return NULL.
|
||||||
@ -505,15 +506,12 @@ static int schedule_fetch(struct rhizome_fetch_slot *slot)
|
|||||||
|
|
||||||
slot->state = RHIZOME_FETCH_CONNECTING;
|
slot->state = RHIZOME_FETCH_CONNECTING;
|
||||||
slot->alarm.function = rhizome_fetch_poll;
|
slot->alarm.function = rhizome_fetch_poll;
|
||||||
fetch_stats.name = "rhizome_fetch_poll";
|
|
||||||
slot->alarm.stats = &fetch_stats;
|
slot->alarm.stats = &fetch_stats;
|
||||||
|
|
||||||
if (slot->peer_ipandport.sin_family == AF_INET && slot->peer_ipandport.sin_port) {
|
if (slot->peer_ipandport.sin_family == AF_INET && slot->peer_ipandport.sin_port) {
|
||||||
/* Transfer via HTTP over IPv4 */
|
/* Transfer via HTTP over IPv4 */
|
||||||
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
|
if ((sock = esocket(AF_INET, SOCK_STREAM, 0)) == -1)
|
||||||
WHY_perror("socket");
|
|
||||||
goto bail_http;
|
goto bail_http;
|
||||||
}
|
|
||||||
if (set_nonblock(sock) == -1)
|
if (set_nonblock(sock) == -1)
|
||||||
goto bail_http;
|
goto bail_http;
|
||||||
char buf[INET_ADDRSTRLEN];
|
char buf[INET_ADDRSTRLEN];
|
||||||
@ -628,7 +626,7 @@ rhizome_fetch(struct rhizome_fetch_slot *slot, rhizome_manifest *m, const struct
|
|||||||
bid,
|
bid,
|
||||||
m->version,
|
m->version,
|
||||||
m->fileLength,
|
m->fileLength,
|
||||||
alloca_sockaddr(peerip)
|
alloca_sockaddr(peerip, sizeof(struct sockaddr_in))
|
||||||
);
|
);
|
||||||
|
|
||||||
// If the payload is empty, no need to fetch, so import now.
|
// If the payload is empty, no need to fetch, so import now.
|
||||||
@ -823,8 +821,6 @@ int rhizome_fetch_has_queue_space(unsigned char log2_size){
|
|||||||
*
|
*
|
||||||
* @author Andrew Bettison <andrew@servalproject.com>
|
* @author Andrew Bettison <andrew@servalproject.com>
|
||||||
*/
|
*/
|
||||||
struct profile_total rsnqf_stats={.name="rhizome_start_next_queued_fetches"};
|
|
||||||
|
|
||||||
int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct sockaddr_in *peerip,const unsigned char peersid[SID_SIZE])
|
int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct sockaddr_in *peerip,const unsigned char peersid[SID_SIZE])
|
||||||
{
|
{
|
||||||
IN();
|
IN();
|
||||||
|
14
serval.h
14
serval.h
@ -168,6 +168,17 @@ int create_serval_instance_dir();
|
|||||||
int form_serval_instance_path(char *buf, size_t bufsiz, const char *path);
|
int form_serval_instance_path(char *buf, size_t bufsiz, const char *path);
|
||||||
void serval_setinstancepath(const char *instancepath);
|
void serval_setinstancepath(const char *instancepath);
|
||||||
|
|
||||||
|
/* Create a named socket using abstract socket on Linux or a local socket on
|
||||||
|
* other platforms.
|
||||||
|
*/
|
||||||
|
int esocket(int domain, int type, int protocol);
|
||||||
|
int socket_setname(struct sockaddr_un *sockname, const char *name, socklen_t *addrlen);
|
||||||
|
int socket_bind(int sock, const struct sockaddr *addr, socklen_t addrlen);
|
||||||
|
int socket_connect(int sock, const struct sockaddr *addr, socklen_t addrlen);
|
||||||
|
int socket_listen(int sock, int backlog);
|
||||||
|
int socket_set_reuseaddr(int fd, int reuseP);
|
||||||
|
int socket_set_rcvbufsize(int fd, unsigned buffer_size);
|
||||||
|
|
||||||
#define SERVER_CONFIG_RELOAD_INTERVAL_MS 1000
|
#define SERVER_CONFIG_RELOAD_INTERVAL_MS 1000
|
||||||
|
|
||||||
struct cli_parsed;
|
struct cli_parsed;
|
||||||
@ -587,9 +598,6 @@ int overlay_mdp_get_fds(struct pollfd *fds,int *fdcount,int fdmax);
|
|||||||
int overlay_mdp_reply_error(int sock,
|
int overlay_mdp_reply_error(int sock,
|
||||||
struct sockaddr_un *recvaddr,int recvaddrlen,
|
struct sockaddr_un *recvaddr,int recvaddrlen,
|
||||||
int error_number,char *message);
|
int error_number,char *message);
|
||||||
extern struct sched_ent mdp_abstract;
|
|
||||||
extern struct sched_ent mdp_named;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct sockaddr_mdp {
|
typedef struct sockaddr_mdp {
|
||||||
unsigned char sid[SID_SIZE];
|
unsigned char sid[SID_SIZE];
|
||||||
|
163
socket.c
163
socket.c
@ -1,66 +1,115 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (C) 2012 Daniel O'Connor, Serval Project.
|
Serval DNA named sockets
|
||||||
|
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
|
This program is free software; you can redistribute it and/or
|
||||||
as published by the Free Software Foundation; either version 2
|
modify it under the terms of the GNU General Public License
|
||||||
of the License, or (at your option) any later version.
|
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
|
This program is distributed in the hope that it will be useful,
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
GNU General Public License for more details.
|
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
|
You should have received a copy of the GNU General Public License
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#include "serval.h"
|
||||||
#include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <strings.h>
|
|
||||||
#include <sys/errno.h>
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#endif
|
|
||||||
#include <sys/un.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "socket.h"
|
#include "strbuf_helpers.h"
|
||||||
|
|
||||||
/* Set the socket name in the abstract namespace for linux or
|
/* Under Linux, create a socket name in the abstract namespace. This permits us to use local
|
||||||
* $SERVALINSTANCE_PATH/name for everything else.
|
* sockets on Android despite its lack of a shared writeable directory on a UFS partition.
|
||||||
|
*
|
||||||
|
* On non-Linux systems, create a conventional named local socket in the $SERVALINSTANCE_PATH
|
||||||
|
* directory.
|
||||||
|
*
|
||||||
|
* @author Andrew Bettison <andrew@servalproject.com>
|
||||||
|
* @author Daniel O'Connor <daniel@servalproject.com>
|
||||||
*/
|
*/
|
||||||
void
|
int socket_setname(struct sockaddr_un *addr, const char *name, socklen_t *addrlen)
|
||||||
socket_setname(struct sockaddr_un *sockname, const char *name, socklen_t *len) {
|
{
|
||||||
bzero(sockname, sizeof(*sockname));
|
bzero(addr, sizeof(*addr));
|
||||||
sockname->sun_family = AF_UNIX;
|
addr->sun_family = AF_UNIX;
|
||||||
|
|
||||||
#ifdef USE_ABSTRACT_NAMESPACE
|
#ifdef USE_ABSTRACT_NAMESPACE
|
||||||
sockname->sun_path[0] = 0;
|
addr->sun_path[0] = '\0'; // mark as Linux abstract socket
|
||||||
/* Note: -2 here not -1 because sprintf will put the trailling nul in */
|
int len = snprintf(addr->sun_path + 1, sizeof addr->sun_path - 1, "%s.%s", DEFAULT_ABSTRACT_PREFIX, name);
|
||||||
*len = snprintf(sockname->sun_path + 1, sizeof(sockname->sun_path) - 2, "%s.%s",
|
if (len > sizeof addr->sun_path - 1)
|
||||||
DEFAULT_ABSTRACT_PREFIX, name);
|
return WHYF("abstract socket name overflow (%d bytes exceeds maximum %u): %s.%s", DEFAULT_ABSTRACT_PREFIX, name, len, sizeof addr->sun_path - 1);
|
||||||
if (*len > sizeof(sockname->sun_path) - 2)
|
*addrlen = sizeof(addr->sun_family) + 1 + len; // abstract socket names do not have a trailing nul
|
||||||
FATALF("Socket path too long (%d > %d)", *len, sizeof(sockname->sun_path) - 2);
|
#else // !USE_ABSTRACT_NAMESPACE
|
||||||
|
if (!FORM_SERVAL_INSTANCE_PATH(addr->sun_path, name))
|
||||||
/* Doesn't include trailing nul */
|
return WHYF("local socket name overflow: %s", name);
|
||||||
*len = 1 + strlen(sockname->sun_path + 1) + sizeof(sockname->sun_family);
|
*addrlen = sizeof(addr->sun_family) + strlen(addr->sun_path) + 1;
|
||||||
#else
|
#endif // !USE_ABSTRACT_NAMESPACE
|
||||||
*len = snprintf(sockname->sun_path, sizeof(sockname->sun_path) - 1, "%s/%s",
|
return 0;
|
||||||
serval_instancepath(), name);
|
}
|
||||||
if (*len > sizeof(sockname->sun_path) - 1)
|
|
||||||
FATALF("Socket path too long (%d > %d)", *len, sizeof(sockname->sun_path) - 1);
|
int esocket(int domain, int type, int protocol)
|
||||||
|
{
|
||||||
#ifdef SUN_LEN
|
int fd;
|
||||||
*len = SUN_LEN(sockname);
|
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
||||||
#else
|
return WHYF_perror("socket(%s, %s, 0)", alloca_socket_domain(domain), alloca_socket_type(type));
|
||||||
/* Includes trailing nul */
|
if (config.debug.io || config.debug.verbose_io)
|
||||||
*len = 1 + strlen(sockname->sun_path) + sizeof(sockname->sun_family);
|
DEBUGF("socket(%s, %s, 0) -> %d", alloca_socket_domain(domain), alloca_socket_type(type), fd);
|
||||||
#endif
|
return fd;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
|
int socket_connect(int sock, const struct sockaddr *addr, socklen_t addrlen)
|
||||||
|
{
|
||||||
|
if (connect(sock, (struct sockaddr *)addr, addrlen) == -1)
|
||||||
|
return WHYF_perror("connect(%d,%s,%lu)", sock, alloca_sockaddr(addr, addrlen), (unsigned long)addrlen);
|
||||||
|
if (config.debug.io || config.debug.verbose_io)
|
||||||
|
DEBUGF("connect(%d, %s, %lu)", sock, alloca_sockaddr(addr, addrlen), (unsigned long)addrlen);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int socket_bind(int sock, const struct sockaddr *addr, socklen_t addrlen)
|
||||||
|
{
|
||||||
|
if (addr->sa_family == AF_UNIX && ((struct sockaddr_un *)addr)->sun_path[0]) {
|
||||||
|
if (unlink(((struct sockaddr_un *)addr)->sun_path) == -1 && errno != ENOENT)
|
||||||
|
WARNF_perror("unlink(%s)", alloca_str_toprint(((struct sockaddr_un *)addr)->sun_path));
|
||||||
|
if (config.debug.io || config.debug.verbose_io)
|
||||||
|
DEBUGF("unlink(%s)", alloca_str_toprint(((struct sockaddr_un *)addr)->sun_path));
|
||||||
|
}
|
||||||
|
if (bind(sock, (struct sockaddr *)addr, addrlen) == -1)
|
||||||
|
return WHYF_perror("bind(%d,%s,%lu)", sock, alloca_sockaddr(addr, addrlen), (unsigned long)addrlen);
|
||||||
|
if (config.debug.io || config.debug.verbose_io)
|
||||||
|
DEBUGF("bind(%d, %s, %lu)", sock, alloca_sockaddr(addr, addrlen), (unsigned long)addrlen);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int socket_listen(int sock, int backlog)
|
||||||
|
{
|
||||||
|
if (listen(sock, backlog) == -1)
|
||||||
|
return WHYF_perror("listen(%d,%d)", sock, backlog);
|
||||||
|
if (config.debug.io || config.debug.verbose_io)
|
||||||
|
DEBUGF("listen(%d, %d)", sock, backlog);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int socket_set_reuseaddr(int sock, int reuseP)
|
||||||
|
{
|
||||||
|
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseP, sizeof reuseP) == -1) {
|
||||||
|
WARNF_perror("setsockopt(%d,SOL_SOCKET,SO_REUSEADDR,&%d,%u)", sock, reuseP, (unsigned)sizeof reuseP);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (config.debug.io || config.debug.verbose_io)
|
||||||
|
DEBUGF("setsockopt(%d, SOL_SOCKET, SO_REUSEADDR, &%d, %u)", sock, reuseP, (unsigned)sizeof reuseP);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int socket_set_rcvbufsize(int sock, unsigned buffer_size)
|
||||||
|
{
|
||||||
|
if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &buffer_size, sizeof buffer_size) == -1) {
|
||||||
|
WARNF_perror("setsockopt(%d,SOL_SOCKET,SO_RCVBUF,&%u,%u)", sock, buffer_size, (unsigned)sizeof buffer_size);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (config.debug.io || config.debug.verbose_io)
|
||||||
|
DEBUGF("setsockopt(%d, SOL_SOCKET, SO_RCVBUF, &%u, %u)", sock, buffer_size, (unsigned)sizeof buffer_size);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
5
socket.h
5
socket.h
@ -1,5 +0,0 @@
|
|||||||
int socket_bind(const char *name, int type, int reuse);
|
|
||||||
void socket_setname(struct sockaddr_un *sockname, const char *name, socklen_t *len);
|
|
||||||
void socket_done(const char *name);
|
|
||||||
|
|
||||||
|
|
@ -22,6 +22,7 @@ SERVAL_SOURCES = \
|
|||||||
$(SERVAL_BASE)os.c \
|
$(SERVAL_BASE)os.c \
|
||||||
$(SERVAL_BASE)mem.c \
|
$(SERVAL_BASE)mem.c \
|
||||||
$(SERVAL_BASE)instance.c \
|
$(SERVAL_BASE)instance.c \
|
||||||
|
$(SERVAL_BASE)socket.c \
|
||||||
$(SERVAL_BASE)monitor.c \
|
$(SERVAL_BASE)monitor.c \
|
||||||
$(SERVAL_BASE)monitor-client.c \
|
$(SERVAL_BASE)monitor-client.c \
|
||||||
$(SERVAL_BASE)monitor-cli.c \
|
$(SERVAL_BASE)monitor-cli.c \
|
||||||
|
@ -238,10 +238,10 @@ strbuf strbuf_append_exit_status(strbuf sb, int status)
|
|||||||
return sb;
|
return sb;
|
||||||
}
|
}
|
||||||
|
|
||||||
strbuf strbuf_append_sockaddr(strbuf sb, const struct sockaddr *addr)
|
strbuf strbuf_append_socket_domain(strbuf sb, int domain)
|
||||||
{
|
{
|
||||||
const char *fam = NULL;
|
const char *fam = NULL;
|
||||||
switch (addr->sa_family) {
|
switch (domain) {
|
||||||
case AF_UNSPEC: fam = "AF_UNSPEC"; break;
|
case AF_UNSPEC: fam = "AF_UNSPEC"; break;
|
||||||
case AF_UNIX: fam = "AF_UNIX"; break;
|
case AF_UNIX: fam = "AF_UNIX"; break;
|
||||||
case AF_INET: fam = "AF_INET"; break;
|
case AF_INET: fam = "AF_INET"; break;
|
||||||
@ -278,18 +278,60 @@ strbuf strbuf_append_sockaddr(strbuf sb, const struct sockaddr *addr)
|
|||||||
if (fam)
|
if (fam)
|
||||||
strbuf_puts(sb, fam);
|
strbuf_puts(sb, fam);
|
||||||
else
|
else
|
||||||
strbuf_sprintf(sb, "[%d]", addr->sa_family);
|
strbuf_sprintf(sb, "[%d]", domain);
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
strbuf strbuf_append_socket_type(strbuf sb, int type)
|
||||||
|
{
|
||||||
|
const char *typ = NULL;
|
||||||
|
switch (type) {
|
||||||
|
case SOCK_STREAM: typ = "SOCK_STREAM"; break;
|
||||||
|
case SOCK_DGRAM: typ = "SOCK_DGRAM"; break;
|
||||||
|
#ifdef SOCK_RAW
|
||||||
|
case SOCK_RAW: typ = "SOCK_RAW"; break;
|
||||||
|
#endif
|
||||||
|
#ifdef SOCK_RDM
|
||||||
|
case SOCK_RDM: typ = "SOCK_RDM"; break;
|
||||||
|
#endif
|
||||||
|
#ifdef SOCK_SEQPACKET
|
||||||
|
case SOCK_SEQPACKET: typ = "SOCK_SEQPACKET"; break;
|
||||||
|
#endif
|
||||||
|
#ifdef SOCK_PACKET
|
||||||
|
case SOCK_PACKET: typ = "SOCK_PACKET"; break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (typ)
|
||||||
|
strbuf_puts(sb, typ);
|
||||||
|
else
|
||||||
|
strbuf_sprintf(sb, "[%d]", type);
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
strbuf strbuf_append_sockaddr(strbuf sb, const struct sockaddr *addr, socklen_t addrlen)
|
||||||
|
{
|
||||||
|
strbuf_append_socket_domain(sb, addr->sa_family);
|
||||||
switch (addr->sa_family) {
|
switch (addr->sa_family) {
|
||||||
case AF_UNIX:
|
case AF_UNIX: {
|
||||||
strbuf_putc(sb, ' ');
|
size_t len = addrlen > sizeof addr->sa_family ? addrlen - sizeof addr->sa_family : 0;
|
||||||
if (addr->sa_data[0])
|
strbuf_putc(sb, ' ');
|
||||||
strbuf_toprint_quoted_len(sb, addr->sa_data, "\"\"", sizeof addr->sa_data);
|
if (addr->sa_data[0]) {
|
||||||
else {
|
strbuf_toprint_quoted_len(sb, "\"\"", addr->sa_data, len);
|
||||||
strbuf_puts(sb, "abstract ");
|
if (len < 2)
|
||||||
strbuf_toprint_quoted_len(sb, addr->sa_data, "\"\"", sizeof addr->sa_data);
|
strbuf_sprintf(sb, " (addrlen=%d too short)", (int)addrlen);
|
||||||
|
if (len && addr->sa_data[len - 1] != '\0')
|
||||||
|
strbuf_sprintf(sb, " (addrlen=%d, no nul terminator)", (int)addrlen);
|
||||||
|
} else {
|
||||||
|
strbuf_puts(sb, "abstract ");
|
||||||
|
strbuf_toprint_quoted_len(sb, "\"\"", addr->sa_data, len);
|
||||||
|
if (len == 0)
|
||||||
|
strbuf_sprintf(sb, " (addrlen=%d too short)", (int)addrlen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AF_INET: {
|
case AF_INET: {
|
||||||
|
if (addrlen != sizeof(struct sockaddr_in))
|
||||||
|
strbuf_sprintf(sb, " (addrlen=%d should be %d)", (int)addrlen, sizeof(struct sockaddr_in));
|
||||||
const struct sockaddr_in *addr_in = (const struct sockaddr_in *) addr;
|
const struct sockaddr_in *addr_in = (const struct sockaddr_in *) addr;
|
||||||
strbuf_sprintf(sb, " %u.%u.%u.%u:%u",
|
strbuf_sprintf(sb, " %u.%u.%u.%u:%u",
|
||||||
((unsigned char *) &addr_in->sin_addr.s_addr)[0],
|
((unsigned char *) &addr_in->sin_addr.s_addr)[0],
|
||||||
@ -301,8 +343,9 @@ strbuf strbuf_append_sockaddr(strbuf sb, const struct sockaddr *addr)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
|
size_t len = addrlen > sizeof addr->sa_family ? addrlen - sizeof addr->sa_family : 0;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < sizeof addr->sa_data; ++i)
|
for (i = 0; i < len; ++i)
|
||||||
strbuf_sprintf(sb, " %02x", addr->sa_data[i]);
|
strbuf_sprintf(sb, " %02x", addr->sa_data[i]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -20,6 +20,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#ifndef __STRBUF_HELPERS_H__
|
#ifndef __STRBUF_HELPERS_H__
|
||||||
#define __STRBUF_HELPERS_H__
|
#define __STRBUF_HELPERS_H__
|
||||||
|
|
||||||
|
// For socklen_t
|
||||||
|
#ifdef WIN32
|
||||||
|
# include "win32/win32.h"
|
||||||
|
#else
|
||||||
|
# ifdef HAVE_SYS_SOCKET_H
|
||||||
|
# include <sys/socket.h>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
|
|
||||||
/* Append a representation of the given chars in a given buffer (including nul
|
/* Append a representation of the given chars in a given buffer (including nul
|
||||||
@ -95,12 +104,24 @@ strbuf strbuf_append_argv(strbuf sb, int argc, const char *const *argv);
|
|||||||
*/
|
*/
|
||||||
strbuf strbuf_append_exit_status(strbuf sb, int status);
|
strbuf strbuf_append_exit_status(strbuf sb, int status);
|
||||||
|
|
||||||
|
/* Append a textual description of a socket domain code (AF_...).
|
||||||
|
* @author Andrew Bettison <andrew@servalproject.com>
|
||||||
|
*/
|
||||||
|
strbuf strbuf_append_socket_domain(strbuf sb, int domain);
|
||||||
|
#define alloca_socket_domain(domain) strbuf_str(strbuf_append_socket_domain(strbuf_alloca(15), domain))
|
||||||
|
|
||||||
|
/* Append a textual description of a socket type code (SOCK_...).
|
||||||
|
* @author Andrew Bettison <andrew@servalproject.com>
|
||||||
|
*/
|
||||||
|
strbuf strbuf_append_socket_type(strbuf sb, int type);
|
||||||
|
#define alloca_socket_type(type) strbuf_str(strbuf_append_socket_type(strbuf_alloca(15), type))
|
||||||
|
|
||||||
/* Append a textual description of a struct sockaddr_in.
|
/* Append a textual description of a struct sockaddr_in.
|
||||||
* @author Andrew Bettison <andrew@servalproject.com>
|
* @author Andrew Bettison <andrew@servalproject.com>
|
||||||
*/
|
*/
|
||||||
struct sockaddr;
|
struct sockaddr;
|
||||||
strbuf strbuf_append_sockaddr(strbuf sb, const struct sockaddr *);
|
strbuf strbuf_append_sockaddr(strbuf sb, const struct sockaddr *addr, socklen_t addrlen);
|
||||||
#define alloca_sockaddr(addr) strbuf_str(strbuf_append_sockaddr(strbuf_alloca(40), (const struct sockaddr *)(addr)))
|
#define alloca_sockaddr(addr, addrlen) strbuf_str(strbuf_append_sockaddr(strbuf_alloca(200), (const struct sockaddr *)(addr), (addrlen)))
|
||||||
|
|
||||||
/* Append a strftime(3) string.
|
/* Append a strftime(3) string.
|
||||||
* @author Andrew Bettison <andrew@servalproject.com>
|
* @author Andrew Bettison <andrew@servalproject.com>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user