use crate::error::{Error, HandleError};
use crate::session::Session;
use crate::wiggle_abi::{fastly_acl, types};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
impl fastly_acl::FastlyAcl for Session {
fn open(
&mut self,
memory: &mut wiggle::GuestMemory<'_>,
acl_name: wiggle::GuestPtr<str>,
) -> Result<types::AclHandle, Error> {
let acl_name = memory.as_str(acl_name)?.ok_or(Error::SharedMemory)?;
self.acl_handle_by_name(acl_name).ok_or(Error::ValueAbsent)
}
async fn lookup(
&mut self,
memory: &mut wiggle::GuestMemory<'_>,
acl_handle: types::AclHandle,
ip_octets: wiggle::GuestPtr<u8>, ip_len: u32, body_handle_out: wiggle::GuestPtr<types::BodyHandle>,
acl_error_out: wiggle::GuestPtr<types::AclError>,
) -> Result<(), Error> {
let acl = self.acl_by_handle(acl_handle).ok_or(Error::HandleError(
HandleError::InvalidAclHandle(acl_handle),
))?;
let ip: IpAddr = {
let ip_octets = memory.to_vec(ip_octets.as_array(ip_len))?;
match ip_len {
4 => IpAddr::V4(Ipv4Addr::from(
TryInto::<[u8; 4]>::try_into(ip_octets).unwrap(),
)),
16 => IpAddr::V6(Ipv6Addr::from(
TryInto::<[u8; 16]>::try_into(ip_octets).unwrap(),
)),
_ => return Err(Error::InvalidArgument),
}
};
match acl.lookup(ip) {
Some(entry) => {
let body =
serde_json::to_vec_pretty(&entry).map_err(|err| Error::Other(err.into()))?;
let body_handle = self.insert_body(body.into());
memory.write(body_handle_out, body_handle)?;
memory.write(acl_error_out, types::AclError::Ok)?;
Ok(())
}
None => {
memory.write(acl_error_out, types::AclError::NoContent)?;
Ok(())
}
}
}
}