Refactor unix domain socket naming to a separate file instead.

Handle selection between normal & abstract sockets in a single place.

overlay_mdp.c tried to have both but this seems like a bug so I've removed the second socket (needs tests).
This commit is contained in:
Daniel O'Connor 2012-07-30 11:19:25 +09:30
parent 09d0fecf28
commit fd1f91db8d
12 changed files with 180 additions and 179 deletions

View File

@ -67,7 +67,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\
-I$(NACL_INC) \ -I$(NACL_INC) \
-I$(SQLITE3_INC) -I$(SQLITE3_INC)

View File

@ -51,6 +51,7 @@ SRCS= \
sha2.c \ sha2.c \
sighandlers.c \ sighandlers.c \
simulate.c \ simulate.c \
socket.c \
sqlite3.c \ sqlite3.c \
srandomdev.c \ srandomdev.c \
strbuf.c \ strbuf.c \
@ -63,6 +64,7 @@ MONITORCLIENTSRCS=conf.c \
mkdir.c \ mkdir.c \
monitor-client.c \ monitor-client.c \
net.c \ net.c \
socket.c \
strbuf.c \ strbuf.c \
strbuf_helpers.c strbuf_helpers.c

View File

@ -88,6 +88,9 @@ AC_CHECK_HEADERS(
alsa/asoundlib.h \ alsa/asoundlib.h \
) )
dnl Lazy way of checking for Linux
AC_CHECK_HEADER(linux/if.h, AC_DEFINE([USE_ABSTRACT_NAMESPACE]))
echo "Fetching and building NaCl if required." echo "Fetching and building NaCl if required."
echo "(this can take HOURS to build depending on your architecture," echo "(this can take HOURS to build depending on your architecture,"
echo " but fortunately it only needs to happen once.)" echo " but fortunately it only needs to happen once.)"

View File

@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <fcntl.h> #include <fcntl.h>
#include "serval.h" #include "serval.h"
#include "socket.h"
static char cmd[1024]; static char cmd[1024];
static int cmdLen=0; static int cmdLen=0;
@ -54,6 +55,7 @@ static int fast_audio=0;
int app_monitor_cli(int argc, const char *const *argv, struct command_line_option *o) int app_monitor_cli(int argc, const char *const *argv, struct command_line_option *o)
{ {
socklen_t len;
const char *sid=NULL; const char *sid=NULL;
cli_arg(argc, argv, o, "sid", &sid, NULL, ""); cli_arg(argc, argv, o, "sid", &sid, NULL, "");
struct sockaddr_un addr; struct sockaddr_un addr;
@ -68,12 +70,8 @@ int app_monitor_cli(int argc, const char *const *argv, struct command_line_optio
exit(-1); exit(-1);
} }
memset(&addr, 0, sizeof(addr)); socket_setname(&addr, confValueGet("monitor.socket",DEFAULT_MONITOR_SOCKET_NAME), &len);
addr.sun_family = AF_UNIX;
addr.sun_path[0]=0;
snprintf(&addr.sun_path[1],100,"%s",
confValueGet("monitor.socket",DEFAULT_MONITOR_SOCKET_NAME));
int len = 1+strlen(&addr.sun_path[1]) + sizeof(addr.sun_family);
char *p=(char *)&addr; char *p=(char *)&addr;
printf("last char='%c' %02x\n",p[len-1],p[len-1]); printf("last char='%c' %02x\n",p[len-1],p[len-1]);

View File

@ -17,26 +17,21 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "monitor-client.h" #include "monitor-client.h"
#include "socket.h"
/* Open monitor interface abstract domain named socket */ /* Open monitor interface abstract domain named socket */
int monitor_client_open() int monitor_client_open()
{ {
int fd; int fd;
struct sockaddr_un addr; struct sockaddr_un addr;
socklen_t len;
if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror("socket"); perror("socket");
exit(-1); exit(-1);
} }
memset(&addr, 0, sizeof(addr)); socket_setname(&addr, confValueGet("monitor.socket",DEFAULT_MONITOR_SOCKET_NAME), &len);
addr.sun_family = AF_UNIX;
/* XXX - On non-linux systems, we need to use a regular named socket */
addr.sun_path[0]=0;
snprintf(&addr.sun_path[1],100,
"%s", confValueGet("monitor.socket",DEFAULT_MONITOR_SOCKET_NAME));
int len = 1+strlen(&addr.sun_path[1]) + sizeof(addr.sun_family);
char *p=(char *)&addr; char *p=(char *)&addr;
printf("last char='%c' %02x\n",p[len-1],p[len-1]); printf("last char='%c' %02x\n",p[len-1],p[len-1]);

View File

@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "serval.h" #include "serval.h"
#include "rhizome.h" #include "rhizome.h"
#include "socket.h"
#include <sys/stat.h> #include <sys/stat.h>
#if defined(LOCAL_PEERCRED) && !defined(SO_PEERCRED) #if defined(LOCAL_PEERCRED) && !defined(SO_PEERCRED)
@ -63,7 +64,7 @@ struct profile_total client_stats;
int monitor_setup_sockets() int monitor_setup_sockets()
{ {
struct sockaddr_un name; struct sockaddr_un name;
int len; socklen_t len;
int sock; int sock;
bzero(&name, sizeof(name)); bzero(&name, sizeof(name));
@ -74,24 +75,7 @@ int monitor_setup_sockets()
goto error; goto error;
} }
#ifdef linux socket_setname(&name, confValueGet("monitor.socket",DEFAULT_MONITOR_SOCKET_NAME), &len);
/* 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,
confValueGet("monitor.socket",DEFAULT_MONITOR_SOCKET_NAME));
/* 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(),
confValueGet("monitor.socket",DEFAULT_MONITOR_SOCKET_NAME));
unlink(name.sun_path);
/* Includes trailing nul */
len = 1+strlen(name.sun_path) + sizeof(name.sun_family);
#endif
if(bind(sock, (struct sockaddr *)&name, len)==-1) { if(bind(sock, (struct sockaddr *)&name, len)==-1) {
WHY_perror("bind"); WHY_perror("bind");

View File

@ -18,87 +18,46 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <sys/stat.h> #include <sys/stat.h>
#include "serval.h" #include "serval.h"
#include "socket.h"
#include "strbuf.h" #include "strbuf.h"
struct sched_ent mdp_abstract; static char overlay_mdp_client_socket_path[1024] = { 0 };
struct sched_ent mdp_named;
struct profile_total mdp_stats; struct sched_ent mdp_sock;
static struct profile_total mdp_stats;
int overlay_mdp_setup_sockets() int overlay_mdp_setup_sockets()
{ {
struct sockaddr_un name; struct sockaddr_un name;
int len; socklen_t len;
name.sun_family = AF_UNIX; name.sun_family = AF_UNIX;
#ifndef HAVE_LINUX_IF_H if (mdp_sock.function != NULL)
/* Abstrack name space (i.e., non-file represented) unix domain sockets are a return 0;
linux-only thing. */
mdp_abstract.poll.fd = -1;
#else
if (mdp_abstract.function==NULL) {
/* 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. */
snprintf(&name.sun_path[1],100,
confValueGet("mdp.socket",DEFAULT_MDP_SOCKET_NAME));
len = 1+strlen(&name.sun_path[1]) + sizeof(name.sun_family);
mdp_abstract.poll.fd = socket(AF_UNIX, SOCK_DGRAM, 0); socket_setname(&name, confValueGet("mdp.socket",DEFAULT_MDP_SOCKET_NAME), &len);
if (mdp_abstract.poll.fd>-1) {
int reuseP=1; mdp_sock.poll.fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (setsockopt( mdp_abstract.poll.fd, SOL_SOCKET, SO_REUSEADDR, &reuseP, sizeof(reuseP)) == -1) { if (mdp_sock.poll.fd>-1) {
WARN_perror("setsockopt(SO_REUSEADDR)"); int reuseP=1;
WARN("Could not set socket reuse addresses"); if (setsockopt( mdp_sock.poll.fd, SOL_SOCKET, SO_REUSEADDR, &reuseP, sizeof(reuseP)) == -1) {
} WARN_perror("setsockopt(SO_REUSEADDR)");
if (bind(mdp_abstract.poll.fd, (struct sockaddr *)&name, len) == -1) { WARN("Could not set socket reuse addresses");
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.function = overlay_mdp_poll;
mdp_abstract.stats.name = "overlay_mdp_poll";
mdp_abstract.poll.events = POLLIN;
watch(&mdp_abstract);
} }
} if (bind(mdp_sock.poll.fd, (struct sockaddr *)&name, len) == -1) {
#endif WARN_perror("bind");
if (mdp_named.function==NULL) { close(mdp_sock.poll.fd);
if (!form_serval_instance_path(&name.sun_path[0], 100, "mdp.socket")) mdp_sock.poll.fd = -1;
return WHY("Cannot construct name of unix domain socket."); WARN("bind of abstract name space socket failed (not a problem on non-linux systems)");
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_stats.name="overlay_mdp_poll";
mdp_named.stats = &mdp_stats;
mdp_named.poll.events = POLLIN;
watch(&mdp_named);
} }
int send_buffer_size=64*1024;
if (setsockopt(mdp_sock.poll.fd, SOL_SOCKET, SO_SNDBUF, &send_buffer_size, sizeof(send_buffer_size)) == -1)
WARN_perror("setsockopt(SO_SNDBUF)");
mdp_sock.function = overlay_mdp_poll;
mdp_sock.stats->name = "overlay_mdp_poll";
mdp_sock.poll.events = POLLIN;
watch(&mdp_sock);
} }
return 0; return 0;
@ -464,7 +423,7 @@ int overlay_saw_mdp_frame(overlay_mdp_frame *mdp,long long now)
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);
} }
@ -691,7 +650,7 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
if (overlay_mdp_sanitytest_sourceaddr(&mdp->out.src,userGeneratedFrameP, if (overlay_mdp_sanitytest_sourceaddr(&mdp->out.src,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"
@ -715,7 +674,7 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
NaCl cryptobox keys can be used for signing. */ NaCl cryptobox keys can be used for signing. */
if (broadcast) { if (broadcast) {
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 ")); }
@ -1125,7 +1084,8 @@ int overlay_mdp_relevant_bytes(overlay_mdp_frame *mdp)
int mdp_client_socket=-1; int mdp_client_socket=-1;
int overlay_mdp_send(overlay_mdp_frame *mdp,int flags,int timeout_ms) int overlay_mdp_send(overlay_mdp_frame *mdp,int flags,int timeout_ms)
{ {
int len=4; socklen_t socklen;
int len;
if (mdp_client_socket==-1) if (mdp_client_socket==-1)
if (overlay_mdp_client_init() != 0) if (overlay_mdp_client_init() != 0)
@ -1138,13 +1098,12 @@ int overlay_mdp_send(overlay_mdp_frame *mdp,int flags,int timeout_ms)
/* Construct name of socket to send to. */ /* Construct name of socket to send to. */
struct sockaddr_un name; struct sockaddr_un name;
name.sun_family = AF_UNIX;
if (!FORM_SERVAL_INSTANCE_PATH(name.sun_path, "mdp.socket")) socket_setname(&name, confValueGet("mdp.socket",DEFAULT_MDP_SOCKET_NAME), &socklen);
return -1;
set_nonblock(mdp_client_socket); set_nonblock(mdp_client_socket);
int result=sendto(mdp_client_socket, mdp, len, 0, int result=sendto(mdp_client_socket, mdp, len, 0,
(struct sockaddr *)&name, sizeof(struct sockaddr_un)); (struct sockaddr *)&name, socklen);
set_block(mdp_client_socket); set_block(mdp_client_socket);
if (result<0) { if (result<0) {
mdp->packetTypeAndFlags=MDP_ERROR; mdp->packetTypeAndFlags=MDP_ERROR;
@ -1180,54 +1139,44 @@ int overlay_mdp_send(overlay_mdp_frame *mdp,int flags,int timeout_ms)
} }
} }
char overlay_mdp_client_socket_path[1024];
int overlay_mdp_client_socket_path_len=-1;
int overlay_mdp_client_init() int overlay_mdp_client_init()
{ {
if (mdp_client_socket==-1) { if (mdp_client_socket != -1)
/* Open socket to MDP server (thus connection is always local) */ return 0;
if (0) WHY("Use of abstract name space socket for Linux not implemented");
mdp_client_socket = socket(AF_UNIX, SOCK_DGRAM, 0); /* Open socket to MDP server (thus connection is always local) */
if (mdp_client_socket < 0) { mdp_client_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
WHY_perror("socket"); if (mdp_client_socket < 0) {
return WHY("Could not open socket to MDP server"); 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");
} }
/* Bind to a random name, but cache it for later use */
struct sockaddr_un name;
socklen_t len;
unsigned int random_value;
if (overlay_mdp_client_socket_path[0] == 0) {
if (urandombytes((unsigned char *)&random_value,sizeof(unsigned int)))
return WHY("urandombytes() failed");
snprintf(overlay_mdp_client_socket_path, sizeof(overlay_mdp_client_socket_path),
"mdp-client-%d-%08x.socket", getpid(), random_value);
if(debug & DEBUG_IO) DEBUGF("MDP client socket name='%s'",overlay_mdp_client_socket_path);
}
socket_setname(&name, overlay_mdp_client_socket_path, &len);
unlink(name.sun_path);
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");
return 0; return 0;
} }
@ -1240,7 +1189,7 @@ int overlay_mdp_client_done()
overlay_mdp_send(&mdp,0,0); overlay_mdp_send(&mdp,0,0);
} }
if (overlay_mdp_client_socket_path_len>-1) if (overlay_mdp_client_socket_path[0] != 0)
unlink(overlay_mdp_client_socket_path); unlink(overlay_mdp_client_socket_path);
if (mdp_client_socket!=-1) if (mdp_client_socket!=-1)
close(mdp_client_socket); close(mdp_client_socket);

View File

@ -1491,5 +1491,5 @@ int overlay_route_node_info(overlay_mdp_frame *mdp,
} }
} }
return overlay_mdp_reply(mdp_named.poll.fd,addr,addrlen,mdp); return overlay_mdp_reply(mdp_sock.poll.fd,addr,addrlen,mdp);
} }

View File

@ -844,8 +844,7 @@ 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_sock;
extern struct sched_ent mdp_named;
typedef struct sockaddr_mdp { typedef struct sockaddr_mdp {

66
socket.c Normal file
View File

@ -0,0 +1,66 @@
/*
Copyright (C) 2012 Daniel O'Connor, Serval Project.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_NETINET_IN_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 "log.h"
#include "socket.h"
/* Set the socket name in the abstract namespace for linux or
* $SERVALINSTANCE_PATH/name for everything else.
*/
void
socket_setname(struct sockaddr_un *sockname, const char *name, socklen_t *len) {
bzero(sockname, sizeof(*sockname));
sockname->sun_family = AF_UNIX;
#ifdef USE_ABSTRACT_NAMESPACE
sockname->sun_path[0] = 0;
/* Note: -2 here not -1 because sprintf will put the trailling nul in */
*len = snprintf(sockname->sun_path + 1, sizeof(sockname->sun_path) - 2, "%s.%s",
DEFAULT_ABSTRACT_PREFIX, name);
if (*len > sizeof(sockname->sun_path) - 2)
FATALF("Socket path too long (%d > %d)", *len, sizeof(sockname->sun_path) - 2);
/* Doesn't include trailing nul */
*len = 1 + strlen(sockname->sun_path + 1) + sizeof(sockname->sun_family);
#else
*len = snprintf(sockname->sun_path, sizeof(sockname->sun_path) - 1, "%s/%s",
serval_instancepath(), name);
if (*len > sizeof(sockname->sun_path) - 1)
FATALF("Socket path too long (%d > %d)", *len, sizeof(sockname->sun_path) - 1);
#ifdef SUN_LEN
*len = SUN_LEN(sockname);
#else
/* Includes trailing nul */
*len = 1 + strlen(sockname->sun_path) + sizeof(sockname->sun_family);
#endif
#endif
}

5
socket.h Normal file
View File

@ -0,0 +1,5 @@
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);

32
vomp.c
View File

@ -340,7 +340,7 @@ int vomp_send_mdp_status_audio(vomp_call_state *call, int audio_codec, unsigned
long long now=overlay_gettime_ms(); long long now=overlay_gettime_ms();
for(i=0;i<vomp_interested_usock_count;i++) for(i=0;i<vomp_interested_usock_count;i++)
if (vomp_interested_expiries[i]>=now) { if (vomp_interested_expiries[i]>=now) {
overlay_mdp_reply(mdp_named.poll.fd, overlay_mdp_reply(mdp_sock.poll.fd,
vomp_interested_usocks[i], vomp_interested_usocks[i],
vomp_interested_usock_lengths[i], vomp_interested_usock_lengths[i],
&mdp); &mdp);
@ -587,7 +587,7 @@ int vomp_mdp_event(overlay_mdp_frame *mdp,
if (!memcmp(recvaddr->sun_path, if (!memcmp(recvaddr->sun_path,
vomp_interested_usocks[i],recvaddrlen)) vomp_interested_usocks[i],recvaddrlen))
/* found it -- so we are already monitoring this one */ /* found it -- so we are already monitoring this one */
return overlay_mdp_reply_error(mdp_named.poll.fd,recvaddr,recvaddrlen, return overlay_mdp_reply_error(mdp_sock.poll.fd,recvaddr,recvaddrlen,
0,"Success"); 0,"Success");
if (vomp_interested_expiries[i]<now) candidate=i; if (vomp_interested_expiries[i]<now) candidate=i;
} }
@ -600,7 +600,7 @@ int vomp_mdp_event(overlay_mdp_frame *mdp,
} }
vomp_interested_usocks[i]=malloc(recvaddrlen); vomp_interested_usocks[i]=malloc(recvaddrlen);
if (!vomp_interested_usocks[i]) if (!vomp_interested_usocks[i])
return overlay_mdp_reply_error(mdp_named.poll.fd, recvaddr,recvaddrlen, return overlay_mdp_reply_error(mdp_sock.poll.fd, recvaddr,recvaddrlen,
4002,"Out of memory"); 4002,"Out of memory");
bcopy(recvaddr,vomp_interested_usocks[i], bcopy(recvaddr,vomp_interested_usocks[i],
recvaddrlen); recvaddrlen);
@ -618,10 +618,10 @@ int vomp_mdp_event(overlay_mdp_frame *mdp,
} }
return overlay_mdp_reply_error return overlay_mdp_reply_error
(mdp_named.poll.fd,recvaddr,recvaddrlen,0,"Success"); (mdp_sock.poll.fd,recvaddr,recvaddrlen,0,"Success");
} else { } else {
return overlay_mdp_reply_error return overlay_mdp_reply_error
(mdp_named.poll.fd,recvaddr,recvaddrlen, (mdp_sock.poll.fd,recvaddr,recvaddrlen,
4003,"Too many listeners (try again in a minute?)"); 4003,"Too many listeners (try again in a minute?)");
} }
} }
@ -649,12 +649,12 @@ int vomp_mdp_event(overlay_mdp_frame *mdp,
} }
vomp_interested_usock_count--; vomp_interested_usock_count--;
return overlay_mdp_reply_error return overlay_mdp_reply_error
(mdp_named.poll.fd,recvaddr,recvaddrlen, (mdp_sock.poll.fd,recvaddr,recvaddrlen,
0,"Success. You have been removed."); 0,"Success. You have been removed.");
} }
} }
return overlay_mdp_reply_error return overlay_mdp_reply_error
(mdp_named.poll.fd,recvaddr,recvaddrlen, (mdp_sock.poll.fd,recvaddr,recvaddrlen,
0,"Success. You were never listening."); 0,"Success. You were never listening.");
} }
break; break;
@ -696,7 +696,7 @@ int vomp_mdp_event(overlay_mdp_frame *mdp,
=vomp_call_states[i].local.state; =vomp_call_states[i].local.state;
} }
return overlay_mdp_reply(mdp_named.poll.fd,recvaddr,recvaddrlen,&mdpreply); return overlay_mdp_reply(mdp_sock.poll.fd,recvaddr,recvaddrlen,&mdpreply);
} }
break; break;
case VOMPEVENT_DIAL: case VOMPEVENT_DIAL:
@ -706,11 +706,11 @@ int vomp_mdp_event(overlay_mdp_frame *mdp,
NULL, NULL,
NULL)) NULL))
return overlay_mdp_reply_error return overlay_mdp_reply_error
(mdp_named.poll.fd,recvaddr,recvaddrlen,4004, (mdp_sock.poll.fd,recvaddr,recvaddrlen,4004,
"Unable to place call"); "Unable to place call");
else{ else{
int result= overlay_mdp_reply_error int result= overlay_mdp_reply_error
(mdp_named.poll.fd,recvaddr,recvaddrlen,0, "Success"); (mdp_sock.poll.fd,recvaddr,recvaddrlen,0, "Success");
if (result) WHY("Failed to send MDP reply"); if (result) WHY("Failed to send MDP reply");
return result; return result;
} }
@ -721,12 +721,12 @@ int vomp_mdp_event(overlay_mdp_frame *mdp,
=vomp_find_call_by_session(mdp->vompevent.call_session_token); =vomp_find_call_by_session(mdp->vompevent.call_session_token);
if (!call) if (!call)
return overlay_mdp_reply_error return overlay_mdp_reply_error
(mdp_named.poll.fd,recvaddr,recvaddrlen,4006, (mdp_sock.poll.fd,recvaddr,recvaddrlen,4006,
"No such call"); "No such call");
vomp_hangup(call); vomp_hangup(call);
return overlay_mdp_reply_error(mdp_named.poll.fd, return overlay_mdp_reply_error(mdp_sock.poll.fd,
recvaddr,recvaddrlen,0,"Success"); recvaddr,recvaddrlen,0,"Success");
} }
break; break;
@ -736,15 +736,15 @@ int vomp_mdp_event(overlay_mdp_frame *mdp,
=vomp_find_call_by_session(mdp->vompevent.call_session_token); =vomp_find_call_by_session(mdp->vompevent.call_session_token);
if (!call) if (!call)
return overlay_mdp_reply_error return overlay_mdp_reply_error
(mdp_named.poll.fd,recvaddr,recvaddrlen,4006, (mdp_sock.poll.fd,recvaddr,recvaddrlen,4006,
"No such call"); "No such call");
if (vomp_pickup(call)) if (vomp_pickup(call))
return overlay_mdp_reply_error(mdp_named.poll.fd, return overlay_mdp_reply_error(mdp_sock.poll.fd,
recvaddr,recvaddrlen,4009, recvaddr,recvaddrlen,4009,
"Call is not RINGINGIN, so cannot be picked up"); "Call is not RINGINGIN, so cannot be picked up");
else else
return overlay_mdp_reply_error(mdp_named.poll.fd, return overlay_mdp_reply_error(mdp_sock.poll.fd,
recvaddr,recvaddrlen,0,"Success"); recvaddr,recvaddrlen,0,"Success");
} }
break; break;
@ -764,7 +764,7 @@ int vomp_mdp_event(overlay_mdp_frame *mdp,
break; break;
default: default:
/* didn't understand it, so respond with an error */ /* didn't understand it, so respond with an error */
return overlay_mdp_reply_error(mdp_named.poll.fd, return overlay_mdp_reply_error(mdp_sock.poll.fd,
recvaddr,recvaddrlen,4001, recvaddr,recvaddrlen,4001,
"Invalid VOMPEVENT request (use DIAL,HANGUP,CALLREJECT,AUDIOSTREAMING,REGISTERINTERST,WITHDRAWINTERST only)"); "Invalid VOMPEVENT request (use DIAL,HANGUP,CALLREJECT,AUDIOSTREAMING,REGISTERINTERST,WITHDRAWINTERST only)");