mirror of
https://github.com/SagerNet/sing.git
synced 2025-04-03 03:47:38 +03:00
90 lines
2 KiB
Go
90 lines
2 KiB
Go
package udpnat
|
|
|
|
import (
|
|
"io"
|
|
"net"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/sagernet/sing/common/buf"
|
|
M "github.com/sagernet/sing/common/metadata"
|
|
N "github.com/sagernet/sing/common/network"
|
|
"github.com/sagernet/sing/common/pipe"
|
|
)
|
|
|
|
type natConn struct {
|
|
writer N.PacketWriter
|
|
localAddr M.Socksaddr
|
|
packetChan chan *Packet
|
|
doneChan chan struct{}
|
|
readDeadline pipe.Deadline
|
|
readWaitOptions N.ReadWaitOptions
|
|
}
|
|
|
|
func (c *natConn) ReadPacket(buffer *buf.Buffer) (addr M.Socksaddr, err error) {
|
|
select {
|
|
case p := <-c.packetChan:
|
|
_, err = buffer.ReadOnceFrom(p.Buffer)
|
|
destination := p.Destination
|
|
p.Buffer.Release()
|
|
PutPacket(p)
|
|
return destination, err
|
|
case <-c.doneChan:
|
|
return M.Socksaddr{}, io.ErrClosedPipe
|
|
case <-c.readDeadline.Wait():
|
|
return M.Socksaddr{}, os.ErrDeadlineExceeded
|
|
}
|
|
}
|
|
|
|
func (c *natConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
|
|
return c.writer.WritePacket(buffer, destination)
|
|
}
|
|
|
|
func (c *natConn) InitializeReadWaiter(options N.ReadWaitOptions) (needCopy bool) {
|
|
c.readWaitOptions = options
|
|
return false
|
|
}
|
|
|
|
func (c *natConn) WaitReadPacket() (buffer *buf.Buffer, destination M.Socksaddr, err error) {
|
|
select {
|
|
case packet := <-c.packetChan:
|
|
buffer = c.readWaitOptions.Copy(packet.Buffer)
|
|
destination = packet.Destination
|
|
PutPacket(packet)
|
|
return
|
|
case <-c.doneChan:
|
|
return nil, M.Socksaddr{}, io.ErrClosedPipe
|
|
case <-c.readDeadline.Wait():
|
|
return nil, M.Socksaddr{}, os.ErrDeadlineExceeded
|
|
}
|
|
}
|
|
|
|
func (c *natConn) Close() error {
|
|
select {
|
|
case <-c.doneChan:
|
|
default:
|
|
close(c.doneChan)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *natConn) LocalAddr() net.Addr {
|
|
return c.localAddr
|
|
}
|
|
|
|
func (c *natConn) RemoteAddr() net.Addr {
|
|
return M.Socksaddr{}
|
|
}
|
|
|
|
func (c *natConn) SetDeadline(t time.Time) error {
|
|
return os.ErrInvalid
|
|
}
|
|
|
|
func (c *natConn) SetReadDeadline(t time.Time) error {
|
|
c.readDeadline.Set(t)
|
|
return nil
|
|
}
|
|
|
|
func (c *natConn) SetWriteDeadline(t time.Time) error {
|
|
return os.ErrInvalid
|
|
}
|