Skip to content

Commit

Permalink
Update the usage of offerer
Browse files Browse the repository at this point in the history
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'.
  • Loading branch information
topworldcoder committed Nov 18, 2024
1 parent 4df7bc3 commit 68cdc65
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 62 deletions.
2 changes: 1 addition & 1 deletion src/agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
59 changes: 26 additions & 33 deletions src/dtls_srtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,19 +186,19 @@ 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,
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);

dtls_srtp_x509_digest(&dtls_srtp->cert, dtls_srtp->local_fingerprint);

LOGD("local fingerprint: %s", dtls_srtp->local_fingerprint);
Expand All @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down
8 changes: 4 additions & 4 deletions src/dtls_srtp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
55 changes: 33 additions & 22 deletions src/peer_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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) {
Expand All @@ -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));
Expand All @@ -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);
}

Expand All @@ -320,22 +331,22 @@ 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;

case CODEC_PCMU:

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:
Expand All @@ -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);
}

Expand All @@ -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;

Expand Down Expand Up @@ -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;

Expand All @@ -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")) {
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions src/peer_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions tests/test_peer_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 68cdc65

Please sign in to comment.