add stun to dingaling
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@1049 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
cd06692667
commit
35b309e91b
|
@ -55,6 +55,9 @@ typedef void (*switch_rtp_invalid_handler)(switch_rtp *rtp_session,
|
|||
switch_sockaddr_t *from_addr);
|
||||
|
||||
|
||||
SWITCH_DECLARE(void) switch_rtp_init(switch_memory_pool *pool);
|
||||
SWITCH_DECLARE(switch_port_t) switch_rtp_request_port(void);
|
||||
|
||||
SWITCH_DECLARE(switch_rtp *)switch_rtp_new(char *rx_ip,
|
||||
switch_port_t rx_port,
|
||||
char *tx_ip,
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
*/
|
||||
#ifndef _SWITCH_STUN_PARSER_H
|
||||
#define _SWITCH_STUN_PARSER_H
|
||||
|
||||
#define SWITCH_STUN_DEFAULT_PORT 3478
|
||||
#define SWITCH_STUN_PACKET_MIN_LEN 20
|
||||
|
||||
typedef enum {
|
||||
|
@ -196,6 +196,23 @@ SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_username(switch_stun_pa
|
|||
*/
|
||||
SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_binded_address(switch_stun_packet_t *packet, char *ipstr, uint16_t port);
|
||||
|
||||
/*!
|
||||
\brief Perform a stun lookup
|
||||
\param ip the local ip to use (replaced with stun results)
|
||||
\param port the local port to use (replaced with stun results)
|
||||
\param stunip the ip of the stun server
|
||||
\param pool the memory pool to use
|
||||
\return SUCCESS or FAIL
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status) switch_stun_lookup (char **ip,
|
||||
switch_port_t *port,
|
||||
char *stunip,
|
||||
switch_port_t stunport,
|
||||
char **err,
|
||||
switch_memory_pool *pool);
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief set a switch_stun_packet_attribute_t pointer to point at the first attribute in a packet
|
||||
\param packet the packet in question
|
||||
|
|
|
@ -68,7 +68,6 @@ static struct {
|
|||
int codec_rates_last;
|
||||
unsigned int flags;
|
||||
unsigned int init;
|
||||
uint16_t rtp_port;
|
||||
switch_hash *profile_hash;
|
||||
int running;
|
||||
int handles;
|
||||
|
@ -95,7 +94,6 @@ struct private_object {
|
|||
struct switch_frame read_frame;
|
||||
struct switch_frame cng_frame;
|
||||
struct mdl_profile *profile;
|
||||
switch_sockaddr_t *switch_stun_addr;
|
||||
unsigned char read_buf[SWITCH_RECCOMMENDED_BUFFER_SIZE];
|
||||
unsigned char cng_buf[SWITCH_RECCOMMENDED_BUFFER_SIZE];
|
||||
switch_core_session *session;
|
||||
|
@ -108,7 +106,8 @@ struct private_object {
|
|||
struct switch_rtp *rtp_session;
|
||||
ldl_session_t *dlsession;
|
||||
char *remote_ip;
|
||||
uint16_t remote_port;
|
||||
switch_port_t local_port;
|
||||
switch_port_t remote_port;
|
||||
char local_user[16];
|
||||
char *remote_user;
|
||||
unsigned int cand_id;
|
||||
|
@ -135,12 +134,6 @@ struct rfc2833_digit {
|
|||
int duration;
|
||||
};
|
||||
|
||||
static uint16_t next_rtp_port(void)
|
||||
{
|
||||
uint16_t ret = globals.rtp_port++;
|
||||
globals.rtp_port++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan)
|
||||
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_string, globals.codec_string)
|
||||
|
@ -280,7 +273,7 @@ static void *SWITCH_THREAD_FUNC negotiate_thread_run(switch_thread *thread, void
|
|||
|
||||
cand[0].name = "rtp";
|
||||
cand[0].address = advip;
|
||||
cand[0].port = next_rtp_port();
|
||||
cand[0].port = tech_pvt->local_port;
|
||||
cand[0].username = tech_pvt->local_user;
|
||||
cand[0].password = tech_pvt->local_user;
|
||||
cand[0].pref = 1;
|
||||
|
@ -878,13 +871,13 @@ static switch_status channel_outgoing_channel(switch_core_session *session, swit
|
|||
}
|
||||
|
||||
switch_core_session_add_stream(*new_session, NULL);
|
||||
if ((tech_pvt =
|
||||
(struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object))) != 0) {
|
||||
if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object))) != 0) {
|
||||
memset(tech_pvt, 0, sizeof(*tech_pvt));
|
||||
channel = switch_core_session_get_channel(*new_session);
|
||||
switch_core_session_set_private(*new_session, tech_pvt);
|
||||
tech_pvt->session = *new_session;
|
||||
tech_pvt->codec_index = -1;
|
||||
tech_pvt->local_port = switch_rtp_request_port();
|
||||
} else {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
|
||||
switch_core_session_destroy(new_session);
|
||||
|
@ -1009,7 +1002,6 @@ static switch_status load_config(void)
|
|||
int lastcat = -1;
|
||||
|
||||
memset(&globals, 0, sizeof(globals));
|
||||
globals.rtp_port = 10000;
|
||||
globals.running = 1;
|
||||
|
||||
switch_core_hash_init(&globals.profile_hash, module_pool);
|
||||
|
@ -1134,6 +1126,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
|
|||
tech_pvt->session = session;
|
||||
tech_pvt->codec_index = -1;
|
||||
tech_pvt->profile = profile;
|
||||
tech_pvt->local_port = switch_rtp_request_port();
|
||||
} else {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
|
||||
switch_core_session_destroy(&session);
|
||||
|
@ -1219,7 +1212,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
|
|||
if (signal) {
|
||||
ldl_candidate_t *candidates;
|
||||
unsigned int len = 0;
|
||||
|
||||
char *err;
|
||||
|
||||
|
||||
if (ldl_session_get_candidates(dlsession, &candidates, &len) == LDL_STATUS_SUCCESS) {
|
||||
|
@ -1257,17 +1250,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
|
|||
tech_pvt->remote_port = candidates[x].port;
|
||||
tech_pvt->remote_user = switch_core_session_strdup(session, candidates[x].username);
|
||||
|
||||
if (switch_sockaddr_info_get(&tech_pvt->switch_stun_addr,
|
||||
tech_pvt->remote_ip,
|
||||
SWITCH_UNSPEC,
|
||||
tech_pvt->remote_port,
|
||||
0,
|
||||
switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Address Error!\n");
|
||||
return LDL_STATUS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (tech_pvt->codec_index < 0) {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Don't have my codec yet here's one\n");
|
||||
tech_pvt->codec_name = tech_pvt->codecs[0]->iananame;
|
||||
|
@ -1286,24 +1269,44 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
|
|||
memset(cand, 0, sizeof(cand));
|
||||
switch_stun_random_string(tech_pvt->local_user, 16, NULL);
|
||||
|
||||
cand[0].name = "rtp";
|
||||
|
||||
cand[0].port = tech_pvt->local_port;
|
||||
cand[0].address = advip;
|
||||
cand[0].port = next_rtp_port();
|
||||
|
||||
if (!strncasecmp(advip, "stun:", 5)) {
|
||||
cand[0].address = profile->ip;
|
||||
if (switch_stun_lookup(&cand[0].address,
|
||||
&cand[0].port,
|
||||
advip + 5,
|
||||
SWITCH_STUN_DEFAULT_PORT,
|
||||
&err,
|
||||
switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Stun Failed! %s:%d [%s]\n", advip + 5, SWITCH_STUN_DEFAULT_PORT, err);
|
||||
switch_channel_hangup(channel);
|
||||
return LDL_STATUS_FALSE;
|
||||
}
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Stun Success %s:%d\n", cand[0].address, cand[0].port);
|
||||
cand[0].type = "stun";
|
||||
} else {
|
||||
cand[0].type = "local";
|
||||
}
|
||||
|
||||
cand[0].name = "rtp";
|
||||
cand[0].username = tech_pvt->local_user;
|
||||
cand[0].password = tech_pvt->local_user;
|
||||
cand[0].pref = 1;
|
||||
cand[0].protocol = "udp";
|
||||
cand[0].type = "local";
|
||||
|
||||
tech_pvt->cand_id = ldl_session_candidates(dlsession, cand, 1);
|
||||
tech_pvt->desc_id = ldl_session_describe(dlsession, payloads, 1, LDL_DESCRIPTION_ACCEPT);
|
||||
|
||||
|
||||
if (!tech_pvt->rtp_session) {
|
||||
const char *err;
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "SETUP RTP %s:%d -> %s:%d\n", profile->ip, cand[0].port, tech_pvt->remote_ip, tech_pvt->remote_port);
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "SETUP RTP %s:%d -> %s:%d\n", profile->ip, tech_pvt->local_port, tech_pvt->remote_ip, tech_pvt->remote_port);
|
||||
|
||||
if (!(tech_pvt->rtp_session = switch_rtp_new(profile->ip,
|
||||
cand[0].port,
|
||||
tech_pvt->local_port,
|
||||
tech_pvt->remote_ip,
|
||||
tech_pvt->remote_port,
|
||||
tech_pvt->codec_num,
|
||||
|
|
|
@ -80,13 +80,10 @@ static struct {
|
|||
int bytes_per_frame;
|
||||
char *dialplan;
|
||||
int port;
|
||||
switch_port_t rtp_start;
|
||||
switch_port_t rtp_end;
|
||||
char *codec_string;
|
||||
char *codec_order[SWITCH_MAX_CODECS];
|
||||
int codec_order_last;
|
||||
switch_hash *call_hash;
|
||||
switch_mutex_t *port_lock;
|
||||
int running;
|
||||
int codec_ms;
|
||||
int dtmf_duration;
|
||||
|
@ -134,20 +131,6 @@ struct private_object {
|
|||
};
|
||||
|
||||
|
||||
static switch_port_t next_rtp_port(void)
|
||||
{
|
||||
switch_port_t port;
|
||||
|
||||
switch_mutex_lock(globals.port_lock);
|
||||
port = globals.rtp_start;
|
||||
globals.rtp_start += 2;
|
||||
if (port >= globals.rtp_end) {
|
||||
port = globals.rtp_start;
|
||||
}
|
||||
switch_mutex_unlock(globals.port_lock);
|
||||
return port;
|
||||
}
|
||||
|
||||
struct rfc2833_digit {
|
||||
char digit;
|
||||
int duration;
|
||||
|
@ -268,7 +251,7 @@ static switch_status exosip_on_init(switch_core_session *session)
|
|||
osip_rfc3264_init(&tech_pvt->sdp_config);
|
||||
/* Decide on local IP and rtp port */
|
||||
strncpy(tech_pvt->local_sdp_audio_ip, localip, sizeof(tech_pvt->local_sdp_audio_ip));
|
||||
tech_pvt->local_sdp_audio_port = next_rtp_port();
|
||||
tech_pvt->local_sdp_audio_port = switch_rtp_request_port();
|
||||
/* Initialize SDP */
|
||||
sdp_message_init(&tech_pvt->local_sdp);
|
||||
sdp_message_v_version_set(tech_pvt->local_sdp, "0");
|
||||
|
@ -1028,7 +1011,6 @@ SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_modul
|
|||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
switch_mutex_init(&globals.port_lock, SWITCH_MUTEX_NESTED, module_pool);
|
||||
switch_core_hash_init(&globals.call_hash, module_pool);
|
||||
|
||||
/* connect my internal structure to the blank pointer passed to me */
|
||||
|
@ -1116,7 +1098,7 @@ static switch_status exosip_create_call(eXosip_event_t * event)
|
|||
}
|
||||
|
||||
eXosip_guess_localip(AF_INET, tech_pvt->local_sdp_audio_ip, 50);
|
||||
tech_pvt->local_sdp_audio_port = next_rtp_port();
|
||||
tech_pvt->local_sdp_audio_port = switch_rtp_request_port();
|
||||
osip_rfc3264_init(&tech_pvt->sdp_config);
|
||||
/* Add in what codecs we support locally */
|
||||
|
||||
|
@ -1565,8 +1547,6 @@ static int config_exosip(int reload)
|
|||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
globals.rtp_start = 16384;
|
||||
globals.rtp_end = 32768;
|
||||
globals.dtmf_duration = 100;
|
||||
|
||||
while (switch_config_next_pair(&cfg, &var, &val)) {
|
||||
|
@ -1583,12 +1563,7 @@ static int config_exosip(int reload)
|
|||
set_global_dialplan(val);
|
||||
} else if (!strcmp(var, "codec_prefs")) {
|
||||
set_global_codec_string(val);
|
||||
globals.codec_order_last =
|
||||
switch_separate_string(globals.codec_string, ',', globals.codec_order, SWITCH_MAX_CODECS);
|
||||
} else if (!strcmp(var, "rtp_min_port")) {
|
||||
globals.rtp_start = (switch_port_t)atoi(val);
|
||||
} else if (!strcmp(var, "rtp_max_port")) {
|
||||
globals.rtp_end = (switch_port_t)atoi(val);
|
||||
globals.codec_order_last = switch_separate_string(globals.codec_string, ',', globals.codec_order, SWITCH_MAX_CODECS);
|
||||
} else if (!strcmp(var, "codec_ms")) {
|
||||
globals.codec_ms = atoi(val);
|
||||
} else if (!strcmp(var, "dtmf_duration")) {
|
||||
|
|
|
@ -2414,11 +2414,10 @@ SWITCH_DECLARE(switch_status) switch_core_init(char *console)
|
|||
}
|
||||
|
||||
|
||||
|
||||
assert(runtime.memory_pool != NULL);
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Allocated memory pool. Sessions are %u bytes\n", sizeof(struct switch_core_session));
|
||||
switch_event_init(runtime.memory_pool);
|
||||
|
||||
assert(runtime.memory_pool != NULL);
|
||||
switch_rtp_init(runtime.memory_pool);
|
||||
|
||||
/* Activate SQL database */
|
||||
if ((runtime.db = switch_core_db_handle()) == 0 ) {
|
||||
|
|
|
@ -780,6 +780,9 @@ static void *audio_bridge_thread(switch_thread *thread, void *obj)
|
|||
switch_channel_hangup(chan_b);
|
||||
}
|
||||
switch_channel_clear_flag(chan_a, CF_ORIGINATOR);
|
||||
} else if (!switch_channel_test_flag(chan_a, CF_ORIGINATOR) && !switch_channel_test_flag(chan_a, CF_TRANSFER)) {
|
||||
switch_core_session_kill_channel(session_a, SWITCH_SIG_KILL);
|
||||
switch_channel_hangup(chan_a);
|
||||
}
|
||||
|
||||
while (his_thread->running > 0) {
|
||||
|
|
|
@ -42,6 +42,11 @@
|
|||
#define MAX_KEY_LEN 64
|
||||
#define rtp_header_len 12
|
||||
#define RTP_MAX_BUF_LEN 16384
|
||||
#define RTP_START_PORT 16384
|
||||
#define RTP_END_PORT 32768
|
||||
|
||||
static switch_port_t NEXT_PORT = RTP_START_PORT;
|
||||
static switch_mutex_t *port_lock = NULL;
|
||||
|
||||
typedef srtp_hdr_t rtp_hdr_t;
|
||||
|
||||
|
@ -160,16 +165,31 @@ static void handle_ice(switch_rtp *rtp_session, void *data, switch_size_t len)
|
|||
}
|
||||
|
||||
|
||||
static void init_rtp(void)
|
||||
SWITCH_DECLARE(void) switch_rtp_init(switch_memory_pool *pool)
|
||||
{
|
||||
if (global_init) {
|
||||
return;
|
||||
}
|
||||
|
||||
srtp_init();
|
||||
switch_mutex_init(&port_lock, SWITCH_MUTEX_NESTED, pool);
|
||||
global_init = 1;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_port_t) switch_rtp_request_port(void)
|
||||
{
|
||||
switch_port_t port;
|
||||
|
||||
switch_mutex_lock(port_lock);
|
||||
port = NEXT_PORT;
|
||||
NEXT_PORT += 2;
|
||||
if (port > RTP_END_PORT) {
|
||||
port = RTP_START_PORT;
|
||||
}
|
||||
switch_mutex_unlock(port_lock);
|
||||
return port;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_rtp *)switch_rtp_new(char *rx_ip,
|
||||
switch_port_t rx_port,
|
||||
char *tx_ip,
|
||||
|
@ -187,9 +207,6 @@ SWITCH_DECLARE(switch_rtp *)switch_rtp_new(char *rx_ip,
|
|||
char key[MAX_KEY_LEN];
|
||||
uint32_t ssrc = rand() & 0xffff;
|
||||
|
||||
if (!global_init) {
|
||||
init_rtp();
|
||||
}
|
||||
|
||||
if (switch_sockaddr_info_get(&rx_addr, rx_ip, SWITCH_UNSPEC, rx_port, 0, pool) != SWITCH_STATUS_SUCCESS) {
|
||||
*err = "RX Address Error!";
|
||||
|
@ -281,6 +298,12 @@ SWITCH_DECLARE(switch_status) switch_rtp_activate_ice(switch_rtp *rtp_session, c
|
|||
rtp_session->ice_user = switch_core_strdup(rtp_session->pool, ice_user);
|
||||
rtp_session->user_ice = switch_core_strdup(rtp_session->pool, user_ice);
|
||||
|
||||
if (rtp_session->ice_user) {
|
||||
if (ice_out(rtp_session) != SWITCH_STATUS_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -319,7 +342,7 @@ SWITCH_DECLARE(int) switch_rtp_read(switch_rtp *rtp_session, void *data, uint32_
|
|||
bytes = sizeof(rtp_msg_t);
|
||||
|
||||
switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock, 0, (void *)&rtp_session->recv_msg, &bytes);
|
||||
|
||||
|
||||
if (bytes <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -266,3 +266,105 @@ SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_username(switch_stun_pa
|
|||
packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
|
||||
return 1;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status) switch_stun_lookup (char **ip,
|
||||
switch_port_t *port,
|
||||
char *stunip,
|
||||
switch_port_t stunport,
|
||||
char **err,
|
||||
switch_memory_pool *pool)
|
||||
|
||||
{
|
||||
switch_sockaddr_t *local_addr = NULL, *remote_addr = NULL, *from_addr = NULL;
|
||||
switch_socket_t *sock = NULL;
|
||||
uint8_t buf[256] = {0};
|
||||
switch_stun_packet_t *packet;
|
||||
switch_stun_packet_attribute_t *attr;
|
||||
switch_size_t bytes = 0;
|
||||
char username[33] = {0};
|
||||
char rip[16];
|
||||
uint16_t rport = 0;
|
||||
switch_time_t started = 0;
|
||||
unsigned int elapsed = 0;
|
||||
|
||||
*err = "Success";
|
||||
|
||||
switch_sockaddr_info_get(&from_addr, NULL, SWITCH_UNSPEC, 0, 0, pool);
|
||||
|
||||
if (switch_sockaddr_info_get(&local_addr, *ip, SWITCH_UNSPEC, *port, 0, pool) != SWITCH_STATUS_SUCCESS) {
|
||||
*err = "Local Address Error!";
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (switch_sockaddr_info_get(&remote_addr, stunip, SWITCH_UNSPEC, stunport, 0, pool) != SWITCH_STATUS_SUCCESS) {
|
||||
*err = "Remote Address Error!";
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (switch_socket_create(&sock, AF_INET, SOCK_DGRAM, 0, pool) != SWITCH_STATUS_SUCCESS) {
|
||||
*err = "Socket Error!";
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (switch_socket_bind(sock, local_addr) != SWITCH_STATUS_SUCCESS) {
|
||||
*err = "Bind Error!";
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
switch_socket_opt_set(sock, APR_SO_NONBLOCK, TRUE);
|
||||
packet = switch_stun_packet_build_header(SWITCH_STUN_BINDING_REQUEST, NULL, buf);
|
||||
switch_stun_random_string(username, 32, NULL);
|
||||
switch_stun_packet_attribute_add_username(packet, username, 32);
|
||||
bytes = switch_stun_packet_length(packet);
|
||||
switch_socket_sendto(sock, remote_addr, 0, (void *)packet, &bytes);
|
||||
started = switch_time_now();
|
||||
|
||||
*ip = NULL;
|
||||
*port = 0;
|
||||
|
||||
|
||||
for(;;) {
|
||||
bytes = sizeof(buf);
|
||||
if (switch_socket_recvfrom(from_addr, sock, 0, (char *)&buf, &bytes) == SWITCH_STATUS_SUCCESS && bytes > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((elapsed = (unsigned int)((switch_time_now() - started) / 1000)) > 5000) {
|
||||
*err = "Timeout";
|
||||
switch_socket_shutdown(sock, APR_SHUTDOWN_READWRITE);
|
||||
switch_socket_close(sock);
|
||||
return SWITCH_STATUS_TIMEOUT;
|
||||
}
|
||||
switch_yield(1000);
|
||||
}
|
||||
switch_socket_close(sock);
|
||||
|
||||
packet = switch_stun_packet_parse(buf, sizeof(buf));
|
||||
switch_stun_packet_first_attribute(packet, attr);
|
||||
|
||||
do {
|
||||
switch(attr->type) {
|
||||
case SWITCH_STUN_ATTR_MAPPED_ADDRESS:
|
||||
if (attr->type) {
|
||||
switch_stun_packet_attribute_get_mapped_address(attr, rip, &rport);
|
||||
}
|
||||
break;
|
||||
case SWITCH_STUN_ATTR_USERNAME:
|
||||
if(attr->type) {
|
||||
switch_stun_packet_attribute_get_username(attr, username, 32);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (switch_stun_packet_next_attribute(attr));
|
||||
|
||||
if (packet->header.type == SWITCH_STUN_BINDING_RESPONSE) {
|
||||
*ip = switch_core_strdup(pool, rip);
|
||||
*port = rport;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
} else {
|
||||
*err = "Invalid Reply";
|
||||
}
|
||||
|
||||
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue