loudmouth/lm-asyncns-resolver.c
changeset 471 a7cf42557aef
parent 457 9eeae02afc18
child 472 5aa76e995f0d
--- a/loudmouth/lm-asyncns-resolver.c	Thu Jul 31 14:12:33 2008 +0200
+++ b/loudmouth/lm-asyncns-resolver.c	Thu Jul 31 19:50:01 2008 +0200
@@ -20,14 +20,24 @@
 
 #include <config.h>
 
+#include <string.h>
+#include <asyncns.h>
+#define freeaddrinfo(x) asyncns_freeaddrinfo(x)
+
+#include "lm-error.h"
+#include "lm-internals.h"
 #include "lm-marshal.h"
+#include "lm-misc.h"
 #include "lm-asyncns-resolver.h"
 
 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), LM_TYPE_ASYNCNS_RESOLVER, LmAsyncnsResolverPriv))
 
 typedef struct LmAsyncnsResolverPriv LmAsyncnsResolverPriv;
 struct LmAsyncnsResolverPriv {
-	gint my_prop;
+	GSource		*watch_resolv;
+	asyncns_query_t *resolv_query;
+	asyncns_t	*asyncns_ctx;
+	GIOChannel	*resolv_channel;
 };
 
 static void     asyncns_resolver_finalize      (GObject     *object);
@@ -69,8 +79,155 @@
 }
 
 static void
+asyncns_resolver_cleanup (LmResolver *resolver)
+{
+        LmAsyncnsResolverPriv *priv = GET_PRIV (resolver);
+
+        if (priv->resolv_channel != NULL) {
+		g_io_channel_unref (priv->resolv_channel);
+                priv->resolv_channel = NULL;
+	}
+ 
+        if (priv->watch_resolv) {
+		g_source_destroy (priv->watch_resolv);
+                priv->watch_resolv = NULL;
+	}
+
+	if (priv->asyncns_ctx) {
+                asyncns_free (priv->asyncns_ctx);
+                priv->asyncns_ctx = NULL;
+	}
+
+        priv->resolv_query = NULL;
+}
+
+static gboolean
+asyncns_resolver_done (GSource      *source,
+                       GIOCondition  condition,
+                       gpointer      data)
+{
+        LmAsyncnsResolverPriv *priv = GET_PRIV (data);
+        struct addrinfo	      *ans;
+	int 		       err;
+	gboolean               result = FALSE;
+
+	/* process pending data */
+        asyncns_wait (priv->asyncns_ctx, FALSE);
+
+	if (!asyncns_isdone (priv->asyncns_ctx, priv->resolv_query)) {
+		result = TRUE;
+	} else {
+                err = asyncns_getaddrinfo_done (priv->asyncns_ctx, priv->resolv_query, &ans);
+                priv->resolv_query = NULL;
+                /* Signal that we are done */
+
+                if (err) {
+                        _lm_resolver_set_result (LM_RESOLVER (data),
+                                                 LM_RESOLVER_RESULT_FAILED, 
+                                                 NULL);
+                } else {
+                        _lm_resolver_set_result (LM_RESOLVER (data),
+                                                 LM_RESOLVER_RESULT_OK,
+                                                 ans);
+                }
+
+                asyncns_resolver_cleanup (LM_RESOLVER (data));
+	}
+
+	return result;
+}
+
+static gboolean
+asyncns_resolver_prep (LmResolver *resolver, GError **error)
+{
+        LmAsyncnsResolverPriv *priv = GET_PRIV (resolver);
+        GMainContext          *context;
+
+
+        if (priv->asyncns_ctx) {
+                return TRUE;
+	}
+
+        priv->asyncns_ctx = asyncns_new (1);
+	if (priv->asyncns_ctx == NULL) {
+                g_set_error (error,
+                             LM_ERROR,                 
+                             LM_ERROR_CONNECTION_FAILED,   
+                             "can't initialise libasyncns");
+		return FALSE;
+	}
+
+        priv->resolv_channel =
+                g_io_channel_unix_new (asyncns_fd (priv->asyncns_ctx));
+
+        g_object_get (resolver, "context", &context, NULL);
+
+        priv->watch_resolv = 
+                lm_misc_add_io_watch (context,
+                                      priv->resolv_channel,
+				      G_IO_IN,
+				      (GIOFunc) asyncns_resolver_done,
+				      socket);
+
+	return TRUE;
+}
+
+static void
+asyncns_resolver_lookup_host (LmResolver *resolver)
+{
+        LmAsyncnsResolverPriv *priv = GET_PRIV (resolver);
+        gchar               *host;
+        struct addrinfo      req;
+
+        g_object_get (resolver, "host", &host, NULL);
+
+	memset (&req, 0, sizeof(req));
+	req.ai_family   = AF_UNSPEC;
+	req.ai_socktype = SOCK_STREAM;
+	req.ai_protocol = IPPROTO_TCP;
+
+	if (!asyncns_resolver_prep (resolver, NULL)) {
+                g_warning ("Signal error\n");
+		return;
+        }
+
+        priv->resolv_query =
+	  	asyncns_getaddrinfo (priv->asyncns_ctx,
+                                     host,
+				     NULL,
+				     &req);
+/*
+	asyncns_setuserdata (priv->asyncns_ctx,
+                             priv->resolv_query,
+			     (gpointer) PHASE_2);
+*/
+}
+
+static void
+asyncns_resolver_lookup_service (LmResolver *resolver)
+{
+}
+
+static void
 asyncns_resolver_lookup (LmResolver *resolver)
 {
+        gint type;
+
+        /* Start the DNS querying */
+
+        /* Decide if we are going to lookup a srv or host */
+        g_object_get (resolver, "type", &type, NULL);
+
+        switch (type) {
+        case LM_RESOLVER_HOST:
+                asyncns_resolver_lookup_host (resolver);
+                break;
+        case LM_RESOLVER_SRV:
+                asyncns_resolver_lookup_service (resolver);
+                break;
+        };
+
+        /* End of DNS querying */
 } 
 
 static void