Fix order of ssl_conf vs ssl_setup in programs

Except ssl_phtread_server that will be done later
diff --git a/ChangeLog b/ChangeLog
index d6ad721..2b8a438 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -16,12 +16,14 @@
    * Headers are now found in the 'mbedtls' directory (previously 'polarssl').
    * The following _init() functions that could return errors have
      been split into an _init() that returns void and another function that
-     should generally called shortly after init and can return errors:
+     should generally be the first function called on this context after init:
      mbedtls_ssl_init() -> mbedtls_ssl_setup()
      mbedtls_ccm_init() -> mbedtls_ccm_setkey()
      mbedtls_gcm_init() -> mbedtls_gcm_setkey()
      mbedtls_hmac_drbg_init() -> mbedtls_hmac_drbg_seed(_buf)()
      mbedtls_ctr_drbg_init()  -> mbedtls_ctr_drbg_seed()
+     Note that for mbetls_ssl_setup(), you need to be done setting up the
+     ssl_config structure before calling it.
    * Most ssl_set_xxx() functions (all except ssl_set_hostname(),
      ssl_set_session() and ssl_set_client_transport_id(), plus
      ssl_legacy_renegotiation()) have been renamed to mbedtls_ssl_conf_xxx()
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index b5e6a8c..1efb6a8 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1152,6 +1152,12 @@
 /**
  * \brief          Set up an SSL context for use
  *
+ * \note           No copy of the configuration context is made, it can be
+ *                 shared by many ssl_context structures.
+ *
+ * \warning        Modifying the conf structure after is has been used in this
+ *                 function is unsupported!
+ *
  * \param ssl      SSL context
  * \param conf     SSL configuration to use
  *
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 8263573..be7a25f 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4915,18 +4915,16 @@
     ssl_transform_init( ssl->transform_negotiate );
     ssl_handshake_params_init( ssl->handshake );
 
-    /*
-     * We may not know yet if we're using DTLS,
-     * so always initiliase DTLS-specific fields.
-     */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    ssl->handshake->alt_transform_out = ssl->transform_out;
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        ssl->handshake->alt_transform_out = ssl->transform_out;
 
-    // TODO: not the right place, we may not know endpoint yet
-    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
-        ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
-    else
-        ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+            ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
+        else
+            ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
+    }
 #endif
 
     return( 0 );
diff --git a/programs/ssl/dtls_client.c b/programs/ssl/dtls_client.c
index fb95adf..3886bbd 100644
--- a/programs/ssl/dtls_client.c
+++ b/programs/ssl/dtls_client.c
@@ -170,26 +170,26 @@
         goto exit;
     }
 
+    /* OPTIONAL is usually a bad choice for security, but makes interop easier
+     * in this simplified example, in which the ca chain is hardcoded.
+     * Production code should set a proper ca chain and use REQUIRED. */
+    mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_OPTIONAL );
+    mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
+    mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
+    mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
+
     if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
         goto exit;
     }
 
-    /* OPTIONAL is usually a bad choice for security, but makes interop easier
-     * in this simplified example, in which the ca chain is hardcoded.
-     * Production code should set a proper ca chain and use REQUIRED. */
-    mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_OPTIONAL );
-    mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
     if( ( ret = mbedtls_ssl_set_hostname( &ssl, SERVER_NAME ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
         goto exit;
     }
 
-    mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
-    mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
-
     mbedtls_ssl_set_bio( &ssl, &server_fd,
                          mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout );
 
diff --git a/programs/ssl/dtls_server.c b/programs/ssl/dtls_server.c
index 55b6b3e..40416be 100644
--- a/programs/ssl/dtls_server.c
+++ b/programs/ssl/dtls_server.c
@@ -200,12 +200,6 @@
         goto exit;
     }
 
-    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
-    {
-        printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
-        goto exit;
-    }
-
     mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
     mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
 
@@ -232,6 +226,12 @@
     mbedtls_ssl_conf_dtls_cookies( &conf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check,
                                &cookie_ctx );
 
+    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
+    {
+        printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
+        goto exit;
+    }
+
     printf( " ok\n" );
 
 reset:
diff --git a/programs/ssl/mini_client.c b/programs/ssl/mini_client.c
index d770754..1bb71a2 100644
--- a/programs/ssl/mini_client.c
+++ b/programs/ssl/mini_client.c
@@ -197,12 +197,6 @@
         goto exit;
     }
 
-    if( mbedtls_ssl_setup( &ssl, &conf ) != 0 )
-    {
-        ret = ssl_setup_failed;
-        goto exit;
-    }
-
     mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
 
 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
@@ -218,13 +212,20 @@
     }
 
     mbedtls_ssl_conf_ca_chain( &conf, &ca, NULL );
+    mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_REQUIRED );
+#endif
+
+    if( mbedtls_ssl_setup( &ssl, &conf ) != 0 )
+    {
+        ret = ssl_setup_failed;
+        goto exit;
+    }
+
     if( mbedtls_ssl_set_hostname( &ssl, HOSTNAME ) != 0 )
     {
         ret = hostname_failed;
         goto exit;
     }
-    mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_REQUIRED );
-#endif
 
     /*
      * 1. Start the connection
diff --git a/programs/ssl/ssl_client1.c b/programs/ssl/ssl_client1.c
index cf5598b..ec1edd8 100644
--- a/programs/ssl/ssl_client1.c
+++ b/programs/ssl/ssl_client1.c
@@ -158,26 +158,27 @@
         goto exit;
     }
 
-    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
-    {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
-        goto exit;
-    }
-
     mbedtls_printf( " ok\n" );
 
     /* OPTIONAL is not optimal for security,
      * but makes interop easier in this simplified example */
     mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_OPTIONAL );
     mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
+    mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
+    mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
+
+    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
+        goto exit;
+    }
+
     if( ( ret = mbedtls_ssl_set_hostname( &ssl, "mbed TLS Server 1" ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
         goto exit;
     }
 
-    mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
-    mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
     mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
 
     /*
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 8d04b9a..79cdb28 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -1057,12 +1057,6 @@
         goto exit;
     }
 
-    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
-    {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned -0x%x\n\n", -ret );
-        goto exit;
-    }
-
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     if( opt.debug_level > 0 )
         mbedtls_ssl_conf_verify( &conf, my_verify, NULL );
@@ -1118,16 +1112,6 @@
     mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
     mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
 
-    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,
-#if defined(MBEDTLS_HAVE_TIME)
-                             opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL
-#else
-                             NULL
-#endif
-                );
     mbedtls_ssl_conf_read_timeout( &conf, opt.read_timeout );
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
@@ -1193,6 +1177,31 @@
         mbedtls_ssl_conf_fallback( &conf, opt.fallback );
 #endif
 
+    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned -0x%x\n\n", -ret );
+        goto exit;
+    }
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    if( ( ret = mbedtls_ssl_set_hostname( &ssl, opt.server_name ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
+        goto exit;
+    }
+#endif
+
+    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,
+#if defined(MBEDTLS_HAVE_TIME)
+                             opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL
+#else
+                             NULL
+#endif
+                );
+
     mbedtls_printf( " ok\n" );
 
     /*
diff --git a/programs/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c
index e064c5c..77aa88d 100644
--- a/programs/ssl/ssl_fork_server.c
+++ b/programs/ssl/ssl_fork_server.c
@@ -257,17 +257,10 @@
             goto exit;
         }
 
-        if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
-        {
-            mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
-            goto exit;
-        }
-
         mbedtls_printf( " ok\n" );
 
         mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
         mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
-        mbedtls_ssl_set_bio( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
 
         mbedtls_ssl_conf_ca_chain( &conf, srvcert.next, NULL );
         if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 )
@@ -276,6 +269,14 @@
             goto exit;
         }
 
+        if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
+        {
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
+            goto exit;
+        }
+
+        mbedtls_ssl_set_bio( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
+
         /*
          * 5. Handshake
          */
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index d28b851..a555d40 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -592,21 +592,12 @@
         goto exit;
     }
 
-    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
-    {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
-        goto exit;
-    }
-
-    mbedtls_printf( " ok\n" );
-
     /* OPTIONAL is not optimal for security,
      * but makes interop easier in this simplified example */
     mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_OPTIONAL );
 
     mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
     mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
-    mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
 
     if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER )
         mbedtls_ssl_conf_ciphersuites( &conf, opt.force_ciphersuite );
@@ -623,7 +614,13 @@
         goto exit;
     }
 
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
+        goto exit;
+    }
+
+#if defined(MBEDTLS_x509_CRT_PARSE_C)
     if( ( ret = mbedtls_ssl_set_hostname( &ssl, opt.server_name ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
@@ -631,6 +628,10 @@
     }
 #endif
 
+    mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
+
+    mbedtls_printf( " ok\n" );
+
     if( opt.mode == MODE_SSL_TLS )
     {
         if( do_handshake( &ssl ) != 0 )
diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c
index 150b626..a919ad9 100644
--- a/programs/ssl/ssl_server.c
+++ b/programs/ssl/ssl_server.c
@@ -199,12 +199,6 @@
         goto exit;
     }
 
-    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
-    {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
-        goto exit;
-    }
-
     mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
     mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
 
@@ -221,6 +215,12 @@
         goto exit;
     }
 
+    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
+        goto exit;
+    }
+
     mbedtls_printf( " ok\n" );
 
 reset:
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index b9e2c09..863cc53 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -1527,12 +1527,6 @@
         goto exit;
     }
 
-    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
-    {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned -0x%x\n\n", -ret );
-        goto exit;
-    }
-
     if( opt.auth_mode != DFL_AUTH_MODE )
         mbedtls_ssl_conf_authmode( &conf, opt.auth_mode );
 
@@ -1740,6 +1734,23 @@
     if( opt.max_version != DFL_MIN_VERSION )
         mbedtls_ssl_conf_max_version( &conf, MBEDTLS_SSL_MAJOR_VERSION_3, opt.max_version );
 
+    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned -0x%x\n\n", -ret );
+        goto exit;
+    }
+
+    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,
+#if defined(MBEDTLS_HAVE_TIME)
+                             opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL
+#else
+                             NULL
+#endif
+                );
+
     mbedtls_printf( " ok\n" );
 
 reset:
@@ -1799,16 +1810,6 @@
         goto exit;
     }
 
-    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,
-#if defined(MBEDTLS_HAVE_TIME)
-                             opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL
-#else
-                             NULL
-#endif
-                );
     mbedtls_ssl_conf_read_timeout( &conf, opt.read_timeout );
 
 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
diff --git a/programs/x509/cert_app.c b/programs/x509/cert_app.c
index 79a652e..41bbb42 100644
--- a/programs/x509/cert_app.c
+++ b/programs/x509/cert_app.c
@@ -404,12 +404,6 @@
             goto exit;
         }
 
-        if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
-        {
-            mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
-            goto ssl_exit;
-        }
-
         if( verify )
         {
             mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_REQUIRED );
@@ -421,7 +415,6 @@
 
         mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
         mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
-        mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
 
         if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &clicert, &pkey ) ) != 0 )
         {
@@ -429,12 +422,20 @@
             goto ssl_exit;
         }
 
+        if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
+        {
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
+            goto ssl_exit;
+        }
+
         if( ( ret = mbedtls_ssl_set_hostname( &ssl, opt.server_name ) ) != 0 )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
             goto ssl_exit;
         }
 
+        mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
+
         /*
          * 4. Handshake
          */