Skip to content

Commit

Permalink
Increase recv time to handle turn server msg and support multiple ice…
Browse files Browse the repository at this point in the history
… servers
  • Loading branch information
sepfy committed Aug 25, 2024
1 parent 78b8b80 commit c549f2f
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 102 deletions.
129 changes: 64 additions & 65 deletions src/agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,16 @@
#define AGENT_POLL_TIMEOUT 1
#define AGENT_CONNCHECK_MAX 300
#define AGENT_CONNCHECK_PERIOD 100
#define AGENT_STUN_RECV_MAXTIMES 1000

static int agent_create_sockets(Agent *agent) {
void agent_clear_candidates(Agent *agent) {

agent->local_candidates_count = 0;
agent->remote_candidates_count = 0;
agent->candidate_pairs_num = 0;
}

int agent_create(Agent *agent) {

int ret;
if ((ret = udp_socket_open(&agent->udp_sockets[0], AF_INET, 0)) < 0) {
Expand All @@ -35,9 +43,24 @@ static int agent_create_sockets(Agent *agent) {
}
LOGI("create IPv6 UDP socket: %d", agent->udp_sockets[1].fd);
#endif

agent_clear_candidates(agent);
return 0;
}

void agent_destroy(Agent *agent) {

if (agent->udp_sockets[0].fd > 0) {
udp_socket_close(&agent->udp_sockets[0]);
}

#if CONFIG_IPV6
if (agent->udp_sockets[1].fd > 0) {
udp_socket_close(&agent->udp_sockets[1]);
}
#endif
}

static int agent_socket_recv(Agent *agent, Address *addr, uint8_t *buf, int len) {

int ret = -1;
Expand Down Expand Up @@ -66,6 +89,7 @@ static int agent_socket_recv(Agent *agent, Address *addr, uint8_t *buf, int len)
} else {
for (i = 0; i < 2; i++) {
if (FD_ISSET(agent->udp_sockets[i].fd, &rfds)) {
memset(buf, 0, len);
ret = udp_socket_recvfrom(&agent->udp_sockets[i], addr, buf, len);
break;
}
Expand All @@ -75,6 +99,18 @@ static int agent_socket_recv(Agent *agent, Address *addr, uint8_t *buf, int len)
return ret;
}

static int agent_socket_recv_attempts(Agent *agent, Address *addr, uint8_t *buf, int len, int maxtimes) {

int ret = -1;
int i = 0;
for (i = 0; i < maxtimes; i++) {
if ((ret = agent_socket_recv(agent, addr, buf, len)) != 0) {
break;
}
}
return ret;
}

static int agent_socket_send(Agent *agent, Address *addr, const uint8_t *buf, int len) {

switch (addr->family) {
Expand All @@ -93,26 +129,23 @@ static int agent_create_host_addr(Agent *agent) {

udp_socket = &agent->udp_sockets[0];
if (ports_get_host_addr(&udp_socket->bind_addr)) {
//LOGD("addr: %d.%d.%d.%d", udp_socket->bind_addr.ipv4[0], udp_socket->bind_addr.ipv4[1], udp_socket->bind_addr.ipv4[2], udp_socket->bind_addr.ipv4[3]);
IceCandidate *ice_candidate = agent->local_candidates + agent->local_candidates_count++;
ice_candidate_create(ice_candidate, agent->local_candidates_count, ICE_CANDIDATE_TYPE_HOST, &udp_socket->bind_addr);
}

#if CONFIG_IPV6
udp_socket = &agent->udp_sockets[1];
if (ports_get_host_addr(&udp_socket->bind_addr)) {
//LOGD("addr: %x:%x:%x:%x:%x:%x:%x:%x", udp_socket->bind_addr.ipv6[0], udp_socket->bind_addr.ipv6[1], udp_socket->bind_addr.ipv6[2], udp_socket->bind_addr.ipv6[3], udp_socket->bind_addr.ipv6[4], udp_socket->bind_addr.ipv6[5], udp_socket->bind_addr.ipv6[6], udp_socket->bind_addr.ipv6[7]);
IceCandidate *ice_candidate = agent->local_candidates + agent->local_candidates_count++;
ice_candidate_create(ice_candidate, agent->local_candidates_count, ICE_CANDIDATE_TYPE_HOST, &udp_socket->bind_addr);
}
#endif
return 0;
}

static int agent_create_bind_addr(Agent *agent, Address *serv_addr) {
static int agent_create_stun_addr(Agent *agent, Address *serv_addr) {

int ret = -1;
int retry = 0;
Address bind_addr;
StunMessage send_msg;
StunMessage recv_msg;
Expand All @@ -128,14 +161,7 @@ static int agent_create_bind_addr(Agent *agent, Address *serv_addr) {
return ret;
}

// blocking 1 second
while (retry < 1000) {
ret = agent_socket_recv(agent, NULL, recv_msg.buf, sizeof(recv_msg.buf));
if (ret > 0) {
break;
}
}

ret = agent_socket_recv_attempts(agent, NULL, recv_msg.buf, sizeof(recv_msg.buf), AGENT_STUN_RECV_MAXTIMES);
if (ret <= 0) {
LOGD("Failed to receive STUN Binding Response.");
return ret;
Expand All @@ -152,7 +178,6 @@ static int agent_create_turn_addr(Agent *agent, Address *serv_addr, const char *

int ret = -1;
uint32_t attr = ntohl(0x11000000);
int retry = 0;
Address turn_addr;
StunMessage send_msg;
StunMessage recv_msg;
Expand All @@ -168,14 +193,7 @@ static int agent_create_turn_addr(Agent *agent, Address *serv_addr, const char *
return -1;
}

// blocking 1 second
while (retry < 1000) {
ret = agent_socket_recv(agent, NULL, recv_msg.buf, sizeof(recv_msg.buf));
if (ret > 0) {
break;
}
}

ret = agent_socket_recv_attempts(agent, NULL, recv_msg.buf, sizeof(recv_msg.buf), AGENT_STUN_RECV_MAXTIMES);
if (ret <= 0) {
LOGD("Failed to receive STUN Binding Response.");
return ret;
Expand Down Expand Up @@ -203,8 +221,7 @@ static int agent_create_turn_addr(Agent *agent, Address *serv_addr, const char *
return -1;
}

memset(&recv_msg, 0, sizeof(recv_msg));
ret = agent_socket_recv(agent, NULL, recv_msg.buf, sizeof(recv_msg.buf));
agent_socket_recv_attempts(agent, NULL, recv_msg.buf, sizeof(recv_msg.buf), AGENT_STUN_RECV_MAXTIMES);
if (ret <= 0) {
LOGD("Failed to receive TURN Binding Response.");
return ret;
Expand All @@ -217,22 +234,6 @@ static int agent_create_turn_addr(Agent *agent, Address *serv_addr, const char *
return ret;
}

void agent_init(Agent *agent) {
agent->local_candidates_count = 0;
}

void agent_deinit(Agent *agent) {

udp_socket_close(&agent->udp_socket);
memset(agent, 0, sizeof(Agent));
}

/*
* gather candidates
* create sockets
* create host candidate
* create server-reflexive candidate or relay candidate
*/
void agent_gather_candidate(Agent *agent, const char *urls, const char *username, const char *credential) {

char *pos;
Expand All @@ -243,46 +244,44 @@ void agent_gather_candidate(Agent *agent, const char *urls, const char *username
int addr_type[1] = {AF_INET}; // ipv6 no need stun
Address resolved_addr;
memset(hostname, 0, sizeof(hostname));
memset(agent, 0, sizeof(Agent));
agent_create_sockets(agent);

agent_create_host_addr(agent);

do {
if (urls == NULL) {
agent_create_host_addr(agent);
return;
}

if ((pos = strstr(urls + 5, ":")) == NULL) {
break;
}
if ((pos = strstr(urls + 5, ":")) == NULL) {
LOGE("Invalid URL");
return;
}

port = atoi(pos + 1);
if (port <= 0) {
break;
LOGE("Cannot parse port");
}
port = atoi(pos + 1);
if (port <= 0) {
LOGE("Cannot parse port");
return;
}

snprintf(hostname, pos - urls - 5 + 1, "%s", urls + 5);
snprintf(hostname, pos - urls - 5 + 1, "%s", urls + 5);

for (i = 0; i < sizeof(addr_type) / sizeof(addr_type[0]); i++) {
for (i = 0; i < sizeof(addr_type) / sizeof(addr_type[0]); i++) {

if (ports_resolve_addr(hostname, &resolved_addr) != 0) {
continue;
}
if (ports_resolve_addr(hostname, &resolved_addr) == 0) {

addr_set_port(&resolved_addr, port);
addr_to_string(&resolved_addr, addr_string, sizeof(addr_string));
LOGI("stun/turn server %s:%d", addr_string, port);
LOGI("Resolved stun/turn server %s:%d", addr_string, port);

if (strncmp(urls, "stun:", 5) == 0) {
LOGD("create stun addr");
agent_create_bind_addr(agent, &resolved_addr);
LOGD("Create stun addr");
agent_create_stun_addr(agent, &resolved_addr);
} else if (strncmp(urls, "turn:", 5) == 0) {
LOGD("create turn addr");
LOGD("Create turn addr");
agent_create_turn_addr(agent, &resolved_addr, username, credential);
}
}

} while (0);

break;
}
}
}

void agent_get_local_description(Agent *agent, char *description, int length) {
Expand Down
17 changes: 4 additions & 13 deletions src/agent.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ struct Agent {
int local_candidates_count;
int remote_candidates_count;

UdpSocket udp_socket;
UdpSocket udp_sockets[2];

Address host_addr;
Expand All @@ -75,37 +74,29 @@ struct Agent {
IceCandidatePair *nominated_pair;

int candidate_pairs_num;

int use_candidate;

uint32_t transaction_id[3];
};

void agent_gather_candidate(Agent *agent, const char *urls, const char *username, const char *credential);

void agent_get_local_description(Agent *agent, char *description, int length);

int agent_loop(Agent *agent);

int agent_send(Agent *agent, const uint8_t *buf, int len);

int agent_recv(Agent *agent, uint8_t *buf, int len);

void agent_set_remote_description(Agent *agent, char *description);

void *agent_thread(void *arg);

int agent_select_candidate_pair(Agent *agent);

void agent_attach_recv_cb(Agent *agent, void (*data_recv_cb)(char *buf, int len, void *user_data));

void agent_set_host_address(Agent *agent, Address *addr);

int agent_connectivity_check(Agent *agent);

void agent_init(Agent *agent);
void agent_clear_candidates(Agent *agent);

int agent_create(Agent *agent);

void agent_deinit(Agent *agent);
void agent_destroy(Agent *agent);

#endif // AGENT_H_

9 changes: 6 additions & 3 deletions src/peer_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ PeerConnection* peer_connection_create(PeerConfiguration *config) {
memcpy(&pc->config, config, sizeof(PeerConfiguration));

pc->agent.mode = AGENT_MODE_CONTROLLED;
agent_create(&pc->agent);

memset(&pc->sctp, 0, sizeof(pc->sctp));
dtls_srtp_init(&pc->dtls_srtp, DTLS_SRTP_ROLE_SERVER, pc);
Expand Down Expand Up @@ -220,6 +221,7 @@ void peer_connection_destroy(PeerConnection *pc) {

if (pc) {

agent_destroy(&pc->agent);
buffer_free(pc->data_rb);
buffer_free(pc->audio_rb);
buffer_free(pc->video_rb);
Expand Down Expand Up @@ -277,16 +279,17 @@ static void peer_connection_state_new(PeerConnection *pc) {

memset(pc->temp_buf, 0, sizeof(pc->temp_buf));

agent_deinit(&pc->agent);

dtls_srtp_reset_session(&pc->dtls_srtp);

pc->sctp.connected = 0;

agent_clear_candidates(&pc->agent);

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) {
LOGI("ice_servers: %s", pc->config.ice_servers[i].urls);
LOGI("ice server: %s", pc->config.ice_servers[i].urls);
agent_gather_candidate(&pc->agent, pc->config.ice_servers[i].urls, pc->config.ice_servers[i].username, pc->config.ice_servers[i].credential);
}
}
Expand Down
42 changes: 21 additions & 21 deletions tests/test_agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,42 @@
#include "ports.h"
#include "agent.h"

void test_turn(Agent *agent, char *turnserver, char *username, char *credential) {
void test_gather_host(Agent *agent) {

agent_gather_candidate(agent, NULL, NULL, NULL);
}

void test_gather_turn(Agent *agent, char *turnserver, char *username, char *credential) {

char description[1024];
memset(&description, 0, sizeof(description));
agent_gather_candidate(agent, turnserver, username, credential);
agent_get_local_description(agent, description, sizeof(description));
printf("turn server: %s\n", turnserver);
printf("sdp: %s\n", description);
}

void test_stun(Agent *agent, char *stunserver) {
void test_gather_stun(Agent *agent, char *stunserver) {

char description[1024];
memset(&description, 0, sizeof(description));
agent_gather_candidate(agent, stunserver, NULL, NULL);
agent_get_local_description(agent, description, sizeof(description));
printf("stun server: %s\n", stunserver);
printf("sdp: %s\n", description);
}

int main(int argc, char *argv[]) {

Agent agent;

char stunserver[] = "stun:stun.l.google.com:19302";
char turnserver[] = "turn:global.turn.twilio.com:3478?transport=udp";
char username[] = "8e9ed7b70d63b66684c74932c8bce26363956e338d353a4e0e039fe6140f64c2";
char credential[] = "hXQwBJFQX8YHPH6adGgb4XCmKnJQPvhU/VaWwypf/LI=";
char turnserver[] = "";
char username[] = "";
char credential[] = "";
char description[1024];
memset(&description, 0, sizeof(description));

agent_create(&agent);

test_gather_host(&agent);
test_gather_stun(&agent, stunserver);
test_gather_turn(&agent, turnserver, username, credential);
agent_get_local_description(&agent, description, sizeof(description));

agent_init(&agent);
printf("sdp:\n%s\n", description);

test_stun(&agent, stunserver);
#if 0
test_turn(&agent, turnserver, username, credential);
#endif
agent_deinit(&agent);
agent_destroy(&agent);

return 0;
}
Expand Down

0 comments on commit c549f2f

Please sign in to comment.