Changeset 1181:22de21feec64 in freeDiameter for libfdcore/cnxctx.c
- Timestamp:
- Jun 5, 2013, 8:22:26 PM (11 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 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 */
Note: See TracChangeset
for help on using the changeset viewer.