Примеры прикладного программирования c-ares
c-ares - это библиотека асинхронного разрешения DNS. Эта статья в основном знакомит с применением c-ares в программировании на c / c ++.
Официальный сайт c-areshttps://c-ares.haxx.se/
В этой статье используется версия c-ares-1.12.0.
Пришлось несколько причесать их текст:
Код: Выделить всё
#include <cstdarg>
#include <time.h>
#include <iostream>
#include <netdb.h>
#include <arpa/inet.h>
#include <ares.h>
#include <sys/select.h>
#include <string.h>
#define IP_LEN 32
typedef struct {
char host[64];
char ip[10][IP_LEN];
int count;
} IpList;
void dns_callback (void * arg, int status, int timeouts, struct hostent * hptr) // обработка ares завершена, возвращаем информацию о разрешении DNS
{
IpList *ips = (IpList*)arg;
if( ips == NULL ) return;
if(status == ARES_SUCCESS) {
strncpy(ips->host, hptr->h_name, sizeof(ips->host));
char **pptr=hptr->h_addr_list;
for(int i=0; *pptr!=NULL && i<10; pptr++,++i) {
inet_ntop(hptr->h_addrtype, *pptr, ips->ip[ips->count++], IP_LEN);
}
} else {
std::cout << "lookup failed: " << status << std::endl;
}
}
void dns_resolve(const char* host, IpList &ips)
{
ares_channel channel; // Создаем ares_channel
int res;
if ((res = ares_init (& channel)) != ARES_SUCCESS) {// ares инициализируют канал
std::cout << "ares feiled: " << res << std::endl;
return;
}
//set dns server
ares_set_servers_csv(channel, "114.114.114.114");
//get host by name
ares_gethostbyname(channel, host, AF_INET, dns_callback, (void*)(&ips));
int nfds;
fd_set readers, writers;
timeval tv, *tvp;
while (true)
{
FD_ZERO(&readers);
FD_ZERO(&writers);
nfds = ares_fds (channel, &readers, &writers); // Получить FD, используемую каналом ares
if (nfds == 0) break;
tvp = ares_timeout(channel, NULL, &tv);
select (nfds, &readers, &writers, NULL, tvp); // Добавляем SOCKET FD площадей в цикл событий
ares_process (channel, &readers, &writers); // событие происходит и обрабатывается ares
}
ares_destroy(channel);
}
int main(int argc, char **argv)
{
if(argc < 2 ) {
std::cout << "usage: " << argv[0] << " ip.address"<< std::endl;
return 1;
}
IpList ips;
do {
memset(&ips, 0, sizeof(ips));
dns_resolve(argv[1],ips);
std::cout <<"hostname:"<< ips.host << std::endl;
for(int i=0; i < ips.count; ++i) {
std::cout<< "address ip:" << ips.ip[i] << std::endl;
}
std::cout<< std::endl;
} while(0);
std::cout << "program end.." << std::endl;
return 0;
}
Код: Выделить всё
olej@R420:~/2023/own.WORK/DNS/c-ares$ c++ c-ares-dns.cc
c-ares-dns.cc:9:10: fatal error: ares.h: Нет такого файла или каталога
9 | #include <ares.h>
| ^~~~~~~~
compilation terminated.
Нужно доустанавливать:
Код: Выделить всё
olej@R420:~$ aptitude search c-ares
p libc-ares-dev - asynchronous name resolver - development files
p libc-ares-dev:i386 - asynchronous name resolver - development files
i libc-ares2 - asynchronous name resolver
p libc-ares2:i386 - asynchronous name resolver
Код: Выделить всё
olej@R420:~/2023/own.WORK/DNS/c-ares$ sudo apt install libc-ares-dev
[sudo] пароль для olej:
Чтение списков пакетов… Готово
Построение дерева зависимостей… Готово
Чтение информации о состоянии… Готово
Следующие НОВЫЕ пакеты будут установлены:
libc-ares-dev
Обновлено 0 пакетов, установлено 1 новых пакетов, для удаления отмечено 0 пакетов, и 48 пакетов не обновлено.
Необходимо скачать 135 kB архивов.
После данной операции объём занятого дискового пространства возрастёт на 379 kB.
Пол:1 http://security.ubuntu.com/ubuntu jammy-security/main amd64 libc-ares-dev amd64 1.18.1-1ubuntu0.22.04.1 [135 kB]
Получено 135 kB за 1с (156 kB/s)
Выбор ранее не выбранного пакета libc-ares-dev:amd64.
(Чтение базы данных … на данный момент установлено 535994 файла и каталога.)
Подготовка к распаковке …/libc-ares-dev_1.18.1-1ubuntu0.22.04.1_amd64.deb …
Распаковывается libc-ares-dev:amd64 (1.18.1-1ubuntu0.22.04.1) …
Настраивается пакет libc-ares-dev:amd64 (1.18.1-1ubuntu0.22.04.1) …
Обрабатываются триггеры для man-db (2.10.2-1) …
Код: Выделить всё
olej@R420:~/2023/own.WORK/DNS/c-ares$ c++ c-ares-dns.cc -o c-ares-dns
/usr/bin/ld: /tmp/ccrO9RY9.o: в функции «dns_resolve(char const*, IpList&)»:
c-ares-dns.cc:(.text+0x140): неопределённая ссылка на «ares_init»
/usr/bin/ld: c-ares-dns.cc:(.text+0x1b0): неопределённая ссылка на «ares_set_servers_csv»
/usr/bin/ld: c-ares-dns.cc:(.text+0x1df): неопределённая ссылка на «ares_gethostbyname»
/usr/bin/ld: c-ares-dns.cc:(.text+0x27d): неопределённая ссылка на «ares_fds»
/usr/bin/ld: c-ares-dns.cc:(.text+0x2a7): неопределённая ссылка на «ares_timeout»
/usr/bin/ld: c-ares-dns.cc:(.text+0x2f8): неопределённая ссылка на «ares_process»
/usr/bin/ld: c-ares-dns.cc:(.text+0x30d): неопределённая ссылка на «ares_destroy»
collect2: error: ld returned 1 exit status
Т.е. компиляция к этому месту уже идёт без ошибок...