current_port = start_port;
host_candidate = NULL;
- while (res == HOST_CANDIDATE_CANT_CREATE_SOCKET) {
+ while (res == HOST_CANDIDATE_CANT_CREATE_SOCKET ||
+ res == HOST_CANDIDATE_DUPLICATE_PORT) {
nice_debug ("Agent %p: Trying to create host candidate on port %d", agent, current_port);
nice_address_set_port (addr, current_port);
res = discovery_add_local_host_candidate (agent, stream->id, cid,
addr, transport, &host_candidate);
if (current_port > 0)
current_port++;
- if (current_port > component->max_port) current_port = component->min_port;
- if (current_port == 0 || current_port == start_port)
+ if (current_port > component->max_port)
+ current_port = component->min_port;
+ if (current_port == start_port && res != HOST_CANDIDATE_DUPLICATE_PORT)
+ break;
+ if (current_port == 0 && res != HOST_CANDIDATE_DUPLICATE_PORT)
break;
}
agent);
continue;
} else if (res == HOST_CANDIDATE_FAILED) {
- nice_debug ("Agent %p: Could ot retrieive component %d/%d", agent,
+ nice_debug ("Agent %p: Could not retrieve component %d/%d", agent,
stream->id, cid);
continue;
} else if (res == HOST_CANDIDATE_CANT_CREATE_SOCKET) {
component->id);
}
continue;
+ } else if (res == HOST_CANDIDATE_DUPLICATE_PORT) {
+ nice_debug ("Agent %p: Ignoring local candidate, duplicate port",
+ agent);
+ continue;
}
found_local_address = TRUE;
}
+static gboolean
+priv_local_host_candidate_duplicate_port (NiceComponent *component,
+ NiceCandidate *candidate)
+{
+ GSList *i;
+
+ if (candidate->transport == NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE)
+ return FALSE;
+
+ for (i = component->local_candidates; i; i = i->next) {
+ NiceCandidate *c = i->data;
+
+ if (candidate->transport == c->transport &&
+ nice_address_ip_version (&candidate->addr) ==
+ nice_address_ip_version (&c->addr) &&
+ nice_address_get_port (&candidate->addr) ==
+ nice_address_get_port (&c->addr))
+ return TRUE;
+ }
+ return FALSE;
+}
+
/*
* Creates a local host candidate for 'component_id' of stream
* 'stream_id'.
candidate->addr = nicesock->addr;
candidate->base_addr = nicesock->addr;
+ if (priv_local_host_candidate_duplicate_port (component, candidate)) {
+ res = HOST_CANDIDATE_DUPLICATE_PORT;
+ goto errors;
+ }
+
if (!priv_add_local_candidate_pruned (agent, stream_id, component,
candidate)) {
res = HOST_CANDIDATE_REDUNDANT;