Add net_recv_timeout()
diff --git a/include/polarssl/error.h b/include/polarssl/error.h
index e6ad54a..00c794e 100644
--- a/include/polarssl/error.h
+++ b/include/polarssl/error.h
@@ -65,7 +65,7 @@
  * DES       1  0x0032-0x0032
  * CTR_DBRG  4  0x0034-0x003A
  * ENTROPY   3  0x003C-0x0040
- * NET      11  0x0042-0x0056
+ * NET      12  0x0042-0x0056   0x0011-0x0011
  * ENTROPY   1  0x0058-0x0058
  * ASN1      7  0x0060-0x006C
  * MD2       1  0x0070-0x0070
diff --git a/include/polarssl/net.h b/include/polarssl/net.h
index 4271a7c..d0c7366 100644
--- a/include/polarssl/net.h
+++ b/include/polarssl/net.h
@@ -27,9 +27,14 @@
 #ifndef POLARSSL_NET_H
 #define POLARSSL_NET_H
 
+#if !defined(POLARSSL_CONFIG_FILE)
+#include "config.h"
+#else
+#include POLARSSL_CONFIG_FILE
+#endif
+
 #include <string.h>
 
-#define POLARSSL_ERR_NET_UNKNOWN_HOST                      -0x0056  /**< Failed to get an IP address for the given hostname. */
 #define POLARSSL_ERR_NET_SOCKET_FAILED                     -0x0042  /**< Failed to open a socket. */
 #define POLARSSL_ERR_NET_CONNECT_FAILED                    -0x0044  /**< The connection to the given server / port failed. */
 #define POLARSSL_ERR_NET_BIND_FAILED                       -0x0046  /**< Binding of the socket failed. */
@@ -40,6 +45,8 @@
 #define POLARSSL_ERR_NET_CONN_RESET                        -0x0050  /**< Connection was reset by peer. */
 #define POLARSSL_ERR_NET_WANT_READ                         -0x0052  /**< Connection requires a read call. */
 #define POLARSSL_ERR_NET_WANT_WRITE                        -0x0054  /**< Connection requires a write call. */
+#define POLARSSL_ERR_NET_UNKNOWN_HOST                      -0x0056  /**< Failed to get an IP address for the given hostname. */
+#define POLARSSL_ERR_NET_TIMEOUT                           -0x0011  /**< The operation timed out. */
 
 #define POLARSSL_NET_LISTEN_BACKLOG         10 /**< The backlog that listen() should use. */
 
@@ -160,6 +167,31 @@
  */
 int net_send( void *ctx, const unsigned char *buf, size_t len );
 
+#if defined(POLARSSL_HAVE_TIME)
+/**
+ * \brief          Read at most 'len' characters, blocking for at most
+ *                 'timeout' seconds. If no error occurs, the actual amount
+ *                 read is returned.
+ *
+ * \param ctx      Socket
+ * \param buf      The buffer to write to
+ * \param len      Maximum length of the buffer
+ * \param timeout  Maximum number of seconds to wait for data
+ *
+ * \return         This function returns the number of bytes received,
+ *                 or a non-zero error code:
+ *                 POLARSSL_ERR_NET_TIMEOUT if the operation timed out,
+ *                 POLARSSL_ERR_NET_WANT_READ if interrupted by a signal.
+ *
+ * \note           This function will block (until data becomes available or
+ *                 timeout is reached) even if the socket is set to
+ *                 non-blocking. Handling timeouts with non-blocking reads
+ *                 requires a different strategy.
+ */
+int net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
+                      unsigned char timeout );
+#endif /* POLARSSL_HAVE_TIME */
+
 /**
  * \brief          Gracefully shutdown the connection
  *
diff --git a/library/error.c b/library/error.c
index 35ecb97..f3c18c2 100644
--- a/library/error.c
+++ b/library/error.c
@@ -658,8 +658,6 @@
 #endif /* POLARSSL_MD5_C */
 
 #if defined(POLARSSL_NET_C)
-    if( use_ret == -(POLARSSL_ERR_NET_UNKNOWN_HOST) )
-        snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" );
     if( use_ret == -(POLARSSL_ERR_NET_SOCKET_FAILED) )
         snprintf( buf, buflen, "NET - Failed to open a socket" );
     if( use_ret == -(POLARSSL_ERR_NET_CONNECT_FAILED) )
@@ -680,6 +678,10 @@
         snprintf( buf, buflen, "NET - Connection requires a read call" );
     if( use_ret == -(POLARSSL_ERR_NET_WANT_WRITE) )
         snprintf( buf, buflen, "NET - Connection requires a write call" );
+    if( use_ret == -(POLARSSL_ERR_NET_UNKNOWN_HOST) )
+        snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" );
+    if( use_ret == -(POLARSSL_ERR_NET_TIMEOUT) )
+        snprintf( buf, buflen, "NET - The operation timed out" );
 #endif /* POLARSSL_NET_C */
 
 #if defined(POLARSSL_OID_C)
diff --git a/library/net.c b/library/net.c
index a0af807..7336f21 100644
--- a/library/net.c
+++ b/library/net.c
@@ -583,6 +583,49 @@
     return( ret );
 }
 
+#if defined(POLARSSL_HAVE_TIME)
+/*
+ * Read at most 'len' characters, blocking for at most 'timeout' seconds
+ */
+int net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
+                      unsigned char timeout )
+{
+    int ret;
+    struct timeval tv;
+    fd_set read_fds;
+    int fd = *((int *) ctx);
+
+    FD_ZERO( &read_fds );
+    FD_SET( fd, &read_fds );
+
+    tv.tv_sec  = timeout;
+    tv.tv_usec = 0;
+
+    ret = select( fd + 1, &read_fds, NULL, NULL, &tv );
+
+    /* Zero fds ready means we timed out */
+    if( ret == 0 )
+        return( POLARSSL_ERR_NET_TIMEOUT );
+
+    if( ret < 0 )
+    {
+#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
+    !defined(EFI32)
+        if( WSAGetLastError() == WSAEINTR )
+            return( POLARSSL_ERR_NET_WANT_READ );
+#else
+        if( errno == EINTR )
+            return( POLARSSL_ERR_NET_WANT_READ );
+#endif
+
+        return( POLARSSL_ERR_NET_RECV_FAILED );
+    }
+
+    /* This call will not block */
+    return( net_recv( ctx, buf, len ) );
+}
+#endif /* POLARSSL_HAVE_TIME */
+
 /*
  * Write at most 'len' characters
  */