summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiraj Razick <siraj.razick@collabora.co.uk>2012-03-25 13:55:41 -0400
committerSiraj Razick <siraj.razick@collabora.co.uk>2012-03-26 11:26:49 -0400
commit7862ef54e777add5febcb8160384726a62547c18 (patch)
tree604837c26e919b4a2aef2033d86e1ff2ca187386
parentd7cb7b863e3de66bfe1f506a8879d180e1534637 (diff)
downloadtelepathy-salut-7862ef54e777add5febcb8160384726a62547c18.tar.gz
bonjour-contact: Handle new Address resolves while another is in progress
We leak if another address resolve starts while another is in progress so we avoid this by stoping the in-progress operation and starting the new one after freeing the record and address_refs properly. The patch also cleans up freeing resolver context data.
-rw-r--r--src/bonjour-contact.c71
1 files changed, 61 insertions, 10 deletions
diff --git a/src/bonjour-contact.c b/src/bonjour-contact.c
index 5544ad6c..564628e9 100644
--- a/src/bonjour-contact.c
+++ b/src/bonjour-contact.c
@@ -91,6 +91,38 @@ salut_bonjour_contact_init (SalutBonjourContact *self)
}
static void
+_salut_bonjour_resolve_ctx_free (SalutBonjourContact *self,
+ SalutBonjourResolveCtx *ctx)
+{
+ SalutBonjourContactPrivate *priv = self->priv;
+
+ if (ctx->address_ref != NULL)
+ {
+ salut_bonjour_discovery_client_drop_svc_ref (priv->discovery_client,
+ ctx->address_ref);
+ }
+
+ if (ctx->txt_record)
+ {
+ g_free (ctx->txt_record);
+ }
+
+ if (ctx->address)
+ g_free (ctx->address);
+
+ if (ctx->name)
+ g_free (ctx->name);
+
+ if (ctx->type)
+ g_free (ctx->type);
+
+ if (ctx->domain)
+ g_free (ctx->domain);
+
+ g_slice_free (SalutBonjourResolveCtx, ctx);
+}
+
+static void
salut_bonjour_contact_get_property (GObject *object,
guint property_id,
GValue *value,
@@ -381,7 +413,7 @@ salut_bonjour_contact_dispose (GObject *object)
salut_bonjour_discovery_client_drop_svc_ref (priv->discovery_client,
ctx->resolve_ref);
- g_slice_free (SalutBonjourResolveCtx, ctx);
+ _salut_bonjour_resolve_ctx_free (self, ctx);
}
g_slist_free (priv->resolvers);
@@ -466,11 +498,18 @@ _bonjour_getaddr_cb (DNSServiceRef service_ref,
if (error_type != kDNSServiceErr_NoError)
{
DEBUG ("Resolver failed with : (%d)", error_type);
- g_free (ctx->txt_record);
- ctx->txt_length = 0;
salut_bonjour_discovery_client_drop_svc_ref (priv->discovery_client,
ctx->address_ref);
- return;
+ ctx->address_ref = NULL;
+ g_free (ctx->txt_record);
+ ctx->txt_record = NULL;
+ return;
+ }
+
+ if (ctx->address)
+ {
+ g_free (ctx->address);
+ ctx->address = NULL;
}
if (address->sa_family == AF_INET)
@@ -482,6 +521,7 @@ _bonjour_getaddr_cb (DNSServiceRef service_ref,
salut_bonjour_discovery_client_drop_svc_ref (priv->discovery_client,
ctx->address_ref);
+ ctx->address_ref = NULL;
salut_contact_freeze (contact);
@@ -567,6 +607,7 @@ _bonjour_getaddr_cb (DNSServiceRef service_ref,
g_free (ctx->txt_record);
ctx->txt_length = 0;
+ ctx->txt_record = NULL;
}
static void DNSSD_API
@@ -586,6 +627,19 @@ _bonjour_service_resolve_cb (DNSServiceRef service_ref,
SalutBonjourContactPrivate *priv = self->priv;
DNSServiceErrorType _error_type = kDNSServiceErr_NoError;
+ if (ctx->address_ref != NULL)
+ {
+ salut_bonjour_discovery_client_drop_svc_ref (priv->discovery_client,
+ ctx->address_ref);
+ ctx->address_ref = NULL;
+ }
+
+ if (ctx->txt_record != NULL)
+ {
+ g_free (ctx->txt_record);
+ ctx->txt_record = NULL;
+ }
+
ctx->txt_record = g_strndup ((const gchar *) txt_record, (guint) txt_length);
ctx->txt_length = txt_length;
ctx->port = ntohs (port);
@@ -624,11 +678,7 @@ salut_bonjour_contact_remove_service (SalutBonjourContact *self,
priv->resolvers = g_slist_remove (priv->resolvers, ctx);
- g_free (ctx->address);
- g_free (ctx->name);
- g_free (ctx->type);
- g_free (ctx->domain);
- g_slice_free (SalutBonjourResolveCtx, ctx);
+ _salut_bonjour_resolve_ctx_free (self, ctx);
if (priv->resolvers == NULL)
salut_contact_lost (SALUT_CONTACT (self));
@@ -658,6 +708,7 @@ salut_bonjour_contact_add_service (SalutBonjourContact *self,
ctx->address = NULL;
ctx->txt_length = 0;
ctx->txt_record = NULL;
+ ctx->address_ref = NULL;
error_type = DNSServiceResolve (&ctx->resolve_ref,
0, interface, name, type, domain, _bonjour_service_resolve_cb, ctx);
@@ -665,7 +716,7 @@ salut_bonjour_contact_add_service (SalutBonjourContact *self,
if (error_type != kDNSServiceErr_NoError)
{
DEBUG ("ServiceResolve failed with : (%d)", error_type);
- g_slice_free (SalutBonjourResolveCtx, ctx);
+ _salut_bonjour_resolve_ctx_free (self, ctx);
return FALSE;
}