Skip to content

Commit

Permalink
transport: improve quic ExchangeReserved
Browse files Browse the repository at this point in the history
  • Loading branch information
IrineSistiana committed Oct 27, 2023
1 parent 77bf3dd commit c0759da
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 29 deletions.
52 changes: 26 additions & 26 deletions pkg/upstream/transport/conn_quic.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import (
"github.com/quic-go/quic-go"
)

const (
quicQueryTimeout = time.Second * 6
)

var _ DnsConn = (*QuicDnsConn)(nil)

type QuicDnsConn struct {
Expand Down Expand Up @@ -46,7 +50,11 @@ type quicReservedExchanger struct {
var _ ReservedExchanger = (*quicReservedExchanger)(nil)

func (ote *quicReservedExchanger) ExchangeReserved(ctx context.Context, q []byte) (resp *[]byte, err error) {
defer ote.WithdrawReserved()
stream := ote.stream
defer func() {
stream.CancelRead(0)
stream.Close()
}()

payload, err := copyMsgWithLenHdr(q)
if err != nil {
Expand All @@ -61,18 +69,28 @@ func (ote *quicReservedExchanger) ExchangeReserved(ctx context.Context, q []byte
orgQid := binary.BigEndian.Uint16((*payload)[2:])
binary.BigEndian.PutUint16((*payload)[2:], 0)

// TODO: use single goroutine.
// See RFC9250 4.3.1. Transaction Cancellation
stream.SetDeadline(time.Now().Add(quicQueryTimeout))
_, err = stream.Write(*payload)
pool.ReleaseBuf(payload)
if err != nil {
return nil, err
}

// RFC 9250 4.2
// The client MUST send the DNS query over the selected stream and MUST
// indicate through the STREAM FIN mechanism that no further data will
// be sent on that stream.
//
// Call Close() here will send the STREAM FIN. It won't close Read.
stream.Close()

type res struct {
resp *[]byte
err error
}
rc := make(chan res, 1)
go func() {
defer func() {
pool.ReleaseBuf(payload)
}()
r, err := exchangeTroughQuicStream(ote.stream, *payload)
r, err := dnsutils.ReadRawMsgFromTCP(stream)
rc <- res{resp: r, err: err}
}()

Expand All @@ -91,24 +109,6 @@ func (ote *quicReservedExchanger) ExchangeReserved(ctx context.Context, q []byte

func (ote *quicReservedExchanger) WithdrawReserved() {
s := ote.stream
s.CancelRead(0)
s.Close()
s.CancelRead(0) // TODO: Needs a proper error code.
}

func exchangeTroughQuicStream(s quic.Stream, payload []byte) (*[]byte, error) {
s.SetDeadline(time.Now().Add(quicQueryTimeout))

_, err := s.Write(payload)
if err != nil {
return nil, err
}

// RFC 9250 4.2
// The client MUST send the DNS query over the selected stream and MUST
// indicate through the STREAM FIN mechanism that no further data will
// be sent on that stream.
//
// Call Close() here will send the STREAM FIN. It won't close Read.
s.Close()
return dnsutils.ReadRawMsgFromTCP(s)
}
3 changes: 0 additions & 3 deletions pkg/upstream/transport/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ const (
defaultIdleTimeout = time.Second * 10
defaultDialTimeout = time.Second * 5


quicQueryTimeout = time.Second * 6

// If a pipeline connection sent a query but did not see any reply (include replies that
// for other queries) from the server after waitingReplyTimeout. It assumes that
// something goes wrong with the connection or the server. The connection will be closed.
Expand Down

0 comments on commit c0759da

Please sign in to comment.