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 #include "belle_sip_internal.h"
20 #include <bctoolbox/defs.h>
21
22 static void belle_sip_dialog_init_200Ok_retrans(belle_sip_dialog_t *obj, belle_sip_response_t *resp);
23 static int belle_sip_dialog_handle_200Ok(belle_sip_dialog_t *obj, belle_sip_response_t *msg);
24 static void belle_sip_dialog_process_queue(belle_sip_dialog_t* dialog);
25 static belle_sip_request_t *create_request(belle_sip_dialog_t *obj, const char *method, int full);
26
belle_sip_dialog_uninit(belle_sip_dialog_t * obj)27 static void belle_sip_dialog_uninit(belle_sip_dialog_t *obj){
28 if (obj->route_set)
29 belle_sip_list_free_with_data(obj->route_set,belle_sip_object_unref);
30 if (obj->remote_target)
31 belle_sip_object_unref(obj->remote_target);
32 if (obj->call_id)
33 belle_sip_object_unref(obj->call_id);
34 if (obj->local_party)
35 belle_sip_object_unref(obj->local_party);
36 if (obj->remote_party)
37 belle_sip_object_unref(obj->remote_party);
38 if (obj->local_tag)
39 belle_sip_free(obj->local_tag);
40 if (obj->remote_tag)
41 belle_sip_free(obj->remote_tag);
42 if (obj->last_out_invite)
43 belle_sip_object_unref(obj->last_out_invite);
44 if (obj->last_out_ack)
45 belle_sip_object_unref(obj->last_out_ack);
46 if (obj->last_transaction)
47 belle_sip_object_unref(obj->last_transaction);
48 if(obj->privacy)
49 belle_sip_object_unref(obj->privacy);
50 if (obj->expiration_timer){ /*In some situations, dialog deleted might not be called*/
51 belle_sip_main_loop_remove_source(obj->provider->stack->ml, obj->expiration_timer);
52 belle_sip_object_unref(obj->expiration_timer);
53 obj->expiration_timer = NULL;
54 }
55 }
56
57 BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_dialog_t);
58 BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_dialog_t)
BELLE_SIP_VPTR_INIT(belle_sip_dialog_t,belle_sip_object_t,TRUE)59 BELLE_SIP_VPTR_INIT(belle_sip_dialog_t, belle_sip_object_t,TRUE),
60 (belle_sip_object_destroy_t)belle_sip_dialog_uninit,
61 NULL,
62 NULL,
63 BELLE_SIP_DEFAULT_BUFSIZE_HINT
64 BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END
65
66 const char* belle_sip_dialog_state_to_string(const belle_sip_dialog_state_t state) {
67 switch(state) {
68 case BELLE_SIP_DIALOG_NULL: return "BELLE_SIP_DIALOG_NULL";
69 case BELLE_SIP_DIALOG_EARLY: return "BELLE_SIP_DIALOG_EARLY";
70 case BELLE_SIP_DIALOG_CONFIRMED: return "BELLE_SIP_DIALOG_CONFIRMED";
71 case BELLE_SIP_DIALOG_TERMINATED: return "BELLE_SIP_DIALOG_TERMINATED";
72 default: return "Unknown state";
73 }
74 }
75
set_state(belle_sip_dialog_t * obj,belle_sip_dialog_state_t state)76 static void set_state(belle_sip_dialog_t *obj,belle_sip_dialog_state_t state) {
77 obj->previous_state=obj->state;
78 obj->state=state;
79 }
80
set_to_tag(belle_sip_dialog_t * obj,belle_sip_header_to_t * to)81 static void set_to_tag(belle_sip_dialog_t *obj, belle_sip_header_to_t *to){
82 const char *to_tag=belle_sip_header_to_get_tag(to);
83 if (obj->is_server){
84 if (to_tag && !obj->local_tag)
85 obj->local_tag=belle_sip_strdup(to_tag);
86 }else{
87 if (to_tag && !obj->remote_tag)
88 obj->remote_tag=belle_sip_strdup(to_tag);
89 }
90 }
91
check_route_set(belle_sip_list_t * rs)92 static void check_route_set(belle_sip_list_t *rs){
93 if (rs){
94 belle_sip_header_route_t *r=(belle_sip_header_route_t*)rs->data;
95 if (!belle_sip_uri_has_lr_param(belle_sip_header_address_get_uri((belle_sip_header_address_t*)r))){
96 belle_sip_warning("top uri of route set does not contain 'lr', not really supported.");
97 }
98 }
99 }
100
belle_sip_dialog_init_as_uas(belle_sip_dialog_t * obj,belle_sip_request_t * req)101 static int belle_sip_dialog_init_as_uas(belle_sip_dialog_t *obj, belle_sip_request_t *req){
102 const belle_sip_list_t *elem;
103 belle_sip_header_contact_t *ct=belle_sip_message_get_header_by_type(req,belle_sip_header_contact_t);
104 belle_sip_header_cseq_t *cseq=belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t);
105 belle_sip_header_via_t *via=belle_sip_message_get_header_by_type(req,belle_sip_header_via_t);
106 belle_sip_uri_t *requri=belle_sip_request_get_uri(req);
107 belle_sip_header_to_t *to=belle_sip_message_get_header_by_type(req,belle_sip_header_to_t);
108
109 if (!ct){
110 belle_sip_error("No contact in request.");
111 return -1;
112 }
113 if (!cseq){
114 belle_sip_error("No cseq in request.");
115 return -1;
116 }
117 if (!via){
118 belle_sip_error("No via in request.");
119 return -1;
120 }
121 if (!to){
122 belle_sip_error("No to in request.");
123 return -1;
124 }
125
126 if (strcasecmp(belle_sip_header_via_get_protocol(via),"TLS")==0
127 && belle_sip_uri_is_secure(requri)){
128 obj->is_secure=TRUE;
129 }
130 /* 12.1.1
131 *The route set MUST be set to the list of URIs in the Record-Route
132 * header field from the request, taken in order and preserving all URI
133 * parameters. If no Record-Route header field is present in the
134 *request, the route set MUST be set to the empty set.
135 */
136 obj->route_set=belle_sip_list_free_with_data(obj->route_set,belle_sip_object_unref);
137 for(elem=belle_sip_message_get_headers((belle_sip_message_t*)req,BELLE_SIP_RECORD_ROUTE);elem!=NULL;elem=elem->next){
138 obj->route_set=belle_sip_list_append(obj->route_set,belle_sip_object_ref(belle_sip_header_route_create(
139 (belle_sip_header_address_t*)elem->data)));
140 }
141 check_route_set(obj->route_set);
142 obj->remote_target=(belle_sip_header_address_t*)belle_sip_object_ref(ct);
143 obj->remote_cseq=belle_sip_header_cseq_get_seq_number(cseq);
144 if (strcmp(belle_sip_request_get_method(req),"INVITE")==0){
145 obj->remote_invite_cseq = belle_sip_header_cseq_get_seq_number(cseq);
146 }
147
148 /*remote party already set */
149 obj->local_party=(belle_sip_header_address_t*)belle_sip_object_ref(to);
150
151 return 0;
152 }
153
set_last_out_invite(belle_sip_dialog_t * obj,belle_sip_request_t * req)154 static void set_last_out_invite(belle_sip_dialog_t *obj, belle_sip_request_t *req){
155 if (obj->last_out_invite)
156 belle_sip_object_unref(obj->last_out_invite);
157 obj->last_out_invite=(belle_sip_request_t*)belle_sip_object_ref(req);
158 }
159
belle_sip_dialog_init_as_uac(belle_sip_dialog_t * obj,belle_sip_request_t * req)160 static int belle_sip_dialog_init_as_uac(belle_sip_dialog_t *obj, belle_sip_request_t *req){
161 belle_sip_header_cseq_t *cseq=belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t);
162 belle_sip_header_to_t *to=belle_sip_message_get_header_by_type(req,belle_sip_header_to_t);
163 belle_sip_header_via_t *via=belle_sip_message_get_header_by_type(req,belle_sip_header_via_t);
164 belle_sip_uri_t *requri=belle_sip_request_get_uri(req);
165
166 if (!to){
167 belle_sip_error("No to in request.");
168 return -1;
169 }
170 if (!cseq){
171 belle_sip_error("No cseq in request.");
172 return -1;
173 }
174 if (!via){
175 belle_sip_error("No via in request.");
176 return -1;
177 }
178
179 if (belle_sip_header_via_get_protocol(via) /*might be null at dialog creation (uac case)*/
180 && strcasecmp(belle_sip_header_via_get_protocol(via),"TLS")==0
181 && belle_sip_uri_is_secure(requri)){
182 obj->is_secure=TRUE;
183 }
184
185 obj->local_cseq=belle_sip_header_cseq_get_seq_number(cseq);
186 /*call id is already set */
187 /*local_tag is already set*/
188 obj->remote_party=(belle_sip_header_address_t*)belle_sip_object_ref(to);
189 /*local party is already set*/
190 if (strcmp(belle_sip_request_get_method(req),"INVITE")==0){
191 set_last_out_invite(obj,req);
192 }
193
194 return 0;
195 }
196
belle_sip_dialog_on_expired(belle_sip_dialog_t * dialog)197 static int belle_sip_dialog_on_expired(belle_sip_dialog_t *dialog){
198 belle_sip_message("Dialog [%p] expired", dialog);
199 dialog->is_expired = TRUE;
200 belle_sip_dialog_delete(dialog);
201 return BELLE_SIP_STOP;
202 }
203
belle_sip_dialog_expired(const belle_sip_dialog_t * dialog)204 int belle_sip_dialog_expired(const belle_sip_dialog_t *dialog){
205 return dialog->is_expired;
206 }
207
208 /*returns BELLE_SIP_STOP if the dialog is to be terminated, BELLE_SIP_CONTINUE otherwise*/
belle_sip_dialog_schedule_expiration(belle_sip_dialog_t * dialog,belle_sip_message_t * request)209 static int belle_sip_dialog_schedule_expiration(belle_sip_dialog_t *dialog, belle_sip_message_t *request){
210 belle_sip_header_expires_t *expires = belle_sip_message_get_header_by_type(request, belle_sip_header_expires_t);
211 int expires_value;
212
213 if (!expires) return BELLE_SIP_CONTINUE;
214 expires_value = belle_sip_header_expires_get_expires(expires);
215 if (dialog->expiration_timer){
216 belle_sip_main_loop_remove_source(dialog->provider->stack->ml, dialog->expiration_timer);
217 belle_sip_object_unref(dialog->expiration_timer);
218 dialog->expiration_timer = NULL;
219 }
220 belle_sip_message("belle_sip_dialog_schedule_expiration() dialog=%p expires_value=%i", dialog, expires_value);
221 if (expires_value == 0) return BELLE_SIP_STOP;
222 dialog->expiration_timer = belle_sip_main_loop_create_timeout(dialog->provider->stack->ml,
223 (belle_sip_source_func_t) belle_sip_dialog_on_expired,
224 dialog,
225 expires_value * 1000,
226 "Dialog expiration");
227 return BELLE_SIP_CONTINUE;
228 }
229
belle_sip_dialog_establish_full(belle_sip_dialog_t * obj,belle_sip_request_t * req,belle_sip_response_t * resp)230 int belle_sip_dialog_establish_full(belle_sip_dialog_t *obj, belle_sip_request_t *req, belle_sip_response_t *resp){
231 belle_sip_header_contact_t *ct=belle_sip_message_get_header_by_type(resp,belle_sip_header_contact_t);
232 belle_sip_header_to_t *to=belle_sip_message_get_header_by_type(resp,belle_sip_header_to_t);
233 const belle_sip_list_t *elem;
234
235 if (strcmp(belle_sip_request_get_method(req),"INVITE")==0)
236 obj->needs_ack=TRUE;
237
238 if (obj->is_server){
239 if (strcmp(belle_sip_request_get_method(req),"INVITE")==0){
240 belle_sip_dialog_init_200Ok_retrans(obj,resp);
241 }
242 } else {
243 if (!ct && !obj->remote_target) {
244 belle_sip_error("Missing contact header in resp [%p] cannot set remote target for dialog [%p]",resp,obj);
245 return -1;
246 }
247 /* 13.2.2.4 2xx Responses
248 ...
249 If the dialog identifier in the 2xx response matches the dialog
250 identifier of an existing dialog, the dialog MUST be transitioned to
251 the "confirmed" state, and the route set for the dialog MUST be
252 recomputed based on the 2xx response using the procedures of Section
253 12.2.1.2.
254 */
255 obj->route_set=belle_sip_list_free_with_data(obj->route_set,belle_sip_object_unref);
256 for(elem=belle_sip_message_get_headers((belle_sip_message_t*)resp,BELLE_SIP_RECORD_ROUTE);elem!=NULL;elem=elem->next){
257 obj->route_set=belle_sip_list_prepend(obj->route_set,belle_sip_object_ref(belle_sip_header_route_create(
258 (belle_sip_header_address_t*)elem->data)));
259 }
260
261 if (ct) {
262 /*remote Contact header may have changed between early dialog to confirmed*/
263 if (obj->remote_target) belle_sip_object_unref(obj->remote_target);
264 obj->remote_target=(belle_sip_header_address_t*)belle_sip_object_ref(ct);
265 }
266 }
267 /*update to tag*/
268 set_to_tag(obj,to);
269 set_state(obj,BELLE_SIP_DIALOG_CONFIRMED);
270 return 0;
271 }
272
belle_sip_dialog_establish(belle_sip_dialog_t * obj,belle_sip_request_t * req,belle_sip_response_t * resp)273 int belle_sip_dialog_establish(belle_sip_dialog_t *obj, belle_sip_request_t *req, belle_sip_response_t *resp){
274 belle_sip_header_to_t *to=belle_sip_message_get_header_by_type(resp,belle_sip_header_to_t);
275 belle_sip_header_via_t *via=belle_sip_message_get_header_by_type(req,belle_sip_header_via_t);
276 belle_sip_uri_t *requri=belle_sip_request_get_uri(req);
277
278 if (obj->state != BELLE_SIP_DIALOG_NULL) {
279 belle_sip_error("Dialog [%p] already established.",obj);
280 return -1;
281 }
282 if (!to){
283 belle_sip_error("No to in response.");
284 return -1;
285 }
286
287 if (!obj->is_server) {
288 belle_sip_header_contact_t *ct=belle_sip_message_get_header_by_type(resp,belle_sip_header_contact_t);
289 const belle_sip_list_t* elem;
290 /*contact might be provided later*/
291 if (ct)
292 obj->remote_target=(belle_sip_header_address_t*)belle_sip_object_ref(ct);
293
294 /**12.1.2
295 * The route set MUST be set to the list of URIs in the Record-Route
296 *header field from the response, taken in reverse order and preserving
297 *all URI parameters. If no Record-Route header field is present in
298 *the response, the route set MUST be set to the empty set.
299 **/
300 obj->route_set=belle_sip_list_free_with_data(obj->route_set,belle_sip_object_unref);
301 for(elem=belle_sip_message_get_headers((belle_sip_message_t*)resp,BELLE_SIP_RECORD_ROUTE);elem!=NULL;elem=elem->next){
302 obj->route_set=belle_sip_list_prepend(obj->route_set,belle_sip_object_ref(belle_sip_header_route_create(
303 (belle_sip_header_address_t*)elem->data)));
304 }
305
306 check_route_set(obj->route_set);
307 /*via might be unknown at dialog creation*/
308 if (strcasecmp(belle_sip_header_via_get_protocol(via),"TLS")==0
309 && belle_sip_uri_is_secure(requri)){
310 obj->is_secure=TRUE;
311 }
312
313 }
314
315 set_to_tag(obj,to);
316
317 return 0;
318 }
319
belle_sip_dialog_check_incoming_request_ordering(belle_sip_dialog_t * obj,belle_sip_request_t * req)320 int belle_sip_dialog_check_incoming_request_ordering(belle_sip_dialog_t *obj, belle_sip_request_t *req){
321 belle_sip_header_cseq_t *cseqh=belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t);
322 unsigned int cseq=belle_sip_header_cseq_get_seq_number(cseqh);
323 if (obj->remote_cseq==0){
324 obj->remote_cseq=cseq;
325 }else if (cseq>obj->remote_cseq){
326 return 0;
327 }
328 belle_sip_warning("Ignoring request because cseq is inconsistent.");
329 return -1;
330 }
331
dialog_on_200Ok_timer(belle_sip_dialog_t * dialog)332 static int dialog_on_200Ok_timer(belle_sip_dialog_t *dialog){
333 /*reset the timer */
334 const belle_sip_timer_config_t *cfg=belle_sip_stack_get_timer_config(dialog->provider->stack);
335 unsigned int prev_timeout=belle_sip_source_get_timeout(dialog->timer_200Ok);
336 belle_sip_source_set_timeout(dialog->timer_200Ok,MIN(2*prev_timeout,(unsigned int)cfg->T2));
337 belle_sip_message("Dialog sending retransmission of 200Ok");
338 belle_sip_provider_send_response(dialog->provider,dialog->last_200Ok);
339 return BELLE_SIP_CONTINUE;
340 }
341
dialog_on_200Ok_end(belle_sip_dialog_t * dialog)342 static int dialog_on_200Ok_end(belle_sip_dialog_t *dialog){
343 belle_sip_request_t *bye;
344 belle_sip_client_transaction_t *trn;
345 belle_sip_dialog_stop_200Ok_retrans(dialog);
346 belle_sip_error("Dialog [%p] was not ACK'd within T1*64 seconds, it is going to be terminated.",dialog);
347 dialog->state=BELLE_SIP_DIALOG_CONFIRMED;
348 bye=belle_sip_dialog_create_request(dialog,"BYE");
349 trn=belle_sip_provider_create_client_transaction(dialog->provider,bye);
350 BELLE_SIP_TRANSACTION(trn)->is_internal=1; /*don't bother user with this transaction*/
351 belle_sip_client_transaction_send_request(trn);
352 return BELLE_SIP_STOP;
353 }
354
belle_sip_dialog_init_200Ok_retrans(belle_sip_dialog_t * obj,belle_sip_response_t * resp)355 static void belle_sip_dialog_init_200Ok_retrans(belle_sip_dialog_t *obj, belle_sip_response_t *resp){
356 const belle_sip_timer_config_t *cfg=belle_sip_stack_get_timer_config(obj->provider->stack);
357 if (obj->timer_200Ok || obj->timer_200Ok_end) {
358 belle_sip_error("dialog [%p] already has a 200ok retransmition timer ! skipping",obj);
359 return;
360 }
361 obj->timer_200Ok=belle_sip_timeout_source_new((belle_sip_source_func_t)dialog_on_200Ok_timer,obj,cfg->T1);
362 belle_sip_object_set_name((belle_sip_object_t*)obj->timer_200Ok,"dialog_200Ok_timer");
363 belle_sip_main_loop_add_source(obj->provider->stack->ml,obj->timer_200Ok);
364
365 obj->timer_200Ok_end=belle_sip_timeout_source_new((belle_sip_source_func_t)dialog_on_200Ok_end,obj,cfg->T1*64);
366 belle_sip_object_set_name((belle_sip_object_t*)obj->timer_200Ok_end,"dialog_200Ok_timer_end");
367 belle_sip_main_loop_add_source(obj->provider->stack->ml,obj->timer_200Ok_end);
368
369 obj->last_200Ok=(belle_sip_response_t*)belle_sip_object_ref(resp);
370 }
371
belle_sip_dialog_stop_200Ok_retrans(belle_sip_dialog_t * obj)372 void belle_sip_dialog_stop_200Ok_retrans(belle_sip_dialog_t *obj){
373 belle_sip_main_loop_t *ml=obj->provider->stack->ml;
374 if (obj->timer_200Ok){
375 belle_sip_main_loop_remove_source(ml,obj->timer_200Ok);
376 belle_sip_object_unref(obj->timer_200Ok);
377 obj->timer_200Ok=NULL;
378 }
379 if (obj->timer_200Ok_end){
380 belle_sip_main_loop_remove_source(ml,obj->timer_200Ok_end);
381 belle_sip_object_unref(obj->timer_200Ok_end);
382 obj->timer_200Ok_end=NULL;
383 }
384 if (obj->last_200Ok){
385 belle_sip_object_unref(obj->last_200Ok);
386 obj->last_200Ok=NULL;
387 }
388 }
389
390 /* returns true if the dialog is terminated by the NOTIFY request or response*/
belle_sip_dialog_should_terminate_by_notify(belle_sip_dialog_t * obj,belle_sip_transaction_t * transaction,int as_uas)391 static int belle_sip_dialog_should_terminate_by_notify(belle_sip_dialog_t *obj, belle_sip_transaction_t* transaction, int as_uas){
392 int should_terminate = FALSE;
393
394 if (obj->type == BELLE_SIP_DIALOG_SUBSCRIBE_NOTIFY) {
395 belle_sip_request_t *req=belle_sip_transaction_get_request(transaction);
396 belle_sip_response_t *resp=belle_sip_transaction_get_response(transaction);
397 belle_sip_header_subscription_state_t* subscription_state_header=belle_sip_message_get_header_by_type(req,belle_sip_header_subscription_state_t);
398 int code = resp ? belle_sip_response_get_status_code(resp) : 0;
399
400 if (!subscription_state_header || strcasecmp(BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED,belle_sip_header_subscription_state_get_state(subscription_state_header)) ==0) {
401 if (as_uas){
402 /*terminate the dialog when the application replies the 200 Ok*/
403 if (code == 200){
404 should_terminate = TRUE;
405 }
406 }else{
407 /*terminate the dialog when we receive the 200OK or the transaction terminates by timeout*/
408 if (code == 200 || belle_sip_transaction_get_state(transaction) == BELLE_SIP_TRANSACTION_TERMINATED){
409 should_terminate = TRUE;
410 }
411 }
412 }
413 }
414 return should_terminate;
415 }
416
belle_sip_dialog_update_remote_target(belle_sip_dialog_t * obj,belle_sip_header_contact_t * ct)417 static void belle_sip_dialog_update_remote_target(belle_sip_dialog_t *obj, belle_sip_header_contact_t *ct) {
418 int remote_target_changed = FALSE;
419 if (obj->remote_target) {
420 belle_sip_uri_t *remote_target_uri = belle_sip_header_address_get_uri(obj->remote_target);
421 belle_sip_uri_t *ct_uri = belle_sip_header_address_get_uri((belle_sip_header_address_t *)ct);
422 remote_target_changed = !belle_sip_uri_equals(remote_target_uri, ct_uri);
423 belle_sip_object_unref(obj->remote_target);
424 }
425 obj->remote_target=(belle_sip_header_address_t*)belle_sip_object_ref(ct);
426 if (remote_target_changed) {
427 belle_sip_message("Dialog [%p]: remote target changed", obj);
428 if (obj->last_out_ack) {
429 belle_sip_request_set_uri(BELLE_SIP_REQUEST(obj->last_out_ack), belle_sip_header_address_get_uri(obj->remote_target));
430 }
431 }
432 }
433
434 /*
435 * return 0 if message should be delivered to the next listener, otherwise, its a retransmision, just keep it
436 * */
belle_sip_dialog_update(belle_sip_dialog_t * obj,belle_sip_transaction_t * transaction,int as_uas)437 int belle_sip_dialog_update(belle_sip_dialog_t *obj, belle_sip_transaction_t* transaction, int as_uas){
438 int is_retransmition=FALSE;
439 int delete_dialog=FALSE;
440 belle_sip_request_t *req=belle_sip_transaction_get_request(transaction);
441 belle_sip_response_t *resp=belle_sip_transaction_get_response(transaction);
442 int code=0;
443 int ret = 0;
444 int is_invite = strcmp(belle_sip_request_get_method(req),"INVITE")==0;
445 int is_subscribe = strcmp(belle_sip_request_get_method(req),"SUBSCRIBE")==0;
446 int is_notify = strcmp(belle_sip_request_get_method(req),"NOTIFY")==0;
447
448 belle_sip_message("Dialog [%p]: now updated by transaction [%p].",obj, transaction);
449
450 if (resp)
451 code=belle_sip_response_get_status_code(resp);
452
453 if (as_uas && code == 491) { /**/
454 belle_sip_message("Dialog [%p]: don't update last transaction by transaction [%p].",obj, transaction);
455 } else {
456 belle_sip_object_ref(transaction);
457 if (obj->last_transaction) belle_sip_object_unref(obj->last_transaction);
458 obj->last_transaction=transaction;
459 }
460 if (!as_uas){
461 belle_sip_header_privacy_t *privacy_header=belle_sip_message_get_header_by_type(req,belle_sip_header_privacy_t);
462 SET_OBJECT_PROPERTY(obj,privacy,privacy_header);
463 }
464
465 /*first update local/remote cseq*/
466 if (as_uas) {
467 belle_sip_header_cseq_t* cseq=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_cseq_t);
468 obj->remote_cseq=belle_sip_header_cseq_get_seq_number(cseq);
469 if (is_invite && code>=200 && code<300)
470 obj->remote_invite_cseq = belle_sip_header_cseq_get_seq_number(cseq);
471 /*else ACK is handled by transaction, not dialog*/
472 }
473
474
475 switch (obj->state){
476 case BELLE_SIP_DIALOG_NULL:
477 /*always establish a dialog*/
478 if (code>100 && code<300 && (is_invite || is_subscribe)) {
479 belle_sip_dialog_establish(obj,req,resp);
480 if (code<200){
481 set_state(obj,BELLE_SIP_DIALOG_EARLY);
482 break;
483 }/* no break for code >200 because need to call belle_sip_dialog_establish_full*/
484 }
485 BCTBX_NO_BREAK; /*intentionally no break*/
486 case BELLE_SIP_DIALOG_EARLY:
487 /*don't terminate dialog for UPDATE*/
488 if (code>=300 && (is_invite || is_subscribe)) {
489 /*12.3 Termination of a Dialog
490 Independent of the method, if a request outside of a dialog generates
491 a non-2xx final response, any early dialogs created through
492 provisional responses to that request are terminated. The mechanism
493 for terminating confirmed dialogs is method specific.*/
494 delete_dialog=TRUE;
495 break;
496 }
497 if (code>=200 && code<300 && (is_invite || is_subscribe)){
498 if (belle_sip_dialog_establish_full(obj,req,resp) != 0){
499 /*the dialog found this response invalid so notify the transaction layer by returning -1*/
500 ret = -1;
501 goto end;
502 }
503 }
504 if (is_subscribe){
505 if (belle_sip_dialog_schedule_expiration(obj, (belle_sip_message_t*)req) == BELLE_SIP_STOP
506 && (code>=200 || (code==0 && belle_sip_transaction_get_state(transaction)==BELLE_SIP_TRANSACTION_TERMINATED))){
507 /*delete the dialog when the 200Ok for a SUBSCRIBE with expires=0 is received or when
508 * no response is received at all*/
509 delete_dialog = TRUE;
510 }
511 }
512 if (code < 200 && belle_sip_transaction_get_state(transaction)==BELLE_SIP_TRANSACTION_TERMINATED){
513 /*no response establishing the dialog, and transaction terminated (transport errors)*/
514 delete_dialog=TRUE;
515 }
516 break;
517 case BELLE_SIP_DIALOG_CONFIRMED:
518 if (code==481 && (is_invite || is_subscribe)) {
519 /*Dialog is terminated in such case*/
520 delete_dialog=TRUE;
521 break;
522 }
523 /*refreshing target is also true in case of subscribe*/
524 if ((is_invite || is_subscribe) && (code>=200 && code<300)) {
525 /*refresh the remote_target*/
526 belle_sip_header_contact_t *ct;
527 if (as_uas){
528 ct=belle_sip_message_get_header_by_type(req,belle_sip_header_contact_t);
529
530 }else{
531 if (is_invite)
532 set_last_out_invite(obj,req);
533 ct=belle_sip_message_get_header_by_type(resp,belle_sip_header_contact_t);
534 }
535 if (ct){
536 belle_sip_dialog_update_remote_target(obj, ct);
537 }
538
539 }
540 if (is_invite){
541 if (code>=200 && code<300){
542 /*handle possible retransmission of 200Ok */
543 if (!as_uas && (is_retransmition=(belle_sip_dialog_handle_200Ok(obj,resp)==0))) {
544 return is_retransmition;
545 } else {
546 if (as_uas)
547 belle_sip_dialog_init_200Ok_retrans(obj,resp);
548 obj->needs_ack=TRUE; /*REINVITE case, ack needed by both uas and uac*/
549 }
550 }else if (code>=300){
551 /*final response, ack will be automatically sent by transaction layer*/
552 /* do not need to do anything because not set yet or set by previous invite transaction obj->needs_ack=FALSE;*/
553 }
554 } else if (strcmp(belle_sip_request_get_method(req),"BYE")==0){
555 /*15.1.1 UAC Behavior
556
557 A BYE request is constructed as would any other request within a
558 dialog, as described in Section 12.
559
560 Once the BYE is constructed, the UAC core creates a new non-INVITE
561 client transaction, and passes it the BYE request. The UAC MUST
562 consider the session terminated (and therefore stop sending or
563 listening for media) as soon as the BYE request is passed to the
564 client transaction. If the response for the BYE is a 481
565 (Call/Transaction Does Not Exist) or a 408 (Request Timeout) or no
566 response at all is received for the BYE (that is, a timeout is
567 returned by the client transaction), the UAC MUST consider the
568 session and the dialog terminated. */
569 /*what should we do with other reponse >300 ?? */
570 if (code>=200 || (code==0 && belle_sip_transaction_get_state(transaction)==BELLE_SIP_TRANSACTION_TERMINATED)){
571 obj->needs_ack=FALSE; /*no longuer need ACK*/
572 if (obj->terminate_on_bye) delete_dialog=TRUE;
573 }
574 }else if (is_subscribe){
575 if (belle_sip_dialog_schedule_expiration(obj, (belle_sip_message_t*)req) == BELLE_SIP_STOP
576 && (code>=200 || (code==0 && belle_sip_transaction_get_state(transaction)==BELLE_SIP_TRANSACTION_TERMINATED))){
577 delete_dialog = TRUE;
578 }else if (!as_uas){
579 if (code >= 300 || (code==0 && belle_sip_transaction_get_state(transaction)==BELLE_SIP_TRANSACTION_TERMINATED)){
580 /*case of a SUBSCRIBE refresh that is rejected or unanswered*/
581 if (code != 491){
582 /*request pending is not fatal for the dialog*/
583 delete_dialog = TRUE;
584 }
585 }
586 }
587 }else if (is_notify){
588 delete_dialog = belle_sip_dialog_should_terminate_by_notify(obj, transaction, as_uas);
589 }
590 break;
591 case BELLE_SIP_DIALOG_TERMINATED:
592 /*ignore*/
593 break;
594 }
595
596 end:
597 if (delete_dialog) belle_sip_dialog_delete(obj);
598 else {
599 belle_sip_dialog_process_queue(obj);
600 }
601 return ret;
602 }
603
belle_sip_dialog_new(belle_sip_transaction_t * t)604 belle_sip_dialog_t *belle_sip_dialog_new(belle_sip_transaction_t *t){
605 belle_sip_dialog_t *obj;
606 belle_sip_header_from_t *from;
607 const char *from_tag;
608 belle_sip_header_to_t *to;
609 const char *to_tag=NULL;
610 belle_sip_header_call_id_t *call_id=belle_sip_message_get_header_by_type(t->request,belle_sip_header_call_id_t);
611
612 from=belle_sip_message_get_header_by_type(t->request,belle_sip_header_from_t);
613 if (from==NULL){
614 belle_sip_error("belle_sip_dialog_new(): no from!");
615 return NULL;
616 }
617 from_tag=belle_sip_header_from_get_tag(from);
618 if (from_tag==NULL){
619 belle_sip_error("belle_sip_dialog_new(): no from tag!");
620 return NULL;
621 }
622
623 to = belle_sip_message_get_header_by_type(t->request,belle_sip_header_to_t);
624 if (to == NULL){
625 belle_sip_error("belle_sip_dialog_new(): no to in request!");
626 return NULL;
627 }
628 to_tag = belle_sip_header_to_get_tag(to);
629 if (to_tag){
630 belle_sip_error("belle_sip_dialog_new(): there is a to tag in the request. This is not allowed"
631 " to create a dialog on such a transaction.");
632 return NULL;
633 }
634 if (!call_id){
635 belle_sip_error("No call-id in response.");
636 return NULL;
637 }
638
639 if (t->last_response) {
640 to=belle_sip_message_get_header_by_type(t->last_response,belle_sip_header_to_t);
641 if (to==NULL){
642 belle_sip_error("belle_sip_dialog_new(): no to!");
643 return NULL;
644 }
645 to_tag = belle_sip_header_to_get_tag(to);
646 }
647 obj=belle_sip_object_new(belle_sip_dialog_t);
648 obj->terminate_on_bye=1;
649 obj->provider=t->provider;
650 obj->pending_trans_checking_enabled=1;
651 obj->call_id=(belle_sip_header_call_id_t*)belle_sip_object_ref(call_id);
652
653 if (strcmp(belle_sip_request_get_method(t->request),"INVITE") == 0){
654 obj->type = BELLE_SIP_DIALOG_INVITE;
655 }else if (strcmp(belle_sip_request_get_method(t->request),"SUBSCRIBE") == 0){
656 obj->type = BELLE_SIP_DIALOG_SUBSCRIBE_NOTIFY;
657 }else{
658 belle_sip_error("belle_sip_dialog_new(): unsupported request [%s] for creating a dialog.", belle_sip_request_get_method(t->request));
659 }
660
661 belle_sip_object_ref(t);
662 obj->last_transaction=t;
663
664 if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_server_transaction_t)){
665 obj->remote_tag=belle_sip_strdup(from_tag);
666 obj->local_tag=belle_sip_strdup(BELLE_SIP_SERVER_TRANSACTION(t)->to_tag);
667 obj->remote_party=(belle_sip_header_address_t*)belle_sip_object_ref(from);
668 obj->is_server=TRUE;
669 belle_sip_dialog_init_as_uas(obj,belle_sip_transaction_get_request(t));
670 }else{
671 const belle_sip_list_t *predefined_routes=NULL;
672 obj->local_tag=belle_sip_strdup(from_tag);
673 obj->remote_tag=to_tag?belle_sip_strdup(to_tag):NULL; /*might be null at dialog creation*/
674 obj->local_party=(belle_sip_header_address_t*)belle_sip_object_ref(from);
675 obj->is_server=FALSE;
676 for(predefined_routes=belle_sip_message_get_headers((belle_sip_message_t*)t->request,BELLE_SIP_ROUTE);
677 predefined_routes!=NULL;predefined_routes=predefined_routes->next){
678 obj->route_set=belle_sip_list_append(obj->route_set,belle_sip_object_ref(predefined_routes->data));
679 }
680 belle_sip_dialog_init_as_uac(obj,belle_sip_transaction_get_request(t));
681 }
682
683
684 belle_sip_message("New %s dialog [%p] , local tag [%s], remote tag [%s]"
685 ,obj->is_server?"server":"client"
686 ,obj
687 ,obj->local_tag?obj->local_tag:""
688 ,obj->remote_tag?obj->remote_tag:"");
689 set_state(obj,BELLE_SIP_DIALOG_NULL);
690 return obj;
691 }
692
belle_sip_dialog_create_ack(belle_sip_dialog_t * obj,unsigned int cseq)693 belle_sip_request_t *belle_sip_dialog_create_ack(belle_sip_dialog_t *obj, unsigned int cseq){
694 belle_sip_header_cseq_t *cseqh;
695 belle_sip_request_t *invite=obj->last_out_invite;
696 belle_sip_request_t *ack;
697
698 if (!invite){
699 belle_sip_error("No INVITE to ACK.");
700 return NULL;
701 }
702 cseqh=belle_sip_message_get_header_by_type(invite,belle_sip_header_cseq_t);
703 if (belle_sip_header_cseq_get_seq_number(cseqh)!=cseq){
704 belle_sip_error("No INVITE with cseq %i to create ack for.",cseq);
705 return NULL;
706 }
707 ack=create_request(obj,"ACK",TRUE);
708 /*
709 22 Usage of HTTP Authentication
710 22.1 Framework
711 While a server can legitimately challenge most SIP requests, there
712 are two requests defined by this document that require special
713 handling for authentication: ACK and CANCEL.
714 Under an authentication scheme that uses responses to carry values
715 used to compute nonces (such as Digest), some problems come up for
716 any requests that take no response, including ACK. For this reason,
717 any credentials in the INVITE that were accepted by a server MUST be
718 accepted by that server for the ACK. UACs creating an ACK message
719 will duplicate all of the Authorization and Proxy-Authorization
720 header field values that appeared in the INVITE to which the ACK
721 corresponds. Servers MUST NOT attempt to challenge an ACK.
722 */
723 if (ack){
724 const belle_sip_list_t *aut=belle_sip_message_get_headers((belle_sip_message_t*)obj->last_out_invite,"Authorization");
725 const belle_sip_list_t *prx_aut=belle_sip_message_get_headers((belle_sip_message_t*)obj->last_out_invite,"Proxy-Authorization");
726 if (aut)
727 belle_sip_message_add_headers((belle_sip_message_t*)ack,aut);
728 if (prx_aut)
729 belle_sip_message_add_headers((belle_sip_message_t*)ack,prx_aut);
730 /*the ack is sent statelessly, the transaction layer doesn't need the dialog information*/
731 belle_sip_request_set_dialog(ack,NULL);
732 }
733 return ack;
734 }
735
create_request(belle_sip_dialog_t * obj,const char * method,int full)736 static belle_sip_request_t *create_request(belle_sip_dialog_t *obj, const char *method, int full){
737 belle_sip_request_t *req;
738 char* from_tag=NULL, *to_tag=NULL;
739
740 if (!obj->remote_target){
741 belle_sip_error("dialog [%p]: no remote_target set, unable to create request.", obj);
742 return NULL;
743 }
744
745 if (!belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(obj->local_party), "tag")) {
746 /*special case for dialog created by server transaction*/
747 from_tag = obj->local_tag;
748 }
749 if (!belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(obj->remote_party), "tag")) {
750 /*special case for dialog created by server transaction*/
751 to_tag = obj->remote_tag;
752 }
753
754 req=belle_sip_request_create(belle_sip_header_address_get_uri(obj->remote_target),
755 method,
756 obj->call_id,
757 belle_sip_header_cseq_create(obj->local_cseq,method),
758 belle_sip_header_from_create(obj->local_party,from_tag),
759 belle_sip_header_to_create(obj->remote_party,to_tag),
760 belle_sip_header_via_new(),
761 0);
762
763 if (full && obj->route_set) {
764 belle_sip_message_add_headers((belle_sip_message_t*)req,obj->route_set);
765 }
766 if (obj->privacy) {
767 /*repeat the last privacy set in new request. I could not find any requirement for this, but this might be safer
768 * as proxies don't store information about dialogs*/
769 belle_sip_message_add_header((belle_sip_message_t*)req,BELLE_SIP_HEADER(obj->privacy));
770 }
771 belle_sip_request_set_dialog(req,obj);
772 return req;
773 }
774
dialog_can_create_request(belle_sip_dialog_t * obj,const char * method)775 static int dialog_can_create_request(belle_sip_dialog_t *obj, const char *method){
776 if (obj->state != BELLE_SIP_DIALOG_CONFIRMED && obj->state != BELLE_SIP_DIALOG_EARLY
777 && (strcmp("NOTIFY", method) != 0
778 || !obj->is_server
779 || !obj->last_transaction
780 || strcmp("SUBSCRIBE", belle_sip_transaction_get_method(obj->last_transaction)) !=0)) {
781 belle_sip_error("belle_sip_dialog_create_request(): cannot create [%s] request from dialog [%p] in state [%s]",method,obj,belle_sip_dialog_state_to_string(obj->state));
782 return FALSE;
783 }
784 return TRUE;
785 }
786
belle_sip_dialog_create_queued_request(belle_sip_dialog_t * obj,const char * method)787 belle_sip_request_t * belle_sip_dialog_create_queued_request(belle_sip_dialog_t *obj, const char *method){
788 belle_sip_request_t *req;
789
790 if (!dialog_can_create_request(obj, method)) return NULL;
791 if (strcmp(method,"INVITE")==0 || strcmp(method,"SUBSCRIBE")==0){
792 /*we don't allow requests that can update the dialog's state to be sent asynchronously*/
793 belle_sip_error("belle_sip_dialog_create_queued_request([%p]): [%s] requests are forbidden using this method.",obj,method);
794 return NULL;
795 }
796 req=create_request(obj,method,FALSE);
797 if (req){
798 req->dialog_queued=TRUE;
799 }
800 return req;
801 }
802
belle_sip_dialog_update_local_cseq(belle_sip_dialog_t * obj,const char * method)803 static void belle_sip_dialog_update_local_cseq(belle_sip_dialog_t *obj, const char *method){
804 if (obj->local_cseq==0) obj->local_cseq=110;
805 if (strcmp(method,"ACK")!=0) obj->local_cseq++;
806 }
807
belle_sip_dialog_create_request(belle_sip_dialog_t * obj,const char * method)808 belle_sip_request_t *belle_sip_dialog_create_request(belle_sip_dialog_t *obj, const char *method){
809 belle_sip_request_t *req;
810
811 if (!dialog_can_create_request(obj, method)) return NULL;
812 /*don't prevent to send a BYE in any case */
813 if ( obj->pending_trans_checking_enabled
814 && strcmp(method,"BYE")!=0
815 && obj->last_transaction
816 && belle_sip_transaction_state_is_transient(belle_sip_transaction_get_state(obj->last_transaction))){
817
818 if (obj->state != BELLE_SIP_DIALOG_EARLY && strcmp(method,"UPDATE")!=0 && strcmp(method,"NOTIFY")!=0) {
819 belle_sip_error("belle_sip_dialog_create_request(): cannot create [%s] request from dialog [%p] while pending [%s] transaction in state [%s]",method,obj,belle_sip_transaction_get_method(obj->last_transaction), belle_sip_transaction_state_to_string(belle_sip_transaction_get_state(obj->last_transaction)));
820 return NULL;
821 } /*else UPDATE transaction can be send in // */
822 }
823 belle_sip_dialog_update_local_cseq(obj,method);
824
825 req=create_request(obj,method,TRUE);
826 return req;
827 }
828
is_system_header(belle_sip_header_t * header)829 static unsigned int is_system_header(belle_sip_header_t* header) {
830 const char* name=belle_sip_header_get_name(header);
831 return strcasecmp(BELLE_SIP_VIA,name) ==0
832 || strcasecmp(BELLE_SIP_FROM,name) ==0
833 || strcasecmp(BELLE_SIP_TO,name) ==0
834 || strcasecmp(BELLE_SIP_CSEQ,name) ==0
835 || strcasecmp(BELLE_SIP_CALL_ID,name) ==0
836 || strcasecmp(BELLE_SIP_PROXY_AUTHORIZATION,name) == 0
837 || strcasecmp(BELLE_SIP_AUTHORIZATION,name) == 0
838 || strcasecmp(BELLE_SIP_MAX_FORWARDS,name) == 0
839 || strcasecmp(BELLE_SIP_ALLOW,name) ==0
840 || strcasecmp(BELLE_SIP_ROUTE,name) ==0;
841 }
copy_non_system_headers(belle_sip_header_t * header,belle_sip_request_t * req)842 static void copy_non_system_headers(belle_sip_header_t* header,belle_sip_request_t* req ) {
843 if (!is_system_header(header)) {
844 belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),header);
845 }
846 }
847
_belle_sip_dialog_create_request_from(belle_sip_dialog_t * obj,const belle_sip_request_t * initial_req,int queued)848 static belle_sip_request_t *_belle_sip_dialog_create_request_from(belle_sip_dialog_t *obj, const belle_sip_request_t *initial_req, int queued){
849 belle_sip_request_t* req;
850 const char *method=belle_sip_request_get_method(initial_req);
851 belle_sip_header_content_length_t* content_lenth;
852 belle_sip_list_t* headers;
853
854 if (queued) req=belle_sip_dialog_create_queued_request(obj,method);
855 else req=belle_sip_dialog_create_request(obj,method);
856
857 if (req==NULL) return NULL;
858
859 content_lenth = belle_sip_message_get_header_by_type(initial_req,belle_sip_header_content_length_t);
860 /*first copy non system headers*/
861 headers = belle_sip_message_get_all_headers(BELLE_SIP_MESSAGE(initial_req));
862 belle_sip_list_for_each2(headers,(void (*)(void *, void *))copy_non_system_headers,req);
863 belle_sip_list_free(headers);
864
865 /*replicate via user parameters, if any, useful for 'alias' parameter in SUBSCRIBE requests*/
866 {
867 belle_sip_header_via_t *orig_via=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(initial_req),belle_sip_header_via_t);
868 belle_sip_header_via_t *new_via=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_via_t);
869 belle_sip_parameters_copy_parameters_from(BELLE_SIP_PARAMETERS(new_via),BELLE_SIP_PARAMETERS(orig_via));
870 }
871
872 /*copy body*/
873 if (content_lenth && belle_sip_header_content_length_get_content_length(content_lenth)>0) {
874 belle_sip_message_set_body(BELLE_SIP_MESSAGE(req),belle_sip_message_get_body(BELLE_SIP_MESSAGE(initial_req)),belle_sip_header_content_length_get_content_length(content_lenth));
875 }
876 return req;
877 }
878
belle_sip_dialog_create_request_from(belle_sip_dialog_t * obj,const belle_sip_request_t * initial_req)879 belle_sip_request_t *belle_sip_dialog_create_request_from(belle_sip_dialog_t *obj, const belle_sip_request_t *initial_req){
880 return _belle_sip_dialog_create_request_from(obj,initial_req,FALSE);
881 }
882
belle_sip_dialog_create_queued_request_from(belle_sip_dialog_t * obj,const belle_sip_request_t * initial_req)883 belle_sip_request_t *belle_sip_dialog_create_queued_request_from(belle_sip_dialog_t *obj, const belle_sip_request_t *initial_req){
884 return _belle_sip_dialog_create_request_from(obj,initial_req,TRUE);
885 }
886
belle_sip_dialog_delete(belle_sip_dialog_t * obj)887 void belle_sip_dialog_delete(belle_sip_dialog_t *obj){
888 size_t dropped_transactions;
889
890 if (obj->expiration_timer){
891 belle_sip_main_loop_remove_source(obj->provider->stack->ml, obj->expiration_timer);
892 belle_sip_object_unref(obj->expiration_timer);
893 obj->expiration_timer = NULL;
894 }
895 belle_sip_message("Dialog [%p] deleted (is_expired=%i)",obj, obj->is_expired);
896 belle_sip_dialog_stop_200Ok_retrans(obj); /*if any*/
897 set_state(obj,BELLE_SIP_DIALOG_TERMINATED);
898 dropped_transactions=belle_sip_list_size(obj->queued_ct);
899 if (dropped_transactions>0) belle_sip_warning("dialog [%p]: leaves %u queued transaction aborted.",obj,(unsigned int)dropped_transactions);
900 belle_sip_list_for_each(obj->queued_ct,(void(*)(void*))belle_sip_transaction_terminate);
901 obj->queued_ct=belle_sip_list_free_with_data(obj->queued_ct,belle_sip_object_unref);
902 belle_sip_provider_remove_dialog(obj->provider,obj);
903 }
904
belle_sip_dialog_get_application_data(const belle_sip_dialog_t * dialog)905 void *belle_sip_dialog_get_application_data(const belle_sip_dialog_t *dialog){
906 return dialog->appdata;
907 }
908
belle_sip_dialog_set_application_data(belle_sip_dialog_t * dialog,void * data)909 void belle_sip_dialog_set_application_data(belle_sip_dialog_t *dialog, void *data){
910 dialog->appdata=data;
911 }
912
belle_sip_dialog_get_call_id(const belle_sip_dialog_t * dialog)913 const belle_sip_header_call_id_t *belle_sip_dialog_get_call_id(const belle_sip_dialog_t *dialog){
914 return dialog->call_id;
915 }
916
belle_sip_dialog_get_local_party(const belle_sip_dialog_t * dialog)917 const belle_sip_header_address_t *belle_sip_dialog_get_local_party(const belle_sip_dialog_t *dialog){
918 return dialog->local_party;
919 }
920
belle_sip_dialog_get_remote_party(const belle_sip_dialog_t * dialog)921 const belle_sip_header_address_t *belle_sip_dialog_get_remote_party(const belle_sip_dialog_t *dialog){
922 return dialog->remote_party;
923 }
924
belle_sip_dialog_get_local_seq_number(const belle_sip_dialog_t * dialog)925 unsigned int belle_sip_dialog_get_local_seq_number(const belle_sip_dialog_t *dialog){
926 return dialog->local_cseq;
927 }
928
belle_sip_dialog_get_remote_seq_number(const belle_sip_dialog_t * dialog)929 unsigned int belle_sip_dialog_get_remote_seq_number(const belle_sip_dialog_t *dialog){
930 return dialog->remote_cseq;
931 }
932
belle_sip_dialog_get_local_tag(const belle_sip_dialog_t * dialog)933 const char *belle_sip_dialog_get_local_tag(const belle_sip_dialog_t *dialog){
934 return dialog->local_tag;
935 }
936
belle_sip_dialog_get_remote_tag(const belle_sip_dialog_t * dialog)937 const char *belle_sip_dialog_get_remote_tag(const belle_sip_dialog_t *dialog){
938 return dialog->remote_tag;
939 }
940
belle_sip_dialog_get_remote_target(belle_sip_dialog_t * dialog)941 const belle_sip_header_address_t *belle_sip_dialog_get_remote_target(belle_sip_dialog_t *dialog){
942 return dialog->remote_target;
943 }
944
belle_sip_dialog_get_route_set(belle_sip_dialog_t * dialog)945 const belle_sip_list_t* belle_sip_dialog_get_route_set(belle_sip_dialog_t *dialog){
946 return dialog->route_set;
947 }
948
belle_sip_dialog_get_state(const belle_sip_dialog_t * dialog)949 belle_sip_dialog_state_t belle_sip_dialog_get_state(const belle_sip_dialog_t *dialog){
950 return dialog->state;
951 }
952
belle_sip_dialog_get_previous_state(const belle_sip_dialog_t * dialog)953 belle_sip_dialog_state_t belle_sip_dialog_get_previous_state(const belle_sip_dialog_t *dialog) {
954 return dialog->previous_state;
955 }
belle_sip_dialog_is_server(const belle_sip_dialog_t * dialog)956 int belle_sip_dialog_is_server(const belle_sip_dialog_t *dialog){
957 return dialog->is_server;
958 }
959
belle_sip_dialog_is_secure(const belle_sip_dialog_t * dialog)960 int belle_sip_dialog_is_secure(const belle_sip_dialog_t *dialog){
961 return dialog->is_secure;
962 }
963
belle_sip_dialog_send_ack(belle_sip_dialog_t * obj,belle_sip_request_t * request)964 void belle_sip_dialog_send_ack(belle_sip_dialog_t *obj, belle_sip_request_t *request){
965 if (obj->needs_ack){
966 obj->needs_ack=FALSE;
967 if (obj->last_out_ack)
968 belle_sip_object_unref(obj->last_out_ack);
969 obj->last_out_ack=(belle_sip_request_t*)belle_sip_object_ref(request);
970 belle_sip_provider_send_request(obj->provider,request);
971 belle_sip_dialog_process_queue(obj);
972 }else{
973 belle_sip_error("Why do you want to send an ACK ?");
974 }
975 }
976
belle_sip_dialog_terminate_on_bye(belle_sip_dialog_t * obj,int val)977 void belle_sip_dialog_terminate_on_bye(belle_sip_dialog_t *obj, int val){
978 obj->terminate_on_bye=val;
979 }
980
981 /*returns 1 if message belongs to the dialog, 0 otherwise */
belle_sip_dialog_match(belle_sip_dialog_t * obj,belle_sip_message_t * msg,int as_uas)982 int belle_sip_dialog_match(belle_sip_dialog_t *obj, belle_sip_message_t *msg, int as_uas){
983 belle_sip_header_call_id_t *call_id=belle_sip_message_get_header_by_type(msg,belle_sip_header_call_id_t);
984 belle_sip_header_from_t *from=belle_sip_message_get_header_by_type(msg,belle_sip_header_from_t);
985 belle_sip_header_to_t *to=belle_sip_message_get_header_by_type(msg,belle_sip_header_to_t);
986 const char *from_tag;
987 const char *to_tag;
988 const char *call_id_value;
989
990 if (call_id==NULL || from==NULL || to==NULL) return 0;
991
992 call_id_value=belle_sip_header_call_id_get_call_id(call_id);
993 from_tag=belle_sip_header_from_get_tag(from);
994 to_tag=belle_sip_header_to_get_tag(to);
995
996 return _belle_sip_dialog_match(obj,call_id_value,as_uas ? to_tag : from_tag, as_uas ? from_tag : to_tag);
997 }
998
_belle_sip_dialog_match(belle_sip_dialog_t * obj,const char * call_id,const char * local_tag,const char * remote_tag)999 int _belle_sip_dialog_match(belle_sip_dialog_t *obj, const char *call_id, const char *local_tag, const char *remote_tag){
1000 const char *dcid;
1001 /*Dialog created by notify matching subscription are still in NULL state if (obj->state==BELLE_SIP_DIALOG_NULL) belle_sip_fatal("_belle_sip_dialog_match() must not be used for dialog in null state.");*/
1002 dcid=belle_sip_header_call_id_get_call_id(obj->call_id);
1003 return strcmp(dcid,call_id)==0
1004 && strcmp(obj->local_tag,local_tag)==0
1005 && obj->remote_tag /* handle 180 without to tag */ && strcmp(obj->remote_tag,remote_tag)==0;
1006 }
1007
belle_sip_dialog_check_ack_sent(belle_sip_dialog_t * obj)1008 void belle_sip_dialog_check_ack_sent(belle_sip_dialog_t*obj){
1009 belle_sip_client_transaction_t* client_trans;
1010 if (obj->needs_ack){
1011 belle_sip_request_t *req;
1012 belle_sip_error("Your listener did not ACK'd the 200Ok for your INVITE request. The dialog will be terminated.");
1013 req=belle_sip_dialog_create_request(obj,"BYE");
1014 if (req){
1015 client_trans=belle_sip_provider_create_client_transaction(obj->provider,req);
1016 BELLE_SIP_TRANSACTION(client_trans)->is_internal=TRUE; /*internal transaction, don't bother user with 200ok*/
1017 belle_sip_client_transaction_send_request(client_trans);
1018 /*call dialog terminated*/
1019 }else{
1020 /*If there is no way to signal the failure to the other party, then force immediate dialog deletion*/
1021 belle_sip_dialog_delete(obj);
1022 }
1023 }
1024 }
1025 /*
1026 * return 0 if dialog handle the 200ok
1027 * */
belle_sip_dialog_handle_200Ok(belle_sip_dialog_t * obj,belle_sip_response_t * msg)1028 static int belle_sip_dialog_handle_200Ok(belle_sip_dialog_t *obj, belle_sip_response_t *msg){
1029 if (obj->last_out_ack){
1030 belle_sip_header_cseq_t *cseq=belle_sip_message_get_header_by_type(msg,belle_sip_header_cseq_t);
1031 if (cseq){
1032 belle_sip_header_cseq_t *ack_cseq=belle_sip_message_get_header_by_type(obj->last_out_ack,belle_sip_header_cseq_t);
1033 if (belle_sip_header_cseq_get_seq_number(cseq)==belle_sip_header_cseq_get_seq_number(ack_cseq)){
1034 /*pass for retransmission*/
1035 belle_sip_message("Dialog retransmitting last ack automatically");
1036 belle_sip_provider_send_request(obj->provider,obj->last_out_ack);
1037 return 0;
1038 }else belle_sip_message("No already created ACK matching 200Ok for dialog [%p]",obj);
1039 }
1040 }
1041 return -1;
1042 }
1043
belle_sip_dialog_handle_ack(belle_sip_dialog_t * obj,belle_sip_request_t * ack)1044 int belle_sip_dialog_handle_ack(belle_sip_dialog_t *obj, belle_sip_request_t *ack){
1045 belle_sip_header_cseq_t *cseq=belle_sip_message_get_header_by_type(ack,belle_sip_header_cseq_t);
1046 if (obj->needs_ack && belle_sip_header_cseq_get_seq_number(cseq)==obj->remote_invite_cseq){
1047 belle_sip_message("Incoming INVITE has ACK, dialog is happy");
1048 obj->needs_ack=FALSE;
1049 belle_sip_dialog_stop_200Ok_retrans(obj);
1050 belle_sip_dialog_process_queue(obj);
1051 return 0;
1052 }
1053 belle_sip_message("Dialog ignoring incoming ACK (surely a retransmission)");
1054 return -1;
1055 }
1056
belle_sip_dialog_get_last_transaction(const belle_sip_dialog_t * dialog)1057 belle_sip_transaction_t* belle_sip_dialog_get_last_transaction(const belle_sip_dialog_t *dialog) {
1058 return dialog->last_transaction;
1059 }
1060
belle_sip_dialog_request_pending(const belle_sip_dialog_t * dialog)1061 int belle_sip_dialog_request_pending(const belle_sip_dialog_t *dialog){
1062 return dialog->needs_ack || (dialog->last_transaction ? belle_sip_transaction_state_is_transient(belle_sip_transaction_get_state(dialog->last_transaction)) : FALSE);
1063 }
1064
1065 /* for notify exception
1066 As per RFC 3265;
1067 3.3.4. Dialog creation and termination
1068
1069 If an initial SUBSCRIBE request is not sent on a pre-existing dialog,
1070 the subscriber will wait for a response to the SUBSCRIBE request or a
1071 matching NOTIFY.
1072 ...
1073 ...
1074
1075 If an initial SUBSCRIBE is sent on a pre-existing dialog, a matching
1076 200-class response or successful NOTIFY request merely creates a new
1077 subscription associated with that dialog.
1078 */
1079
belle_sip_dialog_is_authorized_transaction(const belle_sip_dialog_t * dialog,const char * method)1080 int belle_sip_dialog_is_authorized_transaction(const belle_sip_dialog_t *dialog,const char* method) {
1081 if (belle_sip_dialog_request_pending(dialog)){
1082 const char* last_transaction_request;
1083 if (strcasecmp(method,"BYE")==0)
1084 return TRUE; /*don't reject a BYE*/
1085
1086 last_transaction_request = belle_sip_request_get_method(belle_sip_transaction_get_request(dialog->last_transaction));
1087 if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(dialog->last_transaction,belle_sip_client_transaction_t)
1088 && strcmp(last_transaction_request,"SUBSCRIBE")==0 && strcmp(method,"NOTIFY")==0){
1089 /*stupid as it is, you have to accept a NOTIFY for a SUBSCRIBE for which no answer is received yet...*/
1090 return TRUE;
1091 }
1092 if (strcmp(last_transaction_request,"INVITE")==0 && (strcmp(method,"PRACK")==0 || strcmp(method,"UPDATE")==0)){
1093 /*PRACK /UPDATE needs to be sent or received during reINVITEs.*/
1094 return TRUE;
1095 }
1096 return FALSE;
1097 } else {
1098 return TRUE;
1099 }
1100 }
1101
belle_sip_dialog_queue_client_transaction(belle_sip_dialog_t * dialog,belle_sip_client_transaction_t * tr)1102 void belle_sip_dialog_queue_client_transaction(belle_sip_dialog_t *dialog, belle_sip_client_transaction_t *tr){
1103 dialog->queued_ct=belle_sip_list_append(dialog->queued_ct, belle_sip_object_ref(tr));
1104 }
1105
_belle_sip_dialog_process_queue(belle_sip_dialog_t * dialog)1106 static void _belle_sip_dialog_process_queue(belle_sip_dialog_t* dialog){
1107 belle_sip_client_transaction_t *tr=NULL;
1108
1109 if (dialog->state==BELLE_SIP_DIALOG_TERMINATED || belle_sip_dialog_request_pending(dialog)) goto end;
1110
1111 dialog->queued_ct=belle_sip_list_pop_front(dialog->queued_ct,(void**)&tr);
1112 if (tr){
1113 belle_sip_message("Dialog [%p]: sending queued request.",dialog);
1114 tr->base.sent_by_dialog_queue=TRUE;
1115 belle_sip_client_transaction_send_request(tr);
1116 belle_sip_object_unref(tr);
1117 }
1118 end:
1119 belle_sip_object_unref(dialog);
1120 }
1121
belle_sip_dialog_process_queue(belle_sip_dialog_t * dialog)1122 void belle_sip_dialog_process_queue(belle_sip_dialog_t* dialog){
1123 /*process queue does not process synchronously.
1124 * This is to let the application handle responses and eventually submit new requests without being blocked.
1125 * Typically when a reINVITE is challenged, we want a chance to re-submit an authenticated request before processing
1126 * queued requests*/
1127 if (dialog->queued_ct){
1128 belle_sip_main_loop_do_later(dialog->provider->stack->ml,(belle_sip_callback_t)_belle_sip_dialog_process_queue,belle_sip_object_ref(dialog));
1129 }
1130 }
1131
belle_sip_dialog_update_request(belle_sip_dialog_t * dialog,belle_sip_request_t * req)1132 void belle_sip_dialog_update_request(belle_sip_dialog_t *dialog, belle_sip_request_t *req){
1133 belle_sip_header_cseq_t *cseq=belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t);
1134 belle_sip_dialog_update_local_cseq(dialog,belle_sip_request_get_method(req));
1135 if (dialog->route_set)
1136 belle_sip_message_add_headers((belle_sip_message_t*)req,dialog->route_set);
1137 belle_sip_request_set_uri(req,belle_sip_header_address_get_uri(dialog->remote_target));
1138 belle_sip_header_cseq_set_seq_number(cseq,dialog->local_cseq);
1139 }
1140
belle_sip_dialog_pending_trans_checking_enabled(const belle_sip_dialog_t * dialog)1141 int belle_sip_dialog_pending_trans_checking_enabled( const belle_sip_dialog_t *dialog) {
1142 return dialog->pending_trans_checking_enabled;
1143 }
1144
belle_sip_dialog_enable_pending_trans_checking(belle_sip_dialog_t * dialog,int value)1145 int belle_sip_dialog_enable_pending_trans_checking(belle_sip_dialog_t *dialog, int value) {
1146 dialog->pending_trans_checking_enabled = value;
1147 return 0;
1148 }
1149