Compare commits
14 Commits
Release37-
...
Release37
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a2559f064 | ||
|
|
3605e6ed71 | ||
|
|
6588c9822f | ||
|
|
2f1d83cc2c | ||
|
|
ac042e8bee | ||
|
|
ab415f2ee9 | ||
|
|
d3bbd8edd7 | ||
|
|
9390a49a72 | ||
|
|
798226ddb3 | ||
|
|
d223194eff | ||
|
|
a83818c094 | ||
|
|
4e2161c6fc | ||
|
|
7d62226995 | ||
|
|
092b4ede88 |
9
.github/ISSUE_TEMPLATE/issue.md
vendored
9
.github/ISSUE_TEMPLATE/issue.md
vendored
@@ -15,6 +15,11 @@ assignees: ''
|
||||
|
||||
2. 运营商
|
||||
|
||||
3. smartdns来源以及版本
|
||||
|
||||
4. 涉及的配置(注意去除个人相关信息)
|
||||
|
||||
|
||||
**重现步骤**
|
||||
1. 上游DNS配置。
|
||||
|
||||
@@ -22,8 +27,8 @@ assignees: ''
|
||||
|
||||
|
||||
**信息收集**
|
||||
1. 将/var/log/smrtdns.log日志作为附件上传。
|
||||
2. 如进程异常,请将coredump功能开启,上传coredump信息文件。
|
||||
1. 将/var/log/smrtdns.log日志作为附件上传(注意去除个人相关信息)。
|
||||
2. 如进程异常,请将coredump功能开启,上传coredump信息文件,同时上传配套的smartdns进程文件。
|
||||
在自定义界面,开启设置->自定义设置->生成coredump配置,重现问题后提交coredump文件
|
||||
coredump文件在/tmp目录下
|
||||
|
||||
|
||||
40
Dockerfile
40
Dockerfile
@@ -1,35 +1,41 @@
|
||||
FROM ubuntu:latest as smartdns-builder
|
||||
LABEL previous-stage=smartdns-builder
|
||||
COPY . /smartdns/
|
||||
|
||||
# prepare builder
|
||||
ARG OPENSSL_VER=1.1.1f
|
||||
RUN apt update && \
|
||||
apt install -y perl wget make musl-tools musl-dev && \
|
||||
OPENSSL_VER=1.1.1f && \
|
||||
mkdir /build -p && \
|
||||
apt install -y perl curl make musl-tools musl-dev && \
|
||||
ln -s /usr/include/linux /usr/include/$(uname -m)-linux-musl && \
|
||||
ln -s /usr/include/asm-generic /usr/include/$(uname -m)-linux-musl && \
|
||||
ln -s /usr/include/$(uname -m)-linux-gnu/asm /usr/include/$(uname -m)-linux-musl && \
|
||||
cd /build && \
|
||||
wget http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/openssl_${OPENSSL_VER}.orig.tar.gz && \
|
||||
tar xf openssl_${OPENSSL_VER}.orig.tar.gz && \
|
||||
cd openssl-${OPENSSL_VER} && \
|
||||
\
|
||||
mkdir -p /build/openssl && \
|
||||
cd /build/openssl && \
|
||||
curl -sSL http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/openssl_${OPENSSL_VER}.orig.tar.gz | tar --strip-components=1 -zxv && \
|
||||
\
|
||||
export CC=musl-gcc && \
|
||||
if [ "$(uname -m)" = "aarch64" ]; then \
|
||||
./config --prefix=/opt/build no-tests -mno-outline-atomics ; \
|
||||
else \
|
||||
./config --prefix=/opt/build no-tests; \
|
||||
./config --prefix=/opt/build no-tests ; \
|
||||
fi && \
|
||||
make all -j8 && make install_sw && \
|
||||
cd /smartdns && \
|
||||
cd / && rm -rf /build
|
||||
|
||||
# do make
|
||||
COPY . /build/smartdns/
|
||||
RUN cd /build/smartdns && \
|
||||
export CC=musl-gcc && \
|
||||
export CFLAGS="-I /opt/build/include" && \
|
||||
export LDFLAGS="-L /opt/build/lib" && \
|
||||
sh ./package/build-pkg.sh --platform linux --arch `dpkg --print-architecture` --static && \
|
||||
mkdir /release -p && \
|
||||
cd /smartdns/package && tar xf *.tar.gz && \
|
||||
cp /smartdns/package/smartdns/etc /release/ -a && \
|
||||
cp /smartdns/package/smartdns/usr /release/ -a && \
|
||||
chmod +x /release/etc/init.d/smartdns && \
|
||||
mkdir /release/var/log/ /release/var/run/ -p && \
|
||||
rm -fr /build /smartdns
|
||||
\
|
||||
( cd package && tar -xvf *.tar.gz && chmod a+x smartdns/etc/init.d/smartdns ) && \
|
||||
\
|
||||
mkdir -p /release/var/log /release/var/run && \
|
||||
cp package/smartdns/etc /release/ -a && \
|
||||
cp package/smartdns/usr /release/ -a && \
|
||||
cd / && rm -rf /build
|
||||
|
||||
FROM busybox:latest
|
||||
COPY --from=smartdns-builder /release/ /
|
||||
|
||||
@@ -548,6 +548,8 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
|
||||
|
||||
## 配置文件说明
|
||||
|
||||
配置建议:**smartdns默认已设置为最优模式,适合大部分场景的DNS查询体验改善,一般情况只需要增加上游服务器地址即可,无需做其他配置修改;如有其他配置修改,请务必了解其用途,避免修改后起到反作用。**
|
||||
|
||||
| 键名 | 功能说明 | 默认值 | 可用值/要求 | 举例 |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| server-name | DNS 服务器名称 | 操作系统主机名 / smartdns | 符合主机名规格的字符串 | server-name smartdns |
|
||||
@@ -563,11 +565,11 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
|
||||
| rr-ttl-reply-max | 允许返回给客户端的最大 TTL 值 | 远程查询结果 | 大于 0 的数字 | rr-ttl-reply-max 60 |
|
||||
| max-reply-ip-num | 允许返回给客户的最大IP数量 | IP数量 | 大于 0 的数字 | max-reply-ip-num 1 |
|
||||
| log-level | 设置日志级别 | error | fatal、error、warn、notice、info 或 debug | log-level error |
|
||||
| log-file | 日志文件路径 | /var/log/smartdns.log | 合法路径字符串 | log-file /var/log/smartdns.log |
|
||||
| log-file | 日志文件路径 | /var/log/smartdns/smartdns.log | 合法路径字符串 | log-file /var/log/smartdns/smartdns.log |
|
||||
| log-size | 日志大小 | 128K | 数字 + K、M 或 G | log-size 128K |
|
||||
| log-num | 日志归档个数 | 2 | 大于等于 0 的数字 | log-num 2 |
|
||||
| audit-enable | 设置审计启用 | no | [yes\|no] | audit-enable yes |
|
||||
| audit-file | 审计文件路径 | /var/log/smartdns-audit.log | 合法路径字符串 | audit-file /var/log/smartdns-audit.log |
|
||||
| audit-file | 审计文件路径 | /var/log/smartdns/smartdns-audit.log | 合法路径字符串 | audit-file /var/log/smartdns/smartdns-audit.log |
|
||||
| audit-size | 审计大小 | 128K | 数字 + K、M 或 G | audit-size 128K |
|
||||
| audit-num | 审计归档个数 | 2 | 大于等于 0 的数字 | audit-num 2 |
|
||||
| conf-file | 附加配置文件 | 无 | 合法路径字符串 | conf-file /etc/smartdns/smartdns.more.conf |
|
||||
@@ -576,6 +578,7 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
|
||||
| server-tls | 上游 TLS DNS | 无 | 可重复。<br>[ip][:port]:服务器 IP:端口(可选)<br>[-spki-pin [sha256-pin]]:TLS 合法性校验 SPKI 值,base64 编码的 sha256 SPKI pin 值<br>[-host-name]:TLS SNI 名称<br>[-tls-host-verify]:TLS 证书主机名校验<br> [-no-check-certificate]:跳过证书校验<br>[-blacklist-ip]:配置 IP 过滤结果<br>[-whitelist-ip]:仅接受参数中配置的 IP 范围<br>[-group [group] ...]:DNS 服务器所属组,比如 office 和 foreign,和 nameserver 配套使用<br>[-exclude-default-group]:将 DNS 服务器从默认组中排除 | server-tls 8.8.8.8:853 |
|
||||
| server-https | 上游 HTTPS DNS | 无 | 可重复。<br>https://[host][:port]/path:服务器 IP:端口(可选)<br>[-spki-pin [sha256-pin]]:TLS 合法性校验 SPKI 值,base64 编码的 sha256 SPKI pin 值<br>[-host-name]:TLS SNI 名称<br>[-http-host]:http 协议头主机名<br>[-tls-host-verify]:TLS 证书主机名校验<br> [-no-check-certificate]:跳过证书校验<br>[-blacklist-ip]:配置 IP 过滤结果<br>[-whitelist-ip]:仅接受参数中配置的 IP 范围。<br>[-group [group] ...]:DNS 服务器所属组,比如 office 和 foreign,和 nameserver 配套使用<br>[-exclude-default-group]:将 DNS 服务器从默认组中排除 | server-https https://cloudflare-dns.com/dns-query |
|
||||
| speed-check-mode | 测速模式选择 | 无 | [ping\|tcp:[80]\|none] | speed-check-mode ping,tcp:80,tcp:443 |
|
||||
| response-mode | 首次查询响应模式 | first-ping |模式:[fisrt-ping\|fastest-ip\|first-response]<br> [first-ping]: 最快ping响应地址模式,DNS上游最快查询时延+ping时延最短,查询等待与链接体验最佳;<br>[fastest-ip]: 最快IP地址模式,查询到的所有IP地址中ping最短的IP。需等待IP测速; <br>[first-response]: 最快响应的DNS结果,DNS查询等待时间最短,返回的IP地址可能不是最快。| response-mode first-ping |
|
||||
| address | 指定域名 IP 地址 | 无 | address /domain/[ip\|-\|-4\|-6\|#\|#4\|#6] <br>- 表示忽略 <br># 表示返回 SOA <br>4 表示 IPv4 <br>6 表示 IPv6 | address /www.example.com/1.2.3.4 |
|
||||
| nameserver | 指定域名使用 server 组解析 | 无 | nameserver /domain/[group\|-], group 为组名,- 表示忽略此规则,配套 server 中的 -group 参数使用 | nameserver /www.example.com/office |
|
||||
| ipset | 域名 ipset | 无 | ipset /domain/[ipset\|-\|#[4\|6]:[ipset\|-][,#[4\|6]:[ipset\|-]]],-表示忽略 | ipset /www.example.com/#4:dns4,#6:- |
|
||||
@@ -594,6 +597,7 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
|
||||
| serve-expired-reply-ttl | 回应的过期缓存 TTL | 5 | 秒,0 表示停用超时,大于 0 表示指定的超时的秒数 | serve-expired-reply-ttl 30 |
|
||||
| dualstack-ip-selection | 双栈 IP 优选 | yes | [yes\|no] | dualstack-ip-selection yes |
|
||||
| dualstack-ip-selection-threshold | 双栈 IP 优选阈值 | 15ms | 单位为毫秒(ms) | dualstack-ip-selection-threshold [0-1000] |
|
||||
| user | 进程运行用户 | root | user [username] | user nobody |
|
||||
| ca-file | 证书文件 | /etc/ssl/certs/ca-certificates.crt | 合法路径字符串 | ca-file /etc/ssl/certs/ca-certificates.crt |
|
||||
| ca-path | 证书文件路径 | /etc/ssl/certs | 合法路径字符串 | ca-path /etc/ssl/certs |
|
||||
|
||||
|
||||
@@ -501,11 +501,11 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use
|
||||
|rr-ttl-max|Domain name Maximum TTL|Remote query result|number greater than 0|rr-ttl-max 600
|
||||
|max-reply-ip-num|Maximum number of IPs returned to the client|8|number of IPs, 1~16 |max-reply-ip-num 1
|
||||
|log-level|log level|error|fatal,error,warn,notice,info,debug|log-level error
|
||||
|log-file|log path|/var/log/smartdns.log|File Pah|log-file /var/log/smartdns.log
|
||||
|log-file|log path|/var/log/smartdns/smartdns.log|File Pah|log-file /var/log/smartdns/smartdns.log
|
||||
|log-size|log size|128K|number+K,M,G|log-size 128K
|
||||
|log-num|archived log number|2|Integer|log-num 2
|
||||
|audit-enable|audit log enable|no|[yes\|no]|audit-enable yes
|
||||
|audit-file|audit log file|/var/log/smartdns-audit.log|File Path|audit-file /var/log/smartdns-audit.log
|
||||
|audit-file|audit log file|/var/log/smartdns/smartdns-audit.log|File Path|audit-file /var/log/smartdns/smartdns-audit.log
|
||||
|audit-size|audit log size|128K|number+K,M,G|audit-size 128K
|
||||
|audit-num|archived audit log number|2|Integer|audit-num 2
|
||||
|conf-file|additional conf file|None|File path|conf-file /etc/smartdns/smartdns.more.conf
|
||||
@@ -514,6 +514,7 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use
|
||||
|server-tls|Upstream TLS DNS server|None|Repeatable <br>`[ip][:port]`: Server IP, port optional. <br>`[-spki-pin [sha256-pin]]`: TLS verify SPKI value, a base64 encoded SHA256 hash<br>`[-host-name]`:TLS Server name. <br>`[-tls-host-verify]`: TLS cert hostname to verify. <br>`-no-check-certificate:`: No check certificate. <br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-whitelist-ip]`: whitelist-ip parameter specifies that only the IP range configured in whitelist-ip is accepted. <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server-tls 8.8.8.8:853
|
||||
|server-https|Upstream HTTPS DNS server|None|Repeatable <br>`https://[host][:port]/path`: Server IP, port optional. <br>`[-spki-pin [sha256-pin]]`: TLS verify SPKI value, a base64 encoded SHA256 hash<br>`[-host-name]`:TLS Server name<br>`[-http-host]`:http header host. <br>`[-tls-host-verify]`: TLS cert hostname to verify. <br>`-no-check-certificate:`: No check certificate. <br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-whitelist-ip]`: whitelist-ip parameter specifies that only the IP range configured in whitelist-ip is accepted. <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server-https https://cloudflare-dns.com/dns-query
|
||||
|speed-check-mode|Speed mode|None|[ping\|tcp:[80]\|none]|speed-check-mode ping,tcp:80,tcp:443
|
||||
|response-mode|First query response mode|first-ping|Mode: [fisrt-ping\|fastest-ip\|first-response]<br> [first-ping]: The fastest dns + ping response mode, DNS query delay + ping delay is the shortest;<br>[fastest-ip]: The fastest IP address mode, return the fastest ip address, may take some time to test speed. <br>[first-response]: The fastest response DNS result mode, the DNS query waiting time is the shortest. | response-mode first-ping |
|
||||
|address|Domain IP address|None|address /domain/[ip\|-\|-4\|-6\|#\|#4\|#6], `-` for ignore, `#` for return SOA, `4` for IPV4, `6` for IPV6| address /www.example.com/1.2.3.4
|
||||
|nameserver|To query domain with specific server group|None|nameserver /domain/[group\|-], `group` is the group name, `-` means ignore this rule, use the `-group` parameter in the related server|nameserver /www.example.com/office
|
||||
|ipset|Domain IPSet|None|ipset /domain/[ipset\|-\|#[4\|6]:[ipset\|-][,#[4\|6]:[ipset\|-]]], `-` for ignore|ipset /www.example.com/#4:dns4,#6:-
|
||||
@@ -532,6 +533,7 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use
|
||||
|serve-expired-reply-ttl|TTL value to use when replying with expired data|5|second,0:disable,> 0 seconds after expiration|serve-expired-reply-ttl 30
|
||||
|dualstack-ip-selection|Dualstack ip selection|yes|[yes\|no]|dualstack-ip-selection yes
|
||||
|dualstack-ip-selection-threshold|Dualstack ip select threadhold|15ms|millisecond|dualstack-ip-selection-threshold [0-1000]
|
||||
|user|run as user|root|user [username]|user nobody
|
||||
|ca-file|certificate file|/etc/ssl/certs/ca-certificates.crt|path|ca-file /etc/ssl/certs/ca-certificates.crt
|
||||
|ca-path|certificates path|/etc/ssl/certs|path|ca-path /etc/ssl/certs
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# server-name smartdns
|
||||
#
|
||||
|
||||
# dns server run ser
|
||||
# dns server run user
|
||||
# user [username]
|
||||
# example: run as nobody
|
||||
# user nobody
|
||||
@@ -109,7 +109,7 @@ cache-size 16384
|
||||
# rr-ttl: ttl for all record
|
||||
# rr-ttl-min: minimum ttl for resource record
|
||||
# rr-ttl-max: maximum ttl for resource record
|
||||
# tr-ttl-reply-max: maximum reply ttl for resource record
|
||||
# rr-ttl-reply-max: maximum reply ttl for resource record
|
||||
# example:
|
||||
# rr-ttl 300
|
||||
# rr-ttl-min 60
|
||||
@@ -120,13 +120,17 @@ cache-size 16384
|
||||
# example:
|
||||
# max-reply-ip-num 1
|
||||
|
||||
# response mode
|
||||
# Experimental feature
|
||||
# response-mode [first-ping|fastest-ip|fastest-response]
|
||||
|
||||
# set log level
|
||||
# log-level: [level], level=fatal, error, warn, notice, info, debug
|
||||
# log-file: file path of log file.
|
||||
# log-size: size of each log file, support k,m,g
|
||||
# log-num: number of logs
|
||||
log-level info
|
||||
# log-file /var/log/smartdns.log
|
||||
# log-file /var/log/smartdns/smartdns.log
|
||||
# log-size 128k
|
||||
# log-num 2
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ OBJS=smartdns.o fast_ping.o dns_client.o dns_server.o dns.o util.o tlog.o dns_co
|
||||
|
||||
# cflags
|
||||
ifndef CFLAGS
|
||||
CFLAGS =-O2 -g -Wall -Wstrict-prototypes -fno-omit-frame-pointer -Wstrict-aliasing -funwind-tables
|
||||
CFLAGS =-O2 -g -Wall -Wstrict-prototypes -fno-omit-frame-pointer -Wstrict-aliasing -funwind-tables -Wmissing-prototypes -Wshadow -Wextra -Wno-unused-parameter -Wno-implicit-fallthrough
|
||||
endif
|
||||
override CFLAGS +=-Iinclude
|
||||
override CFLAGS += -DBASE_FILE_NAME=\"$(notdir $<)\"
|
||||
|
||||
252
src/dns.c
252
src/dns.c
@@ -45,7 +45,7 @@
|
||||
/* read short and move pointer */
|
||||
static short _dns_read_short(unsigned char **buffer)
|
||||
{
|
||||
unsigned short value;
|
||||
unsigned short value = 0;
|
||||
|
||||
value = ntohs(*((unsigned short *)(*buffer)));
|
||||
*buffer += 2;
|
||||
@@ -86,7 +86,7 @@ static void _dns_write_int(unsigned char **buffer, unsigned int value)
|
||||
/* read int and move pointer */
|
||||
static unsigned int _dns_read_int(unsigned char **buffer)
|
||||
{
|
||||
unsigned int value;
|
||||
unsigned int value = 0;
|
||||
|
||||
value = ntohl(*((unsigned int *)(*buffer)));
|
||||
*buffer += 4;
|
||||
@@ -99,12 +99,13 @@ static inline int _dns_left_len(struct dns_context *context)
|
||||
return context->maxsize - (context->ptr - context->data);
|
||||
}
|
||||
|
||||
static int _dns_get_domain_from_packet(unsigned char *packet, int packet_size, unsigned char **domain_ptr, char *output, int size)
|
||||
static int _dns_get_domain_from_packet(unsigned char *packet, int packet_size, unsigned char **domain_ptr, char *output,
|
||||
int size)
|
||||
{
|
||||
int output_len = 0;
|
||||
int copy_len = 0;
|
||||
int len = 0;
|
||||
unsigned char *ptr = (unsigned char*)*domain_ptr;
|
||||
unsigned char *ptr = *domain_ptr;
|
||||
int is_compressed = 0;
|
||||
int ptr_jump = 0;
|
||||
|
||||
@@ -140,8 +141,8 @@ static int _dns_get_domain_from_packet(unsigned char *packet, int packet_size, u
|
||||
|
||||
ptr = packet + len;
|
||||
if (ptr > packet + packet_size) {
|
||||
tlog(TLOG_DEBUG, "length is not enough %u:%ld, %p, %p", packet_size, (long)(ptr - packet),
|
||||
*domain_ptr, packet);
|
||||
tlog(TLOG_DEBUG, "length is not enough %u:%ld, %p, %p", packet_size, (long)(ptr - packet), *domain_ptr,
|
||||
packet);
|
||||
return -1;
|
||||
}
|
||||
is_compressed = 1;
|
||||
@@ -159,8 +160,8 @@ static int _dns_get_domain_from_packet(unsigned char *packet, int packet_size, u
|
||||
}
|
||||
|
||||
if (ptr > packet + packet_size) {
|
||||
tlog(TLOG_DEBUG, "length is not enough %u:%ld, %p, %p", packet_size, (long)(ptr - packet),
|
||||
*domain_ptr, packet);
|
||||
tlog(TLOG_DEBUG, "length is not enough %u:%ld, %p, %p", packet_size, (long)(ptr - packet), *domain_ptr,
|
||||
packet);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -169,8 +170,8 @@ static int _dns_get_domain_from_packet(unsigned char *packet, int packet_size, u
|
||||
/* copy sub string */
|
||||
copy_len = (len < size - output_len) ? len : size - 1 - output_len;
|
||||
if ((ptr + copy_len) > (packet + packet_size)) {
|
||||
tlog(TLOG_DEBUG, "length is not enough %u:%ld, %p, %p", packet_size, (long)(ptr - packet),
|
||||
*domain_ptr, packet);
|
||||
tlog(TLOG_DEBUG, "length is not enough %u:%ld, %p, %p", packet_size, (long)(ptr - packet), *domain_ptr,
|
||||
packet);
|
||||
return -1;
|
||||
}
|
||||
memcpy(output, ptr, copy_len);
|
||||
@@ -190,18 +191,20 @@ static int _dns_get_domain_from_packet(unsigned char *packet, int packet_size, u
|
||||
|
||||
static int _dns_decode_domain(struct dns_context *context, char *output, int size)
|
||||
{
|
||||
return _dns_get_domain_from_packet(context->data, context->maxsize, &(context->ptr), output, size);
|
||||
return _dns_get_domain_from_packet(context->data, context->maxsize, &(context->ptr), output, size);
|
||||
}
|
||||
|
||||
unsigned int dict_hash(const char *s)
|
||||
static unsigned int dict_hash(const char *s)
|
||||
{
|
||||
unsigned int hashval;
|
||||
for (hashval = 0; *s != '\0'; s++)
|
||||
hashval = *s + 31 * hashval;
|
||||
return hashval;
|
||||
unsigned int hashval = 0;
|
||||
for (hashval = 0; *s != '\0'; s++) {
|
||||
hashval = *s + 31 * hashval;
|
||||
}
|
||||
return hashval;
|
||||
}
|
||||
|
||||
int _dns_add_domain_dict(struct dns_context *context, unsigned int hash, int pos) {
|
||||
static int _dns_add_domain_dict(struct dns_context *context, unsigned int hash, int pos)
|
||||
{
|
||||
struct dns_packet_dict *dict = context->namedict;
|
||||
|
||||
if (dict->dict_count >= DNS_PACKET_DICT_SIZE) {
|
||||
@@ -224,7 +227,8 @@ int _dns_add_domain_dict(struct dns_context *context, unsigned int hash, int pos
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _dns_get_domain_offset(struct dns_context *context, const char *domain) {
|
||||
static int _dns_get_domain_offset(struct dns_context *context, const char *domain)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
char domain_check[DNS_MAX_CNAME_LEN];
|
||||
@@ -241,7 +245,8 @@ int _dns_get_domain_offset(struct dns_context *context, const char *domain) {
|
||||
}
|
||||
|
||||
unsigned char *domain_check_ptr = dict->names[i].pos + context->data;
|
||||
if (_dns_get_domain_from_packet(context->data, context->maxsize, &domain_check_ptr, domain_check, DNS_MAX_CNAME_LEN) !=0) {
|
||||
if (_dns_get_domain_from_packet(context->data, context->maxsize, &domain_check_ptr, domain_check,
|
||||
DNS_MAX_CNAME_LEN) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -252,7 +257,7 @@ int _dns_get_domain_offset(struct dns_context *context, const char *domain) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _dns_encode_domain(struct dns_context *context, char *domain)
|
||||
static int _dns_encode_domain(struct dns_context *context, const char *domain)
|
||||
{
|
||||
int num = 0;
|
||||
int total_len = 0;
|
||||
@@ -269,7 +274,6 @@ static int _dns_encode_domain(struct dns_context *context, char *domain)
|
||||
int offset = 0xc000 | dict_offset;
|
||||
_dns_write_short(&ptr_num, offset);
|
||||
context->ptr++;
|
||||
dict_offset = -1;
|
||||
ptr_num = NULL;
|
||||
return total_len;
|
||||
}
|
||||
@@ -308,7 +312,7 @@ static int _dns_encode_domain(struct dns_context *context, char *domain)
|
||||
/* iterator get rrs begin */
|
||||
struct dns_rrs *dns_get_rrs_start(struct dns_packet *packet, dns_rr_type type, int *count)
|
||||
{
|
||||
unsigned short start;
|
||||
unsigned short start = 0;
|
||||
struct dns_head *head = &packet->head;
|
||||
|
||||
/* get rrs count by rrs type */
|
||||
@@ -338,7 +342,7 @@ struct dns_rrs *dns_get_rrs_start(struct dns_packet *packet, dns_rr_type type, i
|
||||
break;
|
||||
}
|
||||
|
||||
/* if not resource record, reutrn null */
|
||||
/* if not resource record, return null */
|
||||
if (start == DNS_RR_END) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -357,8 +361,9 @@ struct dns_rrs *dns_get_rrs_next(struct dns_packet *packet, struct dns_rrs *rrs)
|
||||
return (struct dns_rrs *)(packet->data + rrs->next);
|
||||
}
|
||||
|
||||
static void _dns_init_context_by_rrs(struct dns_rrs *rrs, struct dns_context *context) {
|
||||
context->packet =rrs->packet;
|
||||
static void _dns_init_context_by_rrs(struct dns_rrs *rrs, struct dns_context *context)
|
||||
{
|
||||
context->packet = rrs->packet;
|
||||
context->data = rrs->packet->data;
|
||||
context->ptr = rrs->data;
|
||||
context->namedict = &rrs->packet->namedict;
|
||||
@@ -368,10 +373,10 @@ static void _dns_init_context_by_rrs(struct dns_rrs *rrs, struct dns_context *co
|
||||
/* iterator add rrs begin */
|
||||
static int _dns_add_rrs_start(struct dns_packet *packet, struct dns_context *context)
|
||||
{
|
||||
struct dns_rrs *rrs;
|
||||
struct dns_rrs *rrs = NULL;
|
||||
unsigned char *end = packet->data + packet->len;
|
||||
|
||||
if ((packet->len + sizeof(*rrs)) >= packet->size) {
|
||||
if ((packet->len + (int)sizeof(*rrs)) >= packet->size) {
|
||||
return -1;
|
||||
}
|
||||
rrs = (struct dns_rrs *)end;
|
||||
@@ -388,15 +393,15 @@ static int _dns_add_rrs_start(struct dns_packet *packet, struct dns_context *con
|
||||
/* iterator add rrs end */
|
||||
static int _dns_rr_add_end(struct dns_packet *packet, int type, dns_type_t rtype, int len)
|
||||
{
|
||||
struct dns_rrs *rrs;
|
||||
struct dns_rrs *rrs_next;
|
||||
struct dns_rrs *rrs = NULL;
|
||||
struct dns_rrs *rrs_next = NULL;
|
||||
struct dns_head *head = &packet->head;
|
||||
unsigned char *end = packet->data + packet->len;
|
||||
unsigned short *count;
|
||||
unsigned short *start;
|
||||
unsigned short *count = NULL;
|
||||
unsigned short *start = NULL;
|
||||
|
||||
rrs = (struct dns_rrs *)end;
|
||||
if (packet->len + len > packet->size - sizeof(*packet) - sizeof(*rrs)) {
|
||||
if (packet->len + len > packet->size - (int)sizeof(*packet) - (int)sizeof(*rrs)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -426,7 +431,7 @@ static int _dns_rr_add_end(struct dns_packet *packet, int type, dns_type_t rtype
|
||||
break;
|
||||
}
|
||||
|
||||
/* add data to end of dns_packet, and set previouse rrs point to this rrs */
|
||||
/* add data to end of dns_packet, and set previous rrs point to this rrs */
|
||||
if (*start != DNS_RR_END) {
|
||||
rrs_next = (struct dns_rrs *)(packet->data + *start);
|
||||
while (rrs_next->next != DNS_RR_END) {
|
||||
@@ -449,7 +454,7 @@ static int _dns_rr_add_end(struct dns_packet *packet, int type, dns_type_t rtype
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_add_qr_head(struct dns_context *context, char *domain, int qtype, int qclass)
|
||||
static int _dns_add_qr_head(struct dns_context *context, const char *domain, int qtype, int qclass)
|
||||
{
|
||||
int ret = _dns_encode_domain(context, domain);
|
||||
if (ret < 0) {
|
||||
@@ -473,7 +478,7 @@ static int _dns_get_qr_head(struct dns_context *context, char *domain, int maxsi
|
||||
if (domain == NULL || context == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
ret = _dns_decode_domain(context, domain, maxsize);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
@@ -489,8 +494,7 @@ static int _dns_get_qr_head(struct dns_context *context, char *domain, int maxsi
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_add_rr_head(struct dns_context *context, char *domain, int qtype, int qclass, int ttl,
|
||||
int rr_len)
|
||||
static int _dns_add_rr_head(struct dns_context *context, const char *domain, int qtype, int qclass, int ttl, int rr_len)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
@@ -515,8 +519,8 @@ static int _dns_add_rr_head(struct dns_context *context, char *domain, int qtype
|
||||
return len + 6;
|
||||
}
|
||||
|
||||
static int _dns_get_rr_head(struct dns_context *context, char *domain, int maxsize, int *qtype, int *qclass,
|
||||
int *ttl, int *rr_len)
|
||||
static int _dns_get_rr_head(struct dns_context *context, char *domain, int maxsize, int *qtype, int *qclass, int *ttl,
|
||||
int *rr_len)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
@@ -538,12 +542,12 @@ static int _dns_get_rr_head(struct dns_context *context, char *domain, int maxsi
|
||||
return len;
|
||||
}
|
||||
|
||||
static int _dns_add_RAW(struct dns_packet *packet, dns_rr_type rrtype, dns_type_t rtype, char *domain, int ttl,
|
||||
void *raw, int raw_len)
|
||||
static int _dns_add_RAW(struct dns_packet *packet, dns_rr_type rrtype, dns_type_t rtype, const char *domain, int ttl,
|
||||
const void *raw, int raw_len)
|
||||
{
|
||||
int len = 0;
|
||||
struct dns_context context;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
/* resource record */
|
||||
/* |domain |
|
||||
@@ -621,7 +625,7 @@ static int _dns_add_opt_RAW(struct dns_packet *packet, dns_opt_code_t opt_rrtype
|
||||
len += raw_len;
|
||||
len += sizeof(*opt);
|
||||
|
||||
return _dns_add_RAW(packet, DNS_RRS_OPT, DNS_OPT_T_TCP_KEEPALIVE, "", 0, opt_data, len);
|
||||
return _dns_add_RAW(packet, DNS_RRS_OPT, (dns_type_t)DNS_OPT_T_TCP_KEEPALIVE, "", 0, opt_data, len);
|
||||
}
|
||||
|
||||
static int _dns_get_opt_RAW(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, struct dns_opt *dns_opt,
|
||||
@@ -715,7 +719,7 @@ static int __attribute__((unused)) _dns_get_OPT(struct dns_rrs *rrs, unsigned sh
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_add_CNAME(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, char *cname)
|
||||
int dns_add_CNAME(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl, const char *cname)
|
||||
{
|
||||
int rr_len = strnlen(cname, DNS_MAX_CNAME_LEN) + 1;
|
||||
return _dns_add_RAW(packet, type, DNS_T_CNAME, domain, ttl, cname, rr_len);
|
||||
@@ -727,7 +731,8 @@ int dns_get_CNAME(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, char
|
||||
return _dns_get_RAW(rrs, domain, maxsize, ttl, cname, &len);
|
||||
}
|
||||
|
||||
int dns_add_A(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, unsigned char addr[DNS_RR_A_LEN])
|
||||
int dns_add_A(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl,
|
||||
unsigned char addr[DNS_RR_A_LEN])
|
||||
{
|
||||
return _dns_add_RAW(packet, type, DNS_T_A, domain, ttl, addr, DNS_RR_A_LEN);
|
||||
}
|
||||
@@ -738,7 +743,7 @@ int dns_get_A(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsigned
|
||||
return _dns_get_RAW(rrs, domain, maxsize, ttl, addr, &len);
|
||||
}
|
||||
|
||||
int dns_add_PTR(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, char *cname)
|
||||
int dns_add_PTR(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl, char *cname)
|
||||
{
|
||||
int rr_len = strnlen(cname, DNS_MAX_CNAME_LEN) + 1;
|
||||
return _dns_add_RAW(packet, type, DNS_T_PTR, domain, ttl, cname, rr_len);
|
||||
@@ -750,7 +755,7 @@ int dns_get_PTR(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, char *
|
||||
return _dns_get_RAW(rrs, domain, maxsize, ttl, cname, &len);
|
||||
}
|
||||
|
||||
int dns_add_NS(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, char *cname)
|
||||
int dns_add_NS(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl, const char *cname)
|
||||
{
|
||||
int rr_len = strnlen(cname, DNS_MAX_CNAME_LEN) + 1;
|
||||
return _dns_add_RAW(packet, type, DNS_T_NS, domain, ttl, cname, rr_len);
|
||||
@@ -762,7 +767,7 @@ int dns_get_NS(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, char *c
|
||||
return _dns_get_RAW(rrs, domain, maxsize, ttl, cname, &len);
|
||||
}
|
||||
|
||||
int dns_add_AAAA(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl,
|
||||
int dns_add_AAAA(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl,
|
||||
unsigned char addr[DNS_RR_AAAA_LEN])
|
||||
{
|
||||
return _dns_add_RAW(packet, type, DNS_T_AAAA, domain, ttl, addr, DNS_RR_AAAA_LEN);
|
||||
@@ -774,7 +779,7 @@ int dns_get_AAAA(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsig
|
||||
return _dns_get_RAW(rrs, domain, maxsize, ttl, addr, &len);
|
||||
}
|
||||
|
||||
int dns_add_SOA(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, struct dns_soa *soa)
|
||||
int dns_add_SOA(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl, struct dns_soa *soa)
|
||||
{
|
||||
/* SOA */
|
||||
/*| mname |
|
||||
@@ -845,7 +850,6 @@ int dns_get_SOA(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, struct
|
||||
memcpy(&soa->expire, ptr, 4);
|
||||
ptr += 4;
|
||||
memcpy(&soa->minimum, ptr, 4);
|
||||
ptr += 4;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -881,7 +885,7 @@ int dns_add_OPT_ECS(struct dns_packet *packet, struct dns_opt_ecs *ecs)
|
||||
memcpy(opt->data, ecs, len);
|
||||
len += sizeof(*opt);
|
||||
|
||||
return _dns_add_RAW(packet, DNS_RRS_OPT, DNS_OPT_T_ECS, "", 0, opt_data, len);
|
||||
return _dns_add_RAW(packet, DNS_RRS_OPT, (dns_type_t)DNS_OPT_T_ECS, "", 0, opt_data, len);
|
||||
}
|
||||
|
||||
int dns_get_OPT_ECS(struct dns_rrs *rrs, unsigned short *opt_code, unsigned short *opt_len, struct dns_opt_ecs *ecs)
|
||||
@@ -896,7 +900,7 @@ int dns_get_OPT_ECS(struct dns_rrs *rrs, unsigned short *opt_code, unsigned shor
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len < sizeof(*opt)) {
|
||||
if (len < (int)sizeof(*opt)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -934,7 +938,7 @@ int dns_get_OPT_TCP_KEEYALIVE(struct dns_rrs *rrs, unsigned short *opt_code, uns
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len < sizeof(*opt)) {
|
||||
if (len < (int)sizeof(*opt)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -962,7 +966,7 @@ int dns_get_OPT_TCP_KEEYALIVE(struct dns_rrs *rrs, unsigned short *opt_code, uns
|
||||
* Format:
|
||||
* |DNS_NAME\0(string)|qtype(short)|qclass(short)|
|
||||
*/
|
||||
int dns_add_domain(struct dns_packet *packet, char *domain, int qtype, int qclass)
|
||||
int dns_add_domain(struct dns_packet *packet, const char *domain, int qtype, int qclass)
|
||||
{
|
||||
int len = 0;
|
||||
int ret = 0;
|
||||
@@ -995,7 +999,7 @@ int dns_get_domain(struct dns_rrs *rrs, char *domain, int maxsize, int *qtype, i
|
||||
|
||||
static int _dns_decode_head(struct dns_context *context)
|
||||
{
|
||||
unsigned int fields;
|
||||
unsigned int fields = 0;
|
||||
int len = 12;
|
||||
struct dns_head *head = &context->packet->head;
|
||||
|
||||
@@ -1152,7 +1156,8 @@ static int _dns_decode_rr_head(struct dns_context *context, char *domain, int do
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_encode_rr_head(struct dns_context *context, char *domain, int qtype, int qclass, int ttl, int rr_len, unsigned char **rr_len_ptr)
|
||||
static int _dns_encode_rr_head(struct dns_context *context, char *domain, int qtype, int qclass, int ttl, int rr_len,
|
||||
unsigned char **rr_len_ptr)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = _dns_encode_qr_head(context, domain, qtype, qclass);
|
||||
@@ -1175,12 +1180,12 @@ static int _dns_encode_rr_head(struct dns_context *context, char *domain, int qt
|
||||
|
||||
static int _dns_encode_raw(struct dns_context *context, struct dns_rrs *rrs)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
int qtype = 0;
|
||||
int qclass = 0;
|
||||
int ttl = 0;
|
||||
char domain[DNS_MAX_CNAME_LEN];
|
||||
int rr_len;
|
||||
int rr_len = 0;
|
||||
unsigned char *rr_len_ptr = NULL;
|
||||
struct dns_context data_context;
|
||||
/*
|
||||
@@ -1250,12 +1255,12 @@ static int _dns_decode_CNAME(struct dns_context *context, char *cname, int cname
|
||||
|
||||
static int _dns_encode_CNAME(struct dns_context *context, struct dns_rrs *rrs)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
int qtype = 0;
|
||||
int qclass = 0;
|
||||
int ttl = 0;
|
||||
char domain[DNS_MAX_CNAME_LEN];
|
||||
int rr_len;
|
||||
int rr_len = 0;
|
||||
unsigned char *rr_len_ptr = NULL;
|
||||
struct dns_context data_context;
|
||||
|
||||
@@ -1315,7 +1320,7 @@ static int _dns_decode_SOA(struct dns_context *context, struct dns_soa *soa)
|
||||
|
||||
static int _dns_encode_SOA(struct dns_context *context, struct dns_rrs *rrs)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
int qtype = 0;
|
||||
int qclass = 0;
|
||||
int ttl = 0;
|
||||
@@ -1391,7 +1396,7 @@ static int _dns_decode_opt_ecs(struct dns_context *context, struct dns_opt_ecs *
|
||||
len = (ecs->source_prefix / 8);
|
||||
len += (ecs->source_prefix % 8 > 0) ? 1 : 0;
|
||||
|
||||
if (_dns_left_len(context) < len || len > sizeof(ecs->addr)) {
|
||||
if (_dns_left_len(context) < len || len > (int)sizeof(ecs->addr)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1405,7 +1410,6 @@ static int _dns_decode_opt_ecs(struct dns_context *context, struct dns_opt_ecs *
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int _dns_decode_opt_cookie(struct dns_context *context, struct dns_opt_cookie *cookie)
|
||||
{
|
||||
// TODO
|
||||
@@ -1436,16 +1440,15 @@ static int _dns_decode_opt_cookie(struct dns_context *context, struct dns_opt_co
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int _dns_encode_OPT(struct dns_context *context, struct dns_rrs *rrs)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
int opt_code = 0;
|
||||
int qclass = 0;
|
||||
char domain[DNS_MAX_CNAME_LEN];
|
||||
struct dns_context data_context;
|
||||
int rr_len = 0;
|
||||
int ttl;
|
||||
int ttl = 0;
|
||||
struct dns_opt *dns_opt = NULL;
|
||||
|
||||
_dns_init_context_by_rrs(rrs, &data_context);
|
||||
@@ -1454,7 +1457,7 @@ static int _dns_encode_OPT(struct dns_context *context, struct dns_rrs *rrs)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rr_len < sizeof(*dns_opt)) {
|
||||
if (rr_len < (int)sizeof(*dns_opt)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1493,8 +1496,8 @@ static int _dns_get_opts_data_len(struct dns_packet *packet, struct dns_rrs *rrs
|
||||
int len = 0;
|
||||
int opt_code = 0;
|
||||
int qclass = 0;
|
||||
int ttl;
|
||||
int ret;
|
||||
int ttl = 0;
|
||||
int ret = 0;
|
||||
char domain[DNS_MAX_CNAME_LEN];
|
||||
struct dns_context data_context;
|
||||
int rr_len = 0;
|
||||
@@ -1550,10 +1553,10 @@ static int _dns_encode_opts(struct dns_packet *packet, struct dns_context *conte
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __attribute__((unused)) _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsigned int ttl, int rr_len)
|
||||
static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsigned int ttl, int rr_len)
|
||||
{
|
||||
unsigned short opt_code;
|
||||
unsigned short opt_len;
|
||||
unsigned short opt_code = 0;
|
||||
unsigned short opt_len = 0;
|
||||
unsigned short ercode = (ttl >> 16) & 0xFFFF;
|
||||
unsigned short ever = (ttl)&0xFFFF;
|
||||
unsigned char *start = context->ptr;
|
||||
@@ -1599,6 +1602,8 @@ static int __attribute__((unused)) _dns_decode_opt(struct dns_context *context,
|
||||
|
||||
while (context->ptr - start < rr_len) {
|
||||
if (_dns_left_len(context) < 4) {
|
||||
tlog(TLOG_WARN, "data length is invalid, %d:%d", _dns_left_len(context),
|
||||
(int)(context->ptr - context->data));
|
||||
return -1;
|
||||
}
|
||||
opt_code = _dns_read_short(&context->ptr);
|
||||
@@ -1646,7 +1651,7 @@ static int __attribute__((unused)) _dns_decode_opt(struct dns_context *context,
|
||||
static int _dns_decode_qd(struct dns_context *context)
|
||||
{
|
||||
struct dns_packet *packet = context->packet;
|
||||
int len;
|
||||
int len = 0;
|
||||
int qtype = 0;
|
||||
int qclass = 0;
|
||||
char domain[DNS_MAX_CNAME_LEN];
|
||||
@@ -1666,14 +1671,14 @@ static int _dns_decode_qd(struct dns_context *context)
|
||||
|
||||
static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
int qtype = 0;
|
||||
int qclass = 0;
|
||||
int ttl;
|
||||
int ttl = 0;
|
||||
int rr_len = 0;
|
||||
char domain[DNS_MAX_CNAME_LEN];
|
||||
struct dns_packet *packet = context->packet;
|
||||
unsigned char *start;
|
||||
unsigned char *start = NULL;
|
||||
|
||||
/* decode rr head */
|
||||
ret = _dns_decode_rr_head(context, domain, DNS_MAX_CNAME_LEN, &qtype, &qclass, &ttl, &rr_len);
|
||||
@@ -1689,7 +1694,8 @@ static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
unsigned char addr[DNS_RR_A_LEN];
|
||||
ret = _dns_decode_raw(context, addr, sizeof(addr));
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode A failed, %s", domain);
|
||||
tlog(TLOG_DEBUG, "decode A failed, %s, len: %d:%d", domain, (int)(context->ptr - context->data),
|
||||
_dns_left_len(context));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1703,7 +1709,8 @@ static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
char cname[DNS_MAX_CNAME_LEN];
|
||||
ret = _dns_decode_CNAME(context, cname, DNS_MAX_CNAME_LEN);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode CNAME failed, %s", domain);
|
||||
tlog(TLOG_DEBUG, "decode CNAME failed, %s, len: %d:%d", domain, (int)(context->ptr - context->data),
|
||||
_dns_left_len(context));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1717,13 +1724,13 @@ static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
struct dns_soa soa;
|
||||
ret = _dns_decode_SOA(context, &soa);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode CNAME failed, %s", domain);
|
||||
tlog(TLOG_DEBUG, "decode SOA failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = dns_add_SOA(packet, type, domain, ttl, &soa);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "add CNAME failed, %s", domain);
|
||||
tlog(TLOG_ERROR, "add SOA failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
} break;
|
||||
@@ -1731,7 +1738,7 @@ static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
char ns[DNS_MAX_CNAME_LEN];
|
||||
ret = _dns_decode_CNAME(context, ns, DNS_MAX_CNAME_LEN);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode NS failed, %s", domain);
|
||||
tlog(TLOG_DEBUG, "decode NS failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1745,7 +1752,7 @@ static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
char 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);
|
||||
tlog(TLOG_DEBUG, "decode PTR failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1759,7 +1766,7 @@ static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
unsigned char addr[DNS_RR_AAAA_LEN];
|
||||
ret = _dns_decode_raw(context, addr, sizeof(addr));
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode AAAA failed, %s", domain);
|
||||
tlog(TLOG_DEBUG, "decode AAAA failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1773,12 +1780,12 @@ static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
unsigned char *opt_start = context->ptr;
|
||||
ret = _dns_decode_opt(context, type, ttl, rr_len);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode opt failed, %s", domain);
|
||||
tlog(TLOG_DEBUG, "decode opt failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (context->ptr - opt_start != rr_len) {
|
||||
tlog(TLOG_ERROR, "opt length mismatch, %s\n", domain);
|
||||
tlog(TLOG_DEBUG, "opt length mismatch, %s\n", domain);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1786,14 +1793,14 @@ static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
} break;
|
||||
default: {
|
||||
unsigned char raw_data[1024];
|
||||
if (_dns_left_len(context) < rr_len || rr_len >= sizeof(raw_data)) {
|
||||
if (_dns_left_len(context) < rr_len || rr_len >= (int)sizeof(raw_data)) {
|
||||
tlog(TLOG_DEBUG, "length mismatch\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = _dns_decode_raw(context, raw_data, rr_len);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode A failed, %s", domain);
|
||||
tlog(TLOG_DEBUG, "decode A failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1802,7 +1809,7 @@ static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
tlog(TLOG_ERROR, "add raw failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
tlog(TLOG_DEBUG, "DNS type = %d not supported", qtype);
|
||||
break;
|
||||
}
|
||||
@@ -1818,7 +1825,7 @@ static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
|
||||
static int _dns_encode_qd(struct dns_context *context, struct dns_rrs *rrs)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
int qtype = 0;
|
||||
int qclass = 0;
|
||||
char domain[DNS_MAX_CNAME_LEN];
|
||||
@@ -1840,7 +1847,7 @@ static int _dns_encode_qd(struct dns_context *context, struct dns_rrs *rrs)
|
||||
|
||||
static int _dns_encode_an(struct dns_context *context, struct dns_rrs *rrs)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
switch (rrs->type) {
|
||||
case DNS_T_A:
|
||||
case DNS_T_AAAA: {
|
||||
@@ -1930,8 +1937,8 @@ static int _dns_encode_body(struct dns_context *context)
|
||||
struct dns_head *head = &packet->head;
|
||||
int i = 0;
|
||||
int len = 0;
|
||||
struct dns_rrs *rrs;
|
||||
int count;
|
||||
struct dns_rrs *rrs = NULL;
|
||||
int count = 0;
|
||||
|
||||
rrs = dns_get_rrs_start(packet, DNS_RRS_QD, &count);
|
||||
head->qdcount = count;
|
||||
@@ -1984,7 +1991,7 @@ static int _dns_encode_body(struct dns_context *context)
|
||||
int dns_packet_init(struct dns_packet *packet, int size, struct dns_head *head)
|
||||
{
|
||||
struct dns_head *init_head = &packet->head;
|
||||
if (size < sizeof(*packet)) {
|
||||
if (size < (int)sizeof(*packet)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2079,13 +2086,13 @@ int dns_encode(unsigned char *data, int size, struct dns_packet *packet)
|
||||
|
||||
static int _dns_update_an(struct dns_context *context, dns_rr_type type, struct dns_update_param *param)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
int qtype = 0;
|
||||
int qclass = 0;
|
||||
int ttl;
|
||||
int ttl = 0;
|
||||
int rr_len = 0;
|
||||
char domain[DNS_MAX_CNAME_LEN];
|
||||
unsigned char *start;
|
||||
unsigned char *start = NULL;
|
||||
|
||||
/* decode rr head */
|
||||
ret = _dns_decode_rr_head(context, domain, DNS_MAX_CNAME_LEN, &qtype, &qclass, &ttl, &rr_len);
|
||||
@@ -2115,7 +2122,6 @@ static int _dns_update_an(struct dns_context *context, dns_rr_type type, struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int _dns_update_body(struct dns_context *context, struct dns_update_param *param)
|
||||
{
|
||||
struct dns_packet *packet = context->packet;
|
||||
@@ -2128,9 +2134,9 @@ static int _dns_update_body(struct dns_context *context, struct dns_update_param
|
||||
head->qdcount = 0;
|
||||
for (i = 0; i < count; i++) {
|
||||
char domain[DNS_MAX_CNAME_LEN];
|
||||
int qtype;
|
||||
int qclass;
|
||||
int len;
|
||||
int qtype = 0;
|
||||
int qclass = 0;
|
||||
int len = 0;
|
||||
len = _dns_decode_qr_head(context, domain, DNS_MAX_CNAME_LEN, &qtype, &qclass);
|
||||
if (len < 0) {
|
||||
tlog(TLOG_DEBUG, "update qd failed.");
|
||||
@@ -2171,8 +2177,8 @@ static int _dns_update_body(struct dns_context *context, struct dns_update_param
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _dns_update_id(unsigned char *data, int size, struct dns_update_param *param) {
|
||||
|
||||
static int _dns_update_id(unsigned char *data, int size, struct dns_update_param *param)
|
||||
{
|
||||
unsigned char *ptr = data;
|
||||
_dns_write_short(&ptr, param->id);
|
||||
return 0;
|
||||
@@ -2213,47 +2219,7 @@ int dns_packet_update(unsigned char *data, int size, struct dns_update_param *pa
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_DEBUG, "decode body failed.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void dns_debug(void)
|
||||
{
|
||||
unsigned char data[1024];
|
||||
int len;
|
||||
char buff[4096];
|
||||
|
||||
int fd = open("dns.bin", O_RDWR);
|
||||
if (fd < 0) {
|
||||
return;
|
||||
}
|
||||
len = read(fd, data, 1024);
|
||||
close(fd);
|
||||
if (len < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct dns_packet *packet = (struct dns_packet *)buff;
|
||||
if (dns_decode(packet, 4096, data, len) != 0) {
|
||||
tlog(TLOG_ERROR, "decode failed.\n");
|
||||
}
|
||||
|
||||
memset(data, 0, sizeof(data));
|
||||
len = dns_encode(data, 1024, packet);
|
||||
if (len < 0) {
|
||||
tlog(TLOG_ERROR, "encode failed.");
|
||||
}
|
||||
|
||||
fd = open("dns-cmp.bin", O_CREAT | O_TRUNC | O_RDWR, 0660);
|
||||
write(fd, data, len);
|
||||
close(fd);
|
||||
|
||||
packet = (struct dns_packet *)buff;
|
||||
if (dns_decode(packet, 4096, data, len) != 0) {
|
||||
tlog(TLOG_ERROR, "decode failed.\n");
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
24
src/dns.h
24
src/dns.h
@@ -23,8 +23,8 @@
|
||||
#define DNS_RR_AAAA_LEN 16
|
||||
#define DNS_MAX_CNAME_LEN 256
|
||||
#define DNS_MAX_OPT_LEN 256
|
||||
#define DNS_IN_PACKSIZE (512 * 4)
|
||||
#define DNS_PACKSIZE (512 * 10)
|
||||
#define DNS_IN_PACKSIZE (512 * 8)
|
||||
#define DNS_PACKSIZE (512 * 12)
|
||||
#define DNS_DEFAULT_PACKET_SIZE 512
|
||||
|
||||
#define DNS_ADDR_FAMILY_IP 1
|
||||
@@ -121,7 +121,7 @@ struct dns_head {
|
||||
|
||||
#define DNS_PACKET_DICT_SIZE 16
|
||||
struct dns_packet_dict_item {
|
||||
unsigned pos;
|
||||
unsigned short pos;
|
||||
unsigned int hash;
|
||||
};
|
||||
|
||||
@@ -150,7 +150,7 @@ struct dns_rrs {
|
||||
struct dns_packet *packet;
|
||||
unsigned short next;
|
||||
unsigned short len;
|
||||
dns_type_t type;
|
||||
int type;
|
||||
unsigned char data[0];
|
||||
};
|
||||
|
||||
@@ -159,7 +159,7 @@ struct dns_context {
|
||||
struct dns_packet *packet;
|
||||
struct dns_packet_dict *namedict;
|
||||
unsigned char *data;
|
||||
unsigned int maxsize;
|
||||
int maxsize;
|
||||
unsigned char *ptr;
|
||||
};
|
||||
|
||||
@@ -205,29 +205,29 @@ struct dns_rrs *dns_get_rrs_start(struct dns_packet *packet, dns_rr_type type, i
|
||||
/*
|
||||
* Question
|
||||
*/
|
||||
int dns_add_domain(struct dns_packet *packet, char *domain, int qtype, int qclass);
|
||||
int dns_add_domain(struct dns_packet *packet, const char *domain, int qtype, int qclass);
|
||||
int dns_get_domain(struct dns_rrs *rrs, char *domain, int maxsize, int *qtype, int *qclass);
|
||||
|
||||
/*
|
||||
* Answers
|
||||
*/
|
||||
int dns_add_CNAME(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, char *cname);
|
||||
int dns_add_CNAME(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl, const char *cname);
|
||||
int dns_get_CNAME(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, char *cname, int cname_size);
|
||||
|
||||
int dns_add_A(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, unsigned char addr[DNS_RR_A_LEN]);
|
||||
int dns_add_A(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl, unsigned char addr[DNS_RR_A_LEN]);
|
||||
int dns_get_A(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsigned char addr[DNS_RR_A_LEN]);
|
||||
|
||||
int dns_add_PTR(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, char *cname);
|
||||
int dns_add_PTR(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl, char *cname);
|
||||
int dns_get_PTR(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, char *cname, int cname_size);
|
||||
|
||||
int dns_add_AAAA(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl,
|
||||
int dns_add_AAAA(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl,
|
||||
unsigned char addr[DNS_RR_AAAA_LEN]);
|
||||
int dns_get_AAAA(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsigned char addr[DNS_RR_AAAA_LEN]);
|
||||
|
||||
int dns_add_SOA(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, struct dns_soa *soa);
|
||||
int dns_add_SOA(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl, struct dns_soa *soa);
|
||||
int dns_get_SOA(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, struct dns_soa *soa);
|
||||
|
||||
int dns_add_NS(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, char *cname);
|
||||
int dns_add_NS(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl, const char *cname);
|
||||
int dns_get_NS(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, char *cname, int cname_size);
|
||||
|
||||
int dns_set_OPT_payload_size(struct dns_packet *packet, int payload_size);
|
||||
|
||||
@@ -243,8 +243,8 @@ struct dns_cache_data *dns_cache_new_data_packet(uint32_t cache_flag, void *pack
|
||||
return (struct dns_cache_data *)cache_packet;
|
||||
}
|
||||
|
||||
int _dns_cache_replace(char *domain, int ttl, dns_type_t qtype, int speed, int inactive,
|
||||
struct dns_cache_data *cache_data)
|
||||
static int _dns_cache_replace(char *domain, int ttl, dns_type_t qtype, int speed, int inactive,
|
||||
struct dns_cache_data *cache_data)
|
||||
{
|
||||
struct dns_cache *dns_cache = NULL;
|
||||
struct dns_cache_data *old_cache_data = NULL;
|
||||
@@ -300,18 +300,38 @@ int dns_cache_replace_inactive(char *domain, int ttl, dns_type_t qtype, int spee
|
||||
return _dns_cache_replace(domain, ttl, qtype, speed, 1, cache_data);
|
||||
}
|
||||
|
||||
int _dns_cache_insert(struct dns_cache_info *info, struct dns_cache_data *cache_data, struct list_head *head)
|
||||
static void _dns_cache_remove_by_domain(const char *domain, dns_type_t qtype)
|
||||
{
|
||||
uint32_t key = 0;
|
||||
struct dns_cache *dns_cache = NULL;
|
||||
|
||||
key = hash_string(domain);
|
||||
key = jhash(&qtype, sizeof(qtype), key);
|
||||
pthread_mutex_lock(&dns_cache_head.lock);
|
||||
hash_for_each_possible(dns_cache_head.cache_hash, dns_cache, node, key)
|
||||
{
|
||||
if (dns_cache->info.qtype != qtype) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp(domain, dns_cache->info.domain, DNS_MAX_CNAME_LEN) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
_dns_cache_remove(dns_cache);
|
||||
break;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&dns_cache_head.lock);
|
||||
}
|
||||
|
||||
static int _dns_cache_insert(struct dns_cache_info *info, struct dns_cache_data *cache_data, struct list_head *head)
|
||||
{
|
||||
uint32_t key = 0;
|
||||
struct dns_cache *dns_cache = NULL;
|
||||
|
||||
/* if cache already exists, free */
|
||||
dns_cache = dns_cache_lookup(info->domain, info->qtype);
|
||||
if (dns_cache) {
|
||||
dns_cache_delete(dns_cache);
|
||||
dns_cache_release(dns_cache);
|
||||
dns_cache = NULL;
|
||||
}
|
||||
_dns_cache_remove_by_domain(info->domain, info->qtype);
|
||||
|
||||
dns_cache = malloc(sizeof(*dns_cache));
|
||||
if (dns_cache == NULL) {
|
||||
@@ -332,7 +352,7 @@ int _dns_cache_insert(struct dns_cache_info *info, struct dns_cache_data *cache_
|
||||
|
||||
/* Release extra cache, remove oldest cache record */
|
||||
if (atomic_inc_return(&dns_cache_head.num) > dns_cache_head.size) {
|
||||
struct dns_cache *del_cache;
|
||||
struct dns_cache *del_cache = NULL;
|
||||
del_cache = _dns_inactive_cache_first();
|
||||
if (del_cache) {
|
||||
_dns_cache_remove(del_cache);
|
||||
@@ -383,7 +403,7 @@ struct dns_cache *dns_cache_lookup(char *domain, dns_type_t qtype)
|
||||
uint32_t key = 0;
|
||||
struct dns_cache *dns_cache = NULL;
|
||||
struct dns_cache *dns_cache_ret = NULL;
|
||||
time_t now;
|
||||
time_t now = 0;
|
||||
|
||||
if (dns_cache_head.size <= 0) {
|
||||
return NULL;
|
||||
@@ -426,7 +446,7 @@ struct dns_cache *dns_cache_lookup(char *domain, dns_type_t qtype)
|
||||
|
||||
int dns_cache_get_ttl(struct dns_cache *dns_cache)
|
||||
{
|
||||
time_t now;
|
||||
time_t now = 0;
|
||||
int ttl = 0;
|
||||
time(&now);
|
||||
|
||||
@@ -440,7 +460,7 @@ int dns_cache_get_ttl(struct dns_cache *dns_cache)
|
||||
|
||||
int dns_cache_get_cname_ttl(struct dns_cache *dns_cache)
|
||||
{
|
||||
time_t now;
|
||||
time_t now = 0;
|
||||
int ttl = 0;
|
||||
time(&now);
|
||||
|
||||
@@ -522,12 +542,12 @@ void dns_cache_update(struct dns_cache *dns_cache)
|
||||
pthread_mutex_unlock(&dns_cache_head.lock);
|
||||
}
|
||||
|
||||
void _dns_cache_remove_expired_ttl(dns_cache_callback inactive_precallback, int ttl_inactive_pre,
|
||||
unsigned int max_callback_num, time_t *now)
|
||||
static void _dns_cache_remove_expired_ttl(dns_cache_callback inactive_precallback, int ttl_inactive_pre,
|
||||
unsigned int max_callback_num, const time_t *now)
|
||||
{
|
||||
struct dns_cache *dns_cache = NULL;
|
||||
struct dns_cache *tmp;
|
||||
int callback_num = 0;
|
||||
struct dns_cache *tmp = NULL;
|
||||
unsigned int callback_num = 0;
|
||||
int ttl = 0;
|
||||
LIST_HEAD(checklist);
|
||||
|
||||
@@ -579,11 +599,11 @@ void dns_cache_invalidate(dns_cache_callback precallback, int ttl_pre, unsigned
|
||||
dns_cache_callback inactive_precallback, int ttl_inactive_pre)
|
||||
{
|
||||
struct dns_cache *dns_cache = NULL;
|
||||
struct dns_cache *tmp;
|
||||
time_t now;
|
||||
struct dns_cache *tmp = NULL;
|
||||
time_t now = 0;
|
||||
int ttl = 0;
|
||||
LIST_HEAD(checklist);
|
||||
int callback_num = 0;
|
||||
unsigned int callback_num = 0;
|
||||
|
||||
if (max_callback_num <= 0) {
|
||||
max_callback_num = -1;
|
||||
@@ -637,8 +657,8 @@ void dns_cache_invalidate(dns_cache_callback precallback, int ttl_pre, unsigned
|
||||
static int _dns_cache_read_record(int fd, uint32_t cache_number)
|
||||
{
|
||||
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
unsigned int i = 0;
|
||||
ssize_t ret = 0;
|
||||
struct dns_cache_record cache_record;
|
||||
struct dns_cache_data_head data_head;
|
||||
struct dns_cache_data *cache_data = NULL;
|
||||
@@ -706,8 +726,9 @@ errout:
|
||||
int dns_cache_load(const char *file)
|
||||
{
|
||||
int fd = -1;
|
||||
int ret = 0;
|
||||
size_t filesize;
|
||||
ssize_t ret = 0;
|
||||
off_t filesize = 0;
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
return 0;
|
||||
@@ -729,7 +750,7 @@ int dns_cache_load(const char *file)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (strncmp(cache_file.version, __TIMESTAMP__, DNS_CACHE_VERSION_LEN) != 0) {
|
||||
if (strncmp(cache_file.version, __TIMESTAMP__, DNS_CACHE_VERSION_LEN - 1) != 0) {
|
||||
tlog(TLOG_WARN, "cache version is different, skip load cache.");
|
||||
goto errout;
|
||||
}
|
||||
@@ -761,7 +782,7 @@ static int _dns_cache_write_record(int fd, uint32_t *cache_number, enum CACHE_RE
|
||||
cache_record.magic = MAGIC_CACHE_DATA;
|
||||
cache_record.type = type;
|
||||
memcpy(&cache_record.info, &dns_cache->info, sizeof(struct dns_cache_info));
|
||||
int ret = write(fd, &cache_record, sizeof(cache_record));
|
||||
ssize_t ret = write(fd, &cache_record, sizeof(cache_record));
|
||||
if (ret != sizeof(cache_record)) {
|
||||
tlog(TLOG_ERROR, "write cache failed, %s", strerror(errno));
|
||||
goto errout;
|
||||
@@ -769,7 +790,7 @@ static int _dns_cache_write_record(int fd, uint32_t *cache_number, enum CACHE_RE
|
||||
|
||||
struct dns_cache_data *cache_data = dns_cache->cache_data;
|
||||
ret = write(fd, cache_data, sizeof(*cache_data) + cache_data->head.size);
|
||||
if (ret != sizeof(*cache_data) + cache_data->head.size) {
|
||||
if (ret != (int)sizeof(*cache_data) + cache_data->head.size) {
|
||||
tlog(TLOG_ERROR, "write cache data failed, %s", strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
@@ -853,7 +874,8 @@ errout:
|
||||
void dns_cache_destroy(void)
|
||||
{
|
||||
struct dns_cache *dns_cache = NULL;
|
||||
struct dns_cache *tmp;
|
||||
struct dns_cache *tmp = NULL;
|
||||
|
||||
pthread_mutex_lock(&dns_cache_head.lock);
|
||||
list_for_each_entry_safe(dns_cache, tmp, &dns_cache_head.inactive_list, list)
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DNS_CACHE_TTL_MIN 30
|
||||
#define DNS_CACHE_TTL_MIN 1
|
||||
#define DNS_CACHE_VERSION_LEN 32
|
||||
#define MAGIC_NUMBER 0x6548634163536e44
|
||||
#define MAGIC_CACHE_DATA 0x44615461
|
||||
@@ -51,7 +51,7 @@ struct dns_cache_data_head {
|
||||
uint32_t cache_flag;
|
||||
enum CACHE_TYPE cache_type;
|
||||
int is_soa;
|
||||
size_t size;
|
||||
ssize_t size;
|
||||
};
|
||||
|
||||
struct dns_cache_data {
|
||||
|
||||
343
src/dns_client.c
343
src/dns_client.c
@@ -72,7 +72,7 @@ struct dns_client_ecs {
|
||||
/* TCP/TLS buffer */
|
||||
struct dns_server_buff {
|
||||
unsigned char data[DNS_TCP_BUFFER];
|
||||
unsigned short len;
|
||||
int len;
|
||||
};
|
||||
|
||||
typedef enum dns_server_status {
|
||||
@@ -133,6 +133,7 @@ struct dns_server_pending_group {
|
||||
|
||||
struct dns_server_pending {
|
||||
struct list_head list;
|
||||
struct list_head retry_list;
|
||||
atomic_t refcnt;
|
||||
|
||||
char host[DNS_HOSTNAME_LEN];
|
||||
@@ -171,7 +172,7 @@ struct dns_server_group {
|
||||
/* dns client */
|
||||
struct dns_client {
|
||||
pthread_t tid;
|
||||
int run;
|
||||
atomic_t run;
|
||||
int epoll_fd;
|
||||
|
||||
/* dns server list */
|
||||
@@ -251,9 +252,9 @@ static LIST_HEAD(pending_servers);
|
||||
static pthread_mutex_t pending_server_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static int dns_client_has_bootstrap_dns = 0;
|
||||
|
||||
int _ssl_read(struct dns_server_info *server, void *buff, int num)
|
||||
static ssize_t _ssl_read(struct dns_server_info *server, void *buff, int num)
|
||||
{
|
||||
int ret = 0;
|
||||
ssize_t ret = 0;
|
||||
if (server == NULL || buff == NULL) {
|
||||
return SSL_ERROR_SYSCALL;
|
||||
}
|
||||
@@ -263,9 +264,9 @@ int _ssl_read(struct dns_server_info *server, void *buff, int num)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int _ssl_write(struct dns_server_info *server, const void *buff, int num)
|
||||
static ssize_t _ssl_write(struct dns_server_info *server, const void *buff, int num)
|
||||
{
|
||||
int ret = 0;
|
||||
ssize_t ret = 0;
|
||||
if (server == NULL || buff == NULL || server->ssl == NULL) {
|
||||
return SSL_ERROR_SYSCALL;
|
||||
}
|
||||
@@ -276,7 +277,7 @@ int _ssl_write(struct dns_server_info *server, const void *buff, int num)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int _ssl_shutdown(struct dns_server_info *server)
|
||||
static int _ssl_shutdown(struct dns_server_info *server)
|
||||
{
|
||||
int ret = 0;
|
||||
if (server == NULL || server->ssl == NULL) {
|
||||
@@ -289,7 +290,7 @@ int _ssl_shutdown(struct dns_server_info *server)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int _ssl_get_error(struct dns_server_info *server, int ret)
|
||||
static int _ssl_get_error(struct dns_server_info *server, int ret)
|
||||
{
|
||||
int err = 0;
|
||||
if (server == NULL || server->ssl == NULL) {
|
||||
@@ -302,7 +303,7 @@ int _ssl_get_error(struct dns_server_info *server, int ret)
|
||||
return err;
|
||||
}
|
||||
|
||||
int _ssl_do_handshake(struct dns_server_info *server)
|
||||
static int _ssl_do_handshake(struct dns_server_info *server)
|
||||
{
|
||||
int err = 0;
|
||||
if (server == NULL || server->ssl == NULL) {
|
||||
@@ -315,7 +316,7 @@ int _ssl_do_handshake(struct dns_server_info *server)
|
||||
return err;
|
||||
}
|
||||
|
||||
int _ssl_session_reused(struct dns_server_info *server)
|
||||
static int _ssl_session_reused(struct dns_server_info *server)
|
||||
{
|
||||
int err = 0;
|
||||
if (server == NULL || server->ssl == NULL) {
|
||||
@@ -328,9 +329,9 @@ int _ssl_session_reused(struct dns_server_info *server)
|
||||
return err;
|
||||
}
|
||||
|
||||
SSL_SESSION *_ssl_get1_session(struct dns_server_info *server)
|
||||
static SSL_SESSION *_ssl_get1_session(struct dns_server_info *server)
|
||||
{
|
||||
SSL_SESSION *ret = 0;
|
||||
SSL_SESSION *ret = NULL;
|
||||
if (server == NULL || server->ssl == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -377,7 +378,7 @@ dns_server_type_t dns_client_get_server_type(struct dns_server_info *server_info
|
||||
return server_info->type;
|
||||
}
|
||||
|
||||
const char *_dns_server_get_type_string(dns_server_type_t type)
|
||||
static const char *_dns_server_get_type_string(dns_server_type_t type)
|
||||
{
|
||||
const char *type_str = "";
|
||||
|
||||
@@ -431,7 +432,8 @@ errout:
|
||||
/* check whether server exists */
|
||||
static int _dns_client_server_exist(const char *server_ip, int port, dns_server_type_t server_type)
|
||||
{
|
||||
struct dns_server_info *server_info, *tmp;
|
||||
struct dns_server_info *server_info = NULL;
|
||||
struct dns_server_info *tmp = NULL;
|
||||
pthread_mutex_lock(&client.server_list_lock);
|
||||
list_for_each_entry_safe(server_info, tmp, &client.dns_server_list, list)
|
||||
{
|
||||
@@ -439,7 +441,7 @@ static int _dns_client_server_exist(const char *server_ip, int port, dns_server_
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp(server_info->ip, server_ip, DNS_HOSTNAME_LEN)) {
|
||||
if (strncmp(server_info->ip, server_ip, DNS_HOSTNAME_LEN) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -468,7 +470,8 @@ static void _dns_client_server_update_ttl(struct ping_host_struct *ping_host, co
|
||||
/* get server control block by ip and port, type */
|
||||
static struct dns_server_info *_dns_client_get_server(char *server_ip, int port, dns_server_type_t server_type)
|
||||
{
|
||||
struct dns_server_info *server_info, *tmp;
|
||||
struct dns_server_info *server_info = NULL;
|
||||
struct dns_server_info *tmp = NULL;
|
||||
struct dns_server_info *server_info_return = NULL;
|
||||
|
||||
if (server_ip == NULL) {
|
||||
@@ -482,7 +485,7 @@ static struct dns_server_info *_dns_client_get_server(char *server_ip, int port,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp(server_info->ip, server_ip, DNS_HOSTNAME_LEN)) {
|
||||
if (strncmp(server_info->ip, server_ip, DNS_HOSTNAME_LEN) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -499,7 +502,7 @@ static struct dns_server_info *_dns_client_get_server(char *server_ip, int port,
|
||||
/* get server group by name */
|
||||
static struct dns_server_group *_dns_client_get_group(const char *group_name)
|
||||
{
|
||||
unsigned long key;
|
||||
uint32_t key = 0;
|
||||
struct dns_server_group *group = NULL;
|
||||
struct hlist_node *tmp = NULL;
|
||||
|
||||
@@ -541,7 +544,7 @@ static struct dns_server_group *_dns_client_get_dnsserver_group(const char *grou
|
||||
}
|
||||
|
||||
/* add server to group */
|
||||
static int _dns_client_add_to_group(char *group_name, struct dns_server_info *server_info)
|
||||
static int _dns_client_add_to_group(const char *group_name, struct dns_server_info *server_info)
|
||||
{
|
||||
struct dns_server_group *group = NULL;
|
||||
struct dns_server_group_member *group_member = NULL;
|
||||
@@ -571,9 +574,11 @@ errout:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _dns_client_add_to_pending_group(char *group_name, char *server_ip, int port, dns_server_type_t server_type)
|
||||
static int _dns_client_add_to_pending_group(const char *group_name, char *server_ip, int port,
|
||||
dns_server_type_t server_type)
|
||||
{
|
||||
struct dns_server_pending *item, *tmp;
|
||||
struct dns_server_pending *item = NULL;
|
||||
struct dns_server_pending *tmp = NULL;
|
||||
struct dns_server_pending *pending = NULL;
|
||||
struct dns_server_pending_group *group = NULL;
|
||||
|
||||
@@ -617,8 +622,8 @@ errout:
|
||||
}
|
||||
|
||||
/* add server to group */
|
||||
static int _dns_client_add_to_group_pending(char *group_name, char *server_ip, int port, dns_server_type_t server_type,
|
||||
int ispending)
|
||||
static int _dns_client_add_to_group_pending(const char *group_name, char *server_ip, int port,
|
||||
dns_server_type_t server_type, int ispending)
|
||||
{
|
||||
struct dns_server_info *server_info = NULL;
|
||||
|
||||
@@ -638,7 +643,7 @@ static int _dns_client_add_to_group_pending(char *group_name, char *server_ip, i
|
||||
return _dns_client_add_to_group(group_name, server_info);
|
||||
}
|
||||
|
||||
int dns_client_add_to_group(char *group_name, char *server_ip, int port, dns_server_type_t server_type)
|
||||
int dns_client_add_to_group(const char *group_name, char *server_ip, int port, dns_server_type_t server_type)
|
||||
{
|
||||
return _dns_client_add_to_group_pending(group_name, server_ip, port, server_type, 1);
|
||||
}
|
||||
@@ -654,8 +659,8 @@ static int _dns_client_remove_member(struct dns_server_group_member *group_membe
|
||||
|
||||
static int _dns_client_remove_from_group(struct dns_server_group *group, struct dns_server_info *server_info)
|
||||
{
|
||||
struct dns_server_group_member *group_member;
|
||||
struct dns_server_group_member *tmp;
|
||||
struct dns_server_group_member *group_member = NULL;
|
||||
struct dns_server_group_member *tmp = NULL;
|
||||
|
||||
list_for_each_entry_safe(group_member, tmp, &group->head, list)
|
||||
{
|
||||
@@ -671,9 +676,9 @@ static int _dns_client_remove_from_group(struct dns_server_group *group, struct
|
||||
|
||||
static int _dns_client_remove_server_from_groups(struct dns_server_info *server_info)
|
||||
{
|
||||
struct dns_server_group *group;
|
||||
struct dns_server_group *group = NULL;
|
||||
struct hlist_node *tmp = NULL;
|
||||
int i = 0;
|
||||
unsigned long i = 0;
|
||||
|
||||
hash_for_each_safe(client.group, i, tmp, group, node)
|
||||
{
|
||||
@@ -683,7 +688,7 @@ static int _dns_client_remove_server_from_groups(struct dns_server_info *server_
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_client_remove_from_group(char *group_name, char *server_ip, int port, dns_server_type_t server_type)
|
||||
int dns_client_remove_from_group(const char *group_name, char *server_ip, int port, dns_server_type_t server_type)
|
||||
{
|
||||
struct dns_server_info *server_info = NULL;
|
||||
struct dns_server_group *group = NULL;
|
||||
@@ -701,9 +706,9 @@ int dns_client_remove_from_group(char *group_name, char *server_ip, int port, dn
|
||||
return _dns_client_remove_from_group(group, server_info);
|
||||
}
|
||||
|
||||
int dns_client_add_group(char *group_name)
|
||||
int dns_client_add_group(const char *group_name)
|
||||
{
|
||||
unsigned long key;
|
||||
uint32_t key = 0;
|
||||
struct dns_server_group *group = NULL;
|
||||
|
||||
if (group_name == NULL) {
|
||||
@@ -738,8 +743,8 @@ errout:
|
||||
|
||||
static int _dns_client_remove_group(struct dns_server_group *group)
|
||||
{
|
||||
struct dns_server_group_member *group_member;
|
||||
struct dns_server_group_member *tmp;
|
||||
struct dns_server_group_member *group_member = NULL;
|
||||
struct dns_server_group_member *tmp = NULL;
|
||||
|
||||
if (group == NULL) {
|
||||
return 0;
|
||||
@@ -756,9 +761,9 @@ static int _dns_client_remove_group(struct dns_server_group *group)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_client_remove_group(char *group_name)
|
||||
int dns_client_remove_group(const char *group_name)
|
||||
{
|
||||
unsigned long key;
|
||||
uint32_t key = 0;
|
||||
struct dns_server_group *group = NULL;
|
||||
struct hlist_node *tmp = NULL;
|
||||
|
||||
@@ -783,9 +788,9 @@ int dns_client_remove_group(char *group_name)
|
||||
|
||||
static void _dns_client_group_remove_all(void)
|
||||
{
|
||||
struct dns_server_group *group;
|
||||
struct dns_server_group *group = NULL;
|
||||
struct hlist_node *tmp = NULL;
|
||||
int i = 0;
|
||||
unsigned long i = 0;
|
||||
|
||||
hash_for_each_safe(client.group, i, tmp, group, node)
|
||||
{
|
||||
@@ -909,7 +914,7 @@ static int _dns_client_set_trusted_cert(SSL_CTX *ssl_ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
SSL_CTX *_ssl_ctx_get(void)
|
||||
static SSL_CTX *_ssl_ctx_get(void)
|
||||
{
|
||||
pthread_mutex_lock(&client.server_list_lock);
|
||||
SSL_CTX *ssl_ctx = client.ssl_ctx;
|
||||
@@ -959,7 +964,7 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
|
||||
int spki_data_len = 0;
|
||||
int ttl = 0;
|
||||
char port_s[8];
|
||||
int sock_type;
|
||||
int sock_type = 0;
|
||||
char skip_check_cert = 0;
|
||||
|
||||
switch (server_type) {
|
||||
@@ -1195,7 +1200,8 @@ static void _dns_client_server_close(struct dns_server_info *server_info)
|
||||
/* remove all servers information */
|
||||
static void _dns_client_server_remove_all(void)
|
||||
{
|
||||
struct dns_server_info *server_info, *tmp;
|
||||
struct dns_server_info *server_info = NULL;
|
||||
struct dns_server_info *tmp = NULL;
|
||||
pthread_mutex_lock(&client.server_list_lock);
|
||||
list_for_each_entry_safe(server_info, tmp, &client.dns_server_list, list)
|
||||
{
|
||||
@@ -1210,7 +1216,8 @@ static void _dns_client_server_remove_all(void)
|
||||
/* remove single server */
|
||||
static int _dns_client_server_remove(char *server_ip, int port, dns_server_type_t server_type)
|
||||
{
|
||||
struct dns_server_info *server_info, *tmp;
|
||||
struct dns_server_info *server_info = NULL;
|
||||
struct dns_server_info *tmp = NULL;
|
||||
|
||||
/* find server and remove */
|
||||
pthread_mutex_lock(&client.server_list_lock);
|
||||
@@ -1220,7 +1227,7 @@ static int _dns_client_server_remove(char *server_ip, int port, dns_server_type_
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp(server_info->ip, server_ip, DNS_HOSTNAME_LEN)) {
|
||||
if (strncmp(server_info->ip, server_ip, DNS_HOSTNAME_LEN) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1236,28 +1243,28 @@ static int _dns_client_server_remove(char *server_ip, int port, dns_server_type_
|
||||
return -1;
|
||||
}
|
||||
|
||||
void _dns_client_server_pending_get(struct dns_server_pending *pending)
|
||||
static void _dns_client_server_pending_get(struct dns_server_pending *pending)
|
||||
{
|
||||
if (atomic_inc_return(&pending->refcnt) <= 0) {
|
||||
tlog(TLOG_ERROR, "BUG: pending ref is invalid");
|
||||
abort();
|
||||
BUG("pending ref is invalid");
|
||||
}
|
||||
}
|
||||
|
||||
void _dns_client_server_pending_release_lck(struct dns_server_pending *pending)
|
||||
static void _dns_client_server_pending_release(struct dns_server_pending *pending)
|
||||
{
|
||||
struct dns_server_pending_group *group, *tmp;
|
||||
struct dns_server_pending_group *group = NULL;
|
||||
struct dns_server_pending_group *tmp = NULL;
|
||||
|
||||
int refcnt = atomic_dec_return(&pending->refcnt);
|
||||
|
||||
if (refcnt) {
|
||||
if (refcnt < 0) {
|
||||
tlog(TLOG_ERROR, "BUG: pending refcnt is %d", refcnt);
|
||||
abort();
|
||||
BUG("BUG: pending refcnt is %d", refcnt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&pending_server_mutex);
|
||||
list_for_each_entry_safe(group, tmp, &pending->group_list, list)
|
||||
{
|
||||
list_del_init(&group->list);
|
||||
@@ -1265,26 +1272,16 @@ void _dns_client_server_pending_release_lck(struct dns_server_pending *pending)
|
||||
}
|
||||
|
||||
list_del_init(&pending->list);
|
||||
pthread_mutex_unlock(&pending_server_mutex);
|
||||
free(pending);
|
||||
}
|
||||
|
||||
void _dns_client_server_pending_release(struct dns_server_pending *pending)
|
||||
static void _dns_client_server_pending_remove(struct dns_server_pending *pending)
|
||||
{
|
||||
int refcnt = atomic_dec_return(&pending->refcnt);
|
||||
|
||||
if (refcnt) {
|
||||
if (refcnt < 0) {
|
||||
tlog(TLOG_ERROR, "BUG: pending refcnt is %d", refcnt);
|
||||
abort();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&pending_server_mutex);
|
||||
list_del_init(&pending->list);
|
||||
pthread_mutex_unlock(&pending_server_mutex);
|
||||
|
||||
free(pending);
|
||||
_dns_client_server_pending_release(pending);
|
||||
}
|
||||
|
||||
static int _dns_client_server_pending(char *server_ip, int port, dns_server_type_t server_type,
|
||||
@@ -1310,6 +1307,7 @@ static int _dns_client_server_pending(char *server_ip, int port, dns_server_type
|
||||
pending->has_v6 = 0;
|
||||
_dns_client_server_pending_get(pending);
|
||||
INIT_LIST_HEAD(&pending->group_list);
|
||||
INIT_LIST_HEAD(&pending->retry_list);
|
||||
memcpy(&pending->flags, flags, sizeof(struct client_dns_server_flags));
|
||||
|
||||
pthread_mutex_lock(&pending_server_mutex);
|
||||
@@ -1327,7 +1325,7 @@ errout:
|
||||
static int _dns_client_add_server_pending(char *server_ip, char *server_host, int port, dns_server_type_t server_type,
|
||||
struct client_dns_server_flags *flags, int ispending)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (server_type >= DNS_SERVER_TYPE_END) {
|
||||
tlog(TLOG_ERROR, "server type is invalid.");
|
||||
@@ -1374,22 +1372,20 @@ int dns_server_num(void)
|
||||
static void _dns_client_query_get(struct dns_query_struct *query)
|
||||
{
|
||||
if (atomic_inc_return(&query->refcnt) <= 0) {
|
||||
tlog(TLOG_ERROR, "BUG: query ref is invalid, domain: %s", query->domain);
|
||||
abort();
|
||||
BUG("query ref is invalid, domain: %s", query->domain);
|
||||
}
|
||||
}
|
||||
|
||||
static void _dns_client_query_release(struct dns_query_struct *query)
|
||||
{
|
||||
int refcnt = atomic_dec_return(&query->refcnt);
|
||||
int bucket = 0;
|
||||
struct dns_query_replied *replied_map;
|
||||
struct hlist_node *tmp;
|
||||
unsigned long bucket = 0;
|
||||
struct dns_query_replied *replied_map = NULL;
|
||||
struct hlist_node *tmp = NULL;
|
||||
|
||||
if (refcnt) {
|
||||
if (refcnt < 0) {
|
||||
tlog(TLOG_ERROR, "BUG: refcnt is %d", refcnt);
|
||||
abort();
|
||||
BUG("BUG: refcnt is %d", refcnt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1398,7 +1394,7 @@ static void _dns_client_query_release(struct dns_query_struct *query)
|
||||
if (query->callback) {
|
||||
tlog(TLOG_DEBUG, "result: %s, qtype: %d, hasresult: %d, id %d", query->domain, query->qtype, query->has_result,
|
||||
query->sid);
|
||||
query->callback(query->domain, DNS_QUERY_END, 0, NULL, NULL, 0, query->user_ptr);
|
||||
query->callback(query->domain, DNS_QUERY_END, NULL, NULL, NULL, 0, query->user_ptr);
|
||||
}
|
||||
|
||||
/* free resource */
|
||||
@@ -1433,7 +1429,8 @@ static void _dns_client_query_remove(struct dns_query_struct *query)
|
||||
|
||||
static void _dns_client_query_remove_all(void)
|
||||
{
|
||||
struct dns_query_struct *query, *tmp;
|
||||
struct dns_query_struct *query = NULL;
|
||||
struct dns_query_struct *tmp = NULL;
|
||||
LIST_HEAD(check_list);
|
||||
|
||||
pthread_mutex_lock(&client.domain_map_lock);
|
||||
@@ -1448,8 +1445,6 @@ static void _dns_client_query_remove_all(void)
|
||||
list_del_init(&query->period_list);
|
||||
_dns_client_query_remove(query);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void _dns_client_check_udp_nat(struct dns_query_struct *query)
|
||||
@@ -1482,8 +1477,8 @@ static void _dns_client_check_udp_nat(struct dns_query_struct *query)
|
||||
|
||||
static void _dns_client_check_tcp(void)
|
||||
{
|
||||
struct dns_server_info *server_info;
|
||||
time_t now;
|
||||
struct dns_server_info *server_info = NULL;
|
||||
time_t now = 0;
|
||||
|
||||
time(&now);
|
||||
|
||||
@@ -1517,7 +1512,7 @@ static struct dns_query_struct *_dns_client_get_request(unsigned short sid, char
|
||||
struct dns_query_struct *query = NULL;
|
||||
struct dns_query_struct *query_result = NULL;
|
||||
struct hlist_node *tmp = NULL;
|
||||
uint32_t key;
|
||||
uint32_t key = 0;
|
||||
|
||||
/* get query by hash key : id + domain */
|
||||
key = hash_string(domain);
|
||||
@@ -1577,17 +1572,17 @@ static int _dns_replied_check_add(struct dns_query_struct *dns_query, struct soc
|
||||
static int _dns_client_recv(struct dns_server_info *server_info, unsigned char *inpacket, int inpacket_len,
|
||||
struct sockaddr *from, socklen_t from_len)
|
||||
{
|
||||
int len;
|
||||
int i;
|
||||
int qtype;
|
||||
int qclass;
|
||||
int len = 0;
|
||||
int i = 0;
|
||||
int qtype = 0;
|
||||
int qclass = 0;
|
||||
char domain[DNS_MAX_CNAME_LEN];
|
||||
int rr_count;
|
||||
int rr_count = 0;
|
||||
struct dns_rrs *rrs = NULL;
|
||||
unsigned char packet_buff[DNS_PACKSIZE];
|
||||
struct dns_packet *packet = (struct dns_packet *)packet_buff;
|
||||
int ret = 0;
|
||||
struct dns_query_struct *query;
|
||||
struct dns_query_struct *query = NULL;
|
||||
int request_num = 0;
|
||||
int has_opt = 0;
|
||||
|
||||
@@ -1597,8 +1592,11 @@ static int _dns_client_recv(struct dns_server_info *server_info, unsigned char *
|
||||
len = dns_decode(packet, DNS_PACKSIZE, inpacket, inpacket_len);
|
||||
if (len != 0) {
|
||||
char host_name[DNS_MAX_CNAME_LEN];
|
||||
tlog(TLOG_WARN, "decode failed, packet len = %d, tc = %d, id = %d, from = %s\n", inpacket_len, packet->head.tc,
|
||||
tlog(TLOG_INFO, "decode failed, packet len = %d, tc = %d, id = %d, from = %s\n", inpacket_len, packet->head.tc,
|
||||
packet->head.id, gethost_by_addr(host_name, sizeof(host_name), from));
|
||||
if (dns_save_fail_packet) {
|
||||
dns_packet_save(dns_save_fail_packet_dir, "client", host_name, inpacket, inpacket_len);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1638,7 +1636,7 @@ static int _dns_client_recv(struct dns_server_info *server_info, unsigned char *
|
||||
}
|
||||
|
||||
/* avoid multiple replies */
|
||||
if (_dns_replied_check_add(query, (struct sockaddr *)from, from_len) != 0) {
|
||||
if (_dns_replied_check_add(query, from, from_len) != 0) {
|
||||
_dns_client_query_release(query);
|
||||
return 0;
|
||||
}
|
||||
@@ -1683,6 +1681,9 @@ static int _dns_client_create_socket_udp(struct dns_server_info *server_info)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
server_info->fd = fd;
|
||||
server_info->status = DNS_SERVER_STATUS_CONNECTIONLESS;
|
||||
|
||||
memset(&event, 0, sizeof(event));
|
||||
event.events = EPOLLIN;
|
||||
event.data.ptr = server_info;
|
||||
@@ -1691,8 +1692,6 @@ static int _dns_client_create_socket_udp(struct dns_server_info *server_info)
|
||||
return -1;
|
||||
}
|
||||
|
||||
server_info->fd = fd;
|
||||
server_info->status = DNS_SERVER_STATUS_CONNECTIONLESS;
|
||||
setsockopt(server_info->fd, IPPROTO_IP, IP_RECVTTL, &on, sizeof(on));
|
||||
setsockopt(server_info->fd, SOL_IP, IP_TTL, &val, sizeof(val));
|
||||
setsockopt(server_info->fd, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority));
|
||||
@@ -1710,6 +1709,9 @@ errout:
|
||||
close(fd);
|
||||
}
|
||||
|
||||
server_info->fd = -1;
|
||||
server_info->status = DNS_SERVER_STATUS_DISCONNECTED;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1723,7 +1725,7 @@ static int _DNS_client_create_socket_tcp(struct dns_server_info *server_info)
|
||||
|
||||
fd = socket(server_info->ai_family, SOCK_STREAM, 0);
|
||||
if (fd < 0) {
|
||||
tlog(TLOG_ERROR, "create socket failed.");
|
||||
tlog(TLOG_ERROR, "create socket failed, %s", strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
@@ -1734,7 +1736,7 @@ static int _DNS_client_create_socket_tcp(struct dns_server_info *server_info)
|
||||
|
||||
/* enable tcp fast open */
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN_CONNECT, &yes, sizeof(yes)) != 0) {
|
||||
tlog(TLOG_DEBUG, "enable TCP fast open failed.");
|
||||
tlog(TLOG_DEBUG, "enable TCP fast open failed, %s", strerror(errno));
|
||||
}
|
||||
|
||||
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes));
|
||||
@@ -1744,7 +1746,7 @@ static int _DNS_client_create_socket_tcp(struct dns_server_info *server_info)
|
||||
setsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS, &yes, sizeof(yes));
|
||||
set_sock_keepalive(fd, 15, 3, 4);
|
||||
|
||||
if (connect(fd, (struct sockaddr *)&server_info->addr, server_info->ai_addrlen) != 0) {
|
||||
if (connect(fd, &server_info->addr, server_info->ai_addrlen) != 0) {
|
||||
if (errno == ENETUNREACH) {
|
||||
tlog(TLOG_DEBUG, "connect %s failed, %s", server_info->ip, strerror(errno));
|
||||
goto errout;
|
||||
@@ -1826,7 +1828,7 @@ static int _DNS_client_create_socket_tls(struct dns_server_info *server_info, ch
|
||||
setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority));
|
||||
setsockopt(fd, IPPROTO_IP, IP_TOS, &ip_tos, sizeof(ip_tos));
|
||||
|
||||
if (connect(fd, (struct sockaddr *)&server_info->addr, server_info->ai_addrlen) != 0) {
|
||||
if (connect(fd, &server_info->addr, server_info->ai_addrlen) != 0) {
|
||||
if (errno == ENETUNREACH) {
|
||||
tlog(TLOG_DEBUG, "connect %s failed, %s", server_info->ip, strerror(errno));
|
||||
goto errout;
|
||||
@@ -1906,11 +1908,11 @@ static int _dns_client_create_socket(struct dns_server_info *server_info)
|
||||
} else if (server_info->type == DNS_SERVER_TCP) {
|
||||
return _DNS_client_create_socket_tcp(server_info);
|
||||
} else if (server_info->type == DNS_SERVER_TLS) {
|
||||
struct client_dns_server_flag_tls *flag_tls;
|
||||
struct client_dns_server_flag_tls *flag_tls = NULL;
|
||||
flag_tls = &server_info->flags.tls;
|
||||
return _DNS_client_create_socket_tls(server_info, flag_tls->hostname);
|
||||
} else if (server_info->type == DNS_SERVER_HTTPS) {
|
||||
struct client_dns_server_flag_https *flag_https;
|
||||
struct client_dns_server_flag_https *flag_https = NULL;
|
||||
flag_https = &server_info->flags.https;
|
||||
return _DNS_client_create_socket_tls(server_info, flag_https->hostname);
|
||||
} else {
|
||||
@@ -1922,7 +1924,7 @@ static int _dns_client_create_socket(struct dns_server_info *server_info)
|
||||
|
||||
static int _dns_client_process_udp(struct dns_server_info *server_info, struct epoll_event *event, unsigned long now)
|
||||
{
|
||||
int len;
|
||||
int len = 0;
|
||||
unsigned char inpacket[DNS_IN_PACKSIZE];
|
||||
struct sockaddr_storage from;
|
||||
socklen_t from_len = sizeof(from);
|
||||
@@ -1931,7 +1933,7 @@ static int _dns_client_process_udp(struct dns_server_info *server_info, struct e
|
||||
struct iovec iov;
|
||||
char ans_data[4096];
|
||||
int ttl = 0;
|
||||
struct cmsghdr *cmsg;
|
||||
struct cmsghdr *cmsg = NULL;
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
iov.iov_base = (char *)inpacket;
|
||||
@@ -1990,6 +1992,11 @@ static int _dns_client_socket_ssl_send(struct dns_server_info *server, const voi
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (num < 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = _ssl_write(server, buf, num);
|
||||
if (ret > 0) {
|
||||
return ret;
|
||||
@@ -2037,7 +2044,7 @@ static int _dns_client_socket_ssl_send(struct dns_server_info *server, const voi
|
||||
|
||||
static int _dns_client_socket_ssl_recv(struct dns_server_info *server, void *buf, int num)
|
||||
{
|
||||
int ret = 0;
|
||||
ssize_t ret = 0;
|
||||
int ssl_ret = 0;
|
||||
unsigned long ssl_err = 0;
|
||||
|
||||
@@ -2077,7 +2084,7 @@ static int _dns_client_socket_ssl_recv(struct dns_server_info *server, void *buf
|
||||
return 0;
|
||||
}
|
||||
|
||||
tlog(TLOG_ERROR, "SSL read fail error no: %s(%lx)\n", ERR_reason_error_string(ssl_err), ssl_err);
|
||||
tlog(TLOG_INFO, "SSL read fail error no: %s(%lx), len: %d\n", ERR_reason_error_string(ssl_err), ssl_err, num);
|
||||
errno = EFAULT;
|
||||
ret = -1;
|
||||
break;
|
||||
@@ -2211,8 +2218,7 @@ static int _dns_client_process_tcp_buff(struct dns_server_info *server_info)
|
||||
|
||||
server_info->recv_buff.len -= len;
|
||||
if (server_info->recv_buff.len < 0) {
|
||||
tlog(TLOG_ERROR, "Internal error.");
|
||||
abort();
|
||||
BUG("Internal error.");
|
||||
}
|
||||
|
||||
/* move to next result */
|
||||
@@ -2234,7 +2240,7 @@ out:
|
||||
|
||||
static int _dns_client_process_tcp(struct dns_server_info *server_info, struct epoll_event *event, unsigned long now)
|
||||
{
|
||||
int len;
|
||||
int len = 0;
|
||||
int ret = -1;
|
||||
|
||||
if (event->events & EPOLLIN) {
|
||||
@@ -2289,8 +2295,6 @@ static int _dns_client_process_tcp(struct dns_server_info *server_info, struct e
|
||||
|
||||
/* when connected */
|
||||
if (event->events & EPOLLOUT) {
|
||||
struct epoll_event event;
|
||||
|
||||
if (server_info->status == DNS_SERVER_STATUS_CONNECTING) {
|
||||
server_info->status = DNS_SERVER_STATUS_CONNECTED;
|
||||
tlog(TLOG_DEBUG, "tcp server %s connected", server_info->ip);
|
||||
@@ -2315,8 +2319,7 @@ static int _dns_client_process_tcp(struct dns_server_info *server_info, struct e
|
||||
if (server_info->send_buff.len > 0) {
|
||||
memmove(server_info->send_buff.data, server_info->send_buff.data + len, server_info->send_buff.len);
|
||||
} else if (server_info->send_buff.len < 0) {
|
||||
tlog(TLOG_ERROR, "Internal Error");
|
||||
abort();
|
||||
BUG("Internal Error");
|
||||
}
|
||||
pthread_mutex_unlock(&client.server_list_lock);
|
||||
}
|
||||
@@ -2326,10 +2329,11 @@ static int _dns_client_process_tcp(struct dns_server_info *server_info, struct e
|
||||
}
|
||||
|
||||
/* clear epllout event */
|
||||
memset(&event, 0, sizeof(event));
|
||||
event.events = EPOLLIN;
|
||||
event.data.ptr = server_info;
|
||||
if (epoll_ctl(client.epoll_fd, EPOLL_CTL_MOD, server_info->fd, &event) != 0) {
|
||||
struct epoll_event mod_event;
|
||||
memset(&mod_event, 0, sizeof(mod_event));
|
||||
mod_event.events = EPOLLIN;
|
||||
mod_event.data.ptr = server_info;
|
||||
if (epoll_ctl(client.epoll_fd, EPOLL_CTL_MOD, server_info->fd, &mod_event) != 0) {
|
||||
tlog(TLOG_ERROR, "epoll ctl failed, %s", strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
@@ -2351,15 +2355,16 @@ static inline int _dns_client_to_hex(int c)
|
||||
{
|
||||
if (c > 0x9) {
|
||||
return 'A' + c - 0xA;
|
||||
} else {
|
||||
return '0' + c;
|
||||
}
|
||||
|
||||
return '0' + c;
|
||||
}
|
||||
|
||||
static int _dns_client_tls_matchName(const char *host, const char *pattern, int size)
|
||||
{
|
||||
int match = -1;
|
||||
int i = 0, j = 0;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
while (i < size && host[j] != '\0') {
|
||||
if (toupper(pattern[i]) == toupper(host[j])) {
|
||||
@@ -2533,7 +2538,7 @@ static int _dns_client_process_tls(struct dns_server_info *server_info, struct e
|
||||
{
|
||||
int ret = -1;
|
||||
struct epoll_event fd_event;
|
||||
int ssl_ret;
|
||||
int ssl_ret = 0;
|
||||
|
||||
if (unlikely(server_info->ssl == NULL)) {
|
||||
tlog(TLOG_ERROR, "ssl is invalid.");
|
||||
@@ -2644,7 +2649,7 @@ static int _dns_client_send_udp(struct dns_server_info *server_info, void *packe
|
||||
return -1;
|
||||
}
|
||||
|
||||
send_len = sendto(server_info->fd, packet, len, 0, (struct sockaddr *)&server_info->addr, server_info->ai_addrlen);
|
||||
send_len = sendto(server_info->fd, packet, len, 0, &server_info->addr, server_info->ai_addrlen);
|
||||
if (send_len != len) {
|
||||
return -1;
|
||||
}
|
||||
@@ -2833,7 +2838,7 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet,
|
||||
{
|
||||
server_info = group_member->server;
|
||||
if (server_info->prohibit) {
|
||||
time_t now;
|
||||
time_t now = 0;
|
||||
time(&now);
|
||||
if ((now - 60 < server_info->last_send) && (now - 5 > server_info->last_recv)) {
|
||||
continue;
|
||||
@@ -2888,7 +2893,7 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet,
|
||||
|
||||
tlog(TLOG_DEBUG, "send query to %s failed, %s, type: %d", server_info->ip, strerror(send_err),
|
||||
server_info->type);
|
||||
time_t now;
|
||||
time_t now = 0;
|
||||
time(&now);
|
||||
if (now - 5 > server_info->last_recv || send_err != ENOMEM) {
|
||||
server_info->prohibit = 1;
|
||||
@@ -2925,12 +2930,12 @@ static int _dns_client_dns_add_ecs(struct dns_query_struct *query, struct dns_pa
|
||||
return dns_add_OPT_ECS(packet, &query->ecs.ecs);
|
||||
}
|
||||
|
||||
static int _dns_client_send_query(struct dns_query_struct *query, char *doamin)
|
||||
static int _dns_client_send_query(struct dns_query_struct *query, const 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;
|
||||
int encode_len = 0;
|
||||
|
||||
/* init dns packet head */
|
||||
struct dns_head head;
|
||||
@@ -2969,8 +2974,7 @@ static int _dns_client_send_query(struct dns_query_struct *query, char *doamin)
|
||||
}
|
||||
|
||||
if (encode_len > DNS_IN_PACKSIZE) {
|
||||
tlog(TLOG_ERROR, "size is invalid.");
|
||||
abort();
|
||||
BUG("size is invalid.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2978,7 +2982,7 @@ static int _dns_client_send_query(struct dns_query_struct *query, char *doamin)
|
||||
return _dns_client_send_packet(query, inpacket, encode_len);
|
||||
}
|
||||
|
||||
int _dns_client_query_setup_default_ecs(struct dns_query_struct *query)
|
||||
static int _dns_client_query_setup_default_ecs(struct dns_query_struct *query)
|
||||
{
|
||||
int add_ipv4_ecs = 0;
|
||||
int add_ipv6_ecs = 0;
|
||||
@@ -3008,7 +3012,7 @@ int _dns_client_query_setup_default_ecs(struct dns_query_struct *query)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _dns_client_query_parser_options(struct dns_query_struct *query, struct dns_query_options *options)
|
||||
static int _dns_client_query_parser_options(struct dns_query_struct *query, struct dns_query_options *options)
|
||||
{
|
||||
if (options == NULL) {
|
||||
_dns_client_query_setup_default_ecs(query);
|
||||
@@ -3018,7 +3022,7 @@ int _dns_client_query_parser_options(struct dns_query_struct *query, struct dns_
|
||||
if (options->enable_flag & DNS_QUEY_OPTION_ECS_IP) {
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
struct dns_opt_ecs *ecs;
|
||||
struct dns_opt_ecs *ecs = NULL;
|
||||
|
||||
ecs = &query->ecs.ecs;
|
||||
getaddr_by_host(options->ecs_ip.ip, (struct sockaddr *)&addr, &addr_len);
|
||||
@@ -3029,13 +3033,13 @@ int _dns_client_query_parser_options(struct dns_query_struct *query, struct dns_
|
||||
|
||||
switch (addr.ss_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *addr_in;
|
||||
struct sockaddr_in *addr_in = NULL;
|
||||
addr_in = (struct sockaddr_in *)&addr;
|
||||
ecs->family = DNS_OPT_ECS_FAMILY_IPV4;
|
||||
memcpy(&ecs->addr, &addr_in->sin_addr.s_addr, 4);
|
||||
} break;
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *addr_in6;
|
||||
struct sockaddr_in6 *addr_in6 = NULL;
|
||||
addr_in6 = (struct sockaddr_in6 *)&addr;
|
||||
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
|
||||
memcpy(&ecs->addr, addr_in6->sin6_addr.s6_addr + 12, 4);
|
||||
@@ -3072,8 +3076,8 @@ int _dns_client_query_parser_options(struct dns_query_struct *query, struct dns_
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_client_query(char *domain, int qtype, dns_client_callback callback, void *user_ptr, const char *group_name,
|
||||
struct dns_query_options *options)
|
||||
int dns_client_query(const char *domain, int qtype, dns_client_callback callback, void *user_ptr,
|
||||
const char *group_name, struct dns_query_options *options)
|
||||
{
|
||||
struct dns_query_struct *query = NULL;
|
||||
int ret = 0;
|
||||
@@ -3150,7 +3154,8 @@ errout:
|
||||
|
||||
static void _dns_client_check_servers(void)
|
||||
{
|
||||
struct dns_server_info *server_info, *tmp;
|
||||
struct dns_server_info *server_info = NULL;
|
||||
struct dns_server_info *tmp = NULL;
|
||||
static unsigned int second_count = 0;
|
||||
|
||||
second_count++;
|
||||
@@ -3175,7 +3180,7 @@ static void _dns_client_check_servers(void)
|
||||
pthread_mutex_unlock(&client.server_list_lock);
|
||||
}
|
||||
|
||||
static int _dns_client_pending_server_resolve(char *domain, dns_rtcode_t rtcode, dns_type_t addr_type, char *ip,
|
||||
static int _dns_client_pending_server_resolve(const char *domain, dns_rtcode_t rtcode, dns_type_t addr_type, char *ip,
|
||||
unsigned int ping_time, void *user_ptr)
|
||||
{
|
||||
struct dns_server_pending *pending = user_ptr;
|
||||
@@ -3205,7 +3210,8 @@ static int _dns_client_pending_server_resolve(char *domain, dns_rtcode_t rtcode,
|
||||
|
||||
static int _dns_client_add_pendings(struct dns_server_pending *pending, char *ip)
|
||||
{
|
||||
struct dns_server_pending_group *group, *tmp;
|
||||
struct dns_server_pending_group *group = NULL;
|
||||
struct dns_server_pending_group *tmp = NULL;
|
||||
|
||||
if (_dns_client_add_server_pending(ip, pending->host, pending->port, pending->type, &pending->flags, 0) != 0) {
|
||||
return -1;
|
||||
@@ -3226,21 +3232,33 @@ static int _dns_client_add_pendings(struct dns_server_pending *pending, char *ip
|
||||
|
||||
static void _dns_client_remove_all_pending_servers(void)
|
||||
{
|
||||
struct dns_server_pending *pending, *tmp;
|
||||
struct dns_server_pending *pending = NULL;
|
||||
struct dns_server_pending *tmp = NULL;
|
||||
LIST_HEAD(remove_list);
|
||||
|
||||
pthread_mutex_lock(&pending_server_mutex);
|
||||
list_for_each_entry_safe(pending, tmp, &pending_servers, list)
|
||||
{
|
||||
list_del_init(&pending->list);
|
||||
_dns_client_server_pending_release_lck(pending);
|
||||
list_add(&pending->retry_list, &remove_list);
|
||||
_dns_client_server_pending_get(pending);
|
||||
}
|
||||
pthread_mutex_unlock(&pending_server_mutex);
|
||||
|
||||
list_for_each_entry_safe(pending, tmp, &remove_list, retry_list)
|
||||
{
|
||||
list_del_init(&pending->retry_list);
|
||||
_dns_client_server_pending_release(pending);
|
||||
_dns_client_server_pending_remove(pending);
|
||||
}
|
||||
}
|
||||
|
||||
static void _dns_client_add_pending_servers(void)
|
||||
{
|
||||
struct dns_server_pending *pending, *tmp;
|
||||
struct dns_server_pending *pending = NULL;
|
||||
struct dns_server_pending *tmp = NULL;
|
||||
static int dely = 0;
|
||||
LIST_HEAD(retry_list);
|
||||
|
||||
/* add pending server after 3 seconds */
|
||||
if (++dely < 3) {
|
||||
@@ -3250,6 +3268,13 @@ static void _dns_client_add_pending_servers(void)
|
||||
|
||||
pthread_mutex_lock(&pending_server_mutex);
|
||||
list_for_each_entry_safe(pending, tmp, &pending_servers, list)
|
||||
{
|
||||
list_add(&pending->retry_list, &retry_list);
|
||||
_dns_client_server_pending_get(pending);
|
||||
}
|
||||
pthread_mutex_unlock(&pending_server_mutex);
|
||||
|
||||
list_for_each_entry_safe(pending, tmp, &retry_list, retry_list)
|
||||
{
|
||||
/* send dns type A, AAAA query to bootstrap DNS server */
|
||||
int add_success = 0;
|
||||
@@ -3259,7 +3284,8 @@ static void _dns_client_add_pending_servers(void)
|
||||
pending->query_v4 = 1;
|
||||
_dns_client_server_pending_get(pending);
|
||||
if (dns_server_query(pending->host, DNS_T_A, 0, _dns_client_pending_server_resolve, pending) != 0) {
|
||||
_dns_client_server_pending_release_lck(pending);
|
||||
_dns_client_server_pending_release(pending);
|
||||
pending->query_v4 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3267,10 +3293,14 @@ static void _dns_client_add_pending_servers(void)
|
||||
pending->query_v6 = 1;
|
||||
_dns_client_server_pending_get(pending);
|
||||
if (dns_server_query(pending->host, DNS_T_AAAA, 0, _dns_client_pending_server_resolve, pending) != 0) {
|
||||
_dns_client_server_pending_release_lck(pending);
|
||||
_dns_client_server_pending_release(pending);
|
||||
pending->query_v4 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
list_del_init(&pending->retry_list);
|
||||
_dns_client_server_pending_release(pending);
|
||||
|
||||
/* if both A, AAAA has query result, select fastest IP address */
|
||||
if (pending->has_v4 && pending->has_v6) {
|
||||
if (pending->ping_time_v4 <= pending->ping_time_v6 && pending->ipv4[0]) {
|
||||
@@ -3291,14 +3321,17 @@ static void _dns_client_add_pending_servers(void)
|
||||
}
|
||||
|
||||
pending->retry_cnt++;
|
||||
if (pending->retry_cnt >= DNS_PENDING_SERVER_RETRY || add_success) {
|
||||
if (pending->retry_cnt == 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pending->retry_cnt - 1 > DNS_PENDING_SERVER_RETRY || add_success) {
|
||||
if (add_success == 0) {
|
||||
tlog(TLOG_WARN, "add pending DNS server %s failed.", pending->host);
|
||||
}
|
||||
list_del_init(&pending->list);
|
||||
_dns_client_server_pending_release_lck(pending);
|
||||
_dns_client_server_pending_remove(pending);
|
||||
} else {
|
||||
tlog(TLOG_INFO, "add pending DNS server %s failed, retry %d...", pending->host, pending->retry_cnt);
|
||||
tlog(TLOG_INFO, "add pending DNS server %s failed, retry %d...", pending->host, pending->retry_cnt - 1);
|
||||
pending->query_v4 = 0;
|
||||
pending->query_v6 = 0;
|
||||
}
|
||||
@@ -3312,10 +3345,9 @@ static void _dns_client_add_pending_servers(void)
|
||||
return;
|
||||
}
|
||||
|
||||
_dns_client_server_pending_release_lck(pending);
|
||||
_dns_client_server_pending_release(pending);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&pending_server_mutex);
|
||||
}
|
||||
|
||||
static void _dns_client_period_run_second(void)
|
||||
@@ -3327,7 +3359,8 @@ static void _dns_client_period_run_second(void)
|
||||
|
||||
static void _dns_client_period_run(void)
|
||||
{
|
||||
struct dns_query_struct *query, *tmp;
|
||||
struct dns_query_struct *query = NULL;
|
||||
struct dns_query_struct *tmp = NULL;
|
||||
static unsigned int msec = 0;
|
||||
msec++;
|
||||
|
||||
@@ -3366,24 +3399,22 @@ static void _dns_client_period_run(void)
|
||||
if (msec % 10 == 0) {
|
||||
_dns_client_period_run_second();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void *_dns_client_work(void *arg)
|
||||
{
|
||||
struct epoll_event events[DNS_MAX_EVENTS + 1];
|
||||
int num;
|
||||
int i;
|
||||
int num = 0;
|
||||
int i = 0;
|
||||
unsigned long now = {0};
|
||||
unsigned int sleep = 100;
|
||||
int sleep_time;
|
||||
int sleep_time = 0;
|
||||
unsigned long expect_time = 0;
|
||||
|
||||
sleep_time = sleep;
|
||||
now = get_tick_count() - sleep;
|
||||
expect_time = now + sleep;
|
||||
while (client.run) {
|
||||
while (atomic_read(&client.run)) {
|
||||
now = get_tick_count();
|
||||
if (now >= expect_time) {
|
||||
_dns_client_period_run();
|
||||
@@ -3427,7 +3458,7 @@ int dns_client_set_ecs(char *ip, int subnet)
|
||||
|
||||
switch (addr.ss_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *addr_in;
|
||||
struct sockaddr_in *addr_in = NULL;
|
||||
addr_in = (struct sockaddr_in *)&addr;
|
||||
memcpy(&client.ecs_ipv4.ecs.addr, &addr_in->sin_addr.s_addr, 4);
|
||||
client.ecs_ipv4.ecs.source_prefix = subnet;
|
||||
@@ -3436,7 +3467,7 @@ int dns_client_set_ecs(char *ip, int subnet)
|
||||
client.ecs_ipv4.enable = 1;
|
||||
} break;
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *addr_in6;
|
||||
struct sockaddr_in6 *addr_in6 = NULL;
|
||||
addr_in6 = (struct sockaddr_in6 *)&addr;
|
||||
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
|
||||
client.ecs_ipv4.ecs.source_prefix = subnet;
|
||||
@@ -3461,7 +3492,7 @@ int dns_client_init(void)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
int epollfd = -1;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (client.epoll_fd > 0) {
|
||||
return -1;
|
||||
@@ -3492,7 +3523,7 @@ int dns_client_init(void)
|
||||
|
||||
client.default_group = _dns_client_get_group(DNS_SERVER_GROUP_DEFAULT);
|
||||
client.epoll_fd = epollfd;
|
||||
client.run = 1;
|
||||
atomic_set(&client.run, 1);
|
||||
|
||||
/* start work task */
|
||||
ret = pthread_create(&client.tid, &attr, _dns_client_work, NULL);
|
||||
@@ -3503,10 +3534,11 @@ int dns_client_init(void)
|
||||
|
||||
return 0;
|
||||
errout:
|
||||
if (client.tid > 0) {
|
||||
if (client.tid) {
|
||||
void *retval = NULL;
|
||||
client.run = 0;
|
||||
atomic_set(&client.run, 0);
|
||||
pthread_join(client.tid, &retval);
|
||||
client.tid = 0;
|
||||
}
|
||||
|
||||
if (epollfd) {
|
||||
@@ -3521,10 +3553,11 @@ errout:
|
||||
|
||||
void dns_client_exit(void)
|
||||
{
|
||||
if (client.tid > 0) {
|
||||
if (client.tid) {
|
||||
void *ret = NULL;
|
||||
client.run = 0;
|
||||
atomic_set(&client.run, 0);
|
||||
pthread_join(client.tid, &ret);
|
||||
client.tid = 0;
|
||||
}
|
||||
|
||||
/* free all resouces */
|
||||
|
||||
@@ -56,7 +56,7 @@ int dns_client_set_ecs(char *ip, int subnet);
|
||||
|
||||
struct dns_server_info;
|
||||
/* query result notify function */
|
||||
typedef int (*dns_client_callback)(char *domain, dns_result_type rtype, struct dns_server_info *server_info,
|
||||
typedef int (*dns_client_callback)(const char *domain, dns_result_type rtype, struct dns_server_info *server_info,
|
||||
struct dns_packet *packet, unsigned char *inpacket, int inpacket_len,
|
||||
void *user_ptr);
|
||||
|
||||
@@ -80,7 +80,7 @@ struct dns_query_options {
|
||||
};
|
||||
|
||||
/* query domain */
|
||||
int dns_client_query(char *domain, int qtype, dns_client_callback callback, void *user_ptr, const char *group_name,
|
||||
int dns_client_query(const char *domain, int qtype, dns_client_callback callback, void *user_ptr, const char *group_name,
|
||||
struct dns_query_options *options);
|
||||
|
||||
void dns_client_exit(void);
|
||||
@@ -128,13 +128,13 @@ int dns_client_add_server(char *server_ip, int port, dns_server_type_t server_ty
|
||||
/* remove remote dns server */
|
||||
int dns_client_remove_server(char *server_ip, int port, dns_server_type_t server_type);
|
||||
|
||||
int dns_client_add_group(char *group_name);
|
||||
int dns_client_add_group(const char *group_name);
|
||||
|
||||
int dns_client_add_to_group(char *group_name, char *server_ip, int port, dns_server_type_t server_type);
|
||||
int dns_client_add_to_group(const char *group_name, char *server_ip, int port, dns_server_type_t server_type);
|
||||
|
||||
int dns_client_remove_from_group(char *group_name, char *server_ip, int port, dns_server_type_t server_type);
|
||||
int dns_client_remove_from_group(const char *group_name, char *server_ip, int port, dns_server_type_t server_type);
|
||||
|
||||
int dns_client_remove_group(char *group_name);
|
||||
int dns_client_remove_group(const char *group_name);
|
||||
|
||||
int dns_server_num(void);
|
||||
|
||||
|
||||
115
src/dns_conf.c
115
src/dns_conf.c
@@ -46,8 +46,8 @@ struct dns_group_table dns_group_table;
|
||||
|
||||
struct dns_ptr_table dns_ptr_table;
|
||||
|
||||
char dns_conf_dnsmasq_lease_file[DNS_MAX_PATH];
|
||||
time_t dns_conf_dnsmasq_lease_file_time;
|
||||
static char dns_conf_dnsmasq_lease_file[DNS_MAX_PATH];
|
||||
static time_t dns_conf_dnsmasq_lease_file_time;
|
||||
|
||||
struct dns_hosts_table dns_hosts_table;
|
||||
int dns_hosts_record_num;
|
||||
@@ -59,6 +59,14 @@ int dns_conf_tcp_idle_time = 120;
|
||||
|
||||
int dns_conf_max_reply_ip_num = DNS_MAX_REPLY_IP_NUM;
|
||||
|
||||
static struct config_enum_list dns_conf_response_mode_enum[] = {
|
||||
{"first-ping", DNS_RESPONSE_MODE_FIRST_PING_IP},
|
||||
{"fastest-ip", DNS_RESPONSE_MODE_FASTEST_IP},
|
||||
{"fastest-response", DNS_RESPONSE_MODE_FASTEST_RESPONSE},
|
||||
{0, 0}};
|
||||
|
||||
enum response_mode_type dns_conf_response_mode;
|
||||
|
||||
/* cache */
|
||||
int dns_conf_cachesize = DEFAULT_DNS_CACHE_SIZE;
|
||||
int dns_conf_prefetch = 0;
|
||||
@@ -80,7 +88,7 @@ struct dns_domain_check_orders dns_conf_check_orders = {
|
||||
{.type = DOMAIN_CHECK_TCP, .tcp_port = 443},
|
||||
},
|
||||
};
|
||||
int dns_has_cap_ping = 0;
|
||||
static int dns_has_cap_ping = 0;
|
||||
|
||||
/* logging */
|
||||
int dns_conf_log_level = TLOG_ERROR;
|
||||
@@ -122,6 +130,9 @@ int dns_conf_ipset_timeout_enable;
|
||||
|
||||
char dns_conf_user[DNS_CONF_USRNAME_LEN];
|
||||
|
||||
int dns_save_fail_packet;
|
||||
char dns_save_fail_packet_dir[DNS_MAX_PATH];
|
||||
|
||||
/* ECS */
|
||||
struct dns_edns_client_subnet dns_conf_ipv4_ecs;
|
||||
struct dns_edns_client_subnet dns_conf_ipv6_ecs;
|
||||
@@ -249,7 +260,7 @@ static void _config_group_table_destroy(void)
|
||||
{
|
||||
struct dns_server_groups *group = NULL;
|
||||
struct hlist_node *tmp = NULL;
|
||||
int i;
|
||||
unsigned long i = 0;
|
||||
|
||||
hash_for_each_safe(dns_group_table.group, i, tmp, group, node)
|
||||
{
|
||||
@@ -261,7 +272,7 @@ static void _config_group_table_destroy(void)
|
||||
static int _config_server(int argc, char *argv[], dns_server_type_t type, int default_port)
|
||||
{
|
||||
int index = dns_conf_server_num;
|
||||
struct dns_servers *server;
|
||||
struct dns_servers *server = NULL;
|
||||
int port = -1;
|
||||
char *ip = NULL;
|
||||
int opt = 0;
|
||||
@@ -455,7 +466,7 @@ static int _config_domain_rule_add(char *domain, enum domain_rule type, void *ru
|
||||
|
||||
/* Reverse string, for suffix match */
|
||||
len = strlen(domain);
|
||||
if (len >= sizeof(domain_key)) {
|
||||
if (len >= (int)sizeof(domain_key)) {
|
||||
tlog(TLOG_ERROR, "domain name %s too long", domain);
|
||||
goto errout;
|
||||
}
|
||||
@@ -516,7 +527,7 @@ static int _config_domain_rule_flag_set(char *domain, unsigned int flag, unsigne
|
||||
int len = 0;
|
||||
|
||||
len = strlen(domain);
|
||||
if (len >= sizeof(domain_key)) {
|
||||
if (len >= (int)sizeof(domain_key)) {
|
||||
tlog(TLOG_ERROR, "domain %s too long", domain);
|
||||
return -1;
|
||||
}
|
||||
@@ -574,7 +585,7 @@ static void _config_ipset_table_destroy(void)
|
||||
{
|
||||
struct dns_ipset_name *ipset_name = NULL;
|
||||
struct hlist_node *tmp = NULL;
|
||||
int i;
|
||||
unsigned long i = 0;
|
||||
|
||||
hash_for_each_safe(dns_ipset_table.ipset, i, tmp, ipset_name, node)
|
||||
{
|
||||
@@ -619,8 +630,8 @@ static int _conf_domain_rule_ipset(char *domain, const char *ipsetname)
|
||||
struct dns_ipset_rule *ipset_rule = NULL;
|
||||
const char *ipset = NULL;
|
||||
char *copied_name = NULL;
|
||||
enum domain_rule type;
|
||||
int ignore_flag;
|
||||
enum domain_rule type = 0;
|
||||
int ignore_flag = 0;
|
||||
|
||||
copied_name = strdup(ipsetname);
|
||||
|
||||
@@ -630,10 +641,10 @@ static int _conf_domain_rule_ipset(char *domain, const char *ipsetname)
|
||||
|
||||
for (char *tok = strtok(copied_name, ","); tok; tok = strtok(NULL, ",")) {
|
||||
if (tok[0] == '#') {
|
||||
if (strncmp(tok, "#6:", 3u) == 0) {
|
||||
if (strncmp(tok, "#6:", 3U) == 0) {
|
||||
type = DOMAIN_RULE_IPSET_IPV6;
|
||||
ignore_flag = DOMAIN_FLAG_IPSET_IPV6_IGN;
|
||||
} else if (strncmp(tok, "#4:", 3u) == 0) {
|
||||
} else if (strncmp(tok, "#4:", 3U) == 0) {
|
||||
type = DOMAIN_RULE_IPSET_IPV4;
|
||||
ignore_flag = DOMAIN_FLAG_IPSET_IPV4_IGN;
|
||||
} else {
|
||||
@@ -710,7 +721,7 @@ static int _conf_domain_rule_address(char *domain, const char *domain_address)
|
||||
struct dns_address_IPV6 *address_ipv6 = NULL;
|
||||
void *address = NULL;
|
||||
char ip[MAX_IP_LEN];
|
||||
int port;
|
||||
int port = 0;
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
enum domain_rule type = 0;
|
||||
@@ -762,7 +773,7 @@ static int _conf_domain_rule_address(char *domain, const char *domain_address)
|
||||
|
||||
switch (addr.ss_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *addr_in;
|
||||
struct sockaddr_in *addr_in = NULL;
|
||||
address_ipv4 = malloc(sizeof(*address_ipv4));
|
||||
if (address_ipv4 == NULL) {
|
||||
goto errout;
|
||||
@@ -774,7 +785,7 @@ static int _conf_domain_rule_address(char *domain, const char *domain_address)
|
||||
address = address_ipv4;
|
||||
} break;
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *addr_in6;
|
||||
struct sockaddr_in6 *addr_in6 = NULL;
|
||||
addr_in6 = (struct sockaddr_in6 *)&addr;
|
||||
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
|
||||
address_ipv4 = malloc(sizeof(*address_ipv4));
|
||||
@@ -836,8 +847,8 @@ errout:
|
||||
static int _config_speed_check_mode_parser(struct dns_domain_check_orders *check_orders, const char *mode)
|
||||
{
|
||||
char tmpbuff[DNS_MAX_OPT_LEN];
|
||||
char *field;
|
||||
char *ptr;
|
||||
char *field = NULL;
|
||||
char *ptr = NULL;
|
||||
int order = 0;
|
||||
int port = 80;
|
||||
int i = 0;
|
||||
@@ -910,7 +921,7 @@ static int _config_speed_check_mode(void *data, int argc, char *argv[])
|
||||
static int _config_bind_ip(int argc, char *argv[], DNS_BIND_TYPE type)
|
||||
{
|
||||
int index = dns_conf_bind_ip_num;
|
||||
struct dns_bind_ip *bind_ip;
|
||||
struct dns_bind_ip *bind_ip = NULL;
|
||||
char *ip = NULL;
|
||||
int opt = 0;
|
||||
char group_name[DNS_GROUP_NAME_LEN];
|
||||
@@ -1022,7 +1033,7 @@ static int _config_bind_ip(int argc, char *argv[], DNS_BIND_TYPE type)
|
||||
bind_ip->flags = server_flag;
|
||||
bind_ip->group = group;
|
||||
dns_conf_bind_ip_num++;
|
||||
tlog(TLOG_DEBUG, "bind ip %s, type:%d, flag: %X", ip, type, server_flag);
|
||||
tlog(TLOG_DEBUG, "bind ip %s, type: %d, flag: %X", ip, type, server_flag);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1144,8 +1155,8 @@ errout:
|
||||
|
||||
static radix_node_t *_create_addr_node(char *addr)
|
||||
{
|
||||
radix_node_t *node;
|
||||
void *p;
|
||||
radix_node_t *node = NULL;
|
||||
void *p = NULL;
|
||||
prefix_t prefix;
|
||||
const char *errmsg = NULL;
|
||||
radix_tree_t *tree = NULL;
|
||||
@@ -1212,7 +1223,7 @@ static int _config_iplist_rule(char *subnet, enum address_rule rule)
|
||||
|
||||
static int _config_qtype_soa(void *data, int argc, char *argv[])
|
||||
{
|
||||
struct dns_qtype_soa_list *soa_list;
|
||||
struct dns_qtype_soa_list *soa_list = NULL;
|
||||
int i = 0;
|
||||
|
||||
if (argc <= 1) {
|
||||
@@ -1242,7 +1253,7 @@ static void _config_qtype_soa_table_destroy(void)
|
||||
{
|
||||
struct dns_qtype_soa_list *soa_list = NULL;
|
||||
struct hlist_node *tmp = NULL;
|
||||
int i;
|
||||
unsigned long i = 0;
|
||||
|
||||
hash_for_each_safe(dns_qtype_soa_table.qtype, i, tmp, soa_list, node)
|
||||
{
|
||||
@@ -1505,7 +1516,7 @@ static int _conf_ptr_add(const char *hostname, const char *ip)
|
||||
{
|
||||
struct dns_ptr *ptr = NULL;
|
||||
struct sockaddr_storage addr;
|
||||
unsigned char *paddr;
|
||||
unsigned char *paddr = NULL;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
char ptr_domain[DNS_MAX_PTR_LEN];
|
||||
|
||||
@@ -1515,13 +1526,13 @@ static int _conf_ptr_add(const char *hostname, const char *ip)
|
||||
|
||||
switch (addr.ss_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *addr_in;
|
||||
struct sockaddr_in *addr_in = NULL;
|
||||
addr_in = (struct sockaddr_in *)&addr;
|
||||
paddr = (unsigned char *)&(addr_in->sin_addr.s_addr);
|
||||
snprintf(ptr_domain, sizeof(ptr_domain), "%d.%d.%d.%d.in-addr.arpa", paddr[3], paddr[2], paddr[1], paddr[0]);
|
||||
} break;
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *addr_in6;
|
||||
struct sockaddr_in6 *addr_in6 = NULL;
|
||||
addr_in6 = (struct sockaddr_in6 *)&addr;
|
||||
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
|
||||
paddr = addr_in6->sin6_addr.s6_addr + 12;
|
||||
@@ -1565,7 +1576,7 @@ static void _config_ptr_table_destroy(void)
|
||||
{
|
||||
struct dns_ptr *ptr = NULL;
|
||||
struct hlist_node *tmp = NULL;
|
||||
int i;
|
||||
unsigned long i = 0;
|
||||
|
||||
hash_for_each_safe(dns_ptr_table.ptr, i, tmp, ptr, node)
|
||||
{
|
||||
@@ -1617,7 +1628,7 @@ static int _conf_host_add(const char *hostname, const char *ip, dns_hosts_type h
|
||||
{
|
||||
struct dns_hosts *host = NULL;
|
||||
struct dns_hosts *host_other __attribute__((unused));
|
||||
;
|
||||
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
int dns_type = 0;
|
||||
@@ -1633,7 +1644,7 @@ static int _conf_host_add(const char *hostname, const char *ip, dns_hosts_type h
|
||||
dns_type_other = DNS_T_AAAA;
|
||||
break;
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *addr_in6;
|
||||
struct sockaddr_in6 *addr_in6 = NULL;
|
||||
addr_in6 = (struct sockaddr_in6 *)&addr;
|
||||
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
|
||||
dns_type = DNS_T_A;
|
||||
@@ -1660,13 +1671,13 @@ static int _conf_host_add(const char *hostname, const char *ip, dns_hosts_type h
|
||||
|
||||
switch (addr.ss_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *addr_in;
|
||||
struct sockaddr_in *addr_in = NULL;
|
||||
addr_in = (struct sockaddr_in *)&addr;
|
||||
memcpy(host->ipv4_addr, &addr_in->sin_addr.s_addr, 4);
|
||||
host->is_soa = 0;
|
||||
} break;
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *addr_in6;
|
||||
struct sockaddr_in6 *addr_in6 = NULL;
|
||||
addr_in6 = (struct sockaddr_in6 *)&addr;
|
||||
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
|
||||
memcpy(host->ipv4_addr, addr_in6->sin6_addr.s6_addr + 12, 4);
|
||||
@@ -1694,7 +1705,7 @@ static int _conf_dhcp_lease_dnsmasq_add(const char *file)
|
||||
char hostname[DNS_MAX_CNAME_LEN];
|
||||
int ret = 0;
|
||||
int line_no = 0;
|
||||
int filed_num;
|
||||
int filed_num = 0;
|
||||
|
||||
fp = fopen(file, "r");
|
||||
if (fp == NULL) {
|
||||
@@ -1710,7 +1721,7 @@ static int _conf_dhcp_lease_dnsmasq_add(const char *file)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp(hostname, "*", DNS_MAX_CNAME_LEN) == 0) {
|
||||
if (strncmp(hostname, "*", DNS_MAX_CNAME_LEN - 1) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1760,7 +1771,7 @@ static void _config_host_table_destroy(void)
|
||||
{
|
||||
struct dns_hosts *host = NULL;
|
||||
struct hlist_node *tmp = NULL;
|
||||
int i;
|
||||
unsigned long i = 0;
|
||||
|
||||
hash_for_each_safe(dns_hosts_table.hosts, i, tmp, host, node)
|
||||
{
|
||||
@@ -1774,7 +1785,7 @@ static void _config_host_table_destroy(void)
|
||||
int dns_server_check_update_hosts(void)
|
||||
{
|
||||
struct stat statbuf;
|
||||
time_t now;
|
||||
time_t now = 0;
|
||||
|
||||
if (dns_conf_dnsmasq_lease_file[0] == '\0') {
|
||||
return -1;
|
||||
@@ -1838,12 +1849,12 @@ static void _config_setup_smartdns_domain(void)
|
||||
}
|
||||
|
||||
/* get host name again */
|
||||
if (strncmp(hostname, "(none)", DNS_MAX_CNAME_LEN) == 0) {
|
||||
if (strncmp(hostname, "(none)", DNS_MAX_CNAME_LEN - 1) == 0) {
|
||||
gethostname(hostname, DNS_MAX_CNAME_LEN);
|
||||
}
|
||||
|
||||
/* if hostname is (none), return smartdns */
|
||||
if (strncmp(hostname, "(none)", DNS_MAX_CNAME_LEN) == 0) {
|
||||
if (strncmp(hostname, "(none)", DNS_MAX_CNAME_LEN - 1) == 0) {
|
||||
safe_strncpy(hostname, "smartdns", DNS_MAX_CNAME_LEN);
|
||||
}
|
||||
|
||||
@@ -1897,6 +1908,7 @@ static struct config_item _config_item[] = {
|
||||
CONF_INT("rr-ttl-max", &dns_conf_rr_ttl_max, 0, CONF_INT_MAX),
|
||||
CONF_INT("rr-ttl-reply-max", &dns_conf_rr_ttl_reply_max, 0, CONF_INT_MAX),
|
||||
CONF_INT("max-reply-ip-num", &dns_conf_max_reply_ip_num, 1, CONF_INT_MAX),
|
||||
CONF_ENUM("response-mode", &dns_conf_response_mode, &dns_conf_response_mode_enum),
|
||||
CONF_YESNO("force-AAAA-SOA", &dns_conf_force_AAAA_SOA),
|
||||
CONF_YESNO("force-no-CNAME", &dns_conf_force_no_cname),
|
||||
CONF_CUSTOM("force-qtype-SOA", _config_qtype_soa, NULL),
|
||||
@@ -1911,20 +1923,24 @@ static struct config_item _config_item[] = {
|
||||
CONF_STRING("ca-file", (char *)&dns_conf_ca_file, DNS_MAX_PATH),
|
||||
CONF_STRING("ca-path", (char *)&dns_conf_ca_path, DNS_MAX_PATH),
|
||||
CONF_STRING("user", (char *)&dns_conf_user, sizeof(dns_conf_user)),
|
||||
CONF_YESNO("debug-save-fail-packet", &dns_save_fail_packet),
|
||||
CONF_STRING("debug-save-fail-packet-dir", (char *)&dns_save_fail_packet_dir, sizeof(dns_save_fail_packet_dir)),
|
||||
CONF_CUSTOM("conf-file", config_addtional_file, NULL),
|
||||
CONF_END(),
|
||||
};
|
||||
|
||||
static int _conf_printf(const char *file, int lineno, int ret)
|
||||
{
|
||||
if (ret == CONF_RET_ERR) {
|
||||
tlog(TLOG_ERROR, "process config file '%s' failed at line %d.", file, lineno);
|
||||
syslog(LOG_NOTICE, "process config file '%s' failed at line %d.", file, lineno);
|
||||
return -1;
|
||||
} else if (ret == CONF_RET_WARN) {
|
||||
switch (ret) {
|
||||
case CONF_RET_ERR:
|
||||
case CONF_RET_WARN:
|
||||
case CONF_RET_BADCONF:
|
||||
tlog(TLOG_WARN, "process config file '%s' failed at line %d.", file, lineno);
|
||||
syslog(LOG_NOTICE, "process config file '%s' failed at line %d.", file, lineno);
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1932,7 +1948,7 @@ static int _conf_printf(const char *file, int lineno, int ret)
|
||||
|
||||
int config_addtional_file(void *data, int argc, char *argv[])
|
||||
{
|
||||
char *conf_file;
|
||||
char *conf_file = NULL;
|
||||
char file_path[DNS_MAX_PATH];
|
||||
char file_path_dir[DNS_MAX_PATH];
|
||||
|
||||
@@ -2002,7 +2018,8 @@ void dns_server_load_exit(void)
|
||||
|
||||
static int _dns_conf_speed_check_mode_verify(void)
|
||||
{
|
||||
int i, j;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int print_log = 0;
|
||||
|
||||
if (dns_has_cap_ping == 1) {
|
||||
@@ -2031,7 +2048,7 @@ static int _dns_conf_speed_check_mode_verify(void)
|
||||
static int _dns_ping_cap_check(void)
|
||||
{
|
||||
int has_ping = 0;
|
||||
int has_raw_cap;
|
||||
int has_raw_cap = 0;
|
||||
|
||||
has_raw_cap = has_network_raw_cap();
|
||||
has_ping = has_unprivileged_ping();
|
||||
@@ -2056,6 +2073,8 @@ static int _dns_conf_load_pre(void)
|
||||
|
||||
_dns_ping_cap_check();
|
||||
|
||||
safe_strncpy(dns_save_fail_packet_dir, SMARTDNS_DEBUG_DIR, sizeof(dns_save_fail_packet_dir));
|
||||
|
||||
return 0;
|
||||
|
||||
errout:
|
||||
@@ -2066,6 +2085,12 @@ static int _dns_conf_load_post(void)
|
||||
{
|
||||
_dns_conf_speed_check_mode_verify();
|
||||
|
||||
if (dns_conf_cachesize == 0 && dns_conf_response_mode == DNS_RESPONSE_MODE_FASTEST_RESPONSE) {
|
||||
dns_conf_response_mode = DNS_RESPONSE_MODE_FASTEST_IP;
|
||||
tlog(TLOG_WARN, "force set response to %s as cache size is 0",
|
||||
dns_conf_response_mode_enum[dns_conf_response_mode].name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,9 +49,10 @@ extern "C" {
|
||||
#define DEFAULT_DNS_HTTPS_PORT 443
|
||||
#define DNS_MAX_CONF_CNAME_LEN 256
|
||||
#define SMARTDNS_CONF_FILE "/etc/smartdns/smartdns.conf"
|
||||
#define SMARTDNS_LOG_FILE "/var/log/smartdns.log"
|
||||
#define SMARTDNS_AUDIT_FILE "/var/log/smartdns-audit.log"
|
||||
#define SMARTDNS_LOG_FILE "/var/log/smartdns/smartdns.log"
|
||||
#define SMARTDNS_AUDIT_FILE "/var/log/smartdns/smartdns-audit.log"
|
||||
#define SMARTDNS_CACHE_FILE "/tmp/smartdns.cache"
|
||||
#define SMARTDNS_DEBUG_DIR "/tmp/smartdns"
|
||||
|
||||
enum domain_rule {
|
||||
DOMAIN_RULE_FLAGS = 0,
|
||||
@@ -298,6 +299,12 @@ extern int dns_conf_dualstack_ip_allow_force_AAAA;
|
||||
extern int dns_conf_dualstack_ip_selection_threshold;
|
||||
|
||||
extern int dns_conf_max_reply_ip_num;
|
||||
enum response_mode_type {
|
||||
DNS_RESPONSE_MODE_FIRST_PING_IP = 0,
|
||||
DNS_RESPONSE_MODE_FASTEST_IP,
|
||||
DNS_RESPONSE_MODE_FASTEST_RESPONSE,
|
||||
};
|
||||
extern enum response_mode_type dns_conf_response_mode;
|
||||
|
||||
extern int dns_conf_rr_ttl;
|
||||
extern int dns_conf_rr_ttl_reply_max;
|
||||
@@ -315,6 +322,9 @@ extern struct dns_edns_client_subnet dns_conf_ipv6_ecs;
|
||||
|
||||
extern char dns_conf_sni_proxy_ip[DNS_MAX_IPLEN];
|
||||
|
||||
extern int dns_save_fail_packet;
|
||||
extern char dns_save_fail_packet_dir[DNS_MAX_PATH];
|
||||
|
||||
void dns_server_load_exit(void);
|
||||
|
||||
int dns_server_load_conf(const char *file);
|
||||
|
||||
505
src/dns_server.c
505
src/dns_server.c
File diff suppressed because it is too large
Load Diff
@@ -37,11 +37,11 @@ void dns_server_stop(void);
|
||||
void dns_server_exit(void);
|
||||
|
||||
/* query result notify function */
|
||||
typedef int (*dns_result_callback)(char *domain, dns_rtcode_t rtcode, dns_type_t addr_type, char *ip,
|
||||
typedef int (*dns_result_callback)(const char *domain, dns_rtcode_t rtcode, dns_type_t addr_type, char *ip,
|
||||
unsigned int ping_time, void *user_ptr);
|
||||
|
||||
/* query domain */
|
||||
int dns_server_query(char *domain, int qtype, uint32_t server_flags, dns_result_callback callback, void *user_ptr);
|
||||
int dns_server_query(const char *domain, int qtype, uint32_t server_flags, dns_result_callback callback, void *user_ptr);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
|
||||
139
src/fast_ping.c
139
src/fast_ping.c
@@ -124,7 +124,7 @@ struct ping_host_struct {
|
||||
};
|
||||
|
||||
struct fast_ping_struct {
|
||||
int run;
|
||||
atomic_t run;
|
||||
pthread_t tid;
|
||||
pthread_mutex_t lock;
|
||||
unsigned short ident;
|
||||
@@ -151,7 +151,7 @@ static int bool_print_log = 1;
|
||||
static uint16_t _fast_ping_checksum(uint16_t *header, size_t len)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
int i;
|
||||
unsigned int i = 0;
|
||||
|
||||
for (i = 0; i < len / sizeof(uint16_t); i++) {
|
||||
sum += ntohs(header[i]);
|
||||
@@ -262,13 +262,13 @@ static uint32_t _fast_ping_hash_key(unsigned int sid, struct sockaddr *addr)
|
||||
|
||||
switch (addr->sa_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *addr_in;
|
||||
struct sockaddr_in *addr_in = NULL;
|
||||
addr_in = (struct sockaddr_in *)addr;
|
||||
sin_addr = &addr_in->sin_addr.s_addr;
|
||||
sin_addr_len = IPV4_ADDR_LEN;
|
||||
} break;
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *addr_in6;
|
||||
struct sockaddr_in6 *addr_in6 = NULL;
|
||||
addr_in6 = (struct sockaddr_in6 *)addr;
|
||||
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
|
||||
sin_addr = addr_in6->sin6_addr.s6_addr + 12;
|
||||
@@ -358,7 +358,7 @@ static void _fast_ping_close_host_sock(struct ping_host_struct *ping_host)
|
||||
if (ping_host->fd < 0) {
|
||||
return;
|
||||
}
|
||||
struct epoll_event *event;
|
||||
struct epoll_event *event = NULL;
|
||||
event = (struct epoll_event *)1;
|
||||
epoll_ctl(ping.epoll_fd, EPOLL_CTL_DEL, ping_host->fd, event);
|
||||
close(ping_host->fd);
|
||||
@@ -442,8 +442,8 @@ static int _fast_ping_sendping_v6(struct ping_host_struct *ping_host)
|
||||
packet->msg.seq = ping_host->seq;
|
||||
icmp6->icmp6_cksum = _fast_ping_checksum((void *)packet, sizeof(struct fast_ping_packet));
|
||||
|
||||
len = sendto(ping.fd_icmp6, &ping_host->packet, sizeof(struct fast_ping_packet), 0,
|
||||
(struct sockaddr *)&ping_host->addr, ping_host->addr_len);
|
||||
len = sendto(ping.fd_icmp6, &ping_host->packet, sizeof(struct fast_ping_packet), 0, &ping_host->addr,
|
||||
ping_host->addr_len);
|
||||
if (len < 0 || len != sizeof(struct fast_ping_packet)) {
|
||||
int err = errno;
|
||||
if (errno == ENETUNREACH || errno == EINVAL || errno == EADDRNOTAVAIL) {
|
||||
@@ -474,7 +474,7 @@ static int _fast_ping_sendping_v4(struct ping_host_struct *ping_host)
|
||||
{
|
||||
struct fast_ping_packet *packet = &ping_host->packet;
|
||||
struct icmp *icmp = &packet->icmp;
|
||||
int len;
|
||||
int len = 0;
|
||||
|
||||
ping_host->seq++;
|
||||
memset(icmp, 0, sizeof(*icmp));
|
||||
@@ -491,8 +491,7 @@ static int _fast_ping_sendping_v4(struct ping_host_struct *ping_host)
|
||||
packet->msg.cookie = ping_host->cookie;
|
||||
icmp->icmp_cksum = _fast_ping_checksum((void *)packet, sizeof(struct fast_ping_packet));
|
||||
|
||||
len = sendto(ping.fd_icmp, packet, sizeof(struct fast_ping_packet), 0, (struct sockaddr *)&ping_host->addr,
|
||||
ping_host->addr_len);
|
||||
len = sendto(ping.fd_icmp, packet, sizeof(struct fast_ping_packet), 0, &ping_host->addr, ping_host->addr_len);
|
||||
if (len < 0 || len != sizeof(struct fast_ping_packet)) {
|
||||
int err = errno;
|
||||
if (errno == ENETUNREACH || errno == EINVAL || errno == EADDRNOTAVAIL) {
|
||||
@@ -514,7 +513,7 @@ errout:
|
||||
static int _fast_ping_sendping_udp(struct ping_host_struct *ping_host)
|
||||
{
|
||||
struct ping_dns_head dns_head;
|
||||
int len;
|
||||
int len = 0;
|
||||
int flag = 0;
|
||||
int fd = 0;
|
||||
|
||||
@@ -539,7 +538,7 @@ static int _fast_ping_sendping_udp(struct ping_host_struct *ping_host)
|
||||
dns_head.id = htons(ping_host->sid);
|
||||
dns_head.flag = flag;
|
||||
gettimeofday(&ping_host->last, NULL);
|
||||
len = sendto(fd, &dns_head, sizeof(dns_head), 0, (struct sockaddr *)&ping_host->addr, ping_host->addr_len);
|
||||
len = sendto(fd, &dns_head, sizeof(dns_head), 0, &ping_host->addr, ping_host->addr_len);
|
||||
if (len < 0 || len != sizeof(dns_head)) {
|
||||
int err = errno;
|
||||
if (errno == ENETUNREACH || errno == EINVAL || errno == EADDRNOTAVAIL) {
|
||||
@@ -561,7 +560,7 @@ errout:
|
||||
static int _fast_ping_sendping_tcp(struct ping_host_struct *ping_host)
|
||||
{
|
||||
struct epoll_event event;
|
||||
int flags;
|
||||
int flags = 0;
|
||||
int fd = -1;
|
||||
int yes = 1;
|
||||
const int priority = SOCKET_PRIORITY;
|
||||
@@ -586,7 +585,7 @@ static int _fast_ping_sendping_tcp(struct ping_host_struct *ping_host)
|
||||
set_sock_lingertime(fd, 0);
|
||||
|
||||
ping_host->seq++;
|
||||
if (connect(fd, (struct sockaddr *)&ping_host->addr, ping_host->addr_len) != 0) {
|
||||
if (connect(fd, &ping_host->addr, ping_host->addr_len) != 0) {
|
||||
if (errno != EINPROGRESS) {
|
||||
char ping_host_name[PING_MAX_HOSTLEN];
|
||||
if (errno == ENETUNREACH || errno == EINVAL || errno == EADDRNOTAVAIL) {
|
||||
@@ -674,6 +673,12 @@ static int _fast_ping_create_icmp_sock(FAST_PING_TYPE type)
|
||||
}
|
||||
}
|
||||
if (fd < 0) {
|
||||
if (errno == EACCES || errno == EAFNOSUPPORT) {
|
||||
if (bool_print_log == 0) {
|
||||
goto errout;
|
||||
}
|
||||
bool_print_log = 0;
|
||||
}
|
||||
tlog(TLOG_ERROR, "create icmp socket failed, %s\n", strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
@@ -690,6 +695,12 @@ static int _fast_ping_create_icmp_sock(FAST_PING_TYPE type)
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
if (errno == EACCES || errno == EAFNOSUPPORT) {
|
||||
if (bool_print_log == 0) {
|
||||
goto errout;
|
||||
}
|
||||
bool_print_log = 0;
|
||||
}
|
||||
tlog(TLOG_ERROR, "create icmp socket failed, %s\n", strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
@@ -711,6 +722,9 @@ static int _fast_ping_create_icmp_sock(FAST_PING_TYPE type)
|
||||
setsockopt(fd, SOL_IP, IP_TTL, &val, sizeof(val));
|
||||
setsockopt(fd, IPPROTO_IP, IP_TOS, &ip_tos, sizeof(ip_tos));
|
||||
|
||||
icmp_host->fd = fd;
|
||||
icmp_host->type = type;
|
||||
|
||||
memset(&event, 0, sizeof(event));
|
||||
event.events = EPOLLIN;
|
||||
event.data.ptr = icmp_host;
|
||||
@@ -718,12 +732,14 @@ static int _fast_ping_create_icmp_sock(FAST_PING_TYPE type)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
icmp_host->fd = fd;
|
||||
icmp_host->type = type;
|
||||
return fd;
|
||||
|
||||
errout:
|
||||
close(fd);
|
||||
if (icmp_host) {
|
||||
icmp_host->fd = -1;
|
||||
icmp_host->type = 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -883,7 +899,7 @@ static int _fast_ping_get_addr_by_icmp(const char *ip_str, int port, struct addr
|
||||
struct addrinfo *gai = NULL;
|
||||
int socktype = 0;
|
||||
int domain = -1;
|
||||
FAST_PING_TYPE ping_type;
|
||||
FAST_PING_TYPE ping_type = 0;
|
||||
int sockproto = 0;
|
||||
char *service = NULL;
|
||||
|
||||
@@ -932,7 +948,7 @@ static int _fast_ping_get_addr_by_tcp(const char *ip_str, int port, struct addri
|
||||
{
|
||||
struct addrinfo *gai = NULL;
|
||||
int socktype = 0;
|
||||
FAST_PING_TYPE ping_type;
|
||||
FAST_PING_TYPE ping_type = 0;
|
||||
int sockproto = 0;
|
||||
char *service = NULL;
|
||||
char port_str[MAX_IP_LEN];
|
||||
@@ -968,7 +984,7 @@ static int _fast_ping_get_addr_by_dns(const char *ip_str, int port, struct addri
|
||||
{
|
||||
struct addrinfo *gai = NULL;
|
||||
int socktype = 0;
|
||||
FAST_PING_TYPE ping_type;
|
||||
FAST_PING_TYPE ping_type = 0;
|
||||
int sockproto = 0;
|
||||
char port_str[MAX_IP_LEN];
|
||||
int domain = -1;
|
||||
@@ -1045,11 +1061,11 @@ struct ping_host_struct *fast_ping_start(PING_TYPE type, const char *host, int c
|
||||
{
|
||||
struct ping_host_struct *ping_host = NULL;
|
||||
struct addrinfo *gai = NULL;
|
||||
uint32_t addrkey;
|
||||
uint32_t addrkey = 0;
|
||||
char ip_str[PING_MAX_HOSTLEN];
|
||||
int port = -1;
|
||||
FAST_PING_TYPE ping_type = FAST_PING_END;
|
||||
unsigned int seed;
|
||||
unsigned int seed = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (parse_ip(host, ip_str, &port) != 0) {
|
||||
@@ -1114,7 +1130,7 @@ struct ping_host_struct *fast_ping_start(PING_TYPE type, const char *host, int c
|
||||
return ping_host;
|
||||
errout_remove:
|
||||
ping_host->ping_callback(ping_host, ping_host->host, PING_RESULT_ERROR, &ping_host->addr, ping_host->addr_len,
|
||||
ping_host->seq, ping_host->ttl, 0, ping_host->error, ping_host->userptr);
|
||||
ping_host->seq, ping_host->ttl, NULL, ping_host->error, ping_host->userptr);
|
||||
fast_ping_stop(ping_host);
|
||||
_fast_ping_host_put(ping_host);
|
||||
ping_host = NULL;
|
||||
@@ -1154,22 +1170,24 @@ static void tv_sub(struct timeval *out, struct timeval *in)
|
||||
static struct fast_ping_packet *_fast_ping_icmp6_packet(struct ping_host_struct *ping_host, struct msghdr *msg,
|
||||
u_char *packet_data, int data_len)
|
||||
{
|
||||
int icmp_len;
|
||||
int icmp_len = 0;
|
||||
struct fast_ping_packet *packet = (struct fast_ping_packet *)packet_data;
|
||||
struct icmp6_hdr *icmp6 = &packet->icmp6;
|
||||
struct cmsghdr *c;
|
||||
struct cmsghdr *c = NULL;
|
||||
int hops = 0;
|
||||
|
||||
for (c = CMSG_FIRSTHDR(msg); c; c = CMSG_NXTHDR(msg, c)) {
|
||||
if (c->cmsg_level != IPPROTO_IPV6)
|
||||
if (c->cmsg_level != IPPROTO_IPV6) {
|
||||
continue;
|
||||
}
|
||||
switch (c->cmsg_type) {
|
||||
case IPV6_HOPLIMIT:
|
||||
#ifdef IPV6_2292HOPLIMIT
|
||||
case IPV6_2292HOPLIMIT:
|
||||
#endif
|
||||
if (c->cmsg_len < CMSG_LEN(sizeof(int)))
|
||||
if (c->cmsg_len < CMSG_LEN(sizeof(int))) {
|
||||
continue;
|
||||
}
|
||||
memcpy(&hops, CMSG_DATA(c), sizeof(hops));
|
||||
}
|
||||
}
|
||||
@@ -1200,10 +1218,10 @@ static struct fast_ping_packet *_fast_ping_icmp_packet(struct ping_host_struct *
|
||||
u_char *packet_data, int data_len)
|
||||
{
|
||||
struct ip *ip = (struct ip *)packet_data;
|
||||
struct fast_ping_packet *packet;
|
||||
struct icmp *icmp;
|
||||
int hlen;
|
||||
int icmp_len;
|
||||
struct fast_ping_packet *packet = NULL;
|
||||
struct icmp *icmp = NULL;
|
||||
int hlen = 0;
|
||||
int icmp_len = 0;
|
||||
|
||||
hlen = ip->ip_hl << 2;
|
||||
packet = (struct fast_ping_packet *)(packet_data + hlen);
|
||||
@@ -1216,6 +1234,11 @@ static struct fast_ping_packet *_fast_ping_icmp_packet(struct ping_host_struct *
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (icmp->icmp_type != ICMP_ECHOREPLY) {
|
||||
tlog(TLOG_DEBUG, "icmp type faild, %d:%d", icmp->icmp_type, ICMP_ECHOREPLY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ping.no_unprivileged_ping) {
|
||||
if (ip->ip_p != IPPROTO_ICMP) {
|
||||
tlog(TLOG_ERROR, "ip type faild, %d:%d", ip->ip_p, IPPROTO_ICMP);
|
||||
@@ -1228,12 +1251,6 @@ static struct fast_ping_packet *_fast_ping_icmp_packet(struct ping_host_struct *
|
||||
}
|
||||
}
|
||||
|
||||
if (icmp->icmp_type != ICMP_ECHOREPLY) {
|
||||
tlog(TLOG_DEBUG, "icmp type faild, %d:%d", icmp->icmp_type, ICMP_ECHOREPLY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
@@ -1264,18 +1281,18 @@ errout:
|
||||
|
||||
static int _fast_ping_process_icmp(struct ping_host_struct *ping_host, struct timeval *now)
|
||||
{
|
||||
int len;
|
||||
int len = 0;
|
||||
u_char inpacket[ICMP_INPACKET_SIZE];
|
||||
struct sockaddr_storage from;
|
||||
struct ping_host_struct *recv_ping_host;
|
||||
struct ping_host_struct *recv_ping_host = NULL;
|
||||
struct fast_ping_packet *packet = NULL;
|
||||
socklen_t from_len = sizeof(from);
|
||||
uint32_t addrkey;
|
||||
uint32_t addrkey = 0;
|
||||
struct timeval tvresult = *now;
|
||||
struct timeval *tvsend = NULL;
|
||||
unsigned int sid;
|
||||
unsigned int seq;
|
||||
unsigned int cookie;
|
||||
unsigned int sid = 0;
|
||||
unsigned int seq = 0;
|
||||
unsigned int cookie = 0;
|
||||
struct msghdr msg;
|
||||
struct iovec iov;
|
||||
char ans_data[4096];
|
||||
@@ -1392,20 +1409,20 @@ errout:
|
||||
|
||||
static int _fast_ping_process_udp(struct ping_host_struct *ping_host, struct timeval *now)
|
||||
{
|
||||
int len;
|
||||
ssize_t len = 0;
|
||||
u_char inpacket[ICMP_INPACKET_SIZE];
|
||||
struct sockaddr_storage from;
|
||||
struct ping_host_struct *recv_ping_host;
|
||||
struct ping_host_struct *recv_ping_host = NULL;
|
||||
struct ping_dns_head *dns_head = NULL;
|
||||
socklen_t from_len = sizeof(from);
|
||||
uint32_t addrkey;
|
||||
uint32_t addrkey = 0;
|
||||
struct timeval tvresult = *now;
|
||||
struct timeval *tvsend = NULL;
|
||||
unsigned int sid;
|
||||
unsigned int sid = 0;
|
||||
struct msghdr msg;
|
||||
struct iovec iov;
|
||||
char ans_data[4096];
|
||||
struct cmsghdr *cmsg;
|
||||
struct cmsghdr *cmsg = NULL;
|
||||
int ttl = 0;
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
@@ -1440,7 +1457,7 @@ static int _fast_ping_process_udp(struct ping_host_struct *ping_host, struct tim
|
||||
|
||||
from_len = msg.msg_namelen;
|
||||
dns_head = (struct ping_dns_head *)inpacket;
|
||||
if (len < sizeof(*dns_head)) {
|
||||
if (len < (ssize_t)sizeof(*dns_head)) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
@@ -1515,7 +1532,7 @@ static void _fast_ping_remove_all(void)
|
||||
struct ping_host_struct *ping_host = NULL;
|
||||
struct ping_host_struct *ping_host_tmp = NULL;
|
||||
struct hlist_node *tmp = NULL;
|
||||
int i;
|
||||
unsigned long i = 0;
|
||||
|
||||
LIST_HEAD(remove_list);
|
||||
|
||||
@@ -1537,11 +1554,11 @@ static void _fast_ping_period_run(void)
|
||||
struct ping_host_struct *ping_host = NULL;
|
||||
struct ping_host_struct *ping_host_tmp = NULL;
|
||||
struct hlist_node *tmp = NULL;
|
||||
int i = 0;
|
||||
unsigned long i = 0;
|
||||
struct timeval now;
|
||||
struct timezone tz;
|
||||
struct timeval interval;
|
||||
int64_t millisecond;
|
||||
int64_t millisecond = 0;
|
||||
gettimeofday(&now, &tz);
|
||||
LIST_HEAD(action);
|
||||
|
||||
@@ -1607,8 +1624,8 @@ static void _fast_ping_period_run(void)
|
||||
static void *_fast_ping_work(void *arg)
|
||||
{
|
||||
struct epoll_event events[PING_MAX_EVENTS + 1];
|
||||
int num;
|
||||
int i;
|
||||
int num = 0;
|
||||
int i = 0;
|
||||
unsigned long now = {0};
|
||||
struct timeval tvnow = {0};
|
||||
int sleep = 100;
|
||||
@@ -1618,7 +1635,7 @@ static void *_fast_ping_work(void *arg)
|
||||
sleep_time = sleep;
|
||||
now = get_tick_count() - sleep;
|
||||
expect_time = now + sleep;
|
||||
while (ping.run) {
|
||||
while (atomic_read(&ping.run)) {
|
||||
now = get_tick_count();
|
||||
if (now >= expect_time) {
|
||||
_fast_ping_period_run();
|
||||
@@ -1658,7 +1675,7 @@ int fast_ping_init(void)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
int epollfd = -1;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
bool_print_log = 1;
|
||||
|
||||
if (ping.epoll_fd > 0) {
|
||||
@@ -1680,7 +1697,7 @@ int fast_ping_init(void)
|
||||
ping.epoll_fd = epollfd;
|
||||
ping.no_unprivileged_ping = !has_unprivileged_ping();
|
||||
ping.ident = (getpid() & 0XFFFF);
|
||||
ping.run = 1;
|
||||
atomic_set(&ping.run, 1);
|
||||
ret = pthread_create(&ping.tid, &attr, _fast_ping_work, NULL);
|
||||
if (ret != 0) {
|
||||
tlog(TLOG_ERROR, "create ping work thread failed, %s\n", strerror(errno));
|
||||
@@ -1689,10 +1706,11 @@ int fast_ping_init(void)
|
||||
|
||||
return 0;
|
||||
errout:
|
||||
if (ping.tid > 0) {
|
||||
if (ping.tid) {
|
||||
void *retval = NULL;
|
||||
ping.run = 0;
|
||||
atomic_set(&ping.run, 0);
|
||||
pthread_join(ping.tid, &retval);
|
||||
ping.tid = 0;
|
||||
}
|
||||
|
||||
if (epollfd) {
|
||||
@@ -1730,10 +1748,11 @@ static void _fast_ping_close_fds(void)
|
||||
|
||||
void fast_ping_exit(void)
|
||||
{
|
||||
if (ping.tid > 0) {
|
||||
if (ping.tid) {
|
||||
void *ret = NULL;
|
||||
ping.run = 0;
|
||||
atomic_set(&ping.run, 0);
|
||||
pthread_join(ping.tid, &ret);
|
||||
ping.tid = 0;
|
||||
}
|
||||
|
||||
_fast_ping_close_fds();
|
||||
|
||||
@@ -108,7 +108,7 @@ struct http_head_fields *http_head_first_fields(struct http_head *http_head)
|
||||
|
||||
const char *http_head_get_fields_value(struct http_head *http_head, const char *name)
|
||||
{
|
||||
unsigned long key;
|
||||
uint32_t key;
|
||||
struct http_head_fields *filed;
|
||||
|
||||
key = hash_string(name);
|
||||
@@ -193,7 +193,7 @@ int http_head_get_data_len(struct http_head *http_head)
|
||||
|
||||
static int _http_head_add_fields(struct http_head *http_head, char *name, char *value)
|
||||
{
|
||||
unsigned long key = 0;
|
||||
uint32_t key = 0;
|
||||
struct http_head_fields *fields = NULL;
|
||||
fields = malloc(sizeof(*fields));
|
||||
if (fields == NULL) {
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
#ifndef _GENERIC_ATOMIC_H
|
||||
#define _GENERIC_ATOMIC_H
|
||||
|
||||
#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
|
||||
|
||||
#define READ_ONCE(x) \
|
||||
({ typeof(x) ___x = ACCESS_ONCE(x); ___x; })
|
||||
|
||||
/**
|
||||
* Atomic type.
|
||||
*/
|
||||
@@ -35,14 +40,20 @@ typedef struct {
|
||||
*
|
||||
* Atomically reads the value of @v.
|
||||
*/
|
||||
#define atomic_read(v) ((v)->counter)
|
||||
static inline int atomic_read(const atomic_t *v)
|
||||
{
|
||||
return READ_ONCE((v)->counter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set atomic variable
|
||||
* @param v pointer of type atomic_t
|
||||
* @param i required value
|
||||
*/
|
||||
#define atomic_set(v,i) (((v)->counter) = (i))
|
||||
static inline void atomic_set(atomic_t *v, int i)
|
||||
{
|
||||
v->counter = i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add to the atomic variable
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#define CONF_RET_ERR -1
|
||||
#define CONF_RET_WARN -2
|
||||
#define CONF_RET_NOENT -3
|
||||
#define CONF_RET_BADCONF -4
|
||||
|
||||
struct config_item {
|
||||
const char *item;
|
||||
@@ -63,6 +64,16 @@ struct config_item_size {
|
||||
size_t max;
|
||||
};
|
||||
|
||||
struct config_enum_list {
|
||||
char *name;
|
||||
int id;
|
||||
};
|
||||
|
||||
struct config_enum {
|
||||
int *data;
|
||||
struct config_enum_list *list;
|
||||
};
|
||||
|
||||
#define CONF_INT(key, value, min_value, max_value) \
|
||||
{ \
|
||||
key, conf_int, &(struct config_item_int) \
|
||||
@@ -91,6 +102,15 @@ struct config_item_size {
|
||||
.data = value, .min = min_value, .max = max_value \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CONF_ENUM(key, value, enum) \
|
||||
{ \
|
||||
key, conf_enum, &(struct config_enum) \
|
||||
{ \
|
||||
.data = (int *)value, .list = (struct config_enum_list *)enum \
|
||||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* func: int (*func)(void *data, int argc, char *argv[]);
|
||||
*/
|
||||
@@ -117,6 +137,8 @@ extern int conf_yesno(const char *item, void *data, int argc, char *argv[]);
|
||||
|
||||
extern int conf_size(const char *item, void *data, int argc, char *argv[]);
|
||||
|
||||
extern int conf_enum(const char *item, void *data, int argc, char *argv[]);
|
||||
|
||||
/*
|
||||
* Example:
|
||||
* int num = 0;
|
||||
|
||||
@@ -219,14 +219,16 @@ static inline uint32_t hash32_ptr(const void *ptr)
|
||||
return (uint32_t)val;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
hash_string(const char *str)
|
||||
static inline uint32_t hash_string(const char *s)
|
||||
{
|
||||
unsigned long v = 0;
|
||||
const char *c;
|
||||
for (c = str; *c; )
|
||||
v = (((v << 1) + (v >> 14)) ^ (*c++)) & 0x3fff;
|
||||
return(v);
|
||||
uint32_t h = 0;
|
||||
|
||||
while (*s) {
|
||||
h = h * 31 + *s;
|
||||
s++;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
#endif /* _GENERIC_HASH_H */
|
||||
|
||||
@@ -1016,7 +1016,7 @@ static void art_copy_key(art_leaf *leaf, unsigned char *key, int *key_len)
|
||||
return;
|
||||
}
|
||||
|
||||
len = leaf->key_len > *key_len ? *key_len : leaf->key_len;
|
||||
len = (int)leaf->key_len > *key_len ? *key_len : (int)leaf->key_len;
|
||||
memcpy(key, leaf->key, len);
|
||||
*key_len = len;
|
||||
}
|
||||
|
||||
@@ -97,7 +97,6 @@ int conf_yesno(const char *item, void *data, int argc, char *argv[])
|
||||
|
||||
int conf_size(const char *item, void *data, int argc, char *argv[])
|
||||
{
|
||||
/* read dns cache size */
|
||||
int base = 1;
|
||||
size_t size = 0;
|
||||
int num = 0;
|
||||
@@ -129,7 +128,32 @@ int conf_size(const char *item, void *data, int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
void conf_getopt_reset(void)
|
||||
int conf_enum(const char *item, void *data, int argc, char *argv[])
|
||||
{
|
||||
struct config_enum *item_enum = data;
|
||||
char *enum_name = argv[1];
|
||||
int i = 0;
|
||||
|
||||
if (argc <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; item_enum->list[i].name != NULL; i++) {
|
||||
if (strcmp(enum_name, item_enum->list[i].name) == 0) {
|
||||
*(item_enum->data) = item_enum->list[i].id;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Not found config value '%s', valid value is:\n", enum_name);
|
||||
for (i = 0; item_enum->list[i].name != NULL; i++) {
|
||||
printf(" %s\n", item_enum->list[i].name);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void conf_getopt_reset(void)
|
||||
{
|
||||
static struct option long_options[] = {{"-", 0, 0, 0}, {0, 0, 0, 0}};
|
||||
int argc = 2;
|
||||
@@ -144,7 +168,7 @@ void conf_getopt_reset(void)
|
||||
optopt = 0;
|
||||
}
|
||||
|
||||
int conf_parse_args(char *key, char *value, int *argc, char **argv)
|
||||
static int conf_parse_args(char *key, char *value, int *argc, char **argv)
|
||||
{
|
||||
char *start = NULL;
|
||||
char *ptr = value;
|
||||
@@ -205,12 +229,9 @@ int conf_parse_args(char *key, char *value, int *argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void load_exit(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
void load_exit(void) {}
|
||||
|
||||
int load_conf_printf(const char *file, int lineno, int ret)
|
||||
static int load_conf_printf(const char *file, int lineno, int ret)
|
||||
{
|
||||
if (ret != CONF_RET_OK) {
|
||||
printf("process config file '%s' failed at line %d.", file, lineno);
|
||||
@@ -224,15 +245,15 @@ int load_conf_printf(const char *file, int lineno, int ret)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int load_conf_file(const char *file, struct config_item *items, conf_error_handler handler)
|
||||
static int load_conf_file(const char *file, struct config_item *items, conf_error_handler handler)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
char line[MAX_LINE_LEN];
|
||||
char key[MAX_KEY_LEN];
|
||||
char value[MAX_LINE_LEN];
|
||||
int filed_num = 0;
|
||||
int i;
|
||||
int argc;
|
||||
int i = 0;
|
||||
int argc = 0;
|
||||
char *argv[1024];
|
||||
int ret = 0;
|
||||
int call_ret = 0;
|
||||
@@ -262,6 +283,7 @@ int load_conf_file(const char *file, struct config_item *items, conf_error_handl
|
||||
|
||||
/* if field format is not key = value, error */
|
||||
if (filed_num != 2) {
|
||||
handler(file, line_no, CONF_RET_BADCONF);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ comp_with_mask(unsigned char *addr, unsigned char *dest, unsigned int mask)
|
||||
{
|
||||
if (memcmp(addr, dest, mask / 8) == 0) {
|
||||
unsigned int n = mask / 8;
|
||||
unsigned int m = ((~0) << (8 - (mask % 8)));
|
||||
unsigned int m = ((unsigned int)(~0) << (8 - (mask % 8)));
|
||||
|
||||
if (mask % 8 == 0 || (addr[n] & m) == (dest[n] & m))
|
||||
return (1);
|
||||
@@ -549,7 +549,7 @@ sanitise_mask(unsigned char *addr, unsigned int masklen, unsigned int maskbits)
|
||||
unsigned int j = masklen % 8;
|
||||
|
||||
if (j != 0) {
|
||||
addr[i] &= (~0) << (8 - j);
|
||||
addr[i] &= (unsigned int)(~0) << (8 - j);
|
||||
i++;
|
||||
}
|
||||
for (; i < maskbits / 8; i++)
|
||||
|
||||
114
src/smartdns.c
114
src/smartdns.c
@@ -55,12 +55,12 @@ static int verbose_screen;
|
||||
int capget(struct __user_cap_header_struct *header, struct __user_cap_data_struct *cap);
|
||||
int capset(struct __user_cap_header_struct *header, struct __user_cap_data_struct *cap);
|
||||
|
||||
int get_uid_gid(int *uid, int *gid)
|
||||
static int get_uid_gid(int *uid, int *gid)
|
||||
{
|
||||
struct passwd *result = NULL;
|
||||
struct passwd pwd;
|
||||
char *buf = NULL;
|
||||
size_t bufsize;
|
||||
ssize_t bufsize = 0;
|
||||
int ret = -1;
|
||||
|
||||
if (dns_conf_user[0] == '\0') {
|
||||
@@ -79,7 +79,7 @@ int get_uid_gid(int *uid, int *gid)
|
||||
|
||||
ret = getpwnam_r(dns_conf_user, &pwd, buf, bufsize, &result);
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*uid = result->pw_uid;
|
||||
@@ -93,14 +93,15 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int drop_root_privilege(void)
|
||||
static int drop_root_privilege(void)
|
||||
{
|
||||
struct __user_cap_data_struct cap;
|
||||
struct __user_cap_header_struct header;
|
||||
header.version = _LINUX_CAPABILITY_VERSION;
|
||||
header.pid = 0;
|
||||
int uid;
|
||||
int gid;
|
||||
int uid = 0;
|
||||
int gid = 0;
|
||||
int unused __attribute__((unused)) = 0;
|
||||
|
||||
if (get_uid_gid(&uid, &gid) != 0) {
|
||||
return -1;
|
||||
@@ -113,8 +114,8 @@ int drop_root_privilege(void)
|
||||
prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
|
||||
cap.effective |= (1 << CAP_NET_RAW | 1 << CAP_NET_ADMIN);
|
||||
cap.permitted |= (1 << CAP_NET_RAW | 1 << CAP_NET_ADMIN);
|
||||
setuid(uid);
|
||||
setgid(gid);
|
||||
unused = setgid(gid);
|
||||
unused = setuid(uid);
|
||||
if (capset(&header, &cap) < 0) {
|
||||
return -1;
|
||||
}
|
||||
@@ -131,7 +132,7 @@ static void _help(void)
|
||||
"Start smartdns server.\n"
|
||||
" -f run forground.\n"
|
||||
" -c [conf] config file.\n"
|
||||
" -p [pid] pid file path\n"
|
||||
" -p [pid] pid file path, '-' means don't create pid file.\n"
|
||||
" -S ignore segment fault signal.\n"
|
||||
" -x verbose screen.\n"
|
||||
" -v dispaly version.\n"
|
||||
@@ -186,7 +187,7 @@ static int _smartdns_load_from_resolv(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp(key, "nameserver", MAX_KEY_LEN) != 0) {
|
||||
if (strncmp(key, "nameserver", MAX_KEY_LEN - 1) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -212,14 +213,14 @@ static int _smartdns_load_from_resolv(void)
|
||||
|
||||
static int _smartdns_add_servers(void)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned long i = 0;
|
||||
int j = 0;
|
||||
int ret = 0;
|
||||
struct dns_server_groups *group = NULL;
|
||||
struct dns_servers *server = NULL;
|
||||
struct client_dns_server_flags flags;
|
||||
|
||||
for (i = 0; i < dns_conf_server_num; i++) {
|
||||
for (i = 0; i < (unsigned int)dns_conf_server_num; i++) {
|
||||
memset(&flags, 0, sizeof(flags));
|
||||
switch (dns_conf_servers[i].type) {
|
||||
case DNS_SERVER_UDP: {
|
||||
@@ -322,15 +323,22 @@ static int _smartdns_destroy_ssl(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _smartdns_init(void)
|
||||
static const char *_smartdns_log_path(void)
|
||||
{
|
||||
int ret;
|
||||
char *logfile = SMARTDNS_LOG_FILE;
|
||||
|
||||
if (dns_conf_log_file[0] != 0) {
|
||||
logfile = dns_conf_log_file;
|
||||
}
|
||||
|
||||
return logfile;
|
||||
}
|
||||
|
||||
static int _smartdns_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
const char *logfile = _smartdns_log_path();
|
||||
|
||||
ret = tlog_init(logfile, dns_conf_log_size, dns_conf_log_num, 0, 0);
|
||||
if (ret != 0) {
|
||||
tlog(TLOG_ERROR, "start tlog failed.\n");
|
||||
@@ -340,7 +348,7 @@ static int _smartdns_init(void)
|
||||
tlog_setlogscreen(verbose_screen);
|
||||
tlog_setlevel(dns_conf_log_level);
|
||||
|
||||
tlog(TLOG_NOTICE, "smartdns starting...(Copyright (C) Nick Peng <pymumu@gmail.com>, build:%s %s)", __DATE__,
|
||||
tlog(TLOG_NOTICE, "smartdns starting...(Copyright (C) Nick Peng <pymumu@gmail.com>, build: %s %s)", __DATE__,
|
||||
__TIME__);
|
||||
|
||||
if (_smartdns_init_ssl() != 0) {
|
||||
@@ -396,10 +404,10 @@ static int _smartdns_run(void)
|
||||
|
||||
static void _smartdns_exit(void)
|
||||
{
|
||||
tlog(TLOG_INFO, "smartdns starting exit...");
|
||||
dns_server_exit();
|
||||
tlog(TLOG_INFO, "smartdns exit...");
|
||||
dns_client_exit();
|
||||
fast_ping_exit();
|
||||
dns_server_exit();
|
||||
_smartdns_destroy_ssl();
|
||||
tlog_exit();
|
||||
dns_server_load_exit();
|
||||
@@ -407,7 +415,7 @@ static void _smartdns_exit(void)
|
||||
|
||||
static void _sig_exit(int signo)
|
||||
{
|
||||
tlog(TLOG_INFO, "start stop smartdns");
|
||||
tlog(TLOG_INFO, "stop smartdns by signal %d", signo);
|
||||
dns_server_stop();
|
||||
}
|
||||
|
||||
@@ -450,7 +458,8 @@ static int sig_num = sizeof(sig_list) / sizeof(int);
|
||||
|
||||
static void _reg_signal(void)
|
||||
{
|
||||
struct sigaction act, old;
|
||||
struct sigaction act;
|
||||
struct sigaction old;
|
||||
int i = 0;
|
||||
act.sa_sigaction = _sig_error_exit;
|
||||
sigemptyset(&act.sa_mask);
|
||||
@@ -461,11 +470,48 @@ static void _reg_signal(void)
|
||||
}
|
||||
}
|
||||
|
||||
static int _smartdns_create_logdir(void)
|
||||
{
|
||||
int uid = 0;
|
||||
int gid = 0;
|
||||
char logdir[PATH_MAX] = {0};
|
||||
safe_strncpy(logdir, _smartdns_log_path(), PATH_MAX);
|
||||
dirname(logdir);
|
||||
|
||||
if (access(logdir, F_OK) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mkdir(logdir, 0750) != 0) {
|
||||
if (errno == EEXIST) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int unused __attribute__((unused)) = 0;
|
||||
|
||||
if (get_uid_gid(&uid, &gid) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
chown(logdir, uid, gid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _smartdns_init_pre(void)
|
||||
{
|
||||
_smartdns_create_logdir();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
int is_forground = 0;
|
||||
int opt;
|
||||
int opt = 0;
|
||||
char config_file[MAX_LINE_LEN];
|
||||
char pid_file[MAX_LINE_LEN];
|
||||
int signal_ignore = 0;
|
||||
@@ -476,9 +522,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* patch for Asus router: unblock all signal*/
|
||||
sigemptyset(&empty_sigblock);
|
||||
sigprocmask(SIG_SETMASK, &empty_sigblock, NULL);
|
||||
sigprocmask(SIG_SETMASK, &empty_sigblock, NULL);
|
||||
|
||||
while ((opt = getopt(argc, argv, "fhc:p:Svx")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "fhc:p:SvxN:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'f':
|
||||
is_forground = 1;
|
||||
@@ -499,12 +545,21 @@ int main(int argc, char *argv[])
|
||||
_show_version();
|
||||
return 0;
|
||||
break;
|
||||
#ifdef DEBUG
|
||||
case 'N':
|
||||
return dns_packet_debug(optarg);
|
||||
#endif
|
||||
case 'h':
|
||||
_help();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (dns_server_load_conf(config_file) != 0) {
|
||||
fprintf(stderr, "load config failed.\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (is_forground == 0) {
|
||||
if (daemon(0, 0) < 0) {
|
||||
fprintf(stderr, "run daemon process failed, %s\n", strerror(errno));
|
||||
@@ -516,14 +571,17 @@ int main(int argc, char *argv[])
|
||||
_reg_signal();
|
||||
}
|
||||
|
||||
if (create_pid_file(pid_file) != 0) {
|
||||
if (strncmp(pid_file, "-", 2) != 0 && create_pid_file(pid_file) != 0) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
if (dns_server_load_conf(config_file) != 0) {
|
||||
fprintf(stderr, "load config failed.\n");
|
||||
goto errout;
|
||||
signal(SIGINT, _sig_exit);
|
||||
signal(SIGTERM, _sig_exit);
|
||||
|
||||
if (_smartdns_init_pre() != 0) {
|
||||
fprintf(stderr, "init failed.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
drop_root_privilege();
|
||||
@@ -534,8 +592,6 @@ int main(int argc, char *argv[])
|
||||
goto errout;
|
||||
}
|
||||
|
||||
signal(SIGINT, _sig_exit);
|
||||
signal(SIGTERM, _sig_exit);
|
||||
atexit(_smartdns_exit);
|
||||
|
||||
return _smartdns_run();
|
||||
|
||||
52
src/tlog.c
52
src/tlog.c
@@ -79,8 +79,9 @@ struct tlog_log {
|
||||
int zip_pid;
|
||||
int multi_log;
|
||||
int logscreen;
|
||||
int no_write_log;
|
||||
int segment_log;
|
||||
unsigned int max_line_size;
|
||||
int max_line_size;
|
||||
|
||||
tlog_output_func output_func;
|
||||
void *private_data;
|
||||
@@ -216,7 +217,6 @@ static int _tlog_mkdir(const char *path)
|
||||
}
|
||||
|
||||
if (mkdir(path_c, 0750) != 0) {
|
||||
fprintf(stderr, "create directory %s failed, %s\n", path_c, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1091,7 +1091,7 @@ static int _tlog_archive_log(struct tlog_log *log)
|
||||
}
|
||||
}
|
||||
|
||||
void _tlog_get_log_name_dir(struct tlog_log *log)
|
||||
static void _tlog_get_log_name_dir(struct tlog_log *log)
|
||||
{
|
||||
char log_file[PATH_MAX];
|
||||
if (log->fd > 0) {
|
||||
@@ -1130,6 +1130,10 @@ static int _tlog_write(struct tlog_log *log, const char *buff, int bufflen)
|
||||
unused = write(STDOUT_FILENO, buff, bufflen);
|
||||
}
|
||||
|
||||
if (log->no_write_log) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if log file size exceeds threshold, start to compress */
|
||||
if (log->multi_log && log->fd > 0) {
|
||||
log->filesize = lseek(log->fd, 0, SEEK_END);
|
||||
@@ -1160,7 +1164,15 @@ static int _tlog_write(struct tlog_log *log, const char *buff, int bufflen)
|
||||
|
||||
char logfile[PATH_MAX * 2];
|
||||
if (_tlog_mkdir(log->logdir) != 0) {
|
||||
fprintf(stderr, "create log dir %s failed.\n", log->logdir);
|
||||
if (print_errmsg == 0) {
|
||||
return -1;
|
||||
}
|
||||
print_errmsg = 0;
|
||||
fprintf(stderr, "create log dir %s failed, %s\n", log->logdir, strerror(errno));
|
||||
if (errno == EACCES && log->logscreen == 0) {
|
||||
fprintf(stderr, "no permission to write log file, output log to console\n");
|
||||
tlog_logscreen_only(log, 1);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
snprintf(logfile, sizeof(logfile), "%s/%s", log->logdir, log->logname);
|
||||
@@ -1574,11 +1586,26 @@ static void _tlog_log_setlogscreen(struct tlog_log *log, int enable)
|
||||
log->logscreen = (enable != 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
static void _tlog_log_setlogscreen_only(struct tlog_log *log, int enable)
|
||||
{
|
||||
if (log == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
log->logscreen = (enable != 0) ? 1 : 0;
|
||||
log->no_write_log = (enable != 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
void tlog_setlogscreen(int enable)
|
||||
{
|
||||
_tlog_log_setlogscreen(tlog.root, enable);
|
||||
}
|
||||
|
||||
void tlog_setlogscreen_only(int enable)
|
||||
{
|
||||
_tlog_log_setlogscreen_only(tlog.root, enable);
|
||||
}
|
||||
|
||||
int tlog_write_log(char *buff, int bufflen)
|
||||
{
|
||||
if (unlikely(tlog.root == NULL)) {
|
||||
@@ -1597,6 +1624,15 @@ void tlog_logscreen(tlog_log *log, int enable)
|
||||
_tlog_log_setlogscreen(log, enable);
|
||||
}
|
||||
|
||||
void tlog_logscreen_only(tlog_log *log, int enable)
|
||||
{
|
||||
if (log == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
_tlog_log_setlogscreen_only(log, enable);
|
||||
}
|
||||
|
||||
int tlog_reg_output_func(tlog_log *log, tlog_output_func output)
|
||||
{
|
||||
if (log == NULL) {
|
||||
@@ -1830,27 +1866,29 @@ int tlog_init(const char *logfile, int maxlogsize, int maxlogcount, int buffsize
|
||||
}
|
||||
tlog_reg_output_func(log, _tlog_root_write_log);
|
||||
|
||||
tlog.root = log;
|
||||
ret = pthread_create(&tlog.tid, &attr, _tlog_work, NULL);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "create tlog work thread failed, %s\n", strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
tlog.root = log;
|
||||
if (flag & TLOG_SUPPORT_FORK) {
|
||||
pthread_atfork(&tlog_fork_prepare, &tlog_fork_parent, &tlog_fork_child);
|
||||
}
|
||||
return 0;
|
||||
errout:
|
||||
if (tlog.tid > 0) {
|
||||
if (tlog.tid) {
|
||||
void *retval = NULL;
|
||||
tlog.run = 0;
|
||||
pthread_join(tlog.tid, &retval);
|
||||
tlog.tid = 0;
|
||||
}
|
||||
|
||||
pthread_cond_destroy(&tlog.cond);
|
||||
pthread_mutex_destroy(&tlog.lock);
|
||||
tlog.run = 0;
|
||||
tlog.root = NULL;
|
||||
|
||||
_tlog_close(log, 1);
|
||||
|
||||
@@ -1859,7 +1897,7 @@ errout:
|
||||
|
||||
void tlog_exit(void)
|
||||
{
|
||||
if (tlog.tid > 0) {
|
||||
if (tlog.tid) {
|
||||
void *ret = NULL;
|
||||
tlog.run = 0;
|
||||
pthread_mutex_lock(&tlog.lock);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define TLOG_H
|
||||
#include <stdarg.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <functional>
|
||||
@@ -103,6 +104,9 @@ extern void tlog_set_logfile(const char *logfile);
|
||||
/* enalbe log to screen */
|
||||
extern void tlog_setlogscreen(int enable);
|
||||
|
||||
/* output log to screen only */
|
||||
extern void tlog_setlogscreen_only(int enable);
|
||||
|
||||
/* enalbe early log to screen */
|
||||
extern void tlog_set_early_printf(int enable);
|
||||
|
||||
@@ -183,6 +187,9 @@ extern int tlog_vprintf(tlog_log *log, const char *format, va_list ap);
|
||||
/* enalbe log to screen */
|
||||
extern void tlog_logscreen(tlog_log *log, int enable);
|
||||
|
||||
/* enalbe log to screen only*/
|
||||
extern void tlog_logscreen_only(tlog_log *log, int enable);
|
||||
|
||||
/* register output callback */
|
||||
typedef int (*tlog_output_func)(struct tlog_log *log, const char *buff, int bufflen);
|
||||
extern int tlog_reg_output_func(tlog_log *log, tlog_output_func output);
|
||||
|
||||
418
src/util.c
418
src/util.c
@@ -34,11 +34,13 @@
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
@@ -77,7 +79,9 @@
|
||||
|
||||
#define NETLINK_ALIGN(len) (((len) + 3) & ~(3))
|
||||
|
||||
#define BUFF_SZ 256
|
||||
#define BUFF_SZ 1024
|
||||
#define PACKET_BUF_SIZE 8192
|
||||
#define PACKET_MAGIC 0X11040918
|
||||
|
||||
struct ipset_netlink_attr {
|
||||
unsigned short len;
|
||||
@@ -108,12 +112,12 @@ char *gethost_by_addr(char *host, int maxsize, struct sockaddr *addr)
|
||||
host[0] = 0;
|
||||
switch (addr_store->ss_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *addr_in;
|
||||
struct sockaddr_in *addr_in = NULL;
|
||||
addr_in = (struct sockaddr_in *)addr;
|
||||
inet_ntop(AF_INET, &addr_in->sin_addr, host, maxsize);
|
||||
} break;
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *addr_in6;
|
||||
struct sockaddr_in6 *addr_in6 = NULL;
|
||||
addr_in6 = (struct sockaddr_in6 *)addr;
|
||||
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
|
||||
struct sockaddr_in addr_in4;
|
||||
@@ -176,14 +180,14 @@ int getsocknet_inet(int fd, struct sockaddr *addr, socklen_t *addr_len)
|
||||
|
||||
switch (addr_store.ss_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *addr_in;
|
||||
struct sockaddr_in *addr_in = NULL;
|
||||
addr_in = (struct sockaddr_in *)addr;
|
||||
addr_in->sin_family = AF_INET;
|
||||
*addr_len = sizeof(struct sockaddr_in);
|
||||
memcpy(addr, addr_in, sizeof(struct sockaddr_in));
|
||||
} break;
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *addr_in6;
|
||||
struct sockaddr_in6 *addr_in6 = NULL;
|
||||
addr_in6 = (struct sockaddr_in6 *)addr;
|
||||
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
|
||||
struct sockaddr_in addr_in4;
|
||||
@@ -411,7 +415,7 @@ int parse_uri(char *value, char *scheme, char *host, int *port, char *path)
|
||||
};
|
||||
|
||||
field_len = host_end - process_ptr;
|
||||
if (field_len >= sizeof(host_name)) {
|
||||
if (field_len >= (int)sizeof(host_name)) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(host_name, process_ptr, field_len);
|
||||
@@ -431,7 +435,7 @@ int parse_uri(char *value, char *scheme, char *host, int *port, char *path)
|
||||
|
||||
int set_fd_nonblock(int fd, int nonblock)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
int flags = fcntl(fd, F_GETFL);
|
||||
|
||||
if (flags == -1) {
|
||||
@@ -523,7 +527,7 @@ static int _ipset_socket_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _ipset_support_timeout(const char *ipsetname)
|
||||
static int _ipset_support_timeout(void)
|
||||
{
|
||||
if (dns_conf_ipset_timeout_enable) {
|
||||
return 0;
|
||||
@@ -535,15 +539,15 @@ static int _ipset_support_timeout(const char *ipsetname)
|
||||
static int _ipset_operate(const char *ipsetname, const unsigned char addr[], int addr_len, unsigned long timeout,
|
||||
int operate)
|
||||
{
|
||||
struct nlmsghdr *netlink_head;
|
||||
struct ipset_netlink_msg *netlink_msg;
|
||||
struct nlmsghdr *netlink_head = NULL;
|
||||
struct ipset_netlink_msg *netlink_msg = NULL;
|
||||
struct ipset_netlink_attr *nested[3];
|
||||
char buffer[BUFF_SZ];
|
||||
uint8_t proto;
|
||||
ssize_t rc;
|
||||
uint8_t proto = 0;
|
||||
ssize_t rc = 0;
|
||||
int af = 0;
|
||||
static const struct sockaddr_nl snl = {.nl_family = AF_NETLINK};
|
||||
uint32_t expire;
|
||||
uint32_t expire = 0;
|
||||
|
||||
if (addr_len != IPV4_ADDR_LEN && addr_len != IPV6_ADDR_LEN) {
|
||||
errno = EINVAL;
|
||||
@@ -597,7 +601,7 @@ static int _ipset_operate(const char *ipsetname, const unsigned char addr[], int
|
||||
addr);
|
||||
nested[1]->len = (void *)buffer + NETLINK_ALIGN(netlink_head->nlmsg_len) - (void *)nested[1];
|
||||
|
||||
if (timeout > 0 && _ipset_support_timeout(ipsetname) == 0) {
|
||||
if (timeout > 0 && _ipset_support_timeout() == 0) {
|
||||
expire = htonl(timeout);
|
||||
_ipset_add_attr(netlink_head, IPSET_ATTR_TIMEOUT | NLA_F_NET_BYTEORDER, sizeof(expire), &expire);
|
||||
}
|
||||
@@ -636,10 +640,11 @@ unsigned char *SSL_SHA256(const unsigned char *d, size_t n, unsigned char *md)
|
||||
{
|
||||
static unsigned char m[SHA256_DIGEST_LENGTH];
|
||||
|
||||
if (md == NULL)
|
||||
if (md == NULL) {
|
||||
md = m;
|
||||
}
|
||||
|
||||
EVP_MD_CTX* ctx = EVP_MD_CTX_create();
|
||||
EVP_MD_CTX *ctx = EVP_MD_CTX_create();
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -656,7 +661,7 @@ unsigned char *SSL_SHA256(const unsigned char *d, size_t n, unsigned char *md)
|
||||
int SSL_base64_decode(const char *in, unsigned char *out)
|
||||
{
|
||||
size_t inlen = strlen(in);
|
||||
int outlen;
|
||||
int outlen = 0;
|
||||
|
||||
if (inlen == 0) {
|
||||
return 0;
|
||||
@@ -679,8 +684,8 @@ errout:
|
||||
|
||||
int create_pid_file(const char *pid_file)
|
||||
{
|
||||
int fd;
|
||||
int flags;
|
||||
int fd = 0;
|
||||
int flags = 0;
|
||||
char buff[TMP_BUFF_LEN_32];
|
||||
|
||||
/* create pid file, and lock this file */
|
||||
@@ -745,7 +750,7 @@ static __attribute__((unused)) void _pthreads_locking_callback(int mode, int typ
|
||||
|
||||
static __attribute__((unused)) unsigned long _pthreads_thread_id(void)
|
||||
{
|
||||
unsigned long ret;
|
||||
unsigned long ret = 0;
|
||||
|
||||
ret = (unsigned long)pthread_self();
|
||||
return (ret);
|
||||
@@ -753,16 +758,18 @@ static __attribute__((unused)) unsigned long _pthreads_thread_id(void)
|
||||
|
||||
void SSL_CRYPTO_thread_setup(void)
|
||||
{
|
||||
int i;
|
||||
int i = 0;
|
||||
|
||||
lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
|
||||
lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
|
||||
if (!lock_cs || !lock_count) {
|
||||
/* Nothing we can do about this...void function! */
|
||||
if (lock_cs)
|
||||
if (lock_cs) {
|
||||
OPENSSL_free(lock_cs);
|
||||
if (lock_count)
|
||||
}
|
||||
if (lock_count) {
|
||||
OPENSSL_free(lock_count);
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < CRYPTO_num_locks(); i++) {
|
||||
@@ -780,7 +787,7 @@ void SSL_CRYPTO_thread_setup(void)
|
||||
|
||||
void SSL_CRYPTO_thread_cleanup(void)
|
||||
{
|
||||
int i;
|
||||
int i = 0;
|
||||
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
for (i = 0; i < CRYPTO_num_locks(); i++) {
|
||||
@@ -817,18 +824,20 @@ static int parse_server_name_extension(const char *, size_t, char *, const char
|
||||
*/
|
||||
int parse_tls_header(const char *data, size_t data_len, char *hostname, const char **hostname_ptr)
|
||||
{
|
||||
char tls_content_type;
|
||||
char tls_version_major;
|
||||
char tls_version_minor;
|
||||
char tls_content_type = 0;
|
||||
char tls_version_major = 0;
|
||||
char tls_version_minor = 0;
|
||||
size_t pos = TLS_HEADER_LEN;
|
||||
size_t len;
|
||||
size_t len = 0;
|
||||
|
||||
if (hostname == NULL)
|
||||
if (hostname == NULL) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
/* Check that our TCP payload is at least large enough for a TLS header */
|
||||
if (data_len < TLS_HEADER_LEN)
|
||||
if (data_len < TLS_HEADER_LEN) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* SSL 2.0 compatible Client Hello
|
||||
*
|
||||
@@ -856,8 +865,9 @@ int parse_tls_header(const char *data, size_t data_len, char *hostname, const ch
|
||||
data_len = MIN(data_len, len);
|
||||
|
||||
/* Check we received entire TLS record length */
|
||||
if (data_len < len)
|
||||
if (data_len < len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handshake
|
||||
@@ -879,20 +889,23 @@ int parse_tls_header(const char *data, size_t data_len, char *hostname, const ch
|
||||
pos += 38;
|
||||
|
||||
/* Session ID */
|
||||
if (pos + 1 > data_len)
|
||||
if (pos + 1 > data_len) {
|
||||
return -5;
|
||||
}
|
||||
len = (unsigned char)data[pos];
|
||||
pos += 1 + len;
|
||||
|
||||
/* Cipher Suites */
|
||||
if (pos + 2 > data_len)
|
||||
if (pos + 2 > data_len) {
|
||||
return -5;
|
||||
}
|
||||
len = ((unsigned char)data[pos] << 8) + (unsigned char)data[pos + 1];
|
||||
pos += 2 + len;
|
||||
|
||||
/* Compression Methods */
|
||||
if (pos + 1 > data_len)
|
||||
if (pos + 1 > data_len) {
|
||||
return -5;
|
||||
}
|
||||
len = (unsigned char)data[pos];
|
||||
pos += 1 + len;
|
||||
|
||||
@@ -901,20 +914,22 @@ int parse_tls_header(const char *data, size_t data_len, char *hostname, const ch
|
||||
}
|
||||
|
||||
/* Extensions */
|
||||
if (pos + 2 > data_len)
|
||||
if (pos + 2 > data_len) {
|
||||
return -5;
|
||||
}
|
||||
len = ((unsigned char)data[pos] << 8) + (unsigned char)data[pos + 1];
|
||||
pos += 2;
|
||||
|
||||
if (pos + len > data_len)
|
||||
if (pos + len > data_len) {
|
||||
return -5;
|
||||
}
|
||||
return parse_extensions(data + pos, len, hostname, hostname_ptr);
|
||||
}
|
||||
|
||||
static int parse_extensions(const char *data, size_t data_len, char *hostname, const char **hostname_ptr)
|
||||
{
|
||||
size_t pos = 0;
|
||||
size_t len;
|
||||
size_t len = 0;
|
||||
|
||||
/* Parse each 4 bytes for the extension header */
|
||||
while (pos + 4 <= data_len) {
|
||||
@@ -925,15 +940,17 @@ static int parse_extensions(const char *data, size_t data_len, char *hostname, c
|
||||
if (data[pos] == 0x00 && data[pos + 1] == 0x00) {
|
||||
/* There can be only one extension of each type, so we break
|
||||
* our state and move p to beinnging of the extension here */
|
||||
if (pos + 4 + len > data_len)
|
||||
if (pos + 4 + len > data_len) {
|
||||
return -5;
|
||||
}
|
||||
return parse_server_name_extension(data + pos + 4, len, hostname, hostname_ptr);
|
||||
}
|
||||
pos += 4 + len; /* Advance to the next extension header */
|
||||
}
|
||||
/* Check we ended where we expected to */
|
||||
if (pos != data_len)
|
||||
if (pos != data_len) {
|
||||
return -5;
|
||||
}
|
||||
|
||||
return -2;
|
||||
}
|
||||
@@ -941,13 +958,14 @@ static int parse_extensions(const char *data, size_t data_len, char *hostname, c
|
||||
static int parse_server_name_extension(const char *data, size_t data_len, char *hostname, const char **hostname_ptr)
|
||||
{
|
||||
size_t pos = 2; /* skip server name list length */
|
||||
size_t len;
|
||||
size_t len = 0;
|
||||
|
||||
while (pos + 3 < data_len) {
|
||||
len = ((unsigned char)data[pos + 1] << 8) + (unsigned char)data[pos + 2];
|
||||
|
||||
if (pos + 3 + len > data_len)
|
||||
if (pos + 3 + len > data_len) {
|
||||
return -5;
|
||||
}
|
||||
|
||||
switch (data[pos]) { /* name type */
|
||||
case 0x00: /* host_name */
|
||||
@@ -964,8 +982,9 @@ static int parse_server_name_extension(const char *data, size_t data_len, char *
|
||||
pos += 3 + len;
|
||||
}
|
||||
/* Check we ended where we expected to */
|
||||
if (pos != data_len)
|
||||
if (pos != data_len) {
|
||||
return -5;
|
||||
}
|
||||
|
||||
return -2;
|
||||
}
|
||||
@@ -973,8 +992,12 @@ static int parse_server_name_extension(const char *data, size_t data_len, char *
|
||||
void get_compiled_time(struct tm *tm)
|
||||
{
|
||||
char s_month[5];
|
||||
int month, day, year;
|
||||
int hour, min, sec;
|
||||
int month = 0;
|
||||
int day = 0;
|
||||
int year = 0;
|
||||
int hour = 0;
|
||||
int min = 0;
|
||||
int sec = 0;
|
||||
static const char *month_names = "JanFebMarAprMayJunJulAugSepOctNovDec";
|
||||
|
||||
sscanf(__DATE__, "%4s %d %d", s_month, &day, &year);
|
||||
@@ -992,8 +1015,9 @@ void get_compiled_time(struct tm *tm)
|
||||
int is_numeric(const char *str)
|
||||
{
|
||||
while (*str != '\0') {
|
||||
if (*str < '0' || *str > '9')
|
||||
if (*str < '0' || *str > '9') {
|
||||
return -1;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
return 0;
|
||||
@@ -1082,9 +1106,9 @@ static _Unwind_Reason_Code unwind_callback(struct _Unwind_Context *context, void
|
||||
if (pc) {
|
||||
if (state->current == state->end) {
|
||||
return _URC_END_OF_STACK;
|
||||
} else {
|
||||
*state->current++ = (void *)(pc);
|
||||
}
|
||||
|
||||
*state->current++ = (void *)(pc);
|
||||
}
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
@@ -1101,7 +1125,7 @@ void print_stack(void)
|
||||
if (frame_num == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
tlog(TLOG_FATAL, "Stack:");
|
||||
for (idx = 0; idx < frame_num; ++idx) {
|
||||
const void *addr = buffer[idx];
|
||||
@@ -1114,13 +1138,31 @@ void print_stack(void)
|
||||
}
|
||||
|
||||
void *offset = (void *)((char *)(addr) - (char *)(info.dli_fbase));
|
||||
tlog(TLOG_FATAL, "#%.2d: %p %s from %s+%p", idx + 1, addr, symbol, info.dli_fname, offset);
|
||||
tlog(TLOG_FATAL, "#%.2d: %p %s() from %s+%p", idx + 1, addr, symbol, info.dli_fname, offset);
|
||||
}
|
||||
}
|
||||
|
||||
void bug_ext(const char *file, int line, const char *func, const char *errfmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, errfmt);
|
||||
tlog_vext(TLOG_FATAL, file, line, func, NULL, errfmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
print_stack();
|
||||
/* trigger BUG */
|
||||
sleep(1);
|
||||
raise(SIGSEGV);
|
||||
|
||||
while (true) {
|
||||
sleep(1);
|
||||
};
|
||||
}
|
||||
|
||||
int write_file(const char *filename, void *data, int data_len)
|
||||
{
|
||||
int fd = open(filename, O_WRONLY|O_CREAT, 0644);
|
||||
int fd = open(filename, O_WRONLY | O_CREAT, 0644);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1138,4 +1180,278 @@ errout:
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int dns_packet_save(const char *dir, const char *type, const char *from, const void *packet, int packet_len)
|
||||
{
|
||||
char *data = NULL;
|
||||
int data_len = 0;
|
||||
char filename[BUFF_SZ];
|
||||
char time_s[BUFF_SZ];
|
||||
int ret = -1;
|
||||
|
||||
struct tm *ptm;
|
||||
struct tm tm;
|
||||
struct timeval tmval;
|
||||
struct stat sb;
|
||||
|
||||
if (stat(dir, &sb) != 0) {
|
||||
mkdir(dir, 0750);
|
||||
}
|
||||
|
||||
if (gettimeofday(&tmval, NULL) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptm = localtime_r(&tmval.tv_sec, &tm);
|
||||
if (ptm == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = snprintf(time_s, sizeof(time_s) - 1, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d.%.3d", ptm->tm_year + 1900,
|
||||
ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, (int)(tmval.tv_usec / 1000));
|
||||
ret = snprintf(filename, sizeof(filename) - 1, "%s/%s-%.4d%.2d%.2d-%.2d%.2d%.2d%.1d.packet", dir, type,
|
||||
ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec,
|
||||
(int)(tmval.tv_usec / 100000));
|
||||
|
||||
data = malloc(PACKET_BUF_SIZE);
|
||||
if (data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data_len = snprintf(data, PACKET_BUF_SIZE,
|
||||
"type: %s\n"
|
||||
"from: %s\n"
|
||||
"time: %s\n"
|
||||
"packet-len: %d\n",
|
||||
type, from, time_s, packet_len);
|
||||
if (data_len <= 0 || data_len >= PACKET_BUF_SIZE) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
data[data_len] = 0;
|
||||
data_len++;
|
||||
uint32_t magic = htonl(PACKET_MAGIC);
|
||||
memcpy(data + data_len, &magic, sizeof(magic));
|
||||
data_len += sizeof(magic);
|
||||
int len_in_h = htonl(packet_len);
|
||||
memcpy(data + data_len, &len_in_h, sizeof(len_in_h));
|
||||
data_len += 4;
|
||||
memcpy(data + data_len, packet, packet_len);
|
||||
data_len += packet_len;
|
||||
|
||||
ret = write_file(filename, data, data_len);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
if (data) {
|
||||
free(data);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
struct _dns_read_packet_info {
|
||||
int data_len;
|
||||
int message_len;
|
||||
char *message;
|
||||
int packet_len;
|
||||
uint8_t *packet;
|
||||
uint8_t data[0];
|
||||
};
|
||||
|
||||
static struct _dns_read_packet_info *_dns_read_packet_file(const char *packet_file)
|
||||
{
|
||||
struct _dns_read_packet_info *info = NULL;
|
||||
int fd = 0;
|
||||
int len = 0;
|
||||
int message_len = 0;
|
||||
uint8_t *ptr = NULL;
|
||||
|
||||
info = malloc(sizeof(struct _dns_read_packet_info) + PACKET_BUF_SIZE);
|
||||
fd = open(packet_file, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
printf("open file %s failed, %s\n", packet_file, strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
len = read(fd, info->data, PACKET_BUF_SIZE);
|
||||
if (len < 0) {
|
||||
printf("read file %s failed, %s\n", packet_file, strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
message_len = strnlen((char *)info->data, PACKET_BUF_SIZE);
|
||||
if (message_len >= 512 || message_len >= len) {
|
||||
printf("invalid packet file, bad message len\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
info->message_len = message_len;
|
||||
info->message = (char *)info->data;
|
||||
|
||||
ptr = info->data + message_len + 1;
|
||||
uint32_t magic = 0;
|
||||
if (ptr - (uint8_t *)info + sizeof(magic) >= (size_t)len) {
|
||||
printf("invalid packet file, magic length is invalid.\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
memcpy(&magic, ptr, sizeof(magic));
|
||||
if (magic != htonl(PACKET_MAGIC)) {
|
||||
printf("invalid packet file, bad magic\n");
|
||||
goto errout;
|
||||
}
|
||||
ptr += sizeof(magic);
|
||||
|
||||
uint32_t packet_len = 0;
|
||||
if (ptr - info->data + sizeof(packet_len) >= (size_t)len) {
|
||||
printf("invalid packet file, packet length is invalid.\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
memcpy(&packet_len, ptr, sizeof(packet_len));
|
||||
packet_len = ntohl(packet_len);
|
||||
ptr += sizeof(packet_len);
|
||||
if (packet_len != (size_t)len - (ptr - info->data)) {
|
||||
printf("invalid packet file, packet length is invalid\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
info->packet_len = packet_len;
|
||||
info->packet = ptr;
|
||||
|
||||
close(fd);
|
||||
return info;
|
||||
errout:
|
||||
|
||||
if (fd > 0) {
|
||||
close(fd);
|
||||
}
|
||||
|
||||
if (info) {
|
||||
free(info);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _dns_debug_display(struct dns_packet *packet)
|
||||
{
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int ttl = 0;
|
||||
struct dns_rrs *rrs = NULL;
|
||||
int rr_count = 0;
|
||||
char req_host[MAX_IP_LEN];
|
||||
|
||||
for (j = 1; j < DNS_RRS_END; j++) {
|
||||
rrs = dns_get_rrs_start(packet, j, &rr_count);
|
||||
printf("section: %d\n", j);
|
||||
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];
|
||||
char name[DNS_MAX_CNAME_LEN] = {0};
|
||||
/* get A result */
|
||||
dns_get_A(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr);
|
||||
req_host[0] = '\0';
|
||||
inet_ntop(AF_INET, addr, req_host, sizeof(req_host));
|
||||
printf("domain: %s A: %s TTL: %d\n", name, req_host, ttl);
|
||||
} break;
|
||||
case DNS_T_AAAA: {
|
||||
unsigned char addr[16];
|
||||
char name[DNS_MAX_CNAME_LEN] = {0};
|
||||
dns_get_AAAA(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr);
|
||||
req_host[0] = '\0';
|
||||
inet_ntop(AF_INET6, addr, req_host, sizeof(req_host));
|
||||
printf("domain: %s AAAA: %s TTL:%d\n", name, req_host, ttl);
|
||||
} break;
|
||||
case DNS_T_NS: {
|
||||
char cname[DNS_MAX_CNAME_LEN];
|
||||
char name[DNS_MAX_CNAME_LEN] = {0};
|
||||
dns_get_CNAME(rrs, name, DNS_MAX_CNAME_LEN, &ttl, cname, DNS_MAX_CNAME_LEN);
|
||||
printf("domain: %s TTL: %d NS: %s\n", name, ttl, cname);
|
||||
} break;
|
||||
case DNS_T_CNAME: {
|
||||
char cname[DNS_MAX_CNAME_LEN];
|
||||
char name[DNS_MAX_CNAME_LEN] = {0};
|
||||
if (dns_conf_force_no_cname) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dns_get_CNAME(rrs, name, DNS_MAX_CNAME_LEN, &ttl, cname, DNS_MAX_CNAME_LEN);
|
||||
printf("domain: %s TTL: %d CNAME: %s\n", name, ttl, cname);
|
||||
} break;
|
||||
case DNS_T_SOA: {
|
||||
char name[DNS_MAX_CNAME_LEN] = {0};
|
||||
struct dns_soa soa;
|
||||
dns_get_SOA(rrs, name, 128, &ttl, &soa);
|
||||
printf("domain: %s SOA: mname: %s, rname: %s, serial: %d, refresh: %d, retry: %d, expire: "
|
||||
"%d, minimum: %d",
|
||||
name, soa.mname, soa.rname, soa.serial, soa.refresh, soa.retry, soa.expire, soa.minimum);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_packet_debug(const char *packet_file)
|
||||
{
|
||||
struct _dns_read_packet_info *info = NULL;
|
||||
char buff[DNS_PACKSIZE];
|
||||
|
||||
tlog_setlogscreen_only(1);
|
||||
tlog_setlevel(TLOG_DEBUG);
|
||||
|
||||
info = _dns_read_packet_file(packet_file);
|
||||
if (info == NULL) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
const char *send_env = getenv("SMARTDNS_DEBUG_SEND");
|
||||
if (send_env != NULL) {
|
||||
char ip[32];
|
||||
int port = 53;
|
||||
if (parse_ip(send_env, ip, &port) == 0) {
|
||||
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sockfd > 0) {
|
||||
struct sockaddr_in server;
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(port);
|
||||
server.sin_addr.s_addr = inet_addr(ip);
|
||||
sendto(sockfd, info->packet, info->packet_len, 0, (struct sockaddr *)&server, sizeof(server));
|
||||
close(sockfd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct dns_packet *packet = (struct dns_packet *)buff;
|
||||
if (dns_decode(packet, DNS_PACKSIZE, info->packet, info->packet_len) != 0) {
|
||||
printf("decode failed.\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
_dns_debug_display(packet);
|
||||
|
||||
free(info);
|
||||
return 0;
|
||||
|
||||
errout:
|
||||
if (info) {
|
||||
free(info);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
14
src/util.h
14
src/util.h
@@ -45,6 +45,16 @@ extern "C" {
|
||||
#define PORT_NOT_DEFINED -1
|
||||
#define MAX_IP_LEN 64
|
||||
|
||||
#ifndef BASE_FILE_NAME
|
||||
#define BASE_FILE_NAME \
|
||||
(__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 \
|
||||
: __FILE__)
|
||||
#endif
|
||||
#define BUG(format, ...) bug_ext(BASE_FILE_NAME, __LINE__, __func__, format, ##__VA_ARGS__)
|
||||
|
||||
void bug_ext(const char *file, int line, const char *func, const char *errfmt, ...)
|
||||
__attribute__((format(printf, 4, 5))) __attribute__((nonnull(4)));
|
||||
|
||||
unsigned long get_tick_count(void);
|
||||
|
||||
char *gethost_by_addr(char *host, int maxsize, struct sockaddr *addr);
|
||||
@@ -116,6 +126,10 @@ void print_stack(void);
|
||||
|
||||
int write_file(const char *filename, void *data, int data_len);
|
||||
|
||||
int dns_packet_save(const char *dir, const char *type, const char *from, const void *packet, int packet_len);
|
||||
|
||||
int dns_packet_debug(const char *packet_file);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus */
|
||||
|
||||
Reference in New Issue
Block a user