Moved MIN_PORT and MAX_PORT to lm-internals.h and renamed them.
Now call the LM_MIN_PORT and LM_MAX_PORT to make it clear they are defined
inside of Loudmouth.
Also more work on the DNS cleanups.
--- a/loudmouth/lm-blocking-resolver.c Mon Jul 14 23:53:27 2008 +0200
+++ b/loudmouth/lm-blocking-resolver.c Thu Jul 17 00:07:42 2008 +0200
@@ -20,11 +20,25 @@
#include <config.h>
+#include <string.h>
+#include <sys/types.h>
+#include <netdb.h>
+
+/* Needed on Mac OS X */
+#if HAVE_ARPA_NAMESER_COMPAT_H
+#include <arpa/nameser_compat.h>
+#endif
+
+#include <arpa/nameser.h>
+#include <resolv.h>
+
#include "lm-marshal.h"
#include "lm-misc.h"
#include "lm-blocking-resolver.h"
+#define SRV_LEN 8192
+
#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), LM_TYPE_BLOCKING_RESOLVER, LmBlockingResolverPriv))
typedef struct LmBlockingResolverPriv LmBlockingResolverPriv;
@@ -77,15 +91,101 @@
static void
blocking_resolver_lookup_host (LmBlockingResolver *resolver)
{
- gchar *host;
+ gchar *host;
+ struct addrinfo req;
+ struct addrinfo *ans;
+ int err;
g_object_get (resolver, "host", &host, NULL);
/* Lookup */
+ memset (&req, 0, sizeof(req));
+ req.ai_family = AF_UNSPEC;
+ req.ai_socktype = SOCK_STREAM;
+ req.ai_protocol = IPPROTO_TCP;
+
+ err = getaddrinfo (host, NULL, &req, &ans);
+
+ if (err != 0) {
+ /* FIXME: Report error */
+ return;
+ }
+
+ if (ans == NULL) {
+ /* Couldn't find any results */
+ /* FIXME: Report no results */
+ }
+
+ /* FIXME: How to set and iterate the results */
+ /*priv->results = ans;
+ priv->cur_result = ans; */
+
g_free (host);
}
+static gboolean
+blocking_resolver_parse_srv_response (unsigned char *srv,
+ int srv_len,
+ gchar **out_server,
+ guint *out_port)
+{
+ int qdcount;
+ int ancount;
+ int len;
+ const unsigned char *pos;
+ unsigned char *end;
+ HEADER *head;
+ char name[256];
+ char pref_name[256];
+ guint pref_port = 0;
+ guint pref_prio = 9999;
+
+ pref_name[0] = 0;
+
+ pos = srv + sizeof (HEADER);
+ end = srv + srv_len;
+ head = (HEADER *) srv;
+
+ qdcount = ntohs (head->qdcount);
+ ancount = ntohs (head->ancount);
+
+ /* Ignore the questions */
+ while (qdcount-- > 0 && (len = dn_expand (srv, end, pos, name, 255)) >= 0) {
+ g_assert (len >= 0);
+ pos += len + QFIXEDSZ;
+ }
+
+ /* Parse the answers */
+ while (ancount-- > 0 && (len = dn_expand (srv, end, pos, name, 255)) >= 0) {
+ /* Ignore the initial string */
+ uint16_t pref, weight, port;
+
+ g_assert (len >= 0);
+ pos += len;
+ /* Ignore type, ttl, class and dlen */
+ pos += 10;
+ GETSHORT (pref, pos);
+ GETSHORT (weight, pos);
+ GETSHORT (port, pos);
+
+ len = dn_expand (srv, end, pos, name, 255);
+ if (pref < pref_prio) {
+ pref_prio = pref;
+ strcpy (pref_name, name);
+ pref_port = port;
+ }
+ pos += len;
+ }
+
+ if (pref_name[0]) {
+ *out_server = g_strdup (pref_name);
+ *out_port = pref_port;
+ return TRUE;
+ }
+ return FALSE;
+}
+
static void
blocking_resolver_lookup_service (LmBlockingResolver *resolver)
{
@@ -93,6 +193,11 @@
gchar *service;
gchar *protocol;
gchar *srv;
+ gchar *new_server = NULL;
+ guint new_port = 0;
+ gboolean result;
+ unsigned char srv_ans[SRV_LEN];
+ int len;
g_object_get (resolver,
"domain", &domain,
@@ -102,8 +207,24 @@
srv = lm_resolver_create_srv_string (domain, service, protocol);
- /* Lookup */
+ res_init ();
+
+ len = res_query (srv, C_IN, T_SRV, srv_ans, SRV_LEN);
+ result = blocking_resolver_parse_srv_response (srv_ans, len,
+ &new_server, &new_port);
+ if (result == FALSE) {
+ /* FIXME: Report error */
+ }
+
+ g_object_set (resolver,
+ "host", new_server,
+ "port", new_port,
+ NULL);
+
+ /* Lookup the new server and the new port */
+
+ g_free (new_server);
g_free (srv);
g_free (domain);
g_free (service);
--- a/loudmouth/lm-internals.h Mon Jul 14 23:53:27 2008 +0200
+++ b/loudmouth/lm-internals.h Thu Jul 17 00:07:42 2008 +0200
@@ -34,6 +34,9 @@
#include "lm-sock.h"
#include "lm-old-socket.h"
+#define LM_MIN_PORT 1
+#define LM_MAX_PORT 65536
+
#ifndef G_OS_WIN32
typedef int LmOldSocketT;
#else /* G_OS_WIN32 */
--- a/loudmouth/lm-old-socket.c Mon Jul 14 23:53:27 2008 +0200
+++ b/loudmouth/lm-old-socket.c Thu Jul 17 00:07:42 2008 +0200
@@ -54,8 +54,6 @@
#endif
#define IN_BUFFER_SIZE 1024
-#define MIN_PORT 1
-#define MAX_PORT 65536
#define SRV_LEN 8192
struct _LmOldSocket {
@@ -1051,7 +1049,7 @@
#endif
g_return_val_if_fail (domain != NULL, NULL);
- g_return_val_if_fail ((port >= MIN_PORT && port <= MAX_PORT), NULL);
+ g_return_val_if_fail ((port >= LM_MIN_PORT && port <= LM_MAX_PORT), NULL);
g_return_val_if_fail (data_func != NULL, NULL);
g_return_val_if_fail (closed_func != NULL, NULL);
g_return_val_if_fail (connect_func != NULL, NULL);
--- a/loudmouth/lm-resolver.c Mon Jul 14 23:53:27 2008 +0200
+++ b/loudmouth/lm-resolver.c Thu Jul 17 00:07:42 2008 +0200
@@ -20,6 +20,7 @@
#include <config.h>
+#include "lm-internals.h"
#include "lm-marshal.h"
#include "lm-resolver.h"
@@ -35,6 +36,7 @@
/* -- Properties -- */
LmResolverType type;
gchar *host;
+ guint port;
/* For SRV lookups */
gchar *domain;
@@ -59,6 +61,7 @@
PROP_CONTEXT,
PROP_TYPE,
PROP_HOST,
+ PROP_PORT,
PROP_DOMAIN,
PROP_SERVICE,
PROP_PROTOCOL
@@ -96,7 +99,17 @@
"Host",
"Host to lookup",
NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_PORT,
+ g_param_spec_uint ("port",
+ "Port",
+ "Port number",
+ 0,
+ LM_MIN_PORT,
+ LM_MAX_PORT,
+ G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_DOMAIN,
@@ -172,6 +185,9 @@
case PROP_HOST:
g_value_set_string (value, priv->host);
break;
+ case PROP_PORT:
+ g_value_set_uint (value, priv->port);
+ break;
case PROP_DOMAIN:
g_value_set_string (value, priv->domain);
break;
@@ -213,6 +229,9 @@
g_free (priv->host);
priv->host = g_value_dup_string (value);
break;
+ case PROP_PORT:
+ priv->port = g_value_get_uint (value);
+ break;
case PROP_DOMAIN:
g_free (priv->domain);
priv->domain = g_value_dup_string (value);