Allow compile-time configuration of I/O function pointers

Introduce the compile-time options
- MBEDTLS_SSL_CONF_RECV
- MBEDTLS_SSL_CONF_SEND
- MBEDTLS_SSL_CONF_RECV_TIMEOUT
which can be used to configure the callbacks for the underlying
transport at compile-time.

Code-size impact:

|  | GCC 8.2.1 | ARMC5 5.06 | ARMC6 6.12 |
| --- | --- | --- | --- |
| `libmbedtls.a` before | 23471 | 24077 | 27045 |
| `libmbedtls.a` before | 23379 | 23981 | 26941 |
| gain in Bytes | 92 | 96 | 104 |
diff --git a/configs/baremetal.h b/configs/baremetal.h
index a6da5c3..d6ce9a3 100644
--- a/configs/baremetal.h
+++ b/configs/baremetal.h
@@ -93,6 +93,9 @@
 #define MBEDTLS_SSL_CONF_AUTHMODE MBEDTLS_SSL_VERIFY_REQUIRED
 #define MBEDTLS_SSL_CONF_BADMAC_LIMIT 0
 #define MBEDTLS_SSL_CONF_ANTI_REPLAY MBEDTLS_SSL_ANTI_REPLAY_ENABLED
+#define MBEDTLS_SSL_CONF_RECV mbedtls_net_recv
+#define MBEDTLS_SSL_CONF_SEND mbedtls_net_send
+#define MBEDTLS_SSL_CONF_RECV_TIMEOUT mbedtls_net_recv_timeout
 #define MBEDTLS_SSL_CONF_RNG mbedtls_hmac_drbg_random
 #define MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET \
     MBEDTLS_SSL_EXTENDED_MS_ENABLED
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 764fba4..29d9906 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -671,6 +671,18 @@
 #define "MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET and MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET must be defined together."
 #endif
 
+#if ( defined(MBEDTLS_SSL_CONF_SEND) &&                 \
+      !( defined(MBEDTLS_SSL_CONF_RECV) &&              \
+         defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT) ) ) ||  \
+    ( defined(MBEDTLS_SSL_CONF_RECV) &&                 \
+      !( defined(MBEDTLS_SSL_CONF_SEND) &&              \
+         defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT) ) ) ||  \
+    ( defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT) &&         \
+      !( defined(MBEDTLS_SSL_CONF_SEND) &&              \
+         defined(MBEDTLS_SSL_CONF_RECV) ) )
+#define "MBEDTLS_SSL_CONF_SEND/RECV/RECV_TIMEOUT must be defined simultaneously"
+#endif
+
 #if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C)
 #error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites"
 #endif
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 597f2a3..a767cb2 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -3601,6 +3601,22 @@
 //#define MBEDTLS_SSL_CONF_CID_LEN 0
 //#define MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID MBEDTLS_SSL_UNEXPECTED_CID_IGNORE
 
+/* The send and receive callbacks to use by the SSL module.
+ * If defined,
+ * - MBEDTLS_SSL_CONF_RECV must evaluate to the name of an externally
+ *   defined function with signature
+ *      int (*f_recv)( void*, unsigned char *, size_t ),
+ * * MBEDTLS_SSL_CONF_SEND must evaluate to the name of an externally
+ *   defined function with signature
+ *      int (*f_send)( void*, const unsigned char *, size_t ),
+ * * MBEDTLS_SSL_CONF_RECV_TIMEOUT must evaluate to the name of an
+ * externally defined function with signature
+ *      int (*f_recv_timeout)( void*, const unsigned char *, size_t, uint32_t ).
+ */
+//#define MBEDTLS_SSL_CONF_RECV mbedtls_net_recv
+//#define MBEDTLS_SSL_CONF_SEND mbedtls_net_send
+//#define MBEDTLS_SSL_CONF_RECV_TIMEOUT mbedtls_net_recv_timeout
+
 /* The PRNG to use by the SSL module. If defined, this must
  * evaluate to the name on externally defined function with signature
  * int (*f_rng)(void *, unsigned char *, size_t),
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 7364dc4..671d107 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1146,9 +1146,15 @@
     unsigned badmac_seen;       /*!< records with a bad MAC received    */
 #endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
 
+#if !defined(MBEDTLS_SSL_CONF_SEND)
     mbedtls_ssl_send_t *f_send; /*!< Callback for network send */
+#endif /* !MBEDTLS_SSL_CONF_SEND */
+#if !defined(MBEDTLS_SSL_CONF_RECV)
     mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */
+#endif /* !MBEDTLS_SSL_CONF_RECV */
+#if !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
     mbedtls_ssl_recv_timeout_t *f_recv_timeout;
+#endif /* !MBEDTLS_SSL_CONF_RECV_TIMEOUT */
                                 /*!< Callback for network receive with timeout */
 
     void *p_bio;                /*!< context for I/O operations   */
@@ -1510,6 +1516,9 @@
                   void (*f_dbg)(void *, int, const char *, int, const char *),
                   void  *p_dbg );
 
+#if !defined(MBEDTLS_SSL_CONF_RECV) && \
+    !defined(MBEDTLS_SSL_CONF_SEND) && \
+    !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
 /**
  * \brief          Set the underlying BIO callbacks for write, read and
  *                 read-with-timeout.
@@ -1535,6 +1544,13 @@
  *                 \c mbedtls_ssl_recv_t and \c mbedtls_ssl_recv_timeout_t for
  *                 the conventions those callbacks must follow.
  *
+ * \note           On constrained systems, the pointers \p f_send, \p f_recv,
+ *                 and \p f_recv_timeout can also be configured at compile-time
+ *                 via the macros MBEDTLS_SSL_CONF_RECV, MBEDTLS_SSL_CONF_SEND
+ *                 and MBEDTLS_SSL_CONF_RECV_TIMEOUT. In this case, the
+ *                 corresponding parameters to this function don't take
+ *                 any effect.
+ *
  * \note           On some platforms, net_sockets.c provides
  *                 \c mbedtls_net_send(), \c mbedtls_net_recv() and
  *                 \c mbedtls_net_recv_timeout() that are suitable to be used
@@ -1545,6 +1561,18 @@
                           mbedtls_ssl_send_t *f_send,
                           mbedtls_ssl_recv_t *f_recv,
                           mbedtls_ssl_recv_timeout_t *f_recv_timeout );
+#else
+/**
+ * \brief          Set the context to be passed to the underlying BIO callbacks
+ *                 for write, read and read-with-timeout.
+ *
+ * \param ssl      The SSL context to configure.
+ * \param p_bio    The parameter (context) to be used for the BIO callbacks.
+ *
+ */
+void mbedtls_ssl_set_bio_ctx( mbedtls_ssl_context *ssl,
+                              void *p_bio );
+#endif
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
 
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 52835b4..8d5170c 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -1291,8 +1291,68 @@
 
 typedef int (*mbedtls_frng_t)( void*, unsigned char*, size_t );
 
+#if !defined(MBEDTLS_SSL_CONF_RECV)
+static inline mbedtls_ssl_recv_t* mbedtls_ssl_get_recv(
+    mbedtls_ssl_context const *ssl )
+{
+    return( ssl->f_recv );
+}
+#else /* !MBEDTLS_SSL_CONF_RECV */
+
+#define mbedtls_ssl_conf_recv_func MBEDTLS_SSL_CONF_RECV
+extern int mbedtls_ssl_conf_recv_func( void*, unsigned char*, size_t );
+
+static inline mbedtls_ssl_recv_t* mbedtls_ssl_get_recv(
+    mbedtls_ssl_context const *ssl )
+{
+    ((void) ssl);
+    return ((mbedtls_ssl_recv_t*) mbedtls_ssl_conf_recv_func);
+}
+#endif /* MBEDTLS_SSL_CONF_RECV */
+
+#if !defined(MBEDTLS_SSL_CONF_SEND)
+static inline mbedtls_ssl_send_t* mbedtls_ssl_get_send(
+    mbedtls_ssl_context const *ssl )
+{
+    return( ssl->f_send );
+}
+#else /* !MBEDTLS_SSL_CONF_SEND */
+
+#define mbedtls_ssl_conf_send_func MBEDTLS_SSL_CONF_SEND
+extern int mbedtls_ssl_conf_send_func( void*, unsigned char const*, size_t );
+
+static inline mbedtls_ssl_send_t* mbedtls_ssl_get_send(
+    mbedtls_ssl_context const *ssl )
+{
+    ((void) ssl);
+    return ((mbedtls_ssl_send_t*) mbedtls_ssl_conf_send_func);
+}
+#endif /* MBEDTLS_SSL_CONF_SEND */
+
+#if !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
+static inline mbedtls_ssl_recv_timeout_t* mbedtls_ssl_get_recv_timeout(
+    mbedtls_ssl_context const *ssl )
+{
+    return( ssl->f_recv_timeout );
+}
+#else /* !MBEDTLS_SSL_CONF_RECV_TIMEOUT */
+
+#define mbedtls_ssl_conf_recv_timeout_func MBEDTLS_SSL_CONF_RECV_TIMEOUT
+extern int mbedtls_ssl_conf_recv_timeout_func(
+    void*, unsigned char*, size_t, uint32_t );
+
+static inline mbedtls_ssl_recv_timeout_t* mbedtls_ssl_get_recv_timeout(
+    mbedtls_ssl_context const *ssl )
+{
+    ((void) ssl);
+    return ((mbedtls_ssl_recv_timeout_t*) mbedtls_ssl_conf_recv_timeout_func);
+}
+#endif /* MBEDTLS_SSL_CONF_RECV_TIMEOUT */
+
+typedef int mbedtls_frng_t( void*, unsigned char*, size_t );
+
 #if !defined(MBEDTLS_SSL_CONF_RNG)
-static inline mbedtls_frng_t mbedtls_ssl_conf_get_frng(
+static inline mbedtls_frng_t* mbedtls_ssl_conf_get_frng(
     mbedtls_ssl_config const *conf )
 {
     return( conf->f_rng );
@@ -1302,7 +1362,7 @@
 #define mbedtls_ssl_conf_rng_func MBEDTLS_SSL_CONF_RNG
 extern int mbedtls_ssl_conf_rng_func( void*, unsigned char*, size_t );
 
-static inline mbedtls_frng_t mbedtls_ssl_conf_get_frng(
+static inline mbedtls_frng_t* mbedtls_ssl_conf_get_frng(
     mbedtls_ssl_config const *conf )
 {
     ((void) conf);
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 8c24ee9..847ac71 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3064,7 +3064,8 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) );
 
-    if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL )
+    if( mbedtls_ssl_get_recv( ssl ) == NULL &&
+        mbedtls_ssl_get_recv_timeout( ssl ) == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
                             "or mbedtls_ssl_set_bio()" ) );
@@ -3166,11 +3167,16 @@
 
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %u ms", timeout ) );
 
-            if( ssl->f_recv_timeout != NULL )
-                ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len,
-                                                                    timeout );
+            if( mbedtls_ssl_get_recv_timeout( ssl ) != NULL )
+            {
+                ret = mbedtls_ssl_get_recv_timeout( ssl )
+                    ( ssl->p_bio, ssl->in_hdr, len, timeout );
+            }
             else
-                ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len );
+            {
+                ret = mbedtls_ssl_get_recv( ssl )
+                    ( ssl->p_bio, ssl->in_hdr, len );
+            }
 
             MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
 
@@ -3235,15 +3241,15 @@
                 ret = MBEDTLS_ERR_SSL_TIMEOUT;
             else
             {
-                if( ssl->f_recv_timeout != NULL )
+                if( mbedtls_ssl_get_recv_timeout( ssl ) != NULL )
                 {
-                    ret = ssl->f_recv_timeout( ssl->p_bio,
-                             ssl->in_hdr + ssl->in_left, len,
-                             mbedtls_ssl_conf_get_read_timeout( ssl->conf ) );
+                    ret = mbedtls_ssl_get_recv_timeout( ssl )( ssl->p_bio,
+                       ssl->in_hdr + ssl->in_left, len,
+                       mbedtls_ssl_conf_get_read_timeout( ssl->conf ) );
                 }
                 else
                 {
-                    ret = ssl->f_recv( ssl->p_bio,
+                    ret = mbedtls_ssl_get_recv( ssl )( ssl->p_bio,
                                        ssl->in_hdr + ssl->in_left, len );
                 }
             }
@@ -3286,7 +3292,7 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) );
 
-    if( ssl->f_send == NULL )
+    if( mbedtls_ssl_get_send( ssl ) == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
                             "or mbedtls_ssl_set_bio()" ) );
@@ -3306,7 +3312,7 @@
                        mbedtls_ssl_out_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) );
 
         buf = ssl->out_hdr - ssl->out_left;
-        ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left );
+        ret = mbedtls_ssl_get_send( ssl )( ssl->p_bio, buf, ssl->out_left );
 
         MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret );
 
@@ -4581,7 +4587,7 @@
         /* Don't check write errors as we can't do anything here.
          * If the error is permanent we'll catch it later,
          * if it's not, then hopefully it'll work next time. */
-        (void) ssl->f_send( ssl->p_bio, ssl->out_buf, len );
+        (void) mbedtls_ssl_get_send( ssl )( ssl->p_bio, ssl->out_buf, len );
 
         return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
     }
@@ -8212,17 +8218,27 @@
     conf->p_dbg      = p_dbg;
 }
 
+#if !defined(MBEDTLS_SSL_CONF_RECV) && \
+    !defined(MBEDTLS_SSL_CONF_SEND) && \
+    !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
 void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
         void *p_bio,
         mbedtls_ssl_send_t *f_send,
         mbedtls_ssl_recv_t *f_recv,
         mbedtls_ssl_recv_timeout_t *f_recv_timeout )
 {
-    ssl->p_bio          = p_bio;
-    ssl->f_send         = f_send;
-    ssl->f_recv         = f_recv;
+    ssl->p_bio = p_bio;
+    ssl->f_send = f_send;
+    ssl->f_recv = f_recv;
     ssl->f_recv_timeout = f_recv_timeout;
 }
+#else
+void mbedtls_ssl_set_bio_ctx( mbedtls_ssl_context *ssl,
+                              void *p_bio )
+{
+    ssl->p_bio = p_bio;
+}
+#endif
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
 void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu )
diff --git a/programs/ssl/dtls_client.c b/programs/ssl/dtls_client.c
index cb2851b..6f508ae 100644
--- a/programs/ssl/dtls_client.c
+++ b/programs/ssl/dtls_client.c
@@ -205,8 +205,13 @@
         goto exit;
     }
 
-    mbedtls_ssl_set_bio( &ssl, &server_fd,
-                         mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout );
+#if !defined(MBEDTLS_SSL_CONF_RECV) && \
+    !defined(MBEDTLS_SSL_CONF_SEND) && \
+    !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
+    mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
+#else
+     mbedtls_ssl_set_bio_ctx( &ssl, &server_fd );
+#endif
 
     mbedtls_ssl_set_timer_cb( &ssl, &timer, mbedtls_timing_set_delay,
                                             mbedtls_timing_get_delay );
diff --git a/programs/ssl/mini_client.c b/programs/ssl/mini_client.c
index 18e11d0..4231c0c 100644
--- a/programs/ssl/mini_client.c
+++ b/programs/ssl/mini_client.c
@@ -269,7 +269,13 @@
         goto exit;
     }
 
+#if !defined(MBEDTLS_SSL_CONF_RECV) && \
+    !defined(MBEDTLS_SSL_CONF_SEND) && \
+    !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
     mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
+#else
+     mbedtls_ssl_set_bio_ctx( &ssl, &server_fd );
+#endif
 
     if( mbedtls_ssl_handshake( &ssl ) != 0 )
     {
diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c
index 6d2b67b..a4881df 100644
--- a/programs/ssl/query_config.c
+++ b/programs/ssl/query_config.c
@@ -2706,6 +2706,30 @@
     }
 #endif /* MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */
 
+#if defined(MBEDTLS_SSL_CONF_RECV)
+    if( strcmp( "MBEDTLS_SSL_CONF_RECV", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_RECV );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_CONF_RECV */
+
+#if defined(MBEDTLS_SSL_CONF_SEND)
+    if( strcmp( "MBEDTLS_SSL_CONF_SEND", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_SEND );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_CONF_SEND */
+
+#if defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
+    if( strcmp( "MBEDTLS_SSL_CONF_RECV_TIMEOUT", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_RECV_TIMEOUT );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_CONF_RECV_TIMEOUT */
+
 #if defined(MBEDTLS_SSL_CONF_RNG)
     if( strcmp( "MBEDTLS_SSL_CONF_RNG", config ) == 0 )
     {
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index a4af97a..695cc6a 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -466,6 +466,10 @@
     fflush(  (FILE *) ctx  );
 }
 
+
+#if !defined(MBEDTLS_SSL_CONF_RECV) && \
+    !defined(MBEDTLS_SSL_CONF_SEND) && \
+    !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
 /*
  * Test recv/send functions that make sure each try returns
  * WANT_READ/WANT_WRITE at least once before sucesseding
@@ -503,6 +507,9 @@
         first_try = 1; /* Next call will be a new operation */
     return( ret );
 }
+#endif /* MBEDTLS_SSL_CONF_RECV &&
+          MBEDTLS_SSL_CONF_SEND &&
+          MBEDTLS_SSL_CONF_RECV_TIMEOUT */
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 static unsigned char peer_crt_info[1024];
@@ -1876,12 +1883,18 @@
     }
 #endif
 
+#if !defined(MBEDTLS_SSL_CONF_RECV) && \
+    !defined(MBEDTLS_SSL_CONF_SEND) && \
+    !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
     if( opt.nbio == 2 )
         mbedtls_ssl_set_bio( &ssl, &server_fd, my_send, my_recv, NULL );
     else
         mbedtls_ssl_set_bio( &ssl, &server_fd,
                              mbedtls_net_send, mbedtls_net_recv,
                              opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL );
+#else
+     mbedtls_ssl_set_bio_ctx( &ssl, &server_fd );
+#endif
 
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
     if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 2704d4e..916a642 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -597,6 +597,10 @@
     fflush(  (FILE *) ctx  );
 }
 
+
+#if !defined(MBEDTLS_SSL_CONF_RECV) && \
+    !defined(MBEDTLS_SSL_CONF_SEND) && \
+    !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
 /*
  * Test recv/send functions that make sure each try returns
  * WANT_READ/WANT_WRITE at least once before sucesseding
@@ -634,6 +638,9 @@
         first_try = 1; /* Next call will be a new operation */
     return( ret );
 }
+#endif /* MBEDTLS_SSL_CONF_RECV &&
+          MBEDTLS_SSL_CONF_SEND &&
+          MBEDTLS_SSL_CONF_RECV_TIMEOUT */
 
 #if !defined(MBEDTLS_SSL_CONF_AUTHMODE)
 /*
@@ -2859,11 +2866,18 @@
         goto exit;
     }
 
+#if !defined(MBEDTLS_SSL_CONF_RECV) && \
+    !defined(MBEDTLS_SSL_CONF_SEND) && \
+    !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
     if( opt.nbio == 2 )
         mbedtls_ssl_set_bio( &ssl, &client_fd, my_send, my_recv, NULL );
     else
-        mbedtls_ssl_set_bio( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv,
+        mbedtls_ssl_set_bio( &ssl, &client_fd,
+                             mbedtls_net_send, mbedtls_net_recv,
                              opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL );
+#else
+     mbedtls_ssl_set_bio_ctx( &ssl, &client_fd );
+#endif
 
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
     if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )