netlink icon indicating copy to clipboard operation
netlink copied to clipboard

why is socket_mut() repeated?

Open mcr opened this issue 4 years ago • 2 comments

https://github.com/little-dude/netlink/blob/2b7ae364566b1ed6c0a973a1b6dd044ff2ddf28f/rtnetlink/examples/listen.rs#L27

Is this a typo? Or is there a reason for this?

mcr avatar Dec 27 '21 20:12 mcr

In my code, which did:

        let (mut connection, handle, mut messages) = new_connection().map_err(|e| format!("{}", e)).unwrap();

        // These flags specify what kinds of broadcast messages we want to listen for.
        let mgroup_flags = RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR | RTMGRP_LINK;

        // A netlink socket address is created with said flags.
        let addr = SocketAddr::new(0, mgroup_flags);
        // Said address is bound so new conenctions and thus new message broadcasts can be received.
        connection.socket_mut().bind(&addr).expect("failed to bind");
  1. bind() was no longer valid.
  2. if I added the second socket_mut(), this worked only if also did:
use rtnetlink::{
    sys::{AsyncSocket, SocketAddr},
}

rather than just SocketAddr. I don't use AsyncSocket directly, but adding that allowed socket_mut() to be called twice.

mcr avatar Dec 27 '21 20:12 mcr

This is confusing I agree. In connection.socket_mut().socket_mut():

  • the first call is a call to netlink_proto::Connection<_, S, _>::socket_mut(), which returns the connection's socket S. Note that S implements the AsyncSocket trait
  • the second call is a call to netlink_sys::AsyncSocket::socket_mut, which returns the actual socket object. If you're using tokio that's gonna be netlink_sys::TokioSocket

The first call can't really be avoided. There are two ways to avoid having to write the second call:

  • implement DerefMut<Target=Socket> for any type S: AsyncSocket
  • write default implementation of the various Socket methods for AsyncSocket

Not sure which solution is better, I'd have to think about it.

little-dude avatar Feb 12 '22 17:02 little-dude