summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabrice Bellet <fabrice@bellet.info>2020-07-06 13:53:44 +0200
committerOlivier CrĂȘte <olivier.crete@ocrete.ca>2021-04-20 14:07:39 +0000
commit48dac0d702b134f7b11b92602c234ba1120cc75b (patch)
treefd802f13c9b9cea1ed0e0d92d0e772c3656fc338
parente1a841356d227a15a32477b18186df036dd3c479 (diff)
downloadlibnice-48dac0d702b134f7b11b92602c234ba1120cc75b.tar.gz
agent: keep a track of the candidate refreshes being pruned
Refreshes with zero lifetime sent over tcp transport may cause the removal of the underlying socket when the remote peer closes the connection taking our request into account. These refreshes must be tracked and freeed on our side to avoid retransmission attempt on a closed socket and a heap-use-after-free error in that case.
-rw-r--r--agent/agent-priv.h1
-rw-r--r--agent/component.c1
-rw-r--r--agent/conncheck.c1
-rw-r--r--agent/discovery.c31
-rw-r--r--agent/discovery.h1
5 files changed, 35 insertions, 0 deletions
diff --git a/agent/agent-priv.h b/agent/agent-priv.h
index 1e9387c..a40363f 100644
--- a/agent/agent-priv.h
+++ b/agent/agent-priv.h
@@ -166,6 +166,7 @@ struct _NiceAgent
GSource *conncheck_timer_source; /* source of conncheck timer */
GSource *keepalive_timer_source; /* source of keepalive timer */
GSList *refresh_list; /* list of CandidateRefresh items */
+ GSList *pruning_refreshes; /* list of Refreshes current being shut down*/
guint64 tie_breaker; /* tie breaker (ICE sect 5.2
"Determining Role" ID-19) */
NiceCompatibility compatibility; /* property: Compatibility mode */
diff --git a/agent/component.c b/agent/component.c
index 5e86b15..2006c42 100644
--- a/agent/component.c
+++ b/agent/component.c
@@ -173,6 +173,7 @@ nice_component_remove_socket (NiceAgent *agent, NiceComponent *cmp,
stream = agent_find_stream (agent, cmp->stream_id);
discovery_prune_socket (agent, nsocket);
+ refresh_prune_socket (agent, nsocket);
if (stream)
conn_check_prune_socket (agent, stream, cmp, nsocket);
diff --git a/agent/conncheck.c b/agent/conncheck.c
index 689ec48..39ef78f 100644
--- a/agent/conncheck.c
+++ b/agent/conncheck.c
@@ -3855,6 +3855,7 @@ priv_add_new_turn_refresh (NiceAgent *agent, CandidateDiscovery *cdisco,
nice_debug ("timer source is : %p", cand->timer_source);
} else {
+ agent->pruning_refreshes = g_slist_append (agent->pruning_refreshes, cand);
nice_debug ("Agent %p : Sending request to remove TURN allocation "
"for refresh %p", agent, cand);
cand->disposing = TRUE;
diff --git a/agent/discovery.c b/agent/discovery.c
index dc28291..aa3ab96 100644
--- a/agent/discovery.c
+++ b/agent/discovery.c
@@ -152,6 +152,7 @@ void refresh_free (NiceAgent *agent, CandidateRefresh *cand)
nice_debug ("Agent %p : Freeing candidate refresh %p", agent, cand);
agent->refresh_list = g_slist_remove (agent->refresh_list, cand);
+ agent->pruning_refreshes = g_slist_remove (agent->pruning_refreshes, cand);
if (cand->timer_source != NULL) {
g_source_destroy (cand->timer_source);
@@ -311,6 +312,8 @@ static void refresh_prune_async (NiceAgent *agent, GSList *refreshes,
if (cand->disposing)
continue;
+ agent->pruning_refreshes = g_slist_append (agent->pruning_refreshes, cand);
+
timeout += agent->timer_ta;
cand->disposing = TRUE;
cand->destroy_cb = (GDestroyNotify) on_refresh_removed;
@@ -407,6 +410,34 @@ void refresh_prune_candidate_async (NiceAgent *agent,
}
/*
+ * Removes the candidate refreshes related to 'nicesock'.
+ */
+void refresh_prune_socket (NiceAgent *agent, NiceSocket *nicesock)
+{
+ GSList *i;
+
+ for (i = agent->refresh_list; i;) {
+ GSList *next = i->next;
+ CandidateRefresh *refresh = i->data;
+
+ if (refresh->nicesock == nicesock)
+ refresh_free(agent, refresh);
+
+ i = next;
+ }
+
+ for (i = agent->pruning_refreshes; i;) {
+ GSList *next = i->next;
+ CandidateRefresh *refresh = i->data;
+
+ if (refresh->nicesock == nicesock)
+ refresh_free(agent, refresh);
+
+ i = next;
+ }
+}
+
+/*
* Adds a new local candidate. Implements the candidate pruning
* defined in ICE spec section 4.1.3 "Eliminating Redundant
* Candidates" (ID-19).
diff --git a/agent/discovery.h b/agent/discovery.h
index aea526e..703fff6 100644
--- a/agent/discovery.h
+++ b/agent/discovery.h
@@ -94,6 +94,7 @@ void refresh_prune_stream_async (NiceAgent *agent, NiceStream *stream,
void refresh_prune_candidate (NiceAgent *agent, NiceCandidateImpl *candidate);
void refresh_prune_candidate_async (NiceAgent *agent, NiceCandidateImpl *cand,
NiceTimeoutLockedCallback function);
+void refresh_prune_socket (NiceAgent *agent, NiceSocket *nicesock);
void discovery_free (NiceAgent *agent);