Use dns c library if enabled
This commit is contained in:
parent
67af723087
commit
2dde385cf5
@ -42,6 +42,9 @@
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef DNS_C
|
||||
# include <dns.h>
|
||||
#else
|
||||
#ifdef WIN32
|
||||
# include <windns.h>
|
||||
# include <ws2tcpip.h>
|
||||
@ -59,6 +62,7 @@
|
||||
# include <resolv.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <jni.h>
|
||||
@ -571,10 +575,104 @@ void NetworkConfig::fillStunList(std::vector<std::pair<std::string, int> >* l,
|
||||
env->DeleteLocalRef(class_native_activity);
|
||||
env->DeleteLocalRef(native_activity);
|
||||
g_list = NULL;
|
||||
#elif defined(__SWITCH__)
|
||||
// TODO: Unclear how to get SRV records from libnx...
|
||||
return;
|
||||
#elif !defined(__CYGWIN__)
|
||||
#elif defined(DNS_C)
|
||||
int err = 0;
|
||||
struct dns_socket* so = NULL;
|
||||
struct dns_packet* ans = NULL;
|
||||
struct dns_packet* quest = NULL;
|
||||
|
||||
dns_options options = {};
|
||||
struct dns_rr_i rri = {};
|
||||
struct dns_rr rr = {};
|
||||
dns_resolv_conf* conf = dns_resconf_open(&err);
|
||||
if (!conf)
|
||||
{
|
||||
Log::error("ConnectToServer", "Error dns_resconf_open: %s",
|
||||
dns_strerror(err));
|
||||
goto cleanup;
|
||||
}
|
||||
if ((err = dns_resconf_loadpath(conf, "/etc/resolv.conf")))
|
||||
{
|
||||
err = 0;
|
||||
// Fallback name server
|
||||
SocketAddress addr("8.8.8.8:53");
|
||||
memcpy(&conf->nameserver[0], addr.getSockaddr(), addr.getSocklen());
|
||||
}
|
||||
|
||||
so = dns_so_open((sockaddr*)&conf->iface, 0, &options, &err);
|
||||
if (!so)
|
||||
{
|
||||
Log::error("ConnectToServer", "Error dns_so_open: %s",
|
||||
dns_strerror(err));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
quest = dns_p_make(512, &err);
|
||||
if (err)
|
||||
{
|
||||
Log::error("ConnectToServer", "Error dns_p_make: %s",
|
||||
dns_strerror(err));
|
||||
goto cleanup;
|
||||
}
|
||||
if ((err = dns_p_push(quest, DNS_S_QD, dns.c_str(), dns.size(),
|
||||
DNS_T_SRV, DNS_C_IN, 0, 0)))
|
||||
{
|
||||
Log::error("ConnectToServer", "Error dns_p_push: %s",
|
||||
dns_strerror(err));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
dns_header(quest)->rd = 1;
|
||||
while (!(ans = dns_so_query(so, quest, (sockaddr*)&conf->nameserver[0],
|
||||
&err)))
|
||||
{
|
||||
if (err == 0)
|
||||
{
|
||||
Log::error("ConnectToServer", "Error dns_so_query: %s",
|
||||
dns_strerror(err));
|
||||
goto cleanup;
|
||||
}
|
||||
if (dns_so_elapsed(so) > 10)
|
||||
{
|
||||
Log::error("ConnectToServer", "Timeout dns_so_query.");
|
||||
goto cleanup;
|
||||
}
|
||||
dns_so_poll(so, 1);
|
||||
}
|
||||
if (!ans)
|
||||
{
|
||||
Log::error("ConnectToServer", "Timeout dns_so_query.");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rri.sort = dns_rr_i_packet;
|
||||
err = 0;
|
||||
while (dns_rr_grep(&rr, 1, &rri, ans, &err))
|
||||
{
|
||||
if (err != 0)
|
||||
{
|
||||
Log::error("ConnectToServer", "Error dns_rr_grep: %s",
|
||||
dns_strerror(err));
|
||||
goto cleanup;
|
||||
}
|
||||
if (rr.section != DNS_S_ANSWER)
|
||||
continue;
|
||||
dns_srv srv = {};
|
||||
if (dns_srv_parse(&srv, &rr, ans) != 0)
|
||||
goto cleanup;
|
||||
std::string addr = srv.target;
|
||||
if (!addr.empty() && addr.back() == '.')
|
||||
addr.pop_back();
|
||||
l->emplace_back(addr + ":" + StringUtils::toString(srv.port),
|
||||
srv.weight);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
free(ans);
|
||||
free(quest);
|
||||
dns_so_close(so);
|
||||
dns_resconf_close(conf);
|
||||
#else
|
||||
#define SRV_WEIGHT (RRFIXEDSZ+2)
|
||||
#define SRV_PORT (RRFIXEDSZ+4)
|
||||
#define SRV_SERVER (RRFIXEDSZ+6)
|
||||
|
@ -48,6 +48,9 @@
|
||||
#include "utils/utf8/unchecked.h"
|
||||
#endif
|
||||
|
||||
#ifdef DNS_C
|
||||
# include <dns.h>
|
||||
#else
|
||||
#ifdef WIN32
|
||||
# include <windns.h>
|
||||
# include <ws2tcpip.h>
|
||||
@ -65,6 +68,7 @@
|
||||
# include <resolv.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
// ============================================================================
|
||||
@ -689,11 +693,112 @@ bool ConnectToServer::detectPort()
|
||||
if (port_from_dns != 0)
|
||||
break;
|
||||
}
|
||||
#elif defined(__SWITCH__)
|
||||
// TODO: Unclear how to use libnx in this case
|
||||
#elif !defined(__CYGWIN__)
|
||||
unsigned char response[512] = {};
|
||||
|
||||
#elif defined(DNS_C)
|
||||
const std::string& utf8name = StringUtils::wideToUtf8(m_server->getName());
|
||||
|
||||
int err = 0;
|
||||
struct dns_socket* so = NULL;
|
||||
struct dns_packet* ans = NULL;
|
||||
struct dns_packet* quest = NULL;
|
||||
|
||||
dns_options options = {};
|
||||
struct dns_rr_i rri = {};
|
||||
struct dns_rr rr = {};
|
||||
dns_resolv_conf* conf = dns_resconf_open(&err);
|
||||
if (!conf)
|
||||
{
|
||||
Log::error("ConnectToServer", "Error dns_resconf_open: %s",
|
||||
dns_strerror(err));
|
||||
goto cleanup;
|
||||
}
|
||||
if ((err = dns_resconf_loadpath(conf, "/etc/resolv.conf")))
|
||||
{
|
||||
err = 0;
|
||||
// Fallback name server
|
||||
SocketAddress addr("8.8.8.8:53");
|
||||
memcpy(&conf->nameserver[0], addr.getSockaddr(), addr.getSocklen());
|
||||
}
|
||||
|
||||
so = dns_so_open((sockaddr*)&conf->iface, 0, &options, &err);
|
||||
if (!so)
|
||||
{
|
||||
Log::error("ConnectToServer", "Error dns_so_open: %s",
|
||||
dns_strerror(err));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
quest = dns_p_make(512, &err);
|
||||
if (err)
|
||||
{
|
||||
Log::error("ConnectToServer", "Error dns_p_make: %s",
|
||||
dns_strerror(err));
|
||||
goto cleanup;
|
||||
}
|
||||
if ((err = dns_p_push(quest, DNS_S_QD, utf8name.c_str(),
|
||||
utf8name.size(),
|
||||
DNS_T_TXT, DNS_C_IN, 0, 0)))
|
||||
{
|
||||
Log::error("ConnectToServer", "Error dns_p_push: %s",
|
||||
dns_strerror(err));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
dns_header(quest)->rd = 1;
|
||||
while (!(ans = dns_so_query(so, quest, (sockaddr*)&conf->nameserver[0],
|
||||
&err)))
|
||||
{
|
||||
if (err == 0)
|
||||
{
|
||||
Log::error("ConnectToServer", "Error dns_so_query: %s",
|
||||
dns_strerror(err));
|
||||
goto cleanup;
|
||||
}
|
||||
if (dns_so_elapsed(so) > 10)
|
||||
{
|
||||
Log::error("ConnectToServer", "Timeout dns_so_query.");
|
||||
goto cleanup;
|
||||
}
|
||||
dns_so_poll(so, 1);
|
||||
}
|
||||
if (!ans)
|
||||
{
|
||||
Log::error("ConnectToServer", "Timeout dns_so_query.");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rri.sort = dns_rr_i_packet;
|
||||
err = 0;
|
||||
while (dns_rr_grep(&rr, 1, &rri, ans, &err))
|
||||
{
|
||||
if (err != 0)
|
||||
{
|
||||
Log::error("ConnectToServer", "Error dns_rr_grep: %s",
|
||||
dns_strerror(err));
|
||||
goto cleanup;
|
||||
}
|
||||
if (rr.section != DNS_S_ANSWER)
|
||||
continue;
|
||||
dns_txt txt = {};
|
||||
dns_txt_init(&txt, DNS_TXT_MINDATA);
|
||||
if (dns_txt_parse(&txt, &rr, ans) != 0)
|
||||
goto cleanup;
|
||||
std::string txt_record((char*)&txt.data, txt.len);
|
||||
port_from_dns = get_port(txt_record);
|
||||
if (port_from_dns != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
free(ans);
|
||||
free(quest);
|
||||
dns_so_close(so);
|
||||
dns_resconf_close(conf);
|
||||
|
||||
#else
|
||||
const std::string& utf8name = StringUtils::wideToUtf8(m_server->getName());
|
||||
unsigned char response[512] = {};
|
||||
|
||||
int response_len = res_query(utf8name.c_str(), C_IN, T_TXT, response, 512);
|
||||
if (response_len > 0)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user