mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2025-02-27 23:57:06 +08:00
add support for independent dns services for multiple network devices
This commit is contained in:
parent
a0e1f954c8
commit
ef711b623d
@ -99,6 +99,10 @@
|
|||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
#ifdef RT_USING_NETDEV
|
||||||
|
#include "netdev.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Random generator function to create random TXIDs and source ports for queries */
|
/** Random generator function to create random TXIDs and source ports for queries */
|
||||||
#ifndef DNS_RAND_TXID
|
#ifndef DNS_RAND_TXID
|
||||||
#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_XID) != 0)
|
#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_XID) != 0)
|
||||||
@ -300,7 +304,9 @@ static u8_t dns_last_pcb_idx;
|
|||||||
static u8_t dns_seqno;
|
static u8_t dns_seqno;
|
||||||
static struct dns_table_entry dns_table[DNS_TABLE_SIZE];
|
static struct dns_table_entry dns_table[DNS_TABLE_SIZE];
|
||||||
static struct dns_req_entry dns_requests[DNS_MAX_REQUESTS];
|
static struct dns_req_entry dns_requests[DNS_MAX_REQUESTS];
|
||||||
|
#ifndef RT_USING_NETDEV
|
||||||
static ip_addr_t dns_servers[DNS_MAX_SERVERS];
|
static ip_addr_t dns_servers[DNS_MAX_SERVERS];
|
||||||
|
#endif
|
||||||
|
|
||||||
#if LWIP_IPV4
|
#if LWIP_IPV4
|
||||||
const ip_addr_t dns_mquery_v4group = DNS_MQUERY_IPV4_GROUP_INIT;
|
const ip_addr_t dns_mquery_v4group = DNS_MQUERY_IPV4_GROUP_INIT;
|
||||||
@ -364,21 +370,25 @@ dns_setserver(u8_t numdns, const ip_addr_t *dnsserver)
|
|||||||
{
|
{
|
||||||
if (numdns < DNS_MAX_SERVERS) {
|
if (numdns < DNS_MAX_SERVERS) {
|
||||||
if (dnsserver != NULL) {
|
if (dnsserver != NULL) {
|
||||||
dns_servers[numdns] = (*dnsserver);
|
|
||||||
|
|
||||||
#ifdef RT_USING_NETDEV
|
#ifdef RT_USING_NETDEV
|
||||||
extern struct netif *netif_list;
|
|
||||||
extern struct netdev *netdev_get_by_name(const char *name);
|
|
||||||
extern void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
|
|
||||||
struct netif *netif = NULL;
|
struct netif *netif = NULL;
|
||||||
|
|
||||||
/* set network interface device DNS server address */
|
/* set network interface device DNS server address */
|
||||||
for (netif = netif_list; netif != NULL; netif = netif->next) {
|
for (netif = netif_list; netif != NULL; netif = netif->next) {
|
||||||
netdev_low_level_set_dns_server(netdev_get_by_name(netif->name), numdns, dnsserver);
|
netdev_set_dns_server(netdev_get_by_name(netif->name), numdns, dnsserver);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
dns_servers[numdns] = (*dnsserver);
|
||||||
#endif /* RT_USING_NETDEV */
|
#endif /* RT_USING_NETDEV */
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef RT_USING_NETDEV
|
||||||
|
struct netif *netif = NULL;
|
||||||
|
for (netif = netif_list; netif != NULL; netif = netif->next) {
|
||||||
|
netdev_set_dns_server(netdev_get_by_name(netif->name), numdns, IP_ADDR_ANY);
|
||||||
|
}
|
||||||
|
#else
|
||||||
dns_servers[numdns] = *IP_ADDR_ANY;
|
dns_servers[numdns] = *IP_ADDR_ANY;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -395,7 +405,11 @@ const ip_addr_t *
|
|||||||
dns_getserver(u8_t numdns)
|
dns_getserver(u8_t numdns)
|
||||||
{
|
{
|
||||||
if (numdns < DNS_MAX_SERVERS) {
|
if (numdns < DNS_MAX_SERVERS) {
|
||||||
|
#ifdef RT_USING_NETDEV
|
||||||
|
return &netdev_default->dns_servers[numdns];
|
||||||
|
#else
|
||||||
return &dns_servers[numdns];
|
return &dns_servers[numdns];
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
return IP_ADDR_ANY;
|
return IP_ADDR_ANY;
|
||||||
}
|
}
|
||||||
@ -770,11 +784,19 @@ dns_send(u8_t idx)
|
|||||||
u8_t n;
|
u8_t n;
|
||||||
u8_t pcb_idx;
|
u8_t pcb_idx;
|
||||||
struct dns_table_entry *entry = &dns_table[idx];
|
struct dns_table_entry *entry = &dns_table[idx];
|
||||||
|
const ip_addr_t *dns_addr;
|
||||||
|
|
||||||
LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n",
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n",
|
||||||
(u16_t)(entry->server_idx), entry->name));
|
(u16_t)(entry->server_idx), entry->name));
|
||||||
LWIP_ASSERT("dns server out of array", entry->server_idx < DNS_MAX_SERVERS);
|
LWIP_ASSERT("dns server out of array", entry->server_idx < DNS_MAX_SERVERS);
|
||||||
if (ip_addr_isany_val(dns_servers[entry->server_idx])
|
|
||||||
|
#ifdef RT_USING_NETDEV
|
||||||
|
dns_addr = &netdev_default->dns_servers[entry->server_idx];
|
||||||
|
#else
|
||||||
|
dns_addr = &dns_servers[entry->server_idx];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ip_addr_isany(dns_addr)
|
||||||
#if LWIP_DNS_SUPPORT_MDNS_QUERIES
|
#if LWIP_DNS_SUPPORT_MDNS_QUERIES
|
||||||
&& !entry->is_mdns
|
&& !entry->is_mdns
|
||||||
#endif
|
#endif
|
||||||
@ -859,7 +881,11 @@ dns_send(u8_t idx)
|
|||||||
#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */
|
#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */
|
||||||
{
|
{
|
||||||
dst_port = DNS_SERVER_PORT;
|
dst_port = DNS_SERVER_PORT;
|
||||||
dst = &dns_servers[entry->server_idx];
|
dst = dns_addr;
|
||||||
|
#ifdef RT_USING_NETDEV
|
||||||
|
/* set netif index for this pcb, specify the network interface corresponding to the DNS server */
|
||||||
|
dns_pcbs[pcb_idx]->netif_idx = netif_get_index((struct netif *)netdev_default->user_data);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
err = udp_sendto(dns_pcbs[pcb_idx], p, dst, dst_port);
|
err = udp_sendto(dns_pcbs[pcb_idx], p, dst, dst_port);
|
||||||
|
|
||||||
@ -1040,8 +1066,15 @@ dns_backupserver_available(struct dns_table_entry *pentry)
|
|||||||
u8_t ret = 0;
|
u8_t ret = 0;
|
||||||
|
|
||||||
if (pentry) {
|
if (pentry) {
|
||||||
if ((pentry->server_idx + 1 < DNS_MAX_SERVERS) && !ip_addr_isany_val(dns_servers[pentry->server_idx + 1])) {
|
if ((pentry->server_idx + 1 < DNS_MAX_SERVERS)) {
|
||||||
ret = 1;
|
#ifdef RT_USING_NETDEV
|
||||||
|
const ip_addr_t *dns_addr = &netdev_default->dns_servers[pentry->server_idx + 1];
|
||||||
|
#else
|
||||||
|
const ip_addr_t *dns_addr = &dns_servers[pentry->server_idx + 1];
|
||||||
|
#endif
|
||||||
|
if (!ip_addr_isany(dns_addr)) {
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1230,9 +1263,14 @@ dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr,
|
|||||||
if (!entry->is_mdns)
|
if (!entry->is_mdns)
|
||||||
#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */
|
#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */
|
||||||
{
|
{
|
||||||
|
#ifdef RT_USING_NETDEV
|
||||||
|
const ip_addr_t *dns_addr = &netdev_default->dns_servers[entry->server_idx];
|
||||||
|
#else
|
||||||
|
const ip_addr_t *dns_addr = &dns_servers[entry->server_idx];
|
||||||
|
#endif
|
||||||
/* Check whether response comes from the same network address to which the
|
/* Check whether response comes from the same network address to which the
|
||||||
question was sent. (RFC 5452) */
|
question was sent. (RFC 5452) */
|
||||||
if (!ip_addr_cmp(addr, &dns_servers[entry->server_idx])) {
|
if (!ip_addr_cmp(addr, dns_addr)) {
|
||||||
goto ignore_packet; /* ignore this packet */
|
goto ignore_packet; /* ignore this packet */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1631,8 +1669,13 @@ dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, dns_found_call
|
|||||||
if (!is_mdns)
|
if (!is_mdns)
|
||||||
#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */
|
#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */
|
||||||
{
|
{
|
||||||
|
#ifdef RT_USING_NETDEV
|
||||||
|
const ip_addr_t *dns_addr = &netdev_default->dns_servers[0];
|
||||||
|
#else
|
||||||
|
const ip_addr_t *dns_addr = &dns_servers[0];
|
||||||
|
#endif
|
||||||
/* prevent calling found callback if no server is set, return error instead */
|
/* prevent calling found callback if no server is set, return error instead */
|
||||||
if (ip_addr_isany_val(dns_servers[0])) {
|
if (ip_addr_isany(dns_addr)) {
|
||||||
return ERR_VAL;
|
return ERR_VAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -673,7 +673,16 @@ dhcp_handle_ack(struct netif *netif, struct dhcp_msg *msg_in)
|
|||||||
for (n = 0; (n < LWIP_DHCP_PROVIDE_DNS_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n); n++) {
|
for (n = 0; (n < LWIP_DHCP_PROVIDE_DNS_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n); n++) {
|
||||||
ip_addr_t dns_addr;
|
ip_addr_t dns_addr;
|
||||||
ip_addr_set_ip4_u32_val(dns_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n)));
|
ip_addr_set_ip4_u32_val(dns_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n)));
|
||||||
|
#ifdef RT_USING_NETDEV
|
||||||
|
extern struct netdev *netdev_get_by_name(const char *name);
|
||||||
|
extern void netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
|
||||||
|
/* Here we only need to set the dns server of the corresponding network device,
|
||||||
|
* but do not need to configure all network devices.
|
||||||
|
*/
|
||||||
|
netdev_set_dns_server(netdev_get_by_name(netif->name), n, &dns_addr);
|
||||||
|
#else
|
||||||
dns_setserver(n, &dns_addr);
|
dns_setserver(n, &dns_addr);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
|
#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
|
||||||
}
|
}
|
||||||
|
@ -538,7 +538,16 @@ dhcp6_handle_config_reply(struct netif *netif, struct pbuf *p_msg_in)
|
|||||||
}
|
}
|
||||||
ip6_addr_assign_zone(dns_addr6, IP6_UNKNOWN, netif);
|
ip6_addr_assign_zone(dns_addr6, IP6_UNKNOWN, netif);
|
||||||
/* @todo: do we need a different offset than DHCP(v4)? */
|
/* @todo: do we need a different offset than DHCP(v4)? */
|
||||||
|
#ifdef RT_USING_NETDEV
|
||||||
|
extern struct netdev *netdev_get_by_name(const char *name);
|
||||||
|
extern void netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
|
||||||
|
/* Here we only need to set the dns server of the corresponding network device,
|
||||||
|
* but do not need to configure all network devices.
|
||||||
|
*/
|
||||||
|
netdev_set_dns_server(netdev_get_by_name(netif->name), n, &dns_addr);
|
||||||
|
#else
|
||||||
dns_setserver(n, &dns_addr);
|
dns_setserver(n, &dns_addr);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* @ todo: parse and set Domain Search List */
|
/* @ todo: parse and set Domain Search List */
|
||||||
|
@ -776,14 +776,32 @@ nd6_input(struct pbuf *p, struct netif *inp)
|
|||||||
|
|
||||||
if (htonl(rdnss_opt->lifetime) > 0) {
|
if (htonl(rdnss_opt->lifetime) > 0) {
|
||||||
/* TODO implement Lifetime > 0 */
|
/* TODO implement Lifetime > 0 */
|
||||||
|
#ifdef RT_USING_NETDEV
|
||||||
|
extern struct netdev *netdev_get_by_name(const char *name);
|
||||||
|
extern void netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
|
||||||
|
/* Here we only need to set the dns server of the corresponding network device,
|
||||||
|
* but do not need to configure all network devices.
|
||||||
|
*/
|
||||||
|
netdev_set_dns_server(netdev_get_by_name(inp->name), rdnss_server_idx++, &rdnss_address);
|
||||||
|
#else
|
||||||
dns_setserver(rdnss_server_idx++, &rdnss_address);
|
dns_setserver(rdnss_server_idx++, &rdnss_address);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
/* TODO implement DNS removal in dns.c */
|
/* TODO implement DNS removal in dns.c */
|
||||||
u8_t s;
|
u8_t s;
|
||||||
for (s = 0; s < DNS_MAX_SERVERS; s++) {
|
for (s = 0; s < DNS_MAX_SERVERS; s++) {
|
||||||
const ip_addr_t *addr = dns_getserver(s);
|
const ip_addr_t *addr = dns_getserver(s);
|
||||||
if(ip_addr_cmp(addr, &rdnss_address)) {
|
if(ip_addr_cmp(addr, &rdnss_address)) {
|
||||||
dns_setserver(s, NULL);
|
#ifdef RT_USING_NETDEV
|
||||||
|
extern struct netdev *netdev_get_by_name(const char *name);
|
||||||
|
extern void netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
|
||||||
|
/* Here we only need to set the dns server of the corresponding network device,
|
||||||
|
* but do not need to configure all network devices.
|
||||||
|
*/
|
||||||
|
netdev_set_dns_server(netdev_get_by_name(inp->name), s, IP_ADDR_ANY);
|
||||||
|
#else
|
||||||
|
dns_setserver(s, IP_ADDR_ANY);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,8 @@
|
|||||||
*
|
*
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* REVISION HISTORY
|
* REVISION HISTORY
|
||||||
*
|
* 24-09-12 Evlers <1425295900@qq.com>
|
||||||
|
* add support for independent dns services for multiple network devices
|
||||||
* 03-01-01 Marc Boucher <marc@mbsi.ca>
|
* 03-01-01 Marc Boucher <marc@mbsi.ca>
|
||||||
* Ported to lwIP.
|
* Ported to lwIP.
|
||||||
* 97-11-05 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
|
* 97-11-05 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
|
||||||
@ -134,6 +135,9 @@
|
|||||||
#if PPP_IPV6_SUPPORT
|
#if PPP_IPV6_SUPPORT
|
||||||
#include "netif/ppp/ipv6cp.h"
|
#include "netif/ppp/ipv6cp.h"
|
||||||
#endif /* PPP_IPV6_SUPPORT */
|
#endif /* PPP_IPV6_SUPPORT */
|
||||||
|
#ifdef RT_USING_NETDEV
|
||||||
|
#include "netdev.h"
|
||||||
|
#endif /* RT_USING_NETDEV */
|
||||||
|
|
||||||
/*************************/
|
/*************************/
|
||||||
/*** LOCAL DEFINITIONS ***/
|
/*** LOCAL DEFINITIONS ***/
|
||||||
@ -1109,9 +1113,20 @@ int sdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) {
|
|||||||
LWIP_UNUSED_ARG(pcb);
|
LWIP_UNUSED_ARG(pcb);
|
||||||
|
|
||||||
ip_addr_set_ip4_u32_val(ns, ns1);
|
ip_addr_set_ip4_u32_val(ns, ns1);
|
||||||
|
#ifdef RT_USING_NETDEV
|
||||||
|
/* Here we only need to set the dns server of the corresponding network device,
|
||||||
|
* but do not need to configure all network cards.
|
||||||
|
*/
|
||||||
|
netdev_set_dns_server(netdev_get_by_name(pcb->netif->name), 0, &ns);
|
||||||
|
#else
|
||||||
dns_setserver(0, &ns);
|
dns_setserver(0, &ns);
|
||||||
|
#endif
|
||||||
ip_addr_set_ip4_u32_val(ns, ns2);
|
ip_addr_set_ip4_u32_val(ns, ns2);
|
||||||
|
#ifdef RT_USING_NETDEV
|
||||||
|
netdev_set_dns_server(netdev_get_by_name(pcb->netif->name), 1, &ns);
|
||||||
|
#else
|
||||||
dns_setserver(1, &ns);
|
dns_setserver(1, &ns);
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1127,12 +1142,20 @@ int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) {
|
|||||||
nsa = dns_getserver(0);
|
nsa = dns_getserver(0);
|
||||||
ip_addr_set_ip4_u32_val(nsb, ns1);
|
ip_addr_set_ip4_u32_val(nsb, ns1);
|
||||||
if (ip_addr_cmp(nsa, &nsb)) {
|
if (ip_addr_cmp(nsa, &nsb)) {
|
||||||
|
#ifdef RT_USING_NETDEV
|
||||||
|
netdev_set_dns_server(netdev_get_by_name(pcb->netif->name), 0, IP_ADDR_ANY);
|
||||||
|
#else
|
||||||
dns_setserver(0, IP_ADDR_ANY);
|
dns_setserver(0, IP_ADDR_ANY);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
nsa = dns_getserver(1);
|
nsa = dns_getserver(1);
|
||||||
ip_addr_set_ip4_u32_val(nsb, ns2);
|
ip_addr_set_ip4_u32_val(nsb, ns2);
|
||||||
if (ip_addr_cmp(nsa, &nsb)) {
|
if (ip_addr_cmp(nsa, &nsb)) {
|
||||||
|
#ifdef RT_USING_NETDEV
|
||||||
|
netdev_set_dns_server(netdev_get_by_name(pcb->netif->name), 1, IP_ADDR_ANY);
|
||||||
|
#else
|
||||||
dns_setserver(1, IP_ADDR_ANY);
|
dns_setserver(1, IP_ADDR_ANY);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
* 2018-11-02 MurphyZhao port to lwIP 2.1.0
|
* 2018-11-02 MurphyZhao port to lwIP 2.1.0
|
||||||
* 2021-09-07 Grissiom fix eth_tx_msg ack bug
|
* 2021-09-07 Grissiom fix eth_tx_msg ack bug
|
||||||
* 2022-02-22 xiangxistu integrate v1.4.1 v2.0.3 and v2.1.2 porting layer
|
* 2022-02-22 xiangxistu integrate v1.4.1 v2.0.3 and v2.1.2 porting layer
|
||||||
|
* 2024-09-12 Evlers add support for independent dns services for multiple network devices
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -169,8 +170,11 @@ static int lwip_netdev_set_addr_info(struct netdev *netif, ip_addr_t *ip_addr, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_LWIP_DNS
|
#ifdef RT_LWIP_DNS
|
||||||
static int lwip_netdev_set_dns_server(struct netdev *netif, uint8_t dns_num, ip_addr_t *dns_server)
|
static int lwip_netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, ip_addr_t *dns_server)
|
||||||
{
|
{
|
||||||
|
#if RT_USING_LWIP_VER_NUM >= 0x20102
|
||||||
|
netdev_low_level_set_dns_server(netdev, dns_num, dns_server);
|
||||||
|
#else
|
||||||
#if LWIP_VERSION_MAJOR == 1U /* v1.x */
|
#if LWIP_VERSION_MAJOR == 1U /* v1.x */
|
||||||
extern void dns_setserver(u8_t numdns, ip_addr_t *dnsserver);
|
extern void dns_setserver(u8_t numdns, ip_addr_t *dnsserver);
|
||||||
#else /* >=2.x */
|
#else /* >=2.x */
|
||||||
@ -178,6 +182,7 @@ static int lwip_netdev_set_dns_server(struct netdev *netif, uint8_t dns_num, ip_
|
|||||||
#endif /* LWIP_VERSION_MAJOR == 1U */
|
#endif /* LWIP_VERSION_MAJOR == 1U */
|
||||||
|
|
||||||
dns_setserver(dns_num, dns_server);
|
dns_setserver(dns_num, dns_server);
|
||||||
|
#endif /* RT_USING_LWIP_VER_NUM >= 0x20102 */
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
#endif /* RT_LWIP_DNS */
|
#endif /* RT_LWIP_DNS */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user