conf.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #include "conf.h"
  2. #include "tlog.h"
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <unistd.h>
  7. #define MAX_LINE_LEN 1024
  8. #define MAX_KEY_LEN 64
  9. #define DEFAULT_DNS_PORT 53
  10. #define DEFAULT_DNS_CACHE_SIZE 512
  11. int dns_conf_port = DEFAULT_DNS_PORT;
  12. int dns_conf_cachesize = DEFAULT_DNS_CACHE_SIZE;
  13. struct dns_servers dns_conf_servers[DNS_MAX_SERVERS];
  14. int dns_conf_server_num;
  15. int config_port(char *value)
  16. {
  17. int port = atoi(value);
  18. if (port <= 0 || port >= 65535) {
  19. return -1;
  20. }
  21. dns_conf_port = port;
  22. return 0;
  23. }
  24. int config_parse_ip(char *value, char *ip, unsigned short *port)
  25. {
  26. int offset = 0;
  27. char *colon = NULL;
  28. if (strstr(value, "[")) {
  29. /* ipv6 with port */
  30. char *bracket_end = strstr(value, "]");
  31. if (bracket_end == NULL) {
  32. return -1;
  33. }
  34. offset = bracket_end - value - 1;
  35. memcpy(ip, value + 1, offset);
  36. ip[offset] = 0;
  37. colon = bracket_end + 1;
  38. } else if (strstr(value, "::")) {
  39. /* ipv6 without port */
  40. strncpy(ip, value, DNS_MAX_IPLEN);
  41. colon = NULL;
  42. } else {
  43. /* ipv4 */
  44. colon = strstr(value, ":");
  45. if (colon == NULL) {
  46. /* without port */
  47. strncpy(ip, value, DNS_MAX_IPLEN);
  48. } else {
  49. /* with port */
  50. offset = colon - value;
  51. colon++;
  52. memcpy(ip, value, offset);
  53. }
  54. }
  55. if (colon) {
  56. /* get port num */
  57. *port = atoi(colon);
  58. } else {
  59. *port = DEFAULT_DNS_PORT;
  60. }
  61. return 0;
  62. }
  63. int config_server(char *value, dns_conf_server_type_t type)
  64. {
  65. int index = dns_conf_server_num;
  66. struct dns_servers *server;
  67. if (index >= DNS_MAX_SERVERS) {
  68. tlog(TLOG_ERROR, "exceeds max server number");
  69. return -1;
  70. }
  71. server = &dns_conf_servers[index];
  72. if (config_parse_ip(value, server->server, &server->port) != 0) {
  73. return -1;
  74. }
  75. server->type = type;
  76. dns_conf_server_num++;
  77. return 0;
  78. }
  79. int config_server_udp(char *value)
  80. {
  81. return config_server(value, DNS_CONF_TYPE_UDP);
  82. }
  83. int config_server_tcp(char *value)
  84. {
  85. return config_server(value, DNS_CONF_TYPE_TCP);
  86. }
  87. int config_server_http(char *value)
  88. {
  89. return config_server(value, DNS_CONF_TYPE_HTTP);
  90. }
  91. int config_cache_size(char *value)
  92. {
  93. int cache_size = atoi(value);
  94. if (cache_size < 0) {
  95. return -1;
  96. }
  97. dns_conf_cachesize = cache_size;
  98. return 0;
  99. }
  100. struct config_item {
  101. const char *item;
  102. int (*item_func)(char *value);
  103. };
  104. struct config_item config_item[] = {
  105. {"port", config_port},
  106. {"server", config_server_udp},
  107. {"server-tcp", config_server_tcp},
  108. {"server-http", config_server_http},
  109. {"cache-size", config_cache_size},
  110. };
  111. int config_item_num = sizeof(config_item) / sizeof(struct config_item);
  112. int load_conf(const char *file)
  113. {
  114. FILE *fp = NULL;
  115. char line[MAX_LINE_LEN];
  116. char key[MAX_KEY_LEN];
  117. char value[MAX_LINE_LEN];
  118. int filed_num = 0;
  119. int line_num = 0;
  120. int i;
  121. fp = fopen(file, "r");
  122. if (fp == NULL) {
  123. tlog(TLOG_ERROR, "config file %s not exist.", file);
  124. return -1;
  125. }
  126. while (fgets(line, MAX_LINE_LEN, fp)) {
  127. line_num++;
  128. filed_num = sscanf(line, "%63s %1023[^\r\n]s", key, value);
  129. if (filed_num <= 0) {
  130. continue;
  131. }
  132. if (key[0] == '#') {
  133. continue;
  134. }
  135. if (filed_num != 2) {
  136. goto errout;
  137. }
  138. for (i = 0; i < config_item_num; i++) {
  139. if (strncmp(config_item[i].item, key, MAX_KEY_LEN) != 0) {
  140. continue;
  141. }
  142. if (config_item[i].item_func(value) != 0) {
  143. goto errout;
  144. }
  145. break;
  146. }
  147. }
  148. fclose(fp);
  149. return 0;
  150. errout:
  151. printf("invalid config at line %d: %s", line_num, line);
  152. if (fp) {
  153. fclose(fp);
  154. }
  155. return -1;
  156. }