//go:build !freebsd // +build !freebsd package utils import ( "context" "github.com/iwind/TeaGo/logs" "net" "sort" "syscall" ) // ListenReuseAddr 监听可重用的端口 func ListenReuseAddr(network string, addr string) (net.Listener, error) { config := &net.ListenConfig{ Control: func(network, address string, c syscall.RawConn) error { return c.Control(func(fd uintptr) { err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, SO_REUSEPORT, 1) if err != nil { logs.Println("[LISTEN]" + err.Error()) } }) }, KeepAlive: 0, } return config.Listen(context.Background(), network, addr) } // ParseAddrHost 分析地址中的主机名部分 func ParseAddrHost(addr string) string { if len(addr) == 0 { return addr } host, _, err := net.SplitHostPort(addr) if err != nil { return addr } return host } // MergePorts 聚合端口 // 返回 [ [fromPort, toPort], ... ] func MergePorts(ports []int) [][2]int { if len(ports) == 0 { return nil } sort.Ints(ports) var result = [][2]int{} var lastRange = [2]int{0, 0} var lastPort = -1 for _, port := range ports { if port <= 0 /** 只处理有效的端口 **/ || port == lastPort /** 去重 **/ { continue } if lastPort < 0 || port != lastPort+1 { lastRange = [2]int{port, port} result = append(result, lastRange) } else { // 如果是连续的 lastRange[1] = port result[len(result)-1] = lastRange } lastPort = port } return result }