4to6/config.go
2025-02-07 10:32:47 +08:00

140 lines
3.5 KiB
Go

package main
import (
"bufio"
"fmt"
"net"
"os"
"strconv"
"strings"
)
// Config 结构体存储配置信息
type Config struct {
Global struct {
LT map[string]string // 存储本地地址到目标地址的映射
LU map[string]string // 存储本地地址到目标地址的映射
}
}
// isValidHostname 验证主机名格式
func isValidHostname(hostname string) bool {
if len(hostname) > 255 || hostname == "" {
return false
}
for _, part := range strings.Split(hostname, ".") {
if len(part) == 0 || len(part) > 63 {
return false
}
for _, c := range part {
if !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-') {
return false
}
}
}
return true
}
// parseAddress 解析并验证地址字符串
func parseAddress(address string) (string, int, error) {
host, portStr, err := net.SplitHostPort(address)
if err != nil {
return "", 0, fmt.Errorf("地址格式错误: %s (格式应为 host:port)", address)
}
port, err := strconv.Atoi(portStr)
if err != nil || port < 1 || port > 65535 {
return "", 0, fmt.Errorf("无效的端口号: %s", address)
}
host = strings.Trim(host, "[]") // 去除 IPv6 方括号
if net.ParseIP(host) == nil && !isValidHostname(host) {
return "", 0, fmt.Errorf("无效的主机名或 IP: %s", address)
}
return host, port, nil
}
// parseConfig 解析配置文件
func parseConfig(filename string) (Config, error) {
var config Config
config.Global.LT = make(map[string]string)
config.Global.LU = make(map[string]string)
var currentSection string
file, err := os.Open(filename)
if err != nil {
return config, err
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if line == "" || strings.HasPrefix(line, "//") || strings.HasPrefix(line, "#") {
continue
}
if strings.HasSuffix(line, "{") {
currentSection = strings.Fields(line)[0]
continue
}
if line == "}" {
currentSection = ""
continue
}
parts := strings.SplitN(line, "=", 2)
if len(parts) != 2 {
continue
}
key := strings.TrimSpace(parts[0])
value := strings.TrimSpace(strings.TrimSuffix(parts[1], ";"))
if currentSection == "global" && key == "LT" {
lsParts := strings.SplitN(value, "->", 2)
if len(lsParts) == 2 {
localAddr := strings.TrimSpace(lsParts[0])
targetAddr := strings.TrimSpace(lsParts[1])
if _, _, err := parseAddress(localAddr); err != nil {
return config, fmt.Errorf("本地地址格式错误: %s", localAddr)
}
if _, _, err := parseAddress(targetAddr); err != nil {
return config, fmt.Errorf("目标地址格式错误: %s", targetAddr)
}
config.Global.LT[localAddr] = targetAddr
} else {
return config, fmt.Errorf("LT 配置格式错误: %s", value)
}
}
if currentSection == "global" && key == "LU" {
lsParts := strings.SplitN(value, "->", 2)
if len(lsParts) == 2 {
localAddr := strings.TrimSpace(lsParts[0])
targetAddr := strings.TrimSpace(lsParts[1])
if _, _, err := parseAddress(localAddr); err != nil {
return config, fmt.Errorf("本地地址格式错误: %s", localAddr)
}
if _, _, err := parseAddress(targetAddr); err != nil {
return config, fmt.Errorf("目标地址格式错误: %s", targetAddr)
}
config.Global.LU[localAddr] = targetAddr
} else {
return config, fmt.Errorf("LU 配置格式错误: %s", value)
}
}
}
if err := scanner.Err(); err != nil {
return config, err
}
return config, nil
}