bus hacking
authorhallski <hallski>
Fri, 16 Jun 2006 08:51:48 +0000
changeset 154 207483c02cfc
parent 153 b2324df84971
child 155 d24c4392d4e3
bus hacking
loudmouth/lm-socket.c
--- a/loudmouth/lm-socket.c	Tue Jun 06 12:39:19 2006 +0000
+++ b/loudmouth/lm-socket.c	Fri Jun 16 08:51:48 2006 +0000
@@ -28,9 +28,12 @@
 
 /* FIXME: Integrate with the SSL stuff */
 
+/* FIXME: IO Buffering both in/out here? */
+
 struct _LmSocket {
 	LmSock          sock;
-	GIOChannel     *channel;
+	GIOChannel     *io_channel;
+	guint           io_watch;
 	/* FIXME: Add the rest */
 
 	LmSSL          *ssl;
@@ -44,8 +47,36 @@
 	gint            ref;
 };
 
-static LmSocket *  socket_create (void);
-static void        socket_free   (LmSocket *socket);
+typedef void   (* SocketDNSCallback)  (LmSocket      *socket,
+				       SocketDNSData *data,
+				       gboolean       success);
+
+typedef struct {
+	/* Used when socket tries to connect */
+	struct addrinfo   *resolved_addrs;
+	struct addrinfo   *current_addr;
+
+	/* -- Internal during DNS lookup -- */
+	LmSocket          *socket;
+	gchar             *host;
+	SocketDNSCallback  callback;
+} SocketDNSData;
+
+static LmSocket *  socket_create            (void);
+static void        socket_free              (LmSocket          *socket);
+static gboolean    socket_channel_event     (GIOChannel        *source,
+					     GIOCondition       condition,
+					     LmSocket          *socket);
+static void        socket_dns_lookup        (LmSocket          *socket,
+					     const gchar       *host,
+					     SocketDNSCallback  callback);
+static SocketDNSData * socket_dns_data_new  (LmSocket          *socket,
+					     const gchar       *host,
+					     SocketDNSCallback  callbac);
+static void            socket_dns_data_free (SocketDNSData     *data);
+static void            socket_start_connect (LmSocket          *socket,
+					     SocketDNSData     *data,
+					     gboolean           success);
 
 static LmSocket *
 socket_create (void)
@@ -66,13 +97,112 @@
 {
 	/* FIXME: Free up the rest of the memory */
 
+	if (socket->io_channel) {
+		if (socket->io_watch != 0) {
+			g_source_destroy (g_main_context_find_source_by_id (socket->context),
+					  socket->io_watch);
+			socket->io_watch = 0;
+		}
+
+		g_io_channel_unref (socket->io_channel);
+		socket->io_channel = NULL;
+
+		socket->fd = -1;
+	}
+
 	if (socket->ssl) {
 		_lm_ssl_unref (socket->ssl);
 	}
 
 	g_free (socket->host);
+	g_free (socket);
+}
 
-	g_free (socket);
+static gboolean
+socket_channel_event (GIOChannel   *source,
+		      GIOCondition  condition,
+		      LmSocket     *socket)
+{
+	if (condition & G_IO_IN)  {}
+	if (condition & G_IO_OUT) {}
+	if (condition & G_IO_ERR) {}
+	if (condition & G_IO_HUP) {}
+}
+
+static void
+eocket_dns_lookup (LmSocket          *socket,
+		   const gchar       *host,
+		   SocketDNSCallback  callback);
+{
+	SocketDNSData   *data;
+	struct addrinfo  req;
+	struct addrinfo  ans;
+	int              err;
+
+	/* FIXME: This should not be synchronous */
+	data = socket_dns_data_new (socket, host, callback);
+
+	memset (&req, 0, sizeof (req));
+	req.ai_family   = AF_UNSPEC;
+	req.ai_socktype = SOCK_STREAM;
+	req.ai_protocol = IPPROTO_TCP;
+
+	err = getaddrinfo (data->host, NULL, &req, &ans);
+	if (err != 0) {
+		/* FIXME: Handle error */
+		data->callback (data->socket, data, FALSE);
+	}
+
+	data->resolved_addrs = ans;
+	data->current_addr   = ans;
+
+	data->callback (data->socket, data, TRUE);
+
+}
+
+static SocketDNSData *
+socket_dns_data_new (LmSocket          *socket,
+		     const gchar       *host,
+		     SocketDNSCallback  callbac)
+{
+	SocketDNSData *data;
+
+	data = g_new0 (SocketDNSData, 1);
+	
+	data->socket   = lm_socket_ref (socket);
+	data->host     = g_strdup (host);
+	data->callback = callback;
+
+	data->resolved_addrs = data->current_addr = NULL;
+
+	return data;
+}
+
+static void
+socket_dns_data_free (SocketDNSData *data)
+{
+	lm_socket_unref (data->socket);
+	g_free (data->host);
+
+	if (data->resolved_addrs) {
+		freeaddrinfo (data->resolved_addrs);;
+		deta->resolved_addrs = NULL;
+	}
+
+	g_free (data);
+}
+
+static void
+socket_start_connect (LmSocket      *socket,
+		      SocketDNSData *data,
+		      gboolean       success)
+{
+	if (!success) {
+		socket_dns_data_free (data);
+		/* FIXME: Report error */
+	}
+
+	/* FIXME: Continue and connect */
 }
 
 LmSocket *
@@ -95,7 +225,7 @@
 {
 	g_return_if_fail (socket != NULL);
 
-	/* Fork and DNS Lookup */
+	socket_dns_lookup (socket, socket->host, socket_start_connect);
 }
 
 int
@@ -154,7 +284,7 @@
 		gsize     bytes_written = 0;
 
 		while (io_status == G_IO_STATUS_AGAIN) {
-			io_status = g_io_channel_write_chars (socket->channel,
+			io_status = g_io_channel_write_chars (socket->io_channel,
 							      buf, size,
 							      &bytes_written,
 							      NULL);
@@ -186,7 +316,7 @@
 			status = _lm_ssl_read (socket->ssl, 
 					       buf, size, &bytes_read);
 		} else {
-			status = g_io_channel_read_chars (socket->channel, 
+			status = g_io_channel_read_chars (socket->io_channel, 
 							  buf, size, 
 							  &bytes_read,
 							  NULL);