Skip to content

Commit

Permalink
VMess Support
Browse files Browse the repository at this point in the history
  • Loading branch information
reflog committed Nov 26, 2024
1 parent ab3b3c6 commit c6d8502
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 0 deletions.
2 changes: 2 additions & 0 deletions chained/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ func createImpl(configDir, name, addr, transport string, s *config.ProxyConfig,
impl, err = newBroflakeImpl(s, reportDialCore)
case "algeneva":
impl, err = newAlgenevaImpl(addr, s, reportDialCore)
case "vmess":
impl, err = newVmessImpl(name, addr, s, reportDialCore)
case "water":
waterDir := filepath.Join(configDir, "water")
if err := os.MkdirAll(waterDir, 0755); err != nil {
Expand Down
100 changes: 100 additions & 0 deletions chained/vmess_impl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package chained

import (
"context"
crand "crypto/rand"
"encoding/binary"
mrand "math/rand"
"net"
"sync"

"github.com/getlantern/common/config"
"github.com/getlantern/errors"
"github.com/getlantern/flashlight/v7/ops"

vmess "github.com/sagernet/sing-vmess"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)

type vmessImpl struct {
reportDialCore reportDialCoreFn
client *vmess.Client
uuid string
rng *mrand.Rand
rngmx sync.Mutex
addr string
}

// newVmessImpl creates a new VMess proxy implementation.
// supports the following options:
// - uuid: the UUID of the user on the VMess server
// - security: the security level to use, defaults to "auto". Options are:
// "auto": automatically determine the security level
// "none" or "zero": no security
// "aes-128-cfb": legacy security
// "aes-128-gcm": AES-128-GCM security
// "chacha20-poly1305": ChaCha20-Poly1305 security

func newVmessImpl(name, addr string, pc *config.ProxyConfig, reportDialCore reportDialCoreFn) (proxyImpl, error) {
uuid := ptSetting(pc, "uuid")
security := ptSetting(pc, "security")
if security == "" {
security = "auto"
}

client, err := vmess.NewClient(uuid, security, 0)

if err != nil {
return nil, errors.New("failed to create vmess client: %v", err)
}

var seed int64
err = binary.Read(crand.Reader, binary.BigEndian, &seed)
if err != nil {
return nil, errors.New("unable to initialize rng: %v", err)
}

source := mrand.NewSource(seed)

return &vmessImpl{
reportDialCore: reportDialCore,
client: client,
uuid: uuid,
addr: addr,
rng: mrand.New(source),
}, nil
}

func (impl *vmessImpl) close() {
}

func (impl *vmessImpl) dialServer(op *ops.Op, ctx context.Context) (net.Conn, error) {
return impl.reportDialCore(op, func() (net.Conn, error) {
target := metadata.ParseSocksaddrHostPort(impl.generateUpstream(), 443)
conn, err := (&net.Dialer{}).DialContext(ctx, N.NetworkTCP, impl.addr)
if err != nil {
common.Close(conn)
return nil, err
}
return impl.client.DialEarlyConn(conn, target), nil
})
}

// generateUpstream() creates a marker upstream address. This isn't an
// acutal upstream that will be dialed, it signals that the upstream
// should be determined by other methods. It's just a bit random just to
// mix it up and not do anything especially consistent on every dial.
func (impl *vmessImpl) generateUpstream() string {
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
impl.rngmx.Lock()
defer impl.rngmx.Unlock()
// [2 - 22]
sz := 2 + impl.rng.Intn(21)
b := make([]byte, sz)
for i := range b {
b[i] = letters[impl.rng.Intn(len(letters))]
}
return string(b) + ".com"
}
6 changes: 6 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ require (
github.com/pborman/uuid v1.2.1
github.com/refraction-networking/utls v1.3.3
github.com/refraction-networking/water v0.7.0-alpha
github.com/sagernet/sing v0.5.1
github.com/sagernet/sing-vmess v0.1.12
github.com/samber/lo v1.38.1
github.com/shadowsocks/go-shadowsocks2 v0.1.5
github.com/stretchr/testify v1.9.0
Expand Down Expand Up @@ -120,7 +122,11 @@ require (
github.com/getlantern/algeneva v0.0.0-20240222191137-2b4e88234f59 // indirect
github.com/getlantern/lampshade v0.0.0-20201109225444-b06082e15f3a // indirect
github.com/getlantern/withtimeout v0.0.0-20160829163843-511f017cd913 // indirect
<<<<<<< HEAD
github.com/go-llsqlite/crawshaw v0.5.1 // indirect
=======
github.com/gofrs/uuid/v5 v5.2.0 // indirect
>>>>>>> a13db0bc2 (VMess Support)
github.com/tetratelabs/wazero v1.7.1 // indirect
github.com/vishvananda/netns v0.0.1 // indirect
gitlab.com/yawning/edwards25519-extra.git v0.0.0-20211229043746-2f91fcc9fbdb // indirect
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,8 @@ github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/gofrs/uuid/v5 v5.2.0 h1:qw1GMx6/y8vhVsx626ImfKMuS5CvJmhIKKtuyvfajMM=
github.com/gofrs/uuid/v5 v5.2.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
Expand Down Expand Up @@ -765,6 +767,10 @@ github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417 h1:Lt9DzQALzHoDwMBGJ6v
github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417/go.mod h1:qe5TWALJ8/a1Lqznoc5BDHpYX/8HU60Hm2AwRmqzxqA=
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 h1:GHRpF1pTW19a8tTFrMLUcfWwyC0pnifVo2ClaLq+hP8=
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8=
github.com/sagernet/sing v0.5.1 h1:mhL/MZVq0TjuvHcpYcFtmSD1BFOxZ/+8ofbNZcg1k1Y=
github.com/sagernet/sing v0.5.1/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/sagernet/sing-vmess v0.1.12 h1:2gFD8JJb+eTFMoa8FIVMnknEi+vCSfaiTXTfEYAYAPg=
github.com/sagernet/sing-vmess v0.1.12/go.mod h1:luTSsfyBGAc9VhtCqwjR+dt1QgqBhuYBCONB/POhF8I=
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
Expand Down

0 comments on commit c6d8502

Please sign in to comment.