@@ -14,6 +14,7 @@ import (
1414 "sync"
1515 "sync/atomic"
1616 "syscall"
17+ "time"
1718 "unsafe"
1819
1920 "github.com/sirupsen/logrus"
@@ -66,7 +67,7 @@ func NewRIOListener(l *logrus.Logger, addr netip.Addr, port int) (*RIOConn, erro
6667
6768 u := & RIOConn {l : l }
6869
69- err := u .bind (& windows.SockaddrInet6 {Addr : addr .As16 (), Port : port })
70+ err := u .bind (l , & windows.SockaddrInet6 {Addr : addr .As16 (), Port : port })
7071 if err != nil {
7172 return nil , fmt .Errorf ("bind: %w" , err )
7273 }
@@ -82,11 +83,11 @@ func NewRIOListener(l *logrus.Logger, addr netip.Addr, port int) (*RIOConn, erro
8283 return u , nil
8384}
8485
85- func (u * RIOConn ) bind (sa windows.Sockaddr ) error {
86+ func (u * RIOConn ) bind (l * logrus. Logger , sa windows.Sockaddr ) error {
8687 var err error
8788 u .sock , err = winrio .Socket (windows .AF_INET6 , windows .SOCK_DGRAM , windows .IPPROTO_UDP )
8889 if err != nil {
89- return err
90+ return fmt . Errorf ( "winrio.Socket error: %w" , err )
9091 }
9192
9293 // Enable v4 for this socket
@@ -100,35 +101,40 @@ func (u *RIOConn) bind(sa windows.Sockaddr) error {
100101 size := uint32 (unsafe .Sizeof (flag ))
101102 err = syscall .WSAIoctl (syscall .Handle (u .sock ), syscall .SIO_UDP_CONNRESET , (* byte )(unsafe .Pointer (& flag )), size , nil , 0 , & ret , nil , 0 )
102103 if err != nil {
103- return err
104+ // This is a best-effort to prevent errors from being returned by the udp recv operation.
105+ // Quietly log a failure and continue.
106+ l .WithError (err ).Debug ("failed to set UDP_CONNRESET ioctl" )
104107 }
108+
105109 ret = 0
106110 flag = 0
107111 size = uint32 (unsafe .Sizeof (flag ))
108112 SIO_UDP_NETRESET := uint32 (syscall .IOC_IN | syscall .IOC_VENDOR | 15 )
109113 err = syscall .WSAIoctl (syscall .Handle (u .sock ), SIO_UDP_NETRESET , (* byte )(unsafe .Pointer (& flag )), size , nil , 0 , & ret , nil , 0 )
110114 if err != nil {
111- return err
115+ // This is a best-effort to prevent errors from being returned by the udp recv operation.
116+ // Quietly log a failure and continue.
117+ l .WithError (err ).Debug ("failed to set UDP_NETRESET ioctl" )
112118 }
113119
114120 err = u .rx .Open ()
115121 if err != nil {
116- return err
122+ return fmt . Errorf ( "error rx.Open(): %w" , err )
117123 }
118124
119125 err = u .tx .Open ()
120126 if err != nil {
121- return err
127+ return fmt . Errorf ( "error tx.Open(): %w" , err )
122128 }
123129
124130 u .rq , err = winrio .CreateRequestQueue (u .sock , packetsPerRing , 1 , packetsPerRing , 1 , u .rx .cq , u .tx .cq , 0 )
125131 if err != nil {
126- return err
132+ return fmt . Errorf ( "error CreateRequestQueue: %w" , err )
127133 }
128134
129135 err = windows .Bind (u .sock , sa )
130136 if err != nil {
131- return err
137+ return fmt . Errorf ( "error windows.Bind(): %w" , err )
132138 }
133139
134140 return nil
@@ -137,15 +143,22 @@ func (u *RIOConn) bind(sa windows.Sockaddr) error {
137143func (u * RIOConn ) ListenOut (r EncReader ) {
138144 buffer := make ([]byte , MTU )
139145
146+ var lastRecvErr time.Time
147+
140148 for {
141149 // Just read one packet at a time
142150 n , rua , err := u .receive (buffer )
151+
143152 if err != nil {
144153 if errors .Is (err , net .ErrClosed ) {
145154 u .l .WithError (err ).Debug ("udp socket is closed, exiting read loop" )
146155 return
147156 }
148- u .l .WithError (err ).Error ("unexpected udp socket receive error" )
157+ // Dampen unexpected message warns to once per minute
158+ if lastRecvErr .IsZero () || time .Since (lastRecvErr ) > time .Minute {
159+ lastRecvErr = time .Now ()
160+ u .l .WithError (err ).Warn ("unexpected udp socket receive error" )
161+ }
149162 continue
150163 }
151164
0 commit comments