diff options
author | Youness Alaoui <kakaroto@kakaroto.(none)> | 2008-08-06 17:15:02 -0400 |
---|---|---|
committer | Youness Alaoui <kakaroto@kakaroto.(none)> | 2008-08-06 17:15:02 -0400 |
commit | 8338ac59ae180516e7c20812e364f6a6df524ac2 (patch) | |
tree | fdfbf1674a7274f43afad6215a53410e2937ff3c /stun | |
parent | b6e2240258f57834ee41eea552aef8d0f8aacc75 (diff) | |
download | libnice-8338ac59ae180516e7c20812e364f6a6df524ac2.tar.gz |
Completed TURN usage in libstun
Diffstat (limited to 'stun')
-rw-r--r-- | stun/stunmessage.h | 5 | ||||
-rw-r--r-- | stun/tests/test-turn.c | 62 | ||||
-rw-r--r-- | stun/usages/turn.c | 134 | ||||
-rw-r--r-- | stun/usages/turn.h | 11 |
4 files changed, 139 insertions, 73 deletions
diff --git a/stun/stunmessage.h b/stun/stunmessage.h index 3ded5de..def2a6d 100644 --- a/stun/stunmessage.h +++ b/stun/stunmessage.h @@ -57,8 +57,9 @@ typedef enum { STUN_BINDING=0x001, /* RFC3489bis-11 */ STUN_OLD_SHARED_SECRET=0x002, /* old RFC3489 */ - STUN_ALLOCATE=0x003, /* TURN-04 */ + STUN_ALLOCATE=0x003, /* TURN-09 */ STUN_SET_ACTIVE_DST=0x004, /* TURN-04 */ + STUN_REFRESH=0x004, /* TURN-09 */ STUN_SEND=0x004, /* TURN-09 */ STUN_CONNECT=0x005, /* TURN-04 */ STUN_IND_SEND=0x006, /* TURN-04 */ @@ -96,6 +97,7 @@ typedef enum STUN_ATTRIBUTE_REALM=0x0014, /* RFC3489bis-11 */ STUN_ATTRIBUTE_NONCE=0x0015, /* RFC3489bis-11 */ STUN_ATTRIBUTE_RELAY_ADDRESS=0x0016, /* TURN-04 */ + STUN_ATTRIBUTE_RELAYED_ADDRESS=0x0016, /* TURN-09 */ STUN_ATTRIBUTE_REQUESTED_ADDRESS_TYPE=0x0017, /* TURN-IPv6-03 */ STUN_ATTRIBUTE_REQUESTED_PORT_PROPS=0x0018, /* TURN-04 */ STUN_ATTRIBUTE_REQUESTED_TRANSPORT=0x0019, /* TURN-04 */ @@ -154,6 +156,7 @@ static const uint16_t STUN_ALL_KNOWN_ATTRIBUTES[] = STUN_ATTRIBUTE_REALM, STUN_ATTRIBUTE_NONCE, STUN_ATTRIBUTE_RELAY_ADDRESS, + STUN_ATTRIBUTE_RELAYED_ADDRESS, STUN_ATTRIBUTE_REQUESTED_ADDRESS_TYPE, STUN_ATTRIBUTE_REQUESTED_PORT_PROPS, STUN_ATTRIBUTE_REQUESTED_TRANSPORT, diff --git a/stun/tests/test-turn.c b/stun/tests/test-turn.c index 2b43d08..1237af4 100644 --- a/stun/tests/test-turn.c +++ b/stun/tests/test-turn.c @@ -41,7 +41,6 @@ #include <sys/socket.h> #include "stun/stunagent.h" #include "stun/usages/turn.h" -#include "stun/usages/bind.h" #include <stdlib.h> #include <stdio.h> @@ -106,10 +105,13 @@ static void responses (void) { struct sockaddr_storage addr; socklen_t addrlen = sizeof (addr); + struct sockaddr_storage alternate_addr; + socklen_t alternate_addrlen = sizeof (alternate_addr); + struct sockaddr_storage relay_addr; + socklen_t relay_addrlen = sizeof (relay_addr); ssize_t val; size_t len; int fd; - int bind_fd; uint8_t buf[STUN_MAX_MESSAGE_SIZE]; uint8_t req[STUN_MAX_MESSAGE_SIZE]; size_t req_len; @@ -117,17 +119,8 @@ static void responses (void) StunMessage msg; StunMessage req_msg; uint32_t bandwidth, lifetime; - uint8_t username[] = {0x72, 0x63, 0x77, 0x45, -0x4f, 0x37, 0x39, 0x50, -0x75, 0x49, 0x59, 0x36, -0x32, 0x7a, 0x68, 0x7a}; -#if 0 - uint8_t password[] = {0x1e, 0xbc, 0x9f, 0xa3, -0xf9, 0x61, 0x03, 0xa3, -0xfd, 0xdc, 0xee, 0xd7, -0xa6, 0xcf, 0x87, 0x4b}; -#endif - uint8_t *password = NULL; + char username[] = "youness.alaoui@collabora.co.uk"; + char password[] = "badger"; struct addrinfo hints, *res; int ret = -1; @@ -136,17 +129,15 @@ static void responses (void) hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = 0; - ret = getaddrinfo ("216.239.51.126", "19295", &hints, &res); + ret = getaddrinfo ("numb.viagenie.ca", "3478", &hints, &res); assert (ret == 0); stun_agent_init (&agent, STUN_ALL_KNOWN_ATTRIBUTES, - STUN_COMPATIBILITY_RFC3489, 0); + STUN_COMPATIBILITY_3489BIS, 0); /* Allocate a client socket and connect to server */ fd = socket (AF_INET, SOCK_DGRAM, 0); assert (fd != -1); - bind_fd = socket (AF_INET, SOCK_DGRAM, 0); - assert (bind_fd != -1); val = connect (fd,res->ai_addr, res->ai_addrlen); assert (val == 0 || (errno == EINPROGRESS)); @@ -157,36 +148,14 @@ static void responses (void) hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = 0; - ret = getaddrinfo ("216.239.51.126", "19302", &hints, &res); - assert (ret == 0); - - val = connect (bind_fd, res->ai_addr, res->ai_addrlen); - assert (val == 0 || (errno == EINPROGRESS)); - -#if 0 - /* Send old-style response */ - req_len = stun_usage_bind_create (&agent, &req_msg, req, sizeof(req)); - assert (req_len > 0); - - val = send (bind_fd, req, req_len, MSG_NOSIGNAL); - assert (val >= 0); - - val = recv (bind_fd, buf, 1000, 0); - assert (val >= 0); - - assert (stun_agent_validate (&agent, &msg, buf, val, NULL, NULL) - == STUN_VALIDATION_SUCCESS); - - sleep (3); -#endif /* Send old-style response */ req_len = stun_usage_turn_create (&agent, &req_msg, req, sizeof(req), NULL, STUN_USAGE_TURN_REQUEST_PORT_NORMAL, 0, 0, - username, sizeof (username), password, sizeof(password), - STUN_USAGE_TURN_COMPATIBILITY_GOOGLE); + username, strlen (username), password, strlen(password), + STUN_USAGE_TURN_COMPATIBILITY_TD9); assert (req_len > 0); val = send (fd, req, req_len, MSG_NOSIGNAL); @@ -195,13 +164,16 @@ static void responses (void) val = recv (fd, buf, 1000, 0); assert (val >= 0); - /* assert (stun_agent_validate (&agent, &msg, buf, val, NULL, NULL) + assert (stun_agent_validate (&agent, &msg, buf, val, NULL, NULL) == STUN_VALIDATION_SUCCESS); val = stun_usage_turn_process (&msg, - (struct sockaddr *)&addr, &addrlen, (struct sockaddr *)&addr, &addrlen, - &bandwidth, &lifetime); - assert (val == STUN_USAGE_TURN_RETURN_SUCCESS);*/ + (struct sockaddr *)&relay_addr, &relay_addrlen, + (struct sockaddr *)&addr, &addrlen, + (struct sockaddr *)&alternate_addr, &alternate_addrlen, + &bandwidth, &lifetime, + STUN_USAGE_TURN_COMPATIBILITY_TD9); + assert (val == STUN_USAGE_TURN_RETURN_SUCCESS); val = close (fd); assert (val == 0); diff --git a/stun/usages/turn.c b/stun/usages/turn.c index 6a85993..ac5af7c 100644 --- a/stun/usages/turn.c +++ b/stun/usages/turn.c @@ -50,12 +50,21 @@ #include <sys/time.h> #include <fcntl.h> + + +#define REQUESTED_PROPS_E 0x80000000 +#define REQUESTED_PROPS_R 0x40000000 +#define REQUESTED_PROPS_P 0x20000000 + + +#define STUN_ATTRIBUTE_MSN_MAPPED_ADDRESS 0x8000 + /** Non-blocking mode STUN TURN usage */ size_t stun_usage_turn_create (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, - StunMessage *previous_request, - uint32_t request_ports, + StunMessage *previous_response, + uint32_t request_props, uint32_t bandwidth, uint32_t lifetime, uint8_t *username, size_t username_len, uint8_t *password, size_t password_len, @@ -78,35 +87,46 @@ size_t stun_usage_turn_create (StunAgent *agent, StunMessage *msg, return 0; } -#if 0 - if (request_ports != STUN_USAGE_TURN_REQUEST_PORT_NORMAL) { + if (compatibility == STUN_USAGE_TURN_COMPATIBILITY_TD9 && + request_props != STUN_USAGE_TURN_REQUEST_PORT_NORMAL) { uint32_t req = 0; - if (compatibility == STUN_USAGE_TURN_COMPATIBILITY_TD9) { + if ((request_props & STUN_USAGE_TURN_REQUEST_PORT_BOTH) == + STUN_USAGE_TURN_REQUEST_PORT_BOTH){ + req |= REQUESTED_PROPS_R; + req |= REQUESTED_PROPS_E; + } else if (request_props & STUN_USAGE_TURN_REQUEST_PORT_EVEN) { + req |= REQUESTED_PROPS_E; + } + if (request_props & STUN_USAGE_TURN_REQUEST_PORT_PRESERVING) { + req |= REQUESTED_PROPS_P; } + if (stun_message_append32 (msg, STUN_ATTRIBUTE_REQUESTED_PORT_PROPS, req) != 0) return 0; } -#endif - if (previous_request) { - char realm[100]; - char nonce[100]; + if (previous_response) { + uint8_t *realm; + uint8_t *nonce; uint64_t reservation; + uint16_t len; - if (stun_message_find_string (previous_request, STUN_ATTRIBUTE_REALM, - realm, sizeof(realm)) == 0) { - if (stun_message_append_string (msg, STUN_ATTRIBUTE_REALM, realm) != 0) + realm = (uint8_t *) stun_message_find (previous_response, + STUN_ATTRIBUTE_REALM, &len); + if (realm != NULL) { + if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_REALM, realm, len) != 0) return 0; } - if (stun_message_find_string (previous_request, STUN_ATTRIBUTE_NONCE, - nonce, sizeof(nonce)) == 0) { - if (stun_message_append_string (msg, STUN_ATTRIBUTE_NONCE, nonce) != 0) + nonce = (uint8_t *) stun_message_find (previous_response, + STUN_ATTRIBUTE_NONCE, &len); + if (nonce != NULL) { + if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_NONCE, nonce, len) != 0) return 0; } - if (stun_message_find64 (previous_request, STUN_ATTRIBUTE_RESERVATION_TOKEN, + if (stun_message_find64 (previous_response, STUN_ATTRIBUTE_RESERVATION_TOKEN, &reservation) == 0) { if (stun_message_append64 (msg, STUN_ATTRIBUTE_RESERVATION_TOKEN, reservation) != 0) @@ -123,10 +143,61 @@ size_t stun_usage_turn_create (StunAgent *agent, StunMessage *msg, return stun_agent_finish_message (agent, msg, password, password_len); } +size_t stun_usage_turn_create_refresh (StunAgent *agent, StunMessage *msg, + uint8_t *buffer, size_t buffer_len, + StunMessage *previous_request, int lifetime, + StunUsageTurnCompatibility compatibility) +{ + uint8_t *realm = NULL; + uint8_t *nonce = NULL; + uint8_t *username = NULL; + uint16_t len; + + if (compatibility == STUN_USAGE_TURN_COMPATIBILITY_TD9) { + stun_agent_init_request (agent, msg, buffer, buffer_len, STUN_REFRESH); + if (lifetime >= 0) { + if (stun_message_append32 (msg, STUN_ATTRIBUTE_LIFETIME, lifetime) != 0) + return 0; + } + } else { + stun_agent_init_request (agent, msg, buffer, buffer_len, STUN_ALLOCATE); + if (stun_message_append32 (msg, STUN_ATTRIBUTE_MAGIC_COOKIE, + TURN_MAGIC_COOKIE) != 0) + return 0; + } + + + realm = (uint8_t *) stun_message_find (previous_request, + STUN_ATTRIBUTE_REALM, &len); + if (realm != NULL) { + if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_REALM, realm, len) != 0) + return 0; + } + nonce = (uint8_t *) stun_message_find (previous_request, + STUN_ATTRIBUTE_NONCE, &len); + if (nonce != NULL) { + if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_NONCE, nonce, len) != 0) + return 0; + } + username = (uint8_t *) stun_message_find (previous_request, + STUN_ATTRIBUTE_USERNAME, &len); + if (username != NULL) { + if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_USERNAME, + username, len) != 0) + return 0; + } + + + return stun_agent_finish_message (agent, msg, + previous_request->key, previous_request->key_len); +} + StunUsageTurnReturn stun_usage_turn_process (StunMessage *msg, + struct sockaddr *relay_addr, socklen_t *relay_addrlen, struct sockaddr *addr, socklen_t *addrlen, struct sockaddr *alternate_server, socklen_t *alternate_server_len, - uint32_t *bandwidth, uint32_t *lifetime) + uint32_t *bandwidth, uint32_t *lifetime, + StunUsageTurnCompatibility compatibility) { int val, code = -1; @@ -173,15 +244,28 @@ StunUsageTurnReturn stun_usage_turn_process (StunMessage *msg, stun_debug ("Received %u-bytes STUN message\n", stun_message_length (msg)); - val = stun_message_find_xor_addr (msg, - STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, addr, addrlen); - if (val) - { - stun_debug (" No XOR-MAPPED-ADDRESS: %s\n", strerror (val)); + if (compatibility == STUN_USAGE_TURN_COMPATIBILITY_TD9) { + stun_message_find_xor_addr (msg, + STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, addr, addrlen); + val = stun_message_find_addr (msg, + STUN_ATTRIBUTE_RELAY_ADDRESS, relay_addr, relay_addrlen); + if (val) { + stun_debug (" No RELAYED-ADDRESS: %s\n", strerror (val)); + return STUN_USAGE_TURN_RETURN_ERROR; + } + } else if (compatibility == STUN_USAGE_TURN_COMPATIBILITY_TD9) { + val = stun_message_find_addr (msg, + STUN_ATTRIBUTE_MAPPED_ADDRESS, relay_addr, relay_addrlen); + if (val) { + stun_debug (" No MAPPED-ADDRESS: %s\n", strerror (val)); + return STUN_USAGE_TURN_RETURN_ERROR; + } + }else if (compatibility == STUN_USAGE_TURN_COMPATIBILITY_MSN) { + stun_message_find_xor_addr (msg, + STUN_ATTRIBUTE_MSN_MAPPED_ADDRESS, addr, addrlen); val = stun_message_find_addr (msg, - STUN_ATTRIBUTE_MAPPED_ADDRESS, addr, addrlen); - if (val) - { + STUN_ATTRIBUTE_MAPPED_ADDRESS, relay_addr, relay_addrlen); + if (val) { stun_debug (" No MAPPED-ADDRESS: %s\n", strerror (val)); return STUN_USAGE_TURN_RETURN_ERROR; } diff --git a/stun/usages/turn.h b/stun/usages/turn.h index 49a582e..41532b0 100644 --- a/stun/usages/turn.h +++ b/stun/usages/turn.h @@ -54,7 +54,7 @@ extern "C" { #define STUN_USAGE_TURN_REQUEST_PORT_NORMAL 0 #define STUN_USAGE_TURN_REQUEST_PORT_ODD 1 #define STUN_USAGE_TURN_REQUEST_PORT_EVEN 2 -#define STUN_USAGE_TURN_REQUEST_PORT_BOTH 4 +#define STUN_USAGE_TURN_REQUEST_PORT_BOTH 3 #define STUN_USAGE_TURN_REQUEST_PORT_PRESERVING 8 typedef enum { @@ -80,10 +80,17 @@ size_t stun_usage_turn_create (StunAgent *agent, StunMessage *msg, uint8_t *password, size_t password_len, StunUsageTurnCompatibility compatibility); +size_t stun_usage_turn_create_refresh (StunAgent *agent, StunMessage *msg, + uint8_t *buffer, size_t buffer_len, + StunMessage *previous_request, int lifetime, + StunUsageTurnCompatibility compatibility); + StunUsageTurnReturn stun_usage_turn_process (StunMessage *msg, + struct sockaddr *relay_addr, socklen_t *relay_addrlen, struct sockaddr *addr, socklen_t *addrlen, struct sockaddr *alternate_server, socklen_t *alternate_server_len, - uint32_t *bandwidth, uint32_t *lifetime); + uint32_t *bandwidth, uint32_t *lifetime, + StunUsageTurnCompatibility compatibility); # ifdef __cplusplus } |