1 /**
2  * @file strans.c  SIP Server Transaction
3  *
4  * Copyright (C) 2010 Creytiv.com
5  */
6 #include <re_types.h>
7 #include <re_mem.h>
8 #include <re_mbuf.h>
9 #include <re_sa.h>
10 #include <re_list.h>
11 #include <re_hash.h>
12 #include <re_fmt.h>
13 #include <re_uri.h>
14 #include <re_sys.h>
15 #include <re_tmr.h>
16 #include <re_udp.h>
17 #include <re_msg.h>
18 #include <re_sip.h>
19 #include "sip.h"
20 
21 
22 enum state {
23 	TRYING,
24 	PROCEEDING,
25 	ACCEPTED,
26 	COMPLETED,
27 	CONFIRMED,
28 };
29 
30 
31 struct sip_strans {
32 	struct le he;
33 	struct le he_mrg;
34 	struct tmr tmr;
35 	struct tmr tmrg;
36 	struct sa dst;
37 	struct sip *sip;
38 	struct sip_msg *msg;
39 	struct mbuf *mb;
40 	sip_cancel_h *cancelh;
41 	void *arg;
42 	enum state state;
43 	uint32_t txc;
44 	bool invite;
45 };
46 
47 
destructor(void * arg)48 static void destructor(void *arg)
49 {
50 	struct sip_strans *st = arg;
51 
52 	hash_unlink(&st->he);
53 	hash_unlink(&st->he_mrg);
54 	tmr_cancel(&st->tmr);
55 	tmr_cancel(&st->tmrg);
56 	mem_deref(st->msg);
57 	mem_deref(st->mb);
58 }
59 
60 
strans_cmp(const struct sip_msg * msg1,const struct sip_msg * msg2)61 static bool strans_cmp(const struct sip_msg *msg1, const struct sip_msg *msg2)
62 {
63 	if (pl_cmp(&msg1->via.branch, &msg2->via.branch))
64 		return false;
65 
66 	if (pl_cmp(&msg1->via.sentby, &msg2->via.sentby))
67 		return false;
68 
69 	return true;
70 }
71 
72 
cmp_handler(struct le * le,void * arg)73 static bool cmp_handler(struct le *le, void *arg)
74 {
75 	struct sip_strans *st = le->data;
76 	const struct sip_msg *msg = arg;
77 
78 	if (!strans_cmp(st->msg, msg))
79 		return false;
80 
81 	if (pl_cmp(&st->msg->cseq.met, &msg->cseq.met))
82 		return false;
83 
84 	return true;
85 }
86 
87 
cmp_ack_handler(struct le * le,void * arg)88 static bool cmp_ack_handler(struct le *le, void *arg)
89 {
90 	struct sip_strans *st = le->data;
91 	const struct sip_msg *msg = arg;
92 
93 	if (!strans_cmp(st->msg, msg))
94 		return false;
95 
96 	if (pl_strcmp(&st->msg->cseq.met, "INVITE"))
97 		return false;
98 
99 	return true;
100 }
101 
102 
cmp_cancel_handler(struct le * le,void * arg)103 static bool cmp_cancel_handler(struct le *le, void *arg)
104 {
105 	struct sip_strans *st = le->data;
106 	const struct sip_msg *msg = arg;
107 
108 	if (!strans_cmp(st->msg, msg))
109 		return false;
110 
111 	if (!pl_strcmp(&st->msg->cseq.met, "CANCEL"))
112 		return false;
113 
114 	return true;
115 }
116 
117 
cmp_merge_handler(struct le * le,void * arg)118 static bool cmp_merge_handler(struct le *le, void *arg)
119 {
120 	struct sip_strans *st = le->data;
121 	const struct sip_msg *msg = arg;
122 
123 	if (pl_cmp(&st->msg->cseq.met, &msg->cseq.met))
124 		return false;
125 
126 	if (st->msg->cseq.num != msg->cseq.num)
127 		return false;
128 
129 	if (pl_cmp(&st->msg->callid, &msg->callid))
130 		return false;
131 
132 	if (pl_cmp(&st->msg->from.tag, &msg->from.tag))
133 		return false;
134 
135 	if (pl_cmp(&st->msg->ruri, &msg->ruri))
136 		return false;
137 
138 	return true;
139 }
140 
141 
dummy_handler(void * arg)142 static void dummy_handler(void *arg)
143 {
144 	(void)arg;
145 }
146 
147 
tmr_handler(void * arg)148 static void tmr_handler(void *arg)
149 {
150 	struct sip_strans *st = arg;
151 
152 	mem_deref(st);
153 }
154 
155 
retransmit_handler(void * arg)156 static void retransmit_handler(void *arg)
157 {
158 	struct sip_strans *st = arg;
159 
160 	(void)sip_send(st->sip, st->msg->sock, st->msg->tp, &st->dst,
161 		       st->mb);
162 
163 	st->txc++;
164 	tmr_start(&st->tmrg, MIN(SIP_T1<<st->txc, SIP_T2), retransmit_handler,
165 		  st);
166 }
167 
168 
ack_handler(struct sip * sip,const struct sip_msg * msg)169 static bool ack_handler(struct sip *sip, const struct sip_msg *msg)
170 {
171 	struct sip_strans *st;
172 
173 	st = list_ledata(hash_lookup(sip->ht_strans,
174 				     hash_joaat_pl(&msg->via.branch),
175 				     cmp_ack_handler, (void *)msg));
176 	if (!st)
177 		return false;
178 
179 	switch (st->state) {
180 
181 	case ACCEPTED:
182 		/* make sure ACKs for 2xx are passed to TU */
183 		return false;
184 
185 	case COMPLETED:
186 		if (sip_transp_reliable(st->msg->tp)) {
187 			mem_deref(st);
188 			break;
189 		}
190 
191 		tmr_start(&st->tmr, SIP_T4, tmr_handler, st);
192 		tmr_cancel(&st->tmrg);
193 		st->state = CONFIRMED;
194 		break;
195 
196 	default:
197 		break;
198 	}
199 
200 	return true;
201 }
202 
203 
cancel_handler(struct sip * sip,const struct sip_msg * msg)204 static bool cancel_handler(struct sip *sip, const struct sip_msg *msg)
205 {
206 	struct sip_strans *st;
207 
208 	st = list_ledata(hash_lookup(sip->ht_strans,
209 				     hash_joaat_pl(&msg->via.branch),
210 				     cmp_cancel_handler, (void *)msg));
211 	if (!st)
212 		return false;
213 
214 	((struct sip_msg *)msg)->tag = st->msg->tag;
215 
216 	(void)sip_reply(sip, msg, 200, "OK");
217 
218 	switch (st->state) {
219 
220 	case TRYING:
221 	case PROCEEDING:
222 		st->cancelh(st->arg);
223 		break;
224 
225 	default:
226 		break;
227 	}
228 
229 	return true;
230 }
231 
232 
request_handler(const struct sip_msg * msg,void * arg)233 static bool request_handler(const struct sip_msg *msg, void *arg)
234 {
235 	struct sip_strans *st;
236 	struct sip *sip = arg;
237 
238 	if (!pl_strcmp(&msg->met, "ACK"))
239 		return ack_handler(sip, msg);
240 
241 	st = list_ledata(hash_lookup(sip->ht_strans,
242 				     hash_joaat_pl(&msg->via.branch),
243 				     cmp_handler, (void *)msg));
244 	if (st) {
245 		switch (st->state) {
246 
247 		case PROCEEDING:
248 		case COMPLETED:
249 			(void)sip_send(st->sip, st->msg->sock, st->msg->tp,
250 				       &st->dst, st->mb);
251 			break;
252 
253 		default:
254 			break;
255 		}
256 
257 		return true;
258 	}
259 	else if (!pl_isset(&msg->to.tag)) {
260 
261 		st = list_ledata(hash_lookup(sip->ht_strans_mrg,
262 					     hash_joaat_pl(&msg->callid),
263 					     cmp_merge_handler, (void *)msg));
264 		if (st) {
265 			(void)sip_reply(sip, msg, 482, "Loop Detected");
266 			return true;
267 		}
268 	}
269 
270 	if (!pl_strcmp(&msg->met, "CANCEL"))
271 		return cancel_handler(sip, msg);
272 
273 	return false;
274 }
275 
276 
277 /**
278  * Allocate a SIP Server Transaction
279  *
280  * @param stp     Pointer to allocated SIP Server Transaction
281  * @param sip     SIP Stack instance
282  * @param msg     Incoming SIP message
283  * @param cancelh Cancel handler
284  * @param arg     Handler argument
285  *
286  * @return 0 if success, otherwise errorcode
287  */
sip_strans_alloc(struct sip_strans ** stp,struct sip * sip,const struct sip_msg * msg,sip_cancel_h * cancelh,void * arg)288 int sip_strans_alloc(struct sip_strans **stp, struct sip *sip,
289 		     const struct sip_msg *msg, sip_cancel_h *cancelh,
290 		     void *arg)
291 {
292 	struct sip_strans *st;
293 
294 	if (!stp || !sip || !msg)
295 		return EINVAL;
296 
297 	st = mem_zalloc(sizeof(*st), destructor);
298 	if (!st)
299 		return ENOMEM;
300 
301 	hash_append(sip->ht_strans, hash_joaat_pl(&msg->via.branch),
302 		    &st->he, st);
303 
304 	hash_append(sip->ht_strans_mrg, hash_joaat_pl(&msg->callid),
305 		    &st->he_mrg, st);
306 
307 	st->invite  = !pl_strcmp(&msg->met, "INVITE");
308 	st->msg     = mem_ref((void *)msg);
309 	st->state   = TRYING;
310 	st->cancelh = cancelh ? cancelh : dummy_handler;
311 	st->arg     = arg;
312 	st->sip     = sip;
313 
314 	*stp = st;
315 
316 	return 0;
317 }
318 
319 
320 /**
321  * Reply using a SIP Server Transaction
322  *
323  * @param stp   Pointer to allocated SIP Server Transaction
324  * @param sip   SIP Stack instance
325  * @param msg   Incoming SIP message
326  * @param dst   Destination network address
327  * @param scode Response status code
328  * @param mb    Buffer containing SIP response
329  *
330  * @return 0 if success, otherwise errorcode
331  */
sip_strans_reply(struct sip_strans ** stp,struct sip * sip,const struct sip_msg * msg,const struct sa * dst,uint16_t scode,struct mbuf * mb)332 int sip_strans_reply(struct sip_strans **stp, struct sip *sip,
333 		     const struct sip_msg *msg, const struct sa *dst,
334 		     uint16_t scode, struct mbuf *mb)
335 {
336 	struct sip_strans *st = NULL;
337 	int err;
338 
339 	if (!sip || !mb || !dst || (scode < 200 && !stp))
340 		return EINVAL;
341 
342 	if (stp)
343 		st = *stp;
344 
345 	if (!st) {
346 		err = sip_strans_alloc(&st, sip, msg, NULL, NULL);
347 		if (err)
348 			return err;
349 	}
350 
351 	mem_deref(st->mb);
352 	st->mb = mem_ref(mb);
353 	st->dst = *dst;
354 
355 	err = sip_send(sip, st->msg->sock, st->msg->tp, dst, mb);
356 
357 	if (stp)
358 		*stp = (err || scode >= 200) ? NULL : st;
359 
360 	if (err) {
361 		mem_deref(st);
362 		return err;
363 	}
364 
365 	if (st->invite) {
366 		if (scode < 200) {
367 			st->state = PROCEEDING;
368 		}
369 		else if (scode < 300) {
370 			tmr_start(&st->tmr, 64 * SIP_T1, tmr_handler, st);
371 			st->state = ACCEPTED;
372 		}
373 		else {
374 			tmr_start(&st->tmr, 64 * SIP_T1, tmr_handler, st);
375 			st->state = COMPLETED;
376 
377 			if (!sip_transp_reliable(st->msg->tp))
378 				tmr_start(&st->tmrg, SIP_T1,
379 					  retransmit_handler, st);
380 		}
381 	}
382 	else {
383 		if (scode < 200) {
384 			st->state = PROCEEDING;
385 		}
386 		else {
387 			if (!sip_transp_reliable(st->msg->tp)) {
388 				tmr_start(&st->tmr, 64 * SIP_T1, tmr_handler,
389 					  st);
390 				st->state = COMPLETED;
391 			}
392 			else {
393 				mem_deref(st);
394 			}
395 		}
396 	}
397 
398 	return 0;
399 }
400 
401 
sip_strans_init(struct sip * sip,uint32_t sz)402 int sip_strans_init(struct sip *sip, uint32_t sz)
403 {
404 	int err;
405 
406 	err = sip_listen(NULL, sip, true, request_handler, sip);
407 	if (err)
408 		return err;
409 
410 	err = hash_alloc(&sip->ht_strans_mrg, sz);
411 	if (err)
412 		return err;
413 
414 	return hash_alloc(&sip->ht_strans, sz);
415 }
416 
417 
statename(enum state state)418 static const char *statename(enum state state)
419 {
420 	switch (state) {
421 
422 	case TRYING:     return "TRYING";
423 	case PROCEEDING: return "PROCEEDING";
424 	case ACCEPTED:   return "ACCEPTED";
425 	case COMPLETED:  return "COMPLETED";
426 	case CONFIRMED:  return "CONFIRMED";
427 	default:         return "???";
428 	}
429 }
430 
431 
debug_handler(struct le * le,void * arg)432 static bool debug_handler(struct le *le, void *arg)
433 {
434 	struct sip_strans *st = le->data;
435 	struct re_printf *pf = arg;
436 
437 	(void)re_hprintf(pf, "  %-10r %-10s %2llus (%r)\n",
438 			 &st->msg->met,
439 			 statename(st->state),
440 			 tmr_get_expire(&st->tmr)/1000,
441 			 &st->msg->via.branch);
442 
443 	return false;
444 }
445 
446 
sip_strans_debug(struct re_printf * pf,const struct sip * sip)447 int sip_strans_debug(struct re_printf *pf, const struct sip *sip)
448 {
449 	int err;
450 
451 	err = re_hprintf(pf, "server transactions:\n");
452 	hash_apply(sip->ht_strans, debug_handler, pf);
453 
454 	return err;
455 }
456