Commit 8338ac59 authored by Youness Alaoui's avatar Youness Alaoui

Completed TURN usage in libstun

parent b6e22402
......@@ -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,
......
......@@ -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);
......
......@@ -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;
}
......
......@@ -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
}
......
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