Skip to content

Commit

Permalink
transp.c: add sip_transp_add_sock
Browse files Browse the repository at this point in the history
to add SIP transport protocol without opening a listening socket and
adapt sip_transp_send accordingly to make UDP work.
  • Loading branch information
maximilianfridrich committed Jul 23, 2024
1 parent b8b8872 commit ecef413
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 22 deletions.
2 changes: 2 additions & 0 deletions include/re_sip.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,8 @@ void sip_set_trace_handler(struct sip *sip, sip_trace_h *traceh);
/* transport */
int sip_transp_add(struct sip *sip, enum sip_transp tp,
const struct sa *laddr, ...);
int sip_transp_add_sock(struct sip *sip, enum sip_transp tp,
bool listen, const struct sa *laddr, ...);
int sip_transp_add_websock(struct sip *sip, enum sip_transp tp,
const struct sa *laddr,
bool server, const char *cert, struct tls *tls);
Expand Down
136 changes: 114 additions & 22 deletions src/sip/transp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1195,17 +1195,17 @@ static void http_req_handler(struct http_conn *hc, const struct http_msg *msg,
*
* @param sip SIP stack instance
* @param tp SIP Transport
* @param listen True to open listening socket
* @param laddr Local network address
* @param ... Optional transport parameters such as TLS context
* @param ap Optional transport parameters such as TLS context
*
* @return 0 if success, otherwise errorcode
*/
int sip_transp_add(struct sip *sip, enum sip_transp tp,
const struct sa *laddr, ...)
static int add_transp(struct sip *sip, enum sip_transp tp,
bool listen, const struct sa *laddr, va_list ap)
{
struct sip_transport *transp;
struct tls *tls;
va_list ap;
int err = 0;

if (!sip || !laddr || !sa_isset(laddr, SA_ADDR))
Expand All @@ -1221,13 +1221,25 @@ int sip_transp_add(struct sip *sip, enum sip_transp tp,
mem_deref(transp);
return err;
}

tls = va_arg(ap, struct tls *);
if (!tls) {
err = EINVAL;
goto out;
}

transp->tls = mem_ref(tls);
}

list_append(&sip->transpl, &transp->le, transp);
transp->sip = sip;
transp->tp = tp;

va_start(ap, laddr);
if (!listen) {
transp->laddr = *laddr;
sa_set_port(&transp->laddr, 0);
return err;
}

switch (tp) {

Expand All @@ -1241,16 +1253,6 @@ int sip_transp_add(struct sip *sip, enum sip_transp tp,
break;

case SIP_TRANSP_TLS:
tls = va_arg(ap, struct tls *);
if (!tls) {
err = EINVAL;
break;
}

transp->tls = mem_ref(tls);

/*@fallthrough@*/

case SIP_TRANSP_TCP:
err = tcp_listen((struct tcp_sock **)&transp->sock, laddr,
tcp_connect_handler, transp);
Expand All @@ -1265,15 +1267,63 @@ int sip_transp_add(struct sip *sip, enum sip_transp tp,
break;
}

va_end(ap);

out:
if (err)
mem_deref(transp);

return err;
}


/**
* Add a SIP transport
*
* @param sip SIP stack instance
* @param tp SIP Transport
* @param laddr Local network address
* @param ... Optional transport parameters such as TLS context
*
* @return 0 if success, otherwise errorcode
*/
int sip_transp_add(struct sip *sip, enum sip_transp tp,
const struct sa *laddr, ...)
{
int err;
va_list ap;

va_start(ap, laddr);
err = add_transp(sip, tp, true, laddr, ap);
va_end(ap);

return err;
}


/**
* Add a SIP transport and open listening socket if requested
*
* @param sip SIP stack instance
* @param tp SIP Transport
* @param listen True to open listening socket
* @param laddr Local network address
* @param ... Optional transport parameters such as TLS context
*
* @return 0 if success, otherwise errorcode
*/
int sip_transp_add_sock(struct sip *sip, enum sip_transp tp,
bool listen, const struct sa *laddr, ...)
{
int err;
va_list ap;

va_start(ap, laddr);
err = add_transp(sip, tp, listen, laddr, ap);
va_end(ap);

return err;
}


/**
* Add a SIP websocket transport
*
Expand Down Expand Up @@ -1435,7 +1485,7 @@ int sip_transp_send(struct sip_connqent **qentp, struct sip *sip, void *sock,
struct mbuf *mb, sip_conn_h *connh, sip_transp_h *transph,
void *arg)
{
const struct sip_transport *transp;
struct sip_transport *transp;
struct sip_conn *conn;
bool secure = false;
struct sa dsttmp;
Expand All @@ -1459,17 +1509,35 @@ int sip_transp_send(struct sip_connqent **qentp, struct sip *sip, void *sock,
if (err)
return err;

if (connh)
connh(&laddr, dst, mb, arg);

if (!sock) {
transp = transp_find(sip, tp, sa_af(&dsttmp), &dsttmp);
transp = (struct sip_transport *)
transp_find(sip, tp, sa_af(&dsttmp), &dsttmp);
if (!transp)
return EPROTONOSUPPORT;

if (!transp->sock) {
err = udp_listen((struct udp_sock **)
&transp->sock, &transp->laddr,
udp_recv_handler, transp);
if (err)
break;

err = udp_local_get(transp->sock,
&transp->laddr);
if (err) {
transp->sock = mem_deref(transp->sock);
break;
}

laddr = transp->laddr;
}

sock = transp->sock;
}

if (connh)
connh(&laddr, dst, mb, arg);

trace_send(sip, tp, sock, &dsttmp, mb);

err = udp_send(sock, &dsttmp, mb);
Expand Down Expand Up @@ -1768,11 +1836,32 @@ int sip_settos(struct sip *sip, uint8_t tos)
}


static void sip_transports_print(struct re_printf *pf, const struct sip* sip)
{
uint8_t i;
struct le *le;
uint32_t mask = 0;

for (le = sip->transpl.head; le; le = le->next) {
const struct sip_transport *transp = le->data;
mask |= (1 << transp->tp);
}

for (i = 0; i < SIP_TRANSPC; ++i) {
if (mask==0 || (0 != (mask & (1u << i))))
(void)re_hprintf(pf, " %s\n", sip_transp_name(i));
}
}


static bool debug_handler(struct le *le, void *arg)
{
const struct sip_transport *transp = le->data;
struct re_printf *pf = arg;

if (sa_port(&transp->laddr) == 0)
return false;

(void)re_hprintf(pf, " %J (%s)\n",
&transp->laddr,
sip_transp_name(transp->tp));
Expand Down Expand Up @@ -1813,6 +1902,9 @@ int sip_transp_debug(struct re_printf *pf, const struct sip *sip)
int err;

err = re_hprintf(pf, "transports:\n");
sip_transports_print(pf, sip);

err |= re_hprintf(pf, "transport sockets:\n");
list_apply(&sip->transpl, true, debug_handler, pf);

err |= re_hprintf(pf, "connections:\n");
Expand Down

0 comments on commit ecef413

Please sign in to comment.