Ai
1 Star 0 Fork 0

wangcichen/urbackup_backend

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
LookupService.cpp 6.90 KB
一键复制 编辑 原始数据 按行查看 历史
Martin 提交于 2020-02-13 01:25 +08:00 . Shortcut localhost to 127.0.0.1 in c-ares lookup
/*************************************************************************
* UrBackup - Client/Server backup system
* Copyright (C) 2011-2016 Martin Raiber
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/
#include "socket_header.h"
#include <string>
#ifndef _WIN32
#include <memory.h>
#include "LookupService.h"
#endif
#include "LookupService.h"
#include <iostream>
#include <algorithm>
#ifdef ENABLE_C_ARES
#include <ares.h>
#include "Server.h"
#endif
std::vector<SLookupBlockingResult> LookupBlocking(std::string pServer)
{
const char* host = pServer.c_str();
unsigned int addr = inet_addr(host);
if (addr != INADDR_NONE)
{
SLookupBlockingResult res;
res.zone = 0;
res.is_ipv6 = false;
res.addr_v4 = addr;
std::vector<SLookupBlockingResult> ret;
ret.push_back(res);
return ret;
}
addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
std::vector<SLookupBlockingResult> ret;
addrinfo* h;
if (getaddrinfo(pServer.c_str(), NULL, &hints, &h) == 0)
{
addrinfo* orig_h = h;
while (h != NULL)
{
if (h->ai_family != AF_INET6
&& h->ai_family != AF_INET)
{
h = h->ai_next;
continue;
}
if (h->ai_family == AF_INET6)
{
if (h->ai_addrlen >= sizeof(sockaddr_in6))
{
SLookupBlockingResult dest;
dest.is_ipv6 = true;
memcpy(dest.addr_v6, &reinterpret_cast<sockaddr_in6*>(h->ai_addr)->sin6_addr, 16);
dest.zone = reinterpret_cast<sockaddr_in6*>(h->ai_addr)->sin6_scope_id;
ret.push_back(dest);
}
}
else
{
if (h->ai_addrlen >= sizeof(sockaddr_in))
{
SLookupBlockingResult dest;
dest.zone = 0;
dest.is_ipv6 = false;
dest.addr_v4 = reinterpret_cast<sockaddr_in*>(h->ai_addr)->sin_addr.s_addr;
ret.push_back(dest);
}
}
h = h->ai_next;
}
freeaddrinfo(orig_h);
return ret;
}
else
{
return ret;
}
}
#ifdef ENABLE_C_ARES
void addrinfo_callback(void *arg,
int status,
int timeouts,
struct ares_addrinfo *res)
{
std::vector<SLookupBlockingResult>* ret
= reinterpret_cast<std::vector<SLookupBlockingResult>*>(arg);
if (status == ARES_SUCCESS
&& res!=NULL)
{
ares_addrinfo_node* h = res->nodes;
while (h != NULL)
{
if (h->ai_family != AF_INET6
&& h->ai_family != AF_INET)
{
h = h->ai_next;
continue;
}
if (h->ai_family == AF_INET6)
{
if (h->ai_addrlen >= sizeof(sockaddr_in6))
{
SLookupBlockingResult dest;
dest.is_ipv6 = true;
memcpy(dest.addr_v6, &reinterpret_cast<sockaddr_in6*>(h->ai_addr)->sin6_addr, 16);
dest.zone = reinterpret_cast<sockaddr_in6*>(h->ai_addr)->sin6_scope_id;
ret->push_back(dest);
}
}
else
{
if (h->ai_addrlen >= sizeof(sockaddr_in))
{
SLookupBlockingResult dest;
dest.zone = 0;
dest.is_ipv6 = false;
dest.addr_v4 = reinterpret_cast<sockaddr_in*>(h->ai_addr)->sin_addr.s_addr;
ret->push_back(dest);
}
}
h = h->ai_next;
}
}
}
bool LookupInit()
{
int rc = ares_library_init(ARES_LIB_INIT_ALL);
if (rc != ARES_SUCCESS)
{
std::cerr << "C-ares initialization failed with code " << ares_strerror(rc) << std::endl;
return false;
}
return true;
}
std::vector<SLookupBlockingResult> LookupWithTimeout(std::string pServer, int timeoutms, int stop_timeoutms)
{
if (pServer == "localhost")
{
pServer = "127.0.0.1";
}
unsigned int addr = inet_addr(pServer.c_str());
if (addr != INADDR_NONE)
{
SLookupBlockingResult res;
res.zone = 0;
res.is_ipv6 = false;
res.addr_v4 = addr;
std::vector<SLookupBlockingResult> ret;
ret.push_back(res);
return ret;
}
ares_channel channel;
struct ares_options options = {};
int rc = ares_init_options(&channel, &options, 0);
if (rc != ARES_SUCCESS)
{
return std::vector<SLookupBlockingResult>();
}
ares_addrinfo_hints hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
std::vector<SLookupBlockingResult> ret;
ares_getaddrinfo(channel, pServer.c_str(), NULL, &hints, addrinfo_callback, &ret);
int nfds, count;
fd_set readers, writers;
timeval maxtv;
maxtv.tv_sec = (std::min)(stop_timeoutms, timeoutms) / 1000;
maxtv.tv_usec = ((std::min)(stop_timeoutms, timeoutms) % 1000) * 1000;
int64 starttime = Server->getTimeMS();
do
{
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
rc = ares_getsock(channel, socks, ARES_GETSOCK_MAXNUM);
pollfd conn[ARES_GETSOCK_MAXNUM];
bool has_fd = false;
for (int i = 0; i < ARES_GETSOCK_MAXNUM; ++i)
{
conn[i].fd = -1;
conn[i].events = 0;
conn[i].revents = 0;
if (ARES_GETSOCK_READABLE(rc, i))
{
has_fd = true;
conn[i].fd = socks[i];
conn[i].events = POLLIN;
}
if (ARES_GETSOCK_WRITABLE(rc, i))
{
has_fd = true;
conn[i].fd = socks[i];
conn[i].events |= POLLOUT;
}
}
if (!has_fd)
break;
struct timeval tv;
ares_timeout(channel, &maxtv, &tv);
rc = poll(conn, ARES_GETSOCK_MAXNUM, tv.tv_sec*1000+tv.tv_usec/1000);
if (rc == -1)
break;
for (int i = 0; i < ARES_GETSOCK_MAXNUM; ++i)
{
if (conn[i].revents > 0)
{
ares_process_fd(channel, (conn[i].events & POLLIN) ? conn[i].fd : ARES_SOCKET_BAD,
(conn[i].events & POLLOUT) ? conn[i].fd : ARES_SOCKET_BAD);
}
}
if (!ret.empty()
&& Server->getTimeMS() - starttime >= stop_timeoutms)
{
break;
}
} while (Server->getTimeMS() - starttime < timeoutms);
ares_destroy(channel);
return ret;
}
#endif
bool LookupHostname(const std::string & pIp, std::string& hostname)
{
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_addr.s_addr = inet_addr(pIp.c_str());
if (addr.sin_addr.s_addr == INADDR_NONE)
{
return false;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(80);
char buf[NI_MAXHOST];
int rc = getnameinfo(reinterpret_cast<sockaddr*>(&addr), sizeof(addr), buf, sizeof(buf), NULL, 0, NI_NAMEREQD);
if (rc == 0)
{
hostname = buf;
}
return rc == 0;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C
1
https://gitee.com/wangcichen/urbackup_backend.git
git@gitee.com:wangcichen/urbackup_backend.git
wangcichen
urbackup_backend
urbackup_backend
dev

搜索帮助