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