From d5c94f00b54375aef71b1b1fef8bd153e68ec4b5 Mon Sep 17 00:00:00 2001 From: Christian Spielberger Date: Tue, 20 Apr 2021 16:15:26 +0200 Subject: [PATCH 1/3] udp: add setter for ToS (RFC-791) --- include/re_udp.h | 1 + src/udp/udp.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/include/re_udp.h b/include/re_udp.h index f796138bd..4f12e5546 100644 --- a/include/re_udp.h +++ b/include/re_udp.h @@ -40,6 +40,7 @@ int udp_sock_fd(const struct udp_sock *us, int af); int udp_multicast_join(struct udp_sock *us, const struct sa *group); int udp_multicast_leave(struct udp_sock *us, const struct sa *group); +int udp_settos(struct udp_sock *us, uint8_t tos); /* Helper API */ diff --git a/src/udp/udp.c b/src/udp/udp.c index 4f29ce9a3..45a6326b2 100644 --- a/src/udp/udp.c +++ b/src/udp/udp.c @@ -639,6 +639,19 @@ int udp_sockbuf_set(struct udp_sock *us, int size) } +int udp_settos(struct udp_sock *us, uint8_t tos) +{ + int err = 0; + int v = tos; + + if (!us) + return EINVAL; + + err = udp_setsockopt(us, IPPROTO_IP, IP_TOS, &v, sizeof(v)); + return err; +} + + /** * Set the maximum receive chunk size on a UDP Socket * From 12cf74758300ad0ad14bf0d49e7501bf10a3114b Mon Sep 17 00:00:00 2001 From: Christian Spielberger Date: Tue, 20 Apr 2021 16:15:44 +0200 Subject: [PATCH 2/3] tcp: add setter for ToS (RFC-791) --- include/re_tcp.h | 2 ++ src/tcp/tcp.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/include/re_tcp.h b/include/re_tcp.h index 7b7b378d7..e40e071dd 100644 --- a/include/re_tcp.h +++ b/include/re_tcp.h @@ -57,6 +57,8 @@ int tcp_accept(struct tcp_conn **tcp, struct tcp_sock *ts, tcp_estab_h *eh, tcp_recv_h *rh, tcp_close_h *ch, void *arg); void tcp_reject(struct tcp_sock *ts); int tcp_sock_local_get(const struct tcp_sock *ts, struct sa *local); +int tcp_settos(struct tcp_sock *ts, uint32_t tos); +int tcp_conn_settos(struct tcp_conn *tc, uint32_t tos); /* TCP Connection */ diff --git a/src/tcp/tcp.c b/src/tcp/tcp.c index 4b6b969f2..ec21c557a 100644 --- a/src/tcp/tcp.c +++ b/src/tcp/tcp.c @@ -61,6 +61,7 @@ struct tcp_sock { int fdc; /**< Cached connection file descriptor */ tcp_conn_h *connh; /**< TCP Connect handler */ void *arg; /**< Handler argument */ + uint8_t tos; /**< Type-of-service field */ }; @@ -79,6 +80,7 @@ struct tcp_conn { size_t txqsz_max; bool active; /**< We are connecting flag */ bool connected; /**< Connection is connected flag */ + uint8_t tos; /**< Type-of-service field */ }; @@ -488,6 +490,30 @@ static void tcp_sockopt_set(int fd) } +static int tcp_sock_setopt(struct tcp_sock *ts, int level, int optname, + const void *optval, uint32_t optlen) +{ + int err = 0; + + if (!ts) + return EINVAL; + + if (-1 != ts->fdc) { + if (0 != setsockopt(ts->fdc, level, optname, + BUF_CAST optval, optlen)) + err |= errno; + } + + if (-1 != ts->fd) { + if (0 != setsockopt(ts->fd, level, optname, + BUF_CAST optval, optlen)) + err |= errno; + } + + return err; +} + + /** * Handler for incoming TCP connections. * @@ -1413,3 +1439,37 @@ int tcp_register_helper(struct tcp_helper **thp, struct tcp_conn *tc, return 0; } + + +int tcp_settos(struct tcp_sock *ts, uint32_t tos) +{ + int err = 0; + int v = tos; + + if (!ts) + return EINVAL; + + ts->tos = tos; + err = tcp_sock_setopt(ts, IPPROTO_IP, IP_TOS, &v, sizeof(v)); + + return err; +} + + +int tcp_conn_settos(struct tcp_conn *tc, uint32_t tos) +{ + int err = 0; + int v = tos; + + if (!tc) + return EINVAL; + + tc->tos = tos; + if (-1 != tc->fdc) { + if (0 != setsockopt(tc->fdc, IPPROTO_IP, IP_TOS, + BUF_CAST &v, sizeof(v))) + err = errno; + } + + return err; +} From ca83bdc268516e5927455630bd6d661d80f8545b Mon Sep 17 00:00:00 2001 From: Christian Spielberger Date: Tue, 20 Apr 2021 16:15:05 +0200 Subject: [PATCH 3/3] sip: add setter for ToS (RFC-791) --- include/re_sip.h | 1 + src/sip/sip.h | 1 + src/sip/transp.c | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/include/re_sip.h b/include/re_sip.h index 70c0d7146..b087a9f27 100644 --- a/include/re_sip.h +++ b/include/re_sip.h @@ -281,6 +281,7 @@ enum sip_transp sip_transp_decode(const struct pl *pl); uint16_t sip_transp_port(enum sip_transp tp, uint16_t port); int sip_transp_laddr(struct sip *sip, struct sa *laddr, enum sip_transp tp, const struct sa *dst); +int sip_settos(struct sip *sip, uint8_t tos); /* request */ diff --git a/src/sip/sip.h b/src/sip/sip.h index 79ae5d1e1..f8635fa83 100644 --- a/src/sip/sip.h +++ b/src/sip/sip.h @@ -22,6 +22,7 @@ struct sip { sip_trace_h *traceh; void *arg; bool closing; + uint8_t tos; }; diff --git a/src/sip/transp.c b/src/sip/transp.c index 8821165f2..dff54a78f 100644 --- a/src/sip/transp.c +++ b/src/sip/transp.c @@ -49,6 +49,7 @@ struct sip_transport { struct tls *tls; void *sock; enum sip_transp tp; + uint8_t tos; struct http_cli *http_cli; struct http_sock *http_sock; @@ -619,6 +620,7 @@ static void tcp_connect_handler(const struct sa *paddr, void *arg) if (err) goto out; + (void)tcp_conn_settos(conn->tc, transp->tos); #ifdef USE_TLS if (transp->tls) { err = tls_start_tcp(&conn->sc, transp->tls, conn->tc, 0); @@ -717,6 +719,7 @@ static int conn_send(struct sip_connqent **qentp, struct sip *sip, bool secure, if (err) goto out; + (void)tcp_conn_settos(conn->tc, sip->tos); #ifdef USE_TLS if (secure) { const struct sip_transport *transp; @@ -1550,6 +1553,42 @@ uint16_t sip_transp_port(enum sip_transp tp, uint16_t port) } +int sip_settos(struct sip *sip, uint8_t tos) +{ + struct le *le; + int err = 0; + + if (!sip) + return EINVAL; + + sip->tos = tos; + + for (le = sip->transpl.head; le; le = le->next) { + + struct sip_transport *transp = le->data; + transp->tos = tos; + switch (transp->tp) { + case SIP_TRANSP_UDP: + err = udp_settos(transp->sock, tos); + break; + + case SIP_TRANSP_TCP: + case SIP_TRANSP_TLS: + err = tcp_settos(transp->sock, tos); + break; + break; + default: + break; + } + + if (err) + break; + } + + return err; +} + + static bool debug_handler(struct le *le, void *arg) { const struct sip_transport *transp = le->data;