little-dude / netlink

netlink libraries for rust

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

why is socket_mut() repeated?

mcr opened this issue · comments

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

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.

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.