Skip to content

If UdpFrame fails when sending, it cannot flush or send any new message #7648

@ElFantasma

Description

@ElFantasma

Version

├── tokio v1.47.1
│   └── tokio-macros v2.5.0 (proc-macro)
└── tokio-util v0.7.16
    └── tokio v1.47.1 (*)

Platform
Reproduced on
24.6.0 Darwin Kernel Version 24.6.0: Mon Aug 11 21:11:04 PDT 2025; root:xnu-11417.140.69.701.11~1/RELEASE_ARM64_T6031 arm64
and on
Linux 6.1.0-23-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.99-1 (2024-07-15) x86_64 GNU/Linux

Description
If an error happens when using send from SinkEx on an UdpFramed, it doesn't seem to flush/discard the internal buffer, so any new attempt to use it will fail, even with different message and address:

Example:

use bytes::Bytes;
use futures::SinkExt;
use std::{net::SocketAddr, str::FromStr};
use tokio::net::UdpSocket;
use tokio_util::{codec::BytesCodec, udp::UdpFramed};

#[tokio::main]
async fn main() {
    let udp_socket = UdpSocket::bind(SocketAddr::from_str("127.0.0.1:8080").unwrap()).await.unwrap();
    let mut framed = UdpFramed::new(udp_socket, BytesCodec::new());

    let msg = Bytes::from_static(b"UdpFramed test!");

    let invalid_address = SocketAddr::from_str("0.0.0.0:80").unwrap();
    let valid_address = SocketAddr::from_str("127.0.0.1:80").unwrap();

    // 1st. Sending to a valid address. This works.
    send(&mut framed, msg.clone(), valid_address).await;

    // 2nd. Send to invalid address, this fails.
    send(&mut framed, msg.clone(), invalid_address).await;

    // 3rd. Sending to the same previous valid address. This keeps failing :(
    send(&mut framed, msg.clone(), valid_address).await;
}

async fn send(framed: &mut UdpFramed<BytesCodec>, msg: Bytes, addr: SocketAddr) {
    match framed.send((msg, addr)).await {
        Ok(_) => println!("OK, sent msg to address {}", addr),
        Err(e) => println!("Error trying to send msg to address {}: {}", addr, e),
    }
}

I expected first and third send to work, and second to fail, instead, only first worked and second and third failed:

OK, sent msg to address 127.0.0.1:80
Error trying to send msg to address 0.0.0.0:80: No route to host (os error 65)
Error trying to send msg to address 127.0.0.1:80: No route to host (os error 65)

Note: this is independent from the underlying Error that causes the failure. I found the problem when trying to send messages to a list of IP addresses, and an IPv6 address slipped in.
I got
"Address family not supported by protocol"
when it tried the IPv6 address, and then the same error for all the following IPv4 addresses

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-tokioArea: The main tokio crateM-netModule: tokio/net

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions