mirror of
https://github.com/Noratrieb/survey.git
synced 2026-01-14 08:30:12 +01:00
raw listener
This commit is contained in:
parent
e46bcedb93
commit
e5484affdf
4 changed files with 161 additions and 93 deletions
94
src/epoll.rs
Normal file
94
src/epoll.rs
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
#define MAX_EVENTS 10
|
||||
struct epoll_event ev, events[MAX_EVENTS];
|
||||
int listen_sock, conn_sock, nfds, epollfd;
|
||||
|
||||
/* Code to set up listening socket, 'listen_sock',
|
||||
(socket(), bind(), listen()) omitted */
|
||||
|
||||
epollfd = epoll_create1(0);
|
||||
if (epollfd == -1) {
|
||||
perror("epoll_create1");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ev.events = EPOLLIN;
|
||||
ev.data.fd = listen_sock;
|
||||
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {
|
||||
perror("epoll_ctl: listen_sock");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
|
||||
if (nfds == -1) {
|
||||
perror("epoll_wait");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (n = 0; n < nfds; ++n) {
|
||||
if (events[n].data.fd == listen_sock) {
|
||||
conn_sock = accept(listen_sock,
|
||||
(struct sockaddr *) &addr, &addrlen);
|
||||
if (conn_sock == -1) {
|
||||
perror("accept");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
setnonblocking(conn_sock);
|
||||
ev.events = EPOLLIN | EPOLLET;
|
||||
ev.data.fd = conn_sock;
|
||||
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock,
|
||||
&ev) == -1) {
|
||||
perror("epoll_ctl: conn_sock");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
do_use_fd(events[n].data.fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
const MAX_EVENTS: usize = 10;
|
||||
|
||||
pub fn example_from_man_page() -> Result<(), &'static str> {
|
||||
// SAFETY: I trust man pages (maybe a mistake)
|
||||
/*unsafe {
|
||||
let listen_sock: i32 = todo!();
|
||||
let mut events = [libc::epoll_event { events: 0, u64: 0 }; MAX_EVENTS]; // empty value
|
||||
|
||||
let epollfd = libc::epoll_create1(1);
|
||||
if epollfd == -1 {
|
||||
return Err("Failed to crate epoll instance");
|
||||
}
|
||||
|
||||
let ev = libc::epoll_event {
|
||||
events: libc::EPOLLIN.try_into().unwrap(),
|
||||
u64: listen_sock.try_into().unwrap(),
|
||||
};
|
||||
|
||||
loop {
|
||||
let nfds = libc::epoll_wait(
|
||||
epollfd,
|
||||
events.as_mut_ptr(),
|
||||
MAX_EVENTS.try_into().unwrap(),
|
||||
-1,
|
||||
);
|
||||
if nfds == -1 {
|
||||
return Err("Failed to wait for next event");
|
||||
}
|
||||
|
||||
for i in 0usize..nfds.try_into().unwrap() {
|
||||
if events[i].u64 == listen_sock.try_into().unwrap() {
|
||||
let conn_sock = libc::accept(listen_sock, todo!(), todo!());
|
||||
if conn_sock != -1 {
|
||||
return Err("Failed to accept");
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
Ok(()) // this is safe.
|
||||
}
|
||||
98
src/lib.rs
98
src/lib.rs
|
|
@ -1,96 +1,8 @@
|
|||
#![warn(rust_2018_idioms)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
/*
|
||||
#define MAX_EVENTS 10
|
||||
struct epoll_event ev, events[MAX_EVENTS];
|
||||
int listen_sock, conn_sock, nfds, epollfd;
|
||||
pub mod epoll;
|
||||
pub mod listener;
|
||||
|
||||
/* Code to set up listening socket, 'listen_sock',
|
||||
(socket(), bind(), listen()) omitted */
|
||||
|
||||
epollfd = epoll_create1(0);
|
||||
if (epollfd == -1) {
|
||||
perror("epoll_create1");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ev.events = EPOLLIN;
|
||||
ev.data.fd = listen_sock;
|
||||
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {
|
||||
perror("epoll_ctl: listen_sock");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
|
||||
if (nfds == -1) {
|
||||
perror("epoll_wait");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (n = 0; n < nfds; ++n) {
|
||||
if (events[n].data.fd == listen_sock) {
|
||||
conn_sock = accept(listen_sock,
|
||||
(struct sockaddr *) &addr, &addrlen);
|
||||
if (conn_sock == -1) {
|
||||
perror("accept");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
setnonblocking(conn_sock);
|
||||
ev.events = EPOLLIN | EPOLLET;
|
||||
ev.data.fd = conn_sock;
|
||||
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock,
|
||||
&ev) == -1) {
|
||||
perror("epoll_ctl: conn_sock");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
do_use_fd(events[n].data.fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
const MAX_EVENTS: usize = 10;
|
||||
|
||||
pub fn example_from_man_page() -> Result<(), &'static str> {
|
||||
// SAFETY: I trust man pages (maybe a mistake)
|
||||
unsafe {
|
||||
let listen_sock: i32 = todo!();
|
||||
let mut events = [libc::epoll_event { events: 0, u64: 0 }; MAX_EVENTS]; // empty value
|
||||
|
||||
let epollfd = libc::epoll_create1(1);
|
||||
if epollfd == -1 {
|
||||
return Err("Failed to crate epoll instance");
|
||||
}
|
||||
|
||||
let ev = libc::epoll_event {
|
||||
events: libc::EPOLLIN.try_into().unwrap(),
|
||||
u64: listen_sock.try_into().unwrap(),
|
||||
};
|
||||
|
||||
loop {
|
||||
let nfds = libc::epoll_wait(
|
||||
epollfd,
|
||||
events.as_mut_ptr(),
|
||||
MAX_EVENTS.try_into().unwrap(),
|
||||
-1,
|
||||
);
|
||||
if nfds == -1 {
|
||||
return Err("Failed to wait for next event");
|
||||
}
|
||||
|
||||
for i in 0usize..nfds.try_into().unwrap() {
|
||||
if events[i].u64 == listen_sock.try_into().unwrap() {
|
||||
let conn_sock = libc::accept(listen_sock, todo!(), todo!());
|
||||
if conn_sock != -1 {
|
||||
return Err("Failed to accept");
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(()) // this is safe.
|
||||
}
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
compile_error!("yeah not gonna compile that here, rip you");
|
||||
|
|
|
|||
53
src/listener.rs
Normal file
53
src/listener.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
use std::mem::MaybeUninit;
|
||||
use std::{io, mem};
|
||||
|
||||
const PORT: libc::in_port_t = 1234;
|
||||
|
||||
const SOCKADDR_IN_SIZE: libc::socklen_t = mem::size_of::<libc::sockaddr_in>() as _;
|
||||
|
||||
pub fn listener() -> io::Result<()> {
|
||||
unsafe {
|
||||
let socket = libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0);
|
||||
|
||||
if socket == -1 {
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
|
||||
println!("Created socket ({})", socket);
|
||||
|
||||
let addr = libc::sockaddr_in {
|
||||
sin_family: libc::AF_INET.try_into().unwrap(),
|
||||
sin_port: PORT,
|
||||
sin_addr: libc::in_addr {
|
||||
s_addr: libc::INADDR_ANY,
|
||||
},
|
||||
sin_zero: [0; 8],
|
||||
};
|
||||
let addr_erased_ptr = &addr as *const libc::sockaddr_in as _;
|
||||
|
||||
let result = libc::bind(socket, addr_erased_ptr, SOCKADDR_IN_SIZE);
|
||||
if result == -1 {
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
|
||||
println!("Bound socket ({socket}) on port {PORT}");
|
||||
|
||||
let result = libc::listen(socket, 5);
|
||||
if result != 0 {
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
|
||||
println!("Listening on socket ({socket})");
|
||||
|
||||
let mut peer_sockaddr = MaybeUninit::uninit();
|
||||
let mut sockaddr_size = 0;
|
||||
let connection = libc::accept(socket, peer_sockaddr.as_mut_ptr(), &mut sockaddr_size);
|
||||
if connection < 0 {
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
|
||||
println!("Received connection! (connfd={connection})");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
9
src/main.rs
Normal file
9
src/main.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
pub fn main() {
|
||||
match survey::listener::listener() {
|
||||
Ok(()) => {}
|
||||
Err(err) => {
|
||||
eprintln!("{err}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue