Simplify net_accept() with UDP sockets

This is made possible by the new API where net_accept() gets a pointer to
bind_ctx, so it can update it.
diff --git a/ChangeLog b/ChangeLog
index 7c238e5..f87f1e1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -174,6 +174,8 @@
      instead, see mbedtls_ssl_set_timer_cb(), with the Timing module providing
      an example implementation, see mbedtls_timing_delay_context and
      mbedtls_timing_set/get_delay().
+   * With UDP sockets, it is no longer necessary to call net_bind() again
+     after a successful net_accept().
 
 Changes
    * mbedtls_ctr_drbg_random() and mbedtls_hmac_drbg_random() are now
diff --git a/include/mbedtls/net.h b/include/mbedtls/net.h
index 85c4977..19746e5 100644
--- a/include/mbedtls/net.h
+++ b/include/mbedtls/net.h
@@ -126,10 +126,6 @@
  *                  MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small,
  *                  MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to
  *                  non-blocking and accept() would block.
- *
- * \note            With UDP, connects the bind_fd to the client and just copy
- *                  its descriptor to client_fd. New clients will not be able
- *                  to connect until you close the socket and bind a new one.
  */
 int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
                         mbedtls_net_context *client_ctx,
diff --git a/library/net.c b/library/net.c
index 7e72e08..04aa0df 100644
--- a/library/net.c
+++ b/library/net.c
@@ -338,13 +338,34 @@
         return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
     }
 
-    /* UDP: hijack the listening socket for communicating with the client */
+    /* UDP: hijack the listening socket to communicate with the client,
+     * then bind a new socket to accept new connections */
     if( type != SOCK_STREAM )
     {
+        struct sockaddr_storage local_addr;
+        int one = 1;
+
         if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 )
             return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
 
         client_ctx->fd = bind_ctx->fd;
+        bind_ctx->fd   = -1; /* In case we exit early */
+
+        n = sizeof( struct sockaddr_storage );
+        if( getsockname( client_ctx->fd,
+                         (struct sockaddr *) &local_addr, &n ) != 0 ||
+            ( bind_ctx->fd = (int) socket( local_addr.ss_family,
+                                           SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ||
+            setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
+                        (const char *) &one, sizeof( one ) ) != 0 )
+        {
+            return( MBEDTLS_ERR_NET_SOCKET_FAILED );
+        }
+
+        if( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 )
+        {
+            return( MBEDTLS_ERR_NET_BIND_FAILED );
+        }
     }
 
     if( client_ip != NULL )
diff --git a/programs/ssl/dtls_server.c b/programs/ssl/dtls_server.c
index a3839c6..650b687 100644
--- a/programs/ssl/dtls_server.c
+++ b/programs/ssl/dtls_server.c
@@ -273,13 +273,6 @@
         goto exit;
     }
 
-    /* With UDP, bind_fd is hijacked by client_fd, so bind a new one */
-    if( ( ret = mbedtls_net_bind( &listen_fd, NULL, "4433", MBEDTLS_NET_PROTO_UDP ) ) != 0 )
-    {
-        printf( " failed\n  ! mbedtls_net_bind returned -0x%x\n\n", -ret );
-        goto exit;
-    }
-
     /* For HelloVerifyRequest cookies */
     if( ( ret = mbedtls_ssl_set_client_transport_id( &ssl,
                     client_ip, cliip_len ) ) != 0 )
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 99d43c9..a08aa9b 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -1897,28 +1897,6 @@
     mbedtls_printf( " ok\n" );
 
     /*
-     * With UDP, bind_fd is hijacked by client_fd, so bind a new one
-     */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
-    {
-        mbedtls_printf( "  . Re-bind on udp://%s:%s/ ...",
-                opt.server_addr ? opt.server_addr : "*",
-                opt.server_port );
-        fflush( stdout );
-
-        if( ( ret = mbedtls_net_bind( &listen_fd, opt.server_addr,
-                              opt.server_port, MBEDTLS_NET_PROTO_UDP ) ) != 0 )
-        {
-            mbedtls_printf( " failed\n  ! mbedtls_net_bind returned -0x%x\n\n", -ret );
-            goto exit;
-        }
-
-        mbedtls_printf( " ok\n" );
-    }
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
-    /*
      * 4. Handshake
      */
     mbedtls_printf( "  . Performing the SSL/TLS handshake..." );
diff --git a/programs/test/udp_proxy.c b/programs/test/udp_proxy.c
index 7360d8a..76e3b31 100644
--- a/programs/test/udp_proxy.c
+++ b/programs/test/udp_proxy.c
@@ -533,6 +533,8 @@
      * 2. Wait until a client connects
      */
 accept:
+    mbedtls_net_free( &client_fd );
+
     mbedtls_printf( "  . Waiting for a remote connection ..." );
     fflush( stdout );
 
@@ -544,20 +546,6 @@
     }
 
     mbedtls_printf( " ok\n" );
-    fflush( stdout );
-
-    mbedtls_printf( "  . Re-bind on UDP/%s/%s ...",
-            opt.listen_addr, opt.listen_port );
-    fflush( stdout );
-
-    if( ( ret = mbedtls_net_bind( &listen_fd, opt.listen_addr, opt.listen_port,
-                          MBEDTLS_NET_PROTO_UDP ) ) != 0 )
-    {
-        mbedtls_printf( " failed\n  ! mbedtls_net_bind returned %d\n\n", ret );
-        goto exit;
-    }
-
-    mbedtls_printf( " ok\n" );
 
     /*
      * 3. Forward packets forever (kill the process to terminate it)