diff --git a/intra/backend/core_iptree.go b/intra/backend/core_iptree.go index 31e94a9d..d290b37d 100644 --- a/intra/backend/core_iptree.go +++ b/intra/backend/core_iptree.go @@ -13,6 +13,7 @@ import ( "strings" "sync" + "github.com/celzero/firestack/intra/core" "github.com/celzero/firestack/intra/log" "github.com/k-sone/critbitgo" ) @@ -450,7 +451,7 @@ func ip2cidr(ippOrCidr string) (*net.IPNet, error) { ipaddr = ip } else { log.W("iptree: ip2cidr: cidr %v / ipp %v / ip %v", err, err1, err2) - return nil, errors.Join(err, err1, err2) + return nil, core.JoinErr(err, err1, err2) } ip := ipaddr.AsSlice() mask := net.CIDRMask(ipaddr.BitLen(), ipaddr.BitLen()) diff --git a/intra/backend/ipn_pipkeygen.go b/intra/backend/ipn_pipkeygen.go index ae5ae082..7bdbfc14 100644 --- a/intra/backend/ipn_pipkeygen.go +++ b/intra/backend/ipn_pipkeygen.go @@ -16,12 +16,12 @@ import ( "encoding/base64" "encoding/hex" "encoding/json" - "errors" "fmt" "io" "math/big" "strings" + "github.com/celzero/firestack/intra/core" brsa "github.com/celzero/firestack/intra/core/brsa" "github.com/celzero/firestack/intra/log" // "github.com/cloudflare/circl/blindsign/blindrsa" @@ -112,7 +112,7 @@ func NewPipKey(pubjwk string, msgOrExistingState string) (PipKey, error) { c, err1 := brsa.NewClient(brsa.SHA384PSSDeterministic, pub) v, err2 := brsa.NewVerifier(brsa.SHA384PSSDeterministic, pub) if err1 != nil || err2 != nil { - err := errors.Join(err1, err2) + err := core.JoinErr(err1, err2) log.E("pipkey: new: sha384-pss-det verifier err %v", err) return nil, err } diff --git a/intra/core/async.go b/intra/core/async.go index d71a3f0f..0025200b 100644 --- a/intra/core/async.go +++ b/intra/core/async.go @@ -134,12 +134,12 @@ outer: select { case r := <-ch: if r.err != nil { - errs = errors.Join(errs, r.err) + errs = JoinErr(errs, r.err) } else { return r.t, r.i, r.err } case <-time.After(timeout): - errs = errors.Join(errs, errTimeout) + errs = JoinErr(errs, errTimeout) break outer } } diff --git a/intra/core/closer.go b/intra/core/closer.go index 4f0d1c47..555349f3 100644 --- a/intra/core/closer.go +++ b/intra/core/closer.go @@ -7,11 +7,11 @@ package core import ( - "fmt" "io" "net" "os" "reflect" + "strings" "syscall" "gvisor.dev/gvisor/pkg/tcpip/adapters/gonet" @@ -230,13 +230,21 @@ func OneErr(errs ...error) error { } func JoinErr(errs ...error) error { - if len(errs) <= 0 { + var all []error + for _, err := range errs { + if err == nil { + continue + } + all = append(all, err) + } + if len(all) <= 0 { return nil } - if len(errs) == 1 { - return errs[0] + if len(all) == 1 { + return all[0] } - return fmt.Errorf("%v", errs) + + return &errMult{errs: all} } func JoinErrIf(y bool, errs ...error) error { @@ -245,3 +253,26 @@ func JoinErrIf(y bool, errs ...error) error { } return nil } + +type errMult struct { + errs []error +} + +func (e *errMult) Error() string { + if len(e.errs) <= 0 { + return "" + } else if len(e.errs) == 1 { + return e.errs[0].Error() + } + + b := strings.Builder{} + for _, err := range e.errs { + _, _ = b.WriteString(err.Error()) + _, _ = b.WriteString(" | ") + } + return b.String() +} + +func (e *errMult) Unwrap() []error { + return e.errs +} diff --git a/intra/core/connpool.go b/intra/core/connpool.go index 6e6a9fc7..177cea21 100644 --- a/intra/core/connpool.go +++ b/intra/core/connpool.go @@ -434,7 +434,7 @@ func (a agingconn) canread() error { } }) } - return errors.Join(ctlErr, checkErr) // may return nil + return JoinErr(ctlErr, checkErr) // may return nil } func logev(err error) log.LogFn { diff --git a/intra/core/ping.go b/intra/core/ping.go index 299d48b2..08a485cb 100644 --- a/intra/core/ping.go +++ b/intra/core/ping.go @@ -173,11 +173,11 @@ func setttl(c MinConn, v4 bool) (err error) { if raw4 != nil { err1 := raw4.SetControlMessage(ipv4.FlagTTL, true) err2 := raw4.SetTTL(ttl) - err = errors.Join(err1, err2) + err = JoinErr(err1, err2) } else if raw6 != nil { err1 := raw6.SetControlMessage(ipv6.FlagHopLimit, true) err2 := raw6.SetHopLimit(ttl) - err = errors.Join(err1, err2) + err = JoinErr(err1, err2) } return } diff --git a/intra/dialers/cdial.go b/intra/dialers/cdial.go index 2bdccb76..cf530c19 100644 --- a/intra/dialers/cdial.go +++ b/intra/dialers/cdial.go @@ -105,7 +105,7 @@ func commondial2[D rdials, C rconns](d D, network, laddr, raddr string, connect log.V("commondial: ip %s works for %s", confirmed, remote) return conn, nil } - errs = errors.Join(errs, err) + errs = core.JoinErr(errs, err) ips.Disconfirm(confirmed) logwd(err)("rdial: commondial: confirmed %s for %s failed; err %v", confirmed, remote, err) @@ -114,7 +114,7 @@ func commondial2[D rdials, C rconns](d D, network, laddr, raddr string, connect if dontretry { if !confirmedIPOK { log.E("commondial: ip %s not ok for %s", confirmed, raddr) - errs = errors.Join(errs, errNoIps) + errs = core.JoinErr(errs, errNoIps) } return nil, errs } @@ -134,7 +134,7 @@ func commondial2[D rdials, C rconns](d D, network, laddr, raddr string, connect for _, ip := range allips { end := time.Since(start) if end > dialRetryTimeout { - errs = errors.Join(errs, errRetryTimeout) + errs = core.JoinErr(errs, errRetryTimeout) log.D("commondial: timeout %s for %s", end, raddr) break } @@ -150,7 +150,7 @@ func commondial2[D rdials, C rconns](d D, network, laddr, raddr string, connect log.I("commondial: ip %s works for %s", ip, remote) return conn, nil } - errs = errors.Join(errs, err) + errs = core.JoinErr(errs, err) logwd(err)("rdial: commondial: ip %s for %s failed; err %v", ip, remote, err) } else { log.W("commondial: ip %s not ok for %s", ip, raddr) diff --git a/intra/dialers/pdial.go b/intra/dialers/pdial.go index 1567e0e5..c3369128 100644 --- a/intra/dialers/pdial.go +++ b/intra/dialers/pdial.go @@ -7,7 +7,6 @@ package dialers import ( - "errors" "net" "net/netip" "time" @@ -40,29 +39,30 @@ func ProxyDial(d proxy.Dialer, network, addr string) (net.Conn, error) { } // ProxyDials tries to connect to addr using each dialer in dd -func ProxyDials(dd []proxy.Dialer, network, addr string) (c net.Conn, err error) { +func ProxyDials(dd []proxy.Dialer, network, addr string) (c net.Conn, errs error) { start := time.Now() tot := len(dd) for i, d := range dd { if time.Since(start) > dialRetryTimeout { - err = errors.Join(err, errRetryTimeout) + errs = core.JoinErr(errs, errRetryTimeout) break } - c, err = ProxyDial(d, network, addr) - if c == nil && err == nil { - err = errors.Join(err, errNoConn) + conn, err := ProxyDial(d, network, addr) + c = conn + if conn == nil && err == nil { + errs = core.JoinErr(errs, errNoConn) } else if err != nil { - clos(c) + clos(conn) log.W("pdial: trying %s dialer of %d / %d to %s", network, i, tot, addr) - err = errors.Join(err) - } else if c != nil { - err = nil + errs = core.JoinErr(errs, err) + } else if conn != nil { + errs = nil return } } - if c == nil && err == nil { + if c == nil { log.W("pdial: no dialer (sz: %d) succeeded for %s", tot, addr) - return nil, errNoDialer + return nil, core.OneErr(errs, errNoDialer) } return } diff --git a/intra/dialers/retrier.go b/intra/dialers/retrier.go index a777e14a..d082e2c6 100644 --- a/intra/dialers/retrier.go +++ b/intra/dialers/retrier.go @@ -24,7 +24,6 @@ package dialers import ( - "errors" "io" "net" "sync" @@ -475,7 +474,7 @@ func (r *retrier) CloseWrite() error { // Close closes the connection and the read and write flags. func (r *retrier) Close() error { // also close the read and write flags - return errors.Join(r.CloseRead(), r.CloseWrite()) + return core.JoinErr(r.CloseRead(), r.CloseWrite()) } // LocalAddr behaves slightly strangely: its value may change as a @@ -529,5 +528,5 @@ func (r *retrier) SetWriteDeadline(t time.Time) error { func (r *retrier) SetDeadline(t time.Time) error { e1 := r.SetReadDeadline(t) e2 := r.SetWriteDeadline(t) - return errors.Join(e1, e2) + return core.JoinErr(e1, e2) } diff --git a/intra/dns.go b/intra/dns.go index 946e980a..cb2a4756 100644 --- a/intra/dns.go +++ b/intra/dns.go @@ -8,11 +8,11 @@ package intra import ( "context" - "errors" "strings" "sync" x "github.com/celzero/firestack/intra/backend" + "github.com/celzero/firestack/intra/core" "github.com/celzero/firestack/intra/dns53" "github.com/celzero/firestack/intra/dnscrypt" "github.com/celzero/firestack/intra/dnsx" @@ -40,7 +40,7 @@ func AddDNSProxy(t Tunnel, id, ip, port string) error { p, perr := t.internalProxies() r, rerr := t.internalResolver() if rerr != nil || perr != nil { - return errors.Join(rerr, perr) + return core.JoinErr(rerr, perr) } ctx := t.internalCtx() if dns, err := dns53.NewTransport(ctx, id, ip, port, p); err != nil { @@ -63,7 +63,7 @@ func SetSystemDNS(t Tunnel, ipcsv string) error { n := len(ipcsv) if r == nil || p == nil || n <= 0 { log.W("dns: cannot set system dns; n: %d, errs: %v %v", n, rerr, perr) - return errors.Join(dnsx.ErrAddFailed, rerr, perr) + return core.JoinErr(dnsx.ErrAddFailed, rerr, perr) } // if the ipcsv is localhost, use loopback addresses. @@ -130,7 +130,7 @@ func AddProxyDNS(t Tunnel, p x.Proxy) error { pxr, perr := t.internalProxies() r, rerr := t.internalResolver() if rerr != nil || perr != nil { - return errors.Join(rerr, perr) + return core.JoinErr(rerr, perr) } ctx := t.internalCtx() ipOrHostCsv := p.DNS() // may return csv(host:port), csv(ip:port), csv(ips), csv(host) @@ -166,7 +166,7 @@ func AddDoHTransport(t Tunnel, id, url, ips string) error { pxr, perr := t.internalProxies() r, rerr := t.internalResolver() if rerr != nil || perr != nil { - return errors.Join(rerr, perr) + return core.JoinErr(rerr, perr) } ctx := t.internalCtx() split := []string{} @@ -186,7 +186,7 @@ func AddODoHTransport(t Tunnel, id, endpoint, resolver, epips string) error { pxr, perr := t.internalProxies() r, rerr := t.internalResolver() if rerr != nil || perr != nil { - return errors.Join(rerr, perr) + return core.JoinErr(rerr, perr) } ctx := t.internalCtx() split := []string{} @@ -205,7 +205,7 @@ func AddDoTTransport(t Tunnel, id, url, ips string) error { pxr, perr := t.internalProxies() r, rerr := t.internalResolver() if rerr != nil || perr != nil { - return errors.Join(rerr, perr) + return core.JoinErr(rerr, perr) } ctx := t.internalCtx() split := []string{} diff --git a/intra/dns53/goos.go b/intra/dns53/goos.go index 1d01f679..baf14429 100644 --- a/intra/dns53/goos.go +++ b/intra/dns53/goos.go @@ -8,7 +8,6 @@ package dns53 import ( "context" - "errors" "net" "net/netip" "time" @@ -119,7 +118,7 @@ func (t *goosr) send(msg *dns.Msg) (ans *dns.Msg, elapsed time.Duration, qerr *d log.D("dns53: goosr: go resolver (why? %v) for %s => %s", errl, host, ips) ans, err = xdns.AQuadAForQuery(msg, ips...) } else { - err = errors.Join(errl, errc) + err = core.JoinErr(errl, errc) } // TODO: if len(ips) <= 0 synthesize a NXDOMAIN? } diff --git a/intra/dns53/ipmapper.go b/intra/dns53/ipmapper.go index 0d8fa6ef..30f83fcc 100644 --- a/intra/dns53/ipmapper.go +++ b/intra/dns53/ipmapper.go @@ -128,7 +128,7 @@ func (m *ipmapper) queryIP2(_ context.Context, network, host, uid string) ([]net } if err4 != nil || err6 != nil { - errs := errors.Join(err4, err6) + errs := core.JoinErr(err4, err6) log.E("ipmapper: lookup: query %s err %v", host, errs) return nil, errs } @@ -164,14 +164,14 @@ func (m *ipmapper) queryIP2(_ context.Context, network, host, uid string) ([]net } if lerr4 != nil && lerr6 != nil { // all errors - errs := errors.Join(lerr4, lerr6) + errs := core.JoinErr(lerr4, lerr6) log.E("ipmapper: lookup: %s: err %v", host, errs) return nil, errs } else if noval4 && noval6 { // typecast failed or no answer log.E("ipmapper: lookup: no answers for %s; len(4)? %d len(6)? %d", host, len(r4), len(r6)) return nil, errNoAns } else if len(r4) <= 0 && len(r6) <= 0 { // empty answer - errs := errors.Join(errNoAns, lerr4, lerr6) + errs := core.JoinErr(errNoAns, lerr4, lerr6) log.E("ipmapper: lookup: no answers for %s, err %v", host, errs) return nil, errs } diff --git a/intra/dnsx/cacher.go b/intra/dnsx/cacher.go index 692262d5..d73b1423 100644 --- a/intra/dnsx/cacher.go +++ b/intra/dnsx/cacher.go @@ -366,7 +366,7 @@ func (t *ctransport) fetch(network string, q *dns.Msg, summary *x.DNSSummary, cb // return cached/barriered response, instead return an error inhangover := t.hangover.Exceeds(httl) if inhangover { - err = errors.Join(err, errHangover) + err = core.JoinErr(err, errHangover) log.W("cache: barrier: hangover(k: %s); discard ans (has? %t)", key, hasans) if cachehit { fillSummary(cachedres.s, fsmm) @@ -385,7 +385,7 @@ func (t *ctransport) fetch(network string, q *dns.Msg, summary *x.DNSSummary, cb fillSummary(cachedsmm, fsmm) // cachedsmm may itself be fsmm } - return fres, errors.Join(err, ferr) + return fres, core.JoinErr(err, ferr) } // check if underlying transport can connect fine, if not treat cache diff --git a/intra/doh/doh.go b/intra/doh/doh.go index 1714f86e..0a99d40e 100644 --- a/intra/doh/doh.go +++ b/intra/doh/doh.go @@ -178,11 +178,11 @@ func newTransport(ctx context.Context, typ, id, rawurl, otargeturl string, addrs proxy := rawurl // may be empty configurl, err := url.Parse(odohconfigdns) if err != nil || configurl == nil || configurl.Hostname() == "" { - return nil, errors.Join(errNoOdohConfigUrl, err) + return nil, core.JoinErr(errNoOdohConfigUrl, err) } targeturl, err := url.Parse(otargeturl) if err != nil || targeturl == nil || targeturl.Hostname() == "" { - return nil, errors.Join(errNoOdohTarget, err) + return nil, core.JoinErr(errNoOdohTarget, err) } proxyurl, _ := url.Parse(proxy) // ignore err as proxy may be empty diff --git a/intra/ipn/piph2.go b/intra/ipn/piph2.go index 4e1508b4..784570fe 100644 --- a/intra/ipn/piph2.go +++ b/intra/ipn/piph2.go @@ -12,7 +12,6 @@ import ( "crypto/sha256" "crypto/tls" "encoding/hex" - "errors" "io" "net" "net/http" @@ -112,7 +111,7 @@ func (c *pipconn) SetWriteDeadline(t time.Time) error { return nil } func (t *piph2) dialtls(network, addr string, cfg *tls.Config) (net.Conn, error) { rawConn, err := t.dial(network, addr) if err != nil || rawConn == nil || core.IsNil(rawConn) { - return nil, errors.Join(err, errNoProxyConn) + return nil, core.JoinErr(err, errNoProxyConn) } colonPos := strings.LastIndex(addr, ":") diff --git a/intra/ipn/proxies.go b/intra/ipn/proxies.go index 0cfecf93..085036f5 100644 --- a/intra/ipn/proxies.go +++ b/intra/ipn/proxies.go @@ -789,7 +789,7 @@ func (px *proxifier) RegisterWarp(pub string) ([]byte, error) { func (px *proxifier) RegisterSE() error { sec := px.sec if sec == nil { - return errors.Join(errMissingSEClient, px.lastSeErr) + return core.JoinErr(errMissingSEClient, px.lastSeErr) } sep, err := NewSEasyProxy(px.ctx, px.ctl, sec) @@ -808,7 +808,7 @@ func (px *proxifier) RegisterSE() error { func (px *proxifier) Warp() (x.Proxy, error) { warp, err := px.ProxyFor(RpnWg) if warp == nil { - return nil, errors.Join(err, px.lastWarpErr) + return nil, core.JoinErr(err, px.lastWarpErr) } return warp, err } @@ -832,7 +832,7 @@ func (px *proxifier) Exit64() (x.Proxy, error) { func (px *proxifier) SE() (x.Proxy, error) { sep, err := px.ProxyFor(RpnWg) if sep == nil { - return nil, errors.Join(err, px.lastSeErr) + return nil, core.JoinErr(err, px.lastSeErr) } return sep, err } @@ -860,7 +860,7 @@ func (px *proxifier) TestSE() (string, error) { } if len(oks) <= 0 { - return "", errors.Join(errNoSuitableAddress, px.lastSeErr) + return "", core.JoinErr(errNoSuitableAddress, px.lastSeErr) } return strings.Join(oks, ","), nil } @@ -891,7 +891,7 @@ func (px *proxifier) TestWarp() (string, error) { } if len(oks) <= 0 { - return "", errors.Join(errNoSuitableAddress, px.lastWarpErr) + return "", core.JoinErr(errNoSuitableAddress, px.lastWarpErr) } return strings.Join(oks, ","), nil } diff --git a/intra/ipn/seasy/seapi.go b/intra/ipn/seasy/seapi.go index f4d6f33a..41b288ca 100644 --- a/intra/ipn/seasy/seapi.go +++ b/intra/ipn/seasy/seapi.go @@ -16,7 +16,6 @@ package seasy import ( "context" "crypto/tls" - "errors" "fmt" "net/http" "net/netip" @@ -150,7 +149,7 @@ func (sec *SEApi) Start(ctx context.Context) (ok bool, err error) { } } } else { - err = errors.Join(err, discoerr) + err = core.JoinErr(err, discoerr) } } if err != nil { diff --git a/intra/ipn/warp/cfg.go b/intra/ipn/warp/cfg.go index c774067ab..1df267ac 100644 --- a/intra/ipn/warp/cfg.go +++ b/intra/ipn/warp/cfg.go @@ -14,7 +14,6 @@ package warp import ( - "errors" "math/rand" "net/netip" "time" @@ -119,7 +118,7 @@ func Endpoints() (v4 netip.AddrPort, v6 netip.AddrPort, err error) { ip4, err4 := core.RandomIPFromPrefix(cidr4) ip6, err6 := core.RandomIPFromPrefix(cidr6) if err4 != nil && err6 != nil { - err = errors.Join(err4, err6) + err = core.JoinErr(err4, err6) return } v4ok, v6ok := ip4.IsValid(), ip6.IsValid() diff --git a/intra/ipn/wg/wgconn.go b/intra/ipn/wg/wgconn.go index 2e746b08..ee72a539 100644 --- a/intra/ipn/wg/wgconn.go +++ b/intra/ipn/wg/wgconn.go @@ -302,7 +302,7 @@ func (bind *StdNetBind) Close() error { bind.blackhole6 = false log.I("wg: bind: %s close; err4? %v err6? %v", bind.id, err1, err2) - return errors.Join(err1, err2) + return core.JoinErr(err1, err2) } func (s *StdNetBind) makeReceiveFn(uc *net.UDPConn) conn.ReceiveFunc { @@ -406,7 +406,7 @@ func (s *StdNetBind) Send(buf [][]byte, peer conn.Endpoint) (err error) { extend(uc, wgtimeout) n, serr := uc.WriteToUDPAddrPort(data, dst) - errs = errors.Join(errs, serr) + errs = core.JoinErr(errs, serr) nn += n } diff --git a/intra/ipn/wg/wgconn2.go b/intra/ipn/wg/wgconn2.go index 03b8b20d..03a74243 100644 --- a/intra/ipn/wg/wgconn2.go +++ b/intra/ipn/wg/wgconn2.go @@ -488,7 +488,7 @@ func (s *StdNetBind2) Close() error { log.I("wg: bind2: %s close; err4? %v err6? %v", s.id, err4, err6) - return errors.Join(err4, err6) + return core.JoinErr(err4, err6) } func (s *StdNetBind2) Send(bufs [][]byte, peer conn.Endpoint) (err error) { diff --git a/intra/ipn/wgnet.go b/intra/ipn/wgnet.go index c7dfd99b..f355384e 100644 --- a/intra/ipn/wgnet.go +++ b/intra/ipn/wgnet.go @@ -173,7 +173,7 @@ func (tnet *wgtun) dial(network, local, remote string) (net.Conn, error) { return c, nil } dialers.Disconfirm(host, raddr.Addr()) - errs = errors.Join(errs, err) + errs = core.JoinErr(errs, err) } errs = core.OneErr(errs, errMissingAddress) log.W("wg: dial: %s: %s failed: %v", network, addrs, errs) diff --git a/intra/listener.go b/intra/listener.go index 5f1507b1..9dff430e 100644 --- a/intra/listener.go +++ b/intra/listener.go @@ -12,6 +12,7 @@ import ( "net/netip" "time" + "github.com/celzero/firestack/intra/core" "github.com/celzero/firestack/intra/ipn" ) @@ -139,7 +140,7 @@ func (s *SocketSummary) done(errs ...error) *SocketSummary { return s } - err := errors.Join(errs...) // errs may be nil + err := core.JoinErr(errs...) // errs may be nil if err != nil { if s.Msg == errNone.Error() { s.Msg = err.Error() diff --git a/intra/netstack/netstack.go b/intra/netstack/netstack.go index c0c44a16..0f2d93cd 100644 --- a/intra/netstack/netstack.go +++ b/intra/netstack/netstack.go @@ -13,6 +13,7 @@ import ( "net/netip" "syscall" + "github.com/celzero/firestack/intra/core" "github.com/celzero/firestack/intra/log" "github.com/celzero/firestack/intra/settings" "gvisor.dev/gvisor/pkg/tcpip" @@ -202,7 +203,7 @@ func addIfAddrs(s *stack.Stack, nic tcpip.NICID) error { ifaddr6, err6 := netip.ParsePrefix("fd66:f83a:c650::1/120") if err4 != nil || err6 != nil { // should never happen - return errors.Join(err4, err6) + return core.JoinErr(err4, err6) } // go.dev/play/p/Clg4geOwXMf diff --git a/intra/rnet/http.go b/intra/rnet/http.go index 6459440c..120c2985 100644 --- a/intra/rnet/http.go +++ b/intra/rnet/http.go @@ -8,7 +8,6 @@ package rnet import ( "context" - "errors" "io" "net" "net/http" @@ -239,7 +238,7 @@ func http502(w io.WriteCloser, err1 error, ssu *ServerSummary) { if ssu != nil { ssu.done(err1, err2, err3) } - log.D("svchttp: http502: done http-connect; errs? %v", errors.Join(err1, err2, err3)) + log.D("svchttp: http502: done http-connect; errs? %v", core.JoinErr(err1, err2, err3)) } func pipeconn(dst net.Conn, src net.Conn, ssu *ServerSummary, wg *sync.WaitGroup) { diff --git a/intra/rnet/listener.go b/intra/rnet/listener.go index b2972dae..c5f754f8 100644 --- a/intra/rnet/listener.go +++ b/intra/rnet/listener.go @@ -10,6 +10,8 @@ import ( "errors" "fmt" "time" + + "github.com/celzero/firestack/intra/core" ) var errNop = errors.New("no error") @@ -34,7 +36,7 @@ func (s *ServerSummary) done(errs ...error) { s.Duration = int32(time.Since(s.start).Seconds()) - err := errors.Join(errs...) // errs may be nil + err := core.JoinErr(errs...) // errs may be nil if err != nil { if s.Msg == errNop.Error() { s.Msg = err.Error() diff --git a/intra/rnet/socks5.go b/intra/rnet/socks5.go index 22948cef..3882ab06 100644 --- a/intra/rnet/socks5.go +++ b/intra/rnet/socks5.go @@ -8,7 +8,6 @@ package rnet import ( "context" - "errors" "fmt" "io" "net" @@ -328,7 +327,7 @@ func (h *socks5) tcphandle(s *tx.Server, ingress *net.TCPConn, r *tx.Request) (e finrx := <-finrxch fintx := <-fintxch - err = errors.Join(finrx.err, fintx.err) + err = core.JoinErr(finrx.err, fintx.err) summary.Rx = finrx.ex summary.Tx = fintx.ex diff --git a/intra/udpmux.go b/intra/udpmux.go index fc4f5e4b..af9c2a2a 100644 --- a/intra/udpmux.go +++ b/intra/udpmux.go @@ -7,7 +7,6 @@ package intra import ( - "errors" "fmt" "net" "net/netip" @@ -429,7 +428,7 @@ func (c *demuxconn) RemoteAddr() net.Addr { func (c *demuxconn) SetDeadline(t time.Time) error { werr := c.SetReadDeadline(t) rerr := c.SetReadDeadline(t) - return errors.Join(werr, rerr) + return core.JoinErr(werr, rerr) } // SetReadDeadline implements core.UDPConn.SetReadDeadline