1 /**
2  * @file sip/transp.c  SIP Transport
3  *
4  * Copyright (C) 2010 Creytiv.com
5  */
6 #include <string.h>
7 #include <re_types.h>
8 #include <re_mem.h>
9 #include <re_mbuf.h>
10 #include <re_sa.h>
11 #include <re_list.h>
12 #include <re_hash.h>
13 #include <re_fmt.h>
14 #include <re_uri.h>
15 #include <re_sys.h>
16 #include <re_tmr.h>
17 #include <re_udp.h>
18 #include <re_stun.h>
19 #include <re_srtp.h>
20 #include <re_tcp.h>
21 #include <re_tls.h>
22 #include <re_msg.h>
23 #include <re_sip.h>
24 #include "sip.h"
25 
26 
27 enum {
28 	TCP_ACCEPT_TIMEOUT    = 32,
29 	TCP_IDLE_TIMEOUT      = 900,
30 	TCP_KEEPALIVE_TIMEOUT = 10,
31 	TCP_KEEPALIVE_INTVAL  = 120,
32 	TCP_BUFSIZE_MAX       = 65536,
33 };
34 
35 
36 struct sip_transport {
37 	struct le le;
38 	struct sa laddr;
39 	struct sip *sip;
40 	struct tls *tls;
41 	void *sock;
42 	enum sip_transp tp;
43 };
44 
45 
46 struct sip_conn {
47 	struct le he;
48 	struct list ql;
49 	struct list kal;
50 	struct tmr tmr;
51 	struct tmr tmr_ka;
52 	struct sa laddr;
53 	struct sa paddr;
54 	struct tls_conn *sc;
55 	struct tcp_conn *tc;
56 	struct mbuf *mb;
57 	struct sip *sip;
58 	uint32_t ka_interval;
59 	bool established;
60 };
61 
62 
63 struct sip_connqent {
64 	struct le le;
65 	struct mbuf *mb;
66 	struct sip_connqent **qentp;
67 	sip_transp_h *transph;
68 	void *arg;
69 };
70 
71 
72 static uint8_t crlfcrlf[4] = {0x0d, 0x0a, 0x0d, 0x0a};
73 
74 
internal_transport_handler(int err,void * arg)75 static void internal_transport_handler(int err, void *arg)
76 {
77 	(void)err;
78 	(void)arg;
79 }
80 
81 
transp_destructor(void * arg)82 static void transp_destructor(void *arg)
83 {
84 	struct sip_transport *transp = arg;
85 
86 	if (transp->tp == SIP_TRANSP_UDP)
87 		udp_handler_set(transp->sock, NULL, NULL);
88 
89 	list_unlink(&transp->le);
90 	mem_deref(transp->sock);
91 	mem_deref(transp->tls);
92 }
93 
94 
conn_destructor(void * arg)95 static void conn_destructor(void *arg)
96 {
97 	struct sip_conn *conn = arg;
98 
99 	tmr_cancel(&conn->tmr_ka);
100 	tmr_cancel(&conn->tmr);
101 	list_flush(&conn->kal);
102 	list_flush(&conn->ql);
103 	hash_unlink(&conn->he);
104 	mem_deref(conn->sc);
105 	mem_deref(conn->tc);
106 	mem_deref(conn->mb);
107 }
108 
109 
qent_destructor(void * arg)110 static void qent_destructor(void *arg)
111 {
112 	struct sip_connqent *qent = arg;
113 
114 	if (qent->qentp)
115 		*qent->qentp = NULL;
116 
117 	list_unlink(&qent->le);
118 	mem_deref(qent->mb);
119 }
120 
121 
transp_find(struct sip * sip,enum sip_transp tp,int af,const struct sa * dst)122 static const struct sip_transport *transp_find(struct sip *sip,
123 					       enum sip_transp tp,
124 					       int af, const struct sa *dst)
125 {
126 	struct le *le;
127 	(void)dst;
128 
129 	for (le = sip->transpl.head; le; le = le->next) {
130 
131 		const struct sip_transport *transp = le->data;
132 
133 		if (transp->tp != tp)
134 			continue;
135 
136 		if (af != AF_UNSPEC && sa_af(&transp->laddr) != af)
137 			continue;
138 
139 		return transp;
140 	}
141 
142 	return NULL;
143 }
144 
145 
conn_find(struct sip * sip,const struct sa * paddr,bool secure)146 static struct sip_conn *conn_find(struct sip *sip, const struct sa *paddr,
147 				  bool secure)
148 {
149 	struct le *le;
150 
151 	le = list_head(hash_list(sip->ht_conn, sa_hash(paddr, SA_ALL)));
152 
153 	for (; le; le = le->next) {
154 
155 		struct sip_conn *conn = le->data;
156 
157 		if (!secure != (conn->sc == NULL))
158 			continue;
159 
160 		if (!sa_cmp(&conn->paddr, paddr, SA_ALL))
161 			continue;
162 
163 		return conn;
164 	}
165 
166 	return NULL;
167 }
168 
169 
conn_close(struct sip_conn * conn,int err)170 static void conn_close(struct sip_conn *conn, int err)
171 {
172 	struct le *le;
173 
174 	conn->sc = mem_deref(conn->sc);
175 	conn->tc = mem_deref(conn->tc);
176 	tmr_cancel(&conn->tmr_ka);
177 	tmr_cancel(&conn->tmr);
178 	hash_unlink(&conn->he);
179 
180 	le = list_head(&conn->ql);
181 
182 	while (le) {
183 
184 		struct sip_connqent *qent = le->data;
185 		le = le->next;
186 
187 		if (qent->qentp) {
188 			*qent->qentp = NULL;
189 			qent->qentp = NULL;
190 		}
191 
192 		qent->transph(err, qent->arg);
193 		list_unlink(&qent->le);
194 		mem_deref(qent);
195 	}
196 
197 	sip_keepalive_signal(&conn->kal, err);
198 }
199 
200 
conn_tmr_handler(void * arg)201 static void conn_tmr_handler(void *arg)
202 {
203 	struct sip_conn *conn = arg;
204 
205 	conn_close(conn, ETIMEDOUT);
206 	mem_deref(conn);
207 }
208 
209 
conn_keepalive_handler(void * arg)210 static void conn_keepalive_handler(void *arg)
211 {
212 	struct sip_conn *conn = arg;
213 	struct mbuf mb;
214 	int err;
215 
216 	mb.buf  = crlfcrlf;
217 	mb.size = sizeof(crlfcrlf);
218 	mb.pos  = 0;
219 	mb.end  = 4;
220 
221 	err = tcp_send(conn->tc, &mb);
222 	if (err) {
223 		conn_close(conn, err);
224 		mem_deref(conn);
225 		return;
226 	}
227 
228 	tmr_start(&conn->tmr, TCP_KEEPALIVE_TIMEOUT * 1000,
229 		  conn_tmr_handler, conn);
230 	tmr_start(&conn->tmr_ka, sip_keepalive_wait(conn->ka_interval),
231 		  conn_keepalive_handler, conn);
232 }
233 
234 
sip_recv(struct sip * sip,const struct sip_msg * msg)235 static void sip_recv(struct sip *sip, const struct sip_msg *msg)
236 {
237 	struct le *le = sip->lsnrl.head;
238 
239 	while (le) {
240 		struct sip_lsnr *lsnr = le->data;
241 
242 		le = le->next;
243 
244 		if (msg->req != lsnr->req)
245 			continue;
246 
247 		if (lsnr->msgh(msg, lsnr->arg))
248 			return;
249 	}
250 
251 	if (msg->req) {
252 		(void)re_fprintf(stderr, "unhandeled request from %J: %r %r\n",
253 				 &msg->src, &msg->met, &msg->ruri);
254 
255 		if (!pl_strcmp(&msg->met, "CANCEL"))
256 			(void)sip_reply(sip, msg,
257 					481, "Transaction Does Not Exist");
258 		else
259 			(void)sip_reply(sip, msg,
260 					501, "Not Implemented");
261 	}
262 	else {
263 		(void)re_fprintf(stderr, "unhandeled response from %J:"
264 				 " %u %r (%r)\n", &msg->src,
265 				 msg->scode, &msg->reason, &msg->cseq.met);
266 	}
267 }
268 
269 
udp_recv_handler(const struct sa * src,struct mbuf * mb,void * arg)270 static void udp_recv_handler(const struct sa *src, struct mbuf *mb, void *arg)
271 {
272 	struct sip_transport *transp = arg;
273 	struct stun_unknown_attr ua;
274 	struct stun_msg *stun_msg;
275 	struct sip_msg *msg;
276 	int err;
277 
278 	if (mb->end <= 4)
279 		return;
280 
281 	if (!stun_msg_decode(&stun_msg, mb, &ua)) {
282 
283 		if (stun_msg_method(stun_msg) == STUN_METHOD_BINDING) {
284 
285 			switch (stun_msg_class(stun_msg)) {
286 
287 			case STUN_CLASS_REQUEST:
288 				(void)stun_reply(IPPROTO_UDP, transp->sock,
289 						 src, 0, stun_msg,
290 						 NULL, 0, false, 2,
291 						 STUN_ATTR_XOR_MAPPED_ADDR,
292 						 src,
293 						 STUN_ATTR_SOFTWARE,
294 						 transp->sip->software);
295 				break;
296 
297 			default:
298 				(void)stun_ctrans_recv(transp->sip->stun,
299 						       stun_msg, &ua);
300 				break;
301 			}
302 		}
303 
304 		mem_deref(stun_msg);
305 
306 		return;
307 	}
308 
309 	err = sip_msg_decode(&msg, mb);
310 	if (err) {
311 		(void)re_fprintf(stderr, "sip: msg decode err: %m\n", err);
312 		return;
313 	}
314 
315 	msg->sock = mem_ref(transp->sock);
316 	msg->src = *src;
317 	msg->dst = transp->laddr;
318 	msg->tp = SIP_TRANSP_UDP;
319 
320 	sip_recv(transp->sip, msg);
321 
322 	mem_deref(msg);
323 }
324 
325 
tcp_recv_handler(struct mbuf * mb,void * arg)326 static void tcp_recv_handler(struct mbuf *mb, void *arg)
327 {
328 	struct sip_conn *conn = arg;
329 	size_t pos;
330 	int err = 0;
331 
332 	if (conn->mb) {
333 		pos = conn->mb->pos;
334 
335 		conn->mb->pos = conn->mb->end;
336 
337 		err = mbuf_write_mem(conn->mb, mbuf_buf(mb),mbuf_get_left(mb));
338 		if (err)
339 			goto out;
340 
341 		conn->mb->pos = pos;
342 
343 		if (mbuf_get_left(conn->mb) > TCP_BUFSIZE_MAX) {
344 			err = EOVERFLOW;
345 			goto out;
346 		}
347 	}
348 	else {
349 		conn->mb = mem_ref(mb);
350 	}
351 
352 	for (;;) {
353 		struct sip_msg *msg;
354 		uint32_t clen;
355 		size_t end;
356 
357 		if (mbuf_get_left(conn->mb) < 2)
358 			break;
359 
360 		if (!memcmp(mbuf_buf(conn->mb), "\r\n", 2)) {
361 
362 			tmr_start(&conn->tmr, TCP_IDLE_TIMEOUT * 1000,
363 				  conn_tmr_handler, conn);
364 
365 			conn->mb->pos += 2;
366 
367 			if (mbuf_get_left(conn->mb) >= 2 &&
368 			    !memcmp(mbuf_buf(conn->mb), "\r\n", 2)) {
369 
370 				struct mbuf mbr;
371 
372 				conn->mb->pos += 2;
373 
374 				mbr.buf  = crlfcrlf;
375 				mbr.size = sizeof(crlfcrlf);
376 				mbr.pos  = 0;
377 				mbr.end  = 2;
378 
379 				err = tcp_send(conn->tc, &mbr);
380 				if (err)
381 					break;
382 			}
383 
384 			if (mbuf_get_left(conn->mb))
385 				continue;
386 
387 			conn->mb = mem_deref(conn->mb);
388 			break;
389 		}
390 
391 		pos = conn->mb->pos;
392 
393 		err = sip_msg_decode(&msg, conn->mb);
394 		if (err) {
395 			if (err == ENODATA)
396 				err = 0;
397 			break;
398 		}
399 
400 		if (!msg->clen.p) {
401 			mem_deref(msg);
402 			err = EBADMSG;
403 			break;
404 		}
405 
406 		clen = pl_u32(&msg->clen);
407 
408 		if (mbuf_get_left(conn->mb) < clen) {
409 			conn->mb->pos = pos;
410 			mem_deref(msg);
411 			break;
412 		}
413 
414 		tmr_start(&conn->tmr, TCP_IDLE_TIMEOUT * 1000,
415 			  conn_tmr_handler, conn);
416 
417 		end = conn->mb->end;
418 
419 		msg->mb->end = msg->mb->pos + clen;
420 		msg->sock = mem_ref(conn);
421 		msg->src = conn->paddr;
422 		msg->dst = conn->laddr;
423 		msg->tp = conn->sc ? SIP_TRANSP_TLS : SIP_TRANSP_TCP;
424 
425 		sip_recv(conn->sip, msg);
426 		mem_deref(msg);
427 
428 		if (end <= conn->mb->end) {
429 			conn->mb = mem_deref(conn->mb);
430 			break;
431 		}
432 
433 		mb = mbuf_alloc(end - conn->mb->end);
434 		if (!mb) {
435 			err = ENOMEM;
436 			goto out;
437 		}
438 
439 		(void)mbuf_write_mem(mb, &conn->mb->buf[conn->mb->end],
440 				     end - conn->mb->end);
441 
442 		mb->pos = 0;
443 
444 		mem_deref(conn->mb);
445 		conn->mb = mb;
446 	}
447 
448  out:
449 	if (err) {
450 		conn_close(conn, err);
451 		mem_deref(conn);
452 	}
453 }
454 
455 
tcp_estab_handler(void * arg)456 static void tcp_estab_handler(void *arg)
457 {
458 	struct sip_conn *conn = arg;
459 	struct le *le;
460 	int err;
461 
462 	conn->established = true;
463 
464 	le = list_head(&conn->ql);
465 
466 	while (le) {
467 
468 		struct sip_connqent *qent = le->data;
469 		le = le->next;
470 
471 		if (qent->qentp) {
472 			*qent->qentp = NULL;
473 			qent->qentp = NULL;
474 		}
475 
476 		err = tcp_send(conn->tc, qent->mb);
477 		if (err)
478 			qent->transph(err, qent->arg);
479 
480 		list_unlink(&qent->le);
481 		mem_deref(qent);
482 	}
483 }
484 
485 
tcp_close_handler(int err,void * arg)486 static void tcp_close_handler(int err, void *arg)
487 {
488 	struct sip_conn *conn = arg;
489 
490 	conn_close(conn, err ? err : ECONNRESET);
491 	mem_deref(conn);
492 }
493 
494 
tcp_connect_handler(const struct sa * paddr,void * arg)495 static void tcp_connect_handler(const struct sa *paddr, void *arg)
496 {
497 	struct sip_transport *transp = arg;
498 	struct sip_conn *conn;
499 	int err;
500 
501 	conn = mem_zalloc(sizeof(*conn), conn_destructor);
502 	if (!conn) {
503 		err = ENOMEM;
504 		goto out;
505 	}
506 
507 	hash_append(transp->sip->ht_conn, sa_hash(paddr, SA_ALL),
508 		    &conn->he, conn);
509 
510 	conn->paddr = *paddr;
511 	conn->sip   = transp->sip;
512 
513 	err = tcp_accept(&conn->tc, transp->sock, tcp_estab_handler,
514 			 tcp_recv_handler, tcp_close_handler, conn);
515 	if (err)
516 		goto out;
517 
518 	err = tcp_conn_local_get(conn->tc, &conn->laddr);
519 	if (err)
520 		goto out;
521 
522 #ifdef USE_TLS
523 	if (transp->tls) {
524 		err = tls_start_tcp(&conn->sc, transp->tls, conn->tc, 0);
525 		if (err)
526 			goto out;
527 	}
528 #endif
529 
530 	tmr_start(&conn->tmr, TCP_ACCEPT_TIMEOUT * 1000,
531 		  conn_tmr_handler, conn);
532 
533  out:
534 	if (err) {
535 		tcp_reject(transp->sock);
536 		mem_deref(conn);
537 	}
538 }
539 
540 
conn_send(struct sip_connqent ** qentp,struct sip * sip,bool secure,const struct sa * dst,struct mbuf * mb,sip_transp_h * transph,void * arg)541 static int conn_send(struct sip_connqent **qentp, struct sip *sip, bool secure,
542 		     const struct sa *dst, struct mbuf *mb,
543 		     sip_transp_h *transph, void *arg)
544 {
545 	struct sip_conn *conn, *new_conn = NULL;
546 	struct sip_connqent *qent;
547 	int err = 0;
548 
549 	conn = conn_find(sip, dst, secure);
550 	if (conn) {
551 		if (!conn->established)
552 			goto enqueue;
553 
554 		return tcp_send(conn->tc, mb);
555 	}
556 
557 	new_conn = conn = mem_zalloc(sizeof(*conn), conn_destructor);
558 	if (!conn)
559 		return ENOMEM;
560 
561 	hash_append(sip->ht_conn, sa_hash(dst, SA_ALL), &conn->he, conn);
562 	conn->paddr = *dst;
563 	conn->sip   = sip;
564 
565 	err = tcp_connect(&conn->tc, dst, tcp_estab_handler, tcp_recv_handler,
566 			  tcp_close_handler, conn);
567 	if (err)
568 		goto out;
569 
570 	err = tcp_conn_local_get(conn->tc, &conn->laddr);
571 	if (err)
572 		goto out;
573 
574 #ifdef USE_TLS
575 	if (secure) {
576 		const struct sip_transport *transp;
577 
578 		transp = transp_find(sip, SIP_TRANSP_TLS, sa_af(dst), dst);
579 		if (!transp || !transp->tls) {
580 			err = EPROTONOSUPPORT;
581 			goto out;
582 		}
583 
584 		err = tls_start_tcp(&conn->sc, transp->tls, conn->tc, 0);
585 		if (err)
586 			goto out;
587 	}
588 #endif
589 
590 	tmr_start(&conn->tmr, TCP_IDLE_TIMEOUT * 1000, conn_tmr_handler, conn);
591 
592  enqueue:
593 	qent = mem_zalloc(sizeof(*qent), qent_destructor);
594 	if (!qent) {
595 		err = ENOMEM;
596 		goto out;
597 
598 	}
599 
600 	list_append(&conn->ql, &qent->le, qent);
601 	qent->mb = mem_ref(mb);
602 	qent->transph = transph ? transph : internal_transport_handler;
603 	qent->arg = arg;
604 
605 	if (qentp) {
606 		qent->qentp = qentp;
607 		*qentp = qent;
608 	}
609 
610  out:
611 	if (err)
612 		mem_deref(new_conn);
613 
614 	return err;
615 }
616 
617 
sip_transp_init(struct sip * sip,uint32_t sz)618 int sip_transp_init(struct sip *sip, uint32_t sz)
619 {
620 	return hash_alloc(&sip->ht_conn, sz);
621 }
622 
623 
624 /**
625  * Add a SIP transport
626  *
627  * @param sip   SIP stack instance
628  * @param tp    SIP Transport
629  * @param laddr Local network address
630  * @param ...   Optional transport parameters such as TLS context
631  *
632  * @return 0 if success, otherwise errorcode
633  */
sip_transp_add(struct sip * sip,enum sip_transp tp,const struct sa * laddr,...)634 int sip_transp_add(struct sip *sip, enum sip_transp tp,
635 		   const struct sa *laddr, ...)
636 {
637 	struct sip_transport *transp;
638 	struct tls *tls;
639 	va_list ap;
640 	int err;
641 
642 	if (!sip || !laddr || !sa_isset(laddr, SA_ADDR))
643 		return EINVAL;
644 
645 	transp = mem_zalloc(sizeof(*transp), transp_destructor);
646 	if (!transp)
647 		return ENOMEM;
648 
649 	list_append(&sip->transpl, &transp->le, transp);
650 	transp->sip = sip;
651 	transp->tp  = tp;
652 
653 	va_start(ap, laddr);
654 
655 	switch (tp) {
656 
657 	case SIP_TRANSP_UDP:
658 		err = udp_listen((struct udp_sock **)&transp->sock, laddr,
659 				 udp_recv_handler, transp);
660 		if (err)
661 			break;
662 
663 		err = udp_local_get(transp->sock, &transp->laddr);
664 		break;
665 
666 	case SIP_TRANSP_TLS:
667 		tls = va_arg(ap, struct tls *);
668 		if (!tls) {
669 			err = EINVAL;
670 			break;
671 		}
672 
673 		transp->tls = mem_ref(tls);
674 
675 		/*@fallthrough@*/
676 
677 	case SIP_TRANSP_TCP:
678 		err = tcp_listen((struct tcp_sock **)&transp->sock, laddr,
679 				 tcp_connect_handler, transp);
680 		if (err)
681 			break;
682 
683 		err = tcp_sock_local_get(transp->sock, &transp->laddr);
684 		break;
685 
686 	default:
687 		err = EPROTONOSUPPORT;
688 		break;
689 	}
690 
691 	va_end(ap);
692 
693 	if (err)
694 		mem_deref(transp);
695 
696 	return err;
697 }
698 
699 
700 /**
701  * Flush all transports of a SIP stack instance
702  *
703  * @param sip SIP stack instance
704  */
sip_transp_flush(struct sip * sip)705 void sip_transp_flush(struct sip *sip)
706 {
707 	if (!sip)
708 		return;
709 
710 	hash_flush(sip->ht_conn);
711 	list_flush(&sip->transpl);
712 }
713 
714 
sip_transp_send(struct sip_connqent ** qentp,struct sip * sip,void * sock,enum sip_transp tp,const struct sa * dst,struct mbuf * mb,sip_transp_h * transph,void * arg)715 int sip_transp_send(struct sip_connqent **qentp, struct sip *sip, void *sock,
716 		    enum sip_transp tp, const struct sa *dst, struct mbuf *mb,
717 		    sip_transp_h *transph, void *arg)
718 {
719 	const struct sip_transport *transp;
720 	struct sip_conn *conn;
721 	bool secure = false;
722 	int err;
723 
724 	if (!sip || !dst || !mb)
725 		return EINVAL;
726 
727 	switch (tp) {
728 
729 	case SIP_TRANSP_UDP:
730 		if (!sock) {
731 			transp = transp_find(sip, tp, sa_af(dst), dst);
732 			if (!transp)
733 				return EPROTONOSUPPORT;
734 
735 			sock = transp->sock;
736 		}
737 
738 		err = udp_send(sock, dst, mb);
739 		break;
740 
741 	case SIP_TRANSP_TLS:
742 		secure = true;
743 		/*@fallthrough@*/
744 
745 	case SIP_TRANSP_TCP:
746 		conn = sock;
747 
748 		if (conn && conn->tc)
749 			err = tcp_send(conn->tc, mb);
750 		else
751 			err = conn_send(qentp, sip, secure, dst, mb,
752 					transph, arg);
753 		break;
754 
755 	default:
756 		err = EPROTONOSUPPORT;
757 		break;
758 	}
759 
760 	return err;
761 }
762 
763 
sip_transp_laddr(struct sip * sip,struct sa * laddr,enum sip_transp tp,const struct sa * dst)764 int sip_transp_laddr(struct sip *sip, struct sa *laddr, enum sip_transp tp,
765 		      const struct sa *dst)
766 {
767 	const struct sip_transport *transp;
768 
769 	if (!sip || !laddr)
770 		return EINVAL;
771 
772 	transp = transp_find(sip, tp, sa_af(dst), dst);
773 	if (!transp)
774 		return EPROTONOSUPPORT;
775 
776 	*laddr = transp->laddr;
777 
778 	return 0;
779 }
780 
781 
sip_transp_supported(struct sip * sip,enum sip_transp tp,int af)782 bool sip_transp_supported(struct sip *sip, enum sip_transp tp, int af)
783 {
784 	if (!sip)
785 		return false;
786 
787 	return transp_find(sip, tp, af, NULL) != NULL;
788 }
789 
790 
791 /**
792  * Check if network address is part of SIP transports
793  *
794  * @param sip   SIP stack instance
795  * @param tp    SIP transport
796  * @param laddr Local network address to check
797  *
798  * @return True if part of SIP transports, otherwise false
799  */
sip_transp_isladdr(const struct sip * sip,enum sip_transp tp,const struct sa * laddr)800 bool sip_transp_isladdr(const struct sip *sip, enum sip_transp tp,
801 			const struct sa *laddr)
802 {
803 	struct le *le;
804 
805 	if (!sip || !laddr)
806 		return false;
807 
808 	for (le=sip->transpl.head; le; le=le->next) {
809 
810 		const struct sip_transport *transp = le->data;
811 
812 		if (tp != SIP_TRANSP_NONE && transp->tp != tp)
813 			continue;
814 
815 		if (!sa_cmp(&transp->laddr, laddr, SA_ALL))
816 			continue;
817 
818 		return true;
819 	}
820 
821 	return false;
822 }
823 
824 
825 /**
826  * Get the name of a given SIP Transport
827  *
828  * @param tp SIP Transport
829  *
830  * @return Name of the corresponding SIP Transport
831  */
sip_transp_name(enum sip_transp tp)832 const char *sip_transp_name(enum sip_transp tp)
833 {
834 	switch (tp) {
835 
836 	case SIP_TRANSP_UDP: return "UDP";
837 	case SIP_TRANSP_TCP: return "TCP";
838 	case SIP_TRANSP_TLS: return "TLS";
839 	default:             return "???";
840 	}
841 }
842 
843 
sip_transp_srvid(enum sip_transp tp)844 const char *sip_transp_srvid(enum sip_transp tp)
845 {
846 	switch (tp) {
847 
848 	case SIP_TRANSP_UDP: return "_sip._udp";
849 	case SIP_TRANSP_TCP: return "_sip._tcp";
850 	case SIP_TRANSP_TLS: return "_sips._tcp";
851 	default:             return "???";
852 	}
853 }
854 
855 
856 /**
857  * Get the transport parameters for a given SIP Transport
858  *
859  * @param tp SIP Transport
860  *
861  * @return Transport parameters of the corresponding SIP Transport
862  */
sip_transp_param(enum sip_transp tp)863 const char *sip_transp_param(enum sip_transp tp)
864 {
865 	switch (tp) {
866 
867 	case SIP_TRANSP_UDP: return "";
868 	case SIP_TRANSP_TCP: return ";transport=tcp";
869 	case SIP_TRANSP_TLS: return ";transport=tls";
870 	default:             return "";
871 	}
872 }
873 
874 
sip_transp_reliable(enum sip_transp tp)875 bool sip_transp_reliable(enum sip_transp tp)
876 {
877 	switch (tp) {
878 
879 	case SIP_TRANSP_UDP: return false;
880 	case SIP_TRANSP_TCP: return true;
881 	case SIP_TRANSP_TLS: return true;
882 	default:             return false;
883 	}
884 }
885 
886 
887 /**
888  * Get the default port number for a given SIP Transport
889  *
890  * @param tp   SIP Transport
891  * @param port Port number
892  *
893  * @return Corresponding port number
894  */
sip_transp_port(enum sip_transp tp,uint16_t port)895 uint16_t sip_transp_port(enum sip_transp tp, uint16_t port)
896 {
897 	if (port)
898 		return port;
899 
900 	switch (tp) {
901 
902 	case SIP_TRANSP_UDP: return SIP_PORT;
903 	case SIP_TRANSP_TCP: return SIP_PORT;
904 	case SIP_TRANSP_TLS: return SIP_PORT_TLS;
905 	default:             return 0;
906 	}
907 }
908 
909 
debug_handler(struct le * le,void * arg)910 static bool debug_handler(struct le *le, void *arg)
911 {
912 	const struct sip_transport *transp = le->data;
913 	struct re_printf *pf = arg;
914 
915 	(void)re_hprintf(pf, "  %J (%s)\n",
916 			 &transp->laddr,
917 			 sip_transp_name(transp->tp));
918 
919 	return false;
920 }
921 
922 
sip_transp_debug(struct re_printf * pf,const struct sip * sip)923 int sip_transp_debug(struct re_printf *pf, const struct sip *sip)
924 {
925 	int err;
926 
927 	err = re_hprintf(pf, "transports:\n");
928 	list_apply(&sip->transpl, true, debug_handler, pf);
929 
930 	return err;
931 }
932 
933 
934 /**
935  * Get the TCP Connection from a SIP Message
936  *
937  * @param msg SIP Message
938  *
939  * @return TCP Connection if reliable transport, otherwise NULL
940  */
sip_msg_tcpconn(const struct sip_msg * msg)941 struct tcp_conn *sip_msg_tcpconn(const struct sip_msg *msg)
942 {
943 	if (!msg || !msg->sock)
944 		return NULL;
945 
946 	switch (msg->tp) {
947 
948 	case SIP_TRANSP_TCP:
949 	case SIP_TRANSP_TLS:
950 		return ((struct sip_conn *)msg->sock)->tc;
951 
952 	default:
953 		return NULL;
954 	}
955 }
956 
957 
sip_keepalive_tcp(struct sip_keepalive * ka,struct sip_conn * conn,uint32_t interval)958 int  sip_keepalive_tcp(struct sip_keepalive *ka, struct sip_conn *conn,
959 		       uint32_t interval)
960 {
961 	if (!ka || !conn)
962 		return EINVAL;
963 
964 	if (!conn->tc || !conn->established)
965 		return ENOTCONN;
966 
967 	list_append(&conn->kal, &ka->le, ka);
968 
969 	if (!tmr_isrunning(&conn->tmr_ka)) {
970 
971 		interval = MAX(interval ? interval : TCP_KEEPALIVE_INTVAL,
972 			       TCP_KEEPALIVE_TIMEOUT * 2);
973 
974 		conn->ka_interval = interval;
975 
976 		tmr_start(&conn->tmr_ka, sip_keepalive_wait(conn->ka_interval),
977 			  conn_keepalive_handler, conn);
978 	}
979 
980 	return 0;
981 }
982