diff options
author | sandmann <sandmann> | 2005-11-13 20:25:40 +0000 |
---|---|---|
committer | sandmann <sandmann> | 2005-11-13 20:25:40 +0000 |
commit | 8570e7742754fc1313c49297d1d73b7fbae852bb (patch) | |
tree | bfaa80a29246e990510cba6e820d955f544e8306 | |
parent | 224fbe76bc48839e041b055fc9e6db48ab3b799d (diff) |
*** empty log message ***
-rwxr-xr-x | TODO | 1 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/lac.h | 29 | ||||
-rw-r--r-- | src/lacaddress.c | 1 | ||||
-rw-r--r-- | src/lacconnection.c | 188 | ||||
-rw-r--r-- | src/lactls.c | 267 |
6 files changed, 461 insertions, 26 deletions
@@ -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 \ @@ -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 |