From 16d51b09cf43349c10dae93b9a45de5180de5213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cr=C3=AAte?= Date: Sun, 28 Oct 2018 13:54:45 +0000 Subject: agent: Remove explicit parent pointers Remove all pointers that don't include have a reference except to agents --- agent/agent.c | 77 ++++++++++++++++++++++------------------- agent/component.c | 63 ++++++++++++++++++++++------------ agent/component.h | 9 +++-- agent/conncheck.c | 100 ++++++++++++++++++++++++++---------------------------- agent/conncheck.h | 3 +- agent/discovery.c | 47 +++++++++++++------------ agent/discovery.h | 12 +++---- agent/stream.c | 4 ++- agent/stream.h | 2 +- 9 files changed, 172 insertions(+), 145 deletions(-) diff --git a/agent/agent.c b/agent/agent.c index 7f444b9..9e5af2e 100644 --- a/agent/agent.c +++ b/agent/agent.c @@ -1582,7 +1582,7 @@ static void g_cancellable_cancel (component->tcp_writable_cancellable); agent_queue_signal (agent, signals[SIGNAL_RELIABLE_TRANSPORT_WRITABLE], - component->stream->id, component->id); + component->stream_id, component->id); } static void @@ -1600,8 +1600,7 @@ pseudo_tcp_socket_create (NiceAgent *agent, NiceStream *stream, NiceComponent *c agent, component->id); } -static void priv_pseudo_tcp_error (NiceAgent *agent, NiceStream *stream, - NiceComponent *component) +static void priv_pseudo_tcp_error (NiceAgent *agent, NiceComponent *component) { if (component->tcp_writable_cancellable) { g_cancellable_cancel (component->tcp_writable_cancellable); @@ -1609,7 +1608,7 @@ static void priv_pseudo_tcp_error (NiceAgent *agent, NiceStream *stream, } if (component->tcp) { - agent_signal_component_state_change (agent, stream->id, + agent_signal_component_state_change (agent, component->stream_id, component->id, NICE_COMPONENT_STATE_FAILED); nice_component_detach_all_sockets (component); pseudo_tcp_socket_close (component->tcp, TRUE); @@ -1627,10 +1626,9 @@ pseudo_tcp_socket_opened (PseudoTcpSocket *sock, gpointer user_data) { NiceComponent *component = user_data; NiceAgent *agent = component->agent; - NiceStream *stream = component->stream; nice_debug ("Agent %p: s%d:%d pseudo Tcp socket Opened", agent, - stream->id, component->id); + component->stream_id, component->id); agent_signal_socket_writable (agent, component); } @@ -1787,15 +1785,21 @@ pseudo_tcp_socket_readable (PseudoTcpSocket *sock, gpointer user_data) { NiceComponent *component = user_data; NiceAgent *agent = component->agent; - NiceStream *stream = component->stream; gboolean has_io_callback; - guint stream_id = stream->id; + NiceStream *stream = NULL; + guint stream_id = component->stream_id; guint component_id = component->id; g_object_ref (agent); + if (!agent_find_component (agent, stream_id, component_id, + &stream, &component)) { + g_object_unref (agent); + goto out; + } + nice_debug_verbose ("Agent %p: s%d:%d pseudo Tcp socket readable", agent, - stream->id, component->id); + stream_id, component->id); component->tcp_readable = TRUE; @@ -1826,7 +1830,7 @@ pseudo_tcp_socket_readable (PseudoTcpSocket *sock, gpointer user_data) /* Handle errors. */ if (pseudo_tcp_socket_get_error (sock) != EWOULDBLOCK) { nice_debug ("%s: calling priv_pseudo_tcp_error()", G_STRFUNC); - priv_pseudo_tcp_error (agent, stream, component); + priv_pseudo_tcp_error (agent, component); } if (component->recv_buf_error != NULL) { @@ -1889,7 +1893,7 @@ pseudo_tcp_socket_readable (PseudoTcpSocket *sock, gpointer user_data) component->tcp_readable = FALSE; } else if (n_valid_messages < 0) { nice_debug ("%s: calling priv_pseudo_tcp_error()", G_STRFUNC); - priv_pseudo_tcp_error (agent, stream, component); + priv_pseudo_tcp_error (agent, component); } else if (n_valid_messages == 0) { /* Reached EOS. */ component->tcp_readable = FALSE; @@ -1912,10 +1916,9 @@ pseudo_tcp_socket_writable (PseudoTcpSocket *sock, gpointer user_data) { NiceComponent *component = user_data; NiceAgent *agent = component->agent; - NiceStream *stream = component->stream; nice_debug_verbose ("Agent %p: s%d:%d pseudo Tcp socket writable", agent, - stream->id, component->id); + component->stream_id, component->id); agent_signal_socket_writable (agent, component); } @@ -1926,11 +1929,11 @@ pseudo_tcp_socket_closed (PseudoTcpSocket *sock, guint32 err, { NiceComponent *component = user_data; NiceAgent *agent = component->agent; - NiceStream *stream = component->stream; nice_debug ("Agent %p: s%d:%d pseudo Tcp socket closed. " - "Calling priv_pseudo_tcp_error().", agent, stream->id, component->id); - priv_pseudo_tcp_error (agent, stream, component); + "Calling priv_pseudo_tcp_error().", agent, component->stream_id, + component->id); + priv_pseudo_tcp_error (agent, component); } @@ -1953,7 +1956,7 @@ pseudo_tcp_socket_write_packet (PseudoTcpSocket *psocket, nice_debug_verbose ( "Agent %p : s%d:%d: sending %d bytes on socket %p (FD %d) to [%s]:%d", - component->agent, component->stream->id, component->id, len, + component->agent, component->stream_id, component->id, len, sock->fileno, g_socket_get_fd (sock->fileno), tmpbuf, nice_address_get_port (addr)); } @@ -1983,7 +1986,9 @@ notify_pseudo_tcp_socket_clock_agent_locked (NiceAgent *agent, NiceComponent *component = user_data; NiceStream *stream; - stream = component->stream; + stream = agent_find_stream (agent, component->stream_id); + if (!stream) + return G_SOURCE_REMOVE; pseudo_tcp_socket_notify_clock (component->tcp); adjust_tcp_clock (agent, stream, component); @@ -2018,7 +2023,7 @@ adjust_tcp_clock (NiceAgent *agent, NiceStream *stream, NiceComponent *component nice_debug ("Agent %p: component %d pseudo-TCP socket should be " "destroyed. Calling priv_pseudo_tcp_error().", agent, component->id); - priv_pseudo_tcp_error (agent, stream, component); + priv_pseudo_tcp_error (agent, component); } } } @@ -2028,7 +2033,6 @@ _tcp_sock_is_writable (NiceSocket *sock, gpointer user_data) { NiceComponent *component = user_data; NiceAgent *agent = component->agent; - NiceStream *stream = component->stream; agent_lock (agent); @@ -2041,7 +2045,7 @@ _tcp_sock_is_writable (NiceSocket *sock, gpointer user_data) } nice_debug ("Agent %p: s%d:%d Tcp socket writable", agent, - stream->id, component->id); + component->stream_id, component->id); agent_signal_socket_writable (agent, component); agent_unlock_and_emit (agent); @@ -2413,9 +2417,8 @@ priv_add_new_candidate_discovery_stun (NiceAgent *agent, cdisco->type = NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE; cdisco->nicesock = nicesock; cdisco->server = server; - cdisco->stream = stream; - cdisco->component = nice_stream_find_component_by_id (stream, component_id); - cdisco->agent = agent; + cdisco->stream_id = stream->id; + cdisco->component_id = component_id; stun_agent_init (&cdisco->stun_agent, STUN_ALL_KNOWN_ATTRIBUTES, STUN_COMPATIBILITY_RFC3489, (agent->compatibility == NICE_COMPATIBILITY_OC2007 || @@ -2556,9 +2559,8 @@ priv_add_new_candidate_discovery_turn (NiceAgent *agent, cdisco->turn = turn_server_ref (turn); cdisco->server = turn->server; - cdisco->stream = stream; - cdisco->component = nice_stream_find_component_by_id (stream, component_id); - cdisco->agent = agent; + cdisco->stream_id = stream->id; + cdisco->component_id = component_id; if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) { stun_agent_init (&cdisco->stun_agent, STUN_ALL_KNOWN_ATTRIBUTES, @@ -2603,10 +2605,9 @@ nice_agent_add_stream ( g_return_val_if_fail (n_components >= 1, 0); agent_lock (agent); - stream = nice_stream_new (n_components, agent); + stream = nice_stream_new (agent->next_stream_id++, n_components, agent); agent->streams = g_slist_append (agent->streams, stream); - stream->id = agent->next_stream_id++; nice_debug ("Agent %p : allocating stream id %u (%p)", agent, stream->id, stream); if (agent->reliable) { nice_debug ("Agent %p : reliable stream", agent); @@ -4722,7 +4723,7 @@ nice_agent_send_messages_nonblocking_internal ( if (n_sent < 0 && !g_error_matches (child_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { /* Signal errors */ - priv_pseudo_tcp_error (agent, stream, component); + priv_pseudo_tcp_error (agent, component); } } else { g_set_error (&child_error, G_IO_ERROR, G_IO_ERROR_FAILED, @@ -5133,10 +5134,18 @@ component_io_cb (GSocket *gsocket, GIOCondition condition, gpointer user_data) component = socket_source->component; agent = component->agent; - stream = component->stream; agent_lock (agent); + stream = agent_find_stream (agent, component->stream_id); + + if (stream == NULL) { + nice_debug ("%s: stream %d destroyed", G_STRFUNC, component->stream_id); + + agent_unlock (agent); + return G_SOURCE_REMOVE; + } + if (g_source_is_destroyed (g_main_current_source ())) { /* Silently return FALSE. */ nice_debug ("%s: source %p destroyed", G_STRFUNC, g_main_current_source ()); @@ -5160,7 +5169,7 @@ component_io_cb (GSocket *gsocket, GIOCondition condition, gpointer user_data) stream->id, component->id, NICE_COMPONENT_STATE_FAILED); } - nice_component_remove_socket (component, socket_source->socket); + nice_component_remove_socket (agent, component, socket_source->socket); agent_unlock (agent); g_object_unref (agent); return G_SOURCE_REMOVE; @@ -5326,7 +5335,7 @@ component_io_cb (GSocket *gsocket, GIOCondition condition, gpointer user_data) done: if (remove_source) - nice_component_remove_socket (component, socket_source->socket); + nice_component_remove_socket (agent, component, socket_source->socket); /* If we’re in the middle of a read, don’t emit any signals, or we could cause * re-entrancy by (e.g.) emitting component-state-changed and having the @@ -6476,7 +6485,7 @@ nice_agent_forget_relays (NiceAgent *agent, guint stream_id, guint component_id) goto done; } - nice_component_clean_turn_servers (component); + nice_component_clean_turn_servers (agent, component); done: agent_unlock_and_emit (agent); diff --git a/agent/component.c b/agent/component.c index dfdba13..6a03ead 100644 --- a/agent/component.c +++ b/agent/component.c @@ -164,9 +164,13 @@ nice_component_new (guint id, NiceAgent *agent, NiceStream *stream) } void -nice_component_remove_socket (NiceComponent *cmp, NiceSocket *nsocket) +nice_component_remove_socket (NiceAgent *agent, NiceComponent *cmp, + NiceSocket *nsocket) { GSList *i; + NiceStream *stream; + + stream = agent_find_stream (agent, cmp->stream_id); for (i = cmp->local_candidates; i;) { NiceCandidate *candidate = i->data; @@ -179,14 +183,14 @@ nice_component_remove_socket (NiceComponent *cmp, NiceSocket *nsocket) if (candidate == cmp->selected_pair.local) { nice_component_clear_selected_pair (cmp); - agent_signal_component_state_change (cmp->agent, cmp->stream->id, + agent_signal_component_state_change (cmp->agent, cmp->stream_id, cmp->id, NICE_COMPONENT_STATE_FAILED); } refresh_prune_candidate (cmp->agent, candidate); - if (candidate->sockptr != nsocket) { + if (candidate->sockptr != nsocket && stream) { discovery_prune_socket (cmp->agent, candidate->sockptr); - conn_check_prune_socket (cmp->agent, cmp->stream, cmp, + conn_check_prune_socket (cmp->agent, stream, cmp, candidate->sockptr); nice_component_detach_socket (cmp, candidate->sockptr); } @@ -198,14 +202,18 @@ nice_component_remove_socket (NiceComponent *cmp, NiceSocket *nsocket) } discovery_prune_socket (cmp->agent, nsocket); - conn_check_prune_socket (cmp->agent, cmp->stream, cmp, nsocket); + if (stream) + conn_check_prune_socket (cmp->agent, stream, cmp, nsocket); nice_component_detach_socket (cmp, nsocket); } void -nice_component_clean_turn_servers (NiceComponent *cmp) +nice_component_clean_turn_servers (NiceAgent *agent, NiceComponent *cmp) { GSList *i; + NiceStream *stream; + + stream = agent_find_stream (agent, cmp->stream_id); g_list_free_full (cmp->turn_servers, (GDestroyNotify) turn_server_unref); cmp->turn_servers = NULL; @@ -232,8 +240,9 @@ nice_component_clean_turn_servers (NiceComponent *cmp) if (cmp->turn_candidate) { refresh_prune_candidate (cmp->agent, cmp->turn_candidate); discovery_prune_socket (cmp->agent, cmp->turn_candidate->sockptr); - conn_check_prune_socket (cmp->agent, cmp->stream, cmp, - cmp->turn_candidate->sockptr); + if (stream) + conn_check_prune_socket (cmp->agent, stream, cmp, + cmp->turn_candidate->sockptr); nice_component_detach_socket (cmp, cmp->turn_candidate->sockptr); nice_candidate_free (cmp->turn_candidate); } @@ -245,8 +254,9 @@ nice_component_clean_turn_servers (NiceComponent *cmp) } else { refresh_prune_candidate (cmp->agent, candidate); discovery_prune_socket (cmp->agent, candidate->sockptr); - conn_check_prune_socket (cmp->agent, cmp->stream, cmp, - candidate->sockptr); + if (stream) + conn_check_prune_socket (cmp->agent, stream, cmp, + candidate->sockptr); nice_component_detach_socket (cmp, candidate->sockptr); agent_remove_local_candidate (cmp->agent, candidate); nice_candidate_free (candidate); @@ -313,7 +323,7 @@ nice_component_close (NiceComponent *cmp) (GDestroyNotify) incoming_check_free); cmp->incoming_checks = NULL; - nice_component_clean_turn_servers (cmp); + nice_component_clean_turn_servers (cmp->agent, cmp); if (cmp->tcp_clock) { g_source_destroy (cmp->tcp_clock); @@ -418,8 +428,13 @@ nice_component_restart (NiceComponent *cmp) void nice_component_update_selected_pair (NiceComponent *component, const CandidatePair *pair) { + NiceStream *stream; + g_assert (component); g_assert (pair); + + stream = agent_find_stream (component->agent, component->stream_id); + nice_debug ("setting SELECTED PAIR for component %u: %s:%s (prio:%" G_GUINT64_FORMAT ").", component->id, pair->local->foundation, pair->remote->foundation, pair->priority); @@ -429,8 +444,9 @@ nice_component_update_selected_pair (NiceComponent *component, const CandidatePa refresh_prune_candidate (component->agent, component->turn_candidate); discovery_prune_socket (component->agent, component->turn_candidate->sockptr); - conn_check_prune_socket (component->agent, component->stream, component, - component->turn_candidate->sockptr); + if (stream) + conn_check_prune_socket (component->agent, stream, component, + component->turn_candidate->sockptr); nice_component_detach_socket (component, component->turn_candidate->sockptr); nice_candidate_free (component->turn_candidate); component->turn_candidate = NULL; @@ -575,7 +591,7 @@ nice_component_attach_socket (NiceComponent *component, NiceSocket *nicesock) /* Create and attach a source */ nice_debug ("Component %p (agent %p): Attach source (stream %u).", - component, component->agent, component->stream->id); + component, component->agent, component->stream_id); socket_source_attach (socket_source, component->ctx); } @@ -797,7 +813,7 @@ emit_io_callback_cb (gpointer user_data) g_object_ref (agent); - stream_id = component->stream->id; + stream_id = component->stream_id; component_id = component->id; g_mutex_lock (&component->io_mutex); @@ -869,7 +885,7 @@ nice_component_emit_io_callback (NiceComponent *component, g_assert (buf_len > 0); agent = component->agent; - stream_id = component->stream->id; + stream_id = component->stream_id; component_id = component->id; g_mutex_lock (&component->io_mutex); @@ -1029,7 +1045,6 @@ nice_component_init (NiceComponent *component) component->restart_candidate = NULL; component->tcp = NULL; component->agent = NULL; - component->stream = NULL; g_mutex_init (&component->io_mutex); g_queue_init (&component->pending_io_messages); @@ -1084,9 +1099,12 @@ nice_component_get_property (GObject *obj, break; case PROP_STREAM: - g_value_set_object (value, component->stream); - break; - + { + NiceStream *stream = agent_find_stream (component->agent, + component->stream_id); + g_value_set_object (value, stream); + break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec); } @@ -1111,7 +1129,10 @@ nice_component_set_property (GObject *obj, break; case PROP_STREAM: - component->stream = g_value_get_object (value); + { + NiceStream *stream = g_value_get_object (value); + component->stream_id = stream->id; + } break; default: diff --git a/agent/component.h b/agent/component.h index a8a1222..39486d9 100644 --- a/agent/component.h +++ b/agent/component.h @@ -69,7 +69,6 @@ typedef struct _IncomingCheck IncomingCheck; struct _CandidatePairKeepalive { - NiceAgent *agent; GSource *tick_source; guint stream_id; guint component_id; @@ -202,8 +201,7 @@ struct _NiceComponent { NiceAgent *agent; /* unowned, immutable: can be accessed without holding the * agent lock */ - NiceStream *stream; /* unowned, immutable: can be accessed without holding - * the agent lock */ + guint stream_id; StunAgent stun_agent; /* This stun agent is used to validate all stun requests */ @@ -263,7 +261,8 @@ void nice_component_attach_socket (NiceComponent *component, NiceSocket *nsocket); void -nice_component_remove_socket (NiceComponent *component, NiceSocket *nsocket); +nice_component_remove_socket (NiceAgent *agent, NiceComponent *component, + NiceSocket *nsocket); void nice_component_detach_all_sockets (NiceComponent *component); @@ -290,7 +289,7 @@ nice_component_emit_io_callback (NiceComponent *component, gboolean nice_component_has_io_callback (NiceComponent *component); void -nice_component_clean_turn_servers (NiceComponent *component); +nice_component_clean_turn_servers (NiceAgent *agent, NiceComponent *component); TurnServer * diff --git a/agent/conncheck.c b/agent/conncheck.c index e2edebd..3993ef6 100644 --- a/agent/conncheck.c +++ b/agent/conncheck.c @@ -1180,7 +1180,7 @@ static gboolean priv_conn_keepalive_retransmissions_tick_agent_locked ( stun_agent_forget_transaction (&component->stun_agent, id); pair->keepalive.stun_message.buffer = NULL; - if (pair->keepalive.agent->media_after_tick) { + if (agent->media_after_tick) { nice_debug ("Agent %p : Keepalive conncheck timed out!! " "but media was received. Suspecting keepalive lost because of " "network bottleneck", agent); @@ -1369,9 +1369,8 @@ static gboolean priv_conn_keepalive_tick_unlocked (NiceAgent *agent) p->keepalive.stream_id = stream->id; p->keepalive.component_id = component->id; - p->keepalive.agent = agent; - agent_timeout_add_with_context (p->keepalive.agent, + agent_timeout_add_with_context (agent, &p->keepalive.tick_source, "Pair keepalive", stun_timer_remainder (&p->keepalive.timer), priv_conn_keepalive_retransmissions_tick_agent_locked, p); @@ -1490,7 +1489,7 @@ static gboolean priv_turn_allocate_refresh_retransmissions_tick_agent_locked ( stun_message_id (&cand->stun_message, id); stun_agent_forget_transaction (&cand->stun_agent, id); - refresh_cancel (cand); + refresh_cancel (agent, cand); break; } case STUN_USAGE_TIMER_RETURN_RETRANSMIT: @@ -1775,7 +1774,7 @@ static void priv_update_check_list_failed_components (NiceAgent *agent, NiceStre /* There is still discovery ogoing for this stream, * so don't fail any of it's candidates. */ - if (d->stream == stream && !d->done) + if (d->stream_id == stream->id && !d->done) return; } if (agent->discovery_list != NULL) @@ -1939,7 +1938,8 @@ static void priv_mark_pair_nominated (NiceAgent *agent, NiceStream *stream, Nice } guint32 -ensure_unique_priority (NiceComponent *component, guint32 priority) +ensure_unique_priority (NiceStream *stream, NiceComponent *component, + guint32 priority) { GSList *item; @@ -1956,7 +1956,7 @@ ensure_unique_priority (NiceComponent *component, guint32 priority) } } - for (item = component->stream->conncheck_list; item; item = item->next) { + for (item = stream->conncheck_list; item; item = item->next) { CandidateCheckPair *p = item->data; if (p->component_id == component->id && @@ -2013,7 +2013,7 @@ static CandidateCheckPair *priv_add_new_check_pair (NiceAgent *agent, tmpbuf1, nice_address_get_port (&pair->local->addr), tmpbuf2, nice_address_get_port (&pair->remote->addr)); } - pair->prflx_priority = ensure_unique_priority (component, + pair->prflx_priority = ensure_unique_priority (stream, component, peer_reflexive_candidate_priority (agent, local)); stream->conncheck_list = g_slist_insert_sorted (stream->conncheck_list, pair, @@ -2936,7 +2936,7 @@ static CandidateCheckPair *priv_add_peer_reflexive_pair (NiceAgent *agent, guint pair->priority = nice_candidate_pair_priority (pair->remote->priority, pair->local->priority); pair->nominated = FALSE; - pair->prflx_priority = ensure_unique_priority (component, + pair->prflx_priority = ensure_unique_priority (stream, component, peer_reflexive_candidate_priority (agent, local_cand)); nice_debug ("Agent %p : added a new peer-discovered pair with " "foundation '%s'.", agent, pair->foundation); @@ -3349,18 +3349,18 @@ static gboolean priv_map_reply_to_discovery_request (NiceAgent *agent, StunMessa nice_address_set_from_sockaddr (&niceaddr, &sockaddr.addr); discovery_add_server_reflexive_candidate ( - d->agent, - d->stream->id, - d->component->id, + agent, + d->stream_id, + d->component_id, &niceaddr, NICE_CANDIDATE_TRANSPORT_UDP, d->nicesock, FALSE); - if (d->agent->use_ice_tcp) + if (agent->use_ice_tcp) discovery_discover_tcp_server_reflexive_candidates ( - d->agent, - d->stream->id, - d->component->id, + agent, + d->stream_id, + d->component_id, &niceaddr, d->nicesock); } @@ -3384,11 +3384,10 @@ static gboolean priv_map_reply_to_discovery_request (NiceAgent *agent, StunMessa static CandidateRefresh * -priv_add_new_turn_refresh (CandidateDiscovery *cdisco, NiceCandidate *relay_cand, - guint lifetime) +priv_add_new_turn_refresh (NiceAgent *agent, CandidateDiscovery *cdisco, + NiceCandidate *relay_cand, guint lifetime) { CandidateRefresh *cand; - NiceAgent *agent = cdisco->agent; cand = g_slice_new0 (CandidateRefresh); agent->refresh_list = g_slist_append (agent->refresh_list, cand); @@ -3396,9 +3395,8 @@ priv_add_new_turn_refresh (CandidateDiscovery *cdisco, NiceCandidate *relay_cand cand->candidate = relay_cand; cand->nicesock = cdisco->nicesock; cand->server = cdisco->server; - cand->stream = cdisco->stream; - cand->component = cdisco->component; - cand->agent = cdisco->agent; + cand->stream_id = cdisco->stream_id; + cand->component_id = cdisco->component_id; memcpy (&cand->stun_agent, &cdisco->stun_agent, sizeof(StunAgent)); /* Use previous stun response for authentication credentials */ @@ -3412,7 +3410,7 @@ priv_add_new_turn_refresh (CandidateDiscovery *cdisco, NiceCandidate *relay_cand } nice_debug ("Agent %p : Adding new refresh candidate %p with timeout %d", - agent, cand, (lifetime - 60) * 1000); + agent, cand, lifetime - 60); /* step: also start the refresh timer */ /* refresh should be sent 1 minute before it expires */ @@ -3441,7 +3439,7 @@ static void priv_handle_turn_alternate_server (NiceAgent *agent, if (!d->done && d->type == disco->type && - d->stream == disco->stream && + d->stream_id == disco->stream_id && d->turn->type == disco->turn->type && nice_address_equal (&d->server, &server)) { gchar ip[INET6_ADDRSTRLEN]; @@ -3539,15 +3537,15 @@ static gboolean priv_map_reply_to_relay_request (NiceAgent *agent, StunMessage * if (d->turn->type == NICE_RELAY_TYPE_TURN_UDP && !agent->force_relay) { discovery_add_server_reflexive_candidate ( - d->agent, - d->stream->id, - d->component->id, + agent, + d->stream_id, + d->component_id, &mappedniceaddr, NICE_CANDIDATE_TRANSPORT_UDP, d->nicesock, FALSE); } - if (d->agent->use_ice_tcp) { + if (agent->use_ice_tcp) { if ((agent->compatibility == NICE_COMPATIBILITY_OC2007 || agent->compatibility == NICE_COMPATIBILITY_OC2007R2) && !nice_address_equal_no_port (&niceaddr, &d->turn->server)) { @@ -3555,9 +3553,9 @@ static gboolean priv_map_reply_to_relay_request (NiceAgent *agent, StunMessage * "ignoring bogus srflx address"); } else { discovery_discover_tcp_server_reflexive_candidates ( - d->agent, - d->stream->id, - d->component->id, + agent, + d->stream_id, + d->component_id, &mappedniceaddr, d->nicesock); } @@ -3566,9 +3564,9 @@ static gboolean priv_map_reply_to_relay_request (NiceAgent *agent, StunMessage * if (nice_socket_is_reliable (d->nicesock)) { relay_cand = discovery_add_relay_candidate ( - d->agent, - d->stream->id, - d->component->id, + agent, + d->stream_id, + d->component_id, &niceaddr, NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE, d->nicesock, @@ -3582,23 +3580,23 @@ static gboolean priv_map_reply_to_relay_request (NiceAgent *agent, StunMessage * nice_udp_turn_socket_set_ms_connection_id(relay_cand->sockptr, resp); } else { - priv_add_new_turn_refresh (d, relay_cand, lifetime); + priv_add_new_turn_refresh (agent, d, relay_cand, lifetime); } } relay_cand = discovery_add_relay_candidate ( - d->agent, - d->stream->id, - d->component->id, + agent, + d->stream_id, + d->component_id, &niceaddr, NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE, d->nicesock, d->turn); } else { relay_cand = discovery_add_relay_candidate ( - d->agent, - d->stream->id, - d->component->id, + agent, + d->stream_id, + d->component_id, &niceaddr, NICE_CANDIDATE_TRANSPORT_UDP, d->nicesock, @@ -3622,7 +3620,7 @@ static gboolean priv_map_reply_to_relay_request (NiceAgent *agent, StunMessage * nice_udp_turn_socket_set_ms_connection_id(relay_cand->sockptr, resp); } else { - priv_add_new_turn_refresh (d, relay_cand, lifetime); + priv_add_new_turn_refresh (agent, d, relay_cand, lifetime); } /* In case a new candidate has been added */ @@ -3723,12 +3721,12 @@ static gboolean priv_map_reply_to_relay_refresh (NiceAgent *agent, StunMessage * if (memcmp (refresh_id, response_id, sizeof(StunTransactionId)) == 0) { res = stun_usage_turn_refresh_process (resp, - &lifetime, agent_to_turn_compatibility (cand->agent)); + &lifetime, agent_to_turn_compatibility (agent)); nice_debug ("Agent %p : stun_turn_refresh_process for %p res %d.", agent, cand, (int)res); if (res == STUN_USAGE_TURN_RETURN_RELAY_SUCCESS) { /* refresh should be sent 1 minute before it expires */ - agent_timeout_add_seconds_with_context (cand->agent, + agent_timeout_add_seconds_with_context (agent, &cand->timer_source, "Candidate TURN refresh", lifetime - 60, priv_turn_allocate_refresh_tick_agent_locked, cand); @@ -3749,7 +3747,7 @@ static gboolean priv_map_reply_to_relay_refresh (NiceAgent *agent, StunMessage * STUN_ATTRIBUTE_REALM, &recv_realm_len); /* check for unauthorized error response */ - if (cand->agent->compatibility == NICE_COMPATIBILITY_RFC5245 && + if (agent->compatibility == NICE_COMPATIBILITY_RFC5245 && stun_message_get_class (resp) == STUN_ERROR && stun_message_find_error (resp, &code) == STUN_MESSAGE_RETURN_SUCCESS && @@ -3768,11 +3766,11 @@ static gboolean priv_map_reply_to_relay_refresh (NiceAgent *agent, StunMessage * priv_turn_allocate_refresh_tick_unlocked (agent, cand); } else { /* case: a real unauthorized error */ - refresh_cancel (cand); + refresh_cancel (agent, cand); } } else { /* case: STUN error, the check STUN context was freed */ - refresh_cancel (cand); + refresh_cancel (agent, cand); } trans_found = TRUE; } @@ -3958,7 +3956,7 @@ gboolean conn_check_handle_inbound_stun (NiceAgent *agent, NiceStream *stream, valid == STUN_VALIDATION_UNMATCHED_RESPONSE) { for (i = agent->discovery_list; i; i = i->next) { CandidateDiscovery *d = i->data; - if (d->stream == stream && d->component == component && + if (d->stream_id == stream->id && d->component_id == component->id && d->nicesock == nicesock) { valid = stun_agent_validate (&d->stun_agent, &req, (uint8_t *) buf, len, conncheck_stun_validater, &validater_data); @@ -3977,11 +3975,11 @@ gboolean conn_check_handle_inbound_stun (NiceAgent *agent, NiceStream *stream, for (i = agent->refresh_list; i; i = i->next) { CandidateRefresh *r = i->data; - nice_debug_verbose ("Comparing %p to %p, %p to %p and %p and %p to %p", - r->stream, stream, r->component, component, r->nicesock, + nice_debug_verbose ("Comparing r.sid=%u to sid=%u, r.cid=%u to cid=%u and %p and %p to %p", + r->stream_id, stream->id, r->component_id, component->id, r->nicesock, r->candidate->sockptr, nicesock); - if (r->stream == stream && r->component == component && + if (r->stream_id == stream->id && r->component_id == component->id && (r->nicesock == nicesock || r->candidate->sockptr == nicesock)) { valid = stun_agent_validate (&r->stun_agent, &req, (uint8_t *) buf, len, conncheck_stun_validater, &validater_data); diff --git a/agent/conncheck.h b/agent/conncheck.h index 2e4bc45..d162d33 100644 --- a/agent/conncheck.h +++ b/agent/conncheck.h @@ -117,7 +117,8 @@ void conn_check_prune_socket (NiceAgent *agent, NiceStream *stream, NiceComponent *component, NiceSocket *sock); -guint32 ensure_unique_priority (NiceComponent *component, guint32 priority); +guint32 ensure_unique_priority (NiceStream *stream, NiceComponent *component, + guint32 priority); void recalculate_pair_priorities (NiceAgent *agent); #endif /*_NICE_CONNCHECK_H */ diff --git a/agent/discovery.c b/agent/discovery.c index ef27346..40a6c09 100644 --- a/agent/discovery.c +++ b/agent/discovery.c @@ -111,7 +111,7 @@ void discovery_prune_stream (NiceAgent *agent, guint stream_id) CandidateDiscovery *cand = i->data; GSList *next = i->next; - if (cand->stream->id == stream_id) { + if (cand->stream_id == stream_id) { agent->discovery_list = g_slist_remove (agent->discovery_list, cand); discovery_free_item (cand); } @@ -156,9 +156,8 @@ void discovery_prune_socket (NiceAgent *agent, NiceSocket *sock) * Frees the CandidateDiscovery structure pointed to * by 'user data'. Compatible with g_slist_free_full(). */ -static void refresh_free_item (CandidateRefresh *cand) +static void refresh_free_item (NiceAgent *agent, CandidateRefresh *cand) { - NiceAgent *agent = cand->agent; uint8_t *username; gsize username_len; uint8_t *password; @@ -166,6 +165,8 @@ static void refresh_free_item (CandidateRefresh *cand) size_t buffer_len = 0; StunUsageTurnCompatibility turn_compat = agent_to_turn_compatibility (agent); + agent->refresh_list = g_slist_remove (agent->refresh_list, cand); + if (cand->timer_source != NULL) { g_source_destroy (cand->timer_source); g_source_unref (cand->timer_source); @@ -227,8 +228,8 @@ static void refresh_free_item (CandidateRefresh *cand) */ void refresh_free (NiceAgent *agent) { - g_slist_free_full (agent->refresh_list, (GDestroyNotify) refresh_free_item); - agent->refresh_list = NULL; + while (agent->refresh_list) + refresh_free_item (agent, agent->refresh_list->data); } /* @@ -248,9 +249,8 @@ void refresh_prune_stream (NiceAgent *agent, guint stream_id) /* 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_delete_link (agent->refresh_list, i); - refresh_free_item (cand); + if (cand->stream_id == stream_id) { + refresh_free_item (agent, cand); } i = next; @@ -267,8 +267,7 @@ void refresh_prune_candidate (NiceAgent *agent, NiceCandidate *candidate) CandidateRefresh *refresh = i->data; if (refresh->candidate == candidate) { - agent->refresh_list = g_slist_delete_link (agent->refresh_list, i); - refresh_free_item (refresh); + refresh_free_item (agent, refresh); } i = next; @@ -284,19 +283,16 @@ void refresh_prune_socket (NiceAgent *agent, NiceSocket *sock) CandidateRefresh *refresh = i->data; if (refresh->nicesock == sock) { - agent->refresh_list = g_slist_delete_link (agent->refresh_list, i); - refresh_free_item (refresh); + refresh_free_item (agent, refresh); } i = next; } } -void refresh_cancel (CandidateRefresh *refresh) +void refresh_cancel (NiceAgent *agent, CandidateRefresh *refresh) { - refresh->agent->refresh_list = g_slist_remove (refresh->agent->refresh_list, - refresh); - refresh_free_item (refresh); + refresh_free_item (agent, refresh); } @@ -549,7 +545,7 @@ HostCandidateResult discovery_add_local_host_candidate ( agent->reliable, FALSE); } - candidate->priority = ensure_unique_priority (component, + candidate->priority = ensure_unique_priority (stream, component, candidate->priority); priv_generate_candidate_credentials (agent, candidate); priv_assign_foundation (agent, candidate); @@ -641,7 +637,7 @@ discovery_add_server_reflexive_candidate ( agent->reliable, nat_assisted); } - candidate->priority = ensure_unique_priority (component, + candidate->priority = ensure_unique_priority (stream, component, candidate->priority); priv_generate_candidate_credentials (agent, candidate); priv_assign_foundation (agent, candidate); @@ -760,7 +756,7 @@ discovery_add_relay_candidate ( agent->reliable, FALSE); } - candidate->priority = ensure_unique_priority (component, + candidate->priority = ensure_unique_priority (stream, component, candidate->priority); priv_generate_candidate_credentials (agent, candidate); @@ -842,7 +838,7 @@ discovery_add_peer_reflexive_candidate ( agent->reliable, FALSE); } - candidate->priority = ensure_unique_priority (component, + candidate->priority = ensure_unique_priority (stream, component, candidate->priority); priv_assign_foundation (agent, candidate); @@ -1029,12 +1025,15 @@ static gboolean priv_discovery_tick_unlocked (NiceAgent *agent) if (nice_address_is_valid (&cand->server) && (cand->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE || cand->type == NICE_CANDIDATE_TYPE_RELAYED)) { + NiceComponent *component; - if (cand->component->state == NICE_COMPONENT_STATE_DISCONNECTED || - cand->component->state == NICE_COMPONENT_STATE_FAILED) + if (agent_find_component (agent, cand->stream_id, + cand->component_id, NULL, &component) && + (component->state == NICE_COMPONENT_STATE_DISCONNECTED || + component->state == NICE_COMPONENT_STATE_FAILED)) agent_signal_component_state_change (agent, - cand->stream->id, - cand->component->id, + cand->stream_id, + cand->component_id, NICE_COMPONENT_STATE_GATHERING); if (cand->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE) { diff --git a/agent/discovery.h b/agent/discovery.h index 67e2186..fbf1c42 100644 --- a/agent/discovery.h +++ b/agent/discovery.h @@ -46,15 +46,14 @@ typedef struct { - NiceAgent *agent; /* back pointer to owner */ NiceCandidateType type; /* candidate type STUN or TURN */ NiceSocket *nicesock; /* XXX: should be taken from local cand: existing socket to use */ NiceAddress server; /* STUN/TURN server address */ GTimeVal next_tick; /* next tick timestamp */ gboolean pending; /* is discovery in progress? */ gboolean done; /* is discovery complete? */ - NiceStream *stream; - NiceComponent *component; + guint stream_id; + guint component_id; TurnServer *turn; StunAgent stun_agent; StunTimer timer; @@ -66,12 +65,11 @@ typedef struct typedef struct { - NiceAgent *agent; /* back pointer to owner */ NiceSocket *nicesock; /* existing socket to use */ NiceAddress server; /* STUN/TURN server address */ NiceCandidate *candidate; /* candidate to refresh */ - NiceStream *stream; - NiceComponent *component; + guint stream_id; + guint component_id; StunAgent stun_agent; GSource *timer_source; GSource *tick_source; @@ -86,7 +84,7 @@ void refresh_free (NiceAgent *agent); void refresh_prune_stream (NiceAgent *agent, guint stream_id); void refresh_prune_candidate (NiceAgent *agent, NiceCandidate *candidate); void refresh_prune_socket (NiceAgent *agent, NiceSocket *sock); -void refresh_cancel (CandidateRefresh *refresh); +void refresh_cancel (NiceAgent *agent, CandidateRefresh *refresh); void discovery_free (NiceAgent *agent); diff --git a/agent/stream.c b/agent/stream.c index 533ff15..c1bd87b 100644 --- a/agent/stream.c +++ b/agent/stream.c @@ -58,13 +58,15 @@ nice_stream_finalize (GObject *obj); * @brief ICE stream functionality */ NiceStream * -nice_stream_new (guint n_components, NiceAgent *agent) +nice_stream_new (guint stream_id, guint n_components, NiceAgent *agent) { NiceStream *stream = NULL; guint n; stream = g_object_new (NICE_TYPE_STREAM, NULL); + stream->id = stream_id; + /* Create the components. */ for (n = 0; n < n_components; n++) { NiceComponent *component = NULL; diff --git a/agent/stream.h b/agent/stream.h index 954ba66..f586ff8 100644 --- a/agent/stream.h +++ b/agent/stream.h @@ -98,7 +98,7 @@ typedef struct { GType nice_stream_get_type (void); NiceStream * -nice_stream_new (guint n_components, NiceAgent *agent); +nice_stream_new (guint stream_id, guint n_components, NiceAgent *agent); void nice_stream_close (NiceStream *stream); -- cgit v1.2.1