From 321c2d2f250b0985f7f86051c3c2a5db0a3f7711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Thu, 12 Dec 2024 20:56:58 +0800 Subject: [PATCH] Fix Read not implemented for windows --- tun_windows.go | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/tun_windows.go b/tun_windows.go index 45d5b00..85e3009 100644 --- a/tun_windows.go +++ b/tun_windows.go @@ -345,7 +345,40 @@ func (t *NativeTun) configure() error { } func (t *NativeTun) Read(p []byte) (n int, err error) { - return 0, os.ErrInvalid + t.running.Add(1) + defer t.running.Done() +retry: + if t.close.Load() == 1 { + return 0, os.ErrClosed + } + start := nanotime() + shouldSpin := t.rate.current.Load() >= spinloopRateThreshold && uint64(start-t.rate.nextStartTime.Load()) <= rateMeasurementGranularity*2 + for { + if t.close.Load() == 1 { + return 0, os.ErrClosed + } + var packet []byte + packet, err = t.session.ReceivePacket() + switch err { + case nil: + n = copy(p, packet) + t.session.ReleaseReceivePacket(packet) + t.rate.update(uint64(n)) + return + case windows.ERROR_NO_MORE_ITEMS: + if !shouldSpin || uint64(nanotime()-start) >= spinloopDuration { + windows.WaitForSingleObject(t.readWait, windows.INFINITE) + goto retry + } + procyield(1) + continue + case windows.ERROR_HANDLE_EOF: + return 0, os.ErrClosed + case windows.ERROR_INVALID_DATA: + return 0, errors.New("send ring corrupt") + } + return 0, fmt.Errorf("read failed: %w", err) + } } func (t *NativeTun) ReadPacket() ([]byte, func(), error) {