Commit 45ee17d1 authored by Kai Vehmanen's avatar Kai Vehmanen

Updated STUN unit tests.

darcs-hash:20070720213005-77cd4-a4e7354cc57b45e01d9e018e831940560c5b67ae.gz
parent da94499c
...@@ -168,7 +168,7 @@ static void bad_responses (void) ...@@ -168,7 +168,7 @@ static void bad_responses (void)
stun_bind_t *ctx; stun_bind_t *ctx;
struct sockaddr_storage addr; struct sockaddr_storage addr;
socklen_t addrlen = sizeof (addr); socklen_t addrlen = sizeof (addr);
ssize_t val; ssize_t val, len;
uint8_t buf[1000]; uint8_t buf[1000];
/* Allocate a local UDP port */ /* Allocate a local UDP port */
...@@ -196,16 +196,30 @@ static void bad_responses (void) ...@@ -196,16 +196,30 @@ static void bad_responses (void)
(struct sockaddr *)&addr, &addrlen); (struct sockaddr *)&addr, &addrlen);
assert (val == EAGAIN); assert (val == EAGAIN);
/* Send non-matching message (request instead of response) */ /* Send request instead of response */
val = getsockname (servfd, (struct sockaddr *)&addr, &addrlen); val = getsockname (servfd, (struct sockaddr *)&addr, &addrlen);
assert (val == 0); assert (val == 0);
val = recv (servfd, buf, 1000, MSG_DONTWAIT); len = recv (servfd, buf, 1000, MSG_DONTWAIT);
assert (val >= 0); assert (len >= 20);
val = stun_bind_process (ctx, buf, len,
(struct sockaddr *)&addr, &addrlen);
assert (val == EAGAIN);
/* Send response with wrong request type */
buf[0] |= 0x03;
val = stun_bind_process (ctx, buf, len,
(struct sockaddr *)&addr, &addrlen);
assert (val == EAGAIN);
buf[0] ^= 0x02;
val = stun_bind_process (ctx, buf, val, /* Send error response without ERROR-CODE */
buf[1] |= 0x10;
val = stun_bind_process (ctx, buf, len,
(struct sockaddr *)&addr, &addrlen); (struct sockaddr *)&addr, &addrlen);
assert (val == EAGAIN); assert (val == EAGAIN);
stun_bind_cancel (ctx); stun_bind_cancel (ctx);
close (servfd); close (servfd);
} }
...@@ -250,7 +264,7 @@ static void responses (void) ...@@ -250,7 +264,7 @@ static void responses (void)
val = recv (servfd, buf, 1000, MSG_DONTWAIT); val = recv (servfd, buf, 1000, MSG_DONTWAIT);
assert (val >= 0); assert (val >= 0);
stun_init_error (buf, sizeof (buf), buf, STUN_GLOBAL_FAILURE); stun_init_error (buf, sizeof (buf), buf, STUN_SERVER_ERROR);
len = sizeof (buf); len = sizeof (buf);
val = stun_finish (buf, &len); val = stun_finish (buf, &len);
assert (val == 0); assert (val == 0);
...@@ -268,7 +282,7 @@ static void responses (void) ...@@ -268,7 +282,7 @@ static void responses (void)
val = recv (servfd, buf, 1000, MSG_DONTWAIT); val = recv (servfd, buf, 1000, MSG_DONTWAIT);
assert (val >= 0); assert (val >= 0);
stun_init_response (buf, buf); stun_init_response (buf, sizeof (buf), buf);
val = stun_append_string (buf, sizeof (buf), 0x6000, val = stun_append_string (buf, sizeof (buf), 0x6000,
"This is an unknown attribute!"); "This is an unknown attribute!");
assert (val == 0); assert (val == 0);
...@@ -290,7 +304,7 @@ static void responses (void) ...@@ -290,7 +304,7 @@ static void responses (void)
val = recv (servfd, buf, 1000, MSG_DONTWAIT); val = recv (servfd, buf, 1000, MSG_DONTWAIT);
assert (val >= 0); assert (val >= 0);
stun_init_response (buf, buf); stun_init_response (buf, sizeof (buf), buf);
len = sizeof (buf); len = sizeof (buf);
val = stun_finish (buf, &len); val = stun_finish (buf, &len);
assert (val == 0); assert (val == 0);
...@@ -309,7 +323,7 @@ static void responses (void) ...@@ -309,7 +323,7 @@ static void responses (void)
val = recv (servfd, buf, 1000, MSG_DONTWAIT); val = recv (servfd, buf, 1000, MSG_DONTWAIT);
assert (val >= 0); assert (val >= 0);
stun_init_response (buf, buf); stun_init_response (buf, sizeof (buf), buf);
val = stun_append_addr (buf, sizeof (buf), STUN_MAPPED_ADDRESS, val = stun_append_addr (buf, sizeof (buf), STUN_MAPPED_ADDRESS,
(struct sockaddr *)&addr, addrlen); (struct sockaddr *)&addr, addrlen);
assert (val == 0); assert (val == 0);
...@@ -332,6 +346,41 @@ static void responses (void) ...@@ -332,6 +346,41 @@ static void responses (void)
} }
static void keepalive (void)
{
struct sockaddr_storage addr;
socklen_t addrlen = sizeof (addr);
size_t len;
int val, servfd, fd;
/* Allocate a local UDP port for server */
servfd = listen_dgram ();
assert (servfd != -1);
val = getsockname (servfd, (struct sockaddr *)&addr, &addrlen);
assert (val == 0);
/* Allocate a client socket and connect to server */
fd = socket (addr.ss_family, SOCK_DGRAM, 0);
assert (fd != -1);
/* Keep alive sending smoke test */
val = stun_bind_keepalive (fd, (struct sockaddr *)&addr, addrlen);
assert (val == 0);
/* Wrong address family test */
addr.ss_family = addr.ss_family == AF_INET ? AF_INET6 : AF_INET;
val = stun_bind_keepalive (fd, (struct sockaddr *)&addr, addrlen);
assert (val != 0);
/* End */
close (servfd);
val = close (fd);
assert (val == 0);
}
static void test (void (*func) (void), const char *name) static void test (void (*func) (void), const char *name)
{ {
alarm (10); alarm (10);
...@@ -347,8 +396,9 @@ int main (void) ...@@ -347,8 +396,9 @@ int main (void)
test (bad_family, "Bad socket family"); test (bad_family, "Bad socket family");
test (small_srv_addr, "Too small server address"); test (small_srv_addr, "Too small server address");
test (big_srv_addr, "Too big server address"); test (big_srv_addr, "Too big server address");
test (timeout, "Binding discovery timeout");
test (bad_responses, "Bad responses"); test (bad_responses, "Bad responses");
test (responses, "Error responses"); test (responses, "Error responses");
test (keepalive, "Keep alives");
test (timeout, "Binding discovery timeout");
return 0; return 0;
} }
...@@ -85,9 +85,20 @@ int main (void) ...@@ -85,9 +85,20 @@ int main (void)
assert (len > 0); assert (len > 0);
assert (stun_present (buf, STUN_XOR_MAPPED_ADDRESS)); assert (stun_present (buf, STUN_XOR_MAPPED_ADDRESS));
/* Same with too small response buffer */
stun_init_request (buf, STUN_BINDING);
len = sizeof (buf);
stun_finish (buf, &len);
len = 20 + 12 + 4 + stun_align (strlen (PACKAGE_STRING)) + 7;
val = stun_bind_reply (buf, &len, buf,
(struct sockaddr *)&ip4, sizeof (ip4), false);
assert (val == ENOBUFS);
assert (len == 0);
/* Incorrect message class */ /* Incorrect message class */
stun_init_request (buf, STUN_BINDING); stun_init_request (buf, STUN_BINDING);
stun_init_response (buf, buf); stun_init_response (buf, sizeof (buf), buf);
len = sizeof (buf); len = sizeof (buf);
val = stun_finish (buf, &len); val = stun_finish (buf, &len);
assert (val == 0); assert (val == 0);
...@@ -125,6 +136,18 @@ int main (void) ...@@ -125,6 +136,18 @@ int main (void)
assert (val == EPROTO); assert (val == EPROTO);
assert (len > 0); assert (len > 0);
/* Same with too small response buffer */
stun_init_request (buf, STUN_BINDING);
stun_append_string (buf, sizeof (buf), 0x666, "Unknown attribute!");
len = sizeof (buf);
stun_finish (buf, &len);
len = 20 + 4 + stun_align (strlen (PACKAGE_STRING)) + 7;
val = stun_bind_reply (buf, &len, buf,
(struct sockaddr *)&ip4, sizeof (ip4), false);
assert (val == ENOBUFS);
assert (len == 0);
/* Non-multiplexed message */ /* Non-multiplexed message */
len = sizeof (buf); len = sizeof (buf);
val = stun_bind_reply (buf, &len, req, val = stun_bind_reply (buf, &len, req,
......
...@@ -96,11 +96,33 @@ int main (void) ...@@ -96,11 +96,33 @@ int main (void)
sizeof (ip4), pass, &control, tie); sizeof (ip4), pass, &control, tie);
assert (val == EPERM); assert (val == EPERM);
assert (len > 0); assert (len > 0);
assert (stun_get_class (resp) == STUN_ERROR);
assert (!stun_present (resp, STUN_MESSAGE_INTEGRITY));
assert (stun_conncheck_username (req, NULL, 0) == NULL); assert (stun_conncheck_username (req, NULL, 0) == NULL);
assert (stun_conncheck_username (req, nbuf, sizeof (nbuf)) == NULL); assert (stun_conncheck_username (req, nbuf, sizeof (nbuf)) == NULL);
assert (stun_conncheck_priority (req) == 0); assert (stun_conncheck_priority (req) == 0);
assert (stun_conncheck_use_candidate (req) == false); assert (stun_conncheck_use_candidate (req) == false);
/* Bad username */
stun_init_request (req, STUN_BINDING);
len = sizeof (req);
val = stun_finish_short (req, &len, "ab\xff", pass, NULL, 0);
assert (val == 0);
assert (stun_conncheck_username (req, nbuf, sizeof (nbuf)) == NULL);
/* FIXME: use conncheck_reply */
/* Bad fingerprint */
len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4,
sizeof (ip4), "bad", &control, tie);
assert (val == EPERM);
assert (len > 0);
assert (stun_get_class (resp) == STUN_ERROR);
assert (!stun_present (resp, STUN_MESSAGE_INTEGRITY));
/* Good message */ /* Good message */
stun_init_request (req, STUN_BINDING); stun_init_request (req, STUN_BINDING);
val = stun_append32 (req, sizeof (req), STUN_PRIORITY, 0x12345678); val = stun_append32 (req, sizeof (req), STUN_PRIORITY, 0x12345678);
...@@ -116,6 +138,8 @@ int main (void) ...@@ -116,6 +138,8 @@ int main (void)
sizeof (ip4), pass, &control, tie); sizeof (ip4), pass, &control, tie);
assert (val == 0); assert (val == 0);
assert (len > 0); assert (len > 0);
assert (stun_get_class (resp) == STUN_RESPONSE);
assert (stun_present (resp, STUN_MESSAGE_INTEGRITY));
assert (stun_conncheck_priority (req) == 0x12345678); assert (stun_conncheck_priority (req) == 0x12345678);
assert (stun_conncheck_use_candidate (req) == true); assert (stun_conncheck_use_candidate (req) == true);
...@@ -129,19 +153,6 @@ int main (void) ...@@ -129,19 +153,6 @@ int main (void)
assert (strcmp (nbuf, name) == 0); assert (strcmp (nbuf, name) == 0);
/* Bad username */
stun_init_request (req, STUN_BINDING);
len = sizeof (req);
val = stun_finish_short (req, &len, "ab\xff", pass, NULL, 0);
assert (val == 0);
assert (stun_conncheck_username (req, nbuf, sizeof (nbuf)) == NULL);
/* Bad fingerprint */
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4,
sizeof (ip4), "bad", &control, tie);
assert (val == EPERM);
assert (len > 0);
/* Lost role conflict */ /* Lost role conflict */
stun_init_request (req, STUN_BINDING); stun_init_request (req, STUN_BINDING);
val = stun_append64 (req, sizeof (req), STUN_ICE_CONTROLLING, tie + 1); val = stun_append64 (req, sizeof (req), STUN_ICE_CONTROLLING, tie + 1);
...@@ -157,6 +168,8 @@ int main (void) ...@@ -157,6 +168,8 @@ int main (void)
assert (val == EACCES); assert (val == EACCES);
assert (len > 0); assert (len > 0);
assert (control == false); assert (control == false);
assert (stun_get_class (resp) == STUN_RESPONSE);
assert (stun_present (resp, STUN_MESSAGE_INTEGRITY));
/* Won role conflict */ /* Won role conflict */
stun_init_request (req, STUN_BINDING); stun_init_request (req, STUN_BINDING);
...@@ -173,6 +186,8 @@ int main (void) ...@@ -173,6 +186,8 @@ int main (void)
assert (val == 0); assert (val == 0);
assert (len > 0); assert (len > 0);
assert (control == false); assert (control == false);
assert (stun_get_class (resp) == STUN_ERROR);
assert (stun_present (resp, STUN_MESSAGE_INTEGRITY));
return 0; return 0;
} }
...@@ -149,7 +149,7 @@ int main (void) ...@@ -149,7 +149,7 @@ int main (void)
fatal ("Request formatting test failed"); fatal ("Request formatting test failed");
/* Response formatting test */ /* Response formatting test */
stun_init_response (msg, msg); stun_init_response (msg, sizeof (msg), msg);
finish_check (msg); finish_check (msg);
if (memcmp (msg, "\x01\x01", 2)) if (memcmp (msg, "\x01\x01", 2))
fatal ("Response formatting test failed"); fatal ("Response formatting test failed");
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h>
#include "stun/stun-msg.h" #include "stun/stun-msg.h"
#include <stdio.h> #include <stdio.h>
...@@ -180,7 +181,7 @@ static void test_message (void) ...@@ -180,7 +181,7 @@ static void test_message (void)
static void test_attribute (void) static void test_attribute (void)
{ {
static const uint8_t acme[] = static const uint8_t acme[] =
"\x15\x55\x00\x4c" // <-- update message length if needed!! "\x15\x55\x00\x64" // <-- update message length if needed!!
"\x21\x12\xA4\x42" // cookie "\x21\x12\xA4\x42" // cookie
"\x76\x54\x32\x10" "\x76\x54\x32\x10"
"\xfe\xdc\xba\x98" "\xfe\xdc\xba\x98"
...@@ -209,16 +210,28 @@ static void test_attribute (void) ...@@ -209,16 +210,28 @@ static void test_attribute (void)
"\xc0\x00\x02\x01" "\xc0\x00\x02\x01"
"\x66\x60\x00\x00" "\x66\x60\x00\x00"
/* FF06: valid xor'd IPv6 address, 160-bits */
"\xff\x06\x00\x14"
"\x00\x02\x12\x34"
"\x01\x13\xa9\xfa"
"\xa8\xf9\x8c\xff"
"\x20\x26\x74\x48"
"\x8c\x9a\xec\xfd"
/* MESSAGE-INTEGRITY attribute */ /* MESSAGE-INTEGRITY attribute */
"\x00\x08\x00\x14" "\x00\x08\x00\x14"
"\xd2\x0c\x85\xcd" "\x20\x10\xee\x8d"
"\x43\x3b\xec\x9e" "\x61\xc9\x3e\x46"
"\x4d\x84\x2d\x87" "\xbe\x41\xad\x5c"
"\x82\x80\x5b\x3b" "\xad\x38\xaa\x4c"
"\xd5\x54\xd8\xa8" "\xe8\xf1\xaf\x07"
; ;
struct sockaddr addr; union
{
struct sockaddr sa;
struct sockaddr_in6 s6;
} addr;
socklen_t addrlen; socklen_t addrlen;
uint32_t dword; uint32_t dword;
uint64_t qword; uint64_t qword;
...@@ -264,20 +277,25 @@ static void test_attribute (void) ...@@ -264,20 +277,25 @@ static void test_attribute (void)
fatal ("String test failed"); fatal ("String test failed");
addrlen = sizeof (addr); addrlen = sizeof (addr);
if (stun_find_addr (acme, 0xff01, &addr, &addrlen) != EINVAL) if (stun_find_addr (acme, 0xff01, &addr.sa, &addrlen) != EINVAL)
fatal ("Too short addres test failed"); fatal ("Too short addres test failed");
addrlen = sizeof (addr); addrlen = sizeof (addr);
if (stun_find_addr (acme, 0xff02, &addr, &addrlen) != EAFNOSUPPORT) if (stun_find_addr (acme, 0xff02, &addr.sa, &addrlen) != EAFNOSUPPORT)
fatal ("Unknown address family test failed"); fatal ("Unknown address family test failed");
addrlen = sizeof (addr); addrlen = sizeof (addr);
if (stun_find_addr (acme, 0xff03, &addr, &addrlen) != EINVAL) if (stun_find_addr (acme, 0xff03, &addr.sa, &addrlen) != EINVAL)
fatal ("Too short IPv6 address test failed"); fatal ("Too short IPv6 address test failed");
addrlen = sizeof (addr); addrlen = sizeof (addr);
if (stun_find_addr (acme, 0xff04, &addr, &addrlen) != 0) if (stun_find_addr (acme, 0xff04, &addr.sa, &addrlen) != 0)
fatal ("IPv4 address test failed"); fatal ("IPv4 address test failed");
addrlen = sizeof (addr); addrlen = sizeof (addr);
if (stun_find_addr (acme, 0xff05, &addr, &addrlen) != EINVAL) if (stun_find_addr (acme, 0xff05, &addr.sa, &addrlen) != EINVAL)
fatal ("Too big IPv4 address test failed"); fatal ("Too big IPv4 address test failed");
addrlen = sizeof (addr);
if (stun_find_xor_addr (acme, 0xff06, &addr.sa, &addrlen)
|| memcmp (&addr.s6.sin6_addr, "\x20\x01\x0d\xb8""\xde\xad\xbe\xef"
"\xde\xfa\xce\xd0""\xfa\xce\xde\xed", 16))
fatal ("IPv6 address test failed");
if (stun_verify_key (acme, "good_guy", 8) != 0) if (stun_verify_key (acme, "good_guy", 8) != 0)
fatal ("Good secret HMAC test failed"); fatal ("Good secret HMAC test failed");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment