diff -Nru libnice-0.1.5/agent/address.c libnice-0.1.7/agent/address.c --- libnice-0.1.5/agent/address.c 2014-01-06 23:05:12.000000000 +0000 +++ libnice-0.1.7/agent/address.c 2014-04-25 01:46:20.000000000 +0000 @@ -50,6 +50,14 @@ #define inet_pton inet_pton_win32 #define inet_ntop inet_ntop_win32 +/* Defined in recent versions of mingw: + * https://github.com/mirror/mingw-w64/commit/0f4899473c4ba2e34fa447b1931a04e38c1f105e + */ +#ifndef IN6_ARE_ADDR_EQUAL +#define IN6_ARE_ADDR_EQUAL(a, b) \ + (memcmp ((const void *) (a), (const void *) (b), sizeof (struct in6_addr)) == 0) +#endif + static const char * inet_ntop_win32 (int af, const void *src, char *dst, socklen_t cnt) @@ -331,7 +339,7 @@ { return ( /* fe80::/10 */ - ((addr[0] == 0xfe) && ((addr[1] & 0xc) == 0x80)) || + ((addr[0] == 0xfe) && ((addr[1] & 0xc0) == 0x80)) || /* fc00::/7 */ ((addr[0] & 0xfe) == 0xfc) || /* ::1 loopback */ diff -Nru libnice-0.1.5/agent/agent.c libnice-0.1.7/agent/agent.c --- libnice-0.1.5/agent/agent.c 2014-03-07 02:14:00.000000000 +0000 +++ libnice-0.1.7/agent/agent.c 2014-04-28 18:35:48.000000000 +0000 @@ -67,7 +67,6 @@ #include "discovery.h" #include "agent.h" #include "agent-priv.h" -#include "agent-signals-marshal.h" #include "iostream.h" #include "stream.h" @@ -80,7 +79,7 @@ #define MAX_BUFFER_SIZE ((1 << 16) - 1) /* 65535 */ #define DEFAULT_STUN_PORT 3478 -#define DEFAULT_UPNP_TIMEOUT 200 +#define DEFAULT_UPNP_TIMEOUT 200 /* milliseconds */ #define MAX_TCP_MTU 1400 /* Use 1400 because of VPNs and we assume IEE 802.3 */ @@ -158,6 +157,12 @@ #endif +static GType _nice_agent_stream_ids_get_type (void); + +G_DEFINE_POINTER_TYPE (_NiceAgentStreamIds, _nice_agent_stream_ids); + +#define NICE_TYPE_AGENT_STREAM_IDS _nice_agent_stream_ids_get_type () + typedef struct { guint signal_id; GSignalQuery query; @@ -170,10 +175,12 @@ { guint i; + g_value_unset (&sig->params[0]); + for (i = 0; i < sig->query.n_params; i++) { - if (G_VALUE_HOLDS_POINTER (&sig->params[i])) - g_free (g_value_get_pointer (&sig->params[i])); - g_value_unset (&sig->params[i]); + if (G_VALUE_HOLDS(&sig->params[i + 1], NICE_TYPE_AGENT_STREAM_IDS)) + g_free (g_value_get_pointer (&sig->params[i + 1])); + g_value_unset (&sig->params[i + 1]); } g_slice_free1 (sizeof(GValue) * (sig->query.n_params + 1), sig->params); @@ -543,8 +550,8 @@ /** * NiceAgent:upnp-timeout: * - * The maximum amount of time to wait for UPnP discovery to finish before - * signaling the #NiceAgent::candidate-gathering-done signal + * The maximum amount of time (in milliseconds) to wait for UPnP discovery to + * finish before signaling the #NiceAgent::candidate-gathering-done signal * * Since: 0.0.7 */ @@ -599,7 +606,7 @@ 0, NULL, NULL, - agent_marshal_VOID__UINT_UINT_UINT, + NULL, G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, @@ -621,7 +628,7 @@ 0, NULL, NULL, - agent_marshal_VOID__UINT, + NULL, G_TYPE_NONE, 1, G_TYPE_UINT, G_TYPE_INVALID); @@ -645,7 +652,7 @@ 0, NULL, NULL, - agent_marshal_VOID__UINT_UINT_STRING_STRING, + NULL, G_TYPE_NONE, 4, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, @@ -658,7 +665,7 @@ * @component_id: The ID of the component * @foundation: The foundation of the new candidate * - * This signal is fired when the agent discovers a new candidate + * This signal is fired when the agent discovers a new local candidate. * See also: #NiceAgent::candidate-gathering-done */ signals[SIGNAL_NEW_CANDIDATE] = @@ -669,7 +676,7 @@ 0, NULL, NULL, - agent_marshal_VOID__UINT_UINT_STRING, + NULL, G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, @@ -693,7 +700,7 @@ 0, NULL, NULL, - agent_marshal_VOID__UINT_UINT_STRING, + NULL, G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, @@ -715,7 +722,7 @@ 0, NULL, NULL, - agent_marshal_VOID__UINT, + NULL, G_TYPE_NONE, 1, G_TYPE_UINT, @@ -743,7 +750,7 @@ 0, NULL, NULL, - agent_marshal_VOID__UINT_UINT, + NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT, @@ -771,7 +778,7 @@ g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, - G_TYPE_POINTER, + NICE_TYPE_AGENT_STREAM_IDS, G_TYPE_INVALID); /* Init debug options depending on env variables */ @@ -1383,7 +1390,7 @@ static PseudoTcpWriteResult -pseudo_tcp_socket_write_packet (PseudoTcpSocket *socket, +pseudo_tcp_socket_write_packet (PseudoTcpSocket *psocket, const gchar *buffer, guint32 len, gpointer user_data) { Component *component = user_data; @@ -1446,7 +1453,7 @@ adjust_tcp_clock (NiceAgent *agent, Stream *stream, Component *component) { if (component->tcp) { - long timeout = component->last_clock_timeout; + guint64 timeout = component->last_clock_timeout; if (pseudo_tcp_socket_get_next_clock (component->tcp, &timeout)) { if (timeout != component->last_clock_timeout) { @@ -1608,8 +1615,6 @@ { Component *component; Stream *stream; - gchar *lf_copy; - gchar *rf_copy; if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) @@ -1631,14 +1636,8 @@ return; } - lf_copy = g_strdup (local_foundation); - rf_copy = g_strdup (remote_foundation); - agent_queue_signal (agent, signals[SIGNAL_NEW_SELECTED_PAIR], - stream_id, component_id, lf_copy, rf_copy); - - g_free (lf_copy); - g_free (rf_copy); + stream_id, component_id, local_foundation, remote_foundation); } void agent_signal_new_candidate (NiceAgent *agent, NiceCandidate *candidate) @@ -1653,8 +1652,8 @@ candidate->stream_id, candidate->component_id, candidate->foundation); } -static const gchar * -component_state_to_string (NiceComponentState state) +NICEAPI_EXPORT const gchar * +nice_component_state_to_string (NiceComponentState state) { switch (state) { @@ -1687,16 +1686,16 @@ if (agent->reliable && component->tcp == NULL && state != NICE_COMPONENT_STATE_FAILED) { - nice_debug ("Agent %p: not changing component state for s%d:%d to %d " + nice_debug ("Agent %p: not changing component state for s%d:%d to %s " "because pseudo tcp socket does not exist in reliable mode", agent, - stream->id, component->id, state); + stream->id, component->id, nice_component_state_to_string (state)); return; } if (component->state != state && state < NICE_COMPONENT_STATE_LAST) { nice_debug ("Agent %p : stream %u component %u STATE-CHANGE %s -> %s.", agent, - stream_id, component_id, component_state_to_string (component->state), - component_state_to_string (state)); + stream_id, component_id, nice_component_state_to_string (component->state), + nice_component_state_to_string (state)); component->state = state; @@ -1718,7 +1717,7 @@ static void priv_add_new_candidate_discovery_stun (NiceAgent *agent, - NiceSocket *socket, NiceAddress server, + NiceSocket *nicesock, NiceAddress server, Stream *stream, guint component_id) { CandidateDiscovery *cdisco; @@ -1729,7 +1728,7 @@ cdisco = g_slice_new0 (CandidateDiscovery); cdisco->type = NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE; - cdisco->nicesock = socket; + cdisco->nicesock = nicesock; cdisco->server = server; cdisco->stream = stream; cdisco->component = stream_find_component_by_id (stream, component_id); @@ -1749,7 +1748,7 @@ static void priv_add_new_candidate_discovery_turn (NiceAgent *agent, - NiceSocket *socket, TurnServer *turn, + NiceSocket *nicesock, TurnServer *turn, Stream *stream, guint component_id) { CandidateDiscovery *cdisco; @@ -1763,7 +1762,7 @@ if (turn->type == NICE_RELAY_TYPE_TURN_UDP) { if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) { - NiceAddress addr = socket->addr; + NiceAddress addr = nicesock->addr; NiceSocket *new_socket; nice_address_set_port (&addr, 0); @@ -1771,57 +1770,57 @@ if (new_socket) { _priv_set_socket_tos (agent, new_socket, stream->tos); component_attach_socket (component, new_socket); - socket = new_socket; + nicesock = new_socket; } } - cdisco->nicesock = socket; + cdisco->nicesock = nicesock; } else { NiceAddress proxy_server; - socket = NULL; + nicesock = NULL; if (agent->proxy_type != NICE_PROXY_TYPE_NONE && agent->proxy_ip != NULL && nice_address_set_from_string (&proxy_server, agent->proxy_ip)) { nice_address_set_port (&proxy_server, agent->proxy_port); - socket = nice_tcp_bsd_socket_new (agent->main_context, &proxy_server); + nicesock = nice_tcp_bsd_socket_new (agent->main_context, &proxy_server); - if (socket) { - _priv_set_socket_tos (agent, socket, stream->tos); + if (nicesock) { + _priv_set_socket_tos (agent, nicesock, stream->tos); if (agent->proxy_type == NICE_PROXY_TYPE_SOCKS5) { - socket = nice_socks5_socket_new (socket, &turn->server, + nicesock = nice_socks5_socket_new (nicesock, &turn->server, agent->proxy_username, agent->proxy_password); } else if (agent->proxy_type == NICE_PROXY_TYPE_HTTP){ - socket = nice_http_socket_new (socket, &turn->server, + nicesock = nice_http_socket_new (nicesock, &turn->server, agent->proxy_username, agent->proxy_password); } else { - nice_socket_free (socket); - socket = NULL; + nice_socket_free (nicesock); + nicesock = NULL; } } } - if (socket == NULL) { - socket = nice_tcp_bsd_socket_new (agent->main_context, &turn->server); + if (nicesock == NULL) { + nicesock = nice_tcp_bsd_socket_new (agent->main_context, &turn->server); - if (socket) - _priv_set_socket_tos (agent, socket, stream->tos); + if (nicesock) + _priv_set_socket_tos (agent, nicesock, stream->tos); } /* The TURN server may be invalid or not listening */ - if (socket == NULL) + if (nicesock == NULL) return; if (turn->type == NICE_RELAY_TYPE_TURN_TLS && agent->compatibility == NICE_COMPATIBILITY_GOOGLE) { - socket = nice_pseudossl_socket_new (socket); + nicesock = nice_pseudossl_socket_new (nicesock); } - cdisco->nicesock = nice_tcp_turn_socket_new (socket, + cdisco->nicesock = nice_tcp_turn_socket_new (nicesock, agent_to_turn_socket_compatibility (agent)); component_attach_socket (component, cdisco->nicesock); } - cdisco->turn = turn; + cdisco->turn = turn_server_ref (turn); cdisco->server = turn->server; cdisco->stream = stream; @@ -1913,6 +1912,9 @@ { Component *component = NULL; + Stream *stream = NULL; + gboolean ret = TRUE; + TurnServer *turn; g_return_val_if_fail (server_ip, FALSE); g_return_val_if_fail (server_port, FALSE); @@ -1922,42 +1924,59 @@ agent_lock(); - if (agent_find_component (agent, stream_id, component_id, NULL, &component)) { - TurnServer *turn = g_slice_new0 (TurnServer); - nice_address_init (&turn->server); + if (!agent_find_component (agent, stream_id, component_id, &stream, + &component)) { + ret = FALSE; + goto done; + } - if (nice_address_set_from_string (&turn->server, server_ip)) { - nice_address_set_port (&turn->server, server_port); - } else { - g_slice_free (TurnServer, turn); - agent_unlock_and_emit (agent); - return FALSE; - } + turn = turn_server_new (server_ip, server_port, username, password, type); + + if (!turn) { + ret = FALSE; + goto done; + } + nice_debug ("Agent %p: added relay server [%s]:%d of type %d to s/c %d/%d " + "with user/pass : %s -- %s", agent, server_ip, server_port, type, + stream_id, component_id, username, password); - turn->username = g_strdup (username); - turn->password = g_strdup (password); - turn->type = type; + component->turn_servers = g_list_append (component->turn_servers, turn); - nice_debug ("Agent %p: added relay server [%s]:%d of type %d", agent, - server_ip, server_port, type); + if (stream->gathering_started) { + GSList *i; - component->turn_servers = g_list_append (component->turn_servers, turn); + for (i = component->local_candidates; i; i = i->next) { + NiceCandidate *candidate = i->data; + + if (candidate->type == NICE_CANDIDATE_TYPE_HOST) + priv_add_new_candidate_discovery_turn (agent, + candidate->sockptr, turn, stream, + component_id); + } + + if (agent->discovery_unsched_items) + discovery_schedule (agent); } + + done: + agent_unlock_and_emit (agent); - return TRUE; + return ret; } #ifdef HAVE_GUPNP +static void agent_check_upnp_gathering_done (NiceAgent *agent); + static gboolean priv_upnp_timeout_cb (gpointer user_data) { NiceAgent *agent = (NiceAgent*)user_data; - GSList *i; agent_lock(); + /* If the source has been destroyed, we have already freed all mappings. */ if (g_source_is_destroyed (g_main_current_source ())) { agent_unlock (); return FALSE; @@ -1965,13 +1984,29 @@ nice_debug ("Agent %p : UPnP port mapping timed out", agent); - for (i = agent->upnp_mapping; i; i = i->next) { - NiceAddress *a = i->data; - nice_address_free (a); - } - g_slist_free (agent->upnp_mapping); + /* We cannot free priv->upnp here as it may be holding mappings open which + * we are using (e.g. if some mappings were successful and others errored). */ + g_slist_free_full (agent->upnp_mapping, (GDestroyNotify) nice_address_free); agent->upnp_mapping = NULL; + agent_check_upnp_gathering_done (agent); + + agent_unlock_and_emit (agent); + return FALSE; +} + +/* Check whether UPnP gathering is done, which is true when the list of pending + * mappings (upnp_mapping) is empty. When it is empty, we have heard back from + * gupnp-igd about each of the mappings we added, either successfully or not. + * + * Note that upnp_mapping has to be a list, rather than a counter, as the + * mapped-external-port and error-mapping-port signals could be emitted multiple + * times for each mapping. */ +static void agent_check_upnp_gathering_done (NiceAgent *agent) +{ + if (agent->upnp_mapping != NULL) + return; + if (agent->upnp_timer_source != NULL) { g_source_destroy (agent->upnp_timer_source); g_source_unref (agent->upnp_timer_source); @@ -1979,9 +2014,6 @@ } agent_gathering_done (agent); - - agent_unlock_and_emit (agent); - return FALSE; } static void _upnp_mapped_external_port (GUPnPSimpleIgd *self, gchar *proto, @@ -2037,14 +2069,7 @@ } end: - if (g_slist_length (agent->upnp_mapping) == 0) { - if (agent->upnp_timer_source != NULL) { - g_source_destroy (agent->upnp_timer_source); - g_source_unref (agent->upnp_timer_source); - agent->upnp_timer_source = NULL; - } - agent_gathering_done (agent); - } + agent_check_upnp_gathering_done (agent); agent_unlock_and_emit (agent); } @@ -2073,14 +2098,7 @@ } } - if (g_slist_length (agent->upnp_mapping) == 0) { - if (agent->upnp_timer_source != NULL) { - g_source_destroy (agent->upnp_timer_source); - g_source_unref (agent->upnp_timer_source); - agent->upnp_timer_source = NULL; - } - agent_gathering_done (agent); - } + agent_check_upnp_gathering_done (agent); } agent_unlock_and_emit (agent); @@ -2107,6 +2125,12 @@ return FALSE; } + if (stream->gathering_started) { + /* Stream is already gathering, ignore this call */ + agent_unlock_and_emit (agent); + return TRUE; + } + nice_debug ("Agent %p : In %s mode, starting candidate gathering.", agent, agent->full_mode ? "ICE-FULL" : "ICE-LITE"); @@ -2154,9 +2178,9 @@ } else { for (i = agent->local_addresses; i; i = i->next) { NiceAddress *addr = i->data; - NiceAddress *dup = nice_address_dup (addr); + NiceAddress *dupaddr = nice_address_dup (addr); - local_addresses = g_slist_append (local_addresses, dup); + local_addresses = g_slist_append (local_addresses, dupaddr); } } @@ -2260,7 +2284,7 @@ } stream->gathering = TRUE; - + stream->gathering_started = TRUE; /* Only signal the new candidates after we're sure that the gathering was * succesfful. But before sending gathering-done */ @@ -2275,7 +2299,7 @@ /* note: no async discoveries pending, signal that we are ready */ if (agent->discovery_unsched_items == 0 && #ifdef HAVE_GUPNP - g_slist_length (agent->upnp_mapping) == 0) { + agent->upnp_mapping == NULL) { #else TRUE) { #endif @@ -2316,18 +2340,12 @@ static void priv_free_upnp (NiceAgent *agent) { #ifdef HAVE_GUPNP - GSList *i; - if (agent->upnp) { g_object_unref (agent->upnp); agent->upnp = NULL; } - for (i = agent->upnp_mapping; i; i = i->next) { - NiceAddress *a = i->data; - nice_address_free (a); - } - g_slist_free (agent->upnp_mapping); + g_slist_free_full (agent->upnp_mapping, (GDestroyNotify) nice_address_free); agent->upnp_mapping = NULL; if (agent->upnp_timer_source != NULL) { @@ -2378,7 +2396,8 @@ if (!agent->streams) priv_remove_keepalive_timer (agent); - agent_queue_signal (agent, signals[SIGNAL_STREAMS_REMOVED], stream_ids); + agent_queue_signal (agent, signals[SIGNAL_STREAMS_REMOVED], + g_memdup (stream_ids, sizeof(stream_ids))); agent_unlock_and_emit (agent); return; @@ -2388,13 +2407,19 @@ nice_agent_set_port_range (NiceAgent *agent, guint stream_id, guint component_id, guint min_port, guint max_port) { + Stream *stream; Component *component; agent_lock(); - if (agent_find_component (agent, stream_id, component_id, NULL, &component)) { - component->min_port = min_port; - component->max_port = max_port; + if (agent_find_component (agent, stream_id, component_id, &stream, + &component)) { + if (stream->gathering_started) { + g_critical ("nice_agent_gather_candidates (stream_id=%u) already called for this stream", stream_id); + } else { + component->min_port = min_port; + component->max_port = max_port; + } } agent_unlock_and_emit (agent); @@ -2403,13 +2428,13 @@ NICEAPI_EXPORT gboolean nice_agent_add_local_address (NiceAgent *agent, NiceAddress *addr) { - NiceAddress *dup; + NiceAddress *dupaddr; agent_lock(); - dup = nice_address_dup (addr); - nice_address_set_port (dup, 0); - agent->local_addresses = g_slist_append (agent->local_addresses, dup); + dupaddr = nice_address_dup (addr); + nice_address_set_port (dupaddr, 0); + agent->local_addresses = g_slist_append (agent->local_addresses, dupaddr); agent_unlock_and_emit (agent); return TRUE; @@ -2471,8 +2496,6 @@ g_free (candidate->password); candidate->password = g_strdup (password); } - if (conn_check_add_for_candidate (agent, stream_id, component, candidate) < 0) - goto errors; } else { /* case 2: add a new candidate */ @@ -2509,9 +2532,10 @@ if (foundation) g_strlcpy (candidate->foundation, foundation, NICE_CANDIDATE_MAX_FOUNDATION); + } - if (conn_check_add_for_candidate (agent, stream_id, component, candidate) < 0) - goto errors; + if (conn_check_add_for_candidate (agent, stream_id, component, candidate) < 0) { + goto errors; } return TRUE; @@ -2689,7 +2713,7 @@ NiceAgent *agent, Stream *stream, Component *component, - NiceSocket *socket, + NiceSocket *nicesock, NiceInputMessage *message) { NiceAddress from; @@ -2701,10 +2725,10 @@ message->from = &from; } - retval = nice_socket_recv_messages (socket, message, 1); + retval = nice_socket_recv_messages (nicesock, message, 1); nice_debug ("%s: Received %d valid messages of length %" G_GSIZE_FORMAT - " from base socket %p.", G_STRFUNC, retval, message->length, socket); + " from base socket %p.", G_STRFUNC, retval, message->length, nicesock); if (retval == 0) { retval = RECV_WOULD_BLOCK; /* EWOULDBLOCK */ @@ -2717,11 +2741,16 @@ goto done; } - if (nice_debug_is_enabled () && message->length > 0) { + if (retval == RECV_OOB || message->length == 0) { + retval = RECV_OOB; + goto done; + } + + if (nice_debug_is_enabled ()) { gchar tmpbuf[INET6_ADDRSTRLEN]; nice_address_to_string (message->from, tmpbuf); nice_debug ("Agent %p : Packet received on local socket %d from [%s]:%u (%" G_GSSIZE_FORMAT " octets).", agent, - g_socket_get_fd (socket->fileno), tmpbuf, + g_socket_get_fd (nicesock->fileno), tmpbuf, nice_address_get_port (message->from), message->length); } @@ -2741,11 +2770,16 @@ if (cand->type == NICE_CANDIDATE_TYPE_RELAYED && cand->stream_id == stream->id && cand->component_id == component->id) { - nice_turn_socket_parse_recv_message (cand->sockptr, &socket, message); + retval = nice_turn_socket_parse_recv_message (cand->sockptr, &nicesock, + message); + break; } } } + if (retval == RECV_OOB) + goto done; + agent->media_after_tick = TRUE; /* If the message’s stated length is equal to its actual length, it’s probably @@ -2765,7 +2799,7 @@ if (stun_message_validate_buffer_length (big_buf, big_buf_len, (agent->compatibility != NICE_COMPATIBILITY_OC2007 && agent->compatibility != NICE_COMPATIBILITY_OC2007R2)) == (gint) big_buf_len && - conn_check_handle_inbound_stun (agent, stream, component, socket, + conn_check_handle_inbound_stun (agent, stream, component, nicesock, message->from, (gchar *) big_buf, big_buf_len)) { /* Handled STUN message. */ nice_debug ("%s: Valid STUN packet received.", G_STRFUNC); @@ -2797,7 +2831,7 @@ nice_debug ("%s: Queued %" G_GSSIZE_FORMAT " bytes for agent %p.", G_STRFUNC, vec->size, agent); - return 0; + return RECV_OOB; } else { process_queued_tcp_packets (agent, stream, component); } @@ -2925,7 +2959,6 @@ buffer += len; buffer_length -= len; - message->buffers[i].size = len; message->length += len; } @@ -3289,7 +3322,6 @@ memcpy (&prev_recv_messages_iter, &component->recv_messages_iter, sizeof (NiceInputMessageIter)); - agent_unlock_and_emit (agent); g_main_context_iteration (context, blocking); agent_lock (); @@ -3298,7 +3330,11 @@ &stream, &component)) { g_set_error (&child_error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE, "Component removed during call."); - goto done; + + component = NULL; + error_reported = TRUE; + + goto recv_error; } received_enough = @@ -3314,13 +3350,15 @@ nice_input_message_iter_get_n_valid_messages ( &component->recv_messages_iter); /* grab before resetting the iter */ - /* Tidy up. */ + component_set_io_callback (component, NULL, NULL, NULL, 0, NULL); + +recv_error: + /* Tidy up. Below this point, @component may be %NULL. */ if (cancellable_source != NULL) { g_source_destroy (cancellable_source); g_source_unref (cancellable_source); } - component_set_io_callback (component, NULL, NULL, NULL, 0, NULL); g_main_context_unref (context); /* Handle errors and cancellations. */ @@ -3637,31 +3675,52 @@ return ret; } - gboolean nice_agent_restart ( NiceAgent *agent) { GSList *i; - gboolean res = TRUE; agent_lock(); - /* step: clean up all connectivity checks */ - conn_check_free (agent); - /* step: regenerate tie-breaker value */ priv_generate_tie_breaker (agent); - for (i = agent->streams; i && res; i = i->next) { + for (i = agent->streams; i; i = i->next) { Stream *stream = i->data; /* step: reset local credentials for the stream and * clean up the list of remote candidates */ - res = stream_restart (stream, agent->rng); + stream_restart (agent, stream); } agent_unlock_and_emit (agent); + return TRUE; +} + +gboolean +nice_agent_restart_stream ( + NiceAgent *agent, + guint stream_id) +{ + gboolean res = FALSE; + Stream *stream; + + agent_lock(); + + stream = agent_find_stream (agent, stream_id); + if (!stream) { + g_warning ("Could not find stream %u", stream_id); + goto done; + } + + /* step: reset local credentials for the stream and + * clean up the list of remote candidates */ + stream_restart (agent, stream); + + res = TRUE; + done: + agent_unlock_and_emit (agent); return res; } @@ -3736,7 +3795,7 @@ } gboolean -component_io_cb (GSocket *socket, GIOCondition condition, gpointer user_data) +component_io_cb (GSocket *gsocket, GIOCondition condition, gpointer user_data) { SocketSource *socket_source = user_data; Component *component; @@ -4050,6 +4109,10 @@ agent_lock(); + /* Reliable streams are pseudotcp or MUST use RFC 4571 framing */ + if (agent->reliable) + goto done; + /* step: check that params specify an existing pair */ if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) @@ -4625,11 +4688,11 @@ int ntype = -1; gchar **tokens = NULL; const gchar *foundation = NULL; - guint component_id; + guint component_id = 0; const gchar *transport = NULL; - guint32 priority; + guint32 priority = 0; const gchar *addr = NULL; - guint16 port; + guint16 port = 0; const gchar *type = NULL; const gchar *raddr = NULL; guint16 rport = 0; @@ -4749,3 +4812,28 @@ return iostream; } + +NICEAPI_EXPORT gboolean +nice_agent_forget_relays (NiceAgent *agent, guint stream_id, guint component_id) +{ + Component *component; + gboolean ret = TRUE; + + g_return_val_if_fail (NICE_IS_AGENT (agent), FALSE); + g_return_val_if_fail (stream_id >= 1, FALSE); + g_return_val_if_fail (component_id >= 1, FALSE); + + agent_lock (); + + if (!agent_find_component (agent, stream_id, component_id, NULL, &component)) { + ret = FALSE; + goto done; + } + + component_clean_turn_servers (component); + + done: + agent_unlock_and_emit (agent); + + return ret; +} diff -Nru libnice-0.1.5/agent/agent.h libnice-0.1.7/agent/agent.h --- libnice-0.1.5/agent/agent.h 2014-03-07 02:14:00.000000000 +0000 +++ libnice-0.1.7/agent/agent.h 2014-04-29 00:27:22.000000000 +0000 @@ -787,6 +787,28 @@ nice_agent_restart ( NiceAgent *agent); +/** + * nice_agent_restart_stream: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * + * Restarts a single stream as defined in RFC 5245. This function + * needs to be called both when initiating (ICE spec section 9.1.1.1. + * "ICE Restarts"), as well as when reacting (spec section 9.2.1.1. + * "Detecting ICE Restart") to a restart. + * + * Unlike nice_agent_restart(), this applies to a single stream. It also + * does not generate a new tie breaker. + * + * Returns: %TRUE on success %FALSE on error + * + * Since: 0.1.6 + **/ +gboolean +nice_agent_restart_stream ( + NiceAgent *agent, + guint stream_id); + /** * nice_agent_attach_recv: @@ -1412,6 +1434,39 @@ guint stream_id, guint component_id); +/** + * nice_component_state_to_string: + * @state: a #NiceComponentState + * + * Returns a string representation of the state, generally to use in debug + * messages. + * + * Returns: (transfer none): a string representation of @state + * Since: 0.1.6 + */ +const gchar * +nice_component_state_to_string (NiceComponentState state); + +/** + * nice_agent_forget_relays: + * @agent: The #NiceAgent Object + * @stream_id: The ID of the stream + * @component_id: The ID of the component + * + * Forget all the relay servers previously added using + * nice_agent_set_relay_info(). Currently connected streams will keep + * using the relay as long as they have not been restarted and haven't + * succesfully negotiated a different path. + * + * Returns: %FALSE if the component could not be found, %TRUE otherwise + * + * Since: 0.1.6 + */ +gboolean +nice_agent_forget_relays (NiceAgent *agent, + guint stream_id, + guint component_id); + G_END_DECLS #endif /* _AGENT_H */ diff -Nru libnice-0.1.5/agent/agent-signals-marshal.c libnice-0.1.7/agent/agent-signals-marshal.c --- libnice-0.1.5/agent/agent-signals-marshal.c 2014-01-31 08:29:42.000000000 +0000 +++ libnice-0.1.7/agent/agent-signals-marshal.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,210 +0,0 @@ -#include "agent-signals-marshal.h" - -#include - - -#ifdef G_ENABLE_DEBUG -#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) -#define g_marshal_value_peek_char(v) g_value_get_schar (v) -#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) -#define g_marshal_value_peek_int(v) g_value_get_int (v) -#define g_marshal_value_peek_uint(v) g_value_get_uint (v) -#define g_marshal_value_peek_long(v) g_value_get_long (v) -#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) -#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) -#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) -#define g_marshal_value_peek_enum(v) g_value_get_enum (v) -#define g_marshal_value_peek_flags(v) g_value_get_flags (v) -#define g_marshal_value_peek_float(v) g_value_get_float (v) -#define g_marshal_value_peek_double(v) g_value_get_double (v) -#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) -#define g_marshal_value_peek_param(v) g_value_get_param (v) -#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) -#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) -#define g_marshal_value_peek_object(v) g_value_get_object (v) -#define g_marshal_value_peek_variant(v) g_value_get_variant (v) -#else /* !G_ENABLE_DEBUG */ -/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. - * Do not access GValues directly in your code. Instead, use the - * g_value_get_*() functions - */ -#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int -#define g_marshal_value_peek_char(v) (v)->data[0].v_int -#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint -#define g_marshal_value_peek_int(v) (v)->data[0].v_int -#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint -#define g_marshal_value_peek_long(v) (v)->data[0].v_long -#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 -#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 -#define g_marshal_value_peek_enum(v) (v)->data[0].v_long -#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_float(v) (v)->data[0].v_float -#define g_marshal_value_peek_double(v) (v)->data[0].v_double -#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer -#endif /* !G_ENABLE_DEBUG */ - - -/* VOID:UINT,UINT,UINT (agent-signals-marshal.list:2) */ -void -agent_marshal_VOID__UINT_UINT_UINT (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__UINT_UINT_UINT) (gpointer data1, - guint arg_1, - guint arg_2, - guint arg_3, - gpointer data2); - register GMarshalFunc_VOID__UINT_UINT_UINT callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 4); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_VOID__UINT_UINT_UINT) (marshal_data ? marshal_data : cc->callback); - - callback (data1, - g_marshal_value_peek_uint (param_values + 1), - g_marshal_value_peek_uint (param_values + 2), - g_marshal_value_peek_uint (param_values + 3), - data2); -(void)return_value;(void)invocation_hint;} - -/* VOID:UINT,UINT,STRING,STRING (agent-signals-marshal.list:4) */ -void -agent_marshal_VOID__UINT_UINT_STRING_STRING (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__UINT_UINT_STRING_STRING) (gpointer data1, - guint arg_1, - guint arg_2, - gpointer arg_3, - gpointer arg_4, - gpointer data2); - register GMarshalFunc_VOID__UINT_UINT_STRING_STRING callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 5); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_VOID__UINT_UINT_STRING_STRING) (marshal_data ? marshal_data : cc->callback); - - callback (data1, - g_marshal_value_peek_uint (param_values + 1), - g_marshal_value_peek_uint (param_values + 2), - g_marshal_value_peek_string (param_values + 3), - g_marshal_value_peek_string (param_values + 4), - data2); -(void)return_value;(void)invocation_hint;} - -/* VOID:UINT,UINT,STRING (agent-signals-marshal.list:6) */ -void -agent_marshal_VOID__UINT_UINT_STRING (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__UINT_UINT_STRING) (gpointer data1, - guint arg_1, - guint arg_2, - gpointer arg_3, - gpointer data2); - register GMarshalFunc_VOID__UINT_UINT_STRING callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 4); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_VOID__UINT_UINT_STRING) (marshal_data ? marshal_data : cc->callback); - - callback (data1, - g_marshal_value_peek_uint (param_values + 1), - g_marshal_value_peek_uint (param_values + 2), - g_marshal_value_peek_string (param_values + 3), - data2); -(void)return_value;(void)invocation_hint;} - -/* VOID:UINT (agent-signals-marshal.list:9) */ - -/* VOID:UINT,UINT (agent-signals-marshal.list:11) */ -void -agent_marshal_VOID__UINT_UINT (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__UINT_UINT) (gpointer data1, - guint arg_1, - guint arg_2, - gpointer data2); - register GMarshalFunc_VOID__UINT_UINT callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 3); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_VOID__UINT_UINT) (marshal_data ? marshal_data : cc->callback); - - callback (data1, - g_marshal_value_peek_uint (param_values + 1), - g_marshal_value_peek_uint (param_values + 2), - data2); -(void)return_value;(void)invocation_hint;} - diff -Nru libnice-0.1.5/agent/agent-signals-marshal.h libnice-0.1.7/agent/agent-signals-marshal.h --- libnice-0.1.5/agent/agent-signals-marshal.h 2014-01-31 08:29:42.000000000 +0000 +++ libnice-0.1.7/agent/agent-signals-marshal.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ - -#ifndef __agent_marshal_MARSHAL_H__ -#define __agent_marshal_MARSHAL_H__ - -#include - -G_BEGIN_DECLS - -/* VOID:UINT,UINT,UINT (agent-signals-marshal.list:2) */ -extern void agent_marshal_VOID__UINT_UINT_UINT (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* VOID:UINT,UINT,STRING,STRING (agent-signals-marshal.list:4) */ -extern void agent_marshal_VOID__UINT_UINT_STRING_STRING (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* VOID:UINT,UINT,STRING (agent-signals-marshal.list:6) */ -extern void agent_marshal_VOID__UINT_UINT_STRING (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* VOID:UINT (agent-signals-marshal.list:9) */ -#define agent_marshal_VOID__UINT g_cclosure_marshal_VOID__UINT - -/* VOID:UINT,UINT (agent-signals-marshal.list:11) */ -extern void agent_marshal_VOID__UINT_UINT (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -G_END_DECLS - -#endif /* __agent_marshal_MARSHAL_H__ */ - diff -Nru libnice-0.1.5/agent/agent-signals-marshal.list libnice-0.1.7/agent/agent-signals-marshal.list --- libnice-0.1.5/agent/agent-signals-marshal.list 2011-02-02 04:49:41.000000000 +0000 +++ libnice-0.1.7/agent/agent-signals-marshal.list 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -# component-status-changed -VOID:UINT,UINT,UINT -# new-selected-pair -VOID:UINT,UINT,STRING,STRING -# new-candidate -VOID:UINT,UINT,STRING -# candidate-gathering-done -# initial-binding-request-received -VOID:UINT -# reliable-transport-writable -VOID:UINT,UINT - diff -Nru libnice-0.1.5/agent/candidate.c libnice-0.1.7/agent/candidate.c --- libnice-0.1.5/agent/candidate.c 2014-01-06 23:05:12.000000000 +0000 +++ libnice-0.1.7/agent/candidate.c 2014-04-25 01:09:45.000000000 +0000 @@ -80,6 +80,9 @@ if (candidate->password) g_free (candidate->password); + if (candidate->turn) + turn_server_unref (candidate->turn); + g_slice_free (NiceCandidate, candidate); } @@ -163,8 +166,11 @@ { guint32 max = o_prio > a_prio ? o_prio : a_prio; guint32 min = o_prio < a_prio ? o_prio : a_prio; + /* These two constants are here explictly to make some version of GCC happy */ + const guint64 one = 1; + const guint64 thirtytwo = 32; - return ((guint64)1 << 32) * min + 2 * max + (o_prio > a_prio ? 1 : 0); + return (one << thirtytwo) * min + 2 * max + (o_prio > a_prio ? 1 : 0); } /* @@ -177,6 +183,7 @@ memcpy (copy, candidate, sizeof(NiceCandidate)); + copy->turn = NULL; copy->username = g_strdup (copy->username); copy->password = g_strdup (copy->password); diff -Nru libnice-0.1.5/agent/candidate.h libnice-0.1.7/agent/candidate.h --- libnice-0.1.5/agent/candidate.h 2014-01-06 23:05:12.000000000 +0000 +++ libnice-0.1.7/agent/candidate.h 2014-04-25 01:09:45.000000000 +0000 @@ -129,6 +129,8 @@ */ struct _TurnServer { + gint ref_count; + NiceAddress server; /**< TURN server address */ gchar *username; /**< TURN username */ gchar *password; /**< TURN password */ diff -Nru libnice-0.1.5/agent/component.c libnice-0.1.7/agent/component.c --- libnice-0.1.5/agent/component.c 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/agent/component.c 2014-04-25 01:09:45.000000000 +0000 @@ -51,6 +51,7 @@ #include "debug.h" #include "component.h" +#include "discovery.h" #include "agent-priv.h" @@ -129,6 +130,7 @@ component->own_ctx = g_main_context_new (); component->stop_cancellable = g_cancellable_new (); src = g_cancellable_source_new (component->stop_cancellable); + g_source_set_dummy_callback (src); g_source_attach (src, component->own_ctx); g_source_unref (src); component->ctx = g_main_context_ref (component->own_ctx); @@ -145,10 +147,56 @@ } void +component_clean_turn_servers (Component *cmp) +{ + GSList *i; + + g_list_free_full (cmp->turn_servers, (GDestroyNotify) turn_server_unref); + cmp->turn_servers = NULL; + + for (i = cmp->local_candidates; i;) { + NiceCandidate *candidate = i->data; + GSList *next = i->next; + + if (candidate->type != NICE_CANDIDATE_TYPE_RELAYED) { + i = next; + continue; + } + + /* note: do not remove the remote candidate that is + * currently part of the 'selected pair', see ICE + * 9.1.1.1. "ICE Restarts" (ID-19) + * + * So what we do instead is that we put the selected candidate + * in a special location and keep it "alive" that way. This is + * especially important for TURN, because refresh requests to the + * server need to keep happening. + */ + if (candidate == cmp->selected_pair.local) { + if (cmp->turn_candidate) { + refresh_prune_candidate (cmp->agent, cmp->turn_candidate); + component_detach_socket (cmp, cmp->turn_candidate->sockptr); + nice_candidate_free (cmp->turn_candidate); + } + /* Bring the priority down to 0, so that it will be replaced + * on the new run. + */ + cmp->selected_pair.priority = 0; + cmp->turn_candidate = candidate; + } else { + refresh_prune_candidate (cmp->agent, candidate); + component_detach_socket (cmp, candidate->sockptr); + nice_candidate_free (candidate); + } + cmp->local_candidates = g_slist_delete_link (cmp->local_candidates, i); + i = next; + } +} + +void component_free (Component *cmp) { GSList *i; - GList *item; IOCallbackData *data; GOutputVector *vec; @@ -166,6 +214,10 @@ nice_candidate_free (cmp->restart_candidate), cmp->restart_candidate = NULL; + if (cmp->turn_candidate) + nice_candidate_free (cmp->turn_candidate), + cmp->turn_candidate = NULL; + for (i = cmp->incoming_checks; i; i = i->next) { IncomingCheck *icheck = i->data; g_free (icheck->username); @@ -173,17 +225,14 @@ } g_slist_free (cmp->local_candidates); + cmp->local_candidates = NULL; g_slist_free (cmp->remote_candidates); + cmp->remote_candidates = NULL; component_free_socket_sources (cmp); g_slist_free (cmp->incoming_checks); + cmp->incoming_checks = NULL; - for (item = cmp->turn_servers; item; item = g_list_next (item)) { - TurnServer *turn = item->data; - g_free (turn->username); - g_free (turn->password); - g_slice_free (TurnServer, turn); - } - g_list_free (cmp->turn_servers); + component_clean_turn_servers (cmp); if (cmp->selected_pair.keepalive.tick_source != NULL) { g_source_destroy (cmp->selected_pair.keepalive.tick_source); @@ -275,7 +324,7 @@ * Resets the component state to that of a ICE restarted * session. */ -gboolean +void component_restart (Component *cmp) { GSList *i; @@ -283,7 +332,7 @@ for (i = cmp->remote_candidates; i; i = i->next) { NiceCandidate *candidate = i->data; - /* note: do not remove the remote candidate that is + /* note: do not remove the local candidate that is * currently part of the 'selected pair', see ICE * 9.1.1.1. "ICE Restarts" (ID-19) */ if (candidate == cmp->selected_pair.remote) { @@ -306,8 +355,6 @@ cmp->incoming_checks = NULL; /* note: component state managed by agent */ - - return TRUE; } /* @@ -431,36 +478,29 @@ /* This takes ownership of the socket. * It creates and attaches a source to the component’s context. */ void -component_attach_socket (Component *component, NiceSocket *socket) +component_attach_socket (Component *component, NiceSocket *nicesock) { GSList *l; SocketSource *socket_source; g_assert (component != NULL); - g_assert (socket != NULL); + g_assert (nicesock != NULL); g_assert (component->ctx != NULL); /* Find an existing SocketSource in the component which contains @socket, or * create a new one. * - * In order for socket_sources_age to work properly, socket_sources must only - * grow monotonically, or be entirely cleared. i.e. New SocketSources must be - * prepended to socket_sources, and all other existing SocketSource must be - * left untouched; *or* the whole of socket_sources must be cleared. If - * socket_sources is cleared, age is reset to 0 and *must not* be incremented - * again or the new sockets will not be picked up by ComponentSocket. This is - * guaranteed by the fact that socket_sources is only cleared on disconnection - * or discovery failure, which are both unrecoverable states. - * - * An empty socket_sources corresponds to age 0. */ - l = g_slist_find_custom (component->socket_sources, socket, + * Whenever a source is added or remove to socket_sources, socket_sources_age + * must be incremented. + */ + l = g_slist_find_custom (component->socket_sources, nicesock, _find_socket_source); if (l != NULL) { socket_source = l->data; } else { socket_source = g_slice_new0 (SocketSource); - socket_source->socket = socket; + socket_source->socket = nicesock; socket_source->component = component; component->socket_sources = g_slist_prepend (component->socket_sources, socket_source); @@ -495,28 +535,32 @@ * @component: a #Component * @socket: the socket to detach the source for * - * Detach the #GSource for the single specified @socket. Leave the socket itself - * untouched. + * Detach the #GSource for the single specified @socket. It also closes it + * and frees it! * * If the @socket doesn’t exist in this @component, do nothing. */ void -component_detach_socket (Component *component, NiceSocket *socket) +component_detach_socket (Component *component, NiceSocket *nicesock) { GSList *l; SocketSource *socket_source; - nice_debug ("Detach socket %p.", socket); + nice_debug ("Detach socket %p.", nicesock); /* Find the SocketSource for the socket. */ - l = g_slist_find_custom (component->socket_sources, socket, + l = g_slist_find_custom (component->socket_sources, nicesock, _find_socket_source); if (l == NULL) return; /* Detach the source. */ socket_source = l->data; + component->socket_sources = g_slist_delete_link (component->socket_sources, l); + component->socket_sources_age++; + socket_source_detach (socket_source); + socket_source_free (socket_source); } /* @@ -547,7 +591,7 @@ g_slist_free_full (component->socket_sources, (GDestroyNotify) socket_source_free); component->socket_sources = NULL; - component->socket_sources_age = 0; + component->socket_sources_age++; } GMainContext * @@ -823,7 +867,6 @@ component->io_callback_id = 0; } - /** * ComponentSource: * @@ -854,15 +897,20 @@ guint stream_id; guint component_id; guint component_socket_sources_age; + + /* SocketSource, free with free_child_socket_source() */ + GSList *socket_sources; + + GIOCondition condition; } ComponentSource; static gboolean component_source_prepare (GSource *source, gint *timeout_) { ComponentSource *component_source = (ComponentSource *) source; - gint age_diff; NiceAgent *agent; Component *component; + GSList *parentl, *childl; agent = g_weak_ref_get (&component_source->agent_ref); if (!agent) @@ -877,44 +925,67 @@ goto done; - age_diff = - component->socket_sources_age - - component_source->component_socket_sources_age; - - /* If the age has changed, either: - * • a new socket has been *prepended* to component->socket_sources (and - * age_diff > 0); or - * • component->socket_sources has been emptied (and age_diff < 0). - * We can’t remove any child sources without destroying them, so must - * monotonically add new ones, or remove everything. - * - * Removing everything only happens on shutdown or failure, in which case - * the ComponentSource itself can be destroyed, automatically destroying all - * the child sources. */ - if (age_diff < 0) { - g_source_destroy (source); - } else if (age_diff > 0) { - /* Add the new child sources. The difference between the two ages gives - * the number of new child sources. */ - guint i; - GSList *l; - - for (i = 0, l = component->socket_sources; - i < (guint) age_diff && l != NULL; - i++, l = l->next) { - GSource *child_source; - SocketSource *socket_source; - - socket_source = l->data; - - child_source = g_socket_create_source (socket_source->socket->fileno, - G_IO_IN, NULL); - g_source_set_dummy_callback (child_source); - g_source_add_child_source (source, child_source); - g_source_unref (child_source); + if (component->socket_sources_age == + component_source->component_socket_sources_age) + goto done; + + /* If the age has changed, either + * - one or more new socket has been prepended + * - old sockets have been removed + */ + + /* Add the new child sources. */ + + for (parentl = component->socket_sources; parentl; parentl = parentl->next) { + SocketSource *parent_socket_source = parentl->data; + SocketSource *child_socket_source; + + /* Iterating the list of socket sources every time isn't a big problem + * because the number of pairs is limited ~100 normally, so there will + * rarely be more than 10. + */ + childl = g_slist_find_custom (component_source->socket_sources, + parent_socket_source->socket, _find_socket_source); + + /* If we have reached this state, then all sources new sources have been + * added, because they are always prepended. + */ + if (childl) + break; + + child_socket_source = g_slice_new0 (SocketSource); + child_socket_source->socket = parent_socket_source->socket; + child_socket_source->source = + g_socket_create_source (child_socket_source->socket->fileno, G_IO_IN, + NULL); + g_source_set_dummy_callback (child_socket_source->source); + g_source_add_child_source (source, child_socket_source->source); + g_source_unref (child_socket_source->source); + component_source->socket_sources = + g_slist_prepend (component_source->socket_sources, child_socket_source); + } + + + for (childl = component_source->socket_sources; + childl;) { + SocketSource *child_socket_source = childl->data; + GSList *next = childl->next; + + parentl = g_slist_find_custom (component->socket_sources, + child_socket_source->socket, _find_socket_source); + + /* If this is not a currently used socket, remove the relevant source */ + if (!parentl) { + g_source_remove_child_source (source, child_socket_source->source); + g_slice_free (SocketSource, child_socket_source); + component_source->socket_sources = + g_slist_delete_link (component_source->socket_sources, childl); } + + childl = next; } + /* Update the age. */ component_source->component_socket_sources_age = component->socket_sources_age; @@ -938,10 +1009,18 @@ } static void +free_child_socket_source (gpointer data) +{ + g_slice_free (SocketSource, data); +} + +static void component_source_finalize (GSource *source) { ComponentSource *component_source = (ComponentSource *) source; + g_slist_free_full (component_source->socket_sources, free_child_socket_source); + g_weak_ref_clear (&component_source->agent_ref); g_object_unref (component_source->pollable_stream); component_source->pollable_stream = NULL; @@ -1031,3 +1110,46 @@ return (GSource *) component_source; } + + +TurnServer * +turn_server_new (const gchar *server_ip, guint server_port, + const gchar *username, const gchar *password, NiceRelayType type) +{ + TurnServer *turn = g_slice_new (TurnServer); + + nice_address_init (&turn->server); + + turn->ref_count = 1; + if (nice_address_set_from_string (&turn->server, server_ip)) { + nice_address_set_port (&turn->server, server_port); + } else { + g_slice_free (TurnServer, turn); + return NULL; + } + turn->username = g_strdup (username); + turn->password = g_strdup (password); + turn->type = type; + + return turn; +} + +TurnServer * +turn_server_ref (TurnServer *turn) +{ + turn->ref_count++; + + return turn; +} + +void +turn_server_unref (TurnServer *turn) +{ + turn->ref_count--; + + if (turn->ref_count == 0) { + g_free (turn->username); + g_free (turn->password); + g_slice_free (TurnServer, turn); + } +} diff -Nru libnice-0.1.5/agent/component.h libnice-0.1.7/agent/component.h --- libnice-0.1.5/agent/component.h 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/agent/component.h 2014-04-25 01:09:45.000000000 +0000 @@ -149,7 +149,7 @@ CandidatePair selected_pair; /**< independent from checklists, see ICE 11.1. "Sending Media" (ID-19) */ NiceCandidate *restart_candidate; /**< for storing active remote candidate during a restart */ - + NiceCandidate *turn_candidate; /**< for storing active turn candidate if turn servers have been cleared */ /* I/O handling. The main context must always be non-NULL, and is used for all * socket recv() operations. All io_callback emissions are invoked in this * context too. @@ -190,7 +190,7 @@ PseudoTcpSocket *tcp; GSource* tcp_clock; - long last_clock_timeout; + guint64 last_clock_timeout; gboolean tcp_readable; GCancellable *tcp_writable_cancellable; @@ -214,7 +214,7 @@ gboolean component_find_pair (Component *cmp, NiceAgent *agent, const gchar *lfoundation, const gchar *rfoundation, CandidatePair *pair); -gboolean +void component_restart (Component *cmp); void @@ -228,9 +228,9 @@ NiceCandidate *candidate); void -component_attach_socket (Component *component, NiceSocket *socket); +component_attach_socket (Component *component, NiceSocket *nsocket); void -component_detach_socket (Component *component, NiceSocket *socket); +component_detach_socket (Component *component, NiceSocket *nsocket); void component_detach_all_sockets (Component *component); void @@ -257,6 +257,21 @@ gboolean component_has_io_callback (Component *component); +void +component_clean_turn_servers (Component *component); + + +TurnServer * +turn_server_new (const gchar *server_ip, guint server_port, + const gchar *username, const gchar *password, NiceRelayType type); + +TurnServer * +turn_server_ref (TurnServer *turn); + +void +turn_server_unref (TurnServer *turn); + + G_END_DECLS #endif /* _NICE_COMPONENT_H */ diff -Nru libnice-0.1.5/agent/conncheck.c libnice-0.1.7/agent/conncheck.c --- libnice-0.1.5/agent/conncheck.c 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/agent/conncheck.c 2014-04-25 01:09:45.000000000 +0000 @@ -71,6 +71,7 @@ uint8_t *dest, guint dest_len, gboolean inbound); static size_t priv_get_password (NiceAgent *agent, Stream *stream, NiceCandidate *remote, uint8_t **password); +static void conn_check_free_item (gpointer data); static int priv_timer_expired (GTimeVal *timer, GTimeVal *now) { @@ -587,12 +588,12 @@ gchar tmpbuf[INET6_ADDRSTRLEN]; nice_address_to_string (&p->remote->addr, tmpbuf); nice_debug ("Agent %p : Keepalive STUN-CC REQ to '%s:%u', " - "socket=%u (c-id:%u), username='%s' (%" G_GSIZE_FORMAT "), " - "password='%s' (%" G_GSIZE_FORMAT "), priority=%u.", agent, + "socket=%u (c-id:%u), username='%.*s' (%" G_GSIZE_FORMAT "), " + "password='%.*s' (%" G_GSIZE_FORMAT "), priority=%u.", agent, tmpbuf, nice_address_get_port (&p->remote->addr), g_socket_get_fd(((NiceSocket *)p->local->sockptr)->fileno), - component->id, uname, uname_len, password, password_len, - priority); + component->id, (int) uname_len, uname, uname_len, + (int) password_len, password, password_len, priority); } if (uname_len > 0) { buf_len = stun_usage_ice_conncheck_create (&agent->stun_agent, @@ -604,7 +605,7 @@ NULL, agent_to_ice_compatibility (agent)); - nice_debug ("Agent %p: conncheck created %" G_GSIZE_FORMAT " - %p", + nice_debug ("Agent %p: conncheck created %zd - %p", agent, buf_len, p->keepalive.stun_message.buffer); if (buf_len > 0) { @@ -790,17 +791,17 @@ static void priv_turn_allocate_refresh_tick_unlocked (CandidateRefresh *cand) { uint8_t *username; - size_t username_len; + gsize username_len; uint8_t *password; - size_t password_len; + gsize password_len; size_t buffer_len = 0; StunUsageTurnCompatibility turn_compat = agent_to_turn_compatibility (cand->agent); - username = (uint8_t *)cand->turn->username; - username_len = (size_t) strlen (cand->turn->username); - password = (uint8_t *)cand->turn->password; - password_len = (size_t) strlen (cand->turn->password); + username = (uint8_t *)cand->candidate->turn->username; + username_len = (size_t) strlen (cand->candidate->turn->username); + password = (uint8_t *)cand->candidate->turn->password; + password_len = (size_t) strlen (cand->candidate->turn->password); if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN || turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) { @@ -817,14 +818,12 @@ if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN || turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) { - g_free (cand->msn_turn_username); - g_free (cand->msn_turn_password); - cand->msn_turn_username = username; - cand->msn_turn_password = password; + g_free (username); + g_free (password); } - nice_debug ("Agent %p : Sending allocate Refresh %" G_GSIZE_FORMAT, - cand->agent, buffer_len); + nice_debug ("Agent %p : Sending allocate Refresh %zd", cand->agent, + buffer_len); if (cand->tick_source != NULL) { g_source_destroy (cand->tick_source); @@ -1088,9 +1087,8 @@ c = list_len - upper_limit; if (c == list_len) { /* case: delete whole list */ - g_slist_foreach (conncheck_list, conn_check_free_item, NULL); - g_slist_free (conncheck_list), - result = NULL; + g_slist_free_full (conncheck_list, conn_check_free_item); + result = NULL; } else { /* case: remove 'c' items from list end (lowest priority) */ @@ -1102,11 +1100,8 @@ tmp = i->next; i->next = NULL; - if (tmp) { - /* delete the rest of the connectivity check list */ - g_slist_foreach (tmp, conn_check_free_item, NULL); - g_slist_free (tmp); - } + /* delete the rest of the connectivity check list */ + g_slist_free_full (tmp, conn_check_free_item); } } @@ -1133,6 +1128,14 @@ component->selected_pair.keepalive.tick_source = NULL; } + if (component->selected_pair.local && + component->selected_pair.local == component->turn_candidate) { + refresh_prune_candidate (agent, component->turn_candidate); + component_detach_socket (component, component->turn_candidate->sockptr); + nice_candidate_free (component->turn_candidate); + component->turn_candidate = NULL; + } + memset (&component->selected_pair, 0, sizeof(CandidatePair)); component->selected_pair.local = pair->local; component->selected_pair.remote = pair->remote; @@ -1165,6 +1168,18 @@ * must be fetched before entering the loop*/ guint c, components = stream->n_components; + for (i = agent->discovery_list; i; i = i->next) { + CandidateDiscovery *d = i->data; + + /* There is still discovery ogoing for this stream, + * so don't fail any of it's candidates. + */ + if (d->stream == stream && !d->done) + return; + } + if (agent->discovery_list != NULL) + return; + /* note: iterate the conncheck list for each component separately */ for (c = 0; c < components; c++) { Component *comp = NULL; @@ -1173,7 +1188,7 @@ for (i = stream->conncheck_list; i; i = i->next) { CandidateCheckPair *p = i->data; - + if (p->stream_id == stream->id && p->component_id == (c + 1)) { if (p->state != NICE_CHECK_FAILED) @@ -1395,17 +1410,28 @@ /* * Frees the CandidateCheckPair structure pointer to - * by 'user data'. Compatible with g_slist_foreach(). + * by 'user data'. Compatible with GDestroyNotify. */ -void conn_check_free_item (gpointer data, gpointer user_data) +static void conn_check_free_item (gpointer data) { CandidateCheckPair *pair = data; - g_assert (user_data == NULL); + pair->stun_message.buffer = NULL; pair->stun_message.buffer_len = 0; g_slice_free (CandidateCheckPair, pair); } +static void +conn_check_stop (NiceAgent *agent) +{ + if (agent->conncheck_timer_source == NULL) + return; + + g_source_destroy (agent->conncheck_timer_source); + g_source_unref (agent->conncheck_timer_source); + agent->conncheck_timer_source = NULL; +} + /* * Frees all resources of all connectivity checks. */ @@ -1415,19 +1441,15 @@ for (i = agent->streams; i; i = i->next) { Stream *stream = i->data; - nice_debug ("Agent %p, freeing conncheck_list of stream %p", agent, stream); if (stream->conncheck_list) { - g_slist_foreach (stream->conncheck_list, conn_check_free_item, NULL); - g_slist_free (stream->conncheck_list), - stream->conncheck_list = NULL; + nice_debug ("Agent %p, freeing conncheck_list of stream %p", agent, + stream); + g_slist_free_full (stream->conncheck_list, conn_check_free_item); + stream->conncheck_list = NULL; } } - if (agent->conncheck_timer_source != NULL) { - g_source_destroy (agent->conncheck_timer_source); - g_source_unref (agent->conncheck_timer_source); - agent->conncheck_timer_source = NULL; - } + conn_check_stop (agent); } /* @@ -1436,33 +1458,28 @@ * * @return TRUE on success, FALSE on a fatal error */ -gboolean conn_check_prune_stream (NiceAgent *agent, Stream *stream) +void conn_check_prune_stream (NiceAgent *agent, Stream *stream) { - CandidateCheckPair *pair; GSList *i; + gboolean keep_going = FALSE; - for (i = stream->conncheck_list; i ; ) { - GSList *next = i->next; - pair = i->data; - - g_assert (pair->stream_id == stream->id); - - stream->conncheck_list = - g_slist_remove (stream->conncheck_list, pair); - conn_check_free_item (pair, NULL); - i = next; - if (!stream->conncheck_list) - break; - } + if (stream->conncheck_list) { + nice_debug ("Agent %p, freeing conncheck_list of stream %p", agent, stream); - if (!stream->conncheck_list) - conn_check_free (agent); + g_slist_free_full (stream->conncheck_list, conn_check_free_item); + stream->conncheck_list = NULL; + } - /* return FALSE if there was a memory allocation failure */ - if (stream->conncheck_list == NULL && i != NULL) - return FALSE; + for (i = agent->streams; i; i = i->next) { + Stream *s = i->data; + if (s->conncheck_list) { + keep_going = TRUE; + break; + } + } - return TRUE; + if (!keep_going) + conn_check_stop (agent); } /* @@ -1650,11 +1667,11 @@ pair->local->component_id); uint8_t uname[NICE_STREAM_MAX_UNAME]; - size_t uname_len = + gsize uname_len = priv_create_username (agent, agent_find_stream (agent, pair->stream_id), pair->component_id, pair->remote, pair->local, uname, sizeof (uname), FALSE); uint8_t *password = NULL; - size_t password_len = priv_get_password (agent, + gsize password_len = priv_get_password (agent, agent_find_stream (agent, pair->stream_id), pair->remote, &password); bool controlling = agent->controlling_mode; @@ -1673,14 +1690,16 @@ gchar tmpbuf[INET6_ADDRSTRLEN]; nice_address_to_string (&pair->remote->addr, tmpbuf); nice_debug ("Agent %p : STUN-CC REQ to '%s:%u', socket=%u, " - "pair=%s (c-id:%u), tie=%llu, username='%s' (%" G_GSIZE_FORMAT "), " - "password='%s' (%" G_GSIZE_FORMAT "), priority=%u.", agent, + "pair=%s (c-id:%u), tie=%llu, username='%.*s' (%" G_GSIZE_FORMAT "), " + "password='%.*s' (%" G_GSIZE_FORMAT "), priority=%u.", agent, tmpbuf, nice_address_get_port (&pair->remote->addr), g_socket_get_fd(((NiceSocket *)pair->local->sockptr)->fileno), pair->foundation, pair->component_id, (unsigned long long)agent->tie_breaker, - uname, uname_len, password, password_len, priority); + (int) uname_len, uname, uname_len, + (int) password_len, password, password_len, + priority); } @@ -1697,8 +1716,8 @@ pair->foundation, agent_to_ice_compatibility (agent)); - nice_debug ("Agent %p: conncheck created %" G_GSIZE_FORMAT " - %p", - agent, buffer_len, pair->stun_message.buffer); + nice_debug ("Agent %p: conncheck created %zd - %p", agent, buffer_len, + pair->stun_message.buffer); if (agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007) { @@ -1903,7 +1922,7 @@ * * @pre (rcand == NULL || nice_address_equal(rcand->addr, toaddr) == TRUE) */ -static void priv_reply_to_conn_check (NiceAgent *agent, Stream *stream, Component *component, NiceCandidate *rcand, const NiceAddress *toaddr, NiceSocket *socket, size_t rbuf_len, uint8_t *rbuf, gboolean use_candidate) +static void priv_reply_to_conn_check (NiceAgent *agent, Stream *stream, Component *component, NiceCandidate *rcand, const NiceAddress *toaddr, NiceSocket *sockptr, size_t rbuf_len, uint8_t *rbuf, gboolean use_candidate) { g_assert (rcand == NULL || nice_address_equal(&rcand->addr, toaddr) == TRUE); @@ -1913,17 +1932,17 @@ nice_debug ("Agent %p : STUN-CC RESP to '%s:%u', socket=%u, len=%u, cand=%p (c-id:%u), use-cand=%d.", agent, tmpbuf, nice_address_get_port (toaddr), - g_socket_get_fd(socket->fileno), + g_socket_get_fd(sockptr->fileno), (unsigned)rbuf_len, rcand, component->id, (int)use_candidate); } - nice_socket_send (socket, toaddr, rbuf_len, (const gchar*)rbuf); + nice_socket_send (sockptr, toaddr, rbuf_len, (const gchar*)rbuf); if (rcand) { /* note: upon successful check, make the reserve check immediately */ - priv_schedule_triggered_check (agent, stream, component, socket, rcand, use_candidate); + priv_schedule_triggered_check (agent, stream, component, sockptr, rcand, use_candidate); if (use_candidate) priv_mark_pair_nominated (agent, stream, component, rcand); @@ -1939,7 +1958,7 @@ * @return non-zero on error, zero on success */ static int priv_store_pending_check (NiceAgent *agent, Component *component, - const NiceAddress *from, NiceSocket *socket, uint8_t *username, + const NiceAddress *from, NiceSocket *sockptr, uint8_t *username, uint16_t username_len, uint32_t priority, gboolean use_candidate) { IncomingCheck *icheck; @@ -1955,7 +1974,7 @@ icheck = g_slice_new0 (IncomingCheck); component->incoming_checks = g_slist_append (component->incoming_checks, icheck); icheck->from = *from; - icheck->local_socket = socket; + icheck->local_socket = sockptr; icheck->priority = priority; icheck->use_candidate = use_candidate; icheck->username_len = username_len; @@ -2124,7 +2143,7 @@ if (memcmp (discovery_id, response_id, sizeof(StunTransactionId)) == 0) { res = stun_usage_ice_conncheck_process (resp, - &sockaddr.addr, &socklen, + &sockaddr.storage, &socklen, agent_to_ice_compatibility (agent)); nice_debug ("Agent %p : stun_bind_process/conncheck for %p res %d " "(controlling=%d).", agent, p, (int)res, agent->controlling_mode); @@ -2175,7 +2194,7 @@ " conncheck %p SUCCEEDED.", agent, p); priv_conn_check_unfreeze_related (agent, stream, p); } else { - ok_pair = priv_process_response_check_for_peer_reflexive(agent, + ok_pair = priv_process_response_check_for_peer_reflexive (agent, stream, component, p, sockptr, &sockaddr.addr, local_candidate, remote_candidate); } @@ -2318,10 +2337,9 @@ cand = g_slice_new0 (CandidateRefresh); agent->refresh_list = g_slist_append (agent->refresh_list, cand); + cand->candidate = relay_cand; cand->nicesock = cdisco->nicesock; - cand->relay_socket = relay_cand->sockptr; cand->server = cdisco->server; - cand->turn = cdisco->turn; cand->stream = cdisco->stream; cand->component = cdisco->component; cand->agent = cdisco->agent; @@ -2395,9 +2413,9 @@ if (memcmp (discovery_id, response_id, sizeof(StunTransactionId)) == 0) { res = stun_usage_turn_process (resp, - &relayaddr.addr, &relayaddrlen, - &sockaddr.addr, &socklen, - &alternate.addr, &alternatelen, + &relayaddr.storage, &relayaddrlen, + &sockaddr.storage, &socklen, + &alternate.storage, &alternatelen, &bandwidth, &lifetime, agent_to_turn_compatibility (agent)); nice_debug ("Agent %p : stun_turn_process/disc for %p res %d.", agent, d, (int)res); @@ -2684,8 +2702,11 @@ *password_len = strlen (pass); if (msn_msoc_nice_compatibility) { - data->password = g_base64_decode (pass, password_len); + gsize pass_len; + + data->password = g_base64_decode (pass, &pass_len); *password = data->password; + *password_len = pass_len; } } @@ -2710,7 +2731,7 @@ * @param agent self pointer * @param stream stream the packet is related to * @param component component the packet is related to - * @param socket socket from which the packet was received + * @param nicesock socket from which the packet was received * @param from address of the sender * @param buf message contents * @param buf message length @@ -2720,7 +2741,7 @@ * @return XXX (what FALSE means exactly?) */ gboolean conn_check_handle_inbound_stun (NiceAgent *agent, Stream *stream, - Component *component, NiceSocket *socket, const NiceAddress *from, + Component *component, NiceSocket *nicesock, const NiceAddress *from, gchar *buf, guint len) { union { @@ -2768,7 +2789,7 @@ for (i = agent->discovery_list; i; i = i->next) { CandidateDiscovery *d = i->data; if (d->stream == stream && d->component == component && - d->nicesock == socket) { + d->nicesock == nicesock) { valid = stun_agent_validate (&d->stun_agent, &req, (uint8_t *) buf, len, conncheck_stun_validater, &validater_data); @@ -2786,9 +2807,10 @@ for (i = agent->refresh_list; i; i = i->next) { CandidateRefresh *r = i->data; nice_debug ("Comparing %p to %p, %p to %p and %p and %p to %p", r->stream, - stream, r->component, component, r->nicesock, r->relay_socket, socket); + stream, r->component, component, r->nicesock, r->candidate->sockptr, + nicesock); if (r->stream == stream && r->component == component && - (r->nicesock == socket || r->relay_socket == socket)) { + (r->nicesock == nicesock || r->candidate->sockptr == nicesock)) { valid = stun_agent_validate (&r->stun_agent, &req, (uint8_t *) buf, len, conncheck_stun_validater, &validater_data); nice_debug ("Validating gave %d", valid); @@ -2819,7 +2841,7 @@ rbuf_len = stun_agent_build_unknown_attributes_error (&agent->stun_agent, &msg, rbuf, rbuf_len, &req); if (rbuf_len != 0) - nice_socket_send (socket, from, rbuf_len, (const gchar*)rbuf); + nice_socket_send (nicesock, from, rbuf_len, (const gchar*)rbuf); } return TRUE; } @@ -2832,7 +2854,7 @@ rbuf_len = stun_agent_finish_message (&agent->stun_agent, &msg, NULL, 0); if (rbuf_len > 0 && agent->compatibility != NICE_COMPATIBILITY_MSN && agent->compatibility != NICE_COMPATIBILITY_OC2007) - nice_socket_send (socket, from, rbuf_len, (const gchar*)rbuf); + nice_socket_send (nicesock, from, rbuf_len, (const gchar*)rbuf); } return TRUE; } @@ -2843,7 +2865,7 @@ rbuf_len = stun_agent_finish_message (&agent->stun_agent, &msg, NULL, 0); if (rbuf_len > 0 && agent->compatibility != NICE_COMPATIBILITY_MSN && agent->compatibility != NICE_COMPATIBILITY_OC2007) - nice_socket_send (socket, from, rbuf_len, (const gchar*)rbuf); + nice_socket_send (nicesock, from, rbuf_len, (const gchar*)rbuf); } return TRUE; } @@ -2926,6 +2948,8 @@ if ( agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007) { if (local_candidate && remote_candidate2) { + gsize key_len; + if (agent->compatibility == NICE_COMPATIBILITY_MSN) { username = (uint8_t *) stun_message_find (&req, STUN_ATTRIBUTE_USERNAME, &username_len); @@ -2935,10 +2959,12 @@ memcpy (username, uname, MIN (uname_len, username_len)); req.key = g_base64_decode ((gchar *) remote_candidate2->password, - &req.key_len); + &key_len); + req.key_len = key_len; } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007) { req.key = g_base64_decode ((gchar *) local_candidate->password, - &req.key_len); + &key_len); + req.key_len = key_len; } } else { nice_debug ("Agent %p : received MSN incoming check from unknown remote candidate. " @@ -2949,7 +2975,7 @@ rbuf_len = sizeof (rbuf); res = stun_usage_ice_conncheck_create_reply (&agent->stun_agent, &req, - &msg, rbuf, &rbuf_len, &sockaddr.addr, sizeof (sockaddr), + &msg, rbuf, &rbuf_len, &sockaddr.storage, sizeof (sockaddr), &control, agent->tie_breaker, agent_to_ice_compatibility (agent)); @@ -2981,7 +3007,7 @@ nice_debug ("Agent %p : No matching remote candidate for incoming check ->" "peer-reflexive candidate.", agent); remote_candidate = discovery_learn_remote_peer_reflexive_candidate ( - agent, stream, component, priority, from, socket, + agent, stream, component, priority, from, nicesock, local_candidate, remote_candidate2 ? remote_candidate2 : remote_candidate); if(remote_candidate) @@ -2989,7 +3015,7 @@ } priv_reply_to_conn_check (agent, stream, component, remote_candidate, - from, socket, rbuf_len, rbuf, use_candidate); + from, nicesock, rbuf_len, rbuf, use_candidate); if (component->remote_candidates == NULL) { /* case: We've got a valid binding request to a local candidate @@ -2999,7 +3025,7 @@ * we get information about the remote candidates */ /* step: send a reply immediately but postpone other processing */ - priv_store_pending_check (agent, component, from, socket, + priv_store_pending_check (agent, component, from, nicesock, username, username_len, priority, use_candidate); } } else { @@ -3016,7 +3042,7 @@ /* step: let's try to match the response to an existing check context */ if (trans_found != TRUE) trans_found = priv_map_reply_to_conn_check_request (agent, stream, - component, socket, from, local_candidate, remote_candidate, &req); + component, nicesock, from, local_candidate, remote_candidate, &req); /* step: let's try to match the response to an existing discovery */ if (trans_found != TRUE) diff -Nru libnice-0.1.5/agent/conncheck.h libnice-0.1.7/agent/conncheck.h --- libnice-0.1.5/agent/conncheck.h 2014-01-06 23:05:13.000000000 +0000 +++ libnice-0.1.7/agent/conncheck.h 2014-04-25 01:09:45.000000000 +0000 @@ -83,11 +83,10 @@ int conn_check_add_for_candidate (NiceAgent *agent, guint stream_id, Component *component, NiceCandidate *remote); int conn_check_add_for_local_candidate (NiceAgent *agent, guint stream_id, Component *component, NiceCandidate *local); -void conn_check_free_item (gpointer data, gpointer user_data); void conn_check_free (NiceAgent *agent); gboolean conn_check_schedule_next (NiceAgent *agent); int conn_check_send (NiceAgent *agent, CandidateCheckPair *pair); -gboolean conn_check_prune_stream (NiceAgent *agent, Stream *stream); +void conn_check_prune_stream (NiceAgent *agent, Stream *stream); gboolean conn_check_handle_inbound_stun (NiceAgent *agent, Stream *stream, Component *component, NiceSocket *udp_socket, const NiceAddress *from, gchar *buf, guint len); gint conn_check_compare (const CandidateCheckPair *a, const CandidateCheckPair *b); void conn_check_remote_candidates_set(NiceAgent *agent); diff -Nru libnice-0.1.5/agent/discovery.c libnice-0.1.7/agent/discovery.c --- libnice-0.1.5/agent/discovery.c 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/agent/discovery.c 2014-04-25 01:09:45.000000000 +0000 @@ -55,7 +55,6 @@ #include "agent.h" #include "agent-priv.h" -#include "agent-signals-marshal.h" #include "component.h" #include "discovery.h" #include "stun/usages/bind.h" @@ -71,14 +70,13 @@ /* * Frees the CandidateDiscovery structure pointed to - * by 'user data'. Compatible with g_slist_foreach(). + * by 'user data'. Compatible with g_slist_free_full(). */ -void discovery_free_item (gpointer data, gpointer user_data) +static void discovery_free_item (CandidateDiscovery *cand) { - CandidateDiscovery *cand = data; - g_assert (user_data == NULL); - g_free (cand->msn_turn_username); - g_free (cand->msn_turn_password); + if (cand->turn) + turn_server_unref (cand->turn); + g_slice_free (CandidateDiscovery, cand); } @@ -87,9 +85,8 @@ */ void discovery_free (NiceAgent *agent) { - - g_slist_foreach (agent->discovery_list, discovery_free_item, NULL); - g_slist_free (agent->discovery_list); + g_slist_free_full (agent->discovery_list, + (GDestroyNotify) discovery_free_item); agent->discovery_list = NULL; agent->discovery_unsched_items = 0; @@ -116,7 +113,7 @@ if (cand->stream->id == stream_id) { agent->discovery_list = g_slist_remove (agent->discovery_list, cand); - discovery_free_item (cand, NULL); + discovery_free_item (cand); } i = next; } @@ -130,21 +127,18 @@ /* * Frees the CandidateDiscovery structure pointed to - * by 'user data'. Compatible with g_slist_foreach(). + * by 'user data'. Compatible with g_slist_free_full(). */ -void refresh_free_item (gpointer data, gpointer user_data) +static void refresh_free_item (CandidateRefresh *cand) { - CandidateRefresh *cand = data; NiceAgent *agent = cand->agent; uint8_t *username; - size_t username_len; + gsize username_len; uint8_t *password; - size_t password_len; + gsize password_len; size_t buffer_len = 0; StunUsageTurnCompatibility turn_compat = agent_to_turn_compatibility (agent); - g_assert (user_data == NULL); - if (cand->timer_source != NULL) { g_source_destroy (cand->timer_source); g_source_unref (cand->timer_source); @@ -156,10 +150,10 @@ cand->tick_source = NULL; } - username = (uint8_t *)cand->turn->username; - username_len = (size_t) strlen (cand->turn->username); - password = (uint8_t *)cand->turn->password; - password_len = (size_t) strlen (cand->turn->password); + username = (uint8_t *)cand->candidate->turn->username; + username_len = (size_t) strlen (cand->candidate->turn->username); + password = (uint8_t *)cand->candidate->turn->password; + password_len = (size_t) strlen (cand->candidate->turn->password); if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN || turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) { @@ -206,14 +200,13 @@ */ void refresh_free (NiceAgent *agent) { - g_slist_foreach (agent->refresh_list, refresh_free_item, NULL); - g_slist_free (agent->refresh_list); + g_slist_free_full (agent->refresh_list, (GDestroyNotify) refresh_free_item); agent->refresh_list = NULL; } /* * Prunes the list of discovery processes for items related - * to stream 'stream_id'. + * to stream 'stream_id'. * * @return TRUE on success, FALSE on a fatal error */ @@ -225,9 +218,12 @@ CandidateRefresh *cand = i->data; GSList *next = i->next; + /* Don't free the candidate refresh to the currently selected local candidate + * unless the whole pair is being destroyed. + */ if (cand->stream->id == stream_id) { - agent->refresh_list = g_slist_remove (agent->refresh_list, cand); - refresh_free_item (cand, NULL); + agent->refresh_list = g_slist_delete_link (agent->refresh_list, i); + refresh_free_item (cand); } i = next; @@ -235,13 +231,31 @@ } +void refresh_prune_candidate (NiceAgent *agent, NiceCandidate *candidate) +{ + GSList *i; + + for (i = agent->refresh_list; i;) { + GSList *next = i->next; + CandidateRefresh *refresh = i->data; + + if (refresh->candidate == candidate) { + agent->refresh_list = g_slist_delete_link (agent->refresh_list, i); + refresh_free_item (refresh); + } + + i = next; + } +} + void refresh_cancel (CandidateRefresh *refresh) { refresh->agent->refresh_list = g_slist_remove (refresh->agent->refresh_list, refresh); - refresh_free_item (refresh, NULL); + refresh_free_item (refresh); } + /* * Adds a new local candidate. Implements the candidate pruning * defined in ICE spec section 4.1.3 "Eliminating Redundant @@ -594,7 +608,7 @@ candidate->stream_id = stream_id; candidate->component_id = component_id; candidate->addr = *address; - candidate->turn = turn; + candidate->turn = turn_server_ref (turn); /* step: link to the base candidate+socket */ relay_socket = nice_turn_socket_new (agent->main_context, address, @@ -866,9 +880,9 @@ &cand->stun_message, cand->stun_buffer, sizeof(cand->stun_buffer)); } else if (cand->type == NICE_CANDIDATE_TYPE_RELAYED) { uint8_t *username = (uint8_t *)cand->turn->username; - size_t username_len = (size_t) strlen (cand->turn->username); + gsize username_len = strlen (cand->turn->username); uint8_t *password = (uint8_t *)cand->turn->password; - size_t password_len = (size_t) strlen (cand->turn->password); + gsize password_len = strlen (cand->turn->password); StunUsageTurnCompatibility turn_compat = agent_to_turn_compatibility (agent); @@ -889,10 +903,8 @@ if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN || turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) { - g_free (cand->msn_turn_username); - g_free (cand->msn_turn_password); - cand->msn_turn_username = username; - cand->msn_turn_password = password; + g_free (username); + g_free (password); } } diff -Nru libnice-0.1.5/agent/discovery.h libnice-0.1.7/agent/discovery.h --- libnice-0.1.5/agent/discovery.h 2012-09-12 18:33:35.000000000 +0000 +++ libnice-0.1.7/agent/discovery.h 2014-04-25 01:09:45.000000000 +0000 @@ -57,8 +57,6 @@ Component *component; TurnServer *turn; StunAgent stun_agent; - uint8_t *msn_turn_username; - uint8_t *msn_turn_password; StunTimer timer; uint8_t stun_buffer[STUN_MAX_MESSAGE_SIZE]; StunMessage stun_message; @@ -70,16 +68,13 @@ { NiceAgent *agent; /**< back pointer to owner */ NiceSocket *nicesock; /**< existing socket to use */ - NiceSocket *relay_socket; /**< relay socket from which we receive */ NiceAddress server; /**< STUN/TURN server address */ + NiceCandidate *candidate; /**< candidate to refresh */ Stream *stream; Component *component; - TurnServer *turn; StunAgent stun_agent; GSource *timer_source; GSource *tick_source; - uint8_t *msn_turn_username; - uint8_t *msn_turn_password; StunTimer timer; uint8_t stun_buffer[STUN_MAX_MESSAGE_SIZE]; StunMessage stun_message; @@ -87,13 +82,12 @@ StunMessage stun_resp_msg; } CandidateRefresh; -void refresh_free_item (gpointer data, gpointer user_data); void refresh_free (NiceAgent *agent); void refresh_prune_stream (NiceAgent *agent, guint stream_id); +void refresh_prune_candidate (NiceAgent *agent, NiceCandidate *candidate); void refresh_cancel (CandidateRefresh *refresh); -void discovery_free_item (gpointer data, gpointer user_data); void discovery_free (NiceAgent *agent); void discovery_prune_stream (NiceAgent *agent, guint stream_id); void discovery_schedule (NiceAgent *agent); diff -Nru libnice-0.1.5/agent/inputstream.c libnice-0.1.7/agent/inputstream.c --- libnice-0.1.5/agent/inputstream.c 2014-03-07 02:14:00.000000000 +0000 +++ libnice-0.1.7/agent/inputstream.c 2014-03-31 23:18:17.000000000 +0000 @@ -360,9 +360,9 @@ /* Check whether any of the component’s FDs are pollable. */ for (i = component->socket_sources; i != NULL; i = i->next) { SocketSource *socket_source = i->data; - NiceSocket *socket = socket_source->socket; + NiceSocket *nicesock = socket_source->socket; - if (g_socket_condition_check (socket->fileno, G_IO_IN) != 0) { + if (g_socket_condition_check (nicesock->fileno, G_IO_IN) != 0) { retval = TRUE; break; } diff -Nru libnice-0.1.5/agent/Makefile.am libnice-0.1.7/agent/Makefile.am --- libnice-0.1.5/agent/Makefile.am 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/agent/Makefile.am 2014-03-31 23:27:40.000000000 +0000 @@ -22,23 +22,8 @@ AM_CFLAGS += -DWINVER=0x0501 # _WIN32_WINNT_WINXP endif -dist_noinst_DATA = agent-signals-marshal.list noinst_LTLIBRARIES = libagent.la -agent-signals-marshal.h: agent-signals-marshal.list - glib-genmarshal --header --prefix=agent_marshal $? > $@ - -agent-signals-marshal.c: agent-signals-marshal.list - echo '#include "agent-signals-marshal.h"' > $@ - glib-genmarshal --body --prefix=agent_marshal $? | \ - sed -e 's/^}$$/(void)return_value;(void)invocation_hint;}/' >> $@ - -BUILT_SOURCES = \ - agent-signals-marshal.h \ - agent-signals-marshal.c - -CLEANFILES += $(BUILT_SOURCES) - libagent_la_SOURCES = \ address.h \ address.c \ diff -Nru libnice-0.1.5/agent/Makefile.in libnice-0.1.7/agent/Makefile.in --- libnice-0.1.5/agent/Makefile.in 2014-03-07 02:21:09.000000000 +0000 +++ libnice-0.1.7/agent/Makefile.in 2014-05-05 18:58:19.000000000 +0000 @@ -23,7 +23,6 @@ # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. - VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ @@ -90,7 +89,7 @@ target_triplet = @target@ DIST_COMMON = $(top_srcdir)/common.mk $(srcdir)/Makefile.in \ $(srcdir)/Makefile.am $(top_srcdir)/depcomp \ - $(dist_noinst_DATA) $(pkginclude_HEADERS) + $(pkginclude_HEADERS) @WINDOWS_TRUE@am__append_1 = -DWINVER=0x0501 # _WIN32_WINNT_WINXP @WINDOWS_TRUE@am__append_2 = -liphlpapi -lws2_32 subdir = agent @@ -105,11 +104,9 @@ CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = -am__objects_1 = agent-signals-marshal.lo am_libagent_la_OBJECTS = address.lo debug.lo candidate.lo component.lo \ agent.lo stream.lo conncheck.lo discovery.lo interfaces.lo \ - pseudotcp.lo iostream.lo inputstream.lo outputstream.lo \ - $(am__objects_1) + pseudotcp.lo iostream.lo inputstream.lo outputstream.lo libagent_la_OBJECTS = $(am_libagent_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -156,7 +153,6 @@ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac -DATA = $(dist_noinst_DATA) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -349,17 +345,12 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -CLEANFILES = *.gcno *.gcda $(BUILT_SOURCES) +CLEANFILES = *.gcno *.gcda AM_CFLAGS = -DG_LOG_DOMAIN=\"libnice\" $(LIBNICE_CFLAGS) \ $(GLIB_CFLAGS) $(GUPNP_CFLAGS) -I $(top_srcdir) -I \ $(top_srcdir)/random -I $(top_srcdir)/socket -I \ $(top_srcdir)/stun $(am__append_1) -dist_noinst_DATA = agent-signals-marshal.list noinst_LTLIBRARIES = libagent.la -BUILT_SOURCES = \ - agent-signals-marshal.h \ - agent-signals-marshal.c - libagent_la_SOURCES = \ address.h \ address.c \ @@ -407,8 +398,7 @@ pseudotcp.h \ $(NULL) -all: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) all-am +all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj @@ -465,7 +455,6 @@ -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/address.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/agent-signals-marshal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/agent.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/candidate.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/component.Plo@am__quote@ @@ -610,15 +599,13 @@ fi; \ done check-am: all-am -check: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) check-am -all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pkgincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done -install: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) install-am +install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am @@ -649,7 +636,6 @@ maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ @@ -721,7 +707,7 @@ uninstall-am: uninstall-pkgincludeHEADERS -.MAKE: all check install install-am install-strip +.MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ @@ -744,14 +730,6 @@ .PHONY: check-valgrind -agent-signals-marshal.h: agent-signals-marshal.list - glib-genmarshal --header --prefix=agent_marshal $? > $@ - -agent-signals-marshal.c: agent-signals-marshal.list - echo '#include "agent-signals-marshal.h"' > $@ - glib-genmarshal --body --prefix=agent_marshal $? | \ - sed -e 's/^}$$/(void)return_value;(void)invocation_hint;}/' >> $@ - # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff -Nru libnice-0.1.5/agent/outputstream.c libnice-0.1.7/agent/outputstream.c --- libnice-0.1.5/agent/outputstream.c 2014-03-07 02:14:00.000000000 +0000 +++ libnice-0.1.7/agent/outputstream.c 2014-04-16 03:09:44.000000000 +0000 @@ -314,6 +314,13 @@ gboolean cancelled; } WriteData; +static WriteData * +write_data_ref (WriteData *write_data) +{ + g_atomic_int_inc (&write_data->ref_count); + return write_data; +} + static void write_data_unref (WriteData *write_data) { @@ -384,26 +391,25 @@ * GCond solution; would be much better for nice_agent_send() to block * properly in the main loop. */ write_data = g_slice_new0 (WriteData); - g_atomic_int_set (&write_data->ref_count, 4); - + write_data->ref_count = 1; g_mutex_init (&write_data->mutex); g_cond_init (&write_data->cond); if (cancellable != NULL) { cancel_id = g_cancellable_connect (cancellable, - (GCallback) write_cancelled_cb, write_data, + (GCallback) write_cancelled_cb, write_data_ref (write_data), (GDestroyNotify) write_data_unref); } closed_cancel_id = g_cancellable_connect (self->priv->closed_cancellable, - (GCallback) write_cancelled_cb, write_data, + (GCallback) write_cancelled_cb, write_data_ref (write_data), (GDestroyNotify) write_data_unref); g_mutex_lock (&write_data->mutex); writeable_id = g_signal_connect_data (G_OBJECT (agent), "reliable-transport-writable", - (GCallback) reliable_transport_writeable_cb, write_data, + (GCallback) reliable_transport_writeable_cb, write_data_ref (write_data), (GClosureNotify) write_data_unref, 0); @@ -495,9 +501,9 @@ /* Check whether any of the component’s FDs are pollable. */ for (i = component->socket_sources; i != NULL; i = i->next) { SocketSource *socket_source = i->data; - NiceSocket *socket = socket_source->socket; + NiceSocket *nicesock = socket_source->socket; - if (g_socket_condition_check (socket->fileno, G_IO_OUT) != 0) { + if (g_socket_condition_check (nicesock->fileno, G_IO_OUT) != 0) { retval = TRUE; break; } diff -Nru libnice-0.1.5/agent/pseudotcp.c libnice-0.1.7/agent/pseudotcp.c --- libnice-0.1.5/agent/pseudotcp.c 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/agent/pseudotcp.c 2014-04-17 22:14:51.000000000 +0000 @@ -908,6 +908,12 @@ { gboolean retval; + g_assert_cmpuint (message->n_buffers, >, 0); + + if (message->n_buffers == 1) + return pseudo_tcp_socket_notify_packet (self, message->buffers[0].buffer, + message->buffers[0].size); + g_assert_cmpuint (message->n_buffers, ==, 2); g_assert_cmpuint (message->buffers[0].size, ==, HEADER_SIZE); @@ -930,7 +936,7 @@ } gboolean -pseudo_tcp_socket_get_next_clock(PseudoTcpSocket *self, long *timeout) +pseudo_tcp_socket_get_next_clock(PseudoTcpSocket *self, guint64 *timeout) { PseudoTcpSocketPrivate *priv = self->priv; guint32 now = get_current_time (); @@ -974,7 +980,7 @@ pseudo_tcp_socket_recv(PseudoTcpSocket *self, char * buffer, size_t len) { PseudoTcpSocketPrivate *priv = self->priv; - gsize read; + gsize bytesread; gsize available_space; if (priv->state != TCP_ESTABLISHED) { @@ -985,10 +991,10 @@ if (len == 0) return 0; - read = pseudo_tcp_fifo_read (&priv->rbuf, (guint8 *) buffer, len); + bytesread = pseudo_tcp_fifo_read (&priv->rbuf, (guint8 *) buffer, len); // If there's no data in |m_rbuf|. - if (read == 0) { + if (bytesread == 0) { priv->bReadEnable = TRUE; priv->error = EWOULDBLOCK; return -1; @@ -1008,7 +1014,7 @@ } } - return read; + return bytesread; } gint @@ -1296,7 +1302,8 @@ DEBUG (PSEUDO_TCP_DEBUG_VERBOSE, "rtt: %ld srtt: %d rto: %d", rtt, priv->rx_srtt, priv->rx_rto); } else { - g_assert_not_reached (); + DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Invalid RTT: %ld", rtt); + return FALSE; } } @@ -1317,6 +1324,7 @@ if (nFree < data->len) { data->len -= nFree; + data->seq += nFree; nFree = 0; } else { if (data->len > priv->largest) { @@ -1540,7 +1548,13 @@ while (TRUE) { guint32 seq = segment->seq; guint8 flags = (segment->bCtrl ? FLAG_CTL : 0); - PseudoTcpWriteResult wres = packet(self, seq, flags, + PseudoTcpWriteResult wres; + + /* The packet must not have already been acknowledged. */ + g_assert_cmpuint (segment->seq, >=, priv->snd_una); + + /* Write out the packet. */ + wres = packet(self, seq, flags, segment->seq - priv->snd_una, nTransmit, now); if (wres == WR_SUCCESS) @@ -1776,6 +1790,9 @@ guint8 kind = TCP_OPT_EOL; guint8 opt_len; + if (len < pos + 1) + return; + kind = data[pos]; pos++; @@ -1787,11 +1804,16 @@ continue; } + if (len < pos + 1) + return; + // Length of this option. - g_assert(len); opt_len = data[pos]; pos++; + if (len < pos + opt_len) + return; + // Content of this option. if (opt_len <= len - pos) { apply_option (self, kind, data + pos, opt_len); @@ -1876,23 +1898,23 @@ gboolean pseudo_tcp_socket_can_send (PseudoTcpSocket *self) { - PseudoTcpSocketPrivate *priv = self->priv; - - if (priv->state != TCP_ESTABLISHED) { - return FALSE; - } - - return (pseudo_tcp_fifo_get_write_remaining (&priv->sbuf) != 0); + return (pseudo_tcp_socket_get_available_send_space (self) > 0); } gsize pseudo_tcp_socket_get_available_send_space (PseudoTcpSocket *self) { PseudoTcpSocketPrivate *priv = self->priv; + gsize ret; - if (priv->state != TCP_ESTABLISHED) { - return 0; - } - return pseudo_tcp_fifo_get_write_remaining (&priv->sbuf); + if (priv->state == TCP_ESTABLISHED) + ret = pseudo_tcp_fifo_get_write_remaining (&priv->sbuf); + else + ret = 0; + + if (ret == 0) + priv->bWriteEnable = TRUE; + + return ret; } diff -Nru libnice-0.1.5/agent/pseudotcp.h libnice-0.1.7/agent/pseudotcp.h --- libnice-0.1.5/agent/pseudotcp.h 2014-03-07 02:14:00.000000000 +0000 +++ libnice-0.1.7/agent/pseudotcp.h 2014-03-31 21:07:05.000000000 +0000 @@ -357,7 +357,8 @@ * * Since: 0.0.11 */ -gboolean pseudo_tcp_socket_get_next_clock(PseudoTcpSocket *self, long *timeout); +gboolean pseudo_tcp_socket_get_next_clock(PseudoTcpSocket *self, + guint64 *timeout); /** diff -Nru libnice-0.1.5/agent/stream.c libnice-0.1.7/agent/stream.c --- libnice-0.1.5/agent/stream.c 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/agent/stream.c 2014-04-25 01:09:45.000000000 +0000 @@ -132,22 +132,22 @@ * Resets the stream state to that of a ICE restarted * session. */ -gboolean -stream_restart (Stream *stream, NiceRNG *rng) +void +stream_restart (NiceAgent *agent, Stream *stream) { GSList *i; - gboolean res = TRUE; + + /* step: clean up all connectivity checks */ + conn_check_prune_stream (agent, stream); stream->initial_binding_request_received = FALSE; - stream_initialize_credentials (stream, rng); + stream_initialize_credentials (stream, agent->rng); - for (i = stream->components; i && res; i = i->next) { + for (i = stream->components; i; i = i->next) { Component *component = i->data; - - res = component_restart (component); + + component_restart (component); } - - return res; } diff -Nru libnice-0.1.5/agent/stream.h libnice-0.1.7/agent/stream.h --- libnice-0.1.5/agent/stream.h 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/agent/stream.h 2014-04-25 01:09:45.000000000 +0000 @@ -72,6 +72,7 @@ gchar remote_ufrag[NICE_STREAM_MAX_UFRAG]; gchar remote_password[NICE_STREAM_MAX_PWD]; gboolean gathering; + gboolean gathering_started; gint tos; }; @@ -91,8 +92,8 @@ void stream_initialize_credentials (Stream *stream, NiceRNG *rng); -gboolean -stream_restart (Stream *stream, NiceRNG *rng); +void +stream_restart (NiceAgent *agent, Stream *stream); G_END_DECLS diff -Nru libnice-0.1.5/config.h.in libnice-0.1.7/config.h.in --- libnice-0.1.5/config.h.in 2014-03-07 02:22:49.000000000 +0000 +++ libnice-0.1.7/config.h.in 2014-05-05 18:59:29.000000000 +0000 @@ -30,6 +30,12 @@ /* Define to 1 if you have the `poll' function. */ #undef HAVE_POLL +/* Define to 1 if the system has the type `size_t'. */ +#undef HAVE_SIZE_T + +/* Define to 1 if the system has the type `ssize_t'. */ +#undef HAVE_SSIZE_T + /* Define to 1 if stdbool.h conforms to C99. */ #undef HAVE_STDBOOL_H diff -Nru libnice-0.1.5/configure libnice-0.1.7/configure --- libnice-0.1.5/configure 2014-03-07 02:21:10.000000000 +0000 +++ libnice-0.1.7/configure 2014-05-05 18:58:21.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for libnice 0.1.5. +# Generated by GNU Autoconf 2.69 for libnice 0.1.7. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -587,8 +587,8 @@ # Identity of this package. PACKAGE_NAME='libnice' PACKAGE_TARNAME='libnice' -PACKAGE_VERSION='0.1.5' -PACKAGE_STRING='libnice 0.1.5' +PACKAGE_VERSION='0.1.7' +PACKAGE_STRING='libnice 0.1.7' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1374,7 +1374,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libnice 0.1.5 to adapt to many kinds of systems. +\`configure' configures libnice 0.1.7 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1445,7 +1445,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libnice 0.1.5:";; + short | recursive ) echo "Configuration of libnice 0.1.7:";; esac cat <<\_ACEOF @@ -1580,7 +1580,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libnice configure 0.1.5 +libnice configure 0.1.7 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1999,7 +1999,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libnice $as_me 0.1.5, which was +It was created by libnice $as_me 0.1.7, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2347,7 +2347,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -LIBNICE_RELEASE="no" +LIBNICE_RELEASE="yes" ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do @@ -2978,7 +2978,7 @@ # Define the identity of the package. PACKAGE='libnice' - VERSION='0.1.5' + VERSION='0.1.7' cat >>confdefs.h <<_ACEOF @@ -3040,9 +3040,9 @@ # Increment CURRENT and AGE. Set REVISION to 0 # If there was an incompatible interface change: # Increment CURRENT. Set AGE and REVISION to 0 -LIBNICE_CURRENT=13 -LIBNICE_REVISION=0 -LIBNICE_AGE=3 +LIBNICE_CURRENT=14 +LIBNICE_REVISION=1 +LIBNICE_AGE=4 LIBNICE_LIBVERSION=${LIBNICE_CURRENT}:${LIBNICE_REVISION}:${LIBNICE_AGE} LIBNICE_LT_LDFLAGS="-version-info ${LIBNICE_LIBVERSION} -no-undefined" @@ -12729,6 +12729,25 @@ done +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_SIZE_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default" +if test "x$ac_cv_type_ssize_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_SSIZE_T 1 +_ACEOF + + +fi + # Also put matching version in LIBNICE_CFLAGS GLIB_REQ=2.30 @@ -15748,7 +15767,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libnice $as_me 0.1.5, which was +This file was extended by libnice $as_me 0.1.7, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -15814,7 +15833,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -libnice config.status 0.1.5 +libnice config.status 0.1.7 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -Nru libnice-0.1.5/configure.ac libnice-0.1.7/configure.ac --- libnice-0.1.5/configure.ac 2014-03-07 02:19:57.000000000 +0000 +++ libnice-0.1.7/configure.ac 2014-05-05 18:57:58.000000000 +0000 @@ -5,8 +5,8 @@ dnl also use -Werror. git and pre-releases default to -Werror dnl use a three digit version number for releases, and four for cvs/prerelease -AC_INIT([libnice],[0.1.5]) -LIBNICE_RELEASE="no" +AC_INIT([libnice],[0.1.7]) +LIBNICE_RELEASE="yes" AC_CANONICAL_TARGET @@ -39,9 +39,9 @@ # Increment CURRENT and AGE. Set REVISION to 0 # If there was an incompatible interface change: # Increment CURRENT. Set AGE and REVISION to 0 -LIBNICE_CURRENT=13 -LIBNICE_REVISION=0 -LIBNICE_AGE=3 +LIBNICE_CURRENT=14 +LIBNICE_REVISION=1 +LIBNICE_AGE=4 LIBNICE_LIBVERSION=${LIBNICE_CURRENT}:${LIBNICE_REVISION}:${LIBNICE_AGE} LIBNICE_LT_LDFLAGS="-version-info ${LIBNICE_LIBVERSION} -no-undefined" AC_SUBST(LIBNICE_LT_LDFLAGS) @@ -92,6 +92,7 @@ AC_CHECK_HEADERS([ifaddrs.h], \ [AC_DEFINE(HAVE_GETIFADDRS, [1], \ [Whether getifaddrs() is available on the system])]) +AC_CHECK_TYPES([size_t, ssize_t]) # Also put matching version in LIBNICE_CFLAGS GLIB_REQ=2.30 diff -Nru libnice-0.1.5/debian/changelog libnice-0.1.7/debian/changelog --- libnice-0.1.5/debian/changelog 2014-05-15 18:22:15.000000000 +0000 +++ libnice-0.1.7/debian/changelog 2014-05-14 11:00:27.000000000 +0000 @@ -1,24 +1,16 @@ -libnice (0.1.5-1ubuntu3) utopic; urgency=medium +libnice (0.1.7-1) unstable; urgency=low - * Fixed FTBS in tests/test-pseudotcp.c + * New upstream release 0.1.6, 0.1.7 + - fixes various compiler warnings that were mistakenly fatal in 0.1.5 + (Closes: #743232, #743233) + - update symbols file for new API + * Explicitly disable -Werror, even if we package a non-release in future + * Don't run tests during the build. We were ignoring failures already, + and they sometimes hang until the buildd terminates them. + Upstream (Olivier Crête) says they are stable enough to be useful + for developers, but not for integration testing. - -- Tim Gardner Thu, 15 May 2014 12:21:00 -0600 - -libnice (0.1.5-1ubuntu2) utopic; urgency=medium - - * Drop -Wcast-align test as it causes FTBS in glib-2.0 headers. - armhf is affected, but there is kernel support for handling - unaligned accesses (with some small performance penalty). - https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=743233 - - -- Tim Gardner Tue, 13 May 2014 16:19:51 +0000 - -libnice (0.1.5-1ubuntu1) utopic; urgency=medium - - * Fix FTBS due to "error on sign compare warnings" - error: comparison between signed and unsigned integer expressions [-Werror=sign-compare] - - -- Tim Gardner Mon, 12 May 2014 18:17:46 +0000 + -- Simon McVittie Wed, 14 May 2014 12:00:13 +0100 libnice (0.1.5-1) unstable; urgency=low diff -Nru libnice-0.1.5/debian/control libnice-0.1.7/debian/control --- libnice-0.1.5/debian/control 2014-05-12 18:55:59.000000000 +0000 +++ libnice-0.1.7/debian/control 2014-05-14 11:00:27.000000000 +0000 @@ -1,8 +1,7 @@ Source: libnice Section: libs Priority: optional -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: Debian Telepathy maintainers +Maintainer: Debian Telepathy maintainers Uploaders: Dafydd Harries , Simon McVittie , Sjoerd Simons , diff -Nru libnice-0.1.5/debian/libnice10.symbols libnice-0.1.7/debian/libnice10.symbols --- libnice-0.1.5/debian/libnice10.symbols 2014-03-26 15:15:39.000000000 +0000 +++ libnice-0.1.7/debian/libnice10.symbols 2014-05-14 11:00:27.000000000 +0000 @@ -18,6 +18,7 @@ nice_agent_add_local_address@Base 0.1.0 nice_agent_add_stream@Base 0.1.0 nice_agent_attach_recv@Base 0.1.0 + nice_agent_forget_relays@Base 0.1.7 nice_agent_gather_candidates@Base 0.1.0 nice_agent_generate_local_candidate_sdp@Base 0.1.4 nice_agent_generate_local_sdp@Base 0.1.4 @@ -42,6 +43,7 @@ nice_agent_recv_nonblocking@Base 0.1.5 nice_agent_remove_stream@Base 0.1.0 nice_agent_restart@Base 0.1.0 + nice_agent_restart_stream@Base 0.1.7 nice_agent_send@Base 0.1.0 nice_agent_send_messages_nonblocking@Base 0.1.5 nice_agent_set_port_range@Base 0.1.4 @@ -56,6 +58,7 @@ nice_candidate_copy@Base 0.1.0 nice_candidate_free@Base 0.1.0 nice_candidate_new@Base 0.1.0 + nice_component_state_to_string@Base 0.1.7 nice_debug_disable@Base 0.1.0 nice_debug_enable@Base 0.1.0 nice_input_stream_new@Base 0.1.5 diff -Nru libnice-0.1.5/debian/patches/configure.patch libnice-0.1.7/debian/patches/configure.patch --- libnice-0.1.5/debian/patches/configure.patch 2014-05-13 16:29:40.000000000 +0000 +++ libnice-0.1.7/debian/patches/configure.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -Index: libnice-0.1.5/configure.ac -=================================================================== ---- libnice-0.1.5.orig/configure.ac 2014-05-13 16:17:43.868254848 +0000 -+++ libnice-0.1.5/configure.ac 2014-05-13 16:19:03.956254840 +0000 -@@ -133,7 +133,6 @@ - NICE_ADD_FLAG([-Wdeclaration-after-statement]) - NICE_ADD_FLAG([-Wformat=2]) - NICE_ADD_FLAG([-Wold-style-definition]) -- NICE_ADD_FLAG([-Wcast-align]) - NICE_ADD_FLAG([-Wformat-nonliteral]) - NICE_ADD_FLAG([-Wformat-security]) - ]) diff -Nru libnice-0.1.5/debian/patches/pseudotcp.diff libnice-0.1.7/debian/patches/pseudotcp.diff --- libnice-0.1.5/debian/patches/pseudotcp.diff 2014-05-12 18:55:59.000000000 +0000 +++ libnice-0.1.7/debian/patches/pseudotcp.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -Index: libnice-0.1.5/agent/pseudotcp.c -=================================================================== ---- libnice-0.1.5.orig/agent/pseudotcp.c 2014-05-12 18:13:39.455946605 +0000 -+++ libnice-0.1.5/agent/pseudotcp.c 2014-05-12 18:14:19.520747818 +0000 -@@ -946,24 +946,24 @@ - return FALSE; - } - -- if (*timeout == 0 || *timeout < now) -+ if (*timeout == 0 || *timeout < (long)now) - *timeout = now + CLOSED_TIMEOUT; - - if (priv->state == TCP_CLOSED) { -- *timeout = min (*timeout, now + CLOSED_TIMEOUT); -+ *timeout = min (*timeout, (long)now + CLOSED_TIMEOUT); - return TRUE; - } - -- *timeout = min (*timeout, now + DEFAULT_TIMEOUT); -+ *timeout = min (*timeout, (long)now + DEFAULT_TIMEOUT); - - if (priv->t_ack) { -- *timeout = min(*timeout, priv->t_ack + priv->ack_delay); -+ *timeout = min(*timeout, (long)(priv->t_ack + priv->ack_delay)); - } - if (priv->rto_base) { -- *timeout = min(*timeout, priv->rto_base + priv->rx_rto); -+ *timeout = min(*timeout, (long)(priv->rto_base + priv->rx_rto)); - } - if (priv->snd_wnd == 0) { -- *timeout = min(*timeout, priv->lastsend + priv->rx_rto); -+ *timeout = min(*timeout, (long)(priv->lastsend + priv->rx_rto)); - } - - return TRUE; diff -Nru libnice-0.1.5/debian/patches/pseudotcp.patch libnice-0.1.7/debian/patches/pseudotcp.patch --- libnice-0.1.5/debian/patches/pseudotcp.patch 2014-05-15 18:20:26.000000000 +0000 +++ libnice-0.1.7/debian/patches/pseudotcp.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -Index: libnice-0.1.5/tests/test-pseudotcp.c -=================================================================== ---- libnice-0.1.5.orig/tests/test-pseudotcp.c 2014-05-15 12:19:44.241149538 -0600 -+++ libnice-0.1.5/tests/test-pseudotcp.c 2014-05-15 12:20:17.373149086 -0600 -@@ -80,7 +80,7 @@ - total += wlen; - total_read += wlen; - if (wlen < (gint) len) { -- g_debug ("seeking %ld from %lu", wlen - len, ftell (in)); -+ g_debug ("seeking %ld from %lu", (long)wlen - len, ftell (in)); - fseek (in, wlen - len, SEEK_CUR); - g_assert (!feof (in)); - g_debug ("Socket queue full after %d bytes written", total); diff -Nru libnice-0.1.5/debian/patches/series libnice-0.1.7/debian/patches/series --- libnice-0.1.5/debian/patches/series 2014-05-15 18:20:06.000000000 +0000 +++ libnice-0.1.7/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -pseudotcp.diff -configure.patch -pseudotcp.patch diff -Nru libnice-0.1.5/debian/rules libnice-0.1.7/debian/rules --- libnice-0.1.5/debian/rules 2014-03-26 15:15:39.000000000 +0000 +++ libnice-0.1.7/debian/rules 2014-05-14 11:00:27.000000000 +0000 @@ -8,11 +8,13 @@ include /usr/share/cdbs/1/rules/utils.mk common-binary-post-install-arch:: list-missing -DEB_MAKE_CHECK_TARGET := check VERBOSE=1 G_MESSAGES_DEBUG=all || true - DEB_DBG_PACKAGE_libnice10 := libnice-dbg DEB_CONFIGURE_EXTRA_FLAGS := --libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) \ - --enable-gupnp --with-gstreamer-0.10 --with-gstreamer + --enable-compile-warnings=yes \ + --enable-gupnp \ + --with-gstreamer-0.10 \ + --with-gstreamer \ + $(NULL) include $(CURDIR)/debian/update-patches.mk diff -Nru libnice-0.1.5/docs/reference/libnice/html/annotation-glossary.html libnice-0.1.7/docs/reference/libnice/html/annotation-glossary.html --- libnice-0.1.5/docs/reference/libnice/html/annotation-glossary.html 2014-03-07 02:22:50.000000000 +0000 +++ libnice-0.1.7/docs/reference/libnice/html/annotation-glossary.html 2014-05-05 18:59:30.000000000 +0000 @@ -6,14 +6,14 @@ - + - + diff -Nru libnice-0.1.5/docs/reference/libnice/html/api-index-full.html libnice-0.1.7/docs/reference/libnice/html/api-index-full.html --- libnice-0.1.5/docs/reference/libnice/html/api-index-full.html 2014-03-07 02:22:50.000000000 +0000 +++ libnice-0.1.7/docs/reference/libnice/html/api-index-full.html 2014-05-05 18:59:30.000000000 +0000 @@ -591,6 +591,10 @@
+nice_agent_forget_relays, function in NiceAgent +
+
+
nice_agent_gather_candidates, function in NiceAgent
@@ -687,6 +691,10 @@
+nice_agent_restart_stream, function in NiceAgent +
+
+
nice_agent_send, function in NiceAgent
@@ -747,6 +755,10 @@
+nice_component_state_to_string, function in NiceAgent +
+
+
nice_debug_disable, function in Debug messages
diff -Nru libnice-0.1.5/docs/reference/libnice/html/index.html libnice-0.1.7/docs/reference/libnice/html/index.html --- libnice-0.1.5/docs/reference/libnice/html/index.html 2014-03-07 02:22:50.000000000 +0000 +++ libnice-0.1.7/docs/reference/libnice/html/index.html 2014-05-05 18:59:30.000000000 +0000 @@ -95,6 +95,7 @@
Index of new symbols in 0.0.11
Index of new symbols in 0.1.4
Index of new symbols in 0.1.5
+
Index of new symbols in 0.1.6
Annotation Glossary
diff -Nru libnice-0.1.5/docs/reference/libnice/html/index.sgml libnice-0.1.7/docs/reference/libnice/html/index.sgml --- libnice-0.1.5/docs/reference/libnice/html/index.sgml 2014-03-07 02:22:50.000000000 +0000 +++ libnice-0.1.7/docs/reference/libnice/html/index.sgml 2014-05-05 18:59:30.000000000 +0000 @@ -44,6 +44,7 @@ + @@ -63,6 +64,7 @@ + @@ -74,6 +76,7 @@ + diff -Nru libnice-0.1.5/docs/reference/libnice/html/ix10.html libnice-0.1.7/docs/reference/libnice/html/ix10.html --- libnice-0.1.5/docs/reference/libnice/html/ix10.html 2014-03-07 02:22:50.000000000 +0000 +++ libnice-0.1.7/docs/reference/libnice/html/ix10.html 2014-05-05 18:59:30.000000000 +0000 @@ -7,7 +7,7 @@ - + @@ -18,7 +18,7 @@ - + + + + + diff -Nru libnice-0.1.5/docs/reference/libnice/html/libnice-Pseudo-TCP-Socket.html libnice-0.1.7/docs/reference/libnice/html/libnice-Pseudo-TCP-Socket.html --- libnice-0.1.5/docs/reference/libnice/html/libnice-Pseudo-TCP-Socket.html 2014-03-07 02:22:50.000000000 +0000 +++ libnice-0.1.7/docs/reference/libnice/html/libnice-Pseudo-TCP-Socket.html 2014-05-05 18:59:30.000000000 +0000 @@ -66,7 +66,7 @@ gboolean force); intpseudo_tcp_socket_get_error (PseudoTcpSocket *self); gbooleanpseudo_tcp_socket_get_next_clock (PseudoTcpSocket *self, - long *timeout); + guint64 *timeout); voidpseudo_tcp_socket_notify_clock (PseudoTcpSocket *self); voidpseudo_tcp_socket_notify_mtu (PseudoTcpSocket *self, guint16 mtu); @@ -591,7 +591,7 @@

pseudo_tcp_socket_get_next_clock ()

gboolean            pseudo_tcp_socket_get_next_clock    (PseudoTcpSocket *self,
-                                                         long *timeout);
+ guint64 *timeout);

Call this to determine the timeout needed before the next time call to pseudo_tcp_socket_notify_clock() should be made. diff -Nru libnice-0.1.5/docs/reference/libnice/html/libnice-StunMessage.html libnice-0.1.7/docs/reference/libnice/html/libnice-StunMessage.html --- libnice-0.1.5/docs/reference/libnice/html/libnice-StunMessage.html 2014-03-07 02:22:50.000000000 +0000 +++ libnice-0.1.7/docs/reference/libnice/html/libnice-StunMessage.html 2014-05-05 18:59:30.000000000 +0000 @@ -75,15 +75,15 @@ size_t buflen); StunMessageReturn stun_message_find_addr (const StunMessage *msg, StunAttribute type, - struct sockaddr *addr, + struct sockaddr_storage *addr, socklen_t *addrlen); StunMessageReturn stun_message_find_xor_addr (const StunMessage *msg, StunAttribute type, - struct sockaddr *addr, + struct sockaddr_storage *addr, socklen_t *addrlen); StunMessageReturn stun_message_find_xor_addr_full (const StunMessage *msg, StunAttribute type, - struct sockaddr *addr, + struct sockaddr_storage *addr, socklen_t *addrlen, uint32_t magic_cookie); StunMessageReturn stun_message_find_error (const StunMessage *msg, @@ -112,11 +112,11 @@ socklen_t addrlen); StunMessageReturn stun_message_append_xor_addr (StunMessage *msg, StunAttribute type, - const struct sockaddr *addr, + const struct sockaddr_storage *addr, socklen_t addrlen); StunMessageReturn stun_message_append_xor_addr_full (StunMessage *msg, StunAttribute type, - const struct sockaddr *addr, + const struct sockaddr_storage *addr, socklen_t addrlen, uint32_t magic_cookie); StunMessageReturn stun_message_append_error (StunMessage *msg, @@ -1220,7 +1220,7 @@

stun_message_find_addr ()

StunMessageReturn   stun_message_find_addr              (const StunMessage *msg,
                                                          StunAttribute type,
-                                                         struct sockaddr *addr,
+                                                         struct sockaddr_storage *addr,
                                                          socklen_t *addrlen);

Extracts a network address attribute from a STUN message. @@ -1265,7 +1265,7 @@

stun_message_find_xor_addr ()

StunMessageReturn   stun_message_find_xor_addr          (const StunMessage *msg,
                                                          StunAttribute type,
-                                                         struct sockaddr *addr,
+                                                         struct sockaddr_storage *addr,
                                                          socklen_t *addrlen);

Extracts an obfuscated network address attribute from a STUN message. @@ -1310,7 +1310,7 @@

stun_message_find_xor_addr_full ()

StunMessageReturn   stun_message_find_xor_addr_full     (const StunMessage *msg,
                                                          StunAttribute type,
-                                                         struct sockaddr *addr,
+                                                         struct sockaddr_storage *addr,
                                                          socklen_t *addrlen,
                                                          uint32_t magic_cookie);

@@ -1645,7 +1645,7 @@

stun_message_append_xor_addr ()

StunMessageReturn   stun_message_append_xor_addr        (StunMessage *msg,
                                                          StunAttribute type,
-                                                         const struct sockaddr *addr,
+                                                         const struct sockaddr_storage *addr,
                                                          socklen_t addrlen);

Append an obfuscated network address attribute to a STUN message @@ -1687,7 +1687,7 @@

stun_message_append_xor_addr_full ()

StunMessageReturn   stun_message_append_xor_addr_full   (StunMessage *msg,
                                                          StunAttribute type,
-                                                         const struct sockaddr *addr,
+                                                         const struct sockaddr_storage *addr,
                                                          socklen_t addrlen,
                                                          uint32_t magic_cookie);

diff -Nru libnice-0.1.5/docs/reference/libnice/html/libnice-TURN.html libnice-0.1.7/docs/reference/libnice/html/libnice-TURN.html --- libnice-0.1.5/docs/reference/libnice/html/libnice-TURN.html 2014-03-07 02:22:50.000000000 +0000 +++ libnice-0.1.7/docs/reference/libnice/html/libnice-TURN.html 2014-05-05 18:59:30.000000000 +0000 @@ -72,11 +72,11 @@ size_t password_len, StunUsageTurnCompatibility compatibility); StunUsageTurnReturn stun_usage_turn_process (StunMessage *msg, - struct sockaddr *relay_addr, + struct sockaddr_storage *relay_addr, socklen_t *relay_addrlen, - struct sockaddr *addr, + struct sockaddr_storage *addr, socklen_t *addrlen, - struct sockaddr *alternate_server, + struct sockaddr_storage *alternate_server, socklen_t *alternate_server_len, uint32_t *bandwidth, uint32_t *lifetime, @@ -96,7 +96,7 @@ size_t realm_len, uint8_t *nonce, size_t nonce_len, - struct sockaddr *peer, + struct sockaddr_storage *peer, StunUsageTurnCompatibility compatibility);

@@ -448,11 +448,11 @@

stun_usage_turn_process ()

StunUsageTurnReturn stun_usage_turn_process             (StunMessage *msg,
-                                                         struct sockaddr *relay_addr,
+                                                         struct sockaddr_storage *relay_addr,
                                                          socklen_t *relay_addrlen,
-                                                         struct sockaddr *addr,
+                                                         struct sockaddr_storage *addr,
                                                          socklen_t *addrlen,
-                                                         struct sockaddr *alternate_server,
+                                                         struct sockaddr_storage *alternate_server,
                                                          socklen_t *alternate_server_len,
                                                          uint32_t *bandwidth,
                                                          uint32_t *lifetime,
@@ -581,7 +581,7 @@
                                                          size_t realm_len,
                                                          uint8_t *nonce,
                                                          size_t nonce_len,
-                                                         struct sockaddr *peer,
+                                                         struct sockaddr_storage *peer,
                                                          StunUsageTurnCompatibility compatibility);

diff -Nru libnice-0.1.5/docs/reference/libnice/html/NiceAgent.html libnice-0.1.7/docs/reference/libnice/html/NiceAgent.html --- libnice-0.1.5/docs/reference/libnice/html/NiceAgent.html 2014-03-07 02:22:50.000000000 +0000 +++ libnice-0.1.7/docs/reference/libnice/html/NiceAgent.html 2014-05-05 18:59:30.000000000 +0000 @@ -87,6 +87,9 @@ const gchar *username, const gchar *password, NiceRelayType type); +gboolean nice_agent_forget_relays (NiceAgent *agent, + guint stream_id, + guint component_id); gboolean nice_agent_gather_candidates (NiceAgent *agent, guint stream_id); gboolean nice_agent_set_remote_credentials (NiceAgent *agent, @@ -176,6 +179,8 @@ void nice_agent_set_software (NiceAgent *agent, const gchar *software); gboolean nice_agent_restart (NiceAgent *agent); +gboolean nice_agent_restart_stream (NiceAgent *agent, + guint stream_id); gboolean nice_agent_set_stream_name (NiceAgent *agent, guint stream_id, const gchar *name); @@ -210,6 +215,7 @@ GSocket * nice_agent_get_selected_socket (NiceAgent *agent, guint stream_id, guint component_id); +const gchar * nice_component_state_to_string (NiceComponentState state);
@@ -1061,6 +1067,45 @@

+

nice_agent_forget_relays ()

+
gboolean            nice_agent_forget_relays            (NiceAgent *agent,
+                                                         guint stream_id,
+                                                         guint component_id);
+

+Forget all the relay servers previously added using +nice_agent_set_relay_info(). Currently connected streams will keep +using the relay as long as they have not been restarted and haven't +succesfully negotiated a different path. +

+
++++ + + + + + + + + + + + + + + + + + + +

agent :

The NiceAgent Object

stream_id :

The ID of the stream

component_id :

The ID of the component

Returns :

+FALSE if the component could not be found, TRUE otherwise
+

Since 0.1.6

+ +
+

nice_agent_gather_candidates ()

gboolean            nice_agent_gather_candidates        (NiceAgent *agent,
                                                          guint stream_id);
@@ -2171,6 +2216,44 @@

+

nice_agent_restart_stream ()

+
gboolean            nice_agent_restart_stream           (NiceAgent *agent,
+                                                         guint stream_id);
+

+Restarts a single stream as defined in RFC 5245. This function +needs to be called both when initiating (ICE spec section 9.1.1.1. +"ICE Restarts"), as well as when reacting (spec section 9.2.1.1. +"Detecting ICE Restart") to a restart. +

+

+Unlike nice_agent_restart(), this applies to a single stream. It also +does not generate a new tie breaker. +

+
++++ + + + + + + + + + + + + + + +

agent :

The NiceAgent Object

stream_id :

The ID of the stream

Returns :

+TRUE on success FALSE on error
+

Since 0.1.6

+
+
+

nice_agent_set_stream_name ()

gboolean            nice_agent_set_stream_name          (NiceAgent *agent,
                                                          guint stream_id,
@@ -2744,6 +2827,34 @@
 

Since 0.1.5

+
+
+

nice_component_state_to_string ()

+
const gchar *       nice_component_state_to_string      (NiceComponentState state);
+

+Returns a string representation of the state, generally to use in debug +messages. +

+
++++ + + + + + + + + + + +

state :

a NiceComponentState +

Returns :

a string representation of state. [transfer none] +
+

Since 0.1.6

+

Property Details

@@ -2892,8 +3003,8 @@

The "upnp-timeout" property

  "upnp-timeout"             guint                 : Read / Write / Construct

-The maximum amount of time to wait for UPnP discovery to finish before -signaling the "candidate-gathering-done" signal +The maximum amount of time (in milliseconds) to wait for UPnP discovery to +finish before signaling the "candidate-gathering-done" signal

Allowed values: [100,60000]

Default value: 200

@@ -3012,7 +3123,7 @@ gchar *foundation, gpointer user_data) : Run Last

-This signal is fired when the agent discovers a new candidate +This signal is fired when the agent discovers a new local candidate.

See also: "candidate-gathering-done"

@@ -3176,9 +3287,9 @@


The "streams-removed" signal

-
void                user_function                      (NiceAgent *agent,
-                                                        gpointer   stream_ids,
-                                                        gpointer   user_data)       : Run Last
+
void                user_function                      (NiceAgent           *agent,
+                                                        _NiceAgentStreamIds *stream_ids,
+                                                        gpointer             user_data)       : Run Last

This signal is fired whenever one or more streams are removed from the agent. diff -Nru libnice-0.1.5/docs/reference/libnice/html/pt04.html libnice-0.1.7/docs/reference/libnice/html/pt04.html --- libnice-0.1.5/docs/reference/libnice/html/pt04.html 2014-03-07 02:22:50.000000000 +0000 +++ libnice-0.1.7/docs/reference/libnice/html/pt04.html 2014-05-05 18:59:30.000000000 +0000 @@ -35,6 +35,7 @@

Index of new symbols in 0.0.11
Index of new symbols in 0.1.4
Index of new symbols in 0.1.5
+
Index of new symbols in 0.1.6
Annotation Glossary
diff -Nru libnice-0.1.5/docs/reference/libnice/libnice-docs.sgml libnice-0.1.7/docs/reference/libnice/libnice-docs.sgml --- libnice-0.1.5/docs/reference/libnice/libnice-docs.sgml 2014-03-07 02:14:00.000000000 +0000 +++ libnice-0.1.7/docs/reference/libnice/libnice-docs.sgml 2014-04-29 01:09:49.000000000 +0000 @@ -93,6 +93,10 @@ Index of new symbols in 0.1.5 + + Index of new symbols in 0.1.6 + + diff -Nru libnice-0.1.5/docs/reference/libnice/libnice-sections.txt libnice-0.1.7/docs/reference/libnice/libnice-sections.txt --- libnice-0.1.5/docs/reference/libnice/libnice-sections.txt 2014-03-07 02:22:50.000000000 +0000 +++ libnice-0.1.7/docs/reference/libnice/libnice-sections.txt 2014-05-05 18:59:30.000000000 +0000 @@ -17,6 +17,7 @@ nice_agent_add_stream nice_agent_remove_stream nice_agent_set_relay_info +nice_agent_forget_relays nice_agent_gather_candidates nice_agent_set_remote_credentials nice_agent_get_local_credentials @@ -36,6 +37,7 @@ nice_agent_set_stream_tos nice_agent_set_software nice_agent_restart +nice_agent_restart_stream nice_agent_set_stream_name nice_agent_get_stream_name nice_agent_get_default_local_candidate @@ -47,6 +49,7 @@ nice_agent_parse_remote_candidate_sdp nice_agent_get_io_stream nice_agent_get_selected_socket +nice_component_state_to_string NICE_AGENT NICE_IS_AGENT diff -Nru libnice-0.1.5/docs/reference/libnice/Makefile.am libnice-0.1.7/docs/reference/libnice/Makefile.am --- libnice-0.1.5/docs/reference/libnice/Makefile.am 2014-03-07 02:14:00.000000000 +0000 +++ libnice-0.1.7/docs/reference/libnice/Makefile.am 2014-04-04 03:52:17.000000000 +0000 @@ -55,7 +55,7 @@ # Header files to ignore when scanning. # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h IGNORE_HFILES= conncheck.h discovery.h stream.h component.h agent-priv.h \ - agent-signals-marshal.h iostream.h inputstream.h outputstream.h \ + iostream.h inputstream.h outputstream.h \ gstnice.h gstnicesrc.h gstnicesink.h \ md5.h sha1.h stunhmac.h utils.h rand.h stun5389.h stuncrc32.h diff -Nru libnice-0.1.5/docs/reference/libnice/Makefile.in libnice-0.1.7/docs/reference/libnice/Makefile.in --- libnice-0.1.5/docs/reference/libnice/Makefile.in 2014-03-07 02:21:09.000000000 +0000 +++ libnice-0.1.7/docs/reference/libnice/Makefile.in 2014-05-05 18:58:19.000000000 +0000 @@ -316,7 +316,7 @@ # Header files to ignore when scanning. # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h IGNORE_HFILES = conncheck.h discovery.h stream.h component.h agent-priv.h \ - agent-signals-marshal.h iostream.h inputstream.h outputstream.h \ + iostream.h inputstream.h outputstream.h \ gstnice.h gstnicesrc.h gstnicesink.h \ md5.h sha1.h stunhmac.h utils.h rand.h stun5389.h stuncrc32.h diff -Nru libnice-0.1.5/docs/reference/libnice/tmpl/agent.sgml libnice-0.1.7/docs/reference/libnice/tmpl/agent.sgml --- libnice-0.1.5/docs/reference/libnice/tmpl/agent.sgml 2014-03-07 02:22:50.000000000 +0000 +++ libnice-0.1.7/docs/reference/libnice/tmpl/agent.sgml 2014-05-05 18:59:30.000000000 +0000 @@ -340,6 +340,17 @@ @Returns: + + + + + +@agent: +@stream_id: +@component_id: +@Returns: + + @@ -576,6 +587,16 @@ @Returns: + + + + + +@agent: +@stream_id: +@Returns: + + @@ -694,3 +715,12 @@ @Returns: + + + + + +@state: +@Returns: + + diff -Nru libnice-0.1.5/docs/reference/libnice/tmpl/candidate.sgml libnice-0.1.7/docs/reference/libnice/tmpl/candidate.sgml --- libnice-0.1.5/docs/reference/libnice/tmpl/candidate.sgml 2014-03-07 02:22:50.000000000 +0000 +++ libnice-0.1.7/docs/reference/libnice/tmpl/candidate.sgml 2014-05-05 18:59:30.000000000 +0000 @@ -60,6 +60,7 @@ +@ref_count: @server: @username: @password: diff -Nru libnice-0.1.5/examples/simple-example.c libnice-0.1.7/examples/simple-example.c --- libnice-0.1.5/examples/simple-example.c 2014-01-06 23:05:13.000000000 +0000 +++ libnice-0.1.7/examples/simple-example.c 2014-04-25 01:46:20.000000000 +0000 @@ -77,7 +77,7 @@ { NiceAgent *agent; gchar *stun_addr = NULL; - guint stun_port; + guint stun_port = 0; gboolean controlling; // Parse arguments @@ -308,6 +308,7 @@ cand->stream_id = _stream_id; cand->transport = NICE_CANDIDATE_TRANSPORT_UDP; strncpy(cand->foundation, tokens[0], NICE_CANDIDATE_MAX_FOUNDATION); + cand->foundation[NICE_CANDIDATE_MAX_FOUNDATION - 1] = 0; cand->priority = atoi (tokens[1]); if (!nice_address_set_from_string(&cand->addr, tokens[2])) { diff -Nru libnice-0.1.5/examples/threaded-example.c libnice-0.1.7/examples/threaded-example.c --- libnice-0.1.5/examples/threaded-example.c 2014-01-06 23:05:13.000000000 +0000 +++ libnice-0.1.7/examples/threaded-example.c 2014-04-29 03:10:30.000000000 +0000 @@ -331,6 +331,7 @@ cand->stream_id = stream_id; cand->transport = NICE_CANDIDATE_TRANSPORT_UDP; strncpy(cand->foundation, tokens[0], NICE_CANDIDATE_MAX_FOUNDATION); + cand->foundation[NICE_CANDIDATE_MAX_FOUNDATION - 1] = 0; cand->priority = atoi (tokens[1]); if (!nice_address_set_from_string(&cand->addr, tokens[2])) { diff -Nru libnice-0.1.5/NEWS libnice-0.1.7/NEWS --- libnice-0.1.5/NEWS 2014-03-07 02:18:47.000000000 +0000 +++ libnice-0.1.7/NEWS 2014-05-05 18:57:37.000000000 +0000 @@ -1,6 +1,20 @@ -libnice 0.1.5 (2014-03-06) +libnice 0.1.7 (2014-05-05) ========================== +Fix undesired API change that broke Farstream unit testsx +libnice 0.1.6 (2014-04-28) +========================== +API: nice_agent_restart_stream() to do a ICE restart on a single strema +API: nice_component_state_to_string() to get a printable name for a component + state +API: nice_agent_forget_relays() to forget the relays set for a + specific component, along with nice_agent_restart_stream(), it allows + changing the current relay without dropping the connection. +It is now possible to add relays after the initial candidate gathering. +Many bug fixes + +libnice 0.1.5 (2014-03-06) +========================== API: nice_agent_recv() and nice_agent_recv_nonblocking() as an alternative to the nice_agent_attach_recv() @@ -13,7 +27,6 @@ Improve performance Build fixes - libnice 0.1.4 (2013-02-22) ========================== @@ -33,7 +46,6 @@ Add support for GStreamer 1.0, will compile plugins for both 1.0 and 0.10 by default Cache GSocketAddress in UdpBsdSocket, creating it is very slow - libnice 0.1.2 (2012-04-03) ========================== diff -Nru libnice-0.1.5/nice/libnice.sym libnice-0.1.7/nice/libnice.sym --- libnice-0.1.5/nice/libnice.sym 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/nice/libnice.sym 2014-04-25 01:09:45.000000000 +0000 @@ -21,6 +21,7 @@ nice_agent_recv_nonblocking nice_agent_recv_messages_nonblocking nice_agent_attach_recv +nice_agent_forget_relays nice_agent_gather_candidates nice_agent_generate_local_candidate_sdp nice_agent_generate_local_sdp @@ -41,6 +42,7 @@ nice_agent_parse_remote_stream_sdp nice_agent_remove_stream nice_agent_restart +nice_agent_restart_stream nice_agent_send nice_agent_send_messages_nonblocking nice_agent_set_port_range @@ -55,6 +57,7 @@ nice_candidate_copy nice_candidate_free nice_candidate_new +nice_component_state_to_string nice_debug_disable nice_debug_enable nice_interfaces_get_ip_for_interface diff -Nru libnice-0.1.5/socket/tcp-bsd.c libnice-0.1.7/socket/tcp-bsd.c --- libnice-0.1.5/socket/tcp-bsd.c 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/socket/tcp-bsd.c 2014-04-09 03:14:47.000000000 +0000 @@ -106,23 +106,21 @@ nice_address_copy_to_sockaddr (addr, &name.addr); - if (gsock == NULL) { - if (name.storage.ss_family == AF_UNSPEC || name.storage.ss_family == AF_INET) { - gsock = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, - G_SOCKET_PROTOCOL_TCP, NULL); + if (name.storage.ss_family == AF_UNSPEC || name.storage.ss_family == AF_INET) { + gsock = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP, NULL); - name.storage.ss_family = AF_INET; + name.storage.ss_family = AF_INET; #ifdef HAVE_SA_LEN - name.storage.ss_len = sizeof (struct sockaddr_in); + name.storage.ss_len = sizeof (struct sockaddr_in); #endif - } else if (name.storage.ss_family == AF_INET6) { - gsock = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM, - G_SOCKET_PROTOCOL_TCP, NULL); - name.storage.ss_family = AF_INET6; + } else if (name.storage.ss_family == AF_INET6) { + gsock = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP, NULL); + name.storage.ss_family = AF_INET6; #ifdef HAVE_SA_LEN - name.storage.ss_len = sizeof (struct sockaddr_in6); + name.storage.ss_len = sizeof (struct sockaddr_in6); #endif - } } if (gsock == NULL) { @@ -130,24 +128,28 @@ return NULL; } + gaddr = g_socket_address_new_from_native (&name.addr, sizeof (name)); + if (gaddr == NULL) { + g_object_unref (gsock); + g_slice_free (NiceSocket, sock); + return NULL; + } + /* GSocket: All socket file descriptors are set to be close-on-exec. */ g_socket_set_blocking (gsock, false); - gaddr = g_socket_address_new_from_native (&name.addr, sizeof (name)); - - if (gaddr != NULL) { - gret = g_socket_connect (gsock, gaddr, NULL, &gerr); - g_object_unref (gaddr); - } + gret = g_socket_connect (gsock, gaddr, NULL, &gerr); + g_object_unref (gaddr); if (gret == FALSE) { if (g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_PENDING) == FALSE) { + g_error_free (gerr); g_socket_close (gsock, NULL); g_object_unref (gsock); g_slice_free (NiceSocket, sock); return NULL; } - g_error_free(gerr); + g_error_free (gerr); } gaddr = g_socket_get_local_address (gsock, NULL); @@ -164,6 +166,8 @@ sock->priv = priv = g_slice_new0 (TcpPriv); + if (ctx == NULL) + ctx = g_main_context_default (); priv->context = g_main_context_ref (ctx); priv->server_addr = *addr; priv->error = FALSE; @@ -389,8 +393,7 @@ } if (ret < 0) { - if (gerr != NULL && - g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { + if (g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { GOutputVector local_buf = { tbs->buf, tbs->length }; NiceOutputMessage local_message = {&local_buf, 1}; @@ -399,7 +402,7 @@ g_error_free (gerr); break; } - g_error_free (gerr); + g_clear_error (&gerr); } else if (ret < (int) tbs->length) { GOutputVector local_buf = { tbs->buf + ret, tbs->length - ret }; NiceOutputMessage local_message = {&local_buf, 1}; diff -Nru libnice-0.1.5/socket/tcp-turn.c libnice-0.1.7/socket/tcp-turn.c --- libnice-0.1.5/socket/tcp-turn.c 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/socket/tcp-turn.c 2014-04-09 02:44:13.000000000 +0000 @@ -196,7 +196,7 @@ } static gint -socket_recv_messages (NiceSocket *socket, +socket_recv_messages (NiceSocket *nicesock, NiceInputMessage *recv_messages, guint n_recv_messages) { guint i; @@ -205,7 +205,7 @@ for (i = 0; i < n_recv_messages; i++) { gssize len; - len = socket_recv_message (socket, &recv_messages[i]); + len = socket_recv_message (nicesock, &recv_messages[i]); recv_messages[i].length = MAX (len, 0); if (len < 0) @@ -234,6 +234,7 @@ gint ret; guint n_bufs; guint16 header_buf; + guint offset = 0; /* Count the number of buffers. */ if (message->n_buffers == -1) { @@ -247,30 +248,16 @@ /* Allocate a new array of buffers, covering all the buffers in the input * @message, but with an additional one for a header and one for a footer. */ - local_bufs = g_malloc_n (n_bufs + 2, sizeof (GOutputVector)); + local_bufs = g_malloc_n (n_bufs + 1, sizeof (GOutputVector)); local_message.buffers = local_bufs; - local_message.n_buffers = n_bufs + 2; + local_message.n_buffers = n_bufs + 1; - /* Copy the existing buffers across. */ - for (j = 0; j < n_bufs; j++) { - local_bufs[j + 1].buffer = message->buffers[j].buffer; - local_bufs[j + 1].size = message->buffers[j].size; - } - - /* Header buffer. */ if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) { header_buf = htons (output_message_get_size (message)); - local_bufs[0].buffer = &header_buf; local_bufs[0].size = sizeof (header_buf); - } else { - /* Skip over the allocated header buffer. */ - local_message.buffers++; - local_message.n_buffers--; - } - - /* Tail buffer. */ - if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 || + offset = 1; + } else if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 || priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) { gsize message_len = output_message_get_size (message); gsize padlen = (message_len % 4) ? 4 - (message_len % 4) : 0; @@ -278,16 +265,23 @@ local_bufs[n_bufs].buffer = &padbuf; local_bufs[n_bufs].size = padlen; } else { - /* Skip over the allocated tail buffer. */ - local_message.n_buffers--; + local_message.n_buffers = n_bufs; } + /* Copy the existing buffers across. */ + for (j = 0; j < n_bufs; j++) { + local_bufs[j + offset].buffer = message->buffers[j].buffer; + local_bufs[j + offset].size = message->buffers[j].size; + } + + ret = nice_socket_send_messages (priv->base_socket, to, &local_message, 1); + if (ret == 1) + ret = output_message_get_size (&local_message); + g_free (local_bufs); - if (ret == 1) - return output_message_get_size (&local_message); return ret; } diff -Nru libnice-0.1.5/socket/turn.c libnice-0.1.7/socket/turn.c --- libnice-0.1.5/socket/turn.c 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/socket/turn.c 2014-05-02 21:47:09.000000000 +0000 @@ -67,7 +67,7 @@ NiceAddress peer; uint16_t channel; gboolean renew; - guint timeout_source; + GSource *timeout_source; } ChannelBinding; typedef struct { @@ -83,9 +83,9 @@ NiceSocket *base_socket; NiceAddress server_addr; uint8_t *username; - size_t username_len; + gsize username_len; uint8_t *password; - size_t password_len; + gsize password_len; NiceTurnSocketCompatibility compatibility; GQueue *send_requests; uint8_t ms_realm[STUN_MAX_MS_REALM_LEN + 1]; @@ -96,7 +96,7 @@ there is an installed permission */ GList *sent_permissions; /* ongoing permission installed */ GHashTable *send_data_queues; /* stores a send data queue for per peer */ - guint permission_timeout_source; /* timer used to invalidate + GSource *permission_timeout_source; /* timer used to invalidate permissions */ } TurnPriv; @@ -209,13 +209,13 @@ priv->password = g_base64_decode (password, &priv->password_len); } else { priv->username = (uint8_t *)g_strdup (username); - priv->username_len = (size_t) strlen (username); + priv->username_len = (gsize) strlen (username); if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) { priv->password = NULL; priv->password_len = 0; } else { priv->password = (uint8_t *)g_strdup (password); - priv->password_len = (size_t) strlen (password); + priv->password_len = (gsize) strlen (password); } } priv->server_addr = *server_addr; @@ -247,8 +247,10 @@ for (i = priv->channels; i; i = i->next) { ChannelBinding *b = i->data; - if (b->timeout_source) - g_source_remove (b->timeout_source); + if (b->timeout_source) { + g_source_destroy (b->timeout_source); + g_source_unref (b->timeout_source); + } g_free (b); } g_list_free (priv->channels); @@ -288,8 +290,11 @@ g_list_free (priv->sent_permissions); g_hash_table_destroy (priv->send_data_queues); - if (priv->permission_timeout_source) - g_source_remove (priv->permission_timeout_source); + if (priv->permission_timeout_source) { + g_source_destroy (priv->permission_timeout_source); + g_source_unref (priv->permission_timeout_source); + priv->permission_timeout_source = NULL; + } if (priv->ctx) g_main_context_unref (priv->ctx); @@ -339,6 +344,9 @@ n_valid_messages = 1; + if (message->length == 0) + continue; + /* Compact the message’s buffers into a single one for parsing. Avoid this * in the (hopefully) common case of a single-element buffer vector. */ if (message->n_buffers == 1 || @@ -346,7 +354,7 @@ message->buffers[0].buffer != NULL && message->buffers[1].buffer == NULL)) { buffer = message->buffers[0].buffer; - buffer_length = message->buffers[0].size; + buffer_length = message->length; } else { nice_debug ("%s: **WARNING: SLOW PATH**", G_STRFUNC); @@ -366,6 +374,8 @@ /* A TURN control message which needs ignoring. Re-use this * NiceInputMessage in the next loop iteration. */ n_valid_messages = 0; + } else { + *message->from = from; } /* Split up the monolithic buffer again into the caller-provided buffers. */ @@ -391,13 +401,16 @@ static GSource * priv_timeout_add_with_context (TurnPriv *priv, guint interval, - GSourceFunc function, gpointer data) + gboolean seconds, GSourceFunc function, gpointer data) { GSource *source; g_return_val_if_fail (function != NULL, NULL); - source = g_timeout_source_new (interval); + if (seconds) + source = g_timeout_source_new_seconds (interval); + else + source = g_timeout_source_new (interval); g_source_set_callback (source, function, data, NULL); g_source_attach (source, priv->ctx); @@ -482,8 +495,13 @@ NiceAddress *address = (NiceAddress *) iter->data; if (nice_address_equal (address, peer)) { + GList *prev = iter->prev; + nice_address_free (address); list = g_list_delete_link (list, iter); + iter = prev; + if (iter) + iter = list; } } @@ -626,7 +644,7 @@ buffer, sizeof(buffer), STUN_IND_SEND)) goto send; if (stun_message_append_xor_addr (&msg, STUN_ATTRIBUTE_PEER_ADDRESS, - &sa.addr, sizeof(sa)) != + &sa.storage, sizeof(sa)) != STUN_MESSAGE_RETURN_SUCCESS) goto send; } else { @@ -687,7 +705,7 @@ req->priv = priv; stun_message_id (&msg, req->id); req->source = priv_timeout_add_with_context (priv, - STUN_END_TIMEOUT, priv_forget_send_request, req); + STUN_END_TIMEOUT, FALSE, priv_forget_send_request, req); g_queue_push_tail (priv->send_requests, req); } } @@ -822,7 +840,7 @@ /* find current binding and destroy it */ for (i = priv->channels ; i; i = i->next) { ChannelBinding *b = i->data; - if (b->timeout_source == g_source_get_id (source)) { + if (b->timeout_source == source) { priv->channels = g_list_remove (priv->channels, b); /* Make sure we don't free a currently being-refreshed binding */ if (priv->current_binding_msg && !priv->current_binding) { @@ -836,7 +854,7 @@ /* look up binding associated with peer */ stun_message_find_xor_addr ( &priv->current_binding_msg->message, - STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &sa.addr, &sa_len); + STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &sa.storage, &sa_len); nice_address_set_from_sockaddr (&to, &sa.addr); /* If the binding is being refreshed, then move it to @@ -882,11 +900,12 @@ /* find current binding and mark it for renewal */ for (i = priv->channels ; i; i = i->next) { ChannelBinding *b = i->data; - if (b->timeout_source == g_source_get_id (source)) { + if (b->timeout_source == source) { b->renew = TRUE; /* Install timer to expire the permission */ - b->timeout_source = g_timeout_add_seconds (STUN_EXPIRE_TIMEOUT, - priv_binding_expired_timeout, priv); + b->timeout_source = priv_timeout_add_with_context (priv, + STUN_EXPIRE_TIMEOUT, TRUE, priv_binding_expired_timeout, priv); + /* Send renewal */ if (!priv->current_binding_msg) priv_send_channel_bind (priv, NULL, b->channel, &b->peer); @@ -1054,7 +1073,7 @@ /* look up binding associated with peer */ stun_message_find_xor_addr ( &priv->current_binding_msg->message, - STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &sa.addr, &sa_len); + STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &sa.storage, &sa_len); nice_address_set_from_sockaddr (&to, &sa.addr); for (i = priv->channels; i; i = i->next) { @@ -1118,12 +1137,14 @@ binding->renew = FALSE; /* Remove any existing timer */ - if (binding->timeout_source) - g_source_remove (binding->timeout_source); + if (binding->timeout_source) { + g_source_destroy (binding->timeout_source); + g_source_unref (binding->timeout_source); + } /* Install timer to schedule refresh of the permission */ binding->timeout_source = - g_timeout_add_seconds (STUN_BINDING_TIMEOUT, - priv_binding_timeout, priv); + priv_timeout_add_with_context (priv, STUN_BINDING_TIMEOUT, + TRUE, priv_binding_timeout, priv); } priv_process_pending_bindings (priv); } @@ -1155,7 +1176,7 @@ nice_debug ("got response for CreatePermission"); stun_message_find_xor_addr ( ¤t_create_permission_msg->message, - STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &peer.addr, &peer_len); + STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &peer.storage, &peer_len); nice_address_set_from_sockaddr (&to, &peer.addr); /* unathorized => resend with realm and nonce */ @@ -1206,8 +1227,8 @@ 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); + priv_timeout_add_with_context (priv, STUN_PERMISSION_TIMEOUT, + TRUE, priv_permission_timeout, priv); } /* send enqued data */ @@ -1236,12 +1257,12 @@ if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 || priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) { if (stun_message_find_xor_addr (&msg, STUN_ATTRIBUTE_REMOTE_ADDRESS, - &sa.addr, &from_len) != + &sa.storage, &from_len) != STUN_MESSAGE_RETURN_SUCCESS) goto recv; } else { if (stun_message_find_addr (&msg, STUN_ATTRIBUTE_REMOTE_ADDRESS, - &sa.addr, &from_len) != + &sa.storage, &from_len) != STUN_MESSAGE_RETURN_SUCCESS) goto recv; } @@ -1421,7 +1442,7 @@ stun_agent_forget_transaction (&priv->agent, id); stun_message_find_xor_addr ( ¤t_create_permission_msg->message, - STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &addr.addr, &addr_len); + STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &addr.storage, &addr_len); nice_address_set_from_sockaddr (&to, &addr.addr); priv_remove_sent_permission_for_peer (priv, &to); @@ -1532,7 +1553,7 @@ guint timeout = stun_timer_remainder (&priv->current_binding_msg->timer); if (timeout > 0) { priv->tick_source_channel_bind = - priv_timeout_add_with_context (priv, timeout, + priv_timeout_add_with_context (priv, timeout, FALSE, priv_retransmissions_tick, priv); } else { priv_retransmissions_tick_unlocked (priv); @@ -1548,8 +1569,12 @@ timeout = stun_timer_remainder (¤t_create_permission_msg->timer); if (timeout > 0) { + if (priv->tick_source_create_permission) { + g_source_destroy (priv->tick_source_create_permission); + g_source_unref (priv->tick_source_create_permission); + } priv->tick_source_create_permission = - priv_timeout_add_with_context (priv, + priv_timeout_add_with_context (priv, FALSE, timeout, priv_retransmissions_create_permission_tick, priv); @@ -1624,7 +1649,7 @@ priv->password_len, realm, realm_len, nonce, nonce_len, - &addr.addr, + &addr.storage, STUN_USAGE_TURN_COMPATIBILITY_RFC5766); if (msg_buf_len > 0) { @@ -1676,7 +1701,7 @@ } if (stun_message_append_xor_addr (&msg->message, STUN_ATTRIBUTE_PEER_ADDRESS, - &sa.addr, + &sa.storage, sizeof(sa)) != STUN_MESSAGE_RETURN_SUCCESS) { g_free (msg); diff -Nru libnice-0.1.5/stun/stunagent.c libnice-0.1.7/stun/stunagent.c --- libnice-0.1.5/stun/stunagent.c 2014-01-06 23:05:13.000000000 +0000 +++ libnice-0.1.7/stun/stunagent.c 2014-04-25 01:46:20.000000000 +0000 @@ -554,9 +554,9 @@ stun_hash_creds (realm, realm_len, username, username_len, key, key_len, md5); + memcpy (msg->long_term_key, md5, sizeof(msg->long_term_key)); + msg->long_term_valid = TRUE; } - memcpy (msg->long_term_key, md5, sizeof(msg->long_term_key)); - msg->long_term_valid = TRUE; } /* If no realm/username and long term credentials, diff -Nru libnice-0.1.5/stun/stunmessage.c libnice-0.1.7/stun/stunmessage.c --- libnice-0.1.5/stun/stunmessage.c 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/stun/stunmessage.c 2014-05-02 21:45:09.000000000 +0000 @@ -223,7 +223,7 @@ StunMessageReturn stun_message_find_addr (const StunMessage *msg, StunAttribute type, - struct sockaddr *addr, socklen_t *addrlen) + struct sockaddr_storage *addr, socklen_t *addrlen) { const uint8_t *ptr; uint16_t len = 0; @@ -284,8 +284,7 @@ StunMessageReturn stun_message_find_xor_addr (const StunMessage *msg, StunAttribute type, - struct sockaddr *addr, - socklen_t *addrlen) + struct sockaddr_storage *addr, socklen_t *addrlen) { StunMessageReturn val = stun_message_find_addr (msg, type, addr, addrlen); if (val) @@ -296,8 +295,7 @@ StunMessageReturn stun_message_find_xor_addr_full (const StunMessage *msg, StunAttribute type, - struct sockaddr *addr, socklen_t *addrlen, - uint32_t magic_cookie) + struct sockaddr_storage *addr, socklen_t *addrlen, uint32_t magic_cookie) { StunMessageReturn val = stun_message_find_addr (msg, type, addr, addrlen); if (val) @@ -475,48 +473,44 @@ StunMessageReturn stun_message_append_xor_addr (StunMessage *msg, StunAttribute type, - const struct sockaddr *addr, socklen_t addrlen) + const struct sockaddr_storage *addr, socklen_t addrlen) { StunMessageReturn val; /* Must be big enough to hold any supported address: */ - union { - struct sockaddr_storage storage; - struct sockaddr addr; - } xor; - - if ((size_t) addrlen > sizeof (xor)) - addrlen = sizeof (xor); - memcpy (&xor.storage, addr, addrlen); + struct sockaddr_storage tmpaddr; - val = stun_xor_address (msg, &xor.addr, addrlen, + if ((size_t) addrlen > sizeof (tmpaddr)) + addrlen = sizeof (tmpaddr); + memcpy (&tmpaddr, addr, addrlen); + + val = stun_xor_address (msg, &tmpaddr, addrlen, STUN_MAGIC_COOKIE); if (val) return val; - return stun_message_append_addr (msg, type, &xor.addr, addrlen); + return stun_message_append_addr (msg, type, (struct sockaddr *) &tmpaddr, + addrlen); } StunMessageReturn stun_message_append_xor_addr_full (StunMessage *msg, StunAttribute type, - const struct sockaddr *addr, socklen_t addrlen, + const struct sockaddr_storage *addr, socklen_t addrlen, uint32_t magic_cookie) { StunMessageReturn val; /* Must be big enough to hold any supported address: */ - union { - struct sockaddr_storage storage; - struct sockaddr addr; - } xor; - - if ((size_t) addrlen > sizeof (xor)) - addrlen = sizeof (xor); - memcpy (&xor.storage, addr, addrlen); + struct sockaddr_storage tmpaddr; + + if ((size_t) addrlen > sizeof (tmpaddr)) + addrlen = sizeof (tmpaddr); + memcpy (&tmpaddr, addr, addrlen); - val = stun_xor_address (msg, &xor.addr, addrlen, magic_cookie); + val = stun_xor_address (msg, &tmpaddr, addrlen, magic_cookie); if (val) return val; - return stun_message_append_addr (msg, type, &xor.addr, addrlen); + return stun_message_append_addr (msg, type, (struct sockaddr *) &tmpaddr, + addrlen); } @@ -631,7 +625,16 @@ /* from then on, we know we have the entire packet in buffer */ while (len > 0) { - size_t alen = stun_getw (msg + STUN_ATTRIBUTE_TYPE_LEN); + size_t alen; + + if (len < 4) + { + stun_debug ("STUN error: Incomplete STUN attribute header of length " + "%u bytes!\n", (unsigned)len); + return STUN_MESSAGE_BUFFER_INVALID; + } + + alen = stun_getw (msg + STUN_ATTRIBUTE_TYPE_LEN); if (has_padding) alen = stun_align (alen); diff -Nru libnice-0.1.5/stun/stunmessage.h libnice-0.1.7/stun/stunmessage.h --- libnice-0.1.5/stun/stunmessage.h 2014-03-07 02:14:00.000000000 +0000 +++ libnice-0.1.7/stun/stunmessage.h 2014-05-02 21:43:26.000000000 +0000 @@ -645,7 +645,7 @@ * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown. */ StunMessageReturn stun_message_find_addr (const StunMessage *msg, - StunAttribute type, struct sockaddr *addr, socklen_t *addrlen); + StunAttribute type, struct sockaddr_storage *addr, socklen_t *addrlen); /** * stun_message_find_xor_addr: @@ -664,7 +664,7 @@ * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown. */ StunMessageReturn stun_message_find_xor_addr (const StunMessage *msg, - StunAttribute type, struct sockaddr *addr, socklen_t *addrlen); + StunAttribute type, struct sockaddr_storage *addr, socklen_t *addrlen); /** * stun_message_find_xor_addr_full: @@ -684,7 +684,7 @@ * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown. */ StunMessageReturn stun_message_find_xor_addr_full (const StunMessage *msg, - StunAttribute type, struct sockaddr *addr, + StunAttribute type, struct sockaddr_storage *addr, socklen_t *addrlen, uint32_t magic_cookie); @@ -811,7 +811,7 @@ * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown. */ StunMessageReturn stun_message_append_xor_addr (StunMessage * msg, - StunAttribute type, const struct sockaddr *addr, socklen_t addrlen); + StunAttribute type, const struct sockaddr_storage *addr, socklen_t addrlen); /** * stun_message_append_xor_addr_full: @@ -828,7 +828,7 @@ * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown. */ StunMessageReturn stun_message_append_xor_addr_full (StunMessage * msg, - StunAttribute type, const struct sockaddr *addr, socklen_t addrlen, + StunAttribute type, const struct sockaddr_storage *addr, socklen_t addrlen, uint32_t magic_cookie); /** diff -Nru libnice-0.1.5/stun/tests/test-bind.c libnice-0.1.7/stun/tests/test-bind.c --- libnice-0.1.5/stun/tests/test-bind.c 2014-01-06 23:05:13.000000000 +0000 +++ libnice-0.1.7/stun/tests/test-bind.c 2014-03-31 23:18:16.000000000 +0000 @@ -102,7 +102,8 @@ /** Incorrect socket family test */ static void bad_family (void) { - struct sockaddr addr, dummy; + struct sockaddr addr; + struct sockaddr_storage dummy; int val; socklen_t dummylen = sizeof(dummy); @@ -121,7 +122,8 @@ /** Too small socket address test */ static void small_srv_addr (void) { - struct sockaddr addr, dummy; + struct sockaddr addr; + struct sockaddr_storage dummy; int val; socklen_t dummylen = sizeof(dummy); @@ -141,7 +143,7 @@ static void big_srv_addr (void) { uint8_t buf[sizeof (struct sockaddr_storage) + 16]; - struct sockaddr dummy; + struct sockaddr_storage dummy; int val; socklen_t dummylen = sizeof(dummy); @@ -156,8 +158,7 @@ /** Timeout test */ static void timeout (void) { - struct sockaddr_storage srv; - struct sockaddr dummy; + struct sockaddr_storage srv, dummy; socklen_t srvlen = sizeof (srv); socklen_t dummylen = sizeof(dummy); int val; @@ -231,8 +232,7 @@ assert (stun_agent_validate (&agent, &msg, buf, len, NULL, NULL) == STUN_VALIDATION_SUCCESS); - val = stun_usage_bind_process (&msg, - (struct sockaddr *)&addr, &addrlen, (struct sockaddr *)&addr, &addrlen); + val = stun_usage_bind_process (&msg, &addr, &addrlen, &addr, &addrlen); assert (val == STUN_USAGE_BIND_RETURN_INVALID); /* Send response with wrong request type */ @@ -241,8 +241,7 @@ /* Send error response without ERROR-CODE */ buf[1] |= 0x10; - val = stun_usage_bind_process (&msg, - (struct sockaddr *)&addr, &addrlen, (struct sockaddr *)&addr, &addrlen); + val = stun_usage_bind_process (&msg, &addr, &addrlen, &addr, &addrlen); assert (val == STUN_USAGE_BIND_RETURN_INVALID); close (fd); @@ -311,8 +310,7 @@ val = getsockname (servfd, (struct sockaddr *)&addr, &addrlen); assert (val == 0); - val = stun_usage_bind_process (&msg, - (struct sockaddr *)&addr, &addrlen, (struct sockaddr *)&addr, &addrlen); + val = stun_usage_bind_process (&msg, &addr, &addrlen, &addr, &addrlen); assert (val == STUN_USAGE_BIND_RETURN_ERROR); /* Send response with a no mapped address at all */ @@ -342,8 +340,7 @@ val = getsockname (servfd, (struct sockaddr *)&addr, &addrlen); assert (val == 0); - val = stun_usage_bind_process (&msg, - (struct sockaddr *)&addr, &addrlen, (struct sockaddr *)&addr, &addrlen); + val = stun_usage_bind_process (&msg, &addr, &addrlen, &addr, &addrlen); assert (val == STUN_USAGE_BIND_RETURN_ERROR); /* Send old-style response */ @@ -365,7 +362,7 @@ stun_agent_init_response (&agent, &msg, buf, sizeof (buf), &msg); assert (stun_message_append_addr (&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, - (struct sockaddr *)&addr, addrlen) == STUN_MESSAGE_RETURN_SUCCESS); + &addr, addrlen) == STUN_MESSAGE_RETURN_SUCCESS); len = stun_agent_finish_message (&agent, &msg, NULL, 0); assert (len > 0); @@ -375,8 +372,7 @@ val = getsockname (servfd, (struct sockaddr *)&addr, &addrlen); assert (val == 0); - val = stun_usage_bind_process (&msg, - (struct sockaddr *)&addr, &addrlen, (struct sockaddr *)&addr, &addrlen); + val = stun_usage_bind_process (&msg, &addr, &addrlen, &addr, &addrlen); assert (val == STUN_USAGE_BIND_RETURN_SUCCESS); /* End */ diff -Nru libnice-0.1.5/stun/tests/test-conncheck.c libnice-0.1.7/stun/tests/test-conncheck.c --- libnice-0.1.5/stun/tests/test-conncheck.c 2011-02-02 04:49:42.000000000 +0000 +++ libnice-0.1.7/stun/tests/test-conncheck.c 2014-03-31 22:41:13.000000000 +0000 @@ -67,24 +67,30 @@ int main (void) { - struct sockaddr_in ip4; + union { + struct sockaddr sa; + struct sockaddr_storage storage; + struct sockaddr_in ip4; + } addr; uint8_t req_buf[STUN_MAX_MESSAGE_SIZE]; uint8_t resp_buf[STUN_MAX_MESSAGE_SIZE]; - const uint64_t tie = 0x8000000000000000LL; + const const uint64_t tie = 0x8000000000000000LL; StunMessageReturn val; StunUsageIceReturn val2; size_t len; size_t rlen; - static char username[] = "L:R", ufrag[] = "L", pass[] = "secret"; + static char username[] = "L:R"; + static uint8_t ufrag[] = "L", pass[] = "secret"; + size_t ufrag_len = strlen ((char*) ufrag); + size_t pass_len = strlen ((char*) pass); int code; - uint16_t alen; bool control = false; StunAgent agent; StunMessage req; StunMessage resp; StunDefaultValidaterData validater_data[] = { - {ufrag, strlen (ufrag), pass, strlen (pass)}, - {username, strlen (username), pass, strlen (pass)}, + {ufrag, ufrag_len, pass, pass_len}, + {(uint8_t *) username, strlen (username), pass, pass_len}, {NULL, 0, NULL, 0}}; StunValidationStatus valid; @@ -93,13 +99,13 @@ STUN_AGENT_USAGE_USE_FINGERPRINT | STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS); - memset (&ip4, 0, sizeof (ip4)); - ip4.sin_family = AF_INET; + memset (&addr, 0, sizeof (addr)); + addr.ip4.sin_family = AF_INET; #ifdef HAVE_SA_LEN - ip4.sin_len = sizeof (addr); + addr.ip4.sin_len = sizeof (addr); #endif - ip4.sin_port = htons (12345); - ip4.sin_addr.s_addr = htonl (0x7f000001); + addr.ip4.sin_port = htons (12345); + addr.ip4.sin_addr.s_addr = htonl (0x7f000001); /* Incorrect message class */ assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING)); @@ -110,8 +116,8 @@ len = sizeof (resp_buf); val2 = stun_usage_ice_conncheck_create_reply (&agent, &req, - &resp, resp_buf, &len, (struct sockaddr *)&ip4, - sizeof (ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); + &resp, resp_buf, &len, &addr.storage, + sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); assert (val2 == STUN_USAGE_ICE_RETURN_INVALID_REQUEST); assert (len == 0); @@ -119,13 +125,13 @@ assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), 0x666)); val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, username); assert (val == STUN_MESSAGE_RETURN_SUCCESS); - rlen = stun_agent_finish_message (&agent, &req, pass, strlen (pass)); + rlen = stun_agent_finish_message (&agent, &req, pass, pass_len); assert (rlen > 0); len = sizeof (resp_buf); val2 = stun_usage_ice_conncheck_create_reply (&agent, &req, - &resp, resp_buf, &len, (struct sockaddr *)&ip4, - sizeof (ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); + &resp, resp_buf, &len, &addr.storage, + sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); assert (val2 == STUN_USAGE_ICE_RETURN_INVALID_METHOD); assert (len > 0); @@ -135,7 +141,7 @@ assert (val == STUN_MESSAGE_RETURN_SUCCESS); val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, username); assert (val == STUN_MESSAGE_RETURN_SUCCESS); - rlen = stun_agent_finish_message (&agent, &req, pass, strlen (pass)); + rlen = stun_agent_finish_message (&agent, &req, pass, pass_len); assert (rlen > 0); valid = stun_agent_validate (&agent, &req, req_buf, rlen, @@ -155,7 +161,7 @@ /* No username */ assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING)); - rlen = stun_agent_finish_message (&agent, &req, pass, strlen (pass)); + rlen = stun_agent_finish_message (&agent, &req, pass, pass_len); assert (rlen > 0); valid = stun_agent_validate (&agent, &req, req_buf, rlen, @@ -171,16 +177,17 @@ assert (val == STUN_MESSAGE_RETURN_SUCCESS); val = stun_message_append_flag (&req, STUN_ATTRIBUTE_USE_CANDIDATE); assert (val == STUN_MESSAGE_RETURN_SUCCESS); - val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, ufrag); + val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, + (char*) ufrag); assert (val == STUN_MESSAGE_RETURN_SUCCESS); - rlen = stun_agent_finish_message (&agent, &req, pass, strlen (pass)); + rlen = stun_agent_finish_message (&agent, &req, pass, pass_len); assert (rlen > 0); len = sizeof (resp_buf); val2 = stun_usage_ice_conncheck_create_reply (&agent, &req, - &resp, resp_buf, &len, (struct sockaddr *)&ip4, - sizeof (ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); - assert (val == STUN_USAGE_ICE_RETURN_SUCCESS); + &resp, resp_buf, &len, &addr.storage, + sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); + assert (val2 == STUN_USAGE_ICE_RETURN_SUCCESS); assert (len > 0); assert (stun_agent_validate (&agent, &resp, resp_buf, len, stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS); @@ -192,18 +199,18 @@ assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING)); val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, ufrag); assert (val == STUN_MESSAGE_RETURN_SUCCESS); - rlen = stun_agent_finish_message (&agent, &req, pass, strlen (pass)); + rlen = stun_agent_finish_message (&agent, &req, pass, pass_len); assert (rlen > 0); - ip4.sin_family = AF_UNSPEC; + addr.ip4.sin_family = AF_UNSPEC; len = sizeof (resp_buf); val2 = stun_usage_ice_conncheck_create_reply (&agent, &req, - &resp, resp_buf, &len, (struct sockaddr *)&ip4, - sizeof (ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); + &resp, resp_buf, &len, &addr.storage, + sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); assert (val2 == STUN_USAGE_ICE_RETURN_INVALID_ADDRESS); assert (len == 0); - ip4.sin_family = AF_INET; + addr.ip4.sin_family = AF_INET; /* Lost role conflict */ assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING)); @@ -211,15 +218,15 @@ assert (val == STUN_MESSAGE_RETURN_SUCCESS); val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, ufrag); assert (val == STUN_MESSAGE_RETURN_SUCCESS); - rlen = stun_agent_finish_message (&agent, &req, pass, strlen (pass)); + rlen = stun_agent_finish_message (&agent, &req, pass, pass_len); assert (rlen > 0); len = sizeof (resp_buf); control = true; val2 = stun_usage_ice_conncheck_create_reply (&agent, &req, - &resp, resp_buf, &len, (struct sockaddr *)&ip4, - sizeof (ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); + &resp, resp_buf, &len, &addr.storage, + sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); assert (val2 == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT); assert (len > 0); assert (control == false); @@ -233,14 +240,14 @@ assert (val == STUN_MESSAGE_RETURN_SUCCESS); val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, ufrag); assert (val == STUN_MESSAGE_RETURN_SUCCESS); - rlen = stun_agent_finish_message (&agent, &req, pass, strlen (pass)); + rlen = stun_agent_finish_message (&agent, &req, pass, pass_len); assert (rlen > 0); len = sizeof (resp_buf); control = false; val2 = stun_usage_ice_conncheck_create_reply (&agent, &req, - &resp, resp_buf, &len, (struct sockaddr *)&ip4, - sizeof (ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); + &resp, resp_buf, &len, &addr.storage, + sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); assert (val2 == STUN_USAGE_ICE_RETURN_SUCCESS); assert (len > 0); assert (control == false); diff -Nru libnice-0.1.5/stun/tests/test-format.c libnice-0.1.7/stun/tests/test-format.c --- libnice-0.1.5/stun/tests/test-format.c 2011-02-02 04:49:42.000000000 +0000 +++ libnice-0.1.7/stun/tests/test-format.c 2014-05-02 21:48:08.000000000 +0000 @@ -66,20 +66,20 @@ exit (1); } -static const char usr[] = "admin"; -static const char pwd[] = "s3kr3t"; +static const uint8_t usr[] = "admin"; +static const uint8_t pwd[] = "s3kr3t"; -bool dynamic_check_validater (StunAgent *agent, +static bool dynamic_check_validater (StunAgent *agent, StunMessage *message, uint8_t *username, uint16_t username_len, uint8_t **password, size_t *password_len, void *user_data) { - if (username_len != strlen (usr) || - memcmp (username, usr, strlen (usr)) != 0) + if (username_len != strlen ((char *) usr) || + memcmp (username, usr, strlen ((char *) usr)) != 0) fatal ("vector test : Validater received wrong username!"); *password = (uint8_t *) pwd; - *password_len = strlen (pwd); + *password_len = strlen ((char *) pwd); return true; @@ -117,9 +117,9 @@ if (stun_message_find (&msg2, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, &plen) != NULL) fatal ("Missing HMAC test failed"); - stun_message_append_string (&msg2, STUN_ATTRIBUTE_USERNAME, usr); + stun_message_append_string (&msg2, STUN_ATTRIBUTE_USERNAME, (char *) usr); - len = stun_agent_finish_message (agent, &msg2, pwd, strlen (pwd)); + len = stun_agent_finish_message (agent, &msg2, pwd, strlen ((char *) pwd)); if (len <= 0) fatal ("Cannot finish message with short-term creds"); @@ -146,29 +146,30 @@ stun_agent_init_request (&agent, &msg, buf, sizeof(buf), STUN_BINDING); if (stun_message_append_addr (&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, - (struct sockaddr *)&addr, addrlen) != + (struct sockaddr *) &addr, addrlen) != STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS) fatal ("Unknown address family test failed"); if (stun_message_append_xor_addr (&msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, - (struct sockaddr *)&addr, addrlen) != + &addr, addrlen) != STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS) fatal ("Unknown address family xor test failed"); addr.ss_family = family; if (stun_message_append_addr (&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, - (struct sockaddr *)&addr, addrlen - 1) != STUN_MESSAGE_RETURN_INVALID) + (struct sockaddr *) &addr, addrlen - 1) != + STUN_MESSAGE_RETURN_INVALID) fatal ("Too small %s sockaddr test failed", name); if (stun_message_append_xor_addr (&msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, - (struct sockaddr *)&addr, addrlen - 1) != STUN_MESSAGE_RETURN_INVALID) + &addr, addrlen - 1) != STUN_MESSAGE_RETURN_INVALID) fatal ("Too small %s sockaddr xor test failed", name); if (stun_message_append_addr (&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, - (struct sockaddr *)&addr, addrlen) != STUN_MESSAGE_RETURN_SUCCESS) + (struct sockaddr *) &addr, addrlen) != STUN_MESSAGE_RETURN_SUCCESS) fatal ("%s sockaddr test failed", name); if (stun_message_append_xor_addr (&msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, - (struct sockaddr *)&addr, addrlen) != STUN_MESSAGE_RETURN_SUCCESS) + &addr, addrlen) != STUN_MESSAGE_RETURN_SUCCESS) fatal ("%s sockaddr xor test failed", name); } @@ -176,7 +177,10 @@ { uint8_t buf[100]; size_t len; - struct sockaddr addr; + union { + struct sockaddr_storage storage; + struct sockaddr addr; + } addr; StunAgent agent; StunMessage msg; @@ -240,17 +244,17 @@ fatal ("String overflow test failed"); memset (&addr, 0, sizeof (addr)); - addr.sa_family = AF_INET; -#ifdef HAVE_SA_LEN - addr.sa_len = sizeof (addr); + addr.addr.sa_family = AF_INET; +#ifdef HAVE_SS_LEN + addr.addr.ss_len = sizeof (addr); #endif - if (stun_message_append_xor_addr (&msg, 0xffff, &addr, + if (stun_message_append_xor_addr (&msg, 0xffff, &addr.storage, sizeof (addr)) != STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE) fatal ("Address overflow test failed"); len = sizeof (msg); if (stun_agent_finish_message (&agent, &msg, NULL, 0) != 0) fatal ("Fingerprint overflow test failed"); - if (stun_agent_finish_message (&agent, &msg, pwd, strlen (pwd)) != 0) + if (stun_agent_finish_message (&agent, &msg, pwd, strlen ((char *) pwd)) != 0) fatal ("Message integrity overflow test failed"); /* Address attributes tests */ diff -Nru libnice-0.1.5/stun/tests/test-hmac.c libnice-0.1.7/stun/tests/test-hmac.c --- libnice-0.1.5/stun/tests/test-hmac.c 2009-08-14 22:46:12.000000000 +0000 +++ libnice-0.1.7/stun/tests/test-hmac.c 2014-03-31 21:39:58.000000000 +0000 @@ -45,7 +45,7 @@ #include #include -void print_bytes (uint8_t *bytes, int len) +static void print_bytes (const uint8_t *bytes, int len) { int i; @@ -55,12 +55,12 @@ printf ("\n"); } -void test_sha1 (uint8_t *str, uint8_t *expected) { +static void test_sha1 (const uint8_t *str, const uint8_t *expected) { SHA1_CTX ctx; uint8_t sha1[20]; SHA1Init(&ctx); - SHA1Update(&ctx, str, strlen (str)); + SHA1Update(&ctx, str, strlen ((char *) str)); SHA1Final(sha1, &ctx); printf ("SHA1 of '%s' : ", str); @@ -73,10 +73,11 @@ } -void test_hmac (uint8_t *key, uint8_t *str, uint8_t *expected) { +static void test_hmac (const uint8_t *key, const uint8_t *str, + const uint8_t *expected) { uint8_t hmac[20]; - hmac_sha1(key, strlen (key), str, strlen (str), hmac); + hmac_sha1(key, strlen ((char *) key), str, strlen ((char *) str), hmac); printf ("HMAC of '%s' with key '%s' is : ", str, key); print_bytes (hmac, SHA1_MAC_LEN); printf ("Expected : "); @@ -86,13 +87,12 @@ exit (1); } -void test_md5 (uint8_t *str, uint8_t *expected) { +static void test_md5 (const uint8_t *str, const uint8_t *expected) { MD5_CTX ctx; uint8_t md5[20]; - int i; MD5Init(&ctx); - MD5Update(&ctx, str, strlen (str)); + MD5Update(&ctx, str, strlen ((char *) str)); MD5Final(md5, &ctx); printf ("MD5 of '%s' : 0x", str); @@ -128,15 +128,16 @@ 0xaa, 0xe1, 0x16, 0xd3, 0x87, 0x6c, 0x66, 0x4a}; - test_hmac ("hello", "world", hello_world_hmac); + test_hmac ((const uint8_t *) "hello", (const uint8_t*) "world", + hello_world_hmac); - test_sha1 ("abc", abc_sha1); - test_md5 ("abc", abc_md5); + test_sha1 ((const uint8_t *) "abc", abc_sha1); + test_md5 ((const uint8_t *) "abc", abc_md5); - test_sha1 ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - abcd_etc_sha1); - test_md5 ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - abcd_etc_md5); + test_sha1 ((const uint8_t *) + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", abcd_etc_sha1); + test_md5 ((const uint8_t *) + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", abcd_etc_md5); return 0; } diff -Nru libnice-0.1.5/stun/tests/test-parse.c libnice-0.1.7/stun/tests/test-parse.c --- libnice-0.1.5/stun/tests/test-parse.c 2014-03-06 22:24:22.000000000 +0000 +++ libnice-0.1.7/stun/tests/test-parse.c 2014-03-31 22:41:13.000000000 +0000 @@ -285,18 +285,18 @@ } -bool test_attribute_validater (StunAgent *agent, +static bool test_attribute_validater (StunAgent *agent, StunMessage *message, uint8_t *username, uint16_t username_len, uint8_t **password, size_t *password_len, void *user_data) { - char *pwd = (char *) user_data; + uint8_t *pwd = user_data; if (username_len != 4 || memcmp (username, "ABCD", 4) != 0) return false; *password = pwd; - *password_len = strlen (pwd); + *password_len = strlen ((char *) pwd); return true; } @@ -356,7 +356,7 @@ union { - struct sockaddr sa; + struct sockaddr_storage st; struct sockaddr_in6 s6; } addr; socklen_t addrlen; @@ -368,7 +368,7 @@ StunMessage msg; uint16_t known_attributes[] = {STUN_ATTRIBUTE_MESSAGE_INTEGRITY, STUN_ATTRIBUTE_USERNAME, 0}; - printf ("Attribute test message length: %lu\n", sizeof (acme)); + printf ("Attribute test message length: %zd\n", sizeof (acme)); stun_agent_init (&agent, known_attributes, STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS); @@ -378,11 +378,11 @@ fatal ("Unauthorized validation failed"); if (stun_agent_validate (&agent, &msg, acme, sizeof(acme), - test_attribute_validater, "bad__guy") != STUN_VALIDATION_UNAUTHORIZED) + test_attribute_validater, (void *) "bad__guy") != STUN_VALIDATION_UNAUTHORIZED) fatal ("invalid password validation failed"); if (stun_agent_validate (&agent, &msg, acme, sizeof(acme), - test_attribute_validater, "good_guy") != STUN_VALIDATION_SUCCESS) + test_attribute_validater, (void *) "good_guy") != STUN_VALIDATION_SUCCESS) fatal ("good password validation failed"); if (stun_message_has_attribute (&msg, 0xff00)) @@ -422,27 +422,27 @@ fatal ("String test failed"); addrlen = sizeof (addr); - if (stun_message_find_addr (&msg, 0xff01, &addr.sa, &addrlen) != + if (stun_message_find_addr (&msg, 0xff01, &addr.st, &addrlen) != STUN_MESSAGE_RETURN_INVALID) fatal ("Too short addres test failed"); addrlen = sizeof (addr); - if (stun_message_find_addr (&msg, 0xff02, &addr.sa, &addrlen) != + if (stun_message_find_addr (&msg, 0xff02, &addr.st, &addrlen) != STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS) fatal ("Unknown address family test failed"); addrlen = sizeof (addr); - if (stun_message_find_addr (&msg, 0xff03, &addr.sa, &addrlen) != + if (stun_message_find_addr (&msg, 0xff03, &addr.st, &addrlen) != STUN_MESSAGE_RETURN_INVALID) fatal ("Too short IPv6 address test failed"); addrlen = sizeof (addr); - if (stun_message_find_addr (&msg, 0xff04, &addr.sa, &addrlen) != + if (stun_message_find_addr (&msg, 0xff04, &addr.st, &addrlen) != STUN_MESSAGE_RETURN_SUCCESS) fatal ("IPv4 address test failed"); addrlen = sizeof (addr); - if (stun_message_find_addr (&msg, 0xff05, &addr.sa, &addrlen) != + if (stun_message_find_addr (&msg, 0xff05, &addr.st, &addrlen) != STUN_MESSAGE_RETURN_INVALID) fatal ("Too big IPv4 address test failed"); addrlen = sizeof (addr); - if (stun_message_find_xor_addr (&msg, 0xff06, &addr.sa, &addrlen) != + if (stun_message_find_xor_addr (&msg, 0xff06, &addr.st, &addrlen) != STUN_MESSAGE_RETURN_SUCCESS || memcmp (&addr.s6.sin6_addr, "\x20\x01\x0d\xb8""\xde\xad\xbe\xef" "\xde\xfa\xce\xd0""\xfa\xce\xde\xed", 16)) @@ -451,9 +451,9 @@ } static const char vector_username[] = "evtj:h6vY"; -static const char vector_password[] = "VOkJxbRl1RmTxUk/WvJxBt"; +static uint8_t vector_password[] = "VOkJxbRl1RmTxUk/WvJxBt"; -bool test_vector_validater (StunAgent *agent, +static bool test_vector_validater (StunAgent *agent, StunMessage *message, uint8_t *username, uint16_t username_len, uint8_t **password, size_t *password_len, void *user_data) { @@ -466,8 +466,8 @@ memcmp (username, vector_username, strlen (vector_username)) != 0) fatal ("vector test : Validater received wrong username!"); - *password = (uint8_t *) vector_password; - *password_len = strlen (vector_password); + *password = vector_password; + *password_len = strlen ((char *) vector_password); return true; @@ -598,8 +598,11 @@ 0x80, 0x28, 0x00, 0x04, // FINGERPRINT 0xec, 0x27, 0xae, 0xb7}; - struct sockaddr_in ip4; - struct sockaddr_in6 ip6; + union { + struct sockaddr_storage st; + struct sockaddr_in ip4; + struct sockaddr_in6 ip6; + } addr; socklen_t addrlen; StunAgent agent; @@ -616,8 +619,7 @@ STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS | STUN_AGENT_USAGE_USE_FINGERPRINT); - memset (&ip4, 0, sizeof (ip4)); - memset (&ip6, 0, sizeof (ip6)); + memset (&addr, 0, sizeof (addr)); puts ("Checking test vectors..."); @@ -635,7 +637,8 @@ if (stun_message_length (&msg) != sizeof(req) - 32) fatal ("vector test: removing attributes failed"); - stun_agent_finish_message (&agent, &msg, vector_password, strlen (vector_password)); + stun_agent_finish_message (&agent, &msg, vector_password, + strlen ((char *) vector_password)); if (stun_message_length (&msg) != stun_message_length (&msg2) || memcmp (req, req2, sizeof(req)) != 0) @@ -649,15 +652,15 @@ test_vector_validater, (void *) 0) != STUN_VALIDATION_UNMATCHED_RESPONSE) fatal ("Response ipv4 test vector authentication failed"); - addrlen = sizeof (ip4); + addrlen = sizeof (addr.ip4); if (stun_message_find_xor_addr (&msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, - (struct sockaddr *)&ip4, &addrlen) != STUN_MESSAGE_RETURN_SUCCESS) + &addr.st, &addrlen) != STUN_MESSAGE_RETURN_SUCCESS) fatal ("Response test vector IPv4 extraction failed"); - if (ip4.sin_family != AF_INET) + if (addr.ip4.sin_family != AF_INET) fatal ("Response test vector IPv4 family failed"); - if (ntohl (ip4.sin_addr.s_addr) != 0xC0000201) + if (ntohl (addr.ip4.sin_addr.s_addr) != 0xC0000201) fatal ("Response test vector IPv4 address failed"); - if (ntohs (ip4.sin_port) != 32853) + if (ntohs (addr.ip4.sin_port) != 32853) fatal ("Response test vector IPv6 port failed"); if (stun_agent_validate (&agent, &msg, req, sizeof(req), @@ -682,16 +685,16 @@ test_vector_validater, (void *) 1) != STUN_VALIDATION_SUCCESS) fatal ("Response ipv6 test vector authentication failed"); - addrlen = sizeof (ip6); + addrlen = sizeof (addr.ip6); if (stun_message_find_xor_addr (&msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, - (struct sockaddr *)&ip6, &addrlen) != STUN_MESSAGE_RETURN_SUCCESS) + &addr.st, &addrlen) != STUN_MESSAGE_RETURN_SUCCESS) fatal ("Response test vector IPv6 extraction failed"); - if (ip6.sin6_family != AF_INET6) + if (addr.ip6.sin6_family != AF_INET6) fatal ("Response test vector IPv6 family failed"); - if (memcmp (ip6.sin6_addr.s6_addr, "\x20\x01\x0d\xb8\x12\x34\x56\x78" + if (memcmp (addr.ip6.sin6_addr.s6_addr, "\x20\x01\x0d\xb8\x12\x34\x56\x78" "\x00\x11\x22\x33\x44\x55\x66\x77", 16) != 0) fatal ("Response test vector IPv6 address failed"); - if (ntohs (ip6.sin6_port) != 32853) + if (ntohs (addr.ip6.sin6_port) != 32853) fatal ("Response test vector IPv6 port failed"); @@ -710,9 +713,9 @@ puts ("Testing long term credentials hash algorithm..."); - stun_hash_creds ("realm", strlen ("realm"), - "user", strlen ("user"), - "pass", strlen ("pass"), md5); + stun_hash_creds ((uint8_t *) "realm", strlen ("realm"), + (uint8_t *) "user", strlen ("user"), + (uint8_t *) "pass", strlen ("pass"), md5); stun_debug ("key for user:realm:pass is : "); stun_debug_bytes (md5, 16); diff -Nru libnice-0.1.5/stun/tools/stunbdc.c libnice-0.1.7/stun/tools/stunbdc.c --- libnice-0.1.5/stun/tools/stunbdc.c 2014-01-06 23:05:13.000000000 +0000 +++ libnice-0.1.7/stun/tools/stunbdc.c 2014-03-31 22:41:13.000000000 +0000 @@ -108,8 +108,8 @@ printaddr ("Server address", ptr->ai_addr, ptr->ai_addrlen); - val = stun_usage_bind_run (ptr->ai_addr, ptr->ai_addrlen, - &addr.addr, &addrlen); + val = stun_usage_bind_run (ptr->ai_addr, ptr->ai_addrlen, &addr.storage, + &addrlen); if (val) fprintf (stderr, "%d\n", val); else diff -Nru libnice-0.1.5/stun/tools/stund.c libnice-0.1.7/stun/tools/stund.c --- libnice-0.1.5/stun/tools/stund.c 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/stun/tools/stund.c 2014-05-02 21:46:00.000000000 +0000 @@ -223,7 +223,7 @@ stun_agent_init_response (agent, &response, buf, sizeof (buf), &request); if (stun_message_has_cookie (&request)) stun_message_append_xor_addr (&response, - STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr.addr, addr_len); + STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr.storage, addr_len); else stun_message_append_addr (&response, STUN_ATTRIBUTE_MAPPED_ADDRESS, &addr.addr, addr_len); diff -Nru libnice-0.1.5/stun/usages/bind.c libnice-0.1.7/stun/usages/bind.c --- libnice-0.1.5/stun/usages/bind.c 2014-01-19 21:46:57.000000000 +0000 +++ libnice-0.1.7/stun/usages/bind.c 2014-04-16 03:16:34.000000000 +0000 @@ -126,7 +126,7 @@ if ((code / 100) == 3) { if (alternate_server && alternate_server_len) { if (stun_message_find_addr (msg, STUN_ATTRIBUTE_ALTERNATE_SERVER, - alternate_server, + (struct sockaddr_storage *) alternate_server, alternate_server_len) != STUN_MESSAGE_RETURN_SUCCESS) { stun_debug (" Unexpectedly missing ALTERNATE-SERVER attribute\n"); return STUN_USAGE_BIND_RETURN_ERROR; @@ -152,12 +152,14 @@ 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); + STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, (struct sockaddr_storage *)addr, + addrlen); if (val != STUN_MESSAGE_RETURN_SUCCESS) { stun_debug (" No XOR-MAPPED-ADDRESS: %d\n", val); val = stun_message_find_addr (msg, - STUN_ATTRIBUTE_MAPPED_ADDRESS, addr, addrlen); + STUN_ATTRIBUTE_MAPPED_ADDRESS, (struct sockaddr_storage *)addr, + addrlen); if (val != STUN_MESSAGE_RETURN_SUCCESS) { stun_debug (" No MAPPED-ADDRESS: %d\n", val); @@ -355,7 +357,7 @@ static ssize_t stun_trans_sendto (StunTransport *tr, const uint8_t *buf, size_t len, - const struct sockaddr *dst, socklen_t dstlen) + const struct sockaddr *dst, socklen_t dstlen) { static const int flags = MSG_DONTWAIT | MSG_NOSIGNAL; ssize_t val; @@ -375,14 +377,15 @@ static ssize_t stun_trans_recvfrom (StunTransport *tr, uint8_t *buf, size_t maxlen, - struct sockaddr * dst, + struct sockaddr_storage * dst, socklen_t * dstlen) { static const int flags = MSG_DONTWAIT | MSG_NOSIGNAL; ssize_t val; if (dstlen != NULL) - val = recvfrom (tr->fd, (void *)buf, maxlen, flags, dst, dstlen); + val = recvfrom (tr->fd, (void *)buf, maxlen, flags, (struct sockaddr *) dst, + dstlen); else val = recv (tr->fd, (void *)buf, maxlen, flags); @@ -396,14 +399,11 @@ static ssize_t stun_trans_send (StunTransport *tr, const uint8_t *buf, size_t len) { - union { - struct sockaddr_storage *storage; - struct sockaddr *addr; - } conv; + struct sockaddr *conv; - conv.storage = &tr->dst; + conv = (struct sockaddr *) &tr->dst; - return stun_trans_sendto (tr, buf, len, conv.addr, tr->dstlen); + return stun_trans_sendto (tr, buf, len, conv, tr->dstlen); } static ssize_t @@ -454,7 +454,7 @@ /** Blocking mode STUN binding discovery */ StunUsageBindReturn stun_usage_bind_run (const struct sockaddr *srv, - socklen_t srvlen, struct sockaddr *addr, socklen_t *addrlen) + socklen_t srvlen, struct sockaddr_storage *addr, socklen_t *addrlen) { StunTimer timer; StunTransport trans; @@ -467,10 +467,7 @@ size_t len; StunUsageTransReturn ret; int val; - union { - struct sockaddr_storage storage; - struct sockaddr addr; - } alternate_server; + struct sockaddr_storage alternate_server; socklen_t alternate_server_len = sizeof (alternate_server); StunUsageBindReturn bind_ret; @@ -534,13 +531,13 @@ if (valid != STUN_VALIDATION_SUCCESS) { ret = STUN_USAGE_TRANS_RETURN_RETRY; } else { - bind_ret = stun_usage_bind_process (&msg, addr, addrlen, - &alternate_server.addr, &alternate_server_len); + bind_ret = stun_usage_bind_process (&msg, (struct sockaddr *) addr, + addrlen, (struct sockaddr *) &alternate_server, &alternate_server_len); if (bind_ret == STUN_USAGE_BIND_RETURN_ALTERNATE_SERVER) { stun_trans_deinit (&trans); ret = stun_trans_create (&trans, SOCK_DGRAM, 0, - &alternate_server.addr, alternate_server_len); + (struct sockaddr *) &alternate_server, alternate_server_len); if (ret != STUN_USAGE_TRANS_RETURN_SUCCESS) { return STUN_USAGE_BIND_RETURN_ERROR; diff -Nru libnice-0.1.5/stun/usages/bind.h libnice-0.1.7/stun/usages/bind.h --- libnice-0.1.5/stun/usages/bind.h 2014-01-06 23:05:13.000000000 +0000 +++ libnice-0.1.7/stun/usages/bind.h 2014-04-16 03:14:38.000000000 +0000 @@ -156,7 +156,7 @@ * #STUN_USAGE_BIND_RETURN_ERROR and #STUN_USAGE_BIND_RETURN_TIMEOUT */ StunUsageBindReturn stun_usage_bind_run (const struct sockaddr *srv, - socklen_t srvlen, struct sockaddr *addr, socklen_t *addrlen); + socklen_t srvlen, struct sockaddr_storage *addr, socklen_t *addrlen); # ifdef __cplusplus } diff -Nru libnice-0.1.5/stun/usages/ice.c libnice-0.1.7/stun/usages/ice.c --- libnice-0.1.5/stun/usages/ice.c 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/stun/usages/ice.c 2014-05-02 21:45:34.000000000 +0000 @@ -130,7 +130,7 @@ StunUsageIceReturn stun_usage_ice_conncheck_process (StunMessage *msg, - struct sockaddr *addr, socklen_t *addrlen, + struct sockaddr_storage *addr, socklen_t *addrlen, StunUsageIceCompatibility compatibility) { int code = -1; @@ -226,7 +226,7 @@ StunUsageIceReturn stun_usage_ice_conncheck_create_reply (StunAgent *agent, StunMessage *req, StunMessage *msg, uint8_t *buf, size_t *plen, - const struct sockaddr *src, socklen_t srclen, + const struct sockaddr_storage *src, socklen_t srclen, bool *control, uint64_t tie, StunUsageIceCompatibility compatibility) { @@ -305,7 +305,7 @@ src, srclen); } else { val = stun_message_append_addr (msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, - src, srclen); + (struct sockaddr *) src, srclen); } if (val != STUN_MESSAGE_RETURN_SUCCESS) { diff -Nru libnice-0.1.5/stun/usages/ice.h libnice-0.1.7/stun/usages/ice.h --- libnice-0.1.5/stun/usages/ice.h 2011-02-02 04:50:08.000000000 +0000 +++ libnice-0.1.7/stun/usages/ice.h 2014-03-31 22:41:13.000000000 +0000 @@ -171,7 +171,7 @@ * Returns: A #StunUsageIceReturn value */ StunUsageIceReturn stun_usage_ice_conncheck_process (StunMessage *msg, - struct sockaddr *addr, socklen_t *addrlen, + struct sockaddr_storage *addr, socklen_t *addrlen, StunUsageIceCompatibility compatibility); /** @@ -207,7 +207,7 @@ StunUsageIceReturn stun_usage_ice_conncheck_create_reply (StunAgent *agent, StunMessage *req, StunMessage *msg, uint8_t *buf, size_t *plen, - const struct sockaddr *src, socklen_t srclen, + const struct sockaddr_storage *src, socklen_t srclen, bool *control, uint64_t tie, StunUsageIceCompatibility compatibility); diff -Nru libnice-0.1.5/stun/usages/turn.c libnice-0.1.7/stun/usages/turn.c --- libnice-0.1.5/stun/usages/turn.c 2014-01-06 23:05:13.000000000 +0000 +++ libnice-0.1.7/stun/usages/turn.c 2014-03-31 22:41:13.000000000 +0000 @@ -221,7 +221,7 @@ uint8_t *password, size_t password_len, uint8_t *realm, size_t realm_len, uint8_t *nonce, size_t nonce_len, - struct sockaddr *peer, + struct sockaddr_storage *peer, StunUsageTurnCompatibility compatibility) { if (!peer) @@ -262,9 +262,9 @@ 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, + struct sockaddr_storage *relay_addr, socklen_t *relay_addrlen, + struct sockaddr_storage *addr, socklen_t *addrlen, + struct sockaddr_storage *alternate_server, socklen_t *alternate_server_len, uint32_t *bandwidth, uint32_t *lifetime, StunUsageTurnCompatibility compatibility) { diff -Nru libnice-0.1.5/stun/usages/turn.h libnice-0.1.7/stun/usages/turn.h --- libnice-0.1.5/stun/usages/turn.h 2014-01-06 23:05:13.000000000 +0000 +++ libnice-0.1.7/stun/usages/turn.h 2014-03-31 22:41:13.000000000 +0000 @@ -212,7 +212,7 @@ uint8_t *password, size_t password_len, uint8_t *realm, size_t realm_len, uint8_t *nonce, size_t nonce_len, - struct sockaddr *peer, + struct sockaddr_storage *peer, StunUsageTurnCompatibility compatibility); /** @@ -242,9 +242,9 @@ * Returns: A #StunUsageTurnReturn value */ 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, + struct sockaddr_storage *relay_addr, socklen_t *relay_addrlen, + struct sockaddr_storage *addr, socklen_t *addrlen, + struct sockaddr_storage *alternate_server, socklen_t *alternate_server_len, uint32_t *bandwidth, uint32_t *lifetime, StunUsageTurnCompatibility compatibility); diff -Nru libnice-0.1.5/stun/utils.c libnice-0.1.7/stun/utils.c --- libnice-0.1.5/stun/utils.c 2014-01-06 23:05:13.000000000 +0000 +++ libnice-0.1.7/stun/utils.c 2014-03-31 22:41:13.000000000 +0000 @@ -88,18 +88,18 @@ StunMessageReturn stun_xor_address (const StunMessage *msg, - struct sockaddr *addr, socklen_t addrlen, + struct sockaddr_storage *addr, socklen_t addrlen, uint32_t magic_cookie) { union { - struct sockaddr *addr; + struct sockaddr_storage *addr; struct sockaddr_in *in; struct sockaddr_in6 *in6; } addr_ptr; addr_ptr.addr = addr; - switch (addr->sa_family) + switch (addr->ss_family) { case AF_INET: { diff -Nru libnice-0.1.5/stun/utils.h libnice-0.1.7/stun/utils.h --- libnice-0.1.5/stun/utils.h 2011-02-02 04:49:42.000000000 +0000 +++ libnice-0.1.7/stun/utils.h 2014-03-31 22:41:13.000000000 +0000 @@ -68,7 +68,7 @@ void stun_set_type (uint8_t *h, StunClass c, StunMethod m); StunMessageReturn stun_xor_address (const StunMessage *msg, - struct sockaddr *addr, socklen_t addrlen, + struct sockaddr_storage *addr, socklen_t addrlen, uint32_t magic_cookie); diff -Nru libnice-0.1.5/stun/win32_common.h libnice-0.1.7/stun/win32_common.h --- libnice-0.1.5/stun/win32_common.h 2014-01-06 23:05:13.000000000 +0000 +++ libnice-0.1.7/stun/win32_common.h 2014-04-04 03:53:01.000000000 +0000 @@ -57,6 +57,7 @@ #ifndef _WIN32_COMMON_H #define _WIN32_COMMON_H +#include "config.h" #include /* 7.18.1.1 Exact-width integer types */ @@ -69,8 +70,10 @@ typedef long long int64_t; typedef unsigned long long uint64_t; -#ifndef _SSIZE_T_ +#ifndef HAVE_SIZE_T typedef unsigned int size_t; +#endif +#ifndef HAVE_SSIZE_T typedef unsigned long ssize_t; #endif diff -Nru libnice-0.1.5/tests/Makefile.am libnice-0.1.7/tests/Makefile.am --- libnice-0.1.5/tests/Makefile.am 2014-03-07 02:14:00.000000000 +0000 +++ libnice-0.1.7/tests/Makefile.am 2014-04-17 22:14:51.000000000 +0000 @@ -22,6 +22,7 @@ check_PROGRAMS = \ test-pseudotcp \ + test-pseudotcp-fuzzy \ test-bsd \ test \ test-address \ @@ -52,6 +53,8 @@ test_pseudotcp_LDADD = $(COMMON_LDADD) +test_pseudotcp_fuzzy_LDADD = $(COMMON_LDADD) -lm + test_bsd_LDADD = $(COMMON_LDADD) test_LDADD = $(COMMON_LDADD) diff -Nru libnice-0.1.5/tests/Makefile.in libnice-0.1.7/tests/Makefile.in --- libnice-0.1.5/tests/Makefile.in 2014-03-07 02:21:10.000000000 +0000 +++ libnice-0.1.7/tests/Makefile.in 2014-05-05 18:58:20.000000000 +0000 @@ -90,8 +90,8 @@ $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \ $(top_srcdir)/depcomp $(noinst_HEADERS) \ $(top_srcdir)/test-driver -check_PROGRAMS = test-pseudotcp$(EXEEXT) test-bsd$(EXEEXT) \ - test$(EXEEXT) test-address$(EXEEXT) \ +check_PROGRAMS = test-pseudotcp$(EXEEXT) test-pseudotcp-fuzzy$(EXEEXT) \ + test-bsd$(EXEEXT) test$(EXEEXT) test-address$(EXEEXT) \ test-add-remove-stream$(EXEEXT) test-build-io-stream$(EXEEXT) \ test-io-stream-thread$(EXEEXT) \ test-io-stream-closing-write$(EXEEXT) \ @@ -184,6 +184,9 @@ test_pseudotcp_SOURCES = test-pseudotcp.c test_pseudotcp_OBJECTS = test-pseudotcp.$(OBJEXT) test_pseudotcp_DEPENDENCIES = $(am__DEPENDENCIES_2) +test_pseudotcp_fuzzy_SOURCES = test-pseudotcp-fuzzy.c +test_pseudotcp_fuzzy_OBJECTS = test-pseudotcp-fuzzy.$(OBJEXT) +test_pseudotcp_fuzzy_DEPENDENCIES = $(am__DEPENDENCIES_2) test_restart_SOURCES = test-restart.c test_restart_OBJECTS = test-restart.$(OBJEXT) test_restart_DEPENDENCIES = $(am__DEPENDENCIES_2) @@ -236,7 +239,8 @@ $(test_io_stream_pollable_SOURCES) \ $(test_io_stream_thread_SOURCES) test-mainloop.c \ test-new-dribble.c test-priority.c test-pseudotcp.c \ - test-restart.c $(test_send_recv_SOURCES) test-thread.c + test-pseudotcp-fuzzy.c test-restart.c \ + $(test_send_recv_SOURCES) test-thread.c DIST_SOURCES = test.c test-add-remove-stream.c test-address.c \ test-bsd.c test-build-io-stream.c test-dribble.c \ test-fallback.c test-fullmode.c \ @@ -246,7 +250,8 @@ $(test_io_stream_pollable_SOURCES) \ $(test_io_stream_thread_SOURCES) test-mainloop.c \ test-new-dribble.c test-priority.c test-pseudotcp.c \ - test-restart.c $(test_send_recv_SOURCES) test-thread.c + test-pseudotcp-fuzzy.c test-restart.c \ + $(test_send_recv_SOURCES) test-thread.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -639,6 +644,7 @@ TESTS = $(check_PROGRAMS) $(dist_check_SCRIPTS) noinst_HEADERS = test-io-stream-common.h test_pseudotcp_LDADD = $(COMMON_LDADD) +test_pseudotcp_fuzzy_LDADD = $(COMMON_LDADD) -lm test_bsd_LDADD = $(COMMON_LDADD) test_LDADD = $(COMMON_LDADD) test_thread_LDADD = $(COMMON_LDADD) @@ -777,6 +783,10 @@ @rm -f test-pseudotcp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_pseudotcp_OBJECTS) $(test_pseudotcp_LDADD) $(LIBS) +test-pseudotcp-fuzzy$(EXEEXT): $(test_pseudotcp_fuzzy_OBJECTS) $(test_pseudotcp_fuzzy_DEPENDENCIES) $(EXTRA_test_pseudotcp_fuzzy_DEPENDENCIES) + @rm -f test-pseudotcp-fuzzy$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_pseudotcp_fuzzy_OBJECTS) $(test_pseudotcp_fuzzy_LDADD) $(LIBS) + test-restart$(EXEEXT): $(test_restart_OBJECTS) $(test_restart_DEPENDENCIES) $(EXTRA_test_restart_DEPENDENCIES) @rm -f test-restart$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_restart_OBJECTS) $(test_restart_LDADD) $(LIBS) @@ -811,6 +821,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-mainloop.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-new-dribble.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-priority.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-pseudotcp-fuzzy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-pseudotcp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-restart.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-send-recv.Po@am__quote@ @@ -1043,6 +1054,13 @@ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +test-pseudotcp-fuzzy.log: test-pseudotcp-fuzzy$(EXEEXT) + @p='test-pseudotcp-fuzzy$(EXEEXT)'; \ + b='test-pseudotcp-fuzzy'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-bsd.log: test-bsd$(EXEEXT) @p='test-bsd$(EXEEXT)'; \ diff -Nru libnice-0.1.5/tests/test-dribble.c libnice-0.1.7/tests/test-dribble.c --- libnice-0.1.5/tests/test-dribble.c 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/tests/test-dribble.c 2014-04-24 00:30:32.000000000 +0000 @@ -128,15 +128,25 @@ static void cb_component_state_changed (NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data) { + gboolean ready_to_connected = FALSE; g_debug ("test-dribble:%s: %p", G_STRFUNC, data); - if (GPOINTER_TO_UINT (data) == 1) + if (GPOINTER_TO_UINT (data) == 1) { + if (global_lagent_state == NICE_COMPONENT_STATE_READY && + state == NICE_COMPONENT_STATE_CONNECTED) + ready_to_connected = TRUE; global_lagent_state = state; - else if (GPOINTER_TO_UINT (data) == 2) + } else if (GPOINTER_TO_UINT (data) == 2) { + if (global_ragent_state == NICE_COMPONENT_STATE_READY && + state == NICE_COMPONENT_STATE_CONNECTED) + ready_to_connected = TRUE; global_ragent_state = state; - + } + if (state == NICE_COMPONENT_STATE_READY) global_components_ready++; + else if (state == NICE_COMPONENT_STATE_CONNECTED && ready_to_connected) + global_components_ready--; if (state == NICE_COMPONENT_STATE_FAILED) global_components_failed++; @@ -339,7 +349,7 @@ g_timeout_add (500, quit_loop_cb, NULL); g_main_loop_run (global_mainloop); - global_components_ready--; + //global_components_ready--; cands = nice_agent_get_local_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTP); nice_address_set_port(&((NiceCandidate *) cands->data)->addr, 80); diff -Nru libnice-0.1.5/tests/test-fullmode.c libnice-0.1.7/tests/test-fullmode.c --- libnice-0.1.5/tests/test-fullmode.c 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/tests/test-fullmode.c 2014-03-31 23:20:03.000000000 +0000 @@ -155,10 +155,15 @@ return FALSE; } -static void cb_writable (NiceAgent*agent, guint stream_id, guint component_id) +static void cb_writable (NiceAgent*agent, guint stream_id, guint component_id, + gpointer user_data) { + guint *ls_id = user_data; + + if (stream_id == *ls_id && component_id == 1) { g_debug ("Transport is now writable, stopping mainloop"); - g_main_loop_quit (global_mainloop); + *ls_id = 0; + } } static void cb_nice_recv (NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer user_data) @@ -176,6 +181,9 @@ if (strncmp ("12345678", buf, 8)) return; + if (component_id == 2) + return; + if (GPOINTER_TO_UINT (user_data) == 2) { g_debug ("right agent received %d bytes, stopping mainloop", len); global_ragent_read = len; @@ -370,7 +378,7 @@ nice_agent_set_port_range (ragent, rs_id, 2, 10000, 10002); g_assert (nice_agent_gather_candidates (ragent, rs_id) == TRUE); -#ifdef USE_LOOPBACK +#if USE_LOOPBACK { GSList *cands = NULL, *i; NiceCandidate *cand = NULL; @@ -466,10 +474,13 @@ g_debug ("Sending data returned -1 in %s mode", reliable?"Reliable":"Non-reliable"); if (reliable) { gulong signal_handler; + guint ls_id_copy = ls_id; + signal_handler = g_signal_connect (G_OBJECT (lagent), - "reliable-transport-writable", G_CALLBACK (cb_writable), NULL); + "reliable-transport-writable", G_CALLBACK (cb_writable), &ls_id_copy); g_debug ("Running mainloop until transport is writable"); - g_main_loop_run (global_mainloop); + while (ls_id_copy == ls_id) + g_main_context_iteration (NULL, TRUE); g_signal_handler_disconnect(G_OBJECT (lagent), signal_handler); ret = nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678"); @@ -477,7 +488,8 @@ } g_debug ("Sent %d bytes", ret); g_assert (ret == 16); - g_main_loop_run (global_mainloop); + while (global_ragent_read != 16) + g_main_context_iteration (NULL, TRUE); g_assert (global_ragent_read == 16); g_debug ("test-fullmode: Ran mainloop, removing streams..."); @@ -589,14 +601,18 @@ /* note: test payload send and receive */ global_ragent_read = 0; ret = nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678"); - { + if (ret == -1) { gboolean reliable = FALSE; g_object_get (G_OBJECT (lagent), "reliable", &reliable, NULL); if (reliable) { gulong signal_handler; + guint ls_id_copy = ls_id; + signal_handler = g_signal_connect (G_OBJECT (lagent), - "reliable-transport-writable", G_CALLBACK (cb_writable), NULL); - g_main_loop_run (global_mainloop); + "reliable-transport-writable", G_CALLBACK (cb_writable), &ls_id_copy); + g_debug ("Running mainloop until transport is writable"); + while (ls_id_copy == ls_id) + g_main_context_iteration (NULL, TRUE); g_signal_handler_disconnect(G_OBJECT (lagent), signal_handler); ret = nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678"); diff -Nru libnice-0.1.5/tests/test-new-dribble.c libnice-0.1.7/tests/test-new-dribble.c --- libnice-0.1.5/tests/test-new-dribble.c 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/tests/test-new-dribble.c 2014-05-02 21:49:50.000000000 +0000 @@ -192,7 +192,7 @@ if (stun_message_has_cookie (&request)) stun_message_append_xor_addr (&response, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, - &addr.addr, addr_len); + &addr.storage, addr_len); else stun_message_append_addr (&response, STUN_ATTRIBUTE_MAPPED_ADDRESS, &addr.addr, addr_len); diff -Nru libnice-0.1.5/tests/test-pseudotcp.c libnice-0.1.7/tests/test-pseudotcp.c --- libnice-0.1.5/tests/test-pseudotcp.c 2014-03-07 01:21:05.000000000 +0000 +++ libnice-0.1.7/tests/test-pseudotcp.c 2014-03-31 23:20:03.000000000 +0000 @@ -220,7 +220,8 @@ static void adjust_clock (PseudoTcpSocket *sock) { - long timeout = 0; + guint64 timeout = 0; + if (pseudo_tcp_socket_get_next_clock (sock, &timeout)) { timeout -= g_get_monotonic_time () / 1000; g_debug ("Socket %p: Adjuting clock to %ld ms", sock, timeout); diff -Nru libnice-0.1.5/tests/test-pseudotcp-fuzzy.c libnice-0.1.7/tests/test-pseudotcp-fuzzy.c --- libnice-0.1.5/tests/test-pseudotcp-fuzzy.c 1970-01-01 00:00:00.000000000 +0000 +++ libnice-0.1.7/tests/test-pseudotcp-fuzzy.c 2014-04-17 22:14:51.000000000 +0000 @@ -0,0 +1,467 @@ +/* vim: et ts=2 sw=2 tw=80: */ +/* + * This file is part of the Nice GLib ICE library. + * + * (C) 2010, 2014 Collabora Ltd. + * Contact: Philip Withnall + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Nice GLib ICE library. + * + * The Initial Developers of the Original Code are Collabora Ltd and Nokia + * Corporation. All Rights Reserved. + * + * Contributors: + * Philip Withnall, Collabora Ltd. + * Youness Alaoui, Collabora Ltd. + * + * Alternatively, the contents of this file may be used under the terms of the + * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which + * case the provisions of LGPL are applicable instead of those above. If you + * wish to allow use of your version of this file only under the terms of the + * LGPL and not to allow others to use your version of this file under the + * MPL, indicate your decision by deleting the provisions above and replace + * them with the notice and other provisions required by the LGPL. If you do + * not delete the provisions above, a recipient may use your version of this + * file under either the MPL or the LGPL. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include "pseudotcp.h" + + +/** + * A fuzzing test for the pseudotcp socket. This connects two sockets in a + * loopback arrangement, with the packet output from one being fed to the other, + * and vice-versa. Fuzzing happens on the packet interface between the two, + * mutating the packets slightly and seeing what happens. + * + * The input data to the left-most socket is read from a file. The output data + * from the loopback is written to another file, although this probably isn’t + * very useful. If no files are provided, a small amount of dummy data is sent + * through the sockets instead. This almost certainly won’t catch any bugs, and + * is just present to allow this test to be run as part of `make check` so it + * doesn’t bit rot. + * + * A good command to generate an input file is: + * dd if=/dev/urandom of=rand count=10000 ibs=1024 + * + * None of the data is validated, and the test results are effectively the 1-bit + * value of ‘did it crash?’. In particular, the output file is not validated, + * and the TCP packets emitted by both sockets are not checked for validity. + * + * It is suggested that this test is run under GDB and Valgrind. Any crashes or + * errors which are detected can be reproduced by providing the same input file + * and seed (using the --seed option). The seed is printed out at the beginning + * of each test run. + */ + + +PseudoTcpSocket *left; +PseudoTcpSocket *right; +GMainLoop *main_loop = NULL; +GRand *prng = NULL; +gint retval = 0; +FILE *in = NULL; +FILE *out = NULL; +int total_read = 0; +int total_wrote = 0; +guint left_clock = 0; +guint right_clock = 0; +gboolean left_closed = FALSE; +gboolean right_closed = FALSE; +gboolean reading_done = FALSE; + +/* Number of bytes of payload each socket has received so far. */ +guint32 left_stream_pos = 0; +guint32 right_stream_pos = 0; + +/* Configuration options. */ +gint64 seed = 0; +guint32 fuzz_start_pos = 1; /* bytes into stream payload; after the SYN-ACKs */ +guint n_changes_lambda = 2; /* lambda parameter for a Poisson distribution + * controlling the number of mutations made to each + * packet */ + + +static void +adjust_clock (PseudoTcpSocket *sock); + + +static void +write_to_sock (PseudoTcpSocket *sock) +{ + gchar buf[1024]; + gsize len; + gint wlen; + guint total = 0; + + while (TRUE) { + len = fread (buf, 1, sizeof(buf), in); + if (len == 0) { + g_debug ("Done reading data from file"); + g_assert (feof (in)); + reading_done = TRUE; + pseudo_tcp_socket_close (sock, FALSE); + break; + } else { + wlen = pseudo_tcp_socket_send (sock, buf, len); + g_debug ("Sending %" G_GSIZE_FORMAT " bytes : %d", len, wlen); + total += wlen; + total_read += wlen; + if (wlen < (gint) len) { + g_debug ("seeking %ld from %lu", wlen - len, ftell (in)); + fseek (in, wlen - len, SEEK_CUR); + g_assert (!feof (in)); + g_debug ("Socket queue full after %d bytes written", total); + break; + } + } + } + adjust_clock (sock); +} + +static void +opened (PseudoTcpSocket *sock, gpointer data) +{ + g_debug ("Socket %p Opened", sock); + if (sock == left) { + if (in) + write_to_sock (sock); + else { + pseudo_tcp_socket_send (sock, "abcdefghijklmnopqrstuvwxyz", 26); + reading_done = TRUE; + pseudo_tcp_socket_close (sock, FALSE); + } + } +} + +static void +readable (PseudoTcpSocket *sock, gpointer data) +{ + gchar buf[1024]; + gint len; + g_debug ("Socket %p Readable", sock); + + do { + len = pseudo_tcp_socket_recv (sock, buf, sizeof(buf)); + + if (len > 0) { + g_debug ("Read %d bytes", len); + if (out) { + if (fwrite (buf, len, 1, out) == 0) + g_debug ("Error writing to output file"); + else { + total_wrote += len; + + g_assert (total_wrote <= total_read); + g_debug ("Written %d bytes, need %d bytes", total_wrote, total_read); + if (total_wrote == total_read && feof (in)) { + g_assert (reading_done); + pseudo_tcp_socket_close (sock, FALSE); + } + } + } else { + pseudo_tcp_socket_close (sock, FALSE); + } + } + } while (len > 0); + + if (len == -1 && + pseudo_tcp_socket_get_error (sock) != EWOULDBLOCK) { + g_printerr ("Error reading from socket: error code %d.\n", + pseudo_tcp_socket_get_error (sock)); + + retval = -1; + g_main_loop_quit (main_loop); + return; + } +} + +static void +writable (PseudoTcpSocket *sock, gpointer data) +{ + g_debug ("Socket %p Writable", sock); + if (in && sock == left) + write_to_sock (sock); +} + +static void +closed (PseudoTcpSocket *sock, guint32 err, gpointer data) +{ + /* Don’t treat this as an error, since we’re throwing rubbish into the + * socket and can hardly expect it to complete successfully. */ + g_debug ("Socket %p Closed : %d", sock, err); + retval = 0; + g_main_loop_quit (main_loop); +} + +struct notify_data { + PseudoTcpSocket *sock; + guint32 len; + guint32 stream_pos; + guint8 buffer[]; +}; + +/** + * random_int_poisson: + * @lambda: Lambda parameter for the distribution function, which must be + * non-zero + * + * Generate a random variable from a Poisson distribution with parameter + * @lambda. This consumes one %gdouble’s worth of randomness from the global + * @prng. + * + * This is implemented using the inverse transform of the Poisson CDF, and is + * guaranteed to return in time linearly proportional to @lambda. + * + * Returns: Poisson-distributed pseudo-random variable + */ +static guint32 +random_int_poisson (guint lambda) +{ + gdouble U; + guint32 i; + gdouble p, F; + + g_return_val_if_fail (lambda > 0, 0); + + /* + * Reference: http://www.cs.bgu.ac.il/~mps042/invtransnote.htm, + * §Simulating a Poisson random variable. + */ + U = g_rand_double (prng); /* step 1 */ + i = 0; + p = exp (0.0 - (gdouble) lambda); + F = p; /* step 2 */ + + while (U >= F) { /* step 3 */ + p = (lambda * p) / (i + 1); + F += p; + i += 1; /* step 4 and 5 */ + } + + return i; +} + +static guint32 +fuzz_packet (guint8 *buf, guint32 len, guint32 stream_pos) +{ + guint32 i; + guint n_changes; +#define TCP_HEADER_LENGTH 32 /* bytes; or thereabouts (include some options) */ + + /* Do we want to fuzz this packet? */ + if (stream_pos < fuzz_start_pos) { + return len; + } + + /* Get fuzzing. Only bother fuzzing the header; fuzzing the payload is + * pointless. Weight the number of changes towards having only a few changes, + * since that makes them less likely to be summarily rejected. */ + n_changes = random_int_poisson (n_changes_lambda); + g_debug ("Making %u changes for bytes at stream position %u:", + n_changes, stream_pos); + + for (i = 0; i < n_changes; i++) { + guint32 pos = g_rand_int_range (prng, 0, MIN (len, TCP_HEADER_LENGTH)); + g_debug (" • Changing byte %u.", stream_pos + pos); + buf[pos] = g_rand_int_range (prng, 0, G_MAXUINT8 + 1); + } + + return len; +} + +static gboolean +notify_packet (gpointer user_data) +{ + struct notify_data *data = (struct notify_data*) user_data; + + /* Fuzz the packet. */ + data->len = fuzz_packet (data->buffer, data->len, data->stream_pos); + + pseudo_tcp_socket_notify_packet (data->sock, + (gchar *) data->buffer, data->len); + adjust_clock (data->sock); + + g_free (data); + return FALSE; +} + +static PseudoTcpWriteResult +write_packet (PseudoTcpSocket *sock, const gchar *buffer, guint32 len, + gpointer user_data) +{ + struct notify_data *data; + PseudoTcpState state; + g_object_get (sock, "state", &state, NULL); + + data = g_malloc (sizeof(struct notify_data) + len); + + g_debug ("Socket %p(%d) Writing : %d bytes", sock, state, len); + + memcpy (data->buffer, buffer, len); + data->len = len; + + if (sock == left) { + data->stream_pos = left_stream_pos; + left_stream_pos += len; + data->sock = right; + } else { + data->stream_pos = right_stream_pos; + right_stream_pos += len; + data->sock = left; + } + + g_idle_add (notify_packet, data); + + return WR_SUCCESS; +} + + +static gboolean notify_clock (gpointer data) +{ + PseudoTcpSocket *sock = (PseudoTcpSocket *)data; + //g_debug ("Socket %p: Notifying clock", sock); + pseudo_tcp_socket_notify_clock (sock); + adjust_clock (sock); + return FALSE; +} + +static void adjust_clock (PseudoTcpSocket *sock) +{ + guint64 timeout = 0; + + if (pseudo_tcp_socket_get_next_clock (sock, &timeout)) { + timeout -= g_get_monotonic_time () / 1000; + g_debug ("Socket %p: Adjusting clock to %ld ms", sock, timeout); + if (sock == left) { + if (left_clock != 0) + g_source_remove (left_clock); + left_clock = g_timeout_add (timeout, notify_clock, sock); + } else { + if (right_clock != 0) + g_source_remove (right_clock); + right_clock = g_timeout_add (timeout, notify_clock, sock); + } + } else { + g_debug ("Socket %p should be destroyed, it's done", sock); + if (sock == left) + left_closed = TRUE; + else + right_closed = TRUE; + if (left_closed && right_closed) + g_main_loop_quit (main_loop); + } +} + +static GOptionEntry entries[] = { + { "seed", 's', 0, G_OPTION_ARG_INT64, &seed, "PRNG seed", "N" }, + { "fuzz-start-position", 'p', 0, G_OPTION_ARG_INT, &fuzz_start_pos, + "Number of bytes into the stream to start fuzzing after", "B" }, + { "fuzz-n-changes-lambda", 'l', 0, G_OPTION_ARG_INT, &n_changes_lambda, + "Lambda value for the Poisson distribution controlling the number of " + "changes made to each packet", "λ" }, + { NULL } +}; + +int main (int argc, char *argv[]) +{ + PseudoTcpCallbacks cbs = { + NULL, opened, readable, writable, closed, write_packet + }; + GOptionContext *context; + GError *error = NULL; + + setlocale (LC_ALL, ""); + g_type_init (); + + /* Configuration. */ + context = g_option_context_new ("— fuzz-test the pseudotcp socket"); + g_option_context_add_main_entries (context, entries, NULL); + + if (!g_option_context_parse (context, &argc, &argv, &error)) { + g_printerr ("Option parsing failed: %s\n", error->message); + goto context_error; + } + + if (n_changes_lambda == 0) { + g_printerr ("Option parsing failed: %s\n", + "Lambda values must be positive."); + goto context_error; + } + + g_option_context_free (context); + + /* Tweak the configuration. */ + if (seed == 0) { + seed = g_get_real_time (); + } + + /* Open the input and output files */ + if (argc >= 3) { + in = fopen (argv[1], "r"); + out = fopen (argv[2], "w"); + } + + /* Set up the main loop and sockets. */ + main_loop = g_main_loop_new (NULL, FALSE); + + g_print ("Using seed: %" G_GINT64_FORMAT ", start position: %u, λ: %u\n", + seed, fuzz_start_pos, n_changes_lambda); + prng = g_rand_new_with_seed (seed); + + pseudo_tcp_set_debug_level (PSEUDO_TCP_DEBUG_VERBOSE); + + left = pseudo_tcp_socket_new (0, &cbs); + right = pseudo_tcp_socket_new (0, &cbs); + g_debug ("Left: %p. Right: %p", left, right); + + pseudo_tcp_socket_notify_mtu (left, 1496); + pseudo_tcp_socket_notify_mtu (right, 1496); + + pseudo_tcp_socket_connect (left); + adjust_clock (left); + adjust_clock (right); + + /* Run the main loop. */ + g_main_loop_run (main_loop); + g_main_loop_unref (main_loop); + + g_object_unref (left); + g_object_unref (right); + + g_rand_free (prng); + + if (in != NULL) + fclose (in); + if (out != NULL) + fclose (out); + + return retval; + +context_error: + g_printerr ("\n%s\n", g_option_context_get_help (context, TRUE, NULL)); + g_option_context_free (context); + + return 1; +} diff -Nru libnice-0.1.5/tests/test-send-recv.c libnice-0.1.7/tests/test-send-recv.c --- libnice-0.1.5/tests/test-send-recv.c 2014-03-07 02:14:00.000000000 +0000 +++ libnice-0.1.7/tests/test-send-recv.c 2014-03-31 23:18:17.000000000 +0000 @@ -186,7 +186,7 @@ * Guaranteed to be in the interval [1, 1 << 16). ((1 << 16) is the maximum * message size.) */ static gsize -generate_buffer_size (BufferSizeStrategy strategy, GRand *rand, +generate_buffer_size (BufferSizeStrategy strategy, GRand *grand, gsize buffer_offset) { switch (strategy) { @@ -203,7 +203,7 @@ return CLAMP (1L << buffer_offset, 1, (1 << 16) - 1); case BUFFER_SIZE_RANDOM: - return g_rand_int_range (rand, 1, 1 << 16); + return g_rand_int_range (grand, 1, 1 << 16); default: g_assert_not_reached (); @@ -214,7 +214,7 @@ * byte. Guaranteed to be in the interval [1, 100], where 100 was chosen * arbitrarily.*/ static guint -generate_buffer_count (BufferCountStrategy strategy, GRand *rand, +generate_buffer_count (BufferCountStrategy strategy, GRand *grand, gsize buffer_offset) { switch (strategy) { @@ -225,7 +225,7 @@ return 2; case BUFFER_COUNT_RANDOM: - return g_rand_int_range (rand, 1, 100 + 1); + return g_rand_int_range (grand, 1, 100 + 1); default: g_assert_not_reached (); @@ -236,7 +236,7 @@ * @buffer_offset-th byte. Guaranteed to be in the interval [1, 100], where 100 * was chosen arbitrarily.*/ static guint -generate_message_count (MessageCountStrategy strategy, GRand *rand, +generate_message_count (MessageCountStrategy strategy, GRand *grand, guint buffer_index) { switch (strategy) { @@ -247,7 +247,7 @@ return 2; case MESSAGE_COUNT_RANDOM: - return g_rand_int_range (rand, 1, 100 + 1); + return g_rand_int_range (grand, 1, 100 + 1); default: g_assert_not_reached (); diff -Nru libnice-0.1.5/win32/dogenmarshal.cmd libnice-0.1.7/win32/dogenmarshal.cmd --- libnice-0.1.5/win32/dogenmarshal.cmd 2014-01-06 23:05:13.000000000 +0000 +++ libnice-0.1.7/win32/dogenmarshal.cmd 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -..\glib\bin\glib-genmarshal.exe --header --prefix=agent_marshal ..\agent\agent-signals-marshal.list > ..\agent\agent-signals-marshal.h -echo #include "agent-signals-marshal.h" > ..\agent\agent-signals-marshal.c -..\glib\bin\glib-genmarshal.exe --body --prefix=agent_marshal ..\agent\agent-signals-marshal.list >> ..\agent\agent-signals-marshal.c diff -Nru libnice-0.1.5/win32/vs9/libnice.def libnice-0.1.7/win32/vs9/libnice.def --- libnice-0.1.5/win32/vs9/libnice.def 2014-01-06 23:05:13.000000000 +0000 +++ libnice-0.1.7/win32/vs9/libnice.def 2014-04-25 01:09:45.000000000 +0000 @@ -21,6 +21,7 @@ nice_agent_add_local_address nice_agent_add_stream nice_agent_attach_recv +nice_agent_forget_relays nice_agent_gather_candidates nice_agent_generate_local_candidate_sdp nice_agent_generate_local_sdp @@ -53,6 +54,7 @@ nice_candidate_copy nice_candidate_free nice_candidate_new +nice_component_state_to_string nice_debug_disable nice_debug_enable nice_interfaces_get_ip_for_interface diff -Nru libnice-0.1.5/win32/vs9/libnice.vcproj libnice-0.1.7/win32/vs9/libnice.vcproj --- libnice-0.1.5/win32/vs9/libnice.vcproj 2014-01-06 23:05:13.000000000 +0000 +++ libnice-0.1.7/win32/vs9/libnice.vcproj 2014-04-04 03:52:17.000000000 +0000 @@ -191,14 +191,6 @@ > - - - -