Skip to content

Commit

Permalink
Add peer_addr host functions for UDP and TCP (#169)
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkintoshZ authored Dec 19, 2022
1 parent 8578346 commit 7eb5cc2
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 0 deletions.
47 changes: 47 additions & 0 deletions crates/lunatic-networking-api/src/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub fn register<T: NetworkingCtx + ErrorCtx + Send + 'static>(
linker.func_wrap("lunatic::networking", "tcp_local_addr", tcp_local_addr)?;
linker.func_wrap3_async("lunatic::networking", "tcp_accept", tcp_accept)?;
linker.func_wrap7_async("lunatic::networking", "tcp_connect", tcp_connect)?;
linker.func_wrap2_async("lunatic::networking", "tcp_peer_addr", tcp_peer_addr)?;
linker.func_wrap("lunatic::networking", "drop_tcp_stream", drop_tcp_stream)?;
linker.func_wrap("lunatic::networking", "clone_tcp_stream", clone_tcp_stream)?;
linker.func_wrap4_async(
Expand Down Expand Up @@ -320,6 +321,52 @@ fn clone_tcp_stream<T: NetworkingCtx>(mut caller: Caller<T>, tcp_stream_id: u64)
Ok(id)
}

// Returns the remote address this tcp socket is connected to, bound to a DNS
// iterator with just one element.
//
// * 0 on success - The peer address that this socket is bound to, returned as a DNS
// iterator with just one element and written to **id_ptr**.
// * 1 on error - The error ID is written to **id_u64_ptr**.
//
// Traps:
// * If the tcp socket ID doesn't exist.
// * If any memory outside the guest heap space is referenced.
fn tcp_peer_addr<T: NetworkingCtx + ErrorCtx + Send>(
mut caller: Caller<T>,
tcp_stream_id: u64,
id_u64_ptr: u32,
) -> Box<dyn Future<Output = Result<u32>> + Send + '_> {
Box::new(async move {
let tcp_stream = caller
.data()
.tcp_stream_resources()
.get(tcp_stream_id)
.or_trap("lunatic::network::tcp_peer_addr: stream ID doesn't exist")?;
let peer_addr = tcp_stream.writer.lock().await.peer_addr();
let (dns_iter_or_error_id, result) = match peer_addr {
Ok(socket_addr) => {
let dns_iter_id = caller
.data_mut()
.dns_resources_mut()
.add(DnsIterator::new(vec![socket_addr].into_iter()));
(dns_iter_id, 0)
}
Err(error) => (caller.data_mut().error_resources_mut().add(error.into()), 1),
};

let memory = get_memory(&mut caller)?;
memory
.write(
&mut caller,
id_u64_ptr as usize,
&dns_iter_or_error_id.to_le_bytes(),
)
.or_trap("lunatic::network::tcp_peer_addr")?;

Ok(result)
})
}

// Gathers data from the vector buffers and writes them to the stream. **ciovec_array_ptr** points
// to an array of (ciovec_ptr, ciovec_len) pairs where each pair represents a buffer to be written.
//
Expand Down
52 changes: 52 additions & 0 deletions crates/lunatic-networking-api/src/udp.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::future::Future;
use std::io::ErrorKind;
use std::sync::Arc;
use std::time::Duration;

Expand All @@ -18,6 +19,7 @@ pub fn register<T: NetworkingCtx + ErrorCtx + Send + 'static>(
) -> Result<()> {
linker.func_wrap6_async("lunatic::networking", "udp_bind", udp_bind)?;
linker.func_wrap("lunatic::networking", "udp_local_addr", udp_local_addr)?;
linker.func_wrap("lunatic::networking", "udp_peer_addr", udp_peer_addr)?;
linker.func_wrap("lunatic::networking", "drop_udp_socket", drop_udp_socket)?;
linker.func_wrap4_async("lunatic::networking", "udp_receive", udp_receive)?;
linker.func_wrap5_async("lunatic::networking", "udp_receive_from", udp_receive_from)?;
Expand Down Expand Up @@ -530,3 +532,53 @@ fn udp_local_addr<T: NetworkingCtx + ErrorCtx + Send>(

Ok(result)
}

// Returns the remote address this udp socket was connected to, bound to a DNS
// iterator with just one element.
//
// * 0 on success - The peer address that this socket is bound to, returned as a DNS
// iterator with just one element and written to **id_ptr**.
// * 1 on NotConnected error - The error ID is written to **id_u64_ptr**.
// * 2 on Other errors - The error ID is written to **id_u64_ptr**.
//
// Traps:
// * If the udp socket ID doesn't exist.
// * If any memory outside the guest heap space is referenced.
fn udp_peer_addr<T: NetworkingCtx + ErrorCtx + Send>(
mut caller: Caller<T>,
udp_socket_id: u64,
id_u64_ptr: u32,
) -> Result<u32> {
let udp_socket = caller
.data()
.udp_resources()
.get(udp_socket_id)
.or_trap("lunatic::network::udp_peer_addr: listener ID doesn't exist")?;
let (dns_iter_or_error_id, result) = match udp_socket.peer_addr() {
Ok(socket_addr) => {
let dns_iter_id = caller
.data_mut()
.dns_resources_mut()
.add(DnsIterator::new(vec![socket_addr].into_iter()));
(dns_iter_id, 0)
}
Err(error) => {
if error.kind() == ErrorKind::NotConnected {
(caller.data_mut().error_resources_mut().add(error.into()), 1)
} else {
(caller.data_mut().error_resources_mut().add(error.into()), 2)
}
}
};

let memory = get_memory(&mut caller)?;
memory
.write(
&mut caller,
id_u64_ptr as usize,
&dns_iter_or_error_id.to_le_bytes(),
)
.or_trap("lunatic::network::udp_peer_addr")?;

Ok(result)
}

0 comments on commit 7eb5cc2

Please # to comment.