Bug 966547 - Switch sipcc from named to anonymous sockets on Unix. r=jesup, r=kang

This commit is contained in:
Jed Davis 2014-02-20 09:35:26 -05:00
Родитель 034a3313aa
Коммит 3a2e9e491d
12 изменённых файлов: 138 добавлений и 183 удалений

Просмотреть файл

@ -40,19 +40,6 @@
/* The maximum number of connections allowed */
#define MAX_SIP_CONNECTIONS (64 - 2)
/* SIP Message queue waiting thread and the main thread IPC names */
#ifdef __ANDROID__
/* Note that for unit tests to work, this directory currently _must_ be
world-writable or the tests must be run as root. See bug 823741 for the
gory details. */
#define SIP_IPC_TEMP_BASEPATH "/data/local/tmp"
#else
#define SIP_IPC_TEMP_BASEPATH "/tmp"
#endif
#define SIP_IPC_TEMP_DIRNAME "SIP-XXXXXXXX"
#define SIP_MSG_SERV_SUFFIX "/Main"
#define SIP_MSG_CLNT_SUFFIX "/MsgQ"
#define SIP_PAUSE_WAIT_IPC_LISTEN_READY_TIME 50 /* 50ms. */
#define SIP_MAX_WAIT_FOR_IPC_LISTEN_READY 1200 /* 50 * 1200 = 1 minutes */
@ -82,9 +69,6 @@ typedef struct sip_int_msg_t_ {
/* Internal message queue (array) */
static sip_int_msg_t sip_int_msgq_buf[MAX_SIP_MESSAGES] = {{0,0},{0,0}};
static cpr_sockaddr_un_t sip_serv_sock_addr;
static cpr_sockaddr_un_t sip_clnt_sock_addr;
/*---------------------------------------------------------
*
@ -138,97 +122,6 @@ sip_platform_task_init (void)
return;
}
/**
* sip_get_sock_dir returns the name of a temporary directory
* where IPC sockets will live, creating one if it does not yet exist.
*
* If the TMPDIR environment is set, that is used as a base; otherwise
* SIP_IPC_TEMP_BASEPATH is used as a fallback. SIP_IPC_TEMP_DIRAME is
* added as a child directory, and if suffix is non-null, that is
* appended to the end.
*
* The primary motivation for using TMPDIR is that that is how Fennec
* (GeckoAppShell.java) passes in a scratch directory that is guaranteed to be
* writable on Android, and there's no other reliable way to get such a thing.
*
* @param[out] out buffer to be written to
* @param[in] outlen length of out buffer so we don't overrun
* @param[in] suffix if non-NULL, appended to the template
*
* @return The length of the written output not including the NULL
* terminator, or -1 if an error occurs.
*/
static char sip_sock_dir[sizeof(sip_serv_sock_addr.sun_path)] = "\0";
static size_t sip_sock_dir_len = 0;
static uint32_t sip_get_sock_dir(char *out, uint32_t outlen,
const char *suffix) {
const char *fname = "sip_get_sock_dir";
// Initialize the base string and create the directory
// if it hasn't been created yet.
if (!sip_sock_dir_len) {
char *tmpdir;
tmpdir = getenv("TMPDIR");
if (!tmpdir) {
tmpdir = SIP_IPC_TEMP_BASEPATH;
}
sip_sock_dir_len = PR_snprintf(sip_sock_dir, sizeof(sip_sock_dir),
"%s/%s", tmpdir, SIP_IPC_TEMP_DIRNAME);
// Note that mkdtemp modifies the string passed to it.
if (!mkdtemp(sip_sock_dir))
{
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"mkdtemp() returned error"
" errno=%d\n", fname, cpr_errno);
sip_sock_dir_len = 0;
return -1;
}
}
return PR_snprintf(out, outlen, "%s%s", sip_sock_dir, suffix ? suffix : "");
}
/**
* sip_create_IPC_sock creates and bind the socket for IPC.
*
* @param[in]name - pointer to the const. character for the
* IPC address (name) to be bound when the
* IPC socket is successfully created.
*
* @return cpr_socket_t - Returns a valid CPR's socket if
* the socket is created sucessafully otherwise
* returns INVALID_SOCKET.
* @pre (name != NULL)
*/
static cpr_socket_t sip_create_IPC_sock (const char *name)
{
const char *fname = "sip_create_IPC_sock";
cpr_socket_t sock;
cpr_sockaddr_un_t addr;
/* Create socket */
sock = cprSocket(AF_LOCAL, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET) {
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"cprSocket() returned error"
" errno=%d\n", fname, cpr_errno);
return (INVALID_SOCKET);
}
/* Bind to the local socket */
cpr_set_sockun_addr(&addr, name, getpid());
/* make sure file doesn't already exist */
unlink(addr.sun_path);
/* do the bind */
if (cprBind(sock, (cpr_sockaddr_t *)&addr,
cpr_sun_len(addr)) == CPR_FAILURE) {
(void) sipSocketClose(sock, FALSE);
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"cprBind() failed"
" errno=%d\n", fname, cpr_errno);
return (INVALID_SOCKET);
}
return (sock);
}
/**
* The function is a thread loop that waits on SIP message queue
@ -264,7 +157,6 @@ void sip_platform_task_msgqwait (void *arg)
uint8_t num_messages = 0;
uint8_t response = 0;
boolean quit_thread = FALSE;
char tempdir[sizeof(sip_serv_sock_addr.sun_path)];
if (msgq == NULL) {
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"task msgq is null, exiting", fname);
@ -297,21 +189,6 @@ void sip_platform_task_msgqwait (void *arg)
*/
(void) cprAdjustRelativeThreadPriority(SIP_THREAD_RELATIVE_PRIORITY);
/*
* The main thread is ready. set global client socket address
* so that the server can send back response.
*/
sip_get_sock_dir(tempdir, sizeof(tempdir), SIP_MSG_CLNT_SUFFIX);
cpr_set_sockun_addr(&sip_clnt_sock_addr, tempdir, 0);
sip_ipc_clnt_socket = sip_create_IPC_sock(sip_clnt_sock_addr.sun_path);
if (sip_ipc_clnt_socket == INVALID_SOCKET) {
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_create_IPC_sock() failed,"
" exiting\n", fname);
return;
}
while (quit_thread == FALSE) {
msg = cprGetMessage(msgq, TRUE, (void **) &syshdr);
while (msg != NULL) {
@ -355,10 +232,8 @@ void sip_platform_task_msgqwait (void *arg)
* There are some number of messages sent to the main thread,
* trigger the main SIP thread via IPC to process the message.
*/
if (cprSendTo(sip_ipc_clnt_socket, (void *)&num_messages,
sizeof(num_messages), 0,
(cpr_sockaddr_t *)&sip_serv_sock_addr,
cpr_sun_len(sip_serv_sock_addr)) < 0) {
if (cprSend(sip_ipc_clnt_socket, (void *)&num_messages,
sizeof(num_messages), 0) < 0) {
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"send IPC failed errno=%d", fname, cpr_errno);
}
@ -366,8 +241,8 @@ void sip_platform_task_msgqwait (void *arg)
/*
* Wait for main thread to signal us to get more message.
*/
if (cprRecvFrom(sip_ipc_clnt_socket, &response,
sizeof(response), 0, NULL, NULL) < 0) {
if (cprRecv(sip_ipc_clnt_socket, &response,
sizeof(response), 0) < 0) {
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"read IPC failed:"
" errno=%d\n", fname, cpr_errno);
}
@ -376,7 +251,6 @@ void sip_platform_task_msgqwait (void *arg)
}
}
cprCloseSocket(sip_ipc_clnt_socket);
unlink(sip_clnt_sock_addr.sun_path); // removes tmp file
}
/**
@ -398,8 +272,8 @@ static void sip_process_int_msg (void)
phn_syshdr_t *syshdr;
/* read the msg count from the IPC socket */
rcv_len = cprRecvFrom(sip_ipc_serv_socket, &num_messages,
sizeof(num_messages), 0, NULL, NULL);
rcv_len = cprRecv(sip_ipc_serv_socket, &num_messages,
sizeof(num_messages), 0);
if (rcv_len < 0) {
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"read IPC failed:"
@ -425,20 +299,11 @@ static void sip_process_int_msg (void)
syshdr = int_msg->syshdr;
if (msg != NULL && syshdr != NULL) {
if (syshdr->Cmd == THREAD_UNLOAD) {
char stmpdir[sizeof(sip_serv_sock_addr.sun_path)];
/*
/*
* Cleanup here, as SIPTaskProcessListEvent wont return.
* - Remove last tmp file and tmp dir.
*/
cprCloseSocket(sip_ipc_serv_socket);
unlink(sip_serv_sock_addr.sun_path);
sip_get_sock_dir(stmpdir, sizeof(stmpdir), NULL);
if (rmdir(stmpdir) != 0) {
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to remove temp dir",
fname);
}
}
SIPTaskProcessListEvent(syshdr->Cmd, msg, syshdr->Usr.UsrPtr,
syshdr->Len);
@ -455,10 +320,8 @@ static void sip_process_int_msg (void)
/*
* Signal message queue waiting thread to get more messages.
*/
if (cprSendTo(sip_ipc_serv_socket, (void *)&response,
sizeof(response), 0,
(cpr_sockaddr_t *)&sip_clnt_sock_addr,
cpr_sun_len(sip_clnt_sock_addr)) < 0) {
if (cprSend(sip_ipc_serv_socket, (void *)&response,
sizeof(response), 0) < 0) {
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sending IPC", fname);
}
}
@ -511,21 +374,15 @@ sip_platform_task_loop (void *arg)
* Setup IPC socket addresses for main thread (server)
*/
{
char stmpdir[sizeof(sip_serv_sock_addr.sun_path)];
sip_get_sock_dir(stmpdir, sizeof(stmpdir), SIP_MSG_SERV_SUFFIX);
cpr_set_sockun_addr(&sip_serv_sock_addr, stmpdir, 0);
}
/*
* Create IPC between the message queue thread and this main
* thread.
*/
sip_ipc_serv_socket = sip_create_IPC_sock(sip_serv_sock_addr.sun_path);
if (sip_ipc_serv_socket == INVALID_SOCKET) {
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_create_IPC_sock() failed:"
cpr_socket_t sockets[2];
if (cprSocketPair(AF_LOCAL, SOCK_DGRAM, 0, sockets) == CPR_SUCCESS) {
sip_ipc_serv_socket = sockets[0];
sip_ipc_clnt_socket = sockets[1];
} else {
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"socketpair failed:"
" errno=%d\n", fname, cpr_errno);
return;
}
}
/*

Просмотреть файл

@ -706,6 +706,33 @@ cprSocket (uint32_t domain,
*/
/**
* cprSocketPair
*
* @brief The cprSocketPair() function is a wrapper for the "socketpair" API.
*
* The cprSocketPair() function creates a pair of connected, anonymous
* sockets of the given type. The parameters are as for cprSocket(),
* but domains other than AF_LOCAL (== AF_UNIX) may not be implemented.
*
* @param[in] domain The communications domain.
* @param[in] type The type of socket to be created.
* @param[in] protocol The protocol to be used with the socket.
* @param[out] sockets If successful, the two sockets created.
*
* @return On successful completion, CPR_SUCCESS; otherwise, CPR_FAILURE
* is returned and cpr_errno is set to indicate the error.
*/
cpr_status_e
cprSocketPair (uint32_t domain,
uint32_t type,
uint32_t protocol,
cpr_socket_t sockets[2])
{
return ((socketpair(domain, type, protocol, sockets) != 0)
? CPR_FAILURE : CPR_SUCCESS);
}
/* cpr_inet_pton
* Convert from presentation format (which usually means ASCII printable)

Просмотреть файл

@ -17,9 +17,6 @@
/**
* Set public CPR header file options
*/
#ifdef CPR_USE_SOCKETPAIR
#undef CPR_USE_SOCKETPAIR
#endif
#define SUPPORT_CONNECT_CONST const
/**

Просмотреть файл

@ -732,6 +732,33 @@ cprSocket (uint32_t domain,
*/
/**
* cprSocketPair
*
* @brief The cprSocketPair() function is a wrapper for the "socketpair" API.
*
* The cprSocketPair() function creates a pair of connected, anonymous
* sockets of the given type. The parameters are as for cprSocket(),
* but domains other than AF_LOCAL (== AF_UNIX) may not be implemented.
*
* @param[in] domain The communications domain.
* @param[in] type The type of socket to be created.
* @param[in] protocol The protocol to be used with the socket.
* @param[out] sockets If successful, the two sockets created.
*
* @return On successful completion, CPR_SUCCESS; otherwise, CPR_FAILURE
* is returned and cpr_errno is set to indicate the error.
*/
cpr_status_e
cprSocketPair (uint32_t domain,
uint32_t type,
uint32_t protocol,
cpr_socket_t sockets[2])
{
return ((socketpair(domain, type, protocol, sockets) != 0)
? CPR_FAILURE : CPR_SUCCESS);
}
/* cpr_inet_pton
* Convert from presentation format (which usually means ASCII printable)

Просмотреть файл

@ -30,9 +30,6 @@
/**
* Set public CPR header file options
*/
#ifdef CPR_USE_SOCKETPAIR
#undef CPR_USE_SOCKETPAIR
#endif
#define SUPPORT_CONNECT_CONST const
/**

Просмотреть файл

@ -680,6 +680,29 @@ cprSocket(uint32_t domain,
uint32_t type,
uint32_t protocol);
/**
* cprSocketPair
*
* @brief The cprSocketPair() function is a wrapper for the "socketpair" API.
*
* The cprSocketPair() function creates a pair of connected, anonymous
* sockets of the given type. The parameters are as for cprSocket(),
* but domains other than AF_LOCAL (== AF_UNIX) may not be implemented.
*
* @param[in] domain The communications domain.
* @param[in] type The type of socket to be created.
* @param[in] protocol The protocol to be used with the socket.
* @param[out] sockets If successful, the two sockets created.
*
* @return On successful completion, CPR_SUCCESS; otherwise, CPR_FAILURE
* is returned and cpr_errno is set to indicate the error.
*/
cpr_status_e
cprSocketPair(uint32_t domain,
uint32_t type,
uint32_t protocol,
cpr_socket_t sockets[2]);
/* cpr_inet_pton
* Convert from presentation format (which usually means ASCII printable)
* to network format (which is usually some kind of binary format).

Просмотреть файл

@ -712,6 +712,34 @@ cprSocket (uint32_t domain,
/**
* cprSocketPair
*
* @brief The cprSocketPair() function is a wrapper for the "socketpair" API.
*
* The cprSocketPair() function creates a pair of connected, anonymous
* sockets of the given type. The parameters are as for cprSocket(),
* but domains other than AF_LOCAL (== AF_UNIX) may not be implemented.
*
* @param[in] domain The communications domain.
* @param[in] type The type of socket to be created.
* @param[in] protocol The protocol to be used with the socket.
* @param[out] sockets If successful, the two sockets created.
*
* @return On successful completion, CPR_SUCCESS; otherwise, CPR_FAILURE
* is returned and cpr_errno is set to indicate the error.
*/
cpr_status_e
cprSocketPair (uint32_t domain,
uint32_t type,
uint32_t protocol,
cpr_socket_t sockets[2])
{
return ((socketpair(domain, type, protocol, sockets) != 0)
? CPR_FAILURE : CPR_SUCCESS);
}
/* cpr_inet_pton
* Convert from presentation format (which usually means ASCII printable)
* to network format (which is usually some kind of binary format).

Просмотреть файл

@ -17,9 +17,6 @@
/**
* Set public CPR header file options
*/
#ifdef CPR_USE_SOCKETPAIR
#undef CPR_USE_SOCKETPAIR
#endif
#define SUPPORT_CONNECT_CONST const
/**

Просмотреть файл

@ -166,6 +166,9 @@ cprTranslateErrno (void)
case WSAECONNREFUSED:
err = CPR_ECONNREFUSED;
break;
case WSAEOPNOTSUPP:
err = CPR_EOPNOTSUPP;
break;
}
return err;
}

Просмотреть файл

@ -825,22 +825,20 @@ cprSecSockIsConnected (cpr_socket_t sock)
#endif;
}
#ifdef CPR_USE_SOCKETPAIR
/*
* This is really only used in the UNIX domain and not recommended
* for use. The API is provided only for consistency to the POSIX
* definitions.
/**
* cprSocketPair
*
* @todo The socketpair() call is not supported on win32.
*/
cpr_status_e
cprSocketPair (uint32_t domain,
uint32_t type,
uint32_t protocol,
int socket_vector[2])
cpr_socket_t sockets[2])
{
return ((socketpair(domain, type, protocol, socket_vector) != 0) ?
CPR_FAILURE : CPR_SUCCESS);
WSASetLastError(WSAEOPNOTSUPP);
return CPR_FAILURE;
}
#endif
/* int

Просмотреть файл

@ -67,9 +67,5 @@ typedef unsigned short u_short;
#define SUPPORT_CONNECT_CONST const
#ifdef CPR_USE_SOCKETPAIR
#undef CPR_USE_SOCKETPAIR
#endif
#define MAX_RETRY_FOR_EAGAIN 10
#endif

Просмотреть файл

@ -27,6 +27,7 @@
/* Architecture-specific infrequently used syscalls */
#if defined(__arm__)
#define SECCOMP_WHITELIST_ARCH_LOW \
ALLOW_SYSCALL(_newselect), \
ALLOW_SYSCALL(_llseek), \
ALLOW_SYSCALL(getuid32), \
ALLOW_SYSCALL(geteuid32), \
@ -34,13 +35,15 @@
ALLOW_SYSCALL(fcntl64),
#elif defined(__i386__)
#define SECCOMP_WHITELIST_ARCH_LOW \
ALLOW_SYSCALL(_newselect), \
ALLOW_SYSCALL(_llseek), \
ALLOW_SYSCALL(getuid32), \
ALLOW_SYSCALL(geteuid32), \
ALLOW_SYSCALL(sigreturn), \
ALLOW_SYSCALL(fcntl64),
#else
#define SECCOMP_WHITELIST_ARCH_LOW
#define SECCOMP_WHITELIST_ARCH_LOW \
ALLOW_SYSCALL(select),
#endif
/* Architecture-specific very infrequently used syscalls */
@ -114,9 +117,11 @@
#define SECCOMP_WHITELIST_B2G_MED \
ALLOW_SYSCALL(getpid), \
ALLOW_SYSCALL(rt_sigreturn), \
ALLOW_SYSCALL(rt_sigreturn),
#define SECCOMP_WHITELIST_B2G_LOW \
ALLOW_SYSCALL(sendto), \
ALLOW_SYSCALL(recvfrom), \
ALLOW_SYSCALL(getdents64), \
ALLOW_SYSCALL(sched_setscheduler),