mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-30 09:49:26 +00:00
Use new STUN API.
This commit is contained in:
parent
56ca16c58a
commit
3030d9a9c9
2 changed files with 86 additions and 110 deletions
125
coreapi/misc.c
125
coreapi/misc.c
|
|
@ -317,28 +317,30 @@ static ortp_socket_t create_socket(int local_port){
|
|||
return sock;
|
||||
}
|
||||
|
||||
static int sendStunRequest(int sock, const struct sockaddr *server, socklen_t addrlen, int id, bool_t changeAddr){
|
||||
char buf[STUN_MAX_MESSAGE_SIZE];
|
||||
int len = STUN_MAX_MESSAGE_SIZE;
|
||||
StunAtrString username;
|
||||
StunAtrString password;
|
||||
StunMessage req;
|
||||
int err;
|
||||
memset(&req, 0, sizeof(StunMessage));
|
||||
memset(&username,0,sizeof(username));
|
||||
memset(&password,0,sizeof(password));
|
||||
stunBuildReqSimple( &req, &username, changeAddr , changeAddr , id);
|
||||
len = stunEncodeMessage( &req, buf, len, &password);
|
||||
if (len<=0){
|
||||
static int send_stun_request(int sock, const struct sockaddr *server, socklen_t addrlen, int id, bool_t change_addr){
|
||||
char *buf = NULL;
|
||||
int len;
|
||||
int err = 0;
|
||||
MSStunMessage *req = ms_stun_binding_request_create();
|
||||
UInt96 tr_id = ms_stun_message_get_tr_id(req);
|
||||
tr_id.octet[0] = id;
|
||||
ms_stun_message_set_tr_id(req, tr_id);
|
||||
ms_stun_message_enable_change_ip(req, change_addr);
|
||||
ms_stun_message_enable_change_port(req, change_addr);
|
||||
len = ms_stun_message_encode(req, &buf);
|
||||
if (len <= 0) {
|
||||
ms_error("Fail to encode stun message.");
|
||||
return -1;
|
||||
err = -1;
|
||||
} else {
|
||||
err = sendto(sock, buf, len, 0, server, addrlen);
|
||||
if (err < 0) {
|
||||
ms_error("sendto failed: %s",strerror(errno));
|
||||
err = -1;
|
||||
}
|
||||
}
|
||||
err=sendto(sock,buf,len,0,server,addrlen);
|
||||
if (err<0){
|
||||
ms_error("sendto failed: %s",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
if (buf != NULL) ms_free(buf);
|
||||
ms_free(req);
|
||||
return err;
|
||||
}
|
||||
|
||||
int linphone_parse_host_port(const char *input, char *host, size_t hostlen, int *port){
|
||||
|
|
@ -387,23 +389,32 @@ int parse_hostname_to_addr(const char *server, struct sockaddr_storage *ss, sock
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int recvStunResponse(ortp_socket_t sock, char *ipaddr, int *port, int *id){
|
||||
char buf[STUN_MAX_MESSAGE_SIZE];
|
||||
int len = STUN_MAX_MESSAGE_SIZE;
|
||||
StunMessage resp;
|
||||
len=recv(sock,buf,len,0);
|
||||
if (len>0){
|
||||
static int recv_stun_response(ortp_socket_t sock, char *ipaddr, int *port, int *id) {
|
||||
char buf[MS_STUN_MAX_MESSAGE_SIZE];
|
||||
int len = MS_STUN_MAX_MESSAGE_SIZE;
|
||||
MSStunMessage *resp;
|
||||
|
||||
len = recv(sock, buf, len, 0);
|
||||
if (len > 0) {
|
||||
struct in_addr ia;
|
||||
stunParseMessage(buf,len, &resp );
|
||||
*id=resp.msgHdr.tr_id.octet[0];
|
||||
if (resp.hasXorMappedAddress){
|
||||
*port = resp.xorMappedAddress.ipv4.port;
|
||||
ia.s_addr=htonl(resp.xorMappedAddress.ipv4.addr);
|
||||
}else if (resp.hasMappedAddress){
|
||||
*port = resp.mappedAddress.ipv4.port;
|
||||
ia.s_addr=htonl(resp.mappedAddress.ipv4.addr);
|
||||
}else return -1;
|
||||
strncpy(ipaddr,inet_ntoa(ia),LINPHONE_IPADDR_SIZE);
|
||||
resp = ms_stun_message_create_from_buffer_parsing(buf, len);
|
||||
if (resp != NULL) {
|
||||
const MSStunAddress *stun_addr;
|
||||
UInt96 tr_id = ms_stun_message_get_tr_id(resp);
|
||||
*id = tr_id.octet[0];
|
||||
stun_addr = ms_stun_message_get_xor_mapped_address(resp);
|
||||
if (stun_addr != NULL) {
|
||||
*port = stun_addr->ipv4.port;
|
||||
ia.s_addr = htonl(stun_addr->ipv4.addr);
|
||||
} else {
|
||||
stun_addr = ms_stun_message_get_mapped_address(resp);
|
||||
if (stun_addr != NULL) {
|
||||
*port = stun_addr->ipv4.port;
|
||||
ia.s_addr = htonl(stun_addr->ipv4.addr);
|
||||
} else len = -1;
|
||||
}
|
||||
if (len > 0) strncpy(ipaddr, inet_ntoa(ia), LINPHONE_IPADDR_SIZE);
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
|
@ -459,44 +470,32 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){
|
|||
int id;
|
||||
if (loops%20==0){
|
||||
ms_message("Sending stun requests...");
|
||||
sendStunRequest((int)sock1,ai->ai_addr,(socklen_t)ai->ai_addrlen,11,TRUE);
|
||||
sendStunRequest((int)sock1,ai->ai_addr,(socklen_t)ai->ai_addrlen,1,FALSE);
|
||||
send_stun_request((int)sock1,ai->ai_addr,(socklen_t)ai->ai_addrlen,11,TRUE);
|
||||
send_stun_request((int)sock1,ai->ai_addr,(socklen_t)ai->ai_addrlen,1,FALSE);
|
||||
if (sock2!=-1){
|
||||
sendStunRequest((int)sock2,ai->ai_addr,(socklen_t)ai->ai_addrlen,22,TRUE);
|
||||
sendStunRequest((int)sock2,ai->ai_addr,(socklen_t)ai->ai_addrlen,2,FALSE);
|
||||
send_stun_request((int)sock2,ai->ai_addr,(socklen_t)ai->ai_addrlen,22,TRUE);
|
||||
send_stun_request((int)sock2,ai->ai_addr,(socklen_t)ai->ai_addrlen,2,FALSE);
|
||||
}
|
||||
if (sock3!=-1){
|
||||
sendStunRequest((int)sock3,ai->ai_addr,(socklen_t)ai->ai_addrlen,33,TRUE);
|
||||
sendStunRequest((int)sock3,ai->ai_addr,(socklen_t)ai->ai_addrlen,3,FALSE);
|
||||
send_stun_request((int)sock3,ai->ai_addr,(socklen_t)ai->ai_addrlen,33,TRUE);
|
||||
send_stun_request((int)sock3,ai->ai_addr,(socklen_t)ai->ai_addrlen,3,FALSE);
|
||||
}
|
||||
}
|
||||
ms_usleep(10000);
|
||||
|
||||
if (recvStunResponse(sock1,ac->addr,
|
||||
&ac->port,&id)>0){
|
||||
ms_message("STUN test result: local audio port maps to %s:%i",
|
||||
ac->addr,
|
||||
ac->port);
|
||||
if (id==11)
|
||||
cone_audio=TRUE;
|
||||
if (recv_stun_response(sock1, ac->addr, &ac->port, &id) > 0) {
|
||||
ms_message("STUN test result: local audio port maps to %s:%i", ac->addr, ac->port);
|
||||
if (id==11) cone_audio=TRUE;
|
||||
got_audio=TRUE;
|
||||
}
|
||||
if (recvStunResponse(sock2,vc->addr,
|
||||
&vc->port,&id)>0){
|
||||
ms_message("STUN test result: local video port maps to %s:%i",
|
||||
vc->addr,
|
||||
vc->port);
|
||||
if (id==22)
|
||||
cone_video=TRUE;
|
||||
if (recv_stun_response(sock2, vc->addr, &vc->port, &id) > 0) {
|
||||
ms_message("STUN test result: local video port maps to %s:%i", vc->addr, vc->port);
|
||||
if (id==22) cone_video=TRUE;
|
||||
got_video=TRUE;
|
||||
}
|
||||
if (recvStunResponse(sock3,tc->addr,
|
||||
&tc->port,&id)>0){
|
||||
ms_message("STUN test result: local text port maps to %s:%i",
|
||||
tc->addr,
|
||||
tc->port);
|
||||
if (id==33)
|
||||
cone_text=TRUE;
|
||||
if (recv_stun_response(sock3, tc->addr, &tc->port, &id)>0) {
|
||||
ms_message("STUN test result: local text port maps to %s:%i", tc->addr, tc->port);
|
||||
if (id==33) cone_text=TRUE;
|
||||
got_text=TRUE;
|
||||
}
|
||||
ortp_gettimeofday(&cur,NULL);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "linphonecore.h"
|
||||
#include "private.h"
|
||||
#include "liblinphone_tester.h"
|
||||
|
|
@ -24,52 +23,36 @@
|
|||
#include "ortp/port.h"
|
||||
|
||||
|
||||
static const char* stun_address = "stun.linphone.org";
|
||||
static const char *stun_address = "stun.linphone.org";
|
||||
|
||||
|
||||
static int test_stun_encode( char*buffer, size_t len, bool_t expect_fail )
|
||||
static size_t test_stun_encode(char **buffer)
|
||||
{
|
||||
StunAtrString username;
|
||||
StunAtrString password;
|
||||
StunMessage req;
|
||||
memset(&req, 0, sizeof(StunMessage));
|
||||
memset(&username,0,sizeof(username));
|
||||
memset(&password,0,sizeof(password));
|
||||
stunBuildReqSimple( &req, &username, TRUE , TRUE , 11);
|
||||
len = stunEncodeMessage( &req, buffer, (unsigned int)len, &password);
|
||||
if (len<=0){
|
||||
if( expect_fail )
|
||||
ms_message("Fail to encode stun message (EXPECTED).\n");
|
||||
else
|
||||
ms_error("Fail to encode stun message.\n");
|
||||
return -1;
|
||||
}
|
||||
return (int)len;
|
||||
MSStunMessage *req = ms_stun_binding_request_create();
|
||||
UInt96 tr_id = ms_stun_message_get_tr_id(req);
|
||||
tr_id.octet[0] = 11;
|
||||
ms_stun_message_set_tr_id(req, tr_id);
|
||||
return ms_stun_message_encode(req, buffer);
|
||||
}
|
||||
|
||||
|
||||
static void linphone_stun_test_encode(void)
|
||||
{
|
||||
char smallBuff[12];
|
||||
size_t smallLen = 12;
|
||||
char bigBuff[STUN_MAX_MESSAGE_SIZE];
|
||||
size_t bigLen = STUN_MAX_MESSAGE_SIZE;
|
||||
|
||||
size_t len = test_stun_encode(smallBuff, smallLen, TRUE);
|
||||
BC_ASSERT(len == -1);
|
||||
|
||||
len = test_stun_encode(bigBuff, bigLen, TRUE);
|
||||
char *buffer = NULL;
|
||||
size_t len = test_stun_encode(&buffer);
|
||||
BC_ASSERT(len > 0);
|
||||
BC_ASSERT_PTR_NOT_NULL(buffer);
|
||||
if (buffer != NULL) ms_free(buffer);
|
||||
ms_message("STUN message encoded in %i bytes", (int)len);
|
||||
}
|
||||
|
||||
|
||||
static void linphone_stun_test_grab_ip(void)
|
||||
{
|
||||
LinphoneCoreManager* lc_stun = linphone_core_manager_new2( "stun_rc", FALSE);
|
||||
LinphoneCoreManager* lc_stun = linphone_core_manager_new2("stun_rc", FALSE);
|
||||
LinphoneCall dummy_call;
|
||||
int ping_time;
|
||||
int tmp=0;
|
||||
int tmp = 0;
|
||||
|
||||
memset(&dummy_call, 0, sizeof(LinphoneCall));
|
||||
dummy_call.main_audio_stream_index = 0;
|
||||
|
|
@ -82,33 +65,27 @@ static void linphone_stun_test_grab_ip(void)
|
|||
linphone_core_set_stun_server(lc_stun->lc, stun_address);
|
||||
BC_ASSERT_STRING_EQUAL(stun_address, linphone_core_get_stun_server(lc_stun->lc));
|
||||
|
||||
wait_for(lc_stun->lc,lc_stun->lc,&tmp,1);
|
||||
wait_for(lc_stun->lc, lc_stun->lc, &tmp, 1);
|
||||
|
||||
ping_time = linphone_core_run_stun_tests(lc_stun->lc, &dummy_call);
|
||||
BC_ASSERT(ping_time != -1);
|
||||
|
||||
ms_message("Round trip to STUN: %d ms", ping_time);
|
||||
|
||||
BC_ASSERT( dummy_call.ac.addr[0] != '\0');
|
||||
BC_ASSERT( dummy_call.ac.port != 0);
|
||||
BC_ASSERT(dummy_call.ac.addr[0] != '\0');
|
||||
BC_ASSERT(dummy_call.ac.port != 0);
|
||||
#ifdef VIDEO_ENABLED
|
||||
BC_ASSERT( dummy_call.vc.addr[0] != '\0');
|
||||
BC_ASSERT( dummy_call.vc.port != 0);
|
||||
BC_ASSERT(dummy_call.vc.addr[0] != '\0');
|
||||
BC_ASSERT(dummy_call.vc.port != 0);
|
||||
#endif
|
||||
BC_ASSERT( dummy_call.tc.addr[0] != '\0');
|
||||
BC_ASSERT( dummy_call.tc.port != 0);
|
||||
BC_ASSERT(dummy_call.tc.addr[0] != '\0');
|
||||
BC_ASSERT(dummy_call.tc.port != 0);
|
||||
|
||||
ms_message("STUN test result: local audio port maps to %s:%i",
|
||||
dummy_call.ac.addr,
|
||||
dummy_call.ac.port);
|
||||
ms_message("STUN test result: local audio port maps to %s:%i", dummy_call.ac.addr, dummy_call.ac.port);
|
||||
#ifdef VIDEO_ENABLED
|
||||
ms_message("STUN test result: local video port maps to %s:%i",
|
||||
dummy_call.vc.addr,
|
||||
dummy_call.vc.port);
|
||||
ms_message("STUN test result: local video port maps to %s:%i", dummy_call.vc.addr, dummy_call.vc.port);
|
||||
#endif
|
||||
ms_message("STUN test result: local text port maps to %s:%i",
|
||||
dummy_call.tc.addr,
|
||||
dummy_call.tc.port);
|
||||
ms_message("STUN test result: local text port maps to %s:%i", dummy_call.tc.addr, dummy_call.tc.port);
|
||||
|
||||
linphone_core_manager_destroy(lc_stun);
|
||||
}
|
||||
|
|
@ -116,7 +93,7 @@ static void linphone_stun_test_grab_ip(void)
|
|||
|
||||
test_t stun_tests[] = {
|
||||
TEST_NO_TAG("Basic Stun test (Ping/public IP)", linphone_stun_test_grab_ip),
|
||||
TEST_NO_TAG("STUN encode buffer protection", linphone_stun_test_encode)
|
||||
TEST_NO_TAG("STUN encode", linphone_stun_test_encode)
|
||||
};
|
||||
|
||||
test_suite_t stun_test_suite = {"Stun", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue