Separate iochannel implementation from HCConn interface.
[cascardo/rnetproxy.git] / ssl_server.c
index bc68080..270e7bd 100644 (file)
 #include "ssl.h"
 
 static struct ssl_data *
-ssl_data_new (char *server)
+ssl_data_new (void)
 {
   struct ssl_data *ssl;
   int kx_prio[] = {GNUTLS_KX_RSA, 0};
   gnutls_certificate_credentials cred;
   gnutls_certificate_allocate_credentials (&cred);
   ssl = g_slice_new (struct ssl_data);
-  ssl->server = g_strdup (server);
   gnutls_init (&ssl->session, GNUTLS_CLIENT);
   gnutls_set_default_priority (ssl->session);
   gnutls_set_default_priority (ssl->session);
@@ -47,7 +46,6 @@ static void
 ssl_data_destroy (struct ssl_data *ssl)
 {
   gnutls_deinit (ssl->session);
-  g_free (ssl->server);
   g_string_free (ssl->buffer, TRUE);
   g_slice_free (struct ssl_data, ssl);
 }
@@ -60,8 +58,8 @@ ssl_push (gnutls_transport_ptr_t ptr, const void *buffer, size_t len)
   int r;
   if (ssl->handshaking == TRUE)
     {
-      r = hc_conn_read (hook->conn, buffer, len);
-      return r;
+      hc_conn_write (hook->conn, (void *) buffer, len);
+      return len;
     }
   hc_conn_write (hook->conn, (void *) buffer, len);
   return len;
@@ -109,11 +107,14 @@ ssl_server_connect (net_hook_t *hook)
   ssl->handshaking = TRUE;
   if ((error = gnutls_handshake (ssl->session)) < 0)
     {
-      g_message ("%satal error while doing TLS handshaking.\n",
-                 gnutls_error_is_fatal (error) ? "F" : "Nonf");
-      g_message ("%s\n", gnutls_strerror (error));
+      if (gnutls_error_is_fatal (error))
+        g_critical ("Fatal error while doing TLS handshaking: %s\n",
+                    gnutls_strerror (error));
+    }
+  if (error != GNUTLS_E_AGAIN && error != GNUTLS_E_INTERRUPTED)
+    {
+      ssl->handshaking = FALSE;
     }
-  ssl->handshaking = FALSE;
 }
 
 static void
@@ -158,13 +159,16 @@ net_hook_t *
 ssl_server_hook_new (net_hook_t *client_hook, char *server, char *port)
 {
   net_hook_t *hook;
+  int fd;
   hook = g_slice_new (net_hook_t);
   hook->peer = client_hook;
   hook->server = TRUE;
   hook->connect = ssl_server_connect;
   hook->close = ssl_server_close;
   hook->read = ssl_server_read;
-  hook->data = ssl_data_new (server);
-  hook->conn = hc_conn_new (hc_tcp_connect (server, port), nethook_event, hook);
+  hook->data = ssl_data_new ();
+  hook->conn = hc_conn_new (nethook_event, hook);
+  fd = hc_tcp_connect (server, port);
+  hc_conn_set_driver_channel (hook->conn, fd);
   return hook;
 }