Skip to content

Commit

Permalink
dial.go: Re-use tickers during OpenConnectionRequest/Reply sequence.
Browse files Browse the repository at this point in the history
  • Loading branch information
Sandertv committed May 4, 2024
1 parent e76728a commit 664f9c4
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 29 deletions.
6 changes: 3 additions & 3 deletions conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func newConn(conn net.PacketConn, raddr net.Addr, mtu uint16, h connectionHandle
win: newDatagramWindow(),
packetQueue: newPacketQueue(),
retransmission: newRecoveryQueue(),
buf: bytes.NewBuffer(make([]byte, 0, mtu)),
buf: bytes.NewBuffer(make([]byte, 0, mtu-28)), // - headers.
ackBuf: bytes.NewBuffer(make([]byte, 0, 128)),
nackBuf: bytes.NewBuffer(make([]byte, 0, 64)),
}
Expand Down Expand Up @@ -160,7 +160,7 @@ func (conn *Conn) startTicking() {
_ = conn.send(&message.ConnectedPing{ClientTimestamp: timestamp()})

conn.mu.Lock()
if t.Sub(*conn.lastActivity.Load()) > time.Second*5+conn.retransmission.rtt()*2 {
if t.Sub(*conn.lastActivity.Load()) > time.Second*5+conn.retransmission.rtt(t)*2 {
// No activity for too long: Start timeout.
_ = conn.Close()
}
Expand Down Expand Up @@ -196,7 +196,7 @@ func (conn *Conn) checkResend(now time.Time) {

var (
resend []uint24
rtt = conn.retransmission.rtt()
rtt = conn.retransmission.rtt(now)
delay = rtt + rtt/2
)
conn.rtt.Store(int64(rtt))
Expand Down
17 changes: 8 additions & 9 deletions dial.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,8 @@ func (dialer Dialer) DialContext(ctx context.Context, address string) (*Conn, er
return nil, dialer.error("dial", err)
}

cs := &connState{conn: conn, raddr: conn.RemoteAddr(), id: atomic.AddInt64(&dialerID, 1)}
cs := &connState{conn: conn, raddr: conn.RemoteAddr(), id: atomic.AddInt64(&dialerID, 1), ticker: time.NewTicker(time.Second / 2)}
defer cs.ticker.Stop()
if err = cs.discoverMTU(ctx); err != nil {
return nil, dialer.error("dial", err)
} else if err = cs.openConnection(ctx); err != nil {
Expand Down Expand Up @@ -285,6 +286,8 @@ type connState struct {

serverSecurity bool
cookie uint32

ticker *time.Ticker
}

var mtuSizes = []uint16{1492, 1200, 576}
Expand Down Expand Up @@ -337,14 +340,12 @@ func (state *connState) discoverMTU(ctx context.Context) error {
// request1 sends a message.OpenConnectionRequest1 three times for each mtu
// size passed, spaced by 500ms.
func (state *connState) request1(ctx context.Context, sizes []uint16) {
ticker := time.NewTicker(time.Second / 2)
defer ticker.Stop()

state.ticker.Reset(time.Second / 2)
for _, size := range sizes {
for range 3 {
state.openConnectionRequest1(size)
select {
case <-ticker.C:
case <-state.ticker.C:
continue
case <-ctx.Done():
return
Expand Down Expand Up @@ -384,13 +385,11 @@ func (state *connState) openConnection(ctx context.Context) error {

// request2 continuously sends a message.OpenConnectionRequest2 every 500ms.
func (state *connState) request2(ctx context.Context, mtu uint16) {
ticker := time.NewTicker(time.Second / 2)
defer ticker.Stop()

state.ticker.Reset(time.Second / 2)
for {
state.openConnectionRequest2(mtu)
select {
case <-ticker.C:
case <-state.ticker.C:
continue
case <-ctx.Done():
return
Expand Down
32 changes: 15 additions & 17 deletions resend_map.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package raknet

import (
"maps"
"time"
)

Expand Down Expand Up @@ -60,23 +61,20 @@ func (m *resendMap) remove(index uint24, mul int) (*packet, bool) {
// rtt returns the average round trip time between the putting of the value
// into the recovery queue and the taking out of it again. It is measured over
// the last delayRecordCount values add in.
func (m *resendMap) rtt() time.Duration {
const maxRTT = time.Second * 5
var (
total, records time.Duration
now = time.Now()
)
for t, rtt := range m.delays {
if now.Sub(t) > maxRTT {
delete(m.delays, t)
continue
}
total += rtt
records++
}
if records == 0 {
// No records yet, generally should not happen. Just return a reasonable amount of time.
func (m *resendMap) rtt(now time.Time) time.Duration {
const rttCalculationWindow = time.Second * 5
maps.DeleteFunc(m.delays, func(t time.Time, duration time.Duration) bool {
// Remove records that are older than the max window.
return now.Sub(t) > rttCalculationWindow
})
if len(m.delays) == 0 {
// No records yet, generally should not happen. Just return a reasonable
// amount of time.
return time.Millisecond * 50
}
return total / records
var total time.Duration
for _, rtt := range m.delays {
total += rtt
}
return total / time.Duration(len(m.delays))
}

0 comments on commit 664f9c4

Please sign in to comment.