/// Computes the [`CachedInfo`] for an IPv4 socket based on its definition.
///
/// Returns an error if the socket is currently unroutable.
Computes the [`CachedInfo`] for an IPv4 socket based on its definition.
Returns an error if the socket is currently unroutable.
Computes the [ ` CachedInfo ` ] for an IPv4 socket based on its definition . Returns an error if the socket is currently unroutable .
fn compute_ipv4_cached_info<C: IpSocketContext<Ipv4>>(
    ctx: &C,
    defn: &IpSockDefinition<Ipv4>,
) -> Result<CachedInfo<Ipv4, C::DeviceId>, IpSockUnroutableError> {
    ctx.lookup_route(defn.remote_ip).ok_or(IpSockUnroutableError::NoRouteToRemoteAddr).and_then(
        |dst| {
            let mut local_on_device = false;
            let mut next_hop = NextHop::Remote(dst.next_hop);
            for addr_sub in ctx.get_ip_device_state(dst.device).iter_addrs() {
                let assigned_addr = addr_sub.addr();
                local_on_device = local_on_device || assigned_addr == defn.local_ip;
                if assigned_addr == defn.remote_ip {
                    next_hop = NextHop::Local;
                }
                if local_on_device && next_hop == NextHop::Local {
                    break;
                }
            }
            if !local_on_device {
                return Err(IpSockUnroutableError::LocalAddrNotAssigned);
            }
            Ok(CachedInfo {
                builder: Ipv4PacketBuilder::new(
                    defn.local_ip,
                    defn.remote_ip,
                    defn.hop_limit,
                    defn.proto,
                ),
                device: dst.device,
                next_hop,
            })
        },
    )
}
fn compute_ipv4_cached_info < C : IpSocketContext < Ipv4 > > ( ctx : & C , defn : & IpSockDefinition < Ipv4 > , ) -> Result < CachedInfo < Ipv4 , C :: DeviceId > , IpSockUnroutableError > { ctx . lookup_route ( defn . remote_ip ) . ok_or ( IpSockUnroutableError :: NoRouteToRemoteAddr ) . and_then ( | dst | { let mut local_on_device = false ; let mut next_hop = NextHop :: Remote ( dst . next_hop ) ; for addr_sub in ctx . get_ip_device_state ( dst . device ) . iter_addrs ( ) { let assigned_addr = addr_sub . addr ( ) ; local_on_device = local_on_device || assigned_addr == defn . local_ip ; if assigned_addr == defn . remote_ip { next_hop = NextHop :: Local ; } if local_on_device && next_hop == NextHop :: Local { break ; } } if ! local_on_device { return Err ( IpSockUnroutableError :: LocalAddrNotAssigned ) ; } Ok ( CachedInfo { builder : Ipv4PacketBuilder :: new ( defn . local_ip , defn . remote_ip , defn . hop_limit , defn . proto , ) , device : dst . device , next_hop , } ) } , ) }
Computes the [`CachedInfo`] for an IPv4 socket based on its definition.
Computes the [ ` CachedInfo ` ] for an IPv4 socket based on its definition .
ctx
&C
defn
&IpSockDefinition<Ipv4>