mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-27 11:01:28 +00:00
63 lines
1.3 KiB
Go
63 lines
1.3 KiB
Go
package proxyproto
|
|
|
|
import (
|
|
std_bufio "bufio"
|
|
"net"
|
|
|
|
"github.com/sagernet/sing/common/buf"
|
|
"github.com/sagernet/sing/common/bufio"
|
|
M "github.com/sagernet/sing/common/metadata"
|
|
|
|
"github.com/pires/go-proxyproto"
|
|
)
|
|
|
|
type Listener struct {
|
|
net.Listener
|
|
AcceptNoHeader bool
|
|
}
|
|
|
|
func (l *Listener) Accept() (net.Conn, error) {
|
|
conn, err := l.Listener.Accept()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
bufReader := std_bufio.NewReader(conn)
|
|
header, err := proxyproto.Read(bufReader)
|
|
if err != nil && !(l.AcceptNoHeader && err == proxyproto.ErrNoProxyProtocol) {
|
|
return nil, &Error{err}
|
|
}
|
|
if bufReader.Buffered() > 0 {
|
|
cache := buf.NewSize(bufReader.Buffered())
|
|
_, err = cache.ReadFullFrom(bufReader, cache.FreeLen())
|
|
if err != nil {
|
|
return nil, &Error{err}
|
|
}
|
|
conn = bufio.NewCachedConn(conn, cache)
|
|
}
|
|
if header != nil {
|
|
return &bufio.AddrConn{Conn: conn, Metadata: M.Metadata{
|
|
Source: M.SocksaddrFromNet(header.SourceAddr).Unwrap(),
|
|
Destination: M.SocksaddrFromNet(header.DestinationAddr).Unwrap(),
|
|
}}, nil
|
|
}
|
|
return conn, nil
|
|
}
|
|
|
|
var _ net.Error = (*Error)(nil)
|
|
|
|
type Error struct {
|
|
error
|
|
}
|
|
|
|
func (e *Error) Unwrap() error {
|
|
return e.error
|
|
}
|
|
|
|
func (e *Error) Timeout() bool {
|
|
return false
|
|
}
|
|
|
|
func (e *Error) Temporary() bool {
|
|
return true
|
|
}
|