feature: support lookup local network host name or ip via mDNS

This commit is contained in:
Nick Peng
2023-12-22 22:39:14 +08:00
parent 33ee73cbf2
commit c67031eb7c
13 changed files with 425 additions and 46 deletions

View File

@@ -199,7 +199,7 @@ log-level info
# g|-group [group]: set server to group, use with nameserver /domain/group. # g|-group [group]: set server to group, use with nameserver /domain/group.
# e|-exclude-default-group: exclude this server from default group. # e|-exclude-default-group: exclude this server from default group.
# p|-proxy [proxy-name]: use proxy to connect to server. # p|-proxy [proxy-name]: use proxy to connect to server.
# -bootstrap-dns: set as bootstrap dns server. # b|-bootstrap-dns: set as bootstrap dns server.
# -set-mark: set mark on packets. # -set-mark: set mark on packets.
# -subnet [ip/subnet]: set edns client subnet. # -subnet [ip/subnet]: set edns client subnet.
# -host-ip [ip]: set dns server host ip. # -host-ip [ip]: set dns server host ip.
@@ -307,6 +307,10 @@ log-level info
# set ddns domain # set ddns domain
# ddns-domain domain # ddns-domain domain
# lookup local network hostname or ip address from mdns
# mdns-lookup [yes|no]
# mdns-lookup no
# set domain rules # set domain rules
# domain-rules /domain/ [-speed-check-mode [...]] # domain-rules /domain/ [-speed-check-mode [...]]
# rules: # rules:

View File

@@ -350,6 +350,9 @@ msgstr "日志数量"
msgid "Log File" msgid "Log File"
msgstr "日志文件路径" msgstr "日志文件路径"
msgid "mDNS Lookup"
msgstr "mDNS查询"
msgid "Marking Packets" msgid "Marking Packets"
msgstr "数据包标记" msgstr "数据包标记"
@@ -434,6 +437,9 @@ msgstr "解析本地主机名"
msgid "Resolve local hostnames by reading Dnsmasq lease file." msgid "Resolve local hostnames by reading Dnsmasq lease file."
msgstr "读取Dnsmasq的租约文件解析本地主机名。" msgstr "读取Dnsmasq的租约文件解析本地主机名。"
msgid "Resolve local network hostname via mDNS protocol."
msgstr "使用mDNS协议解析本地网络主机名。"
msgid "Response Mode" msgid "Response Mode"
msgstr "响应模式" msgstr "响应模式"

View File

@@ -239,7 +239,7 @@ o.cfgvalue = function(...)
return Flag.cfgvalue(...) or "1" return Flag.cfgvalue(...) or "1"
end end
-- cache-size -- resolve local hostname
o = s:taboption("advanced", Flag, "resolve_local_hostnames", translate("Resolve Local Hostnames"), translate("Resolve local hostnames by reading Dnsmasq lease file.")) o = s:taboption("advanced", Flag, "resolve_local_hostnames", translate("Resolve Local Hostnames"), translate("Resolve local hostnames by reading Dnsmasq lease file."))
o.rmempty = false o.rmempty = false
o.default = o.enabled o.default = o.enabled
@@ -247,6 +247,14 @@ o.cfgvalue = function(...)
return Flag.cfgvalue(...) or "1" return Flag.cfgvalue(...) or "1"
end end
-- resolve local network hostname via mDNS
o = s:taboption("advanced", Flag, "mdns_lookup", translate("mDNS Lookup"), translate("Resolve local network hostname via mDNS protocol."))
o.rmempty = true
o.default = o.disabled
o.cfgvalue = function(...)
return Flag.cfgvalue(...) or "0"
end
-- Force AAAA SOA -- Force AAAA SOA
o = s:taboption("advanced", Flag, "force_aaaa_soa", translate("Force AAAA SOA"), translate("Force AAAA SOA.")) o = s:taboption("advanced", Flag, "force_aaaa_soa", translate("Force AAAA SOA"), translate("Force AAAA SOA."))
o.rmempty = true o.rmempty = true

View File

@@ -393,6 +393,9 @@ msgstr "日志数量"
msgid "Log File" msgid "Log File"
msgstr "日志文件路径" msgstr "日志文件路径"
msgid "mDNS Lookup"
msgstr "mDNS查询"
msgid "Marking Packets" msgid "Marking Packets"
msgstr "数据包标记" msgstr "数据包标记"
@@ -483,6 +486,9 @@ msgstr "解析本地主机名"
msgid "Resolve local hostnames by reading Dnsmasq lease file." msgid "Resolve local hostnames by reading Dnsmasq lease file."
msgstr "读取Dnsmasq的租约文件解析本地主机名。" msgstr "读取Dnsmasq的租约文件解析本地主机名。"
msgid "Resolve local network hostname via mDNS protocol."
msgstr "使用mDNS协议解析本地网络主机名。"
msgid "Response Mode" msgid "Response Mode"
msgstr "响应模式" msgstr "响应模式"

View File

@@ -311,11 +311,16 @@ return view.extend({
o.rmempty = false; o.rmempty = false;
o.default = o.enabled; o.default = o.enabled;
// cache-size; // resolve local hostname;
o = s.taboption("advanced", form.Flag, "resolve_local_hostnames", _("Resolve Local Hostnames"), _("Resolve local hostnames by reading Dnsmasq lease file.")); o = s.taboption("advanced", form.Flag, "resolve_local_hostnames", _("Resolve Local Hostnames"), _("Resolve local hostnames by reading Dnsmasq lease file."));
o.rmempty = false; o.rmempty = false;
o.default = o.enabled; o.default = o.enabled;
// resolve local network hostname via mDNS;
o = s.taboption("advanced", form.Flag, "mdns_lookup", _("mDNS Lookup"), _("Resolve local network hostname via mDNS protocol."));
o.rmempty = true;
o.default = o.disabled;
// Force AAAA SOA // Force AAAA SOA
o = s.taboption("advanced", form.Flag, "force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA.")); o = s.taboption("advanced", form.Flag, "force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA."));
o.rmempty = true; o.rmempty = true;

View File

@@ -644,6 +644,9 @@ load_service()
config_get dns64 "$section" "dns64" "" config_get dns64 "$section" "dns64" ""
[ -z "$dns64" ] || conf_append "dns64" "$dns64" [ -z "$dns64" ] || conf_append "dns64" "$dns64"
config_get_bool mdns_lookup "$section" "mdns_lookup" "0"
[ "$mdns_lookup" = "1" ] && conf_append "mdns-lookup" "yes"
config_get redirect "$section" "redirect" "" config_get redirect "$section" "redirect" ""
config_get old_port "$section" "old_port" "0" config_get old_port "$section" "old_port" "0"
config_get old_enabled "$section" "old_enabled" "0" config_get old_enabled "$section" "old_enabled" "0"

View File

@@ -33,7 +33,9 @@
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <ifaddrs.h>
#include <linux/filter.h> #include <linux/filter.h>
#include <net/if.h>
#include <netdb.h> #include <netdb.h>
#include <netinet/icmp6.h> #include <netinet/icmp6.h>
#include <netinet/ip.h> #include <netinet/ip.h>
@@ -50,6 +52,7 @@
#include <string.h> #include <string.h>
#include <sys/epoll.h> #include <sys/epoll.h>
#include <sys/eventfd.h> #include <sys/eventfd.h>
#include <sys/ioctl.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
@@ -67,6 +70,9 @@
#define SOCKET_PRIORITY (6) #define SOCKET_PRIORITY (6)
#define SOCKET_IP_TOS (IPTOS_LOWDELAY | IPTOS_RELIABILITY) #define SOCKET_IP_TOS (IPTOS_LOWDELAY | IPTOS_RELIABILITY)
#define DNS_MDNS_IP "224.0.0.251"
#define DNS_MDNS_PORT 5353
/* ECS info */ /* ECS info */
struct dns_client_ecs { struct dns_client_ecs {
int enable; int enable;
@@ -400,6 +406,42 @@ int dns_client_get_server_port(struct dns_server_info *server_info)
return server_info->port; return server_info->port;
} }
static inline void _dns_server_inc_server_num(struct dns_server_info *server_info)
{
if (server_info->type == DNS_SERVER_MDNS) {
return;
}
atomic_inc(&client.dns_server_num);
}
static inline void _dns_server_dec_server_num(struct dns_server_info *server_info)
{
if (server_info->type == DNS_SERVER_MDNS) {
return;
}
atomic_dec(&client.dns_server_num);
}
static inline void _dns_server_inc_prohibit_server_num(struct dns_server_info *server_info)
{
if (server_info->type == DNS_SERVER_MDNS) {
return;
}
atomic_inc(&client.dns_server_prohibit_num);
}
static inline void _dns_server_dec_prohibit_server_num(struct dns_server_info *server_info)
{
if (server_info->type == DNS_SERVER_MDNS) {
return;
}
atomic_dec(&client.dns_server_prohibit_num);
}
dns_server_type_t dns_client_get_server_type(struct dns_server_info *server_info) dns_server_type_t dns_client_get_server_type(struct dns_server_info *server_info)
{ {
if (server_info == NULL) { if (server_info == NULL) {
@@ -426,6 +468,9 @@ static const char *_dns_server_get_type_string(dns_server_type_t type)
case DNS_SERVER_HTTPS: case DNS_SERVER_HTTPS:
type_str = "https"; type_str = "https";
break; break;
case DNS_SERVER_MDNS:
type_str = "mdns";
break;
default: default:
break; break;
} }
@@ -760,8 +805,7 @@ int dns_client_add_group(const char *group_name)
} }
if (_dns_client_get_group(group_name) != NULL) { if (_dns_client_get_group(group_name) != NULL) {
tlog(TLOG_ERROR, "add group %s failed, group already exists", group_name); return 0;
return -1;
} }
group = malloc(sizeof(*group)); group = malloc(sizeof(*group));
@@ -872,6 +916,8 @@ static char *_dns_client_server_get_tls_host_verify(struct dns_server_info *serv
} break; } break;
case DNS_SERVER_TCP: case DNS_SERVER_TCP:
break; break;
case DNS_SERVER_MDNS:
break;
default: default:
return NULL; return NULL;
break; break;
@@ -905,6 +951,8 @@ static char *_dns_client_server_get_spki(struct dns_server_info *server_info, in
} break; } break;
case DNS_SERVER_TCP: case DNS_SERVER_TCP:
break; break;
case DNS_SERVER_MDNS:
break;
default: default:
return NULL; return NULL;
break; break;
@@ -1064,6 +1112,11 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
case DNS_SERVER_TCP: case DNS_SERVER_TCP:
sock_type = SOCK_STREAM; sock_type = SOCK_STREAM;
break; break;
case DNS_SERVER_MDNS: {
struct client_dns_server_flag_mdns *flag_mdns = &flags->mdns;
safe_strncpy(flag_mdns->ifname, server_host, DNS_MAX_CNAME_LEN);
sock_type = SOCK_DGRAM;
} break;
default: default:
return -1; return -1;
break; break;
@@ -1168,9 +1221,8 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
list_add(&server_info->list, &client.dns_server_list); list_add(&server_info->list, &client.dns_server_list);
pthread_mutex_unlock(&client.server_list_lock); pthread_mutex_unlock(&client.server_list_lock);
atomic_inc(&client.dns_server_num); _dns_server_inc_server_num(server_info);
freeaddrinfo(gai); freeaddrinfo(gai);
tlog(TLOG_INFO, "add server %s:%d, type: %s", server_ip, port, _dns_server_get_type_string(server_info->type)); tlog(TLOG_INFO, "add server %s:%d, type: %s", server_ip, port, _dns_server_get_type_string(server_info->type));
return 0; return 0;
@@ -1250,6 +1302,8 @@ static void _dns_client_shutdown_socket(struct dns_server_info *server_info)
shutdown(server_info->fd, SHUT_RDWR); shutdown(server_info->fd, SHUT_RDWR);
} }
break; break;
case DNS_SERVER_MDNS:
break;
default: default:
break; break;
} }
@@ -1312,8 +1366,8 @@ static int _dns_client_server_remove(char *server_ip, int port, dns_server_type_
_dns_client_server_close(server_info); _dns_client_server_close(server_info);
pthread_mutex_unlock(&client.server_list_lock); pthread_mutex_unlock(&client.server_list_lock);
_dns_client_remove_server_from_groups(server_info); _dns_client_remove_server_from_groups(server_info);
_dns_server_dec_server_num(server_info);
free(server_info); free(server_info);
atomic_dec(&client.dns_server_num);
return 0; return 0;
} }
pthread_mutex_unlock(&client.server_list_lock); pthread_mutex_unlock(&client.server_list_lock);
@@ -1585,7 +1639,7 @@ static void _dns_client_check_tcp(void)
pthread_mutex_lock(&client.server_list_lock); pthread_mutex_lock(&client.server_list_lock);
list_for_each_entry(server_info, &client.dns_server_list, list) list_for_each_entry(server_info, &client.dns_server_list, list)
{ {
if (server_info->type == DNS_SERVER_UDP) { if (server_info->type == DNS_SERVER_UDP || server_info->type == DNS_SERVER_MDNS) {
/* no need to check udp server */ /* no need to check udp server */
continue; continue;
} }
@@ -1929,6 +1983,74 @@ errout:
return -1; return -1;
} }
#include <net/if.h>
#include <sys/ioctl.h>
static int _dns_client_create_socket_udp_mdns(struct dns_server_info *server_info)
{
int fd = 0;
struct epoll_event event;
const int on = 1;
const int val = 1;
const int priority = SOCKET_PRIORITY;
const int ip_tos = SOCKET_IP_TOS;
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
tlog(TLOG_ERROR, "create socket failed, %s", strerror(errno));
goto errout;
}
if (set_fd_nonblock(fd, 1) != 0) {
tlog(TLOG_ERROR, "set socket non block failed, %s", strerror(errno));
goto errout;
}
struct ifreq ifr;
memset(&ifr, 0, sizeof(struct ifreq));
safe_strncpy(ifr.ifr_name, server_info->flags.mdns.ifname, sizeof(ifr.ifr_name));
ioctl(fd, SIOCGIFINDEX, &ifr);
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(struct ifreq)) < 0) {
tlog(TLOG_ERROR, "bind socket to device %s failed, %s\n", ifr.ifr_name, strerror(errno));
goto errout;
}
server_info->fd = fd;
server_info->status = DNS_SERVER_STATUS_CONNECTIONLESS;
memset(&event, 0, sizeof(event));
event.events = EPOLLIN;
event.data.ptr = server_info;
if (epoll_ctl(client.epoll_fd, EPOLL_CTL_ADD, fd, &event) != 0) {
tlog(TLOG_ERROR, "epoll ctl failed.");
return -1;
}
setsockopt(server_info->fd, IPPROTO_IP, IP_RECVTTL, &on, sizeof(on));
setsockopt(server_info->fd, SOL_IP, IP_TTL, &val, sizeof(val));
setsockopt(server_info->fd, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority));
setsockopt(server_info->fd, IPPROTO_IP, IP_TOS, &ip_tos, sizeof(ip_tos));
setsockopt(server_info->fd, IPPROTO_IP, IP_MULTICAST_TTL, &val, sizeof(val));
if (server_info->ai_family == AF_INET6) {
/* for receiving ip ttl value */
setsockopt(server_info->fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, sizeof(on));
setsockopt(server_info->fd, IPPROTO_IPV6, IPV6_2292HOPLIMIT, &on, sizeof(on));
setsockopt(server_info->fd, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, sizeof(on));
setsockopt(server_info->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val, sizeof(val));
}
return 0;
errout:
if (fd > 0) {
close(fd);
}
server_info->fd = -1;
server_info->status = DNS_SERVER_STATUS_DISCONNECTED;
return -1;
}
static int _DNS_client_create_socket_tcp(struct dns_server_info *server_info) static int _DNS_client_create_socket_tcp(struct dns_server_info *server_info)
{ {
int fd = 0; int fd = 0;
@@ -2171,6 +2293,8 @@ static int _dns_client_create_socket(struct dns_server_info *server_info)
if (server_info->type == DNS_SERVER_UDP) { if (server_info->type == DNS_SERVER_UDP) {
return _dns_client_create_socket_udp(server_info); return _dns_client_create_socket_udp(server_info);
} else if (server_info->type == DNS_SERVER_MDNS) {
return _dns_client_create_socket_udp_mdns(server_info);
} else if (server_info->type == DNS_SERVER_TCP) { } else if (server_info->type == DNS_SERVER_TCP) {
return _DNS_client_create_socket_tcp(server_info); return _DNS_client_create_socket_tcp(server_info);
} else if (server_info->type == DNS_SERVER_TLS) { } else if (server_info->type == DNS_SERVER_TLS) {
@@ -2556,6 +2680,8 @@ static int _dns_client_socket_send(struct dns_server_info *server_info)
} }
} }
return ret; return ret;
} else if (server_info->type == DNS_SERVER_MDNS) {
return -1;
} else { } else {
return -1; return -1;
} }
@@ -2579,6 +2705,8 @@ static int _dns_client_socket_recv(struct dns_server_info *server_info)
} }
return ret; return ret;
} else if (server_info->type == DNS_SERVER_MDNS) {
return -1;
} else { } else {
return -1; return -1;
} }
@@ -3181,7 +3309,7 @@ static int _dns_client_process(struct dns_server_info *server_info, struct epoll
} }
} }
if (server_info->type == DNS_SERVER_UDP) { if (server_info->type == DNS_SERVER_UDP || server_info->type == DNS_SERVER_MDNS) {
/* receive from udp */ /* receive from udp */
return _dns_client_process_udp(server_info, event, now); return _dns_client_process_udp(server_info, event, now);
} else if (server_info->type == DNS_SERVER_TCP) { } else if (server_info->type == DNS_SERVER_TCP) {
@@ -3261,6 +3389,27 @@ errout:
return -1; return -1;
} }
static int _dns_client_send_udp_mdns(struct dns_server_info *server_info, void *packet, int len)
{
int send_len = 0;
const struct sockaddr *addr = &server_info->addr;
socklen_t addrlen = server_info->ai_addrlen;
if (server_info->fd <= 0) {
return -1;
}
send_len = sendto(server_info->fd, packet, len, 0, addr, addrlen);
if (send_len != len) {
goto errout;
}
return 0;
errout:
return -1;
}
static int _dns_client_send_data_to_buffer(struct dns_server_info *server_info, void *packet, int len) static int _dns_client_send_data_to_buffer(struct dns_server_info *server_info, void *packet, int len)
{ {
struct epoll_event event; struct epoll_event event;
@@ -3483,7 +3632,7 @@ static int _dns_client_setup_server_packet(struct dns_server_info *server_info,
dns_set_OPT_option(packet, DNS_OPT_FLAG_DO); dns_set_OPT_option(packet, DNS_OPT_FLAG_DO);
} }
if (server_info->type != DNS_SERVER_UDP) { if (server_info->type != DNS_SERVER_UDP && server_info->type != DNS_SERVER_MDNS) {
dns_add_OPT_TCP_KEEPALIVE(packet, 6000); dns_add_OPT_TCP_KEEPALIVE(packet, 6000);
} }
@@ -3549,7 +3698,7 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet,
if (server_info->prohibit) { if (server_info->prohibit) {
if (server_info->is_already_prohibit == 0) { if (server_info->is_already_prohibit == 0) {
server_info->is_already_prohibit = 1; server_info->is_already_prohibit = 1;
atomic_inc(&client.dns_server_prohibit_num); _dns_server_inc_prohibit_server_num(server_info);
time(&server_info->last_send); time(&server_info->last_send);
time(&server_info->last_recv); time(&server_info->last_recv);
tlog(TLOG_INFO, "server %s not alive, prohibit", server_info->ip); tlog(TLOG_INFO, "server %s not alive, prohibit", server_info->ip);
@@ -3563,7 +3712,7 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet,
} }
server_info->prohibit = 0; server_info->prohibit = 0;
server_info->is_already_prohibit = 0; server_info->is_already_prohibit = 0;
atomic_dec(&client.dns_server_prohibit_num); _dns_server_dec_prohibit_server_num(server_info);
if (now - 60 > server_info->last_send) { if (now - 60 > server_info->last_send) {
_dns_client_close_socket(server_info); _dns_client_close_socket(server_info);
} }
@@ -3609,6 +3758,11 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet,
ret = _dns_client_send_https(server_info, packet_data, packet_data_len); ret = _dns_client_send_https(server_info, packet_data, packet_data_len);
send_err = errno; send_err = errno;
break; break;
case DNS_SERVER_MDNS:
/* mdns query */
ret = _dns_client_send_udp_mdns(server_info, packet_data, packet_data_len);
send_err = errno;
break;
default: default:
/* unsupported query type */ /* unsupported query type */
ret = -1; ret = -1;
@@ -4440,6 +4594,78 @@ static void _dns_client_do_wakeup_event(void)
unused = write(client.fd_wakeup, &val, sizeof(val)); unused = write(client.fd_wakeup, &val, sizeof(val));
} }
static int _dns_client_add_mdns_server(void)
{
struct client_dns_server_flags server_flags;
int ret = 0;
struct ifaddrs *ifaddr = NULL;
struct ifaddrs *ifa = NULL;
if (dns_conf_mdns_lookup != 1) {
return 0;
}
memset(&server_flags, 0, sizeof(server_flags));
server_flags.server_flag |= SERVER_FLAG_EXCLUDE_DEFAULT | DOMAIN_FLAG_IPSET_IGN | DOMAIN_FLAG_NFTSET_INET_IGN;
if (dns_client_add_group(DNS_SERVER_GROUP_MDNS) != 0) {
tlog(TLOG_ERROR, "add default server group failed.");
goto errout;
}
if (getifaddrs(&ifaddr) == -1) {
goto errout;
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
const unsigned char *addr = NULL;
int addr_len = 0;
if (ifa->ifa_addr == NULL) {
continue;
}
if (AF_INET != ifa->ifa_addr->sa_family) {
continue;
}
addr = (const unsigned char *)&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
addr_len = sizeof(struct in_addr);
// Skip the local interface
if (strcmp(ifa->ifa_name, "lo") == 0 || strcmp(ifa->ifa_name, "localhost") == 0) {
continue;
}
if (is_private_addr(addr, addr_len) == 0) {
continue;
}
ret = _dns_client_server_add(DNS_MDNS_IP, ifa->ifa_name, DNS_MDNS_PORT, DNS_SERVER_MDNS, &server_flags);
if (ret != 0) {
tlog(TLOG_ERROR, "add mdns server failed.");
goto errout;
}
if (dns_client_add_to_group(DNS_SERVER_GROUP_MDNS, DNS_MDNS_IP, DNS_MDNS_PORT, DNS_SERVER_MDNS,
&server_flags) != 0) {
tlog(TLOG_ERROR, "add mdns server to group failed.");
goto errout;
}
}
freeifaddrs(ifaddr);
return 0;
errout:
if (ifaddr) {
freeifaddrs(ifaddr);
}
return -1;
}
int dns_client_init(void) int dns_client_init(void)
{ {
pthread_attr_t attr; pthread_attr_t attr;
@@ -4480,6 +4706,11 @@ int dns_client_init(void)
goto errout; goto errout;
} }
if (_dns_client_add_mdns_server() != 0) {
tlog(TLOG_ERROR, "add mdns server failed.");
goto errout;
}
client.default_group = _dns_client_get_group(DNS_SERVER_GROUP_DEFAULT); client.default_group = _dns_client_get_group(DNS_SERVER_GROUP_DEFAULT);
client.epoll_fd = epollfd; client.epoll_fd = epollfd;
atomic_set(&client.run, 1); atomic_set(&client.run, 1);

View File

@@ -27,12 +27,15 @@ extern "C" {
#define DNS_SERVER_SPKI_LEN 64 #define DNS_SERVER_SPKI_LEN 64
#define DNS_SERVER_GROUP_DEFAULT "default" #define DNS_SERVER_GROUP_DEFAULT "default"
#define DNS_SERVER_GROUP_MDNS "mdns"
#define DNS_SERVER_GROUP_LOCAL "local"
typedef enum { typedef enum {
DNS_SERVER_UDP, DNS_SERVER_UDP,
DNS_SERVER_TCP, DNS_SERVER_TCP,
DNS_SERVER_TLS, DNS_SERVER_TLS,
DNS_SERVER_HTTPS, DNS_SERVER_HTTPS,
DNS_SERVER_MDNS,
DNS_SERVER_TYPE_END, DNS_SERVER_TYPE_END,
} dns_server_type_t; } dns_server_type_t;
@@ -90,6 +93,10 @@ struct client_dns_server_flag_udp {
int ttl; int ttl;
}; };
struct client_dns_server_flag_mdns {
char ifname[DNS_MAX_CNAME_LEN];
};
struct client_dns_server_flag_tls { struct client_dns_server_flag_tls {
char spki[DNS_SERVER_SPKI_LEN]; char spki[DNS_SERVER_SPKI_LEN];
int spi_len; int spi_len;
@@ -129,6 +136,7 @@ struct client_dns_server_flags {
struct client_dns_server_flag_udp udp; struct client_dns_server_flag_udp udp;
struct client_dns_server_flag_tls tls; struct client_dns_server_flag_tls tls;
struct client_dns_server_flag_https https; struct client_dns_server_flag_https https;
struct client_dns_server_flag_mdns mdns;
}; };
}; };

View File

@@ -162,6 +162,7 @@ struct dns_ipset_names dns_conf_ipset_no_speed;
int dns_conf_nftset_timeout_enable; int dns_conf_nftset_timeout_enable;
struct dns_nftset_names dns_conf_nftset_no_speed; struct dns_nftset_names dns_conf_nftset_no_speed;
int dns_conf_nftset_debug_enable; int dns_conf_nftset_debug_enable;
int dns_conf_mdns_lookup;
char dns_conf_user[DNS_CONF_USERNAME_LEN]; char dns_conf_user[DNS_CONF_USERNAME_LEN];
@@ -3967,16 +3968,15 @@ static struct dns_hosts *_dns_conf_get_hosts(const char *hostname, int dns_type)
{ {
uint32_t key = 0; uint32_t key = 0;
struct dns_hosts *host = NULL; struct dns_hosts *host = NULL;
char hostname_lower[DNS_MAX_CNAME_LEN];
key = hash_string(to_lower_case(hostname_lower, hostname, DNS_MAX_CNAME_LEN)); key = hash_string_case(hostname);
key = jhash(&dns_type, sizeof(dns_type), key); key = jhash(&dns_type, sizeof(dns_type), key);
hash_for_each_possible(dns_hosts_table.hosts, host, node, key) hash_for_each_possible(dns_hosts_table.hosts, host, node, key)
{ {
if (host->dns_type != dns_type) { if (host->dns_type != dns_type) {
continue; continue;
} }
if (strncmp(host->domain, hostname_lower, DNS_MAX_CNAME_LEN) != 0) { if (strncasecmp(host->domain, hostname, DNS_MAX_CNAME_LEN) != 0) {
continue; continue;
} }
@@ -3988,7 +3988,7 @@ static struct dns_hosts *_dns_conf_get_hosts(const char *hostname, int dns_type)
goto errout; goto errout;
} }
safe_strncpy(host->domain, hostname_lower, DNS_MAX_CNAME_LEN); safe_strncpy(host->domain, hostname, DNS_MAX_CNAME_LEN);
host->dns_type = dns_type; host->dns_type = dns_type;
host->is_soa = 1; host->is_soa = 1;
hash_add(dns_hosts_table.hosts, &host->node, key); hash_add(dns_hosts_table.hosts, &host->node, key);
@@ -4275,6 +4275,15 @@ static void _config_setup_smartdns_domain(void)
_config_domain_rule_flag_set("smartdns", DOMAIN_FLAG_SMARTDNS_DOMAIN, 0); _config_domain_rule_flag_set("smartdns", DOMAIN_FLAG_SMARTDNS_DOMAIN, 0);
} }
static int _dns_conf_setup_mdns(void)
{
if (dns_conf_mdns_lookup != 1) {
return 0;
}
return _conf_domain_rule_nameserver(DNS_SERVER_GROUP_LOCAL, DNS_SERVER_GROUP_MDNS);
}
static struct config_item _config_item[] = { static struct config_item _config_item[] = {
CONF_STRING("server-name", (char *)dns_conf_server_name, DNS_MAX_SERVER_NAME_LEN), CONF_STRING("server-name", (char *)dns_conf_server_name, DNS_MAX_SERVER_NAME_LEN),
CONF_YESNO("resolv-hostname", &dns_conf_resolv_hostname), CONF_YESNO("resolv-hostname", &dns_conf_resolv_hostname),
@@ -4289,6 +4298,7 @@ static struct config_item _config_item[] = {
CONF_CUSTOM("server-tcp", _config_server_tcp, NULL), CONF_CUSTOM("server-tcp", _config_server_tcp, NULL),
CONF_CUSTOM("server-tls", _config_server_tls, NULL), CONF_CUSTOM("server-tls", _config_server_tls, NULL),
CONF_CUSTOM("server-https", _config_server_https, NULL), CONF_CUSTOM("server-https", _config_server_https, NULL),
CONF_YESNO("mdns-lookup", &dns_conf_mdns_lookup),
CONF_CUSTOM("nameserver", _config_nameserver, NULL), CONF_CUSTOM("nameserver", _config_nameserver, NULL),
CONF_YESNO("expand-ptr-from-address", &dns_conf_expand_ptr_from_address), CONF_YESNO("expand-ptr-from-address", &dns_conf_expand_ptr_from_address),
CONF_CUSTOM("address", _config_address, NULL), CONF_CUSTOM("address", _config_address, NULL),
@@ -4728,6 +4738,8 @@ static int _dns_conf_load_post(void)
_dns_conf_auto_set_cache_size(); _dns_conf_auto_set_cache_size();
_dns_conf_setup_mdns();
if (dns_conf_cachesize == 0 && dns_conf_response_mode == DNS_RESPONSE_MODE_FASTEST_RESPONSE) { if (dns_conf_cachesize == 0 && dns_conf_response_mode == DNS_RESPONSE_MODE_FASTEST_RESPONSE) {
dns_conf_response_mode = DNS_RESPONSE_MODE_FASTEST_IP; dns_conf_response_mode = DNS_RESPONSE_MODE_FASTEST_IP;
tlog(TLOG_WARN, "force set response to %s as cache size is 0", tlog(TLOG_WARN, "force set response to %s as cache size is 0",

View File

@@ -578,6 +578,7 @@ extern int dns_conf_ipset_timeout_enable;
extern int dns_conf_nftset_timeout_enable; extern int dns_conf_nftset_timeout_enable;
extern int dns_conf_nftset_debug_enable; extern int dns_conf_nftset_debug_enable;
extern int dns_conf_local_ttl; extern int dns_conf_local_ttl;
extern int dns_conf_mdns_lookup;
extern int dns_conf_force_no_cname; extern int dns_conf_force_no_cname;

View File

@@ -280,6 +280,8 @@ struct dns_request {
int has_soa; int has_soa;
int force_soa; int force_soa;
int is_mdns_lookup;
struct dns_srv_records *srv_records; struct dns_srv_records *srv_records;
atomic_t notified; atomic_t notified;
@@ -365,6 +367,7 @@ static int _dns_server_do_query(struct dns_request *request, int skip_notify_eve
static int _dns_request_post(struct dns_server_post_context *context); static int _dns_request_post(struct dns_server_post_context *context);
static int _dns_server_reply_all_pending_list(struct dns_request *request, struct dns_server_post_context *context); static int _dns_server_reply_all_pending_list(struct dns_request *request, struct dns_server_post_context *context);
static void *_dns_server_get_dns_rule(struct dns_request *request, enum domain_rule rule); static void *_dns_server_get_dns_rule(struct dns_request *request, enum domain_rule rule);
static int _dns_server_get_local_ttl(struct dns_request *request);
static const char *_dns_server_get_request_groupname(struct dns_request *request); static const char *_dns_server_get_request_groupname(struct dns_request *request);
static int _dns_server_tcp_socket_send(struct dns_server_conn_tcp_client *tcp_client, void *data, int data_len); static int _dns_server_tcp_socket_send(struct dns_server_conn_tcp_client *tcp_client, void *data, int data_len);
static int _dns_server_update_request_connection_timeout(struct dns_server_conn_head *conn, int timeout); static int _dns_server_update_request_connection_timeout(struct dns_server_conn_head *conn, int timeout);
@@ -761,8 +764,8 @@ static void _dns_server_audit_log(struct dns_server_post_context *context)
continue; continue;
} }
if (strncmp(name, request->domain, DNS_MAX_CNAME_LEN - 1) != 0 && if (strncasecmp(name, request->domain, DNS_MAX_CNAME_LEN - 1) != 0 &&
strncmp(name, request->cname, DNS_MAX_CNAME_LEN - 1) != 0) { strncasecmp(name, request->cname, DNS_MAX_CNAME_LEN - 1) != 0) {
continue; continue;
} }
@@ -782,8 +785,8 @@ static void _dns_server_audit_log(struct dns_server_post_context *context)
continue; continue;
} }
if (strncmp(name, request->domain, DNS_MAX_CNAME_LEN - 1) != 0 && if (strncasecmp(name, request->domain, DNS_MAX_CNAME_LEN - 1) != 0 &&
strncmp(name, request->cname, DNS_MAX_CNAME_LEN - 1) != 0) { strncasecmp(name, request->cname, DNS_MAX_CNAME_LEN - 1) != 0) {
continue; continue;
} }
@@ -1559,7 +1562,7 @@ static int _dns_cache_cname_packet(struct dns_server_post_context *context)
continue; continue;
} }
if (strncmp(request->cname, name, DNS_MAX_CNAME_LEN - 1) != 0) { if (strncasecmp(request->cname, name, DNS_MAX_CNAME_LEN - 1) != 0) {
continue; continue;
} }
@@ -1575,7 +1578,7 @@ static int _dns_cache_cname_packet(struct dns_server_post_context *context)
continue; continue;
} }
if (strncmp(request->cname, name, DNS_MAX_CNAME_LEN - 1) != 0) { if (strncasecmp(request->cname, name, DNS_MAX_CNAME_LEN - 1) != 0) {
continue; continue;
} }
@@ -2770,6 +2773,9 @@ static void _dns_server_ping_result(struct ping_host_struct *ping_host, const ch
} }
int rtt = tv->tv_sec * 10000 + tv->tv_usec / 100; int rtt = tv->tv_sec * 10000 + tv->tv_usec / 100;
if (rtt == 0) {
rtt = 1;
}
if (result == PING_RESULT_RESPONSE) { if (result == PING_RESULT_RESPONSE) {
tlog(TLOG_DEBUG, "from %s: seq=%d time=%d, lasttime=%d id=%d", host, seqno, rtt, last_rtt, request->id); tlog(TLOG_DEBUG, "from %s: seq=%d time=%d, lasttime=%d id=%d", host, seqno, rtt, last_rtt, request->id);
@@ -3127,7 +3133,7 @@ static int _dns_server_process_answer_A(struct dns_rrs *rrs, struct dns_request
tlog(TLOG_DEBUG, "domain: %s TTL: %d IP: %d.%d.%d.%d", name, ttl, addr[0], addr[1], addr[2], addr[3]); tlog(TLOG_DEBUG, "domain: %s TTL: %d IP: %d.%d.%d.%d", name, ttl, addr[0], addr[1], addr[2], addr[3]);
/* if domain is not match */ /* if domain is not match */
if (strncmp(name, domain, DNS_MAX_CNAME_LEN) != 0 && strncmp(cname, name, DNS_MAX_CNAME_LEN) != 0) { if (strncasecmp(name, domain, DNS_MAX_CNAME_LEN) != 0 && strncasecmp(cname, name, DNS_MAX_CNAME_LEN) != 0) {
return -1; return -1;
} }
@@ -3214,7 +3220,7 @@ static int _dns_server_process_answer_AAAA(struct dns_rrs *rrs, struct dns_reque
addr[11], addr[12], addr[13], addr[14], addr[15]); addr[11], addr[12], addr[13], addr[14], addr[15]);
/* if domain is not match */ /* if domain is not match */
if (strncmp(name, domain, DNS_MAX_CNAME_LEN) != 0 && strncmp(cname, name, DNS_MAX_CNAME_LEN) != 0) { if (strncasecmp(name, domain, DNS_MAX_CNAME_LEN) != 0 && strncasecmp(cname, name, DNS_MAX_CNAME_LEN) != 0) {
return -1; return -1;
} }
@@ -3338,8 +3344,8 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d
char domain_name[DNS_MAX_CNAME_LEN] = {0}; char domain_name[DNS_MAX_CNAME_LEN] = {0};
char domain_cname[DNS_MAX_CNAME_LEN] = {0}; char domain_cname[DNS_MAX_CNAME_LEN] = {0};
dns_get_CNAME(rrs, domain_name, DNS_MAX_CNAME_LEN, &ttl, domain_cname, DNS_MAX_CNAME_LEN); dns_get_CNAME(rrs, domain_name, DNS_MAX_CNAME_LEN, &ttl, domain_cname, DNS_MAX_CNAME_LEN);
if (strncmp(domain_name, request->domain, DNS_MAX_CNAME_LEN - 1) != 0 && if (strncasecmp(domain_name, request->domain, DNS_MAX_CNAME_LEN - 1) != 0 &&
strncmp(domain_name, cname, DNS_MAX_CNAME_LEN - 1) != 0) { strncasecmp(domain_name, cname, DNS_MAX_CNAME_LEN - 1) != 0) {
continue; continue;
} }
safe_strncpy(cname, domain_cname, DNS_MAX_CNAME_LEN); safe_strncpy(cname, domain_cname, DNS_MAX_CNAME_LEN);
@@ -3431,7 +3437,8 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, const
dns_get_A(rrs, name, DNS_MAX_CNAME_LEN, &ttl_tmp, addr); dns_get_A(rrs, name, DNS_MAX_CNAME_LEN, &ttl_tmp, addr);
/* if domain is not match */ /* if domain is not match */
if (strncmp(name, domain, DNS_MAX_CNAME_LEN) != 0 && strncmp(cname, name, DNS_MAX_CNAME_LEN) != 0) { if (strncasecmp(name, domain, DNS_MAX_CNAME_LEN) != 0 &&
strncasecmp(cname, name, DNS_MAX_CNAME_LEN) != 0) {
_dns_server_request_release(request); _dns_server_request_release(request);
continue; continue;
} }
@@ -3470,7 +3477,8 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, const
dns_get_AAAA(rrs, name, DNS_MAX_CNAME_LEN, &ttl_tmp, addr); dns_get_AAAA(rrs, name, DNS_MAX_CNAME_LEN, &ttl_tmp, addr);
/* if domain is not match */ /* if domain is not match */
if (strncmp(name, domain, DNS_MAX_CNAME_LEN) != 0 && strncmp(cname, name, DNS_MAX_CNAME_LEN) != 0) { if (strncasecmp(name, domain, DNS_MAX_CNAME_LEN) != 0 &&
strncasecmp(cname, name, DNS_MAX_CNAME_LEN) != 0) {
_dns_server_request_release(request); _dns_server_request_release(request);
continue; continue;
} }
@@ -3552,8 +3560,8 @@ static int _dns_server_get_answer(struct dns_server_post_context *context)
/* get A result */ /* get A result */
dns_get_A(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr); dns_get_A(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr);
if (strncmp(name, request->domain, DNS_MAX_CNAME_LEN - 1) != 0 && if (strncasecmp(name, request->domain, DNS_MAX_CNAME_LEN - 1) != 0 &&
strncmp(name, request->cname, DNS_MAX_CNAME_LEN - 1) != 0) { strncasecmp(name, request->cname, DNS_MAX_CNAME_LEN - 1) != 0) {
continue; continue;
} }
@@ -3584,8 +3592,8 @@ static int _dns_server_get_answer(struct dns_server_post_context *context)
} }
dns_get_AAAA(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr); dns_get_AAAA(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr);
if (strncmp(name, request->domain, DNS_MAX_CNAME_LEN - 1) != 0 && if (strncasecmp(name, request->domain, DNS_MAX_CNAME_LEN - 1) != 0 &&
strncmp(name, request->cname, DNS_MAX_CNAME_LEN - 1) != 0) { strncasecmp(name, request->cname, DNS_MAX_CNAME_LEN - 1) != 0) {
continue; continue;
} }
@@ -3619,8 +3627,8 @@ static int _dns_server_get_answer(struct dns_server_post_context *context)
dns_get_CNAME(rrs, name, DNS_MAX_CNAME_LEN, &ttl, cname, DNS_MAX_CNAME_LEN); dns_get_CNAME(rrs, name, DNS_MAX_CNAME_LEN, &ttl, cname, DNS_MAX_CNAME_LEN);
tlog(TLOG_DEBUG, "name: %s, ttl: %d, cname: %s\n", name, ttl, cname); tlog(TLOG_DEBUG, "name: %s, ttl: %d, cname: %s\n", name, ttl, cname);
if (strncmp(name, request->domain, DNS_MAX_CNAME_LEN - 1) != 0 && if (strncasecmp(name, request->domain, DNS_MAX_CNAME_LEN - 1) != 0 &&
strncmp(name, request->cname, DNS_MAX_CNAME_LEN - 1) != 0) { strncasecmp(name, request->cname, DNS_MAX_CNAME_LEN - 1) != 0) {
continue; continue;
} }
@@ -3698,6 +3706,13 @@ static void _dns_server_query_end(struct dns_request *request)
int ip_num = 0; int ip_num = 0;
int request_wait = 0; int request_wait = 0;
/* if mdns request timeout */
if (request->is_mdns_lookup == 1 && request->rcode == DNS_RC_SERVFAIL) {
request->rcode = DNS_RC_NOERROR;
request->force_soa = 1;
request->ip_ttl = _dns_server_get_local_ttl(request);
}
pthread_mutex_lock(&request->ip_map_lock); pthread_mutex_lock(&request->ip_map_lock);
ip_num = atomic_read(&request->ip_map_num); ip_num = atomic_read(&request->ip_map_num);
request_wait = request->request_wait; request_wait = request->request_wait;
@@ -4100,7 +4115,7 @@ static int _dns_server_process_local_ptr(struct dns_request *request)
} }
/* Determine if the smartdns service is in effect. */ /* Determine if the smartdns service is in effect. */
if (found == 0 && strncmp(request->domain, "smartdns", sizeof("smartdns")) == 0) { if (found == 0 && strncasecmp(request->domain, "smartdns", sizeof("smartdns")) == 0) {
found = 1; found = 1;
} }
@@ -4179,6 +4194,15 @@ static int _dns_server_get_local_ttl(struct dns_request *request)
return DNS_SERVER_ADDR_TTL; return DNS_SERVER_ADDR_TTL;
} }
static void _dns_server_set_request_mdns(struct dns_request *request)
{
if (dns_conf_mdns_lookup != 1) {
return;
}
request->is_mdns_lookup = 1;
}
static int _dns_server_process_private_ptr(struct dns_request *request) static int _dns_server_process_private_ptr(struct dns_request *request)
{ {
int a, b, c, d; int a, b, c, d;
@@ -4188,9 +4212,12 @@ static int _dns_server_process_private_ptr(struct dns_request *request)
} }
if (d == 10 || (d == 172 && c >= 16 && c <= 31) || (d == 192 && c == 168)) { if (d == 10 || (d == 172 && c >= 16 && c <= 31) || (d == 192 && c == 168)) {
request->has_soa = 1; if (dns_conf_mdns_lookup == 0) {
_dns_server_setup_soa(request); request->has_soa = 1;
return 0; _dns_server_setup_soa(request);
return 0;
}
_dns_server_set_request_mdns(request);
} }
return -1; return -1;
@@ -4253,7 +4280,7 @@ static int _dns_server_process_srv(struct dns_request *request)
static int _dns_server_process_svcb(struct dns_request *request) static int _dns_server_process_svcb(struct dns_request *request)
{ {
if (strncmp("_dns.resolver.arpa", request->domain, DNS_MAX_CNAME_LEN) == 0) { if (strncasecmp("_dns.resolver.arpa", request->domain, DNS_MAX_CNAME_LEN) == 0) {
return _dns_server_process_DDR(request); return _dns_server_process_DDR(request);
} }
@@ -4842,7 +4869,7 @@ static int _dns_server_process_cname(struct dns_request *request)
struct dns_cname_rule *child_cname = _dns_server_get_dns_rule(child_request, DOMAIN_RULE_CNAME); struct dns_cname_rule *child_cname = _dns_server_get_dns_rule(child_request, DOMAIN_RULE_CNAME);
/* sub domain rule*/ /* sub domain rule*/
if (child_cname != NULL && strncmp(child_request->domain, child_cname->cname, DNS_MAX_CNAME_LEN) == 0) { if (child_cname != NULL && strncasecmp(child_request->domain, child_cname->cname, DNS_MAX_CNAME_LEN) == 0) {
child_request->domain_rule.rules[DOMAIN_RULE_CNAME] = NULL; child_request->domain_rule.rules[DOMAIN_RULE_CNAME] = NULL;
child_request->has_cname_loop = 1; child_request->has_cname_loop = 1;
} }
@@ -5462,13 +5489,12 @@ static int _dns_server_process_host(struct dns_request *request)
struct dns_hosts *host = NULL; struct dns_hosts *host = NULL;
struct dns_hosts *host_tmp = NULL; struct dns_hosts *host_tmp = NULL;
int dns_type = request->qtype; int dns_type = request->qtype;
char hostname_lower[DNS_MAX_CNAME_LEN];
if (dns_hosts_record_num <= 0) { if (dns_hosts_record_num <= 0) {
return -1; return -1;
} }
key = hash_string(to_lower_case(hostname_lower, request->domain, DNS_MAX_CNAME_LEN)); key = hash_string_case(request->domain);
key = jhash(&dns_type, sizeof(dns_type), key); key = jhash(&dns_type, sizeof(dns_type), key);
hash_for_each_possible(dns_hosts_table.hosts, host_tmp, node, key) hash_for_each_possible(dns_hosts_table.hosts, host_tmp, node, key)
{ {
@@ -5476,7 +5502,7 @@ static int _dns_server_process_host(struct dns_request *request)
continue; continue;
} }
if (strncmp(host_tmp->domain, hostname_lower, DNS_MAX_CNAME_LEN) != 0) { if (strncasecmp(host_tmp->domain, request->domain, DNS_MAX_CNAME_LEN) != 0) {
continue; continue;
} }
@@ -5536,6 +5562,35 @@ static int _dns_server_setup_query_option(struct dns_request *request, struct dn
return 0; return 0;
} }
static int _dns_server_mdns_query_setup(struct dns_request *request, const char *group_name, char **request_domain,
char *domain_buffer, int domain_buffer_len)
{
if (dns_conf_mdns_lookup != 1) {
return 0;
}
switch (request->qtype) {
case DNS_T_A:
case DNS_T_AAAA:
case DNS_T_SRV:
if (request->domain[0] != '\0' && strstr(request->domain, ".") == NULL) {
snprintf(domain_buffer, domain_buffer_len, "%s.%s", request->domain, DNS_SERVER_GROUP_LOCAL);
*request_domain = domain_buffer;
_dns_server_set_request_mdns(request);
}
if (group_name != NULL && strncmp(group_name, DNS_SERVER_GROUP_MDNS, DNS_GROUP_NAME_LEN) == 0) {
_dns_server_set_request_mdns(request);
}
break;
default:
break;
}
return 0;
}
static int _dns_server_query_dualstack(struct dns_request *request) static int _dns_server_query_dualstack(struct dns_request *request)
{ {
int ret = -1; int ret = -1;
@@ -5598,6 +5653,8 @@ static int _dns_server_do_query(struct dns_request *request, int skip_notify_eve
const char *group_name = NULL; const char *group_name = NULL;
const char *dns_group = NULL; const char *dns_group = NULL;
struct dns_query_options options; struct dns_query_options options;
char *request_domain = request->domain;
char domain_buffer[DNS_MAX_CNAME_LEN * 2];
if (request->conn) { if (request->conn) {
dns_group = request->conn->dns_group; dns_group = request->conn->dns_group;
@@ -5691,10 +5748,19 @@ static int _dns_server_do_query(struct dns_request *request, int skip_notify_eve
list_add_tail(&request->list, &server.request_list); list_add_tail(&request->list, &server.request_list);
pthread_mutex_unlock(&server.request_list_lock); pthread_mutex_unlock(&server.request_list_lock);
if (_dns_server_mdns_query_setup(request, group_name, &request_domain, domain_buffer, sizeof(domain_buffer)) != 0) {
goto errout;
}
/* if request MDNS */
if (request->is_mdns_lookup) {
group_name = DNS_SERVER_GROUP_MDNS;
}
// Get reference for DNS query // Get reference for DNS query
request->request_wait++; request->request_wait++;
_dns_server_request_get(request); _dns_server_request_get(request);
if (dns_client_query(request->domain, request->qtype, dns_server_resolve_callback, request, group_name, &options) != if (dns_client_query(request_domain, request->qtype, dns_server_resolve_callback, request, group_name, &options) !=
0) { 0) {
request->request_wait--; request->request_wait--;
_dns_server_request_release(request); _dns_server_request_release(request);
@@ -6464,7 +6530,7 @@ static int _dns_server_tcp_process_one_request(struct dns_server_conn_tcp_client
const char *content_type = http_head_get_fields_value(http_head, "Content-Type"); const char *content_type = http_head_get_fields_value(http_head, "Content-Type");
if (content_type == NULL || if (content_type == NULL ||
strncmp(content_type, "application/dns-message", sizeof("application/dns-message")) != 0) { strncasecmp(content_type, "application/dns-message", sizeof("application/dns-message")) != 0) {
tlog(TLOG_DEBUG, "content type not supported, %s", content_type); tlog(TLOG_DEBUG, "content type not supported, %s", content_type);
goto errout; goto errout;
} }

View File

@@ -218,6 +218,33 @@ int generate_addr_map(const unsigned char *addr_from, const unsigned char *addr_
return 0; return 0;
} }
int is_private_addr(const unsigned char *addr, int addr_len)
{
if (addr_len == IPV4_ADDR_LEN) {
if (addr[0] == 10) {
return 1;
}
if (addr[0] == 172 && addr[1] >= 16 && addr[1] <= 31) {
return 1;
}
if (addr[0] == 192 && addr[1] == 168) {
return 1;
}
} else if (addr_len == IPV6_ADDR_LEN) {
if (addr[0] == 0xFD) {
return 1;
}
if (addr[0] == 0xFE && addr[1] == 0x80) {
return 1;
}
}
return 0;
}
int getaddr_by_host(const char *host, struct sockaddr *addr, socklen_t *addr_len) int getaddr_by_host(const char *host, struct sockaddr *addr, socklen_t *addr_len)
{ {
struct addrinfo hints; struct addrinfo hints;

View File

@@ -64,6 +64,8 @@ int generate_random_addr(unsigned char *addr, int addr_len, int mask);
int generate_addr_map(const unsigned char *addr_from, const unsigned char *addr_to, unsigned char *addr_out, int generate_addr_map(const unsigned char *addr_from, const unsigned char *addr_to, unsigned char *addr_out,
int addr_len, int mask); int addr_len, int mask);
int is_private_addr(const unsigned char *addr, int addr_len);
int getaddr_by_host(const char *host, struct sockaddr *addr, socklen_t *addr_len); int getaddr_by_host(const char *host, struct sockaddr *addr, socklen_t *addr_len);
int getsocket_inet(int fd, struct sockaddr *addr, socklen_t *addr_len); int getsocket_inet(int fd, struct sockaddr *addr, socklen_t *addr_len);