mirror of https://github.com/cbeuw/Cloak
Support session per connection mode (like GoQuiet) when NumConn = 0.
This commit is contained in:
parent
98a7b731f3
commit
dab137dbd7
|
|
@ -81,7 +81,7 @@ Example:
|
||||||
|
|
||||||
`ServerName` is the domain you want to make your ISP or firewall think you are visiting.
|
`ServerName` is the domain you want to make your ISP or firewall think you are visiting.
|
||||||
|
|
||||||
`NumConn` is the amount of underlying TCP connections you want to use. The default of 4 should be appropriate for most people. Setting it too high will hinder the performance.
|
`NumConn` is the amount of underlying TCP connections you want to use. The default of 4 should be appropriate for most people. Setting it too high will hinder the performance. Setting it to 0 will disable connection multiplexing and each TCP connection will spawn a separate short lived session that will be closed after it is terminated. This makes it behave like GoQuiet. This maybe useful for people with unstable connections.
|
||||||
|
|
||||||
`BrowserSig` is the browser you want to **appear** to be using. It's not relevant to the browser you are actually using. Currently, `chrome` and `firefox` are supported.
|
`BrowserSig` is the browser you want to **appear** to be using. It's not relevant to the browser you are actually using. Currently, `chrome` and `firefox` are supported.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -169,18 +169,20 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useSessionPerConnection := remoteConfig.NumConn == 0
|
||||||
|
|
||||||
if authInfo.Unordered {
|
if authInfo.Unordered {
|
||||||
acceptor := func() (*net.UDPConn, error) {
|
acceptor := func() (*net.UDPConn, error) {
|
||||||
udpAddr, _ := net.ResolveUDPAddr("udp", localConfig.LocalAddr)
|
udpAddr, _ := net.ResolveUDPAddr("udp", localConfig.LocalAddr)
|
||||||
return net.ListenUDP("udp", udpAddr)
|
return net.ListenUDP("udp", udpAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
client.RouteUDP(acceptor, localConfig.Timeout, seshMaker)
|
client.RouteUDP(acceptor, localConfig.Timeout, seshMaker, useSessionPerConnection)
|
||||||
} else {
|
} else {
|
||||||
listener, err := net.Listen("tcp", localConfig.LocalAddr)
|
listener, err := net.Listen("tcp", localConfig.LocalAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
client.RouteTCP(listener, localConfig.Timeout, seshMaker)
|
client.RouteTCP(listener, localConfig.Timeout, seshMaker, useSessionPerConnection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,16 @@ func MakeSession(connConfig RemoteConnConfig, authInfo AuthInfo, dialer common.D
|
||||||
authInfo.SessionId = 0
|
authInfo.SessionId = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
connsCh := make(chan net.Conn, connConfig.NumConn)
|
numConn := connConfig.NumConn
|
||||||
|
if numConn <= 0 {
|
||||||
|
log.Infof("Using session per connection (no multiplexing)")
|
||||||
|
numConn = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
connsCh := make(chan net.Conn, numConn)
|
||||||
var _sessionKey atomic.Value
|
var _sessionKey atomic.Value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
for i := 0; i < connConfig.NumConn; i++ {
|
for i := 0; i < numConn; i++ {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
makeconn:
|
makeconn:
|
||||||
|
|
@ -70,7 +76,7 @@ func MakeSession(connConfig RemoteConnConfig, authInfo AuthInfo, dialer common.D
|
||||||
}
|
}
|
||||||
sesh := mux.MakeSession(authInfo.SessionId, seshConfig)
|
sesh := mux.MakeSession(authInfo.SessionId, seshConfig)
|
||||||
|
|
||||||
for i := 0; i < connConfig.NumConn; i++ {
|
for i := 0; i < numConn; i++ {
|
||||||
conn := <-connsCh
|
conn := <-connsCh
|
||||||
sesh.AddConnection(conn)
|
sesh.AddConnection(conn)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,31 @@ import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RouteUDP(bindFunc func() (*net.UDPConn, error), streamTimeout time.Duration, newSeshFunc func() *mux.Session) {
|
type ConnWithReadFromTimeout interface {
|
||||||
|
net.Conn
|
||||||
|
SetReadFromTimeout(d time.Duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
type CloseSessionAfterCloseStream struct {
|
||||||
|
ConnWithReadFromTimeout
|
||||||
|
Session *mux.Session
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CloseSessionAfterCloseStream) Close() error {
|
||||||
|
if err := s.ConnWithReadFromTimeout.Close(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return s.Session.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func RouteUDP(bindFunc func() (*net.UDPConn, error), streamTimeout time.Duration, newSeshFunc func() *mux.Session, useSessionPerConnection bool) {
|
||||||
var sesh *mux.Session
|
var sesh *mux.Session
|
||||||
localConn, err := bindFunc()
|
localConn, err := bindFunc()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
streams := make(map[string]*mux.Stream)
|
streams := make(map[string]ConnWithReadFromTimeout)
|
||||||
|
|
||||||
data := make([]byte, 8192)
|
data := make([]byte, 8192)
|
||||||
for {
|
for {
|
||||||
|
|
@ -27,17 +44,34 @@ func RouteUDP(bindFunc func() (*net.UDPConn, error), streamTimeout time.Duration
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if sesh == nil || sesh.IsClosed() {
|
if !useSessionPerConnection && (sesh == nil || sesh.IsClosed()) {
|
||||||
sesh = newSeshFunc()
|
sesh = newSeshFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var stream ConnWithReadFromTimeout
|
||||||
stream, ok := streams[addr.String()]
|
stream, ok := streams[addr.String()]
|
||||||
if !ok {
|
if !ok {
|
||||||
stream, err = sesh.OpenStream()
|
connectionSession := sesh
|
||||||
|
if useSessionPerConnection {
|
||||||
|
connectionSession = newSeshFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
stream, err = connectionSession.OpenStream()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Failed to open stream: %v", err)
|
log.Errorf("Failed to open stream: %v", err)
|
||||||
|
if useSessionPerConnection {
|
||||||
|
connectionSession.Close()
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if useSessionPerConnection {
|
||||||
|
stream = &CloseSessionAfterCloseStream{
|
||||||
|
ConnWithReadFromTimeout: stream,
|
||||||
|
Session: connectionSession,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
streams[addr.String()] = stream
|
streams[addr.String()] = stream
|
||||||
proxyAddr := addr
|
proxyAddr := addr
|
||||||
go func() {
|
go func() {
|
||||||
|
|
@ -70,7 +104,7 @@ func RouteUDP(bindFunc func() (*net.UDPConn, error), streamTimeout time.Duration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func RouteTCP(listener net.Listener, streamTimeout time.Duration, newSeshFunc func() *mux.Session) {
|
func RouteTCP(listener net.Listener, streamTimeout time.Duration, newSeshFunc func() *mux.Session, useSessionPerConnection bool) {
|
||||||
var sesh *mux.Session
|
var sesh *mux.Session
|
||||||
for {
|
for {
|
||||||
localConn, err := listener.Accept()
|
localConn, err := listener.Accept()
|
||||||
|
|
@ -78,7 +112,7 @@ func RouteTCP(listener net.Listener, streamTimeout time.Duration, newSeshFunc fu
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if sesh == nil || sesh.IsClosed() {
|
if !useSessionPerConnection && (sesh == nil || sesh.IsClosed()) {
|
||||||
sesh = newSeshFunc()
|
sesh = newSeshFunc()
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
|
|
@ -89,12 +123,30 @@ func RouteTCP(listener net.Listener, streamTimeout time.Duration, newSeshFunc fu
|
||||||
localConn.Close()
|
localConn.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
stream, err := sesh.OpenStream()
|
|
||||||
|
connectionSession := sesh
|
||||||
|
if useSessionPerConnection {
|
||||||
|
connectionSession = newSeshFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
var stream ConnWithReadFromTimeout
|
||||||
|
stream, err = connectionSession.OpenStream()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Failed to open stream: %v", err)
|
log.Errorf("Failed to open stream: %v", err)
|
||||||
localConn.Close()
|
localConn.Close()
|
||||||
|
if useSessionPerConnection {
|
||||||
|
connectionSession.Close()
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if useSessionPerConnection {
|
||||||
|
stream = &CloseSessionAfterCloseStream{
|
||||||
|
ConnWithReadFromTimeout: stream,
|
||||||
|
Session: connectionSession,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_, err = stream.Write(data[:i])
|
_, err = stream.Write(data[:i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Failed to write to stream: %v", err)
|
log.Errorf("Failed to write to stream: %v", err)
|
||||||
|
|
|
||||||
|
|
@ -172,8 +172,8 @@ func (raw *RawConfig) SplitConfigs(worldState common.WorldState) (local LocalCon
|
||||||
return nullErr("RemotePort")
|
return nullErr("RemotePort")
|
||||||
}
|
}
|
||||||
remote.RemoteAddr = net.JoinHostPort(raw.RemoteHost, raw.RemotePort)
|
remote.RemoteAddr = net.JoinHostPort(raw.RemoteHost, raw.RemotePort)
|
||||||
if raw.NumConn == 0 {
|
if raw.NumConn <= 0 {
|
||||||
return nullErr("NumConn")
|
raw.NumConn = 0
|
||||||
}
|
}
|
||||||
remote.NumConn = raw.NumConn
|
remote.NumConn = raw.NumConn
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,7 @@ func establishSession(lcc client.LocalConnConfig, rcc client.RemoteConnConfig, a
|
||||||
return client.MakeSession(rcc, ai, ckClientDialer, false)
|
return client.MakeSession(rcc, ai, ckClientDialer, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useSessionPerConnection := rcc.NumConn == 0
|
||||||
var proxyToCkClientD common.Dialer
|
var proxyToCkClientD common.Dialer
|
||||||
if ai.Unordered {
|
if ai.Unordered {
|
||||||
addrCh := make(chan *net.UDPAddr, 1)
|
addrCh := make(chan *net.UDPAddr, 1)
|
||||||
|
|
@ -151,12 +152,12 @@ func establishSession(lcc client.LocalConnConfig, rcc client.RemoteConnConfig, a
|
||||||
addrCh <- conn.LocalAddr().(*net.UDPAddr)
|
addrCh <- conn.LocalAddr().(*net.UDPAddr)
|
||||||
return conn, err
|
return conn, err
|
||||||
}
|
}
|
||||||
go client.RouteUDP(acceptor, lcc.Timeout, clientSeshMaker)
|
go client.RouteUDP(acceptor, lcc.Timeout, clientSeshMaker, useSessionPerConnection)
|
||||||
proxyToCkClientD = mDialer
|
proxyToCkClientD = mDialer
|
||||||
} else {
|
} else {
|
||||||
var proxyToCkClientL *connutil.PipeListener
|
var proxyToCkClientL *connutil.PipeListener
|
||||||
proxyToCkClientD, proxyToCkClientL = connutil.DialerListener(10 * 1024)
|
proxyToCkClientD, proxyToCkClientL = connutil.DialerListener(10 * 1024)
|
||||||
go client.RouteTCP(proxyToCkClientL, lcc.Timeout, clientSeshMaker)
|
go client.RouteTCP(proxyToCkClientL, lcc.Timeout, clientSeshMaker, useSessionPerConnection)
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up server
|
// set up server
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue