Skip to content

Commit

Permalink
- Use the same interface listening port discovery code for all needed
Browse files Browse the repository at this point in the history
  protocols.
- Port to string only when needed before getaddrinfo().
  • Loading branch information
gthess committed Jan 21, 2025
1 parent d62fff2 commit 048c193
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 119 deletions.
5 changes: 5 additions & 0 deletions doc/Changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
21 January 2025: Yorgos
- Use the same interface listening port discovery code for all needed
protocols.
- Port to string only when needed before getaddrinfo().

20 January 2025: Yorgos
- Merge #1222: Unique DoT and DoH SSL contexts to allow for different
ALPN.
Expand Down
2 changes: 1 addition & 1 deletion doc/unbound.conf.5.in
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,7 @@ and initial ACL (check if the proxy itself is denied/refused by configuration).
The proxied address (if any) will then be used as the true client address and
will be used where applicable for logging, ACL, DNSTAP, RPZ and IP ratelimiting.
PROXYv2 is supported for UDP and TCP/TLS listening interfaces.
There is no support for PROXYv2 on a DoH or DNSCrypt listening interface.
There is no support for PROXYv2 on a DoH, DoQ or DNSCrypt listening interface.
Can list multiple, each on a new statement.
.TP
.B quic\-port: \fI<number>
Expand Down
56 changes: 25 additions & 31 deletions services/listen_dnsport.c
Original file line number Diff line number Diff line change
Expand Up @@ -1034,25 +1034,27 @@ create_local_accept_sock(const char *path, int* noproto, int use_systemd)
* Create socket from getaddrinfo results
*/
static int
make_sock(int stype, const char* ifname, const char* port,
make_sock(int stype, const char* ifname, int port,
struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
int* reuseport, int transparent, int tcp_mss, int nodelay, int freebind,
int use_systemd, int dscp, struct unbound_socket* ub_sock,
const char* additional)
{
struct addrinfo *res = NULL;
int r, s, inuse, noproto;
char portbuf[32];
snprintf(portbuf, sizeof(portbuf), "%d", port);
hints->ai_socktype = stype;
*noip6 = 0;
if((r=getaddrinfo(ifname, port, hints, &res)) != 0 || !res) {
if((r=getaddrinfo(ifname, portbuf, hints, &res)) != 0 || !res) {
#ifdef USE_WINSOCK
if(r == EAI_NONAME && hints->ai_family == AF_INET6){
*noip6 = 1; /* 'Host not found' for IP6 on winXP */
return -1;
}
#endif
log_err("node %s:%s getaddrinfo: %s %s",
ifname?ifname:"default", port, gai_strerror(r),
ifname?ifname:"default", portbuf, gai_strerror(r),
#ifdef EAI_SYSTEM
(r==EAI_SYSTEM?(char*)strerror(errno):"")
#else
Expand Down Expand Up @@ -1106,7 +1108,7 @@ make_sock(int stype, const char* ifname, const char* port,

/** make socket and first see if ifname contains port override info */
static int
make_sock_port(int stype, const char* ifname, const char* port,
make_sock_port(int stype, const char* ifname, int port,
struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
int* reuseport, int transparent, int tcp_mss, int nodelay, int freebind,
int use_systemd, int dscp, struct unbound_socket* ub_sock,
Expand All @@ -1115,23 +1117,22 @@ make_sock_port(int stype, const char* ifname, const char* port,
char* s = strchr(ifname, '@');
if(s) {
/* override port with ifspec@port */
char p[16];
int port;
char newif[128];
if((size_t)(s-ifname) >= sizeof(newif)) {
log_err("ifname too long: %s", ifname);
*noip6 = 0;
return -1;
}
if(strlen(s+1) >= sizeof(p)) {
log_err("portnumber too long: %s", ifname);
port = atoi(s+1);
if(port < 0 || 0 == port || port > 65535) {
log_err("invalid portnumber in interface: %s", ifname);
*noip6 = 0;
return -1;
}
(void)strlcpy(newif, ifname, sizeof(newif));
newif[s-ifname] = 0;
(void)strlcpy(p, s+1, sizeof(p));
p[strlen(s+1)]=0;
return make_sock(stype, newif, p, hints, v6only, noip6, rcv,
return make_sock(stype, newif, port, hints, v6only, noip6, rcv,
snd, reuseport, transparent, tcp_mss, nodelay, freebind,
use_systemd, dscp, ub_sock, additional);
}
Expand Down Expand Up @@ -1248,7 +1249,7 @@ set_recvpktinfo(int s, int family)
* @param do_udp: if udp should be used.
* @param do_tcp: if tcp should be used.
* @param hints: for getaddrinfo. family and flags have to be set by caller.
* @param port: Port number to use (as string).
* @param port: Port number to use.
* @param list: list of open ports, appended to, changed to point to list head.
* @param rcv: receive buffer size for UDP
* @param snd: send buffer size for UDP
Expand All @@ -1274,7 +1275,7 @@ set_recvpktinfo(int s, int family)
*/
static int
ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
struct addrinfo *hints, const char* port, struct listen_port** list,
struct addrinfo *hints, int port, struct listen_port** list,
size_t rcv, size_t snd, int ssl_port,
struct config_strlist* tls_additional_port, int https_port,
struct config_strlist* proxy_protocol_port,
Expand All @@ -1287,14 +1288,14 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
int is_https = if_is_https(ifname, port, https_port);
int is_dnscrypt = if_is_dnscrypt(ifname, port, dnscrypt_port);
int is_pp2 = if_is_pp2(ifname, port, proxy_protocol_port);
int is_doq = if_is_quic(ifname, port, quic_port);
/* Always set TCP_NODELAY on TLS connection as it speeds up the TLS
* handshake. DoH had already such option so we respect it.
* Otherwise the server waits before sending more handshake data for
* the client ACK (Nagle's algorithm), which is delayed because the
* client waits for more data before ACKing (delayed ACK). */
int nodelay = is_https?http2_nodelay:is_ssl;
struct unbound_socket* ub_sock;
int is_doq = if_is_quic(ifname, port, quic_port);
const char* add = NULL;

if(!do_udp && !do_tcp)
Expand Down Expand Up @@ -1358,13 +1359,11 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
} else if(is_doq) {
udp_port_type = listen_type_doq;
add = "doq";
if(((strchr(ifname, '@') &&
atoi(strchr(ifname, '@')+1) == 53) ||
(!strchr(ifname, '@') && atoi(port) == 53))) {
log_err("DNS over QUIC is not allowed on "
"port 53. Port 53 is for DNS "
"datagrams. Error for "
"interface '%s'.", ifname);
if(if_listens_on(ifname, port, 53, NULL)) {
log_err("DNS over QUIC is strictly not "
"allowed on port 53 as per RFC 9250. "
"Port 53 is for DNS datagrams. Error "
"for interface '%s'.", ifname);
free(ub_sock->addr);
free(ub_sock);
return 0;
Expand Down Expand Up @@ -1412,8 +1411,6 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
}
}
if(do_tcp) {
int is_ssl = if_is_ssl(ifname, port, ssl_port,
tls_additional_port);
enum listen_type port_type;
ub_sock = calloc(1, sizeof(struct unbound_socket));
if(!ub_sock)
Expand Down Expand Up @@ -1881,8 +1878,6 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
struct addrinfo hints;
int i, do_ip4, do_ip6;
int do_tcp, do_auto;
char portbuf[32];
snprintf(portbuf, sizeof(portbuf), "%d", cfg->port);
do_ip4 = cfg->do_ip4;
do_ip6 = cfg->do_ip6;
do_tcp = cfg->do_tcp;
Expand Down Expand Up @@ -1928,12 +1923,11 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
return NULL;
}
now = after;
snprintf(portbuf, sizeof(portbuf), "%d", extraport);
if(do_ip6) {
hints.ai_family = AF_INET6;
if(!ports_create_if("::0",
do_auto, cfg->do_udp, do_tcp,
&hints, portbuf, &list,
&hints, extraport, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, cfg->tls_additional_port,
cfg->https_port,
Expand All @@ -1952,7 +1946,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
hints.ai_family = AF_INET;
if(!ports_create_if("0.0.0.0",
do_auto, cfg->do_udp, do_tcp,
&hints, portbuf, &list,
&hints, extraport, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, cfg->tls_additional_port,
cfg->https_port,
Expand All @@ -1974,7 +1968,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
hints.ai_family = AF_INET6;
if(!ports_create_if(do_auto?"::0":"::1",
do_auto, cfg->do_udp, do_tcp,
&hints, portbuf, &list,
&hints, cfg->port, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, cfg->tls_additional_port,
cfg->https_port, cfg->proxy_protocol_port,
Expand All @@ -1992,7 +1986,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
hints.ai_family = AF_INET;
if(!ports_create_if(do_auto?"0.0.0.0":"127.0.0.1",
do_auto, cfg->do_udp, do_tcp,
&hints, portbuf, &list,
&hints, cfg->port, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, cfg->tls_additional_port,
cfg->https_port, cfg->proxy_protocol_port,
Expand All @@ -2012,7 +2006,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
continue;
hints.ai_family = AF_INET6;
if(!ports_create_if(ifs[i], 0, cfg->do_udp,
do_tcp, &hints, portbuf, &list,
do_tcp, &hints, cfg->port, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, cfg->tls_additional_port,
cfg->https_port, cfg->proxy_protocol_port,
Expand All @@ -2030,7 +2024,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
continue;
hints.ai_family = AF_INET;
if(!ports_create_if(ifs[i], 0, cfg->do_udp,
do_tcp, &hints, portbuf, &list,
do_tcp, &hints, cfg->port, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, cfg->tls_additional_port,
cfg->https_port, cfg->proxy_protocol_port,
Expand Down
12 changes: 7 additions & 5 deletions smallapp/unbound-checkconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,6 @@ interfacechecks(struct config_file* cfg)
int i, j, i2, j2;
char*** resif = NULL;
int* num_resif = NULL;
char portbuf[32];
snprintf(portbuf, sizeof(portbuf), "%d", cfg->port);

if(cfg->num_ifs != 0) {
resif = (char***)calloc(cfg->num_ifs, sizeof(char**));
Expand All @@ -366,15 +364,19 @@ interfacechecks(struct config_file* cfg)
cfg->ifs[i]);
}
/* check for port combinations that are not supported */
if(if_is_pp2(resif[i][0], portbuf, cfg->proxy_protocol_port)) {
if(if_is_dnscrypt(resif[i][0], portbuf,
if(if_is_pp2(resif[i][0], cfg->port, cfg->proxy_protocol_port)) {
if(if_is_dnscrypt(resif[i][0], cfg->port,
cfg->dnscrypt_port)) {
fatal_exit("PROXYv2 and DNSCrypt combination not "
"supported!");
} else if(if_is_https(resif[i][0], portbuf,
} else if(if_is_https(resif[i][0], cfg->port,
cfg->https_port)) {
fatal_exit("PROXYv2 and DoH combination not "
"supported!");
} else if(if_is_quic(resif[i][0], cfg->port,
cfg->quic_port)) {
fatal_exit("PROXYv2 and DoQ combination not "
"supported!");
}
}
/* search for duplicates in the returned addresses */
Expand Down
Loading

0 comments on commit 048c193

Please sign in to comment.