Fix USBIP parsing and lifecycle handling

This commit is contained in:
世界 2026-04-21 21:45:24 +08:00
parent c511144a3d
commit daaa4d1e27
No known key found for this signature in database
GPG Key ID: CD109927C34A63C4
3 changed files with 18 additions and 13 deletions

View File

@ -39,13 +39,9 @@ func (h *USBIPHexUint16) UnmarshalJSON(data []byte) error {
*h = 0
return nil
}
parsed, err := strconv.ParseUint(asString, 0, 16)
asString = strings.TrimPrefix(strings.TrimPrefix(asString, "0x"), "0X")
parsed, err := strconv.ParseUint(asString, 16, 16)
if err != nil {
// Allow bare hex without 0x prefix.
if parsed2, err2 := strconv.ParseUint(asString, 16, 16); err2 == nil {
*h = USBIPHexUint16(parsed2)
return nil
}
return E.Cause(err, "parse usb id ", asString)
}
*h = USBIPHexUint16(parsed)

View File

@ -312,12 +312,7 @@ func (c *ClientService) attemptAttach(busid string) (int, error) {
if err != nil {
return -1, E.Cause(err, "dial ", c.serverAddr)
}
success := false
defer func() {
if !success {
conn.Close()
}
}()
defer conn.Close()
if err := WriteOpReqImport(conn, busid); err != nil {
return -1, E.Cause(err, "write OP_REQ_IMPORT")
}
@ -353,7 +348,6 @@ func (c *ClientService) attemptAttach(busid string) (int, error) {
if err := vhciAttach(port, file.Fd(), info.DevID(), info.Speed); err != nil {
return -1, E.Cause(err, "vhci attach")
}
success = true
return port, nil
}

View File

@ -6,6 +6,7 @@ import (
"context"
"net"
"sync"
"time"
"github.com/sagernet/sing-box/adapter"
boxService "github.com/sagernet/sing-box/adapter/service"
@ -113,6 +114,12 @@ func (s *ServerService) bindExports() error {
matched++
continue
}
if devices[i].DeviceClass == 0x09 {
seen[devices[i].BusID] = true
matched++
s.logger.Warn("skip hub device ", devices[i].BusID, " matched by ", describeMatch(m))
continue
}
if err := s.bindOne(&devices[i]); err != nil {
s.logger.Warn("bind ", devices[i].BusID, ": ", err)
continue
@ -219,6 +226,14 @@ func (s *ServerService) acceptLoop(ln net.Listener) {
if E.IsClosed(err) {
return
}
//nolint:staticcheck
if netError, isNetError := err.(net.Error); isNetError && netError.Temporary() {
s.logger.Error("accept: ", err)
if !sleepCtx(s.ctx, 200*time.Millisecond) {
return
}
continue
}
s.logger.Error("accept: ", err)
return
}