diff --git a/tester/Makefile.am b/tester/Makefile.am index 4012b83e2..f1d5f1f8e 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -14,7 +14,8 @@ liblinphone_tester_SOURCES= liblinphone_tester.c liblinphone_tester.h\ presence_tester.c \ upnp_tester.c \ eventapi_tester.c \ - flexisip_tester.c + flexisip_tester.c \ + stun_tester.c #liblinphone_tester_CFLAGS=$(CUNIT_CFLAGS) diff --git a/tester/liblinphone_tester.c b/tester/liblinphone_tester.c index 67a0416c1..dc844e539 100644 --- a/tester/liblinphone_tester.c +++ b/tester/liblinphone_tester.c @@ -7,13 +7,13 @@ the Free Software Foundation, either version 2 of the License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include @@ -53,7 +53,7 @@ const char *userhostsfile = "tester_hosts"; #ifdef ANDROID extern void AndroidPrintf(FILE *stream, const char *fmt, ...); -#define fprintf(file, fmt, ...) AndroidPrintf(file, fmt, ##__VA_ARGS__) +#define fprintf(file, fmt, ...) AndroidPrintf(file, fmt, ##__VA_ARGS__) #endif @@ -94,14 +94,14 @@ static LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* char rootcapath[256]={0}; char dnsuserhostspath[256]={0}; char nowebcampath[256]={0}; - + if (path==NULL) path="."; if (file){ sprintf(filepath, "%s/%s", path, file); CU_ASSERT_TRUE_FATAL(ortp_file_exist(filepath)==0); } - + lc = linphone_core_new(v_table,NULL,*filepath!='\0' ? filepath : NULL,NULL); sal_enable_test_features(lc->sal,TRUE); @@ -182,7 +182,7 @@ LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, int check_f LinphoneProxyConfig* proxy; int proxy_count; int retry=0; - + mgr->v_table.registration_state_changed=registration_state_changed; mgr->v_table.auth_info_requested=auth_info_requested; mgr->v_table.call_state_changed=call_state_changed; @@ -211,7 +211,7 @@ LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, int check_f } CU_ASSERT_EQUAL(mgr->stat.number_of_LinphoneRegistrationOk,proxy_count); enable_codec(mgr->lc,"PCMU",8000); - + linphone_core_get_default_proxy(mgr->lc,&proxy); if (proxy) { mgr->identity = linphone_address_new(linphone_proxy_config_get_identity(proxy)); @@ -277,7 +277,7 @@ static int test_suite_index(const char *suite_name) { static int test_index(const char *suite_name, const char *test_name) { int j,i; - + j = test_suite_index(suite_name); if(j != -1) { for (i = 0; i < test_suite[j]->nb_tests; i++) { @@ -321,6 +321,7 @@ void liblinphone_tester_init(void) { #ifdef UPNP add_test_suite(&upnp_test_suite); #endif + add_test_suite(&stun_test_suite); add_test_suite(&event_test_suite); add_test_suite(&flexisip_test_suite); } @@ -444,7 +445,7 @@ int main (int argc, char *argv[]) { int ret; const char *suite_name=NULL; const char *test_name=NULL; - + liblinphone_tester_init(); for(i=1;iDeleteLocalRef(env,javaString); } -JNIEXPORT +JNIEXPORT JNIEXPORT jint JNICALL Java_org_linphone_tester_Tester_run(JNIEnv *env, jobject obj, jobjectArray stringArray) { int i, ret; diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h index ec8d2b6dc..b2987a408 100644 --- a/tester/liblinphone_tester.h +++ b/tester/liblinphone_tester.h @@ -7,13 +7,13 @@ the Free Software Foundation, either version 2 of the License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ @@ -54,6 +54,7 @@ extern test_suite_t presence_test_suite; extern test_suite_t upnp_test_suite; extern test_suite_t event_test_suite; extern test_suite_t flexisip_test_suite; +extern test_suite_t stun_test_suite; extern int liblinphone_tester_nb_test_suites(void); @@ -155,7 +156,7 @@ typedef struct _stats { int number_of_LinphonePresenceActivityWorking; int number_of_LinphonePresenceActivityWorship; const LinphonePresenceModel *last_received_presence; - + int number_of_inforeceived; LinphoneInfoMessage* last_received_info_message; diff --git a/tester/stun_rc b/tester/stun_rc new file mode 100644 index 000000000..954a83b6c --- /dev/null +++ b/tester/stun_rc @@ -0,0 +1,2 @@ + [net] + firewall_policy=2 diff --git a/tester/stun_tester.c b/tester/stun_tester.c new file mode 100644 index 000000000..b5757b547 --- /dev/null +++ b/tester/stun_tester.c @@ -0,0 +1,116 @@ +/* + belle-sip - SIP (RFC3261) library. + Copyright (C) 2014 Belledonne Communications SARL + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include "CUnit/Basic.h" +#include "linphonecore.h" +#include "private.h" +#include "liblinphone_tester.h" +#include "ortp/stun.h" +#include "ortp/port.h" + + +static const char* stun_address = "stun.linphone.org"; + + +static int test_stun_encode( char*buffer, size_t len, bool_t expect_fail ) +{ + 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, 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 len; +} + + +static void linphone_stun_test_encode() +{ + 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); + CU_ASSERT(len == -1); + + len = test_stun_encode(bigBuff, bigLen, TRUE); + CU_ASSERT(len > 0); + ms_message("STUN message encoded in %d bytes", len); +} + + +static void linphone_stun_test_grab_ip() +{ + LinphoneCoreManager* lc_stun = linphone_core_manager_new2( "stun_rc", FALSE); + LinphoneCall dummy_call; + int ping_time; + int tmp=0; + + memset(&dummy_call, 0, sizeof(LinphoneCall)); + dummy_call.audio_port = 7078; + dummy_call.audio_port = 9078; + + linphone_core_set_stun_server(lc_stun->lc, stun_address); + CU_ASSERT_STRING_EQUAL(stun_address, linphone_core_get_stun_server(lc_stun->lc)); + + wait_for(lc_stun->lc,lc_stun->lc,&tmp,1); + + ping_time = linphone_core_run_stun_tests(lc_stun->lc, &dummy_call); + CU_ASSERT(ping_time != -1); + + ms_message("Round trip to STUN: %d ms", ping_time); + + CU_ASSERT( dummy_call.ac.addr[0] != '\0'); + CU_ASSERT( dummy_call.ac.port != 0); + CU_ASSERT( dummy_call.vc.addr[0] != '\0'); + CU_ASSERT( dummy_call.vc.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 video port maps to %s:%i", + dummy_call.vc.addr, + dummy_call.vc.port); + + linphone_core_manager_destroy(lc_stun); +} + + +test_t stun_tests[] = { + { "Basic Stun test (Ping/public IP)", linphone_stun_test_grab_ip }, + { "STUN encode buffer protection", linphone_stun_test_encode }, +}; + +test_suite_t stun_test_suite = { + "Stun", + NULL, + NULL, + sizeof(stun_tests) / sizeof(stun_tests[0]), + stun_tests +};