mirror of
https://github.com/howmp/reality
synced 2025-02-22 09:52:16 +08:00
add multi grsc and grsu
This commit is contained in:
parent
9bb9c6d084
commit
e9162c84b2
13
README.md
13
README.md
@ -26,6 +26,8 @@ grs是一个反向socks5代理,其中grss和grsc和grsu是通过REALITY协议通
|
||||
|
||||
若SNIAddr或ServerAddr不指定,则尝试加载已有配置文件
|
||||
|
||||
默认生成3个不同id文件名的客户端,可通过`-c`参数指定
|
||||
|
||||
```txt
|
||||
Usage:
|
||||
grss [OPTIONS] gen [gen-OPTIONS] [SNIAddr] [ServerAddr]
|
||||
@ -40,6 +42,7 @@ Help Options:
|
||||
-f=[chrome|firefox|safari|ios|android|edge|360|qq] client finger print (default: chrome)
|
||||
-e= expire second (default: 30)
|
||||
-o= server config output path (default: config.json)
|
||||
-c= client count (default: 3)
|
||||
--dir= client output directory (default: .)
|
||||
|
||||
[gen command arguments]
|
||||
@ -66,14 +69,20 @@ Help Options:
|
||||
|
||||
### 启动客户端
|
||||
|
||||
`grsc`
|
||||
`grscX`
|
||||
|
||||
**X表示id**
|
||||
|
||||
### 启动用户端
|
||||
|
||||
`grsu`
|
||||
`grsu -id 0`
|
||||
|
||||
**这里id参数对应了grsc的id,不同id会连接不同的grsc**
|
||||
|
||||
```txt
|
||||
Usage of grsu:
|
||||
-i uint
|
||||
id
|
||||
-l string
|
||||
socks5 listen address (default "127.0.0.1:61080")
|
||||
```
|
||||
|
15
client.go
15
client.go
@ -23,9 +23,10 @@ type ClientConfig struct {
|
||||
SNI string `json:"sni_name"`
|
||||
PublicKeyECDH string `json:"public_key_ecdh"`
|
||||
PublicKeyVerify string `json:"public_key_verify"`
|
||||
FingerPrint string `json:"finger_print,omitempty"`
|
||||
ExpireSecond uint32 `json:"expire_second,omitempty"`
|
||||
Debug bool `json:"debug,omitempty"`
|
||||
FingerPrint string `json:"finger_print"`
|
||||
ExpireSecond uint32 `json:"expire_second"`
|
||||
Debug bool `json:"debug"`
|
||||
OverlayData byte `json:"overlay_data"`
|
||||
|
||||
fingerPrint *utls.ClientHelloID // 客户端的TLS指纹
|
||||
publicKeyECDH *ecdh.PublicKey // 用于密钥协商
|
||||
@ -133,7 +134,7 @@ func UnmarshalClientConfig(configData []byte) (*ClientConfig, error) {
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
func NewClient(ctx context.Context, config *ClientConfig, overlayData byte) (net.Conn, error) {
|
||||
func NewClient(ctx context.Context, config *ClientConfig) (net.Conn, error) {
|
||||
if err := config.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -213,10 +214,10 @@ func NewClient(ctx context.Context, config *ClientConfig, overlayData byte) (net
|
||||
is12 := state.Version == versionTLS12
|
||||
if is12 {
|
||||
// 进行我们私有握手,客户端发送附加数据,服务端回复64字节签名数据
|
||||
logger.Debugf("overlayData: %x", overlayData)
|
||||
logger.Debugf("overlayData: %x", config.OverlayData)
|
||||
// record数据前缀模仿seq
|
||||
data := generateRandomData(seqNumerOne[:])
|
||||
data[len(data)-1] = overlayData
|
||||
data[len(data)-1] = config.OverlayData
|
||||
record := newTLSRecord(recordTypeApplicationData, versionTLS12, data)
|
||||
if _, err := record.writeTo(uconn.GetUnderlyingConn()); err != nil {
|
||||
uconn.Close()
|
||||
@ -247,7 +248,7 @@ func NewClient(ctx context.Context, config *ClientConfig, overlayData byte) (net
|
||||
}
|
||||
// 服务端回复验证通过
|
||||
logger.Debugln("verify ok")
|
||||
return newWarpConn(uconn.GetUnderlyingConn(), aead, overlayData, seqNumerOne), nil
|
||||
return newWarpConn(uconn.GetUnderlyingConn(), aead, config.OverlayData, seqNumerOne), nil
|
||||
}
|
||||
uconn.Close()
|
||||
return nil, ErrVerifyFailed
|
||||
|
@ -36,7 +36,7 @@ func TestClient(t *testing.T) {
|
||||
}
|
||||
t.Log(string(d))
|
||||
|
||||
_, err = reality.NewClient(context.Background(), config, 0)
|
||||
_, err = reality.NewClient(context.Background(), config)
|
||||
if err == nil {
|
||||
t.Fatal("should error")
|
||||
}
|
||||
@ -48,7 +48,7 @@ func TestClientConfig(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
config := configServer.ToClientConfig()
|
||||
config := configServer.ToClientConfig(0)
|
||||
configData, err := config.Marshal()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -1,8 +1,20 @@
|
||||
package cmd
|
||||
|
||||
const (
|
||||
OverlayGRSC = byte(0x95)
|
||||
OverlayGRSU = byte(0x27)
|
||||
)
|
||||
func NewShortID(isGRSC bool, id byte) byte {
|
||||
if id > 0x80 {
|
||||
panic("id should be less than 128")
|
||||
}
|
||||
if isGRSC {
|
||||
return id
|
||||
}
|
||||
return 0x80 | id
|
||||
}
|
||||
|
||||
func ParseShortID(shortID byte) (isGRSC bool, id byte) {
|
||||
if shortID >= 0x80 {
|
||||
return false, shortID & 0x7f
|
||||
}
|
||||
return true, shortID
|
||||
}
|
||||
|
||||
var ConfigDataPlaceholder = []byte{0xff, 0xff, 'g', 'r', 's', 'c', 'o', 'n', 'f', 'i', 'g', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
|
@ -45,7 +45,7 @@ type client struct {
|
||||
|
||||
func (c *client) serve() error {
|
||||
c.logger.Infoln("try connect to server")
|
||||
client, err := reality.NewClient(context.Background(), c.config, cmd.OverlayGRSC)
|
||||
client, err := reality.NewClient(context.Background(), c.config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -4,8 +4,10 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
utls "github.com/refraction-networking/utls"
|
||||
|
||||
@ -19,6 +21,7 @@ type gen struct {
|
||||
FingerPrint string `short:"f" default:"chrome" description:"client finger print" choice:"chrome" choice:"firefox" choice:"safari" choice:"ios" choice:"android" choice:"edge" choice:"360" choice:"qq"`
|
||||
ExpireSecond uint32 `short:"e" default:"30" description:"expire second"`
|
||||
ConfigPath string `short:"o" default:"config.json" description:"server config output path"`
|
||||
ClientCount byte `short:"c" default:"3" description:"client count"`
|
||||
ClientOutputDir string `long:"dir" default:"." description:"client output directory"`
|
||||
Positional struct {
|
||||
SNIAddr string `description:"tls server address, e.g. example.com:443"`
|
||||
@ -32,6 +35,11 @@ func (c *gen) Execute(args []string) error {
|
||||
c.logger = reality.GetLogger(c.Debug)
|
||||
var config *reality.ServerConfig
|
||||
var err error
|
||||
if c.ClientCount > 128 {
|
||||
return errors.New("client count must less than 128")
|
||||
} else if c.ClientCount == 0 {
|
||||
c.ClientCount = 1
|
||||
}
|
||||
if c.Positional.SNIAddr == "" || c.Positional.ServerAddr == "" {
|
||||
c.logger.Infof("try loading config, path %s", c.ConfigPath)
|
||||
config, err = loadConfig(c.ConfigPath)
|
||||
@ -52,7 +60,7 @@ func (c *gen) Execute(args []string) error {
|
||||
if err := c.check(); err != nil {
|
||||
return err
|
||||
}
|
||||
return c.genClient(config.ToClientConfig())
|
||||
return c.genClient(config.ToClientConfig(0))
|
||||
|
||||
}
|
||||
|
||||
@ -118,6 +126,28 @@ func (c *gen) genClient(clientConfig *reality.ClientConfig) error {
|
||||
}
|
||||
|
||||
for _, name := range AssetNames() {
|
||||
if strings.HasPrefix(name, "grsc") {
|
||||
// 根据客户端数量生成多个客户端
|
||||
for i := 0; i < int(c.ClientCount); i++ {
|
||||
path := filepath.Join(c.ClientOutputDir, fmt.Sprintf("grsc%d%s", i, name[4:]))
|
||||
clientConfig.OverlayData = cmd.NewShortID(true, byte(i))
|
||||
clientConfigData, err := clientConfig.Marshal()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ClientBin, err := replaceClientTemplate(MustAsset(name), clientConfigData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.WriteFile(path, ClientBin, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
c.logger.Infof("generated %s", path)
|
||||
}
|
||||
continue
|
||||
}
|
||||
path := filepath.Join(c.ClientOutputDir, name)
|
||||
ClientBin, err := replaceClientTemplate(MustAsset(name), configData)
|
||||
if err != nil {
|
||||
|
161
cmd/grss/serv.go
161
cmd/grss/serv.go
@ -1,7 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
@ -27,19 +26,81 @@ func (s *serv) Execute(args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type sessionManager struct {
|
||||
logger logrus.FieldLogger
|
||||
sessions [128]*yamux.Session
|
||||
sessionsLock [128]sync.Mutex
|
||||
}
|
||||
|
||||
func (s *sessionManager) createSession(conn net.Conn, id byte) {
|
||||
if s.isSessionOpen(id) {
|
||||
s.logger.Errorf("client(id:%d) session already open, close %s", id, conn.RemoteAddr())
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
s.sessionsLock[id].Lock()
|
||||
defer s.sessionsLock[id].Unlock()
|
||||
session, err := yamux.Server(conn, nil)
|
||||
if err != nil {
|
||||
s.logger.Error(err)
|
||||
conn.Close()
|
||||
}
|
||||
go s.checkSession(id, session)
|
||||
s.sessions[id] = session
|
||||
s.logger.Infof("client(id:%d) session opened %s", id, conn.RemoteAddr())
|
||||
}
|
||||
|
||||
func (s *sessionManager) isSessionOpen(id byte) bool {
|
||||
s.sessionsLock[id].Lock()
|
||||
defer s.sessionsLock[id].Unlock()
|
||||
session := s.sessions[id]
|
||||
if session != nil {
|
||||
return !session.IsClosed()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *sessionManager) openClientSessionStream(id byte) (*yamux.Stream, error) {
|
||||
s.sessionsLock[id].Lock()
|
||||
defer s.sessionsLock[id].Unlock()
|
||||
session := s.sessions[id]
|
||||
if session != nil {
|
||||
stream, err := session.OpenStream()
|
||||
if err != nil {
|
||||
session.Close()
|
||||
s.sessions[id] = nil
|
||||
return nil, err
|
||||
}
|
||||
return stream, nil
|
||||
}
|
||||
return nil, fmt.Errorf("client(id:%d) session not open", id)
|
||||
}
|
||||
|
||||
func (s *sessionManager) checkSession(id byte, session *yamux.Session) {
|
||||
<-session.CloseChan()
|
||||
s.logger.Infof("client session closed %s", session.RemoteAddr())
|
||||
s.sessionsLock[id].Lock()
|
||||
defer s.sessionsLock[id].Unlock()
|
||||
if s.sessions[id] == session {
|
||||
s.sessions[id] = nil
|
||||
}
|
||||
}
|
||||
|
||||
// Server 反向socks5代理服务端
|
||||
type Server struct {
|
||||
config *reality.ServerConfig
|
||||
logger logrus.FieldLogger
|
||||
session *yamux.Session
|
||||
sessionLock *sync.Mutex
|
||||
config *reality.ServerConfig
|
||||
logger logrus.FieldLogger
|
||||
sm *sessionManager
|
||||
}
|
||||
|
||||
func NewServer(config *reality.ServerConfig) *Server {
|
||||
logger := reality.GetLogger(config.Debug)
|
||||
return &Server{
|
||||
config: config,
|
||||
logger: reality.GetLogger(config.Debug),
|
||||
sessionLock: &sync.Mutex{},
|
||||
config: config,
|
||||
logger: logger,
|
||||
sm: &sessionManager{
|
||||
logger: logger,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,66 +124,48 @@ func (s *Server) Serve() {
|
||||
}
|
||||
|
||||
if o, ok := conn.(reality.OverlayData); ok {
|
||||
overlayData := o.OverlayData()
|
||||
isGRSC, id := cmd.ParseShortID(o.OverlayData())
|
||||
if isGRSC {
|
||||
s.logger.Infof("accept client(id:%d) %s", id, conn.RemoteAddr())
|
||||
|
||||
if overlayData == cmd.OverlayGRSC {
|
||||
s.logger.Infof("accept client %s", conn.RemoteAddr())
|
||||
go s.handleClient(conn)
|
||||
go s.sm.createSession(conn, id)
|
||||
continue
|
||||
} else if overlayData == cmd.OverlayGRSU {
|
||||
s.logger.Infof("accept user %s", conn.RemoteAddr())
|
||||
go s.handleUser(conn)
|
||||
} else {
|
||||
s.logger.Infof("accept user(id:%d) %s", id, conn.RemoteAddr())
|
||||
go s.handleUser(conn, id)
|
||||
continue
|
||||
}
|
||||
}
|
||||
s.logger.Warnf("accept %s, but overlay wrong", conn.RemoteAddr())
|
||||
s.logger.Warnf("accept %s, but no overlay data", conn.RemoteAddr())
|
||||
conn.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) handleClient(conn net.Conn) {
|
||||
if s.isSessionOpen() {
|
||||
s.logger.Errorf("client session already open, close %s", conn.RemoteAddr())
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
s.sessionLock.Lock()
|
||||
defer s.sessionLock.Unlock()
|
||||
session, err := yamux.Server(conn, nil)
|
||||
if err != nil {
|
||||
s.logger.Error(err)
|
||||
conn.Close()
|
||||
}
|
||||
go s.checkSession(session)
|
||||
s.session = session
|
||||
s.logger.Infof("session opened %s", conn.RemoteAddr())
|
||||
}
|
||||
|
||||
func (s *Server) handleUser(conn net.Conn) {
|
||||
func (s *Server) handleUser(conn net.Conn, id byte) {
|
||||
defer conn.Close()
|
||||
|
||||
session, err := yamux.Client(conn, nil)
|
||||
if err != nil {
|
||||
s.logger.Errorf("yamux: %v", err)
|
||||
s.logger.Errorf("user(id:%d) yamux: %v", id, err)
|
||||
return
|
||||
}
|
||||
defer session.Close()
|
||||
for {
|
||||
stream, err := session.Accept()
|
||||
if err != nil {
|
||||
s.logger.Errorf("user session accept: %v", err)
|
||||
s.logger.Errorf("user(id:%d) session accept: %v", id, err)
|
||||
return
|
||||
}
|
||||
s.logger.Infof("user stream accept %s", stream.RemoteAddr())
|
||||
go s.handleUserStream(stream)
|
||||
s.logger.Infof("user(id:%d) stream accept %s", id, stream.RemoteAddr())
|
||||
go s.handleUserStream(stream, id)
|
||||
|
||||
}
|
||||
}
|
||||
func (s *Server) handleUserStream(stream net.Conn) {
|
||||
func (s *Server) handleUserStream(stream net.Conn, id byte) {
|
||||
defer stream.Close()
|
||||
conn, err := s.openClientSessionStream()
|
||||
conn, err := s.sm.openClientSessionStream(id)
|
||||
if err != nil {
|
||||
s.logger.Errorf("open client session stream: %v", err)
|
||||
s.logger.Errorf("open client(id:%d) session stream: %v", id, err)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
@ -130,37 +173,3 @@ func (s *Server) handleUserStream(stream net.Conn) {
|
||||
io.Copy(stream, conn)
|
||||
|
||||
}
|
||||
|
||||
func (s *Server) isSessionOpen() bool {
|
||||
s.sessionLock.Lock()
|
||||
defer s.sessionLock.Unlock()
|
||||
if s.session != nil {
|
||||
return !s.session.IsClosed()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Server) openClientSessionStream() (*yamux.Stream, error) {
|
||||
s.sessionLock.Lock()
|
||||
defer s.sessionLock.Unlock()
|
||||
if s.session != nil {
|
||||
stream, err := s.session.OpenStream()
|
||||
if err != nil {
|
||||
s.session.Close()
|
||||
s.session = nil
|
||||
return nil, err
|
||||
}
|
||||
return stream, nil
|
||||
}
|
||||
return nil, errors.New("client session not open")
|
||||
}
|
||||
|
||||
func (s *Server) checkSession(session *yamux.Session) {
|
||||
<-session.CloseChan()
|
||||
s.logger.Infof("client session closed %s", session.RemoteAddr())
|
||||
s.sessionLock.Lock()
|
||||
defer s.sessionLock.Unlock()
|
||||
if s.session == session {
|
||||
s.session = nil
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ func (s *serverSession) connectForever() {
|
||||
}
|
||||
func (s *serverSession) connect() {
|
||||
logger := s.logger
|
||||
client, err := reality.NewClient(context.Background(), s.config, cmd.OverlayGRSU)
|
||||
client, err := reality.NewClient(context.Background(), s.config)
|
||||
if err != nil {
|
||||
logger.Errorf("connect server: %v", err)
|
||||
return
|
||||
@ -76,10 +76,12 @@ func main() {
|
||||
println(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
addr := flag.String("l", "127.0.0.1:61080", "socks5 listen address")
|
||||
flag.Parse()
|
||||
logger := reality.GetLogger(config.Debug)
|
||||
addr := flag.String("l", "127.0.0.1:61080", "socks5 listen address")
|
||||
id := flag.Uint("i", 0, "id")
|
||||
flag.Parse()
|
||||
logger.Infof("server addr: %s, sni: %s, id: %d", config.ServerAddr, config.SNI, byte(*id))
|
||||
config.OverlayData = cmd.NewShortID(false, byte(*id))
|
||||
l, err := net.Listen("tcp", *addr)
|
||||
if err != nil {
|
||||
logger.Panic(err)
|
||||
|
@ -27,7 +27,7 @@ func main() {
|
||||
logger.Panic(err)
|
||||
}
|
||||
|
||||
client, err := reality.NewClient(context.Background(), &config, 0)
|
||||
client, err := reality.NewClient(context.Background(), &config)
|
||||
if err != nil {
|
||||
logger.Panic(err)
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ func main() {
|
||||
log.Panic(err)
|
||||
}
|
||||
config.Debug = true
|
||||
jsonData, err := json.MarshalIndent(config.ToClientConfig(), "", " ")
|
||||
jsonData, err := json.MarshalIndent(config.ToClientConfig(0), "", " ")
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ func (c *ServerConfig) SNIHost() string {
|
||||
func (c *ServerConfig) SNIPort() string {
|
||||
return c.sniPort
|
||||
}
|
||||
func (s *ServerConfig) ToClientConfig() *ClientConfig {
|
||||
func (s *ServerConfig) ToClientConfig(overlayData byte) *ClientConfig {
|
||||
|
||||
return &ClientConfig{
|
||||
SNI: s.sniHost,
|
||||
@ -116,6 +116,7 @@ func (s *ServerConfig) ToClientConfig() *ClientConfig {
|
||||
ExpireSecond: s.ExpireSecond,
|
||||
Debug: s.Debug,
|
||||
FingerPrint: s.ClientFingerPrint,
|
||||
OverlayData: overlayData,
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user