mirror of
https://github.com/cedar2025/hysteria.git
synced 2025-06-08 13:29:56 +00:00

This commit rewrites proxymux package to provide following functions: + proxymux.ListenSOCKS(address string) + proxymux.ListenHTTP(address string) both are drop-in replacements for net.Listen("tcp", address) The above functions can be called with the same address to take advantage of the mux feature. Tests are not included, but we will have them very soon. This commit should be in PR #1006, but I ended up with it in a separate branch here. Please rebase if you want to merge it.
73 lines
1.3 KiB
Go
73 lines
1.3 KiB
Go
package proxymux
|
|
|
|
import (
|
|
"net"
|
|
"sync"
|
|
|
|
"github.com/apernet/hysteria/extras/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()
|
|
}
|