Commit 6e91f5b9 authored by Marcus Lundblad's avatar Marcus Lundblad Committed by Youness Alaoui

Fixing tabs, trailing whitespaces and indentation

parent 29f97e9e
...@@ -89,11 +89,12 @@ typedef struct { ...@@ -89,11 +89,12 @@ typedef struct {
uint8_t ms_connection_id[20]; uint8_t ms_connection_id[20];
uint32_t ms_sequence_num; uint32_t ms_sequence_num;
bool ms_connection_id_valid; bool ms_connection_id_valid;
GList *permissions; /* the peers (NiceAddress) for which GList *permissions; /* the peers (NiceAddress) for which
there is an installed permission */ there is an installed permission */
GList *sent_permissions; /* ongoing permission installed */ GList *sent_permissions; /* ongoing permission installed */
GHashTable *send_data_queues; /* stores a send data queue for per peer */ GHashTable *send_data_queues; /* stores a send data queue for per peer */
guint permission_timeout_source; /* timer used to invalidate permissions */ guint permission_timeout_source; /* timer used to invalidate
permissions */
gboolean has_binding; gboolean has_binding;
gboolean sent_binding; gboolean sent_binding;
guint binding_timeout_source; guint binding_timeout_source;
...@@ -114,9 +115,9 @@ typedef struct { ...@@ -114,9 +115,9 @@ typedef struct {
static void socket_close (NiceSocket *sock); static void socket_close (NiceSocket *sock);
static gint socket_recv (NiceSocket *sock, NiceAddress *from, static gint socket_recv (NiceSocket *sock, NiceAddress *from,
guint len, gchar *buf); guint len, gchar *buf);
static gboolean socket_send (NiceSocket *sock, const NiceAddress *to, static gboolean socket_send (NiceSocket *sock, const NiceAddress *to,
guint len, const gchar *buf); guint len, const gchar *buf);
static gboolean socket_is_reliable (NiceSocket *sock); static gboolean socket_is_reliable (NiceSocket *sock);
static void priv_process_pending_bindings (TurnPriv *priv); static void priv_process_pending_bindings (TurnPriv *priv);
...@@ -125,11 +126,14 @@ static gboolean priv_retransmissions_tick (gpointer pointer); ...@@ -125,11 +126,14 @@ static gboolean priv_retransmissions_tick (gpointer pointer);
static void priv_schedule_tick (TurnPriv *priv); static void priv_schedule_tick (TurnPriv *priv);
static void priv_send_turn_message (TurnPriv *priv, TURNMessage *msg); static void priv_send_turn_message (TurnPriv *priv, TURNMessage *msg);
static gboolean priv_send_create_permission (TurnPriv *priv, static gboolean priv_send_create_permission (TurnPriv *priv,
uint8_t *realm, gsize realm_len, uint8_t *nonce, gsize nonce_len, uint8_t *realm, gsize realm_len,
const NiceAddress *peer); uint8_t *nonce, gsize nonce_len,
const NiceAddress *peer);
static gboolean priv_send_channel_bind (TurnPriv *priv, StunMessage *resp, static gboolean priv_send_channel_bind (TurnPriv *priv, StunMessage *resp,
uint16_t channel, const NiceAddress *peer); uint16_t channel,
static gboolean priv_add_channel_binding (TurnPriv *priv, const NiceAddress *peer); const NiceAddress *peer);
static gboolean priv_add_channel_binding (TurnPriv *priv,
const NiceAddress *peer);
static gboolean priv_forget_send_request (gpointer pointer); static gboolean priv_forget_send_request (gpointer pointer);
static guint static guint
...@@ -139,28 +143,29 @@ priv_nice_address_hash (gconstpointer data) ...@@ -139,28 +143,29 @@ priv_nice_address_hash (gconstpointer data)
nice_address_to_string ((NiceAddress *) data, address); nice_address_to_string ((NiceAddress *) data, address);
return g_str_hash(address); return g_str_hash(address);
} }
static void static void
priv_send_data_queue_destroy (gpointer data) priv_send_data_queue_destroy (gpointer data)
{ {
GQueue *send_queue = (GQueue *) data; GQueue *send_queue = (GQueue *) data;
GList *i; GList *i;
for (i = g_queue_peek_head_link (send_queue); i; i = i->next) {
SendData *data = (SendData *) i->data;
g_free (data->data); for (i = g_queue_peek_head_link (send_queue); i; i = i->next) {
g_slice_free (SendData, data); SendData *data = (SendData *) i->data;
}
g_queue_free (send_queue); g_free (data->data);
g_slice_free (SendData, data);
}
g_queue_free (send_queue);
} }
NiceSocket * NiceSocket *
nice_turn_socket_new (NiceAgent *agent, NiceAddress *addr, nice_turn_socket_new (NiceAgent *agent, NiceAddress *addr,
NiceSocket *base_socket, NiceAddress *server_addr, NiceSocket *base_socket, NiceAddress *server_addr,
gchar *username, gchar *password, NiceTurnSocketCompatibility compatibility) gchar *username, gchar *password,
NiceTurnSocketCompatibility compatibility)
{ {
TurnPriv *priv = g_new0 (TurnPriv, 1); TurnPriv *priv = g_new0 (TurnPriv, 1);
NiceSocket *sock = g_slice_new0 (NiceSocket); NiceSocket *sock = g_slice_new0 (NiceSocket);
...@@ -172,13 +177,13 @@ nice_turn_socket_new (NiceAgent *agent, NiceAddress *addr, ...@@ -172,13 +177,13 @@ nice_turn_socket_new (NiceAgent *agent, NiceAddress *addr,
if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 || if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 ||
compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) { compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) {
stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES, stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES,
STUN_COMPATIBILITY_RFC5389, STUN_COMPATIBILITY_RFC5389,
STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS); STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS);
} else if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_MSN) { } else if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_MSN) {
stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES, stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES,
STUN_COMPATIBILITY_RFC3489, STUN_COMPATIBILITY_RFC3489,
STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS | STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS |
STUN_AGENT_USAGE_NO_INDICATION_AUTH); STUN_AGENT_USAGE_NO_INDICATION_AUTH);
} else if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) { } else if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES, stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES,
STUN_COMPATIBILITY_RFC3489, STUN_COMPATIBILITY_RFC3489,
...@@ -217,10 +222,10 @@ nice_turn_socket_new (NiceAgent *agent, NiceAddress *addr, ...@@ -217,10 +222,10 @@ nice_turn_socket_new (NiceAgent *agent, NiceAddress *addr,
priv->send_requests = g_queue_new (); priv->send_requests = g_queue_new ();
priv->send_data_queues = priv->send_data_queues =
g_hash_table_new_full (priv_nice_address_hash, g_hash_table_new_full (priv_nice_address_hash,
(GEqualFunc) nice_address_equal, (GEqualFunc) nice_address_equal,
(GDestroyNotify) nice_address_free, (GDestroyNotify) nice_address_free,
priv_send_data_queue_destroy); priv_send_data_queue_destroy);
sock->addr = *addr; sock->addr = *addr;
sock->fileno = base_socket->fileno; sock->fileno = base_socket->fileno;
sock->send = socket_send; sock->send = socket_send;
...@@ -246,7 +251,7 @@ socket_close (NiceSocket *sock) ...@@ -246,7 +251,7 @@ socket_close (NiceSocket *sock)
g_list_free (priv->channels); g_list_free (priv->channels);
g_list_foreach (priv->pending_bindings, (GFunc) nice_address_free, g_list_foreach (priv->pending_bindings, (GFunc) nice_address_free,
NULL); NULL);
g_list_free (priv->pending_bindings); g_list_free (priv->pending_bindings);
if (priv->tick_source_channel_bind != NULL) { if (priv->tick_source_channel_bind != NULL) {
...@@ -272,7 +277,7 @@ socket_close (NiceSocket *sock) ...@@ -272,7 +277,7 @@ socket_close (NiceSocket *sock)
g_list_free (priv->permissions); g_list_free (priv->permissions);
g_hash_table_destroy (priv->send_data_queues); g_hash_table_destroy (priv->send_data_queues);
g_source_remove (priv->permission_timeout_source); g_source_remove (priv->permission_timeout_source);
g_free (priv->current_binding); g_free (priv->current_binding);
g_free (priv->current_binding_msg); g_free (priv->current_binding_msg);
g_free (priv->current_create_permission_msg); g_free (priv->current_create_permission_msg);
...@@ -291,13 +296,14 @@ socket_recv (NiceSocket *sock, NiceAddress *from, guint len, gchar *buf) ...@@ -291,13 +296,14 @@ socket_recv (NiceSocket *sock, NiceAddress *from, guint len, gchar *buf)
NiceSocket *dummy; NiceSocket *dummy;
nice_debug ("received message on TURN socket"); nice_debug ("received message on TURN socket");
recv_len = nice_socket_recv (priv->base_socket, &recv_from, recv_len = nice_socket_recv (priv->base_socket, &recv_from,
sizeof(recv_buf), (gchar *) recv_buf); sizeof(recv_buf), (gchar *) recv_buf);
if (recv_len > 0) if (recv_len > 0)
return nice_turn_socket_parse_recv (sock, &dummy, from, len, buf, return nice_turn_socket_parse_recv (sock, &dummy, from, len, buf,
&recv_from, (gchar *) recv_buf, (guint) recv_len); &recv_from, (gchar *) recv_buf,
(guint) recv_len);
else else
return recv_len; return recv_len;
} }
...@@ -333,7 +339,7 @@ static gboolean ...@@ -333,7 +339,7 @@ static gboolean
priv_has_permission_for_peer (TurnPriv *priv, const NiceAddress *to) priv_has_permission_for_peer (TurnPriv *priv, const NiceAddress *to)
{ {
GList *found = g_list_find_custom (priv->permissions, to, GList *found = g_list_find_custom (priv->permissions, to,
(GCompareFunc) nice_address_equal); (GCompareFunc) nice_address_equal);
return found != NULL; return found != NULL;
} }
...@@ -341,54 +347,54 @@ priv_has_permission_for_peer (TurnPriv *priv, const NiceAddress *to) ...@@ -341,54 +347,54 @@ priv_has_permission_for_peer (TurnPriv *priv, const NiceAddress *to)
static gboolean static gboolean
priv_has_sent_permission_for_peer (TurnPriv *priv, const NiceAddress *to) priv_has_sent_permission_for_peer (TurnPriv *priv, const NiceAddress *to)
{ {
return g_list_find_custom (priv->sent_permissions, to, return g_list_find_custom (priv->sent_permissions, to,
(GCompareFunc) nice_address_equal) != NULL; (GCompareFunc) nice_address_equal) != NULL;
} }
static void static void
socket_enqueue_data(TurnPriv *priv, const NiceAddress *to, socket_enqueue_data(TurnPriv *priv, const NiceAddress *to,
guint len, const gchar *buf) guint len, const gchar *buf)
{ {
SendData *data = g_slice_new0 (SendData); SendData *data = g_slice_new0 (SendData);
GQueue *queue = g_hash_table_lookup (priv->send_data_queues, to); GQueue *queue = g_hash_table_lookup (priv->send_data_queues, to);
if (queue == NULL) { if (queue == NULL) {
queue = g_queue_new (); queue = g_queue_new ();
g_hash_table_insert (priv->send_data_queues, nice_address_dup (to), g_hash_table_insert (priv->send_data_queues, nice_address_dup (to),
queue); queue);
} }
data->data = g_memdup(buf, len); data->data = g_memdup(buf, len);
data->data_len = len; data->data_len = len;
g_queue_push_tail (queue, data); g_queue_push_tail (queue, data);
} }
static void static void
socket_dequeue_all_data (TurnPriv *priv, const NiceAddress *to) socket_dequeue_all_data (TurnPriv *priv, const NiceAddress *to)
{ {
GQueue *send_queue = g_hash_table_lookup (priv->send_data_queues, to); GQueue *send_queue = g_hash_table_lookup (priv->send_data_queues, to);
if (send_queue) {
while (!g_queue_is_empty (send_queue)) {
SendData *data =
(SendData *) g_queue_pop_head(send_queue);
nice_debug("dequeing data enqueued when installing permission or binding");
nice_socket_send (priv->base_socket, to, data->data_len, data->data);
g_free (data->data);
g_slice_free (SendData, data);
}
/* remove queue from table */ if (send_queue) {
g_hash_table_remove (priv->send_data_queues, to); while (!g_queue_is_empty (send_queue)) {
} SendData *data =
(SendData *) g_queue_pop_head(send_queue);
nice_debug("dequeing data enqueued when installing permission or binding");
nice_socket_send (priv->base_socket, to, data->data_len, data->data);
g_free (data->data);
g_slice_free (SendData, data);
}
/* remove queue from table */
g_hash_table_remove (priv->send_data_queues, to);
}
} }
static gboolean static gboolean
socket_send (NiceSocket *sock, const NiceAddress *to, socket_send (NiceSocket *sock, const NiceAddress *to,
guint len, const gchar *buf) guint len, const gchar *buf)
{ {
TurnPriv *priv = (TurnPriv *) sock->priv; TurnPriv *priv = (TurnPriv *) sock->priv;
StunMessage msg; StunMessage msg;
...@@ -405,7 +411,7 @@ socket_send (NiceSocket *sock, const NiceAddress *to, ...@@ -405,7 +411,7 @@ socket_send (NiceSocket *sock, const NiceAddress *to,
break; break;
} }
} }
nice_address_copy_to_sockaddr (to, (struct sockaddr *)&sa); nice_address_copy_to_sockaddr (to, (struct sockaddr *)&sa);
if (binding) { if (binding) {
...@@ -425,32 +431,34 @@ socket_send (NiceSocket *sock, const NiceAddress *to, ...@@ -425,32 +431,34 @@ socket_send (NiceSocket *sock, const NiceAddress *to,
return nice_socket_send (priv->base_socket, &priv->server_addr, len, buf); return nice_socket_send (priv->base_socket, &priv->server_addr, len, buf);
} }
} else { } else {
nice_debug("no binding"); nice_debug("no binding");
if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 || if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 ||
priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) { priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) {
if (!stun_agent_init_indication (&priv->agent, &msg, if (!stun_agent_init_indication (&priv->agent, &msg,
buffer, sizeof(buffer), STUN_IND_SEND)) buffer, sizeof(buffer), STUN_IND_SEND))
goto send; goto send;
if (stun_message_append_xor_addr (&msg, STUN_ATTRIBUTE_PEER_ADDRESS, if (stun_message_append_xor_addr (&msg, STUN_ATTRIBUTE_PEER_ADDRESS,
(struct sockaddr *)&sa, sizeof(sa)) != (struct sockaddr *)&sa, sizeof(sa)) !=
STUN_MESSAGE_RETURN_SUCCESS) STUN_MESSAGE_RETURN_SUCCESS)
goto send; goto send;
} else { } else {
if (!stun_agent_init_request (&priv->agent, &msg, if (!stun_agent_init_request (&priv->agent, &msg,
buffer, sizeof(buffer), STUN_SEND)) buffer, sizeof(buffer), STUN_SEND))
goto send; goto send;
if (stun_message_append32 (&msg, STUN_ATTRIBUTE_MAGIC_COOKIE, if (stun_message_append32 (&msg, STUN_ATTRIBUTE_MAGIC_COOKIE,
TURN_MAGIC_COOKIE) != STUN_MESSAGE_RETURN_SUCCESS) TURN_MAGIC_COOKIE) !=
STUN_MESSAGE_RETURN_SUCCESS)
goto send; goto send;
if (priv->username != NULL && priv->username_len > 0) { if (priv->username != NULL && priv->username_len > 0) {
if (stun_message_append_bytes (&msg, STUN_ATTRIBUTE_USERNAME, if (stun_message_append_bytes (&msg, STUN_ATTRIBUTE_USERNAME,
priv->username, priv->username_len) != priv->username, priv->username_len) !=
STUN_MESSAGE_RETURN_SUCCESS) STUN_MESSAGE_RETURN_SUCCESS)
goto send; goto send;
} }
if (stun_message_append_addr (&msg, STUN_ATTRIBUTE_DESTINATION_ADDRESS, if (stun_message_append_addr (&msg, STUN_ATTRIBUTE_DESTINATION_ADDRESS,
(struct sockaddr *)&sa, sizeof(sa)) != STUN_MESSAGE_RETURN_SUCCESS) (struct sockaddr *)&sa,
sizeof(sa)) != STUN_MESSAGE_RETURN_SUCCESS)
goto send; goto send;
if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE && if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE &&
...@@ -471,49 +479,51 @@ socket_send (NiceSocket *sock, const NiceAddress *to, ...@@ -471,49 +479,51 @@ socket_send (NiceSocket *sock, const NiceAddress *to,
} }
if (stun_message_append_bytes (&msg, STUN_ATTRIBUTE_DATA, if (stun_message_append_bytes (&msg, STUN_ATTRIBUTE_DATA,
buf, len) != STUN_MESSAGE_RETURN_SUCCESS) buf, len) != STUN_MESSAGE_RETURN_SUCCESS)
goto send; goto send;
msg_len = stun_agent_finish_message (&priv->agent, &msg, msg_len = stun_agent_finish_message (&priv->agent, &msg,
priv->password, priv->password_len); priv->password, priv->password_len);
if (msg_len > 0 && stun_message_get_class (&msg) == STUN_REQUEST) { if (msg_len > 0 && stun_message_get_class (&msg) == STUN_REQUEST) {
SendRequest *req = g_slice_new0 (SendRequest); SendRequest *req = g_slice_new0 (SendRequest);
req->priv = priv; req->priv = priv;
stun_message_id (&msg, req->id); stun_message_id (&msg, req->id);
req->source = agent_timeout_add_with_context (priv->nice, STUN_END_TIMEOUT, req->source = agent_timeout_add_with_context (priv->nice,
priv_forget_send_request, req); STUN_END_TIMEOUT,
priv_forget_send_request,
req);
g_queue_push_tail (priv->send_requests, req); g_queue_push_tail (priv->send_requests, req);
} }
} }
if (msg_len > 0) { if (msg_len > 0) {
if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) { if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) {
if (!priv_has_permission_for_peer (priv, to) && if (!priv_has_permission_for_peer (priv, to) &&
!priv_has_sent_permission_for_peer (priv, to)) { !priv_has_sent_permission_for_peer (priv, to)) {
nice_debug ("no permission installed for peer"); nice_debug ("no permission installed for peer");
priv_send_create_permission(priv, NULL, 0, NULL, 0, to); priv_send_create_permission(priv, NULL, 0, NULL, 0, to);
} }
} }
if (!priv->has_binding && !priv->sent_binding && binding) { if (!priv->has_binding && !priv->sent_binding && binding) {
nice_debug("renewing channel binding"); nice_debug("renewing channel binding");
priv_send_channel_bind (priv, NULL, binding->channel, to); priv_send_channel_bind (priv, NULL, binding->channel, to);
} }
if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766 && if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766 &&
!priv_has_permission_for_peer (priv, to)) { !priv_has_permission_for_peer (priv, to)) {
/* enque data */ /* enque data */
nice_debug("enqueing data to be sent when aquiring permission or binding"); nice_debug("enqueing data to be sent when aquiring permission or binding");
socket_enqueue_data(priv, to, msg_len, (gchar *)buffer); socket_enqueue_data(priv, to, msg_len, (gchar *)buffer);
return TRUE; return TRUE;
} else { } else {
return nice_socket_send (priv->base_socket, &priv->server_addr, return nice_socket_send (priv->base_socket, &priv->server_addr,
msg_len, (gchar *)buffer); msg_len, (gchar *)buffer);
} }
} }
send: send:
return nice_socket_send (priv->base_socket, to, len, buf); return nice_socket_send (priv->base_socket, to, len, buf);
} }
static gboolean static gboolean
...@@ -532,7 +542,7 @@ priv_forget_send_request (gpointer pointer) ...@@ -532,7 +542,7 @@ priv_forget_send_request (gpointer pointer)
if (g_source_is_destroyed (g_main_current_source ())) { if (g_source_is_destroyed (g_main_current_source ())) {
nice_debug ("Source was destroyed. " nice_debug ("Source was destroyed. "
"Avoided race condition in turn.c:priv_forget_send_request"); "Avoided race condition in turn.c:priv_forget_send_request");
agent_unlock (); agent_unlock ();
return FALSE; return FALSE;
} }
...@@ -555,39 +565,39 @@ priv_forget_send_request (gpointer pointer) ...@@ -555,39 +565,39 @@ priv_forget_send_request (gpointer pointer)
static gboolean static gboolean
priv_permission_timeout (gpointer data) priv_permission_timeout (gpointer data)
{ {
TurnPriv *priv = (TurnPriv *) data; TurnPriv *priv = (TurnPriv *) data;
nice_debug ("Permission is about to timeout, schedule renewal");
nice_debug ("Permission is about to timeout, schedule renewal"); agent_lock ();
/* remove all permissions for this agent (the permission for the peer
agent_lock (); we are sending to will be renewed) */
/* remove all permissions for this agent (the permission for the peer
we are sending to will be renewed) */
g_list_foreach (priv->permissions, (GFunc) nice_address_free, NULL); g_list_foreach (priv->permissions, (GFunc) nice_address_free, NULL);
g_list_free (priv->permissions); g_list_free (priv->permissions);
priv->permissions = NULL; priv->permissions = NULL;
agent_unlock (); agent_unlock ();
return TRUE; return TRUE;
} }
static gboolean static gboolean
priv_binding_timeout (gpointer data) priv_binding_timeout (gpointer data)
{ {
TurnPriv *priv = (TurnPriv *) data; TurnPriv *priv = (TurnPriv *) data;
nice_debug ("Permission is about to timeout, schedule renewal");
nice_debug ("Permission is about to timeout, schedule renewal"); agent_lock ();
priv->has_binding = FALSE;
agent_lock (); agent_unlock ();
priv->has_binding = FALSE;
agent_unlock ();
return TRUE; return TRUE;
} }
gint gint
nice_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock, nice_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock,
NiceAddress *from, guint len, gchar *buf, NiceAddress *from, guint len, gchar *buf,
NiceAddress *recv_from, gchar *recv_buf, guint recv_len) NiceAddress *recv_from, gchar *recv_buf, guint recv_len)
{ {
TurnPriv *priv = (TurnPriv *) sock->priv; TurnPriv *priv = (TurnPriv *) sock->priv;
...@@ -600,14 +610,15 @@ nice_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock, ...@@ -600,14 +610,15 @@ nice_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock,
if (nice_address_equal (&priv->server_addr, recv_from)) { if (nice_address_equal (&priv->server_addr, recv_from)) {
valid = stun_agent_validate (&priv->agent, &msg, valid = stun_agent_validate (&priv->agent, &msg,
(uint8_t *) recv_buf, (size_t) recv_len, NULL, NULL); (uint8_t *) recv_buf, (size_t) recv_len, NULL,
NULL);
if (valid == STUN_VALIDATION_SUCCESS) { if (valid == STUN_VALIDATION_SUCCESS) {
if (priv->compatibility != NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 && if (priv->compatibility != NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 &&
priv->compatibility != NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) { priv->compatibility != NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) {
uint32_t cookie; uint32_t cookie;
if (stun_message_find32 (&msg, STUN_ATTRIBUTE_MAGIC_COOKIE, if (stun_message_find32 (&msg, STUN_ATTRIBUTE_MAGIC_COOKIE,
&cookie) != STUN_MESSAGE_RETURN_SUCCESS) &cookie) != STUN_MESSAGE_RETURN_SUCCESS)
goto recv; goto recv;
if (cookie != TURN_MAGIC_COOKIE) if (cookie != TURN_MAGIC_COOKIE)
goto recv; goto recv;
...@@ -653,7 +664,8 @@ nice_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock, ...@@ -653,7 +664,8 @@ nice_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock,
if (priv->current_binding && priv->current_binding_msg) { if (priv->current_binding && priv->current_binding_msg) {
stun_message_id (&msg, response_id); stun_message_id (&msg, response_id);
stun_message_id (&priv->current_binding_msg->message, request_id); stun_message_id (&priv->current_binding_msg->message, request_id);
if (memcmp (request_id, response_id, sizeof(StunTransactionId)) == 0) { if (memcmp (request_id, response_id,
sizeof(StunTransactionId)) == 0) {
g_free (priv->current_binding_msg); g_free (priv->current_binding_msg);
priv->current_binding_msg = NULL; priv->current_binding_msg = NULL;
...@@ -672,73 +684,77 @@ nice_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock, ...@@ -672,73 +684,77 @@ nice_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock,
} else if (stun_message_get_method (&msg) == STUN_CHANNELBIND) { } else if (stun_message_get_method (&msg) == STUN_CHANNELBIND) {
StunTransactionId request_id; StunTransactionId request_id;
StunTransactionId response_id; StunTransactionId response_id;
if (priv->current_binding_msg) { if (priv->current_binding_msg) {
stun_message_id (&msg, response_id); stun_message_id (&msg, response_id);
stun_message_id (&priv->current_binding_msg->message, request_id); stun_message_id (&priv->current_binding_msg->message, request_id);
if (memcmp (request_id, response_id, sizeof(StunTransactionId)) == 0) { if (memcmp (request_id, response_id,
if (stun_message_get_class (&msg) == STUN_ERROR) { sizeof(StunTransactionId)) == 0) {
if (stun_message_get_class (&msg) == STUN_ERROR) {
int code = -1; int code = -1;
uint8_t *sent_realm = NULL; uint8_t *sent_realm = NULL;
uint8_t *recv_realm = NULL; uint8_t *recv_realm = NULL;
uint16_t sent_realm_len = 0; uint16_t sent_realm_len = 0;
uint16_t recv_realm_len = 0; uint16_t recv_realm_len = 0;
sent_realm = (uint8_t *) stun_message_find ( sent_realm =
&priv->current_binding_msg->message, (uint8_t *) stun_message_find (
STUN_ATTRIBUTE_REALM, &sent_realm_len); &priv->current_binding_msg->message,
recv_realm = (uint8_t *) stun_message_find (&msg, STUN_ATTRIBUTE_REALM, &sent_realm_len);
STUN_ATTRIBUTE_REALM, &recv_realm_len); recv_realm =
(uint8_t *) stun_message_find (&msg,
if (!priv->has_binding) { STUN_ATTRIBUTE_REALM, &recv_realm_len);
nice_debug ("sent realm: %s\n", sent_realm);
nice_debug ("recv realm: %s\n", recv_realm); if (!priv->has_binding) {
} nice_debug ("sent realm: %s\n", sent_realm);
nice_debug ("recv realm: %s\n", recv_realm);
}
/* check for unauthorized error response */ /* check for unauthorized error response */
if (stun_message_find_error (&msg, &code) == if (stun_message_find_error (&msg, &code) ==
STUN_MESSAGE_RETURN_SUCCESS && STUN_MESSAGE_RETURN_SUCCESS &&
(code == 438 || (code == 401 && (code == 438 || (code == 401 &&
!(recv_realm != NULL && !(recv_realm != NULL &&
recv_realm_len > 0 && recv_realm_len > 0 &&
recv_realm_len == sent_realm_len && recv_realm_len == sent_realm_len &&
sent_realm != NULL && sent_realm != NULL &&
memcmp (sent_realm, recv_realm, sent_realm_len) == 0)))) { memcmp (sent_realm, recv_realm,
sent_realm_len) == 0)))) {
if (priv->current_binding) { if (priv->current_binding) {
g_free (priv->current_binding_msg); g_free (priv->current_binding_msg);
priv->current_binding_msg = NULL; priv->current_binding_msg = NULL;
priv_send_channel_bind (priv, &msg, priv_send_channel_bind (priv, &msg,
priv->current_binding->channel, priv->current_binding->channel,
&priv->current_binding->peer); &priv->current_binding->peer);
} else { } else {
/* look up binding associated with peer */ /* look up binding associated with peer */
GList *i = priv->channels; GList *i = priv->channels;
ChannelBinding *binding = NULL; ChannelBinding *binding = NULL;
struct sockaddr sa; struct sockaddr sa;
socklen_t sa_len = sizeof(sa); socklen_t sa_len = sizeof(sa);
NiceAddress to; NiceAddress to;
stun_message_find_xor_addr (&priv->current_binding_msg->message, stun_message_find_xor_addr (&priv->current_binding_msg->message,
STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &sa, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &sa,
&sa_len); &sa_len);
nice_address_set_from_sockaddr (&to, &sa); nice_address_set_from_sockaddr (&to, &sa);
for (; i; i = i->next) { for (; i; i = i->next) {
ChannelBinding *b = i->data; ChannelBinding *b = i->data;
if (nice_address_equal (&b->peer, &to)) { if (nice_address_equal (&b->peer, &to)) {
binding = b; binding = b;
break; break;
} }
} }
g_free (priv->current_binding_msg); g_free (priv->current_binding_msg);
priv->current_binding_msg = NULL; priv->current_binding_msg = NULL;
if (binding) if (binding)
priv_send_channel_bind (priv, &msg, binding->channel, &to); priv_send_channel_bind (priv, &msg, binding->channel, &to);
} }
} else { } else {
g_free (priv->current_binding); g_free (priv->current_binding);
priv->current_binding = NULL; priv->current_binding = NULL;
g_free (priv->current_binding_msg); g_free (priv->current_binding_msg);
...@@ -748,122 +764,123 @@ nice_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock, ...@@ -748,122 +764,123 @@ nice_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock,
} else if (stun_message_get_class (&msg) == STUN_RESPONSE) { } else if (stun_message_get_class (&msg) == STUN_RESPONSE) {
g_free (priv->current_binding_msg); g_free (priv->current_binding_msg);
priv->current_binding_msg = NULL; priv->current_binding_msg = NULL;
priv->has_binding = TRUE; priv->has_binding = TRUE;
priv->sent_binding = FALSE; priv->sent_binding = FALSE;
if (priv->current_binding) { if (priv->current_binding) {
priv->channels = g_list_append (priv->channels, priv->channels = g_list_append (priv->channels,
priv->current_binding); priv->current_binding);
priv->current_binding = NULL; priv->current_binding = NULL;
} }
priv_process_pending_bindings (priv); priv_process_pending_bindings (priv);
/* install timer to schedule refresh of the permission */ /* install timer to schedule refresh of the permission */
if (!priv->binding_timeout_source) { if (!priv->binding_timeout_source) {
priv->binding_timeout_source = priv->binding_timeout_source =
g_timeout_add_seconds (STUN_BINDING_TIMEOUT, g_timeout_add_seconds (STUN_BINDING_TIMEOUT,
priv_binding_timeout, priv); priv_binding_timeout, priv);
} }
} }
} }
} }
return 0; return 0;
} else if (stun_message_get_method (&msg) == STUN_CREATEPERMISSION) { } else if (stun_message_get_method (&msg) == STUN_CREATEPERMISSION) {
StunTransactionId request_id; StunTransactionId request_id;
StunTransactionId response_id; StunTransactionId response_id;
if (priv->current_create_permission_msg) { if (priv->current_create_permission_msg) {
stun_message_id (&msg, response_id); stun_message_id (&msg, response_id);
stun_message_id (&priv->current_create_permission_msg->message, request_id); stun_message_id (&priv->current_create_permission_msg->message,
request_id);
if (memcmp (request_id, response_id, sizeof(StunTransactionId)) == 0) {
struct sockaddr peer; if (memcmp (request_id, response_id, sizeof(StunTransactionId)) == 0) {
socklen_t peer_len = sizeof(peer); struct sockaddr peer;
int code = -1; socklen_t peer_len = sizeof(peer);
NiceAddress *to = nice_address_new ();; int code = -1;
NiceAddress *to = nice_address_new ();;
nice_debug("got response for CreatePermission");
stun_message_find_xor_addr (&priv->current_create_permission_msg->message, nice_debug("got response for CreatePermission");
STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &peer, stun_message_find_xor_addr (&priv->current_create_permission_msg->message,
&peer_len); STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &peer,
nice_address_set_from_sockaddr (to, &peer); &peer_len);
nice_address_set_from_sockaddr (to, &peer);
g_free (priv->current_create_permission_msg);
priv->current_create_permission_msg = NULL; g_free (priv->current_create_permission_msg);
priv->current_create_permission_msg = NULL;
/* unathorized => resend with realm and nonce) */
if (stun_message_get_class (&msg) == STUN_ERROR && /* unathorized => resend with realm and nonce) */
stun_message_find_error (&msg, &code) == if (stun_message_get_class (&msg) == STUN_ERROR &&
STUN_MESSAGE_RETURN_SUCCESS && stun_message_find_error (&msg, &code) ==
(code == 438 || (code == 401))) { STUN_MESSAGE_RETURN_SUCCESS &&
uint8_t *recv_realm = NULL; (code == 438 || (code == 401))) {
uint16_t recv_realm_len = 0; uint8_t *recv_realm = NULL;
uint8_t *recv_nonce = NULL; uint16_t recv_realm_len = 0;
uint16_t recv_nonce_len = 0; uint8_t *recv_nonce = NULL;
uint16_t recv_nonce_len = 0;
recv_realm = (uint8_t *) stun_message_find (&msg,
STUN_ATTRIBUTE_REALM, &recv_realm_len); recv_realm = (uint8_t *) stun_message_find (&msg,
recv_nonce = (uint8_t *) stun_message_find (&msg, STUN_ATTRIBUTE_REALM, &recv_realm_len);
STUN_ATTRIBUTE_NONCE, &recv_nonce_len); recv_nonce = (uint8_t *) stun_message_find (&msg,
STUN_ATTRIBUTE_NONCE, &recv_nonce_len);
nice_debug("got realm: %s", recv_realm);
nice_debug("got nonce: %s", recv_nonce); nice_debug("got realm: %s", recv_realm);
nice_debug("got nonce: %s", recv_nonce);
/* resend CreatePermission */
priv_send_create_permission (priv, recv_realm, recv_realm_len, /* resend CreatePermission */
recv_nonce, recv_nonce_len, to); priv_send_create_permission (priv, recv_realm, recv_realm_len,
nice_address_free (to); recv_nonce, recv_nonce_len, to);
} else { nice_address_free (to);
/* we now have a permission installed for this peer */ } else {
GList *sent_permission = /* we now have a permission installed for this peer */
g_list_find_custom (priv->sent_permissions, to, GList *sent_permission =
(GCompareFunc) nice_address_equal); g_list_find_custom (priv->sent_permissions, to,
(GCompareFunc) nice_address_equal);
priv->permissions =
g_list_append (priv->permissions, to); priv->permissions =
g_list_append (priv->permissions, to);
if (sent_permission) {
nice_address_free ((NiceAddress *) sent_permission->data); if (sent_permission) {
priv->sent_permissions = nice_address_free ((NiceAddress *) sent_permission->data);
g_list_remove_link (priv->sent_permissions, sent_permission); priv->sent_permissions =
} g_list_remove_link (priv->sent_permissions, sent_permission);
}
/* install timer to schedule refresh of the permission */
/* (will not schedule refresh if we got an error) */
if (stun_message_get_class (&msg) == STUN_RESPONSE &&
!priv->permission_timeout_source) {
priv->permission_timeout_source =
g_timeout_add_seconds (STUN_PERMISSION_TIMEOUT,
priv_permission_timeout, priv);
}
/* send enqued data */
nice_debug("about to dequeue data");
socket_dequeue_all_data (priv, to);
}
}
}
/* install timer to schedule refresh of the permission */ return 0;
/* (will not schedule refresh if we got an error) */ } else if (stun_message_get_class (&msg) == STUN_INDICATION &&
if (stun_message_get_class (&msg) == STUN_RESPONSE && stun_message_get_method (&msg) == STUN_IND_DATA) {
!priv->permission_timeout_source) {
priv->permission_timeout_source =
g_timeout_add_seconds (STUN_PERMISSION_TIMEOUT,
priv_permission_timeout, priv);
}
/* send enqued data */
nice_debug("about to dequeue data");
socket_dequeue_all_data (priv, to);
}
}
}
return 0;
} else if (stun_message_get_class (&msg) == STUN_INDICATION &&
stun_message_get_method (&msg) == STUN_IND_DATA) {
uint16_t data_len; uint16_t data_len;
uint8_t *data; uint8_t *data;
if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 || if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 ||
priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) { priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) {
if (stun_message_find_xor_addr (&msg, STUN_ATTRIBUTE_REMOTE_ADDRESS, if (stun_message_find_xor_addr (&msg, STUN_ATTRIBUTE_REMOTE_ADDRESS,
(struct sockaddr *)&sa, &from_len) != (struct sockaddr *)&sa, &from_len) !=
STUN_MESSAGE_RETURN_SUCCESS) STUN_MESSAGE_RETURN_SUCCESS)
goto recv; goto recv;
} else { } else {
if (stun_message_find_addr (&msg, STUN_ATTRIBUTE_REMOTE_ADDRESS, if (stun_message_find_addr (&msg, STUN_ATTRIBUTE_REMOTE_ADDRESS,
(struct sockaddr *)&sa, &from_len) != (struct sockaddr *)&sa, &from_len) !=
STUN_MESSAGE_RETURN_SUCCESS) STUN_MESSAGE_RETURN_SUCCESS)
goto recv; goto recv;
} }
data = (uint8_t *) stun_message_find (&msg, STUN_ATTRIBUTE_DATA, data = (uint8_t *) stun_message_find (&msg, STUN_ATTRIBUTE_DATA,
&data_len); &data_len);
if (data == NULL) if (data == NULL)
goto recv; goto recv;
...@@ -876,7 +893,7 @@ nice_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock, ...@@ -876,7 +893,7 @@ nice_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock,
} else { } else {
goto recv; goto recv;
} }
} }
} }
recv: recv:
...@@ -902,7 +919,7 @@ nice_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock, ...@@ -902,7 +919,7 @@ nice_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock,
} else { } else {
*from = *recv_from; *from = *recv_from;
} }
memmove (buf, recv_buf, len > recv_len ? recv_len : len); memmove (buf, recv_buf, len > recv_len ? recv_len : len);
return len > recv_len ? recv_len : len; return len > recv_len ? recv_len : len;
...@@ -949,31 +966,31 @@ priv_retransmissions_tick_unlocked (TurnPriv *priv) ...@@ -949,31 +966,31 @@ priv_retransmissions_tick_unlocked (TurnPriv *priv)
{ {
if (priv->current_binding_msg) { if (priv->current_binding_msg) {
switch (stun_timer_refresh (&priv->current_binding_msg->timer)) { switch (stun_timer_refresh (&priv->current_binding_msg->timer)) {
case STUN_USAGE_TIMER_RETURN_TIMEOUT: case STUN_USAGE_TIMER_RETURN_TIMEOUT:
{ {
/* Time out */ /* Time out */
StunTransactionId id; StunTransactionId id;
stun_message_id (&priv->current_binding_msg->message, id); stun_message_id (&priv->current_binding_msg->message, id);
stun_agent_forget_transaction (&priv->agent, id); stun_agent_forget_transaction (&priv->agent, id);
g_free (priv->current_binding); g_free (priv->current_binding);
priv->current_binding = NULL; priv->current_binding = NULL;
g_free (priv->current_binding_msg); g_free (priv->current_binding_msg);
priv->current_binding_msg = NULL; priv->current_binding_msg = NULL;
priv_process_pending_bindings (priv); priv_process_pending_bindings (priv);
break; break;
} }
case STUN_USAGE_TIMER_RETURN_RETRANSMIT: case STUN_USAGE_TIMER_RETURN_RETRANSMIT:
/* Retransmit */ /* Retransmit */
nice_socket_send (priv->base_socket, &priv->server_addr, nice_socket_send (priv->base_socket, &priv->server_addr,
stun_message_length (&priv->current_binding_msg->message), stun_message_length (&priv->current_binding_msg->message),
(gchar *)priv->current_binding_msg->buffer); (gchar *)priv->current_binding_msg->buffer);
break; break;
case STUN_USAGE_TIMER_RETURN_SUCCESS: case STUN_USAGE_TIMER_RETURN_SUCCESS:
break; break;
} }
} }
...@@ -986,50 +1003,52 @@ priv_retransmissions_create_permission_tick_unlocked (TurnPriv *priv) ...@@ -986,50 +1003,52 @@ priv_retransmissions_create_permission_tick_unlocked (TurnPriv *priv)
{ {
if (priv->current_create_permission_msg) { if (priv->current_create_permission_msg) {
switch (stun_timer_refresh (&priv->current_create_permission_msg->timer)) { switch (stun_timer_refresh (&priv->current_create_permission_msg->timer)) {
case STUN_USAGE_TIMER_RETURN_TIMEOUT: case STUN_USAGE_TIMER_RETURN_TIMEOUT:
{ {
/* Time out */ /* Time out */
StunTransactionId id; StunTransactionId id;
NiceAddress *to = nice_address_new (); NiceAddress *to = nice_address_new ();
struct sockaddr addr; struct sockaddr addr;
socklen_t addr_len = sizeof(addr); socklen_t addr_len = sizeof(addr);
GList *sent_permission; GList *sent_permission;
stun_message_id (&priv->current_create_permission_msg->message, id); stun_message_id (&priv->current_create_permission_msg->message, id);
stun_agent_forget_transaction (&priv->agent, id); stun_agent_forget_transaction (&priv->agent, id);
stun_message_find_xor_addr (&priv->current_create_permission_msg->message, stun_message_find_xor_addr (&priv->current_create_permission_msg->message,
STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &addr, &addr_len); STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &addr,
nice_address_set_from_sockaddr (to, &addr); &addr_len);
sent_permission = g_list_find_custom (priv->sent_permissions, to, nice_address_set_from_sockaddr (to, &addr);
(GCompareFunc) nice_address_equal); sent_permission =
g_list_find_custom (priv->sent_permissions, to,
g_free (priv->current_create_permission_msg); (GCompareFunc) nice_address_equal);
priv->current_create_permission_msg = NULL;
g_free (priv->current_create_permission_msg);
/* we got a timeout when retransmitting a CreatePermission priv->current_create_permission_msg = NULL;
message, assume we can just send the data, the server
might not support RFC TURN, or connectivity check will /* we got a timeout when retransmitting a CreatePermission
fail eventually anyway */ message, assume we can just send the data, the server
priv->permissions = g_list_append (priv->permissions, to); might not support RFC TURN, or connectivity check will
fail eventually anyway */
if (sent_permission) { priv->permissions = g_list_append (priv->permissions, to);
nice_address_free ((NiceAddress *) sent_permission->data);
priv->sent_permissions = if (sent_permission) {
g_list_delete_link (priv->sent_permissions, sent_permission); nice_address_free ((NiceAddress *) sent_permission->data);
} priv->sent_permissions =
g_list_delete_link (priv->sent_permissions, sent_permission);
}
socket_dequeue_all_data (priv, to); socket_dequeue_all_data (priv, to);
break; break;
} }
case STUN_USAGE_TIMER_RETURN_RETRANSMIT: case STUN_USAGE_TIMER_RETURN_RETRANSMIT:
/* Retransmit */ /* Retransmit */
nice_socket_send (priv->base_socket, &priv->server_addr, nice_socket_send (priv->base_socket, &priv->server_addr,
stun_message_length (&priv->current_create_permission_msg->message), stun_message_length (&priv->current_create_permission_msg->message),
(gchar *)priv->current_create_permission_msg->buffer); (gchar *)priv->current_create_permission_msg->buffer);
break; break;
case STUN_USAGE_TIMER_RETURN_SUCCESS: case STUN_USAGE_TIMER_RETURN_SUCCESS:
break; break;
} }
} }
...@@ -1046,7 +1065,7 @@ priv_retransmissions_tick (gpointer pointer) ...@@ -1046,7 +1065,7 @@ priv_retransmissions_tick (gpointer pointer)
agent_lock (); agent_lock ();
if (g_source_is_destroyed (g_main_current_source ())) { if (g_source_is_destroyed (g_main_current_source ())) {
nice_debug ("Source was destroyed. " nice_debug ("Source was destroyed. "
"Avoided race condition in turn.c:priv_retransmissions_tick"); "Avoided race condition in turn.c:priv_retransmissions_tick");
agent_unlock (); agent_unlock ();
return FALSE; return FALSE;
} }
...@@ -1073,7 +1092,7 @@ priv_retransmissions_create_permission_tick (gpointer pointer) ...@@ -1073,7 +1092,7 @@ priv_retransmissions_create_permission_tick (gpointer pointer)
agent_lock (); agent_lock ();
if (g_source_is_destroyed (g_main_current_source ())) { if (g_source_is_destroyed (g_main_current_source ())) {
nice_debug ("Source was destroyed. " nice_debug ("Source was destroyed. "
"Avoided race condition in turn.c:priv_retransmissions_create_permission_tick"); "Avoided race condition in turn.c:priv_retransmissions_create_permission_tick");
agent_unlock (); agent_unlock ();
return FALSE; return FALSE;
} }
...@@ -1114,8 +1133,11 @@ priv_schedule_tick (TurnPriv *priv) ...@@ -1114,8 +1133,11 @@ priv_schedule_tick (TurnPriv *priv)
if (priv->current_create_permission_msg) { if (priv->current_create_permission_msg) {
guint timeout = stun_timer_remainder (&priv->current_create_permission_msg->timer); guint timeout = stun_timer_remainder (&priv->current_create_permission_msg->timer);
if (timeout > 0) { if (timeout > 0) {
priv->tick_source_create_permission = agent_timeout_add_with_context (priv->nice, timeout, priv->tick_source_create_permission =
priv_retransmissions_create_permission_tick, priv); agent_timeout_add_with_context (priv->nice,
timeout,
priv_retransmissions_create_permission_tick,
priv);
} else { } else {
priv_retransmissions_create_permission_tick_unlocked (priv); priv_retransmissions_create_permission_tick_unlocked (priv);
} }
...@@ -1133,7 +1155,7 @@ priv_send_turn_message (TurnPriv *priv, TURNMessage *msg) ...@@ -1133,7 +1155,7 @@ priv_send_turn_message (TurnPriv *priv, TURNMessage *msg)
} }
nice_socket_send (priv->base_socket, &priv->server_addr, nice_socket_send (priv->base_socket, &priv->server_addr,
stun_len, (gchar *)msg->buffer); stun_len, (gchar *)msg->buffer);
if (nice_socket_is_reliable (priv->base_socket)) { if (nice_socket_is_reliable (priv->base_socket)) {
stun_timer_start_reliable (&msg->timer, stun_timer_start_reliable (&msg->timer,
...@@ -1152,49 +1174,55 @@ priv_send_create_permission(TurnPriv *priv, uint8_t *realm, gsize realm_len, ...@@ -1152,49 +1174,55 @@ priv_send_create_permission(TurnPriv *priv, uint8_t *realm, gsize realm_len,
uint8_t *nonce, gsize nonce_len, uint8_t *nonce, gsize nonce_len,
const NiceAddress *peer) const NiceAddress *peer)
{ {
guint msg_buf_len; guint msg_buf_len;
gboolean res = FALSE; gboolean res = FALSE;
TURNMessage *msg = g_new0 (TURNMessage, 1); TURNMessage *msg = g_new0 (TURNMessage, 1);
struct sockaddr addr; struct sockaddr addr;
NiceAddress *to = nice_address_dup (peer); NiceAddress *to = nice_address_dup (peer);
nice_debug("creating CreatePermission message"); nice_debug("creating CreatePermission message");
priv->sent_permissions = g_list_append (priv->sent_permissions, to); priv->sent_permissions = g_list_append (priv->sent_permissions, to);
nice_address_copy_to_sockaddr (peer, &addr); nice_address_copy_to_sockaddr (peer, &addr);
/* send CreatePermission */ /* send CreatePermission */
msg_buf_len = stun_usage_turn_create_permission(&priv->agent, &msg->message, msg_buf_len = stun_usage_turn_create_permission(&priv->agent, &msg->message,
msg->buffer, sizeof(msg->buffer), priv->username, priv->username_len, msg->buffer,
priv->password, priv->password_len, realm, realm_len, nonce, nonce_len, sizeof(msg->buffer),
&addr, priv->username,
NICE_TURN_SOCKET_COMPATIBILITY_RFC5766); priv->username_len,
priv->password,
if (msg_buf_len > 0) { priv->password_len,
nice_debug("sending CreatePermission message, lenght: %d", realm, realm_len,
msg_buf_len); nonce, nonce_len,
res = nice_socket_send (priv->base_socket, &priv->server_addr, &addr,
msg_buf_len, (gchar *) msg->buffer); NICE_TURN_SOCKET_COMPATIBILITY_RFC5766);
nice_debug("sent CreatePermission message, result: %d", res);
if (msg_buf_len > 0) {
if (nice_socket_is_reliable (priv->base_socket)) { nice_debug("sending CreatePermission message, lenght: %d",
stun_timer_start_reliable (&msg->timer); msg_buf_len);
} else { res = nice_socket_send (priv->base_socket, &priv->server_addr,
stun_timer_start (&msg->timer); msg_buf_len, (gchar *) msg->buffer);
} nice_debug("sent CreatePermission message, result: %d", res);
priv_schedule_tick (priv); if (nice_socket_is_reliable (priv->base_socket)) {
priv->current_create_permission_msg = msg; stun_timer_start_reliable (&msg->timer);
} else { } else {
g_free(msg); stun_timer_start (&msg->timer);
} }
priv_schedule_tick (priv);
priv->current_create_permission_msg = msg;
} else {
g_free(msg);
}
return res; return res;
} }
static gboolean static gboolean
priv_send_channel_bind (TurnPriv *priv, StunMessage *resp, priv_send_channel_bind (TurnPriv *priv, StunMessage *resp,
uint16_t channel, const NiceAddress *peer) uint16_t channel, const NiceAddress *peer)
{ {
uint32_t channel_attr = channel << 16; uint32_t channel_attr = channel << 16;
size_t stun_len; size_t stun_len;
...@@ -1205,26 +1233,30 @@ priv_send_channel_bind (TurnPriv *priv, StunMessage *resp, ...@@ -1205,26 +1233,30 @@ priv_send_channel_bind (TurnPriv *priv, StunMessage *resp,
nice_address_copy_to_sockaddr (peer, (struct sockaddr *)&sa); nice_address_copy_to_sockaddr (peer, (struct sockaddr *)&sa);
if (!stun_agent_init_request (&priv->agent, &msg->message, if (!stun_agent_init_request (&priv->agent, &msg->message,
msg->buffer, sizeof(msg->buffer), STUN_CHANNELBIND)) { msg->buffer, sizeof(msg->buffer),
STUN_CHANNELBIND)) {
g_free (msg); g_free (msg);
return FALSE; return FALSE;
} }
if (stun_message_append32 (&msg->message, STUN_ATTRIBUTE_CHANNEL_NUMBER, if (stun_message_append32 (&msg->message, STUN_ATTRIBUTE_CHANNEL_NUMBER,
channel_attr) != STUN_MESSAGE_RETURN_SUCCESS) { channel_attr) != STUN_MESSAGE_RETURN_SUCCESS) {
g_free (msg); g_free (msg);
return FALSE; return FALSE;
} }
if (stun_message_append_xor_addr (&msg->message, STUN_ATTRIBUTE_PEER_ADDRESS, if (stun_message_append_xor_addr (&msg->message, STUN_ATTRIBUTE_PEER_ADDRESS,
(struct sockaddr *)&sa, sizeof(sa)) != STUN_MESSAGE_RETURN_SUCCESS) { (struct sockaddr *)&sa,
sizeof(sa))
!= STUN_MESSAGE_RETURN_SUCCESS) {
g_free (msg); g_free (msg);
return FALSE; return FALSE;
} }
if (priv->username != NULL && priv->username_len > 0) { if (priv->username != NULL && priv->username_len > 0) {
if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_USERNAME, if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_USERNAME,
priv->username, priv->username_len) != STUN_MESSAGE_RETURN_SUCCESS) { priv->username, priv->username_len)
!= STUN_MESSAGE_RETURN_SUCCESS) {
g_free (msg); g_free (msg);
return FALSE; return FALSE;
} }
...@@ -1238,7 +1270,8 @@ priv_send_channel_bind (TurnPriv *priv, StunMessage *resp, ...@@ -1238,7 +1270,8 @@ priv_send_channel_bind (TurnPriv *priv, StunMessage *resp,
realm = (uint8_t *) stun_message_find (resp, STUN_ATTRIBUTE_REALM, &len); realm = (uint8_t *) stun_message_find (resp, STUN_ATTRIBUTE_REALM, &len);
if (realm != NULL) { if (realm != NULL) {
if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_REALM, if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_REALM,
realm, len) != STUN_MESSAGE_RETURN_SUCCESS) { realm, len)
!= STUN_MESSAGE_RETURN_SUCCESS) {
g_free (msg); g_free (msg);
return 0; return 0;
} }
...@@ -1246,7 +1279,8 @@ priv_send_channel_bind (TurnPriv *priv, StunMessage *resp, ...@@ -1246,7 +1279,8 @@ priv_send_channel_bind (TurnPriv *priv, StunMessage *resp,
nonce = (uint8_t *) stun_message_find (resp, STUN_ATTRIBUTE_NONCE, &len); nonce = (uint8_t *) stun_message_find (resp, STUN_ATTRIBUTE_NONCE, &len);
if (nonce != NULL) { if (nonce != NULL) {
if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_NONCE, if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_NONCE,
nonce, len) != STUN_MESSAGE_RETURN_SUCCESS) { nonce, len)
!= STUN_MESSAGE_RETURN_SUCCESS) {
g_free (msg); g_free (msg);
return 0; return 0;
} }
...@@ -1254,10 +1288,10 @@ priv_send_channel_bind (TurnPriv *priv, StunMessage *resp, ...@@ -1254,10 +1288,10 @@ priv_send_channel_bind (TurnPriv *priv, StunMessage *resp,
} }
stun_len = stun_agent_finish_message (&priv->agent, &msg->message, stun_len = stun_agent_finish_message (&priv->agent, &msg->message,
priv->password, priv->password_len); priv->password, priv->password_len);
if (stun_len > 0) { if (stun_len > 0) {
priv_send_turn_message (priv, msg); priv_send_turn_message (priv, msg);
return TRUE; return TRUE;
} }
...@@ -1308,20 +1342,23 @@ priv_add_channel_binding (TurnPriv *priv, const NiceAddress *peer) ...@@ -1308,20 +1342,23 @@ priv_add_channel_binding (TurnPriv *priv, const NiceAddress *peer)
priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_OC2007) { priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_OC2007) {
TURNMessage *msg = g_new0 (TURNMessage, 1); TURNMessage *msg = g_new0 (TURNMessage, 1);
if (!stun_agent_init_request (&priv->agent, &msg->message, if (!stun_agent_init_request (&priv->agent, &msg->message,
msg->buffer, sizeof(msg->buffer), STUN_OLD_SET_ACTIVE_DST)) { msg->buffer, sizeof(msg->buffer),
STUN_OLD_SET_ACTIVE_DST)) {
g_free (msg); g_free (msg);
return FALSE; return FALSE;
} }
if (stun_message_append32 (&msg->message, STUN_ATTRIBUTE_MAGIC_COOKIE, if (stun_message_append32 (&msg->message, STUN_ATTRIBUTE_MAGIC_COOKIE,
TURN_MAGIC_COOKIE) != STUN_MESSAGE_RETURN_SUCCESS) { TURN_MAGIC_COOKIE)
!= STUN_MESSAGE_RETURN_SUCCESS) {
g_free (msg); g_free (msg);
return FALSE; return FALSE;
} }
if (priv->username != NULL && priv->username_len > 0) { if (priv->username != NULL && priv->username_len > 0) {
if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_USERNAME, if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_USERNAME,
priv->username, priv->username_len) != STUN_MESSAGE_RETURN_SUCCESS) { priv->username, priv->username_len)
!= STUN_MESSAGE_RETURN_SUCCESS) {
g_free (msg); g_free (msg);
return FALSE; return FALSE;
} }
...@@ -1336,14 +1373,15 @@ priv_add_channel_binding (TurnPriv *priv, const NiceAddress *peer) ...@@ -1336,14 +1373,15 @@ priv_add_channel_binding (TurnPriv *priv, const NiceAddress *peer)
} }
if (stun_message_append_addr (&msg->message, if (stun_message_append_addr (&msg->message,
STUN_ATTRIBUTE_DESTINATION_ADDRESS, STUN_ATTRIBUTE_DESTINATION_ADDRESS,
(struct sockaddr *)&sa, sizeof(sa)) != STUN_MESSAGE_RETURN_SUCCESS) { (struct sockaddr *)&sa, sizeof(sa))
!= STUN_MESSAGE_RETURN_SUCCESS) {
g_free (msg); g_free (msg);
return FALSE; return FALSE;
} }
stun_len = stun_agent_finish_message (&priv->agent, &msg->message, stun_len = stun_agent_finish_message (&priv->agent, &msg->message,
priv->password, priv->password_len); priv->password, priv->password_len);
if (stun_len > 0) { if (stun_len > 0) {
priv->current_binding = g_new0 (ChannelBinding, 1); priv->current_binding = g_new0 (ChannelBinding, 1);
......
...@@ -544,7 +544,7 @@ size_t stun_agent_finish_message (StunAgent *agent, StunMessage *msg, ...@@ -544,7 +544,7 @@ size_t stun_agent_finish_message (StunAgent *agent, StunMessage *msg,
uint8_t *username = NULL; uint8_t *username = NULL;
uint16_t realm_len; uint16_t realm_len;
uint16_t username_len; uint16_t username_len;
realm = (uint8_t *) stun_message_find (msg, realm = (uint8_t *) stun_message_find (msg,
STUN_ATTRIBUTE_REALM, &realm_len); STUN_ATTRIBUTE_REALM, &realm_len);
username = (uint8_t *) stun_message_find (msg, username = (uint8_t *) stun_message_find (msg,
......
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
bool stun_message_init (StunMessage *msg, StunClass c, StunMethod m, bool stun_message_init (StunMessage *msg, StunClass c, StunMethod m,
const StunTransactionId id) const StunTransactionId id)
{ {
if (msg->buffer_len < STUN_MESSAGE_HEADER_LENGTH) if (msg->buffer_len < STUN_MESSAGE_HEADER_LENGTH)
return FALSE; return FALSE;
......
...@@ -225,7 +225,7 @@ size_t stun_usage_turn_create_permission (StunAgent *agent, StunMessage *msg, ...@@ -225,7 +225,7 @@ size_t stun_usage_turn_create_permission (StunAgent *agent, StunMessage *msg,
{ {
stun_agent_init_request (agent, msg, buffer, buffer_len, stun_agent_init_request (agent, msg, buffer, buffer_len,
STUN_CREATEPERMISSION); STUN_CREATEPERMISSION);
/* PEER address */ /* PEER address */
if (peer) { if (peer) {
if (stun_message_append_xor_addr (msg, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, if (stun_message_append_xor_addr (msg, STUN_ATTRIBUTE_XOR_PEER_ADDRESS,
...@@ -233,7 +233,7 @@ size_t stun_usage_turn_create_permission (StunAgent *agent, StunMessage *msg, ...@@ -233,7 +233,7 @@ size_t stun_usage_turn_create_permission (StunAgent *agent, StunMessage *msg,
return 0; return 0;
} }
} }
/* nonce */ /* nonce */
if (nonce != NULL) { if (nonce != NULL) {
if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_NONCE, if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_NONCE,
...@@ -247,7 +247,7 @@ size_t stun_usage_turn_create_permission (StunAgent *agent, StunMessage *msg, ...@@ -247,7 +247,7 @@ size_t stun_usage_turn_create_permission (StunAgent *agent, StunMessage *msg,
realm, realm_len) != STUN_MESSAGE_RETURN_SUCCESS) realm, realm_len) != STUN_MESSAGE_RETURN_SUCCESS)
return 0; return 0;
} }
/* username */ /* username */
if (username != NULL) { if (username != NULL) {
if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_USERNAME, if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_USERNAME,
......
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