Add config

This commit is contained in:
Nick Peng
2018-06-07 01:11:44 +08:00
parent d92a67bf2a
commit db3c7df954
7 changed files with 272 additions and 11 deletions

191
conf.c Normal file
View File

@@ -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;
}