Skip to content

Commit

Permalink
Fix bugs in network code
Browse files Browse the repository at this point in the history
  • Loading branch information
maximecb committed Nov 9, 2023
1 parent c90efb7 commit 4a9cc27
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 12 deletions.
3 changes: 2 additions & 1 deletion ncc/build_and_run.sh
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
RUST_BACKTRACE=1 cargo run -- $* && cd ../vm && cargo run ../ncc/out.asm && cd ../vm
export RUST_BACKTRACE=1
cargo run -- $* && cd ../vm && cargo run ../ncc/out.asm && cd ../vm
11 changes: 8 additions & 3 deletions ncc/examples/telnet_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,18 @@ void on_new_conn(u64 socket_id)

void on_incoming_data(u64 socket_id, u64 num_bytes)
{
puts("got incoming data");
printf("received %d bytes of incoming data\n", num_bytes);

char read_buf[1024];
memset(read_buf, 0, 1024);
net_read(socket_id, read_buf, 1024 - 1);

// If this is a telnet command (non-printable), ignore it
if (read_buf[0] & 0x80)
{
return;
}

puts(read_buf);

if (strncmp(read_buf, "exit", 4) == 0)
Expand All @@ -30,8 +37,6 @@ void on_incoming_data(u64 socket_id, u64 num_bytes)
char* response = "Goodbye!\n";
net_write(socket_id, response, strlen(response));
net_close(socket_id);

net_close(listen_sock);
return;
}

Expand Down
43 changes: 35 additions & 8 deletions vm/src/sys/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,32 @@ fn listen_thread(
{
// Block until a connection can be accepted
for result in listener.incoming() {
let stream = match result {
Ok(s) => s,

Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
// Sleep for a bit, then try again
thread::sleep(std::time::Duration::from_millis(10));
continue;
}

Err(e) => panic!("encountered IO error: {e}"),
};

let arc = vm_mutex.upgrade().unwrap();
let mut vm = arc.lock().unwrap();

// TODO: note, accepting the connection may error,
// for example if the socket was closed
let stream = result.unwrap();

// Add the new connection to the queue
let mut net_state = &mut vm.sys_state.net_state;
match net_state.sockets.get_mut(&socket_id) {
Some(Socket::Listen{ incoming, .. }) => {
incoming.push_back(stream);
}
_ => panic!()

// Socket closed
_ => {
break;
}
}

// Call on_new_conn to signal an incoming connection
Expand Down Expand Up @@ -100,6 +112,12 @@ pub fn net_listen(
let listener = TcpListener::bind(listen_addr).unwrap();
let socket_fd = listener.as_raw_fd();

// Set the listener to non-blocking
// We do this because Rust offers us no way to close the TcpListener
// from another thread, and so the listening thread has to periodically
// check if it should exit.
listener.set_nonblocking(true).expect("Cannot set non-blocking");

// Assign a socket id to the socket
let mut net_state = &mut vm.sys_state.net_state;
let socket_id = net_state.next_id;
Expand Down Expand Up @@ -141,8 +159,12 @@ fn read_thread(
let mut buf: [u8; 16384] = [0; 16384];

match stream.read(&mut buf) {
Ok(num_bytes) => {
// End of file, connection closed
Ok(0) => {
break;
}

Ok(num_bytes) => {
let arc = vm_mutex.upgrade().unwrap();
let mut vm = arc.lock().unwrap();

Expand All @@ -167,7 +189,10 @@ fn read_thread(
}
}

Err(_) => break
Err(e) => {
println!("error in read thread: {e}");
break
}
}
}
}
Expand Down Expand Up @@ -199,6 +224,7 @@ pub fn net_accept(
}

let stream = incoming.pop_front().unwrap();
stream.set_nonblocking(false).expect("could not set stream to blocking");

// TODO: handle the error case here
// The connection could have dropped
Expand Down Expand Up @@ -314,7 +340,8 @@ pub fn net_close(
}

Some(Socket::Listen { listener, .. }) => {
//listener.shutdown(std::net::Shutdown::Both).unwrap();
// The listen thread will detect that the socket state
// has been removed and exit
}

_ => panic!()
Expand Down

0 comments on commit 4a9cc27

Please sign in to comment.