Documentation run on schemes/ipd. (#18)
* Documentation run on schemes/ipd. * Update main.rs * Update resource.rs
This commit is contained in:
parent
3634afe549
commit
35696f4169
|
@ -1,5 +1,24 @@
|
|||
#![feature(rand)]
|
||||
|
||||
//! Implementation of the IP Scheme as a userland driver.
|
||||
//!
|
||||
//! # Role
|
||||
//!
|
||||
//! See https://en.wikipedia.org/wiki/Internet_Protocol for more details about the
|
||||
//! IP protocol. Clients will often prefer using either higher-level protocols TCP
|
||||
//! or UDP, both of which are built upon IP.
|
||||
//!
|
||||
//! # URL Syntax
|
||||
//!
|
||||
//! To open a IP connection, use `ip:[host]/protocol`.
|
||||
//!
|
||||
//! * If `host` is specified, it must be an ipv4 number (e.g. `192.168.0.1`)
|
||||
//! and the connection may be used immediately to send/receive data.
|
||||
//! * If `host` is omitted, this connectino will wait for a distant peer to
|
||||
//! connect.
|
||||
//! * The `protocol` is the hex-based number of the ip protocol
|
||||
//! (see http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml).
|
||||
|
||||
extern crate netutils;
|
||||
extern crate resource_scheme;
|
||||
extern crate syscall;
|
||||
|
|
|
@ -5,22 +5,48 @@ use resource_scheme::Resource;
|
|||
use syscall;
|
||||
use syscall::error::*;
|
||||
|
||||
/// A IP (internet protocole) resource
|
||||
/// A IP (internet protocol) resource.
|
||||
///
|
||||
/// Each instance represents a connection (~ a IP socket).
|
||||
pub struct IpResource {
|
||||
/// Link to the underlying device (typically, an Ethernet card).
|
||||
pub link: usize,
|
||||
pub data: Vec<u8>,
|
||||
|
||||
/// If this connection was opened waiting for a peer (i.e. `ip:/protocol`),
|
||||
/// the data received when the peer actually connected. Otherwise, empty.
|
||||
/// Emptied during the first call to `read()`.
|
||||
pub init_data: Vec<u8>,
|
||||
|
||||
/// The IP address of the host (i.e. this machine).
|
||||
pub host_addr: Ipv4Addr,
|
||||
|
||||
/// The IP address of the peer (i.e. the other machine).
|
||||
pub peer_addr: Ipv4Addr,
|
||||
|
||||
/// The IP protocol used by this connection. See
|
||||
/// http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
|
||||
/// for the list of valid protocols.
|
||||
pub proto: u8,
|
||||
|
||||
/// The id of the next packet being sent.
|
||||
/// See https://en.wikipedia.org/wiki/IPv4#Identification .
|
||||
pub id: u16,
|
||||
}
|
||||
|
||||
impl Resource for IpResource {
|
||||
/// Duplicate the connection.
|
||||
///
|
||||
/// This duplicates both `self.link` and `self.init_data`.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Fails if the `link` to the underlying device cannot be
|
||||
/// duplicated.
|
||||
fn dup(&self) -> Result<Box<Self>> {
|
||||
let link = try!(syscall::dup(self.link));
|
||||
Ok(Box::new(IpResource {
|
||||
link: link,
|
||||
data: self.data.clone(),
|
||||
init_data: self.init_data.clone(),
|
||||
host_addr: self.host_addr,
|
||||
peer_addr: self.peer_addr,
|
||||
proto: self.proto,
|
||||
|
@ -28,6 +54,12 @@ impl Resource for IpResource {
|
|||
}))
|
||||
}
|
||||
|
||||
/// Get the current path, as `ip:peer/protocol`, where `peer`
|
||||
/// is the IPv4 address of the peer and `protocol` is the hex-based
|
||||
/// number of the IP protocol used.
|
||||
///
|
||||
/// Note that the `peer` is specified even if the connection was initially
|
||||
/// created as `ip:/protocol`.
|
||||
fn path(&self, buf: &mut [u8]) -> Result<usize> {
|
||||
let path_string = format!("ip:{}/{:X}", self.peer_addr.to_string(), self.proto);
|
||||
let path = path_string.as_bytes();
|
||||
|
@ -39,10 +71,21 @@ impl Resource for IpResource {
|
|||
Ok(cmp::min(buf.len(), path.len()))
|
||||
}
|
||||
|
||||
/// Read data from the device.
|
||||
///
|
||||
/// If some data has already been made available during the establishment
|
||||
/// of the connection, this data is (entirely) read during the first call
|
||||
/// to `read()`, without attempting to actually read from the device. This
|
||||
/// can happen only if the connection was waiting for a remote peer to connect, i.e.
|
||||
/// with a url `ip:/protocol`, without host.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Fails if the call to `syscall::read()` fails for this device.
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
||||
if !self.data.is_empty() {
|
||||
if !self.init_data.is_empty() {
|
||||
let mut data: Vec<u8> = Vec::new();
|
||||
mem::swap(&mut self.data, &mut data);
|
||||
mem::swap(&mut self.init_data, &mut data);
|
||||
|
||||
for (b, d) in buf.iter_mut().zip(data.iter()) {
|
||||
*b = *d;
|
||||
|
@ -69,6 +112,11 @@ impl Resource for IpResource {
|
|||
Ok(0)
|
||||
}
|
||||
|
||||
/// Send data to the peer.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Fails if the call to `syscall::write()` fails for this device.
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
let ip_data = Vec::from(buf);
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ impl ResourceScheme<IpResource> for IpScheme {
|
|||
if let Ok(link) = syscall::open(&format!("ethernet:{}/800", &route_mac.to_string()), O_RDWR) {
|
||||
return Ok(Box::new(IpResource {
|
||||
link: link,
|
||||
data: Vec::new(),
|
||||
init_data: Vec::new(),
|
||||
host_addr: ip_addr,
|
||||
peer_addr: peer_addr,
|
||||
proto: proto,
|
||||
|
@ -127,6 +127,7 @@ impl ResourceScheme<IpResource> for IpScheme {
|
|||
} else {
|
||||
while let Ok(link) = syscall::open("ethernet:/800", O_RDWR) {
|
||||
let mut bytes = [0; 65536];
|
||||
// FIXME: Blocking call?
|
||||
match syscall::read(link, &mut bytes) {
|
||||
Ok(count) => {
|
||||
if let Some(packet) = Ipv4::from_bytes(&bytes[..count]) {
|
||||
|
@ -134,7 +135,7 @@ impl ResourceScheme<IpResource> for IpScheme {
|
|||
(packet.header.dst.equals(ip_addr) || packet.header.dst.equals(Ipv4Addr::BROADCAST)) {
|
||||
return Ok(Box::new(IpResource {
|
||||
link: link,
|
||||
data: packet.data,
|
||||
init_data: packet.data,
|
||||
host_addr: ip_addr,
|
||||
peer_addr: packet.header.src,
|
||||
proto: proto,
|
||||
|
|
Loading…
Reference in a new issue