From 3ee4bc1dbff6956975aab709b2a5995e2e11d8ef Mon Sep 17 00:00:00 2001 From: Nick Peng Date: Fri, 18 May 2018 00:02:32 +0800 Subject: [PATCH] Update code --- dns_client.c | 449 +++++++++++++++++++++++++++++++++++++-------------- dns_client.h | 5 +- dns_server.c | 309 +++++++++++++++++++++++------------ 3 files changed, 540 insertions(+), 223 deletions(-) diff --git a/dns_client.c b/dns_client.c index 9560398..73fa503 100644 --- a/dns_client.c +++ b/dns_client.c @@ -1,7 +1,7 @@ /************************************************************************* -* -* Copyright (C) 2018 Ruilin Peng (Nick) . -* + * + * Copyright (C) 2018 Ruilin Peng (Nick) . + * * smartdns is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or @@ -18,6 +18,7 @@ #include "dns_client.h" #include "atomic.h" +#include "dns.h" #include "fast_ping.h" #include "hashtable.h" #include @@ -39,176 +40,390 @@ #define DNS_MAX_HOSTNAME 256 -#define DNS_INPACKET_SIZE 512 - #define DNS_MAX_EVENTS 64 -#define DNS_HOSTNAME_LEN 128 +#define DNS_HOSTNAME_LEN 128 struct dns_query_server { - int fd; - int type; - char host[DNS_HOSTNAME_LEN]; - struct list_head list; + int fd; + int type; + char host[DNS_HOSTNAME_LEN]; + struct list_head list; }; struct dns_client { - pthread_t tid; - int run; - int epoll_fd; + pthread_t tid; + int run; + int epoll_fd; - struct list_head dns_server_list; + struct list_head dns_server_list; - pthread_mutex_t map_lock; - DECLARE_HASHTABLE(hostmap, 6); + pthread_mutex_t map_lock; + DECLARE_HASHTABLE(hostmap, 6); - int udp; - int tcp; + int udp; + int tcp; }; struct dns_query_struct { - char host[DNS_MAX_HOSTNAME]; - struct hlist_node host_node; + char domain[DNS_MAX_HOSTNAME]; + struct hlist_node host_node; + void *user_ptr; }; static struct dns_client client; +static dns_client_callback dns_callback; + static void tv_sub(struct timeval *out, struct timeval *in) { - if ((out->tv_usec -= in->tv_usec) < 0) { /* out -= in */ - --out->tv_sec; - out->tv_usec += 1000000; - } - out->tv_sec -= in->tv_sec; + if ((out->tv_usec -= in->tv_usec) < 0) { /* out -= in */ + --out->tv_sec; + out->tv_usec += 1000000; + } + out->tv_sec -= in->tv_sec; } void _dns_client_period_run() { + +} + +static int _dns_client_recv(unsigned char *inpacket, int inpacket_len, struct sockaddr_storage *from, socklen_t from_len) +{ + int len; + int i; + int j; + int qtype; + int qclass; + int ttl; + char name[DNS_MAX_CNAME_LEN]; + int rr_count; + struct dns_rrs *rrs = NULL; + unsigned char packet_buff[DNS_PACKSIZE]; + struct dns_packet *packet = (struct dns_packet *)packet_buff; + + len = dns_decode(packet, DNS_PACKSIZE, inpacket, inpacket_len); + if (len != 0) { + printf("decode failed.\n"); + return -1; + } + + printf("qdcount = %d, ancount = %d, nscount = %d, nrcount = %d, len = %d\n", packet->head.qdcount, packet->head.ancount, packet->head.nscount, + packet->head.nrcount, inpacket_len); + + rrs = dns_get_rrs_start(packet, DNS_RRS_QD, &rr_count); + for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) { + dns_get_domain(rrs, name, 128, &qtype, &qclass); + printf("domain: %s qtype: %d qclass: %d\n", name, qtype, qclass); + } + + 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)) { + switch (rrs->type) { + case DNS_T_A: { + unsigned char addr[4]; + dns_get_A(rrs, name, 128, &ttl, addr); + printf("%s %d : %d.%d.%d.%d\n", name, ttl, addr[0], addr[1], addr[2], addr[3]); + dns_callback(name, addr, DNS_T_A, 0); + } break; + case DNS_T_NS: + case DNS_T_CNAME: { + char cname[128]; + dns_get_CNAME(rrs, name, 128, &ttl, cname, 128); + printf("%s %d : %s\n", name, ttl, cname); + } break; + default: + break; + } + } + } + + printf("\n"); + + return 0; } static int _dns_client_process(struct dns_query_struct *dns_query, struct timeval *now) { - int len; - u_char inpacket[DNS_INPACKET_SIZE]; - struct sockaddr_storage from; - socklen_t from_len = sizeof(from); + int len; + unsigned char inpacket[DNS_IN_PACKSIZE]; + struct sockaddr_storage from; + socklen_t from_len = sizeof(from); - len = recvfrom(client.udp, inpacket, sizeof(inpacket), 0, (struct sockaddr *)&from, (socklen_t *)&from_len); - if (len < 0) { - fprintf(stderr, "recvfrom failed, %s\n", strerror(errno)); - goto errout; - } + len = recvfrom(client.udp, inpacket, sizeof(inpacket), 0, (struct sockaddr *)&from, (socklen_t *)&from_len); + if (len < 0) { + fprintf(stderr, "recvfrom failed, %s\n", strerror(errno)); + return -1; + } - return 0; -errout: - return -1; + return _dns_client_recv(inpacket, len, &from, from_len); } static void *_dns_client_work(void *arg) { - struct epoll_event events[DNS_MAX_EVENTS + 1]; - int num; - int i; - struct timeval last = { 0 }; - struct timeval now = { 0 }; - struct timeval diff = { 0 }; - uint millisec = 0; + struct epoll_event events[DNS_MAX_EVENTS + 1]; + int num; + int i; + struct timeval last = {0}; + struct timeval now = {0}; + struct timeval diff = {0}; + uint millisec = 0; - while (client.run) { - diff = now; - tv_sub(&diff, &last); - millisec = diff.tv_sec * 1000 + diff.tv_usec / 1000; - if (millisec >= 100) { - _dns_client_period_run(); - last = now; - } + while (client.run) { + diff = now; + tv_sub(&diff, &last); + millisec = diff.tv_sec * 1000 + diff.tv_usec / 1000; + if (millisec >= 1000) { + _dns_client_period_run(); + last = now; + } - num = epoll_wait(client.epoll_fd, events, DNS_MAX_EVENTS, 100); - if (num < 0) { - gettimeofday(&now, 0); - usleep(100000); - continue; - } + num = epoll_wait(client.epoll_fd, events, DNS_MAX_EVENTS, 1000); + if (num < 0) { + gettimeofday(&now, 0); + usleep(100000); + continue; + } - if (num == 0) { - gettimeofday(&now, 0); - continue; - } + if (num == 0) { + gettimeofday(&now, 0); + continue; + } - gettimeofday(&now, 0); - for (i = 0; i < num; i++) { - struct epoll_event *event = &events[i]; - struct dns_query_struct *dns_query = (struct dns_query_struct *)event->data.ptr; - _dns_client_process(dns_query, &now); - } - } + gettimeofday(&now, 0); + for (i = 0; i < num; i++) { + struct epoll_event *event = &events[i]; + struct dns_query_struct *dns_query = (struct dns_query_struct *)event->data.ptr; + _dns_client_process(dns_query, &now); + } + } - close(client.epoll_fd); - client.epoll_fd = -1; + close(client.epoll_fd); + client.epoll_fd = -1; - return NULL; + return NULL; +} + +static int _dns_client_send_packet(void *packet, int len) +{ + struct sockaddr_in to; + int send_len = 0; + socklen_t to_len = sizeof(to); + + memset(&to, 0, sizeof(to)); + to.sin_addr.s_addr = inet_addr("192.168.1.1"); + to.sin_port = htons(53); + + send_len = sendto(client.udp, packet, len, 0, (struct sockaddr *)&to, to_len); + if (send_len != len) { + printf("send to server failed."); + return -1; + } + + return 0; +} + +static int _dns_client_send_request(struct dns_query_struct *request, char *doamin) +{ + unsigned char packet_buff[DNS_PACKSIZE]; + unsigned char inpacket[DNS_IN_PACKSIZE]; + struct dns_packet *packet = (struct dns_packet *)packet_buff; + int encode_len; + + struct dns_head head; + memset(&head, 0, sizeof(head)); + head.rcode = 0; + head.qr = DNS_OP_QUERY; + head.rd = 1; + head.ra = 0; + head.id = 1; + + dns_packet_init(packet, DNS_PACKSIZE, &head); + dns_add_domain(packet, doamin, DNS_T_A, DNS_C_IN); + encode_len = dns_encode(inpacket, DNS_IN_PACKSIZE, packet); + if (encode_len <= 0) { + printf("encode request failed.\n"); + return -1; + } + + return _dns_client_send_packet(inpacket, encode_len); +} + +int dns_client_query(char *domain, void *user_ptr) +{ + struct dns_query_struct *request = NULL; + int ret = 0; + request = malloc(sizeof(*request)); + if (request == NULL) { + return -1; + } + INIT_HLIST_NODE(&request->host_node); + strncpy(request->domain, domain, DNS_MAX_CNAME_LEN); + request->user_ptr = user_ptr; + + ret =_dns_client_send_request(request, domain); + if (ret != 0) { + goto errout; + } + free(request); + return 0; +errout: + if (request) { + free(request); + } + return -1; +} + +int dns_register_callback(dns_client_callback callback) +{ + dns_callback = callback; + return 0; +} + +static struct addrinfo *_dns_server_getaddr(const char *host, const char *port, int type, int protocol) +{ + struct addrinfo hints; + struct addrinfo *result = NULL; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = type; + hints.ai_protocol = protocol; + hints.ai_flags = AI_PASSIVE; + if (getaddrinfo(host, port, &hints, &result) != 0) { + fprintf(stderr, "get addr info failed. %s\n", strerror(errno)); + goto errout; + } + + return result; +errout: + if (result) { + freeaddrinfo(result); + } + return NULL; +} + +int dns_client_start(void) +{ + struct epoll_event event; + event.events = EPOLLIN; + event.data.fd = client.udp; + if (epoll_ctl(client.epoll_fd, EPOLL_CTL_ADD, client.udp, &event) != 0) { + fprintf(stderr, "epoll ctl failed."); + return -1; + } + + return 0; +} + +int dns_client_socket(void) +{ + int fd = -1; + struct addrinfo *gai = NULL; + + gai = _dns_server_getaddr(NULL, "54", SOCK_DGRAM, 0); + if (gai == NULL) { + fprintf(stderr, "get address failed.\n"); + goto errout; + } + + fd = socket(gai->ai_family, gai->ai_socktype, gai->ai_protocol); + if (fd < 0) { + fprintf(stderr, "create socket failed.\n"); + goto errout; + } + + client.udp = fd; + freeaddrinfo(gai); + + return fd; +errout: + if (fd > 0) { + close(fd); + } + + if (gai) { + freeaddrinfo(gai); + } + return -1; } int dns_client_init() { - pthread_attr_t attr; - int epollfd = -1; - int ret; + pthread_attr_t attr; + int epollfd = -1; + int ret; + int fd = 1; - if (client.epoll_fd > 0) { - return -1; - } + if (client.epoll_fd > 0) { + return -1; + } - memset(&client, 0, sizeof(client)); - pthread_attr_init(&attr); + memset(&client, 0, sizeof(client)); + pthread_attr_init(&attr); - epollfd = epoll_create1(EPOLL_CLOEXEC); - if (epollfd < 0) { - fprintf(stderr, "create epoll failed, %s\n", strerror(errno)); - goto errout; - } + epollfd = epoll_create1(EPOLL_CLOEXEC); + if (epollfd < 0) { + fprintf(stderr, "create epoll failed, %s\n", strerror(errno)); + goto errout; + } - client.run = 1; - ret = pthread_create(&client.tid, &attr, _dns_client_work, NULL); - if (ret != 0) { - fprintf(stderr, "create client work thread failed, %s\n", strerror(errno)); - goto errout; - } + fd = dns_client_socket(); + if (fd < 0) { + fprintf(stderr, "create client socket failed.\n"); + goto errout; + } - pthread_mutex_init(&client.map_lock, 0); - hash_init(client.hostmap); - client.epoll_fd = epollfd; + client.run = 1; + client.udp = fd; + ret = pthread_create(&client.tid, &attr, _dns_client_work, NULL); + if (ret != 0) { + fprintf(stderr, "create client work thread failed, %s\n", strerror(errno)); + goto errout; + } - return 0; + pthread_mutex_init(&client.map_lock, 0); + hash_init(client.hostmap); + client.epoll_fd = epollfd; + + if (dns_client_start()) { + fprintf(stderr, "start client failed.\n"); + goto errout; + } + + return 0; errout: - if (client.tid > 0) { - void *retval = NULL; - client.run = 0; - pthread_join(client.tid, &retval); - } + if (client.tid > 0) { + void *retval = NULL; + client.run = 0; + pthread_join(client.tid, &retval); + } - if (epollfd) { - close(epollfd); - } + if (fd > 0) { + close(fd); + } - pthread_mutex_destroy(&client.map_lock); + if (epollfd) { + close(epollfd); + } - return -1; -} + pthread_mutex_destroy(&client.map_lock); -int dns_client_query(char *host) -{ - return 0; -errout: - return -1; + return -1; } void dns_client_exit() { - if (client.tid > 0) { - void *ret = NULL; - client.run = 0; - pthread_join(client.tid, &ret); - } + if (client.tid > 0) { + void *ret = NULL; + client.run = 0; + pthread_join(client.tid, &ret); + } - pthread_mutex_destroy(&client.map_lock); + if (client.udp > 0) { + close(client.udp); + } + + pthread_mutex_destroy(&client.map_lock); } \ No newline at end of file diff --git a/dns_client.h b/dns_client.h index e95a922..cb876ab 100644 --- a/dns_client.h +++ b/dns_client.h @@ -3,7 +3,10 @@ int dns_client_init(void); -int dns_client_query(char *host); +typedef int (*dns_client_callback)(char *domain, unsigned char *addr, int addr_type, void *user_ptr); +int dns_register_callback(dns_client_callback callback); + +int dns_client_query(char *domain, void *user_ptr); void dns_client_exit(void); diff --git a/dns_server.c b/dns_server.c index 123d9eb..ee93ca2 100644 --- a/dns_server.c +++ b/dns_server.c @@ -18,8 +18,9 @@ #include "dns_server.h" #include "dns.h" -#include "list.h" #include "hashtable.h" +#include "list.h" +#include "dns_client.h" #include #include #include @@ -50,10 +51,23 @@ struct dns_server { DECLARE_HASHTABLE(hostmap, 6); }; - struct dns_request { struct hlist_node map; - char host[DNS_MAX_CNAME_LEN]; + char domain[DNS_MAX_CNAME_LEN]; + unsigned short qtype; + unsigned short id; + unsigned short ss_family; + socklen_t addr_len; + union { + struct sockaddr_in in; + struct sockaddr_in6 in6; + struct sockaddr addr; + }; + + union { + unsigned char ipv4_addr[DNS_RR_A_LEN]; + unsigned char ipv6_addr[DNS_RR_AAAA_LEN]; + }; }; static struct dns_server server; @@ -69,6 +83,7 @@ static void tv_sub(struct timeval *out, struct timeval *in) void _dns_server_period_run() { + return; unsigned char packet_data[DNS_PACKSIZE]; unsigned char data[DNS_IN_PACKSIZE]; @@ -98,121 +113,198 @@ void _dns_server_period_run() if (len < 0) { printf("send failed."); } + printf("send.\n"); +} + +static int _dns_server_forward_request(unsigned char *inpacket, int inpacket_len) +{ + printf("forward request.\n"); + return -1; +} + +static int _dns_recv_addr(struct dns_request *request, struct sockaddr_storage *from, socklen_t from_len) +{ + switch (from->ss_family) { + case AF_INET: + memcpy(&request->in, from, from_len); + request->addr_len = from_len; + break; + case AF_INET6: + memcpy(&request->in6, from, from_len); + request->addr_len = from_len; + break; + default: + return -1; + break; + } + + return 0; +} + +static int _dns_add_rrs(struct dns_packet *packet, struct dns_request *request) +{ + int qtype; + int ret = -1; + + qtype = request->qtype; + + switch (qtype) { + case DNS_T_PTR: { + char hostname[DNS_MAX_CNAME_LEN]; + if (getdomainname(hostname, DNS_MAX_CNAME_LEN) != 0) { + if (gethostname(hostname, DNS_MAX_CNAME_LEN) != 0) { + return -1; + } + } + + if (strncmp(hostname, "(none)", DNS_MAX_CNAME_LEN) == 0) { + if (gethostname(hostname, DNS_MAX_CNAME_LEN) != 0) { + return -1; + } + } + + ret = dns_add_PTR(packet, DNS_RRS_AN, request->domain, 60 * 60, hostname); + } break; + case DNS_T_A: + ret = dns_add_A(packet, DNS_RRS_AN, request->domain, 60 * 60, request->ipv4_addr); + break; + case DNS_T_AAAA: + ret = dns_add_AAAA(packet, DNS_RRS_AN, request->domain, 60 * 60, request->ipv6_addr); + break; + default: + break; + } + return ret; +} + +static int _dns_reply(struct dns_request *request) +{ + unsigned char inpacket[DNS_IN_PACKSIZE]; + unsigned char packet_buff[DNS_PACKSIZE]; + struct dns_packet *packet = (struct dns_packet *)packet_buff; + struct dns_head head; + int ret = 0; + int encode_len = 0; + int send_len = 0; + + memset(&head, 0, sizeof(head)); + head.id = request->id; + head.qr = DNS_OP_IQUERY; + head.rd = 1; + head.ra = 0; + ret = dns_packet_init(packet, DNS_PACKSIZE, &head); + if (ret != 0) { + return -1; + } + + ret = dns_add_domain(packet, request->domain, request->qtype, DNS_C_IN); + if (ret != 0) { + return -1; + } + + ret = _dns_add_rrs(packet, request); + if (ret != 0) { + return -1; + } + + encode_len = dns_encode(inpacket, DNS_IN_PACKSIZE, packet); + if (encode_len <= 0) { + return -1; + } + + send_len = sendto(server.fd, inpacket, encode_len, 0, &request->addr, request->addr_len); + if (send_len != encode_len) { + printf("send failed."); + } + + return 0; +} + +static int _dns_server_recv(unsigned char *inpacket, int inpacket_len, struct sockaddr_storage *from, socklen_t from_len) +{ + int decode_len; + int ret = -1; + unsigned char packet_buff[DNS_PACKSIZE]; + struct dns_packet *packet = (struct dns_packet *)packet_buff; + struct dns_request *request = NULL; + struct dns_rrs *rrs; + int rr_count = 0; + int i = 0; + int qclass; + int qtype; + + decode_len = dns_decode(packet, DNS_PACKSIZE, inpacket, inpacket_len); + if (decode_len < 0) { + printf("decode failed.\n"); + goto errout; + } + + if (packet->head.qr != DNS_OP_QUERY) { + goto errout; + } + + request = malloc(sizeof(*request)); + if (request == NULL) { + printf("malloc failed.\n"); + goto errout; + } + + if (_dns_recv_addr(request, from, from_len) != 0) { + goto errout; + } + + request->id = packet->head.id; + + rrs = dns_get_rrs_start(packet, DNS_RRS_QD, &rr_count); + if (rr_count > 1) { + goto errout; + } + + for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) { + ret = dns_get_domain(rrs, request->domain, sizeof(request->domain), &qtype, &qclass); + if (ret != 0) { + goto errout; + } + + request->qtype = qtype; + } + + switch (qtype) { + case DNS_T_PTR: + ret = _dns_reply(request); + free(request); + return ret; + break; + default: + break; + } + + dns_client_query(request->domain, request); + + free(request); + return 0; +errout: + if (request) { + ret = _dns_server_forward_request(inpacket, inpacket_len); + free(request); + } + return ret; } static int _dns_server_process(struct timeval *now) { int len; unsigned char inpacket[DNS_IN_PACKSIZE]; - unsigned char rsppacket[DNS_PACKSIZE]; - unsigned char aswpacket[DNS_PACKSIZE]; - unsigned char outpacket[DNS_IN_PACKSIZE]; - - struct dns_packet *packet = (struct dns_packet *)rsppacket; - struct dns_packet *anspacket = (struct dns_packet *)aswpacket; - struct sockaddr_storage from; socklen_t from_len = sizeof(from); - int data_len; len = recvfrom(server.fd, inpacket, sizeof(inpacket), 0, (struct sockaddr *)&from, (socklen_t *)&from_len); if (len < 0) { fprintf(stderr, "recvfrom failed, %s\n", strerror(errno)); - goto errout; - } - data_len = len; - - len = dns_decode(packet, DNS_PACKSIZE, inpacket, len); - if (len) { - printf("decode failed.\n"); - return 0; - goto errout; + return -1; } - int count; - struct dns_rrs *rrs; - char name[128]; - int i = 0; - int j = 0; - int ttl; - int qtype; - int qclass; - - struct dns_head head; - memset(&head, 0, sizeof(head)); - head.rcode = 0; - head.qr = 1; - head.rd = packet->head.rd; - head.ra = packet->head.ra; - head.id = packet->head.id; - int n = 0; - - dns_packet_init(anspacket, DNS_PACKSIZE, &head); - - printf("qdcount = %d, ancount = %d, nscount = %d, nrcount = %d, len = %d\n", packet->head.qdcount, packet->head.ancount, packet->head.nscount, - packet->head.nrcount, data_len); - - rrs = dns_get_rrs_start(packet, DNS_RRS_QD, &count); - for (i = 0; i < count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) { - dns_get_domain(rrs, name, 128, &qtype, &qclass); - printf("domain: %s qtype: %d qclass: %d\n", name, qtype, qclass); - switch (qtype) { - case DNS_T_A: { - unsigned char addr[4]; - addr[0] = 192; - addr[1] = 148; - addr[2] = 9; - addr[3] = 3; - dns_add_A(anspacket, DNS_RRS_AN, name, 60 * 60, addr); - n++; - } break; - case DNS_T_AAAA: { - unsigned char addr[16]; - memset(addr, 0, 16); - addr[0] = 1; - dns_add_AAAA(anspacket, DNS_RRS_AN, name, 60 * 60, addr); - n++; - } break; - case DNS_T_PTR:{ - dns_add_PTR(anspacket, DNS_RRS_AN, name, 60 * 60, "raspberrypi.larva-family.com"); - n++; - } break; - default: - break; - } - } - - if (n > 0 && packet->head.qr == 0) { - dns_add_domain(anspacket, name, qtype, qclass); - len = dns_encode(outpacket, DNS_IN_PACKSIZE, anspacket); - sendto(server.fd, outpacket, len, 0, (struct sockaddr *)&from, from_len); - } - - for (j = 1; j < DNS_RRS_END; j++) { - rrs = dns_get_rrs_start(packet, j, &count); - for (i = 0; i < count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) { - switch (rrs->type) { - case DNS_T_A: { - unsigned char addr[4]; - dns_get_A(rrs, name, 128, &ttl, addr); - printf("%s %d : %d.%d.%d.%d\n", name, ttl, addr[0], addr[1], addr[2], addr[3]); - } break; - case DNS_T_NS: - case DNS_T_CNAME: { - char cname[128]; - dns_get_CNAME(rrs, name, 128, &ttl, cname, 128); - printf("%s %d : %s\n", name, ttl, cname); - } break; - default: - break; - } - } - } - - printf("\n"); - return 0; -errout: - return -1; + return _dns_server_recv(inpacket, len, &from, from_len); } int dns_server_run(void) @@ -229,7 +321,7 @@ int dns_server_run(void) diff = now; tv_sub(&diff, &last); millisec = diff.tv_sec * 1000 + diff.tv_usec / 1000; - if (millisec >= 100) { + if (millisec >= 1000) { _dns_server_period_run(); last = now; } @@ -337,6 +429,11 @@ errout: return -1; } +static int dns_server_resolve_callback(char *domain, unsigned char *addr, int addr_type, void *user_ptr) +{ + return 0; +} + int dns_server_init(void) { pthread_attr_t attr; @@ -368,6 +465,8 @@ int dns_server_init(void) server.fd = fd; server.run = 1; + dns_register_callback(dns_server_resolve_callback); + if (dns_server_start() != 0) { fprintf(stderr, "start service failed.\n"); goto errout;