Orbital (#16)
* Port previous ethernet scheme
* Add ipd
* Fix initfs rebuilds, use QEMU user networking addresses in ipd
* Add tcp/udp, netutils, dns, and network config
* Add fsync to network driver
* Add dns, router, subnet by default
* Fix e1000 driver. Make ethernet and IP non-blocking to avoid deadlocks
* Add orbital server, WIP
* Add futex
* Add orbutils and orbital
* Update libstd, orbutils, and orbital
Move ANSI key encoding to vesad
* Add orbital assets
* Update orbital
* Update to add login manager
* Add blocking primitives, block for most things except waitpid, update orbital
* Wait in waitpid and IRQ, improvements for other waits
* Fevent in root scheme
* WIP: Switch to using fevent
* Reorganize
* Event based e1000d driver
* Superuser-only access to some network schemes, display, and disk
* Superuser root and irq schemes
* Fix orbital
2016-10-14 01:21:42 +02:00
|
|
|
#![feature(rand)]
|
|
|
|
|
2016-10-24 15:40:44 +02:00
|
|
|
//! 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`)
|
2016-10-24 22:17:12 +02:00
|
|
|
//! and the connection may be used immediately to send/receive data. Ip v4 number
|
|
|
|
//! `127.0.0.1` is hardwired to the loopback device (i.e. localhost), which doesn't
|
|
|
|
//! access any physical device and in which data can only be read by the same
|
|
|
|
//! connection that has written it.
|
2016-10-24 15:40:44 +02:00
|
|
|
//! * 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).
|
|
|
|
|
2016-10-21 01:49:54 +02:00
|
|
|
extern crate netutils;
|
Orbital (#16)
* Port previous ethernet scheme
* Add ipd
* Fix initfs rebuilds, use QEMU user networking addresses in ipd
* Add tcp/udp, netutils, dns, and network config
* Add fsync to network driver
* Add dns, router, subnet by default
* Fix e1000 driver. Make ethernet and IP non-blocking to avoid deadlocks
* Add orbital server, WIP
* Add futex
* Add orbutils and orbital
* Update libstd, orbutils, and orbital
Move ANSI key encoding to vesad
* Add orbital assets
* Update orbital
* Update to add login manager
* Add blocking primitives, block for most things except waitpid, update orbital
* Wait in waitpid and IRQ, improvements for other waits
* Fevent in root scheme
* WIP: Switch to using fevent
* Reorganize
* Event based e1000d driver
* Superuser-only access to some network schemes, display, and disk
* Superuser root and irq schemes
* Fix orbital
2016-10-14 01:21:42 +02:00
|
|
|
extern crate resource_scheme;
|
|
|
|
extern crate syscall;
|
|
|
|
|
|
|
|
use std::fs::File;
|
|
|
|
use std::io::{Read, Write};
|
|
|
|
use std::thread;
|
|
|
|
|
|
|
|
use resource_scheme::ResourceScheme;
|
|
|
|
use syscall::Packet;
|
|
|
|
|
|
|
|
use scheme::IpScheme;
|
|
|
|
|
2016-10-21 01:49:54 +02:00
|
|
|
mod resource;
|
|
|
|
mod scheme;
|
Orbital (#16)
* Port previous ethernet scheme
* Add ipd
* Fix initfs rebuilds, use QEMU user networking addresses in ipd
* Add tcp/udp, netutils, dns, and network config
* Add fsync to network driver
* Add dns, router, subnet by default
* Fix e1000 driver. Make ethernet and IP non-blocking to avoid deadlocks
* Add orbital server, WIP
* Add futex
* Add orbutils and orbital
* Update libstd, orbutils, and orbital
Move ANSI key encoding to vesad
* Add orbital assets
* Update orbital
* Update to add login manager
* Add blocking primitives, block for most things except waitpid, update orbital
* Wait in waitpid and IRQ, improvements for other waits
* Fevent in root scheme
* WIP: Switch to using fevent
* Reorganize
* Event based e1000d driver
* Superuser-only access to some network schemes, display, and disk
* Superuser root and irq schemes
* Fix orbital
2016-10-14 01:21:42 +02:00
|
|
|
|
|
|
|
fn main() {
|
|
|
|
thread::spawn(move || {
|
|
|
|
let mut socket = File::create(":ip").expect("ipd: failed to create ip scheme");
|
|
|
|
let scheme = IpScheme::new();
|
|
|
|
loop {
|
|
|
|
let mut packet = Packet::default();
|
|
|
|
socket.read(&mut packet).expect("ipd: failed to read events from ip scheme");
|
|
|
|
scheme.handle(&mut packet);
|
|
|
|
socket.write(&packet).expect("ipd: failed to write responses to ip scheme");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2016-10-24 22:17:12 +02:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
fn test() {
|
|
|
|
use scheme::IpScheme;
|
|
|
|
|
|
|
|
println!("* Test that we can read a simple packet from the same connection.");
|
|
|
|
let bytes = "TEST".as_bytes();
|
|
|
|
let mut scheme = IpScheme::new();
|
2016-10-24 23:02:57 +02:00
|
|
|
let a = scheme.open(&"ip:127.0.0.1/11".as_bytes(), 0, 0, 0).unwrap();
|
2016-10-24 22:17:12 +02:00
|
|
|
let num_bytes_written = scheme.write(a, bytes).unwrap();
|
|
|
|
assert_eq!(num_bytes_written, bytes.len());
|
|
|
|
|
|
|
|
let mut buf = [0;65536];
|
|
|
|
let num_bytes_read = scheme.read(a, &mut buf).unwrap();
|
|
|
|
assert_eq!(num_bytes_read, num_bytes_written);
|
|
|
|
|
|
|
|
let bytes_read = &buf[0..num_bytes_read];
|
|
|
|
assert_eq!(bytes, bytes_read);
|
|
|
|
|
2016-10-24 23:02:57 +02:00
|
|
|
|
|
|
|
|
|
|
|
println!("* Test that the loopback is now empty.");
|
|
|
|
let num_bytes_read = scheme.read(a, &mut buf).unwrap();
|
|
|
|
assert_eq!(num_bytes_read, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
println!("* Test that we can read the same packet from a different connection.");
|
|
|
|
let num_bytes_written = scheme.write(a, bytes).unwrap();
|
|
|
|
assert_eq!(num_bytes_written, bytes.len());
|
|
|
|
|
|
|
|
let b = scheme.open("ip:127.0.0.1/11".as_bytes(), 0, 0, 0).unwrap();
|
|
|
|
|
|
|
|
let num_bytes_read = scheme.read(b, &mut buf).unwrap();
|
|
|
|
assert_eq!(num_bytes_read, num_bytes_written);
|
|
|
|
|
|
|
|
let bytes_read = &buf[0..num_bytes_read];
|
|
|
|
assert_eq!(bytes, bytes_read);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
println!("* Test that the loopback is now empty for both connections.");
|
|
|
|
|
|
|
|
let num_bytes_read = scheme.read(a, &mut buf).unwrap();
|
|
|
|
assert_eq!(num_bytes_read, 0);
|
|
|
|
|
2016-10-24 22:17:12 +02:00
|
|
|
let num_bytes_read = scheme.read(b, &mut buf).unwrap();
|
|
|
|
assert_eq!(num_bytes_read, 0);
|
|
|
|
|
2016-10-24 23:02:57 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
2016-10-24 22:17:12 +02:00
|
|
|
println!("* Push a number of packets, check that we get them in the right order.");
|
2016-10-24 23:02:57 +02:00
|
|
|
let mut payloads : Vec<String> = (0..100).map(|i| format!("TEST {}", i)).collect();
|
2016-10-24 22:17:12 +02:00
|
|
|
for payload in &payloads {
|
|
|
|
let bytes = payload.into_bytes();
|
|
|
|
let num_bytes_written = scheme.write(a, &bytes).unwrap();
|
|
|
|
assert_eq!(bytes.len(), num_bytes_written);
|
|
|
|
}
|
|
|
|
for payload in &payloads {
|
|
|
|
let bytes = payload.into_bytes();
|
|
|
|
let mut buf = [0;65536];
|
|
|
|
let num_bytes_read = scheme.read(a, &mut buf).unwrap();
|
|
|
|
assert_eq!(bytes.len(), num_bytes_read);
|
|
|
|
let bytes_read = &buf[0..num_bytes_read];
|
|
|
|
assert_eq!(bytes, bytes_read);
|
|
|
|
}
|
|
|
|
}
|