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:
+49
-32
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user