Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abstractions of socket and related network entities #1066

Open
wants to merge 7 commits into
base: staging/rust-net
Choose a base branch
from

Commits on Feb 24, 2024

  1. rust/net: add net module files and shared enums.

    Create `net` module files and network headers in `bindings_helper.h`.
    Add `IpProtocol`, `AddressFamily` and `Namespace`.
    
    The wrappers added with this patch are shared across the whole network
    subsystem. For this reason, they are placed in the `net.rs` module file.
    
    The enum `IpProtocol`, however, is placed in an individual `ip.rs`
    submodule, allowing to place together all the ip-related structures,
    such as wrappers for `iphdr`, `ip_auth_hdr`, etc.
    
    Signed-off-by: Michele Dalle Rive <dallerivemichele@gmail.com>
    Michele Dalle Rive authored and micheledallerive committed Feb 24, 2024
    Configuration menu
    Copy the full SHA
    371ab19 View commit details
    Browse the repository at this point in the history
  2. rust/net: add ip and socket address bindings.

    Create structures to handle addresses: `Ipv4Addr`, `Ipv6Addr`,
    `SocketAddr`, `SocketAddrV4` and `SocketAddrV6`.
    
    These structures are meant to be as similar as possible to the ones in
    Rust `std::net`, while, at the same time, providing functionalities
    available in the kernel.
    
    Some extra structures are added, compared to `std`:
    - `SocketAddrStorage`: wraps `struct sockaddr_storage` and is used to
      interact with the kernel functions when the type of socket address is
      unknown. Since it is only used for FFI, it is crate-public.
    - `GenericSocketAddr`: trait that defines shared functions and traits
      amont all socket addresses.
    
    Signed-off-by: Michele Dalle Rive <dallerivemichele@gmail.com>
    Michele Dalle Rive authored and micheledallerive committed Feb 24, 2024
    Configuration menu
    Copy the full SHA
    bec8bf0 View commit details
    Browse the repository at this point in the history
  3. rust/net: add socket-related flags and flagset.

    Add enums representing flags related to sockets:
    - `ReceiveFlag` to modify the behaviour of the socket receive operation.
    - `SendFlag` to modify the behaviour of the socket send operation.
    - `MessageFlag` to represent the flags in a `msghdr`.
    - `SocketFlag` to represent the flags in the `socket` struct.
    
    Introduce a `FlagSet` structure to offer a convenient way to handle the
    flags.
    Having an abstraction over the "raw" numerical value of the flags offers
    many advantages:
    - A `FlagSet` can be created in different ways: from an `IntoIterator`,
      a value, a single flag or using the defined macro `flag_set!(...)`.
    - Custom operations can be defined, such as the bitwise or.
    - Flags in the set can be set, tested, unset through functions instead
      of using bitwise operations.
    - FlagSet implements the IntoIterator trait, allowing for iteration over
      the flags contained.
    
    Signed-off-by: Michele Dalle Rive <dallerivemichele@gmail.com>
    Michele Dalle Rive authored and micheledallerive committed Feb 24, 2024
    Configuration menu
    Copy the full SHA
    81206e7 View commit details
    Browse the repository at this point in the history
  4. rust/net: add socket wrapper.

    Create a `Socket` abstraction, which provides a Rust API to the kernel
    socket functionalities.
    
    The Socket structures tries to keep the same function signatures of the
    Rust standard library; at the same time, functions are added or modified
    in order to provide as much as possible of the C kernel functionalities.
    
    Most of the internals of the C socket is not accessible by Rust, because
    those structures are still to be wrapped. However, sockets are mainly
    managed through the functions provided by the kernel; thus, even if some
    fields are not accessible, since the functions are wrapped, most of the
    kernel functionality should be available in Rust as well.
    
    Specifically, the usage of `msghdr` is mostly abstracted away in the
    Rust interface, because using it would mean having to deal, both in the
    kernel and in modules, with Pinned instances (msghdr is self-referencing),
    which would be a struggle that provides no particular advantage.
    A `MessageHeader` object is actually created and returned when a message
    is received, because at that point the structure is not really
    self-referencing, as long as the source address is copied. The wrapper
    is not used when a message is sent.
    Anyways, some useful functionalities of `msghdr`, like `cmsghdr`s, are
    missing and should be implemented in the future to provide a complete API.
    
    Signed-off-by: Michele Dalle Rive <dallerivemichele@gmail.com>
    Michele Dalle Rive authored and micheledallerive committed Feb 24, 2024
    Configuration menu
    Copy the full SHA
    725e990 View commit details
    Browse the repository at this point in the history
  5. rust/net: implement socket options API.

    Create socket `Option`s and `set_option` function in the `Socket`
    abstraction.
    
    These changes introduce wrappers and functions to handle socket options
    in Rust, with compilation-time advantages compared to the C API:
    - Type safety: A specific option accepts only a value of the correct
      type.
    - Read/write safety: A read-only option cannot be set.
    - Coherence safety: An option of, for example, IP level cannot be set by
      specifying another level.
    
    The downside of using options in the kernel is the lack of functions to
    get the value of an option. For this reason, in Rust, kernel options can
    only be set, but not retrieved.
    
    Everything that can be done by socket options can actually be done
    through helper functions, or by accessing directly the specific fields.
    However, since the Rust-wrapped structures are few, it can be useful to
    have options in order to still be able to modify the behaviour of the
    socket.
    
    As specified in the documentation of `opts.rs`, options could (and
    should) be removed when the Rust API will be developed enough.
    
    Signed-off-by: Michele Dalle Rive <dallerivemichele@gmail.com>
    Michele Dalle Rive authored and micheledallerive committed Feb 24, 2024
    Configuration menu
    Copy the full SHA
    f4aa2cb View commit details
    Browse the repository at this point in the history
  6. rust/net: add socket TCP wrappers.

    Add `TcpListener` and `TcpStream` wrappers around the Rust Socket.
    They provide a convenient way to handle TCP sockets.
    
    This interface is intended to be as close as possible to the one in `std::net`.
    
    Signed-off-by: Michele Dalle Rive <dallerivemichele@gmail.com>
    Michele Dalle Rive authored and micheledallerive committed Feb 24, 2024
    Configuration menu
    Copy the full SHA
    ad0527f View commit details
    Browse the repository at this point in the history
  7. rust/net: add socket UDP wrappers.

    Add a UDP socket wrapper, which allows to handle UDP sockets conveniently.
    
    This interface is intended to be as close as possible to the one in `std::net`.
    
    Signed-off-by: Michele Dalle Rive <dallerivemichele@gmail.com>
    Michele Dalle Rive authored and micheledallerive committed Feb 24, 2024
    Configuration menu
    Copy the full SHA
    b54cf7b View commit details
    Browse the repository at this point in the history