Skip to content

Commit 5942afc

Browse files
committed
conn.go: Only log errors from writing to a connection that aren't net.ErrClosed instead of returning.
Other errors are recoverable through resending and don't need to be propagated into error chains.
1 parent e4fd2fe commit 5942afc

File tree

4 files changed

+40
-18
lines changed

4 files changed

+40
-18
lines changed

conn.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ func (conn *Conn) sendAcknowledgement(packets []uint24, bitflag byte, buf *bytes
537537
// We managed to write n packets in the ACK with this MTU size, write
538538
// the next of the packets in a new ACK.
539539
ack.packets = ack.packets[n:]
540-
if _, err := conn.conn.WriteTo(buf.Bytes(), conn.raddr); err != nil {
540+
if err := conn.writeTo(buf.Bytes(), conn.raddr); err != nil {
541541
return fmt.Errorf("send acknowlegement: %w", err)
542542
}
543543
buf.Reset()
@@ -603,15 +603,28 @@ func (conn *Conn) sendDatagram(pk *packet) error {
603603
seq := conn.seq.Inc()
604604
writeUint24(conn.buf, seq)
605605
pk.write(conn.buf)
606+
defer conn.buf.Reset()
606607

607-
// We then send the pk to the connection.
608-
if _, err := conn.conn.WriteTo(conn.buf.Bytes(), conn.raddr); err != nil {
609-
return fmt.Errorf("send datagram: write to %v: %w", conn.raddr, err)
610-
}
611608
// We then re-add the pk to the recovery queue in case the new one gets
612609
// lost too, in which case we need to resend it again.
613610
conn.retransmission.add(seq, pk)
614-
conn.buf.Reset()
611+
612+
if err := conn.writeTo(conn.buf.Bytes(), conn.raddr); err != nil {
613+
return fmt.Errorf("send datagram: %w", err)
614+
}
615+
return nil
616+
}
617+
618+
// writeTo calls WriteTo on the underlying UDP connection and returns an error
619+
// only if the error returned is net.ErrClosed. In any other case, the error
620+
// is logged but not returned. This is done because at this stage, packets
621+
// being lost to an error can be recovered through resending.
622+
func (conn *Conn) writeTo(p []byte, raddr net.Addr) error {
623+
if _, err := conn.conn.WriteTo(p, raddr); errors.Is(err, net.ErrClosed) {
624+
return fmt.Errorf("write to: %w", err)
625+
} else if err != nil {
626+
conn.handler.log().Error("write to: " + err.Error())
627+
}
615628
return nil
616629
}
617630

dial.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ func (dialer Dialer) DialContext(ctx context.Context, address string) (*Conn, er
233233
// dial finishes the RakNet connection sequence and returns a Conn if
234234
// successful.
235235
func (dialer Dialer) connect(ctx context.Context, state *connState) (*Conn, error) {
236-
conn := newConn(internal.ConnToPacketConn(state.conn), state.raddr, state.mtu, dialerConnectionHandler{})
236+
conn := newConn(internal.ConnToPacketConn(state.conn), state.raddr, state.mtu, dialerConnectionHandler{l: dialer.ErrorLog})
237237
if err := conn.send((&message.ConnectionRequest{ClientGUID: state.id, RequestTime: timestamp()})); err != nil {
238238
return nil, dialer.error("dial", fmt.Errorf("send connection request: %w", err))
239239
}
@@ -259,17 +259,15 @@ func (dialer Dialer) clientListen(rakConn *Conn, conn net.Conn) {
259259
b := make([]byte, rakConn.effectiveMTU())
260260
for {
261261
n, err := conn.Read(b)
262+
if err == nil && n != 0 {
263+
err = rakConn.receive(b[:n])
264+
}
262265
if err != nil {
263-
if !errors.Is(err, net.ErrClosed) {
264-
// Errors reading a packet other than the connection being
265-
// may be worth logging.
266-
dialer.ErrorLog.Error("client: read packet: " + err.Error())
266+
if errors.Is(err, net.ErrClosed) {
267+
return
267268
}
268-
return
269-
} else if n == 0 {
270-
continue
271-
}
272-
if err := rakConn.receive(b[:n]); err != nil {
269+
// Errors reading a packet other than the connection being
270+
// closed may be worth logging.
273271
dialer.ErrorLog.Error("client: " + err.Error())
274272
}
275273
}

handler.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"github.com/sandertv/go-raknet/internal/message"
88
"hash/crc32"
9+
"log/slog"
910
"net"
1011
"time"
1112
)
@@ -14,6 +15,7 @@ type connectionHandler interface {
1415
handle(conn *Conn, b []byte) (handled bool, err error)
1516
limitsEnabled() bool
1617
close(conn *Conn)
18+
log() *slog.Logger
1719
}
1820

1921
type listenerConnectionHandler struct {
@@ -26,6 +28,10 @@ var (
2628
errUnexpectedAdditionalNIC = errors.New("unexpected additional NEW_INCOMING_CONNECTION packet")
2729
)
2830

31+
func (h listenerConnectionHandler) log() *slog.Logger {
32+
return h.l.conf.ErrorLog
33+
}
34+
2935
func (h listenerConnectionHandler) limitsEnabled() bool {
3036
return true
3137
}
@@ -185,14 +191,18 @@ func (h listenerConnectionHandler) handleNewIncomingConnection(conn *Conn) error
185191
return nil
186192
}
187193

188-
type dialerConnectionHandler struct{}
194+
type dialerConnectionHandler struct{ l *slog.Logger }
189195

190196
var (
191197
errUnexpectedCR = errors.New("unexpected CONNECTION_REQUEST packet")
192198
errUnexpectedAdditionalCRA = errors.New("unexpected additional CONNECTION_REQUEST_ACCEPTED packet")
193199
errUnexpectedNIC = errors.New("unexpected NEW_INCOMING_CONNECTION packet")
194200
)
195201

202+
func (h dialerConnectionHandler) log() *slog.Logger {
203+
return h.l
204+
}
205+
196206
func (h dialerConnectionHandler) close(conn *Conn) {
197207
_ = conn.conn.Close()
198208
}

listener.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package raknet
22

33
import (
4+
"errors"
45
"fmt"
56
"github.com/sandertv/go-raknet/internal"
67
"log/slog"
@@ -182,7 +183,7 @@ func (listener *Listener) listen() {
182183
} else if n == 0 || listener.sec.blocked(addr) {
183184
continue
184185
}
185-
if err = listener.handle(b[:n], addr); err != nil {
186+
if err = listener.handle(b[:n], addr); err != nil && !errors.Is(err, net.ErrClosed) {
186187
listener.conf.ErrorLog.Error("listener: handle packet: "+err.Error(), "address", addr.String(), "block-duration", max(0, listener.conf.BlockDuration))
187188
listener.sec.block(addr)
188189
}

0 commit comments

Comments
 (0)