@@ -18,9 +18,10 @@ use rt::uv::uvll;
18
18
use rt:: uv:: uvll:: UV_GETADDRINFO ;
19
19
use rt:: uv:: { Loop , UvError , NativeHandle } ;
20
20
use rt:: uv:: status_to_maybe_uv_error;
21
- use rt:: uv:: net:: UvAddrInfo ;
21
+ use rt:: uv:: net;
22
+ use ai = rt:: io:: net:: addrinfo;
22
23
23
- type GetAddrInfoCallback = ~fn ( GetAddrInfoRequest , & UvAddrInfo , Option < UvError > ) ;
24
+ type GetAddrInfoCallback = ~fn ( GetAddrInfoRequest , & net :: UvAddrInfo , Option < UvError > ) ;
24
25
25
26
pub struct GetAddrInfoRequest ( * uvll:: uv_getaddrinfo_t ) ;
26
27
@@ -38,7 +39,7 @@ impl GetAddrInfoRequest {
38
39
}
39
40
40
41
pub fn getaddrinfo ( & mut self , loop_ : & Loop , node : Option < & str > ,
41
- service : Option < & str > , hints : Option < UvAddrInfo > ,
42
+ service : Option < & str > , hints : Option < ai :: Hint > ,
42
43
cb : GetAddrInfoCallback ) {
43
44
44
45
assert ! ( node. is_some( ) || service. is_some( ) ) ;
@@ -72,8 +73,37 @@ impl GetAddrInfoRequest {
72
73
cb ( req, addrinfo, err)
73
74
} ;
74
75
75
- // XXX: Implement hints
76
- assert ! ( hints. is_none( ) ) ;
76
+ let hint = hints. map ( |hint| unsafe {
77
+ let mut flags = 0 ;
78
+ do each_ai_flag |cval, aival| {
79
+ if hint. flags & ( aival as uint ) != 0 {
80
+ flags |= cval as i32 ;
81
+ }
82
+ }
83
+ let socktype = match hint. socktype {
84
+ Some ( ai:: Stream ) => uvll:: rust_SOCK_STREAM ( ) ,
85
+ Some ( ai:: Datagram ) => uvll:: rust_SOCK_DGRAM ( ) ,
86
+ Some ( ai:: Raw ) => uvll:: rust_SOCK_RAW ( ) ,
87
+ None => 0 ,
88
+ } ;
89
+ let protocol = match hint. protocol {
90
+ Some ( ai:: UDP ) => uvll:: rust_IPPROTO_UDP ( ) ,
91
+ Some ( ai:: TCP ) => uvll:: rust_IPPROTO_TCP ( ) ,
92
+ _ => 0 ,
93
+ } ;
94
+
95
+ uvll:: addrinfo {
96
+ ai_flags : flags,
97
+ ai_family : hint. family as c_int ,
98
+ ai_socktype : socktype,
99
+ ai_protocol : protocol,
100
+ ai_addrlen : 0 ,
101
+ ai_canonname : null ( ) ,
102
+ ai_addr : null ( ) ,
103
+ ai_next : null ( ) ,
104
+ }
105
+ } ) ;
106
+ let hint_ptr = hint. as_ref ( ) . map_default ( null ( ) , |x| x as * uvll:: addrinfo ) ;
77
107
78
108
self . get_req_data ( ) . getaddrinfo_cb = Some ( wrapper_cb) ;
79
109
@@ -83,15 +113,15 @@ impl GetAddrInfoRequest {
83
113
getaddrinfo_cb,
84
114
c_node_ptr,
85
115
c_service_ptr,
86
- null ( ) ) ) ;
116
+ hint_ptr ) ) ;
87
117
}
88
118
89
119
extern "C" fn getaddrinfo_cb ( req : * uvll:: uv_getaddrinfo_t ,
90
120
status : c_int ,
91
121
res : * uvll:: addrinfo ) {
92
122
let mut req: GetAddrInfoRequest = NativeHandle :: from_native_handle ( req) ;
93
123
let err = status_to_maybe_uv_error ( status) ;
94
- let addrinfo = UvAddrInfo ( res) ;
124
+ let addrinfo = net :: UvAddrInfo ( res) ;
95
125
let data = req. get_req_data ( ) ;
96
126
( * data. getaddrinfo_cb . get_ref ( ) ) ( req, & addrinfo, err) ;
97
127
unsafe {
@@ -137,6 +167,66 @@ impl GetAddrInfoRequest {
137
167
}
138
168
}
139
169
170
+ fn each_ai_flag ( f : & fn ( c_int , ai:: Flag ) ) {
171
+ unsafe {
172
+ f ( uvll:: rust_AI_ADDRCONFIG ( ) , ai:: AddrConfig ) ;
173
+ f ( uvll:: rust_AI_ALL ( ) , ai:: All ) ;
174
+ f ( uvll:: rust_AI_CANONNAME ( ) , ai:: CanonName ) ;
175
+ f ( uvll:: rust_AI_NUMERICHOST ( ) , ai:: NumericHost ) ;
176
+ f ( uvll:: rust_AI_NUMERICSERV ( ) , ai:: NumericServ ) ;
177
+ f ( uvll:: rust_AI_PASSIVE ( ) , ai:: Passive ) ;
178
+ f ( uvll:: rust_AI_V4MAPPED ( ) , ai:: V4Mapped ) ;
179
+ }
180
+ }
181
+
182
+ // Traverse the addrinfo linked list, producing a vector of Rust socket addresses
183
+ pub fn accum_addrinfo( addr : & net:: UvAddrInfo ) -> ~[ ai:: Info ] {
184
+ unsafe {
185
+ let & net:: UvAddrInfo ( addr) = addr;
186
+ let mut addr = addr;
187
+
188
+ let mut addrs = ~[ ] ;
189
+ loop {
190
+ let uvaddr = net:: sockaddr_to_UvSocketAddr ( ( * addr) . ai_addr ) ;
191
+ let rustaddr = net:: uv_socket_addr_to_socket_addr ( uvaddr) ;
192
+
193
+ let mut flags = 0 ;
194
+ do each_ai_flag |cval, aival| {
195
+ if ( * addr) . ai_flags & cval != 0 {
196
+ flags |= aival as uint ;
197
+ }
198
+ }
199
+
200
+ let protocol = match ( * addr) . ai_protocol {
201
+ p if p == uvll:: rust_IPPROTO_UDP ( ) => Some ( ai:: UDP ) ,
202
+ p if p == uvll:: rust_IPPROTO_TCP ( ) => Some ( ai:: TCP ) ,
203
+ _ => None ,
204
+ } ;
205
+ let socktype = match ( * addr) . ai_socktype {
206
+ p if p == uvll:: rust_SOCK_STREAM ( ) => Some ( ai:: Stream ) ,
207
+ p if p == uvll:: rust_SOCK_DGRAM ( ) => Some ( ai:: Datagram ) ,
208
+ p if p == uvll:: rust_SOCK_RAW ( ) => Some ( ai:: Raw ) ,
209
+ _ => None ,
210
+ } ;
211
+
212
+ addrs. push ( ai:: Info {
213
+ address : rustaddr,
214
+ family : ( * addr) . ai_family as uint ,
215
+ socktype : socktype,
216
+ protocol : protocol,
217
+ flags : flags,
218
+ } ) ;
219
+ if ( * addr) . ai_next . is_not_null ( ) {
220
+ addr = ( * addr) . ai_next ;
221
+ } else {
222
+ break ;
223
+ }
224
+ }
225
+
226
+ return addrs;
227
+ }
228
+ }
229
+
140
230
impl NativeHandle < * uvll:: uv_getaddrinfo_t > for GetAddrInfoRequest {
141
231
fn from_native_handle ( handle : * uvll:: uv_getaddrinfo_t ) -> GetAddrInfoRequest {
142
232
GetAddrInfoRequest ( handle)
@@ -150,7 +240,6 @@ impl NativeHandle<*uvll::uv_getaddrinfo_t> for GetAddrInfoRequest {
150
240
mod test {
151
241
use option:: { Some , None } ;
152
242
use rt:: uv:: Loop ;
153
- use rt:: uv:: net:: accum_sockaddrs;
154
243
use rt:: io:: net:: ip:: { SocketAddr , Ipv4Addr } ;
155
244
use super :: * ;
156
245
@@ -159,14 +248,14 @@ mod test {
159
248
let mut loop_ = Loop :: new ( ) ;
160
249
let mut req = GetAddrInfoRequest :: new ( ) ;
161
250
do req. getaddrinfo ( & loop_, Some ( "localhost" ) , None , None ) |_, addrinfo, _| {
162
- let sockaddrs = accum_sockaddrs ( addrinfo) ;
251
+ let sockaddrs = accum_addrinfo ( addrinfo) ;
163
252
let mut found_local = false ;
164
253
let local_addr = & SocketAddr {
165
254
ip : Ipv4Addr ( 127 , 0 , 0 , 1 ) ,
166
255
port : 0
167
256
} ;
168
257
for addr in sockaddrs. iter ( ) {
169
- found_local = found_local || addr == local_addr;
258
+ found_local = found_local || addr. address == * local_addr;
170
259
}
171
260
assert ! ( found_local) ;
172
261
}
0 commit comments