1 /*
2 	belle-sip - SIP (RFC3261) library.
3     Copyright (C) 2010  Belledonne Communications SARL
4 
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 2 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 
20 #include "belle_sip_internal.h"
21 #include <limits.h>
22 #include <ctype.h>
23 #include <wchar.h>
24 
25 #ifdef __ANDROID__
26 #include "wakelock_internal.h"
27 #endif
28 
29 #define BELLE_SIP_CHANNEL_INVOKE_MESSAGE_HEADERS_LISTENERS(channel,msg) \
30 	BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2(channel->full_listeners, belle_sip_channel_listener_t, on_message_headers, channel, msg)
31 
32 #define BELLE_SIP_CHANNEL_INVOKE_SENDING_LISTENERS(channel,msg) \
33 	BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2(channel->full_listeners, belle_sip_channel_listener_t, on_sending, channel, msg)
34 
35 #define BELLE_SIP_CHANNEL_INVOKE_STATE_LISTENERS(channel,state) \
36 	BELLE_SIP_INVOKE_LISTENERS_REVERSE_ARG1_ARG2(channel->full_listeners, belle_sip_channel_listener_t, on_state_changed, channel, state) \
37 	BELLE_SIP_INVOKE_LISTENERS_REVERSE_ARG1_ARG2(channel->state_listeners, belle_sip_channel_listener_t, on_state_changed, channel, state)
38 
39 
40 static void channel_prepare_continue(belle_sip_channel_t *obj);
41 static void channel_process_queue(belle_sip_channel_t *obj);
42 static void channel_begin_send_background_task(belle_sip_channel_t *obj);
43 static void channel_end_send_background_task(belle_sip_channel_t *obj);
44 static void channel_begin_recv_background_task(belle_sip_channel_t *obj);
45 static void channel_end_recv_background_task(belle_sip_channel_t *obj);
46 static void channel_process_queue(belle_sip_channel_t *obj);
47 static char *make_logbuf(belle_sip_channel_t *obj, belle_sip_log_level level, const char *buffer, size_t size);
48 static void channel_remove_listener(belle_sip_channel_t *obj, belle_sip_channel_listener_t *l);
49 static void free_ewouldblock_buffer(belle_sip_channel_t *obj);
50 
belle_sip_channel_state_to_string(belle_sip_channel_state_t state)51 const char *belle_sip_channel_state_to_string(belle_sip_channel_state_t state){
52 	switch(state){
53 		case BELLE_SIP_CHANNEL_INIT:
54 			return "INIT";
55 		case BELLE_SIP_CHANNEL_RES_IN_PROGRESS:
56 			return "RES_IN_PROGRESS";
57 		case BELLE_SIP_CHANNEL_RES_DONE:
58 			return "RES_DONE";
59 		case BELLE_SIP_CHANNEL_CONNECTING:
60 			return "CONNECTING";
61 		case BELLE_SIP_CHANNEL_RETRY:
62 			return "RETRY";
63 		case BELLE_SIP_CHANNEL_READY:
64 			return "READY";
65 		case BELLE_SIP_CHANNEL_ERROR:
66 			return "ERROR";
67 		case BELLE_SIP_CHANNEL_DISCONNECTED:
68 			return "DISCONNECTED";
69 	}
70 	return "BAD";
71 }
72 
for_each_weak_unref_free(belle_sip_list_t * l,belle_sip_object_destroy_notify_t notify,void * ptr)73 static belle_sip_list_t * for_each_weak_unref_free(belle_sip_list_t *l, belle_sip_object_destroy_notify_t notify, void *ptr){
74 	belle_sip_list_t *elem,*next;
75 	for(elem=l;elem!=NULL;elem=next){
76 		next=elem->next;
77 		belle_sip_object_weak_unref(elem->data,notify,ptr);
78 		belle_sip_free(elem);
79 	}
80 	return NULL;
81 }
82 
belle_sip_channel_input_stream_rewind(belle_sip_channel_input_stream_t * input_stream)83 static void belle_sip_channel_input_stream_rewind(belle_sip_channel_input_stream_t* input_stream){
84 	int remaining;
85 
86 	remaining=(int)(input_stream->write_ptr-input_stream->read_ptr);
87 	if (remaining>0){
88 		/* copy remaning bytes at top of buffer*/
89 		memmove(input_stream->buff,input_stream->read_ptr,remaining);
90 		input_stream->read_ptr=input_stream->buff;
91 		input_stream->write_ptr=input_stream->buff+remaining;
92 		*input_stream->write_ptr='\0';
93 	}else{
94 		input_stream->read_ptr=input_stream->write_ptr=input_stream->buff;
95 	}
96 }
97 
belle_sip_channel_input_stream_reset(belle_sip_channel_input_stream_t * input_stream)98 static void belle_sip_channel_input_stream_reset(belle_sip_channel_input_stream_t* input_stream) {
99 	belle_sip_channel_input_stream_rewind(input_stream);
100 	input_stream->state=WAITING_MESSAGE_START;
101 	if (input_stream->msg != NULL) belle_sip_object_unref(input_stream->msg);
102 	input_stream->msg=NULL;
103 	input_stream->chuncked_mode=FALSE;
104 	input_stream->content_length=-1;
105 }
106 
belle_sip_channel_input_stream_get_buff_length(belle_sip_channel_input_stream_t * input_stream)107 static size_t belle_sip_channel_input_stream_get_buff_length(belle_sip_channel_input_stream_t* input_stream) {
108 	return sizeof(input_stream->buff) - (input_stream->write_ptr-input_stream->buff);
109 }
110 
belle_sip_channel_destroy(belle_sip_channel_t * obj)111 static void belle_sip_channel_destroy(belle_sip_channel_t *obj){
112 	belle_sip_channel_input_stream_reset(&obj->input_stream);
113 	if (obj->peer_list) bctbx_freeaddrinfo(obj->peer_list);
114 	if (obj->peer_cname) belle_sip_free(obj->peer_cname);
115 	belle_sip_free(obj->peer_name);
116 	if (obj->local_ip) belle_sip_free(obj->local_ip);
117 	obj->state_listeners=for_each_weak_unref_free(obj->state_listeners,(belle_sip_object_destroy_notify_t)channel_remove_listener,obj);
118 	obj->full_listeners=for_each_weak_unref_free(obj->full_listeners,(belle_sip_object_destroy_notify_t)channel_remove_listener,obj);
119 
120 	if (obj->resolver_ctx != NULL) {
121 		belle_sip_resolver_context_cancel(obj->resolver_ctx);
122 		belle_sip_object_unref(obj->resolver_ctx);
123 	}
124 	if (obj->inactivity_timer){
125 		belle_sip_main_loop_remove_source(obj->stack->ml,obj->inactivity_timer);
126 		belle_sip_object_unref(obj->inactivity_timer);
127 	}
128 	if (obj->dns_ttl_timer) {
129 		belle_sip_main_loop_remove_source(obj->stack->ml, obj->dns_ttl_timer);
130 		belle_sip_object_unref(obj->dns_ttl_timer);
131 	}
132 	if (obj->public_ip) belle_sip_free(obj->public_ip);
133 	if (obj->outgoing_messages) belle_sip_list_free_with_data(obj->outgoing_messages,belle_sip_object_unref);
134 	if (obj->incoming_messages) belle_sip_list_free_with_data(obj->incoming_messages,belle_sip_object_unref);
135 	free_ewouldblock_buffer(obj);
136 	if (obj->cur_out_message){
137 		belle_sip_object_unref(obj->cur_out_message);
138 		obj->cur_out_message=NULL;
139 	}
140 	channel_end_send_background_task(obj);
141 	channel_end_recv_background_task(obj);
142 	/*normally this should do nothing because it sould have been terminated already,
143 		however leaving a background task open is so dangerous that we have to be paranoid*/
144 	belle_sip_message("Channel [%p] destroyed",obj);
145 }
146 
147 BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_channel_t);
148 
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_channel_t)149 BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_channel_t)
150 	{
151 		BELLE_SIP_VPTR_INIT(belle_sip_channel_t,belle_sip_source_t,FALSE),
152 		(belle_sip_object_destroy_t)belle_sip_channel_destroy,
153 		NULL, /*clone*/
154 		NULL, /*marshal*/
155 		BELLE_SIP_DEFAULT_BUFSIZE_HINT
156 	},
157 	NULL, /* transport */
158 	0, /* reliable */
159 	NULL, /* connect */
160 	NULL, /* channel_send */
161 	NULL, /* channel_recv */
162 	NULL /* close */
163 BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END
164 
165 static void fix_incoming_via(belle_sip_request_t *msg, const struct addrinfo* origin){
166 	char received[NI_MAXHOST];
167 	char rport[NI_MAXSERV];
168 	belle_sip_header_via_t *via;
169 	int err;
170 	struct sockaddr_storage saddr;
171 	socklen_t slen=sizeof(saddr);
172 
173 	if (!origin) {
174 		belle_sip_warning("cannot fix via for message [%p], probably a test",msg);
175 		return;
176 	}
177 	bctbx_sockaddr_remove_v4_mapping(origin->ai_addr, (struct sockaddr*)&saddr, &slen);
178 	err=bctbx_getnameinfo((struct sockaddr*)&saddr,slen,received,sizeof(received),
179 	                rport,sizeof(rport),NI_NUMERICHOST|NI_NUMERICSERV);
180 	if (err!=0){
181 		belle_sip_error("fix_via: getnameinfo() failed: %s",gai_strerror(errno));
182 		return;
183 	}
184 	via=BELLE_SIP_HEADER_VIA(belle_sip_message_get_header((belle_sip_message_t*)msg,"via"));
185 	if (via){
186 		const char* host = belle_sip_header_via_get_host(via);
187 
188 		if (strcmp(host,received)!=0)
189 				belle_sip_header_via_set_received(via,received);
190 
191 		if (belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(via),"rport")){
192 			int port = belle_sip_header_via_get_listening_port(via);
193 			int rport_int=atoi(rport);
194 			if (rport_int!=port) belle_sip_header_via_set_rport(via,atoi(rport));
195 		}
196 	}
197 }
198 
199 /*token       =  1*(alphanum / "-" / "." / "!" / "%" / "*"
200                      / "_" / "+" / "`" / "'" / "~" )
201  *
202  * */
is_token(const char * buff,size_t bufflen)203 static int is_token(const char* buff,size_t bufflen ) {
204 	size_t i;
205 	for (i=0; i<bufflen && buff[i]!='\0';i++) {
206 		switch(buff[i]) {
207 			case '-' :
208 			case '.' :
209 			case '!' :
210 			case '%' :
211 			case '*' :
212 			case '_' :
213 			case '+' :
214 			case '`' :
215 			case '\'' :
216 			case '~' :
217 				break;
218 		default:
219 			if ((buff[i]>='0' && buff[i]<='9')
220 				|| (buff[i]>='A' && buff[i]<='Z')
221 				|| (buff[i]>='a' && buff[i]<='z')
222 				|| (buff[i]=='\0'))
223 				continue;
224 			else
225 				return 0;
226 		}
227 	}
228 	return 1;
229 }
get_message_start_pos(char * buff,size_t bufflen)230 static int get_message_start_pos(char *buff, size_t bufflen) {
231 	/*FIXME still to optimize and better test, specially REQUEST PATH and error path*/
232 	int i;
233 	int res=0;
234 	int status_code;
235 	char method[17]={0};
236 	char saved_char1;
237 	char sip_version[10]={0};
238 	size_t saved_char1_index;
239 
240 	for(i=0; i<(int)bufflen-12;i++) { /*9=strlen( SIP/2.0\r\n)*/
241 		switch (buff[i]) { /*to avoid this character to be ignored by scanf*/
242 			case '\r':
243 			case '\n':
244 			case ' ' :
245 			case '\t':
246 				continue;
247 			default:
248 				break;
249 		}
250 		saved_char1_index=bufflen-1;
251 		saved_char1=buff[saved_char1_index]; /*make sure buff is null terminated*/
252 		buff[saved_char1_index]='\0';
253 		res=sscanf(buff+i,"SIP/2.0 %d ",&status_code);
254 		if (res!=1) res=sscanf(buff+i,"HTTP/1.%*i %d ",&status_code); /*might be HTTP ?*/
255 		if (res!=1) {
256 			res= sscanf(buff+i,"%16s %*s %9s\r\n",method,sip_version)==2
257 					&& is_token(method,sizeof(method))
258 					&& (strcmp("SIP/2.0",sip_version)==0 || strncmp("HTTP/1.",sip_version,strlen("HTTP/1."))==0);
259 		}
260 		buff[saved_char1_index]=saved_char1;
261 		if (res==1) return i;
262 	}
263 	return -1;
264 }
265 
belle_sip_channel_set_public_ip_port(belle_sip_channel_t * obj,const char * public_ip,int port)266 void belle_sip_channel_set_public_ip_port(belle_sip_channel_t *obj, const char *public_ip, int port){
267 	if (obj->public_ip){
268 		int ip_changed=0;
269 		int port_changed=0;
270 
271 		if (public_ip && strcmp(obj->public_ip,public_ip)!=0){
272 			ip_changed=1;
273 		}
274 		if (port!=obj->public_port){
275 			port_changed=1;
276 		}
277 		if (ip_changed || port_changed){
278 			belle_sip_warning("channel [%p]: public ip is changed from [%s:%i] to [%s:%i]",obj,obj->public_ip,obj->public_port,public_ip,port);
279 		}
280 		belle_sip_free(obj->public_ip);
281 		obj->public_ip=NULL;
282 	}else if (public_ip){
283 		belle_sip_message("channel [%p]: discovered public ip and port are [%s:%i]",obj,public_ip,port);
284 	}
285 	if (public_ip){
286 		obj->public_ip=belle_sip_strdup(public_ip);
287 	}
288 	obj->public_port=port;
289 }
290 
belle_sip_channel_learn_public_ip_port(belle_sip_channel_t * obj,belle_sip_response_t * resp)291 static void belle_sip_channel_learn_public_ip_port(belle_sip_channel_t *obj, belle_sip_response_t *resp){
292 	belle_sip_header_via_t *via=belle_sip_message_get_header_by_type(resp,belle_sip_header_via_t);
293 	const char *received;
294 	int rport;
295 
296 	if (!via){
297 		belle_sip_error("channel [%p]: no via in response.",obj);
298 		return;
299 	}
300 
301 	if (!(received=belle_sip_header_via_get_received(via))) {
302 		/*use address from via*/;
303 		received=belle_sip_header_via_get_host(via);
304 	}
305 
306 	rport=belle_sip_header_via_get_rport(via);
307 	if (rport<=0){
308 		/* no rport, the via port might be good then*/
309 		rport=belle_sip_header_via_get_listening_port(via);
310 	}
311 	belle_sip_channel_set_public_ip_port(obj,received,rport);
312 
313 	obj->learnt_ip_port=TRUE;
314 }
315 
uncompress_body_if_required(belle_sip_message_t * msg)316 static void uncompress_body_if_required(belle_sip_message_t *msg) {
317 	belle_sip_body_handler_t *bh = belle_sip_message_get_body_handler(msg);
318 	belle_sip_memory_body_handler_t *mbh = NULL;
319 	belle_sip_header_t *ceh = NULL;
320 	size_t body_len = 0;
321 
322 	if (bh != NULL) {
323 		body_len = belle_sip_message_get_body_size(msg);
324 		ceh = belle_sip_message_get_header(msg, "Content-Encoding");
325 	}
326 	if ((body_len > 0) && (ceh != NULL)) {
327 		const char *content_encoding = belle_sip_header_get_unparsed_value(ceh);
328 		if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(bh, belle_sip_memory_body_handler_t)) {
329 			mbh = BELLE_SIP_MEMORY_BODY_HANDLER(bh);
330 			if (belle_sip_memory_body_handler_unapply_encoding(mbh, content_encoding) == 0) {
331 				belle_sip_header_content_type_t *content_type = belle_sip_message_get_header_by_type(msg, belle_sip_header_content_type_t);
332 				belle_sip_message_remove_header_from_ptr(msg, ceh);
333 				if (content_type
334 					&& (strcmp(belle_sip_header_content_type_get_type(content_type), "multipart") == 0)) {
335 					const char *unparsed_value = belle_sip_header_get_unparsed_value(BELLE_SIP_HEADER(content_type));
336 					const char *boundary = strstr(unparsed_value, ";boundary=");
337 					if (boundary != NULL) boundary += 10;
338 					if (boundary[0] == '\0') boundary = NULL;
339 					bh = (belle_sip_body_handler_t *)belle_sip_multipart_body_handler_new_from_buffer(
340 						belle_sip_memory_body_handler_get_buffer(mbh), belle_sip_body_handler_get_size((belle_sip_body_handler_t *)mbh), boundary);
341 					belle_sip_message_set_body_handler(msg, bh);
342 				}
343 			}
344 		} else {
345 			belle_sip_warning("message [%p] has Content-Encoding [%s] that cannot be unapplied", msg, content_encoding);
346 		}
347 	}
348 }
349 
belle_sip_channel_message_ready(belle_sip_channel_t * obj)350 static void belle_sip_channel_message_ready(belle_sip_channel_t *obj){
351 	belle_sip_message_t *msg=obj->input_stream.msg;
352 	belle_sip_body_handler_t *bh=belle_sip_message_get_body_handler(msg);
353 	if (bh) belle_sip_body_handler_end_transfer(bh);
354 	if (belle_sip_message_is_response(msg)) belle_sip_channel_learn_public_ip_port(obj,BELLE_SIP_RESPONSE(msg));
355 	uncompress_body_if_required(msg);
356 	obj->incoming_messages=belle_sip_list_append(obj->incoming_messages,belle_sip_object_ref(msg));
357 	obj->stop_logging_buffer=0;
358 	belle_sip_channel_input_stream_reset(&obj->input_stream);
359 }
360 
feed_body(belle_sip_channel_t * obj,size_t len)361 static void feed_body(belle_sip_channel_t *obj, size_t len){
362 	belle_sip_message_t *msg=obj->input_stream.msg;
363 	belle_sip_body_handler_t *bh=belle_sip_message_get_body_handler(msg);
364 	belle_sip_body_handler_recv_chunk(bh,msg,(uint8_t*)obj->input_stream.read_ptr,len);
365 	obj->input_stream.read_ptr+=len;
366 	belle_sip_channel_input_stream_rewind(&obj->input_stream);
367 }
368 
369 /*returns TRUE if a body is expected, and initialize a few things in the input stream context*/
check_body(belle_sip_channel_t * obj)370 static int check_body(belle_sip_channel_t *obj){
371 	belle_sip_message_t *msg=obj->input_stream.msg;
372 	belle_sip_header_content_length_t* content_length_header = belle_sip_message_get_header_by_type(msg,belle_sip_header_content_length_t);
373 	int expect_body=FALSE;
374 
375 	obj->input_stream.content_length= content_length_header ? belle_sip_header_content_length_get_content_length(content_length_header) : 0;
376 
377 	expect_body=obj->input_stream.content_length>0;
378 
379 	if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(msg,belle_http_response_t) || BELLE_SIP_OBJECT_IS_INSTANCE_OF(msg,belle_http_request_t)){
380 		/*http chunked mode handling*/
381 		if (belle_sip_message_get_header_by_type(msg, belle_sip_header_content_type_t)!=NULL){
382 			belle_sip_header_t *transfer_encoding=belle_sip_message_get_header(msg,"Transfer-Encoding");
383 
384 			if (transfer_encoding){
385 				const char *value=belle_sip_header_get_unparsed_value(transfer_encoding);
386 				if (strstr(value,"chunked")!=0){
387 					obj->input_stream.chuncked_mode=1;
388 					obj->input_stream.content_length=0;
389 					obj->input_stream.chunk_size=-1;
390 					obj->input_stream.chunk_read_size=0;
391 				}
392 			}
393 			expect_body=TRUE;
394 		}
395 	}
396 	if (expect_body){
397 		belle_sip_body_handler_t *bh;
398 		/*should notify the listeners*/
399 		BELLE_SIP_CHANNEL_INVOKE_MESSAGE_HEADERS_LISTENERS(obj,msg);
400 		/*check if the listener has setup a body handler, otherwise create a default one*/
401 		if ((bh=belle_sip_message_get_body_handler(msg))==NULL){
402 			belle_sip_header_t *content_encoding = belle_sip_message_get_header(msg, "Content-Encoding");
403 			belle_sip_header_content_type_t *content_type = belle_sip_message_get_header_by_type(msg, belle_sip_header_content_type_t);
404 			if (content_encoding != NULL) {
405 				belle_sip_message_set_body_handler(msg, (bh = (belle_sip_body_handler_t *)belle_sip_memory_body_handler_new(NULL, NULL)));
406 			} else if (content_type
407 				&& (strcmp(belle_sip_header_content_type_get_type(content_type), "multipart") == 0)) {
408 				const char *unparsed_value = belle_sip_header_get_unparsed_value(BELLE_SIP_HEADER(content_type));
409 				const char *boundary = strstr(unparsed_value, ";boundary=");
410 				if (boundary != NULL) boundary += 10;
411 				if (boundary[0] == '\0') boundary = NULL;
412 				belle_sip_message_set_body_handler(msg, (bh = (belle_sip_body_handler_t *)belle_sip_multipart_body_handler_new(belle_sip_multipart_body_handler_progress_cb, NULL, NULL, boundary)));
413 				belle_sip_body_handler_set_size(bh, obj->input_stream.content_length);
414 			} else {
415 				belle_sip_message_set_body_handler(msg,(bh=(belle_sip_body_handler_t*)belle_sip_memory_body_handler_new(NULL,NULL)));
416 			}
417 		}
418 		belle_sip_body_handler_begin_recv_transfer(bh);
419 	}
420 	return expect_body;
421 }
422 
acquire_body_simple(belle_sip_channel_t * obj,int end_of_stream)423 static int acquire_body_simple(belle_sip_channel_t *obj, int end_of_stream){
424 	size_t content_length=obj->input_stream.content_length;
425 	size_t to_read=obj->input_stream.write_ptr-obj->input_stream.read_ptr;
426 	belle_sip_message_t *msg=obj->input_stream.msg;
427 	belle_sip_body_handler_t *bh=belle_sip_message_get_body_handler(msg);
428 	size_t cursize=belle_sip_body_handler_get_transfered_size(bh);
429 
430 	if ((cursize == 0) && (to_read == 0)) {
431 		/**
432 		 * No data has been received yet, so do not call feed_body() with a size
433 		 * of 0 that is meaning that the transfer is finished.
434 		 */
435 	} else {
436 		to_read=MIN(content_length-cursize, to_read);
437 		feed_body(obj,to_read);
438 	}
439 
440 	if (end_of_stream ||  belle_sip_body_handler_get_transfered_size(bh)>=content_length){
441 		/*great body completed*/
442 		belle_sip_message("channel [%p] read [%i] bytes of body from [%s:%i]"	,obj
443 			,(int)content_length
444 			,obj->peer_name
445 			,obj->peer_port);
446 		belle_sip_channel_message_ready(obj);
447 		return BELLE_SIP_CONTINUE;
448 	}
449 	/*body is not finished, we need more data*/
450 	return BELLE_SIP_STOP;
451 }
452 
acquire_chuncked_body(belle_sip_channel_t * obj)453 static int acquire_chuncked_body(belle_sip_channel_t *obj){
454 	belle_sip_channel_input_stream_t *st=&obj->input_stream;
455 	int readsize;
456 	do{
457 		if (st->chunk_size==-1){
458 			char *tmp;
459 			/*belle_sip_message("seeing: %s",st->read_ptr);*/
460 			while ( (tmp=strstr(st->read_ptr,"\r\n"))==st->read_ptr){/*skip \r\n*/
461 				st->read_ptr+=2;
462 			}
463 
464 			if (tmp!=NULL){
465 				/*the chunk length is there*/
466 				long chunksize=strtol(st->read_ptr,NULL,16);
467 				if (chunksize>=0 && chunksize!=LONG_MAX){
468 					if (chunksize==0){
469 						belle_sip_message("Got end of chunked body");
470 						st->read_ptr=tmp+4; /*last chunk indicator finishes with two \r\n*/
471 						if (st->read_ptr>st->write_ptr) st->read_ptr=st->write_ptr;
472 						belle_sip_channel_message_ready(obj);
473 						return BELLE_SIP_CONTINUE;
474 					}else{
475 						belle_sip_message("Will get a chunk of %i bytes",(int)chunksize);
476 						st->chunk_size=chunksize;
477 						st->chunk_read_size=0;
478 						st->read_ptr=tmp+2;
479 					}
480 				}else{
481 					belle_sip_error("Chunk parse error");
482 					belle_sip_channel_input_stream_reset(st);
483 					return BELLE_SIP_CONTINUE;
484 				}
485 			}else{
486 				/*need more data*/
487 				return BELLE_SIP_STOP;
488 			}
489 		}
490 		readsize=MIN((int)(st->write_ptr-st->read_ptr),st->chunk_size-st->chunk_read_size);
491 		if (readsize>0){
492 			feed_body(obj,readsize);
493 			st->chunk_read_size+=readsize;
494 		}
495 		if (st->chunk_size==st->chunk_read_size){
496 			/*we have a chunk completed*/
497 			st->content_length+=st->chunk_size;
498 			belle_sip_message("Chunk of [%i] bytes completed",st->chunk_size);
499 			st->chunk_size=-1;/*wait for next chunk indicator*/
500 		}else{
501 			/*need more data*/
502 			return BELLE_SIP_STOP;
503 		}
504 	}while(st->write_ptr-st->read_ptr>0); /*no need to continue if nothing to read*/
505 	return BELLE_SIP_STOP;
506 }
507 
acquire_body(belle_sip_channel_t * obj,int end_of_stream)508 static int acquire_body(belle_sip_channel_t *obj, int end_of_stream){
509 	if (obj->input_stream.chuncked_mode)
510 		return acquire_chuncked_body(obj);
511 	else return acquire_body_simple(obj,end_of_stream);
512 }
513 
notify_incoming_messages(belle_sip_channel_t * obj)514 static void notify_incoming_messages(belle_sip_channel_t *obj){
515 	belle_sip_list_t *elem,*l_it;
516 
517 	belle_sip_list_t *listeners=belle_sip_list_copy_with_data(obj->full_listeners,(void *(*)(void*))belle_sip_object_ref);
518 
519 	for(l_it=listeners;l_it!=NULL;l_it=l_it->next){
520 		belle_sip_channel_listener_t *listener=(belle_sip_channel_listener_t*)l_it->data;
521 		for(elem=obj->incoming_messages;elem!=NULL;elem=elem->next){
522 			belle_sip_message_t *msg=(belle_sip_message_t*)elem->data;
523 			BELLE_SIP_INTERFACE_METHODS_TYPE(belle_sip_channel_listener_t) *methods;
524 			methods=BELLE_SIP_INTERFACE_GET_METHODS(listener,belle_sip_channel_listener_t);
525 			if (methods->on_message)
526 				methods->on_message(listener,obj,msg);
527 		}
528 	}
529 	belle_sip_list_free_with_data(listeners,belle_sip_object_unref);
530 	belle_sip_list_free_with_data(obj->incoming_messages,belle_sip_object_unref);
531 	obj->incoming_messages=NULL;
532 }
533 
belle_sip_channel_parse_stream(belle_sip_channel_t * obj,int end_of_stream)534 void belle_sip_channel_parse_stream(belle_sip_channel_t *obj, int end_of_stream){
535 	int offset;
536 	size_t read_size=0;
537 	int num;
538 
539 	while ((num=(int)(obj->input_stream.write_ptr-obj->input_stream.read_ptr))>0){
540 
541 		if (obj->input_stream.state == WAITING_MESSAGE_START) {
542 			int i;
543 			/*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*/
544 			for (i=0;i<num-1;i++) {
545 				if ((obj->input_stream.read_ptr[i]=='\r' && obj->input_stream.read_ptr[i+1]=='\n')
546 						|| 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*/) {
547 					/*good, now we can start searching  for request/response*/
548 					if ((offset=get_message_start_pos(obj->input_stream.read_ptr,num)) >=0 ) {
549 						/*message found !*/
550 						if (offset>0) {
551 							belle_sip_warning("trashing [%i] bytes in front of sip message on channel [%p]",offset,obj);
552 							obj->input_stream.read_ptr+=offset;
553 						}
554 						obj->input_stream.state=MESSAGE_AQUISITION;
555 					} else {
556 						belle_sip_debug("Unexpected [%s] received on channel [%p], trashing",obj->input_stream.read_ptr,obj);
557 						obj->input_stream.read_ptr=obj->input_stream.write_ptr;
558 						belle_sip_channel_input_stream_reset(&obj->input_stream);
559 						continue;
560 					}
561 				break;
562 				}
563 			}
564 
565 			if (i >= num-1) {
566 				belle_sip_debug("[%s] received on channel [%p], cannot determine if expected or not, waiting for new data",obj->input_stream.read_ptr,obj);
567 				break;
568 			}
569 		}
570 
571 		if (obj->input_stream.state==MESSAGE_AQUISITION) {
572 			/*search for \r\n\r\n*/
573 			char* end_of_message=NULL;
574 			if ((end_of_message=strstr(obj->input_stream.read_ptr,"\r\n\r\n"))){
575 				int bytes_to_parse;
576 				char tmp;
577 				/*end of message found*/
578 				end_of_message+=4;/*add \r\n\r\n*/
579 				bytes_to_parse=(int)(end_of_message-obj->input_stream.read_ptr);
580 				tmp=*end_of_message;
581 				*end_of_message='\0';/*this is in order for the following log to print the message only to its end.*/
582 				/*belle_sip_message("channel [%p] read message of [%i] bytes:\n%.40s...",obj, bytes_to_parse, obj->input_stream.read_ptr);*/
583 				obj->input_stream.msg=belle_sip_message_parse_raw(obj->input_stream.read_ptr
584 										,bytes_to_parse
585 										,&read_size);
586 				*end_of_message=tmp;
587 				obj->input_stream.read_ptr+=read_size;
588 				if (obj->input_stream.msg && read_size > 0){
589 					belle_sip_message("channel [%p] [%i] bytes parsed",obj,(int)read_size);
590 					belle_sip_object_ref(obj->input_stream.msg);
591 					if (belle_sip_message_is_request(obj->input_stream.msg)) fix_incoming_via(BELLE_SIP_REQUEST(obj->input_stream.msg),obj->current_peer);
592 					/*check for body*/
593 
594 					if (check_body(obj)){
595 						obj->input_stream.state=BODY_AQUISITION;
596 					} else {
597 						/*no body*/
598 						belle_sip_channel_message_ready(obj);
599 						continue;
600 					}
601 				}else{
602 					belle_sip_error("Could not parse [%s], on channel [%p] skipping to [%s]",obj->input_stream.read_ptr
603 														,obj
604 														,end_of_message);
605 					obj->input_stream.read_ptr=end_of_message;
606 					obj->input_stream.state=WAITING_MESSAGE_START;
607 					continue;
608 				}
609 			}else break; /*The message isn't finished to be receive, we need more data*/
610 		}
611 
612 		if (obj->input_stream.state==BODY_AQUISITION) {
613 			if (acquire_body(obj,end_of_stream)==BELLE_SIP_STOP) break;
614 		}
615 	}
616 }
617 
belle_sip_channel_process_stream(belle_sip_channel_t * obj,int eos)618 static void belle_sip_channel_process_stream(belle_sip_channel_t *obj, int eos){
619 	belle_sip_channel_parse_stream(obj,eos);
620 	if (obj->incoming_messages) {
621 		if (obj->simulated_recv_return == 1500) {
622 			belle_sip_list_t *elem;
623 			for(elem=obj->incoming_messages;elem!=NULL;elem=elem->next){
624 				belle_sip_message_t *msg=(belle_sip_message_t*)elem->data;
625 				char* dump = belle_sip_message_to_string(msg);
626 				belle_sip_message("Silently discarding incoming message [%.50s...] on channel [%p]",dump, obj);
627 				belle_sip_free(dump);
628 			}
629 			belle_sip_list_free_with_data(obj->incoming_messages,belle_sip_object_unref);
630 			obj->incoming_messages=NULL;
631 		} else {
632 			notify_incoming_messages(obj);
633 		}
634 	}
635 }
636 
belle_sip_channel_process_read_data(belle_sip_channel_t * obj)637 static int belle_sip_channel_process_read_data(belle_sip_channel_t *obj){
638 	int num;
639 	int ret=BELLE_SIP_CONTINUE;
640 
641 	/*prevent system to suspend the process until we have finish reading everything from the socket and notified the upper layer*/
642 	if (obj->input_stream.state == WAITING_MESSAGE_START) {
643 		channel_begin_recv_background_task(obj);
644 	}
645 
646 	if (obj->simulated_recv_return>0) {
647 		num=belle_sip_channel_recv(obj,obj->input_stream.write_ptr,belle_sip_channel_input_stream_get_buff_length(&obj->input_stream)-1);
648 	} else {
649 		belle_sip_message("channel [%p]: simulating recv() returning %i",obj,obj->simulated_recv_return);
650 		num=obj->simulated_recv_return;
651 	}
652 	if (num>0){
653 		char *begin=obj->input_stream.write_ptr;
654 		obj->input_stream.write_ptr+=num;
655 		/*first null terminate the read buff*/
656 		*obj->input_stream.write_ptr='\0';
657 		if (num>20 || obj->input_stream.state != WAITING_MESSAGE_START ) /*to avoid tracing server based keep alives*/ {
658 			char *logbuf = make_logbuf(obj, BELLE_SIP_LOG_MESSAGE ,begin,num);
659 			if (logbuf) {
660 				belle_sip_message("channel [%p]: received [%i] new bytes from [%s://%s:%i]:\n%s",
661 						obj,
662 						num,
663 						belle_sip_channel_get_transport_name(obj),
664 						obj->peer_name,
665 						obj->peer_port,
666 						logbuf);
667 				belle_sip_free(logbuf);
668 			}
669 		}
670 		belle_sip_channel_process_stream(obj,FALSE);
671 		if (obj->input_stream.state == WAITING_MESSAGE_START){
672 			channel_end_recv_background_task(obj);
673 		}/*if still in message acquisition state, keep the backgroud task*/
674 	} else if (num == 0) {
675 		/*before closing the channel, check if there was a pending message to receive, whose body acquisition is to be finished.*/
676 		belle_sip_channel_process_stream(obj,TRUE);
677 		obj->closed_by_remote = TRUE;
678 		channel_set_state(obj,BELLE_SIP_CHANNEL_DISCONNECTED);
679 		ret=BELLE_SIP_STOP;
680 	} else if (belle_sip_error_code_is_would_block(-num)){
681 		belle_sip_message("channel [%p]: recv() EWOULDBLOCK",obj);
682 		ret=BELLE_SIP_CONTINUE;
683 	}else{
684 		belle_sip_error("Receive error on channel [%p]",obj);
685 		channel_set_state(obj,BELLE_SIP_CHANNEL_ERROR);
686 		ret=BELLE_SIP_STOP;
687 	}
688 	return ret;
689 }
690 
belle_sip_channel_process_data(belle_sip_channel_t * obj,unsigned int revents)691 int belle_sip_channel_process_data(belle_sip_channel_t *obj,unsigned int revents){
692 	int ret=BELLE_SIP_CONTINUE;
693 	belle_sip_object_ref(obj);
694 	if (revents & BELLE_SIP_EVENT_READ) {
695 		int rret=belle_sip_channel_process_read_data(obj);
696 		if (rret==BELLE_SIP_STOP) ret=BELLE_SIP_STOP;
697 	}
698 	if (revents & BELLE_SIP_EVENT_WRITE){
699 		/*if we are here, this is because we had an EWOULDBLOCK while sending a message*/
700 		/*continue to send pending messages but before check the channel is still alive because
701 		it may have been closed by belle_sip_channel_process_read_data() above.*/
702 		if (obj->state == BELLE_SIP_CHANNEL_READY){
703 			channel_process_queue(obj);
704 		}
705 	}
706 	belle_sip_object_unref(obj);
707 	return ret;
708 }
709 
channel_inactive_timeout(void * data,unsigned int event)710 static int channel_inactive_timeout(void *data, unsigned int event){
711 	belle_sip_channel_t *obj=(belle_sip_channel_t *)data;
712 	belle_sip_message("Channel [%p]: inactivity timeout reached.",obj);
713 	channel_set_state(obj,BELLE_SIP_CHANNEL_DISCONNECTED);
714 	return BELLE_SIP_STOP;
715 }
716 
update_inactivity_timer(belle_sip_channel_t * obj,int from_recv)717 static void update_inactivity_timer(belle_sip_channel_t *obj, int from_recv){
718 	int inactive_timeout=belle_sip_stack_get_inactive_transport_timeout(obj->stack)*1000;
719 	if (inactive_timeout>0){
720 		if (!obj->inactivity_timer ){
721 			obj->inactivity_timer=belle_sip_main_loop_create_timeout(obj->stack->ml,channel_inactive_timeout,obj,inactive_timeout,"Channel inactivity timer");
722 		}else{
723 			/*restart the timer for new period*/
724 			belle_sip_source_set_timeout(obj->inactivity_timer,inactive_timeout);
725 		}
726 	}else{
727 		if (obj->inactivity_timer){
728 			belle_sip_main_loop_remove_source(obj->stack->ml,obj->inactivity_timer);
729 			belle_sip_object_unref(obj->inactivity_timer);
730 			obj->inactivity_timer=NULL;
731 		}
732 	}
733 	if (from_recv)
734 		obj->last_recv_time=belle_sip_time_ms();
735 }
736 
737 /*constructor for channels creating an outgoing connection
738  * bindip local ip address to bind on, typically 0.0.0.0 or ::0
739  * locaport locaport to use for binding, can be set to 0 if port doesn't matter
740  * peer_cname canonical name of remote host, used for TLS verification
741  * peername peer's hostname, either ip address or DNS name
742  * pee_port peer's port to connect to.
743  */
belle_sip_channel_init(belle_sip_channel_t * obj,belle_sip_stack_t * stack,const char * bindip,int localport,const char * peer_cname,const char * peername,int peer_port)744 void belle_sip_channel_init(belle_sip_channel_t *obj, belle_sip_stack_t *stack,const char *bindip,int localport,const char *peer_cname, const char *peername, int peer_port){
745 	/*to initialize our base class:*/
746 	belle_sip_channel_set_socket(obj,-1,NULL);
747 
748 	/*then initialize members*/
749 	obj->ai_family=AF_INET;
750 	obj->peer_cname=peer_cname ? belle_sip_strdup(peer_cname) : NULL;
751 	obj->peer_name=belle_sip_strdup(peername);
752 	obj->peer_port=peer_port;
753 	obj->stack=stack;
754 	if (bindip){
755 		if (strcmp(bindip,"::0")!=0 && strcmp(bindip,"0.0.0.0")!=0)
756 			obj->local_ip=belle_sip_strdup(bindip);
757 		if (strchr(bindip,':')!=NULL)
758 			obj->ai_family=AF_INET6;
759 	}
760 	obj->local_port=localport;
761 	obj->simulated_recv_return=1;/*not set*/
762 	if (peername){
763 		/*check if we are given a real dns name or just an ip address*/
764 		struct addrinfo *ai=bctbx_ip_address_to_addrinfo(AF_UNSPEC,SOCK_STREAM,peername,peer_port);
765 		if (ai) bctbx_freeaddrinfo(ai);
766 		else obj->has_name=TRUE;
767 	}
768 	belle_sip_channel_input_stream_reset(&obj->input_stream);
769 	update_inactivity_timer(obj,FALSE);
770 }
771 
772 /*constructor for channels created by incoming connections*/
belle_sip_channel_init_with_addr(belle_sip_channel_t * obj,belle_sip_stack_t * stack,const char * bindip,int localport,const struct sockaddr * peer_addr,socklen_t addrlen)773 void belle_sip_channel_init_with_addr(belle_sip_channel_t *obj, belle_sip_stack_t *stack, const char *bindip, int localport, const struct sockaddr *peer_addr, socklen_t addrlen){
774 	char remoteip[64];
775 	struct addrinfo ai;
776 	int peer_port;
777 
778 	memset(&ai,0,sizeof(ai));
779 	ai.ai_family=peer_addr->sa_family;
780 	ai.ai_addr=(struct sockaddr*)peer_addr;
781 	ai.ai_addrlen=addrlen;
782 	bctbx_addrinfo_to_ip_address(&ai,remoteip,sizeof(remoteip),&peer_port);
783 	belle_sip_channel_init(obj,stack,bindip,localport,NULL,remoteip,peer_port);
784 	obj->peer_list=obj->current_peer=bctbx_ip_address_to_addrinfo(ai.ai_family, ai.ai_socktype, obj->peer_name,obj->peer_port);
785 	obj->ai_family=ai.ai_family;
786 }
787 
belle_sip_channel_set_socket(belle_sip_channel_t * obj,belle_sip_socket_t sock,belle_sip_source_func_t datafunc)788 void belle_sip_channel_set_socket(belle_sip_channel_t *obj, belle_sip_socket_t sock, belle_sip_source_func_t datafunc){
789 	belle_sip_socket_source_init((belle_sip_source_t*)obj
790 									, datafunc
791 									, obj
792 									, sock
793 									, BELLE_SIP_EVENT_READ|BELLE_SIP_EVENT_WRITE
794 									, -1);
795 }
796 
is_state_only_listener(const belle_sip_channel_listener_t * listener)797 static bool_t is_state_only_listener(const belle_sip_channel_listener_t *listener) {
798 	BELLE_SIP_INTERFACE_METHODS_TYPE(belle_sip_channel_listener_t) *methods;
799 	methods=BELLE_SIP_INTERFACE_GET_METHODS(listener,belle_sip_channel_listener_t);
800 	return methods->on_state_changed && !(methods->on_message_headers || methods->on_message || methods->on_sending || methods->on_auth_requested);
801 }
channel_remove_listener(belle_sip_channel_t * obj,belle_sip_channel_listener_t * l)802 static void channel_remove_listener(belle_sip_channel_t *obj, belle_sip_channel_listener_t *l){
803 	if (is_state_only_listener(l))
804 		obj->state_listeners=belle_sip_list_remove(obj->state_listeners,l);
805 	else
806 		obj->full_listeners=belle_sip_list_remove(obj->full_listeners,l);
807 
808 }
809 
belle_sip_channel_add_listener(belle_sip_channel_t * obj,belle_sip_channel_listener_t * l)810 void belle_sip_channel_add_listener(belle_sip_channel_t *obj, belle_sip_channel_listener_t *l){
811 
812 	if (is_state_only_listener(l)) {
813 		obj->state_listeners=belle_sip_list_prepend(obj->state_listeners,
814 												   belle_sip_object_weak_ref(l,
815 																	   (belle_sip_object_destroy_notify_t)channel_remove_listener,obj));
816 	} else {
817 		obj->full_listeners=belle_sip_list_prepend(obj->full_listeners,
818 													belle_sip_object_weak_ref(l,
819 																		(belle_sip_object_destroy_notify_t)channel_remove_listener,obj));
820 	}
821 
822 }
823 
belle_sip_channel_remove_listener(belle_sip_channel_t * obj,belle_sip_channel_listener_t * l)824 void belle_sip_channel_remove_listener(belle_sip_channel_t *obj, belle_sip_channel_listener_t *l){
825 	belle_sip_object_weak_unref(l,(belle_sip_object_destroy_notify_t)channel_remove_listener,obj);
826 	channel_remove_listener(obj,l);
827 }
828 
belle_sip_channel_matches(const belle_sip_channel_t * obj,const belle_sip_hop_t * hop,const struct addrinfo * addr)829 int belle_sip_channel_matches(const belle_sip_channel_t *obj, const belle_sip_hop_t *hop, const struct addrinfo *addr){
830 	if (hop && strcmp(hop->host,obj->peer_name)==0 && (hop->port==obj->peer_port || obj->srv_overrides_port)){
831 		if (hop->cname && obj->peer_cname && strcmp(hop->cname,obj->peer_cname)!=0)
832 			return 0; /*cname mismatch*/
833 		return 1;
834 	}
835 	if (addr && obj->current_peer)
836 		return bctbx_sockaddr_equals(addr->ai_addr,obj->current_peer->ai_addr);
837 	return 0;
838 }
839 
belle_sip_channel_get_local_address(belle_sip_channel_t * obj,int * port)840 const char *belle_sip_channel_get_local_address(belle_sip_channel_t *obj, int *port){
841 	if (port) *port=obj->local_port;
842 	return obj->local_ip;
843 }
844 
belle_sip_channel_get_public_address(belle_sip_channel_t * obj,int * port)845 const char *belle_sip_channel_get_public_address(belle_sip_channel_t *obj, int *port){
846 	const char *ret = obj->public_ip ? obj->public_ip : obj->local_ip;
847 	if (*port) *port= obj->public_port;
848 	return ret;
849 }
850 
belle_sip_channel_create_routable_uri(belle_sip_channel_t * chan)851 belle_sip_uri_t *belle_sip_channel_create_routable_uri(belle_sip_channel_t *chan) {
852 	const char *transport = belle_sip_channel_get_transport_name_lower_case(chan);
853 	belle_sip_uri_t* uri = belle_sip_uri_new();
854 	unsigned char natted = chan->public_ip && strcmp(chan->public_ip,chan->local_ip)!=0;
855 
856 	if (natted) {
857 		belle_sip_uri_set_host(uri, chan->public_ip);
858 		belle_sip_uri_set_port(uri, chan->public_port);
859 	} else {
860 
861 		belle_sip_uri_set_host(uri, chan->local_ip);
862 		// With streamed protocols listening port is what we want
863 		if (chan->lp)
864 			belle_sip_uri_set_port(uri, belle_sip_uri_get_port(chan->lp->listening_uri));
865 		else belle_sip_uri_set_port(uri,chan->local_port);
866 	}
867 
868 	belle_sip_uri_set_transport_param(uri, transport);
869 	belle_sip_uri_set_lr_param(uri, TRUE);
870 	return uri;
871 }
872 
873 
belle_sip_channel_is_reliable(const belle_sip_channel_t * obj)874 int belle_sip_channel_is_reliable(const belle_sip_channel_t *obj){
875 	return BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->reliable;
876 }
877 
belle_sip_channel_get_transport_name_lower_case(const belle_sip_channel_t * obj)878 const char * belle_sip_channel_get_transport_name_lower_case(const belle_sip_channel_t *obj){
879 	const char* transport = belle_sip_channel_get_transport_name(obj);
880 	if (strcasecmp("udp",transport)==0) return "udp";
881 	else if (strcasecmp("tcp",transport)==0) return "tcp";
882 	else if (strcasecmp("tls",transport)==0) return "tls";
883 	else if (strcasecmp("dtls",transport)==0) return "dtls";
884 	else {
885 		belle_sip_message("Cannot convert [%s] to lower case",transport);
886 		return transport;
887 	}
888 }
889 
belle_sip_channel_get_transport_name(const belle_sip_channel_t * obj)890 const char * belle_sip_channel_get_transport_name(const belle_sip_channel_t *obj){
891 	return BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->transport;
892 }
893 
belle_sip_channel_send(belle_sip_channel_t * obj,const void * buf,size_t buflen)894 int belle_sip_channel_send(belle_sip_channel_t *obj, const void *buf, size_t buflen){
895 	update_inactivity_timer(obj,FALSE);
896 	return BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->channel_send(obj,buf,buflen);
897 }
898 
belle_sip_channel_recv(belle_sip_channel_t * obj,void * buf,size_t buflen)899 int belle_sip_channel_recv(belle_sip_channel_t *obj, void *buf, size_t buflen){
900 	update_inactivity_timer(obj,TRUE);
901 	return BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->channel_recv(obj,buf,buflen);
902 }
903 
belle_sip_channel_close(belle_sip_channel_t * obj)904 void belle_sip_channel_close(belle_sip_channel_t *obj){
905 	if (BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->close)
906 		BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->close(obj); /*udp channel doesn't have close function*/
907 	/*removing the source (our base class) will decrement the ref count, this why this code needs to be protected by ref/unref.*/
908 	belle_sip_main_loop_remove_source(obj->stack->ml,(belle_sip_source_t*)obj);
909 	belle_sip_source_uninit((belle_sip_source_t*)obj);
910 }
911 
belle_sip_channel_get_peer(belle_sip_channel_t * obj)912 const struct addrinfo * belle_sip_channel_get_peer(belle_sip_channel_t *obj){
913 	return obj->current_peer;
914 }
915 
channel_on_send_background_task_ended(belle_sip_channel_t * obj)916 static void channel_on_send_background_task_ended(belle_sip_channel_t *obj){
917 	belle_sip_warning("channel [%p]: send background task has to be ended now, but work isn't finished.",obj);
918 	channel_end_send_background_task(obj);
919 }
920 
channel_begin_send_background_task(belle_sip_channel_t * obj)921 static void channel_begin_send_background_task(belle_sip_channel_t *obj){
922 	if (obj->bg_task_id==0){
923 		obj->bg_task_id=belle_sip_begin_background_task("belle-sip send channel",(void (*)(void*))channel_on_send_background_task_ended, obj);
924 		if (obj->bg_task_id) belle_sip_message("channel [%p]: starting send background task with id=[%lx].",obj,obj->bg_task_id);
925 	}
926 }
927 
channel_end_send_background_task(belle_sip_channel_t * obj)928 static void channel_end_send_background_task(belle_sip_channel_t *obj){
929 	if (obj->bg_task_id){
930 		belle_sip_message("channel [%p]: ending send background task with id=[%lx].",obj,obj->bg_task_id);
931 		belle_sip_end_background_task(obj->bg_task_id);
932 		obj->bg_task_id=0;
933 	}
934 }
935 
channel_on_recv_background_task_ended(belle_sip_channel_t * obj)936 static void channel_on_recv_background_task_ended(belle_sip_channel_t *obj){
937 	belle_sip_warning("channel [%p]: recv background task has to be ended now, but work isn't finished.",obj);
938 	channel_end_recv_background_task(obj);
939 }
940 
channel_begin_recv_background_task(belle_sip_channel_t * obj)941 static void channel_begin_recv_background_task(belle_sip_channel_t *obj){
942 	if (obj->recv_bg_task_id==0){
943 		obj->recv_bg_task_id=belle_sip_begin_background_task("belle-sip recv channel",(void (*)(void*))channel_on_recv_background_task_ended, obj);
944 		if (obj->recv_bg_task_id) belle_sip_message("channel [%p]: starting recv background task with id=[%lx].",obj,obj->recv_bg_task_id);
945 	}
946 }
947 
channel_end_recv_background_task(belle_sip_channel_t * obj)948 static void channel_end_recv_background_task(belle_sip_channel_t *obj){
949 	if (obj->recv_bg_task_id){
950 		belle_sip_message("channel [%p]: ending recv background task with id=[%lx].",obj,obj->recv_bg_task_id);
951 		belle_sip_end_background_task(obj->recv_bg_task_id);
952 		obj->recv_bg_task_id=0;
953 	}
954 }
955 
channel_invoke_state_listener(belle_sip_channel_t * obj)956 static void channel_invoke_state_listener(belle_sip_channel_t *obj){
957 	int close = FALSE;
958 	switch(obj->state){
959 		case BELLE_SIP_CHANNEL_DISCONNECTED:
960 		case BELLE_SIP_CHANNEL_ERROR:
961 		/*the background tasks must be released "after" notifying the app of the disconnected or error state
962 		 By "after" it is means not before the main loop iteration that will notify the app.
963 		 This is the reason why these calls are done here rather than in the channel_set_state() function.*/
964 		channel_end_send_background_task(obj);
965 		channel_end_recv_background_task(obj);
966 		close = TRUE;
967 		break;
968 		default:
969 		break;
970 	}
971 	/*Channel listeners may drop the last reference of the channel, so protect by ref/unref until we finish.*/
972 	belle_sip_object_ref(obj);
973 	BELLE_SIP_CHANNEL_INVOKE_STATE_LISTENERS(obj,obj->state);
974 	if (close) belle_sip_channel_close(obj);
975 	belle_sip_object_unref(obj);
976 }
977 
channel_notify_error_to_listeners(belle_sip_channel_t * obj)978 static void channel_notify_error_to_listeners(belle_sip_channel_t *obj){
979 	/* The channel may have been passed to DISCONNECTED state due to _force_close() method.
980 	 * Do not notify the error in this case, since the channel is already closed.
981 	 */
982 	if (obj->state == BELLE_SIP_CHANNEL_ERROR){
983 		channel_invoke_state_listener(obj);
984 	}
985 	belle_sip_object_unref(obj);
986 }
987 
channel_connect_next(belle_sip_channel_t * obj)988 static void channel_connect_next(belle_sip_channel_t *obj){
989 	if (obj->state == BELLE_SIP_CHANNEL_RETRY){
990 		belle_sip_channel_connect(obj);
991 	}
992 	belle_sip_object_unref(obj);
993 }
994 
belle_sip_channel_handle_error(belle_sip_channel_t * obj)995 static void belle_sip_channel_handle_error(belle_sip_channel_t *obj){
996 	if (obj->state!=BELLE_SIP_CHANNEL_READY || obj->soft_error){
997 		/* Previous connection attempts were failed (channel could not get ready) OR soft error reported*/
998 		obj->soft_error = FALSE;
999 		/* See if you can retry on an alternate ip address.*/
1000 		if (obj->current_peer && obj->current_peer->ai_next){ /*obj->current_peer may be null in case of dns error*/
1001 			obj->current_peer=obj->current_peer->ai_next;
1002 			channel_set_state(obj,BELLE_SIP_CHANNEL_RETRY);
1003 			belle_sip_channel_close(obj);
1004 			belle_sip_main_loop_do_later(obj->stack->ml,(belle_sip_callback_t)channel_connect_next,belle_sip_object_ref(obj));
1005 			return;
1006 		}/*else we have already tried all the ip addresses, so give up and notify the error*/
1007 	}/*else the channel was previously working good with the current ip address but now fails, so let's notify the error*/
1008 
1009 	obj->state=BELLE_SIP_CHANNEL_ERROR;
1010 	/*Because error notification will in practice trigger the destruction of possible transactions and this channel,
1011 	* it is safer to invoke the listener outside the current call stack.
1012 	* Indeed the channel encounters network errors while being called for transmiting by a transaction.
1013 	*/
1014 	belle_sip_main_loop_do_later(obj->stack->ml,(belle_sip_callback_t)channel_notify_error_to_listeners,belle_sip_object_ref(obj));
1015 }
1016 
belle_sip_channel_notify_timeout(belle_sip_channel_t * obj)1017 int belle_sip_channel_notify_timeout(belle_sip_channel_t *obj){
1018 	const int too_long=60;
1019 
1020 	if (obj->state != BELLE_SIP_CHANNEL_READY){
1021 		/*no need to notify the timeout if the channel is already in error or retry state*/
1022 		return FALSE;
1023 	}
1024 
1025 	if ((int)(belle_sip_time_ms() - obj->last_recv_time) >= (too_long * 1000)){
1026 		belle_sip_message("A timeout related to this channel occured and no message received during last %i seconds. This channel is suspect, moving to error state",too_long);
1027 		channel_set_state(obj,BELLE_SIP_CHANNEL_ERROR);
1028 		return TRUE;
1029 	}
1030 	return FALSE;
1031 }
1032 
belle_sip_channel_notify_server_error(belle_sip_channel_t * obj)1033 void belle_sip_channel_notify_server_error(belle_sip_channel_t *obj){
1034 	belle_sip_message("channel[%p]: this server is encountering internal errors, moving to error state to eventually connect to another IP.", obj);
1035 	obj->soft_error = TRUE;
1036 	channel_set_state(obj,BELLE_SIP_CHANNEL_ERROR);
1037 }
1038 
channel_set_state(belle_sip_channel_t * obj,belle_sip_channel_state_t state)1039 void channel_set_state(belle_sip_channel_t *obj, belle_sip_channel_state_t state) {
1040 	belle_sip_message("channel %p: state %s",obj,belle_sip_channel_state_to_string(state));
1041 
1042 	if (state==BELLE_SIP_CHANNEL_ERROR){
1043 		belle_sip_channel_handle_error(obj);
1044 	}else{
1045 		obj->state=state;
1046 		channel_invoke_state_listener(obj);
1047 	}
1048 }
1049 
free_ewouldblock_buffer(belle_sip_channel_t * obj)1050 static void free_ewouldblock_buffer(belle_sip_channel_t *obj){
1051 	if (obj->ewouldblock_buffer){
1052 		belle_sip_free(obj->ewouldblock_buffer);
1053 		obj->ewouldblock_buffer=NULL;
1054 		obj->ewouldblock_size=0;
1055 		obj->ewouldblock_offset=0;
1056 	}
1057 }
1058 
handle_ewouldblock(belle_sip_channel_t * obj,const char * buffer,size_t size)1059 static void handle_ewouldblock(belle_sip_channel_t *obj, const char *buffer, size_t size){
1060 	belle_sip_source_set_events((belle_sip_source_t*)obj,BELLE_SIP_EVENT_READ|BELLE_SIP_EVENT_WRITE|BELLE_SIP_EVENT_ERROR);
1061 	free_ewouldblock_buffer(obj);
1062 	obj->ewouldblock_buffer=belle_sip_malloc(size);
1063 	obj->ewouldblock_size=size;
1064 	memcpy(obj->ewouldblock_buffer,buffer,size);
1065 }
1066 
find_non_printable(const char * buffer,size_t size)1067 static size_t find_non_printable(const char *buffer, size_t size){
1068 #if 0
1069 	size_t i;
1070 	for(i=0;i<size;++i){
1071 		/*we must check that character is printable, not just ascii
1072 		(31 'US' char is not printable for instance)*/
1073 #ifdef _MSC_VER
1074 		if ((buffer[i] < 0) || (buffer[i] > 255)) return i;
1075 #endif
1076 		if (!isprint(buffer[i]) && !isspace(buffer[i])) return i;
1077 	}
1078 	return size;
1079 #else
1080 	size_t i=0;
1081 	mbstate_t mbs;
1082 	memset(&mbs, 0, sizeof(mbs));
1083 	do {
1084 		size_t valid_multibyte_len = mbrlen(buffer+i, size-i, &mbs);
1085 		if (valid_multibyte_len == (size_t)-1 || valid_multibyte_len == (size_t)-2 || valid_multibyte_len == 0) break;
1086 		i += valid_multibyte_len;
1087 	}while(1);
1088 	return i;
1089 #endif
1090 }
1091 /*
1092  * this function is to avoid logging too much or non-ascii data received.
1093  */
make_logbuf(belle_sip_channel_t * obj,belle_sip_log_level level,const char * buffer,size_t size)1094 static char *make_logbuf(belle_sip_channel_t *obj, belle_sip_log_level level, const char *buffer, size_t size){
1095 	char *logbuf;
1096 	char truncate_msg[128]={0};
1097 	size_t limit=7000; /*big message when many ice candidates*/
1098 
1099 	if (!belle_sip_log_level_enabled(level)){
1100 		return NULL;
1101 	}
1102 	if (obj->stop_logging_buffer == 1) {
1103 		return NULL;
1104 	}
1105 	size = MIN(size,limit);
1106 	limit=find_non_printable(buffer, size);
1107 	if (limit < size) {
1108 		belle_sip_message("channel [%p]: found binary data in buffer, will stop logging it now.", obj);
1109 		obj->stop_logging_buffer = 1;
1110 		if (limit == 0){
1111 			snprintf(truncate_msg,sizeof(truncate_msg)-1,"... (binary data)");
1112 		} else {
1113 			snprintf(truncate_msg,sizeof(truncate_msg)-1,"... (first %u bytes shown)",(unsigned int)limit);
1114 		}
1115 	}
1116 	size = limit;
1117 
1118 	size += strlen(truncate_msg);
1119 
1120 	logbuf=belle_sip_malloc(size+1);
1121 	strncpy(logbuf, buffer, size);
1122 	if (truncate_msg[0]!=0){
1123 		strcpy(logbuf+limit,truncate_msg);
1124 	}
1125 	logbuf[size]='\0';
1126 	return logbuf;
1127 }
1128 
send_buffer(belle_sip_channel_t * obj,const char * buffer,size_t size)1129 static int send_buffer(belle_sip_channel_t *obj, const char *buffer, size_t size){
1130 	int ret=0;
1131 	char *logbuf=NULL;
1132 
1133 	if (obj->stack->send_error == 0){
1134 		ret=belle_sip_channel_send(obj,buffer,size);
1135 	}else if (obj->stack->send_error<0){
1136 		/*for testing purpose only */
1137 		ret=obj->stack->send_error;
1138 	} else {
1139 		ret=(int)size; /*to silently discard message*/
1140 	}
1141 
1142 	if (ret<0){
1143 		if (!belle_sip_error_code_is_would_block(-ret)){
1144 			belle_sip_error("channel [%p]: could not send [%i] bytes from [%s://%s:%i] to [%s:%i]"	,obj
1145 				,(int)size
1146 				,belle_sip_channel_get_transport_name(obj)
1147 				,obj->local_ip
1148 				,obj->local_port
1149 				,obj->peer_name
1150 				,obj->peer_port);
1151 			channel_set_state(obj,BELLE_SIP_CHANNEL_ERROR);
1152 		}/*ewouldblock error has to be handled by caller*/
1153 	}else if (size==(size_t)ret){
1154 		logbuf=make_logbuf(obj, BELLE_SIP_LOG_MESSAGE, buffer,size);
1155 		if (logbuf) {
1156 			belle_sip_message("channel [%p]: message %s to [%s://%s:%i], size: [%i] bytes\n%s"
1157 								,obj
1158 								,obj->stack->send_error==0?"sent":"silently discarded"
1159 								,belle_sip_channel_get_transport_name(obj)
1160 								,obj->peer_name
1161 								,obj->peer_port
1162 								,ret
1163 								,logbuf);
1164 		}
1165 	}else{
1166 		logbuf=make_logbuf(obj, BELLE_SIP_LOG_MESSAGE,buffer,ret);
1167 		if (logbuf) {
1168 			belle_sip_message("channel [%p]: message partly sent to [%s://%s:%i], sent: [%i/%i] bytes:\n%s"
1169 								,obj
1170 								,belle_sip_channel_get_transport_name(obj)
1171 								,obj->peer_name
1172 								,obj->peer_port
1173 								,ret
1174 								,(int)size
1175 								,logbuf);
1176 		}
1177 	}
1178 	if (logbuf) belle_sip_free(logbuf);
1179 	return ret;
1180 }
1181 
check_content_length(belle_sip_message_t * msg,size_t body_len)1182 static void check_content_length(belle_sip_message_t *msg, size_t body_len){
1183 	belle_sip_header_content_length_t *ctlen=belle_sip_message_get_header_by_type(msg,belle_sip_header_content_length_t);
1184 	size_t value=ctlen ? belle_sip_header_content_length_get_content_length(ctlen) : 0;
1185 	if (body_len){
1186 		if (ctlen==NULL){
1187 			belle_sip_message("message [%p] has body of size ["FORMAT_SIZE_T"] but no Content-Length, adding it.",msg,body_len);
1188 			belle_sip_message_add_header(msg,
1189 				(belle_sip_header_t*)belle_sip_header_content_length_create(body_len)
1190 			);
1191 		}else{
1192 			if (value!=body_len){
1193 				belle_sip_warning("message [%p] has Content-Length ["FORMAT_SIZE_T"] and body size ["FORMAT_SIZE_T"] which are inconsistent, fixing it.",
1194 					msg, value, body_len);
1195 				belle_sip_header_content_length_set_content_length(ctlen,body_len);
1196 			}
1197 		}
1198 	}else{
1199 		/*no body, or undetermined size body*/
1200 		if (ctlen && value!=0){
1201 			belle_sip_error("message [%p] has Content-Length ["FORMAT_SIZE_T"], but without body or body with undetermined size. Fix your app.",
1202 				msg,value);
1203 		}
1204 	}
1205 }
1206 
compress_body_if_required(belle_sip_message_t * msg)1207 static void compress_body_if_required(belle_sip_message_t *msg) {
1208 	belle_sip_body_handler_t *bh = belle_sip_message_get_body_handler(msg);
1209 	belle_sip_memory_body_handler_t *mbh = NULL;
1210 	belle_sip_header_t *ceh = NULL;
1211 	size_t body_len = 0;
1212 
1213 	if (bh != NULL) {
1214 		body_len = belle_sip_message_get_body_size(msg);
1215 		ceh = belle_sip_message_get_header(msg, "Content-Encoding");
1216 	}
1217 	if ((body_len > 0) && (ceh != NULL)) {
1218 		const char *content_encoding = belle_sip_header_get_unparsed_value(ceh);
1219 		if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(bh, belle_sip_multipart_body_handler_t)) {
1220 			char *marshalled_content = belle_sip_object_to_string(BELLE_SIP_OBJECT(bh));
1221 			mbh = belle_sip_memory_body_handler_new_from_buffer(marshalled_content, strlen(marshalled_content), NULL, NULL);
1222 			bh = BELLE_SIP_BODY_HANDLER(mbh);
1223 			belle_sip_message_set_body_handler(msg, bh);
1224 		}
1225 		if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(bh, belle_sip_memory_body_handler_t)) {
1226 			mbh = BELLE_SIP_MEMORY_BODY_HANDLER(bh);
1227 			belle_sip_memory_body_handler_apply_encoding(mbh, content_encoding);
1228 		} else {
1229 			belle_sip_warning("message [%p] has Content-Encoding [%s] that cannot be applied", msg, content_encoding);
1230 		}
1231 	}
1232 }
1233 
_send_message(belle_sip_channel_t * obj)1234 static void _send_message(belle_sip_channel_t *obj){
1235 	char buffer[belle_sip_send_network_buffer_size];
1236 	size_t len=0;
1237 	belle_sip_error_code error=BELLE_SIP_OK;
1238 	belle_sip_message_t *msg=obj->cur_out_message;
1239 	belle_sip_body_handler_t *bh=belle_sip_message_get_body_handler(msg);
1240 	size_t body_len=bh ? belle_sip_body_handler_get_size(bh) : 0;
1241 	int sendret;
1242 	size_t off;
1243 	int ret;
1244 
1245 	while (obj->ewouldblock_buffer){
1246 		sendret=send_buffer(obj,(const char*)obj->ewouldblock_buffer+obj->ewouldblock_offset,obj->ewouldblock_size-obj->ewouldblock_offset);
1247 		if (sendret>0){
1248 			obj->ewouldblock_offset+=sendret;
1249 			if (obj->ewouldblock_offset==obj->ewouldblock_size){
1250 				free_ewouldblock_buffer(obj);
1251 			}
1252 			/* continue to expedite the ewouldblock error until we it is completed or get a new ewouldblock*/
1253 		}else if (belle_sip_error_code_is_would_block(-sendret)) {
1254 			/*we got an ewouldblock again. Nothing to do, we'll be called later in order to retry*/
1255 			return;
1256 		}else {/*error or disconnection case*/
1257 			goto done;
1258 		}
1259 	}
1260 
1261 	if (obj->out_state==OUTPUT_STREAM_SENDING_HEADERS){
1262 		BELLE_SIP_CHANNEL_INVOKE_SENDING_LISTENERS(obj,msg);
1263 		check_content_length(msg,body_len);
1264 		error=belle_sip_object_marshal((belle_sip_object_t*)msg,buffer,sizeof(buffer)-1,&len);
1265 		if (error!=BELLE_SIP_OK) {
1266 			belle_sip_error("channel [%p] _send_message: marshaling failed.",obj);
1267 			goto done;
1268 		}
1269 		/*send the headers and eventually the body if it fits in our buffer*/
1270 		if (bh){
1271 			size_t max_body_len=sizeof(buffer)-1-len;
1272 
1273 			if (body_len>0 && body_len<=max_body_len){ /*if size is known and fits into our buffer, send together with headers*/
1274 				belle_sip_body_handler_begin_send_transfer(bh);
1275 				do{
1276 					max_body_len=sizeof(buffer)-1-len;
1277 					ret=belle_sip_body_handler_send_chunk(bh,msg,(uint8_t*)buffer+len,&max_body_len);
1278 					if (max_body_len==0)
1279 						belle_sip_warning("belle_sip_body_handler_send_chunk on channel [%p], 0 bytes read",obj);
1280 					len+=max_body_len;
1281 				}while(ret==BELLE_SIP_CONTINUE);
1282 				belle_sip_body_handler_end_transfer(bh);
1283 			}else{
1284 				if (body_len==0){
1285 					belle_sip_fatal("Sending bodies whose size is not known must be done in chunked mode, which is not supported yet.");
1286 				}
1287 				belle_sip_body_handler_begin_send_transfer(bh);
1288 				obj->out_state=OUTPUT_STREAM_SENDING_BODY;
1289 			}
1290 		}
1291 		off=0;
1292 		do{
1293 			sendret=send_buffer(obj,buffer+off,len-off);
1294 			if (sendret>0){
1295 				off+=sendret;
1296 				if (off==len){
1297 					break;
1298 				}
1299 			}else if (belle_sip_error_code_is_would_block(-sendret)) {
1300 				handle_ewouldblock(obj,buffer+off,len-off);
1301 				return;
1302 			}else {/*error or disconnection case*/
1303 				goto done;
1304 			}
1305 		}while(1);
1306 	}
1307 	if (obj->out_state==OUTPUT_STREAM_SENDING_BODY){
1308 		do{
1309 			size_t chunk_len=sizeof(buffer)-1;
1310 			ret=belle_sip_body_handler_send_chunk(bh,msg,(uint8_t*)buffer,&chunk_len);
1311 			if (chunk_len!=0){
1312 				off=0;
1313 				do{
1314 					sendret=send_buffer(obj,buffer+off,chunk_len-off);
1315 					if (sendret>0){
1316 						off+=sendret;
1317 						if (off==chunk_len){
1318 							break;
1319 						}
1320 					}else if (belle_sip_error_code_is_would_block(-sendret)) {
1321 						handle_ewouldblock(obj,buffer+off,chunk_len-off);
1322 						return;
1323 					}else {/*error or disconnection case*/
1324 						goto done;
1325 					}
1326 				}while(1);
1327 			}
1328 		}while(ret==BELLE_SIP_CONTINUE);
1329 		belle_sip_body_handler_end_transfer(bh);
1330 	}
1331 	done:
1332 		/*we get ready to send another message*/
1333 		belle_sip_source_set_events((belle_sip_source_t*)obj,BELLE_SIP_EVENT_READ|BELLE_SIP_EVENT_ERROR);
1334 		free_ewouldblock_buffer(obj);
1335 		obj->out_state=OUTPUT_STREAM_IDLE;
1336 		obj->stop_logging_buffer=0;
1337 		belle_sip_object_unref(obj->cur_out_message);
1338 		obj->cur_out_message=NULL;
1339 }
1340 
send_message(belle_sip_channel_t * obj,belle_sip_message_t * msg)1341 static void send_message(belle_sip_channel_t *obj, belle_sip_message_t *msg){
1342 	obj->cur_out_message=(belle_sip_message_t*)belle_sip_object_ref(msg);
1343 	obj->out_state=OUTPUT_STREAM_SENDING_HEADERS;
1344 	compress_body_if_required(obj->cur_out_message);
1345 	_send_message(obj);
1346 }
1347 
belle_sip_channel_prepare(belle_sip_channel_t * obj)1348 void belle_sip_channel_prepare(belle_sip_channel_t *obj){
1349 	channel_prepare_continue(obj);
1350 }
1351 
channel_push_outgoing(belle_sip_channel_t * obj,belle_sip_message_t * msg)1352 static void channel_push_outgoing(belle_sip_channel_t *obj, belle_sip_message_t *msg){
1353 	obj->outgoing_messages=belle_sip_list_append(obj->outgoing_messages,msg);
1354 }
1355 
channel_pop_outgoing(belle_sip_channel_t * obj)1356 static belle_sip_message_t *channel_pop_outgoing(belle_sip_channel_t *obj){
1357 	belle_sip_message_t *msg=NULL;
1358 	if (obj->outgoing_messages){
1359 		msg=(belle_sip_message_t*)obj->outgoing_messages->data;
1360 		obj->outgoing_messages=belle_sip_list_delete_link(obj->outgoing_messages,obj->outgoing_messages);
1361 	}
1362 	return msg;
1363 }
1364 
channel_prepare_continue(belle_sip_channel_t * obj)1365 static void channel_prepare_continue(belle_sip_channel_t *obj){
1366 	switch(obj->state){
1367 		case BELLE_SIP_CHANNEL_INIT:
1368 			channel_begin_send_background_task(obj);
1369 			belle_sip_channel_resolve(obj);
1370 		break;
1371 		case BELLE_SIP_CHANNEL_RES_DONE:
1372 			belle_sip_channel_connect(obj);
1373 		break;
1374 		case BELLE_SIP_CHANNEL_READY:
1375 			channel_process_queue(obj);
1376 		break;
1377 		default:
1378 		break;
1379 	}
1380 }
1381 
channel_process_queue(belle_sip_channel_t * obj)1382 static void channel_process_queue(belle_sip_channel_t *obj){
1383 	belle_sip_message_t *msg;
1384 	belle_sip_object_ref(obj);/* we need to ref ourself because code below may trigger our destruction*/
1385 
1386 	if (obj->out_state!=OUTPUT_STREAM_IDLE) {
1387 		_send_message(obj);
1388 	}
1389 
1390 	while((msg=channel_pop_outgoing(obj))!=NULL && obj->state==BELLE_SIP_CHANNEL_READY && obj->out_state==OUTPUT_STREAM_IDLE) {
1391 		send_message(obj, msg);
1392 		belle_sip_object_unref(msg);
1393 	}
1394 	if (obj->state == BELLE_SIP_CHANNEL_READY && obj->out_state == OUTPUT_STREAM_IDLE) {
1395 		channel_end_send_background_task(obj);
1396 	}
1397 
1398 	belle_sip_object_unref(obj);
1399 }
1400 
belle_sip_channel_set_ready(belle_sip_channel_t * obj,const struct sockaddr * addr,socklen_t slen)1401 void belle_sip_channel_set_ready(belle_sip_channel_t *obj, const struct sockaddr *addr, socklen_t slen){
1402 	char name[NI_MAXHOST];
1403 	char serv[NI_MAXSERV];
1404 
1405 	if (obj->local_ip==NULL){
1406 		struct sockaddr_storage saddr;
1407 		socklen_t slen2=sizeof(saddr);
1408 		int err;
1409 
1410 		bctbx_sockaddr_remove_v4_mapping(addr,(struct sockaddr*) &saddr,&slen2);
1411 
1412 		err=bctbx_getnameinfo((struct sockaddr*)&saddr,slen2,name,sizeof(name),serv,sizeof(serv),NI_NUMERICHOST|NI_NUMERICSERV);
1413 		if (err!=0){
1414 			belle_sip_error("belle_sip_channel_set_ready(): getnameinfo() failed: %s",gai_strerror(err));
1415 		}else{
1416 			obj->local_ip=belle_sip_strdup(name);
1417 			obj->local_port=atoi(serv);
1418 			belle_sip_message("Channel has local address %s:%s",name,serv);
1419 		}
1420 	}
1421 	channel_set_state(obj,BELLE_SIP_CHANNEL_READY);
1422 	channel_process_queue(obj);
1423 }
1424 
channel_dns_ttl_timeout(void * data,unsigned int event)1425 static int channel_dns_ttl_timeout(void *data, unsigned int event) {
1426 	belle_sip_channel_t *obj = (belle_sip_channel_t *)data;
1427 	belle_sip_message("Channel [%p]: DNS TTL timeout reached.", obj);
1428 	obj->dns_ttl_timedout = TRUE;
1429 	return BELLE_SIP_STOP;
1430 }
1431 
addrinfo_in_list(const struct addrinfo * ai,const struct addrinfo * list)1432 static bool_t addrinfo_in_list(const struct addrinfo *ai, const struct addrinfo *list) {
1433 	const struct addrinfo *item = list;
1434 	bool_t in_list = FALSE;
1435 	while (item != NULL) {
1436 		if ((ai->ai_family == item->ai_family) && (bctbx_sockaddr_equals(ai->ai_addr, item->ai_addr))) {
1437 			in_list = TRUE;
1438 			break;
1439 		}
1440 		item = item->ai_next;
1441 	}
1442 	return in_list;
1443 }
1444 
channel_res_done(void * data,const char * name,struct addrinfo * ai_list,uint32_t ttl)1445 static void channel_res_done(void *data, const char *name, struct addrinfo *ai_list, uint32_t ttl){
1446 	belle_sip_channel_t *obj=(belle_sip_channel_t*)data;
1447 	if (obj->resolver_ctx){
1448 		belle_sip_object_unref(obj->resolver_ctx);
1449 		obj->resolver_ctx=NULL;
1450 	}
1451 	if (ai_list){
1452 		if (!obj->current_peer) {
1453 			obj->peer_list=obj->current_peer=ai_list;
1454 			channel_set_state(obj,BELLE_SIP_CHANNEL_RES_DONE);
1455 		} else {
1456 			if (addrinfo_in_list(obj->current_peer, ai_list)) {
1457 				belle_sip_message("channel[%p]: DNS resolution returned the currently used address, continue using it", obj);
1458 				obj->peer_list = ai_list;
1459 				channel_set_state(obj, BELLE_SIP_CHANNEL_READY);
1460 			} else {
1461 				belle_sip_message("channel[%p]: DNS resolution returned an address different than the one being used, reconnect to the new address", obj);
1462 				obj->peer_list = obj->current_peer = ai_list;
1463 				belle_sip_channel_close(obj);
1464 				belle_sip_main_loop_do_later(obj->stack->ml, (belle_sip_callback_t)channel_connect_next, belle_sip_object_ref(obj));
1465 				channel_set_state(obj, BELLE_SIP_CHANNEL_RETRY);
1466 			}
1467 		}
1468 		channel_prepare_continue(obj);
1469 		if (!obj->dns_ttl_timer ) {
1470 			obj->dns_ttl_timer = belle_sip_main_loop_create_timeout(obj->stack->ml, channel_dns_ttl_timeout, obj, ttl * 1000, "Channel DNS TTL timer");
1471 		} else {
1472 			/* Restart the timer for new period. */
1473 			belle_sip_source_set_timeout(obj->dns_ttl_timer, ttl * 1000);
1474 			belle_sip_main_loop_add_source(obj->stack->ml, obj->dns_ttl_timer);
1475 		}
1476 	}else{
1477 		belle_sip_error("%s: DNS resolution failed for %s", __FUNCTION__, name);
1478 		channel_set_state(obj,BELLE_SIP_CHANNEL_ERROR);
1479 	}
1480 }
1481 
belle_sip_channel_resolve(belle_sip_channel_t * obj)1482 void belle_sip_channel_resolve(belle_sip_channel_t *obj){
1483 	belle_sip_message("channel [%p]: starting resolution of %s", obj, obj->peer_name);
1484 	channel_set_state(obj,BELLE_SIP_CHANNEL_RES_IN_PROGRESS);
1485 	if (belle_sip_stack_dns_srv_enabled(obj->stack) && obj->lp!=NULL)
1486 		obj->resolver_ctx=belle_sip_stack_resolve(obj->stack, "sip", belle_sip_channel_get_transport_name_lower_case(obj), obj->peer_name, obj->peer_port, obj->ai_family, channel_res_done, obj);
1487 	else
1488 		obj->resolver_ctx=belle_sip_stack_resolve_a(obj->stack, obj->peer_name, obj->peer_port, obj->ai_family, channel_res_done, obj);
1489 	if (obj->resolver_ctx){
1490 		belle_sip_object_ref(obj->resolver_ctx);
1491 	}
1492 	return ;
1493 }
1494 
belle_sip_channel_connect(belle_sip_channel_t * obj)1495 void belle_sip_channel_connect(belle_sip_channel_t *obj){
1496 	char ip[64];
1497 	int port=obj->peer_port;
1498 
1499 	channel_set_state(obj,BELLE_SIP_CHANNEL_CONNECTING);
1500 	bctbx_addrinfo_to_ip_address(obj->current_peer,ip,sizeof(ip),&port);
1501 	/* update peer_port as it may have been overriden by SRV resolution*/
1502 	if (port!=obj->peer_port){
1503 		/*the SRV resolution provided a port number that must be used*/
1504 		obj->srv_overrides_port=TRUE;
1505 		obj->peer_port=port;
1506 	}
1507 	belle_sip_message("Trying to connect to [%s://%s:%i]",belle_sip_channel_get_transport_name(obj),ip,obj->peer_port);
1508 
1509 	if(BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->connect(obj,obj->current_peer)) {
1510 		belle_sip_error("Cannot connect to [%s://%s:%i]",belle_sip_channel_get_transport_name(obj),obj->peer_name,obj->peer_port);
1511 		channel_set_state(obj,BELLE_SIP_CHANNEL_ERROR);
1512 	}
1513 	return;
1514 }
1515 
queue_message(belle_sip_channel_t * obj,belle_sip_message_t * msg)1516 static void queue_message(belle_sip_channel_t *obj, belle_sip_message_t *msg){
1517 	belle_sip_object_ref(msg);
1518 	channel_push_outgoing(obj,msg);
1519 	if (obj->state==BELLE_SIP_CHANNEL_INIT){
1520 		belle_sip_channel_prepare(obj);
1521 	}else if (obj->state==BELLE_SIP_CHANNEL_READY) {
1522 		channel_process_queue(obj);
1523 	}
1524 }
1525 
1526 typedef struct delay_send{
1527 	belle_sip_channel_t *chan;
1528 	belle_sip_message_t *msg;
1529 }delay_send_t;
1530 
1531 /* just to emulate network transmission delay */
on_delayed_send_do(delay_send_t * ctx)1532 static int on_delayed_send_do(delay_send_t *ctx){
1533 	belle_sip_message("on_delayed_send_do(): sending now");
1534 	if (ctx->chan->state!=BELLE_SIP_CHANNEL_ERROR && ctx->chan->state!=BELLE_SIP_CHANNEL_DISCONNECTED){
1535 		queue_message(ctx->chan,ctx->msg);
1536 	}
1537 	belle_sip_object_unref(ctx->chan);
1538 	belle_sip_object_unref(ctx->msg);
1539 	belle_sip_free(ctx);
1540 	return FALSE;
1541 }
1542 
queue_message_delayed(belle_sip_channel_t * obj,belle_sip_message_t * msg)1543 static void queue_message_delayed(belle_sip_channel_t *obj, belle_sip_message_t *msg){
1544 	delay_send_t *ctx=belle_sip_malloc(sizeof(delay_send_t));
1545 	ctx->chan=(belle_sip_channel_t*)belle_sip_object_ref(obj);
1546 	ctx->msg=(belle_sip_message_t*)belle_sip_object_ref(msg);
1547 	belle_sip_main_loop_add_timeout(obj->stack->ml,(belle_sip_source_func_t)on_delayed_send_do,ctx,obj->stack->tx_delay);
1548 	belle_sip_message("channel %p: message sending delayed by %i ms",obj,obj->stack->tx_delay);
1549 }
1550 
belle_sip_channel_queue_message(belle_sip_channel_t * obj,belle_sip_message_t * msg)1551 int belle_sip_channel_queue_message(belle_sip_channel_t *obj, belle_sip_message_t *msg){
1552 	if (obj->stack->tx_delay>0){
1553 		queue_message_delayed(obj,msg);
1554 	}else queue_message(obj,msg);
1555 	return 0;
1556 }
1557 
belle_sip_channel_force_close(belle_sip_channel_t * obj)1558 void belle_sip_channel_force_close(belle_sip_channel_t *obj){
1559 	obj->force_close=1;
1560 	channel_set_state(obj,BELLE_SIP_CHANNEL_DISCONNECTED);
1561 }
1562 
belle_sip_channel_find_from_list_with_addrinfo(belle_sip_list_t * l,const belle_sip_hop_t * hop,const struct addrinfo * addr)1563 belle_sip_channel_t *belle_sip_channel_find_from_list_with_addrinfo(belle_sip_list_t *l, const belle_sip_hop_t *hop, const struct addrinfo *addr){
1564 	belle_sip_list_t *elem;
1565 	belle_sip_channel_t *chan;
1566 
1567 	for(elem=l;elem!=NULL;elem=elem->next){
1568 		chan=(belle_sip_channel_t*)elem->data;
1569 		if (!chan->about_to_be_closed && belle_sip_channel_matches(chan,hop,addr)){
1570 			return chan;
1571 		}
1572 	}
1573 	return NULL;
1574 }
1575 
1576 
1577 /* search a matching channel from a list according to supplied hop. The ai_family tells which address family is supported by the list of channels*/
belle_sip_channel_find_from_list(belle_sip_list_t * l,int ai_family,const belle_sip_hop_t * hop)1578 belle_sip_channel_t *belle_sip_channel_find_from_list(belle_sip_list_t *l, int ai_family, const belle_sip_hop_t *hop){
1579 	belle_sip_channel_t *chan=NULL;
1580 	struct addrinfo *res = bctbx_ip_address_to_addrinfo(ai_family,SOCK_STREAM/*needed on some platforms that return an error otherwise (QNX)*/,hop->host,hop->port);
1581 	chan=belle_sip_channel_find_from_list_with_addrinfo(l,hop,res);
1582 	if (res) bctbx_freeaddrinfo(res);
1583 	return chan;
1584 }
1585 
belle_sip_channel_check_dns_reusability(belle_sip_channel_t * obj)1586 void belle_sip_channel_check_dns_reusability(belle_sip_channel_t *obj) {
1587 	if (obj->dns_ttl_timedout) {
1588 		obj->dns_ttl_timedout = FALSE;
1589 		belle_sip_channel_resolve(obj);
1590 	}
1591 }
1592 
1593 #ifdef __ANDROID__
1594 
belle_sip_begin_background_task(const char * name,belle_sip_background_task_end_callback_t cb,void * data)1595 unsigned long belle_sip_begin_background_task(const char *name, belle_sip_background_task_end_callback_t cb, void *data){
1596     return wake_lock_acquire(name);
1597 }
1598 
belle_sip_end_background_task(unsigned long id)1599 void belle_sip_end_background_task(unsigned long id){
1600     wake_lock_release(id);
1601 }
1602 
1603 #elif !TARGET_OS_IPHONE && !defined(__APPLE__)
1604 
1605 /*defines stubs*/
belle_sip_begin_background_task(const char * name,belle_sip_background_task_end_callback_t cb,void * data)1606 unsigned long belle_sip_begin_background_task(const char *name, belle_sip_background_task_end_callback_t cb, void *data){
1607 	return 0;
1608 }
1609 
belle_sip_end_background_task(unsigned long id)1610 void belle_sip_end_background_task(unsigned long id){
1611 	return;
1612 }
1613 
1614 #endif
1615 
1616