2022-08-23 21:07:35 +08:00
|
|
|
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
|
2022-09-07 23:01:57 +08:00
|
|
|
AcceptNoHeader bool
|
2022-08-23 21:07:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
2022-09-07 23:01:57 +08:00
|
|
|
if err != nil && !(l.AcceptNoHeader && err == proxyproto.ErrNoProxyProtocol) {
|
2022-08-23 21:07:35 +08:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if bufReader.Buffered() > 0 {
|
|
|
|
cache := buf.NewSize(bufReader.Buffered())
|
|
|
|
_, err = cache.ReadFullFrom(bufReader, cache.FreeLen())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
conn = bufio.NewCachedConn(conn, cache)
|
|
|
|
}
|
2022-09-07 23:01:57 +08:00
|
|
|
if header != nil {
|
|
|
|
return &bufio.AddrConn{Conn: conn, Metadata: M.Metadata{
|
2022-09-25 22:16:24 +08:00
|
|
|
Source: M.SocksaddrFromNet(header.SourceAddr).Unwrap(),
|
|
|
|
Destination: M.SocksaddrFromNet(header.DestinationAddr).Unwrap(),
|
2022-09-07 23:01:57 +08:00
|
|
|
}}, nil
|
|
|
|
}
|
|
|
|
return conn, nil
|
2022-08-23 21:07:35 +08:00
|
|
|
}
|