Skip to content

Commit

Permalink
[starnix] Add socket wrappers to syncio
Browse files Browse the repository at this point in the history
This adds helper functions to simplify calling zxio functions from
inet sockets.

This also adds stubs/missing_includes.h to the syncio library so
bindgen can generate zxio shutdown option constants. Without this,
bindgen runs into the issue where it can't expand C macros.
See: rust-lang/rust-bindgen#753

Change-Id: I8e3e9aa015212a2cb8dabdc678d5c08329060014
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/729108
Reviewed-by: Adam Barth <abarth@google.com>
Commit-Queue: Vickie Cheng <vickiecheng@google.com>
  • Loading branch information
vickiecheng authored and CQ Bot committed Sep 28, 2022
1 parent fc1df73 commit 7475d5f
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 13 deletions.
12 changes: 1 addition & 11 deletions src/proc/bin/starnix/fs/socket/socket_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use zerocopy::AsBytes;

use crate::fs::*;
use crate::types::*;
pub use syncio::ZxioShutdownFlags as SocketShutdownFlags;

bitflags! {
pub struct SocketMessageFlags: u32 {
Expand All @@ -34,17 +35,6 @@ bitflags! {
}
}

bitflags! {
/// The flags for shutting down sockets.
pub struct SocketShutdownFlags: u32 {
/// Further receptions will be disallowed.
const READ = 1 << 0;

/// Further transmissions will be disallowed.
const WRITE = 1 << 2;
}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum SocketDomain {
/// The `Unix` socket domain contains sockets that were created with the `AF_UNIX` domain. These
Expand Down
1 change: 1 addition & 0 deletions src/proc/lib/syncio/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ rustc_library("syncio") {
"//sdk/fidl/fuchsia.io:fuchsia.io_rust",
"//src/lib/fidl/rust/fidl",
"//src/lib/zircon/rust:fuchsia-zircon",
"//src/proc/lib/linux_uapi",
"//third_party/rust_crates:bitflags",
]

Expand Down
1 change: 1 addition & 0 deletions src/proc/lib/syncio/bindgen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ PATH="$PWD/prebuilt/third_party/rust/linux-x64/bin:$PATH" \
--size_t-is-usize \
--with-derive-default \
--allowlist-function "zxio_.*" \
--allowlist-var "ZXIO_SHUTDOWN.*" \
--allowlist-var "E[A-Z]*" \
--raw-line "${RAW_LINES}" \
-o src/proc/lib/syncio/src/zxio.rs \
Expand Down
159 changes: 157 additions & 2 deletions src/proc/lib/syncio/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

use std::convert::From;

use crate::zxio::{zxio_dirent_iterator_next, zxio_dirent_iterator_t};
use bitflags::bitflags;
use fidl::encoding::const_assert_eq;
use fidl::endpoints::ServerEnd;
use fidl_fuchsia_io as fio;
use fuchsia_zircon::{self as zx, HandleBased};

use crate::zxio::{zxio_dirent_iterator_next, zxio_dirent_iterator_t};
use linux_uapi::x86_64::sockaddr_storage;
use zxio::{sockaddr, socklen_t, ZXIO_SHUTDOWN_OPTIONS_READ, ZXIO_SHUTDOWN_OPTIONS_WRITE};

pub mod zxio;

Expand All @@ -33,6 +35,20 @@ bitflags! {
}
}

bitflags! {
/// The flags for shutting down sockets.
pub struct ZxioShutdownFlags: u32 {
/// Further transmissions will be disallowed.
const WRITE = 1 << 0;

/// Further receptions will be disallowed.
const READ = 1 << 1;
}
}

const_assert_eq!(ZxioShutdownFlags::WRITE.bits(), ZXIO_SHUTDOWN_OPTIONS_WRITE);
const_assert_eq!(ZxioShutdownFlags::READ.bits(), ZXIO_SHUTDOWN_OPTIONS_READ);

// TODO: We need a more comprehensive error strategy.
// Our dependencies create elaborate error objects, but Starnix would prefer
// this library produce zx::Status errors for easier conversion to Errno.
Expand Down Expand Up @@ -110,6 +126,8 @@ impl ZxioDirent {
}
}

pub struct ZxioErrorCode(i16);

#[derive(Default)]
pub struct Zxio {
storage: zxio::zxio_storage_t,
Expand Down Expand Up @@ -268,6 +286,143 @@ impl Zxio {
zx::ok(status)?;
Ok(iterator)
}

pub fn connect(&self, addr: &[u8]) -> Result<ZxioErrorCode, zx::Status> {
let mut out_code = 0;
let status = unsafe {
zxio::zxio_connect(
self.as_ptr(),
addr.as_ptr() as *const sockaddr,
addr.len() as socklen_t,
&mut out_code,
)
};
zx::ok(status)?;
Ok(ZxioErrorCode(out_code))
}

pub fn bind(&self, addr: &[u8]) -> Result<ZxioErrorCode, zx::Status> {
let mut out_code = 0;
let status = unsafe {
zxio::zxio_bind(
self.as_ptr(),
addr.as_ptr() as *const sockaddr,
addr.len() as socklen_t,
&mut out_code,
)
};
zx::ok(status)?;
Ok(ZxioErrorCode(out_code))
}

pub fn listen(&self, backlog: i32) -> Result<ZxioErrorCode, zx::Status> {
let mut out_code = 0;
let status = unsafe {
zxio::zxio_listen(self.as_ptr(), backlog as std::os::raw::c_int, &mut out_code)
};
zx::ok(status)?;
Ok(ZxioErrorCode(out_code))
}

pub fn accept(&self) -> Result<(Zxio, ZxioErrorCode), zx::Status> {
let mut addrlen = std::mem::size_of::<sockaddr_storage>() as socklen_t;
let mut addr = vec![0u8; addrlen as usize];
let zxio = Zxio::default();
let mut out_code = 0;
let status = unsafe {
zxio::zxio_accept(
self.as_ptr(),
addr.as_mut_ptr() as *mut sockaddr,
&mut addrlen,
zxio.as_storage_ptr(),
&mut out_code,
)
};
zx::ok(status)?;
Ok((zxio, ZxioErrorCode(out_code)))
}

pub fn getsockname(&self) -> Result<(Vec<u8>, ZxioErrorCode), zx::Status> {
let mut addrlen = std::mem::size_of::<sockaddr_storage>() as socklen_t;
let mut addr = vec![0u8; addrlen as usize];
let mut out_code = 0;
let status = unsafe {
zxio::zxio_getsockname(
self.as_ptr(),
addr.as_mut_ptr() as *mut sockaddr,
&mut addrlen,
&mut out_code,
)
};
zx::ok(status)?;
Ok((addr[..addrlen as usize].to_vec(), ZxioErrorCode(out_code)))
}

pub fn getpeername(&self) -> Result<(Vec<u8>, ZxioErrorCode), zx::Status> {
let mut addrlen = std::mem::size_of::<sockaddr_storage>() as socklen_t;
let mut addr = vec![0u8; addrlen as usize];
let mut out_code = 0;
let status = unsafe {
zxio::zxio_getpeername(
self.as_ptr(),
addr.as_mut_ptr() as *mut sockaddr,
&mut addrlen,
&mut out_code,
)
};
zx::ok(status)?;
Ok((addr[..addrlen as usize].to_vec(), ZxioErrorCode(out_code)))
}

pub fn getsockopt(
&self,
level: u32,
optname: u32,
mut optlen: socklen_t,
) -> Result<(Vec<u8>, ZxioErrorCode), zx::Status> {
let mut optval = vec![0u8; optlen as usize];
let mut out_code = 0;
let status = unsafe {
zxio::zxio_getsockopt(
self.as_ptr(),
level as std::os::raw::c_int,
optname as std::os::raw::c_int,
optval.as_mut_ptr() as *mut std::os::raw::c_void,
&mut optlen,
&mut out_code,
)
};
zx::ok(status)?;
Ok((optval[..optlen as usize].to_vec(), ZxioErrorCode(out_code)))
}

pub fn setsockopt(
&self,
level: i32,
optname: i32,
optval: &[u8],
) -> Result<ZxioErrorCode, zx::Status> {
let mut out_code = 0;
let status = unsafe {
zxio::zxio_setsockopt(
self.as_ptr(),
level,
optname,
optval.as_ptr() as *const std::os::raw::c_void,
optval.len() as socklen_t,
&mut out_code,
)
};
zx::ok(status)?;
Ok(ZxioErrorCode(out_code))
}

pub fn shutdown(&self, flags: ZxioShutdownFlags) -> Result<ZxioErrorCode, zx::Status> {
let mut out_code = 0;
let status = unsafe { zxio::zxio_shutdown(self.as_ptr(), flags.bits(), &mut out_code) };
zx::ok(status)?;
Ok(ZxioErrorCode(out_code))
}
}

impl Drop for Zxio {
Expand Down
2 changes: 2 additions & 0 deletions src/proc/lib/syncio/src/zxio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -659,3 +659,5 @@ extern "C" {
abilities: zxio_abilities_t,
) -> u32;
}
pub const ZXIO_SHUTDOWN_OPTIONS_READ: zxio_shutdown_options_t = 2;
pub const ZXIO_SHUTDOWN_OPTIONS_WRITE: zxio_shutdown_options_t = 1;
21 changes: 21 additions & 0 deletions src/proc/lib/syncio/stub/missing_includes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_PROC_LIB_SYNCIO_STUB_MISSING_INCLUDES_H_
#define SRC_PROC_LIB_SYNCIO_STUB_MISSING_INCLUDES_H_

// Adding includes that are not detected by rust-bindings because they are
// defined using functions

#include <lib/zxio/types.h>

const zxio_shutdown_options_t _ZXIO_SHUTDOWN_OPTIONS_READ = ZXIO_SHUTDOWN_OPTIONS_READ;
#undef ZXIO_SHUTDOWN_OPTIONS_READ
const zxio_shutdown_options_t ZXIO_SHUTDOWN_OPTIONS_READ = _ZXIO_SHUTDOWN_OPTIONS_READ;

const zxio_shutdown_options_t _ZXIO_SHUTDOWN_OPTIONS_WRITE = ZXIO_SHUTDOWN_OPTIONS_WRITE;
#undef ZXIO_SHUTDOWN_OPTIONS_WRITE
const zxio_shutdown_options_t ZXIO_SHUTDOWN_OPTIONS_WRITE = _ZXIO_SHUTDOWN_OPTIONS_WRITE;

#endif // SRC_PROC_LIB_SYNCIO_STUB_MISSING_INCLUDES_H_
2 changes: 2 additions & 0 deletions src/proc/lib/syncio/wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@
#include <lib/zxio/posix_mode.h>
#include <lib/zxio/zxio.h>

#include "stub/missing_includes.h"

#endif // SRC_PROC_LIB_SYNCIO_WRAPPER_H_

0 comments on commit 7475d5f

Please sign in to comment.