Feature: SOCKS4/SOCKS4A Inbound Compatible Support (#1491)

This commit is contained in:
xᴊᴀsᴏɴʟʏᴜ
2021-07-18 16:09:09 +08:00
committed by GitHub
parent 46f4f84442
commit a461c2306a
5 changed files with 241 additions and 11 deletions

View File

@ -6,8 +6,10 @@ import (
"net"
"github.com/Dreamacro/clash/adapter/inbound"
N "github.com/Dreamacro/clash/common/net"
C "github.com/Dreamacro/clash/constant"
authStore "github.com/Dreamacro/clash/listener/auth"
"github.com/Dreamacro/clash/transport/socks4"
"github.com/Dreamacro/clash/transport/socks5"
)
@ -33,7 +35,7 @@ func New(addr string, in chan<- C.ConnContext) (*Listener, error) {
}
continue
}
go HandleSocks(c, in)
go handleSocks(c, in)
}
}()
@ -49,7 +51,37 @@ func (l *Listener) Address() string {
return l.address
}
func HandleSocks(conn net.Conn, in chan<- C.ConnContext) {
func handleSocks(conn net.Conn, in chan<- C.ConnContext) {
bufConn := N.NewBufferedConn(conn)
head, err := bufConn.Peek(1)
if err != nil {
conn.Close()
return
}
switch head[0] {
case socks4.Version:
HandleSocks4(bufConn, in)
case socks5.Version:
HandleSocks5(bufConn, in)
default:
conn.Close()
}
}
func HandleSocks4(conn net.Conn, in chan<- C.ConnContext) {
addr, _, err := socks4.ServerHandshake(conn, authStore.Authenticator())
if err != nil {
conn.Close()
return
}
if c, ok := conn.(*net.TCPConn); ok {
c.SetKeepAlive(true)
}
in <- inbound.NewSocket(socks5.ParseAddr(addr), conn, C.SOCKS)
}
func HandleSocks5(conn net.Conn, in chan<- C.ConnContext) {
target, command, err := socks5.ServerHandshake(conn, authStore.Authenticator())
if err != nil {
conn.Close()