viceroy_lib/wiggle_abi/
geo_impl.rs1use std::{
4 convert::TryInto,
5 net::{IpAddr, Ipv4Addr, Ipv6Addr},
6};
7
8use {
9 crate::{error::Error, session::Session, wiggle_abi::fastly_geo::FastlyGeo},
10 std::convert::TryFrom,
11 wiggle::{GuestMemory, GuestPtr},
12};
13
14impl FastlyGeo for Session {
15 fn lookup(
16 &mut self,
17 memory: &mut GuestMemory<'_>,
18 addr_octets: GuestPtr<u8>,
19 addr_len: u32,
20 buf: GuestPtr<u8>,
21 buf_len: u32,
22 nwritten_out: GuestPtr<u32>,
23 ) -> Result<(), Error> {
24 let octets = memory.to_vec(addr_octets.as_array(addr_len))?;
25
26 let ip_addr: IpAddr = match addr_len {
27 4 => IpAddr::V4(Ipv4Addr::from(
28 TryInto::<[u8; 4]>::try_into(octets).unwrap(),
29 )),
30 16 => IpAddr::V6(Ipv6Addr::from(
31 TryInto::<[u8; 16]>::try_into(octets).unwrap(),
32 )),
33 _ => return Err(Error::InvalidArgument),
34 };
35
36 let result = self.geolocation_lookup(&ip_addr).unwrap_or_default();
37
38 if result.len() > buf_len as usize {
39 memory.write(nwritten_out, u32::try_from(result.len()).unwrap_or(0))?;
40 return Err(Error::BufferLengthError {
41 buf: "geolocation_lookup",
42 len: "geolocation_lookup_max_len",
43 });
44 }
45
46 let result_len =
47 u32::try_from(result.len()).expect("smaller than value_max_len means it must fit");
48
49 memory.copy_from_slice(result.as_bytes(), buf.as_array(result_len))?;
50 memory.write(nwritten_out, result_len)?;
51 Ok(())
52 }
53}