register_tester.c 16.1 KB
Newer Older
jehan's avatar
jehan committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
	belle-sip - SIP (RFC3261) library.
    Copyright (C) 2010  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 <http://www.gnu.org/licenses/>.
*/
Ghislain MARY's avatar
Ghislain MARY committed
18

jehan's avatar
jehan committed
19 20 21 22 23 24 25 26 27 28 29 30 31
#include <stdio.h>
#include "CUnit/Basic.h"
#include "linphonecore.h"
#include "private.h"
#include "liblinphone_tester.h"



static LinphoneCore* create_lc() {
	return create_lc_with_auth(0);
}

void registration_state_changed(struct _LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char *message){
32
		stats* counters;
jehan's avatar
jehan committed
33 34 35 36
		ms_message("New registration state %s for user id [%s] at proxy [%s]\n"
				,linphone_registration_state_to_string(cstate)
				,linphone_proxy_config_get_identity(cfg)
				,linphone_proxy_config_get_addr(cfg));
37
		counters = (stats*)linphone_core_get_user_data(lc);
jehan's avatar
jehan committed
38 39 40 41 42 43 44 45 46 47 48
		switch (cstate) {
		case LinphoneRegistrationNone:counters->number_of_LinphoneRegistrationNone++;break;
		case LinphoneRegistrationProgress:counters->number_of_LinphoneRegistrationProgress++;break;
		case LinphoneRegistrationOk:counters->number_of_LinphoneRegistrationOk++;break;
		case LinphoneRegistrationCleared:counters->number_of_LinphoneRegistrationCleared++;break;
		case LinphoneRegistrationFailed:counters->number_of_LinphoneRegistrationFailed++;break;
		default:
			CU_FAIL("unexpected event");break;
		}

}
Ghislain MARY's avatar
Ghislain MARY committed
49

50
static void register_with_refresh_base_2(LinphoneCore* lc, bool_t refresh,const char* domain,const char* route,bool_t late_auth_info,LCSipTransports transport) {
jehan's avatar
jehan committed
51
	int retry=0;
Simon Morlat's avatar
Simon Morlat committed
52
	char* addr;
53 54 55 56 57 58
	LinphoneProxyConfig* proxy_cfg;
	stats* counters;
	LinphoneAddress *from;
	const char* server_addr;
	LinphoneAuthInfo *info;

jehan's avatar
jehan committed
59 60
	CU_ASSERT_PTR_NOT_NULL(lc);
	if (!lc) return;
61
	counters = (stats*)linphone_core_get_user_data(lc);
jehan's avatar
jehan committed
62 63 64 65 66
	reset_counters(counters);
	linphone_core_set_sip_transports(lc,&transport);

	proxy_cfg = linphone_proxy_config_new();

67
	from = create_linphone_address(domain);
jehan's avatar
jehan committed
68

69 70
	linphone_proxy_config_set_identity(proxy_cfg,addr=linphone_address_as_string(from));
	ms_free(addr);
71
	server_addr = linphone_address_get_domain(from);
jehan's avatar
jehan committed
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87

	linphone_proxy_config_enable_register(proxy_cfg,TRUE);
	linphone_proxy_config_expires(proxy_cfg,1);
	if (route) {
		linphone_proxy_config_set_route(proxy_cfg,route);
		linphone_proxy_config_set_server_addr(proxy_cfg,route);
	} else {
		linphone_proxy_config_set_server_addr(proxy_cfg,server_addr);
	}
	linphone_address_destroy(from);

	linphone_core_add_proxy_config(lc,proxy_cfg);
	linphone_core_set_default_proxy(lc,proxy_cfg);

	while (counters->number_of_LinphoneRegistrationOk<1+(refresh!=0) && retry++ <310) {
		linphone_core_iterate(lc);
jehan's avatar
jehan committed
88
		if (counters->number_of_auth_info_requested>0 && late_auth_info) {
89
			info=linphone_auth_info_new(test_username,NULL,test_password,NULL,auth_domain); /*create authentication structure from identity*/
jehan's avatar
jehan committed
90 91
			linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/
		}
jehan's avatar
jehan committed
92 93
		ms_usleep(100000);
	}
jehan's avatar
jehan committed
94
	CU_ASSERT_TRUE(linphone_proxy_config_is_registered(proxy_cfg));
jehan's avatar
jehan committed
95
	CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationNone,0);
jehan's avatar
jehan committed
96
	CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationProgress,1);
jehan's avatar
jehan committed
97
	CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationOk,1+(refresh!=0));
98
	CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,late_auth_info?1:0);
jehan's avatar
jehan committed
99 100 101
	CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationCleared,0);

}
Ghislain MARY's avatar
Ghislain MARY committed
102

jehan's avatar
jehan committed
103
static void register_with_refresh_base(LinphoneCore* lc, bool_t refresh,const char* domain,const char* route) {
104 105
	LCSipTransports transport = {5070,5070,0,5071};
	register_with_refresh_base_2(lc,refresh,domain,route,FALSE,transport);
jehan's avatar
jehan committed
106
}
Ghislain MARY's avatar
Ghislain MARY committed
107

jehan's avatar
jehan committed
108 109 110 111 112 113 114 115 116
static void register_with_refresh(LinphoneCore* lc, bool_t refresh,const char* domain,const char* route) {
	stats* counters = (stats*)linphone_core_get_user_data(lc);
	register_with_refresh_base(lc,refresh,domain,route);
	linphone_core_destroy(lc);
	CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationCleared,1);


}

117
static void register_with_refresh_with_send_error() {
jehan's avatar
jehan committed
118 119 120 121
	int retry=0;
	LinphoneCore* lc = create_lc_with_auth(1);
	stats* counters = (stats*)linphone_core_get_user_data(lc);
	LinphoneAuthInfo *info=linphone_auth_info_new(test_username,NULL,test_password,NULL,auth_domain); /*create authentication structure from identity*/
122 123
	char route[256];
	sprintf(route,"sip:%s",test_route);
jehan's avatar
jehan committed
124 125
	linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/

126
	register_with_refresh_base(lc,TRUE,auth_domain,route);
jehan's avatar
jehan committed
127 128 129 130 131 132 133 134 135 136 137 138
	/*simultate a network error*/
	sal_set_send_error(lc->sal, -1);
	while (counters->number_of_LinphoneRegistrationFailed<1 && retry++ <20) {
			linphone_core_iterate(lc);
			ms_usleep(100000);
	}
	CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,1);
	linphone_core_destroy(lc);

	CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationCleared,0);

}
Ghislain MARY's avatar
Ghislain MARY committed
139

jehan's avatar
jehan committed
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
static void simple_register(){
	LinphoneCore* lc = create_lc();
	stats* counters = (stats*)linphone_core_get_user_data(lc);
	register_with_refresh(lc,FALSE,NULL,NULL);
	CU_ASSERT_EQUAL(counters->number_of_auth_info_requested,0);
}

/*take care of min expires configuration from server*/
static void simple_register_with_refresh() {
	LinphoneCore* lc = create_lc();
	stats* counters = (stats*)linphone_core_get_user_data(lc);
	register_with_refresh(lc,TRUE,NULL,NULL);
	CU_ASSERT_EQUAL(counters->number_of_auth_info_requested,0);
}

static void simple_auth_register_with_refresh() {
	LinphoneCore* lc = create_lc_with_auth(1);
	stats* counters = (stats*)linphone_core_get_user_data(lc);
158 159 160
	char route[256];
	sprintf(route,"sip:%s",test_route);
	register_with_refresh(lc,TRUE,auth_domain,route);
jehan's avatar
jehan committed
161 162 163 164 165
	CU_ASSERT_EQUAL(counters->number_of_auth_info_requested,1);
}

static void simple_tcp_register(){
	char route[256];
166
	LinphoneCore* lc;
167
	sprintf(route,"sip:%s;transport=tcp",test_route);
168
	lc = create_lc();
169
	register_with_refresh(lc,FALSE,test_domain,route);
jehan's avatar
jehan committed
170
}
Ghislain MARY's avatar
Ghislain MARY committed
171

172
static void simple_tcp_register_compatibility_mode(){
173
	char route[256];
174 175
	LinphoneCore* lc;
	LCSipTransports transport = {0,5070,0,0};
176
	sprintf(route,"sip:%s",test_route);
177
	lc = create_lc();
178
	register_with_refresh_base_2(lc,FALSE,test_domain,route,FALSE,transport);
179 180 181
}


jehan's avatar
jehan committed
182 183
static void simple_tls_register(){
	char route[256];
184
	LinphoneCore* lc;
185
	sprintf(route,"sip:%s;transport=tls",test_route);
186
	lc = create_lc();
187
	register_with_refresh(lc,FALSE,test_domain,route);
jehan's avatar
jehan committed
188 189 190
}

static void simple_authenticated_register(){
191
	stats* counters;
jehan's avatar
jehan committed
192 193
	LinphoneCore* lc = create_lc();
	LinphoneAuthInfo *info=linphone_auth_info_new(test_username,NULL,test_password,NULL,auth_domain); /*create authentication structure from identity*/
194 195
	char route[256];
	sprintf(route,"sip:%s",test_route);
jehan's avatar
jehan committed
196
	linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/
197
	counters = (stats*)linphone_core_get_user_data(lc);
198
	register_with_refresh(lc,FALSE,auth_domain,route);
jehan's avatar
jehan committed
199 200 201
	CU_ASSERT_EQUAL(counters->number_of_auth_info_requested,0);
}

202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
static void ha1_authenticated_register(){
	stats* counters;
	LinphoneCore* lc = create_lc();
	char ha1[33];
	LinphoneAuthInfo *info;
	char route[256];
	sal_auth_compute_ha1(test_username,auth_domain,test_password,ha1);
	info=linphone_auth_info_new(test_username,NULL,NULL,ha1,auth_domain); /*create authentication structure from identity*/
	sprintf(route,"sip:%s",test_route);
	linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/
	counters = (stats*)linphone_core_get_user_data(lc);
	register_with_refresh(lc,FALSE,auth_domain,route);
	CU_ASSERT_EQUAL(counters->number_of_auth_info_requested,0);
}

jehan's avatar
jehan committed
217 218 219 220
static void authenticated_register_with_no_initial_credentials(){
	LinphoneCoreVTable v_table;
	LinphoneCore* lc;
	stats stat;
221
	stats* counters;
222 223
	char route[256];
	sprintf(route,"sip:%s",test_route);
jehan's avatar
jehan committed
224 225 226
	memset (&v_table,0,sizeof(v_table));
	v_table.registration_state_changed=registration_state_changed;
	v_table.auth_info_requested=auth_info_requested;
227
	lc = linphone_core_new(&v_table,NULL,NULL,NULL);
jehan's avatar
jehan committed
228
	linphone_core_set_user_data(lc,&stat);
229
	counters= (stats*)linphone_core_get_user_data(lc);
jehan's avatar
jehan committed
230
	counters->number_of_auth_info_requested=0;
231
	register_with_refresh(lc,FALSE,auth_domain,route);
jehan's avatar
jehan committed
232 233
	CU_ASSERT_EQUAL(counters->number_of_auth_info_requested,1);
}
Ghislain MARY's avatar
Ghislain MARY committed
234

jehan's avatar
jehan committed
235
static void auth_info_requested2(LinphoneCore *lc, const char *realm, const char *username) {
236
	stats* counters;
jehan's avatar
jehan committed
237 238 239
	ms_message("Auth info requested  for user id [%s] at realm [%s]\n"
					,username
					,realm);
240
	counters = (stats*)linphone_core_get_user_data(lc);
jehan's avatar
jehan committed
241 242 243 244 245 246 247
	counters->number_of_auth_info_requested++;
}

static void authenticated_register_with_late_credentials(){
	LinphoneCoreVTable v_table;
	LinphoneCore* lc;
	stats stat;
248
	stats* counters;
249
	LCSipTransports transport = {5070,5070,0,5071};
250 251
	char route[256];
	sprintf(route,"sip:%s",test_route);
jehan's avatar
jehan committed
252 253 254 255 256
	memset (&v_table,0,sizeof(v_table));
	v_table.registration_state_changed=registration_state_changed;
	v_table.auth_info_requested=auth_info_requested2;
	lc =  linphone_core_new(&v_table,NULL,NULL,NULL);
	linphone_core_set_user_data(lc,&stat);
257
	counters = (stats*)linphone_core_get_user_data(lc);
258
	register_with_refresh_base_2(lc,FALSE,auth_domain,route,TRUE,transport);
jehan's avatar
jehan committed
259
	CU_ASSERT_EQUAL(counters->number_of_auth_info_requested,1);
260
	linphone_core_destroy(lc);
jehan's avatar
jehan committed
261
}
jehan's avatar
jehan committed
262 263

static LinphoneCore* configure_lc(LinphoneCoreVTable* v_table) {
264
	return configure_lc_from(v_table, liblinphone_tester_file_prefix, "multi_account_lrc", 3);
jehan's avatar
jehan committed
265 266 267 268 269 270 271 272 273 274 275
}

static void multiple_proxy(){
	LinphoneCoreVTable v_table;
	LinphoneCore* lc;
	memset (&v_table,0,sizeof(LinphoneCoreVTable));
	v_table.registration_state_changed=registration_state_changed;
	lc=configure_lc(&v_table);
	linphone_core_destroy(lc);
}

jehan's avatar
jehan committed
276 277 278 279 280 281 282 283 284 285 286 287
static void network_state_change(){
	LinphoneCoreVTable v_table;
	LinphoneCore* lc;
	int register_ok;
	stats* counters ;

	memset (&v_table,0,sizeof(LinphoneCoreVTable));
	v_table.registration_state_changed=registration_state_changed;
	lc=configure_lc(&v_table);
	counters = (stats*)linphone_core_get_user_data(lc);
	register_ok=counters->number_of_LinphoneRegistrationOk;
	linphone_core_set_network_reachable(lc,FALSE);
jehan's avatar
jehan committed
288
	CU_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_LinphoneRegistrationNone,register_ok));
jehan's avatar
jehan committed
289 290 291 292
	linphone_core_set_network_reachable(lc,TRUE);
	wait_for(lc,lc,&counters->number_of_LinphoneRegistrationOk,2*register_ok);
	linphone_core_destroy(lc);
}
jehan's avatar
jehan committed
293 294 295 296 297 298 299 300 301 302 303
static int get_number_of_udp_proxy(const LinphoneCore* lc) {
	int number_of_udp_proxy=0;
	LinphoneProxyConfig* proxy_cfg;
	MSList* proxys;
	for (proxys=(MSList*)linphone_core_get_proxy_config_list(lc);proxys!=NULL;proxys=proxys->next) {
			proxy_cfg=(LinphoneProxyConfig*)proxys->data;
			if (strcmp("udp",linphone_proxy_config_get_transport(proxy_cfg))==0)
				number_of_udp_proxy++;
	}
	return number_of_udp_proxy;
}
304 305 306 307 308 309 310
static void transport_change(){
	LinphoneCoreVTable v_table;
	LinphoneCore* lc;
	int register_ok;
	stats* counters ;
	LCSipTransports sip_tr;
	LCSipTransports sip_tr_orig;
jehan's avatar
jehan committed
311
	int number_of_udp_proxy=0;
jehan's avatar
jehan committed
312
	int total_number_of_proxies;
jehan's avatar
jehan committed
313
	memset(&sip_tr,0,sizeof(sip_tr));
314 315 316 317 318
	memset (&v_table,0,sizeof(LinphoneCoreVTable));
	v_table.registration_state_changed=registration_state_changed;
	lc=configure_lc(&v_table);
	counters = (stats*)linphone_core_get_user_data(lc);
	register_ok=counters->number_of_LinphoneRegistrationOk;
jehan's avatar
jehan committed
319 320

	number_of_udp_proxy=get_number_of_udp_proxy(lc);
jehan's avatar
jehan committed
321
	total_number_of_proxies=ms_list_size(linphone_core_get_proxy_config_list(lc));
322
	linphone_core_get_sip_transports(lc,&sip_tr_orig);
jehan's avatar
jehan committed
323

324 325 326 327
	sip_tr.udp_port=sip_tr_orig.udp_port;

	/*keep only udp*/
	linphone_core_set_sip_transports(lc,&sip_tr);
jehan's avatar
jehan committed
328
	CU_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_LinphoneRegistrationOk,register_ok+number_of_udp_proxy));
329

jehan's avatar
jehan committed
330
	CU_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_LinphoneRegistrationFailed,register_ok+(total_number_of_proxies-number_of_udp_proxy)));
331 332 333 334

	linphone_core_destroy(lc);
}

jehan's avatar
jehan committed
335 336 337 338 339
static void io_recv_error(){
	LinphoneCoreVTable v_table;
	LinphoneCore* lc;
	int register_ok;
	stats* counters ;
jehan's avatar
jehan committed
340
	int number_of_udp_proxy=0;
jehan's avatar
jehan committed
341 342 343 344 345 346

	memset (&v_table,0,sizeof(LinphoneCoreVTable));
	v_table.registration_state_changed=registration_state_changed;
	lc=configure_lc(&v_table);
	counters = (stats*)linphone_core_get_user_data(lc);
	register_ok=counters->number_of_LinphoneRegistrationOk;
jehan's avatar
jehan committed
347
	number_of_udp_proxy=get_number_of_udp_proxy(lc);
jehan's avatar
jehan committed
348 349
	sal_set_recv_error(lc->sal, 0);

jehan's avatar
jehan committed
350
	CU_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_LinphoneRegistrationFailed,register_ok-number_of_udp_proxy /*because 1 udp*/));
jehan's avatar
jehan committed
351 352 353 354 355
	sal_set_recv_error(lc->sal, 1); /*reset*/

	linphone_core_destroy(lc);
}

jehan's avatar
jehan committed
356

jehan's avatar
jehan committed
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
static void tls_certificate_failure(){
	LinphoneCoreVTable v_table;
	LinphoneCore* lc;
	stats stat;
	stats* counters;
	char rootcapath[256];
	memset (&v_table,0,sizeof(v_table));
	reset_counters(&stat);
	v_table.registration_state_changed=registration_state_changed;
	lc = configure_lc_from(&v_table,liblinphone_tester_file_prefix, "pauline_rc", 0);
	linphone_core_set_user_data(lc,&stat);
	counters = (stats*)linphone_core_get_user_data(lc);
	sprintf(rootcapath, "%s/certificates/agent.pem", liblinphone_tester_file_prefix); /*bad root ca*/
	linphone_core_set_root_ca(lc,rootcapath);
	linphone_core_set_network_reachable(lc,TRUE);
	CU_ASSERT_TRUE(wait_for(lc,lc,&stat.number_of_LinphoneRegistrationFailed,1));
	linphone_core_set_root_ca(lc,NULL); /*no root ca*/
	linphone_core_refresh_registers(lc);
	CU_ASSERT_TRUE(wait_for(lc,lc,&stat.number_of_LinphoneRegistrationFailed,2));
	sprintf(rootcapath, "%s/certificates/cacert.pem", liblinphone_tester_file_prefix); /*goot root ca*/
	linphone_core_set_root_ca(lc,rootcapath);
	linphone_core_refresh_registers(lc);
	CU_ASSERT_TRUE(wait_for(lc,lc,&stat.number_of_LinphoneRegistrationOk,1));
	CU_ASSERT_EQUAL(stat.number_of_LinphoneRegistrationFailed,2);
	linphone_core_destroy(lc);
}
/*
static void tls_with_non_tls_server(){
	LinphoneCoreVTable v_table;
	LinphoneCore* lc;
	stats stat;
	stats* counters;

	LinphoneProxyConfig* proxy_cfg;
	LinphoneAddress* addr;
	char tmp[256];
	memset (&v_table,0,sizeof(v_table));
	reset_counters(&stat);
	v_table.registration_state_changed=registration_state_changed;
	lc = configure_lc_from(&v_table,liblinphone_tester_file_prefix, "marie_rc", 0);
	linphone_core_set_user_data(lc,&stat);
	counters = (stats*)linphone_core_get_user_data(lc);
	linphone_core_get_default_proxy(lc,&proxy_cfg);
	linphone_proxy_config_edit(proxy_cfg);
	addr=linphone_address_new(linphone_proxy_config_get_addr(proxy_cfg));
	snprintf(tmp,sizeof(tmp),"sip:%s:%i;transport=tls"	,linphone_address_get_domain(addr)
														,linphone_address_get_port_int(addr));
	linphone_proxy_config_set_server_addr(proxy_cfg,tmp);
	linphone_proxy_config_done(proxy_cfg);
	linphone_address_destroy(addr);

	CU_ASSERT_TRUE(wait_for(lc,lc,&stat.number_of_LinphoneRegistrationFailed,1));
	linphone_core_destroy(lc);
}*/

Ghislain MARY's avatar
Ghislain MARY committed
412 413 414
test_t register_tests[] = {
	{ "Simple register", simple_register },
	{ "TCP register", simple_tcp_register },
415
	{ "TCP register compatibility mode", simple_tcp_register_compatibility_mode },
416
	{ "TLS register", simple_tls_register },
jehan's avatar
jehan committed
417 418
	{ "TLS certificate not verified",tls_certificate_failure},
/*	{ "TLS with non tls server",tls_with_non_tls_server},*/
Ghislain MARY's avatar
Ghislain MARY committed
419
	{ "Simple authenticated register", simple_authenticated_register },
420
	{ "Ha1 authenticated register", ha1_authenticated_register },
Ghislain MARY's avatar
Ghislain MARY committed
421 422 423 424
	{ "Digest auth without initial credentials", authenticated_register_with_no_initial_credentials },
	{ "Authenticated register with late credentials", authenticated_register_with_late_credentials },
	{ "Register with refresh", simple_register_with_refresh },
	{ "Authenticated register with refresh", simple_auth_register_with_refresh },
425
	{ "Register with refresh and send error", register_with_refresh_with_send_error },
Ghislain MARY's avatar
Ghislain MARY committed
426 427 428 429 430 431 432 433 434 435 436 437 438
	{ "Multi account", multiple_proxy },
	{ "Transport change", transport_change },
	{ "Network state change", network_state_change },
	{ "io_recv_error_0", io_recv_error }
};

test_suite_t register_test_suite = {
	"Register",
	NULL,
	NULL,
	sizeof(register_tests) / sizeof(register_tests[0]),
	register_tests
};
jehan's avatar
jehan committed
439