1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-06-25 17:05:23 +00:00

refactor mux

This commit is contained in:
Darien Raymond 2017-04-05 14:13:26 +02:00
parent 0a15bceb55
commit 4d682c01e0
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169

View File

@ -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 {