Files
monibuca/pkg/config/udp.go
2025-09-26 15:57:26 +08:00

78 lines
1.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package config
import (
"crypto/tls"
"log/slog"
"net"
"time"
task "github.com/langhuihui/gotask"
)
type UDP struct {
ListenAddr string `desc:"监听地址格式为ip:portip 可省略默认监听所有网卡"`
CertFile string `desc:"证书文件"`
KeyFile string `desc:"私钥文件"`
AutoListen bool `default:"true" desc:"是否自动监听"`
}
func (config *UDP) CreateUDPWork(logger *slog.Logger, handler func(conn *net.UDPConn) task.ITask) *ListenUDPWork {
ret := &ListenUDPWork{UDP: config, handler: handler}
ret.Logger = logger.With("addr", config.ListenAddr)
return ret
}
type ListenUDPWork struct {
task.Work
*UDP
net.Listener
handler func(conn *net.UDPConn) task.ITask
}
func (task *ListenUDPWork) Dispose() {
task.Close()
}
func (task *ListenUDPWork) Start() (err error) {
task.Listener, err = net.Listen("udp", task.ListenAddr)
if err == nil {
task.Info("listen udp")
} else {
task.Error("failed to listen udp", "error", err)
}
return
}
func (task *ListenUDPWork) Go() error {
var tempDelay time.Duration
for {
conn, err := task.Accept()
if err != nil {
if ne, ok := err.(net.Error); ok && !ne.Timeout() {
if tempDelay == 0 {
tempDelay = 5 * time.Millisecond
} else {
tempDelay *= 2
}
if max := 1 * time.Second; tempDelay > max {
tempDelay = max
}
// slog.Warnf("%s: Accept error: %v; retrying in %v", tcp.DownListenAddr, err, tempDelay)
time.Sleep(tempDelay)
continue
}
return err
}
var udpConn *net.UDPConn
switch v := conn.(type) {
case *net.UDPConn:
udpConn = v
case *tls.Conn:
udpConn = v.NetConn().(*net.UDPConn)
}
tempDelay = 0
subTask := task.handler(udpConn)
task.AddTask(subTask)
}
}