Some checks failed
Test mosdns / build (push) Has been cancelled
1. 连接管理优化 mikrotik_addresslist_impl.go:132
- 添加连接状态管理和重连锁机制
- 改进重连逻辑,防止并发重连
2. 缓存机制增强 mikrotik_addresslist_impl.go:162-202
- 优化缓存锁使用,避免死锁
- 添加缓存大小限制和LRU驱逐策略
- 定期清理过期缓存项
3. 智能重试机制 mikrotik_addresslist_impl.go:420
- 指数退避算法
- 更智能的连接错误识别
- 改进的错误处理
4. 动态并发控制 mikrotik_addresslist_impl.go:589
- 根据地址数量动态调整工作池大小
- 批量处理优化
5. 性能监控改进
- 更详细的日志记录
- 缓存统计信息
- 处理过程可观察性
142 lines
3.9 KiB
Go
142 lines
3.9 KiB
Go
/*
|
||
* Copyright (C) 2020-2022, IrineSistiana
|
||
*
|
||
* This file is part of mosdns.
|
||
*
|
||
* mosdns is free software: you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation, either version 3 of the License, or
|
||
* (at your option) any later version.
|
||
*
|
||
* mosdns is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
package mikrotik_addresslist
|
||
|
||
import (
|
||
"fmt"
|
||
"strconv"
|
||
"strings"
|
||
|
||
"github.com/IrineSistiana/mosdns/v5/coremain"
|
||
"github.com/IrineSistiana/mosdns/v5/plugin/executable/sequence"
|
||
)
|
||
|
||
const PluginType = "mikrotik_addresslist"
|
||
|
||
func init() {
|
||
coremain.RegNewPluginFunc(PluginType, Init, func() any { return new(Args) })
|
||
sequence.MustRegExecQuickSetup(PluginType, QuickSetup)
|
||
}
|
||
|
||
type Args struct {
|
||
Host string `yaml:"host"` // MikroTik 路由器 IP 地址
|
||
Port int `yaml:"port"` // API 端口,默认 8728
|
||
Username string `yaml:"username"` // 用户名
|
||
Password string `yaml:"password"` // 密码
|
||
UseTLS bool `yaml:"use_tls"` // 是否使用 TLS,默认 false
|
||
Timeout int `yaml:"timeout"` // 连接超时时间(秒),默认 10
|
||
|
||
AddressList4 string `yaml:"address_list4"` // IPv4 address list 名称
|
||
AddressList6 string `yaml:"address_list6"` // IPv6 address list 名称
|
||
Mask4 int `yaml:"mask4"` // IPv4 掩码,默认 24
|
||
Mask6 int `yaml:"mask6"` // IPv6 掩码,默认 32
|
||
Comment string `yaml:"comment"` // 添加的地址的注释
|
||
TimeoutAddr int `yaml:"timeout_addr"` // 地址超时时间(秒),0 表示永久
|
||
CacheTTL int `yaml:"cache_ttl"` // 缓存 TTL(秒),默认 3600(1小时)
|
||
}
|
||
|
||
var _ sequence.Executable = (*mikrotikAddressListPlugin)(nil)
|
||
|
||
// Init initializes the plugin from coremain
|
||
func Init(bp *coremain.BP, args any) (any, error) {
|
||
return newMikrotikAddressListPlugin(args.(*Args))
|
||
}
|
||
|
||
// QuickSetup format: host:port:username:password:use_tls:timeout:address_list4:address_list6:mask4:mask6:comment:timeout_addr:cache_ttl
|
||
// e.g. "192.168.1.1:8728:admin:password:false:10:my_list4:my_list6:24:32:from_dns:3600:3600"
|
||
func QuickSetup(_ sequence.BQ, s string) (any, error) {
|
||
parts := strings.Split(s, ":")
|
||
if len(parts) < 6 {
|
||
return nil, fmt.Errorf("invalid args, expect at least 6 parts, got %d", len(parts))
|
||
}
|
||
|
||
args := &Args{
|
||
Host: parts[0],
|
||
Username: parts[2],
|
||
Password: parts[3],
|
||
UseTLS: false,
|
||
Timeout: 10,
|
||
Mask4: 24,
|
||
Mask6: 32,
|
||
}
|
||
|
||
// 解析端口
|
||
if port, err := strconv.Atoi(parts[1]); err == nil {
|
||
args.Port = port
|
||
} else {
|
||
args.Port = 8728
|
||
}
|
||
|
||
// 解析 TLS 设置
|
||
if len(parts) > 4 {
|
||
if useTLS, err := strconv.ParseBool(parts[4]); err == nil {
|
||
args.UseTLS = useTLS
|
||
}
|
||
}
|
||
|
||
// 解析超时时间
|
||
if len(parts) > 5 {
|
||
if timeout, err := strconv.Atoi(parts[5]); err == nil {
|
||
args.Timeout = timeout
|
||
}
|
||
}
|
||
|
||
// 解析 address list 名称
|
||
if len(parts) > 6 {
|
||
args.AddressList4 = parts[6]
|
||
}
|
||
if len(parts) > 7 {
|
||
args.AddressList6 = parts[7]
|
||
}
|
||
|
||
// 解析掩码
|
||
if len(parts) > 8 {
|
||
if mask4, err := strconv.Atoi(parts[8]); err == nil {
|
||
args.Mask4 = mask4
|
||
}
|
||
}
|
||
if len(parts) > 9 {
|
||
if mask6, err := strconv.Atoi(parts[9]); err == nil {
|
||
args.Mask6 = mask6
|
||
}
|
||
}
|
||
|
||
// 解析注释
|
||
if len(parts) > 10 {
|
||
args.Comment = parts[10]
|
||
}
|
||
|
||
// 解析地址超时时间
|
||
if len(parts) > 11 {
|
||
if timeoutAddr, err := strconv.Atoi(parts[11]); err == nil {
|
||
args.TimeoutAddr = timeoutAddr
|
||
}
|
||
}
|
||
|
||
// 解析缓存 TTL
|
||
if len(parts) > 12 {
|
||
if cacheTTL, err := strconv.Atoi(parts[12]); err == nil {
|
||
args.CacheTTL = cacheTTL
|
||
}
|
||
}
|
||
|
||
return newMikrotikAddressListPlugin(args)
|
||
}
|