|
@@ -5,6 +5,7 @@ mod dns;
|
|
|
use core::str::FromStr;
|
|
|
use core::{mem, ptr, slice, str};
|
|
|
|
|
|
+use alloc::borrow::ToOwned;
|
|
|
use alloc::boxed::Box;
|
|
|
use alloc::str::SplitWhitespace;
|
|
|
use alloc::vec::Vec;
|
|
@@ -13,11 +14,11 @@ use c_str::{CStr, CString};
|
|
|
use header::arpa_inet::htons;
|
|
|
use header::errno::*;
|
|
|
use header::fcntl::O_RDONLY;
|
|
|
-use header::netinet_in::{in_addr, sockaddr_in};
|
|
|
+use header::netinet_in::{in_addr, sockaddr_in, sockaddr_in6};
|
|
|
use header::stdlib::atoi;
|
|
|
use header::strings::strcasecmp;
|
|
|
use header::sys_socket::constants::{AF_UNSPEC, AF_INET};
|
|
|
-use header::sys_socket::{sockaddr, socklen_t};
|
|
|
+use header::sys_socket::{sa_family_t, sockaddr, socklen_t};
|
|
|
use header::unistd::SEEK_SET;
|
|
|
use platform;
|
|
|
use platform::rlb::{Line, RawLineBuffer};
|
|
@@ -670,15 +671,72 @@ pub unsafe extern "C" fn getaddrinfo(
|
|
|
|
|
|
let hints_opt = if hints.is_null() { None } else { Some(&*hints) };
|
|
|
|
|
|
- eprintln!(
|
|
|
+ trace!(
|
|
|
"getaddrinfo({:?}, {:?}, {:?})",
|
|
|
node_opt.map(|c| str::from_utf8_unchecked(c.to_bytes())),
|
|
|
service_opt.map(|c| str::from_utf8_unchecked(c.to_bytes())),
|
|
|
hints_opt
|
|
|
);
|
|
|
|
|
|
- platform::errno = ENOSYS;
|
|
|
- EAI_SYSTEM
|
|
|
+ //TODO: Use hints
|
|
|
+ let mut ai_flags = hints_opt.map_or(0, |hints| hints.ai_flags);
|
|
|
+ let mut ai_family = hints_opt.map_or(AF_UNSPEC, |hints| hints.ai_family);
|
|
|
+ let mut ai_socktype = hints_opt.map_or(0, |hints| hints.ai_socktype);
|
|
|
+ let mut ai_protocol = hints_opt.map_or(0, |hints| hints.ai_protocol);
|
|
|
+
|
|
|
+ *res = ptr::null_mut();
|
|
|
+
|
|
|
+ //TODO: Check hosts file
|
|
|
+ if let Some(node) = node_opt {
|
|
|
+ let lookuphost = match lookup_host(str::from_utf8_unchecked(node.to_bytes())) {
|
|
|
+ Ok(lookuphost) => lookuphost,
|
|
|
+ Err(e) => {
|
|
|
+ platform::errno = e;
|
|
|
+ return EAI_SYSTEM;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ for in_addr in lookuphost {
|
|
|
+ ai_family = AF_INET;
|
|
|
+ ai_socktype = AF_UNSPEC;
|
|
|
+ ai_protocol = 0;
|
|
|
+
|
|
|
+ let ai_addr = Box::into_raw(Box::new(sockaddr_in {
|
|
|
+ sin_family: AF_INET as sa_family_t,
|
|
|
+ sin_port: 0,
|
|
|
+ sin_addr: in_addr,
|
|
|
+ sin_zero: [0; 8]
|
|
|
+ })) as *mut sockaddr;
|
|
|
+
|
|
|
+ let ai_addrlen = mem::size_of::<sockaddr_in>();
|
|
|
+
|
|
|
+ let ai_canonname = if ai_flags & AI_CANONNAME > 0 {
|
|
|
+ ai_flags &= !AI_CANONNAME;
|
|
|
+ node.to_owned().into_raw()
|
|
|
+ } else {
|
|
|
+ ptr::null_mut()
|
|
|
+ };
|
|
|
+
|
|
|
+ let addrinfo = Box::new(addrinfo {
|
|
|
+ ai_flags: 0,
|
|
|
+ ai_family,
|
|
|
+ ai_socktype,
|
|
|
+ ai_protocol,
|
|
|
+ ai_addrlen,
|
|
|
+ ai_canonname,
|
|
|
+ ai_addr,
|
|
|
+ ai_next: ptr::null_mut(),
|
|
|
+ });
|
|
|
+
|
|
|
+ let mut indirect = res;
|
|
|
+ while !(*indirect).is_null() {
|
|
|
+ indirect=&mut (**indirect).ai_next;
|
|
|
+ }
|
|
|
+ *indirect = Box::into_raw(addrinfo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ 0
|
|
|
}
|
|
|
|
|
|
#[no_mangle]
|
|
@@ -721,8 +779,19 @@ pub unsafe extern "C" fn freeaddrinfo(res: *mut addrinfo) {
|
|
|
let mut ai = res;
|
|
|
while !ai.is_null() {
|
|
|
let bai = Box::from_raw(ai);
|
|
|
- ai = (*ai).ai_next;
|
|
|
- drop(bai);
|
|
|
+ if !bai.ai_canonname.is_null() {
|
|
|
+ CString::from_raw(bai.ai_canonname);
|
|
|
+ }
|
|
|
+ if !bai.ai_addr.is_null() {
|
|
|
+ if bai.ai_addrlen == mem::size_of::<sockaddr_in>() {
|
|
|
+ Box::from_raw(bai.ai_addr as *mut sockaddr_in);
|
|
|
+ } else if bai.ai_addrlen == mem::size_of::<sockaddr_in6>() {
|
|
|
+ Box::from_raw(bai.ai_addr as *mut sockaddr_in6);
|
|
|
+ } else {
|
|
|
+ eprintln!("freeaddrinfo: unknown ai_addrlen {}", bai.ai_addrlen);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ai = bai.ai_next;
|
|
|
}
|
|
|
}
|
|
|
|