summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2014-05-31 03:35:22 +0200
committerMichael Adam <obnox@samba.org>2014-06-01 10:03:32 +0200
commit9e91b00ee329578987c579b2c9d6db967055a59a (patch)
tree9cfff110a718287dbb6fb6faaa62c066c6959b62
parent0c3efeb3b07083e36068e354b20208316d02c79a (diff)
downloadsocket_wrapper-9e91b00ee329578987c579b2c9d6db967055a59a.tar.gz
socket_wrapper-9e91b00ee329578987c579b2c9d6db967055a59a.tar.xz
socket_wrapper-9e91b00ee329578987c579b2c9d6db967055a59a.zip
tests: add new test test_bind_ipv4_addr_in_use()
This tests binding an address that is already in use. Signed-off-by: Michael Adam <obnox@samba.org> Reviewed-by: Andreas Schneider <asn@samba.org>
-rw-r--r--tests/test_echo_tcp_bind.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/tests/test_echo_tcp_bind.c b/tests/test_echo_tcp_bind.c
index 51528c2..c699b06 100644
--- a/tests/test_echo_tcp_bind.c
+++ b/tests/test_echo_tcp_bind.c
@@ -154,6 +154,160 @@ static void test_bind_ipv4(void **state)
close(s);
}
+static void test_bind_ipv4_addr_in_use(void **state)
+{
+ struct sockaddr_in sin, sin2;
+ socklen_t slen = sizeof(struct sockaddr_in);
+ int rc;
+ int s, s2;
+
+ (void) state; /* unused */
+
+ s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ assert_return_code(s, errno);
+
+ /*
+ * Try to bind to the same address as already bound by a
+ * different process.
+ */
+
+ /* Without specifying the port - success */
+
+ ZERO_STRUCT(sin);
+ sin.sin_family = AF_INET;
+ rc = inet_pton(AF_INET, torture_server_address(AF_INET), &sin.sin_addr);
+ assert_int_equal(rc, 1);
+ rc = bind(s, (struct sockaddr *)&sin, slen);
+ assert_return_code(rc, errno);
+
+ close(s);
+
+ s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ assert_return_code(s, errno);
+
+#if 0
+ /* specify the same port - fail with EADDRINUSE. */
+
+ /* Not supported by socket_wrapper yet. ==> TODO! */
+
+ ZERO_STRUCT(sin);
+ sin.sin_family = AF_INET,
+ sin.sin_port = htons(torture_server_port());
+ rc = inet_pton(AF_INET, torture_server_address(AF_INET), &sin.sin_addr);
+ assert_int_equal(rc, 1);
+
+ rc = bind(s, (struct sockaddr *)&sin, slen);
+ assert_int_equal(rc, -1);
+ assert_int_equal(errno, EADDRINUSE);
+#endif
+
+ /*
+ * Try double binding when the firs bind is with port == 0
+ */
+
+ ZERO_STRUCT(sin);
+ sin.sin_family = AF_INET;
+
+ rc = inet_pton(AF_INET, "127.0.0.20", &sin.sin_addr);
+ assert_int_equal(rc, 1);
+
+ rc = bind(s, (struct sockaddr *)&sin, slen);
+ assert_return_code(rc, errno);
+
+ /*
+ * Open a second socket locally and try to bind to the same address.
+ */
+
+ /* Succeeds with port == 0 */
+
+ s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ assert_return_code(s, errno);
+
+ ZERO_STRUCT(sin2);
+ sin2.sin_family = AF_INET;
+
+ rc = inet_pton(AF_INET, "127.0.0.20", &sin2.sin_addr);
+ assert_int_equal(rc, 1);
+
+ rc = bind(s2, (struct sockaddr *)&sin2, slen);
+ assert_return_code(rc, errno);
+
+ close(s2);
+
+ /* second bind with port != 0 - succeeds */
+
+ s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ assert_return_code(s, errno);
+
+ ZERO_STRUCT(sin2);
+ sin2.sin_family = AF_INET;
+ sin2.sin_port = htons(12345);
+
+ rc = inet_pton(AF_INET, "127.0.0.20", &sin2.sin_addr);
+ assert_int_equal(rc, 1);
+
+ rc = bind(s2, (struct sockaddr *)&sin2, slen);
+ assert_return_code(rc, errno);
+
+ close(s2);
+ close(s);
+
+ /*
+ * Try double binding when the first bind is with port != 0
+ */
+
+ s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ assert_return_code(s, errno);
+
+ ZERO_STRUCT(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(12345);
+
+ rc = inet_pton(AF_INET, "127.0.0.20", &sin.sin_addr);
+ assert_int_equal(rc, 1);
+
+ rc = bind(s, (struct sockaddr *)&sin, slen);
+ assert_return_code(rc, errno);
+
+ /*
+ * Open a second socket locally and try to bind to the same address.
+ */
+
+ /* Succeeds with port == 0 */
+
+ s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ assert_return_code(s, errno);
+
+ ZERO_STRUCT(sin2);
+ sin2.sin_family = AF_INET;
+
+ rc = inet_pton(AF_INET, "127.0.0.20", &sin2.sin_addr);
+ assert_int_equal(rc, 1);
+
+ rc = bind(s2, (struct sockaddr *)&sin2, slen);
+ assert_return_code(rc, errno);
+
+ close(s2);
+
+ /* with same port as above - fail with EADDRINUSE */
+
+ s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ assert_return_code(s, errno);
+
+ ZERO_STRUCT(sin2);
+ sin2.sin_family = AF_INET;
+ sin2.sin_port = htons(12345);
+
+ rc = inet_pton(AF_INET, "127.0.0.20", &sin2.sin_addr);
+ assert_int_equal(rc, 1);
+
+ rc = bind(s2, (struct sockaddr *)&sin2, slen);
+ assert_int_equal(rc, -1);
+ assert_int_equal(errno, EADDRINUSE);
+
+ close(s);
+}
+
static void test_bindresvport_ipv4(void **state)
{
struct sockaddr_in sin;
@@ -312,6 +466,9 @@ int main(void) {
unit_test_setup_teardown(test_bind_ipv4,
setup_echo_srv_tcp_ipv4,
teardown),
+ unit_test_setup_teardown(test_bind_ipv4_addr_in_use,
+ setup_echo_srv_tcp_ipv4,
+ teardown),
unit_test_setup_teardown(test_bindresvport_ipv4,
setup_echo_srv_tcp_ipv4,
teardown),