github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/common/pipelistener/listener.go (about) 1 package pipelistener 2 3 import ( 4 "io" 5 "net" 6 ) 7 8 var _ net.Listener = (*Listener)(nil) 9 10 type Listener struct { 11 pipe chan net.Conn 12 done chan struct{} 13 } 14 15 func New(channelSize int) *Listener { 16 return &Listener{ 17 pipe: make(chan net.Conn, channelSize), 18 done: make(chan struct{}), 19 } 20 } 21 22 func (l *Listener) Serve(conn net.Conn) { 23 l.pipe <- conn 24 } 25 26 func (l *Listener) Accept() (net.Conn, error) { 27 select { 28 case conn := <-l.pipe: 29 return conn, nil 30 case <-l.done: 31 return nil, io.ErrClosedPipe 32 } 33 } 34 35 func (l *Listener) Close() error { 36 select { 37 case <-l.done: 38 return io.ErrClosedPipe 39 default: 40 } 41 close(l.done) 42 return nil 43 } 44 45 func (l *Listener) Addr() net.Addr { 46 return addr{} 47 } 48 49 type addr struct{} 50 51 func (a addr) Network() string { 52 return "pipe" 53 } 54 55 func (a addr) String() string { 56 return "pipe" 57 }