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  }