Adapt new shadowsocks library.

1. Modify ss/ssu handler and connector
2. Add users to metadata of ss and ssu handler
This commit is contained in:
RMT
2025-11-05 21:26:24 +08:00
committed by ginuerzh
parent d2cc07d3ac
commit 0c97db3c05
12 changed files with 372 additions and 192 deletions
+49 -32
View File
@@ -1,11 +1,14 @@
package ss
import (
"bytes"
"errors"
"net"
"net/netip"
"sync"
"github.com/go-gost/core/common/bufpool"
"github.com/go-gost/gosocks5"
"github.com/go-gost/go-shadowsocks2/core"
"github.com/go-gost/go-shadowsocks2/socks"
)
const (
@@ -17,14 +20,19 @@ var (
_ net.Conn = (*UDPConn)(nil)
)
// This wrapped connection has different behavior than ordinary connection:
// 1. ReadFrom will return target addr of shadowsocks instead of remote addr
type UDPConn struct {
client *core.UDPClient
server *core.UDPServer
sessionMap *sync.Map
net.PacketConn
raddr net.Addr
taddr net.Addr
bufferSize int
}
func UDPClientConn(c net.PacketConn, remoteAddr, targetAddr net.Addr, bufferSize int) *UDPConn {
func UDPClientConn(c net.PacketConn, remoteAddr, targetAddr net.Addr, bufferSize int, client *core.UDPClient, sessionMap *sync.Map) *UDPConn {
if bufferSize <= 0 {
bufferSize = defaultBufferSize
}
@@ -34,18 +42,8 @@ func UDPClientConn(c net.PacketConn, remoteAddr, targetAddr net.Addr, bufferSize
raddr: remoteAddr,
taddr: targetAddr,
bufferSize: bufferSize,
}
}
func UDPServerConn(c net.PacketConn, remoteAddr net.Addr, bufferSize int) *UDPConn {
if bufferSize <= 0 {
bufferSize = defaultBufferSize
}
return &UDPConn{
PacketConn: c,
raddr: remoteAddr,
bufferSize: bufferSize,
client: client,
sessionMap: sessionMap,
}
}
@@ -53,19 +51,34 @@ func (c *UDPConn) ReadFrom(b []byte) (n int, addr net.Addr, err error) {
buf := bufpool.Get(c.bufferSize)
defer bufpool.Put(buf)
clientAddr, err := netip.ParseAddrPort(c.LocalAddr().String())
if err != nil {
return
}
n, _, err = c.PacketConn.ReadFrom(buf)
if err != nil {
return
}
saddr := gosocks5.Addr{}
addrLen, err := saddr.ReadFrom(bytes.NewReader(buf[:n]))
if err != nil {
return
var payload []byte
var session core.UDPSession
if c.client != nil {
s, ok := c.sessionMap.Load(core.SessionHashFromAddrPort(clientAddr))
if !ok {
return 0, nil, errors.New("udp session cannot find")
}
session = s.(core.UDPSession)
payload, err = c.client.Outbound(buf[:n], session)
if err != nil {
return
}
} else {
return 0, nil, errors.New("UDPConn must be client ")
}
n = copy(b, buf[addrLen:n])
addr, err = net.ResolveUDPAddr("udp", saddr.String())
n = copy(b, payload)
addr, err = net.ResolveUDPAddr("udp", session.Target().String())
return
}
@@ -76,22 +89,26 @@ func (c *UDPConn) Read(b []byte) (n int, err error) {
}
func (c *UDPConn) WriteTo(b []byte, addr net.Addr) (n int, err error) {
socksAddr := gosocks5.Addr{}
if err = socksAddr.ParseFrom(addr.String()); err != nil {
return
}
buf := bufpool.Get(c.bufferSize)
defer bufpool.Put(buf)
addrLen, err := socksAddr.Encode(buf)
target := socks.ParseAddr(c.taddr.String())
clientAddr, err := netip.ParseAddrPort(c.LocalAddr().String())
if err != nil {
return
}
n = copy(buf[addrLen:], b)
_, err = c.PacketConn.WriteTo(buf[:addrLen+n], c.raddr)
var session core.UDPSession
var encrypted []byte
if c.client != nil {
session, encrypted, err = c.client.Inbound(b, clientAddr, target)
if err != nil {
return
}
c.sessionMap.Store(session.Hash(), session)
} else {
return 0, errors.New("UDPConn must be client")
}
_, err = c.PacketConn.WriteTo(encrypted, c.raddr)
n = len(b)
return
}