Browse Source

fix ICE processing for multiple sockets

pull/163/head
Richard Fuchs 11 years ago
parent
commit
e2d2581f8f
3 changed files with 28 additions and 23 deletions
  1. +1
    -0
      daemon/call.c
  2. +26
    -22
      daemon/ice.c
  3. +1
    -1
      daemon/ice.h

+ 1
- 0
daemon/call.c View File

@ -848,6 +848,7 @@ static void __fill_stream(struct packet_stream *ps, const struct endpoint *epp,
crypto_reset(&ps->crypto);
dtls_shutdown(ps);
PS_SET(ps, FILLED);
/* XXX reset/repair ICE */
}
/* called with call locked in R or W, but ps not locked */


+ 26
- 22
daemon/ice.c View File

@ -132,20 +132,20 @@ static void __all_pairs_list(struct ice_agent *ag) {
}
/* agent must be locked */
static struct ice_candidate_pair *__pair_candidate(const struct local_intf *addr, struct ice_agent *ag,
struct ice_candidate *cand, struct packet_stream *ps)
static struct ice_candidate_pair *__pair_candidate(struct stream_fd *sfd, struct ice_agent *ag,
struct ice_candidate *cand)
{
struct ice_candidate_pair *pair;
if (addr->spec->address.addr.family != cand->endpoint.address.family)
if (sfd->socket.family != cand->endpoint.address.family)
return NULL;
pair = g_slice_alloc0(sizeof(*pair));
pair->agent = ag;
pair->remote_candidate = cand;
pair->local_intf = addr;
pair->packet_stream = ps;
pair->local_intf = sfd->local_intf;
pair->sfd = sfd;
if (cand->component_id != 1)
PAIR_SET(pair, FROZEN);
__do_ice_pair_priority(pair);
@ -156,7 +156,7 @@ static struct ice_candidate_pair *__pair_candidate(const struct local_intf *addr
g_tree_insert(ag->all_pairs, pair, pair);
ilog(LOG_DEBUG, "Created candidate pair "PAIR_FORMAT" between %s and %s, type %s", PAIR_FMT(pair),
sockaddr_print_buf(&addr->spec->address.addr),
sockaddr_print_buf(&sfd->socket.local.address),
endpoint_print_buf(&cand->endpoint),
ice_candidate_type_str(cand->type));
@ -308,6 +308,7 @@ void ice_update(struct ice_agent *ag, struct stream_params *sp) {
unsigned int comps;
struct packet_stream *components[MAX_COMPONENTS], *ps;
GQueue *candidates;
struct stream_fd *sfd;
if (!ag)
return;
@ -412,11 +413,13 @@ void ice_update(struct ice_agent *ag, struct stream_params *sp) {
pair:
if (!ps)
continue;
for (k = ag->logical_intf->list.head; k; k = k->next) {
for (k = ps->sfds.head; k; k = k->next) {
sfd = k->data;
/* skip duplicates here also */
if (__pair_lookup(ag, dup, k->data))
if (__pair_lookup(ag, dup, sfd->local_intf))
continue;
__pair_candidate(k->data, ag, dup, ps);
__pair_candidate(sfd, ag, dup);
}
}
@ -574,7 +577,7 @@ static void __fail_pair(struct ice_candidate_pair *pair) {
/* agent must NOT be locked, but call must be locked in R */
static void __do_ice_check(struct ice_candidate_pair *pair) {
struct packet_stream *ps = pair->packet_stream;
struct stream_fd *sfd = pair->sfd;
struct ice_agent *ag = pair->agent;
u_int32_t prio, transact[3];
@ -620,7 +623,7 @@ static void __do_ice_check(struct ice_candidate_pair *pair) {
stun_binding_request(&pair->remote_candidate->endpoint, transact, &ag->pwd[0], ag->ufrag,
AGENT_ISSET(ag, CONTROLLING), tie_breaker,
prio, &ps->selected_sfd->socket,
prio, &sfd->socket,
PAIR_ISSET(pair, TO_USE));
}
@ -675,7 +678,7 @@ static void __nominate_pairs(struct ice_agent *ag) {
static void __do_ice_checks(struct ice_agent *ag) {
GList *l;
struct ice_candidate_pair *pair, *highest = NULL, *frozen = NULL, *valid;
struct packet_stream *ps;
struct stream_fd *sfd;
GQueue retransmits = G_QUEUE_INIT;
struct timeval next_run = {0,0};
int have_more = 0;
@ -710,8 +713,8 @@ static void __do_ice_checks(struct ice_agent *ag) {
pair = l->data;
/* skip dead streams */
ps = pair->packet_stream;
if (!ps || !ps->selected_sfd)
sfd = pair->sfd;
if (!sfd || !sfd->stream || !sfd->stream->selected_sfd)
continue;
if (PAIR_ISSET(pair, FAILED))
continue;
@ -822,16 +825,17 @@ static void __cand_ice_foundation(struct call *call, struct ice_candidate *cand)
}
/* agent must be locked */
static struct ice_candidate_pair *__learned_candidate(struct ice_agent *ag, struct packet_stream *ps,
const endpoint_t *src, const struct local_intf *ifa, unsigned long priority)
static struct ice_candidate_pair *__learned_candidate(struct ice_agent *ag, struct stream_fd *sfd,
const endpoint_t *src, unsigned long priority)
{
struct ice_candidate *cand, *old_cand;
struct ice_candidate_pair *pair;
struct call *call = ag->call;
struct packet_stream *ps = sfd->stream;
cand = g_slice_alloc0(sizeof(*cand));
cand->component_id = ps->component;
cand->transport = ifa->spec->address.type;
cand->transport = sfd->local_intf->spec->address.type; // XXX add socket type into socket_t?
cand->priority = priority;
cand->endpoint = *src;
cand->type = ICT_PRFLX;
@ -843,7 +847,7 @@ static struct ice_candidate_pair *__learned_candidate(struct ice_agent *ag, stru
* address, but from different ports. we cannot distinguish such candidates and
* will drop the one with the lower priority */
g_slice_free1(sizeof(*cand), cand);
pair = __pair_lookup(ag, old_cand, ifa);
pair = __pair_lookup(ag, old_cand, sfd->local_intf);
if (pair)
goto out; /* nothing to do */
cand = old_cand;
@ -855,7 +859,7 @@ static struct ice_candidate_pair *__learned_candidate(struct ice_agent *ag, stru
g_hash_table_insert(ag->foundation_hash, cand, cand);
pair:
pair = __pair_candidate(ifa, ag, cand, ps);
pair = __pair_candidate(sfd, ag, cand);
PAIR_SET(pair, LEARNED);
__all_pairs_list(ag);
@ -1060,9 +1064,9 @@ int ice_request(struct stream_fd *sfd, const endpoint_t *src,
cand = __cand_lookup(ag, src, ps->component);
if (!cand)
pair = __learned_candidate(ag, ps, src, ifa, attrs->priority);
pair = __learned_candidate(ag, sfd, src, attrs->priority);
else
pair = __pair_lookup(ag, cand, ifa);
pair = __pair_lookup(ag, cand, sfd->local_intf);
err = "Failed to determine ICE candidate from STUN request";
if (!pair)
@ -1184,7 +1188,7 @@ int ice_response(struct stream_fd *sfd, const endpoint_t *src,
goto err;
err = "ICE/STUN response received, but destination address didn't match local interface address";
if (pair->packet_stream != ps)
if (pair->sfd != sfd)
goto err;
PAIR_CLEAR(pair, IN_PROGRESS);


+ 1
- 1
daemon/ice.h View File

@ -88,7 +88,7 @@ struct ice_candidate {
struct ice_candidate_pair {
struct ice_candidate *remote_candidate;
const struct local_intf *local_intf;
struct packet_stream *packet_stream;
struct stream_fd *sfd;
volatile unsigned int pair_flags;
u_int32_t stun_transaction[3]; /* belongs to transaction_hash, thus agent->lock */
unsigned int retransmit_ms;


Loading…
Cancel
Save