github.com/eagleql/xray-core@v1.4.4/common/mux/session.go (about)

     1  package mux
     2  
     3  import (
     4  	"sync"
     5  
     6  	"github.com/eagleql/xray-core/common"
     7  	"github.com/eagleql/xray-core/common/buf"
     8  	"github.com/eagleql/xray-core/common/net"
     9  	"github.com/eagleql/xray-core/common/protocol"
    10  )
    11  
    12  type SessionManager struct {
    13  	sync.RWMutex
    14  	sessions map[uint16]*Session
    15  	count    uint16
    16  	closed   bool
    17  }
    18  
    19  func NewSessionManager() *SessionManager {
    20  	return &SessionManager{
    21  		count:    0,
    22  		sessions: make(map[uint16]*Session, 16),
    23  	}
    24  }
    25  
    26  func (m *SessionManager) Closed() bool {
    27  	m.RLock()
    28  	defer m.RUnlock()
    29  
    30  	return m.closed
    31  }
    32  
    33  func (m *SessionManager) Size() int {
    34  	m.RLock()
    35  	defer m.RUnlock()
    36  
    37  	return len(m.sessions)
    38  }
    39  
    40  func (m *SessionManager) Count() int {
    41  	m.RLock()
    42  	defer m.RUnlock()
    43  
    44  	return int(m.count)
    45  }
    46  
    47  func (m *SessionManager) Allocate() *Session {
    48  	m.Lock()
    49  	defer m.Unlock()
    50  
    51  	if m.closed {
    52  		return nil
    53  	}
    54  
    55  	m.count++
    56  	s := &Session{
    57  		ID:     m.count,
    58  		parent: m,
    59  	}
    60  	m.sessions[s.ID] = s
    61  	return s
    62  }
    63  
    64  func (m *SessionManager) Add(s *Session) {
    65  	m.Lock()
    66  	defer m.Unlock()
    67  
    68  	if m.closed {
    69  		return
    70  	}
    71  
    72  	m.count++
    73  	m.sessions[s.ID] = s
    74  }
    75  
    76  func (m *SessionManager) Remove(id uint16) {
    77  	m.Lock()
    78  	defer m.Unlock()
    79  
    80  	if m.closed {
    81  		return
    82  	}
    83  
    84  	delete(m.sessions, id)
    85  
    86  	if len(m.sessions) == 0 {
    87  		m.sessions = make(map[uint16]*Session, 16)
    88  	}
    89  }
    90  
    91  func (m *SessionManager) Get(id uint16) (*Session, bool) {
    92  	m.RLock()
    93  	defer m.RUnlock()
    94  
    95  	if m.closed {
    96  		return nil, false
    97  	}
    98  
    99  	s, found := m.sessions[id]
   100  	return s, found
   101  }
   102  
   103  func (m *SessionManager) CloseIfNoSession() bool {
   104  	m.Lock()
   105  	defer m.Unlock()
   106  
   107  	if m.closed {
   108  		return true
   109  	}
   110  
   111  	if len(m.sessions) != 0 {
   112  		return false
   113  	}
   114  
   115  	m.closed = true
   116  	return true
   117  }
   118  
   119  func (m *SessionManager) Close() error {
   120  	m.Lock()
   121  	defer m.Unlock()
   122  
   123  	if m.closed {
   124  		return nil
   125  	}
   126  
   127  	m.closed = true
   128  
   129  	for _, s := range m.sessions {
   130  		common.Close(s.input)
   131  		common.Close(s.output)
   132  	}
   133  
   134  	m.sessions = nil
   135  	return nil
   136  }
   137  
   138  // Session represents a client connection in a Mux connection.
   139  type Session struct {
   140  	input        buf.Reader
   141  	output       buf.Writer
   142  	parent       *SessionManager
   143  	ID           uint16
   144  	transferType protocol.TransferType
   145  }
   146  
   147  // Close closes all resources associated with this session.
   148  func (s *Session) Close() error {
   149  	common.Close(s.output)
   150  	common.Close(s.input)
   151  	s.parent.Remove(s.ID)
   152  	return nil
   153  }
   154  
   155  // NewReader creates a buf.Reader based on the transfer type of this Session.
   156  func (s *Session) NewReader(reader *buf.BufferedReader, dest *net.Destination) buf.Reader {
   157  	if s.transferType == protocol.TransferTypeStream {
   158  		return NewStreamReader(reader)
   159  	}
   160  	return NewPacketReader(reader, dest)
   161  }