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

UDP: setsockopt REUSEADDR suport, when we run process_udp #925

Open
YXalix opened this issue Apr 25, 2024 · 2 comments
Open

UDP: setsockopt REUSEADDR suport, when we run process_udp #925

YXalix opened this issue Apr 25, 2024 · 2 comments

Comments

@YXalix
Copy link

YXalix commented Apr 25, 2024

when we run process_udp, if there are two sockets that bind under the same Ipaddr, one of them will be ignored here

// iface/interface/udp.rs
#[cfg(feature = "socket-udp")]
for udp_socket in sockets
    .items_mut()
    .filter_map(|i| UdpSocket::downcast_mut(&mut i.socket))
{
    if udp_socket.accepts(self, &ip_repr, &udp_repr) {
        udp_socket.process(self, meta, &ip_repr, &udp_repr, udp_packet.payload());
        return None;
    }
}

Is it possible to iterate over all udp here and then return? I'm also happy to contribute pr to this great repo.

@YXalix YXalix changed the title UDP: process_udp, if OS UDP: setsockopt REUSEADDR suport, when we run process_udp Apr 25, 2024
@Dirbaio
Copy link
Member

Dirbaio commented Apr 26, 2024

what behavior would you consider correct? duplicating the packet to the two sockets? Is this what Linux does?

Also, I'm curious: What's the use case for binding 2 sockets to the same addr?

@YXalix
Copy link
Author

YXalix commented Apr 27, 2024

Yeah, I think the correct behavior is packet will be duplicated to the two sockets related doc, and I'm just verify this behavior as follows:

import socket
import threading
import time

MULTICAST_ADDR = '239.255.0.1'
PORT = 12345
def send_broadcast_message():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    message = "Hello, world!"
    sock.sendto(message.encode(), ('239.255.0.1', 12345))
    print("Sent broadcast message: {}".format(message))
    sock.close()

def receive_broadcast_message():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    mreq = socket.inet_aton(MULTICAST_ADDR) + socket.inet_aton('127.0.0.1')
    sock.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, mreq)
    sock.bind(('239.255.0.1', 12345))
    data, addr = sock.recvfrom(1024)
    print("Received from {}: {}".format(addr, data.decode()))
    sock.close()

receive_thread1 = threading.Thread(target=receive_broadcast_message)
receive_thread1.daemon = True
receive_thread1.start()

receive_thread2 = threading.Thread(target=receive_broadcast_message)
receive_thread2.daemon = True
receive_thread2.start()

time.sleep(1)

send_thread = threading.Thread(target=send_broadcast_message)
send_thread.daemon = True
send_thread.start()

send_thread.join()
receive_thread1.join()
receive_thread2.join()

Background
I met this requirement when i did fastdds support for starry-os. The RTPS protocol adopted by fastdds is simply to use UDP broadcast to discover participants, and then use UDP unicast for communication.

I'm also glad to receive your reply ✨

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

No branches or pull requests

2 participants