github.com/sagernet/sing-box@v1.2.7/transport/wireguard/server_bind.go (about) 1 package wireguard 2 3 import ( 4 "io" 5 6 "github.com/sagernet/sing/common/buf" 7 E "github.com/sagernet/sing/common/exceptions" 8 M "github.com/sagernet/sing/common/metadata" 9 N "github.com/sagernet/sing/common/network" 10 "github.com/sagernet/wireguard-go/conn" 11 ) 12 13 var _ conn.Bind = (*ServerBind)(nil) 14 15 type ServerBind struct { 16 inbound chan serverPacket 17 done chan struct{} 18 writeBack N.PacketWriter 19 } 20 21 func NewServerBind(writeBack N.PacketWriter) *ServerBind { 22 return &ServerBind{ 23 inbound: make(chan serverPacket, 256), 24 done: make(chan struct{}), 25 writeBack: writeBack, 26 } 27 } 28 29 func (s *ServerBind) Abort() error { 30 select { 31 case <-s.done: 32 return io.ErrClosedPipe 33 default: 34 close(s.done) 35 } 36 return nil 37 } 38 39 type serverPacket struct { 40 buffer *buf.Buffer 41 source M.Socksaddr 42 } 43 44 func (s *ServerBind) Open(port uint16) (fns []conn.ReceiveFunc, actualPort uint16, err error) { 45 fns = []conn.ReceiveFunc{s.receive} 46 return 47 } 48 49 func (s *ServerBind) receive(b []byte) (n int, ep conn.Endpoint, err error) { 50 select { 51 case packet := <-s.inbound: 52 defer packet.buffer.Release() 53 n = copy(b, packet.buffer.Bytes()) 54 ep = Endpoint(packet.source) 55 return 56 case <-s.done: 57 err = io.ErrClosedPipe 58 return 59 } 60 } 61 62 func (s *ServerBind) WriteIsThreadUnsafe() { 63 } 64 65 func (s *ServerBind) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error { 66 select { 67 case s.inbound <- serverPacket{ 68 buffer: buffer, 69 source: destination, 70 }: 71 return nil 72 case <-s.done: 73 return io.ErrClosedPipe 74 } 75 } 76 77 func (s *ServerBind) Close() error { 78 return nil 79 } 80 81 func (s *ServerBind) SetMark(mark uint32) error { 82 return nil 83 } 84 85 func (s *ServerBind) Send(b []byte, ep conn.Endpoint) error { 86 return s.writeBack.WritePacket(buf.As(b), M.Socksaddr(ep.(Endpoint))) 87 } 88 89 func (s *ServerBind) ParseEndpoint(addr string) (conn.Endpoint, error) { 90 destination := M.ParseSocksaddr(addr) 91 if !destination.IsValid() || destination.Port == 0 { 92 return nil, E.New("invalid endpoint: ", addr) 93 } 94 return Endpoint(destination), nil 95 }