Commit 17d8474e authored by Olivier Crête's avatar Olivier Crête

merge bellet

parents 55276cbf 14b2f2d9
......@@ -2,5 +2,6 @@
"phabricator.uri" : "https:\/\/phabricator.freedesktop.org\/",
"history.immutable" : true,
"project.name" : "libnice",
"repository.callsign" : "LIBNICE"
"repository.callsign" : "LIBNICE",
"default-reviewers" : "#libnice"
}
......@@ -154,6 +154,7 @@ tests/test-restart
tests/test-tcp
tests/test-thread
tests/test-new-dribble
tests/test-nomination
# examples/ stuff
examples/simple-example
......
......@@ -17,8 +17,8 @@ SUBDIRS = \
agent \
nice \
gst \
docs \
tests \
docs \
examples
DISTCHECK_CONFIGURE_FLAGS = --disable-assert -enable-gtk-doc --enable-introspection
......@@ -47,6 +47,7 @@ dist_check_SCRIPTS = \
# but not Linux, for no particular reason. They can’t be removed without
# breaking ABI. FIXME: Remove them when we next break ABI.
win32/vs9/libnice.def: nice/libnice.sym
$(MKDIR_P) $(dir $@)
$(AM_V_GEN)(echo "LIBRARY libnice"; \
echo ""; \
echo "EXPORTS"; \
......
libnice 0.1.14 (2017-04-03)
===========================
Improved RFC compliance
Split verbose logs into a separate option
Numerous bug fixes
Use GnuTLS for hash functions
Implement NewReno in PseudoTCP
Requires GLib 2.44 GnuTLS 2.12
libnice 0.1.13 (2015-04-28)
===========================
Fix build on non-Windows platforms that don't have getifaddrs()
......
......@@ -5,7 +5,7 @@ Nice: GLib ICE library
Copyright
---------
(C) 2006-2011 Collabora Ltd.
(C) 2006-2017 Collabora Ltd.
(C) 2006-2011 Nokia Corporation
License
......@@ -16,10 +16,12 @@ See the file COPYING.
Requirements
------------
glib >= 2.10
glib >= 2.44
pkg-config
gnutls >= 2.12.0
gupnp-igd >= 0.1.2 (optional)
gstreamer-0.10 >= 0.10.0 (optional)
gstreamer-1.0 (optional)
Build instructions
------------------
......@@ -50,7 +52,7 @@ Relevant standards
These standards are relevant to nice's current implementation.
ICE draft 15
ICE RFC 5245
http://tools.ietf.org/html/rfc5245
STUN
http://tools.ietf.org/html/rfc3489
......
......@@ -22,6 +22,12 @@ if WINDOWS
AM_CFLAGS += -DWINVER=0x0501 # _WIN32_WINNT_WINXP
endif
BUILT_SOURCES = \
agent-enum-types.h \
agent-enum-types.c
CLEANFILES += $(BUILT_SOURCES)
noinst_LTLIBRARIES = libagent.la
libagent_la_SOURCES = \
......@@ -54,6 +60,23 @@ libagent_la_SOURCES = \
pseudo-tcp-output-stream.h \
$(BUILT_SOURCES)
agent-enum-types.h: agent.h Makefile
$(AM_V_GEN)$(GLIB_MKENUMS) \
--fhead "#ifndef __AGENT_ENUM_TYPES_H__\n#define __AGENT_ENUM_TYPES_H__ 1\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS\n" \
--fprod "/* enumerations from \"@filename@\" */\n" \
--vhead "GType @enum_name@_get_type (void) G_GNUC_CONST;\n#define NICE_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \
--ftail "G_END_DECLS\n\n#endif /* !AGENT_ENUM_TYPES_H */" \
$(addprefix $(srcdir)/,agent.h) > $@
agent-enum-types.c: agent.h Makefile agent-enum-types.h
$(AM_V_GEN)$(GLIB_MKENUMS) \
--fhead "#include <config.h>\n#include <glib-object.h>\n#include \"agent.h\"\n#include \"agent-enum-types.h\"" \
--fprod "\n/* enumerations from \"@filename@\" */" \
--vhead "GType\n@enum_name@_get_type (void)\n{\n static GType type = 0;\n if (!type) {\n static const G@Type@Value values[] = {" \
--vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
--vtail " { 0, NULL, NULL }\n };\n type = g_@type@_register_static (\"@EnumName@\", values);\n }\n return type;\n}\n\n" \
$(addprefix $(srcdir)/,agent.h) > $@
libagent_la_LIBADD = \
$(top_builddir)/random/libnice-random.la \
$(top_builddir)/socket/libsocket.la \
......
......@@ -116,12 +116,32 @@ nice_input_message_iter_compare (const NiceInputMessageIter *a,
* MTU and estimated typical sizes of ICE STUN packet */
#define MAX_STUN_DATAGRAM_PAYLOAD 1300
#define NICE_COMPONENT_MAX_VALID_CANDIDATES 50 /* maximum number of validates remote candidates to keep, the number is arbitrary but hopefully large enough */
/* A convenient macro to test if the agent is compatible with RFC5245
* or OC2007R2. Specifically these two modes share the support
* of the regular or aggressive nomination mode */
#define NICE_AGENT_IS_COMPATIBLE_WITH_RFC5245_OR_OC2007R2(obj) \
((obj)->compatibility == NICE_COMPATIBILITY_RFC5245 || \
(obj)->compatibility == NICE_COMPATIBILITY_OC2007R2)
/* A grace period before declaring a component as failed, in msecs. This
* delay is added to reduce the chance to see the agent receiving new
* stun activity just after the conncheck list has been declared failed,
* reactiviting conncheck activity, and causing a (valid) state
* transitions like that: connecting -> failed -> connecting ->
* connected -> ready.
* Such transitions are not buggy per-se, but may break the
* test-suite, that counts precisely the number of time each state
* has been set, and doesnt expect these transcient failed states.
*/
#define NICE_AGENT_MAX_TIMER_GRACE_PERIOD 1000
struct _NiceAgent
{
GObject parent; /* gobject pointer */
gboolean full_mode; /* property: full-mode */
GTimeVal next_check_tv; /* property: next conncheck timestamp */
gchar *stun_server_ip; /* property: STUN server IP */
guint stun_server_port; /* property: STUN server port */
gchar *proxy_ip; /* property: Proxy server IP */
......@@ -134,6 +154,7 @@ struct _NiceAgent
guint max_conn_checks; /* property: max connectivity checks */
gboolean force_relay; /* property: force relay */
gboolean turn_short_term; /* property: turn short term credentials */
NiceNominationMode nomination_mode; /* property: Nomination mode */
GSList *local_addresses; /* list of NiceAddresses for local
interfaces */
......@@ -167,6 +188,8 @@ struct _NiceAgent
guint16 rfc4571_expecting_length;
gboolean use_ice_udp;
gboolean use_ice_tcp;
guint conncheck_timer_grace_period; /* ongoing delay before timer stop */
/* XXX: add pointer to internal data struct for ABI-safe extensions */
};
......
......@@ -72,6 +72,9 @@
#include "stream.h"
#include "interfaces.h"
#include "pseudotcp.h"
#include "agent-enum-types.h"
/* Maximum size of a UDP packet’s payload, as the packet’s length field is 16b
* wide. */
#define MAX_BUFFER_SIZE ((1 << 16) - 1) /* 65535 */
......@@ -108,7 +111,8 @@ enum
PROP_BYTESTREAM_TCP,
PROP_KEEPALIVE_CONNCHECK,
PROP_FORCE_RELAY,
PROP_TURN_SHORT_TERM
PROP_TURN_SHORT_TERM,
PROP_NOMINATION_MODE
};
......@@ -242,11 +246,11 @@ agent_to_ice_compatibility (NiceAgent *agent)
agent->compatibility == NICE_COMPATIBILITY_MSN ?
STUN_USAGE_ICE_COMPATIBILITY_MSN :
agent->compatibility == NICE_COMPATIBILITY_WLM2009 ?
STUN_USAGE_ICE_COMPATIBILITY_WLM2009 :
STUN_USAGE_ICE_COMPATIBILITY_MSICE2 :
agent->compatibility == NICE_COMPATIBILITY_OC2007 ?
STUN_USAGE_ICE_COMPATIBILITY_MSN :
agent->compatibility == NICE_COMPATIBILITY_OC2007R2 ?
STUN_USAGE_ICE_COMPATIBILITY_WLM2009 :
STUN_USAGE_ICE_COMPATIBILITY_MSICE2 :
STUN_USAGE_ICE_COMPATIBILITY_RFC5245;
}
......@@ -425,6 +429,24 @@ nice_agent_class_init (NiceAgentClass *klass)
0, /* default set in init */
G_PARAM_READWRITE));
/**
* NiceAgent:nomination-mode:
*
* The nomination mode used in the ICE specification for describing
* the selection of valid pairs to be used upstream.
* <para> See also: #NiceNominationMode </para>
*
* Since: UNRELEASED
*/
g_object_class_install_property (gobject_class, PROP_NOMINATION_MODE,
g_param_spec_enum (
"nomination-mode",
"ICE nomination mode",
"Nomination mode used in the ICE specification for describing "
"the selection of valid pairs to be used upstream",
NICE_TYPE_NOMINATION_MODE, NICE_NOMINATION_MODE_AGGRESSIVE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
/**
* NiceAgent:proxy-ip:
*
......@@ -671,7 +693,7 @@ nice_agent_class_init (NiceAgentClass *klass)
* local candidates are available before relay servers have been set
* with nice_agent_set_relay_info().
*
* Since: UNRELEASED
* Since: 0.1.14
*/
g_object_class_install_property (gobject_class, PROP_FORCE_RELAY,
g_param_spec_boolean (
......@@ -986,6 +1008,7 @@ nice_agent_init (NiceAgent *agent)
agent->stun_server_port = DEFAULT_STUN_PORT;
agent->controlling_mode = TRUE;
agent->max_conn_checks = NICE_AGENT_MAX_CONNECTIVITY_CHECKS_DEFAULT;
agent->nomination_mode = NICE_NOMINATION_MODE_AGGRESSIVE;
agent->discovery_list = NULL;
agent->discovery_unsched_items = 0;
......@@ -1018,6 +1041,21 @@ nice_agent_new (GMainContext *ctx, NiceCompatibility compat)
return agent;
}
NICEAPI_EXPORT NiceAgent *
nice_agent_new_regular_nomination (GMainContext *ctx, NiceCompatibility compat)
{
NiceAgent *agent = g_object_new (NICE_TYPE_AGENT,
"compatibility", compat,
"main-context", ctx,
"reliable", FALSE,
"nomination-mode", NICE_NOMINATION_MODE_REGULAR,
NULL);
return agent;
}
static void
nice_agent_get_property (
GObject *object,
......@@ -1064,6 +1102,10 @@ nice_agent_get_property (
/* XXX: should we prune the list of already existing checks? */
break;
case PROP_NOMINATION_MODE:
g_value_set_enum (value, agent->nomination_mode);
break;
case PROP_PROXY_IP:
g_value_set_string (value, agent->proxy_ip);
break;
......@@ -1149,7 +1191,7 @@ nice_agent_init_stun_agent (NiceAgent *agent, StunAgent *stun_agent)
STUN_AGENT_USAGE_FORCE_VALIDATER);
} else if (agent->compatibility == NICE_COMPATIBILITY_WLM2009) {
stun_agent_init (stun_agent, STUN_ALL_KNOWN_ATTRIBUTES,
STUN_COMPATIBILITY_WLM2009,
STUN_COMPATIBILITY_MSICE2,
STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS |
STUN_AGENT_USAGE_USE_FINGERPRINT);
} else if (agent->compatibility == NICE_COMPATIBILITY_OC2007) {
......@@ -1160,7 +1202,7 @@ nice_agent_init_stun_agent (NiceAgent *agent, StunAgent *stun_agent)
STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES);
} else if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) {
stun_agent_init (stun_agent, STUN_ALL_KNOWN_ATTRIBUTES,
STUN_COMPATIBILITY_WLM2009,
STUN_COMPATIBILITY_MSICE2,
STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS |
STUN_AGENT_USAGE_USE_FINGERPRINT |
STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES);
......@@ -1249,6 +1291,10 @@ nice_agent_set_property (
agent->max_conn_checks = g_value_get_uint (value);
break;
case PROP_NOMINATION_MODE:
agent->nomination_mode = g_value_get_enum (value);
break;
case PROP_PROXY_IP:
g_free (agent->proxy_ip);
agent->proxy_ip = g_value_dup_string (value);
......@@ -1345,6 +1391,17 @@ void agent_gathering_done (NiceAgent *agent)
for (i = agent->streams; i; i = i->next) {
NiceStream *stream = i->data;
/* We ignore streams not in gathering state, typically already in
* ready state. Such streams may have couples (local,remote)
* candidates that have not resulted in the creation a new pair
* during a previous conncheck session, and we don't want these new
* pairs to be added now, because it would generate unneeded
* transition changes for a stream unconcerned by this gathering.
*/
if (!stream->gathering)
continue;
for (j = stream->components; j; j = j->next) {
NiceComponent *component = j->data;
......@@ -2122,29 +2179,30 @@ nice_agent_gather_candidates (
}
}
/* generate a local host candidate for each local address */
for (i = local_addresses; i; i = i->next) {
NiceAddress *addr = i->data;
NiceCandidate *host_candidate;
for (cid = 1; cid <= stream->n_components; cid++) {
NiceComponent *component = nice_stream_find_component_by_id (stream, cid);
gboolean found_local_address = FALSE;
enum {
ADD_HOST_MIN = 0,
ADD_HOST_UDP = ADD_HOST_MIN,
ADD_HOST_TCP_ACTIVE,
ADD_HOST_TCP_PASSIVE,
ADD_HOST_MAX = ADD_HOST_TCP_PASSIVE
} add_type;
if (component == NULL)
continue;
/* generate a local host candidate for each local address */
for (i = local_addresses; i; i = i->next) {
NiceAddress *addr = i->data;
NiceCandidate *host_candidate;
#ifdef HAVE_GUPNP
gchar local_ip[NICE_ADDRESS_STRING_LEN];
nice_address_to_string (addr, local_ip);
gchar local_ip[NICE_ADDRESS_STRING_LEN];
nice_address_to_string (addr, local_ip);
#endif
for (cid = 1; cid <= stream->n_components; cid++) {
NiceComponent *component = nice_stream_find_component_by_id (stream, cid);
enum {
ADD_HOST_MIN = 0,
ADD_HOST_UDP = ADD_HOST_MIN,
ADD_HOST_TCP_ACTIVE,
ADD_HOST_TCP_PASSIVE,
ADD_HOST_MAX = ADD_HOST_TCP_PASSIVE
} add_type;
if (component == NULL)
continue;
for (add_type = ADD_HOST_MIN; add_type <= ADD_HOST_MAX; add_type++) {
NiceCandidateTransport transport;
guint current_port;
......@@ -2194,8 +2252,7 @@ nice_agent_gather_candidates (
} else if (res == HOST_CANDIDATE_FAILED) {
nice_debug ("Agent %p: Could ot retrieive component %d/%d", agent,
stream->id, cid);
ret = FALSE;
goto error;
continue;
} else if (res == HOST_CANDIDATE_CANT_CREATE_SOCKET) {
if (nice_debug_is_enabled ()) {
gchar ip[NICE_ADDRESS_STRING_LEN];
......@@ -2204,14 +2261,10 @@ nice_agent_gather_candidates (
" s%d:%d. Invalid interface?", agent, ip, stream->id,
component->id);
}
if (agent->local_addresses == NULL) {
/* Ignore when an auto-generated address fails. */
continue;
}
ret = FALSE;
goto error;
continue;
}
found_local_address = TRUE;
nice_address_set_port (addr, 0);
#ifdef HAVE_GUPNP
......@@ -2249,10 +2302,15 @@ nice_agent_gather_candidates (
if (agent->full_mode && component &&
transport != NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE) {
GList *item;
int host_ip_version = nice_address_ip_version (&host_candidate->addr);
for (item = component->turn_servers; item; item = item->next) {
TurnServer *turn = item->data;
if (host_ip_version != nice_address_ip_version (&turn->server)) {
continue;
}
priv_add_new_candidate_discovery_turn (agent,
host_candidate->sockptr,
turn,
......@@ -2263,6 +2321,13 @@ nice_agent_gather_candidates (
}
}
}
/* Go to error if we could not find a local address for a given
* component
*/
if (!found_local_address) {
ret = FALSE;
goto error;
}
}
stream->gathering = TRUE;
......@@ -2337,6 +2402,9 @@ void agent_remove_local_candidate (NiceAgent *agent, NiceCandidate *candidate)
if (candidate->type != NICE_CANDIDATE_TYPE_HOST)
return;
if (nice_address_get_port (&candidate->addr) == 0)
return;
nice_address_to_string (&candidate->addr, local_ip);
gupnp_simple_igd_remove_port_local (GUPNP_SIMPLE_IGD (agent->upnp), "UDP",
......@@ -2477,6 +2545,13 @@ static gboolean priv_add_remote_candidate (
NiceComponent *component;
NiceCandidate *candidate;
if (transport == NICE_CANDIDATE_TRANSPORT_UDP &&
!agent->use_ice_udp)
return FALSE;
if (transport != NICE_CANDIDATE_TRANSPORT_UDP &&
!agent->use_ice_tcp)
return FALSE;
if (!agent_find_component (agent, stream_id, component_id, NULL, &component))
return FALSE;
......@@ -2559,6 +2634,19 @@ static gboolean priv_add_remote_candidate (
username, password, priority);
}
if (NICE_AGENT_IS_COMPATIBLE_WITH_RFC5245_OR_OC2007R2 (agent)) {
/* note: If there are TCP candidates for a media stream,
* a controlling agent MUST use the regular selection algorithm,
* RFC 6544, sect 8, "Concluding ICE Processing"
*/
if (agent->nomination_mode == NICE_NOMINATION_MODE_AGGRESSIVE &&
transport != NICE_CANDIDATE_TRANSPORT_UDP) {
nice_debug ("Agent %p : we have TCP candidates, switching back "
"to regular nomination mode", agent);
agent->nomination_mode = NICE_NOMINATION_MODE_REGULAR;
}
}
if (base_addr)
candidate->base_addr = *base_addr;
......@@ -2604,6 +2692,8 @@ nice_agent_set_remote_credentials (
g_strlcpy (stream->remote_ufrag, ufrag, NICE_STREAM_MAX_UFRAG);
g_strlcpy (stream->remote_password, pwd, NICE_STREAM_MAX_PWD);
conn_check_remote_credentials_set(agent, stream);
ret = TRUE;
goto done;
}
......@@ -2706,8 +2796,6 @@ _set_remote_candidates_locked (NiceAgent *agent, NiceStream *stream,
}
}
conn_check_remote_candidates_set(agent, stream, component);
if (added > 0) {
conn_check_schedule_next (agent);
}
......@@ -2787,7 +2875,8 @@ agent_recv_message_unlocked (
{
NiceAddress from;
GList *item;
gint retval;
RecvStatus retval;
gint sockret;
gboolean is_turn = FALSE;
/* We need an address for packet parsing, below. */
......@@ -2820,7 +2909,7 @@ agent_recv_message_unlocked (
if (cand->type == NICE_CANDIDATE_TYPE_RELAYED &&
cand->stream_id == stream->id &&
cand->component_id == component->id &&
((NiceSocket *)cand->sockptr)->fileno == nicesock->fileno) {
nice_socket_is_based_on(cand->sockptr, nicesock)) {
nice_debug ("Agent %p : Packet received from a TURN socket.",
agent);
nicesock = cand->sockptr;
......@@ -2848,8 +2937,8 @@ agent_recv_message_unlocked (
local_bufs[i + 1].buffer = message->buffers[i].buffer;
local_bufs[i + 1].size = message->buffers[i].size;
}
retval = nice_socket_recv_messages (nicesock, &local_message, 1);
if (retval == 1) {
sockret = nice_socket_recv_messages (nicesock, &local_message, 1);
if (sockret == 1) {
message->length = ntohs (rfc4571_frame);
}
} else {
......@@ -2864,7 +2953,7 @@ agent_recv_message_unlocked (
_priv_set_socket_tos (agent, new_socket, stream->tos);
nice_component_attach_socket (component, new_socket);
}
retval = 0;
sockret = 0;
} else {
/* In the case of a real ICE-TCP connection, we can use the socket as a
* bytestream and do the read here with caching of data being read
......@@ -2873,9 +2962,9 @@ agent_recv_message_unlocked (
/* TODO: Support bytestream reads */
message->length = 0;
retval = 0;
sockret = 0;
if (available <= 0) {
retval = available;
sockret = available;
/* If we don't call check_connect_result on an outbound connection,
* then is_connected will always return FALSE. That's why we check
......@@ -2888,7 +2977,7 @@ agent_recv_message_unlocked (
* not connected, it means that it failed to connect, so we must
* return an error to make the socket fail/closed
*/
retval = -1;
sockret = -1;
} else {
gint flags = G_SOCKET_MSG_PEEK;
......@@ -2901,7 +2990,7 @@ agent_recv_message_unlocked (
*/
if (g_socket_receive_message (nicesock->fileno, NULL,
NULL, 0, NULL, NULL, &flags, NULL, NULL) == 0)
retval = -1;
sockret = -1;
}
} else if (agent->rfc4571_expecting_length == 0) {
if ((gsize) available >= sizeof(guint16)) {
......@@ -2909,8 +2998,8 @@ agent_recv_message_unlocked (
GInputVector local_buf = { &rfc4571_frame, sizeof(guint16)};
NiceInputMessage local_message = { &local_buf, 1, message->from, 0};
retval = nice_socket_recv_messages (nicesock, &local_message, 1);
if (retval == 1) {
sockret = nice_socket_recv_messages (nicesock, &local_message, 1);
if (sockret == 1) {
agent->rfc4571_expecting_length = ntohs (rfc4571_frame);
available = g_socket_get_available_bytes (nicesock->fileno);
}
......@@ -2954,8 +3043,8 @@ agent_recv_message_unlocked (
off += local_bufs[i].size;
}
}
retval = nice_socket_recv_messages (nicesock, &local_message, 1);
if (retval == 1) {
sockret = nice_socket_recv_messages (nicesock, &local_message, 1);
if (sockret == 1) {
message->length = local_message.length;
agent->rfc4571_expecting_length -= local_message.length;
}
......@@ -2963,33 +3052,38 @@ agent_recv_message_unlocked (
}
}
} else {
retval = nice_socket_recv_messages (nicesock, message, 1);
sockret = nice_socket_recv_messages (nicesock, message, 1);
}
nice_debug_verbose ("%s: Received %d valid messages of length %" G_GSIZE_FORMAT
" from base socket %p.", G_STRFUNC, retval, message->length, nicesock);
if (retval == 0) {
if (sockret == 0) {
retval = RECV_WOULD_BLOCK; /* EWOULDBLOCK */
nice_debug_verbose ("%s: Agent %p: no message available on read attempt",
G_STRFUNC, agent);
goto done;
} else if (retval < 0) {
} else if (sockret < 0) {
nice_debug ("Agent %p: %s returned %d, errno (%d) : %s",
agent, G_STRFUNC, retval, errno, g_strerror (errno));
agent, G_STRFUNC, sockret, errno, g_strerror (errno));
retval = RECV_ERROR;
goto done;
} else {
retval = sockret;
}
if (retval == RECV_OOB || message->length == 0) {
g_assert (retval != RECV_OOB);
if (message->length == 0) {
retval = RECV_OOB;
nice_debug_verbose ("%s: Agent %p: message handled out-of-band", G_STRFUNC,
agent);
goto done;
}
if (nice_debug_is_verbose ()) {
gchar tmpbuf[INET6_ADDRSTRLEN];
nice_address_to_string (message->from, tmpbuf);
nice_debug_verbose ("Agent %p : Packet received on local socket %d from [%s]:%u (%" G_GSSIZE_FORMAT " octets).", agent,
g_socket_get_fd (nicesock->fileno), tmpbuf,
nice_debug_verbose ("%s: Agent %p : Packet received on local socket %p "
"(fd %d) from [%s]:%u (%" G_GSSIZE_FORMAT " octets).", G_STRFUNC, agent,
nicesock, g_socket_get_fd (nicesock->fileno), tmpbuf,
nice_address_get_port (message->from), message->length);
}
......@@ -3041,8 +3135,6 @@ agent_recv_message_unlocked (
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
* a STUN message; otherwise it’s probably data. */
if (stun_message_validate_buffer_length_fast (
......@@ -3074,6 +3166,7 @@ agent_recv_message_unlocked (
nice_debug ("%s: Valid STUN packet received.", G_STRFUNC);
retval = RECV_OOB;
g_free (big_buf);
agent->media_after_tick = TRUE;
goto done;
}
}
......@@ -3596,7 +3689,6 @@ nice_agent_recv_messages_blocking_or_nonblocking (NiceAgent *agent,
"Component removed during call.");
component = NULL;
error_reported = TRUE;
goto recv_error;
}
......@@ -4241,21 +4333,26 @@ component_io_cb (GSocket *gsocket, GIOCondition condition, gpointer user_data)
retval = agent_recv_message_unlocked (agent, stream, component,
socket_source->socket, &local_message);
nice_debug_verbose ("%s: %p: received %d valid messages with %" G_GSSIZE_FORMAT
" bytes", G_STRFUNC, agent, retval, local_message.length);
if (retval == RECV_WOULD_BLOCK) {
/* EWOULDBLOCK. */
nice_debug_verbose ("%s: %p: no message available on read attempt",
G_STRFUNC, agent);
break;