summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsandmann <sandmann>2005-11-13 20:25:40 +0000
committersandmann <sandmann>2005-11-13 20:25:40 +0000
commit8570e7742754fc1313c49297d1d73b7fbae852bb (patch)
treebfaa80a29246e990510cba6e820d955f544e8306
parent224fbe76bc48839e041b055fc9e6db48ab3b799d (diff)
*** empty log message ***
-rwxr-xr-xTODO1
-rw-r--r--src/Makefile.am1
-rw-r--r--src/lac.h29
-rw-r--r--src/lacaddress.c1
-rw-r--r--src/lacconnection.c188
-rw-r--r--src/lactls.c267
6 files changed, 461 insertions, 26 deletions
diff --git a/TODO b/TODO
index 38669a2..5298e80 100755
--- a/TODO
+++ b/TODO
@@ -61,6 +61,7 @@ correctness:
* Make sure local names are handled. (/etc/host.conf and /etc/hosts)
misc:
+ * Probably use gsize instead of guint in some places, such as lac_send
* consider moving complexity from nameserver to query, ie.
have the nameserver have one response function used for all
replies. The nameserver would not keep the map between
diff --git a/src/Makefile.am b/src/Makefile.am
index 139e44a..5364b72 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -20,6 +20,7 @@ liblac_1_la_SOURCES = \
lacuri.c \
lacconnection.c \
lachttp.c \
+ lactls.c \
\
lacinternals.h \
lacdns-messages.h \
diff --git a/src/lac.h b/src/lac.h
index 0f5a50b..4f96105 100644
--- a/src/lac.h
+++ b/src/lac.h
@@ -203,6 +203,35 @@ void lac_fd_set_priority_callback (gint fd,
void lac_fd_remove_watch (gint fd);
gboolean lac_fd_is_watched (gint fd);
+
+/*
+ * TLS
+ */
+typedef struct LacTLS LacTLS;
+
+LacTLS * lac_tls_new (GError **err);
+void lac_tls_connect (LacTLS *tls);
+void lac_tls_set_read_callback (LacTLS *tls,
+ LacWatchCallback read_cb);
+void lac_tls_set_write_callback (LacTLS *tls,
+ LacWatchCallback write_cb);
+void lac_tls_set_hangup_callback (LacTLS *tls,
+ LacWatchCallback hangup_cb);
+void lac_tls_set_error_callback (LacTLS *tls,
+ LacWatchCallback error_cb);
+void lac_tls_set_priority_callback (LacTLS *tls,
+ LacWatchCallback priority_cb);
+int lac_tls_send (LacTLS *tls,
+ char *msg,
+ guint len,
+ GError **err);
+int lac_tls_recv (LacTLS *tls,
+ char *buf,
+ guint size,
+ GError **err);
+gboolean lac_tls_free (LacTLS *tls,
+ GError **err);
+
/*
* Connection
*/
diff --git a/src/lacaddress.c b/src/lacaddress.c
index cb4ef92..512b72b 100644
--- a/src/lacaddress.c
+++ b/src/lacaddress.c
@@ -410,7 +410,6 @@ lac_address_new_from_name_wait (const gchar *name,
GetHostByNameInfo ghbn_info;
ghbn_info.loop = g_main_loop_new (NULL, FALSE);
- ghbn_info.done = FALSE;
lac_address_new_lookup_all_from_name (
name, ghbn_callback, &ghbn_info);
diff --git a/src/lacconnection.c b/src/lacconnection.c
index 466c78b..8ec0a6a 100644
--- a/src/lacconnection.c
+++ b/src/lacconnection.c
@@ -22,6 +22,40 @@
#include "lac.h"
#include <string.h>
+/*
+ * Prototypes for a primitive abstraction covering TCP and SSL
+ */
+
+typedef struct Socket Socket;
+
+static Socket * socket_new_tcp (GError **err);
+static Socket * socket_new_ssl (GError **err);
+static gboolean socket_connect (Socket *socket,
+ LacAddress *address,
+ gint port,
+ GError **err);
+static gboolean socket_is_connected (Socket *socket);
+static gint socket_send (Socket *socket,
+ const gchar *msg,
+ guint len,
+ GError **err);
+static gint socket_recv (Socket *socket,
+ gchar *buf,
+ guint size,
+ GError **err);
+static int socket_get_fd (Socket *socket);
+static void socket_flush (Socket *socket);
+static gboolean socket_shutdown (Socket *socket,
+ LacShutdownMethod how,
+ GError **err);
+static gboolean socket_set_blocking (Socket *socket,
+ gboolean blocking,
+ GError **err);
+static gboolean socket_close (Socket *socket,
+ GError **err);
+
+
+
typedef enum {
UNDEFINED,
CONNECT_IN_PROGRESS,
@@ -30,8 +64,7 @@ typedef enum {
} ConnectionState;
struct _LacConnection {
- gint fd;
-
+ Socket * socket;
LacAddress * address;
gint port;
LacConnectionFunc callback;
@@ -49,6 +82,7 @@ struct _LacConnection {
gint ref_count;
};
+
static void
event_free (LacConnectionEvent *event)
{
@@ -126,8 +160,8 @@ emit_events (LacConnection *connection)
if (connection->has_fd)
{
- lac_fd_remove_watch (connection->fd);
- lac_close (connection->fd, NULL);
+ lac_fd_remove_watch (socket_get_fd (connection->socket));
+ socket_close (connection->socket, NULL);
connection->has_fd = FALSE;
}
}
@@ -176,7 +210,7 @@ lac_connection_do_reads (gpointer data)
guint8 buf [BUF_SIZE];
GError *err = NULL;
- len = lac_recv (connection->fd, buf, BUF_SIZE, &err);
+ len = socket_recv (connection->socket, buf, BUF_SIZE, &err);
if (len < 0)
{
g_assert (err);
@@ -210,7 +244,8 @@ lac_connection_do_writes (LacConnection *connection)
{
if (connection->state != CONNECTED)
{
- lac_fd_set_write_callback (connection->fd, lac_connection_writable);
+ lac_fd_set_write_callback (
+ socket_get_fd (connection->socket), lac_connection_writable);
return;
}
@@ -218,8 +253,8 @@ lac_connection_do_writes (LacConnection *connection)
{
GError *err = NULL;
- gsize sent = lac_send (
- connection->fd,
+ gsize sent = socket_send (
+ connection->socket,
connection->unwritten->str, connection->unwritten->len, &err);
if (err)
@@ -228,7 +263,8 @@ lac_connection_do_writes (LacConnection *connection)
err, LAC_SOCKET_ERROR, LAC_SOCKET_ERROR_AGAIN))
{
lac_fd_set_write_callback (
- connection->fd, lac_connection_writable);
+ socket_get_fd (connection->socket),
+ lac_connection_writable);
}
else
{
@@ -244,7 +280,7 @@ lac_connection_do_writes (LacConnection *connection)
/* FIXME check that we haven't used too much time? */
}
- lac_fd_set_write_callback (connection->fd, NULL);
+ lac_fd_set_write_callback (socket_get_fd (connection->socket), NULL);
if (connection->need_flush)
{
@@ -252,8 +288,7 @@ lac_connection_do_writes (LacConnection *connection)
* has queued up.
*/
- lac_set_nagle (connection->fd, FALSE, NULL);
- lac_set_nagle (connection->fd, TRUE, NULL);
+ socket_flush (connection->socket);
connection->need_flush = FALSE;
}
@@ -262,7 +297,7 @@ lac_connection_do_writes (LacConnection *connection)
{
GError *err = NULL;
- lac_shutdown (connection->fd, LAC_SHUTDOWN_WRITE, &err);
+ socket_shutdown (connection->socket, LAC_SHUTDOWN_WRITE, &err);
if (err)
{
queue_error (connection, err);
@@ -287,6 +322,9 @@ lac_connection_writable (gpointer data)
if (connection->state == CONNECT_IN_PROGRESS)
{
+ if (!socket_is_connected (connection->socket))
+ return;
+
connection->state = CONNECTED;
queue_connect (connection);
}
@@ -300,9 +338,9 @@ lac_connection_connect (LacConnection *connection)
{
GError *err = NULL;
- lac_connect (connection->fd,
- connection->address, connection->port,
- &err);
+ socket_connect (connection->socket,
+ connection->address, connection->port,
+ &err);
if (err)
{
@@ -338,12 +376,14 @@ lac_connection_discard_pending_events (LacConnection *connection)
static void
lac_connection_add_watch (LacConnection *connection)
{
- lac_fd_add_watch (connection->fd, connection);
+ int fd = socket_get_fd (connection->socket);
+
+ lac_fd_add_watch (fd, connection);
- lac_fd_set_read_callback (connection->fd, lac_connection_readable);
- lac_fd_set_hangup_callback (connection->fd, lac_connection_readable);
- lac_fd_set_error_callback (connection->fd, lac_connection_readable);
- lac_fd_set_write_callback (connection->fd, lac_connection_writable);
+ lac_fd_set_read_callback (fd, lac_connection_readable);
+ lac_fd_set_hangup_callback (fd, lac_connection_readable);
+ lac_fd_set_error_callback (fd, lac_connection_readable);
+ lac_fd_set_write_callback (fd, lac_connection_writable);
}
LacConnection *
@@ -378,7 +418,7 @@ lac_connection_new (const LacAddress *address,
connection->in_emit_events = FALSE;
connection->need_flush = FALSE;
- connection->fd = lac_socket_tcp (&err);
+ connection->socket = socket_new_tcp (&err);
if (err)
{
queue_error (connection, err);
@@ -389,7 +429,7 @@ lac_connection_new (const LacAddress *address,
connection->has_fd = TRUE;
- lac_set_blocking (connection->fd, FALSE, &err);
+ socket_set_blocking (connection->socket, FALSE, &err);
if (err)
{
queue_error (connection, err);
@@ -499,8 +539,8 @@ lac_connection_unref (LacConnection *connection)
if (connection->has_fd)
{
- lac_fd_remove_watch (connection->fd);
- lac_close (connection->fd, NULL);
+ lac_fd_remove_watch (socket_get_fd (connection->socket));
+ socket_close (connection->socket, NULL);
}
g_free (connection);
@@ -533,3 +573,101 @@ lac_connection_flush (LacConnection *connection)
if (connection->unwritten->len == 0)
lac_connection_do_writes (connection);
}
+
+
+/*
+ * Socket abstraction
+ */
+struct Socket
+{
+ int fd;
+};
+
+static Socket *
+socket_new_tcp (GError **err)
+{
+ Socket *socket;
+ int fd;
+
+ fd = lac_socket_tcp (err);
+
+ if (fd < 0)
+ return NULL;
+
+ socket = g_new0 (Socket, 1);
+ socket->fd = fd;
+
+ return socket;
+}
+
+static gboolean
+socket_connect (Socket *socket,
+ LacAddress *address,
+ gint port,
+ GError **err)
+{
+ return lac_connect (socket->fd, address, port, err);
+}
+
+static gboolean
+socket_is_connected (Socket *socket)
+{
+ /* We only get called when the fd is writable, which
+ * for TCP sockets means it's connected
+ */
+ return TRUE;
+}
+
+static gint
+socket_send (Socket *socket,
+ const gchar *msg,
+ guint len,
+ GError **err)
+{
+ return lac_send (socket->fd, msg, len, err);
+}
+
+static gint
+socket_recv (Socket *socket,
+ gchar *buf,
+ guint size,
+ GError **err)
+{
+ return lac_recv (socket->fd, buf, size, err);
+}
+
+static int
+socket_get_fd (Socket *socket)
+{
+ return socket->fd;
+}
+
+static gboolean
+socket_close (Socket *socket,
+ GError **err)
+{
+ return lac_close (socket->fd, err);
+}
+
+static void
+socket_flush (Socket *socket)
+{
+ lac_set_nagle (socket->fd, FALSE, NULL);
+ lac_set_nagle (socket->fd, TRUE, NULL);
+}
+
+static gboolean
+socket_set_blocking (Socket *socket,
+ gboolean blocking,
+ GError **err)
+{
+ return lac_set_blocking (socket->fd, blocking, err);
+}
+
+static gboolean
+socket_shutdown (Socket *socket,
+ LacShutdownMethod how,
+ GError **err)
+{
+ return lac_shutdown (socket->fd, how, err);
+}
diff --git a/src/lactls.c b/src/lactls.c
new file mode 100644
index 0000000..6689674
--- /dev/null
+++ b/src/lactls.c
@@ -0,0 +1,267 @@
+#include "lac.h"
+
+#include <gnutls/gnutls.h>
+
+struct LacTLS
+{
+ int fd;
+
+ LacWatchCallback read_cb;
+ LacWatchCallback write_cb;
+ LacWatchCallback hangup_cb;
+ LacWatchCallback error_cb;
+ LacWatchCallback priority_cb;
+
+};
+
+LacTLS *
+lac_tls_new (GError **err)
+{
+ int fd;
+ LacTLS *tls;
+
+ fd = lac_socket_tcp (err);
+
+ if (fd < 0)
+ return NULL;
+
+ tls = g_new0 (LacTLS, 1);
+ tls->fd = fd;
+
+ return tls;
+}
+
+static void
+on_writable (LacTLS *tls)
+{
+
+}
+
+static void
+on_readable (LacTLS *tls)
+{
+
+}
+
+void
+lac_tls_connect (LacTLS *tls)
+{
+
+}
+
+void
+lac_tls_set_read_callback (LacTLS *tls,
+ LacWatchCallback read_cb)
+{
+}
+
+void
+lac_tls_set_write_callback (LacTLS *tls,
+ LacWatchCallback write_cb)
+{
+}
+
+void
+lac_tls_set_hangup_callback (LacTLS *tls,
+ LacWatchCallback hangup_cb)
+{
+}
+
+void
+lac_tls_set_error_callback (LacTLS *tls,
+ LacWatchCallback error_cb)
+{
+}
+
+void
+lac_tls_set_priority_callback (LacTLS *tls,
+ LacWatchCallback priority_cb)
+{
+}
+
+int
+lac_tls_send (LacTLS *tls,
+ char *msg,
+ guint len,
+ GError **err)
+{
+}
+
+int
+lac_tls_recv (LacTLS *tls,
+ char *buf,
+ guint size,
+ GError **err)
+{
+}
+
+gboolean
+lac_tls_free (LacTLS *tls,
+ GError **err)
+{
+}
+
+#if 0
+LacTLS * lac_tls_new (GError *err);
+gboolean lac_tls_connect (LacTLS *tls,
+ LacAddress *addr,
+ int port,
+ GError **err);
+void lac_tls_set_read_callback (LacTLS *tls,
+ LacReadCallback cb,
+ gpointer data);
+void lac_tls_set_write_callback (LacTLS *tls);
+void lac_tls_set_hangup_callback (LacTLS *tls);
+void lac_tls_send (LacTLS *tls);
+void lac_tls_read (LacTLS *tls);
+
+
+struct LacTLS
+{
+ int fd;
+
+ /* tls */
+ gnutls_anon_client_credentials_t anoncred;
+ gnutls_session_t session;
+};
+
+
+static Socket *
+socket_new_tcp (GError **err)
+{
+ Socket *socket;
+ int fd;
+
+ fd = lac_socket_tcp (err);
+
+ if (fd < 0)
+ return NULL;
+
+ socket = g_new0 (Socket, 1);
+ socket->fd = fd;
+
+ return socket;
+}
+
+static Socket *
+socket_new_ssl (GError **err)
+{
+ const int kx_prio[] = { GNUTLS_KX_ANON_DH, 0 };
+
+ fd = lac_socket_tcp (err);
+ if (fd < 0)
+ return NULL;
+
+ socket = g_new0 (Socket, 1);
+
+ socket->is_tls = TRUE;
+
+ gnutls_global_init ();
+ gnutls_anon_allocate_client_credentials (&socket->anoncred);
+ gnutls_init (&socket->session, GNUTLS_CLIENT);
+ gnutls_set_default_priority (socket->session);
+ gnutls_kx_set_priority (socket->session, kx_prio);
+ gnutls_credentials_set (socket->session,
+ GNUTLS_CRD_ANON, &socket->anoncred);
+
+ gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) socket->fd);
+}
+
+static gboolean
+socket_connect (Socket *socket,
+ LacAddress *address,
+ gint port,
+ GError **err)
+{
+ return lac_connect (socket->fd, address, port, err);
+}
+
+static gboolean
+socket_is_connected (Socket *socket,
+ GError **err)
+{
+ if (socket->is_tls)
+ {
+ /* We only get called when the fd is writable, which
+ * for TCP sockets means it's connected
+ */
+ return TRUE;
+ }
+ else
+ {
+ int ret;
+
+ do
+ {
+ ret = gnutls_handshake (socket->session);
+ } while (ret == GNUTLS_E_INTR);
+
+ if (ret >= 0)
+ return TRUE;
+
+ if (ret != GNUTLS_E_AGAIN)
+ {
+ /* FIXME: set error */
+ g_warning ("err\n");
+ }
+
+ return FALSE;
+ }
+}
+
+static gint
+socket_send (Socket *socket,
+ const gchar *msg,
+ guint len,
+ GError **err)
+{
+ return lac_send (socket->fd, msg, len, err);
+}
+
+static gint
+socket_recv (Socket *socket,
+ gchar *buf,
+ guint size,
+ GError **err)
+{
+ return lac_recv (socket->fd, buf, size, err);
+}
+
+static int
+socket_get_fd (Socket *socket)
+{
+ return socket->fd;
+}
+
+static gboolean
+socket_close (Socket *socket,
+ GError **err)
+{
+ return lac_close (socket->fd, err);
+}
+
+static void
+socket_flush (Socket *socket)
+{
+ lac_set_nagle (socket->fd, FALSE, NULL);
+ lac_set_nagle (socket->fd, TRUE, NULL);
+}
+
+static gboolean
+socket_set_blocking (Socket *socket,
+ gboolean blocking,
+ GError **err)
+{
+ return lac_set_blocking (socket->fd, blocking, err);
+}
+
+static gboolean
+socket_shutdown (Socket *socket,
+ LacShutdownMethod how,
+ GError **err)
+{
+ return lac_shutdown (socket->fd, how, err);
+}
+
+
+#endif