Nick Peng %!s(int64=7) %!d(string=hai) anos
pai
achega
db3c7df954
Modificáronse 7 ficheiros con 272 adicións e 11 borrados
  1. 1 1
      Makefile
  2. 191 0
      conf.c
  3. 25 0
      conf.h
  4. 3 1
      dns_client.c
  5. 4 1
      dns_server.c
  6. 35 8
      smartdns.c
  7. 13 0
      smartdns.conf

+ 1 - 1
Makefile

@@ -1,6 +1,6 @@
 
 BIN=smartdns 
-OBJS=smartdns.o fast_ping.o lib/bitops.o dns_client.o dns_server.o dns.o util.o tlog.o
+OBJS=smartdns.o fast_ping.o lib/bitops.o dns_client.o dns_server.o dns.o util.o tlog.o conf.o
 CFLAGS=-g -O0 -Wall 
 CFLAGS +=-Iinclude
 CFLAGS += -DBASE_FILE_NAME=\"$(notdir $<)\"

+ 191 - 0
conf.c

@@ -0,0 +1,191 @@
+#include "conf.h"
+#include "tlog.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define MAX_LINE_LEN 1024
+#define MAX_KEY_LEN 64
+
+#define DEFAULT_DNS_PORT 53
+#define DEFAULT_DNS_CACHE_SIZE 512
+
+int dns_conf_port = DEFAULT_DNS_PORT;
+int dns_conf_cachesize = DEFAULT_DNS_CACHE_SIZE;
+struct dns_servers dns_conf_servers[DNS_MAX_SERVERS];
+int dns_conf_server_num;
+
+int config_port(char *value)
+{
+	int port = atoi(value);
+	if (port <= 0 || port >= 65535) {
+		return -1;
+	}
+
+	dns_conf_port = port;
+
+	return 0;
+}
+
+int config_parse_ip(char *value, char *ip, unsigned short *port)
+{
+	int offset = 0;
+	char *colon = NULL;
+
+	if (strstr(value, "[")) {
+		/* ipv6 with port */
+		char *bracket_end = strstr(value, "]");
+		if (bracket_end == NULL) {
+			return -1;
+		}
+
+		offset = bracket_end - value - 1;
+		memcpy(ip, value + 1, offset);
+		ip[offset] = 0;
+
+		colon = bracket_end + 1;
+
+	} else if (strstr(value, "::")) {
+		/* ipv6 without port */
+		strncpy(ip, value, DNS_MAX_IPLEN);
+		colon = NULL;
+	} else {
+		/* ipv4 */
+		colon = strstr(value, ":");
+		if (colon == NULL) {
+			/* without port */
+			strncpy(ip, value, DNS_MAX_IPLEN);
+		} else {
+			/* with port */
+			offset = colon - value;
+			colon++;
+			memcpy(ip, value, offset);
+		}
+	}
+
+	if (colon) {
+		/* get port num */
+		*port = atoi(colon);
+	} else {
+		*port = DEFAULT_DNS_PORT;
+	}
+
+	return 0;
+}
+
+int config_server(char *value, dns_conf_server_type_t type)
+{
+	int index = dns_conf_server_num;
+	struct dns_servers *server;
+	if (index >= DNS_MAX_SERVERS) {
+		tlog(TLOG_ERROR, "exceeds max server number");
+		return -1;
+	}
+
+	server = &dns_conf_servers[index];
+    if (config_parse_ip(value, server->server, &server->port) != 0) {
+		return -1;
+    }
+
+	server->type = type;
+	dns_conf_server_num++;
+
+	return 0;
+}
+
+int config_server_udp(char *value)
+{
+	return config_server(value, DNS_CONF_TYPE_UDP);
+}
+
+int config_server_tcp(char *value)
+{
+	return config_server(value, DNS_CONF_TYPE_TCP);
+}
+
+int config_server_http(char *value)
+{
+	return config_server(value, DNS_CONF_TYPE_HTTP);
+}
+
+int config_cache_size(char *value)
+{
+	int cache_size = atoi(value);
+	if (cache_size < 0) {
+		return -1;
+	}
+
+	dns_conf_cachesize = cache_size;
+
+	return 0;
+}
+
+struct config_item {
+	const char *item;
+	int (*item_func)(char *value);
+};
+
+struct config_item config_item[] = {
+	{"port", config_port},
+	{"server", config_server_udp},
+    {"server-tcp", config_server_tcp},
+    {"server-http", config_server_http},
+	{"cache-size", config_cache_size},
+};
+int config_item_num = sizeof(config_item) / sizeof(struct config_item);
+
+int load_conf(const char *file)
+{
+	FILE *fp = NULL;
+	char line[MAX_LINE_LEN];
+	char key[MAX_KEY_LEN];
+	char value[MAX_LINE_LEN];
+	int filed_num = 0;
+	int line_num = 0;
+	int i;
+
+	fp = fopen(file, "r");
+	if (fp == NULL) {
+		tlog(TLOG_ERROR, "config file %s not exist.", file);
+		return -1;
+	}
+
+	while (fgets(line, MAX_LINE_LEN, fp)) {
+		line_num++;
+		filed_num = sscanf(line, "%63s %1023[^\r\n]s", key, value);
+		if (filed_num <= 0) {
+			continue;
+		}
+
+		if (key[0] == '#') {
+			continue;
+		}
+
+		if (filed_num != 2) {
+			goto errout;
+		}
+
+		for (i = 0; i < config_item_num; i++) {
+			if (strncmp(config_item[i].item, key, MAX_KEY_LEN) != 0) {
+				continue;
+			}
+
+			if (config_item[i].item_func(value) != 0) {
+				goto errout;
+			}
+
+			break;
+		}
+	}
+
+	fclose(fp);
+
+	return 0;
+errout:
+	printf("invalid config at line %d: %s", line_num, line);
+	if (fp) {
+		fclose(fp);
+	}
+	return -1;
+}

+ 25 - 0
conf.h

@@ -0,0 +1,25 @@
+#ifndef _DNS_CONF
+
+#define DNS_MAX_SERVERS 32
+#define DNS_MAX_IPLEN 64
+
+typedef enum dns_conf_server_type {
+	DNS_CONF_TYPE_UDP,
+	DNS_CONF_TYPE_TCP,
+	DNS_CONF_TYPE_HTTP,
+} dns_conf_server_type_t;
+
+struct dns_servers {
+	char server[DNS_MAX_IPLEN];
+	unsigned short port;
+	dns_conf_server_type_t type;
+};
+
+extern int dns_conf_port;
+extern int dns_conf_cachesize;
+extern struct dns_servers dns_conf_servers[DNS_MAX_SERVERS];
+extern int dns_conf_server_num;
+
+int load_conf(const char *file);
+
+#endif // !_DNS_CONF

+ 3 - 1
dns_client.c

@@ -169,7 +169,8 @@ int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_server_typ
 	server_info->ss_family = gai->ai_family;
 	server_info->addr_len = gai->ai_addrlen;
 	server_info->type = server_type;
-	if (gai->ai_addrlen > sizeof(server_info->addr)) {
+	if (gai->ai_addrlen > sizeof(server_info->in6)) {
+		tlog(TLOG_ERROR, "addr len invalid, %d, %d, %d", gai->ai_addrlen, sizeof(server_info->addr), server_info->ss_family);
 		goto errout;
 	}
 	memcpy(&server_info->addr, gai->ai_addr, gai->ai_addrlen);
@@ -235,6 +236,7 @@ int _dns_client_server_operate(char *server_ip, int port, dns_server_type_t serv
 	snprintf(port_s, 8, "%d", port);
 	gai = _dns_client_getaddr(server_ip, port_s, sock_type, 0);
 	if (gai == NULL) {
+		tlog(TLOG_ERROR, "get address failed, %s:%d", server_ip, port);
 		goto errout;
 	}
 

+ 4 - 1
dns_server.c

@@ -25,6 +25,7 @@
 #include "list.h"
 #include "tlog.h"
 #include "util.h"
+#include "conf.h"
 #include <arpa/inet.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -784,8 +785,10 @@ int dns_server_socket(void)
 {
 	int fd = -1;
 	struct addrinfo *gai = NULL;
+	char port_str[8];
 
-	gai = _dns_server_getaddr(NULL, "53", SOCK_DGRAM, 0);
+	snprintf(port_str, sizeof(port_str), "%d", dns_conf_port);
+	gai = _dns_server_getaddr(NULL, port_str, SOCK_DGRAM, 0);
 	if (gai == NULL) {
 		tlog(TLOG_ERROR, "get address failed.\n");
 		goto errout;

+ 35 - 8
smartdns.c

@@ -22,6 +22,7 @@
 #include "hashtable.h"
 #include "list.h"
 #include "tlog.h"
+#include "conf.h"
 #include "atomic.h"
 #include <stdio.h>
 #include <stdlib.h>
@@ -42,13 +43,33 @@ void print_result(struct ping_host_struct *ping_host, const char *host, FAST_PIN
     #endif
 }
 
+int smartdns_add_servers(void)
+{
+	int i = 0;
+	int ret = 0;
+	for (i = 0; i < dns_conf_server_num; i++) {
+		ret = dns_add_server(dns_conf_servers[i].server, dns_conf_servers[i].port, dns_conf_servers[i].type);
+		if (ret != 0) {
+			tlog(TLOG_ERROR, "add server failed, %s:%d", dns_conf_servers[i].server, dns_conf_servers[i].port);
+			return -1;
+		}
+    }
+
+	return 0;
+}
+
 int smartdns_init()
 {
     int ret;
 
+	if (load_conf("smartdns.conf") != 0) {
+		fprintf(stderr, "load config failed.");
+		goto errout;
+	}
+
 	ret = tlog_init(".", "smartdns.log", 1024 * 1024, 8, 1, 0, 0);
     if (ret != 0) {
-		fprintf(stderr, "start tlog failed.\n");
+		tlog(TLOG_ERROR, "start tlog failed.\n");
 		goto errout;
 	}
 
@@ -57,22 +78,29 @@ int smartdns_init()
 
 	ret = fast_ping_init();
     if (ret != 0) {
-        fprintf(stderr, "start ping failed.\n");
+        tlog(TLOG_ERROR, "start ping failed.\n");
         goto errout;
     }
 
     ret = dns_server_init();
     if (ret != 0) {
-        fprintf(stderr, "start dns server failed.\n");
+        tlog(TLOG_ERROR, "start dns server failed.\n");
         goto errout;
     }
 
     ret = dns_client_init();
     if (ret != 0) {
-        fprintf(stderr, "start dns client failed.\n");
+        tlog(TLOG_ERROR, "start dns client failed.\n");
         goto errout;
     }
 
+	ret = smartdns_add_servers();
+    if (ret != 0) {
+		tlog(TLOG_ERROR, "add servers failed.");
+		goto errout;
+	}
+
+    /*
 	dns_add_server("192.168.1.1", 53, DNS_SERVER_UDP);
     dns_add_server("114.114.114.114", 53, DNS_SERVER_UDP);
 	dns_add_server("123.207.137.88", 53, DNS_SERVER_UDP);
@@ -82,7 +110,7 @@ int smartdns_init()
 	dns_add_server("77.88.8.8", 53, DNS_SERVER_UDP);
 	dns_add_server("202.141.162.123", 53, DNS_SERVER_UDP);
 	dns_add_server("101.132.183.99", 53, DNS_SERVER_UDP);
-
+    */
 	// int i = 0;
 	// for(i = 0; i < 10; i++)
     // {
@@ -249,18 +277,17 @@ int rbtree_test()
 void sig_handle(int sig)
 {
 	tlog(TLOG_ERROR, "process exit.\n");
-	sleep(1);
 	_exit(0);
 }
+
 int main(int argc, char *argv[])
 {
     int ret;
 
-    atexit(smartdns_exit);
+	atexit(smartdns_exit);
 	signal(SIGABRT, sig_handle);
 	ret = smartdns_init();
     if (ret != 0) {
-        fprintf(stderr, "init smartdns failed.\n");
         goto errout;
     }
 

+ 13 - 0
smartdns.conf

@@ -0,0 +1,13 @@
+
+# port
+port 53
+
+cache-size 1024
+
+server 114.114.114.114
+server 123.207.137.88
+server 202.141.178.13:5353
+server 208.67.222.222:5353
+server 77.88.8.8:53
+server 202.141.162.123:53
+server 101.132.183.99:53