Changeset 1181:22de21feec64 in freeDiameter for libfdcore
- Timestamp:
- Jun 5, 2013, 8:22:26 PM (11 years ago)
- Branch:
- default
- Phase:
- public
- Location:
- libfdcore
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
libfdcore/cnxctx.c
r1180 r1181 96 96 } 97 97 98 #define CC_ID_HDR "{----} " 99 98 100 /* Create and bind a server socket to the given endpoint and port */ 99 101 struct cnxctx * fd_cnx_serv_tcp(uint16_t port, int family, struct fd_endpoint * ep) … … 139 141 if (rc) 140 142 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); 142 144 } 143 145 … … 179 181 180 182 /* 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); 182 184 183 185 cnx->cc_proto = IPPROTO_SCTP; … … 249 251 250 252 /* 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)", 252 254 IPPROTO_NAME(cli->cc_proto), addrbuf, portbuf, serv->cc_socket, cli->cc_socket); 253 255 … … 313 315 int rc; 314 316 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); 316 318 317 319 /* ...Name for log messages */ … … 376 378 int rc; 377 379 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); 379 381 380 382 /* ...Name for log messages */ … … 433 435 return st & flag; 434 436 } 437 void 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 } 435 458 void fd_cnx_addstate(struct cnxctx * conn, uint32_t orstate) 436 459 { 437 460 CHECK_POSIX_DO( pthread_mutex_lock(&state_lock), { ASSERT(0); } ); 438 461 conn->cc_state |= orstate; 462 fd_cnx_update_id(conn); 439 463 CHECK_POSIX_DO( pthread_mutex_unlock(&state_lock), { ASSERT(0); } ); 440 464 } … … 443 467 CHECK_POSIX_DO( pthread_mutex_lock(&state_lock), { ASSERT(0); } ); 444 468 conn->cc_state = abstate; 469 fd_cnx_update_id(conn); 445 470 CHECK_POSIX_DO( pthread_mutex_unlock(&state_lock), { ASSERT(0); } ); 446 471 } … … 659 684 } 660 685 661 #ifndef DISABLE_SCTP 686 #ifndef DISABLE_SCTP /* WE use this function only in SCTP code */ 662 687 static uint8_t * fd_cnx_realloc_msg_buffer(uint8_t * buffer, size_t expected_len, struct fd_msg_pmdl ** pmdl) 663 688 { … … 853 878 854 879 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. */ 856 881 static ssize_t fd_tls_recv_handle_error(struct cnxctx * conn, gnutls_session_t session, void * data, size_t sz) 857 882 { 858 883 ssize_t ret; 859 884 again: 860 CHECK_GNUTLS_DO( ret = gnutls_record_recv(session, data, sz), 885 CHECK_GNUTLS_DO( ret = gnutls_record_recv(session, data, sz), 861 886 { 862 887 switch (ret) { … … 885 910 886 911 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)); 888 917 } 889 918 } ); … … 898 927 } 899 928 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 */ 901 930 static ssize_t fd_tls_send_handle_error(struct cnxctx * conn, gnutls_session_t session, void * data, size_t sz) 902 931 { … … 925 954 926 955 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)); 928 961 } 929 962 } ); … … 937 970 938 971 /* 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. */ 939 978 int fd_tls_rcvthr_core(struct cnxctx * conn, gnutls_session_t session) 940 979 { 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. */ 942 981 do { 943 982 uint8_t header[4]; … … 1025 1064 1026 1065 /* Prepare a gnutls session object for handshake */ 1027 int fd_tls_prepare(gnutls_session_t * session, int mode, char * priority, void * alt_creds) 1028 { 1066 int 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 1029 1073 /* Create the session context */ 1030 1074 CHECK_GNUTLS_DO( gnutls_init (session, mode), return ENOMEM ); … … 1066 1110 1067 1111 /* 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) { 1069 1114 const char *tmp; 1070 1115 gnutls_kx_algorithm_t kx; 1071 1116 gnutls_credentials_type_t cred; 1072 1117 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); 1074 1119 1075 1120 /* print the key exchange's algorithm name */ 1076 1121 GNUTLS_TRACE( kx = gnutls_kx_get (session) ); 1077 1122 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); 1079 1124 1080 1125 /* Check the authentication type used and switch … … 1084 1129 { 1085 1130 case GNUTLS_CRD_IA: 1086 fd_log_debug("\t - TLS/IA session");1131 LOG_A("\t - TLS/IA session"); 1087 1132 break; 1088 1133 … … 1090 1135 /* This returns NULL in server side. */ 1091 1136 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'", 1093 1138 gnutls_psk_client_get_hint (session)); 1094 1139 /* This returns NULL in client side. */ 1095 1140 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'", 1097 1142 gnutls_psk_server_get_username (session)); 1098 1143 break; 1099 1144 1100 1145 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", 1102 1147 gnutls_dh_get_prime_bits (session)); 1103 1148 break; … … 1106 1151 /* Check if we have been using ephemeral Diffie-Hellman. */ 1107 1152 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", 1109 1154 gnutls_dh_get_prime_bits (session)); 1110 1155 } … … 1112 1157 #ifdef ENABLE_SRP 1113 1158 case GNUTLS_CRD_SRP: 1114 fd_log_debug("\t - SRP session with username %s",1159 LOG_A("\t - SRP session with username %s", 1115 1160 gnutls_srp_server_get_username (session)); 1116 1161 break; … … 1125 1170 /* print the protocol's name (ie TLS 1.0) */ 1126 1171 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); 1128 1173 1129 1174 /* print the certificate type of the peer. ie X.509 */ 1130 1175 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); 1132 1177 1133 1178 /* print the compression algorithm (if any) */ 1134 1179 tmp = gnutls_compression_get_name (gnutls_compression_get (session)); 1135 fd_log_debug("\t - Compression: %s", tmp);1180 LOG_A("\t - Compression: %s", tmp); 1136 1181 1137 1182 /* print the name of the cipher used. ie 3DES. */ 1138 1183 tmp = gnutls_cipher_get_name (gnutls_cipher_get (session)); 1139 fd_log_debug("\t - Cipher: %s", tmp);1184 LOG_A("\t - Cipher: %s", tmp); 1140 1185 1141 1186 /* Print the MAC algorithms name. ie SHA1 */ 1142 1187 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 */ 1145 1191 1146 1192 /* First, use built-in verification */ … … 1173 1219 now = time(NULL); 1174 1220 1175 if (verbose && TRACE_BOOL(FULL)) {1221 #ifdef DEBUG 1176 1222 char serial[40]; 1177 1223 char dn[128]; … … 1180 1226 time_t expiration_time, activation_time; 1181 1227 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); 1183 1229 for (i = 0; i < cert_list_size; i++) 1184 1230 { … … 1187 1233 CHECK_GNUTLS_DO( gnutls_x509_crt_import (cert, &cert_list[i], GNUTLS_X509_FMT_DER), return EINVAL); 1188 1234 1189 fd_log_debug(" Certificate %d info:", i);1235 LOG_A(" Certificate %d info:", i); 1190 1236 1191 1237 GNUTLS_TRACE( expiration_time = gnutls_x509_crt_get_expiration_time (cert) ); 1192 1238 GNUTLS_TRACE( activation_time = gnutls_x509_crt_get_activation_time (cert) ); 1193 1239 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)); 1196 1242 1197 1243 /* Print the serial number of the certificate. */ … … 1206 1252 snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%02hhx", serial[j]); 1207 1253 } 1208 fd_log_debug("%s", buf);1254 LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "%s", buf); 1209 1255 } 1210 1256 1211 1257 /* Extract some of the public key algorithm's parameters */ 1212 1258 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", 1214 1260 gnutls_pk_algorithm_get_name (algo)); 1215 1261 1216 1262 /* 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", 1218 1264 gnutls_x509_crt_get_version (cert)); 1219 1265 1220 1266 size = sizeof (dn); 1221 1267 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); 1223 1269 1224 1270 size = sizeof (dn); 1225 1271 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); 1227 1273 1228 1274 GNUTLS_TRACE( gnutls_x509_crt_deinit (cert) ); 1229 1275 } 1230 }1276 #endif /* DEBUG */ 1231 1277 1232 1278 /* Check validity of all the certificates */ … … 1291 1337 1292 1338 /* Trace the session information -- http://www.gnu.org/software/gnutls/manual/gnutls.html#Obtaining-session-information */ 1293 if (TRACE_BOOL(FULL)) { 1339 #ifdef DEBUG 1294 1340 const char *tmp; 1295 1341 gnutls_credentials_type_t cred; … … 1299 1345 dhe = ecdh = 0; 1300 1346 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); 1302 1348 1303 1349 /* print the key exchange's algorithm name … … 1305 1351 GNUTLS_TRACE( kx = gnutls_kx_get (session) ); 1306 1352 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); 1308 1354 1309 1355 /* Check the authentication type used and switch … … 1314 1360 { 1315 1361 case GNUTLS_CRD_IA: 1316 fd_log_debug("\t - TLS/IA session");1362 LOG_A("\t - TLS/IA session"); 1317 1363 break; 1318 1364 … … 1320 1366 #ifdef ENABLE_SRP 1321 1367 case GNUTLS_CRD_SRP: 1322 fd_log_debug("\t - SRP session with username %s",1368 LOG_A("\t - SRP session with username %s", 1323 1369 gnutls_srp_server_get_username (session)); 1324 1370 break; … … 1329 1375 */ 1330 1376 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'", 1332 1378 gnutls_psk_client_get_hint (session)); 1333 1379 /* This returns NULL in client side. 1334 1380 */ 1335 1381 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'", 1337 1383 gnutls_psk_server_get_username (session)); 1338 1384 … … 1344 1390 1345 1391 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", 1347 1393 gnutls_dh_get_prime_bits (session)); 1348 1394 if (kx == GNUTLS_KX_ANON_ECDH) … … 1367 1413 cert_list = gnutls_certificate_get_peers (session, &cert_list_size); 1368 1414 1369 fd_log_debug("\t Peer provided %d certificates.", cert_list_size);1415 LOG_A("\t Peer provided %d certificates.", cert_list_size); 1370 1416 1371 1417 if (cert_list_size > 0) … … 1379 1425 gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER); 1380 1426 1381 fd_log_debug("\t Certificate info:");1427 LOG_A("\t Certificate info:"); 1382 1428 1383 1429 /* This is the preferred way of printing short information about … … 1387 1433 if (ret == 0) 1388 1434 { 1389 fd_log_debug("\t\t%s", cinfo.data);1435 LOG_A("\t\t%s", cinfo.data); 1390 1436 gnutls_free (cinfo.data); 1391 1437 } … … 1410 1456 1411 1457 default: 1412 fd_log_debug("\t - unknown session type (%d)", cred);1458 LOG_A("\t - unknown session type (%d)", cred); 1413 1459 1414 1460 } /* switch */ 1415 1461 1416 1462 if (ecdh != 0) 1417 fd_log_debug("\t - Ephemeral ECDH using curve %s",1463 LOG_A("\t - Ephemeral ECDH using curve %s", 1418 1464 gnutls_ecc_curve_get_name (gnutls_ecc_curve_get (session))); 1419 1465 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", 1421 1467 gnutls_dh_get_prime_bits (session)); 1422 1468 … … 1424 1470 */ 1425 1471 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); 1427 1473 1428 1474 /* print the certificate type of the peer. … … 1430 1476 */ 1431 1477 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); 1433 1479 1434 1480 /* print the compression algorithm (if any) 1435 1481 */ 1436 1482 tmp = gnutls_compression_get_name (gnutls_compression_get (session)); 1437 fd_log_debug("\t - Compression: %s", tmp);1483 LOG_A("\t - Compression: %s", tmp); 1438 1484 1439 1485 /* print the name of the cipher used. … … 1441 1487 */ 1442 1488 tmp = gnutls_cipher_get_name (gnutls_cipher_get (session)); 1443 fd_log_debug("\t - Cipher: %s", tmp);1489 LOG_A("\t - Cipher: %s", tmp); 1444 1490 1445 1491 /* Print the MAC algorithms name. … … 1447 1493 */ 1448 1494 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 */ 1452 1498 1453 1499 /* This verification function uses the trusted CAs in the credentials … … 1509 1555 #endif /* GNUTLS_VERSION_300 */ 1510 1556 1557 static 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 1565 static int fd_cnx_uses_dtls(struct cnxctx * conn) { 1566 return fd_cnx_may_dtls(conn) && (fd_cnx_teststate(conn, CC_STATUS_TLS)); 1567 } 1568 1511 1569 /* 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); 1570 int 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); 1515 1575 CHECK_PARAMS( conn && (!fd_cnx_teststate(conn, CC_STATUS_TLS)) && ( (mode == GNUTLS_CLIENT) || (mode == GNUTLS_SERVER) ) && (!conn->cc_loop) ); 1516 1576 1517 1577 /* Save the mode */ 1518 1578 conn->cc_tls_para.mode = mode; 1579 conn->cc_tls_para.algo = algo; 1519 1580 1520 1581 /* Cancel receiving thread if any -- it should already be terminated anyway, we just release the resources */ … … 1524 1585 conn->cc_loop = 1; 1525 1586 1587 dtls = fd_cnx_may_dtls(conn); 1588 1526 1589 /* 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) ); 1528 1591 1529 1592 /* 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)) { 1531 1594 #ifdef DISABLE_SCTP 1532 1595 ASSERT(0); … … 1541 1604 1542 1605 /* 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 } 1545 1613 } 1546 1614 … … 1589 1657 #endif /* GNUTLS_VERSION_300 */ 1590 1658 } 1591 1659 1592 1660 /* 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)) { 1594 1662 #ifndef DISABLE_SCTP 1595 1663 /* Start reading the messages from the master session. That way, if the remote peer closed, we are not stuck inside handshake */ … … 1604 1672 } else { 1605 1673 /* 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 } 1607 1681 } 1608 1682 … … 1737 1811 #ifndef DISABLE_SCTP 1738 1812 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 */ 1755 1818 CHECK_FCT( send_simple(conn, buf, len) ); 1756 1819 } 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) ); 1759 1833 } 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 } 1771 1849 } 1772 1850 } 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; 1773 1856 } 1774 1857 } … … 1802 1885 if (fd_cnx_teststate(conn, CC_STATUS_TLS)) { 1803 1886 #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)) { 1805 1889 if (! fd_cnx_teststate(conn, CC_STATUS_ERROR )) { 1806 1890 /* Bye on master session */ -
libfdcore/cnxctx.h
r1180 r1181 41 41 /* The connection context structure */ 42 42 struct 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). */ 44 44 char cc_remid[60]; /* Id of remote peer */ 45 45 … … 65 65 DiamId_t cn; /* If not NULL, remote certif will be checked to match this Common Name */ 66 66 int mode; /* GNUTLS_CLIENT / GNUTLS_SERVER */ 67 int algo; /* ALGO_HANDSHAKE_DEFAULT / ALGO_HANDSHAKE_3436 */ 67 68 gnutls_session_t session; /* Session object (stream #0 in case of SCTP) */ 68 69 } cc_tls_para; … … 97 98 /* TLS */ 98 99 int 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);100 int fd_tls_prepare(gnutls_session_t * session, int mode, int dtls, char * priority, void * alt_creds); 100 101 #ifndef GNUTLS_VERSION_300 101 102 int fd_tls_verify_credentials(gnutls_session_t session, struct cnxctx * conn, int verbose); -
libfdcore/config.c
r1155 r1181 94 94 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local port ............. : %hu\n", fd_g_config->cnf_port), return NULL); 95 95 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 } 96 99 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Number of SCTP streams . : %hu\n", fd_g_config->cnf_sctp_str), return NULL); 97 100 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 342 342 int fd_cnx_start_clear(struct cnxctx * conn, int loop); 343 343 void 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 */ 346 int fd_cnx_handshake(struct cnxctx * conn, int mode, int algo, char * priority, void * alt_creds); 345 347 char * fd_cnx_getid(struct cnxctx * conn); 346 348 int fd_cnx_getproto(struct cnxctx * conn); -
libfdcore/p_ce.c
r1155 r1181 786 786 } else { 787 787 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), 789 789 { 790 790 /* Handshake failed ... */ … … 955 955 if (isi & PI_SEC_TLS_OLD) { 956 956 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), 958 958 { 959 959 /* Handshake failed ... */ -
libfdcore/p_cnx.c
r1155 r1181 282 282 /* Handshake if needed (secure port) */ 283 283 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), 285 287 { 286 288 /* Handshake failed ... */ -
libfdcore/p_psm.c
r1120 r1181 785 785 case STATE_WAITCNXACK_ELEC: 786 786 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)); 788 788 fd_p_ce_handle_newcnx(peer, cnx); 789 789 break; -
libfdcore/peers.c
r1113 r1181 430 430 } 431 431 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", 433 433 peer->p_dbgorig ?: "unset", 434 434 peer->p_hdr.info.config.pic_flags.pro3 == PI_P3_DEFAULT ? "-" : … … 439 439 peer->p_hdr.info.config.pic_flags.sec & PI_SEC_NONE ? "N" :"-", 440 440 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" :"-", 441 442 peer->p_hdr.info.config.pic_flags.exp ? "E" : "-", 442 443 peer->p_hdr.info.config.pic_flags.persist ? "P" : "-", -
libfdcore/sctp3436.c
r1180 r1181 566 566 for (i = 1; i < conn->cc_sctp_para.pairs; i++) { 567 567 /* 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) ); 569 569 570 570 /* additional initialization for gnutls 3.x */ -
libfdcore/server.c
r1136 r1181 54 54 struct cnxctx * conn; /* server connection context (listening socket) */ 55 55 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) */ 57 57 58 58 pthread_t thr; /* The thread listening for new connections */ … … 105 105 106 106 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), 108 108 IPPROTO_NAME( s->proto ), 109 s->secur ? "Secur" : "NotSecur", 109 s->secur ? "Secur" : "NotSecur", s->secur, 110 110 (st == NOT_CREATED) ? "Thread not created" : 111 111 ((st == RUNNING) ? "Thread running" : … … 147 147 TRACE_ENTRY("%p", c); 148 148 149 memset(&rcv_data, 0, sizeof(rcv_data)); 150 149 151 CHECK_PARAMS_DO(c && c->conn && c->chain.head, goto fatal_error ); 152 150 153 151 154 s = c->chain.head->o; … … 156 159 /* Handshake if we are a secure server port, or start clear otherwise */ 157 160 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); 159 162 if (ret != 0) { 160 163 char buf[1024]; … … 360 363 CHECK_MALLOC( s = new_serv(IPPROTO_SCTP, 1) ); 361 364 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) ); 362 373 fd_list_insert_before( &FD_SERVERS, &s->chain ); 363 374 CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) );
Note: See TracChangeset
for help on using the changeset viewer.