Delete obsolete code for openssl-based test server

See https://dev.eclipse.org/ipzilla/show_bug.cgi?id=10521#c15
and following.

Change-Id: I5a2caf1c713ada011dfc6bb11b30401304a06f12
diff --git a/tests/secure-server.c b/tests/secure-server.c
deleted file mode 100644
index 6ba5258..0000000
--- a/tests/secure-server.c
+++ /dev/null
@@ -1,862 +0,0 @@
-/* secure-server -- A (broken) DTLS server example
- *
- * Copyright (C) 2011 Olaf Bergmann <bergmann@tzi.org>
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <sys/select.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <signal.h>
-
-#include <openssl/ssl.h>
-#include <openssl/bio.h>
-#include <openssl/err.h>
-#include <openssl/rand.h>
-
-#ifdef WITH_DTLS
-#define SERVER_CERT_PEM "./server-cert.pem"
-#define SERVER_KEY_PEM  "./server-key.pem"
-#define CA_CERT_PEM     "./ca-cert.pem"
-#endif
-
-#ifdef HAVE_ASSERT_H
-# include <assert.h>
-#else
-# define assert(x)
-#endif /* HAVE_ASSERT_H */
-
-static int quit=0;
-
-/* SIGINT handler: set quit to 1 for graceful termination */
-void
-handle_sigint(int signum) {
-  quit = 1;
-}
-
-int 
-check_connect(int sockfd, char *buf, int buflen, 
-	   struct sockaddr *src, int *ifindex) {
-
-  /* for some reason, the definition in netinet/in.h is not exported */
-#ifndef IN6_PKTINFO
-  struct in6_pktinfo
-  {
-    struct in6_addr ipi6_addr;	/* src/dst IPv6 address */
-    unsigned int ipi6_ifindex;	/* send/recv interface index */
-  };
-#endif
-
-  size_t bytes;
-
-  struct iovec iov[1] = { {buf, buflen} };
-  char cmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
-  struct in6_pktinfo *p = NULL;
-  
-  struct msghdr msg = { 0 };
-  struct cmsghdr *cmsg;
-
-  msg.msg_name = src;
-  msg.msg_namelen = sizeof(struct sockaddr_in6);
-  msg.msg_iov = iov;
-  msg.msg_iovlen = 1;
-  msg.msg_control = cmsgbuf;
-  msg.msg_controllen = sizeof(cmsgbuf);
-
-  bytes = recvmsg(sockfd, &msg, MSG_DONTWAIT | MSG_PEEK);
-  if (bytes < 0) {
-    perror("recvmsg");
-    return bytes;
-  }
-
-  /* TODO: handle msg.msg_flags & MSG_TRUNC */
-  if (msg.msg_flags & MSG_CTRUNC) {
-    fprintf(stderr, "control was truncated!\n");
-    return -1;
-  }
-
-  if (ifindex) {
-    /* Here we try to retrieve the interface index where the packet was received */
-    *ifindex = 0;
-    for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
-	 cmsg = CMSG_NXTHDR(&msg, cmsg)) {
-
-      if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) {
-	p = (struct in6_pktinfo *)(CMSG_DATA(cmsg));
-	*ifindex = p->ipi6_ifindex;
-	break;
-      }
-    }
-  }
-
-  return bytes;
-}
-
-typedef enum { UNKNOWN=0, DTLS=1 } protocol_t;
-
-protocol_t
-demux_protocol(const char *buf, int len) {
-  return DTLS;
-}
-
-#ifdef WITH_DTLS
-typedef enum { 
-  PEER_ST_ESTABLISHED, PEER_ST_PENDING, PEER_ST_CLOSED 
- } peer_state_t;
-typedef struct {
-  peer_state_t state;
-  unsigned long h;
-  SSL *ssl;
-} ssl_peer_t;
-
-#define MAX_SSL_PENDING      2	/* must be less than MAX_SSL_PEERS */
-#define MAX_SSL_PEERS       10	/* MAX_SSL_PENDING of these might be pending  */
-ssl_peer_t *ssl_peer_storage[MAX_SSL_PEERS];
-static int pending = 0;
-
-void
-check_peers() {
-typedef struct bio_dgram_data_st
-	{
-	union {
-		struct sockaddr sa;
-		struct sockaddr_in sa_in;
-		struct sockaddr_in6 sa_in6;
-	} peer;
-	unsigned int connected;
-	unsigned int _errno;
-	unsigned int mtu;
-	struct timeval next_timeout;
-	struct timeval socket_timeout;
-	} bio_dgram_data;
-
-  struct sockaddr_in6 peer;
-  int i;
-  BIO *bio;
-  for (i = 0; i < MAX_SSL_PEERS; i++) {
-    if (ssl_peer_storage[i]) {
-      if (!ssl_peer_storage[i]->ssl)
-	fprintf(stderr, "invalid SSL object for peer %d!\n",i);
-      else {
-	bio = SSL_get_rbio(ssl_peer_storage[i]->ssl);
-	if (bio) {
-	  (void) BIO_dgram_get_peer(bio, (struct sockaddr *)&peer);
-	  if (peer.sin6_port && ssl_peer_storage[i]->h != ntohs(peer.sin6_port)) {
-	    fprintf(stderr, "   bio %p: port differs from hash: %d != %d! (%sconnected)\n", bio,
-		    ssl_peer_storage[i]->h, 
-		    ntohs(((struct sockaddr_in6 *)&peer)->sin6_port),
-		    ((bio_dgram_data *)bio->ptr)->connected ? "" : "not ");
-	  }
-
-	}
-      }
-    }
-  }
-}
-
-/** Creates a hash value from the first num bytes of s, taking init as
- * initialization value. */
-static inline unsigned long
-_hash(unsigned long init, const char *s, int num) {
-  int c;
-
-  while (num--)
-    while ( (c = *s++) ) {
-      init = ((init << 7) + init) + c;
-    }
-
-  return init;
-}
-
-static inline unsigned long
-hash_peer(const struct sockaddr *peer, int ifindex) {
-  unsigned long h;
-
-  /* initialize hash value to interface index */
-  h = _hash(0, (char *)&ifindex, sizeof(int));
-
-#define CAST(TYPE,VAR) ((TYPE)VAR)
-
-  assert(peer);
-  switch (peer->sa_family) {
-  case AF_INET: 
-    return ntohs(CAST(const struct sockaddr_in *, peer)->sin_port);
-    h = _hash(h, (char *) &CAST(const struct sockaddr_in *, peer)->sin_addr, 
-	      sizeof(struct in_addr));
-    h = _hash(h, (char *) &CAST(const struct sockaddr_in *, peer)->sin_port, 
-	      sizeof(in_port_t));
-    break;
-  case AF_INET6:
-    return ntohs(CAST(const struct sockaddr_in6 *, peer)->sin6_port);
-    h = _hash(h, 
-	      (char *) &CAST(const struct sockaddr_in6 *, peer)->sin6_addr, 
-	      sizeof(struct in6_addr));
-    h = _hash(h, 
-	      (char *) &CAST(const struct sockaddr_in6 *, peer)->sin6_port, 
-	      sizeof(in_port_t));
-    break;
-  default:
-    /* last resort */
-    h = _hash(h, (char *)peer, sizeof(struct sockaddr));
-  }
-
-  return 42;
-  return h;
-}
-
-/* Returns index of peer object for specified address/ifindex pair. */
-int
-get_index_of_peer(const struct sockaddr *peer, int ifindex) {
-  unsigned long h;
-  int idx;
-#ifndef NDEBUG
-  char addr[INET6_ADDRSTRLEN];
-  char port[6];
-#endif
-
-  if (!peer)
-    return -1;
-
-  h = hash_peer(peer,ifindex);
-
-  for (idx = 0; idx < MAX_SSL_PEERS; idx++) {
-    if (ssl_peer_storage[idx] && ssl_peer_storage[idx]->h == h) {
-#ifndef NDEBUG
-      getnameinfo((struct sockaddr *)peer, sizeof(struct sockaddr_in6), 
-		  addr, sizeof(addr), port, sizeof(port), 
-		  NI_NUMERICHOST | NI_NUMERICSERV);
-
-      fprintf(stderr, "get_index_of_peer: [%s]:%s  =>  %lu\n",
-	      addr, port, h);
-#endif
-      return idx;
-    }
-  }
-  return -1;
-}
-
-SSL *
-get_ssl(SSL_CTX *ctx, int sockfd, struct sockaddr *src, int ifindex) {
-  int idx;
-  BIO *bio;
-  SSL *ssl;
-#ifndef NDEBUG
-  struct sockaddr_storage peer;
-  char addr[INET6_ADDRSTRLEN];
-  char port[6];
-  int i;
-#endif
-
-  idx = get_index_of_peer(src,ifindex);
-  if (idx >= 0) {
-    fprintf(stderr,"found peer %d ",idx);
-    switch (ssl_peer_storage[idx]->state) {
-    case PEER_ST_ESTABLISHED: fprintf(stderr,"established\n"); break;
-    case PEER_ST_PENDING:     fprintf(stderr,"pending\n"); break;
-    case PEER_ST_CLOSED:      fprintf(stderr,"closed\n"); break;
-    default:
-      OPENSSL_assert(0);
-    }
-
-#ifndef NDEBUG
-    memset(&peer, 0, sizeof(peer));
-    (void) BIO_dgram_get_peer(SSL_get_rbio(ssl_peer_storage[idx]->ssl), &peer);
-
-    getnameinfo((struct sockaddr *)&peer, sizeof(peer), 
-		addr, sizeof(addr), port, sizeof(port), 
-		NI_NUMERICHOST | NI_NUMERICSERV);
-
-    fprintf(stderr,"      [%s]:%s   \n", addr, port);
-#endif
-    return ssl_peer_storage[idx]->ssl;
-  }
-
-  /* none found, create new if sufficient space available */
-  if (pending < MAX_SSL_PENDING) {
-    for (idx = 0; idx < MAX_SSL_PEERS; idx++) {
-      if (ssl_peer_storage[idx] == NULL) { /* found space */
-	ssl = SSL_new(ctx);
-	
-	if (ssl) {
-	  bio = BIO_new_dgram(sockfd, BIO_NOCLOSE);
-	  if (!bio) {
-	    SSL_free(ssl);
-	    return NULL;
-	  }
-	  
-	  SSL_set_bio(ssl, bio, bio);
-	  SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
-	  
-	  SSL_set_accept_state(ssl);
-	  ssl_peer_storage[idx] = (ssl_peer_t *) malloc(sizeof(ssl_peer_t));
-	  if (!ssl_peer_storage[idx]) {
-	    SSL_free(ssl);
-	    return NULL;
-	  }
-	  ssl_peer_storage[idx]->state = PEER_ST_PENDING;
-	  ssl_peer_storage[idx]->h = hash_peer(src,ifindex);
-	  ssl_peer_storage[idx]->ssl = ssl;
-	  
-	  pending++;
-	  
-	  fprintf(stderr,
-		  "created new SSL peer %d for ssl object %p (storage: %p)\n", 
-		 idx, ssl, ssl_peer_storage[idx]);
-#ifndef NDEBUG
-    if (getnameinfo((struct sockaddr *)&src, sizeof(src), 
-		addr, sizeof(addr), port, sizeof(port), 
-		    NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
-      perror("getnameinfo");
-      fprintf(stderr, "port was %u\n", ntohs(((struct sockaddr_in6 *)src)->sin6_port));
-    } else {
-    fprintf(stderr,"      [%s]:%s   \n", addr, port);
-      }
-#endif
-    OPENSSL_assert(ssl_peer_storage[idx]->ssl == ssl);
-	  fprintf(stderr,"%d objects pending\n", pending);
-	  check_peers();
-	  return ssl;
-	}
-      }
-    }
-  } else {
-    fprintf(stderr, "too many pending SSL objects\n");
-    return NULL;
-  }
-
-  fprintf(stderr, "too many peers\n");
-  return NULL;
-}
-
-/** Deletes peer stored at index idx and frees allocated memory. */
-static inline void
-delete_peer(int idx) {
-  if (idx < 0 || !ssl_peer_storage[idx])
-    return;
-
-  if (ssl_peer_storage[idx]->state == PEER_ST_PENDING)
-    pending--;
-
-  OPENSSL_assert(ssl_peer_storage[idx]->ssl);
-  SSL_free(ssl_peer_storage[idx]->ssl);
-    
-  free(ssl_peer_storage[idx]);
-  ssl_peer_storage[idx] = NULL;
-
-  printf("deleted peer %d\n",idx);
-}
-
-/** Deletes all closed objects from ssl_peer_storage. */
-void
-remove_closed() {
-  int idx;
-
-  for (idx = 0; idx < MAX_SSL_PEERS; idx++)
-    if (ssl_peer_storage[idx] 
-	&& ssl_peer_storage[idx]->state == PEER_ST_CLOSED)
-      delete_peer(idx);
-}
-
-#define min(a,b) ((a) < (b) ? (a) : (b))
-
-unsigned int
-psk_server_callback(SSL *ssl, const char *identity,
-		    unsigned char *psk, unsigned int max_psk_len) {
-  static char keybuf[] = "secretPSK";
-
-  printf("psk_server_callback: check identity of client %s\n", identity);
-  memcpy(psk, keybuf, min(strlen(keybuf), max_psk_len));
-
-  return min(strlen(keybuf), max_psk_len);
-}
-
-#endif
-
-#ifdef WITH_DTLS
-/**
- * This function tracks the status changes from libssl to manage local
- * object state.
- */
-void
-info_callback(const SSL *ssl, int where, int ret) {
-  int idx, i;
-  struct sockaddr_storage peer;
-  struct sockaddr_storage peer2;
-  char addr[INET6_ADDRSTRLEN];
-  char port[6];
-
-  if (where & SSL_CB_LOOP)  /* do not care for intermediary states */
-    return;
-
-  memset(&peer, 0, sizeof(peer));
-  (void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
-
-  /* lookup SSL object */   /* FIXME: need to get the ifindex */
-  idx = get_index_of_peer((struct sockaddr *)&peer, 0);
-  
-  if (idx >= 0)
-    fprintf(stderr, "info_callback: assert: %d < 0 || %p == %p (storage: %p)\n",
-	    idx, ssl, ssl_peer_storage[idx]->ssl, ssl_peer_storage[idx]); 
-  if (idx >= 0 && ssl != ssl_peer_storage[idx]->ssl) {
-    getnameinfo((struct sockaddr *)&peer, sizeof(peer), 
-		addr, sizeof(addr), port, sizeof(port), 
-		NI_NUMERICHOST | NI_NUMERICSERV);
-
-    fprintf(stderr," ssl: [%s]:%s   ", addr, port);
-    
-    (void) BIO_dgram_get_peer(SSL_get_rbio(ssl_peer_storage[idx]->ssl), &peer2);
-    getnameinfo((struct sockaddr *)&peer2, sizeof(peer2), 
-		addr, sizeof(addr), port, sizeof(port), 
-		NI_NUMERICHOST | NI_NUMERICSERV);
-
-    fprintf(stderr," ssl_peer_storage[idx]->ssl: [%s]:%s\n", addr, port);
-
-    fprintf(stderr, " hash:%lu     h: %lu\n",
-	    hash_peer((const struct sockaddr *)&peer, 0),
-	    ssl_peer_storage[idx]->h);
-
-    for (i = 0; i < MAX_SSL_PEERS; i++) {
-      if (ssl_peer_storage[i]) {
-	fprintf(stderr, "%02d: %p ssl: %p  ",
-		i, ssl_peer_storage[i] ,ssl_peer_storage[i]->ssl);
-
-	(void) BIO_dgram_get_peer(SSL_get_rbio(ssl_peer_storage[i]->ssl), &peer2);
-	getnameinfo((struct sockaddr *)&peer2, sizeof(peer2), 
-		    addr, sizeof(addr), port, sizeof(port), 
-		    NI_NUMERICHOST | NI_NUMERICSERV);
-	
-	fprintf(stderr," peer: [%s]:%s    h: %lu\n", addr, port, ssl_peer_storage[i]->h);
-      }
-    }
-    fprintf(stderr, "***** ASSERT FAILED ******\n");
-
-    memset(&peer, 0, sizeof(peer));
-    (void) BIO_dgram_get_peer(SSL_get_wbio(ssl), &peer);
-
-    idx = get_index_of_peer((struct sockaddr *)&peer, 0);
-    fprintf(stderr, "  get_index_of_peer for wbio returns %d, type is %04x\n",
-	    idx, where);    
-  }
-#if 1
-	  check_peers();
-  OPENSSL_assert((idx < 0) || (ssl == ssl_peer_storage[idx]->ssl));
-#endif
-
-  if (where & SSL_CB_ALERT) {
-#ifndef NDEBUG
-    if (ret != 0)
-      fprintf(stderr,"%s:%s:%s\n", SSL_alert_type_string(ret),
-	      SSL_alert_desc_string(ret), SSL_alert_desc_string_long(ret));
-#endif
-
-    /* examine alert type */
-    switch (*SSL_alert_type_string(ret)) {
-    case 'F':
-      /* move SSL object from pending to close */
-      if (idx >= 0) {
-	ssl_peer_storage[idx]->state = PEER_ST_CLOSED;
-	pending--;
-      }
-      break;
-    case 'W': 
-      if ((ret & 0xff) == SSL_AD_CLOSE_NOTIFY) {
-	if (where == SSL_CB_WRITE_ALERT) 
-	  fprintf(stderr,"sent CLOSE_NOTIFY\n");
-	else /* received CN */
-	  fprintf(stderr,"received CLOSE_NOTIFY\n");
-      }
-      break;
-    default: 			/* handle unknown alert types */
-#ifndef NDEBUG
-      printf("not handled!\n");
-#endif
-    }
-  }
-
-  if (where & SSL_CB_HANDSHAKE_DONE) {
-    /* move SSL object from pending to established */
-    printf("HANDSHAKE_DONE ");
-    if (idx >= 0) {
-      
-      if (ssl_peer_storage[idx]->state == PEER_ST_PENDING) {
-	ssl_peer_storage[idx]->state = PEER_ST_ESTABLISHED;
-	pending--;
-	printf("moved SSL object %d to ESTABLISHED\n", idx);
-	printf("%d objects pending\n", pending);
-      } else {
-#ifndef NDEBUG
-	printf("huh, object %d was not pending? (%d)\n", idx,
-	       ssl_peer_storage[idx]->state);
-#endif
-      }
-      return;
-    }
-    return;
-  }
-
-  return;
-}
-#endif
-
-#ifdef WITH_DTLS
-/* checks if ssl object was closed and can be removed */
-int 
-check_close(SSL *ssl) {
-  int res, err, idx;
-  struct sockaddr_storage peer;
-  
-  memset(&peer, 0, sizeof(peer));
-  (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
-
-  res = 0;
-  if (SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN) {
-    printf("SSL_RECEIVED_SHUTDOWN\n");
-    res = SSL_shutdown(ssl);
-    if (res == 0) {
-      printf("must call SSL_shutdown again\n");
-      res = SSL_shutdown(ssl);
-    }
-    if (res < 0) {
-	err = SSL_get_error(ssl,res);	
-	fprintf(stderr, "shutdown: SSL error %d: %s\n", err,
-		ERR_error_string(err, NULL));
-    } 
-
-    /* we can close the SSL object anyway */
-    /* FIXME: need to get ifindex from somewhere */
-    idx = get_index_of_peer((struct sockaddr *)&peer, 0);
-    OPENSSL_assert(idx < 0 || ssl == ssl_peer_storage[idx]->ssl);
-    if (idx >= 0) {
-      ssl_peer_storage[idx]->state = PEER_ST_CLOSED;
-      printf("moved SSL object %d to CLOSED\n",idx);
-    }
-  }
-  
-  return res;
-}
-
-int 
-check_timeout() {
-  int i, result, err;
-
-  for (i = 0; i < MAX_SSL_PEERS; i++) {
-    if (ssl_peer_storage[i]) {
-      OPENSSL_assert(ssl_peer_storage[i]->ssl);
-      result = DTLSv1_handle_timeout(ssl_peer_storage[i]->ssl);
-      if (result < 0) {
-	err = SSL_get_error(ssl_peer_storage[i]->ssl,result);
-	fprintf(stderr, "dtls1_handle_timeout (%d): %s\n",
-		err, ERR_error_string(err, NULL));
-      }
-    }
-  }
-
-  /* remove outdated obbjects? */
-  
-  return 0;
-}
-#endif /* WITH_DTLS */
-  
-int 
-_read(SSL_CTX *ctx, int sockfd) {
-  char buf[2000];
-  struct sockaddr_in6 src;
-  int len, ifindex, i;
-  char addr[INET6_ADDRSTRLEN];
-  char port[6];
-  socklen_t sz = sizeof(struct sockaddr_in6);
-#ifdef WITH_DTLS
-  SSL *ssl;
-  int err;
-#endif
-
-  /* Retrieve remote address and interface index as well as the first
-     few bytes of the message to demultiplex protocols. */
-  memset(&src, 0, sizeof(struct sockaddr_in6));
-  len = check_connect(sockfd, buf, 4, (struct sockaddr *)&src, &ifindex);
-
-  if (len < 0)			/* error */
-    return len;
-
-#ifndef NDEBUG
-  fprintf(stderr,"received packet");
-  
-  if (getnameinfo((struct sockaddr *)&src, sizeof(src), 
-		  addr, sizeof(addr), port, sizeof(port), 
-		  NI_NUMERICHOST | NI_NUMERICSERV) == 0)
-    fprintf(stderr," from [%s]:%s", addr, port);
-  
-  fprintf(stderr," on interface %d\n", ifindex);
-#endif
-
-  switch (demux_protocol(buf, len)) {
-#ifdef WITH_DTLS
-  case DTLS :
-    ssl = get_ssl(ctx, sockfd, (struct sockaddr *)&src, ifindex);
-    if (!ssl) {
-      fprintf(stderr, "cannot create new SSL object\n");
-      /*      return recv(sockfd, buf, sizeof(buf), MSG_DONTWAIT);*/
-      len = recvfrom(sockfd, buf, sizeof(buf), MSG_DONTWAIT,
-		     (struct sockaddr *)&src, &sz);
-      getnameinfo((struct sockaddr *)&src, sz, 
-		  addr, sizeof(addr), port, sizeof(port), 
-		  NI_NUMERICHOST | NI_NUMERICSERV);
-      printf("discarded %d bytes from [%s]:%s\n", len, addr, port);      
-      return len;
-    }
-    len = SSL_read(ssl, buf, sizeof(buf));
-    break;
-#endif
-  case UNKNOWN:
-  default :
-    len = recv(sockfd, buf, sizeof(buf), MSG_DONTWAIT);
-  }
-
-  if (len > 0) {
-    printf("here is the data:\n");
-    for (i=0; i<len; i++)
-      printf("%c",buf[i]);
-  } if (len == 0) {		/* session closed? */
-#ifdef WITH_DTLS
-    if (check_close(ssl) <= 0) {
-      fprintf(stderr, "not closed\n");
-    }
-#endif
-  } else {
-#ifdef WITH_DTLS
-    err = SSL_get_error(ssl,len);
-    switch (err) {
-    case SSL_ERROR_WANT_READ:
-      fprintf(stderr, "SSL_ERROR_WANT_READ\n");
-      return 0;
-    case SSL_ERROR_WANT_WRITE:
-      fprintf(stderr, "SSL_ERROR_WANT_WRITE\n");
-      return 0;
-    default:
-      fprintf(stderr, "read: SSL error %d: %s\n", err,
-	      ERR_error_string(err, NULL));
-      return 0;
-    }
-#else
-    perror("recv");
-#endif
-  }
-
-  return len;
-}
-
-int 
-_write(SSL_CTX *ctx, int sockfd) {
-  int res = 0;
-#ifdef WITH_DTLS
-  SSL *ssl;
-  int err;
-
-  ssl = get_ssl(ctx, sockfd, NULL, 1);
-  if (!ssl) {
-    fprintf(stderr, "no SSL object for writing");
-    return 0;
-  }
-  res = SSL_write(ssl, NULL, 0);
-  if (res < 0) {
-    /*
-    if (SSL_want_write(ssl))
-      return 0;
-    */
-    /* FIXME: check SSL_want_read(ssl) */
-
-    err = SSL_get_error(ssl,res);
-    fprintf(stderr,"SSL_write returned %d (%s)\n", err, ERR_error_string(err, NULL));
-  } else {
-    printf("SSL_write successful\n");
-  }
-#else
-#endif
-  
-  return res;
-}
-
-
-int 
-generate_cookie(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len) {
-  /* FIXME: generate secure client-specific cookie */
-#define DUMMYSTR "ABCDEFGHIJKLMNOP"
-  *cookie_len = strlen(DUMMYSTR);
-  memcpy(cookie, DUMMYSTR, *cookie_len);
-
-  return 1;
-}
-
-int 
-verify_cookie(SSL *ssl, unsigned char *cookie, unsigned int cookie_len) {
-  /* FIXME */
-  return 1;
-}
-
-enum { READ, WRITE };
-
-int
-main(int argc, char **argv) {
-  int sockfd = 0;
-  int on = 1;
-  struct sockaddr_in6 listen_addr = { AF_INET6, htons(20220), 0, IN6ADDR_ANY_INIT, 0 };
-  size_t addr_size = sizeof(struct sockaddr_in6);
-  fd_set fds[2];
-  int result, flags;
-  int idx, res = 0;
-  struct timeval timeout;
-  struct sigaction act, oact;
-  
-#ifdef WITH_DTLS
-  SSL_CTX *ctx;
-
-  memset(ssl_peer_storage, 0, sizeof(ssl_peer_storage));
-
-  SSL_load_error_strings();
-  SSL_library_init();
-  ctx = SSL_CTX_new(DTLSv1_server_method());
-
-  SSL_CTX_set_cipher_list(ctx, "ALL");
-  SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
-
-  res = SSL_CTX_use_certificate_file(ctx, SERVER_CERT_PEM, SSL_FILETYPE_PEM);
-  if (res != 1) {
-    fprintf(stderr, "cannot read server certificate from file '%s' (%s)\n", 
-	    SERVER_CERT_PEM, ERR_error_string(res,NULL));
-    goto end;
-  }
-
-  res = SSL_CTX_use_PrivateKey_file(ctx, SERVER_KEY_PEM, SSL_FILETYPE_PEM);
-  if (res != 1) {
-    fprintf(stderr, "cannot read server key from file '%s' (%s)\n", 
-	    SERVER_KEY_PEM, ERR_error_string(res,NULL));
-    goto end;
-  }
-
-  res = SSL_CTX_check_private_key (ctx);
-  if (res != 1) {
-    fprintf(stderr, "invalid private key\n");
-    goto end;
-  }
-
-  res = SSL_CTX_load_verify_locations(ctx, CA_CERT_PEM, NULL);
-  if (res != 1) {
-    fprintf(stderr, "cannot read ca file '%s'\n", CA_CERT_PEM);
-    goto end;
-  }
-
-  /* Client has to authenticate */
-
-  /* Client has to authenticate */
-  SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL);
-
-  SSL_CTX_set_read_ahead(ctx, 1); /* disable read-ahead */
-  SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie);
-  SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie);
-
-  SSL_CTX_use_psk_identity_hint(ctx, "Enter password for CoAP-Gateway");
-  SSL_CTX_set_psk_server_callback(ctx, psk_server_callback);
-
-  SSL_CTX_set_info_callback(ctx, info_callback);
-#endif
-
-  sockfd = socket(listen_addr.sin6_family, SOCK_DGRAM, 0);
-  if ( sockfd < 0 ) {
-    perror("socket");
-    return -1;
-  }
-
-  if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) < 0)
-    perror("setsockopt SO_REUSEADDR");
-
-  flags = fcntl(sockfd, F_GETFL, 0);
-  if (flags < 0 || fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) {
-    perror("fcntl");
-    return -1;
-  }
-
-  on = 1;
-  if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on) ) < 0) {
-    perror("setsockopt IPV6_PKTINFO");
-  }
-
-  if (bind (sockfd, (const struct sockaddr *)&listen_addr, addr_size) < 0) {
-    perror("bind");
-    res = -2;
-    goto end;
-  }
-
-  act.sa_handler = handle_sigint;
-  sigemptyset(&act.sa_mask);
-  act.sa_flags = 0;
-  sigaction(SIGINT, &act, &oact);
-
-  while (!quit) {
-    FD_ZERO(&fds[READ]);
-    FD_ZERO(&fds[WRITE]);
-    FD_SET(sockfd, &fds[READ]);
-
-    timeout.tv_sec = 1;
-    timeout.tv_usec = 0;
-    result = select( FD_SETSIZE, &fds[READ], &fds[WRITE], 0, &timeout);
-
-    if (result < 0) {		/* error */
-      if (errno != EINTR)
-	perror("select");
-    } else if (result > 0) {	/* read from socket */
-      if ( FD_ISSET( sockfd, &fds[READ]) ) {
-	_read(ctx, sockfd);	/* read received data */
-      } else if ( FD_ISSET( sockfd, &fds[WRITE]) ) { /* write to socket */
-	_write(ctx, sockfd);		/* write data */
-      }
-    } else {			/* timeout */
-      check_timeout();
-    }
-    remove_closed();
-  }
-  
- end:
-#ifdef WITH_DTLS
-  for (idx = 0; idx < MAX_SSL_PEERS; idx++) {
-    if (ssl_peer_storage[idx] && ssl_peer_storage[idx]->ssl) {
-      if (ssl_peer_storage[idx]->state == PEER_ST_ESTABLISHED)
-	SSL_shutdown(ssl_peer_storage[idx]->ssl);
-      SSL_free(ssl_peer_storage[idx]->ssl);
-    }
-  }
-
-  SSL_CTX_free(ctx);
-#endif
-  close(sockfd);		/* don't care if we close stdin at this point */
-  return res;
-}