diff options
| author | Michael Adam <obnox@samba.org> | 2014-05-31 03:35:22 +0200 |
|---|---|---|
| committer | Michael Adam <obnox@samba.org> | 2014-06-01 10:03:32 +0200 |
| commit | 9e91b00ee329578987c579b2c9d6db967055a59a (patch) | |
| tree | 9cfff110a718287dbb6fb6faaa62c066c6959b62 | |
| parent | 0c3efeb3b07083e36068e354b20208316d02c79a (diff) | |
| download | socket_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.c | 157 |
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), |
