Empty transmit buffers before starting to receive.
This commit is contained in:
parent
f86fac2223
commit
095005a597
|
@ -118,6 +118,12 @@ impl<'a, 'b: 'a,
|
||||||
Icmpv4(Ipv4Repr, Icmpv4Repr<'a>)
|
Icmpv4(Ipv4Repr, Icmpv4Repr<'a>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// First, transmit any outgoing packets.
|
||||||
|
loop {
|
||||||
|
if try!(self.emit()) { break }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, receive any incoming packets.
|
||||||
let rx_buffer = try!(self.device.receive());
|
let rx_buffer = try!(self.device.receive());
|
||||||
let eth_frame = try!(EthernetFrame::new(&rx_buffer));
|
let eth_frame = try!(EthernetFrame::new(&rx_buffer));
|
||||||
|
|
||||||
|
@ -229,7 +235,9 @@ impl<'a, 'b: 'a,
|
||||||
frame.set_ethertype(EthernetProtocolType::Arp);
|
frame.set_ethertype(EthernetProtocolType::Arp);
|
||||||
|
|
||||||
let mut packet = try!(ArpPacket::new(frame.payload_mut()));
|
let mut packet = try!(ArpPacket::new(frame.payload_mut()));
|
||||||
repr.emit(&mut packet)
|
repr.emit(&mut packet);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
},
|
},
|
||||||
|
|
||||||
Response::Icmpv4(ip_repr, icmp_repr) => {
|
Response::Icmpv4(ip_repr, icmp_repr) => {
|
||||||
|
@ -252,17 +260,48 @@ impl<'a, 'b: 'a,
|
||||||
|
|
||||||
let mut icmp_packet = try!(Icmpv4Packet::new(ip_packet.payload_mut()));
|
let mut icmp_packet = try!(Icmpv4Packet::new(ip_packet.payload_mut()));
|
||||||
icmp_repr.emit(&mut icmp_packet);
|
icmp_repr.emit(&mut icmp_packet);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::Nop => {
|
Response::Nop => {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn emit(&mut self) -> Result<bool, Error> {
|
||||||
// Borrow checker is being overly careful around closures, so we have
|
// Borrow checker is being overly careful around closures, so we have
|
||||||
// to hack around that.
|
// to hack around that.
|
||||||
let src_hardware_addr = self.hardware_addr;
|
let src_hardware_addr = self.hardware_addr;
|
||||||
|
let src_protocol_addrs = self.protocol_addrs.borrow();
|
||||||
let arp_cache = &mut self.arp_cache;
|
let arp_cache = &mut self.arp_cache;
|
||||||
let device = &mut self.device;
|
let device = &mut self.device;
|
||||||
|
|
||||||
|
let mut nothing_to_transmit = true;
|
||||||
for socket in self.sockets.borrow_mut() {
|
for socket in self.sockets.borrow_mut() {
|
||||||
let result = socket.dispatch(&mut |src_addr, dst_addr, protocol, payload| {
|
let result = socket.dispatch(&mut |src_addr, dst_addr, protocol, payload| {
|
||||||
|
let src_addr =
|
||||||
|
match src_addr {
|
||||||
|
&InternetAddress::Ipv4(_) if src_addr.is_unspecified() => {
|
||||||
|
let mut assigned_addr = None;
|
||||||
|
for addr in src_protocol_addrs {
|
||||||
|
match addr {
|
||||||
|
addr @ &InternetAddress::Ipv4(_) => {
|
||||||
|
assigned_addr = Some(addr);
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assigned_addr.expect(
|
||||||
|
"to respond to an UDP packet without a source address,\
|
||||||
|
the interface must have an assigned address from \
|
||||||
|
the same family")
|
||||||
|
},
|
||||||
|
addr => addr
|
||||||
|
};
|
||||||
|
|
||||||
let ip_repr =
|
let ip_repr =
|
||||||
match (src_addr, dst_addr) {
|
match (src_addr, dst_addr) {
|
||||||
(&InternetAddress::Ipv4(src_addr),
|
(&InternetAddress::Ipv4(src_addr),
|
||||||
|
@ -299,15 +338,16 @@ impl<'a, 'b: 'a,
|
||||||
});
|
});
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(()) => break,
|
Ok(()) => {
|
||||||
|
nothing_to_transmit = false;
|
||||||
|
break
|
||||||
|
}
|
||||||
Err(Error::Exhausted) => continue,
|
Err(Error::Exhausted) => continue,
|
||||||
Err(e) => return Err(e)
|
Err(e) => return Err(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
Ok(nothing_to_transmit)
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue