/*******************************************************************************
 *
 * Copyright (c) 2011, 2012, 2013, 2014, 2015 Olaf Bergmann (TZI) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
 *
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *    Olaf Bergmann  - initial API and implementation
 *    Hauke Mehrtens - memory optimization, ECC integration
 *    Achim Kraus    - session recovery
 *
 *******************************************************************************/

/**
 * @file dtls.h
 * @brief High level DTLS API and visible structures. 
 */

#ifndef _DTLS_DTLS_H_
#define _DTLS_DTLS_H_

#include <stdint.h>

#include "state.h"
#include "peer.h"

#include "uthash.h"

#include "alert.h"
#include "crypto.h"
#include "hmac.h"

#include "global.h"
#include "dtls_time.h"

#ifndef DTLSv12
#define DTLS_VERSION 0xfeff	/* DTLS v1.1 */
#else
#define DTLS_VERSION 0xfefd	/* DTLS v1.2 */
#endif

typedef enum dtls_credentials_type_t {
  DTLS_PSK_HINT, DTLS_PSK_IDENTITY, DTLS_PSK_KEY
} dtls_credentials_type_t;

typedef struct dtls_ecdsa_key_t {
  dtls_ecdh_curve curve;
  const unsigned char *priv_key;	/** < private key as bytes > */
  const unsigned char *pub_key_x;	/** < x part of the public key for the given private key > */
  const unsigned char *pub_key_y;	/** < y part of the public key for the given private key > */
} dtls_ecdsa_key_t;

/** Length of the secret that is used for generating Hello Verify cookies. */
#define DTLS_COOKIE_SECRET_LENGTH 12

struct dtls_context_t;

/**
 * This structure contains callback functions used by tinydtls to
 * communicate with the application. At least the write function must
 * be provided. It is called by the DTLS state machine to send packets
 * over the network. The read function is invoked to deliver decrypted
 * and verfified application data. The third callback is an event
 * handler function that is called when alert messages are encountered
 * or events generated by the library have occured.
 */ 
typedef struct {
  /** 
   * Called from dtls_handle_message() to send DTLS packets over the
   * network. The callback function must use the network interface
   * denoted by session->ifindex to send the data.
   *
   * @param ctx  The current DTLS context.
   * @param session The session object, including the address of the
   *              remote peer where the data shall be sent.
   * @param buf  The data to send.
   * @param len  The actual length of @p buf.
   * @return The callback function must return the number of bytes 
   *         that were sent, or a value less than zero to indicate an 
   *         error.
   */
  int (*write)(struct dtls_context_t *ctx, 
	       session_t *session, uint8 *buf, size_t len);

  /** 
   * Called from dtls_handle_message() deliver application data that was 
   * received on the given session. The data is delivered only after
   * decryption and verification have succeeded. 
   *
   * @param ctx  The current DTLS context.
   * @param session The session object, including the address of the
   *              data's origin. 
   * @param buf  The received data packet.
   * @param len  The actual length of @p buf.
   * @return ignored
   */
  int (*read)(struct dtls_context_t *ctx, 
	       session_t *session, uint8 *buf, size_t len);

  /**
   * The event handler is called when a message from the alert
   * protocol is received or the state of the DTLS session changes.
   *
   * @param ctx     The current dtls context.
   * @param session The session object that was affected.
   * @param level   The alert level or @c 0 when an event ocurred that 
   *                is not an alert. 
   * @param code    Values less than @c 256 indicate alerts, while
   *                @c 256 or greater indicate internal DTLS session changes.
   * @return ignored
   */
  int (*event)(struct dtls_context_t *ctx, session_t *session, 
		dtls_alert_level_t level, unsigned short code);

#ifdef DTLS_PSK
  /**
   * Called during handshake to get information related to the
   * psk key exchange. The type of information requested is
   * indicated by @p type which will be one of DTLS_PSK_HINT,
   * DTLS_PSK_IDENTITY, or DTLS_PSK_KEY. The called function
   * must store the requested item in the buffer @p result of
   * size @p result_length. On success, the function must return
   * the actual number of bytes written to @p result, of a
   * value less than zero on error. The parameter @p desc may
   * contain additional request information (e.g. the psk_identity
   * for which a key is requested when @p type == @c DTLS_PSK_KEY.
   *
   * @param ctx     The current dtls context.
   * @param session The session where the key will be used.
   * @param type    The type of the requested information.
   * @param desc    Additional request information
   * @param desc_len The actual length of desc.
   * @param result  Must be filled with the requested information.
   * @param result_length  Maximum size of @p result.
   * @return The number of bytes written to @p result or a value
   *         less than zero on error.
   */
  int (*get_psk_info)(struct dtls_context_t *ctx,
		      const session_t *session,
		      dtls_credentials_type_t type,
		      const unsigned char *desc, size_t desc_len,
		      unsigned char *result, size_t result_length);

#endif /* DTLS_PSK */

#ifdef DTLS_ECC
  /**
   * Called during handshake to get the server's or client's ecdsa
   * key used to authenticate this server or client in this 
   * session. If found, the key must be stored in @p result and 
   * the return value must be @c 0. If not found, @p result is 
   * undefined and the return value must be less than zero.
   *
   * If ECDSA should not be supported, set this pointer to NULL.
   *
   * Implement this if you want to provide your own certificate to 
   * the other peer. This is mandatory for a server providing ECDSA
   * support and optional for a client. A client doing DTLS client
   * authentication has to implementing this callback.
   *
   * @param ctx     The current dtls context.
   * @param session The session where the key will be used.
   * @param result  Must be set to the key object to used for the given
   *                session.
   * @return @c 0 if result is set, or less than zero on error.
   */
  int (*get_ecdsa_key)(struct dtls_context_t *ctx, 
		       const session_t *session,
		       const dtls_ecdsa_key_t **result);

  /**
   * Called during handshake to check the peer's pubic key in this
   * session. If the public key matches the session and should be
   * considerated valid the return value must be @c 0. If not valid,
   * the return value must be less than zero.
   *
   * If ECDSA should not be supported, set this pointer to NULL.
   *
   * Implement this if you want to verify the other peers public key.
   * This is mandatory for a DTLS client doing based ECDSA
   * authentication. A server implementing this will request the
   * client to do DTLS client authentication.
   *
   * @param ctx          The current dtls context.
   * @param session      The session where the key will be used.
   * @param other_pub_x  x component of the public key.
   * @param other_pub_y  y component of the public key.
   * @return @c 0 if public key matches, or less than zero on error.
   * error codes:
   *   return dtls_alert_fatal_create(DTLS_ALERT_BAD_CERTIFICATE);
   *   return dtls_alert_fatal_create(DTLS_ALERT_UNSUPPORTED_CERTIFICATE);
   *   return dtls_alert_fatal_create(DTLS_ALERT_CERTIFICATE_REVOKED);
   *   return dtls_alert_fatal_create(DTLS_ALERT_CERTIFICATE_EXPIRED);
   *   return dtls_alert_fatal_create(DTLS_ALERT_CERTIFICATE_UNKNOWN);
   *   return dtls_alert_fatal_create(DTLS_ALERT_UNKNOWN_CA);
   */
  int (*verify_ecdsa_key)(struct dtls_context_t *ctx, 
			  const session_t *session,
			  const unsigned char *other_pub_x,
			  const unsigned char *other_pub_y,
			  size_t key_size);
#endif /* DTLS_ECC */
} dtls_handler_t;

struct netq_t;

/** Holds global information of the DTLS engine. */
typedef struct dtls_context_t {
  unsigned char cookie_secret[DTLS_COOKIE_SECRET_LENGTH];
  clock_time_t cookie_secret_age; /**< the time the secret has been generated */

  dtls_peer_t *peers;		/**< peer hash map */
#ifdef WITH_CONTIKI
  struct etimer retransmit_timer; /**< fires when the next packet must be sent */
#endif /* WITH_CONTIKI */

  struct netq_t *sendqueue;     /**< the packets to send */

  void *app;			/**< application-specific data */

  dtls_handler_t *h;		/**< callback handlers */

  unsigned char readbuf[DTLS_MAX_BUF];
} dtls_context_t;

/** 
 * This function initializes the tinyDTLS memory management and must
 * be called first.
 */
void dtls_init();

/** 
 * Creates a new context object. The storage allocated for the new
 * object must be released with dtls_free_context(). */
dtls_context_t *dtls_new_context(void *app_data);

/** Releases any storage that has been allocated for \p ctx. */
void dtls_free_context(dtls_context_t *ctx);

#define dtls_set_app_data(CTX,DATA) ((CTX)->app = (DATA))
#define dtls_get_app_data(CTX) ((CTX)->app)

/** Sets the callback handler object for @p ctx to @p h. */
static inline void dtls_set_handler(dtls_context_t *ctx, dtls_handler_t *h) {
  ctx->h = h;
}

/**
 * Establishes a DTLS channel with the specified remote peer @p dst.
 * This function returns @c 0 if that channel already exists, a value
 * greater than zero when a new ClientHello message was sent, and
 * a value less than zero on error.
 *
 * @param ctx    The DTLS context to use.
 * @param dst    The remote party to connect to.
 * @return A value less than zero on error, greater or equal otherwise.
 */
int dtls_connect(dtls_context_t *ctx, const session_t *dst);

/**
 * Establishes a DTLS channel with the specified remote peer.
 * This function returns @c 0 if that channel already exists, a value
 * greater than zero when a new ClientHello message was sent, and
 * a value less than zero on error.
 *
 * @param ctx    The DTLS context to use.
 * @param peer   The peer object that describes the session.
 * @return A value less than zero on error, greater or equal otherwise.
 */
int dtls_connect_peer(dtls_context_t *ctx, dtls_peer_t *peer);

/**
 * Closes the DTLS connection associated with @p remote. This function
 * returns zero on success, and a value less than zero on error.
 */
int dtls_close(dtls_context_t *ctx, const session_t *remote);

int dtls_renegotiate(dtls_context_t *ctx, const session_t *dst);

/** 
 * Writes the application data given in @p buf to the peer specified
 * by @p session. 
 * 
 * @param ctx      The DTLS context to use.
 * @param session  The remote transport address and local interface.
 * @param buf      The data to write.
 * @param len      The actual length of @p data.
 * 
 * @return The number of bytes written or @c -1 on error.
 */
int dtls_write(struct dtls_context_t *ctx, session_t *session, 
	       uint8 *buf, size_t len);

/**
 * Checks sendqueue of given DTLS context object for any outstanding
 * packets to be transmitted. 
 *
 * @param context The DTLS context object to use.
 * @param next    If not NULL, @p next is filled with the timestamp
 *  of the next scheduled retransmission, or @c 0 when no packets are
 *  waiting.
 */
void dtls_check_retransmit(dtls_context_t *context, clock_time_t *next);

#define DTLS_COOKIE_LENGTH 16

#define DTLS_CT_CHANGE_CIPHER_SPEC 20
#define DTLS_CT_ALERT              21
#define DTLS_CT_HANDSHAKE          22
#define DTLS_CT_APPLICATION_DATA   23

/** Generic header structure of the DTLS record layer. */
typedef struct __attribute__((__packed__)) {
  uint8 content_type;		/**< content type of the included message */
  uint16 version;		/**< Protocol version */
  uint16 epoch;		        /**< counter for cipher state changes */
  uint48 sequence_number;       /**< sequence number */
  uint16 length;		/**< length of the following fragment */
  /* fragment */
} dtls_record_header_t;

/* Handshake types */

#define DTLS_HT_HELLO_REQUEST        0
#define DTLS_HT_CLIENT_HELLO         1
#define DTLS_HT_SERVER_HELLO         2
#define DTLS_HT_HELLO_VERIFY_REQUEST 3
#define DTLS_HT_CERTIFICATE         11
#define DTLS_HT_SERVER_KEY_EXCHANGE 12
#define DTLS_HT_CERTIFICATE_REQUEST 13
#define DTLS_HT_SERVER_HELLO_DONE   14
#define DTLS_HT_CERTIFICATE_VERIFY  15
#define DTLS_HT_CLIENT_KEY_EXCHANGE 16
#define DTLS_HT_FINISHED            20

/** Header structure for the DTLS handshake protocol. */
typedef struct __attribute__((__packed__)) {
  uint8 msg_type; /**< Type of handshake message  (one of DTLS_HT_) */
  uint24 length;  /**< length of this message */
  uint16 message_seq; 	/**< Message sequence number */
  uint24 fragment_offset;	/**< Fragment offset. */
  uint24 fragment_length;	/**< Fragment length. */
  /* body */
} dtls_handshake_header_t;

/** Structure of the Client Hello message. */
typedef struct __attribute__((__packed__)) {
  uint16 version;	  /**< Client version */
  uint32 gmt_random;	  /**< GMT time of the random byte creation */
  unsigned char random[28];	/**< Client random bytes */
  /* session id (up to 32 bytes) */
  /* cookie (up to 32 bytes) */
  /* cipher suite (2 to 2^16 -1 bytes) */
  /* compression method */
} dtls_client_hello_t;

/** Structure of the Hello Verify Request. */
typedef struct __attribute__((__packed__)) {
  uint16 version;		/**< Server version */
  uint8 cookie_length;	/**< Length of the included cookie */
  uint8 cookie[];		/**< up to 32 bytes making up the cookie */
} dtls_hello_verify_t;  

#if 0
/** 
 * Checks a received DTLS record for consistency and eventually decrypt,
 * verify, decompress and reassemble the contained fragment for 
 * delivery to high-lever clients. 
 * 
 * \param state The DTLS record state for the current session. 
 * \param 
 */
int dtls_record_read(dtls_state_t *state, uint8 *msg, int msglen);
#endif

/** 
 * Handles incoming data as DTLS message from given peer.
 *
 * @param ctx     The dtls context to use.
 * @param session The current session
 * @param msg     The received data
 * @param msglen  The actual length of @p msg.
 * @return A value less than zero on error, zero on success.
 */
int dtls_handle_message(dtls_context_t *ctx, session_t *session,
			uint8 *msg, int msglen);

/**
 * Check if @p session is associated with a peer object in @p context.
 * This function returns a pointer to the peer if found, NULL otherwise.
 *
 * @param context  The DTLS context to search.
 * @param session  The remote address and local interface
 * @return A pointer to the peer associated with @p session or NULL if
 *  none exists.
 */
dtls_peer_t *dtls_get_peer(const dtls_context_t *context,
			   const session_t *session);

/**
 * Resets all connections with @p peer.
 *
 * @param context  The active DTLS context.
 * @param peer     The peer to reset.
 */
void dtls_reset_peer(dtls_context_t *context, dtls_peer_t *peer);

#endif /* _DTLS_DTLS_H_ */

/**
 * @mainpage 
 *
 * @author Olaf Bergmann, TZI Uni Bremen
 *
 * This library provides a very simple datagram server with DTLS
 * support. It is designed to support session multiplexing in
 * single-threaded applications and thus targets specifically on
 * embedded systems.
 *
 * @section license License
 *
 * This software is under the <a 
 * href="http://www.opensource.org/licenses/mit-license.php">MIT License</a>.
 * 
 * @subsection uthash UTHash
 *
 * This library uses <a href="http://uthash.sourceforge.net/">uthash</a> to manage
 * its peers (not used for Contiki). @b uthash uses the <b>BSD revised license</b>, see
 * <a href="http://uthash.sourceforge.net/license.html">http://uthash.sourceforge.net/license.html</a>.
 *
 * @subsection sha256 Aaron D. Gifford's SHA256 Implementation
 *
 * tinyDTLS provides HMAC-SHA256 with BSD-licensed code from Aaron D. Gifford, 
 * see <a href="http://www.aarongifford.com/">www.aarongifford.com</a>.
 *
 * @subsection aes Rijndael Implementation From OpenBSD
 *
 * The AES implementation is taken from rijndael.{c,h} contained in the crypto 
 * sub-system of the OpenBSD operating system. It is copyright by Vincent Rijmen, *
 * Antoon Bosselaers and Paulo Barreto. See <a 
 * href="http://www.openbsd.org/cgi-bin/cvsweb/src/sys/crypto/rijndael.c">rijndael.c</a> 
 * for License info.
 *
 * @section download Getting the Files
 *
 * You can get the sources either from the <a 
 * href="http://sourceforge.net/projects/tinydtls/files">downloads</a> section or 
 * through git from the <a 
 * href="http://sourceforge.net/projects/tinydtls/develop">project develop page</a>.
 *
 * @section config Configuration
 *
 * Use @c configure to set up everything for a successful build. For Contiki, use the
 * option @c --with-contiki.
 *
 * @section build Building
 *
 * After configuration, just type 
 * @code
make
 * @endcode
 * optionally followed by
 * @code
make install
 * @endcode
 * The Contiki version is integrated with the Contiki build system, hence you do not
 * need to invoke @c make explicitely. Just add @c tinydtls to the variable @c APPS
 * in your @c Makefile.
 *
 * @addtogroup dtls_usage DTLS Usage
 *
 * @section dtls_server_example DTLS Server Example
 *
 * This section shows how to use the DTLS library functions to setup a 
 * simple secure UDP echo server. The application is responsible for the
 * entire network communication and thus will look like a usual UDP
 * server with socket creation and binding and a typical select-loop as
 * shown below. The minimum configuration required for DTLS is the 
 * creation of the dtls_context_t using dtls_new_context(), and a callback
 * for sending data. Received packets are read by the application and
 * passed to dtls_handle_message() as shown in @ref dtls_read_cb. 
 * For any useful communication to happen, read and write call backs 
 * and a key management function should be registered as well. 
 * 
 * @code 
 dtls_context_t *the_context = NULL;
 int fd, result;

 static dtls_handler_t cb = {
   .write = send_to_peer,
   .read  = read_from_peer,
   .event = NULL,
   .get_psk_key = get_psk_key
 };

 fd = socket(...);
 if (fd < 0 || bind(fd, ...) < 0)
   exit(-1);

 the_context = dtls_new_context(&fd);
 dtls_set_handler(the_context, &cb);

 while (1) {
   ...initialize fd_set rfds and timeout ...
   result = select(fd+1, &rfds, NULL, 0, NULL);
    
   if (FD_ISSET(fd, &rfds))
     dtls_handle_read(the_context);
 }

 dtls_free_context(the_context);
 * @endcode
 * 
 * @subsection dtls_read_cb The Read Callback
 *
 * The DTLS library expects received raw data to be passed to
 * dtls_handle_message(). The application is responsible for
 * filling a session_t structure with the address data of the
 * remote peer as illustrated by the following example:
 * 
 * @code
int dtls_handle_read(struct dtls_context_t *ctx) {
  int *fd;
  session_t session;
  static uint8 buf[DTLS_MAX_BUF];
  int len;

  fd = dtls_get_app_data(ctx);

  assert(fd);

  session.size = sizeof(session.addr);
  len = recvfrom(*fd, buf, sizeof(buf), 0, &session.addr.sa, &session.size);
  
  return len < 0 ? len : dtls_handle_message(ctx, &session, buf, len);
}    
 * @endcode 
 * 
 * Once a new DTLS session was established and DTLS ApplicationData has been
 * received, the DTLS server invokes the read callback with the MAC-verified 
 * cleartext data as its argument. A read callback for a simple echo server
 * could look like this:
 * @code
int read_from_peer(struct dtls_context_t *ctx, session_t *session, uint8 *data, size_t len) {
  return dtls_write(ctx, session, data, len);
}
 * @endcode 
 * 
 * @subsection dtls_send_cb The Send Callback
 * 
 * The callback function send_to_peer() is called whenever data must be
 * sent over the network. Here, the sendto() system call is used to
 * transmit data within the given session. The socket descriptor required
 * by sendto() has been registered as application data when the DTLS context
 * was created with dtls_new_context().
 * Note that it is on the application to buffer the data when it cannot be
 * sent at the time this callback is invoked. The following example thus
 * is incomplete as it would have to deal with EAGAIN somehow.
 * @code
int send_to_peer(struct dtls_context_t *ctx, session_t *session, uint8 *data, size_t len) {
  int fd = *(int *)dtls_get_app_data(ctx);
  return sendto(fd, data, len, MSG_DONTWAIT, &session->addr.sa, session->size);
}
 * @endcode
 * 
 * @subsection dtls_get_psk_info The Key Storage
 *
 * When a new DTLS session is created, the library must ask the application
 * for keying material. To do so, it invokes the registered call-back function
 * get_psk_info() with the current context and session information as parameter.
 * When the call-back function is invoked with the parameter @p type set to 
 * @c DTLS_PSK_IDENTITY, the result parameter @p result must be filled with
 * the psk_identity_hint in case of a server, or the actual psk_identity in 
 * case of a client. When @p type is @c DTLS_PSK_KEY, the result parameter
 * must be filled with a key for the given identity @p id. The function must
 * return the number of bytes written to @p result which must not exceed
 * @p result_length.
 * In case of an error, the function must return a negative value that 
 * corresponds to a valid error code defined in alert.h.
 * 
 * @code
int get_psk_info(struct dtls_context_t *ctx UNUSED_PARAM,
	    const session_t *session UNUSED_PARAM,
	    dtls_credentials_type_t type,
	    const unsigned char *id, size_t id_len,
	    unsigned char *result, size_t result_length) {

  switch (type) {
  case DTLS_PSK_IDENTITY:
    if (result_length < psk_id_length) {
      dtls_warn("cannot set psk_identity -- buffer too small\n");
      return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
    }

    memcpy(result, psk_id, psk_id_length);
    return psk_id_length;
  case DTLS_PSK_KEY:
    if (id_len != psk_id_length || memcmp(psk_id, id, id_len) != 0) {
      dtls_warn("PSK for unknown id requested, exiting\n");
      return dtls_alert_fatal_create(DTLS_ALERT_ILLEGAL_PARAMETER);
    } else if (result_length < psk_key_length) {
      dtls_warn("cannot set psk -- buffer too small\n");
      return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
    }

    memcpy(result, psk_key, psk_key_length);
    return psk_key_length;
  default:
    dtls_warn("unsupported request type: %d\n", type);
  }

  return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
}
 * @endcode
 * 
 * @subsection dtls_events The Event Notifier
 *
 * Applications that want to be notified whenever the status of a DTLS session
 * has changed can register an event handling function with the field @c event
 * in the dtls_handler_t structure (see \ref dtls_server_example). The call-back
 * function is called for alert messages and internal state changes. For alert
 * messages, the argument @p level will be set to a value greater than zero, and
 * @p code will indicate the notification code. For internal events, @p level
 * is @c 0, and @p code a value greater than @c 255. 
 *
 * Internal events are DTLS_EVENT_CONNECTED, @c DTLS_EVENT_CONNECT, and
 * @c DTLS_EVENT_RENEGOTIATE.
 *
 * @code
int handle_event(struct dtls_context_t *ctx, session_t *session, 
                 dtls_alert_level_t level, unsigned short code) {
  ... do something with event ...
  return 0;
}
 * @endcode
 *
 * @section dtls_client_example DTLS Client Example
 *
 * A DTLS client is constructed like a server but needs to actively setup
 * a new session by calling dtls_connect() at some point. As this function
 * usually returns before the new DTLS channel is established, the application
 * must register an event handler and wait for @c DTLS_EVENT_CONNECT before
 * it can send data over the DTLS channel.
 *
 */

/**
 * @addtogroup contiki Contiki
 *
 * To use tinyDTLS as Contiki application, place the source code in the directory 
 * @c apps/tinydtls in the Contiki source tree and invoke configure with the option
 * @c --with-contiki. This will define WITH_CONTIKI in tinydtls.h and include 
 * @c Makefile.contiki in the main Makefile. To cross-compile for another platform
 * you will need to set your host and build system accordingly. For example,
 * when configuring for ARM, you would invoke
 * @code
./configure --with-contiki --build=x86_64-linux-gnu --host=arm-none-eabi 
 * @endcode
 * on an x86_64 linux host.
 *
 * Then, create a Contiki project with @c APPS += tinydtls in its Makefile. A sample
 * server could look like this (with read_from_peer() and get_psk_key() as shown above).
 *
 * @code
#include "contiki.h"

#include "tinydtls.h"
#include "dtls.h"

#define UIP_IP_BUF   ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
#define UIP_UDP_BUF  ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN])

int send_to_peer(struct dtls_context_t *, session_t *, uint8 *, size_t);

static struct uip_udp_conn *server_conn;
static dtls_context_t *dtls_context;

static dtls_handler_t cb = {
  .write = send_to_peer,
  .read  = read_from_peer,
  .event = NULL,
  .get_psk_key = get_psk_key
};

PROCESS(server_process, "DTLS server process");
AUTOSTART_PROCESSES(&server_process);

PROCESS_THREAD(server_process, ev, data)
{
  PROCESS_BEGIN();

  dtls_init();

  server_conn = udp_new(NULL, 0, NULL);
  udp_bind(server_conn, UIP_HTONS(5684));

  dtls_context = dtls_new_context(server_conn);
  if (!dtls_context) {
    dtls_emerg("cannot create context\n");
    PROCESS_EXIT();
  }

  dtls_set_handler(dtls_context, &cb);

  while(1) {
    PROCESS_WAIT_EVENT();
    if(ev == tcpip_event && uip_newdata()) {
      session_t session;

      uip_ipaddr_copy(&session.addr, &UIP_IP_BUF->srcipaddr);
      session.port = UIP_UDP_BUF->srcport;
      session.size = sizeof(session.addr) + sizeof(session.port);
    
      dtls_handle_message(ctx, &session, uip_appdata, uip_datalen());
    }
  }

  PROCESS_END();
}

int send_to_peer(struct dtls_context_t *ctx, session_t *session, uint8 *data, size_t len) {
  struct uip_udp_conn *conn = (struct uip_udp_conn *)dtls_get_app_data(ctx);

  uip_ipaddr_copy(&conn->ripaddr, &session->addr);
  conn->rport = session->port;

  uip_udp_packet_send(conn, data, len);

  memset(&conn->ripaddr, 0, sizeof(server_conn->ripaddr));
  memset(&conn->rport, 0, sizeof(conn->rport));

  return len;
}
 * @endcode
 */
