Skip to content

Commit

Permalink
rpc: avoid a panic in delayingConn
Browse files Browse the repository at this point in the history
If the remote server shuts down while the connection is established,
the delaying conn may not complete its handshake. Avoid a panic in
that case.

Release note: None
  • Loading branch information
knz committed Apr 13, 2021
1 parent 0101785 commit c9432ed
Showing 1 changed file with 13 additions and 11 deletions.
24 changes: 13 additions & 11 deletions pkg/rpc/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,8 @@ func (d delayingConn) Write(b []byte) (n int, err error) {
return n, err
}

var errMagicNotFound = errors.New("didn't get expected magic bytes header")

func (d *delayingConn) Read(b []byte) (n int, err error) {
if d.readBuf.Len() == 0 {
var hdr delayingHeader
Expand All @@ -912,17 +914,17 @@ func (d *delayingConn) Read(b []byte) (n int, err error) {
}
// If we somehow don't get our expected magic, throw an error.
if hdr.Magic != magic {
panic(errors.New("didn't get expected magic bytes header"))
} else {
// Once we receive our first packet, we set our delay to the expected
// delay that was sent on the write side.
d.latency = time.Duration(hdr.DelayMS) * time.Millisecond
defer func() {
time.Sleep(timeutil.Until(timeutil.Unix(0, hdr.ReadTime)))
}()
if _, err := io.CopyN(d.readBuf, d.Conn, int64(hdr.Sz)); err != nil {
return 0, err
}
return 0, errors.WithStack(errMagicNotFound)
}

// Once we receive our first packet, we set our delay to the expected
// delay that was sent on the write side.
d.latency = time.Duration(hdr.DelayMS) * time.Millisecond
defer func() {
time.Sleep(timeutil.Until(timeutil.Unix(0, hdr.ReadTime)))
}()
if _, err := io.CopyN(d.readBuf, d.Conn, int64(hdr.Sz)); err != nil {
return 0, err
}
}
return d.readBuf.Read(b)
Expand Down

0 comments on commit c9432ed

Please sign in to comment.