add fd handler example code for ssl connecting to a remote server in only 3 ecore...
authordiscomfitor <discomfitor@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 29 Sep 2010 19:12:43 +0000 (19:12 +0000)
committerdiscomfitor <discomfitor@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 29 Sep 2010 19:12:43 +0000 (19:12 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@52903 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

doc/ecore.dox.in
examples/ecore_fd_handler_example.c [new file with mode: 0644]

index 1cee60c..1b7bb82 100644 (file)
@@ -315,6 +315,11 @@ Shows how to use event handlers.
 */
 
 /**
+@example ecore_fd_handler_example.c
+Shows how to use fd handlers.
+*/
+
+/**
 @example ecore_timer_example.c
 Demonstrates use of the ecore_timer.
 */
diff --git a/examples/ecore_fd_handler_example.c b/examples/ecore_fd_handler_example.c
new file mode 100644 (file)
index 0000000..63aeb30
--- /dev/null
@@ -0,0 +1,188 @@
+#include <Ecore.h>
+#include <fcntl.h>
+#include <netinet/tcp.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <unistd.h>
+#include <gnutls/gnutls.h>
+
+/* Ecore_Fd_Handler example
+ * 2010 Mike Blumenkrantz
+ */
+
+#define print(...) fprintf(stderr, "line %i: ", __LINE__); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n")
+
+static int done = 0;
+
+static void
+tls_log_func (int level, const char *str)
+{
+  fprintf (stderr, "|<%d>| %s", level, str);
+}
+
+static const char*
+SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_description_t status)
+{
+   switch (status)
+     {
+      case GNUTLS_HANDSHAKE_HELLO_REQUEST:
+        return "Hello request";
+      case GNUTLS_HANDSHAKE_CLIENT_HELLO:
+        return "Client hello";
+      case GNUTLS_HANDSHAKE_SERVER_HELLO:
+        return "Server hello";
+      case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET:
+        return "New session ticket";
+      case GNUTLS_HANDSHAKE_CERTIFICATE_PKT:
+        return "Certificate packet";
+      case GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE:
+        return "Server key exchange";
+      case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST:
+        return "Certificate request";
+      case GNUTLS_HANDSHAKE_SERVER_HELLO_DONE:
+        return "Server hello done";
+      case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY:
+        return "Certificate verify";
+      case GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE:
+        return "Client key exchange";
+      case GNUTLS_HANDSHAKE_FINISHED:
+        return "Finished";
+      case GNUTLS_HANDSHAKE_SUPPLEMENTAL:
+        return "Supplemental";
+     }
+   return NULL;
+}
+
+/* Connects to the peer and returns a socket
+ * descriptor.
+ */
+static int
+tcp_connect (void)
+{
+  const char *PORT = "443";
+  const char *SERVER = "69.58.181.89"; //verisign.com
+  int err, sd;
+  int flag = 1, curstate = 0;
+  struct sockaddr_in sa;
+
+  /* sets some fd options such as nonblock */
+  fcntl(sd, F_SETFL, O_NONBLOCK);
+  fcntl(sd, F_SETFD, FD_CLOEXEC);
+  setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate, sizeof(curstate));
+
+  setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
+  sd = socket (AF_INET, SOCK_STREAM, 0);
+
+  memset (&sa, '\0', sizeof (sa));
+  sa.sin_family = AF_INET;
+  sa.sin_port = htons (atoi (PORT));
+  inet_pton (AF_INET, SERVER, &sa.sin_addr);
+
+  /* connects to server
+   */
+  err = connect (sd, (struct sockaddr *) &sa, sizeof (sa));
+  if (err < 0)
+    {
+      fprintf (stderr, "Connect error\n");
+      exit (1);
+    }
+
+  return sd;
+}
+
+/* closes the given socket descriptor.
+ */
+static void
+tcp_close (int sd)
+{
+  shutdown (sd, SHUT_RDWR);    /* no more receptions */
+  close (sd);
+}
+
+static Eina_Bool
+_process_data(gnutls_session_t client, Ecore_Fd_Handler *fd_handler)
+{
+   static int ret, lastret;
+   
+   if (!done)
+     {
+        lastret = ret;
+        ret = gnutls_handshake (client);
+        /* avoid printing messages infinity times */
+        if (lastret != ret)
+          {
+             print("gnutls returned with: %s - %s", gnutls_strerror_name(ret), gnutls_strerror(ret));
+             if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED))
+               print("Also received alert: %s", gnutls_alert_get_name(gnutls_alert_get(client)));
+             print("last out: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_out(client)));
+             print("last in: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_in(client)));
+          }
+
+        if (gnutls_error_is_fatal(ret))
+          {
+             print("yarrr this be an error!");
+             exit(1);
+          }
+        
+     }
+  if (ret == GNUTLS_E_SUCCESS)
+    {
+       done = 1;
+       print("Handshake successful!");
+       ecore_main_loop_quit();
+    }
+
+   return ECORE_CALLBACK_RENEW;
+}
+
+int
+main (void)
+{
+  /* credentials */
+  gnutls_anon_client_credentials_t c_anoncred;
+  gnutls_certificate_credentials_t c_certcred;
+  
+  gnutls_session_t client;
+  int sd;
+
+  /* General init. */
+  gnutls_global_init ();
+  ecore_init();
+  gnutls_global_set_log_function (tls_log_func);
+    gnutls_global_set_log_level (6);
+
+  /* Init client */
+  gnutls_anon_allocate_client_credentials (&c_anoncred);
+  gnutls_certificate_allocate_credentials (&c_certcred);
+  gnutls_init (&client, GNUTLS_CLIENT);
+  /* set very specific priorities */
+  gnutls_priority_set_direct(client, "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0", NULL);
+  gnutls_credentials_set (client, GNUTLS_CRD_ANON, c_anoncred);
+  gnutls_credentials_set (client, GNUTLS_CRD_CERTIFICATE, c_certcred);
+
+
+  /* connect to the peer
+   */
+  sd = tcp_connect ();
+
+  /* associate gnutls with socket */
+  gnutls_transport_set_ptr (client, (gnutls_transport_ptr_t) sd);
+  /* add a callback for data being available for send/receive on socket */
+  if (!ecore_main_fd_handler_add(sd, ECORE_FD_READ | ECORE_FD_WRITE, (Ecore_Fd_Cb)_process_data, client, NULL, NULL))
+    {
+       print("could not create fd handler!");
+       exit(1);
+    }
+  /* begin main loop */
+  ecore_main_loop_begin();
+
+  gnutls_bye (client, GNUTLS_SHUT_RDWR);
+
+  gnutls_deinit (client);
+
+  tcp_close (sd);
+  
+  return 0;
+}