summaryrefslogtreecommitdiff
path: root/stun
diff options
context:
space:
mode:
authorYouness Alaoui <kakaroto@kakaroto.(none)>2008-08-06 17:15:02 -0400
committerYouness Alaoui <kakaroto@kakaroto.(none)>2008-08-06 17:15:02 -0400
commit8338ac59ae180516e7c20812e364f6a6df524ac2 (patch)
treefdfbf1674a7274f43afad6215a53410e2937ff3c /stun
parentb6e2240258f57834ee41eea552aef8d0f8aacc75 (diff)
downloadlibnice-8338ac59ae180516e7c20812e364f6a6df524ac2.tar.gz
Completed TURN usage in libstun
Diffstat (limited to 'stun')
-rw-r--r--stun/stunmessage.h5
-rw-r--r--stun/tests/test-turn.c62
-rw-r--r--stun/usages/turn.c134
-rw-r--r--stun/usages/turn.h11
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
}