From 68cdc652fb37d49a73a9a9bc1bfa14aed16f2610 Mon Sep 17 00:00:00 2001 From: topworldcoder <63830798+topworldcoder@users.noreply.github.com> Date: Mon, 18 Nov 2024 20:44:03 +0800 Subject: [PATCH] Update the usage of offerer In webrtc, offerer usually acts the role of 'AGENT_MODE_CONTROLLING', and set 'a=setup:active' in sdp, and acts the role of 'DTLS_SRTP_ROLE_CLIENT'. --- src/agent.c | 2 +- src/dtls_srtp.c | 59 ++++++++++++++++-------------------- src/dtls_srtp.h | 8 ++--- src/peer_connection.c | 55 +++++++++++++++++++-------------- src/peer_connection.h | 2 ++ tests/test_peer_connection.c | 4 +-- 6 files changed, 68 insertions(+), 62 deletions(-) diff --git a/src/agent.c b/src/agent.c index c0942ac..525301f 100644 --- a/src/agent.c +++ b/src/agent.c @@ -321,7 +321,7 @@ static void agent_create_binding_response(Agent* agent, StunMessage* msg, Addres } static void agent_create_binding_request(Agent* agent, StunMessage* msg) { - uint64_t tie_breaker = 0; // always be controlled + uint64_t tie_breaker = 1; // always be controlled // send binding request stun_msg_create(msg, STUN_CLASS_REQUEST | STUN_METHOD_BINDING); char username[584]; diff --git a/src/dtls_srtp.c b/src/dtls_srtp.c index a233fe8..622a95e 100644 --- a/src/dtls_srtp.c +++ b/src/dtls_srtp.c @@ -186,12 +186,6 @@ int dtls_srtp_init(DtlsSrtp* dtls_srtp, DtlsSrtpRole role, void* user_data) { MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT); - mbedtls_ssl_cookie_init(&dtls_srtp->cookie_ctx); - - mbedtls_ssl_cookie_setup(&dtls_srtp->cookie_ctx, mbedtls_ctr_drbg_random, &dtls_srtp->ctr_drbg); - - mbedtls_ssl_conf_dtls_cookies(&dtls_srtp->conf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check, &dtls_srtp->cookie_ctx); - } else { mbedtls_ssl_config_defaults(&dtls_srtp->conf, MBEDTLS_SSL_IS_CLIENT, @@ -199,6 +193,12 @@ int dtls_srtp_init(DtlsSrtp* dtls_srtp, DtlsSrtpRole role, void* user_data) { MBEDTLS_SSL_PRESET_DEFAULT); } + mbedtls_ssl_cookie_init(&dtls_srtp->cookie_ctx); + + mbedtls_ssl_cookie_setup(&dtls_srtp->cookie_ctx, mbedtls_ctr_drbg_random, &dtls_srtp->ctr_drbg); + + mbedtls_ssl_conf_dtls_cookies(&dtls_srtp->conf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check, &dtls_srtp->cookie_ctx); + dtls_srtp_x509_digest(&dtls_srtp->cert, dtls_srtp->local_fingerprint); LOGD("local fingerprint: %s", dtls_srtp->local_fingerprint); @@ -223,9 +223,7 @@ void dtls_srtp_deinit(DtlsSrtp* dtls_srtp) { mbedtls_entropy_free(&dtls_srtp->entropy); mbedtls_ctr_drbg_free(&dtls_srtp->ctr_drbg); - if (dtls_srtp->role == DTLS_SRTP_ROLE_SERVER) { - mbedtls_ssl_cookie_free(&dtls_srtp->cookie_ctx); - } + mbedtls_ssl_cookie_free(&dtls_srtp->cookie_ctx); if (dtls_srtp->state == DTLS_SRTP_STATE_CONNECTED) { srtp_dealloc(dtls_srtp->srtp_in); @@ -267,40 +265,35 @@ static int dtls_srtp_key_derivation(DtlsSrtp* dtls_srtp, const unsigned char* ma #endif // derive inbounds keys + memset(&dtls_srtp->srtp_in_policy, 0, sizeof(dtls_srtp->srtp_in_policy)); + // derive outbounds keys + memset(&dtls_srtp->srtp_out_policy, 0, sizeof(dtls_srtp->srtp_out_policy)); - memset(&dtls_srtp->remote_policy, 0, sizeof(dtls_srtp->remote_policy)); - - srtp_crypto_policy_set_rtp_default(&dtls_srtp->remote_policy.rtp); - srtp_crypto_policy_set_rtcp_default(&dtls_srtp->remote_policy.rtcp); - - memcpy(dtls_srtp->remote_policy_key, key_material, SRTP_MASTER_KEY_LENGTH); - memcpy(dtls_srtp->remote_policy_key + SRTP_MASTER_KEY_LENGTH, key_material + SRTP_MASTER_KEY_LENGTH + SRTP_MASTER_KEY_LENGTH, SRTP_MASTER_SALT_LENGTH); + memcpy(dtls_srtp->client_policy_key, key_material, SRTP_MASTER_KEY_LENGTH); + memcpy(dtls_srtp->client_policy_key + SRTP_MASTER_KEY_LENGTH, key_material + SRTP_MASTER_KEY_LENGTH + SRTP_MASTER_KEY_LENGTH, SRTP_MASTER_SALT_LENGTH); + memcpy(dtls_srtp->server_policy_key, key_material + SRTP_MASTER_KEY_LENGTH, SRTP_MASTER_KEY_LENGTH); + memcpy(dtls_srtp->server_policy_key + SRTP_MASTER_KEY_LENGTH, key_material + SRTP_MASTER_KEY_LENGTH + SRTP_MASTER_KEY_LENGTH + SRTP_MASTER_SALT_LENGTH, SRTP_MASTER_SALT_LENGTH); - dtls_srtp->remote_policy.ssrc.type = ssrc_any_inbound; - dtls_srtp->remote_policy.key = dtls_srtp->remote_policy_key; - dtls_srtp->remote_policy.next = NULL; + srtp_crypto_policy_set_rtp_default(&dtls_srtp->srtp_in_policy.rtp); + srtp_crypto_policy_set_rtcp_default(&dtls_srtp->srtp_in_policy.rtcp); + dtls_srtp->srtp_in_policy.ssrc.type = ssrc_any_inbound; + dtls_srtp->srtp_in_policy.key = (dtls_srtp->role == DTLS_SRTP_ROLE_SERVER) ? dtls_srtp->client_policy_key : dtls_srtp->server_policy_key; + dtls_srtp->srtp_in_policy.next = NULL; - if (srtp_create(&dtls_srtp->srtp_in, &dtls_srtp->remote_policy) != srtp_err_status_ok) { + if (srtp_create(&dtls_srtp->srtp_in, &dtls_srtp->srtp_in_policy) != srtp_err_status_ok) { LOGD("Error creating inbound SRTP session for component"); return -1; } LOGI("Created inbound SRTP session"); - // derive outbounds keys - memset(&dtls_srtp->local_policy, 0, sizeof(dtls_srtp->local_policy)); - - srtp_crypto_policy_set_rtp_default(&dtls_srtp->local_policy.rtp); - srtp_crypto_policy_set_rtcp_default(&dtls_srtp->local_policy.rtcp); - - memcpy(dtls_srtp->local_policy_key, key_material + SRTP_MASTER_KEY_LENGTH, SRTP_MASTER_KEY_LENGTH); - memcpy(dtls_srtp->local_policy_key + SRTP_MASTER_KEY_LENGTH, key_material + SRTP_MASTER_KEY_LENGTH + SRTP_MASTER_KEY_LENGTH + SRTP_MASTER_SALT_LENGTH, SRTP_MASTER_SALT_LENGTH); - - dtls_srtp->local_policy.ssrc.type = ssrc_any_outbound; - dtls_srtp->local_policy.key = dtls_srtp->local_policy_key; - dtls_srtp->local_policy.next = NULL; + srtp_crypto_policy_set_rtp_default(&dtls_srtp->srtp_out_policy.rtp); + srtp_crypto_policy_set_rtcp_default(&dtls_srtp->srtp_out_policy.rtcp); + dtls_srtp->srtp_out_policy.ssrc.type = ssrc_any_outbound; + dtls_srtp->srtp_out_policy.key = (dtls_srtp->role == DTLS_SRTP_ROLE_SERVER) ? dtls_srtp->server_policy_key : dtls_srtp->client_policy_key; + dtls_srtp->srtp_out_policy.next = NULL; - if (srtp_create(&dtls_srtp->srtp_out, &dtls_srtp->local_policy) != srtp_err_status_ok) { + if (srtp_create(&dtls_srtp->srtp_out, &dtls_srtp->srtp_out_policy) != srtp_err_status_ok) { LOGE("Error creating outbound SRTP session"); return -1; } diff --git a/src/dtls_srtp.h b/src/dtls_srtp.h index 09d2401..650472c 100644 --- a/src/dtls_srtp.h +++ b/src/dtls_srtp.h @@ -48,12 +48,12 @@ typedef struct DtlsSrtp { mbedtls_ctr_drbg_context ctr_drbg; // SRTP - srtp_policy_t remote_policy; - srtp_policy_t local_policy; + srtp_policy_t srtp_in_policy; + srtp_policy_t srtp_out_policy; srtp_t srtp_in; srtp_t srtp_out; - unsigned char remote_policy_key[SRTP_MASTER_KEY_LENGTH + SRTP_MASTER_SALT_LENGTH]; - unsigned char local_policy_key[SRTP_MASTER_KEY_LENGTH + SRTP_MASTER_SALT_LENGTH]; + unsigned char client_policy_key[SRTP_MASTER_KEY_LENGTH + SRTP_MASTER_SALT_LENGTH]; + unsigned char server_policy_key[SRTP_MASTER_KEY_LENGTH + SRTP_MASTER_SALT_LENGTH]; int (*udp_send)(void* ctx, const unsigned char* buf, size_t len); int (*udp_recv)(void* ctx, unsigned char* buf, size_t len); diff --git a/src/peer_connection.c b/src/peer_connection.c index 56ec655..49f4569 100644 --- a/src/peer_connection.c +++ b/src/peer_connection.c @@ -38,6 +38,7 @@ struct PeerConnection { uint8_t temp_buf[CONFIG_MTU]; uint8_t agent_buf[CONFIG_MTU]; int agent_ret; + int is_offerer; int b_local_description_created; Buffer* audio_rb; @@ -165,6 +166,7 @@ PeerConnection* peer_connection_create(PeerConfiguration* config) { return NULL; } + pc->is_offerer = 1; memcpy(&pc->config, config, sizeof(PeerConfiguration)); agent_create(&pc->agent); @@ -206,6 +208,14 @@ PeerConnection* peer_connection_create(PeerConfiguration* config) { return pc; } +PeerConnection* peer_connection_create_ex(int is_offerer, PeerConfiguration* config) { + PeerConnection* pc = peer_connection_create(config); + if (pc != NULL) { + pc->is_offerer = is_offerer; + } + return pc; +} + void peer_connection_destroy(PeerConnection* pc) { if (pc) { sctp_destroy_socket(&pc->sctp); @@ -268,14 +278,20 @@ int peer_connection_datachannel_send_sid(PeerConnection* pc, char* message, size #endif } -static char* peer_connection_dtls_role_setup_value(DtlsSrtpRole d) { - return d == DTLS_SRTP_ROLE_SERVER ? "a=setup:passive" : "a=setup:active"; +static char* peer_connection_dtls_role_setup_value(int is_offerer) { + return is_offerer == 0 ? "a=setup:passive" : "a=setup:active"; } -static void peer_connection_state_new(PeerConnection* pc, DtlsSrtpRole role, int isOfferer) { - char* description = (char*)pc->temp_buf; - - memset(pc->temp_buf, 0, sizeof(pc->temp_buf)); +static void peer_connection_state_new(PeerConnection* pc, int is_offerer) { + DtlsSrtpRole role = DTLS_SRTP_ROLE_CLIENT; + if (is_offerer) { + role = DTLS_SRTP_ROLE_CLIENT; + agent_clear_candidates(&pc->agent); + pc->agent.mode = AGENT_MODE_CONTROLLING; + } else { + role = DTLS_SRTP_ROLE_SERVER; + pc->agent.mode = AGENT_MODE_CONTROLLED; + } dtls_srtp_reset_session(&pc->dtls_srtp); dtls_srtp_init(&pc->dtls_srtp, role, pc); @@ -284,13 +300,6 @@ static void peer_connection_state_new(PeerConnection* pc, DtlsSrtpRole role, int pc->sctp.connected = 0; - if (isOfferer) { - agent_clear_candidates(&pc->agent); - pc->agent.mode = AGENT_MODE_CONTROLLING; - } else { - pc->agent.mode = AGENT_MODE_CONTROLLED; - } - agent_gather_candidate(&pc->agent, NULL, NULL, NULL); // host address for (int i = 0; i < sizeof(pc->config.ice_servers) / sizeof(pc->config.ice_servers[0]); ++i) { if (pc->config.ice_servers[i].urls) { @@ -299,6 +308,8 @@ static void peer_connection_state_new(PeerConnection* pc, DtlsSrtpRole role, int } } + char* description = (char*)pc->temp_buf; + memset(pc->temp_buf, 0, sizeof(pc->temp_buf)); agent_get_local_description(&pc->agent, description, sizeof(pc->temp_buf)); memset(&pc->local_sdp, 0, sizeof(pc->local_sdp)); @@ -311,7 +322,7 @@ static void peer_connection_state_new(PeerConnection* pc, DtlsSrtpRole role, int if (pc->config.video_codec == CODEC_H264) { sdp_append_h264(&pc->local_sdp); sdp_append(&pc->local_sdp, "a=fingerprint:sha-256 %s", pc->dtls_srtp.local_fingerprint); - sdp_append(&pc->local_sdp, peer_connection_dtls_role_setup_value(role)); + sdp_append(&pc->local_sdp, peer_connection_dtls_role_setup_value(is_offerer)); strcat(pc->local_sdp.content, description); } @@ -320,7 +331,7 @@ static void peer_connection_state_new(PeerConnection* pc, DtlsSrtpRole role, int sdp_append_pcma(&pc->local_sdp); sdp_append(&pc->local_sdp, "a=fingerprint:sha-256 %s", pc->dtls_srtp.local_fingerprint); - sdp_append(&pc->local_sdp, peer_connection_dtls_role_setup_value(role)); + sdp_append(&pc->local_sdp, peer_connection_dtls_role_setup_value(is_offerer)); strcat(pc->local_sdp.content, description); break; @@ -328,14 +339,14 @@ static void peer_connection_state_new(PeerConnection* pc, DtlsSrtpRole role, int sdp_append_pcmu(&pc->local_sdp); sdp_append(&pc->local_sdp, "a=fingerprint:sha-256 %s", pc->dtls_srtp.local_fingerprint); - sdp_append(&pc->local_sdp, peer_connection_dtls_role_setup_value(role)); + sdp_append(&pc->local_sdp, peer_connection_dtls_role_setup_value(is_offerer)); strcat(pc->local_sdp.content, description); break; case CODEC_OPUS: sdp_append_opus(&pc->local_sdp); sdp_append(&pc->local_sdp, "a=fingerprint:sha-256 %s", pc->dtls_srtp.local_fingerprint); - sdp_append(&pc->local_sdp, peer_connection_dtls_role_setup_value(role)); + sdp_append(&pc->local_sdp, peer_connection_dtls_role_setup_value(is_offerer)); strcat(pc->local_sdp.content, description); default: @@ -345,7 +356,7 @@ static void peer_connection_state_new(PeerConnection* pc, DtlsSrtpRole role, int if (pc->config.datachannel) { sdp_append_datachannel(&pc->local_sdp); sdp_append(&pc->local_sdp, "a=fingerprint:sha-256 %s", pc->dtls_srtp.local_fingerprint); - sdp_append(&pc->local_sdp, peer_connection_dtls_role_setup_value(role)); + sdp_append(&pc->local_sdp, peer_connection_dtls_role_setup_value(is_offerer)); strcat(pc->local_sdp.content, description); } @@ -367,7 +378,7 @@ int peer_connection_loop(PeerConnection* pc) { case PEER_CONNECTION_NEW: if (!pc->b_local_description_created) { - peer_connection_state_new(pc, DTLS_SRTP_ROLE_SERVER, 1); + peer_connection_state_new(pc, pc->is_offerer); } break; @@ -480,7 +491,7 @@ void peer_connection_set_remote_description(PeerConnection* pc, const char* sdp_ char buf[256]; char* val_start = NULL; uint32_t* ssrc = NULL; - DtlsSrtpRole role = DTLS_SRTP_ROLE_SERVER; + DtlsSrtpRole role = DTLS_SRTP_ROLE_CLIENT; int is_update = 0; Agent* agent = &pc->agent; @@ -490,7 +501,7 @@ void peer_connection_set_remote_description(PeerConnection* pc, const char* sdp_ buf[line - start] = '\0'; if (strstr(buf, "a=setup:passive")) { - role = DTLS_SRTP_ROLE_CLIENT; + role = DTLS_SRTP_ROLE_SERVER; } if (strstr(buf, "a=fingerprint")) { @@ -522,7 +533,7 @@ void peer_connection_set_remote_description(PeerConnection* pc, const char* sdp_ } if (!pc->b_local_description_created) { - peer_connection_state_new(pc, role, 0); + peer_connection_state_new(pc, role == DTLS_SRTP_ROLE_CLIENT ? 0 : 1); } agent_set_remote_description(&pc->agent, (char*)sdp_text); diff --git a/src/peer_connection.h b/src/peer_connection.h index d917884..127a38f 100644 --- a/src/peer_connection.h +++ b/src/peer_connection.h @@ -79,6 +79,8 @@ void* peer_connection_get_sctp(PeerConnection* pc); PeerConnection* peer_connection_create(PeerConfiguration* config); +PeerConnection* peer_connection_create_ex(int is_offerer, PeerConfiguration* config); + void peer_connection_destroy(PeerConnection* pc); void peer_connection_close(PeerConnection* pc); diff --git a/tests/test_peer_connection.c b/tests/test_peer_connection.c index fa17832..c054d4e 100644 --- a/tests/test_peer_connection.c +++ b/tests/test_peer_connection.c @@ -64,8 +64,8 @@ int main(int argc, char* argv[]) { peer_init(); - test_user_data.offer_peer_connection = peer_connection_create(&config); - test_user_data.answer_peer_connection = peer_connection_create(&config); + test_user_data.offer_peer_connection = peer_connection_create_ex(1, &config); + test_user_data.answer_peer_connection = peer_connection_create_ex(0, &config); peer_connection_oniceconnectionstatechange(test_user_data.offer_peer_connection, onconnectionstatechange_offerer_peer_connection); peer_connection_oniceconnectionstatechange(test_user_data.answer_peer_connection, onconnectionstatechange_answerer_peer_connection);