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