mirror of
https://github.com/apernet/hysteria.git
synced 2025-04-03 20:47:38 +03:00
72 lines
1.3 KiB
Go
72 lines
1.3 KiB
Go
package proxymux
|
|
|
|
import (
|
|
"net"
|
|
"sync"
|
|
|
|
"github.com/apernet/hysteria/extras/v2/correctnet"
|
|
)
|
|
|
|
type muxManager struct {
|
|
listeners map[string]*muxListener
|
|
lock sync.Mutex
|
|
}
|
|
|
|
var globalMuxManager *muxManager
|
|
|
|
func init() {
|
|
globalMuxManager = &muxManager{
|
|
listeners: make(map[string]*muxListener),
|
|
}
|
|
}
|
|
|
|
func (m *muxManager) GetOrCreate(address string) (*muxListener, error) {
|
|
key, err := m.canonicalizeAddrPort(address)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
m.lock.Lock()
|
|
defer m.lock.Unlock()
|
|
|
|
if ml, ok := m.listeners[key]; ok {
|
|
return ml, nil
|
|
}
|
|
|
|
listener, err := correctnet.Listen("tcp", key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
ml := newMuxListener(listener, func() {
|
|
m.lock.Lock()
|
|
defer m.lock.Unlock()
|
|
delete(m.listeners, key)
|
|
})
|
|
m.listeners[key] = ml
|
|
return ml, nil
|
|
}
|
|
|
|
func (m *muxManager) canonicalizeAddrPort(address string) (string, error) {
|
|
taddr, err := net.ResolveTCPAddr("tcp", address)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return taddr.String(), nil
|
|
}
|
|
|
|
func ListenHTTP(address string) (net.Listener, error) {
|
|
ml, err := globalMuxManager.GetOrCreate(address)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return ml.ListenHTTP()
|
|
}
|
|
|
|
func ListenSOCKS(address string) (net.Listener, error) {
|
|
ml, err := globalMuxManager.GetOrCreate(address)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return ml.ListenSOCKS()
|
|
}
|