earlyconn.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. package net
  2. import (
  3. "net"
  4. "sync"
  5. "github.com/metacubex/mihomo/common/buf"
  6. "github.com/metacubex/mihomo/common/once"
  7. )
  8. type earlyConn struct {
  9. ExtendedConn // only expose standard N.ExtendedConn function to outside
  10. resFunc func() error
  11. resOnce sync.Once
  12. resErr error
  13. }
  14. func (conn *earlyConn) Response() error {
  15. conn.resOnce.Do(func() {
  16. conn.resErr = conn.resFunc()
  17. })
  18. return conn.resErr
  19. }
  20. func (conn *earlyConn) Read(b []byte) (n int, err error) {
  21. err = conn.Response()
  22. if err != nil {
  23. return 0, err
  24. }
  25. return conn.ExtendedConn.Read(b)
  26. }
  27. func (conn *earlyConn) ReadBuffer(buffer *buf.Buffer) (err error) {
  28. err = conn.Response()
  29. if err != nil {
  30. return err
  31. }
  32. return conn.ExtendedConn.ReadBuffer(buffer)
  33. }
  34. func (conn *earlyConn) Upstream() any {
  35. return conn.ExtendedConn
  36. }
  37. func (conn *earlyConn) Success() bool {
  38. return once.Done(&conn.resOnce) && conn.resErr == nil
  39. }
  40. func (conn *earlyConn) ReaderReplaceable() bool {
  41. return conn.Success()
  42. }
  43. func (conn *earlyConn) ReaderPossiblyReplaceable() bool {
  44. return !conn.Success()
  45. }
  46. func (conn *earlyConn) WriterReplaceable() bool {
  47. return true
  48. }
  49. var _ ExtendedConn = (*earlyConn)(nil)
  50. func NewEarlyConn(c net.Conn, f func() error) net.Conn {
  51. return &earlyConn{ExtendedConn: NewExtendedConn(c), resFunc: f}
  52. }