]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
updated server examples
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Tue, 27 Dec 2011 21:32:12 +0000 (23:32 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 28 Dec 2011 14:08:55 +0000 (16:08 +0200)
.gitignore
doc/examples/ex-serv-dtls.c
doc/examples/ex-serv1.c

index 7e45f1417d378caf38848cbe9731504b2444633c..f06f9f3168b1c6c3eecb45bde23a8fcf027d26ed 100644 (file)
@@ -70,6 +70,7 @@ doc/examples/ex-serv-pgp
 doc/examples/ex-serv-psk
 doc/examples/ex-serv-srp
 doc/examples/ex-serv1
+doc/examples/ex-serv-dtls
 doc/examples/libexamples.la
 doc/extra.c.texi
 doc/gnutls-api.texi
index bdcbe3bb61a201954d8077d4b6a69bd53be64b86..52c96c328b2f515fc5199968a833c0af45ec1ff8 100644 (file)
 #define CRLFILE "crl.pem"
 
 /* This is a sample DTLS echo server, using X.509 authentication.
+ * Note that error checking is minimal to simplify the example.
  */
 
-#define SA struct sockaddr
-#define SOCKET_ERR(err,s) if(err==-1) {perror(s);return(1);}
 #define MAX_BUFFER 1024
-#define PORT 5556               /* listen to 5556 port */
+#define PORT 5556
 
-typedef struct {
+typedef struct
+{
   gnutls_session_t session;
   int fd;
-  struct sockaddr * cli_addr;
+  struct sockaddr *cli_addr;
   socklen_t cli_addr_size;
 } priv_data_st;
 
-static int pull_timeout_func(gnutls_transport_ptr_t ptr, unsigned int ms);
-static ssize_t push_func (gnutls_transport_ptr_t p, const void * data, size_t size);
-static ssize_t pull_func(gnutls_transport_ptr_t p, void * data, size_t size);
-static const char *
-human_addr (const struct sockaddr *sa, socklen_t salen,
-            char *buf, size_t buflen);
-static int wait_for_connection(int fd);
+static int pull_timeout_func (gnutls_transport_ptr_t ptr, unsigned int ms);
+static ssize_t push_func (gnutls_transport_ptr_t p, const void *data,
+                          size_t size);
+static ssize_t pull_func (gnutls_transport_ptr_t p, void *data, size_t size);
+static const char *human_addr (const struct sockaddr *sa, socklen_t salen,
+                               char *buf, size_t buflen);
+static int wait_for_connection (int fd);
 static gnutls_session_t initialize_tls_session (void);
 static int generate_dh_params (void);
 
-/* These are global */
+/* Use global credentials and parameters to simplify
+ * the example. */
 static gnutls_certificate_credentials_t x509_cred;
 static gnutls_priority_t priority_cache;
 static gnutls_dh_params_t dh_params;
@@ -56,7 +57,7 @@ static gnutls_dh_params_t dh_params;
 int
 main (void)
 {
-  int err, listen_sd;
+  int listen_sd;
   int sock, ret;
   struct sockaddr_in sa_serv;
   struct sockaddr_in cli_addr;
@@ -80,99 +81,105 @@ main (void)
   gnutls_certificate_set_x509_crl_file (x509_cred, CRLFILE,
                                         GNUTLS_X509_FMT_PEM);
 
-  gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE,
+  ret = gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE,
                                         GNUTLS_X509_FMT_PEM);
+  if (ret < 0)
+    {
+      printf("No certificate or key were found\n");
+      exit(1);
+    }
 
   generate_dh_params ();
 
   gnutls_certificate_set_dh_params (x509_cred, dh_params);
 
-  ret = gnutls_priority_init (&priority_cache, "NORMAL:-VERS-TLS-ALL:+VERS-DTLS1.0", NULL);
-  if (ret < 0)
-    {
-      fprintf(stderr, "Error in the priority string\n");
-      exit(1);
-    }
+  gnutls_priority_init (&priority_cache,
+                        "NORMAL:-VERS-TLS-ALL:+VERS-DTLS1.0", NULL);
 
-  ret = gnutls_key_generate(&cookie_key, GNUTLS_COOKIE_KEY_SIZE);
-  if (ret < 0)
-    {
-      fprintf(stderr, "Cannot generate key\n");
-      exit(1);
-    }
+  gnutls_key_generate (&cookie_key, GNUTLS_COOKIE_KEY_SIZE);
 
   /* Socket operations
    */
   listen_sd = socket (AF_INET, SOCK_DGRAM, 0);
-  SOCKET_ERR (listen_sd, "socket");
 
   memset (&sa_serv, '\0', sizeof (sa_serv));
   sa_serv.sin_family = AF_INET;
   sa_serv.sin_addr.s_addr = INADDR_ANY;
-  sa_serv.sin_port = htons (PORT);      /* Server Port number */
+  sa_serv.sin_port = htons (PORT);
 
-#ifdef IP_DONTFRAG
-  {
+  { /* DTLS requires the IP don't fragment (DF) bit to be set */
+#if defined(IP_DONTFRAG)
     int optval = 1;
-    if (setsockopt (s, IPPROTO_IP, IP_DONTFRAG,
-                    (const void *) &optval, sizeof (optval)) < 0)
-      {
-        perror ("setsockopt(IP_DF) failed");
-      }
-  }
+    setsockopt (listen_sd, IPPROTO_IP, IP_DONTFRAG,
+                (const void *) &optval, sizeof (optval));
+#elif defined(IP_MTU_DISCOVER)
+    int optval = IP_PMTUDISC_DO;
+    setsockopt(listen_sd, IPPROTO_IP, IP_MTU_DISCOVER, 
+               (const void*) &optval, sizeof (optval));
 #endif
-  err = bind (listen_sd, (SA *) &sa_serv, sizeof (sa_serv));
-  SOCKET_ERR (err, "bind");
+  }
+
+  bind (listen_sd, (struct sockaddr *) &sa_serv, sizeof (sa_serv));
 
   printf ("UDP server ready. Listening to port '%d'.\n\n", PORT);
 
   for (;;)
     {
-      printf("Waiting for connection...\n");
-      sock = wait_for_connection(listen_sd);
+      printf ("Waiting for connection...\n");
+      sock = wait_for_connection (listen_sd);
       if (sock < 0)
         continue;
 
-      cli_addr_size = sizeof(cli_addr);
-      ret = recvfrom(sock, buffer, sizeof(buffer), MSG_PEEK, (struct sockaddr*)&cli_addr, &cli_addr_size);
+      cli_addr_size = sizeof (cli_addr);
+      ret = recvfrom (sock, buffer, sizeof (buffer), MSG_PEEK,
+                      (struct sockaddr *) &cli_addr, &cli_addr_size);
       if (ret > 0)
         {
-          memset(&prestate, 0, sizeof(prestate));
-          ret = gnutls_dtls_cookie_verify(&cookie_key, &cli_addr, sizeof(cli_addr), buffer, ret, &prestate);
-          if (ret < 0) /* cookie not valid */
+          memset (&prestate, 0, sizeof (prestate));
+          ret = gnutls_dtls_cookie_verify (&cookie_key, &cli_addr,
+                                           sizeof (cli_addr), buffer, ret,
+                                           &prestate);
+          if (ret < 0)          /* cookie not valid */
             {
               priv_data_st s;
-              
-              memset(&s, 0, sizeof(s));
+
+              memset (&s, 0, sizeof (s));
               s.fd = sock;
-              s.cli_addr = (void*)&cli_addr;
-              s.cli_addr_size = sizeof(cli_addr);
-              
-              printf("Sending hello verify request to %s\n", human_addr ((struct sockaddr *)
-                  &cli_addr, sizeof(cli_addr), buffer, sizeof(buffer)));
-              gnutls_dtls_cookie_send(&cookie_key, &cli_addr, sizeof(cli_addr), &prestate, (gnutls_transport_ptr_t)&s, push_func);
-
-              /* discard peeked data*/
-              recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&cli_addr, &cli_addr_size);
-              usleep(100);
+              s.cli_addr = (void *) &cli_addr;
+              s.cli_addr_size = sizeof (cli_addr);
+
+              printf ("Sending hello verify request to %s\n",
+                      human_addr ((struct sockaddr *) &cli_addr,
+                                  sizeof (cli_addr), buffer,
+                                  sizeof (buffer)));
+
+              gnutls_dtls_cookie_send (&cookie_key, &cli_addr,
+                                       sizeof (cli_addr), &prestate,
+                                       (gnutls_transport_ptr_t) & s,
+                                       push_func);
+
+              /* discard peeked data */
+              recvfrom (sock, buffer, sizeof (buffer), 0,
+                        (struct sockaddr *) &cli_addr, &cli_addr_size);
+              usleep (100);
               continue;
             }
           printf ("Accepted connection from %s\n",
                   human_addr ((struct sockaddr *)
-                  &cli_addr, sizeof(cli_addr), buffer,
-                  sizeof (buffer)));
+                              &cli_addr, sizeof (cli_addr), buffer,
+                              sizeof (buffer)));
         }
       else
         continue;
 
       session = initialize_tls_session ();
-      gnutls_dtls_prestate_set(session, &prestate);
-      gnutls_dtls_set_mtu(session, mtu);
+      gnutls_dtls_prestate_set (session, &prestate);
+      gnutls_dtls_set_mtu (session, mtu);
 
       priv.session = session;
       priv.fd = sock;
-      priv.cli_addr = (struct sockaddr *)&cli_addr;
-      priv.cli_addr_size = sizeof(cli_addr);
+      priv.cli_addr = (struct sockaddr *) &cli_addr;
+      priv.cli_addr_size = sizeof (cli_addr);
 
       gnutls_transport_set_ptr (session, &priv);
       gnutls_transport_set_push_function (session, push_func);
@@ -181,45 +188,51 @@ main (void)
 
       do
         {
-          ret = gnutls_handshake(session);
+          ret = gnutls_handshake (session);
         }
-      while(gnutls_error_is_fatal(ret) == 0);
+      while (gnutls_error_is_fatal (ret) == 0);
 
       if (ret < 0)
         {
-          fprintf(stderr, "Error in handshake(): %s\n", gnutls_strerror(ret));
-          gnutls_deinit(session);
+          fprintf (stderr, "Error in handshake(): %s\n",
+                   gnutls_strerror (ret));
+          gnutls_deinit (session);
           continue;
         }
 
       printf ("- Handshake was completed\n");
 
-      for(;;)
+      for (;;)
         {
-          do {
-            ret = gnutls_record_recv_seq(session, buffer, MAX_BUFFER, sequence);
-          } while(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
+          do
+            {
+              ret = gnutls_record_recv_seq (session, buffer, MAX_BUFFER,
+                                            sequence);
+            }
+          while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
 
           if (ret < 0)
             {
-              fprintf(stderr, "Error in recv(): %s\n", gnutls_strerror(ret));
+              fprintf (stderr, "Error in recv(): %s\n",
+                       gnutls_strerror (ret));
               break;
             }
           if (ret == 0)
             {
-              printf("EOF\n\n");
+              printf ("EOF\n\n");
               break;
             }
           buffer[ret] = 0;
-          printf("received[%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x]: %s\n", sequence[0], 
-                 sequence[1], sequence[2], sequence[3], sequence[4], sequence[5], 
-                 sequence[6], sequence[7], buffer);
+          printf ("received[%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x]: %s\n",
+                  sequence[0], sequence[1], sequence[2], sequence[3],
+                  sequence[4], sequence[5], sequence[6], sequence[7], buffer);
 
           /* reply back */
-          ret = gnutls_record_send(session, buffer, ret);
+          ret = gnutls_record_send (session, buffer, ret);
           if (ret < 0)
             {
-              fprintf(stderr, "Error in send(): %s\n", gnutls_strerror(ret));
+              fprintf (stderr, "Error in send(): %s\n",
+                       gnutls_strerror (ret));
               break;
             }
         }
@@ -239,7 +252,8 @@ main (void)
 
 }
 
-static int wait_for_connection(int fd)
+static int
+wait_for_connection (int fd)
 {
   fd_set rd, wr;
   int n;
@@ -264,23 +278,24 @@ static int wait_for_connection(int fd)
 
 /* Wait for data to be received within a timeout period in milliseconds
  */
-static int pull_timeout_func(gnutls_transport_ptr_t ptr, unsigned int ms)
+static int
+pull_timeout_func (gnutls_transport_ptr_t ptr, unsigned int ms)
 {
-fd_set rfds;
-struct timeval tv;
-priv_data_st *priv = ptr;
-struct sockaddr_in cli_addr;
-socklen_t cli_addr_size;
-int ret;
-char c;
-
-  FD_ZERO(&rfds);
-  FD_SET(priv->fd, &rfds);
-  
+  fd_set rfds;
+  struct timeval tv;
+  priv_data_st *priv = ptr;
+  struct sockaddr_in cli_addr;
+  socklen_t cli_addr_size;
+  int ret;
+  char c;
+
+  FD_ZERO (&rfds);
+  FD_SET (priv->fd, &rfds);
+
   tv.tv_sec = 0;
   tv.tv_usec = ms * 1000;
-  
-  ret = select(priv->fd+1, &rfds, NULL, NULL, &tv);
+
+  ret = select (priv->fd + 1, &rfds, NULL, NULL, &tv);
 
   if (ret <= 0)
     return ret;
@@ -288,46 +303,54 @@ char c;
   /* only report ok if the next message is from the peer we expect
    * from 
    */
-  cli_addr_size = sizeof(cli_addr);
-  ret = recvfrom(priv->fd, &c, 1, MSG_PEEK, (struct sockaddr*)&cli_addr, &cli_addr_size);
+  cli_addr_size = sizeof (cli_addr);
+  ret =
+    recvfrom (priv->fd, &c, 1, MSG_PEEK, (struct sockaddr *) &cli_addr,
+              &cli_addr_size);
   if (ret > 0)
     {
-      if (cli_addr_size == priv->cli_addr_size && memcmp(&cli_addr, priv->cli_addr, sizeof(cli_addr))==0)
+      if (cli_addr_size == priv->cli_addr_size
+          && memcmp (&cli_addr, priv->cli_addr, sizeof (cli_addr)) == 0)
         return 1;
     }
 
   return 0;
 }
 
-static ssize_t push_func (gnutls_transport_ptr_t p, const void * data, size_t size)
+static ssize_t
+push_func (gnutls_transport_ptr_t p, const void *data, size_t size)
 {
-priv_data_st *priv = p;
+  priv_data_st *priv = p;
 
-  return sendto(priv->fd, data, size, 0, priv->cli_addr, priv->cli_addr_size);
+  return sendto (priv->fd, data, size, 0, priv->cli_addr,
+                 priv->cli_addr_size);
 }
 
-static ssize_t pull_func(gnutls_transport_ptr_t p, void * data, size_t size)
+static ssize_t
+pull_func (gnutls_transport_ptr_t p, void *data, size_t size)
 {
-priv_data_st *priv = p;
-struct sockaddr_in cli_addr;
-socklen_t cli_addr_size;
-char buffer[64];
-int ret;
-
-  cli_addr_size = sizeof(cli_addr);
-  ret = recvfrom(priv->fd, data, size, 0, (struct sockaddr*)&cli_addr, &cli_addr_size);
+  priv_data_st *priv = p;
+  struct sockaddr_in cli_addr;
+  socklen_t cli_addr_size;
+  char buffer[64];
+  int ret;
+
+  cli_addr_size = sizeof (cli_addr);
+  ret =
+    recvfrom (priv->fd, data, size, 0, (struct sockaddr *) &cli_addr,
+              &cli_addr_size);
   if (ret == -1)
     return ret;
 
-  if (cli_addr_size == priv->cli_addr_size && memcmp(&cli_addr, priv->cli_addr, sizeof(cli_addr))==0)
+  if (cli_addr_size == priv->cli_addr_size
+      && memcmp (&cli_addr, priv->cli_addr, sizeof (cli_addr)) == 0)
     return ret;
 
   printf ("Denied connection from %s\n",
-                human_addr ((struct sockaddr *)
-                            &cli_addr, sizeof(cli_addr), buffer,
-                            sizeof (buffer)));
-  
-  gnutls_transport_set_errno(priv->session, EAGAIN);
+          human_addr ((struct sockaddr *)
+                      &cli_addr, sizeof (cli_addr), buffer, sizeof (buffer)));
+
+  gnutls_transport_set_errno (priv->session, EAGAIN);
   return -1;
 }
 
@@ -384,7 +407,7 @@ initialize_tls_session (void)
 {
   gnutls_session_t session;
 
-  gnutls_init (&session, GNUTLS_SERVER|GNUTLS_DATAGRAM);
+  gnutls_init (&session, GNUTLS_SERVER | GNUTLS_DATAGRAM);
 
   gnutls_priority_set (session, priority_cache);
 
@@ -393,7 +416,8 @@ initialize_tls_session (void)
   return session;
 }
 
-static int generate_dh_params (void)
+static int
+generate_dh_params (void)
 {
   int bits = gnutls_sec_param_to_pk_bits (GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LOW);
 
index 97eba2f7298cea1bad430f8e54b7e85fc050729d..eaf09f6474f36c095a30157482eb78c6dd424f62 100644 (file)
@@ -23,9 +23,6 @@
 /* This is a sample TLS 1.0 echo server, using X.509 authentication.
  */
 
-
-#define SA struct sockaddr
-#define SOCKET_ERR(err,s) if(err==-1) {perror(s);return(1);}
 #define MAX_BUF 1024
 #define PORT 5556               /* listen to 5556 port */
 
@@ -71,7 +68,7 @@ generate_dh_params (void)
 int
 main (void)
 {
-  int err, listen_sd;
+  int listen_sd;
   int sd, ret;
   struct sockaddr_in sa_serv;
   struct sockaddr_in sa_cli;
@@ -92,8 +89,13 @@ main (void)
   gnutls_certificate_set_x509_crl_file (x509_cred, CRLFILE,
                                         GNUTLS_X509_FMT_PEM);
 
-  gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE,
+  ret = gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE,
                                         GNUTLS_X509_FMT_PEM);
+  if (ret < 0)
+    {
+      printf("No certificate or key were found\n");
+      exit(1);
+    }
 
   generate_dh_params ();
 
@@ -105,7 +107,6 @@ main (void)
   /* Socket operations
    */
   listen_sd = socket (AF_INET, SOCK_STREAM, 0);
-  SOCKET_ERR (listen_sd, "socket");
 
   memset (&sa_serv, '\0', sizeof (sa_serv));
   sa_serv.sin_family = AF_INET;
@@ -115,10 +116,9 @@ main (void)
   setsockopt (listen_sd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval,
               sizeof (int));
 
-  err = bind (listen_sd, (SA *) & sa_serv, sizeof (sa_serv));
-  SOCKET_ERR (err, "bind");
-  err = listen (listen_sd, 1024);
-  SOCKET_ERR (err, "listen");
+  bind (listen_sd, (struct sockaddr *) & sa_serv, sizeof (sa_serv));
+
+  listen (listen_sd, 1024);
 
   printf ("Server ready. Listening to port '%d'.\n\n", PORT);
 
@@ -127,7 +127,7 @@ main (void)
     {
       session = initialize_tls_session ();
 
-      sd = accept (listen_sd, (SA *) & sa_cli, &client_len);
+      sd = accept (listen_sd, (struct sockaddr *) & sa_cli, &client_len);
 
       printf ("- connection from %s, port %d\n",
               inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf,