Commit 747364e2 authored by Olivier Crête's avatar Olivier Crête

discovery: Differentiate socket creation failure from other errors

If the socket can't be bound, then trying another port makes sense,
otherwise it doesn't.
parent 9f0dfa2d
...@@ -2482,6 +2482,7 @@ nice_agent_gather_candidates ( ...@@ -2482,6 +2482,7 @@ nice_agent_gather_candidates (
NiceCandidateTransport transport; NiceCandidateTransport transport;
guint current_port; guint current_port;
guint start_port; guint start_port;
HostCandidateResult res = HOST_CANDIDATE_CANT_CREATE_SOCKET;
if ((agent->use_ice_udp == FALSE && add_type == ADD_HOST_UDP) || if ((agent->use_ice_udp == FALSE && add_type == ADD_HOST_UDP) ||
(agent->use_ice_tcp == FALSE && add_type != ADD_HOST_UDP)) (agent->use_ice_tcp == FALSE && add_type != ADD_HOST_UDP))
...@@ -2507,20 +2508,28 @@ nice_agent_gather_candidates ( ...@@ -2507,20 +2508,28 @@ nice_agent_gather_candidates (
current_port = start_port; current_port = start_port;
host_candidate = NULL; host_candidate = NULL;
while (host_candidate == NULL) { while (res == HOST_CANDIDATE_CANT_CREATE_SOCKET) {
nice_debug ("Agent %p: Trying to create host candidate on port %d", agent, current_port); nice_debug ("Agent %p: Trying to create host candidate on port %d", agent, current_port);
nice_address_set_port (addr, current_port); nice_address_set_port (addr, current_port);
host_candidate = discovery_add_local_host_candidate (agent, stream->id, res = discovery_add_local_host_candidate (agent, stream->id, cid,
cid, addr, transport); addr, transport, &host_candidate);
if (current_port > 0) if (current_port > 0)
current_port++; current_port++;
if (current_port > component->max_port) current_port = component->min_port; if (current_port > component->max_port) current_port = component->min_port;
if (current_port == 0 || current_port == start_port) if (current_port == 0 || current_port == start_port)
break; break;
} }
nice_address_set_port (addr, 0);
if (!host_candidate) { if (res == HOST_CANDIDATE_REDUNDANT) {
nice_debug ("Agent %p: Ignoring local candidate, it's redundant",
agent);
continue;
} else if (res == HOST_CANDIDATE_FAILED) {
nice_debug ("Agent %p: Could ot retrieive component %d/%d", agent,
stream->id, cid);
ret = FALSE;
goto error;
} else if (res == HOST_CANDIDATE_CANT_CREATE_SOCKET) {
if (nice_debug_is_enabled ()) { if (nice_debug_is_enabled ()) {
gchar ip[NICE_ADDRESS_STRING_LEN]; gchar ip[NICE_ADDRESS_STRING_LEN];
nice_address_to_string (addr, ip); nice_address_to_string (addr, ip);
...@@ -2532,6 +2541,9 @@ nice_agent_gather_candidates ( ...@@ -2532,6 +2541,9 @@ nice_agent_gather_candidates (
goto error; goto error;
} }
nice_address_set_port (addr, 0);
if (agent->reliable) if (agent->reliable)
nice_socket_set_writable_callback (host_candidate->sockptr, nice_socket_set_writable_callback (host_candidate->sockptr,
_tcp_sock_is_writable, component); _tcp_sock_is_writable, component);
...@@ -4077,7 +4089,8 @@ nice_agent_send_messages_nonblocking_internal ( ...@@ -4077,7 +4089,8 @@ nice_agent_send_messages_nonblocking_internal (
n_sent_framed = nice_socket_send_messages_reliable (sock, addr, n_sent_framed = nice_socket_send_messages_reliable (sock, addr,
&local_message, 1); &local_message, 1);
if (!nice_socket_can_send (sock, addr)) if (component->tcp_writable_cancellable &&
!nice_socket_can_send (sock, addr))
g_cancellable_reset (component->tcp_writable_cancellable); g_cancellable_reset (component->tcp_writable_cancellable);
if (n_sent_framed < 0 && n_sent == 0) if (n_sent_framed < 0 && n_sent == 0)
......
...@@ -459,20 +459,22 @@ void priv_generate_candidate_credentials (NiceAgent *agent, ...@@ -459,20 +459,22 @@ void priv_generate_candidate_credentials (NiceAgent *agent,
* *
* @return pointer to the created candidate, or NULL on error * @return pointer to the created candidate, or NULL on error
*/ */
NiceCandidate *discovery_add_local_host_candidate ( HostCandidateResult discovery_add_local_host_candidate (
NiceAgent *agent, NiceAgent *agent,
guint stream_id, guint stream_id,
guint component_id, guint component_id,
NiceAddress *address, NiceAddress *address,
NiceCandidateTransport transport) NiceCandidateTransport transport,
NiceCandidate **outcandidate)
{ {
NiceCandidate *candidate; NiceCandidate *candidate;
Component *component; Component *component;
Stream *stream; Stream *stream;
NiceSocket *nicesock = NULL; NiceSocket *nicesock = NULL;
HostCandidateResult res = HOST_CANDIDATE_FAILED;
if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) if (!agent_find_component (agent, stream_id, component_id, &stream, &component))
return NULL; return res;
candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_HOST); candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_HOST);
candidate->transport = transport; candidate->transport = transport;
...@@ -507,26 +509,33 @@ NiceCandidate *discovery_add_local_host_candidate ( ...@@ -507,26 +509,33 @@ NiceCandidate *discovery_add_local_host_candidate (
} else { } else {
/* TODO: Add TCP-SO */ /* TODO: Add TCP-SO */
} }
if (!nicesock) if (!nicesock) {
res = HOST_CANDIDATE_CANT_CREATE_SOCKET;
goto errors; goto errors;
}
candidate->sockptr = nicesock; candidate->sockptr = nicesock;
candidate->addr = nicesock->addr; candidate->addr = nicesock->addr;
candidate->base_addr = nicesock->addr; candidate->base_addr = nicesock->addr;
if (!priv_add_local_candidate_pruned (agent, stream_id, component, candidate)) if (!priv_add_local_candidate_pruned (agent, stream_id, component,
candidate)) {
res = HOST_CANDIDATE_REDUNDANT;
goto errors; goto errors;
}
_priv_set_socket_tos (agent, nicesock, stream->tos); _priv_set_socket_tos (agent, nicesock, stream->tos);
component_attach_socket (component, nicesock); component_attach_socket (component, nicesock);
return candidate; *outcandidate = candidate;
return HOST_CANDIDATE_SUCCESS;
errors: errors:
nice_candidate_free (candidate); nice_candidate_free (candidate);
if (nicesock) if (nicesock)
nice_socket_free (nicesock); nice_socket_free (nicesock);
return NULL; return res;
} }
/* /*
......
...@@ -92,13 +92,21 @@ void discovery_free (NiceAgent *agent); ...@@ -92,13 +92,21 @@ void discovery_free (NiceAgent *agent);
void discovery_prune_stream (NiceAgent *agent, guint stream_id); void discovery_prune_stream (NiceAgent *agent, guint stream_id);
void discovery_schedule (NiceAgent *agent); void discovery_schedule (NiceAgent *agent);
NiceCandidate * typedef enum {
HOST_CANDIDATE_SUCCESS,
HOST_CANDIDATE_FAILED,
HOST_CANDIDATE_CANT_CREATE_SOCKET,
HOST_CANDIDATE_REDUNDANT
} HostCandidateResult;
HostCandidateResult
discovery_add_local_host_candidate ( discovery_add_local_host_candidate (
NiceAgent *agent, NiceAgent *agent,
guint stream_id, guint stream_id,
guint component_id, guint component_id,
NiceAddress *address, NiceAddress *address,
NiceCandidateTransport transport); NiceCandidateTransport transport,
NiceCandidate **candidate);
NiceCandidate* NiceCandidate*
discovery_add_relay_candidate ( discovery_add_relay_candidate (
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment