1 6b5c4000 2026-03-02 rsadowski /* $OpenBSD: relay_udp.c,v 1.52 2026/03/02 19:28:01 rsadowski Exp $ */
4 dc2f787f 2014-06-25 reyk * Copyright (c) 2007 - 2013 Reyk Floeter <reyk@openbsd.org>
6 7ba7514d 2007-09-10 reyk * Permission to use, copy, modify, and distribute this software for any
7 7ba7514d 2007-09-10 reyk * purpose with or without fee is hereby granted, provided that the above
8 7ba7514d 2007-09-10 reyk * copyright notice and this permission notice appear in all copies.
10 7ba7514d 2007-09-10 reyk * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 7ba7514d 2007-09-10 reyk * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 7ba7514d 2007-09-10 reyk * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 7ba7514d 2007-09-10 reyk * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 7ba7514d 2007-09-10 reyk * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 7ba7514d 2007-09-10 reyk * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 7ba7514d 2007-09-10 reyk * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 7ba7514d 2007-09-10 reyk #include <sys/types.h>
20 e1f9d231 2007-11-24 reyk #include <sys/queue.h>
21 7ba7514d 2007-09-10 reyk #include <sys/time.h>
22 7ba7514d 2007-09-10 reyk #include <sys/socket.h>
23 7ba7514d 2007-09-10 reyk #include <sys/tree.h>
25 7ba7514d 2007-09-10 reyk #include <netinet/in.h>
26 d93c36af 2015-01-22 reyk #include <arpa/inet.h>
28 2f6ec04d 2015-01-16 deraadt #include <signal.h>
29 7ba7514d 2007-09-10 reyk #include <errno.h>
30 7ba7514d 2007-09-10 reyk #include <fcntl.h>
31 7ba7514d 2007-09-10 reyk #include <stdlib.h>
32 7ba7514d 2007-09-10 reyk #include <string.h>
33 7ba7514d 2007-09-10 reyk #include <unistd.h>
34 7ba7514d 2007-09-10 reyk #include <stdio.h>
35 7ba7514d 2007-09-10 reyk #include <event.h>
36 d93c36af 2015-01-22 reyk #include <imsg.h>
38 6d0767ae 2007-12-07 reyk #include "relayd.h"
39 6b5c4000 2026-03-02 rsadowski #include "log.h"
41 7ba7514d 2007-09-10 reyk extern volatile sig_atomic_t relay_sessions;
42 7ba7514d 2007-09-10 reyk extern objid_t relay_conid;
44 69fde657 2014-07-09 reyk static struct relayd *env = NULL;
45 c0255773 2008-07-09 reyk struct shuffle relay_shuffle;
47 7ba7514d 2007-09-10 reyk int relay_udp_socket(struct sockaddr_storage *, in_port_t,
48 7ba7514d 2007-09-10 reyk struct protocol *);
49 7ba7514d 2007-09-10 reyk void relay_udp_timeout(int, short, void *);
51 61afd4d6 2009-08-07 reyk void relay_dns_log(struct rsession *, u_int8_t *, size_t);
52 61afd4d6 2009-08-07 reyk void *relay_dns_validate(struct rsession *,
53 4068a26b 2008-07-09 reyk struct relay *, struct sockaddr_storage *,
54 6e9314ae 2008-05-08 reyk u_int8_t *, size_t);
55 61afd4d6 2009-08-07 reyk int relay_dns_request(struct rsession *);
56 4068a26b 2008-07-09 reyk void relay_udp_response(int, short, void *);
57 61afd4d6 2009-08-07 reyk void relay_dns_result(struct rsession *, u_int8_t *, size_t);
58 61afd4d6 2009-08-07 reyk int relay_dns_cmp(struct rsession *, struct rsession *);
61 a2811280 2017-07-04 benno relay_udp_privinit(struct relay *rlay)
63 096ff28b 2014-12-12 reyk if (rlay->rl_conf.flags & F_TLS)
64 096ff28b 2014-12-12 reyk fatalx("tls over udp is not supported");
65 146643ba 2008-01-31 reyk rlay->rl_conf.flags |= F_UDP;
69 a2811280 2017-07-04 benno relay_udp_init(struct relayd *x_env, struct relay *rlay)
71 c0255773 2008-07-09 reyk struct protocol *proto = rlay->rl_proto;
73 a2811280 2017-07-04 benno if (env == NULL)
74 a2811280 2017-07-04 benno env = x_env;
76 7ba7514d 2007-09-10 reyk switch (proto->type) {
77 7ba7514d 2007-09-10 reyk case RELAY_PROTO_DNS:
78 7ba7514d 2007-09-10 reyk proto->validate = relay_dns_validate;
79 7ba7514d 2007-09-10 reyk proto->request = relay_dns_request;
80 7ba7514d 2007-09-10 reyk proto->cmp = relay_dns_cmp;
81 c0255773 2008-07-09 reyk shuffle_init(&relay_shuffle);
84 7ba7514d 2007-09-10 reyk fatalx("unsupported udp protocol");
90 7ba7514d 2007-09-10 reyk relay_udp_bind(struct sockaddr_storage *ss, in_port_t port,
91 7ba7514d 2007-09-10 reyk struct protocol *proto)
95 7ba7514d 2007-09-10 reyk if ((s = relay_udp_socket(ss, port, proto)) == -1)
96 7ba7514d 2007-09-10 reyk return (-1);
98 7ba7514d 2007-09-10 reyk if (bind(s, (struct sockaddr *)ss, ss->ss_len) == -1)
101 7ba7514d 2007-09-10 reyk return (s);
105 7ba7514d 2007-09-10 reyk return (-1);
109 7ba7514d 2007-09-10 reyk relay_udp_socket(struct sockaddr_storage *ss, in_port_t port,
110 7ba7514d 2007-09-10 reyk struct protocol *proto)
112 7ba7514d 2007-09-10 reyk int s = -1, val;
114 7ba7514d 2007-09-10 reyk if (relay_socket_af(ss, port) == -1)
117 24dcf092 2015-11-28 reyk if ((s = socket(ss->ss_family, SOCK_DGRAM | SOCK_NONBLOCK,
118 24dcf092 2015-11-28 reyk IPPROTO_UDP)) == -1)
122 7ba7514d 2007-09-10 reyk * Socket options
124 7ba7514d 2007-09-10 reyk if (proto->tcpflags & TCPFLAG_BUFSIZ) {
125 7ba7514d 2007-09-10 reyk val = proto->tcpbufsiz;
126 7ba7514d 2007-09-10 reyk if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
127 7ba7514d 2007-09-10 reyk &val, sizeof(val)) == -1)
129 7ba7514d 2007-09-10 reyk val = proto->tcpbufsiz;
130 7ba7514d 2007-09-10 reyk if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
131 7ba7514d 2007-09-10 reyk &val, sizeof(val)) == -1)
136 7ba7514d 2007-09-10 reyk * IP options
138 7ba7514d 2007-09-10 reyk if (proto->tcpflags & TCPFLAG_IPTTL) {
139 7ba7514d 2007-09-10 reyk val = (int)proto->tcpipttl;
140 99857652 2016-11-10 jca switch (ss->ss_family) {
141 99857652 2016-11-10 jca case AF_INET:
142 99857652 2016-11-10 jca if (setsockopt(s, IPPROTO_IP, IP_TTL,
143 99857652 2016-11-10 jca &val, sizeof(val)) == -1)
146 99857652 2016-11-10 jca case AF_INET6:
147 99857652 2016-11-10 jca if (setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
148 99857652 2016-11-10 jca &val, sizeof(val)) == -1)
153 7ba7514d 2007-09-10 reyk if (proto->tcpflags & TCPFLAG_IPMINTTL) {
154 7ba7514d 2007-09-10 reyk val = (int)proto->tcpipminttl;
155 99857652 2016-11-10 jca switch (ss->ss_family) {
156 99857652 2016-11-10 jca case AF_INET:
157 99857652 2016-11-10 jca if (setsockopt(s, IPPROTO_IP, IP_MINTTL,
158 99857652 2016-11-10 jca &val, sizeof(val)) == -1)
161 99857652 2016-11-10 jca case AF_INET6:
162 99857652 2016-11-10 jca if (setsockopt(s, IPPROTO_IPV6, IPV6_MINHOPCOUNT,
163 99857652 2016-11-10 jca &val, sizeof(val)) == -1)
169 7ba7514d 2007-09-10 reyk return (s);
172 7ba7514d 2007-09-10 reyk if (s != -1)
174 7ba7514d 2007-09-10 reyk return (-1);
178 4068a26b 2008-07-09 reyk relay_udp_response(int fd, short sig, void *arg)
180 6e65a975 2013-01-17 bluhm struct rsession *con = arg;
181 4068a26b 2008-07-09 reyk struct relay *rlay = con->se_relay;
182 4068a26b 2008-07-09 reyk struct protocol *proto = rlay->rl_proto;
183 c7b7c92e 2008-07-09 reyk void *priv = NULL;
184 4068a26b 2008-07-09 reyk struct sockaddr_storage ss;
185 fb0e4fa0 2010-05-26 nicm u_int8_t buf[IBUF_READ_SIZE];
186 4068a26b 2008-07-09 reyk ssize_t len;
187 4068a26b 2008-07-09 reyk socklen_t slen;
189 4068a26b 2008-07-09 reyk if (sig == EV_TIMEOUT) {
190 4068a26b 2008-07-09 reyk relay_udp_timeout(fd, sig, arg);
194 62110500 2018-04-18 claudio if (rlay->rl_conf.flags & F_DISABLE)
197 4068a26b 2008-07-09 reyk slen = sizeof(ss);
198 4068a26b 2008-07-09 reyk if ((len = recvfrom(fd, buf, sizeof(buf), 0,
199 4068a26b 2008-07-09 reyk (struct sockaddr*)&ss, &slen)) < 1)
202 4068a26b 2008-07-09 reyk /* Parse and validate the packet header */
203 4068a26b 2008-07-09 reyk if (proto->validate != NULL &&
204 c7b7c92e 2008-07-09 reyk (priv = (*proto->validate)(con, rlay, &ss, buf, len)) == NULL)
207 37ed6014 2018-08-06 benno relay_close(con, "unknown response", 1);
208 ba24b6a0 2015-12-07 mmcc free(priv);
212 7ba7514d 2007-09-10 reyk relay_udp_server(int fd, short sig, void *arg)
214 b14526d5 2016-09-02 reyk struct privsep *ps = env->sc_ps;
215 6e65a975 2013-01-17 bluhm struct relay *rlay = arg;
216 146643ba 2008-01-31 reyk struct protocol *proto = rlay->rl_proto;
217 61afd4d6 2009-08-07 reyk struct rsession *con = NULL;
218 7ba7514d 2007-09-10 reyk struct ctl_natlook *cnl = NULL;
219 7ba7514d 2007-09-10 reyk socklen_t slen;
220 7ba7514d 2007-09-10 reyk struct timeval tv;
221 7ba7514d 2007-09-10 reyk struct sockaddr_storage ss;
222 fb0e4fa0 2010-05-26 nicm u_int8_t buf[IBUF_READ_SIZE];
223 6e9314ae 2008-05-08 reyk void *priv = NULL;
224 7ba7514d 2007-09-10 reyk ssize_t len;
226 58721a38 2014-08-08 reyk event_add(&rlay->rl_ev, NULL);
228 62110500 2018-04-18 claudio if (rlay->rl_conf.flags & F_DISABLE)
231 7ba7514d 2007-09-10 reyk slen = sizeof(ss);
232 7ba7514d 2007-09-10 reyk if ((len = recvfrom(fd, buf, sizeof(buf), 0,
233 7ba7514d 2007-09-10 reyk (struct sockaddr*)&ss, &slen)) < 1)
236 7ba7514d 2007-09-10 reyk if (proto->validate != NULL &&
237 4068a26b 2008-07-09 reyk (priv = (*proto->validate)(NULL, rlay, &ss, buf, len)) == NULL)
240 6e65a975 2013-01-17 bluhm if ((con = calloc(1, sizeof(*con))) == NULL) {
241 6e9314ae 2008-05-08 reyk free(priv);
246 ac536058 2008-03-03 reyk * Replace the DNS request Id with a random Id.
248 6e9314ae 2008-05-08 reyk con->se_priv = priv;
249 aa79f3aa 2008-01-31 thib con->se_in.s = -1;
250 aa79f3aa 2008-01-31 thib con->se_out.s = -1;
251 aa79f3aa 2008-01-31 thib con->se_in.dst = &con->se_out;
252 aa79f3aa 2008-01-31 thib con->se_out.dst = &con->se_in;
253 aa79f3aa 2008-01-31 thib con->se_in.con = con;
254 aa79f3aa 2008-01-31 thib con->se_out.con = con;
255 aa79f3aa 2008-01-31 thib con->se_relay = rlay;
256 aa79f3aa 2008-01-31 thib con->se_id = ++relay_conid;
257 aa79f3aa 2008-01-31 thib con->se_in.dir = RELAY_DIR_REQUEST;
258 aa79f3aa 2008-01-31 thib con->se_out.dir = RELAY_DIR_RESPONSE;
259 aa79f3aa 2008-01-31 thib con->se_retry = rlay->rl_conf.dstretry;
260 aa79f3aa 2008-01-31 thib con->se_out.port = rlay->rl_conf.dstport;
261 7ba7514d 2007-09-10 reyk switch (ss.ss_family) {
262 7ba7514d 2007-09-10 reyk case AF_INET:
263 aa79f3aa 2008-01-31 thib con->se_in.port = ((struct sockaddr_in *)&ss)->sin_port;
265 7ba7514d 2007-09-10 reyk case AF_INET6:
266 aa79f3aa 2008-01-31 thib con->se_in.port = ((struct sockaddr_in6 *)&ss)->sin6_port;
269 b7f7a948 2013-03-10 reyk bcopy(&ss, &con->se_in.ss, sizeof(con->se_in.ss));
271 b7f7a948 2013-03-10 reyk getmonotime(&con->se_tv_start);
272 b7f7a948 2013-03-10 reyk bcopy(&con->se_tv_start, &con->se_tv_last, sizeof(con->se_tv_last));
274 7ba7514d 2007-09-10 reyk relay_sessions++;
275 146643ba 2008-01-31 reyk SPLAY_INSERT(session_tree, &rlay->rl_sessions, con);
276 28bd28ce 2014-11-19 blambert relay_session_publish(con);
278 7ba7514d 2007-09-10 reyk /* Increment the per-relay session counter */
279 b14526d5 2016-09-02 reyk rlay->rl_stats[ps->ps_instance].last++;
281 7ba7514d 2007-09-10 reyk /* Pre-allocate output buffer */
282 aa79f3aa 2008-01-31 thib con->se_out.output = evbuffer_new();
283 aa79f3aa 2008-01-31 thib if (con->se_out.output == NULL) {
284 37ed6014 2018-08-06 benno relay_close(con, "failed to allocate output buffer", 1);
288 7ba7514d 2007-09-10 reyk /* Pre-allocate log buffer */
289 c72024a8 2014-07-13 benno con->se_haslog = 0;
290 aa79f3aa 2008-01-31 thib con->se_log = evbuffer_new();
291 aa79f3aa 2008-01-31 thib if (con->se_log == NULL) {
292 37ed6014 2018-08-06 benno relay_close(con, "failed to allocate log buffer", 1);
296 146643ba 2008-01-31 reyk if (rlay->rl_conf.flags & F_NATLOOK) {
297 6e65a975 2013-01-17 bluhm if ((cnl = calloc(1, sizeof(*cnl))) == NULL) {
298 37ed6014 2018-08-06 benno relay_close(con, "failed to allocate natlookup", 1);
303 7ba7514d 2007-09-10 reyk /* Save the received data */
304 aa79f3aa 2008-01-31 thib if (evbuffer_add(con->se_out.output, buf, len) == -1) {
305 37ed6014 2018-08-06 benno relay_close(con, "failed to store buffer", 1);
310 d89b4c88 2012-12-18 reyk if (cnl != NULL) {
311 aa79f3aa 2008-01-31 thib con->se_cnl = cnl;
312 7ba7514d 2007-09-10 reyk bzero(cnl, sizeof(*cnl));
313 7ba7514d 2007-09-10 reyk cnl->in = -1;
314 aa79f3aa 2008-01-31 thib cnl->id = con->se_id;
315 b14526d5 2016-09-02 reyk cnl->proc = ps->ps_instance;
316 555b1b20 2008-07-09 reyk cnl->proto = IPPROTO_UDP;
317 aa79f3aa 2008-01-31 thib bcopy(&con->se_in.ss, &cnl->src, sizeof(cnl->src));
318 146643ba 2008-01-31 reyk bcopy(&rlay->rl_conf.ss, &cnl->dst, sizeof(cnl->dst));
319 141b9058 2015-12-02 reyk proc_compose(env->sc_ps, PROC_PFE,
320 141b9058 2015-12-02 reyk IMSG_NATLOOK, cnl, sizeof(*cnl));
322 7ba7514d 2007-09-10 reyk /* Schedule timeout */
323 aa79f3aa 2008-01-31 thib evtimer_set(&con->se_ev, relay_natlook, con);
324 146643ba 2008-01-31 reyk bcopy(&rlay->rl_conf.timeout, &tv, sizeof(tv));
325 aa79f3aa 2008-01-31 thib evtimer_add(&con->se_ev, &tv);
329 7ba7514d 2007-09-10 reyk relay_session(con);
333 7ba7514d 2007-09-10 reyk relay_udp_timeout(int fd, short sig, void *arg)
335 6e65a975 2013-01-17 bluhm struct rsession *con = arg;
337 7ba7514d 2007-09-10 reyk if (sig != EV_TIMEOUT)
338 7ba7514d 2007-09-10 reyk fatalx("invalid timeout event");
340 37ed6014 2018-08-06 benno relay_close(con, "udp timeout", 1);
344 7ba7514d 2007-09-10 reyk * Domain Name System support
347 6e9314ae 2008-05-08 reyk struct relay_dns_priv {
348 6e9314ae 2008-05-08 reyk u_int16_t dp_inkey;
349 6e9314ae 2008-05-08 reyk u_int16_t dp_outkey;
352 7ba7514d 2007-09-10 reyk struct relay_dnshdr {
353 7ba7514d 2007-09-10 reyk u_int16_t dns_id;
355 7ba7514d 2007-09-10 reyk u_int8_t dns_flags0;
356 7ba7514d 2007-09-10 reyk #define DNS_F0_QR 0x80 /* response flag */
357 7ba7514d 2007-09-10 reyk #define DNS_F0_OPCODE 0x78 /* message type */
358 57122c1b 2022-12-28 jmc #define DNS_F0_AA 0x04 /* authoritative answer */
359 7ba7514d 2007-09-10 reyk #define DNS_F0_TC 0x02 /* truncated message */
360 7ba7514d 2007-09-10 reyk #define DNS_F0_RD 0x01 /* recursion desired */
362 7ba7514d 2007-09-10 reyk u_int8_t dns_flags1;
363 7ba7514d 2007-09-10 reyk #define DNS_F1_RA 0x80 /* recursion available */
364 7ba7514d 2007-09-10 reyk #define DNS_F1_RES 0x40 /* reserved */
365 7ba7514d 2007-09-10 reyk #define DNS_F1_AD 0x20 /* authentic data */
366 7ba7514d 2007-09-10 reyk #define DNS_F1_CD 0x10 /* checking disabled */
367 7ba7514d 2007-09-10 reyk #define DNS_F1_RCODE 0x0f /* response code */
369 7ba7514d 2007-09-10 reyk u_int16_t dns_qdcount;
370 7ba7514d 2007-09-10 reyk u_int16_t dns_ancount;
371 7ba7514d 2007-09-10 reyk u_int16_t dns_nscount;
372 7ba7514d 2007-09-10 reyk u_int16_t dns_arcount;
373 7ba7514d 2007-09-10 reyk } __packed;
376 61afd4d6 2009-08-07 reyk relay_dns_log(struct rsession *con, u_int8_t *buf, size_t len)
378 7ba7514d 2007-09-10 reyk struct relay_dnshdr *hdr = (struct relay_dnshdr *)buf;
380 2b52c839 2008-07-23 reyk /* Validate the header length */
381 2b52c839 2008-07-23 reyk if (len < sizeof(*hdr)) {
382 666bd316 2011-05-05 reyk log_debug("%s: session %d: short dns packet", __func__,
383 2b52c839 2008-07-23 reyk con->se_id);
387 666bd316 2011-05-05 reyk log_debug("%s: session %d: %s id 0x%x "
388 666bd316 2011-05-05 reyk "flags 0x%x:0x%x qd %u an %u ns %u ar %u", __func__,
389 aa79f3aa 2008-01-31 thib con->se_id,
390 7ba7514d 2007-09-10 reyk hdr->dns_flags0 & DNS_F0_QR ? "response" : "request",
391 7ba7514d 2007-09-10 reyk ntohs(hdr->dns_id),
392 7ba7514d 2007-09-10 reyk hdr->dns_flags0,
393 7ba7514d 2007-09-10 reyk hdr->dns_flags1,
394 7ba7514d 2007-09-10 reyk ntohs(hdr->dns_qdcount),
395 7ba7514d 2007-09-10 reyk ntohs(hdr->dns_ancount),
396 7ba7514d 2007-09-10 reyk ntohs(hdr->dns_nscount),
397 7ba7514d 2007-09-10 reyk ntohs(hdr->dns_arcount));
401 61afd4d6 2009-08-07 reyk relay_dns_validate(struct rsession *con, struct relay *rlay,
402 4068a26b 2008-07-09 reyk struct sockaddr_storage *ss, u_int8_t *buf, size_t len)
404 7ba7514d 2007-09-10 reyk struct relay_dnshdr *hdr = (struct relay_dnshdr *)buf;
405 61afd4d6 2009-08-07 reyk struct rsession lookup;
406 6e9314ae 2008-05-08 reyk u_int16_t key;
407 6e9314ae 2008-05-08 reyk struct relay_dns_priv *priv, lpriv;
409 7ba7514d 2007-09-10 reyk /* Validate the header length */
410 7ba7514d 2007-09-10 reyk if (len < sizeof(*hdr))
411 6e9314ae 2008-05-08 reyk return (NULL);
413 6e9314ae 2008-05-08 reyk key = ntohs(hdr->dns_id);
416 7ba7514d 2007-09-10 reyk * Check if the header has the response flag set, otherwise
417 7ba7514d 2007-09-10 reyk * return 0 to tell the UDP server to create a new session.
419 6e9314ae 2008-05-08 reyk if ((hdr->dns_flags0 & DNS_F0_QR) == 0) {
420 6e9314ae 2008-05-08 reyk priv = malloc(sizeof(struct relay_dns_priv));
421 6e9314ae 2008-05-08 reyk if (priv == NULL)
422 6e9314ae 2008-05-08 reyk return (NULL);
423 c0255773 2008-07-09 reyk priv->dp_inkey = shuffle_generate16(&relay_shuffle);
424 6e9314ae 2008-05-08 reyk priv->dp_outkey = key;
425 6e9314ae 2008-05-08 reyk return ((void *)priv);
429 7ba7514d 2007-09-10 reyk * Lookup if this response is for a known session and if the
430 7ba7514d 2007-09-10 reyk * remote host matches the original destination of the request.
432 4068a26b 2008-07-09 reyk if (con == NULL) {
433 4068a26b 2008-07-09 reyk lpriv.dp_inkey = key;
434 4068a26b 2008-07-09 reyk lookup.se_priv = &lpriv;
435 4068a26b 2008-07-09 reyk if ((con = SPLAY_FIND(session_tree,
436 4068a26b 2008-07-09 reyk &rlay->rl_sessions, &lookup)) != NULL &&
437 4068a26b 2008-07-09 reyk con->se_priv != NULL &&
438 4068a26b 2008-07-09 reyk relay_cmp_af(ss, &con->se_out.ss) == 0)
439 4068a26b 2008-07-09 reyk relay_dns_result(con, buf, len);
441 6e65a975 2013-01-17 bluhm priv = con->se_priv;
442 c7b7c92e 2008-07-09 reyk if (priv == NULL || key != priv->dp_inkey) {
443 37ed6014 2018-08-06 benno relay_close(con, "invalid response", 1);
444 c7b7c92e 2008-07-09 reyk return (NULL);
446 4068a26b 2008-07-09 reyk relay_dns_result(con, buf, len);
450 7ba7514d 2007-09-10 reyk * This is not a new session, ignore it in the UDP server.
452 6e9314ae 2008-05-08 reyk return (NULL);
456 61afd4d6 2009-08-07 reyk relay_dns_request(struct rsession *con)
458 6e65a975 2013-01-17 bluhm struct relay *rlay = con->se_relay;
459 6e65a975 2013-01-17 bluhm struct relay_dns_priv *priv = con->se_priv;
460 aa79f3aa 2008-01-31 thib u_int8_t *buf = EVBUFFER_DATA(con->se_out.output);
461 aa79f3aa 2008-01-31 thib size_t len = EVBUFFER_LENGTH(con->se_out.output);
462 7ba7514d 2007-09-10 reyk struct relay_dnshdr *hdr;
463 7ba7514d 2007-09-10 reyk socklen_t slen;
465 6e9314ae 2008-05-08 reyk if (buf == NULL || priv == NULL || len < 1)
466 7ba7514d 2007-09-10 reyk return (-1);
467 afbe8d84 2017-01-09 reyk if (log_getverbose() > 1)
468 2b52c839 2008-07-23 reyk relay_dns_log(con, buf, len);
470 b7f7a948 2013-03-10 reyk getmonotime(&con->se_tv_start);
472 0f7a5e2e 2012-10-03 reyk if (!TAILQ_EMPTY(&rlay->rl_tables)) {
473 7ba7514d 2007-09-10 reyk if (relay_from_table(con) != 0)
474 7ba7514d 2007-09-10 reyk return (-1);
475 aa79f3aa 2008-01-31 thib } else if (con->se_out.ss.ss_family == AF_UNSPEC) {
476 e8962295 2008-09-29 reyk bcopy(&rlay->rl_conf.dstss, &con->se_out.ss,
477 e8962295 2008-09-29 reyk sizeof(con->se_out.ss));
478 aa79f3aa 2008-01-31 thib con->se_out.port = rlay->rl_conf.dstport;
481 4068a26b 2008-07-09 reyk if ((con->se_out.s = relay_udp_socket(&con->se_out.ss,
482 4068a26b 2008-07-09 reyk con->se_out.port, rlay->rl_proto)) == -1)
483 7ba7514d 2007-09-10 reyk return (-1);
484 aa79f3aa 2008-01-31 thib slen = con->se_out.ss.ss_len;
486 7ba7514d 2007-09-10 reyk hdr = (struct relay_dnshdr *)buf;
487 6e9314ae 2008-05-08 reyk hdr->dns_id = htons(priv->dp_inkey);
490 4068a26b 2008-07-09 reyk if (sendto(con->se_out.s, buf, len, 0,
491 aa79f3aa 2008-01-31 thib (struct sockaddr *)&con->se_out.ss, slen) == -1) {
492 aa79f3aa 2008-01-31 thib if (con->se_retry) {
493 aa79f3aa 2008-01-31 thib con->se_retry--;
494 666bd316 2011-05-05 reyk log_debug("%s: session %d: "
495 666bd316 2011-05-05 reyk "forward failed: %s, %s", __func__,
496 aa79f3aa 2008-01-31 thib con->se_id, strerror(errno),
497 aa79f3aa 2008-01-31 thib con->se_retry ? "next retry" : "last retry");
498 7ba7514d 2007-09-10 reyk goto retry;
500 666bd316 2011-05-05 reyk log_debug("%s: session %d: forward failed: %s", __func__,
501 aa79f3aa 2008-01-31 thib con->se_id, strerror(errno));
502 7ba7514d 2007-09-10 reyk return (-1);
505 4068a26b 2008-07-09 reyk event_again(&con->se_ev, con->se_out.s, EV_TIMEOUT|EV_READ,
506 58721a38 2014-08-08 reyk relay_udp_response, &con->se_tv_start, &rlay->rl_conf.timeout, con);
508 7ba7514d 2007-09-10 reyk return (0);
512 61afd4d6 2009-08-07 reyk relay_dns_result(struct rsession *con, u_int8_t *buf, size_t len)
514 6e65a975 2013-01-17 bluhm struct relay *rlay = con->se_relay;
515 6e65a975 2013-01-17 bluhm struct relay_dns_priv *priv = con->se_priv;
516 7ba7514d 2007-09-10 reyk struct relay_dnshdr *hdr;
517 7ba7514d 2007-09-10 reyk socklen_t slen;
519 6e9314ae 2008-05-08 reyk if (priv == NULL)
520 09e53fee 2017-05-28 benno fatalx("%s: response to invalid session", __func__);
522 afbe8d84 2017-01-09 reyk if (log_getverbose() > 1)
523 2b52c839 2008-07-23 reyk relay_dns_log(con, buf, len);
526 7ba7514d 2007-09-10 reyk * Replace the random DNS request Id with the original Id
528 7ba7514d 2007-09-10 reyk hdr = (struct relay_dnshdr *)buf;
529 6e9314ae 2008-05-08 reyk hdr->dns_id = htons(priv->dp_outkey);
531 aa79f3aa 2008-01-31 thib slen = con->se_out.ss.ss_len;
532 146643ba 2008-01-31 reyk if (sendto(rlay->rl_s, buf, len, 0,
533 aa79f3aa 2008-01-31 thib (struct sockaddr *)&con->se_in.ss, slen) == -1) {
534 37ed6014 2018-08-06 benno relay_close(con, "response failed", 1);
538 37ed6014 2018-08-06 benno relay_close(con, "session closed", 0);
542 61afd4d6 2009-08-07 reyk relay_dns_cmp(struct rsession *a, struct rsession *b)
544 6e65a975 2013-01-17 bluhm struct relay_dns_priv *ap = a->se_priv;
545 6e65a975 2013-01-17 bluhm struct relay_dns_priv *bp = b->se_priv;
547 6e9314ae 2008-05-08 reyk if (ap == NULL || bp == NULL)
548 09e53fee 2017-05-28 benno fatalx("%s: invalid session", __func__);
550 6e9314ae 2008-05-08 reyk return (memcmp(&ap->dp_inkey, &bp->dp_inkey, sizeof(u_int16_t)));