close timer faster

pull/182/merge
Darien Raymond 2017-05-09 00:01:15 +02:00
parent aea71c2aa8
commit 5829b45bbe
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
12 changed files with 96 additions and 90 deletions

View File

@ -141,11 +141,14 @@ func (h *DynamicInboundHandler) refresh() error {
} }
func (h *DynamicInboundHandler) monitor() { func (h *DynamicInboundHandler) monitor() {
timer := time.NewTicker(time.Minute * time.Duration(h.receiverConfig.AllocationStrategy.GetRefreshValue()))
defer timer.Stop()
for { for {
select { select {
case <-h.ctx.Done(): case <-h.ctx.Done():
return return
case <-time.After(time.Minute * time.Duration(h.receiverConfig.AllocationStrategy.GetRefreshValue())): case <-timer.C:
h.refresh() h.refresh()
} }
} }

View File

@ -278,11 +278,14 @@ func (w *udpWorker) Close() {
} }
func (w *udpWorker) monitor() { func (w *udpWorker) monitor() {
timer := time.NewTicker(time.Second * 16)
defer timer.Stop()
for { for {
select { select {
case <-w.ctx.Done(): case <-w.ctx.Done():
return return
case <-time.After(time.Second * 16): case <-timer.C:
nowSec := time.Now().Unix() nowSec := time.Now().Unix()
w.Lock() w.Lock()
for addr, conn := range w.activeConn { for addr, conn := range w.activeConn {

View File

@ -115,6 +115,9 @@ func (m *Client) Closed() bool {
func (m *Client) monitor() { func (m *Client) monitor() {
defer m.manager.onClientFinish() defer m.manager.onClientFinish()
timer := time.NewTicker(time.Second * 16)
defer timer.Stop()
for { for {
select { select {
case <-m.ctx.Done(): case <-m.ctx.Done():
@ -122,7 +125,7 @@ func (m *Client) monitor() {
m.inboundRay.InboundInput().Close() m.inboundRay.InboundInput().Close()
m.inboundRay.InboundOutput().CloseError() m.inboundRay.InboundOutput().CloseError()
return return
case <-time.After(time.Second * 16): case <-timer.C:
size := m.sessionManager.Size() size := m.sessionManager.Size()
if size == 0 && m.sessionManager.CloseIfNoSession() { if size == 0 && m.sessionManager.CloseIfNoSession() {
m.cancel() m.cancel()

View File

@ -35,7 +35,7 @@ func (r *retryer) On(method func() error) error {
accumulatedError = append(accumulatedError, err) accumulatedError = append(accumulatedError, err)
} }
delay := r.nextDelay() delay := r.nextDelay()
<-time.After(time.Duration(delay) * time.Millisecond) time.Sleep(time.Duration(delay) * time.Millisecond)
attempt++ attempt++
} }
return newError(accumulatedError).Base(ErrRetryFailed) return newError(accumulatedError).Base(ErrRetryFailed)

View File

@ -100,7 +100,7 @@ func (*Server) handleUDP() error {
// The TCP connection closes after v method returns. We need to wait until // The TCP connection closes after v method returns. We need to wait until
// the client closes it. // the client closes it.
// TODO: get notified from UDP part // TODO: get notified from UDP part
<-time.After(5 * time.Minute) time.Sleep(5 * time.Minute)
return nil return nil
} }

View File

@ -34,7 +34,7 @@ func TestBuildAndRun(t *testing.T) {
cmd.Stderr = errBuffer cmd.Stderr = errBuffer
cmd.Start() cmd.Start()
<-time.After(1 * time.Second) time.Sleep(1 * time.Second)
cmd.Process.Kill() cmd.Process.Kill()
outStr := string(outBuffer.Bytes()) outStr := string(outBuffer.Bytes())

View File

@ -18,13 +18,7 @@ import (
func TestDialAndListen(t *testing.T) { func TestDialAndListen(t *testing.T) {
assert := assert.On(t) assert := assert.On(t)
conns := make(chan internet.Connection, 16) listerner, err := NewListener(internet.ContextWithTransportSettings(context.Background(), &Config{}), v2net.LocalHostIP, v2net.Port(0), func(ctx context.Context, conn internet.Connection) bool {
listerner, err := NewListener(internet.ContextWithTransportSettings(context.Background(), &Config{}), v2net.LocalHostIP, v2net.Port(0), conns)
assert.Error(err).IsNil()
port := v2net.Port(listerner.Addr().(*net.UDPAddr).Port)
go func() {
for conn := range conns {
go func(c internet.Connection) { go func(c internet.Connection) {
payload := make([]byte, 4096) payload := make([]byte, 4096)
for { for {
@ -39,8 +33,10 @@ func TestDialAndListen(t *testing.T) {
} }
c.Close() c.Close()
}(conn) }(conn)
} return true
}() })
assert.Error(err).IsNil()
port := v2net.Port(listerner.Addr().(*net.UDPAddr).Port)
ctx := internet.ContextWithTransportSettings(context.Background(), &Config{}) ctx := internet.ContextWithTransportSettings(context.Background(), &Config{})
wg := new(sync.WaitGroup) wg := new(sync.WaitGroup)
@ -76,5 +72,4 @@ func TestDialAndListen(t *testing.T) {
assert.Int(listerner.ActiveConnections()).Equals(0) assert.Int(listerner.ActiveConnections()).Equals(0)
listerner.Close() listerner.Close()
close(conns)
} }

View File

@ -81,10 +81,10 @@ type Listener struct {
reader PacketReader reader PacketReader
header internet.PacketHeader header internet.PacketHeader
security cipher.AEAD security cipher.AEAD
conns chan<- internet.Connection addConn internet.AddConnection
} }
func NewListener(ctx context.Context, address v2net.Address, port v2net.Port, conns chan<- internet.Connection) (*Listener, error) { func NewListener(ctx context.Context, address v2net.Address, port v2net.Port, addConn internet.AddConnection) (*Listener, error) {
networkSettings := internet.TransportSettingsFromContext(ctx) networkSettings := internet.TransportSettingsFromContext(ctx)
kcpSettings := networkSettings.(*Config) kcpSettings := networkSettings.(*Config)
@ -106,7 +106,7 @@ func NewListener(ctx context.Context, address v2net.Address, port v2net.Port, co
sessions: make(map[ConnectionID]*Connection), sessions: make(map[ConnectionID]*Connection),
ctx: ctx, ctx: ctx,
config: kcpSettings, config: kcpSettings,
conns: conns, addConn: addConn,
} }
securitySettings := internet.SecuritySettingsFromContext(ctx) securitySettings := internet.SecuritySettingsFromContext(ctx)
if securitySettings != nil { if securitySettings != nil {
@ -190,10 +190,7 @@ func (v *Listener) OnReceive(payload *buf.Buffer, src v2net.Destination, origina
netConn = tlsConn netConn = tlsConn
} }
select { if !v.addConn(context.Background(), netConn) {
case v.conns <- netConn:
case <-time.After(time.Second * 5):
conn.Close()
return return
} }
v.sessions[id] = conn v.sessions[id] = conn
@ -254,8 +251,8 @@ func (v *Writer) Close() error {
return nil return nil
} }
func ListenKCP(ctx context.Context, address v2net.Address, port v2net.Port, conns chan<- internet.Connection) (internet.Listener, error) { func ListenKCP(ctx context.Context, address v2net.Address, port v2net.Port, addConn internet.AddConnection) (internet.Listener, error) {
return NewListener(ctx, address, port, conns) return NewListener(ctx, address, port, addConn)
} }
func init() { func init() {

View File

@ -4,7 +4,6 @@ import (
"context" "context"
gotls "crypto/tls" gotls "crypto/tls"
"net" "net"
"time"
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/common" "v2ray.com/core/common"
@ -20,10 +19,10 @@ type TCPListener struct {
tlsConfig *gotls.Config tlsConfig *gotls.Config
authConfig internet.ConnectionAuthenticator authConfig internet.ConnectionAuthenticator
config *Config config *Config
conns chan<- internet.Connection addConn internet.AddConnection
} }
func ListenTCP(ctx context.Context, address v2net.Address, port v2net.Port, conns chan<- internet.Connection) (internet.Listener, error) { func ListenTCP(ctx context.Context, address v2net.Address, port v2net.Port, addConn internet.AddConnection) (internet.Listener, error) {
listener, err := net.ListenTCP("tcp", &net.TCPAddr{ listener, err := net.ListenTCP("tcp", &net.TCPAddr{
IP: address.IP(), IP: address.IP(),
Port: int(port), Port: int(port),
@ -39,7 +38,7 @@ func ListenTCP(ctx context.Context, address v2net.Address, port v2net.Port, conn
ctx: ctx, ctx: ctx,
listener: listener, listener: listener,
config: tcpSettings, config: tcpSettings,
conns: conns, addConn: addConn,
} }
if securitySettings := internet.SecuritySettingsFromContext(ctx); securitySettings != nil { if securitySettings := internet.SecuritySettingsFromContext(ctx); securitySettings != nil {
tlsConfig, ok := securitySettings.(*tls.Config) tlsConfig, ok := securitySettings.(*tls.Config)
@ -90,11 +89,7 @@ func (v *TCPListener) KeepAccepting() {
conn = v.authConfig.Server(conn) conn = v.authConfig.Server(conn)
} }
select { v.addConn(context.Background(), internet.Connection(conn))
case v.conns <- internet.Connection(conn):
case <-time.After(time.Second * 5):
conn.Close()
}
} }
} }

View File

@ -3,6 +3,7 @@ package internet
import ( import (
"context" "context"
"net" "net"
"time"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
) )
@ -19,7 +20,9 @@ func RegisterTransportListener(protocol TransportProtocol, listener ListenFunc)
return nil return nil
} }
type ListenFunc func(ctx context.Context, address v2net.Address, port v2net.Port, conns chan<- Connection) (Listener, error) type AddConnection func(context.Context, Connection) bool
type ListenFunc func(ctx context.Context, address v2net.Address, port v2net.Port, addConn AddConnection) (Listener, error)
type Listener interface { type Listener interface {
Close() error Close() error
@ -45,7 +48,26 @@ func ListenTCP(ctx context.Context, address v2net.Address, port v2net.Port, conn
if listenFunc == nil { if listenFunc == nil {
return nil, newError(protocol, " listener not registered.").AtError() return nil, newError(protocol, " listener not registered.").AtError()
} }
listener, err := listenFunc(ctx, address, port, conns) listener, err := listenFunc(ctx, address, port, func(ctx context.Context, conn Connection) bool {
select {
case <-ctx.Done():
conn.Close()
return false
case conns <- conn:
return true
default:
select {
case <-ctx.Done():
conn.Close()
return false
case conns <- conn:
return true
case <-time.After(time.Second * 5):
conn.Close()
return false
}
}
})
if err != nil { if err != nil {
return nil, newError("failed to listen on address: ", address, ":", port).Base(err) return nil, newError("failed to listen on address: ", address, ":", port).Base(err)
} }

View File

@ -7,7 +7,6 @@ import (
"net/http" "net/http"
"strconv" "strconv"
"sync" "sync"
"time"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
@ -33,13 +32,7 @@ func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Req
return return
} }
select { h.ln.addConn(h.ln.ctx, internet.Connection(conn))
case <-h.ln.ctx.Done():
conn.Close()
case h.ln.conns <- internet.Connection(conn):
case <-time.After(time.Second * 5):
conn.Close()
}
} }
type Listener struct { type Listener struct {
@ -48,17 +41,17 @@ type Listener struct {
listener net.Listener listener net.Listener
tlsConfig *tls.Config tlsConfig *tls.Config
config *Config config *Config
conns chan<- internet.Connection addConn internet.AddConnection
} }
func ListenWS(ctx context.Context, address v2net.Address, port v2net.Port, conns chan<- internet.Connection) (internet.Listener, error) { func ListenWS(ctx context.Context, address v2net.Address, port v2net.Port, addConn internet.AddConnection) (internet.Listener, error) {
networkSettings := internet.TransportSettingsFromContext(ctx) networkSettings := internet.TransportSettingsFromContext(ctx)
wsSettings := networkSettings.(*Config) wsSettings := networkSettings.(*Config)
l := &Listener{ l := &Listener{
ctx: ctx, ctx: ctx,
config: wsSettings, config: wsSettings,
conns: conns, addConn: addConn,
} }
if securitySettings := internet.SecuritySettingsFromContext(ctx); securitySettings != nil { if securitySettings := internet.SecuritySettingsFromContext(ctx); securitySettings != nil {
tlsConfig, ok := securitySettings.(*v2tls.Config) tlsConfig, ok := securitySettings.(*v2tls.Config)

View File

@ -16,13 +16,9 @@ import (
func Test_listenWSAndDial(t *testing.T) { func Test_listenWSAndDial(t *testing.T) {
assert := assert.On(t) assert := assert.On(t)
conns := make(chan internet.Connection, 16)
listen, err := ListenWS(internet.ContextWithTransportSettings(context.Background(), &Config{ listen, err := ListenWS(internet.ContextWithTransportSettings(context.Background(), &Config{
Path: "ws", Path: "ws",
}), v2net.DomainAddress("localhost"), 13146, conns) }), v2net.DomainAddress("localhost"), 13146, func(ctx context.Context, conn internet.Connection) bool {
assert.Error(err).IsNil()
go func() {
for conn := range conns {
go func(c internet.Connection) { go func(c internet.Connection) {
defer c.Close() defer c.Close()
@ -37,8 +33,9 @@ func Test_listenWSAndDial(t *testing.T) {
_, err = c.Write([]byte("Response")) _, err = c.Write([]byte("Response"))
assert.Error(err).IsNil() assert.Error(err).IsNil()
}(conn) }(conn)
} return true
}() })
assert.Error(err).IsNil()
ctx := internet.ContextWithTransportSettings(context.Background(), &Config{Path: "ws"}) ctx := internet.ContextWithTransportSettings(context.Background(), &Config{Path: "ws"})
conn, err := Dial(ctx, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13146)) conn, err := Dial(ctx, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13146))
@ -73,8 +70,6 @@ func Test_listenWSAndDial(t *testing.T) {
assert.Error(conn.Close()).IsNil() assert.Error(conn.Close()).IsNil()
assert.Error(listen.Close()).IsNil() assert.Error(listen.Close()).IsNil()
close(conns)
} }
func Test_listenWSAndDial_TLS(t *testing.T) { func Test_listenWSAndDial_TLS(t *testing.T) {
@ -91,14 +86,14 @@ func Test_listenWSAndDial_TLS(t *testing.T) {
AllowInsecure: true, AllowInsecure: true,
Certificate: []*v2tls.Certificate{tlsgen.GenerateCertificateForTest()}, Certificate: []*v2tls.Certificate{tlsgen.GenerateCertificateForTest()},
}) })
conns := make(chan internet.Connection, 16) listen, err := ListenWS(ctx, v2net.DomainAddress("localhost"), 13143, func(ctx context.Context, conn internet.Connection) bool {
listen, err := ListenWS(ctx, v2net.DomainAddress("localhost"), 13143, conns)
assert.Error(err).IsNil()
go func() { go func() {
conn := <-conns
conn.Close() conn.Close()
listen.Close()
}() }()
return true
})
assert.Error(err).IsNil()
defer listen.Close()
conn, err := Dial(ctx, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13143)) conn, err := Dial(ctx, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13143))
assert.Error(err).IsNil() assert.Error(err).IsNil()