Update code

This commit is contained in:
Nick Peng
2018-06-02 18:13:02 +08:00
parent c0c7b8f811
commit 3dca337e24
4 changed files with 174 additions and 174 deletions

217
dns.c
View File

@@ -457,7 +457,7 @@ static inline int _dns_left_len(struct dns_context *context)
return context->maxsize - (context->ptr - context->data);
}
int _dns_decode_head(struct dns_context *context)
static int _dns_decode_head(struct dns_context *context)
{
unsigned int fields;
int len = 12;
@@ -484,7 +484,7 @@ int _dns_decode_head(struct dns_context *context)
return 0;
}
int _dns_encode_head(struct dns_context *context)
static int _dns_encode_head(struct dns_context *context)
{
int len = 12;
struct dns_head *head = &context->packet->head;
@@ -512,7 +512,7 @@ int _dns_encode_head(struct dns_context *context)
return len;
}
int _dns_decode_domain(struct dns_context *context, char *output, int size)
static int _dns_decode_domain(struct dns_context *context, char *output, int size)
{
int output_len = 0;
int copy_len = 0;
@@ -577,7 +577,7 @@ int _dns_decode_domain(struct dns_context *context, char *output, int size)
return 0;
}
int _dns_encode_domain(struct dns_context *context, char *domain)
static int _dns_encode_domain(struct dns_context *context, char *domain)
{
int num = 0;
unsigned char *ptr_num = context->ptr++;
@@ -603,7 +603,7 @@ int _dns_encode_domain(struct dns_context *context, char *domain)
return 0;
}
int _dns_decode_qr_head(struct dns_context *context, char *domain, int domain_size, int *qtype, int *qclass)
static int _dns_decode_qr_head(struct dns_context *context, char *domain, int domain_size, int *qtype, int *qclass)
{
int ret = 0;
@@ -624,7 +624,7 @@ int _dns_decode_qr_head(struct dns_context *context, char *domain, int domain_si
return 0;
}
int _dns_encode_qr_head(struct dns_context *context, char *domain, int qtype, int qclass)
static int _dns_encode_qr_head(struct dns_context *context, char *domain, int qtype, int qclass)
{
int ret = 0;
ret = _dns_encode_domain(context, domain);
@@ -642,7 +642,7 @@ int _dns_encode_qr_head(struct dns_context *context, char *domain, int qtype, in
return 0;
}
int _dns_decode_rr_head(struct dns_context *context, char *domain, int domain_size, int *qtype, int *qclass, int *ttl, int *rr_len)
static int _dns_decode_rr_head(struct dns_context *context, char *domain, int domain_size, int *qtype, int *qclass, int *ttl, int *rr_len)
{
int len = 0;
@@ -663,7 +663,7 @@ int _dns_decode_rr_head(struct dns_context *context, char *domain, int domain_si
return 0;
}
int _dns_encode_rr_head(struct dns_context *context, char *domain, int qtype, int qclass, int ttl, int rr_len)
static int _dns_encode_rr_head(struct dns_context *context, char *domain, int qtype, int qclass, int ttl, int rr_len)
{
int ret = 0;
ret = _dns_encode_qr_head(context, domain, qtype, qclass);
@@ -681,6 +681,53 @@ int _dns_encode_rr_head(struct dns_context *context, char *domain, int qtype, in
return 0;
}
static int _dns_encode_raw(struct dns_context *context, struct dns_rrs *rrs)
{
int ret;
int qtype = 0;
int qclass = 0;
int ttl = 0;
char domain[DNS_MAX_CNAME_LEN];
int rr_len;
struct dns_data_context data_context;
data_context.data = rrs->data;
data_context.ptr = rrs->data;
data_context.maxsize = rrs->len;
ret = _dns_get_rr_head(&data_context, domain, DNS_MAX_CNAME_LEN, &qtype, &qclass, &ttl, &rr_len);
if (ret < 0) {
return -1;
}
ret = _dns_encode_rr_head(context, domain, qtype, qclass, ttl, rr_len);
if (ret < 0) {
return -1;
}
if (_dns_left_len(context) < rr_len) {
return -1;
}
memcpy(context->ptr, data_context.ptr, rr_len);
context->ptr += rr_len;
data_context.ptr += rr_len;
return 0;
}
static int _dns_decode_raw(struct dns_context *context, unsigned char *raw, int len)
{
if (_dns_left_len(context) < len) {
return -1;
}
memcpy(raw, context->ptr, len);
context->ptr += len;
return 0;
}
int _dns_decode_CNAME(struct dns_context *context, char *cname, int cname_size)
{
int ret = 0;
@@ -724,141 +771,13 @@ int _dns_encode_CNAME(struct dns_context *context, struct dns_rrs *rrs)
if (ret < 0) {
return -1;
}
data_context.ptr += strnlen((char*)(data_context.ptr), DNS_MAX_CNAME_LEN) + 1;
return 0;
}
int _dns_decode_A(struct dns_context *context, unsigned char addr[4])
{
if (_dns_left_len(context) < DNS_RR_A_LEN) {
return -1;
}
memcpy(addr, context->ptr, DNS_RR_A_LEN);
context->ptr += DNS_RR_A_LEN;
return 0;
}
int _dns_encode_A(struct dns_context *context, struct dns_rrs *rrs)
{
int ret;
int qtype = 0;
int qclass = 0;
int ttl = 0;
char domain[DNS_MAX_CNAME_LEN];
int rr_len;
struct dns_data_context data_context;
data_context.data = rrs->data;
data_context.ptr = rrs->data;
data_context.maxsize = rrs->len;
ret = _dns_get_rr_head(&data_context, domain, DNS_MAX_CNAME_LEN, &qtype, &qclass, &ttl, &rr_len);
if (ret < 0) {
return -1;
}
if (rr_len != DNS_RR_A_LEN) {
return -1;
}
ret = _dns_encode_rr_head(context, domain, qtype, qclass, ttl, DNS_RR_A_LEN);
if (ret < 0) {
return -1;
}
if (_dns_left_len(context) < DNS_RR_A_LEN) {
return -1;
}
memcpy(context->ptr, data_context.ptr, DNS_RR_A_LEN);
context->ptr += DNS_RR_A_LEN;
data_context.ptr += DNS_RR_A_LEN;
return 0;
}
int _dns_decode_PTR(struct dns_context *context, char *name, int name_size)
{
int ret;
ret = _dns_decode_domain(context, name, name_size);
return ret;
}
int _dns_encode_PTR(struct dns_context *context, struct dns_rrs *rrs)
{
return _dns_encode_CNAME(context, rrs);
}
int _dns_decode_AAAA(struct dns_context *context, unsigned char addr[DNS_RR_AAAA_LEN])
{
if (_dns_left_len(context) < DNS_RR_AAAA_LEN) {
return -1;
}
memcpy(addr, context->ptr, DNS_RR_AAAA_LEN);
context->ptr += DNS_RR_AAAA_LEN;
return 0;
}
int _dns_encode_AAAA(struct dns_context *context, struct dns_rrs *rrs)
{
int ret;
int qtype = 0;
int qclass = 0;
int ttl = 0;
char domain[DNS_MAX_CNAME_LEN];
int rr_len;
struct dns_data_context data_context;
data_context.data = rrs->data;
data_context.ptr = rrs->data;
data_context.maxsize = rrs->len;
ret = _dns_get_rr_head(&data_context, domain, DNS_MAX_CNAME_LEN, &qtype, &qclass, &ttl, &rr_len);
if (ret < 0) {
return -1;
}
if (rr_len != DNS_RR_AAAA_LEN) {
return -1;
}
ret = _dns_encode_rr_head(context, domain, qtype, qclass, ttl, DNS_RR_AAAA_LEN);
if (ret < 0) {
return -1;
}
if (_dns_left_len(context) < DNS_RR_AAAA_LEN) {
return -1;
}
memcpy(context->ptr, data_context.ptr, DNS_RR_AAAA_LEN);
context->ptr += DNS_RR_AAAA_LEN;
data_context.ptr += DNS_RR_AAAA_LEN;
return 0;
}
int _dns_decode_NS(struct dns_context *context, unsigned char addr[4])
{
if (_dns_left_len(context) < DNS_RR_A_LEN) {
return -1;
}
memcpy(addr, context->ptr, DNS_RR_A_LEN);
context->ptr += DNS_RR_A_LEN;
return 0;
}
int _dns_encode_NS(struct dns_context *context, struct dns_rrs *rrs)
{
return _dns_encode_CNAME(context, rrs);
}
int _dns_decode_qd(struct dns_context *context)
static int _dns_decode_qd(struct dns_context *context)
{
struct dns_packet *packet = context->packet;
int len;
@@ -879,7 +798,7 @@ int _dns_decode_qd(struct dns_context *context)
return 0;
}
int _dns_decode_an(struct dns_context *context, dns_rr_type type)
static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
{
int ret;
int qtype = 0;
@@ -900,7 +819,7 @@ int _dns_decode_an(struct dns_context *context, dns_rr_type type)
switch (qtype) {
case DNS_T_A: {
unsigned char addr[DNS_RR_A_LEN];
ret = _dns_decode_A(context, addr);
ret = _dns_decode_raw(context, addr, sizeof(addr));
if (ret < 0) {
tlog(TLOG_ERROR, "decode A failed, %s", domain);
return -1;
@@ -942,7 +861,7 @@ int _dns_decode_an(struct dns_context *context, dns_rr_type type)
} break;
case DNS_T_PTR: {
char name[DNS_MAX_CNAME_LEN];
ret = _dns_decode_PTR(context, name, DNS_MAX_CNAME_LEN);
ret = _dns_decode_CNAME(context, name, DNS_MAX_CNAME_LEN);
if (ret < 0) {
tlog(TLOG_ERROR, "decode PTR failed, %s", domain);
return -1;
@@ -956,7 +875,7 @@ int _dns_decode_an(struct dns_context *context, dns_rr_type type)
} break;
case DNS_T_AAAA: {
unsigned char addr[DNS_RR_AAAA_LEN];
ret = _dns_decode_AAAA(context, addr);
ret = _dns_decode_raw(context, addr, sizeof(addr));
if (ret < 0) {
tlog(TLOG_ERROR, "decode AAAA failed, %s", domain);
return -1;
@@ -982,7 +901,7 @@ int _dns_decode_an(struct dns_context *context, dns_rr_type type)
return 0;
}
int _dns_encode_qd(struct dns_context *context, struct dns_rrs *rrs)
static int _dns_encode_qd(struct dns_context *context, struct dns_rrs *rrs)
{
int ret;
int qtype = 0;
@@ -1007,24 +926,24 @@ int _dns_encode_qd(struct dns_context *context, struct dns_rrs *rrs)
return 0;
}
int _dns_encode_an(struct dns_context *context, struct dns_rrs *rrs)
static int _dns_encode_an(struct dns_context *context, struct dns_rrs *rrs)
{
int ret;
switch (rrs->type) {
case DNS_T_A: {
ret = _dns_encode_A(context, rrs);
ret = _dns_encode_raw(context, rrs);
if (ret < 0) {
return -1;
}
} break;
case DNS_T_PTR:
ret = _dns_encode_PTR(context, rrs);
ret = _dns_encode_CNAME(context, rrs);
if (ret < 0) {
return -1;
}
break;
case DNS_T_AAAA:
ret = _dns_encode_AAAA(context, rrs);
ret = _dns_encode_raw(context, rrs);
if (ret < 0) {
return -1;
}
@@ -1036,7 +955,7 @@ int _dns_encode_an(struct dns_context *context, struct dns_rrs *rrs)
return 0;
}
int _dns_decode_body(struct dns_context *context)
static int _dns_decode_body(struct dns_context *context)
{
struct dns_packet *packet = context->packet;
struct dns_head *head = &packet->head;
@@ -1082,7 +1001,7 @@ int _dns_decode_body(struct dns_context *context)
return 0;
}
int _dns_encode_body(struct dns_context *context)
static int _dns_encode_body(struct dns_context *context)
{
struct dns_packet *packet = context->packet;
struct dns_head *head = &packet->head;

View File

@@ -315,7 +315,7 @@ void _dns_client_period_run()
pthread_mutex_lock(&client.domain_map_lock);
list_for_each_entry_safe(query, tmp, &client.dns_request_list, dns_request_list)
{
if (now - query->send_tick >= 2000) {
if (now - query->send_tick >= 1000) {
_dns_client_query_remove(query, 1);
}
}
@@ -416,7 +416,7 @@ static int _dns_client_process(struct dns_query_struct *dns_query, unsigned long
return -1;
}
tlog(TLOG_DEBUG, "recv from %s", gethost_by_addr(from_host, (struct sockaddr *)&from, from_len));
tlog(TLOG_INFO, "recv from %s", gethost_by_addr(from_host, (struct sockaddr *)&from, from_len));
if (_dns_client_recv(inpacket, len, &from, from_len) != 0) {
int fd = open("dns.bin", O_CREAT | O_TRUNC | O_RDWR);

View File

@@ -27,6 +27,8 @@
#include "util.h"
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <ifaddrs.h>
#include <linux/filter.h>
#include <netdb.h>
#include <netinet/icmp6.h>
@@ -39,6 +41,7 @@
#include <string.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
@@ -64,6 +67,7 @@ struct dns_request {
unsigned long send_tick;
unsigned short qtype;
unsigned short id;
unsigned short rcode;
unsigned short ss_family;
socklen_t addr_len;
union {
@@ -115,14 +119,14 @@ void _dns_server_period_run()
len = sendto(server.fd, data, len, 0, (struct sockaddr *)&to, to_len);
if (len < 0) {
printf("send failed.");
tlog(TLOG_ERROR, "send failed.");
}
printf("send.\n");
tlog(TLOG_ERROR, "send.\n");
}
static int _dns_server_forward_request(unsigned char *inpacket, int inpacket_len)
{
printf("forward request.\n");
tlog(TLOG_ERROR, "forward request.\n");
return -1;
}
@@ -166,7 +170,7 @@ static int _dns_add_rrs(struct dns_packet *packet, struct dns_request *request)
return -1;
}
}
ret = dns_add_PTR(packet, DNS_RRS_AN, request->domain, 30, hostname);
} break;
case DNS_T_A:
@@ -215,7 +219,8 @@ static int _dns_reply(struct dns_request *request)
head.ra = 0;
head.aa = 0;
head.tc = 0;
head.rcode = DNS_RC_NOERROR;
head.rcode = request->rcode;
ret = dns_packet_init(packet, DNS_PACKSIZE, &head);
if (ret != 0) {
return -1;
@@ -251,13 +256,13 @@ int _dns_server_request_complete(struct dns_request *request)
}
if (request->qtype == DNS_T_A) {
tlog(TLOG_INFO, "result: %s, %d.%d.%d.%d\n", request->domain, request->ipv4_addr[0], request->ipv4_addr[1], request->ipv4_addr[2],
request->ipv4_addr[3]);
tlog(TLOG_INFO, "result: %s, rcode: %d, %d.%d.%d.%d\n", request->domain, request->rcode, request->ipv4_addr[0], request->ipv4_addr[1],
request->ipv4_addr[2], request->ipv4_addr[3]);
} else if (request->qtype == DNS_T_AAAA) {
tlog(TLOG_INFO, "result :%s, %x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x", request->domain, request->ipv6_addr[0], request->ipv6_addr[1],
request->ipv6_addr[2], request->ipv6_addr[3], request->ipv6_addr[4], request->ipv6_addr[5], request->ipv6_addr[6], request->ipv6_addr[7],
request->ipv6_addr[8], request->ipv6_addr[9], request->ipv6_addr[10], request->ipv6_addr[11], request->ipv6_addr[12], request->ipv6_addr[13],
request->ipv6_addr[14], request->ipv6_addr[15]);
tlog(TLOG_INFO, "result :%s, rcode: %d, %x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x", request->domain, request->rcode, request->ipv6_addr[0],
request->ipv6_addr[1], request->ipv6_addr[2], request->ipv6_addr[3], request->ipv6_addr[4], request->ipv6_addr[5], request->ipv6_addr[6],
request->ipv6_addr[7], request->ipv6_addr[8], request->ipv6_addr[9], request->ipv6_addr[10], request->ipv6_addr[11], request->ipv6_addr[12],
request->ipv6_addr[13], request->ipv6_addr[14], request->ipv6_addr[15]);
}
_dns_reply(request);
@@ -349,7 +354,7 @@ void _dns_server_ping_result(struct ping_host_struct *ping_host, const char *hos
static int _dns_client_process_answer(struct dns_request *request, char *domain, struct dns_packet *packet)
{
int ttl;
char name[DNS_MAX_CNAME_LEN];
char name[DNS_MAX_CNAME_LEN] = {0};
char alias[DNS_MAX_CNAME_LEN] = {0};
char ip[DNS_MAX_CNAME_LEN] = {0};
int rr_count;
@@ -358,10 +363,15 @@ static int _dns_client_process_answer(struct dns_request *request, char *domain,
struct dns_rrs *rrs = NULL;
if (packet->head.rcode != DNS_RC_NOERROR) {
tlog(TLOG_ERROR, "inquery failed, %s, rcode = %d\n", name, packet->head.rcode);
if (request->rcode == (unsigned short)-1) {
request->rcode = packet->head.rcode;
}
tlog(TLOG_ERROR, "inquery failed, %s, rcode = %d, id = %d\n", domain, packet->head.rcode, packet->head.id);
return -1;
}
request->rcode = packet->head.rcode;
for (j = 1; j < DNS_RRS_END; j++) {
rrs = dns_get_rrs_start(packet, j, &rr_count);
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
@@ -369,12 +379,12 @@ static int _dns_client_process_answer(struct dns_request *request, char *domain,
case DNS_T_A: {
unsigned char addr[4];
dns_get_A(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr);
tlog(TLOG_DEBUG, "%s %d : %d.%d.%d.%d", name, ttl, addr[0], addr[1], addr[2], addr[3]);
tlog(TLOG_INFO, "%s %d : %d.%d.%d.%d", name, ttl, addr[0], addr[1], addr[2], addr[3]);
sprintf(ip, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
if (strncmp(name, domain, DNS_MAX_CNAME_LEN) == 0 || strncmp(alias, name, DNS_MAX_CNAME_LEN) == 0) {
_dns_server_request_get(request);
if (fast_ping_start(ip, 1, 500, _dns_server_ping_result, request) == NULL) {
if (fast_ping_start(ip, 1, 1000, _dns_server_ping_result, request) == NULL) {
_dns_server_request_release(request);
}
}
@@ -385,7 +395,7 @@ static int _dns_client_process_answer(struct dns_request *request, char *domain,
sprintf(name, "%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8],
addr[9], addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]);
_dns_server_request_get(request);
if (fast_ping_start(name, 1, 500, _dns_server_ping_result, request) == NULL) {
if (fast_ping_start(name, 1, 1000, _dns_server_ping_result, request) == NULL) {
_dns_server_request_release(request);
}
} break;
@@ -435,6 +445,68 @@ static int dns_server_resolve_callback(char *domain, dns_result_type rtype, stru
return 0;
}
static int _dns_server_process_ptr(struct dns_request *request, struct dns_packet *packet)
{
struct ifaddrs *ifaddr = NULL;
struct ifaddrs *ifa = NULL;
unsigned char *addr;
char reverse_addr[128] = {0};
char host_name[DNS_MAX_CNAME_LEN];
int found = 0;
if (getifaddrs(&ifaddr) == -1) {
return -1;
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL) {
continue;
}
switch (ifa->ifa_addr->sa_family) {
case AF_INET: {
struct sockaddr_in *addr_in;
addr_in = (struct sockaddr_in *)ifa->ifa_addr;
addr = (unsigned char *)&(addr_in->sin_addr.s_addr);
snprintf(reverse_addr, sizeof(reverse_addr), "%d.%d.%d.%d.in-addr.arpa", addr[3], addr[2], addr[1], addr[0]);
} break;
case AF_INET6: {
struct sockaddr_in6 *addr_in6;
addr_in6 = (struct sockaddr_in6 *)ifa->ifa_addr;
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
addr = addr_in6->sin6_addr.s6_addr + 12;
snprintf(reverse_addr, sizeof(reverse_addr), "%d.%d.%d.%d.in-addr.arpa", addr[3], addr[2], addr[1], addr[0]);
} else {
addr = addr_in6->sin6_addr.s6_addr;
snprintf(reverse_addr, sizeof(reverse_addr), "%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x.in-addr.arpa", addr[15],
addr[14], addr[13], addr[12], addr[11], addr[10], addr[9], addr[8], addr[7], addr[6], addr[5], addr[4], addr[3], addr[2], addr[1],
addr[0]);
}
} break;
default:
break;
}
if (strncmp(request->domain, reverse_addr, sizeof(reverse_addr)) != 0) {
found = 1;
break;
}
}
if (found == 0) {
goto errout;
}
_dns_reply(request);
freeifaddrs(ifaddr);
return 0;
errout:
if (ifaddr) {
freeifaddrs(ifaddr);
}
return -1;
}
static int _dns_server_recv(unsigned char *inpacket, int inpacket_len, struct sockaddr_storage *from, socklen_t from_len)
{
int decode_len;
@@ -451,7 +523,7 @@ static int _dns_server_recv(unsigned char *inpacket, int inpacket_len, struct so
decode_len = dns_decode(packet, DNS_PACKSIZE, inpacket, inpacket_len);
if (decode_len < 0) {
printf("decode failed.\n");
tlog(TLOG_ERROR, "decode failed.\n");
goto errout;
}
@@ -463,8 +535,9 @@ static int _dns_server_recv(unsigned char *inpacket, int inpacket_len, struct so
memset(request, 0, sizeof(*request));
request->ttl_v4 = -1;
request->ttl_v6 = -1;
request->rcode = -1;
if (request == NULL) {
printf("malloc failed.\n");
tlog(TLOG_ERROR, "malloc failed.\n");
goto errout;
}
@@ -491,14 +564,20 @@ static int _dns_server_recv(unsigned char *inpacket, int inpacket_len, struct so
switch (qtype) {
case DNS_T_PTR:
ret = _dns_reply(request);
free(request);
return ret;
ret = _dns_server_process_ptr(request, packet);
if (ret == 0) {
free(request);
return ret;
} else {
request->passthrough = 1;
}
break;
case DNS_T_A:
break;
case DNS_T_AAAA:
break;
default:
tlog(TLOG_INFO, "unsupport qtype: %d, domain: %s", qtype, request->domain);
tlog(TLOG_DEBUG, "unsupport qtype: %d, domain: %s", qtype, request->domain);
request->passthrough = 1;
break;
}

View File

@@ -519,7 +519,9 @@ struct ping_host_struct *fast_ping_start(const char *host, int count, int timeou
}
memcpy(&ping_host->addr, gai->ai_addr, gai->ai_addrlen);
_fast_ping_sendping(ping_host);
if (_fast_ping_sendping(ping_host) != 0) {
}
hostkey = hash_string(ping_host->host);
addrkey = jhash(&ping_host->addr, ping_host->addr_len, 0);