Skip to content

Conversation

JayKickliter
Copy link

@JayKickliter JayKickliter commented Oct 7, 2025

This PR implements the UEFI TCPv4 protocol, building upon #1130. As-is, the code performs well in a custom bootloader.

Overview

This implementation adds support for the EFI_TCP4_PROTOCOL and EFI_TCP4_SERVICE_BINDING_PROTOCOL as defined in the UEFI specification (Section 28.1). It enables UEFI applications to establish TCP connections, transmit and receive data over the network.

Changes

uefi-raw

  • Complete protocol structure definitions matching UEFI spec.
  • TCP connection states enum (Closed, Listen, SynSent, Established, etc.)
  • Configuration structure for client mode only.
  • I/O token structures for async operations
  • Fragment table support for scatter-gather I/O (hard-coded for single fragment buffer at the moment)
  • IPv4 mode data structures for network configuration

uefi

  • Tcpv4ServiceBinding for creating TCP protocol instances
  • Tcpv4 protocol wrapper with higher-level API
  • Automatic DHCP-aware configuration with retry logic
  • Event-based async I/O handling
  • Convenience methods like receive_exact() for reading exact byte counts
  • Proper lifetime management for all operations (best effort, needs review)

Key Features

  1. Connection Modes: Support for both client and server TCP connections

    • Client mode with remote IP and port configuration
    • Server mode foundation (accept functionality pending)
  2. Async Operations: All I/O operations wrap async operations in high-level sync interface

    • Transmit and receive operations with completion tokens
    • Proper event waiting and status checking
  3. DHCP Integration: Automatic retry logic when DHCP is still configuring the network

    • Handles NO_MAPPING status during network initialization
    • Configurable timeout with 10-second maximum wait

Example Usage

use alloc::string::String;
use uefi::{
    boot, print, println,
    proto::network::tcpv4::{Tcpv4, Tcpv4ServiceBinding},
};
use uefi_raw::{
    Ipv4Address,
    protocol::network::tcpv4::{Tcpv4ClientConnectionModeParams, Tcpv4ConnectionMode},
};

let addr = Ipv4Address([192, 0, 2, 2]);
let port = 5050;

println!("Connecting to {addr:?}:{port}...");
let mut tcp = {
    let tcp_svc_handle = boot::get_handle_for_protocol::<Tcpv4ServiceBinding>()?;
    let mut tcp_svc_proto =
        boot::open_protocol_exclusive::<Tcpv4ServiceBinding>(tcp_svc_handle)?;
    let tcp_proto_handle = tcp_svc_proto.create_child()?;
    let mut tcp_proto = boot::open_protocol_exclusive::<Tcpv4>(tcp_proto_handle)?;
    tcp_proto
        .configure(Tcpv4ConnectionMode::Client(
            Tcpv4ClientConnectionModeParams::new(addr, port),
        ))
        .expect("configure failed");
    tcp_proto.connect()?;
    tcp_proto
};

let tx_msg = "Hello";
println!("Sending {tx_msg:?} over TCP...");
tcp.transmit(tx_msg.as_bytes())?;

print!("Received ");
let mut buf = [0_u8; 64];
let n = tcp.receive(&mut buf)?;
let rx_string = String::from_utf8_lossy(&buf[..n]);
println!("{rx_string:?}");

Current Limitations

  • Server accept functionality uses UnmodelledPtr (implementation pending)
  • Close and cancel operations use UnmodelledPtr (implementation pending)
  • Some network configuration options not fully exposed in safe API

Future Work

  • Implement close and cancel operations
  • Improve TCP configuration support
  • Create integration tests with test TCP server
  • Complete server mode (accept) implementation (low priority)

Checklist

  • Sensible git history (for example, squash "typo" or "fix" commits). See the Rewriting History guide for help.
  • Update the changelog (if necessary)

Closes #1130

@phip1611
Copy link
Member

phip1611 commented Oct 8, 2025

Thanks for your contribution! I'll look hopefully next week into this, as I'm at the EuroRust conference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants