sip: SIP/TLS Server Name Indication
A change in the API of ctrans and transp is necessary. At the
calls between request and ctrans, the hostname information of the
next hop is lost. This information is crucial for SNI, which is set
in transp.
MODIFY
src/sip/ctrans.c
src/sip/ctrans.c
@@ -45,6 +45,7 @@ struct sip_ctrans {
struct sip_connqent *qent;
char *met;
char *branch;
+ char *host;
sip_resp_h *resph;
void *arg;
enum sip_transp tp;
@@ -112,6 +113,7 @@ static void destructor(void *arg)
tmr_cancel(&ct->tmre);
mem_deref(ct->met);
mem_deref(ct->branch);
+ mem_deref(ct->host);
mem_deref(ct->qent);
mem_deref(ct->req);
mem_deref(ct->mb);
@@ -205,7 +207,7 @@ static void retransmit_handler(void *arg)
tmr_start(&ct->tmre, timeout, retransmit_handler, ct);
err = sip_transp_send(&ct->qent, ct->sip, NULL, ct->tp, &ct->dst,
- ct->mb, transport_handler, ct);
+ ct->host, ct->mb, transport_handler, ct);
if (err) {
terminate(ct, err);
mem_deref(ct);
@@ -309,7 +311,7 @@ static bool response_handler(const struct sip_msg *msg, void *arg)
int sip_ctrans_request(struct sip_ctrans **ctp, struct sip *sip,
enum sip_transp tp, const struct sa *dst, char *met,
- char *branch, struct mbuf *mb,
+ char *branch, char *host, struct mbuf *mb,
sip_resp_h *resph, void *arg)
{
struct sip_ctrans *ct;
@@ -326,6 +328,7 @@ int sip_ctrans_request(struct sip_ctrans **ctp, struct sip *sip,
ct->invite = !strcmp(met, "INVITE");
ct->branch = mem_ref(branch);
+ ct->host = mem_ref(host);
ct->met = mem_ref(met);
ct->mb = mem_ref(mb);
ct->dst = *dst;
@@ -335,7 +338,7 @@ int sip_ctrans_request(struct sip_ctrans **ctp, struct sip *sip,
ct->resph = resph ? resph : dummy_handler;
ct->arg = arg;
- err = sip_transp_send(&ct->qent, sip, NULL, tp, dst, mb,
+ err = sip_transp_send(&ct->qent, sip, NULL, tp, dst, host, mb,
transport_handler, ct);
if (err)
goto out;
@@ -386,7 +389,7 @@ int sip_ctrans_cancel(struct sip_ctrans *ct)
goto out;
err = sip_ctrans_request(NULL, ct->sip, ct->tp, &ct->dst, cancel,
- ct->branch, mb, NULL, NULL);
+ ct->branch, NULL, mb, NULL, NULL);
if (err)
goto out;

MODIFY
src/sip/request.c
src/sip/request.c
@@ -194,7 +194,8 @@ static int request(struct sip_request *req, enum sip_transp tp,
err = sip_send(req->sip, NULL, tp, dst, mb);
else
err = sip_ctrans_request(&req->ct, req->sip, tp, dst, req->met,
- branch, mb, response_handler, req);
+ branch, req->host, mb,
+ response_handler, req);
if (err)
goto out;

MODIFY
src/sip/sip.c
src/sip/sip.c
@@ -207,7 +207,7 @@ void sip_close(struct sip *sip, bool force)
int sip_send(struct sip *sip, void *sock, enum sip_transp tp,
const struct sa *dst, struct mbuf *mb)
{
- return sip_transp_send(NULL, sip, sock, tp, dst, mb, NULL, NULL);
+ return sip_transp_send(NULL, sip, sock, tp, dst, NULL, mb, NULL, NULL);
}

MODIFY
src/sip/sip.h
src/sip/sip.h
@@ -51,8 +51,8 @@ struct sip_ctrans;
int sip_ctrans_request(struct sip_ctrans **ctp, struct sip *sip,
enum sip_transp tp, const struct sa *dst, char *met,
- char *branch, struct mbuf *mb, sip_resp_h *resph,
- void *arg);
+ char *branch, char *host, struct mbuf *mb,
+ sip_resp_h *resph, void *arg);
int sip_ctrans_cancel(struct sip_ctrans *ct);
int sip_ctrans_init(struct sip *sip, uint32_t sz);
int sip_ctrans_debug(struct re_printf *pf, const struct sip *sip);
@@ -70,8 +70,8 @@ typedef void(sip_transp_h)(int err, void *arg);
int sip_transp_init(struct sip *sip, uint32_t sz);
int 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);
+ enum sip_transp tp, const struct sa *dst, char *host,
+ struct mbuf *mb, sip_transp_h *transph, void *arg);
bool sip_transp_supported(struct sip *sip, enum sip_transp tp, int af);
const char *sip_transp_srvid(enum sip_transp tp);
bool sip_transp_reliable(enum sip_transp tp);

MODIFY
src/sip/transp.c
src/sip/transp.c
@@ -632,13 +632,17 @@ static void tcp_connect_handler(const struct sa *paddr, void *arg)
static int conn_send(struct sip_connqent **qentp, struct sip *sip, bool secure,
- const struct sa *dst, struct mbuf *mb,
+ const struct sa *dst, char *host, struct mbuf *mb,
sip_transp_h *transph, void *arg)
{
struct sip_conn *conn, *new_conn = NULL;
struct sip_connqent *qent;
int err = 0;
+#ifndef USE_TLS
+ (void) host;
+#endif
+
conn = conn_find(sip, dst, secure);
if (conn) {
if (!conn->established)
@@ -683,6 +687,10 @@ static int conn_send(struct sip_connqent **qentp, struct sip *sip, bool secure,
err = tls_start_tcp(&conn->sc, transp->tls, conn->tc, 0);
if (err)
goto out;
+
+ err = tls_set_verify_server(conn->sc, host);
+ if (err)
+ goto out;
}
#endif
@@ -1155,8 +1163,8 @@ void sip_transp_flush(struct sip *sip)
int 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)
+ enum sip_transp tp, const struct sa *dst, char *host,
+ struct mbuf *mb, sip_transp_h *transph, void *arg)
{
const struct sip_transport *transp;
struct sip_conn *conn;
@@ -1196,7 +1204,7 @@ int sip_transp_send(struct sip_connqent **qentp, struct sip *sip, void *sock,
err = tcp_send(conn->tc, mb);
}
else
- err = conn_send(qentp, sip, secure, dst, mb,
+ err = conn_send(qentp, sip, secure, dst, host, mb,
transph, arg);
break;

sip: SIP/TLS Server Name Indication (#67)

A change in the API of ctrans and transp is necessary. At the
calls between request and ctrans, the hostname information of the
next hop is lost. This information is crucial for SNI, which is set
in transp.