--- 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