static void test_extract_source(void) {
	const char * invite_1="INVITE sip:[email protected]:50343;transport=tcp;line=f18e0009dd6cc43 SIP/2.0\r\n"
						"Via: SIP/2.0/TCP 37.59.129.73;branch=z9hG4bK.SKvK9U327e8mU68XUv5rt144pg\r\n"
						"Via: SIP/2.0/UDP 192.168.1.12:15060;rport=15060;branch=z9hG4bK1596944937;received=81.56.113.2\r\n"
						"Record-Route: <sip:37.59.129.73;lr;transport=tcp>\r\n"
						"Record-Route: <sip:37.59.129.73;lr>\r\n"
						"Max-Forwards: 70\r\n"
						"From: <sip:[email protected]>;tag=711138653\r\n"
						"To: <sip:[email protected]>\r\n"
						"Call-ID: 977107319\r\n"
						"CSeq: 21 INVITE\r\n"
						"Contact: <sip:[email protected]:15060>\r\n"
						"Subject: Phone call\r\n"
						"User-Agent: Linphone/3.5.2 (eXosip2/3.6.0)\r\n"
						"Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO\r\n"
						"Content-Type: application/sdp\r\n"\
						"Content-Length: 230\r\n\r\n";

	const char * invite_2="INVITE sip:[email protected]:50343;transport=tcp;line=f18e0009dd6cc43 SIP/2.0\r\n"
						"Via: SIP/2.0/UDP 192.168.1.12:15060;rport=15060;branch=z9hG4bK1596944937;received=81.56.113.2\r\n"
						"Via: SIP/2.0/TCP 37.59.129.73;branch=z9hG4bK.SKvK9U327e8mU68XUv5rt144pg\r\n"
						"Record-Route: <sip:37.59.129.73;lr;transport=tcp>\r\n"
						"Record-Route: <sip:37.59.129.73;lr>\r\n"
						"Max-Forwards: 70\r\n"
						"From: <sip:[email protected]>;tag=711138653\r\n"
						"To: <sip:[email protected]>\r\n"
						"Call-ID: 977107319\r\n"
						"CSeq: 21 INVITE\r\n"
						"Contact: <sip:[email protected]:15060>\r\n"
						"Subject: Phone call\r\n"
						"User-Agent: Linphone/3.5.2 (eXosip2/3.6.0)\r\n"
						"Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO\r\n"
						"Content-Length: 0\r\n\r\n";

	belle_sip_message_t* message = belle_sip_message_parse(invite_1);
	belle_sip_request_t* request = BELLE_SIP_REQUEST(message);
	belle_sip_uri_t* source =belle_sip_request_extract_origin(request);
	CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Content-type"));
	CU_ASSERT_PTR_NOT_NULL(source);
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(source),"37.59.129.73");
	CU_ASSERT_EQUAL(belle_sip_uri_get_port(source),0);
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_transport_param(source),"tcp");
	belle_sip_object_unref(message);

	message = belle_sip_message_parse(invite_2);
	request = BELLE_SIP_REQUEST(message);
	source =belle_sip_request_extract_origin(request);
	CU_ASSERT_PTR_NOT_NULL(source);
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(source),"81.56.113.2");
	CU_ASSERT_EQUAL(belle_sip_uri_get_port(source),15060);
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_transport_param(source),"udp");
	belle_sip_object_unref(message);

}
static void testInviteMessage(void) {
	const char* raw_message = "INVITE sip:[email protected] SIP/2.0\r\n"\
							"Via: SIP/2.0/UDP 10.23.17.117:22600;branch=z9hG4bK-d8754z-4d7620d2feccbfac-1---d8754z-;rport=4820;received=202.165.193.129\r\n"\
							"Max-Forwards: 70\r\n"\
							"Contact: <sip:[email protected]:4820>\r\n"\
							"To: \"becheong\" <sip:[email protected]>\r\n"\
							"From: \"Benjamin Cheong\" <sip:[email protected]>;tag=7326e5f6\r\n"\
							"Call-ID: Y2NlNzg0ODc0ZGIxODU1MWI5MzhkNDVkNDZhOTQ4YWU.\r\n"\
							"CSeq: 1 INVITE\r\n"\
							"Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO\r\n"\
							"c: application/sdp\r\n"\
							"Supported: replaces\r\n"\
							"Authorization: Digest username=\"003332176\", realm=\"sip.ovh.net\", nonce=\"24212965507cde726e8bc37e04686459\", uri=\"sip:sip.ovh.net\", response=\"896e786e9c0525ca3085322c7f1bce7b\", algorithm=MD5, opaque=\"241b9fb347752f2\"\r\n"\
							"User-Agent: X-Lite 4 release 4.0 stamp 58832\r\n"\
							"Content-Length: 230\r\n\r\n";
	belle_sip_request_t* request;
	belle_sip_message_t* message = belle_sip_message_parse(raw_message);
	char* encoded_message = belle_sip_object_to_string(BELLE_SIP_OBJECT(message));
	belle_sip_object_unref(BELLE_SIP_OBJECT(message));
	message = belle_sip_message_parse(encoded_message);
	request = BELLE_SIP_REQUEST(message);
	CU_ASSERT_STRING_EQUAL(belle_sip_request_get_method(request),"INVITE");
	CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Contact"));
	CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Authorization"));
	CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Content-Type"));
	check_uri_and_headers(message);
	belle_sip_object_unref(message);
	belle_sip_free(encoded_message);
}
static void testRegisterMessage(void) {
	const char* raw_message = "REGISTER sip:192.168.0.20 SIP/2.0\r\n"\
							"v: SIP/2.0/UDP 192.168.1.8:5062;rport;branch=z9hG4bK1439638806\r\n"\
							"f: <sip:[email protected]>;tag=465687829\r\n"\
							"t: <sip:[email protected]>\r\n"\
							"i: 1053183492\r\n"\
							"CSeq: 1 REGISTER\r\n"\
							"m: <sip:[email protected]:5062>\r\n"\
							"Max-Forwards: 70\r\n"\
							"User-Agent: Linphone/3.3.99.10 (eXosip2/3.3.0)\r\n"\
							"Expires: 3600\r\n"\
							"Proxy-Authorization: Digest username=\"8117396\", realm=\"Realm\", nonce=\"MTMwNDAwMjIxMjA4NzVkODY4ZmZhODMzMzU4ZDJkOTA1NzM2NTQ2NDZlNmIz"\
							", uri=\"sip:linphone.net\", response=\"eed376ff7c963441255ec66594e470e7\", algorithm=MD5, cnonce=\"0a4f113b\", qop=auth, nc=00000001\r\n"\
							"l: 0\r\n\r\n";
	belle_sip_request_t* request;
	belle_sip_message_t* message = belle_sip_message_parse(raw_message);
	char* encoded_message = belle_sip_object_to_string(BELLE_SIP_OBJECT(message));
	belle_sip_object_unref(BELLE_SIP_OBJECT(message));
	message = belle_sip_message_parse(encoded_message);

	request = BELLE_SIP_REQUEST(message);
	CU_ASSERT_STRING_EQUAL(belle_sip_request_get_method(request),"REGISTER");
	CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Expires"));
	CU_ASSERT_PTR_NOT_NULL(BELLE_SIP_HEADER_EXPIRES(belle_sip_message_get_header(message,"Expires")));
	CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Proxy-Authorization"));
	CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Contact"));

	check_uri_and_headers(message);
	belle_sip_free(encoded_message);
	belle_sip_object_unref(message);

}
static void check_uri_and_headers(belle_sip_message_t* message) {
	if (belle_sip_message_is_request(message)) {
		CU_ASSERT_TRUE(belle_sip_request_get_uri(BELLE_SIP_REQUEST(message))|| belle_sip_request_get_absolute_uri(BELLE_SIP_REQUEST(message)) );

		CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Max-Forwards"));
		CU_ASSERT_PTR_NOT_NULL(BELLE_SIP_HEADER_MAX_FORWARDS(belle_sip_message_get_header(message,"Max-Forwards")));

		CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"User-Agent"));
		CU_ASSERT_PTR_NOT_NULL(BELLE_SIP_HEADER_USER_AGENT(belle_sip_message_get_header(message,"User-Agent")));
	}
	CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"From"));
	CU_ASSERT_PTR_NOT_NULL(BELLE_SIP_HEADER_FROM(belle_sip_message_get_header(message,"From")));

	CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"To"));
	CU_ASSERT_PTR_NOT_NULL(BELLE_SIP_HEADER_TO(belle_sip_message_get_header(message,"To")));

	CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"CSeq"));
	CU_ASSERT_PTR_NOT_NULL(BELLE_SIP_HEADER_CSEQ(belle_sip_message_get_header(message,"CSeq")));

	CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Via"));
	CU_ASSERT_PTR_NOT_NULL(BELLE_SIP_HEADER_VIA(belle_sip_message_get_header(message,"Via")));

	CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Call-ID"));
	CU_ASSERT_PTR_NOT_NULL(BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header(message,"Call-ID")));


	CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Content-Length"));
	CU_ASSERT_PTR_NOT_NULL(BELLE_SIP_HEADER_CONTENT_LENGTH(belle_sip_message_get_header(message,"Content-Length")));





}
static void testOptionMessage(void) {
	const char* raw_message = "REGISTER sip:192.168.0.20 SIP/2.0\r\n"\
							"Via: SIP/2.0/UDP 192.168.1.8:5062;rport;branch=z9hG4bK1439638806\r\n"\
							"From: <sip:[email protected]>;tag=465687829\r\n"\
							"To: <sip:[email protected]>\r\n"\
							"Call-ID: 1053183492\r\n"\
							"CSeq: 1 REGISTER\r\n"\
							"Contact: <sip:[email protected]:5062>\r\n"\
							"Max-Forwards: 70\r\n"\
							"User-Agent: Linphone/3.3.99.10 (eXosip2/3.3.0)\r\n"\
							"Expires: 3600\r\n"\
							"Content-Length: 0\r\n\r\n";
	belle_sip_message_t* message = belle_sip_message_parse(raw_message);
	belle_sip_request_t* request = BELLE_SIP_REQUEST(message);
	CU_ASSERT_STRING_EQUAL(belle_sip_request_get_method(request),"REGISTER");
	CU_ASSERT_PTR_NOT_NULL(belle_sip_request_get_uri(request));
	belle_sip_object_unref(message);
}
static void testRFC2543_base(char* branch) {
	belle_sip_server_transaction_t *tr;
	const char* raw_message_base = 	"INVITE sip:[email protected] SIP/2.0\r\n"
			"Via: SIP/2.0/UDP 192.168.1.12:15060;%srport=15060;received=81.56.113.2\r\n"
			"Record-Route: <sip:37.59.129.73;lr;transport=tcp>\r\n"
			"Record-Route: <sip:37.59.129.73;lr>\r\n"
			"Max-Forwards: 70\r\n"
			"From: <sip:[email protected]>;tag=711138653\r\n"
			"To: <sip:[email protected]>\r\n"
			"Call-ID: 977107319\r\n"
			"CSeq: 21 INVITE\r\n"
			"Contact: <sip:[email protected]:5062>\r\n"
			"Subject: Phone call\r\n"
			"User-Agent: Linphone/3.5.2 (eXosip2/3.6.0)\r\n"
			"Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO\r\n"
			"Content-Length: 0\r\n"
			"Extended: \r\n" /*fixme lexer*/
			"\r\n";

	char raw_message[2048];
	belle_sip_request_t* request;
	belle_sip_stack_t *stack=belle_sip_stack_new(NULL);
	belle_sip_provider_t *prov=belle_sip_provider_new(stack,NULL);
	belle_sip_message_t* message;

	snprintf(raw_message,sizeof(raw_message),raw_message_base,branch);

	message = belle_sip_message_parse(raw_message);
	belle_sip_object_ref(message);
	belle_sip_object_ref(message); /*yes double ref: originally the message is created with 0 refcount, and dispatch_message will unref() it.*/
	belle_sip_provider_dispatch_message(prov,message);
	request = BELLE_SIP_REQUEST(message);

	CU_ASSERT_PTR_NOT_NULL(request);
	tr=belle_sip_provider_create_server_transaction(prov,request);
	CU_ASSERT_PTR_NOT_NULL(belle_sip_provider_find_matching_server_transaction(prov,request)); /*make sure branch id is properly set*/
	CU_ASSERT_PTR_NOT_NULL(tr);
	belle_sip_object_unref(prov);
	belle_sip_object_unref(stack);
	belle_sip_object_unref(message);
}
void channel_parser_tester_recovery_from_error_base (const char* prelude,const char* raw_message) {

	belle_sip_stack_t* stack = belle_sip_stack_new(NULL);
	belle_sip_channel_t* channel = belle_sip_stream_channel_new_client(stack
																	, NULL
																	, 45421
																	, NULL
																	, "127.0.0.1"
																	, 45421);


	belle_sip_request_t* request;
	belle_sip_message_t* message;

	if (prelude) {
		channel->input_stream.write_ptr = strcpy(channel->input_stream.write_ptr,prelude);
		channel->input_stream.write_ptr+=strlen(prelude);
		belle_sip_channel_parse_stream(channel,FALSE);
	}

	channel->input_stream.write_ptr = strcpy(channel->input_stream.write_ptr,raw_message);
	channel->input_stream.write_ptr+=strlen(raw_message);

	belle_sip_channel_parse_stream(channel,FALSE);

	CU_ASSERT_PTR_NOT_NULL(channel->incoming_messages);
	CU_ASSERT_PTR_NOT_NULL(channel->incoming_messages->data);
	message=BELLE_SIP_MESSAGE(channel->incoming_messages->data);
	CU_ASSERT_TRUE(BELLE_SIP_OBJECT_IS_INSTANCE_OF(message,belle_sip_request_t));
	request = BELLE_SIP_REQUEST(message);
	CU_ASSERT_STRING_EQUAL(belle_sip_request_get_method(request),"REGISTER");
	CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Expires"));
	CU_ASSERT_PTR_NOT_NULL(BELLE_SIP_HEADER_EXPIRES(belle_sip_message_get_header(message,"Expires")));
	CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Proxy-Authorization"));

	check_uri_and_headers(message);

	belle_sip_object_unref(BELLE_SIP_OBJECT(message));
	belle_sip_object_unref(stack);

}
Esempio n. 8
0
void belle_sip_channel_parse_stream(belle_sip_channel_t *obj, int end_of_stream){
	int offset;
	size_t read_size=0;
	int num;
	
	while ((num=(obj->input_stream.write_ptr-obj->input_stream.read_ptr))>0){
	
		if (obj->input_stream.state == WAITING_MESSAGE_START) {
			int i;
			/*first, make sure there is \r\n in the buffer, otherwise, micro parser cannot conclude, because we need a complete request or response line somewhere*/
			for (i=0;i<num-1;i++) {
				if ((obj->input_stream.read_ptr[i]=='\r' && obj->input_stream.read_ptr[i+1]=='\n')
						|| belle_sip_channel_input_stream_get_buff_length(&obj->input_stream) <= 1 /*1 because null terminated*/  /*if buffer full try to parse in any case*/) {
					/*good, now we can start searching  for request/response*/
					if ((offset=get_message_start_pos(obj->input_stream.read_ptr,num)) >=0 ) {
						/*message found !*/
						if (offset>0) {
							belle_sip_warning("trashing [%i] bytes in front of sip message on channel [%p]",offset,obj);
							obj->input_stream.read_ptr+=offset;
						}
						obj->input_stream.state=MESSAGE_AQUISITION;
					} else {
						belle_sip_debug("Unexpected [%s] received on channel [%p], trashing",obj->input_stream.read_ptr,obj);
						obj->input_stream.read_ptr=obj->input_stream.write_ptr;
						belle_sip_channel_input_stream_reset(&obj->input_stream);
						continue;
					}
				break;
				}
			}

			if (i >= num-1) {
				belle_sip_debug("[%s] received on channel [%p], cannot determine if expected or not, waiting for new data",obj->input_stream.read_ptr,obj);
				break;
			}
		}

		if (obj->input_stream.state==MESSAGE_AQUISITION) {
			/*search for \r\n\r\n*/
			char* end_of_message=NULL;
			if ((end_of_message=strstr(obj->input_stream.read_ptr,"\r\n\r\n"))){
				int bytes_to_parse;
				char tmp;
				/*end of message found*/
				end_of_message+=4;/*add \r\n\r\n*/
				bytes_to_parse=end_of_message-obj->input_stream.read_ptr;
				tmp=*end_of_message;
				*end_of_message='\0';/*this is in order for the following log to print the message only to its end.*/
				/*belle_sip_message("channel [%p] read message of [%i] bytes:\n%.40s...",obj, bytes_to_parse, obj->input_stream.read_ptr);*/
				obj->input_stream.msg=belle_sip_message_parse_raw(obj->input_stream.read_ptr
										,bytes_to_parse
										,&read_size);
				*end_of_message=tmp;
				obj->input_stream.read_ptr+=read_size;
				if (obj->input_stream.msg && read_size > 0){
					belle_sip_message("channel [%p] [%i] bytes parsed",obj,(int)read_size);
					belle_sip_object_ref(obj->input_stream.msg);
					if (belle_sip_message_is_request(obj->input_stream.msg)) fix_incoming_via(BELLE_SIP_REQUEST(obj->input_stream.msg),obj->current_peer);
					/*check for body*/
					
					if (check_body(obj)){
						obj->input_stream.state=BODY_AQUISITION;
					} else {
						/*no body*/
						belle_sip_channel_message_ready(obj);
						continue;
					}
				}else{
					belle_sip_error("Could not parse [%s], on channel [%p] skipping to [%s]",obj->input_stream.read_ptr
														,obj
														,end_of_message);
					obj->input_stream.read_ptr=end_of_message;
					obj->input_stream.state=WAITING_MESSAGE_START;
					continue;
				}
			}else break; /*The message isn't finished to be receive, we need more data*/
		}

		if (obj->input_stream.state==BODY_AQUISITION) {
			if (acquire_body(obj,end_of_stream)==BELLE_SIP_STOP) break;
		}
	}
}