11using System ;
22using System . Collections . Concurrent ;
33using System . Collections . Generic ;
4- using System . IO ;
54using System . Linq ;
65using System . Net ;
76using System . Net . Sockets ;
@@ -40,12 +39,13 @@ public override async Task<DnsResponseMessage> QueryAsync(
4039 cancellationToken . ThrowIfCancellationRequested ( ) ;
4140
4241 ClientPool pool ;
43- ClientPool . ClientEntry entry = null ;
4442 while ( ! _pools . TryGetValue ( server , out pool ) )
4543 {
4644 _pools . TryAdd ( server , new ClientPool ( true , server ) ) ;
4745 }
4846
47+ var entry = await pool . GetNextClient ( ) . ConfigureAwait ( false ) ;
48+
4949 using var cancelCallback = cancellationToken . Register ( ( ) =>
5050 {
5151 if ( entry == null )
@@ -56,33 +56,21 @@ public override async Task<DnsResponseMessage> QueryAsync(
5656 entry . DisposeClient ( ) ;
5757 } ) ;
5858
59- DnsResponseMessage response = null ;
60-
61- // Simple retry in case the pooled clients are
62- var tries = 0 ;
63- while ( response == null && tries < 3 )
59+ try
6460 {
65- tries ++ ;
66- entry = await pool . GetNextClient ( ) . ConfigureAwait ( false ) ;
61+ var response = await QueryAsyncInternal ( entry . Client , request , cancellationToken ) . ConfigureAwait ( false ) ;
6762
68- cancellationToken . ThrowIfCancellationRequested ( ) ;
63+ ValidateResponse ( request , response ) ;
6964
70- response = await QueryAsyncInternal ( entry . Client , request , cancellationToken )
71- . ConfigureAwait ( false ) ;
65+ pool . Enqueue ( entry ) ;
7266
73- if ( response != null )
74- {
75- pool . Enqueue ( entry ) ;
76- }
77- else
78- {
79- entry . DisposeClient ( ) ;
80- }
67+ return response ;
68+ }
69+ catch
70+ {
71+ entry . DisposeClient ( ) ;
72+ throw ;
8173 }
82-
83- ValidateResponse ( request , response ) ;
84-
85- return response ;
8674 }
8775
8876 private async Task < DnsResponseMessage > QueryAsyncInternal ( TcpClient client , DnsRequestMessage request , CancellationToken cancellationToken )
@@ -107,7 +95,8 @@ private async Task<DnsResponseMessage> QueryAsyncInternal(TcpClient client, DnsR
10795
10896 if ( ! stream . CanRead )
10997 {
110- return null ;
98+ // might retry
99+ throw new TimeoutException ( ) ;
111100 }
112101
113102 cancellationToken . ThrowIfCancellationRequested ( ) ;
@@ -117,33 +106,25 @@ private async Task<DnsResponseMessage> QueryAsyncInternal(TcpClient client, DnsR
117106 do
118107 {
119108 int length ;
120- try
109+ using ( var lengthBuffer = new PooledBytes ( 2 ) )
121110 {
122- //length = stream.ReadByte() << 8 | stream.ReadByte() ;
123- using ( var lengthBuffer = new PooledBytes ( 2 ) )
111+ int bytesReceived = 0 , read ;
112+ while ( ( bytesReceived += ( read = await stream . ReadAsync ( lengthBuffer . Buffer , bytesReceived , 2 , cancellationToken ) . ConfigureAwait ( false ) ) ) < 2 )
124113 {
125- int bytesReceived = 0 , read ;
126- while ( ( bytesReceived += ( read = await stream . ReadAsync ( lengthBuffer . Buffer , bytesReceived , 2 , cancellationToken ) . ConfigureAwait ( false ) ) ) < 2 )
114+ if ( read <= 0 )
127115 {
128- if ( read <= 0 )
129- {
130- // disconnected, might retry
131- return null ;
132- }
116+ // disconnected, might retry
117+ throw new TimeoutException ( ) ;
133118 }
134-
135- length = lengthBuffer . Buffer [ 0 ] << 8 | lengthBuffer . Buffer [ 1 ] ;
136119 }
137- }
138- catch ( Exception ex ) when ( ex is IOException || ex is SocketException )
139- {
140- return null ;
120+
121+ length = lengthBuffer . Buffer [ 0 ] << 8 | lengthBuffer . Buffer [ 1 ] ;
141122 }
142123
143124 if ( length <= 0 )
144125 {
145- // server signals close/disconnecting
146- return null ;
126+ // server signals close/disconnecting, might retry
127+ throw new TimeoutException ( ) ;
147128 }
148129
149130 using ( var memory = new PooledBytes ( length ) )
@@ -157,7 +138,7 @@ private async Task<DnsResponseMessage> QueryAsyncInternal(TcpClient client, DnsR
157138 if ( read <= 0 )
158139 {
159140 // disconnected
160- return null ;
141+ throw new TimeoutException ( ) ;
161142 }
162143 if ( bytesReceived + readSize > length )
163144 {
0 commit comments