⛏️ index : haiku.git

#include "SocketTests.h"

#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>

#include <cppunit/TestAssert.h>
#include <cppunit/TestCaller.h>
#include <cppunit/TestSuite.h>


// This test reproduces a KDL from issue #13927 where a socket is created
// and an attempt is made to connect to an address, which fails. The socket
// is closed and then reused to connect to a *different* address.
void
SocketTests::ClientSocketReuseTest()
{
	// TODO: Try to find unused ports instead of using these hard-coded ones.
	const uint16_t kFirstPort = 14025;
	const uint16_t kSecondPort = 14026;

	int fd = ::socket(AF_INET, SOCK_STREAM, 0);
	CPPUNIT_ASSERT(fd > 0);

	// Connect to 127.0.0.1:kFirstPort
	sockaddr_in address;
	memset(&address, 0, sizeof(sockaddr_in));
	address.sin_family = AF_INET;
	address.sin_port = htons(kFirstPort);
	address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

	int connect_result = ::connect(
		fd,
		reinterpret_cast<const sockaddr *>(&address),
		sizeof(struct sockaddr));
	CPPUNIT_ASSERT_EQUAL(connect_result, -1);

	// Connection to 127.0.0.1:kFirstPort failed as expected.
	// Now try connecting to 127.0.0.1:kSecondPort.
	address.sin_port = htons(kSecondPort);
	connect_result = ::connect(
		fd,
		reinterpret_cast<const sockaddr *>(&address),
		sizeof(struct sockaddr));
	CPPUNIT_ASSERT_EQUAL(connect_result, -1);

	close(fd);
}


// This test reproduces a KDL from issue #19755.
void
SocketTests::TcpRecvmsgTest()
{
	// create a client socket
	int fd = socket(AF_INET, SOCK_STREAM, 0);
	CPPUNIT_ASSERT(fd >= 0);

	struct msghdr msg;
	memset(&msg, 0, sizeof(msg));
	ssize_t r = recvmsg(fd, &msg, 0);
	CPPUNIT_ASSERT(r == -1);

	close(fd);
}


void
SocketTests::AddTests(BTestSuite &parent)
{
	CppUnit::TestSuite &suite = *new CppUnit::TestSuite("SocketTests");

	suite.addTest(new CppUnit::TestCaller<SocketTests>(
		"SocketTests::ClientSocketReuseTest",
		&SocketTests::ClientSocketReuseTest));
	suite.addTest(new CppUnit::TestCaller<SocketTests>(
		"SocketTests::TcpRecvmsgTest",
		&SocketTests::TcpRecvmsgTest));

	parent.addTest("SocketTests", &suite);
}