10
10
use alloc:: string:: { String , ToString } ;
11
11
use core:: ffi:: c_void;
12
12
use core:: fmt;
13
+ use core:: num:: NonZero ;
13
14
use core:: pin:: Pin ;
14
15
use core:: ptr:: NonNull ;
15
16
use core:: task:: { Context , Poll , Waker } ;
@@ -37,8 +38,6 @@ pub enum Error {
37
38
Resolver ( ResolverError , String ) ,
38
39
/// Allocation failed
39
40
AllocationFailed ,
40
- /// Unexpected error
41
- Unexpected ( String ) ,
42
41
}
43
42
44
43
impl fmt:: Display for Error {
@@ -47,7 +46,6 @@ impl fmt::Display for Error {
47
46
Error :: NoResolver => write ! ( f, "No resolver configured" ) ,
48
47
Error :: Resolver ( err, context) => write ! ( f, "{err}: resolving `{context}`" ) ,
49
48
Error :: AllocationFailed => write ! ( f, "Allocation failed" ) ,
50
- Error :: Unexpected ( err) => write ! ( f, "Unexpected error: {err}" ) ,
51
49
}
52
50
}
53
51
}
@@ -88,19 +86,17 @@ impl fmt::Display for ResolverError {
88
86
}
89
87
impl core:: error:: Error for ResolverError { }
90
88
91
- /// Convert from the NGX_RESOLVE_ error codes. Fails if code was success.
92
- impl TryFrom < isize > for ResolverError {
93
- type Error = ( ) ;
94
- fn try_from ( code : isize ) -> Result < ResolverError , Self :: Error > {
95
- match code as u32 {
96
- 0 => Err ( ( ) ) ,
97
- NGX_RESOLVE_FORMERR => Ok ( ResolverError :: FormErr ) ,
98
- NGX_RESOLVE_SERVFAIL => Ok ( ResolverError :: ServFail ) ,
99
- NGX_RESOLVE_NXDOMAIN => Ok ( ResolverError :: NXDomain ) ,
100
- NGX_RESOLVE_NOTIMP => Ok ( ResolverError :: NotImp ) ,
101
- NGX_RESOLVE_REFUSED => Ok ( ResolverError :: Refused ) ,
102
- NGX_RESOLVE_TIMEDOUT => Ok ( ResolverError :: TimedOut ) ,
103
- _ => Ok ( ResolverError :: Unknown ( code) ) ,
89
+ /// Convert from the NGX_RESOLVE_ error codes.
90
+ impl From < NonZero < isize > > for ResolverError {
91
+ fn from ( code : NonZero < isize > ) -> ResolverError {
92
+ match code. get ( ) as u32 {
93
+ NGX_RESOLVE_FORMERR => ResolverError :: FormErr ,
94
+ NGX_RESOLVE_SERVFAIL => ResolverError :: ServFail ,
95
+ NGX_RESOLVE_NXDOMAIN => ResolverError :: NXDomain ,
96
+ NGX_RESOLVE_NOTIMP => ResolverError :: NotImp ,
97
+ NGX_RESOLVE_REFUSED => ResolverError :: Refused ,
98
+ NGX_RESOLVE_TIMEDOUT => ResolverError :: TimedOut ,
99
+ _ => ResolverError :: Unknown ( code. get ( ) ) ,
104
100
}
105
101
}
106
102
}
@@ -197,18 +193,16 @@ impl<'a> Resolution<'a> {
197
193
// will be called later by nginx when it gets a dns response or a
198
194
// timeout.
199
195
let ret = unsafe { ngx_resolve_name ( ctx. as_ptr ( ) ) } ;
200
- if ret != 0 {
201
- return Err ( Error :: Resolver (
202
- ResolverError :: try_from ( ret) . expect ( "nonzero, checked above" ) ,
203
- name. to_string ( ) ,
204
- ) ) ;
196
+ if let Some ( e) = NonZero :: new ( ret) {
197
+ return Err ( Error :: Resolver ( ResolverError :: from ( e) , name. to_string ( ) ) ) ;
205
198
}
206
199
207
200
Ok ( this)
208
201
}
209
202
210
203
// Nginx will call this handler when name resolution completes. If the
211
- // result is cached, this could be
204
+ // result is in the cache, this could be called from inside ngx_resolve_name.
205
+ // Otherwise, it will be called later on the event loop.
212
206
unsafe extern "C" fn handler ( ctx : * mut ngx_resolver_ctx_t ) {
213
207
let mut data = unsafe { NonNull :: new_unchecked ( ( * ctx) . data as * mut Resolution ) } ;
214
208
let this: & mut Resolution = unsafe { data. as_mut ( ) } ;
@@ -225,38 +219,36 @@ impl<'a> Resolution<'a> {
225
219
}
226
220
227
221
/// Take the results in a ctx and make an owned copy as a
228
- /// Result<Vec<ngx_addr_t>, Error>, where both the Vec and internals of
229
- /// the ngx_addr_t are allocated on the given Pool
222
+ /// Result<Vec<ngx_addr_t>, Error>, where the internals of the ngx_addr_t
223
+ /// are allocated on the given Pool
230
224
fn resolve_result ( ctx : * mut ngx_resolver_ctx_t , pool : & Pool ) -> Res {
231
225
let ctx = unsafe { ctx. as_ref ( ) . unwrap ( ) } ;
232
- let s = ctx. state ;
233
- if s != 0 {
226
+ if let Some ( e) = NonZero :: new ( ctx. state ) {
234
227
return Err ( Error :: Resolver (
235
- ResolverError :: try_from ( s ) . expect ( "nonzero, checked above" ) ,
228
+ ResolverError :: from ( e ) ,
236
229
ctx. name . to_string ( ) ,
237
230
) ) ;
238
231
}
239
232
if ctx. addrs . is_null ( ) {
240
233
Err ( Error :: AllocationFailed ) ?;
241
234
}
242
- let mut out = Vec :: new ( ) ;
243
- for i in 0 ..ctx. naddrs {
244
- out. push ( Self :: copy_resolved_addr ( unsafe { ctx. addrs . add ( i) } , pool) ?) ;
235
+
236
+ if ctx. naddrs > 0 {
237
+ unsafe { core:: slice:: from_raw_parts ( ctx. addrs , ctx. naddrs ) }
238
+ . iter ( )
239
+ . map ( |addr| Self :: copy_resolved_addr ( addr, pool) )
240
+ . collect :: < Result < Vec < _ > , _ > > ( )
241
+ } else {
242
+ Ok ( Vec :: new ( ) )
245
243
}
246
- Ok ( out)
247
244
}
248
245
249
246
/// Take the contents of an ngx_resolver_addr_t and make an owned copy as
250
247
/// an ngx_addr_t, using the Pool for allocation of the internals.
251
248
fn copy_resolved_addr (
252
- addr : * mut nginx_sys:: ngx_resolver_addr_t ,
249
+ addr : & nginx_sys:: ngx_resolver_addr_t ,
253
250
pool : & Pool ,
254
251
) -> Result < ngx_addr_t , Error > {
255
- let addr = NonNull :: new ( addr) . ok_or ( Error :: Unexpected (
256
- "null ngx_resolver_addr_t in ngx_resolver_ctx_t.addrs" . to_string ( ) ,
257
- ) ) ?;
258
- let addr = unsafe { addr. as_ref ( ) } ;
259
-
260
252
let sockaddr = pool. alloc ( addr. socklen as usize ) as * mut nginx_sys:: sockaddr ;
261
253
if sockaddr. is_null ( ) {
262
254
Err ( Error :: AllocationFailed ) ?;
0 commit comments