From 3030d9a9c90a0b4bf45e3986fdeabd571284d4bc Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 30 Mar 2016 14:10:58 +0200 Subject: [PATCH] Use new STUN API. --- coreapi/misc.c | 125 +++++++++++++++++++++---------------------- tester/stun_tester.c | 71 +++++++++--------------- 2 files changed, 86 insertions(+), 110 deletions(-) diff --git a/coreapi/misc.c b/coreapi/misc.c index 835acb6e9..65bf11ad5 100644 --- a/coreapi/misc.c +++ b/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); diff --git a/tester/stun_tester.c b/tester/stun_tester.c index e52927386..bccd747ac 100644 --- a/tester/stun_tester.c +++ b/tester/stun_tester.c @@ -16,7 +16,6 @@ along with this program. If not, see . */ - #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,