Navigation


Changeset 1181:22de21feec64 in freeDiameter for libfdcore


Ignore:
Timestamp:
Jun 5, 2013, 8:22:26 PM (11 years ago)
Author:
Sebastien Decugis <sdecugis@freediameter.net>
Branch:
default
Phase:
public
Message:

Preparing for DTLS support

Location:
libfdcore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • libfdcore/cnxctx.c

    r1180 r1181  
    9696}
    9797
     98#define CC_ID_HDR "{----} "
     99
    98100/* Create and bind a server socket to the given endpoint and port */
    99101struct cnxctx * fd_cnx_serv_tcp(uint16_t port, int family, struct fd_endpoint * ep)
     
    139141                if (rc)
    140142                        snprintf(addrbuf, sizeof(addrbuf), "[err:%s]", gai_strerror(rc));
    141                 snprintf(cnx->cc_id, sizeof(cnx->cc_id), "TCP srv [%s]:%hu (%d)", addrbuf, port, cnx->cc_socket);
     143                snprintf(cnx->cc_id, sizeof(cnx->cc_id), CC_ID_HDR "TCP srv [%s]:%hu (%d)", addrbuf, port, cnx->cc_socket);
    142144        }
    143145
     
    179181
    180182        /* Generate the name for the connection object */
    181         snprintf(cnx->cc_id, sizeof(cnx->cc_id), "SCTP srv :%hu (%d)", port, cnx->cc_socket);
     183        snprintf(cnx->cc_id, sizeof(cnx->cc_id), CC_ID_HDR "SCTP srv :%hu (%d)", port, cnx->cc_socket);
    182184
    183185        cnx->cc_proto = IPPROTO_SCTP;
     
    249251               
    250252                /* Numeric values for debug... */
    251                 snprintf(cli->cc_id, sizeof(cli->cc_id), "%s from [%s]:%s (%d<-%d)",
     253                snprintf(cli->cc_id, sizeof(cli->cc_id), CC_ID_HDR "%s from [%s]:%s (%d<-%d)",
    252254                                IPPROTO_NAME(cli->cc_proto), addrbuf, portbuf, serv->cc_socket, cli->cc_socket);
    253255               
     
    313315                int  rc;
    314316               
    315                 snprintf(cnx->cc_id, sizeof(cnx->cc_id), "TCP,#%d->%s", cnx->cc_socket, sa_buf);
     317                snprintf(cnx->cc_id, sizeof(cnx->cc_id), CC_ID_HDR "TCP,#%d->%s", cnx->cc_socket, sa_buf);
    316318               
    317319                /* ...Name for log messages */
     
    376378                int  rc;
    377379               
    378                 snprintf(cnx->cc_id, sizeof(cnx->cc_id), "SCTP,#%d->%s", cnx->cc_socket, sa_buf);
     380                snprintf(cnx->cc_id, sizeof(cnx->cc_id), CC_ID_HDR "SCTP,#%d->%s", cnx->cc_socket, sa_buf);
    379381               
    380382                /* ...Name for log messages */
     
    433435        return st & flag;
    434436}
     437void fd_cnx_update_id(struct cnxctx * conn) {
     438        if (conn->cc_state & CC_STATUS_CLOSING)
     439                conn->cc_id[1] = 'C';
     440        else
     441                conn->cc_id[1] = '-';
     442       
     443        if (conn->cc_state & CC_STATUS_ERROR)
     444                conn->cc_id[2] = 'E';
     445        else
     446                conn->cc_id[2] = '-';
     447       
     448        if (conn->cc_state & CC_STATUS_SIGNALED)
     449                conn->cc_id[3] = 'S';
     450        else
     451                conn->cc_id[3] = '-';
     452       
     453        if (conn->cc_state & CC_STATUS_TLS)
     454                conn->cc_id[4] = 'T';
     455        else
     456                conn->cc_id[4] = '-';
     457}
    435458void fd_cnx_addstate(struct cnxctx * conn, uint32_t orstate)
    436459{
    437460        CHECK_POSIX_DO( pthread_mutex_lock(&state_lock), { ASSERT(0); } );
    438461        conn->cc_state |= orstate;
     462        fd_cnx_update_id(conn);
    439463        CHECK_POSIX_DO( pthread_mutex_unlock(&state_lock), { ASSERT(0); } );
    440464}
     
    443467        CHECK_POSIX_DO( pthread_mutex_lock(&state_lock), { ASSERT(0); } );
    444468        conn->cc_state = abstate;
     469        fd_cnx_update_id(conn);
    445470        CHECK_POSIX_DO( pthread_mutex_unlock(&state_lock), { ASSERT(0); } );
    446471}
     
    659684}
    660685
    661 #ifndef DISABLE_SCTP
     686#ifndef DISABLE_SCTP /* WE use this function only in SCTP code */
    662687static uint8_t * fd_cnx_realloc_msg_buffer(uint8_t * buffer, size_t expected_len, struct fd_msg_pmdl ** pmdl)
    663688{
     
    853878
    854879
    855 /* Returns 0 on error, received data size otherwise (always >= 0) */
     880/* Returns 0 on error, received data size otherwise (always >= 0). This is not used for DTLS-protected associations. */
    856881static ssize_t fd_tls_recv_handle_error(struct cnxctx * conn, gnutls_session_t session, void * data, size_t sz)
    857882{
    858883        ssize_t ret;
    859884again: 
    860         CHECK_GNUTLS_DO( ret = gnutls_record_recv(session, data, sz),
     885        CHECK_GNUTLS_DO( ret = gnutls_record_recv(session, data, sz), 
    861886                {
    862887                        switch (ret) {
     
    885910                               
    886911                                default:
    887                                         TRACE_DEBUG(INFO, "This GNU TLS error is not handled, assume unrecoverable error");
     912                                        if (gnutls_error_is_fatal (ret) == 0) {
     913                                                LOG_N("Ignoring non-fatal GNU TLS error: %s", gnutls_strerror (ret));
     914                                                goto again;
     915                                        }
     916                                        LOG_E("Fatal GNUTLS error: %s", gnutls_strerror (ret));
    888917                        }
    889918                } );
     
    898927}
    899928
    900 /* Wrapper around gnutls_record_send to handle some error codes */
     929/* Wrapper around gnutls_record_send to handle some error codes. This is also used for DTLS-protected associations */
    901930static ssize_t fd_tls_send_handle_error(struct cnxctx * conn, gnutls_session_t session, void * data, size_t sz)
    902931{
     
    925954
    926955                                default:
    927                                         TRACE_DEBUG(INFO, "This TLS error is not handled, assume unrecoverable error");
     956                                        if (gnutls_error_is_fatal (ret) == 0) {
     957                                                LOG_N("Ignoring non-fatal GNU TLS error: %s", gnutls_strerror (ret));
     958                                                goto again;
     959                                        }
     960                                        LOG_E("Fatal GNUTLS error: %s", gnutls_strerror (ret));
    928961                        }
    929962                } );
     
    937970
    938971/* The function that receives TLS data and re-builds a Diameter message -- it exits only on error or cancelation */
     972/*         For the case of DTLS, since we are not using SCTP_UNORDERED, the messages over a single stream are ordered.
     973           Furthermore, as long as messages are shorter than the MTU [2^14 = 16384 bytes], they are delivered in a single
     974           record, as far as I understand.
     975           For larger messages, however, it is possible that pieces of messages coming from different streams can get interleaved.
     976           As a result, we do not use the following function for DTLS reception, because we use the sequence number to rebuild the
     977           messages. */
    939978int fd_tls_rcvthr_core(struct cnxctx * conn, gnutls_session_t session)
    940979{
    941         /* No guarantee that GnuTLS preserves the message boundaries, so we re-build it as in TCP */
     980        /* No guarantee that GnuTLS preserves the message boundaries, so we re-build it as in TCP. */
    942981        do {
    943982                uint8_t header[4];
     
    10251064
    10261065/* Prepare a gnutls session object for handshake */
    1027 int fd_tls_prepare(gnutls_session_t * session, int mode, char * priority, void * alt_creds)
    1028 {
     1066int fd_tls_prepare(gnutls_session_t * session, int mode, int dtls, char * priority, void * alt_creds)
     1067{
     1068        if (dtls) {
     1069                LOG_E("DTLS sessions not yet supported");
     1070                return ENOTSUP;
     1071        }
     1072
    10291073        /* Create the session context */
    10301074        CHECK_GNUTLS_DO( gnutls_init (session, mode), return ENOMEM );
     
    10661110       
    10671111        /* Trace the session information -- http://www.gnu.org/software/gnutls/manual/gnutls.html#Obtaining-session-information */
    1068         if (verbose && TRACE_BOOL(FULL)) {
     1112        #ifdef DEBUG
     1113        if (verbose) {
    10691114                const char *tmp;
    10701115                gnutls_kx_algorithm_t kx;
    10711116                gnutls_credentials_type_t cred;
    10721117               
    1073                 fd_log_debug("TLS Session information for connection '%s':", conn->cc_id);
     1118                LOG_A("TLS Session information for connection '%s':", conn->cc_id);
    10741119
    10751120                /* print the key exchange's algorithm name */
    10761121                GNUTLS_TRACE( kx = gnutls_kx_get (session) );
    10771122                GNUTLS_TRACE( tmp = gnutls_kx_get_name (kx) );
    1078                 fd_log_debug("\t - Key Exchange: %s", tmp);
     1123                LOG_A("\t - Key Exchange: %s", tmp);
    10791124
    10801125                /* Check the authentication type used and switch
     
    10841129                {
    10851130                        case GNUTLS_CRD_IA:
    1086                                 fd_log_debug("\t - TLS/IA session");
     1131                                LOG_A("\t - TLS/IA session");
    10871132                                break;
    10881133
     
    10901135                                /* This returns NULL in server side. */
    10911136                                if (gnutls_psk_client_get_hint (session) != NULL)
    1092                                         fd_log_debug("\t - PSK authentication. PSK hint '%s'",
     1137                                        LOG_A("\t - PSK authentication. PSK hint '%s'",
    10931138                                                gnutls_psk_client_get_hint (session));
    10941139                                /* This returns NULL in client side. */
    10951140                                if (gnutls_psk_server_get_username (session) != NULL)
    1096                                         fd_log_debug("\t - PSK authentication. Connected as '%s'",
     1141                                        LOG_A("\t - PSK authentication. Connected as '%s'",
    10971142                                                gnutls_psk_server_get_username (session));
    10981143                                break;
    10991144
    11001145                        case GNUTLS_CRD_ANON:   /* anonymous authentication */
    1101                                 fd_log_debug("\t - Anonymous DH using prime of %d bits",
     1146                                LOG_A("\t - Anonymous DH using prime of %d bits",
    11021147                                        gnutls_dh_get_prime_bits (session));
    11031148                                break;
     
    11061151                                /* Check if we have been using ephemeral Diffie-Hellman. */
    11071152                                if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) {
    1108                                         fd_log_debug("\t - Ephemeral DH using prime of %d bits",
     1153                                        LOG_A("\t - Ephemeral DH using prime of %d bits",
    11091154                                                gnutls_dh_get_prime_bits (session));
    11101155                                }
     
    11121157#ifdef ENABLE_SRP                               
    11131158                        case GNUTLS_CRD_SRP:
    1114                                 fd_log_debug("\t - SRP session with username %s",
     1159                                LOG_A("\t - SRP session with username %s",
    11151160                                        gnutls_srp_server_get_username (session));
    11161161                                break;
     
    11251170                /* print the protocol's name (ie TLS 1.0) */
    11261171                tmp = gnutls_protocol_get_name (gnutls_protocol_get_version (session));
    1127                 fd_log_debug("\t - Protocol: %s", tmp);
     1172                LOG_A("\t - Protocol: %s", tmp);
    11281173
    11291174                /* print the certificate type of the peer. ie X.509 */
    11301175                tmp = gnutls_certificate_type_get_name (gnutls_certificate_type_get (session));
    1131                 fd_log_debug("\t - Certificate Type: %s", tmp);
     1176                LOG_A("\t - Certificate Type: %s", tmp);
    11321177
    11331178                /* print the compression algorithm (if any) */
    11341179                tmp = gnutls_compression_get_name (gnutls_compression_get (session));
    1135                 fd_log_debug("\t - Compression: %s", tmp);
     1180                LOG_A("\t - Compression: %s", tmp);
    11361181
    11371182                /* print the name of the cipher used. ie 3DES. */
    11381183                tmp = gnutls_cipher_get_name (gnutls_cipher_get (session));
    1139                 fd_log_debug("\t - Cipher: %s", tmp);
     1184                LOG_A("\t - Cipher: %s", tmp);
    11401185
    11411186                /* Print the MAC algorithms name. ie SHA1 */
    11421187                tmp = gnutls_mac_get_name (gnutls_mac_get (session));
    1143                 fd_log_debug("\t - MAC: %s", tmp);
    1144         }
     1188                LOG_A("\t - MAC: %s", tmp);
     1189        }
     1190        #endif /* DEBUG */
    11451191       
    11461192        /* First, use built-in verification */
     
    11731219        now = time(NULL);
    11741220       
    1175         if (verbose && TRACE_BOOL(FULL)) {
     1221        #ifdef DEBUG
    11761222                char serial[40];
    11771223                char dn[128];
     
    11801226                time_t expiration_time, activation_time;
    11811227               
    1182                 fd_log_debug("TLS Certificate information for connection '%s' (%d certs provided):", conn->cc_id, cert_list_size);
     1228                LOG_D("TLS Certificate information for connection '%s' (%d certs provided):", conn->cc_id, cert_list_size);
    11831229                for (i = 0; i < cert_list_size; i++)
    11841230                {
     
    11871233                        CHECK_GNUTLS_DO( gnutls_x509_crt_import (cert, &cert_list[i], GNUTLS_X509_FMT_DER), return EINVAL);
    11881234               
    1189                         fd_log_debug(" Certificate %d info:", i);
     1235                        LOG_A(" Certificate %d info:", i);
    11901236
    11911237                        GNUTLS_TRACE( expiration_time = gnutls_x509_crt_get_expiration_time (cert) );
    11921238                        GNUTLS_TRACE( activation_time = gnutls_x509_crt_get_activation_time (cert) );
    11931239
    1194                         fd_log_debug("\t - Certificate is valid since: %s", ctime (&activation_time));
    1195                         fd_log_debug("\t - Certificate expires: %s", ctime (&expiration_time));
     1240                        LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "\t - Certificate is valid since: %.24s", ctime (&activation_time));
     1241                        LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "\t - Certificate expires: %.24s", ctime (&expiration_time));
    11961242
    11971243                        /* Print the serial number of the certificate. */
     
    12061252                                        snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%02hhx", serial[j]);
    12071253                                }
    1208                                 fd_log_debug("%s", buf);
     1254                                LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "%s", buf);
    12091255                        }
    12101256
    12111257                        /* Extract some of the public key algorithm's parameters */
    12121258                        GNUTLS_TRACE( algo = gnutls_x509_crt_get_pk_algorithm (cert, &bits) );
    1213                         fd_log_debug("\t - Certificate public key: %s",
     1259                        LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "\t - Certificate public key: %s",
    12141260                              gnutls_pk_algorithm_get_name (algo));
    12151261
    12161262                        /* Print the version of the X.509 certificate. */
    1217                         fd_log_debug("\t - Certificate version: #%d",
     1263                        LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "\t - Certificate version: #%d",
    12181264                              gnutls_x509_crt_get_version (cert));
    12191265
    12201266                        size = sizeof (dn);
    12211267                        GNUTLS_TRACE( gnutls_x509_crt_get_dn (cert, dn, &size) );
    1222                         fd_log_debug("\t - DN: %s", dn);
     1268                        LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "\t - DN: %s", dn);
    12231269
    12241270                        size = sizeof (dn);
    12251271                        GNUTLS_TRACE( gnutls_x509_crt_get_issuer_dn (cert, dn, &size) );
    1226                         fd_log_debug("\t - Issuer's DN: %s", dn);
     1272                        LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "\t - Issuer's DN: %s", dn);
    12271273
    12281274                        GNUTLS_TRACE( gnutls_x509_crt_deinit (cert) );
    12291275                }
    1230         }
     1276        #endif /* DEBUG */
    12311277
    12321278        /* Check validity of all the certificates */
     
    12911337       
    12921338        /* Trace the session information -- http://www.gnu.org/software/gnutls/manual/gnutls.html#Obtaining-session-information */
    1293         if (TRACE_BOOL(FULL)) {
     1339#ifdef DEBUG
    12941340                const char *tmp;
    12951341                gnutls_credentials_type_t cred;
     
    12991345                dhe = ecdh = 0;
    13001346
    1301                 fd_log_debug("TLS Session information for connection '%s':", conn->cc_id);
     1347                LOG_A("TLS Session information for connection '%s':", conn->cc_id);
    13021348               
    13031349                /* print the key exchange's algorithm name
     
    13051351                GNUTLS_TRACE( kx = gnutls_kx_get (session) );
    13061352                GNUTLS_TRACE( tmp = gnutls_kx_get_name (kx) );
    1307                 fd_log_debug("\t- Key Exchange: %s", tmp);
     1353                LOG_A("\t- Key Exchange: %s", tmp);
    13081354
    13091355                /* Check the authentication type used and switch
     
    13141360                {
    13151361                        case GNUTLS_CRD_IA:
    1316                                 fd_log_debug("\t - TLS/IA session");
     1362                                LOG_A("\t - TLS/IA session");
    13171363                                break;
    13181364
     
    13201366                        #ifdef ENABLE_SRP
    13211367                        case GNUTLS_CRD_SRP:
    1322                                 fd_log_debug("\t - SRP session with username %s",
     1368                                LOG_A("\t - SRP session with username %s",
    13231369                                        gnutls_srp_server_get_username (session));
    13241370                                break;
     
    13291375                                */
    13301376                                if (gnutls_psk_client_get_hint (session) != NULL)
    1331                                         fd_log_debug("\t - PSK authentication. PSK hint '%s'",
     1377                                        LOG_A("\t - PSK authentication. PSK hint '%s'",
    13321378                                                gnutls_psk_client_get_hint (session));
    13331379                                /* This returns NULL in client side.
    13341380                                */
    13351381                                if (gnutls_psk_server_get_username (session) != NULL)
    1336                                         fd_log_debug("\t - PSK authentication. Connected as '%s'",
     1382                                        LOG_A("\t - PSK authentication. Connected as '%s'",
    13371383                                                gnutls_psk_server_get_username (session));
    13381384
     
    13441390
    13451391                        case GNUTLS_CRD_ANON:      /* anonymous authentication */
    1346                                 fd_log_debug("\t - Anonymous DH using prime of %d bits",
     1392                                LOG_A("\t - Anonymous DH using prime of %d bits",
    13471393                                        gnutls_dh_get_prime_bits (session));
    13481394                                if (kx == GNUTLS_KX_ANON_ECDH)
     
    13671413                                        cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
    13681414
    1369                                         fd_log_debug("\t Peer provided %d certificates.", cert_list_size);
     1415                                        LOG_A("\t Peer provided %d certificates.", cert_list_size);
    13701416
    13711417                                        if (cert_list_size > 0)
     
    13791425                                                gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER);
    13801426
    1381                                                 fd_log_debug("\t Certificate info:");
     1427                                                                                                LOG_A("\t Certificate info:");
    13821428
    13831429                                                /* This is the preferred way of printing short information about
     
    13871433                                                if (ret == 0)
    13881434                                                {
    1389                                                   fd_log_debug("\t\t%s", cinfo.data);
     1435                                                  LOG_A("\t\t%s", cinfo.data);
    13901436                                                  gnutls_free (cinfo.data);
    13911437                                                }
     
    14101456
    14111457                        default:
    1412                                 fd_log_debug("\t - unknown session type (%d)", cred);
     1458                                LOG_A("\t - unknown session type (%d)", cred);
    14131459
    14141460                }                           /* switch */
    14151461
    14161462                if (ecdh != 0)
    1417                         fd_log_debug("\t - Ephemeral ECDH using curve %s",
     1463                        LOG_A("\t - Ephemeral ECDH using curve %s",
    14181464                                gnutls_ecc_curve_get_name (gnutls_ecc_curve_get (session)));
    14191465                else if (dhe != 0)
    1420                         fd_log_debug("\t - Ephemeral DH using prime of %d bits",
     1466                        LOG_A("\t - Ephemeral DH using prime of %d bits",
    14211467                                gnutls_dh_get_prime_bits (session));
    14221468
     
    14241470                */
    14251471                tmp = gnutls_protocol_get_name (gnutls_protocol_get_version (session));
    1426                 fd_log_debug("\t - Protocol: %s", tmp);
     1472                LOG_A("\t - Protocol: %s", tmp);
    14271473
    14281474                /* print the certificate type of the peer.
     
    14301476                */
    14311477                tmp = gnutls_certificate_type_get_name (gnutls_certificate_type_get (session));
    1432                 fd_log_debug("\t - Certificate Type: %s", tmp);
     1478                LOG_A("\t - Certificate Type: %s", tmp);
    14331479
    14341480                /* print the compression algorithm (if any)
    14351481                */
    14361482                tmp = gnutls_compression_get_name (gnutls_compression_get (session));
    1437                 fd_log_debug("\t - Compression: %s", tmp);
     1483                LOG_A("\t - Compression: %s", tmp);
    14381484
    14391485                /* print the name of the cipher used.
     
    14411487                */
    14421488                tmp = gnutls_cipher_get_name (gnutls_cipher_get (session));
    1443                 fd_log_debug("\t - Cipher: %s", tmp);
     1489                LOG_A("\t - Cipher: %s", tmp);
    14441490
    14451491                /* Print the MAC algorithms name.
     
    14471493                */
    14481494                tmp = gnutls_mac_get_name (gnutls_mac_get (session));
    1449                 fd_log_debug("\t - MAC: %s", tmp);
    1450        
    1451         }
     1495                LOG_A("\t - MAC: %s", tmp);
     1496       
     1497#endif /* DEBUG */             
    14521498
    14531499        /* This verification function uses the trusted CAs in the credentials
     
    15091555#endif /* GNUTLS_VERSION_300 */
    15101556
     1557static int fd_cnx_may_dtls(struct cnxctx * conn) {
     1558#ifndef DISABLE_SCTP
     1559        if ((conn->cc_proto == IPPROTO_SCTP) && (conn->cc_tls_para.algo == ALGO_HANDSHAKE_DEFAULT))
     1560                return 1;
     1561#endif /* DISABLE_SCTP */
     1562        return 0;
     1563}
     1564
     1565static int fd_cnx_uses_dtls(struct cnxctx * conn) {
     1566        return fd_cnx_may_dtls(conn) && (fd_cnx_teststate(conn, CC_STATUS_TLS));
     1567}
     1568
    15111569/* TLS handshake a connection; no need to have called start_clear before. Reception is active if handhsake is successful */
    1512 int fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority, void * alt_creds)
    1513 {
    1514         TRACE_ENTRY( "%p %d %p %p", conn, mode, priority, alt_creds);
     1570int fd_cnx_handshake(struct cnxctx * conn, int mode, int algo, char * priority, void * alt_creds)
     1571{
     1572        int dtls = 0;
     1573       
     1574        TRACE_ENTRY( "%p %d %d %p %p", conn, mode, algo, priority, alt_creds);
    15151575        CHECK_PARAMS( conn && (!fd_cnx_teststate(conn, CC_STATUS_TLS)) && ( (mode == GNUTLS_CLIENT) || (mode == GNUTLS_SERVER) ) && (!conn->cc_loop) );
    15161576
    15171577        /* Save the mode */
    15181578        conn->cc_tls_para.mode = mode;
     1579        conn->cc_tls_para.algo = algo;
    15191580       
    15201581        /* Cancel receiving thread if any -- it should already be terminated anyway, we just release the resources */
     
    15241585        conn->cc_loop = 1;
    15251586       
     1587        dtls = fd_cnx_may_dtls(conn);
     1588       
    15261589        /* Prepare the master session credentials and priority */
    1527         CHECK_FCT( fd_tls_prepare(&conn->cc_tls_para.session, mode, priority, alt_creds) );
     1590        CHECK_FCT( fd_tls_prepare(&conn->cc_tls_para.session, mode, dtls, priority, alt_creds) );
    15281591
    15291592        /* Special case: multi-stream TLS is not natively managed in GNU TLS, we use a wrapper library */
    1530         if (conn->cc_sctp_para.pairs > 1) {
     1593        if ((!dtls) && (conn->cc_sctp_para.pairs > 1)) {
    15311594#ifdef DISABLE_SCTP
    15321595                ASSERT(0);
     
    15411604
    15421605                /* Set the push and pull callbacks */
    1543                 GNUTLS_TRACE( gnutls_transport_set_pull_function(conn->cc_tls_para.session, (void *)fd_cnx_s_recv) );
    1544                 GNUTLS_TRACE( gnutls_transport_set_push_function(conn->cc_tls_para.session, (void *)fd_cnx_s_send) );
     1606                if (!dtls) {
     1607                        GNUTLS_TRACE( gnutls_transport_set_pull_function(conn->cc_tls_para.session, (void *)fd_cnx_s_recv) );
     1608                        GNUTLS_TRACE( gnutls_transport_set_push_function(conn->cc_tls_para.session, (void *)fd_cnx_s_send) );
     1609                } else {
     1610                        TODO("DTLS push/pull functions");
     1611                        return ENOTSUP;
     1612                }
    15451613        }
    15461614       
     
    15891657                #endif /* GNUTLS_VERSION_300 */
    15901658        }
    1591 
     1659       
    15921660        /* Multi-stream TLS: handshake other streams as well */
    1593         if (conn->cc_sctp_para.pairs > 1) {
     1661        if ((!dtls) && (conn->cc_sctp_para.pairs > 1)) {
    15941662#ifndef DISABLE_SCTP
    15951663                /* Start reading the messages from the master session. That way, if the remote peer closed, we are not stuck inside handshake */
     
    16041672        } else {
    16051673                /* Start decrypting the data */
    1606                 CHECK_POSIX( pthread_create( &conn->cc_rcvthr, NULL, rcvthr_tls_single, conn ) );
     1674                if (!dtls) {
     1675                        CHECK_POSIX( pthread_create( &conn->cc_rcvthr, NULL, rcvthr_tls_single, conn ) );
     1676                } else {
     1677                        TODO("Signal the dtls_push function that multiple streams can be used from this point.");
     1678                        TODO("Create DTLS rcvthr (must reassembly based on seq numbers & stream id ?)");
     1679                        return ENOTSUP;
     1680                }
    16071681        }
    16081682       
     
    17371811#ifndef DISABLE_SCTP
    17381812                case IPPROTO_SCTP: {
    1739                         if (flags & FD_CNX_ORDERED) {
    1740                                 /* We send over stream #0 */
    1741                                 CHECK_FCT( send_simple(conn, buf, len) );
    1742                         } else {
    1743                                 /* Default case : no flag specified */
    1744                        
    1745                                 int another_str = 0; /* do we send over stream #0 ? */
    1746                                
    1747                                 if ((conn->cc_sctp_para.str_out > 1) && ((!fd_cnx_teststate(conn, CC_STATUS_TLS)) || (conn->cc_sctp_para.pairs > 1)))  {
    1748                                         /* Update the id of the stream we will send this message over */
    1749                                         conn->cc_sctp_para.next += 1;
    1750                                         conn->cc_sctp_para.next %= (fd_cnx_teststate(conn, CC_STATUS_TLS) ? conn->cc_sctp_para.pairs : conn->cc_sctp_para.str_out);
    1751                                         another_str = (conn->cc_sctp_para.next ? 1 : 0);
    1752                                 }
    1753 
    1754                                 if ( ! another_str ) {
     1813                        int dtls = fd_cnx_uses_dtls(conn);
     1814
     1815                        if (!dtls) {
     1816                                if (flags & FD_CNX_ORDERED) {
     1817                                        /* We send over stream #0 */
    17551818                                        CHECK_FCT( send_simple(conn, buf, len) );
    17561819                                } else {
    1757                                         if (!fd_cnx_teststate(conn, CC_STATUS_TLS)) {
    1758                                                 CHECK_FCT_DO( fd_sctp_sendstr(conn, conn->cc_sctp_para.next, buf, len), { fd_cnx_markerror(conn); return ENOTCONN; } );
     1820                                        /* Default case : no flag specified */
     1821                       
     1822                                        int another_str = 0; /* do we send over stream #0 ? */
     1823
     1824                                        if ((conn->cc_sctp_para.str_out > 1) && ((!fd_cnx_teststate(conn, CC_STATUS_TLS)) || (conn->cc_sctp_para.pairs > 1)))  {
     1825                                                /* Update the id of the stream we will send this message over */
     1826                                                conn->cc_sctp_para.next += 1;
     1827                                                conn->cc_sctp_para.next %= (fd_cnx_teststate(conn, CC_STATUS_TLS) ? conn->cc_sctp_para.pairs : conn->cc_sctp_para.str_out);
     1828                                                another_str = (conn->cc_sctp_para.next ? 1 : 0);
     1829                                        }
     1830
     1831                                        if ( ! another_str ) {
     1832                                                CHECK_FCT( send_simple(conn, buf, len) );
    17591833                                        } else {
    1760                                                 /* push the record to the appropriate session */
    1761                                                 ssize_t ret;
    1762                                                 size_t sent = 0;
    1763                                                 ASSERT(conn->cc_sctp3436_data.array != NULL);
    1764                                                 do {
    1765                                                         CHECK_GNUTLS_DO( ret = fd_tls_send_handle_error(conn, conn->cc_sctp3436_data.array[conn->cc_sctp_para.next].session, buf + sent, len - sent), );
    1766                                                         if (ret <= 0)
    1767                                                                 return ENOTCONN;
    1768 
    1769                                                         sent += ret;
    1770                                                 } while ( sent < len );
     1834                                                if (!fd_cnx_teststate(conn, CC_STATUS_TLS)) {
     1835                                                        CHECK_FCT_DO( fd_sctp_sendstr(conn, conn->cc_sctp_para.next, buf, len), { fd_cnx_markerror(conn); return ENOTCONN; } );
     1836                                                } else {
     1837                                                        /* push the record to the appropriate session */
     1838                                                        ssize_t ret;
     1839                                                        size_t sent = 0;
     1840                                                        ASSERT(conn->cc_sctp3436_data.array != NULL);
     1841                                                        do {
     1842                                                                CHECK_GNUTLS_DO( ret = fd_tls_send_handle_error(conn, conn->cc_sctp3436_data.array[conn->cc_sctp_para.next].session, buf + sent, len - sent), );
     1843                                                                if (ret <= 0)
     1844                                                                        return ENOTCONN;
     1845
     1846                                                                sent += ret;
     1847                                                        } while ( sent < len );
     1848                                                }
    17711849                                        }
    17721850                                }
     1851                        } else {
     1852                                /* DTLS */
     1853                                /* We signal the push function directly to tell if using stream 0 or round-robin */
     1854                                TODO("DTLS send");
     1855                                return ENOTSUP;
    17731856                        }
    17741857                }
     
    18021885        if (fd_cnx_teststate(conn, CC_STATUS_TLS)) {
    18031886#ifndef DISABLE_SCTP
    1804                 if (conn->cc_sctp_para.pairs > 1) {
     1887                int dtls = fd_cnx_uses_dtls(conn);
     1888                if ((!dtls) && (conn->cc_sctp_para.pairs > 1)) {
    18051889                        if (! fd_cnx_teststate(conn, CC_STATUS_ERROR )) {
    18061890                                /* Bye on master session */
  • libfdcore/cnxctx.h

    r1180 r1181  
    4141/* The connection context structure */
    4242struct cnxctx {
    43         char            cc_id[60];      /* The name of this connection */
     43        char            cc_id[60];      /* The name of this connection. the first 5 chars are reserved for flags display (cc_state). */
    4444        char            cc_remid[60];   /* Id of remote peer */
    4545       
     
    6565                DiamId_t                         cn;            /* If not NULL, remote certif will be checked to match this Common Name */
    6666                int                              mode;          /* GNUTLS_CLIENT / GNUTLS_SERVER */
     67                int                              algo;          /* ALGO_HANDSHAKE_DEFAULT / ALGO_HANDSHAKE_3436 */
    6768                gnutls_session_t                 session;       /* Session object (stream #0 in case of SCTP) */
    6869        }               cc_tls_para;
     
    9798/* TLS */
    9899int fd_tls_rcvthr_core(struct cnxctx * conn, gnutls_session_t session);
    99 int fd_tls_prepare(gnutls_session_t * session, int mode, char * priority, void * alt_creds);
     100int fd_tls_prepare(gnutls_session_t * session, int mode, int dtls, char * priority, void * alt_creds);
    100101#ifndef GNUTLS_VERSION_300
    101102int fd_tls_verify_credentials(gnutls_session_t session, struct cnxctx * conn, int verbose);
  • libfdcore/config.c

    r1155 r1181  
    9494        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  Local port ............. : %hu\n", fd_g_config->cnf_port), return NULL);
    9595        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  Local secure port ...... : %hu\n", fd_g_config->cnf_port_tls), return NULL);
     96        if (fd_g_config->cnf_port_3436) {
     97                CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  Local SCTP TLS port .... : %hu\n", fd_g_config->cnf_port_3436), return NULL);
     98        }
    9699        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  Number of SCTP streams . : %hu\n", fd_g_config->cnf_sctp_str), return NULL);
    97100        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  Number of server threads : %hu\n", fd_g_config->cnf_dispthr), return NULL);
  • libfdcore/fdcore-internal.h

    r1102 r1181  
    342342int             fd_cnx_start_clear(struct cnxctx * conn, int loop);
    343343void            fd_cnx_sethostname(struct cnxctx * conn, DiamId_t hn);
    344 int             fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority, void * alt_creds);
     344#define ALGO_HANDSHAKE_DEFAULT  0 /* TLS for TCP, DTLS for SCTP */
     345#define ALGO_HANDSHAKE_3436     1 /* For TLS for SCTP also */
     346int             fd_cnx_handshake(struct cnxctx * conn, int mode, int algo, char * priority, void * alt_creds);
    345347char *          fd_cnx_getid(struct cnxctx * conn);
    346348int             fd_cnx_getproto(struct cnxctx * conn);
  • libfdcore/p_ce.c

    r1155 r1181  
    786786                } else {
    787787                        fd_psm_change_state(peer, STATE_OPEN_HANDSHAKE);
    788                         CHECK_FCT_DO( fd_cnx_handshake(peer->p_cnxctx, GNUTLS_CLIENT, peer->p_hdr.info.config.pic_priority, NULL),
     788                        CHECK_FCT_DO( fd_cnx_handshake(peer->p_cnxctx, GNUTLS_CLIENT, ALGO_HANDSHAKE_3436, peer->p_hdr.info.config.pic_priority, NULL),
    789789                                {
    790790                                        /* Handshake failed ...  */
     
    955955        if (isi & PI_SEC_TLS_OLD) {
    956956                fd_psm_change_state(peer, STATE_OPEN_HANDSHAKE);
    957                 CHECK_FCT_DO( fd_cnx_handshake(peer->p_cnxctx, GNUTLS_SERVER, peer->p_hdr.info.config.pic_priority, NULL),
     957                CHECK_FCT_DO( fd_cnx_handshake(peer->p_cnxctx, GNUTLS_SERVER, ALGO_HANDSHAKE_3436, peer->p_hdr.info.config.pic_priority, NULL),
    958958                        {
    959959                                /* Handshake failed ...  */
  • libfdcore/p_cnx.c

    r1155 r1181  
    282282        /* Handshake if needed (secure port) */
    283283        if (nc->dotls) {
    284                 CHECK_FCT_DO( fd_cnx_handshake(cnx, GNUTLS_CLIENT, peer->p_hdr.info.config.pic_priority, NULL),
     284                CHECK_FCT_DO( fd_cnx_handshake(cnx, GNUTLS_CLIENT,
     285                                                (peer->p_hdr.info.config.pic_flags.sctpsec == PI_SCTPSEC_3436) ? ALGO_HANDSHAKE_3436 : ALGO_HANDSHAKE_DEFAULT,
     286                                                peer->p_hdr.info.config.pic_priority, NULL),
    285287                        {
    286288                                /* Handshake failed ...  */
  • libfdcore/p_psm.c

    r1120 r1181  
    785785                        case STATE_WAITCNXACK_ELEC:
    786786                        case STATE_WAITCNXACK:
    787                                 LOG_D("%s: Connection established", peer->p_hdr.info.pi_diamid);
     787                                LOG_D("%s: Connection established, %s", peer->p_hdr.info.pi_diamid, fd_cnx_getid(cnx));
    788788                                fd_p_ce_handle_newcnx(peer, cnx);
    789789                                break;
  • libfdcore/peers.c

    r1113 r1181  
    430430                }
    431431                if (details > 1) {
    432                         CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " [from:%s] flags:%s%s%s%s%s%s%s lft:%ds",
     432                        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " [from:%s] flags:%s%s%s%s%s%s%s%s lft:%ds",
    433433                                peer->p_dbgorig ?: "unset",
    434434                                peer->p_hdr.info.config.pic_flags.pro3 == PI_P3_DEFAULT ? "-" :
     
    439439                                peer->p_hdr.info.config.pic_flags.sec & PI_SEC_NONE ? "N" :"-",
    440440                                peer->p_hdr.info.config.pic_flags.sec & PI_SEC_TLS_OLD ? "O" :"-",
     441                                peer->p_hdr.info.config.pic_flags.sctpsec & PI_SCTPSEC_3436 ? "3" :"-",
    441442                                peer->p_hdr.info.config.pic_flags.exp ? "E" : "-",
    442443                                peer->p_hdr.info.config.pic_flags.persist ? "P" : "-",
  • libfdcore/sctp3436.c

    r1180 r1181  
    566566        for (i = 1; i < conn->cc_sctp_para.pairs; i++) {
    567567                /* Set credentials and priority */
    568                 CHECK_FCT( fd_tls_prepare(&conn->cc_sctp3436_data.array[i].session, conn->cc_tls_para.mode, priority, alt_creds) );
     568                CHECK_FCT( fd_tls_prepare(&conn->cc_sctp3436_data.array[i].session, conn->cc_tls_para.mode, 0, priority, alt_creds) );
    569569               
    570570                /* additional initialization for gnutls 3.x */
  • libfdcore/server.c

    r1136 r1181  
    5454        struct cnxctx * conn;           /* server connection context (listening socket) */
    5555        int             proto;          /* IPPROTO_TCP or IPPROTO_SCTP */
    56         int             secur;          /* TLS is started immediatly after connection ? */
     56        int             secur;          /* TLS is started immediatly after connection ? 0: no; 1: yes (TLS/TCP or DTLS/SCTP); 2: yes (TLS/TCP or TLS/SCTP) */
    5757       
    5858        pthread_t       thr;            /* The thread listening for new connections */
     
    105105               
    106106                if (details) {
    107                         CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{server}(@%p)'%s': %s, %s, %s", s, fd_cnx_getid(s->conn),
     107                        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{server}(@%p)'%s': %s, %s(%d), %s", s, fd_cnx_getid(s->conn),
    108108                                        IPPROTO_NAME( s->proto ),
    109                                         s->secur ? "Secur" : "NotSecur",
     109                                        s->secur ? "Secur" : "NotSecur", s->secur,
    110110                                        (st == NOT_CREATED) ? "Thread not created" :
    111111                                        ((st == RUNNING) ? "Thread running" :
     
    147147        TRACE_ENTRY("%p", c);
    148148       
     149        memset(&rcv_data, 0, sizeof(rcv_data));
     150       
    149151        CHECK_PARAMS_DO(c && c->conn && c->chain.head, goto fatal_error );
     152       
    150153       
    151154        s = c->chain.head->o;
     
    156159        /* Handshake if we are a secure server port, or start clear otherwise */
    157160        if (s->secur) {
    158                 int ret = fd_cnx_handshake(c->conn, GNUTLS_SERVER, NULL, NULL);
     161                int ret = fd_cnx_handshake(c->conn, GNUTLS_SERVER, (s->secur == 1) ? ALGO_HANDSHAKE_DEFAULT : ALGO_HANDSHAKE_3436, NULL, NULL);
    159162                if (ret != 0) {
    160163                        char buf[1024];
     
    360363                        CHECK_MALLOC( s = new_serv(IPPROTO_SCTP, 1) );
    361364                        CHECK_MALLOC( s->conn = fd_cnx_serv_sctp(fd_g_config->cnf_port_tls, empty_conf_ep ? NULL : &fd_g_config->cnf_endpoints) );
     365                        fd_list_insert_before( &FD_SERVERS, &s->chain );
     366                        CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) );
     367                }
     368               
     369                /* Create the other server on 3436 secure port */
     370                if (fd_g_config->cnf_port_3436) {
     371                        CHECK_MALLOC( s = new_serv(IPPROTO_SCTP, 2) );
     372                        CHECK_MALLOC( s->conn = fd_cnx_serv_sctp(fd_g_config->cnf_port_3436, empty_conf_ep ? NULL : &fd_g_config->cnf_endpoints) );
    362373                        fd_list_insert_before( &FD_SERVERS, &s->chain );
    363374                        CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) );
Note: See TracChangeset for help on using the changeset viewer.