From ed6cde73f795f97f9220a2f317e364a31a048592 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= <i@sekai.icu>
Date: Sun, 18 Aug 2024 09:10:10 +0800
Subject: [PATCH] udpnat: Implement read deadline

---
 common/udpnat/conn_wait.go | 3 +++
 common/udpnat/service.go   | 7 ++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/common/udpnat/conn_wait.go b/common/udpnat/conn_wait.go
index 2e6d741..968d557 100644
--- a/common/udpnat/conn_wait.go
+++ b/common/udpnat/conn_wait.go
@@ -2,6 +2,7 @@ package udpnat
 
 import (
 	"io"
+	"os"
 
 	"github.com/sagernet/sing/common/buf"
 	M "github.com/sagernet/sing/common/metadata"
@@ -34,5 +35,7 @@ func (c *conn) WaitReadPacket() (buffer *buf.Buffer, destination M.Socksaddr, er
 		return
 	case <-c.ctx.Done():
 		return nil, M.Socksaddr{}, io.ErrClosedPipe
+	case <-c.readDeadline.Wait():
+		return nil, M.Socksaddr{}, os.ErrDeadlineExceeded
 	}
 }
diff --git a/common/udpnat/service.go b/common/udpnat/service.go
index 100a390..8dd88c5 100644
--- a/common/udpnat/service.go
+++ b/common/udpnat/service.go
@@ -13,6 +13,7 @@ import (
 	E "github.com/sagernet/sing/common/exceptions"
 	M "github.com/sagernet/sing/common/metadata"
 	N "github.com/sagernet/sing/common/network"
+	"github.com/sagernet/sing/common/pipe"
 )
 
 type Handler interface {
@@ -116,6 +117,7 @@ type conn struct {
 	localAddr       M.Socksaddr
 	remoteAddr      M.Socksaddr
 	source          N.PacketWriter
+	readDeadline    pipe.Deadline
 	readWaitOptions N.ReadWaitOptions
 }
 
@@ -127,6 +129,8 @@ func (c *conn) ReadPacket(buffer *buf.Buffer) (addr M.Socksaddr, err error) {
 		return p.destination, err
 	case <-c.ctx.Done():
 		return M.Socksaddr{}, io.ErrClosedPipe
+	case <-c.readDeadline.Wait():
+		return M.Socksaddr{}, os.ErrDeadlineExceeded
 	}
 }
 
@@ -159,7 +163,8 @@ func (c *conn) SetDeadline(t time.Time) error {
 }
 
 func (c *conn) SetReadDeadline(t time.Time) error {
-	return os.ErrInvalid
+	c.readDeadline.Set(t)
+	return nil
 }
 
 func (c *conn) SetWriteDeadline(t time.Time) error {