package transport import ( "errors" "net" "strings" "time" ) var ErrNamedPipeUnsupported = errors.New("named pipe transport is only supported on windows") func IsUDPNetwork(network string) bool { return strings.Contains(strings.ToLower(strings.TrimSpace(network)), "udp") } func IsNamedPipeNetwork(network string) bool { switch strings.ToLower(strings.TrimSpace(network)) { case "npipe", "pipe", "namedpipe", "named-pipe": return true default: return false } } func Dial(network string, addr string) (net.Conn, error) { if IsNamedPipeNetwork(network) { return dialNamedPipe(addr, nil) } return net.Dial(network, addr) } func DialTimeout(network string, addr string, timeout time.Duration) (net.Conn, error) { if IsNamedPipeNetwork(network) { return dialNamedPipe(addr, &timeout) } return net.DialTimeout(network, addr, timeout) } func Listen(network string, addr string) (net.Listener, error) { if IsNamedPipeNetwork(network) { return listenNamedPipe(addr) } return net.Listen(network, addr) } func NormalizeNamedPipeAddr(addr string) string { trimmed := strings.TrimSpace(addr) if trimmed == "" { return trimmed } if strings.HasPrefix(trimmed, `\\.\pipe\`) { return trimmed } if strings.HasPrefix(trimmed, `//./pipe/`) { return `\\.\pipe\` + strings.TrimPrefix(trimmed, `//./pipe/`) } trimmed = strings.TrimPrefix(trimmed, `\\`) trimmed = strings.TrimPrefix(trimmed, `//`) trimmed = strings.TrimPrefix(trimmed, `.\pipe\`) trimmed = strings.TrimPrefix(trimmed, `./pipe/`) trimmed = strings.TrimPrefix(trimmed, `pipe\`) trimmed = strings.TrimPrefix(trimmed, `pipe/`) trimmed = strings.TrimLeft(strings.ReplaceAll(trimmed, "/", `\`), `\`) return `\\.\pipe\` + trimmed } func ConnRemoteAddrString(conn net.Conn) string { if conn == nil { return "unknown" } addr := conn.RemoteAddr() if addr == nil { return "unknown" } if value := addr.String(); value != "" { return value } return "unknown" }