2021-09-06 02:03:27 -07:00
|
|
|
package proxy
|
2021-08-27 09:59:27 -07:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net"
|
2021-09-05 03:56:21 -07:00
|
|
|
"sync"
|
2021-08-27 09:59:27 -07:00
|
|
|
|
|
|
|
"github.com/anon55555/mt"
|
|
|
|
)
|
|
|
|
|
2021-09-06 02:03:27 -07:00
|
|
|
type Listener struct {
|
|
|
|
mt.Listener
|
2021-09-06 09:26:24 -07:00
|
|
|
mu sync.RWMutex
|
2021-09-05 03:56:21 -07:00
|
|
|
|
2021-09-06 02:03:27 -07:00
|
|
|
clts map[*ClientConn]struct{}
|
2021-08-27 09:59:27 -07:00
|
|
|
}
|
|
|
|
|
2021-09-06 02:03:27 -07:00
|
|
|
func Listen(pc net.PacketConn) *Listener {
|
|
|
|
return &Listener{
|
|
|
|
Listener: mt.Listen(pc),
|
2021-09-06 09:26:24 -07:00
|
|
|
clts: make(map[*ClientConn]struct{}),
|
2021-08-27 09:59:27 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-06 02:03:27 -07:00
|
|
|
func (l *Listener) Clts() map[*ClientConn]struct{} {
|
|
|
|
clts := make(map[*ClientConn]struct{})
|
|
|
|
|
|
|
|
l.mu.RLock()
|
|
|
|
defer l.mu.RUnlock()
|
2021-08-27 09:59:27 -07:00
|
|
|
|
2021-09-06 02:03:27 -07:00
|
|
|
for cc := range l.clts {
|
|
|
|
clts[cc] = struct{}{}
|
|
|
|
}
|
|
|
|
|
|
|
|
return clts
|
|
|
|
}
|
2021-08-27 09:59:27 -07:00
|
|
|
|
2021-09-06 02:03:27 -07:00
|
|
|
func (l *Listener) Accept() (*ClientConn, error) {
|
|
|
|
p, err := l.Listener.Accept()
|
2021-08-27 09:59:27 -07:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2021-09-06 02:03:27 -07:00
|
|
|
cc := &ClientConn{
|
2021-08-27 09:59:27 -07:00
|
|
|
Peer: p,
|
|
|
|
initCh: make(chan struct{}),
|
2021-09-01 04:27:53 -07:00
|
|
|
modChs: make(map[string]struct{}),
|
2021-08-27 09:59:27 -07:00
|
|
|
}
|
|
|
|
|
2021-09-05 03:56:21 -07:00
|
|
|
l.mu.Lock()
|
|
|
|
l.clts[cc] = struct{}{}
|
|
|
|
l.mu.Unlock()
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
<-cc.Closed()
|
|
|
|
l.mu.Lock()
|
|
|
|
defer l.mu.Unlock()
|
|
|
|
|
|
|
|
delete(l.clts, cc)
|
|
|
|
}()
|
|
|
|
|
2021-09-06 02:03:27 -07:00
|
|
|
cc.Log("-->", "connect")
|
2021-08-27 09:59:27 -07:00
|
|
|
go handleClt(cc)
|
|
|
|
|
|
|
|
select {
|
|
|
|
case <-cc.Closed():
|
|
|
|
return nil, fmt.Errorf("%s is closed", cc.RemoteAddr())
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
|
|
|
|
return cc, nil
|
|
|
|
}
|