mirror of https://github.com/v2ray/v2ray-core
refactor mux
parent
0a15bceb55
commit
4d682c01e0
|
@ -42,7 +42,7 @@ func (s *session) closeUplink() {
|
|||
allDone = s.uplinkClosed && s.downlinkClosed
|
||||
s.Unlock()
|
||||
if allDone {
|
||||
go s.parent.remove(s.id)
|
||||
s.parent.remove(s.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ func (s *session) closeDownlink() {
|
|||
allDone = s.uplinkClosed && s.downlinkClosed
|
||||
s.Unlock()
|
||||
if allDone {
|
||||
go s.parent.remove(s.id)
|
||||
s.parent.remove(s.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,13 +109,14 @@ func (m *ClientManager) onClientFinish() {
|
|||
}
|
||||
|
||||
type Client struct {
|
||||
access sync.RWMutex
|
||||
count uint16
|
||||
sessions map[uint16]*session
|
||||
inboundRay ray.InboundRay
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
manager *ClientManager
|
||||
access sync.RWMutex
|
||||
count uint16
|
||||
sessions map[uint16]*session
|
||||
inboundRay ray.InboundRay
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
manager *ClientManager
|
||||
session2Remove chan uint16
|
||||
}
|
||||
|
||||
var muxCoolDestination = net.TCPDestination(net.DomainAddress("v1.mux.cool"), net.Port(9527))
|
||||
|
@ -126,27 +127,24 @@ func NewClient(p proxy.Outbound, dialer proxy.Dialer, m *ClientManager) (*Client
|
|||
pipe := ray.NewRay(ctx)
|
||||
go p.Process(ctx, pipe, dialer)
|
||||
c := &Client{
|
||||
sessions: make(map[uint16]*session, 256),
|
||||
inboundRay: pipe,
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
manager: m,
|
||||
count: 0,
|
||||
sessions: make(map[uint16]*session, 256),
|
||||
inboundRay: pipe,
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
manager: m,
|
||||
count: 0,
|
||||
session2Remove: make(chan uint16, 16),
|
||||
}
|
||||
go c.fetchOutput()
|
||||
go c.monitor()
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (m *Client) remove(id uint16) {
|
||||
m.access.Lock()
|
||||
defer m.access.Unlock()
|
||||
|
||||
delete(m.sessions, id)
|
||||
|
||||
if len(m.sessions) == 0 {
|
||||
m.cancel()
|
||||
m.inboundRay.InboundInput().Close()
|
||||
go m.manager.onClientFinish()
|
||||
select {
|
||||
case m.session2Remove <- id:
|
||||
default:
|
||||
// Probably not gonna happen.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,6 +157,31 @@ func (m *Client) Closed() bool {
|
|||
}
|
||||
}
|
||||
|
||||
func (m *Client) monitor() {
|
||||
for {
|
||||
select {
|
||||
case <-m.ctx.Done():
|
||||
m.cleanup()
|
||||
return
|
||||
case id := <-m.session2Remove:
|
||||
m.access.Lock()
|
||||
delete(m.sessions, id)
|
||||
m.access.Unlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Client) cleanup() {
|
||||
m.access.Lock()
|
||||
defer m.access.Unlock()
|
||||
|
||||
for _, s := range m.sessions {
|
||||
s.closeUplink()
|
||||
s.closeDownlink()
|
||||
s.output.CloseError()
|
||||
}
|
||||
}
|
||||
|
||||
func fetchInput(ctx context.Context, s *session, output buf.Writer) {
|
||||
dest, _ := proxy.TargetFromContext(ctx)
|
||||
writer := &Writer{
|
||||
|
@ -242,6 +265,8 @@ func pipe(reader *Reader, writer buf.Writer) error {
|
|||
}
|
||||
|
||||
func (m *Client) fetchOutput() {
|
||||
defer m.cancel()
|
||||
|
||||
reader := NewReader(m.inboundRay.InboundOutput())
|
||||
for {
|
||||
meta, err := reader.ReadMetadata()
|
||||
|
@ -271,15 +296,6 @@ func (m *Client) fetchOutput() {
|
|||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Close all downlinks
|
||||
m.access.RLock()
|
||||
for _, s := range m.sessions {
|
||||
s.closeUplink()
|
||||
s.closeDownlink()
|
||||
s.output.CloseError()
|
||||
}
|
||||
m.access.RUnlock()
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
|
|
Loading…
Reference in New Issue