/*
 * Check decoding of msg_name* fields of struct msghdr array argument
 * of sendmmsg and recvmmsg syscalls.
 *
 * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
 * Copyright (c) 2016-2017 The strace developers.
 * 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.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "tests.h"

#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/un.h>

#include "msghdr.h"

#define IOV_MAX1 (IOV_MAX + 1)

#ifndef TEST_NAME
# define TEST_NAME "mmsg_name"
#endif

static void
print_msghdr(const struct msghdr *const msg, const int user_msg_namelen)
{
	const struct sockaddr_un *const un = msg->msg_name;
	const int offsetof_sun_path = offsetof(struct sockaddr_un, sun_path);

	printf("{msg_name=");
	if (!un)
		printf("NULL");
	else if (user_msg_namelen < offsetof_sun_path) {
		printf("%p", un);
	} else {
		printf("{sa_family=AF_UNIX");
		if (user_msg_namelen > offsetof_sun_path) {
			int len = user_msg_namelen < (int) msg->msg_namelen ?
				  user_msg_namelen : (int) msg->msg_namelen;
			len -= offsetof_sun_path;
			if (len > (int) sizeof(un->sun_path))
				len = sizeof(un->sun_path);
			printf(", sun_path=\"%.*s\"", len, un->sun_path);
		}
		printf("}");
	}
	printf(", msg_namelen=");
	if (user_msg_namelen != (int) msg->msg_namelen) {
		printf("%d->", user_msg_namelen);
	}
	printf("%d, msg_iov=[{iov_base=\"%c\", iov_len=1}]"
	       ", msg_iovlen=1, msg_controllen=0, msg_flags=0}",
	       (int) msg->msg_namelen, *(char *) msg->msg_iov[0].iov_base);
}

static void
test_mmsg_name(const int send_fd, const int recv_fd)
{
	struct sockaddr_un *const send_addr =
		tail_alloc(sizeof(*send_addr) * IOV_MAX1);
	char *const send_buf = tail_alloc(sizeof(*send_buf) * IOV_MAX1);
	struct iovec *const send_iov = tail_alloc(sizeof(*send_iov) * IOV_MAX1);
	struct mmsghdr *const send_mh = tail_alloc(sizeof(*send_mh) * IOV_MAX1);

	int i, rc;

	for (i = 0; i < IOV_MAX1; ++i) {
		int sun_len = i + 1 > (int) sizeof(send_addr[i].sun_path)
				    ? (int) sizeof(send_addr[i].sun_path)
				    : i + 1;

		send_addr[i].sun_family = AF_UNIX;
		memset(send_addr[i].sun_path, 'a' + i % 26, sun_len);

		send_buf[i] = '0' + i % 10;

		send_iov[i].iov_base = &send_buf[i];
		send_iov[i].iov_len = sizeof(*send_buf);

		send_mh[i].msg_hdr.msg_iov = &send_iov[i];
		send_mh[i].msg_hdr.msg_iovlen = 1;
		send_mh[i].msg_hdr.msg_name = &send_addr[i];
		send_mh[i].msg_hdr.msg_namelen = i + 1;
		send_mh[i].msg_hdr.msg_control = 0;
		send_mh[i].msg_hdr.msg_controllen = 0;
		send_mh[i].msg_hdr.msg_flags = 0;
	}

	rc = send_mmsg(send_fd, send_mh, IOV_MAX1, MSG_DONTWAIT);
	int saved_errno = errno;

	printf("sendmmsg(%d, [", send_fd);
	for (i = 0; i < IOV_MAX1; ++i) {
		if (i)
			printf(", ");
		if (i >= IOV_MAX
# if !VERBOSE
			|| i >= DEFAULT_STRLEN
# endif
		   ) {
			printf("...");
			break;
		}
		printf("{msg_hdr=");
		print_msghdr(&send_mh[i].msg_hdr, i + 1);
		printf("}");
	}
	errno = saved_errno;
	printf("], %u, MSG_DONTWAIT) = %d %s (%m)\n",
	       IOV_MAX1, rc, errno2name());

	for (i = 0; i < IOV_MAX1; ++i) {
		send_mh[i].msg_hdr.msg_name = 0;
		send_mh[i].msg_hdr.msg_namelen = 0;
	}

	/*
	 * When recvmmsg is called with a valid descriptor
	 * but inaccessible memory, it causes segfaults on some architectures.
	 * As in these cases we test decoding of failed recvmmsg calls,
	 * it's ok to fail recvmmsg with any reason as long as
	 * it doesn't read that inaccessible memory.
	 */
	rc = send_mmsg(-1, &send_mh[IOV_MAX], 2, MSG_DONTWAIT);
	saved_errno = errno;
	printf("sendmmsg(-1, [{msg_hdr=");
	print_msghdr(&send_mh[IOV_MAX].msg_hdr, 0);
	errno = saved_errno;
	printf("}, %p], %u, MSG_DONTWAIT) = %d %s (%m)\n",
	       &send_mh[IOV_MAX1], 2, rc, errno2name());

	rc = send_mmsg(send_fd, send_mh, IOV_MAX1, MSG_DONTWAIT);
	if (rc < 0)
		perror_msg_and_skip("sendmmsg");

	printf("sendmmsg(%d, [", send_fd);
	for (i = 0; i < IOV_MAX1; ++i) {
		if (i)
			printf(", ");
		if (i >= IOV_MAX
#if !VERBOSE
			|| i >= DEFAULT_STRLEN
#endif
		   ) {
			printf("...");
			break;
		}
		printf("{msg_hdr=");
		print_msghdr(&send_mh[i].msg_hdr, 0);
		printf("%s}", i < rc ? ", msg_len=1" : "");
	}
	printf("], %u, MSG_DONTWAIT) = %d\n", IOV_MAX1, rc);

	struct sockaddr_un *const recv_addr =
		tail_alloc(sizeof(*recv_addr) * IOV_MAX1);
	char *const recv_buf = tail_alloc(sizeof(*recv_buf) * IOV_MAX1);
	struct iovec *const recv_iov = tail_alloc(sizeof(*recv_iov) * IOV_MAX1);
	struct mmsghdr *const recv_mh = tail_alloc(sizeof(*recv_mh) * IOV_MAX1);

	for (i = 0; i < IOV_MAX1; ++i) {
		recv_iov[i].iov_base = &recv_buf[i];
		recv_iov[i].iov_len = sizeof(*recv_buf);

		recv_mh[i].msg_hdr.msg_name = &recv_addr[i];
		recv_mh[i].msg_hdr.msg_namelen = i;
		recv_mh[i].msg_hdr.msg_iov = &recv_iov[i];
		recv_mh[i].msg_hdr.msg_iovlen = 1;
		recv_mh[i].msg_hdr.msg_control = 0;
		recv_mh[i].msg_hdr.msg_controllen = 0;
		recv_mh[i].msg_hdr.msg_flags = 0;
	}

	rc = recv_mmsg(recv_fd, recv_mh, IOV_MAX1, MSG_DONTWAIT, 0);
	if (rc < 0)
		perror_msg_and_skip("recvmmsg");

	printf("recvmmsg(%d, [", recv_fd);
	for (i = 0; i < rc; ++i) {
		if (i)
			printf(", ");
#if !VERBOSE
		if (i >= DEFAULT_STRLEN) {
			printf("...");
			break;
		}
#endif
		printf("{msg_hdr=");
		print_msghdr(&recv_mh[i].msg_hdr, i);
		printf(", msg_len=1}");
	}
	printf("], %u, MSG_DONTWAIT, NULL) = %d\n", IOV_MAX1, rc);
}

int
main(void)
{
	int fds[2];
	if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
		perror_msg_and_skip("socketpair");

	const struct sockaddr_un un = {
		.sun_family = AF_UNIX,
		.sun_path = TEST_NAME "-recvmmsg.test.send.socket"
	};

	(void) unlink(un.sun_path);
	if (bind(fds[1], (const void *) &un, sizeof(un)))
		perror_msg_and_skip("bind");
	(void) unlink(un.sun_path);

	test_mmsg_name(fds[1], fds[0]);

	puts("+++ exited with 0 +++");
	return 0;
}
