1#include "SocketTests.h"
2
3#include <netinet/in.h>
4#include <stdio.h>
5#include <string.h>
6#include <sys/socket.h>
7#include <unistd.h>
8
9#include <cppunit/TestAssert.h>
10#include <cppunit/TestCaller.h>
11#include <cppunit/TestSuite.h>
12
13
14// This test reproduces a KDL from issue #13927 where a socket is created
15// and an attempt is made to connect to an address, which fails. The socket
16// is closed and then reused to connect to a *different* address.
17void SocketTests::ClientSocketReuseTest()
18{
19	// TODO: Try to find unused ports instead of using these hard-coded ones.
20	const uint16_t kFirstPort = 14025;
21	const uint16_t kSecondPort = 14026;
22
23	int fd = ::socket(AF_INET, SOCK_STREAM, 0);
24	CPPUNIT_ASSERT(fd > 0);
25
26	// Connect to 127.0.0.1:kFirstPort
27	sockaddr_in address;
28	memset(&address, 0, sizeof(sockaddr_in));
29	address.sin_family = AF_INET;
30	address.sin_port = htons(kFirstPort);
31	address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
32
33	int connect_result = ::connect(
34		fd,
35		reinterpret_cast<const sockaddr *>(&address),
36		sizeof(struct sockaddr));
37	CPPUNIT_ASSERT_EQUAL(connect_result, -1);
38
39	// Connection to 127.0.0.1:kFirstPort failed as expected.
40	// Now try connecting to 127.0.0.1:kSecondPort.
41	address.sin_port = htons(kSecondPort);
42	connect_result = ::connect(
43		fd,
44		reinterpret_cast<const sockaddr *>(&address),
45		sizeof(struct sockaddr));
46	CPPUNIT_ASSERT_EQUAL(connect_result, -1);
47
48	close(fd);
49}
50
51
52void SocketTests::AddTests(BTestSuite &parent) {
53	CppUnit::TestSuite &suite = *new CppUnit::TestSuite("SocketTests");
54
55	suite.addTest(new CppUnit::TestCaller<SocketTests>(
56		"SocketTests::ClientSocketReuseTest",
57		&SocketTests::ClientSocketReuseTest));
58
59	parent.addTest("SocketTests", &suite);
60}
61