Refactor the regression test code by splitting huge monolithic C
file into smaller pieces that are hopefully easier to understand and extend. This is to pave the ground for adding few more socket timestamp formats that I am working on here. No functional changes (I hope).
This commit is contained in:
parent
65d5084f54
commit
1fab62b1e1
@ -1,6 +1,10 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= unix_cmsg
|
||||
SRCS= unix_cmsg.c t_bintime.h t_bintime.c uc_common.h uc_common.c \
|
||||
t_generic.h t_generic.c t_peercred.h t_peercred.c t_timeval.h \
|
||||
t_timeval.c t_cmsgcred.h t_cmsgcred.c t_sockcred.h t_sockcred.c \
|
||||
t_cmsgcred_sockcred.h t_cmsgcred_sockcred.c t_cmsg_len.h t_cmsg_len.c
|
||||
MAN=
|
||||
WARNS?= 3
|
||||
|
||||
|
156
tools/regression/sockets/unix_cmsg/t_bintime.c
Normal file
156
tools/regression/sockets/unix_cmsg/t_bintime.c
Normal file
@ -0,0 +1,156 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Andrey Simonenko
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "t_bintime.h"
|
||||
#include "t_generic.h"
|
||||
#include "uc_common.h"
|
||||
|
||||
static int
|
||||
check_scm_bintime(struct cmsghdr *cmsghdr)
|
||||
{
|
||||
const struct bintime *bt;
|
||||
|
||||
if (uc_check_cmsghdr(cmsghdr, SCM_BINTIME, sizeof(struct bintime)) < 0)
|
||||
return (-1);
|
||||
|
||||
bt = (struct bintime *)CMSG_DATA(cmsghdr);
|
||||
|
||||
uc_dbgmsg("bintime.sec %"PRIdMAX", bintime.frac %"PRIu64,
|
||||
(intmax_t)bt->sec, bt->frac);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
t_bintime_client(int fd)
|
||||
{
|
||||
struct msghdr msghdr;
|
||||
struct iovec iov[1];
|
||||
void *cmsg_data;
|
||||
size_t cmsg_size;
|
||||
int rv;
|
||||
|
||||
if (uc_sync_recv() < 0)
|
||||
return (-2);
|
||||
|
||||
rv = -2;
|
||||
|
||||
cmsg_size = CMSG_SPACE(sizeof(struct bintime));
|
||||
cmsg_data = malloc(cmsg_size);
|
||||
if (cmsg_data == NULL) {
|
||||
uc_logmsg("malloc");
|
||||
goto done;
|
||||
}
|
||||
uc_msghdr_init_client(&msghdr, iov, cmsg_data, cmsg_size,
|
||||
SCM_BINTIME, sizeof(struct bintime));
|
||||
|
||||
if (uc_socket_connect(fd) < 0)
|
||||
goto done;
|
||||
|
||||
if (uc_message_sendn(fd, &msghdr) < 0)
|
||||
goto done;
|
||||
|
||||
rv = 0;
|
||||
done:
|
||||
free(cmsg_data);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static int
|
||||
t_bintime_server(int fd1)
|
||||
{
|
||||
struct msghdr msghdr;
|
||||
struct iovec iov[1];
|
||||
struct cmsghdr *cmsghdr;
|
||||
void *cmsg_data;
|
||||
size_t cmsg_size;
|
||||
u_int i;
|
||||
int fd2, rv;
|
||||
|
||||
if (uc_sync_send() < 0)
|
||||
return (-2);
|
||||
|
||||
fd2 = -1;
|
||||
rv = -2;
|
||||
|
||||
cmsg_size = CMSG_SPACE(sizeof(struct bintime));
|
||||
cmsg_data = malloc(cmsg_size);
|
||||
if (cmsg_data == NULL) {
|
||||
uc_logmsg("malloc");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (uc_cfg.sock_type == SOCK_STREAM) {
|
||||
fd2 = uc_socket_accept(fd1);
|
||||
if (fd2 < 0)
|
||||
goto done;
|
||||
} else
|
||||
fd2 = fd1;
|
||||
|
||||
rv = -1;
|
||||
for (i = 1; i <= uc_cfg.ipc_msg.msg_num; ++i) {
|
||||
uc_dbgmsg("message #%u", i);
|
||||
|
||||
uc_msghdr_init_server(&msghdr, iov, cmsg_data, cmsg_size);
|
||||
if (uc_message_recv(fd2, &msghdr) < 0) {
|
||||
rv = -2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (uc_check_msghdr(&msghdr, sizeof(*cmsghdr)) < 0)
|
||||
break;
|
||||
|
||||
cmsghdr = CMSG_FIRSTHDR(&msghdr);
|
||||
if (check_scm_bintime(cmsghdr) < 0)
|
||||
break;
|
||||
}
|
||||
if (i > uc_cfg.ipc_msg.msg_num)
|
||||
rv = 0;
|
||||
done:
|
||||
free(cmsg_data);
|
||||
if (uc_cfg.sock_type == SOCK_STREAM && fd2 >= 0)
|
||||
if (uc_socket_close(fd2) < 0)
|
||||
rv = -2;
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
t_bintime(void)
|
||||
{
|
||||
return (t_generic(t_bintime_client, t_bintime_server));
|
||||
}
|
30
tools/regression/sockets/unix_cmsg/t_bintime.h
Normal file
30
tools/regression/sockets/unix_cmsg/t_bintime.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Andrey Simonenko
|
||||
* Copyright (c) 2016 Maksym Sobolyev <sobomax@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
int t_bintime(void);
|
138
tools/regression/sockets/unix_cmsg/t_cmsg_len.c
Normal file
138
tools/regression/sockets/unix_cmsg/t_cmsg_len.c
Normal file
@ -0,0 +1,138 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Andrey Simonenko
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <inttypes.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "uc_common.h"
|
||||
#include "t_generic.h"
|
||||
#include "t_cmsg_len.h"
|
||||
|
||||
#ifndef __LP64__
|
||||
static int
|
||||
t_cmsg_len_client(int fd)
|
||||
{
|
||||
struct msghdr msghdr;
|
||||
struct iovec iov[1];
|
||||
struct cmsghdr *cmsghdr;
|
||||
void *cmsg_data;
|
||||
size_t size, cmsg_size;
|
||||
socklen_t socklen;
|
||||
int rv;
|
||||
|
||||
if (uc_sync_recv() < 0)
|
||||
return (-2);
|
||||
|
||||
rv = -2;
|
||||
|
||||
cmsg_size = CMSG_SPACE(sizeof(struct cmsgcred));
|
||||
cmsg_data = malloc(cmsg_size);
|
||||
if (cmsg_data == NULL) {
|
||||
uc_logmsg("malloc");
|
||||
goto done;
|
||||
}
|
||||
uc_msghdr_init_client(&msghdr, iov, cmsg_data, cmsg_size,
|
||||
SCM_CREDS, sizeof(struct cmsgcred));
|
||||
cmsghdr = CMSG_FIRSTHDR(&msghdr);
|
||||
|
||||
if (uc_socket_connect(fd) < 0)
|
||||
goto done;
|
||||
|
||||
size = msghdr.msg_iov != NULL ? msghdr.msg_iov->iov_len : 0;
|
||||
rv = -1;
|
||||
for (socklen = 0; socklen < CMSG_LEN(0); ++socklen) {
|
||||
cmsghdr->cmsg_len = socklen;
|
||||
uc_dbgmsg("send: data size %zu", size);
|
||||
uc_dbgmsg("send: msghdr.msg_controllen %u",
|
||||
(u_int)msghdr.msg_controllen);
|
||||
uc_dbgmsg("send: cmsghdr.cmsg_len %u",
|
||||
(u_int)cmsghdr->cmsg_len);
|
||||
if (sendmsg(fd, &msghdr, 0) < 0) {
|
||||
uc_dbgmsg("sendmsg(2) failed: %s; retrying",
|
||||
strerror(errno));
|
||||
continue;
|
||||
}
|
||||
uc_logmsgx("sent message with cmsghdr.cmsg_len %u < %u",
|
||||
(u_int)cmsghdr->cmsg_len, (u_int)CMSG_LEN(0));
|
||||
break;
|
||||
}
|
||||
if (socklen == CMSG_LEN(0))
|
||||
rv = 0;
|
||||
|
||||
if (uc_sync_send() < 0) {
|
||||
rv = -2;
|
||||
goto done;
|
||||
}
|
||||
done:
|
||||
free(cmsg_data);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static int
|
||||
t_cmsg_len_server(int fd1)
|
||||
{
|
||||
int fd2, rv;
|
||||
|
||||
if (uc_sync_send() < 0)
|
||||
return (-2);
|
||||
|
||||
rv = -2;
|
||||
|
||||
if (uc_cfg.sock_type == SOCK_STREAM) {
|
||||
fd2 = uc_socket_accept(fd1);
|
||||
if (fd2 < 0)
|
||||
goto done;
|
||||
} else
|
||||
fd2 = fd1;
|
||||
|
||||
if (uc_sync_recv() < 0)
|
||||
goto done;
|
||||
|
||||
rv = 0;
|
||||
done:
|
||||
if (uc_cfg.sock_type == SOCK_STREAM && fd2 >= 0)
|
||||
if (uc_socket_close(fd2) < 0)
|
||||
rv = -2;
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
t_cmsg_len(void)
|
||||
{
|
||||
return (t_generic(t_cmsg_len_client, t_cmsg_len_server));
|
||||
}
|
||||
#endif
|
32
tools/regression/sockets/unix_cmsg/t_cmsg_len.h
Normal file
32
tools/regression/sockets/unix_cmsg/t_cmsg_len.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Andrey Simonenko
|
||||
* Copyright (c) 2016 Maksym Sobolyev <sobomax@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef __LP64__
|
||||
int t_cmsg_len(void);
|
||||
#endif
|
139
tools/regression/sockets/unix_cmsg/t_cmsgcred.c
Normal file
139
tools/regression/sockets/unix_cmsg/t_cmsgcred.c
Normal file
@ -0,0 +1,139 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Andrey Simonenko
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "uc_common.h"
|
||||
#include "t_generic.h"
|
||||
#include "t_cmsgcred.h"
|
||||
|
||||
int
|
||||
t_cmsgcred_client(int fd)
|
||||
{
|
||||
struct msghdr msghdr;
|
||||
struct iovec iov[1];
|
||||
void *cmsg_data;
|
||||
size_t cmsg_size;
|
||||
int rv;
|
||||
|
||||
if (uc_sync_recv() < 0)
|
||||
return (-2);
|
||||
|
||||
rv = -2;
|
||||
|
||||
cmsg_size = CMSG_SPACE(sizeof(struct cmsgcred));
|
||||
cmsg_data = malloc(cmsg_size);
|
||||
if (cmsg_data == NULL) {
|
||||
uc_logmsg("malloc");
|
||||
goto done;
|
||||
}
|
||||
uc_msghdr_init_client(&msghdr, iov, cmsg_data, cmsg_size,
|
||||
SCM_CREDS, sizeof(struct cmsgcred));
|
||||
|
||||
if (uc_socket_connect(fd) < 0)
|
||||
goto done;
|
||||
|
||||
if (uc_message_sendn(fd, &msghdr) < 0)
|
||||
goto done;
|
||||
|
||||
rv = 0;
|
||||
done:
|
||||
free(cmsg_data);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static int
|
||||
t_cmsgcred_server(int fd1)
|
||||
{
|
||||
struct msghdr msghdr;
|
||||
struct iovec iov[1];
|
||||
struct cmsghdr *cmsghdr;
|
||||
void *cmsg_data;
|
||||
size_t cmsg_size;
|
||||
u_int i;
|
||||
int fd2, rv;
|
||||
|
||||
if (uc_sync_send() < 0)
|
||||
return (-2);
|
||||
|
||||
fd2 = -1;
|
||||
rv = -2;
|
||||
|
||||
cmsg_size = CMSG_SPACE(sizeof(struct cmsgcred));
|
||||
cmsg_data = malloc(cmsg_size);
|
||||
if (cmsg_data == NULL) {
|
||||
uc_logmsg("malloc");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (uc_cfg.sock_type == SOCK_STREAM) {
|
||||
fd2 = uc_socket_accept(fd1);
|
||||
if (fd2 < 0)
|
||||
goto done;
|
||||
} else
|
||||
fd2 = fd1;
|
||||
|
||||
rv = -1;
|
||||
for (i = 1; i <= uc_cfg.ipc_msg.msg_num; ++i) {
|
||||
uc_dbgmsg("message #%u", i);
|
||||
|
||||
uc_msghdr_init_server(&msghdr, iov, cmsg_data, cmsg_size);
|
||||
if (uc_message_recv(fd2, &msghdr) < 0) {
|
||||
rv = -2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (uc_check_msghdr(&msghdr, sizeof(*cmsghdr)) < 0)
|
||||
break;
|
||||
|
||||
cmsghdr = CMSG_FIRSTHDR(&msghdr);
|
||||
if (uc_check_scm_creds_cmsgcred(cmsghdr) < 0)
|
||||
break;
|
||||
}
|
||||
if (i > uc_cfg.ipc_msg.msg_num)
|
||||
rv = 0;
|
||||
done:
|
||||
free(cmsg_data);
|
||||
if (uc_cfg.sock_type == SOCK_STREAM && fd2 >= 0)
|
||||
if (uc_socket_close(fd2) < 0)
|
||||
rv = -2;
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
t_cmsgcred(void)
|
||||
{
|
||||
return (t_generic(t_cmsgcred_client, t_cmsgcred_server));
|
||||
}
|
30
tools/regression/sockets/unix_cmsg/t_cmsgcred.h
Normal file
30
tools/regression/sockets/unix_cmsg/t_cmsgcred.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Andrey Simonenko
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
int t_cmsgcred_client(int fd);
|
||||
int t_cmsgcred(void);
|
125
tools/regression/sockets/unix_cmsg/t_cmsgcred_sockcred.c
Normal file
125
tools/regression/sockets/unix_cmsg/t_cmsgcred_sockcred.c
Normal file
@ -0,0 +1,125 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Andrey Simonenko
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "uc_common.h"
|
||||
#include "t_generic.h"
|
||||
#include "t_cmsgcred.h"
|
||||
#include "t_cmsgcred_sockcred.h"
|
||||
|
||||
static int
|
||||
t_cmsgcred_sockcred_server(int fd1)
|
||||
{
|
||||
struct msghdr msghdr;
|
||||
struct iovec iov[1];
|
||||
struct cmsghdr *cmsghdr;
|
||||
void *cmsg_data, *cmsg1_data, *cmsg2_data;
|
||||
size_t cmsg_size, cmsg1_size, cmsg2_size;
|
||||
u_int i;
|
||||
int fd2, rv, val;
|
||||
|
||||
fd2 = -1;
|
||||
rv = -2;
|
||||
|
||||
cmsg1_size = CMSG_SPACE(SOCKCREDSIZE(uc_cfg.proc_cred.gid_num));
|
||||
cmsg2_size = CMSG_SPACE(sizeof(struct cmsgcred));
|
||||
cmsg1_data = malloc(cmsg1_size);
|
||||
cmsg2_data = malloc(cmsg2_size);
|
||||
if (cmsg1_data == NULL || cmsg2_data == NULL) {
|
||||
uc_logmsg("malloc");
|
||||
goto done;
|
||||
}
|
||||
|
||||
uc_dbgmsg("setting LOCAL_CREDS");
|
||||
val = 1;
|
||||
if (setsockopt(fd1, 0, LOCAL_CREDS, &val, sizeof(val)) < 0) {
|
||||
uc_logmsg("setsockopt(LOCAL_CREDS)");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (uc_sync_send() < 0)
|
||||
goto done;
|
||||
|
||||
if (uc_cfg.sock_type == SOCK_STREAM) {
|
||||
fd2 = uc_socket_accept(fd1);
|
||||
if (fd2 < 0)
|
||||
goto done;
|
||||
} else
|
||||
fd2 = fd1;
|
||||
|
||||
cmsg_data = cmsg1_data;
|
||||
cmsg_size = cmsg1_size;
|
||||
rv = -1;
|
||||
for (i = 1; i <= uc_cfg.ipc_msg.msg_num; ++i) {
|
||||
uc_dbgmsg("message #%u", i);
|
||||
|
||||
uc_msghdr_init_server(&msghdr, iov, cmsg_data, cmsg_size);
|
||||
if (uc_message_recv(fd2, &msghdr) < 0) {
|
||||
rv = -2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (uc_check_msghdr(&msghdr, sizeof(*cmsghdr)) < 0)
|
||||
break;
|
||||
|
||||
cmsghdr = CMSG_FIRSTHDR(&msghdr);
|
||||
if (i == 1 || uc_cfg.sock_type == SOCK_DGRAM) {
|
||||
if (uc_check_scm_creds_sockcred(cmsghdr) < 0)
|
||||
break;
|
||||
} else {
|
||||
if (uc_check_scm_creds_cmsgcred(cmsghdr) < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
cmsg_data = cmsg2_data;
|
||||
cmsg_size = cmsg2_size;
|
||||
}
|
||||
if (i > uc_cfg.ipc_msg.msg_num)
|
||||
rv = 0;
|
||||
done:
|
||||
free(cmsg1_data);
|
||||
free(cmsg2_data);
|
||||
if (uc_cfg.sock_type == SOCK_STREAM && fd2 >= 0)
|
||||
if (uc_socket_close(fd2) < 0)
|
||||
rv = -2;
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
t_cmsgcred_sockcred(void)
|
||||
{
|
||||
return (t_generic(t_cmsgcred_client, t_cmsgcred_sockcred_server));
|
||||
}
|
30
tools/regression/sockets/unix_cmsg/t_cmsgcred_sockcred.h
Normal file
30
tools/regression/sockets/unix_cmsg/t_cmsgcred_sockcred.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Andrey Simonenko
|
||||
* Copyright (c) 2016 Maksym Sobolyev <sobomax@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
int t_cmsgcred_sockcred(void);
|
73
tools/regression/sockets/unix_cmsg/t_generic.c
Normal file
73
tools/regression/sockets/unix_cmsg/t_generic.c
Normal file
@ -0,0 +1,73 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Andrey Simonenko
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "uc_common.h"
|
||||
#include "t_generic.h"
|
||||
|
||||
int
|
||||
t_generic(int (*client_func)(int), int (*server_func)(int))
|
||||
{
|
||||
int fd, rv, rv_client;
|
||||
|
||||
switch (uc_client_fork()) {
|
||||
case 0:
|
||||
fd = uc_socket_create();
|
||||
if (fd < 0)
|
||||
rv = -2;
|
||||
else {
|
||||
rv = client_func(fd);
|
||||
if (uc_socket_close(fd) < 0)
|
||||
rv = -2;
|
||||
}
|
||||
uc_client_exit(rv);
|
||||
break;
|
||||
case 1:
|
||||
fd = uc_socket_create();
|
||||
if (fd < 0)
|
||||
rv = -2;
|
||||
else {
|
||||
rv = server_func(fd);
|
||||
rv_client = uc_client_wait();
|
||||
if (rv == 0 || (rv == -2 && rv_client != 0))
|
||||
rv = rv_client;
|
||||
if (uc_socket_close(fd) < 0)
|
||||
rv = -2;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rv = -2;
|
||||
}
|
||||
return (rv);
|
||||
}
|
30
tools/regression/sockets/unix_cmsg/t_generic.h
Normal file
30
tools/regression/sockets/unix_cmsg/t_generic.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Andrey Simonenko
|
||||
* Copyright (c) 2016 Maksym Sobolyev <sobomax@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
int t_generic(int (*client_func)(int), int (*server_func)(int));
|
153
tools/regression/sockets/unix_cmsg/t_peercred.c
Normal file
153
tools/regression/sockets/unix_cmsg/t_peercred.c
Normal file
@ -0,0 +1,153 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Andrey Simonenko
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ucred.h>
|
||||
#include <sys/un.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "uc_common.h"
|
||||
#include "t_generic.h"
|
||||
#include "t_peercred.h"
|
||||
|
||||
static int
|
||||
check_xucred(const struct xucred *xucred, socklen_t len)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (len != sizeof(*xucred)) {
|
||||
uc_logmsgx("option value size %zu != %zu",
|
||||
(size_t)len, sizeof(*xucred));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
uc_dbgmsg("xucred.cr_version %u", xucred->cr_version);
|
||||
uc_dbgmsg("xucred.cr_uid %lu", (u_long)xucred->cr_uid);
|
||||
uc_dbgmsg("xucred.cr_ngroups %d", xucred->cr_ngroups);
|
||||
|
||||
rc = 0;
|
||||
|
||||
if (xucred->cr_version != XUCRED_VERSION) {
|
||||
uc_logmsgx("xucred.cr_version %u != %d",
|
||||
xucred->cr_version, XUCRED_VERSION);
|
||||
rc = -1;
|
||||
}
|
||||
if (xucred->cr_uid != uc_cfg.proc_cred.euid) {
|
||||
uc_logmsgx("xucred.cr_uid %lu != %lu (EUID)",
|
||||
(u_long)xucred->cr_uid, (u_long)uc_cfg.proc_cred.euid);
|
||||
rc = -1;
|
||||
}
|
||||
if (xucred->cr_ngroups == 0) {
|
||||
uc_logmsgx("xucred.cr_ngroups == 0");
|
||||
rc = -1;
|
||||
}
|
||||
if (xucred->cr_ngroups < 0) {
|
||||
uc_logmsgx("xucred.cr_ngroups < 0");
|
||||
rc = -1;
|
||||
}
|
||||
if (xucred->cr_ngroups > XU_NGROUPS) {
|
||||
uc_logmsgx("xucred.cr_ngroups %hu > %u (max)",
|
||||
xucred->cr_ngroups, XU_NGROUPS);
|
||||
rc = -1;
|
||||
}
|
||||
if (xucred->cr_groups[0] != uc_cfg.proc_cred.egid) {
|
||||
uc_logmsgx("xucred.cr_groups[0] %lu != %lu (EGID)",
|
||||
(u_long)xucred->cr_groups[0], (u_long)uc_cfg.proc_cred.egid);
|
||||
rc = -1;
|
||||
}
|
||||
if (uc_check_groups("xucred.cr_groups", xucred->cr_groups,
|
||||
"xucred.cr_ngroups", xucred->cr_ngroups, false) < 0)
|
||||
rc = -1;
|
||||
return (rc);
|
||||
}
|
||||
|
||||
static int
|
||||
t_peercred_client(int fd)
|
||||
{
|
||||
struct xucred xucred;
|
||||
socklen_t len;
|
||||
|
||||
if (uc_sync_recv() < 0)
|
||||
return (-1);
|
||||
|
||||
if (uc_socket_connect(fd) < 0)
|
||||
return (-1);
|
||||
|
||||
len = sizeof(xucred);
|
||||
if (getsockopt(fd, 0, LOCAL_PEERCRED, &xucred, &len) < 0) {
|
||||
uc_logmsg("getsockopt(LOCAL_PEERCRED)");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (check_xucred(&xucred, len) < 0)
|
||||
return (-1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
t_peercred_server(int fd1)
|
||||
{
|
||||
struct xucred xucred;
|
||||
socklen_t len;
|
||||
int fd2, rv;
|
||||
|
||||
if (uc_sync_send() < 0)
|
||||
return (-2);
|
||||
|
||||
fd2 = uc_socket_accept(fd1);
|
||||
if (fd2 < 0)
|
||||
return (-2);
|
||||
|
||||
len = sizeof(xucred);
|
||||
if (getsockopt(fd2, 0, LOCAL_PEERCRED, &xucred, &len) < 0) {
|
||||
uc_logmsg("getsockopt(LOCAL_PEERCRED)");
|
||||
rv = -2;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (check_xucred(&xucred, len) < 0) {
|
||||
rv = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rv = 0;
|
||||
done:
|
||||
if (uc_socket_close(fd2) < 0)
|
||||
rv = -2;
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
t_peercred(void)
|
||||
{
|
||||
return (t_generic(t_peercred_client, t_peercred_server));
|
||||
}
|
29
tools/regression/sockets/unix_cmsg/t_peercred.h
Normal file
29
tools/regression/sockets/unix_cmsg/t_peercred.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Andrey Simonenko
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
int t_peercred(void);
|
215
tools/regression/sockets/unix_cmsg/t_sockcred.c
Normal file
215
tools/regression/sockets/unix_cmsg/t_sockcred.c
Normal file
@ -0,0 +1,215 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Andrey Simonenko
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "uc_common.h"
|
||||
#include "t_generic.h"
|
||||
#include "t_sockcred.h"
|
||||
|
||||
static int
|
||||
t_sockcred_client(int type, int fd)
|
||||
{
|
||||
struct msghdr msghdr;
|
||||
struct iovec iov[1];
|
||||
int rv;
|
||||
|
||||
if (uc_sync_recv() < 0)
|
||||
return (-2);
|
||||
|
||||
rv = -2;
|
||||
|
||||
uc_msghdr_init_client(&msghdr, iov, NULL, 0, 0, 0);
|
||||
|
||||
if (uc_socket_connect(fd) < 0)
|
||||
goto done;
|
||||
|
||||
if (type == 2)
|
||||
if (uc_sync_recv() < 0)
|
||||
goto done;
|
||||
|
||||
if (uc_message_sendn(fd, &msghdr) < 0)
|
||||
goto done;
|
||||
|
||||
rv = 0;
|
||||
done:
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static int
|
||||
t_sockcred_server(int type, int fd1)
|
||||
{
|
||||
struct msghdr msghdr;
|
||||
struct iovec iov[1];
|
||||
struct cmsghdr *cmsghdr;
|
||||
void *cmsg_data;
|
||||
size_t cmsg_size;
|
||||
u_int i;
|
||||
int fd2, rv, val;
|
||||
|
||||
fd2 = -1;
|
||||
rv = -2;
|
||||
|
||||
cmsg_size = CMSG_SPACE(SOCKCREDSIZE(uc_cfg.proc_cred.gid_num));
|
||||
cmsg_data = malloc(cmsg_size);
|
||||
if (cmsg_data == NULL) {
|
||||
uc_logmsg("malloc");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (type == 1) {
|
||||
uc_dbgmsg("setting LOCAL_CREDS");
|
||||
val = 1;
|
||||
if (setsockopt(fd1, 0, LOCAL_CREDS, &val, sizeof(val)) < 0) {
|
||||
uc_logmsg("setsockopt(LOCAL_CREDS)");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (uc_sync_send() < 0)
|
||||
goto done;
|
||||
|
||||
if (uc_cfg.sock_type == SOCK_STREAM) {
|
||||
fd2 = uc_socket_accept(fd1);
|
||||
if (fd2 < 0)
|
||||
goto done;
|
||||
} else
|
||||
fd2 = fd1;
|
||||
|
||||
if (type == 2) {
|
||||
uc_dbgmsg("setting LOCAL_CREDS");
|
||||
val = 1;
|
||||
if (setsockopt(fd2, 0, LOCAL_CREDS, &val, sizeof(val)) < 0) {
|
||||
uc_logmsg("setsockopt(LOCAL_CREDS)");
|
||||
goto done;
|
||||
}
|
||||
if (uc_sync_send() < 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
rv = -1;
|
||||
for (i = 1; i <= uc_cfg.ipc_msg.msg_num; ++i) {
|
||||
uc_dbgmsg("message #%u", i);
|
||||
|
||||
uc_msghdr_init_server(&msghdr, iov, cmsg_data, cmsg_size);
|
||||
if (uc_message_recv(fd2, &msghdr) < 0) {
|
||||
rv = -2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i > 1 && uc_cfg.sock_type == SOCK_STREAM) {
|
||||
if (uc_check_msghdr(&msghdr, 0) < 0)
|
||||
break;
|
||||
} else {
|
||||
if (uc_check_msghdr(&msghdr, sizeof(*cmsghdr)) < 0)
|
||||
break;
|
||||
|
||||
cmsghdr = CMSG_FIRSTHDR(&msghdr);
|
||||
if (uc_check_scm_creds_sockcred(cmsghdr) < 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i > uc_cfg.ipc_msg.msg_num)
|
||||
rv = 0;
|
||||
done:
|
||||
free(cmsg_data);
|
||||
if (uc_cfg.sock_type == SOCK_STREAM && fd2 >= 0)
|
||||
if (uc_socket_close(fd2) < 0)
|
||||
rv = -2;
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
t_sockcred_1(void)
|
||||
{
|
||||
u_int i;
|
||||
int fd, rv, rv_client;
|
||||
|
||||
switch (uc_client_fork()) {
|
||||
case 0:
|
||||
for (i = 1; i <= 2; ++i) {
|
||||
uc_dbgmsg("client #%u", i);
|
||||
fd = uc_socket_create();
|
||||
if (fd < 0)
|
||||
rv = -2;
|
||||
else {
|
||||
rv = t_sockcred_client(1, fd);
|
||||
if (uc_socket_close(fd) < 0)
|
||||
rv = -2;
|
||||
}
|
||||
if (rv != 0)
|
||||
break;
|
||||
}
|
||||
uc_client_exit(rv);
|
||||
break;
|
||||
case 1:
|
||||
fd = uc_socket_create();
|
||||
if (fd < 0)
|
||||
rv = -2;
|
||||
else {
|
||||
rv = t_sockcred_server(1, fd);
|
||||
if (rv == 0)
|
||||
rv = t_sockcred_server(3, fd);
|
||||
rv_client = uc_client_wait();
|
||||
if (rv == 0 || (rv == -2 && rv_client != 0))
|
||||
rv = rv_client;
|
||||
if (uc_socket_close(fd) < 0)
|
||||
rv = -2;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rv = -2;
|
||||
}
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static int
|
||||
t_sockcred_2_client(int fd)
|
||||
{
|
||||
return (t_sockcred_client(2, fd));
|
||||
}
|
||||
|
||||
static int
|
||||
t_sockcred_2_server(int fd)
|
||||
{
|
||||
return (t_sockcred_server(2, fd));
|
||||
}
|
||||
|
||||
int
|
||||
t_sockcred_2(void)
|
||||
{
|
||||
return (t_generic(t_sockcred_2_client, t_sockcred_2_server));
|
||||
}
|
31
tools/regression/sockets/unix_cmsg/t_sockcred.h
Normal file
31
tools/regression/sockets/unix_cmsg/t_sockcred.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Andrey Simonenko
|
||||
* Copyright (c) 2016 Maksym Sobolyev <sobomax@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
int t_sockcred_1(void);
|
||||
int t_sockcred_2(void);
|
155
tools/regression/sockets/unix_cmsg/t_timeval.c
Normal file
155
tools/regression/sockets/unix_cmsg/t_timeval.c
Normal file
@ -0,0 +1,155 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Andrey Simonenko
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "uc_common.h"
|
||||
#include "t_generic.h"
|
||||
#include "t_timeval.h"
|
||||
|
||||
static int
|
||||
check_scm_timestamp(struct cmsghdr *cmsghdr)
|
||||
{
|
||||
const struct timeval *tv;
|
||||
|
||||
if (uc_check_cmsghdr(cmsghdr, SCM_TIMESTAMP, sizeof(struct timeval)) < 0)
|
||||
return (-1);
|
||||
|
||||
tv = (struct timeval *)CMSG_DATA(cmsghdr);
|
||||
|
||||
uc_dbgmsg("timeval.tv_sec %"PRIdMAX", timeval.tv_usec %"PRIdMAX,
|
||||
(intmax_t)tv->tv_sec, (intmax_t)tv->tv_usec);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
t_timeval_client(int fd)
|
||||
{
|
||||
struct msghdr msghdr;
|
||||
struct iovec iov[1];
|
||||
void *cmsg_data;
|
||||
size_t cmsg_size;
|
||||
int rv;
|
||||
|
||||
if (uc_sync_recv() < 0)
|
||||
return (-2);
|
||||
|
||||
rv = -2;
|
||||
|
||||
cmsg_size = CMSG_SPACE(sizeof(struct timeval));
|
||||
cmsg_data = malloc(cmsg_size);
|
||||
if (cmsg_data == NULL) {
|
||||
uc_logmsg("malloc");
|
||||
goto done;
|
||||
}
|
||||
uc_msghdr_init_client(&msghdr, iov, cmsg_data, cmsg_size,
|
||||
SCM_TIMESTAMP, sizeof(struct timeval));
|
||||
|
||||
if (uc_socket_connect(fd) < 0)
|
||||
goto done;
|
||||
|
||||
if (uc_message_sendn(fd, &msghdr) < 0)
|
||||
goto done;
|
||||
|
||||
rv = 0;
|
||||
done:
|
||||
free(cmsg_data);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static int
|
||||
t_timeval_server(int fd1)
|
||||
{
|
||||
struct msghdr msghdr;
|
||||
struct iovec iov[1];
|
||||
struct cmsghdr *cmsghdr;
|
||||
void *cmsg_data;
|
||||
size_t cmsg_size;
|
||||
u_int i;
|
||||
int fd2, rv;
|
||||
|
||||
if (uc_sync_send() < 0)
|
||||
return (-2);
|
||||
|
||||
fd2 = -1;
|
||||
rv = -2;
|
||||
|
||||
cmsg_size = CMSG_SPACE(sizeof(struct timeval));
|
||||
cmsg_data = malloc(cmsg_size);
|
||||
if (cmsg_data == NULL) {
|
||||
uc_logmsg("malloc");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (uc_cfg.sock_type == SOCK_STREAM) {
|
||||
fd2 = uc_socket_accept(fd1);
|
||||
if (fd2 < 0)
|
||||
goto done;
|
||||
} else
|
||||
fd2 = fd1;
|
||||
|
||||
rv = -1;
|
||||
for (i = 1; i <= uc_cfg.ipc_msg.msg_num; ++i) {
|
||||
uc_dbgmsg("message #%u", i);
|
||||
|
||||
uc_msghdr_init_server(&msghdr, iov, cmsg_data, cmsg_size);
|
||||
if (uc_message_recv(fd2, &msghdr) < 0) {
|
||||
rv = -2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (uc_check_msghdr(&msghdr, sizeof(*cmsghdr)) < 0)
|
||||
break;
|
||||
|
||||
cmsghdr = CMSG_FIRSTHDR(&msghdr);
|
||||
if (check_scm_timestamp(cmsghdr) < 0)
|
||||
break;
|
||||
}
|
||||
if (i > uc_cfg.ipc_msg.msg_num)
|
||||
rv = 0;
|
||||
done:
|
||||
free(cmsg_data);
|
||||
if (uc_cfg.sock_type == SOCK_STREAM && fd2 >= 0)
|
||||
if (uc_socket_close(fd2) < 0)
|
||||
rv = -2;
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
t_timeval(void)
|
||||
{
|
||||
return (t_generic(t_timeval_client, t_timeval_server));
|
||||
}
|
29
tools/regression/sockets/unix_cmsg/t_timeval.h
Normal file
29
tools/regression/sockets/unix_cmsg/t_timeval.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Andrey Simonenko
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
int t_timeval(void);
|
744
tools/regression/sockets/unix_cmsg/uc_common.c
Normal file
744
tools/regression/sockets/unix_cmsg/uc_common.c
Normal file
@ -0,0 +1,744 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Andrey Simonenko
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "uc_common.h"
|
||||
|
||||
#ifndef LISTENQ
|
||||
# define LISTENQ 1
|
||||
#endif
|
||||
|
||||
#ifndef TIMEOUT
|
||||
# define TIMEOUT 2
|
||||
#endif
|
||||
|
||||
#define SYNC_SERVER 0
|
||||
#define SYNC_CLIENT 1
|
||||
#define SYNC_RECV 0
|
||||
#define SYNC_SEND 1
|
||||
|
||||
#define LOGMSG_SIZE 128
|
||||
|
||||
void
|
||||
uc_output(const char *format, ...)
|
||||
{
|
||||
char buf[LOGMSG_SIZE];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
if (vsnprintf(buf, sizeof(buf), format, ap) < 0)
|
||||
err(EXIT_FAILURE, "output: vsnprintf failed");
|
||||
write(STDOUT_FILENO, buf, strlen(buf));
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
uc_logmsg(const char *format, ...)
|
||||
{
|
||||
char buf[LOGMSG_SIZE];
|
||||
va_list ap;
|
||||
int errno_save;
|
||||
|
||||
errno_save = errno;
|
||||
va_start(ap, format);
|
||||
if (vsnprintf(buf, sizeof(buf), format, ap) < 0)
|
||||
err(EXIT_FAILURE, "logmsg: vsnprintf failed");
|
||||
if (errno_save == 0)
|
||||
uc_output("%s: %s\n", uc_cfg.proc_name, buf);
|
||||
else
|
||||
uc_output("%s: %s: %s\n", uc_cfg.proc_name, buf,
|
||||
strerror(errno_save));
|
||||
va_end(ap);
|
||||
errno = errno_save;
|
||||
}
|
||||
|
||||
void
|
||||
uc_vlogmsgx(const char *format, va_list ap)
|
||||
{
|
||||
char buf[LOGMSG_SIZE];
|
||||
|
||||
if (vsnprintf(buf, sizeof(buf), format, ap) < 0)
|
||||
err(EXIT_FAILURE, "uc_logmsgx: vsnprintf failed");
|
||||
uc_output("%s: %s\n", uc_cfg.proc_name, buf);
|
||||
}
|
||||
|
||||
void
|
||||
uc_logmsgx(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
uc_vlogmsgx(format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
uc_dbgmsg(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (uc_cfg.debug) {
|
||||
va_start(ap, format);
|
||||
uc_vlogmsgx(format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
uc_socket_create(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
int fd;
|
||||
|
||||
fd = socket(PF_LOCAL, uc_cfg.sock_type, 0);
|
||||
if (fd < 0) {
|
||||
uc_logmsg("socket_create: socket(PF_LOCAL, %s, 0)", uc_cfg.sock_type_str);
|
||||
return (-1);
|
||||
}
|
||||
if (uc_cfg.server_flag)
|
||||
uc_cfg.serv_sock_fd = fd;
|
||||
|
||||
tv.tv_sec = TIMEOUT;
|
||||
tv.tv_usec = 0;
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0 ||
|
||||
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0) {
|
||||
uc_logmsg("socket_create: setsockopt(SO_RCVTIMEO/SO_SNDTIMEO)");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (uc_cfg.server_flag) {
|
||||
if (bind(fd, (struct sockaddr *)&uc_cfg.serv_addr_sun,
|
||||
uc_cfg.serv_addr_sun.sun_len) < 0) {
|
||||
uc_logmsg("socket_create: bind(%s)",
|
||||
uc_cfg.serv_addr_sun.sun_path);
|
||||
goto failed;
|
||||
}
|
||||
if (uc_cfg.sock_type == SOCK_STREAM) {
|
||||
int val;
|
||||
|
||||
if (listen(fd, LISTENQ) < 0) {
|
||||
uc_logmsg("socket_create: listen");
|
||||
goto failed;
|
||||
}
|
||||
val = fcntl(fd, F_GETFL, 0);
|
||||
if (val < 0) {
|
||||
uc_logmsg("socket_create: fcntl(F_GETFL)");
|
||||
goto failed;
|
||||
}
|
||||
if (fcntl(fd, F_SETFL, val | O_NONBLOCK) < 0) {
|
||||
uc_logmsg("socket_create: fcntl(F_SETFL)");
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (fd);
|
||||
|
||||
failed:
|
||||
if (close(fd) < 0)
|
||||
uc_logmsg("socket_create: close");
|
||||
if (uc_cfg.server_flag)
|
||||
if (unlink(uc_cfg.serv_addr_sun.sun_path) < 0)
|
||||
uc_logmsg("socket_close: unlink(%s)",
|
||||
uc_cfg.serv_addr_sun.sun_path);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
uc_socket_close(int fd)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = 0;
|
||||
if (close(fd) < 0) {
|
||||
uc_logmsg("socket_close: close");
|
||||
rv = -1;
|
||||
}
|
||||
if (uc_cfg.server_flag && fd == uc_cfg.serv_sock_fd)
|
||||
if (unlink(uc_cfg.serv_addr_sun.sun_path) < 0) {
|
||||
uc_logmsg("socket_close: unlink(%s)",
|
||||
uc_cfg.serv_addr_sun.sun_path);
|
||||
rv = -1;
|
||||
}
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
uc_socket_connect(int fd)
|
||||
{
|
||||
uc_dbgmsg("connect");
|
||||
|
||||
if (connect(fd, (struct sockaddr *)&uc_cfg.serv_addr_sun,
|
||||
uc_cfg.serv_addr_sun.sun_len) < 0) {
|
||||
uc_logmsg("socket_connect: connect(%s)", uc_cfg.serv_addr_sun.sun_path);
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
uc_sync_recv(void)
|
||||
{
|
||||
ssize_t ssize;
|
||||
int fd;
|
||||
char buf;
|
||||
|
||||
uc_dbgmsg("sync: wait");
|
||||
|
||||
fd = uc_cfg.sync_fd[uc_cfg.server_flag ? SYNC_SERVER : SYNC_CLIENT][SYNC_RECV];
|
||||
|
||||
ssize = read(fd, &buf, 1);
|
||||
if (ssize < 0) {
|
||||
uc_logmsg("sync_recv: read");
|
||||
return (-1);
|
||||
}
|
||||
if (ssize < 1) {
|
||||
uc_logmsgx("sync_recv: read %zd of 1 byte", ssize);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
uc_dbgmsg("sync: received");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
uc_sync_send(void)
|
||||
{
|
||||
ssize_t ssize;
|
||||
int fd;
|
||||
|
||||
uc_dbgmsg("sync: send");
|
||||
|
||||
fd = uc_cfg.sync_fd[uc_cfg.server_flag ? SYNC_CLIENT : SYNC_SERVER][SYNC_SEND];
|
||||
|
||||
ssize = write(fd, "", 1);
|
||||
if (ssize < 0) {
|
||||
uc_logmsg("uc_sync_send: write");
|
||||
return (-1);
|
||||
}
|
||||
if (ssize < 1) {
|
||||
uc_logmsgx("uc_sync_send: sent %zd of 1 byte", ssize);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
uc_message_send(int fd, const struct msghdr *msghdr)
|
||||
{
|
||||
const struct cmsghdr *cmsghdr;
|
||||
size_t size;
|
||||
ssize_t ssize;
|
||||
|
||||
size = msghdr->msg_iov != 0 ? msghdr->msg_iov->iov_len : 0;
|
||||
uc_dbgmsg("send: data size %zu", size);
|
||||
uc_dbgmsg("send: msghdr.msg_controllen %u",
|
||||
(u_int)msghdr->msg_controllen);
|
||||
cmsghdr = CMSG_FIRSTHDR(msghdr);
|
||||
if (cmsghdr != NULL)
|
||||
uc_dbgmsg("send: cmsghdr.cmsg_len %u",
|
||||
(u_int)cmsghdr->cmsg_len);
|
||||
|
||||
ssize = sendmsg(fd, msghdr, 0);
|
||||
if (ssize < 0) {
|
||||
uc_logmsg("message_send: sendmsg");
|
||||
return (-1);
|
||||
}
|
||||
if ((size_t)ssize != size) {
|
||||
uc_logmsgx("message_send: sendmsg: sent %zd of %zu bytes",
|
||||
ssize, size);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (!uc_cfg.send_data_flag)
|
||||
if (uc_sync_send() < 0)
|
||||
return (-1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
uc_message_sendn(int fd, struct msghdr *msghdr)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
for (i = 1; i <= uc_cfg.ipc_msg.msg_num; ++i) {
|
||||
uc_dbgmsg("message #%u", i);
|
||||
if (uc_message_send(fd, msghdr) < 0)
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
uc_message_recv(int fd, struct msghdr *msghdr)
|
||||
{
|
||||
const struct cmsghdr *cmsghdr;
|
||||
size_t size;
|
||||
ssize_t ssize;
|
||||
|
||||
if (!uc_cfg.send_data_flag)
|
||||
if (uc_sync_recv() < 0)
|
||||
return (-1);
|
||||
|
||||
size = msghdr->msg_iov != NULL ? msghdr->msg_iov->iov_len : 0;
|
||||
ssize = recvmsg(fd, msghdr, MSG_WAITALL);
|
||||
if (ssize < 0) {
|
||||
uc_logmsg("message_recv: recvmsg");
|
||||
return (-1);
|
||||
}
|
||||
if ((size_t)ssize != size) {
|
||||
uc_logmsgx("message_recv: recvmsg: received %zd of %zu bytes",
|
||||
ssize, size);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
uc_dbgmsg("recv: data size %zd", ssize);
|
||||
uc_dbgmsg("recv: msghdr.msg_controllen %u",
|
||||
(u_int)msghdr->msg_controllen);
|
||||
cmsghdr = CMSG_FIRSTHDR(msghdr);
|
||||
if (cmsghdr != NULL)
|
||||
uc_dbgmsg("recv: cmsghdr.cmsg_len %u",
|
||||
(u_int)cmsghdr->cmsg_len);
|
||||
|
||||
if (memcmp(uc_cfg.ipc_msg.buf_recv, uc_cfg.ipc_msg.buf_send, size) != 0) {
|
||||
uc_logmsgx("message_recv: received message has wrong content");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
uc_socket_accept(int listenfd)
|
||||
{
|
||||
fd_set rset;
|
||||
struct timeval tv;
|
||||
int fd, rv, val;
|
||||
|
||||
uc_dbgmsg("accept");
|
||||
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(listenfd, &rset);
|
||||
tv.tv_sec = TIMEOUT;
|
||||
tv.tv_usec = 0;
|
||||
rv = select(listenfd + 1, &rset, (fd_set *)NULL, (fd_set *)NULL, &tv);
|
||||
if (rv < 0) {
|
||||
uc_logmsg("socket_accept: select");
|
||||
return (-1);
|
||||
}
|
||||
if (rv == 0) {
|
||||
uc_logmsgx("socket_accept: select timeout");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
fd = accept(listenfd, (struct sockaddr *)NULL, (socklen_t *)NULL);
|
||||
if (fd < 0) {
|
||||
uc_logmsg("socket_accept: accept");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
val = fcntl(fd, F_GETFL, 0);
|
||||
if (val < 0) {
|
||||
uc_logmsg("socket_accept: fcntl(F_GETFL)");
|
||||
goto failed;
|
||||
}
|
||||
if (fcntl(fd, F_SETFL, val & ~O_NONBLOCK) < 0) {
|
||||
uc_logmsg("socket_accept: fcntl(F_SETFL)");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return (fd);
|
||||
|
||||
failed:
|
||||
if (close(fd) < 0)
|
||||
uc_logmsg("socket_accept: close");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
uc_check_msghdr(const struct msghdr *msghdr, size_t size)
|
||||
{
|
||||
if (msghdr->msg_flags & MSG_TRUNC) {
|
||||
uc_logmsgx("msghdr.msg_flags has MSG_TRUNC");
|
||||
return (-1);
|
||||
}
|
||||
if (msghdr->msg_flags & MSG_CTRUNC) {
|
||||
uc_logmsgx("msghdr.msg_flags has MSG_CTRUNC");
|
||||
return (-1);
|
||||
}
|
||||
if (msghdr->msg_controllen < size) {
|
||||
uc_logmsgx("msghdr.msg_controllen %u < %zu",
|
||||
(u_int)msghdr->msg_controllen, size);
|
||||
return (-1);
|
||||
}
|
||||
if (msghdr->msg_controllen > 0 && size == 0) {
|
||||
uc_logmsgx("msghdr.msg_controllen %u > 0",
|
||||
(u_int)msghdr->msg_controllen);
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
uc_check_cmsghdr(const struct cmsghdr *cmsghdr, int type, size_t size)
|
||||
{
|
||||
if (cmsghdr == NULL) {
|
||||
uc_logmsgx("cmsghdr is NULL");
|
||||
return (-1);
|
||||
}
|
||||
if (cmsghdr->cmsg_level != SOL_SOCKET) {
|
||||
uc_logmsgx("cmsghdr.cmsg_level %d != SOL_SOCKET",
|
||||
cmsghdr->cmsg_level);
|
||||
return (-1);
|
||||
}
|
||||
if (cmsghdr->cmsg_type != type) {
|
||||
uc_logmsgx("cmsghdr.cmsg_type %d != %d",
|
||||
cmsghdr->cmsg_type, type);
|
||||
return (-1);
|
||||
}
|
||||
if (cmsghdr->cmsg_len != CMSG_LEN(size)) {
|
||||
uc_logmsgx("cmsghdr.cmsg_len %u != %zu",
|
||||
(u_int)cmsghdr->cmsg_len, CMSG_LEN(size));
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
uc_msghdr_init_generic(struct msghdr *msghdr, struct iovec *iov, void *cmsg_data)
|
||||
{
|
||||
msghdr->msg_name = NULL;
|
||||
msghdr->msg_namelen = 0;
|
||||
if (uc_cfg.send_data_flag) {
|
||||
iov->iov_base = uc_cfg.server_flag ?
|
||||
uc_cfg.ipc_msg.buf_recv : uc_cfg.ipc_msg.buf_send;
|
||||
iov->iov_len = uc_cfg.ipc_msg.buf_size;
|
||||
msghdr->msg_iov = iov;
|
||||
msghdr->msg_iovlen = 1;
|
||||
} else {
|
||||
msghdr->msg_iov = NULL;
|
||||
msghdr->msg_iovlen = 0;
|
||||
}
|
||||
msghdr->msg_control = cmsg_data;
|
||||
msghdr->msg_flags = 0;
|
||||
}
|
||||
|
||||
void
|
||||
uc_msghdr_init_server(struct msghdr *msghdr, struct iovec *iov,
|
||||
void *cmsg_data, size_t cmsg_size)
|
||||
{
|
||||
uc_msghdr_init_generic(msghdr, iov, cmsg_data);
|
||||
msghdr->msg_controllen = cmsg_size;
|
||||
uc_dbgmsg("init: data size %zu", msghdr->msg_iov != NULL ?
|
||||
msghdr->msg_iov->iov_len : (size_t)0);
|
||||
uc_dbgmsg("init: msghdr.msg_controllen %u",
|
||||
(u_int)msghdr->msg_controllen);
|
||||
}
|
||||
|
||||
void
|
||||
uc_msghdr_init_client(struct msghdr *msghdr, struct iovec *iov,
|
||||
void *cmsg_data, size_t cmsg_size, int type, size_t arr_size)
|
||||
{
|
||||
struct cmsghdr *cmsghdr;
|
||||
|
||||
uc_msghdr_init_generic(msghdr, iov, cmsg_data);
|
||||
if (cmsg_data != NULL) {
|
||||
if (uc_cfg.send_array_flag)
|
||||
uc_dbgmsg("sending an array");
|
||||
else
|
||||
uc_dbgmsg("sending a scalar");
|
||||
msghdr->msg_controllen = uc_cfg.send_array_flag ?
|
||||
cmsg_size : CMSG_SPACE(0);
|
||||
cmsghdr = CMSG_FIRSTHDR(msghdr);
|
||||
cmsghdr->cmsg_level = SOL_SOCKET;
|
||||
cmsghdr->cmsg_type = type;
|
||||
cmsghdr->cmsg_len = CMSG_LEN(uc_cfg.send_array_flag ? arr_size : 0);
|
||||
} else
|
||||
msghdr->msg_controllen = 0;
|
||||
}
|
||||
|
||||
int
|
||||
uc_client_fork(void)
|
||||
{
|
||||
int fd1, fd2;
|
||||
|
||||
if (pipe(uc_cfg.sync_fd[SYNC_SERVER]) < 0 ||
|
||||
pipe(uc_cfg.sync_fd[SYNC_CLIENT]) < 0) {
|
||||
uc_logmsg("client_fork: pipe");
|
||||
return (-1);
|
||||
}
|
||||
uc_cfg.client_pid = fork();
|
||||
if (uc_cfg.client_pid == (pid_t)-1) {
|
||||
uc_logmsg("client_fork: fork");
|
||||
return (-1);
|
||||
}
|
||||
if (uc_cfg.client_pid == 0) {
|
||||
uc_cfg.proc_name = "CLIENT";
|
||||
uc_cfg.server_flag = false;
|
||||
fd1 = uc_cfg.sync_fd[SYNC_SERVER][SYNC_RECV];
|
||||
fd2 = uc_cfg.sync_fd[SYNC_CLIENT][SYNC_SEND];
|
||||
} else {
|
||||
fd1 = uc_cfg.sync_fd[SYNC_SERVER][SYNC_SEND];
|
||||
fd2 = uc_cfg.sync_fd[SYNC_CLIENT][SYNC_RECV];
|
||||
}
|
||||
if (close(fd1) < 0 || close(fd2) < 0) {
|
||||
uc_logmsg("client_fork: close");
|
||||
return (-1);
|
||||
}
|
||||
return (uc_cfg.client_pid != 0);
|
||||
}
|
||||
|
||||
void
|
||||
uc_client_exit(int rv)
|
||||
{
|
||||
if (close(uc_cfg.sync_fd[SYNC_SERVER][SYNC_SEND]) < 0 ||
|
||||
close(uc_cfg.sync_fd[SYNC_CLIENT][SYNC_RECV]) < 0) {
|
||||
uc_logmsg("client_exit: close");
|
||||
rv = -1;
|
||||
}
|
||||
rv = rv == 0 ? EXIT_SUCCESS : -rv;
|
||||
uc_dbgmsg("exit: code %d", rv);
|
||||
_exit(rv);
|
||||
}
|
||||
|
||||
int
|
||||
uc_client_wait(void)
|
||||
{
|
||||
int status;
|
||||
pid_t pid;
|
||||
|
||||
uc_dbgmsg("waiting for client");
|
||||
|
||||
if (close(uc_cfg.sync_fd[SYNC_SERVER][SYNC_RECV]) < 0 ||
|
||||
close(uc_cfg.sync_fd[SYNC_CLIENT][SYNC_SEND]) < 0) {
|
||||
uc_logmsg("client_wait: close");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
pid = waitpid(uc_cfg.client_pid, &status, 0);
|
||||
if (pid == (pid_t)-1) {
|
||||
uc_logmsg("client_wait: waitpid");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (WIFEXITED(status)) {
|
||||
if (WEXITSTATUS(status) != EXIT_SUCCESS) {
|
||||
uc_logmsgx("client exit status is %d",
|
||||
WEXITSTATUS(status));
|
||||
return (-WEXITSTATUS(status));
|
||||
}
|
||||
} else {
|
||||
if (WIFSIGNALED(status))
|
||||
uc_logmsgx("abnormal termination of client, signal %d%s",
|
||||
WTERMSIG(status), WCOREDUMP(status) ?
|
||||
" (core file generated)" : "");
|
||||
else
|
||||
uc_logmsgx("termination of client, unknown status");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
uc_check_groups(const char *gid_arr_str, const gid_t *gid_arr,
|
||||
const char *gid_num_str, int gid_num, bool all_gids)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < gid_num; ++i)
|
||||
uc_dbgmsg("%s[%d] %lu", gid_arr_str, i, (u_long)gid_arr[i]);
|
||||
|
||||
if (all_gids) {
|
||||
if (gid_num != uc_cfg.proc_cred.gid_num) {
|
||||
uc_logmsgx("%s %d != %d", gid_num_str, gid_num,
|
||||
uc_cfg.proc_cred.gid_num);
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
if (gid_num > uc_cfg.proc_cred.gid_num) {
|
||||
uc_logmsgx("%s %d > %d", gid_num_str, gid_num,
|
||||
uc_cfg.proc_cred.gid_num);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
if (memcmp(gid_arr, uc_cfg.proc_cred.gid_arr,
|
||||
gid_num * sizeof(*gid_arr)) != 0) {
|
||||
uc_logmsgx("%s content is wrong", gid_arr_str);
|
||||
for (i = 0; i < gid_num; ++i)
|
||||
if (gid_arr[i] != uc_cfg.proc_cred.gid_arr[i]) {
|
||||
uc_logmsgx("%s[%d] %lu != %lu",
|
||||
gid_arr_str, i, (u_long)gid_arr[i],
|
||||
(u_long)uc_cfg.proc_cred.gid_arr[i]);
|
||||
break;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
uc_check_scm_creds_cmsgcred(struct cmsghdr *cmsghdr)
|
||||
{
|
||||
const struct cmsgcred *cmcred;
|
||||
int rc;
|
||||
|
||||
if (uc_check_cmsghdr(cmsghdr, SCM_CREDS, sizeof(struct cmsgcred)) < 0)
|
||||
return (-1);
|
||||
|
||||
cmcred = (struct cmsgcred *)CMSG_DATA(cmsghdr);
|
||||
|
||||
uc_dbgmsg("cmsgcred.cmcred_pid %ld", (long)cmcred->cmcred_pid);
|
||||
uc_dbgmsg("cmsgcred.cmcred_uid %lu", (u_long)cmcred->cmcred_uid);
|
||||
uc_dbgmsg("cmsgcred.cmcred_euid %lu", (u_long)cmcred->cmcred_euid);
|
||||
uc_dbgmsg("cmsgcred.cmcred_gid %lu", (u_long)cmcred->cmcred_gid);
|
||||
uc_dbgmsg("cmsgcred.cmcred_ngroups %d", cmcred->cmcred_ngroups);
|
||||
|
||||
rc = 0;
|
||||
|
||||
if (cmcred->cmcred_pid != uc_cfg.client_pid) {
|
||||
uc_logmsgx("cmsgcred.cmcred_pid %ld != %ld",
|
||||
(long)cmcred->cmcred_pid, (long)uc_cfg.client_pid);
|
||||
rc = -1;
|
||||
}
|
||||
if (cmcred->cmcred_uid != uc_cfg.proc_cred.uid) {
|
||||
uc_logmsgx("cmsgcred.cmcred_uid %lu != %lu",
|
||||
(u_long)cmcred->cmcred_uid, (u_long)uc_cfg.proc_cred.uid);
|
||||
rc = -1;
|
||||
}
|
||||
if (cmcred->cmcred_euid != uc_cfg.proc_cred.euid) {
|
||||
uc_logmsgx("cmsgcred.cmcred_euid %lu != %lu",
|
||||
(u_long)cmcred->cmcred_euid, (u_long)uc_cfg.proc_cred.euid);
|
||||
rc = -1;
|
||||
}
|
||||
if (cmcred->cmcred_gid != uc_cfg.proc_cred.gid) {
|
||||
uc_logmsgx("cmsgcred.cmcred_gid %lu != %lu",
|
||||
(u_long)cmcred->cmcred_gid, (u_long)uc_cfg.proc_cred.gid);
|
||||
rc = -1;
|
||||
}
|
||||
if (cmcred->cmcred_ngroups == 0) {
|
||||
uc_logmsgx("cmsgcred.cmcred_ngroups == 0");
|
||||
rc = -1;
|
||||
}
|
||||
if (cmcred->cmcred_ngroups < 0) {
|
||||
uc_logmsgx("cmsgcred.cmcred_ngroups %d < 0",
|
||||
cmcred->cmcred_ngroups);
|
||||
rc = -1;
|
||||
}
|
||||
if (cmcred->cmcred_ngroups > CMGROUP_MAX) {
|
||||
uc_logmsgx("cmsgcred.cmcred_ngroups %d > %d",
|
||||
cmcred->cmcred_ngroups, CMGROUP_MAX);
|
||||
rc = -1;
|
||||
}
|
||||
if (cmcred->cmcred_groups[0] != uc_cfg.proc_cred.egid) {
|
||||
uc_logmsgx("cmsgcred.cmcred_groups[0] %lu != %lu (EGID)",
|
||||
(u_long)cmcred->cmcred_groups[0], (u_long)uc_cfg.proc_cred.egid);
|
||||
rc = -1;
|
||||
}
|
||||
if (uc_check_groups("cmsgcred.cmcred_groups", cmcred->cmcred_groups,
|
||||
"cmsgcred.cmcred_ngroups", cmcred->cmcred_ngroups, false) < 0)
|
||||
rc = -1;
|
||||
return (rc);
|
||||
}
|
||||
|
||||
int
|
||||
uc_check_scm_creds_sockcred(struct cmsghdr *cmsghdr)
|
||||
{
|
||||
const struct sockcred *sc;
|
||||
int rc;
|
||||
|
||||
if (uc_check_cmsghdr(cmsghdr, SCM_CREDS,
|
||||
SOCKCREDSIZE(uc_cfg.proc_cred.gid_num)) < 0)
|
||||
return (-1);
|
||||
|
||||
sc = (struct sockcred *)CMSG_DATA(cmsghdr);
|
||||
|
||||
rc = 0;
|
||||
|
||||
uc_dbgmsg("sockcred.sc_uid %lu", (u_long)sc->sc_uid);
|
||||
uc_dbgmsg("sockcred.sc_euid %lu", (u_long)sc->sc_euid);
|
||||
uc_dbgmsg("sockcred.sc_gid %lu", (u_long)sc->sc_gid);
|
||||
uc_dbgmsg("sockcred.sc_egid %lu", (u_long)sc->sc_egid);
|
||||
uc_dbgmsg("sockcred.sc_ngroups %d", sc->sc_ngroups);
|
||||
|
||||
if (sc->sc_uid != uc_cfg.proc_cred.uid) {
|
||||
uc_logmsgx("sockcred.sc_uid %lu != %lu",
|
||||
(u_long)sc->sc_uid, (u_long)uc_cfg.proc_cred.uid);
|
||||
rc = -1;
|
||||
}
|
||||
if (sc->sc_euid != uc_cfg.proc_cred.euid) {
|
||||
uc_logmsgx("sockcred.sc_euid %lu != %lu",
|
||||
(u_long)sc->sc_euid, (u_long)uc_cfg.proc_cred.euid);
|
||||
rc = -1;
|
||||
}
|
||||
if (sc->sc_gid != uc_cfg.proc_cred.gid) {
|
||||
uc_logmsgx("sockcred.sc_gid %lu != %lu",
|
||||
(u_long)sc->sc_gid, (u_long)uc_cfg.proc_cred.gid);
|
||||
rc = -1;
|
||||
}
|
||||
if (sc->sc_egid != uc_cfg.proc_cred.egid) {
|
||||
uc_logmsgx("sockcred.sc_egid %lu != %lu",
|
||||
(u_long)sc->sc_egid, (u_long)uc_cfg.proc_cred.egid);
|
||||
rc = -1;
|
||||
}
|
||||
if (sc->sc_ngroups == 0) {
|
||||
uc_logmsgx("sockcred.sc_ngroups == 0");
|
||||
rc = -1;
|
||||
}
|
||||
if (sc->sc_ngroups < 0) {
|
||||
uc_logmsgx("sockcred.sc_ngroups %d < 0",
|
||||
sc->sc_ngroups);
|
||||
rc = -1;
|
||||
}
|
||||
if (sc->sc_ngroups != uc_cfg.proc_cred.gid_num) {
|
||||
uc_logmsgx("sockcred.sc_ngroups %d != %u",
|
||||
sc->sc_ngroups, uc_cfg.proc_cred.gid_num);
|
||||
rc = -1;
|
||||
}
|
||||
if (uc_check_groups("sockcred.sc_groups", sc->sc_groups,
|
||||
"sockcred.sc_ngroups", sc->sc_ngroups, true) < 0)
|
||||
rc = -1;
|
||||
return (rc);
|
||||
}
|
86
tools/regression/sockets/unix_cmsg/uc_common.h
Normal file
86
tools/regression/sockets/unix_cmsg/uc_common.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Andrey Simonenko
|
||||
* Copyright (c) 2016 Maksym Sobolyev <sobomax@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
struct uc_cfg {
|
||||
int sock_type;
|
||||
const char *sock_type_str;
|
||||
bool debug;
|
||||
const char *proc_name;
|
||||
int sync_fd[2][2];
|
||||
int serv_sock_fd;
|
||||
bool server_flag;
|
||||
bool send_data_flag;
|
||||
struct sockaddr_un serv_addr_sun;
|
||||
bool send_array_flag;
|
||||
pid_t client_pid;
|
||||
struct {
|
||||
char *buf_send;
|
||||
char *buf_recv;
|
||||
size_t buf_size;
|
||||
u_int msg_num;
|
||||
} ipc_msg;
|
||||
struct {
|
||||
uid_t uid;
|
||||
uid_t euid;
|
||||
gid_t gid;
|
||||
gid_t egid;
|
||||
gid_t *gid_arr;
|
||||
int gid_num;
|
||||
} proc_cred;
|
||||
};
|
||||
|
||||
extern struct uc_cfg uc_cfg;
|
||||
|
||||
int uc_check_msghdr(const struct msghdr *msghdr, size_t size);
|
||||
int uc_check_cmsghdr(const struct cmsghdr *cmsghdr, int type, size_t size);
|
||||
void uc_output(const char *format, ...) __printflike(1, 2);
|
||||
void uc_logmsgx(const char *format, ...) __printflike(1, 2);
|
||||
void uc_dbgmsg(const char *format, ...) __printflike(1, 2);
|
||||
void uc_logmsg(const char *format, ...) __printflike(1, 2);
|
||||
void uc_vlogmsgx(const char *format, va_list ap);
|
||||
int uc_message_recv(int fd, struct msghdr *msghdr);
|
||||
int uc_message_send(int fd, const struct msghdr *msghdr);
|
||||
int uc_message_sendn(int fd, struct msghdr *msghdr);
|
||||
void uc_msghdr_init_server(struct msghdr *msghdr, struct iovec *iov,
|
||||
void *cmsg_data, size_t cmsg_size);
|
||||
void uc_msghdr_init_client(struct msghdr *msghdr, struct iovec *iov,
|
||||
void *cmsg_data, size_t cmsg_size, int type, size_t arr_size);
|
||||
int uc_socket_create(void);
|
||||
int uc_socket_accept(int listenfd);
|
||||
int uc_socket_close(int fd);
|
||||
int uc_socket_connect(int fd);
|
||||
int uc_sync_recv(void);
|
||||
int uc_sync_send(void);
|
||||
int uc_client_fork(void);
|
||||
void uc_client_exit(int rv);
|
||||
int uc_client_wait(void);
|
||||
int uc_check_groups(const char *gid_arr_str, const gid_t *gid_arr,
|
||||
const char *gid_num_str, int gid_num, bool all_gids);
|
||||
int uc_check_scm_creds_cmsgcred(struct cmsghdr *cmsghdr);
|
||||
int uc_check_scm_creds_sockcred(struct cmsghdr *cmsghdr);
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user