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:
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user