Пример #1
0
ATF_TC_BODY(send_recv, tc)
{
	int s;
	int sv[2];
	const int bufsize = 64;
	const char *data = "data";
	char recv_buf[bufsize];
	size_t datalen;
	ssize_t ssize, rsize;

	/* setup the socket pair */
	do_socketpair(sv);

	/* send and receive a small packet */
	datalen = strlen(data) + 1;	/* +1 for the null */
	ssize = send(sv[0], data, datalen, MSG_EOR);
	if (ssize < 0) {
		perror("send");
		atf_tc_fail("send returned < 0");
	}
	ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd",
	    datalen, ssize);

	rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL);
	ATF_CHECK_EQ(datalen, rsize);
}
Пример #2
0
ATF_TC_BODY(resize_connected_buffers, tc)
{
	int sv[2];
	int sndbuf = 12345;
	int rcvbuf = 23456;
	int err;
	int ls, lr, rs, rr;
	socklen_t sl = sizeof(ls);

	/* setup the socket pair */
	do_socketpair(sv);

	printf("                       Socket Buffer Sizes\n");
	printf("                              | Left Socket       | Right Socket      |\n");
	printf("                              | SNDBUF  | RCVBUF  | SNDBUF  | RCVBUF  |\n");
	ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl));
	ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl));
	ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl));
	ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl));
	printf("Default                       | %7d | %7d | %7d | %7d |\n",
	    ls, lr, rs, rr);

	/* Update one side's send buffer */
	err = setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));
	if (err != 0){
		perror("setsockopt");
		atf_tc_fail("setsockopt(SO_SNDBUF) failed");
	}

	ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl));
	ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl));
	ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl));
	ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl));
	printf("After changing Left's SNDBUF  | %7d | %7d | %7d | %7d |\n",
	    ls, lr, rs, rr);

	/* Update the same side's receive buffer */
	err = setsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
	if (err != 0){
		perror("setsockopt");
		atf_tc_fail("setsockopt(SO_RCVBUF) failed");
	}

	ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl));
	ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl));
	ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl));
	ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl));
	printf("After changing Left's RCVBUF  | %7d | %7d | %7d | %7d |\n",
	    ls, lr, rs, rr);
}
Пример #3
0
static void
test_pipe(size_t sndbufsize, size_t rcvbufsize)
{
	test_pipe_thread_data_t writer_data, reader_data;
	pthread_t writer, reader;
	int sv[2];
	const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4;
	int numpkts;

	/* setup the socket pair */
	do_socketpair(sv);
	/* Setup the buffers */
	ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize,
	    sizeof(sndbufsize)));
	ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
	    sizeof(rcvbufsize)));

	/* Send a total amount of data comfortably greater than the buffers */
	numpkts = MAX(sndbufsize, rcvbufsize) * 8 / pktsize;

	/* Start the child threads */
	writer_data.pktsize = pktsize;
	writer_data.numpkts = numpkts;
	writer_data.so = sv[0];
	reader_data.pktsize = pktsize;
	reader_data.numpkts = numpkts;
	reader_data.so = sv[1];
	ATF_REQUIRE_EQ(0, pthread_create(&writer, NULL, test_pipe_writer,
	    				 (void*)&writer_data));
	/* 
	 * Give the writer time to start writing, and hopefully block, before
	 * starting the reader.  This increases the likelihood of the test case
	 * failing due to PR kern/185812
	 */
	usleep(1000);
	ATF_REQUIRE_EQ(0, pthread_create(&reader, NULL, test_pipe_reader,
	    				 (void*)&reader_data));

	/* Join the children */
	ATF_REQUIRE_EQ(0, pthread_join(writer, NULL));
	ATF_REQUIRE_EQ(0, pthread_join(reader, NULL));
}
Пример #4
0
void
test_sendrecv_symmetric_buffers(size_t bufsize, int blocking) {
	int s;
	int sv[2];
	const size_t pktsize = bufsize / 2;
	char sndbuf[pktsize];
	char recv_buf[pktsize];
	ssize_t ssize, rsize;

	/* setup the socket pair */
	if (blocking)
		do_socketpair(sv);
	else
		do_socketpair_nonblocking(sv);

	/* Setup the buffers */
	s = setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize));
	ATF_REQUIRE_EQ(0, s);
	s = setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize));
	ATF_REQUIRE_EQ(0, s);

	/* Fill the send buffer */
	bzero(sndbuf, pktsize);

	/* send and receive the packet */
	ssize = send(sv[0], sndbuf, pktsize, MSG_EOR);
	if (ssize < 0) {
		perror("send");
		atf_tc_fail("send returned < 0");
	}
	ATF_CHECK_EQ_MSG(pktsize, ssize, "expected %zd=send(...) but got %zd",
	    pktsize, ssize);

	rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL);
	if (rsize < 0) {
		perror("recv");
		atf_tc_fail("recv returned < 0");
	}
	ATF_CHECK_EQ_MSG(pktsize, rsize, "expected %zd=send(...) but got %zd",
	    pktsize, rsize);
}
Пример #5
0
ATF_TC_BODY(emsgsize, tc)
{
	int sv[2];
	const size_t sndbufsize = 8192;
	const size_t rcvbufsize = 8192;
	const size_t pktsize = (sndbufsize + rcvbufsize) * 2;
	char sndbuf[pktsize];
	ssize_t ssize;

	/* setup the socket pair */
	do_socketpair(sv);
	/* Setup the buffers */
	ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize,
	    sizeof(sndbufsize)));
	ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
	    sizeof(rcvbufsize)));

	ssize = send(sv[0], sndbuf, pktsize, MSG_EOR);
	ATF_CHECK_EQ(EMSGSIZE, errno);
	ATF_CHECK_EQ(-1, ssize);
}
Пример #6
0
void
test_pipe(size_t sndbufsize, size_t rcvbufsize)
{
	test_pipe_thread_data_t writer_data, reader_data;
	pthread_t writer, reader;
	int num_sent, num_received;
	int sv[2];
	const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4;
	int numpkts;

	/* setup the socket pair */
	do_socketpair(sv);
	/* Setup the buffers */
	ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize,
	    sizeof(sndbufsize)));
	ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
	    sizeof(rcvbufsize)));

	/* Send a total amount of data comfortably greater than the buffers */
	numpkts = MAX(sndbufsize, rcvbufsize) * 8 / pktsize;

	/* Start the child threads */
	writer_data.pktsize = pktsize;
	writer_data.numpkts = numpkts;
	writer_data.so = sv[0];
	reader_data.pktsize = pktsize;
	reader_data.numpkts = numpkts;
	reader_data.so = sv[1];
	ATF_REQUIRE_EQ(0, pthread_create(&writer, NULL, test_pipe_writer,
	    				 (void*)&writer_data));
	ATF_REQUIRE_EQ(0, pthread_create(&reader, NULL, test_pipe_reader,
	    				 (void*)&reader_data));

	/* Join the children */
	ATF_REQUIRE_EQ(0, pthread_join(writer, NULL));
	ATF_REQUIRE_EQ(0, pthread_join(reader, NULL));
}
Пример #7
0
PUBLIC int uds_ioctl(message *dev_m_in, message *dev_m_out)
{
	int minor;

#if DEBUG == 1
	static int call_count = 0;
	printf("(uds) [%d] uds_ioctl() call_count=%d\n", uds_minor(dev_m_in),
							++call_count);
 	printf("Endpoint: 0x%x | Position 0x%x\n", dev_m_in->IO_ENDPT, 
							dev_m_in->POSITION);
#endif

	minor = uds_minor(dev_m_in);

	if (uds_fd_table[minor].state != UDS_INUSE) {

		/* attempted to close a socket that hasn't been opened --
		 * something is very wrong :(
		 */
		uds_set_reply(dev_m_out, TASK_REPLY, dev_m_in->IO_ENDPT,
				(cp_grant_id_t) dev_m_in->IO_GRANT, EINVAL);

		return EINVAL;
	}

	/* track the system call we are performing in case it gets cancelled */
	uds_fd_table[minor].call_nr = dev_m_in->m_type;
	uds_fd_table[minor].ioctl = dev_m_in->COUNT;
	uds_fd_table[minor].syscall_done = 0;

	/* setup select(2) framework */
	uds_fd_table[minor].selecting = 0;

	/* update the owner endpoint - yes it's really stored in POSITION */
	uds_fd_table[minor].owner = dev_m_in->POSITION;

	switch (dev_m_in->COUNT) {	/* Handle the ioctl(2) command */

		case NWIOSUDSCONN:

			/* connect to a listening socket -- connect() */
			return do_connect(dev_m_in, dev_m_out);

		case NWIOSUDSACCEPT:

			/* accept an incoming connection -- accept() */
			return do_accept(dev_m_in, dev_m_out);

		case NWIOSUDSBLOG:

			/* set the backlog_size and put the socket into the
			 * listening state -- listen()
			 */
			return do_listen(dev_m_in, dev_m_out);

		case NWIOSUDSTYPE:

			/* set the type for this socket (i.e. 
			 * SOCK_STREAM, SOCK_DGRAM, etc) -- socket()
			 */
			return do_socket(dev_m_in, dev_m_out);

		case NWIOSUDSADDR:

			/* set the address for this socket -- bind() */
			return do_bind(dev_m_in, dev_m_out);

		case NWIOGUDSADDR:

			/* get the address for this socket -- getsockname() */
			return do_getsockname(dev_m_in, dev_m_out);

		case NWIOGUDSPADDR:

			/* get the address for the peer -- getpeername() */
			return do_getpeername(dev_m_in, dev_m_out);

		case NWIOSUDSSHUT:

			/* shutdown a socket for reading, writing, or 
			 * both -- shutdown()
			 */
			return do_shutdown(dev_m_in, dev_m_out);

		case NWIOSUDSPAIR:

			/* connect two sockets -- socketpair() */
			return do_socketpair(dev_m_in, dev_m_out);

		case NWIOGUDSSOTYPE:

			/* get socket type -- getsockopt(SO_TYPE) */
			return do_getsockopt_sotype(dev_m_in, dev_m_out);

		case NWIOGUDSPEERCRED:

			/* get peer endpoint -- getsockopt(SO_PEERCRED) */
			return do_getsockopt_peercred(dev_m_in, dev_m_out);

		case NWIOSUDSTADDR:

			/* set target address -- sendto() */
			return do_sendto(dev_m_in, dev_m_out);

		case NWIOGUDSFADDR:

			/* get from address -- recvfrom() */
			return do_recvfrom(dev_m_in, dev_m_out);

		case NWIOGUDSSNDBUF:

			/* get the send buffer size -- getsockopt(SO_SNDBUF) */
			return do_getsockopt_sndbuf(dev_m_in, dev_m_out);

		case NWIOSUDSSNDBUF:

			/* set the send buffer size -- setsockopt(SO_SNDBUF) */
			return do_setsockopt_sndbuf(dev_m_in, dev_m_out);

		case NWIOGUDSRCVBUF:

			/* get the send buffer size -- getsockopt(SO_SNDBUF) */
			return do_getsockopt_rcvbuf(dev_m_in, dev_m_out);

		case NWIOSUDSRCVBUF:

			/* set the send buffer size -- setsockopt(SO_SNDBUF) */
			return do_setsockopt_rcvbuf(dev_m_in, dev_m_out);

		case NWIOSUDSCTRL:

			/* set the control data -- sendmsg() */
			return do_sendmsg(dev_m_in, dev_m_out);

		case NWIOGUDSCTRL:

			/* set the control data -- recvmsg() */
			return do_recvmsg(dev_m_in, dev_m_out);

		default:

			/* the IOCTL command is not valid for /dev/uds --
			 * this happens a lot and is normal. a lot of 
			 * libc functions determine the socket type with 
			 * IOCTLs. Any not for us simply get a EBADIOCTL
			 * response.
			 */
			uds_fd_table[minor].syscall_done = 1;
			uds_set_reply(dev_m_out, TASK_REPLY,
					dev_m_in->IO_ENDPT, 
					(cp_grant_id_t) dev_m_in->IO_GRANT,
					EBADIOCTL);

			return EBADIOCTL;
	}
}