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 
belle_sip_transaction_state_to_string(belle_sip_transaction_state_t state)21 const char *belle_sip_transaction_state_to_string(belle_sip_transaction_state_t state){
22 	switch(state){
23 		case BELLE_SIP_TRANSACTION_INIT:
24 			return "INIT";
25 		case BELLE_SIP_TRANSACTION_TRYING:
26 			return "TRYING";
27 		case BELLE_SIP_TRANSACTION_CALLING:
28 			return "CALLING";
29 		case BELLE_SIP_TRANSACTION_COMPLETED:
30 			return "COMPLETED";
31 		case BELLE_SIP_TRANSACTION_CONFIRMED:
32 			return "CONFIRMED";
33 		case BELLE_SIP_TRANSACTION_ACCEPTED:
34 			return "ACCEPTED";
35 		case BELLE_SIP_TRANSACTION_PROCEEDING:
36 			return "PROCEEDING";
37 		case BELLE_SIP_TRANSACTION_TERMINATED:
38 			return "TERMINATED";
39 	}
40 	belle_sip_fatal("Invalid transaction state.");
41 	return "INVALID";
42 }
43 
belle_sip_transaction_set_state(belle_sip_transaction_t * t,belle_sip_transaction_state_t state)44 void belle_sip_transaction_set_state(belle_sip_transaction_t *t, belle_sip_transaction_state_t state) {
45 	belle_sip_message("Changing [%s] [%s] transaction [%p], from state [%s] to [%s]",
46 				BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_client_transaction_t) ? "client" : "server",
47 				belle_sip_request_get_method(t->request),
48 				t,
49 				belle_sip_transaction_state_to_string(t->state),
50 				belle_sip_transaction_state_to_string(state));
51 	t->state=state;
52 }
53 
belle_sip_transaction_get_method(const belle_sip_transaction_t * t)54 BELLESIP_EXPORT const char *belle_sip_transaction_get_method(const belle_sip_transaction_t *t){
55 	return belle_sip_request_get_method(t->request);
56 }
57 
transaction_end_background_task(belle_sip_transaction_t * obj)58 static void transaction_end_background_task(belle_sip_transaction_t *obj){
59 	if (obj->bg_task_id){
60 		belle_sip_message("transaction [%p]: ending transaction background task with id=[%lx].",obj,obj->bg_task_id);
61 		belle_sip_end_background_task(obj->bg_task_id);
62 		obj->bg_task_id=0;
63 	}
64 }
65 
transaction_background_task_ended(belle_sip_transaction_t * obj)66 static void transaction_background_task_ended(belle_sip_transaction_t *obj){
67 	belle_sip_warning("transaction [%p]: transaction background task has to be ended now, but work isn't finished.",obj);
68 	transaction_end_background_task(obj);
69 }
70 
transaction_begin_background_task(belle_sip_transaction_t * obj)71 static void transaction_begin_background_task(belle_sip_transaction_t *obj){
72 	if (obj->bg_task_id==0){
73 		char *transaction = bctbx_strdup_printf("belle-sip transaction(%p)", obj);
74         obj->bg_task_id=belle_sip_begin_background_task(transaction,(void (*)(void*))transaction_background_task_ended, obj);
75         if (obj->bg_task_id) belle_sip_message("transaction [%p]: starting transaction background task with id=[%lx].",obj,obj->bg_task_id);
76         bctbx_free(transaction);
77 	}
78 }
79 
belle_sip_transaction_init(belle_sip_transaction_t * t,belle_sip_provider_t * prov,belle_sip_request_t * req)80 static void belle_sip_transaction_init(belle_sip_transaction_t *t, belle_sip_provider_t *prov, belle_sip_request_t *req){
81 	transaction_begin_background_task(t);
82 	t->request=(belle_sip_request_t*)belle_sip_object_ref(req);
83 	t->provider=prov;
84 }
85 
transaction_destroy(belle_sip_transaction_t * t)86 static void transaction_destroy(belle_sip_transaction_t *t){
87 	if (t->call_repair_timer) {
88 		belle_sip_transaction_stop_timer(t, t->call_repair_timer);
89 		belle_sip_object_unref(t->call_repair_timer);
90 		t->call_repair_timer = NULL;
91 	}
92 	if (t->request) belle_sip_object_unref(t->request);
93 	if (t->last_response) belle_sip_object_unref(t->last_response);
94 	if (t->channel) belle_sip_object_unref(t->channel);
95 	if (t->branch_id) belle_sip_free(t->branch_id);
96 	belle_sip_transaction_set_dialog(t,NULL);
97 	belle_sip_message("Transaction [%p] deleted",t);
98 
99 }
100 
notify_timeout(belle_sip_transaction_t * t)101 static void notify_timeout(belle_sip_transaction_t *t){
102 	belle_sip_timeout_event_t ev;
103 	ev.source=(belle_sip_object_t*)t->provider;
104 	ev.transaction=t;
105 	ev.is_server_transaction=BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_server_transaction_t);
106 	BELLE_SIP_PROVIDER_INVOKE_LISTENERS_FOR_TRANSACTION(t,process_timeout,&ev);
107 }
108 
server_transaction_on_call_repair_timer(belle_sip_transaction_t * t)109 static int server_transaction_on_call_repair_timer(belle_sip_transaction_t *t) {
110 	belle_sip_server_transaction_send_response(BELLE_SIP_SERVER_TRANSACTION(t), belle_sip_response_create_from_request(t->request, 503));
111 	return BELLE_SIP_STOP;
112 }
113 
client_transaction_on_call_repair_timer(belle_sip_transaction_t * t)114 static int client_transaction_on_call_repair_timer(belle_sip_transaction_t *t) {
115 	belle_sip_transaction_terminate(t);
116 	return BELLE_SIP_STOP;
117 }
118 
on_channel_state_changed(belle_sip_channel_listener_t * l,belle_sip_channel_t * chan,belle_sip_channel_state_t state)119 static void on_channel_state_changed(belle_sip_channel_listener_t *l, belle_sip_channel_t *chan, belle_sip_channel_state_t state){
120 	belle_sip_transaction_t *t=(belle_sip_transaction_t*)l;
121 	belle_sip_io_error_event_t ev;
122 	const belle_sip_timer_config_t *timercfg = NULL;
123 	belle_sip_transaction_state_t tr_state=belle_sip_transaction_get_state((belle_sip_transaction_t*)t);
124 
125 	belle_sip_message("transaction [%p] channel state changed to [%s]"
126 						,t
127 						,belle_sip_channel_state_to_string(state));
128 	switch(state){
129 		case BELLE_SIP_CHANNEL_READY:
130 			if (tr_state==BELLE_SIP_TRANSACTION_INIT && BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_client_transaction_t) ){
131 				belle_sip_client_transaction_t *ct = (belle_sip_client_transaction_t*) t;
132 				BELLE_SIP_OBJECT_VPTR(ct,belle_sip_client_transaction_t)->send_request(ct);
133 			}
134 		break;
135 		case BELLE_SIP_CHANNEL_DISCONNECTED:
136 		case BELLE_SIP_CHANNEL_ERROR:
137 			belle_sip_object_ref(t);  /*take a ref in the case where the app calls belle_sip_transaction_terminate() within the listener*/
138 			ev.transport=belle_sip_channel_get_transport_name(chan);
139 			ev.source=BELLE_SIP_OBJECT(t);
140 			ev.port=chan->peer_port;
141 			ev.host=chan->peer_name;
142 			if ( tr_state!=BELLE_SIP_TRANSACTION_COMPLETED
143 				&& tr_state!=BELLE_SIP_TRANSACTION_CONFIRMED
144 				&& tr_state!=BELLE_SIP_TRANSACTION_ACCEPTED
145 				&& tr_state!=BELLE_SIP_TRANSACTION_TERMINATED) {
146 				BELLE_SIP_PROVIDER_INVOKE_LISTENERS_FOR_TRANSACTION(((belle_sip_transaction_t*)t),process_io_error,&ev);
147 			}
148 			if (t->timed_out) {
149 				notify_timeout((belle_sip_transaction_t*)t);
150 			} else {
151 				if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(t, belle_sip_ist_t) || BELLE_SIP_OBJECT_IS_INSTANCE_OF(t, belle_sip_ict_t)) {
152 					timercfg = belle_sip_transaction_get_timer_config(t);
153 					if (t->call_repair_timer) {
154 						belle_sip_transaction_stop_timer(t, t->call_repair_timer);
155 						belle_sip_object_unref(t->call_repair_timer);
156 						t->call_repair_timer = NULL;
157 					}
158 				}
159 			}
160 
161 			if (!t->timed_out && belle_sip_transaction_state_is_transient(t->state) && BELLE_SIP_OBJECT_IS_INSTANCE_OF(t, belle_sip_ist_t)) {
162 				t->call_repair_timer = belle_sip_timeout_source_new((belle_sip_source_func_t)server_transaction_on_call_repair_timer, t, 32 * timercfg->T1);
163 				belle_sip_transaction_start_timer(t, t->call_repair_timer);
164 			} else if (!t->timed_out && belle_sip_transaction_state_is_transient(t->state) && BELLE_SIP_OBJECT_IS_INSTANCE_OF(t, belle_sip_ict_t)) {
165 				t->call_repair_timer = belle_sip_timeout_source_new((belle_sip_source_func_t)client_transaction_on_call_repair_timer, t, 32 * timercfg->T1);
166 				belle_sip_transaction_start_timer(t, t->call_repair_timer);
167 			} else {
168 				belle_sip_transaction_terminate(t);
169 			}
170 			if (t->channel){
171 				belle_sip_channel_remove_listener(t->channel, l);
172 				belle_sip_object_unref(t->channel);
173 				t->channel = NULL;
174 			}
175 			belle_sip_object_unref(t);
176 
177 		break;
178 		default:
179 			/*ignored*/
180 		break;
181 	}
182 }
183 
184 BELLE_SIP_IMPLEMENT_INTERFACE_BEGIN(belle_sip_transaction_t,belle_sip_channel_listener_t)
185 on_channel_state_changed,
186 NULL, /* on_message_headers */
187 NULL, /* on_message */
188 NULL, /* on_sending */
189 NULL /* on_auth_requested */
190 BELLE_SIP_IMPLEMENT_INTERFACE_END
191 
192 BELLE_SIP_DECLARE_IMPLEMENTED_INTERFACES_1(belle_sip_transaction_t, belle_sip_channel_listener_t);
193 
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_transaction_t)194 BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_transaction_t)
195 	{
196 		BELLE_SIP_VPTR_INIT(belle_sip_transaction_t,belle_sip_object_t,FALSE),
197 		(belle_sip_object_destroy_t) transaction_destroy,
198 		NULL,/*no clone*/
199 		NULL,/*no marshal*/
200 		BELLE_SIP_DEFAULT_BUFSIZE_HINT
201 	},
202 	NULL /*on_terminate*/
203 BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END
204 
205 void *belle_sip_transaction_get_application_data_internal(const belle_sip_transaction_t *t){
206 	return t->appdata;
207 }
208 
belle_sip_transaction_get_application_data(const belle_sip_transaction_t * t)209 void *belle_sip_transaction_get_application_data(const belle_sip_transaction_t *t){
210 	if (t->is_internal) {
211 		belle_sip_error("belle_sip_transaction_get_application_data should not be used on internal transaction [%p]",t);
212 		return NULL;
213 	} else {
214 		return belle_sip_transaction_get_application_data_internal(t);
215 	};
216 }
217 
belle_sip_transaction_set_application_data(belle_sip_transaction_t * t,void * data)218 void belle_sip_transaction_set_application_data(belle_sip_transaction_t *t, void *data){
219 	t->appdata=data;
220 }
221 
belle_sip_transaction_get_branch_id(const belle_sip_transaction_t * t)222 const char *belle_sip_transaction_get_branch_id(const belle_sip_transaction_t *t){
223 	return t->branch_id;
224 }
225 
belle_sip_transaction_get_state(const belle_sip_transaction_t * t)226 belle_sip_transaction_state_t belle_sip_transaction_get_state(const belle_sip_transaction_t *t){
227 	return t->state;
228 }
229 
belle_sip_transaction_state_is_transient(const belle_sip_transaction_state_t state)230 int belle_sip_transaction_state_is_transient(const belle_sip_transaction_state_t state) {
231 	switch(state){
232 		case BELLE_SIP_TRANSACTION_INIT:
233 		case BELLE_SIP_TRANSACTION_TRYING:
234 		case BELLE_SIP_TRANSACTION_CALLING:
235 		case BELLE_SIP_TRANSACTION_PROCEEDING:
236 			return 1;
237 		default:
238 			return 0;
239 	}
240 }
241 
belle_sip_transaction_terminate(belle_sip_transaction_t * t)242 void belle_sip_transaction_terminate(belle_sip_transaction_t *t){
243 	belle_sip_object_ref(t);
244 	if (t->call_repair_timer) {
245 		belle_sip_transaction_stop_timer(t, t->call_repair_timer);
246 		belle_sip_object_unref(t->call_repair_timer);
247 		t->call_repair_timer = NULL;
248 	}
249 	if (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(t))!=BELLE_SIP_TRANSACTION_TERMINATED) {
250 		int is_client=BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_client_transaction_t);
251 		belle_sip_transaction_set_state(t,BELLE_SIP_TRANSACTION_TERMINATED);
252 		if (t->dialog && (!t->last_response || belle_sip_response_get_status_code(t->last_response)<200)){
253 			/*inform the dialog if a transaction terminates without final response.*/
254 			belle_sip_dialog_update(t->dialog,t,!is_client);
255 		}
256 		belle_sip_message("%s%s %s transaction [%p] terminated"	,is_client ? "Client":"Server"
257 									,t->is_internal ? " internal":""
258 									,belle_sip_request_get_method(belle_sip_transaction_get_request(t))
259 									,t);
260 		BELLE_SIP_OBJECT_VPTR(t,belle_sip_transaction_t)->on_terminate(t);
261 		belle_sip_provider_set_transaction_terminated(t->provider,t);
262 	}
263 	transaction_end_background_task(t);
264 	belle_sip_object_unref(t);
265 }
266 
belle_sip_transaction_get_request(const belle_sip_transaction_t * t)267 belle_sip_request_t *belle_sip_transaction_get_request(const belle_sip_transaction_t *t){
268 	return t->request;
269 }
belle_sip_transaction_get_response(const belle_sip_transaction_t * t)270 belle_sip_response_t *belle_sip_transaction_get_response(const belle_sip_transaction_t *t) {
271 	return t->last_response;
272 }
273 
belle_sip_transaction_notify_timeout(belle_sip_transaction_t * t)274 void belle_sip_transaction_notify_timeout(belle_sip_transaction_t *t){
275 	/*report the channel as possibly dead. If an alternate IP can be tryied, the channel will notify us with the RETRY state.
276 	 * Otherwise it will report the error.
277 	 * We limit this dead channel reporting to REGISTER transactions, who are unlikely to be unresponded.
278 	**/
279 	belle_sip_object_ref(t);  /*take a ref in the case where the app calls belle_sip_transaction_terminate() within the timeout listener*/
280 	if (strcmp(belle_sip_request_get_method(t->request),"REGISTER")==0){
281 		if ( belle_sip_channel_notify_timeout(t->channel)==TRUE){
282 			belle_sip_warning("Transaction [%p] has timeout, reported to channel.",t);
283 			t->timed_out=TRUE;
284 		}
285 	}else {
286 		notify_timeout(t);
287 		belle_sip_transaction_terminate(t);
288 	}
289 	belle_sip_object_unref(t);
290 }
291 
belle_sip_transaction_get_dialog(const belle_sip_transaction_t * t)292 belle_sip_dialog_t*  belle_sip_transaction_get_dialog(const belle_sip_transaction_t *t) {
293 	return t->dialog;
294 }
295 
belle_sip_transaction_reset_dialog(belle_sip_transaction_t * tr,belle_sip_dialog_t * dialog_disapeearing)296 static void belle_sip_transaction_reset_dialog(belle_sip_transaction_t *tr, belle_sip_dialog_t *dialog_disapeearing){
297 	if (tr->dialog!=dialog_disapeearing) belle_sip_error("belle_sip_transaction_reset_dialog(): inconsistency.");
298 	tr->dialog=NULL;
299 }
300 
belle_sip_transaction_set_dialog(belle_sip_transaction_t * t,belle_sip_dialog_t * dialog)301 void belle_sip_transaction_set_dialog(belle_sip_transaction_t *t, belle_sip_dialog_t *dialog){
302 	if (t->dialog==dialog) return;
303 	if (dialog) belle_sip_object_weak_ref(dialog,(belle_sip_object_destroy_notify_t)belle_sip_transaction_reset_dialog,t);
304 	if (t->dialog) belle_sip_object_weak_unref(t->dialog,(belle_sip_object_destroy_notify_t)belle_sip_transaction_reset_dialog,t);
305 	t->dialog=dialog;
306 }
307 
308 /*
309  * Server transaction
310  */
311 
server_transaction_destroy(belle_sip_server_transaction_t * t)312 static void server_transaction_destroy(belle_sip_server_transaction_t *t){
313 }
314 
315 
316 BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_server_transaction_t);
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_server_transaction_t)317 BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_server_transaction_t)
318 	{
319 		{
320 			BELLE_SIP_VPTR_INIT(belle_sip_server_transaction_t,belle_sip_transaction_t,FALSE),
321 			(belle_sip_object_destroy_t) server_transaction_destroy,
322 			NULL,
323 			NULL,
324 			BELLE_SIP_DEFAULT_BUFSIZE_HINT
325 		},
326 		NULL
327 	},
328 	NULL, /* send_new_response */
329 	NULL /* on_request_retransmission */
330 BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END
331 
332 void belle_sip_server_transaction_init(belle_sip_server_transaction_t *t, belle_sip_provider_t *prov,belle_sip_request_t *req){
333 	const char *branch;
334 	belle_sip_header_via_t *via=BELLE_SIP_HEADER_VIA(belle_sip_message_get_header((belle_sip_message_t*)req,"via"));
335 	branch=belle_sip_header_via_get_branch(via);
336 	if (branch==NULL || strncmp(branch,BELLE_SIP_BRANCH_MAGIC_COOKIE,strlen(BELLE_SIP_BRANCH_MAGIC_COOKIE))!=0){
337 		branch=req->rfc2543_branch;
338 		if (branch==NULL) belle_sip_fatal("No computed branch for RFC2543 style of message, this should never happen.");
339 	}
340 	t->base.branch_id=belle_sip_strdup(branch);
341 	belle_sip_transaction_init((belle_sip_transaction_t*)t,prov,req);
342 	belle_sip_random_token(t->to_tag,sizeof(t->to_tag));
343 }
344 
belle_sip_server_transaction_send_response(belle_sip_server_transaction_t * t,belle_sip_response_t * resp)345 void belle_sip_server_transaction_send_response(belle_sip_server_transaction_t *t, belle_sip_response_t *resp){
346 	belle_sip_transaction_t *base=(belle_sip_transaction_t*)t;
347 	belle_sip_header_to_t *to=(belle_sip_header_to_t*)belle_sip_message_get_header((belle_sip_message_t*)resp,"to");
348 	belle_sip_dialog_t *dialog=base->dialog;
349 	int status_code;
350 
351 	belle_sip_object_ref(resp);
352 	if (!base->last_response || !base->channel){
353 		belle_sip_hop_t* hop=belle_sip_response_get_return_hop(resp);
354 		base->channel=belle_sip_provider_get_channel(base->provider,hop);
355 		belle_sip_object_unref(hop);
356 		if (!base->channel){
357 			belle_sip_error("Transaction [%p]: No channel available for sending response.",t);
358 			return;
359 		}
360 		belle_sip_object_ref(base->channel);
361 		belle_sip_channel_add_listener(base->channel, BELLE_SIP_CHANNEL_LISTENER(t));
362 	}
363 	status_code=belle_sip_response_get_status_code(resp);
364 	if (status_code!=100){
365 		if (belle_sip_header_to_get_tag(to)==NULL){
366 			//add a random to tag
367 			belle_sip_header_to_set_tag(to,t->to_tag);
368 		}
369 		/*12.1 Creation of a Dialog
370 		   Dialogs are created through the generation of non-failure responses
371 		   to requests with specific methods.  Within this specification, only
372 		   2xx and 101-199 responses with a To tag, where the request was
373 		   INVITE, will establish a dialog.*/
374 		if (dialog && status_code>100 && status_code<300){
375 			belle_sip_response_fill_for_dialog(resp,base->request);
376 		}
377 	}
378 	if (BELLE_SIP_OBJECT_VPTR(t,belle_sip_server_transaction_t)->send_new_response(t,resp)==0){
379 		if (base->last_response)
380 			belle_sip_object_unref(base->last_response);
381 		base->last_response=resp;
382 	}
383 	if (dialog)
384 		belle_sip_dialog_update(dialog,BELLE_SIP_TRANSACTION(t),TRUE);
385 }
386 
server_transaction_notify(belle_sip_server_transaction_t * t,belle_sip_request_t * req,belle_sip_dialog_t * dialog)387 static void server_transaction_notify(belle_sip_server_transaction_t *t, belle_sip_request_t *req, belle_sip_dialog_t *dialog){
388 	belle_sip_request_event_t event;
389 
390 	event.source=(belle_sip_object_t*)t->base.provider;
391 	event.server_transaction=t;
392 	event.dialog=dialog;
393 	event.request=req;
394 	BELLE_SIP_PROVIDER_INVOKE_LISTENERS_FOR_TRANSACTION(((belle_sip_transaction_t*) t),process_request_event,&event);
395 }
396 
belle_sip_server_transaction_on_request(belle_sip_server_transaction_t * t,belle_sip_request_t * req)397 void belle_sip_server_transaction_on_request(belle_sip_server_transaction_t *t, belle_sip_request_t *req){
398 	const char *method=belle_sip_request_get_method(req);
399 	if (strcmp(method,"ACK")==0){
400 		/*this must be for an INVITE server transaction */
401 		if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_ist_t)){
402 			belle_sip_ist_t *ist=(belle_sip_ist_t*)t;
403 			if (belle_sip_ist_process_ack(ist,(belle_sip_message_t*)req)==0){
404 				belle_sip_dialog_t *dialog=t->base.dialog;
405 				if (dialog && belle_sip_dialog_handle_ack(dialog,req)==0)
406 					server_transaction_notify(t,req,dialog);
407 				/*else nothing to do because retransmission of ACK*/
408 
409 			}
410 		}else{
411 			belle_sip_warning("ACK received for non-invite server transaction ?");
412 		}
413 	}else if (strcmp(method,"CANCEL")==0){
414 		server_transaction_notify(t,req,t->base.dialog);
415 	}else
416 		BELLE_SIP_OBJECT_VPTR(t,belle_sip_server_transaction_t)->on_request_retransmission(t);
417 }
418 
419 /*
420  * client transaction
421  */
422 
423 
424 
belle_sip_client_transaction_create_cancel(belle_sip_client_transaction_t * t)425 belle_sip_request_t * belle_sip_client_transaction_create_cancel(belle_sip_client_transaction_t *t){
426 	belle_sip_message_t *orig=(belle_sip_message_t*)t->base.request;
427 	belle_sip_request_t *req;
428 	const char *orig_method=belle_sip_request_get_method((belle_sip_request_t*)orig);
429 	if (strcmp(orig_method,"ACK")==0 || strcmp(orig_method,"INVITE")!=0){
430 		belle_sip_error("belle_sip_client_transaction_create_cancel() cannot be used for ACK or non-INVITE transactions.");
431 		return NULL;
432 	}
433 	if ((t->base.state != BELLE_SIP_TRANSACTION_PROCEEDING) && (t->base.state != BELLE_SIP_TRANSACTION_CALLING)) {
434 		belle_sip_error("belle_sip_client_transaction_create_cancel() can only be used in state PROCEEDING or CALLING"
435 		               " but current transaction state is %s",belle_sip_transaction_state_to_string(t->base.state));
436 		return NULL;
437 	}
438 	req=belle_sip_request_new();
439 	belle_sip_request_set_method(req,"CANCEL");
440 /*	9.1 Client Behavior
441 	   Since requests other than INVITE are responded to immediately,
442 	   sending a CANCEL for a non-INVITE request would always create a
443 	   race condition.
444 	   The following procedures are used to construct a CANCEL request.  The
445 	   Request-URI, Call-ID, To, the numeric part of CSeq, and From header
446 	   fields in the CANCEL request MUST be identical to those in the
447 	   request being cancelled, including tags.  A CANCEL constructed by a
448 	   client MUST have only a single Via header field value matching the
449 	   top Via value in the request being cancelled.*/
450 	belle_sip_request_set_uri(req,(belle_sip_uri_t*)belle_sip_object_clone((belle_sip_object_t*)belle_sip_request_get_uri((belle_sip_request_t*)orig)));
451 	belle_sip_util_copy_headers(orig,(belle_sip_message_t*)req,"via",FALSE);
452 	belle_sip_util_copy_headers(orig,(belle_sip_message_t*)req,"call-id",FALSE);
453 	belle_sip_util_copy_headers(orig,(belle_sip_message_t*)req,"from",FALSE);
454 	belle_sip_util_copy_headers(orig,(belle_sip_message_t*)req,"to",FALSE);
455 	belle_sip_util_copy_headers(orig,(belle_sip_message_t*)req,"route",TRUE);
456 	belle_sip_util_copy_headers(orig,(belle_sip_message_t*)req,BELLE_SIP_MAX_FORWARDS,FALSE);
457 	belle_sip_message_add_header((belle_sip_message_t*)req,
458 		(belle_sip_header_t*)belle_sip_header_cseq_create(
459 			belle_sip_header_cseq_get_seq_number((belle_sip_header_cseq_t*)belle_sip_message_get_header(orig,"cseq")),
460 		    "CANCEL"));
461 	return req;
462 }
463 
464 
belle_sip_client_transaction_send_request(belle_sip_client_transaction_t * t)465 int belle_sip_client_transaction_send_request(belle_sip_client_transaction_t *t){
466 	return belle_sip_client_transaction_send_request_to(t,NULL);
467 
468 }
469 
belle_sip_client_transaction_send_request_to(belle_sip_client_transaction_t * t,belle_sip_uri_t * outbound_proxy)470 int belle_sip_client_transaction_send_request_to(belle_sip_client_transaction_t *t,belle_sip_uri_t* outbound_proxy) {
471 	belle_sip_channel_t *chan;
472 	belle_sip_provider_t *prov=t->base.provider;
473 	belle_sip_dialog_t *dialog=t->base.dialog;
474 	belle_sip_request_t *req=t->base.request;
475 	int result=-1;
476 
477 	if (t->base.state!=BELLE_SIP_TRANSACTION_INIT){
478 		belle_sip_error("belle_sip_client_transaction_send_request: bad state.");
479 		return -1;
480 	}
481 
482 	/*check uris components compliance*/
483 	if (!belle_sip_request_check_uris_components(t->base.request)) {
484 		belle_sip_error("belle_sip_client_transaction_send_request: bad request for transaction [%p]",t);
485 		return -1;
486 	}
487 	/*store preset route for future use by refresher*/
488 	if (outbound_proxy){
489 		t->preset_route=outbound_proxy;
490 		belle_sip_object_ref(t->preset_route);
491 	}
492 
493 	if (t->base.sent_by_dialog_queue){
494 
495 		/*it can be sent immediately, so update the request with latest cseq and route_set */
496 		/*update route and contact just in case they changed*/
497 		belle_sip_dialog_update_request(dialog,req);
498 	} else if (t->base.request->dialog_queued){
499 		/*this request was created by belle_sip_dialog_create_queued_request().*/
500 
501 		if (dialog == NULL){
502 			belle_sip_error("belle_sip_client_transaction_send_request(): transaction [%p], cannot send"
503 				" request because it was created in the context of a dialog that appears to be "
504 				" no longer existing.", t);
505 			belle_sip_transaction_terminate(BELLE_SIP_TRANSACTION(t));
506 			return -1;
507 		}
508 
509 		if (belle_sip_dialog_request_pending(dialog) || dialog->queued_ct!=NULL){
510 			/*it cannot be sent immediately, queue the transaction into dialog*/
511 			belle_sip_message("belle_sip_client_transaction_send_request(): transaction [%p], cannot send request now because dialog [%p] is busy"
512 			" or other transactions are queued, so queuing into dialog.",t, dialog);
513 			belle_sip_dialog_queue_client_transaction(dialog,t);
514 			return 0;
515 		}
516 		belle_sip_dialog_update_request(dialog,req);
517 	}
518 
519 	if (dialog){
520 		belle_sip_dialog_update(dialog,(belle_sip_transaction_t*)t,BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_server_transaction_t));
521 	}
522 
523 	if (!t->next_hop) {
524 		if (t->preset_route) {
525 			t->next_hop=belle_sip_hop_new_from_uri(t->preset_route);
526 		} else {
527 			t->next_hop = belle_sip_stack_get_next_hop(prov->stack,t->base.request);
528 		}
529 		belle_sip_object_ref(t->next_hop);
530 	} else {
531 		/*next hop already preset, probably in case of CANCEL*/
532 	}
533 	belle_sip_provider_add_client_transaction(t->base.provider,t); /*add it in any case*/
534 	chan=belle_sip_provider_get_channel(prov,t->next_hop);
535 	if (chan){
536 		belle_sip_object_ref(chan);
537 		belle_sip_channel_add_listener(chan,BELLE_SIP_CHANNEL_LISTENER(t));
538 		t->base.channel=chan;
539 		if (belle_sip_channel_get_state(chan)==BELLE_SIP_CHANNEL_INIT){
540 			belle_sip_message("belle_sip_client_transaction_send_request(): waiting channel to be ready");
541 			belle_sip_channel_prepare(chan);
542 			/*the channel will notify us when it is ready*/
543 		} else if (belle_sip_channel_get_state(chan)==BELLE_SIP_CHANNEL_READY){
544 			/*otherwise we can send immediately*/
545 			BELLE_SIP_OBJECT_VPTR(t,belle_sip_client_transaction_t)->send_request(t);
546 		}
547 		result=0;
548 	}else {
549 		belle_sip_error("belle_sip_client_transaction_send_request(): no channel available");
550 		belle_sip_transaction_terminate(BELLE_SIP_TRANSACTION(t));
551 		result=-1;
552 	}
553 	return result;
554 }
555 
should_dialog_be_created(belle_sip_client_transaction_t * t,belle_sip_response_t * resp)556 static unsigned int should_dialog_be_created(belle_sip_client_transaction_t *t, belle_sip_response_t *resp){
557 	belle_sip_request_t* req = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(t));
558 	const char* method = belle_sip_request_get_method(req);
559 	int status_code = belle_sip_response_get_status_code(resp);
560 	return status_code>=101 && status_code<300 && (strcmp(method,"INVITE")==0 || strcmp(method,"SUBSCRIBE")==0);
561 }
562 
belle_sip_client_transaction_notify_response(belle_sip_client_transaction_t * t,belle_sip_response_t * resp)563 void belle_sip_client_transaction_notify_response(belle_sip_client_transaction_t *t, belle_sip_response_t *resp){
564 	belle_sip_transaction_t *base=(belle_sip_transaction_t*)t;
565 	belle_sip_request_t* req = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(t));
566 	const char* method = belle_sip_request_get_method(req);
567 	belle_sip_response_event_t event;
568 	belle_sip_dialog_t *dialog=base->dialog;
569 	int status_code =  belle_sip_response_get_status_code(resp);
570 	if (base->last_response)
571 		belle_sip_object_unref(base->last_response);
572 	base->last_response=(belle_sip_response_t*)belle_sip_object_ref(resp);
573 
574 	if (dialog){
575 		if (status_code>=101 && status_code<300
576 			&& strcmp(method,"INVITE")==0
577 			&& (dialog->state==BELLE_SIP_DIALOG_EARLY || dialog->state==BELLE_SIP_DIALOG_CONFIRMED)){
578 			/*make sure this response matches the current dialog, or creates a new one*/
579 			if (!belle_sip_dialog_match(dialog,(belle_sip_message_t*)resp,FALSE)){
580 				dialog=belle_sip_provider_find_dialog_from_message(t->base.provider,(belle_sip_message_t*)resp,FALSE);
581 				if (!dialog){
582 					dialog=belle_sip_provider_create_dialog_internal(t->base.provider,BELLE_SIP_TRANSACTION(t),FALSE);/*belle_sip_dialog_new(base);*/
583 					belle_sip_message("Handling response creating a new dialog !");
584 				}
585 			}
586 		}
587 	} else if (should_dialog_be_created(t,resp)) {
588 		dialog=belle_sip_provider_create_dialog_internal(t->base.provider,BELLE_SIP_TRANSACTION(t),FALSE);
589 	}
590 
591 	if (dialog && belle_sip_dialog_update(dialog,BELLE_SIP_TRANSACTION(t),FALSE)) {
592 		/* retransmition, just return*/
593 		belle_sip_message("Response [%p] absorbed by dialog [%p], skipped from transaction layer.",resp,dialog);
594 		return;
595 	}
596 
597 	event.source=(belle_sip_object_t*)base->provider;
598 	event.client_transaction=t;
599 	event.dialog=dialog;
600 	event.response=(belle_sip_response_t*)resp;
601 	BELLE_SIP_PROVIDER_INVOKE_LISTENERS_FOR_TRANSACTION(((belle_sip_transaction_t*)t),process_response_event,&event);
602 	/*check that 200Ok for INVITEs have been acknowledged by listener*/
603 	if (dialog && status_code>=200 && status_code<300 && strcmp(method,"INVITE")==0){
604 		belle_sip_dialog_check_ack_sent(dialog);
605 	}
606 	/*report a server having internal errors for REGISTER to the channel, in order to go to a fallback IP*/
607 	if (status_code == 500 && strcmp(method,"REGISTER") == 0){
608 		belle_sip_channel_notify_server_error(base->channel);
609 	}
610 }
611 
612 
belle_sip_client_transaction_add_response(belle_sip_client_transaction_t * t,belle_sip_response_t * resp)613 void belle_sip_client_transaction_add_response(belle_sip_client_transaction_t *t, belle_sip_response_t *resp){
614 	BELLE_SIP_OBJECT_VPTR(t,belle_sip_client_transaction_t)->on_response(t,resp);
615 }
616 
belle_sip_client_transaction_get_route(belle_sip_client_transaction_t * t)617 belle_sip_uri_t *belle_sip_client_transaction_get_route(belle_sip_client_transaction_t *t){
618 	return t->preset_route;
619 }
620 
client_transaction_destroy(belle_sip_client_transaction_t * t)621 static void client_transaction_destroy(belle_sip_client_transaction_t *t ){
622 	if (t->preset_route) belle_sip_object_unref(t->preset_route);
623 	if (t->next_hop) belle_sip_object_unref(t->next_hop);
624 }
625 
626 
627 
628 BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_client_transaction_t);
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_client_transaction_t)629 BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_client_transaction_t)
630 	{
631 		{
632 			BELLE_SIP_VPTR_INIT(belle_sip_client_transaction_t,belle_sip_transaction_t,FALSE),
633 			(belle_sip_object_destroy_t)client_transaction_destroy,
634 			NULL,
635 			NULL,
636 			BELLE_SIP_DEFAULT_BUFSIZE_HINT
637 		},
638 		NULL
639 	},
640 	NULL,
641 	NULL
642 BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END
643 
644 void belle_sip_client_transaction_init(belle_sip_client_transaction_t *obj, belle_sip_provider_t *prov, belle_sip_request_t *req){
645 	belle_sip_header_via_t *via=BELLE_SIP_HEADER_VIA(belle_sip_message_get_header((belle_sip_message_t*)req,"via"));
646 	char token[BELLE_SIP_BRANCH_ID_LENGTH];
647 
648 	if (!via){
649 		belle_sip_fatal("belle_sip_client_transaction_init(): No via in request.");
650 	}
651 
652 	if (strcmp(belle_sip_request_get_method(req),"CANCEL")!=0){
653 		obj->base.branch_id=belle_sip_strdup_printf(BELLE_SIP_BRANCH_MAGIC_COOKIE ".%s",belle_sip_random_token(token,sizeof(token)));
654 		belle_sip_header_via_set_branch(via,obj->base.branch_id);
655 	}else{
656 		obj->base.branch_id=belle_sip_strdup(belle_sip_header_via_get_branch(via));
657 	}
658 	belle_sip_transaction_init((belle_sip_transaction_t*)obj, prov,req);
659 }
660 
belle_sip_client_transaction_create_refresher(belle_sip_client_transaction_t * t)661 belle_sip_refresher_t* belle_sip_client_transaction_create_refresher(belle_sip_client_transaction_t *t) {
662 	return belle_sip_refresher_new(t);
663 }
664 
belle_sip_client_transaction_create_authenticated_request(belle_sip_client_transaction_t * t,belle_sip_list_t ** auth_infos,const char * realm)665 belle_sip_request_t* belle_sip_client_transaction_create_authenticated_request(belle_sip_client_transaction_t *t,belle_sip_list_t** auth_infos,const char* realm) {
666 	belle_sip_request_t* initial_request=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(t));
667 	belle_sip_request_t* req=belle_sip_request_clone_with_body(initial_request);
668 	belle_sip_header_cseq_t* cseq=belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t);
669 	belle_sip_header_cseq_set_seq_number(cseq,belle_sip_header_cseq_get_seq_number(cseq)+1);
670 	if (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(t)) != BELLE_SIP_TRANSACTION_COMPLETED
671 		&& belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(t)) != BELLE_SIP_TRANSACTION_TERMINATED) {
672 		belle_sip_error("Invalid state [%s] for transaction [%p], should be BELLE_SIP_TRANSACTION_COMPLETED | BELLE_SIP_TRANSACTION_TERMINATED"
673 					,belle_sip_transaction_state_to_string(belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(t)))
674 					,t);
675 		belle_sip_object_unref(req);
676 		return NULL;
677 	}
678 	/*remove auth headers*/
679 	belle_sip_message_remove_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_AUTHORIZATION);
680 	belle_sip_message_remove_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_PROXY_AUTHORIZATION);
681 
682 	/*put auth header*/
683 	belle_sip_provider_add_authorization(t->base.provider,req,t->base.last_response,NULL,auth_infos,realm);
684 	return req;
685 }
686 
687 /*
688  rfc 3265
689  3.3.4. Dialog creation and termination
690  ...
691  NOTIFY requests are matched to such SUBSCRIBE requests if they
692  contain the same "Call-ID", a "To" header "tag" parameter which
693  matches the "From" header "tag" parameter of the SUBSCRIBE, and the
694  same "Event" header field.  Rules for comparisons of the "Event"
695  headers are described in section 7.2.1.  If a matching NOTIFY request
696  contains a "Subscription-State" of "active" or "pending", it creates
697  a new subscription and a new dialog (unless they have already been
698  created by a matching response, as described above).
699 
700 
701  */
702 
belle_sip_client_transaction_is_notify_matching_pending_subscribe(belle_sip_client_transaction_t * trans,belle_sip_request_t * notify)703 int belle_sip_client_transaction_is_notify_matching_pending_subscribe(belle_sip_client_transaction_t *trans
704 																	  , belle_sip_request_t *notify) {
705 	belle_sip_request_t *subscription;
706 	belle_sip_header_event_t *sub_event, *notif_event;
707 	belle_sip_header_call_id_t *sub_call_id, *notif_call_id;
708 	const char* sub_from_tag, *notif_to_tag;
709 
710 	if (!belle_sip_transaction_state_is_transient(belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(trans)))
711 		|| strcmp("SUBSCRIBE", belle_sip_transaction_get_method(BELLE_SIP_TRANSACTION(trans)))!=0) return 0;
712 
713 
714 	if (strcmp("NOTIFY",belle_sip_request_get_method(notify)) != 0) {
715 		belle_sip_error("belle_sip_client_transaction_is_notify_matching_pending_subscribe for dialog [%p], requires a notify request",notify);
716 	}
717 
718 	subscription = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(trans));
719 	sub_event = belle_sip_message_get_header_by_type(subscription, belle_sip_header_event_t);
720 	if (!sub_event || !belle_sip_header_event_get_package_name(sub_event))
721 		return 0;
722 
723 	notif_event = belle_sip_message_get_header_by_type(notify, belle_sip_header_event_t);
724 	if (!notif_event || !belle_sip_header_event_get_package_name(notif_event))
725 		return 0;
726 
727 	sub_call_id = belle_sip_message_get_header_by_type(subscription, belle_sip_header_call_id_t);
728 	notif_call_id = belle_sip_message_get_header_by_type(notify, belle_sip_header_call_id_t);
729 	sub_from_tag = belle_sip_header_from_get_tag(belle_sip_message_get_header_by_type(subscription, belle_sip_header_from_t));
730 	notif_to_tag = belle_sip_header_to_get_tag(belle_sip_message_get_header_by_type(notify, belle_sip_header_to_t));
731 
732 	return strcmp(belle_sip_header_call_id_get_call_id(sub_call_id),belle_sip_header_call_id_get_call_id(notif_call_id))==0
733 	&& sub_from_tag && notif_to_tag && strcmp(sub_from_tag,notif_to_tag)==0
734 	&& strcasecmp(belle_sip_header_event_get_package_name(sub_event),belle_sip_header_event_get_package_name(notif_event))==0;
735 
736 }
737 
738