fixed fallback for non io_uring packet send/recv

This commit is contained in:
Ryan Huber
2025-11-03 10:45:30 +00:00
parent 3dea761530
commit c73b2dfbc7
2 changed files with 85 additions and 26 deletions

View File

@@ -1,6 +1,7 @@
package cert package cert
import ( import (
"encoding/hex"
"encoding/pem" "encoding/pem"
"fmt" "fmt"
"time" "time"
@@ -249,9 +250,11 @@ func UnmarshalNebulaCertificateFromPEM(b []byte) (*NebulaCertificate, []byte, er
// Handle issuer // Handle issuer
if c.Issuer() != "" { if c.Issuer() != "" {
// Convert hex string fingerprint back to bytes (this is an approximation) issuerBytes, err := hex.DecodeString(c.Issuer())
// The old API used raw bytes, new API uses hex string if err != nil {
nc.Details.Issuer = []byte(c.Issuer()) return nil, rest, fmt.Errorf("failed to decode issuer fingerprint: %w", err)
}
nc.Details.Issuer = issuerBytes
} }
return nc, rest, nil return nc, rest, nil

View File

@@ -1628,6 +1628,57 @@ func isEAgain(err error) bool {
return false return false
} }
func (u *StdConn) readSingleSyscall(msgs []rawMessage) (int, error) {
if len(msgs) == 0 {
return 0, nil
}
for {
n, _, errno := unix.Syscall6(
unix.SYS_RECVMSG,
uintptr(u.sysFd),
uintptr(unsafe.Pointer(&msgs[0].Hdr)),
0,
0,
0,
0,
)
if errno != 0 {
err := syscall.Errno(errno)
if err == unix.EINTR {
continue
}
return 0, &net.OpError{Op: "recvmsg", Err: err}
}
msgs[0].Len = uint32(n)
return 1, nil
}
}
func (u *StdConn) readMultiSyscall(msgs []rawMessage) (int, error) {
if len(msgs) == 0 {
return 0, nil
}
for {
n, _, errno := unix.Syscall6(
unix.SYS_RECVMMSG,
uintptr(u.sysFd),
uintptr(unsafe.Pointer(&msgs[0])),
uintptr(len(msgs)),
unix.MSG_WAITFORONE,
0,
0,
)
if errno != 0 {
err := syscall.Errno(errno)
if err == unix.EINTR {
continue
}
return 0, &net.OpError{Op: "recvmmsg", Err: err}
}
return int(n), nil
}
}
func (u *StdConn) ReadSingle(msgs []rawMessage) (int, error) { func (u *StdConn) ReadSingle(msgs []rawMessage) (int, error) {
if len(msgs) == 0 { if len(msgs) == 0 {
return 0, nil return 0, nil
@@ -1637,8 +1688,7 @@ func (u *StdConn) ReadSingle(msgs []rawMessage) (int, error) {
state := u.ioState.Load() state := u.ioState.Load()
if state == nil { if state == nil {
u.l.Error("ReadSingle: io_uring not initialized") return u.readSingleSyscall(msgs)
return 0, &net.OpError{Op: "recvmsg", Err: errors.New("io_uring not initialized")}
} }
u.l.Debug("ReadSingle: converting rawMessage to unix.Msghdr") u.l.Debug("ReadSingle: converting rawMessage to unix.Msghdr")
@@ -1679,8 +1729,7 @@ func (u *StdConn) ReadMulti(msgs []rawMessage) (int, error) {
state := u.ioState.Load() state := u.ioState.Load()
if state == nil { if state == nil {
u.l.Error("ReadMulti: io_uring not initialized") return u.readMultiSyscall(msgs)
return 0, &net.OpError{Op: "recvmsg", Err: errors.New("io_uring not initialized")}
} }
count := 0 count := 0
@@ -2176,7 +2225,14 @@ func (u *StdConn) directWrite(b []byte, addr netip.AddrPort) error {
"remote_is_v6": addr.Addr().Is6(), "remote_is_v6": addr.Addr().Is6(),
}).Debug("io_uring directWrite invoked") }).Debug("io_uring directWrite invoked")
if state == nil { if state == nil {
return errors.New("io_uring state unavailable") written, err := u.sendMsgSync(addr, b, nil, 0)
if err != nil {
return err
}
if written != len(b) {
return fmt.Errorf("sendmsg short write: wrote %d expected %d", written, len(b))
}
return nil
} }
n, err := u.sendMsgIOUring(state, addr, b, nil, 0) n, err := u.sendMsgIOUring(state, addr, b, nil, 0)
if err != nil { if err != nil {