fix(listener): add panic recovery in TUN/TAP listenLoop for wintun crashes

On Windows, wintun.dll may pass an invalid pointer to the logMessage
callback, causing a nil pointer dereference in UTF16PtrToString that
panics the entire process. The upstream wintun-go library has not fixed
this since 2021.

Add defer/recover in tun/tungo/tap listenLoop inner closures to convert
panics from createTun/createTap into logged errors, allowing the retry
loop to recover gracefully instead of crashing the process.

Fixes go-gost/gost#482
This commit is contained in:
ginuerzh
2026-06-21 16:47:12 +08:00
parent e814852ca1
commit 9ea10763e4
3 changed files with 24 additions and 3 deletions
+8 -1
View File
@@ -2,6 +2,7 @@ package tap
import ( import (
"context" "context"
"fmt"
"net" "net"
"time" "time"
@@ -68,7 +69,13 @@ func (l *tapListener) Init(md mdata.Metadata) (err error) {
func (l *tapListener) listenLoop() { func (l *tapListener) listenLoop() {
for { for {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
err := func() error { err := func() (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic in createTap: %v", r)
}
}()
ifce, name, ip, err := l.createTap() ifce, name, ip, err := l.createTap()
if err != nil { if err != nil {
if ifce != nil { if ifce != nil {
+8 -1
View File
@@ -2,6 +2,7 @@ package tun
import ( import (
"context" "context"
"fmt"
"net" "net"
"time" "time"
@@ -75,7 +76,13 @@ func (l *tunListener) Init(md mdata.Metadata) (err error) {
func (l *tunListener) listenLoop(ready context.CancelCauseFunc) { func (l *tunListener) listenLoop(ready context.CancelCauseFunc) {
for { for {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
err := func() error { err := func() (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic in createTun: %v", r)
}
}()
ifce, name, ip, err := l.createTun() ifce, name, ip, err := l.createTun()
if err != nil { if err != nil {
if ifce != nil { if ifce != nil {
+8 -1
View File
@@ -2,6 +2,7 @@ package tungo
import ( import (
"context" "context"
"fmt"
"net" "net"
"time" "time"
@@ -68,7 +69,13 @@ func (l *tunListener) Init(md mdata.Metadata) (err error) {
func (l *tunListener) listenLoop(ready context.CancelCauseFunc) { func (l *tunListener) listenLoop(ready context.CancelCauseFunc) {
for { for {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
err := func() error { err := func() (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic in createTun: %v", r)
}
}()
ifce, name, ip, err := l.createTun() ifce, name, ip, err := l.createTun()
if err != nil { if err != nil {
if ifce != nil { if ifce != nil {