dnomd343
3 years ago
2 changed files with 109 additions and 109 deletions
@ -1,6 +1,6 @@ |
|||||
#ifndef _DNS_H_ |
#ifndef _DNS_H_ |
||||
#define _DNS_H_ |
#define _DNS_H_ |
||||
|
|
||||
char* dns_resolve(char *domain); |
char* dns_resolve(char *domain); |
||||
|
|
||||
#endif |
#endif |
||||
|
@ -1,103 +1,103 @@ |
|||||
#include <stdio.h> |
#include <stdio.h> |
||||
#include <stdlib.h> |
#include <stdlib.h> |
||||
#include <string.h> |
#include <string.h> |
||||
#include <netdb.h> |
#include <netdb.h> |
||||
#include <arpa/inet.h> |
#include <arpa/inet.h> |
||||
#include <sys/socket.h> |
#include <sys/socket.h> |
||||
#include <netinet/in.h> |
#include <netinet/in.h> |
||||
#include "dns.h" |
#include "dns.h" |
||||
|
|
||||
char** init_dns_result(); |
char** init_dns_result(); |
||||
char** add_dns_result(char **dns_result, char *str); |
char** add_dns_result(char **dns_result, char *str); |
||||
void free_dns_result(char **dns_result); |
void free_dns_result(char **dns_result); |
||||
char** ipv4_dns_resolve(char *domain); |
char** ipv4_dns_resolve(char *domain); |
||||
char** ipv6_dns_resolve(char *domain); |
char** ipv6_dns_resolve(char *domain); |
||||
|
|
||||
char** init_dns_result() { // 初始化DNS解析存储结构
|
char** init_dns_result() { // 初始化DNS解析存储结构
|
||||
char **dns_result = (char**)malloc(sizeof(char*)); |
char **dns_result = (char**)malloc(sizeof(char*)); |
||||
dns_result[0] = NULL; |
dns_result[0] = NULL; |
||||
return dns_result; |
return dns_result; |
||||
} |
} |
||||
|
|
||||
char** add_dns_result(char **dns_result, char *str) { // 添加DNS解析记录
|
char** add_dns_result(char **dns_result, char *str) { // 添加DNS解析记录
|
||||
int num = 0; |
int num = 0; |
||||
while(dns_result[num++] != NULL); // 获取原存储个数
|
while(dns_result[num++] != NULL); // 获取原存储个数
|
||||
dns_result = (char**)realloc(dns_result, sizeof(char**) * (num + 1)); |
dns_result = (char**)realloc(dns_result, sizeof(char**) * (num + 1)); |
||||
dns_result[num - 1] = strcpy((char*)malloc(strlen(str) + 1), str); |
dns_result[num - 1] = strcpy((char*)malloc(strlen(str) + 1), str); |
||||
dns_result[num] = NULL; // 结束标志
|
dns_result[num] = NULL; // 结束标志
|
||||
return dns_result; |
return dns_result; |
||||
} |
} |
||||
|
|
||||
void free_dns_result(char **dns_result) { // 释放DNS解析结果
|
void free_dns_result(char **dns_result) { // 释放DNS解析结果
|
||||
int num = 0; |
int num = 0; |
||||
while(dns_result[num] != NULL) { // 逐个释放
|
while(dns_result[num] != NULL) { // 逐个释放
|
||||
free(dns_result[num++]); |
free(dns_result[num++]); |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
char** ipv4_dns_resolve(char *domain) { // DNS解析IPv4地址
|
char** ipv4_dns_resolve(char *domain) { // DNS解析IPv4地址
|
||||
char **result = init_dns_result(); |
char **result = init_dns_result(); |
||||
char ip_str[16]; // IPv4地址字符串 (3 * 4 + 1 * 3 + 1)
|
char ip_str[16]; // IPv4地址字符串 (3 * 4 + 1 * 3 + 1)
|
||||
struct sockaddr_in *ipv4_addr; |
struct sockaddr_in *ipv4_addr; |
||||
struct addrinfo *answer, hint, *p; |
struct addrinfo *answer, hint, *p; |
||||
bzero(&hint, sizeof(hint)); // 清空为0x00
|
bzero(&hint, sizeof(hint)); // 清空为0x00
|
||||
hint.ai_family = AF_INET; |
hint.ai_family = AF_INET; |
||||
hint.ai_socktype = SOCK_STREAM; |
hint.ai_socktype = SOCK_STREAM; |
||||
int ret = getaddrinfo(domain, NULL, &hint, &answer); // 发起解析
|
int ret = getaddrinfo(domain, NULL, &hint, &answer); // 发起解析
|
||||
if (ret != 0) { // 解析失败
|
if (ret != 0) { // 解析失败
|
||||
printf("[Shadowsocks Bootstrap] IPv4 DNS resolve `%s`: %s\n", domain, gai_strerror(ret)); |
printf("[Shadowsocks Bootstrap] IPv4 DNS resolve `%s`: %s\n", domain, gai_strerror(ret)); |
||||
return result; // 返回空数据
|
return result; // 返回空数据
|
||||
} |
} |
||||
for (p = answer; p != NULL; p = p->ai_next) { // 遍历解析结果
|
for (p = answer; p != NULL; p = p->ai_next) { // 遍历解析结果
|
||||
ipv4_addr = (struct sockaddr_in*)(p->ai_addr); // 获取IPv4地址
|
ipv4_addr = (struct sockaddr_in*)(p->ai_addr); // 获取IPv4地址
|
||||
inet_ntop(AF_INET, &ipv4_addr->sin_addr, ip_str, sizeof(ip_str)); // 转化为字符串形式
|
inet_ntop(AF_INET, &ipv4_addr->sin_addr, ip_str, sizeof(ip_str)); // 转化为字符串形式
|
||||
result = add_dns_result(result, ip_str); |
result = add_dns_result(result, ip_str); |
||||
} |
} |
||||
freeaddrinfo(answer); // 释放解析结果
|
freeaddrinfo(answer); // 释放解析结果
|
||||
return result; |
return result; |
||||
} |
} |
||||
|
|
||||
char** ipv6_dns_resolve(char *domain) { // DNS解析IPv6地址
|
char** ipv6_dns_resolve(char *domain) { // DNS解析IPv6地址
|
||||
char **result = init_dns_result(); |
char **result = init_dns_result(); |
||||
char ip_str[40]; // IPv6地址字符串 (4 * 8 + 1 * 7 + 1)
|
char ip_str[40]; // IPv6地址字符串 (4 * 8 + 1 * 7 + 1)
|
||||
struct sockaddr_in6 *ipv6_addr; |
struct sockaddr_in6 *ipv6_addr; |
||||
struct addrinfo *answer, hint, *p; |
struct addrinfo *answer, hint, *p; |
||||
bzero(&hint, sizeof(hint)); // 清空为0x00
|
bzero(&hint, sizeof(hint)); // 清空为0x00
|
||||
hint.ai_family = AF_INET6; |
hint.ai_family = AF_INET6; |
||||
hint.ai_socktype = SOCK_STREAM; |
hint.ai_socktype = SOCK_STREAM; |
||||
int ret = getaddrinfo(domain, NULL, &hint, &answer); // 发起解析
|
int ret = getaddrinfo(domain, NULL, &hint, &answer); // 发起解析
|
||||
if (ret != 0) { // 解析失败
|
if (ret != 0) { // 解析失败
|
||||
printf("[Shadowsocks Bootstrap] IPv6 DNS resolve `%s`: %s\n", domain, gai_strerror(ret)); |
printf("[Shadowsocks Bootstrap] IPv6 DNS resolve `%s`: %s\n", domain, gai_strerror(ret)); |
||||
return result; // 返回空数据
|
return result; // 返回空数据
|
||||
} |
} |
||||
for (p = answer; p != NULL; p = p->ai_next) { // 遍历解析结果
|
for (p = answer; p != NULL; p = p->ai_next) { // 遍历解析结果
|
||||
ipv6_addr = (struct sockaddr_in6*)(p->ai_addr); // 获取IPv6地址
|
ipv6_addr = (struct sockaddr_in6*)(p->ai_addr); // 获取IPv6地址
|
||||
inet_ntop(AF_INET6, &ipv6_addr->sin6_addr, ip_str, sizeof(ip_str)); // 转化为字符串形式
|
inet_ntop(AF_INET6, &ipv6_addr->sin6_addr, ip_str, sizeof(ip_str)); // 转化为字符串形式
|
||||
result = add_dns_result(result, ip_str); |
result = add_dns_result(result, ip_str); |
||||
} |
} |
||||
freeaddrinfo(answer); // 释放解析结果
|
freeaddrinfo(answer); // 释放解析结果
|
||||
return result; |
return result; |
||||
} |
} |
||||
|
|
||||
char* dns_resolve(char *domain) { // DNS解析 返回首个IP地址 IPv4优先
|
char* dns_resolve(char *domain) { // DNS解析 返回首个IP地址 IPv4优先
|
||||
int num = 0; |
int num = 0; |
||||
char **result = init_dns_result(); |
char **result = init_dns_result(); |
||||
result = ipv4_dns_resolve(domain); // IPv4解析
|
result = ipv4_dns_resolve(domain); // IPv4解析
|
||||
while(result[num++] != NULL); // num - 1 为IPv4地址数
|
while(result[num++] != NULL); // num - 1 为IPv4地址数
|
||||
if (num - 1 != 0) { // 存在IPv4解析
|
if (num - 1 != 0) { // 存在IPv4解析
|
||||
char *tmp = strcpy((char*)malloc(strlen(result[0]) + 1), result[0]); |
char *tmp = strcpy((char*)malloc(strlen(result[0]) + 1), result[0]); |
||||
free_dns_result(result); // 释放IPv4结果
|
free_dns_result(result); // 释放IPv4结果
|
||||
return tmp; // 返回首个IPv4地址
|
return tmp; // 返回首个IPv4地址
|
||||
} |
} |
||||
free_dns_result(result); // 释放IPv4结果
|
free_dns_result(result); // 释放IPv4结果
|
||||
result = ipv6_dns_resolve(domain); |
result = ipv6_dns_resolve(domain); |
||||
num = 0; |
num = 0; |
||||
while(result[num++] != NULL); // num - 1 为IPv6地址数
|
while(result[num++] != NULL); // num - 1 为IPv6地址数
|
||||
if (num - 1 == 0) { // 无IPv6解析
|
if (num - 1 == 0) { // 无IPv6解析
|
||||
free_dns_result(result); // 释放IPv6结果
|
free_dns_result(result); // 释放IPv6结果
|
||||
return NULL; |
return NULL; |
||||
} |
} |
||||
char *tmp = strcpy((char*)malloc(strlen(result[0]) + 1), result[0]); |
char *tmp = strcpy((char*)malloc(strlen(result[0]) + 1), result[0]); |
||||
free_dns_result(result); // 释放IPv6结果
|
free_dns_result(result); // 释放IPv6结果
|
||||
return tmp; // 返回首个IPv6地址
|
return tmp; // 返回首个IPv6地址
|
||||
} |
} |
||||
|
Loading…
Reference in new issue