#!/usr/bin/env bash
# ==============================================================================
# 脚本名称: check_dns_timeout.sh
# 功能描述: 自动化诊断本地 resolv.conf 中存在的 DNS 超时死节点及配置隐患 (纯只读)
# 使用方式: 在目标 Linux 宿主机直接执行
# ==============================================================================

set -o pipefail

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
PLAIN='\033[0m'

echo -e "${BLUE}================================================================${PLAIN}"
echo -e "${BLUE}            系统 DNS 解析链路 5秒隐形卡顿自动化诊断脚本          ${PLAIN}"
echo -e "${BLUE}================================================================${PLAIN}"

# 1. 提取当前系统配置的 Nameserver
DNS_SERVERS=$(grep -v "^[[:space:]]*#" /etc/resolv.conf 2>/dev/null | grep "^nameserver" | awk '{print $2}')

if [ -z "$DNS_SERVERS" ]; then
    echo -e "${RED}[FATAL] /etc/resolv.conf 中未配置任何有效的 nameserver。${PLAIN}"
    exit 1
fi

echo -e "\n${YELLOW}[1/2] 正在提取并逐一探测本地 DNS 节点的连通性与响应耗时...${PLAIN}"

BAD_DNS_FOUND=0
INDEX=1

for dns in $DNS_SERVERS; do
    echo -e "  -> [节点 $INDEX] 目标 DNS IP: ${YELLOW}${dns}${PLAIN}"
    
    # 记录探测起始时间
    START_TIME=$(date +%s)
    
    # 发起真实 DNS 解析请求，强制 1 秒超时
    if dig @"$dns" www.baidu.com +time=1 +tries=1 >/dev/null 2>&1; then
        END_TIME=$(date +%s)
        COST=$((END_TIME - START_TIME))
        echo -e "     连通状态: ${GREEN}OK (响应耗时 < 1s)${PLAIN}"
    else
        echo -e "     连通状态: ${RED}Timeout / Refused${PLAIN}"
        echo -e "     ${RED}[ALERT] 发现失效 DNS 节点！该节点将强制引发 Linux 底层每次解析 5 秒的 poll 阻塞卡顿。${PLAIN}"
        BAD_DNS_FOUND=1
    fi
    ((INDEX++))
done

# 2. 检查 resolv.conf 高级配置优化参数
echo -e "\n${YELLOW}[2/2] 检查 DNS 底层超时优化参数 (options)...${PLAIN}"
OPTIONS_LINE=$(grep -v "^[[:space:]]*#" /etc/resolv.conf 2>/dev/null | grep "^options")

if echo "$OPTIONS_LINE" | grep -q "timeout:"; then
    TIMEOUT_VAL=$(echo "$OPTIONS_LINE" | grep -o 'timeout:[0-9]*' | cut -d':' -f2)
    if [ "$TIMEOUT_VAL" -le 2 ]; then
        echo -e "  -> ${GREEN}[OK] 已配置短超时优化 (timeout:${TIMEOUT_VAL})，有效降低单点失效带来的延迟惩罚。${PLAIN}"
    else
        echo -e "  -> ${YELLOW}[WARN] 存在 timeout 配置，但设定数值偏大 (${TIMEOUT_VAL}s)，仍会引发明显卡顿。${PLAIN}"
    fi
else
    echo -e "  -> ${RED}[WARN] 未配置 options timeout 参数！若遭遇首选节点失效，系统将强制等待默认的 5 秒超时。${PLAIN}"
    echo -e "  -> ${GREEN}[优化建议] 建议在 /etc/resolv.conf 尾部追加配置: options timeout:1 attempts:1${PLAIN}"
fi

# 3. 输出综合诊断结论
echo -e "\n${BLUE}----------------------------------------------------------------${PLAIN}"
if [ "$BAD_DNS_FOUND" -eq 1 ]; then
    echo -e "${RED}[最终诊断] 明确存在失效的 DNS 节点！这是引发业务接口恒定 5 秒隐形阻塞的直接根源。${PLAIN}"
    echo -e "${YELLOW}处置建议: 请立即编辑 /etc/resolv.conf，注释或移除失效的 nameserver 记录。${PLAIN}"
else
    echo -e "${GREEN}[最终诊断] 本地 DNS 解析链路健康，未发现引发 5 秒底层阻塞的基础设施隐患。${PLAIN}"
    echo -e "${GREEN}排障指引: 若接口依然存在卡顿，请使用 strace -f -p <PID> -T 检查是否阻塞在应用层的网络 I/O (如 recvfrom 等待下游返回)。${PLAIN}"
fi
echo -e "${BLUE}================================================================${PLAIN}"
