belle_sip_register_tester.c 13.3 KB
Newer Older
Simon Morlat's avatar
Simon Morlat committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
	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/>.
*/

#include <stdio.h>
jehan's avatar
jehan committed
20
#include "CUnit/Basic.h"
Simon Morlat's avatar
Simon Morlat committed
21
#include "belle-sip/belle-sip.h"
jehan's avatar
jehan committed
22
#include "pthread.h"
Simon Morlat's avatar
Simon Morlat committed
23

Simon Morlat's avatar
Simon Morlat committed
24
const char *test_domain="test.linphone.org";
25
const char *auth_domain="sip.linphone.org";
jehan's avatar
jehan committed
26
static int is_register_ok;
27
static int number_of_challange;
28
static int using_transaction;
jehan's avatar
jehan committed
29 30 31
belle_sip_stack_t * stack;
belle_sip_provider_t *prov;
static belle_sip_listener_t* l;
jehan's avatar
jehan committed
32

Simon Morlat's avatar
Simon Morlat committed
33 34 35 36
static void process_dialog_terminated(belle_sip_listener_t *obj, const belle_sip_dialog_terminated_event_t *event){
	belle_sip_message("process_dialog_terminated called");
}
static void process_io_error(belle_sip_listener_t *obj, const belle_sip_io_error_event_t *event){
37 38 39
	belle_sip_warning("process_io_error");
	belle_sip_main_loop_quit(belle_sip_stack_get_main_loop(stack));
	/*CU_ASSERT(CU_FALSE);*/
Simon Morlat's avatar
Simon Morlat committed
40 41 42 43
}
static void process_request_event(belle_sip_listener_t *obj, const belle_sip_request_event_t *event){
	belle_sip_message("process_request_event");
}
44
belle_sip_request_t* authorized_request;
Simon Morlat's avatar
Simon Morlat committed
45
static void process_response_event(belle_sip_listener_t *obj, const belle_sip_response_event_t *event){
46 47
	int status;
	belle_sip_request_t* request;
jehan's avatar
jehan committed
48
	CU_ASSERT_PTR_NOT_NULL_FATAL(belle_sip_response_event_get_response(event));
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
	belle_sip_message("process_response_event [%i] [%s]"
					,status=belle_sip_response_get_status_code(belle_sip_response_event_get_response(event))
					,belle_sip_response_get_reason_phrase(belle_sip_response_event_get_response(event)));
	if (status==401) {
		CU_ASSERT_NOT_EQUAL_FATAL(number_of_challange,2);
		CU_ASSERT_PTR_NOT_NULL_FATAL(belle_sip_response_event_get_client_transaction(event)); /*require transaction mode*/
		request=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(belle_sip_response_event_get_client_transaction(event)));
		belle_sip_header_cseq_t* cseq=(belle_sip_header_cseq_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_CSEQ);
		belle_sip_header_cseq_set_seq_number(cseq,belle_sip_header_cseq_get_seq_number(cseq)+1);
		CU_ASSERT_TRUE_FATAL(belle_sip_provider_add_authorization(prov,request,belle_sip_response_event_get_response(event)));
		belle_sip_client_transaction_t *t=belle_sip_provider_create_client_transaction(prov,request);
		belle_sip_client_transaction_send_request(t);
		number_of_challange++;
		authorized_request=request;
	}  else {
		CU_ASSERT_EQUAL(status,200);
		is_register_ok=1;
		using_transaction=belle_sip_response_event_get_client_transaction(event)!=NULL;
		belle_sip_main_loop_quit(belle_sip_stack_get_main_loop(stack));
	}
Simon Morlat's avatar
Simon Morlat committed
69 70 71 72 73 74 75
}
static void process_timeout(belle_sip_listener_t *obj, const belle_sip_timeout_event_t *event){
	belle_sip_message("process_timeout");
}
static void process_transaction_terminated(belle_sip_listener_t *obj, const belle_sip_transaction_terminated_event_t *event){
	belle_sip_message("process_transaction_terminated");
}
76 77 78 79 80 81
static void process_auth_requested(belle_sip_listener_t *obj, belle_sip_auth_event_t *event){
	belle_sip_message("process_auth_requested requested for [%s@%s]"
			,belle_sip_auth_event_get_username(event)
			,belle_sip_auth_event_get_realm(event));
	belle_sip_auth_event_set_passwd(event,"secret");
}
Simon Morlat's avatar
Simon Morlat committed
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
/*this would normally go to a .h file*/
struct test_listener{
	belle_sip_object_t base;
	void *some_context;
};

typedef struct test_listener test_listener_t;

BELLE_SIP_DECLARE_TYPES_BEGIN(test,0x1000)
	BELLE_SIP_TYPE_ID(test_listener_t)
BELLE_SIP_DECLARE_TYPES_END

BELLE_SIP_DECLARE_VPTR(test_listener_t);

/*the following would go to .c file */

BELLE_SIP_IMPLEMENT_INTERFACE_BEGIN(test_listener_t,belle_sip_listener_t)
	process_dialog_terminated,
	process_io_error,
	process_request_event,
	process_response_event,
	process_timeout,
104 105
	process_transaction_terminated,
	process_auth_requested
Simon Morlat's avatar
Simon Morlat committed
106 107 108 109 110
BELLE_SIP_IMPLEMENT_INTERFACE_END

BELLE_SIP_DECLARE_IMPLEMENTED_INTERFACES_1(test_listener_t,belle_sip_listener_t);

BELLE_SIP_INSTANCIATE_VPTR(test_listener_t,belle_sip_object_t,NULL,NULL,NULL,FALSE);
Simon Morlat's avatar
Simon Morlat committed
111 112 113

static test_listener_t *listener;

jehan's avatar
jehan committed
114
int register_init(void) {
jehan's avatar
jehan committed
115
	stack=belle_sip_stack_new(NULL);
Simon Morlat's avatar
Simon Morlat committed
116 117
	belle_sip_listening_point_t *lp=belle_sip_stack_create_listening_point(stack,"0.0.0.0",7060,"UDP");
	prov=belle_sip_stack_create_provider(stack,lp);
118
	
Simon Morlat's avatar
Simon Morlat committed
119 120 121
	lp=belle_sip_stack_create_listening_point(stack,"0.0.0.0",7060,"TCP");
	belle_sip_provider_add_listening_point(prov,lp);
	belle_sip_object_unref(lp);
122
	lp=belle_sip_stack_create_listening_point(stack,"0.0.0.0",7061,"TLS");
jehan's avatar
jehan committed
123 124 125 126
	if (lp) {
		belle_sip_provider_add_listening_point(prov,lp);
		belle_sip_object_unref(lp);
	}
Simon Morlat's avatar
Simon Morlat committed
127
	listener=belle_sip_object_new(test_listener_t);
jehan's avatar
jehan committed
128

jehan's avatar
jehan committed
129 130
	return 0;
}
jehan's avatar
jehan committed
131
int register_uninit(void) {
Simon Morlat's avatar
Simon Morlat committed
132
	belle_sip_object_unref(prov);
jehan's avatar
jehan committed
133
	belle_sip_object_unref(stack);
Simon Morlat's avatar
Simon Morlat committed
134
	belle_sip_object_unref(listener);
jehan's avatar
jehan committed
135 136
	return 0;
}
jehan's avatar
jehan committed
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151

void unregister_user(belle_sip_stack_t * stack
					,belle_sip_provider_t *prov
					,belle_sip_request_t* initial_request
					,int use_transaction) {
	belle_sip_request_t *req;
	belle_sip_provider_add_sip_listener(prov,l);
	is_register_ok=0;
	using_transaction=0;
	req=(belle_sip_request_t*)belle_sip_object_clone((belle_sip_object_t*)initial_request);
	belle_sip_header_cseq_t* cseq=(belle_sip_header_cseq_t*)belle_sip_message_get_header((belle_sip_message_t*)req,BELLE_SIP_CSEQ);
	belle_sip_header_cseq_set_seq_number(cseq,belle_sip_header_cseq_get_seq_number(cseq)+1);
	belle_sip_header_expires_t* expires_header=(belle_sip_header_expires_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_EXPIRES);
	belle_sip_header_expires_set_expires(expires_header,0);
	if (use_transaction){
152 153 154
		belle_sip_message_remove_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_AUTHORIZATION);
		belle_sip_message_remove_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_PROXY_AUTHORIZATION);
		belle_sip_provider_add_authorization(prov,req,NULL); /*just in case*/
jehan's avatar
jehan committed
155 156 157
		belle_sip_client_transaction_t *t=belle_sip_provider_create_client_transaction(prov,req);
		belle_sip_client_transaction_send_request(t);
	}else belle_sip_provider_send_request(prov,req);
jehan's avatar
jehan committed
158 159 160
	int i;
	for(i=0;!is_register_ok && i<2 ;i++)
		belle_sip_stack_sleep(stack,5000);
jehan's avatar
jehan committed
161 162 163 164
	CU_ASSERT_EQUAL(is_register_ok,1);
	CU_ASSERT_EQUAL(using_transaction,use_transaction);
	belle_sip_provider_remove_sip_listener(prov,l);
}
165
belle_sip_request_t* register_user_at_domain(belle_sip_stack_t * stack
jehan's avatar
jehan committed
166 167 168
					,belle_sip_provider_t *prov
					,const char *transport
					,int use_transaction
169 170
					,const char* username
					,const char* domain) {
171
	belle_sip_request_t *req,*copy;
Simon Morlat's avatar
Simon Morlat committed
172 173
	char identity[256];
	char uri[256];
Simon Morlat's avatar
Simon Morlat committed
174

Simon Morlat's avatar
Simon Morlat committed
175
	if (transport)
176 177
		snprintf(uri,sizeof(uri),"sip:%s;transport=%s",domain,transport);
	else snprintf(uri,sizeof(uri),"sip:%s",domain);
jehan's avatar
jehan committed
178

Simon Morlat's avatar
Simon Morlat committed
179 180
	if (transport && strcasecmp("tls",transport)==0 && belle_sip_provider_get_listening_point(prov,"tls")==NULL){
		belle_sip_error("No TLS support, test skipped.");
jehan's avatar
jehan committed
181
		return NULL;
Simon Morlat's avatar
Simon Morlat committed
182 183
	}

184
	snprintf(identity,sizeof(identity),"Tester <sip:%s@%s>",username,domain);
Simon Morlat's avatar
Simon Morlat committed
185
	req=belle_sip_request_create(
Simon Morlat's avatar
Simon Morlat committed
186
	                    belle_sip_uri_parse(uri),
Simon Morlat's avatar
Simon Morlat committed
187 188 189
	                    "REGISTER",
	                    belle_sip_provider_create_call_id(prov),
	                    belle_sip_header_cseq_create(20,"REGISTER"),
190
	                    belle_sip_header_from_create2(identity,BELLE_SIP_RANDOM_TAG),
jehan's avatar
jehan committed
191
	                    belle_sip_header_to_create2(identity,NULL),
192
	                    belle_sip_header_via_new(),
Simon Morlat's avatar
Simon Morlat committed
193
	                    70);
jehan's avatar
jehan committed
194
	is_register_ok=0;
195
	using_transaction=0;
jehan's avatar
jehan committed
196
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(600)));
Simon Morlat's avatar
Simon Morlat committed
197
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_contact_new()));
198
	copy=(belle_sip_request_t*)belle_sip_object_clone((belle_sip_object_t*)req);
jehan's avatar
jehan committed
199
	belle_sip_provider_add_sip_listener(prov,l=BELLE_SIP_LISTENER(listener));
Simon Morlat's avatar
Simon Morlat committed
200 201 202 203
	if (use_transaction){
		belle_sip_client_transaction_t *t=belle_sip_provider_create_client_transaction(prov,req);
		belle_sip_client_transaction_send_request(t);
	}else belle_sip_provider_send_request(prov,req);
jehan's avatar
jehan committed
204 205 206
	int i;
	for(i=0;!is_register_ok && i<2 ;i++)
		belle_sip_stack_sleep(stack,5000);
jehan's avatar
jehan committed
207
	CU_ASSERT_EQUAL(is_register_ok,1);
208
	CU_ASSERT_EQUAL(using_transaction,use_transaction);
209

jehan's avatar
jehan committed
210 211
	belle_sip_provider_remove_sip_listener(prov,l);

212
	return copy;
Simon Morlat's avatar
Simon Morlat committed
213
}
214 215 216 217 218 219 220
belle_sip_request_t* register_user(belle_sip_stack_t * stack
					,belle_sip_provider_t *prov
					,const char *transport
					,int use_transaction
					,const char* username) {
	return register_user_at_domain(stack,prov,transport,use_transaction,username,test_domain);
}
jehan's avatar
jehan committed
221 222 223
static void register_test(const char *transport, int use_transaction) {
	belle_sip_request_t *req;
	req=register_user(stack, prov, transport,use_transaction,"tester");
224
	if (req) unregister_user(stack,prov,req,use_transaction);
jehan's avatar
jehan committed
225
}
Simon Morlat's avatar
Simon Morlat committed
226 227 228

static void stateless_register_udp(void){
	register_test(NULL,0);
jehan's avatar
jehan committed
229
}
Simon Morlat's avatar
Simon Morlat committed
230

jehan's avatar
jehan committed
231 232 233 234
static void stateless_register_tls(void){
	register_test("tls",0);
}

Simon Morlat's avatar
Simon Morlat committed
235 236 237 238 239 240 241 242
static void stateless_register_tcp(void){
	register_test("tcp",0);
}

static void stateful_register_udp(void){
	register_test(NULL,1);
}

Simon Morlat's avatar
Simon Morlat committed
243
static void stateful_register_udp_delayed(void){
244
	belle_sip_stack_set_tx_delay(stack,3000);
Simon Morlat's avatar
Simon Morlat committed
245 246 247 248
	register_test(NULL,1);
	belle_sip_stack_set_tx_delay(stack,0);
}

Simon Morlat's avatar
Simon Morlat committed
249 250
static void stateful_register_tcp(void){
	register_test("tcp",1);
jehan's avatar
jehan committed
251
}
Simon Morlat's avatar
Simon Morlat committed
252

253 254 255
static void stateful_register_tls(void){
	register_test("tls",1);
}
jehan's avatar
jehan committed
256

jehan's avatar
jehan committed
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299

static void bad_req_process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){
	belle_sip_message("bad_req_process_io_error not implemented yet");
}
static void bad_req_process_response_event(void *user_ctx, const belle_sip_response_event_t *event){
	belle_sip_message("bad_req_process_response_event not implemented yet");
}

static void test_bad_request() {
	belle_sip_request_t *req;
	belle_sip_header_address_t* route_address=belle_sip_header_address_create(NULL,belle_sip_uri_create(NULL,test_domain));
	belle_sip_header_route_t* route;
	belle_sip_header_to_t* to = belle_sip_header_to_create2("sip:toto@titi.com",NULL);
	belle_sip_listener_callbacks_t cbs;
	memset(&cbs,0,sizeof(cbs));

	belle_sip_listener_t* bad_req_listener = belle_sip_listener_create_from_callbacks(&cbs,NULL);
	cbs.process_io_error=bad_req_process_io_error;
	cbs.process_response_event=bad_req_process_response_event;

	req=belle_sip_request_create(
	                    BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(belle_sip_header_address_get_uri(route_address)))),
	                    "REGISTER",
	                    belle_sip_provider_create_call_id(prov),
	                    belle_sip_header_cseq_create(20,"REGISTER"),
	                    belle_sip_header_from_create2("sip:toto@titi.com",BELLE_SIP_RANDOM_TAG),
	                    to,
	                    belle_sip_header_via_new(),
	                    70);

	belle_sip_uri_set_transport_param(belle_sip_header_address_get_uri(route_address),"tcp");
	route = belle_sip_header_route_create(route_address);
	belle_sip_header_set_name(BELLE_SIP_HEADER(to),"BrokenHeader");

	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(600)));
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(route));
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_contact_new()));
	belle_sip_provider_add_sip_listener(prov,bad_req_listener);
	belle_sip_client_transaction_t *t=belle_sip_provider_create_client_transaction(prov,req);
	belle_sip_client_transaction_send_request(t);
	belle_sip_stack_sleep(stack,100);
	belle_sip_provider_remove_sip_listener(prov,bad_req_listener);
}
300 301 302 303 304 305
static void test_register_authenticate() {
	number_of_challange=0;
	authorized_request=NULL;
	register_user_at_domain(stack, prov, "udp",1,"bellesip",auth_domain);
	if (authorized_request) unregister_user(stack,prov,authorized_request,1);
}
jehan's avatar
jehan committed
306

jehan's avatar
jehan committed
307
int belle_sip_register_test_suite(){
jehan's avatar
jehan committed
308
	CU_pSuite pSuite = CU_add_suite("Register", register_init, register_uninit);
jehan's avatar
jehan committed
309

310
	if (NULL == CU_add_test(pSuite, "stateful-udp-register", stateful_register_udp)) {
Simon Morlat's avatar
Simon Morlat committed
311 312
		return CU_get_error();
	}
313
	if (NULL == CU_add_test(pSuite, "stateful-udp-register-with-network-delay", stateful_register_udp_delayed)) {
Simon Morlat's avatar
Simon Morlat committed
314 315
		return CU_get_error();
	}
jehan's avatar
jehan committed
316
	if (NULL == CU_add_test(pSuite, "stateful-tcp-register", stateful_register_tcp)) {
Simon Morlat's avatar
Simon Morlat committed
317 318
		return CU_get_error();
	}
319 320 321
	if (NULL == CU_add_test(pSuite, "stateful tls register", stateful_register_tls)) {
		return CU_get_error();
	}
Simon Morlat's avatar
Simon Morlat committed
322
	if (NULL == CU_add_test(pSuite, "stateless udp register", stateless_register_udp)) {
jehan's avatar
jehan committed
323 324
		return CU_get_error();
	}
Simon Morlat's avatar
Simon Morlat committed
325
	if (NULL == CU_add_test(pSuite, "stateless tcp register", stateless_register_tcp)) {
jehan's avatar
jehan committed
326 327
		return CU_get_error();
	}
jehan's avatar
jehan committed
328 329 330
	if (NULL == CU_add_test(pSuite, "stateless tls register", stateless_register_tls)) {
			return CU_get_error();
	}
jehan's avatar
jehan committed
331 332 333
	if (NULL == CU_add_test(pSuite, "Bad request tcp", test_bad_request)) {
			return CU_get_error();
	}
334 335 336
	if (NULL == CU_add_test(pSuite, "authenticate", test_register_authenticate)) {
			return CU_get_error();
	}
jehan's avatar
jehan committed
337
	return 0;
jehan's avatar
jehan committed
338 339
}