github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/common/proxyproto/listener.go (about) 1 package proxyproto 2 3 import ( 4 std_bufio "bufio" 5 "net" 6 7 "github.com/sagernet/sing/common/buf" 8 "github.com/sagernet/sing/common/bufio" 9 M "github.com/sagernet/sing/common/metadata" 10 11 "github.com/pires/go-proxyproto" 12 ) 13 14 type Listener struct { 15 net.Listener 16 AcceptNoHeader bool 17 } 18 19 func (l *Listener) Accept() (net.Conn, error) { 20 conn, err := l.Listener.Accept() 21 if err != nil { 22 return nil, err 23 } 24 bufReader := std_bufio.NewReader(conn) 25 header, err := proxyproto.Read(bufReader) 26 if err != nil && !(l.AcceptNoHeader && err == proxyproto.ErrNoProxyProtocol) { 27 return nil, &Error{err} 28 } 29 if bufReader.Buffered() > 0 { 30 cache := buf.NewSize(bufReader.Buffered()) 31 _, err = cache.ReadFullFrom(bufReader, cache.FreeLen()) 32 if err != nil { 33 return nil, &Error{err} 34 } 35 conn = bufio.NewCachedConn(conn, cache) 36 } 37 if header != nil { 38 return &bufio.AddrConn{Conn: conn, Metadata: M.Metadata{ 39 Source: M.SocksaddrFromNet(header.SourceAddr).Unwrap(), 40 Destination: M.SocksaddrFromNet(header.DestinationAddr).Unwrap(), 41 }}, nil 42 } 43 return conn, nil 44 } 45 46 var _ net.Error = (*Error)(nil) 47 48 type Error struct { 49 error 50 } 51 52 func (e *Error) Unwrap() error { 53 return e.error 54 } 55 56 func (e *Error) Timeout() bool { 57 return false 58 } 59 60 func (e *Error) Temporary() bool { 61 return true 62 }