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